@cueframe/kernel 0.2.53 → 0.2.54

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.
Files changed (40) hide show
  1. package/dist/_members/composition/ops/compositionOps.shared.d.ts +1 -0
  2. package/dist/_members/composition/validators/composition.d.ts +80 -0
  3. package/dist/_members/composition/validators/render.d.ts +40 -0
  4. package/dist/_members/composition-ops/index.d.ts +15 -0
  5. package/dist/_members/core/render/compositionAudioAndDepth.d.ts +2 -1
  6. package/dist/_members/primitives/lib/text/spec.d.ts +1 -0
  7. package/dist/authoring/build-tools.js +5 -5
  8. package/dist/authoring/context.js +4 -4
  9. package/dist/authoring/tools.js +4 -4
  10. package/dist/authoring.js +6 -6
  11. package/dist/{chunk-P3DYA5NA.js → chunk-C3ARYFN6.js} +4 -4
  12. package/dist/{chunk-D2EG7J7X.js → chunk-DFB7UFZD.js} +1 -1
  13. package/dist/{chunk-ZIPGDGBR.js → chunk-FYMXVYWS.js} +1 -1
  14. package/dist/{chunk-LPUQTBKU.js → chunk-GZMKTLO3.js} +11 -1
  15. package/dist/{chunk-5E4YP44R.js → chunk-Q2FWFTDZ.js} +1 -1
  16. package/dist/{chunk-CJMUTCJW.js → chunk-QCGT3M7M.js} +1 -1
  17. package/dist/{chunk-4DM63RTI.js → chunk-QCJUGKRC.js} +4 -4
  18. package/dist/{chunk-VTM7NEJC.js → chunk-SIGKJOSF.js} +3 -3
  19. package/dist/{chunk-TPKPU4PE.js → chunk-T7WKIMTB.js} +8 -7
  20. package/dist/{chunk-46DGDPXR.js → chunk-V6GL37RZ.js} +98 -7
  21. package/dist/{chunk-UFNIB3JL.js → chunk-VKZTGD5Z.js} +11 -1
  22. package/dist/{chunk-ZFW35DLG.js → chunk-VYSBZUXZ.js} +1 -1
  23. package/dist/{chunk-7AUHC2X7.js → chunk-ZDE5S3DE.js} +1 -1
  24. package/dist/composition/graphics-plan.js +1 -1
  25. package/dist/composition/ops.js +3 -3
  26. package/dist/composition/validators.js +2 -2
  27. package/dist/composition-ops.js +5 -5
  28. package/dist/composition.js +2 -2
  29. package/dist/{context-UAS5WJRB.js → context-I7SPXR2Z.js} +4 -4
  30. package/dist/core/render.js +1 -1
  31. package/dist/core.js +1 -1
  32. package/dist/mcp/adapter.js +2 -2
  33. package/dist/mcp/core.js +1 -1
  34. package/dist/mcp/scene-shot.js +2 -2
  35. package/dist/mcp/server.js +9 -9
  36. package/dist/mcp.js +9 -9
  37. package/dist/primitives/captions.js +115 -46
  38. package/dist/primitives/lib/text/marker.js +1 -1
  39. package/dist/render-harness.js +1 -1
  40. package/package.json +11 -11
@@ -2,12 +2,12 @@ import {
2
2
  SCENE_SHOT_RESOURCE_DESCRIPTION,
3
3
  SCENE_SHOT_RESOURCE_URI,
4
4
  sceneShotContract
5
- } from "./chunk-7AUHC2X7.js";
5
+ } from "./chunk-ZDE5S3DE.js";
6
6
  import {
7
7
  querySchemaShape,
8
8
  serializeQuery,
9
9
  waitForJob
10
- } from "./chunk-ZFW35DLG.js";
10
+ } from "./chunk-VYSBZUXZ.js";
11
11
  import {
12
12
  CURATED_TOOLS
13
13
  } from "./chunk-4WBSXHQA.js";
@@ -28,10 +28,10 @@ import {
28
28
  text,
29
29
  textWithData,
30
30
  withMedia
31
- } from "./chunk-46DGDPXR.js";
31
+ } from "./chunk-V6GL37RZ.js";
32
32
  import {
33
33
  CompositionOp
34
- } from "./chunk-VTM7NEJC.js";
34
+ } from "./chunk-SIGKJOSF.js";
35
35
 
36
36
  // ../mcp/src/prompts.ts
37
37
  var skillListCache = null;
@@ -15,7 +15,7 @@ function Marker({ spec, progress }) {
15
15
  d: path,
16
16
  fill: "none",
17
17
  stroke: spec.color,
18
- strokeWidth: 4,
18
+ strokeWidth: spec.strokeWidth ?? 4,
19
19
  strokeLinecap: "round",
20
20
  strokeLinejoin: "round",
21
21
  pathLength: 1,
@@ -2,7 +2,7 @@ import {
2
2
  selectAllClips,
3
3
  selectAllOverlays,
4
4
  selectSceneMarkers
5
- } from "./chunk-TPKPU4PE.js";
5
+ } from "./chunk-T7WKIMTB.js";
6
6
 
7
7
  // ../authoring/src/context/transcript.ts
8
8
  var MAX_TRANSCRIPT_CHARS = 6e4;
@@ -1283,6 +1283,11 @@ function coversLowerPictures(upper, lower, output, effects) {
1283
1283
  return upperRect.left <= rect.left + epsilon && upperRect.top <= rect.top + epsilon && upperRect.right + epsilon >= rect.right && upperRect.bottom + epsilon >= rect.bottom;
1284
1284
  });
1285
1285
  }
1286
+ function explicitlyHidesCaptions(clip, effects) {
1287
+ if (!clip || clip.captionVisibility !== "hidden" || clip.mediaType === "image") return false;
1288
+ const region = clip.region;
1289
+ return !!region && region.x === 0 && region.y === 0 && region.w === 1 && region.h === 1 && (clip.opacity ?? 1) === 1 && (clip.scale ?? 1) === 1 && (clip.rotation ?? 0) === 0 && !clip.animate && !clip.cropTrajectory && !clip.cropTrajectoryUrl && !clip.hasCropIntent && !hasClipEffect(clip, effects) && !clip.hasTransition && (!clip.transitionIn || clip.transitionIn === "none");
1290
+ }
1286
1291
  function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects = [], hostMode = "packed-only") {
1287
1292
  if (endFrame <= startFrame) return [];
1288
1293
  const boundaries = /* @__PURE__ */ new Set([startFrame, endFrame]);
@@ -1318,7 +1323,7 @@ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects =
1318
1323
  effects
1319
1324
  ));
1320
1325
  const suppressesCaption = provesOcclusion && !globalEffectActive && pictureRect(top[0], output, effects) !== void 0;
1321
- const captionVisible = !(suppressesCaption && top[0].captionVisibility === "hidden");
1326
+ const captionVisible = !(top.length === 1 && !globalEffectActive && (suppressesCaption && top[0].captionVisibility === "hidden" || explicitlyHidesCaptions(top[0], effects)));
1322
1327
  const candidateHost = (clip) => hostMode === "all-video-candidates" ? clip.mediaType !== "image" : !!clip.packedUrl;
1323
1328
  const host = provesOcclusion && candidateHost(top[0]) ? top[0] : void 0;
1324
1329
  const unresolvedOverlap = top.length > 1 || top.length === 1 && active.length > 1 && !provesOcclusion;
@@ -1890,6 +1895,11 @@ function captionVisibilityWindowsForComposition(composition, sourceDimensions) {
1890
1895
  ...item.region ? { region: item.region } : {},
1891
1896
  ...item.fit ? { fit: item.fit } : {},
1892
1897
  ...track.kind === "video" && item.captionVisibility ? { captionVisibility: item.captionVisibility } : {},
1898
+ ...item.opacity !== void 0 ? { opacity: item.opacity } : {},
1899
+ ...item.scale !== void 0 ? { scale: item.scale } : {},
1900
+ ...item.rotation !== void 0 ? { rotation: item.rotation } : {},
1901
+ ...item.animate !== void 0 ? { animate: item.animate } : {},
1902
+ ...spanIndex === 0 && item.transitionIn?.type !== void 0 && item.transitionIn.type !== "cut" && item.transitionIn.type !== "none" ? { hasTransition: true } : {},
1893
1903
  ...item.source.reframe?.segments.length ? { hasCropIntent: true } : {},
1894
1904
  ...item.effects?.length ? { hasClipEffects: true } : {}
1895
1905
  });
@@ -2,7 +2,7 @@ import {
2
2
  COMPOSE_PLANNER_TOOLS,
3
3
  COMPOSE_ROLE_TOOLS,
4
4
  dispatchComposeRoleTool
5
- } from "./chunk-4DM63RTI.js";
5
+ } from "./chunk-QCJUGKRC.js";
6
6
 
7
7
  // ../authoring/src/agent/buildTools.ts
8
8
  import { tool } from "ai";
@@ -4,7 +4,7 @@ import {
4
4
  Format,
5
5
  GraphicRole,
6
6
  OpaqueId
7
- } from "./chunk-UFNIB3JL.js";
7
+ } from "./chunk-VKZTGD5Z.js";
8
8
  import {
9
9
  brandKitCaptionFaceIssues
10
10
  } from "./chunk-7RGDRDAR.js";
@@ -7,13 +7,13 @@ import {
7
7
  } from "./chunk-7AZLFN26.js";
8
8
  import {
9
9
  selectAllOverlays
10
- } from "./chunk-TPKPU4PE.js";
10
+ } from "./chunk-T7WKIMTB.js";
11
11
  import {
12
12
  ComposePlan
13
- } from "./chunk-CJMUTCJW.js";
13
+ } from "./chunk-QCGT3M7M.js";
14
14
  import {
15
15
  OverlayClipSource
16
- } from "./chunk-UFNIB3JL.js";
16
+ } from "./chunk-VKZTGD5Z.js";
17
17
 
18
18
  // ../authoring/src/tools/toolSets.ts
19
19
  var COMPOSE_PLANNER_TOOLS = [
@@ -63,7 +63,7 @@ var COMPOSE_ROLE_TOOLS = Object.freeze({
63
63
  schema: z.object({}),
64
64
  metadata: { label: "Get Context" },
65
65
  handler: async (_args, capabilities) => {
66
- const { buildDirectorContext } = await import("./context-UAS5WJRB.js");
66
+ const { buildDirectorContext } = await import("./context-I7SPXR2Z.js");
67
67
  return buildDirectorContext(capabilities);
68
68
  }
69
69
  },
@@ -3,13 +3,13 @@ import {
3
3
  projectMediaPlaybackSpans,
4
4
  sliceTranscriptWords,
5
5
  splitIntoSentences
6
- } from "./chunk-LPUQTBKU.js";
6
+ } from "./chunk-GZMKTLO3.js";
7
7
  import {
8
8
  createHeadlessStore,
9
9
  findClipById,
10
10
  findMarkerById,
11
11
  findTrackContainingClipId
12
- } from "./chunk-TPKPU4PE.js";
12
+ } from "./chunk-T7WKIMTB.js";
13
13
  import {
14
14
  CaptionLayoutInput,
15
15
  CaptionSegment,
@@ -25,7 +25,7 @@ import {
25
25
  captionLayoutIssues,
26
26
  captionSegmentSignature,
27
27
  captionVisibilityIssues
28
- } from "./chunk-UFNIB3JL.js";
28
+ } from "./chunk-VKZTGD5Z.js";
29
29
  import {
30
30
  ReframeSegment
31
31
  } from "./chunk-B7J5UUUV.js";
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  Composition
3
- } from "./chunk-UFNIB3JL.js";
3
+ } from "./chunk-VKZTGD5Z.js";
4
4
  import {
5
5
  expandToLinkGroup
6
6
  } from "./chunk-KYRDKK2D.js";
7
7
 
8
8
  // ../composition/src/ops/compositionOps.shared.ts
9
+ var TIMELINE_BOUNDARY_EPSILON_SECONDS = 1e-9;
9
10
  function findOrCreateTrackByKind(composition, kind) {
10
11
  const existing = composition.tracks.find((t) => t.kind === kind);
11
12
  if (existing) return existing;
@@ -67,8 +68,8 @@ function trimSourceFor(source, clipRelStart, clipRelEnd, clipDuration) {
67
68
  for (let i = 0; i < playable.length; i++) {
68
69
  const span = playable[i];
69
70
  const length = span.end - span.start;
70
- if (remaining < length - 1e-9) return span.start + remaining;
71
- if (Math.abs(remaining - length) <= 1e-9) {
71
+ if (remaining < length - TIMELINE_BOUNDARY_EPSILON_SECONDS) return span.start + remaining;
72
+ if (Math.abs(remaining - length) <= TIMELINE_BOUNDARY_EPSILON_SECONDS) {
72
73
  return edge === "start" && playable[i + 1] ? playable[i + 1].start : span.end;
73
74
  }
74
75
  remaining -= length;
@@ -508,20 +509,20 @@ function createCompositionOps(get, set) {
508
509
  const c = item;
509
510
  const cs = c.startTime;
510
511
  const ce = c.startTime + c.duration;
511
- if (ce <= start) {
512
+ if (ce <= start + TIMELINE_BOUNDARY_EPSILON_SECONDS) {
512
513
  next.push(c);
513
514
  continue;
514
515
  }
515
- if (cs >= end) {
516
+ if (cs >= end - TIMELINE_BOUNDARY_EPSILON_SECONDS) {
516
517
  next.push({ ...c, startTime: Math.max(0, cs - span) });
517
518
  continue;
518
519
  }
519
- if (cs < start) {
520
+ if (cs < start - TIMELINE_BOUNDARY_EPSILON_SECONDS) {
520
521
  const leftDuration = start - cs;
521
522
  const leftSource = trimSourceFor(c.source, 0, leftDuration, c.duration);
522
523
  next.push({ ...c, id: c.id, duration: leftDuration, source: leftSource });
523
524
  }
524
- if (ce > end) {
525
+ if (ce > end + TIMELINE_BOUNDARY_EPSILON_SECONDS) {
525
526
  const rightDuration = ce - end;
526
527
  const sourceOffsetIntoOriginal = end - cs;
527
528
  const rightSource = trimSourceFor(
@@ -1436,7 +1436,7 @@ var BriefCreateRequest = zod19.strictObject({
1436
1436
  "h": zod19.number().gt(briefCreateRequestSeededGraphicsItemRegionHExclusiveMin).max(briefCreateRequestSeededGraphicsItemRegionHMax)
1437
1437
  }).optional(),
1438
1438
  "fit": zod19.enum(["cover", "contain"]).optional(),
1439
- "captionVisibility": zod19.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
1439
+ "captionVisibility": zod19.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
1440
1440
  "effects": zod19.array(zod19.strictObject({
1441
1441
  "primitiveId": zod19.string().min(1),
1442
1442
  "params": zod19.record(zod19.string(), zod19.unknown()).optional()
@@ -1698,7 +1698,7 @@ var BriefResponse = zod21.strictObject({
1698
1698
  "h": zod21.number().gt(briefResponseSeededGraphicsItemRegionHExclusiveMin).max(briefResponseSeededGraphicsItemRegionHMax)
1699
1699
  }).optional(),
1700
1700
  "fit": zod21.enum(["cover", "contain"]).optional(),
1701
- "captionVisibility": zod21.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
1701
+ "captionVisibility": zod21.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
1702
1702
  "effects": zod21.array(zod21.strictObject({
1703
1703
  "primitiveId": zod21.string().min(1),
1704
1704
  "params": zod21.record(zod21.string(), zod21.unknown()).optional()
@@ -1949,7 +1949,7 @@ var BriefPatchRequest = zod23.strictObject({
1949
1949
  "h": zod23.number().gt(briefPatchRequestSeededGraphicsItemRegionHExclusiveMin).max(briefPatchRequestSeededGraphicsItemRegionHMax)
1950
1950
  }).optional(),
1951
1951
  "fit": zod23.enum(["cover", "contain"]).optional(),
1952
- "captionVisibility": zod23.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
1952
+ "captionVisibility": zod23.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
1953
1953
  "effects": zod23.array(zod23.strictObject({
1954
1954
  "primitiveId": zod23.string().min(1),
1955
1955
  "params": zod23.record(zod23.string(), zod23.unknown()).optional()
@@ -2595,6 +2595,12 @@ var compositionCaptionsOneStyleRegionWExclusiveMin = 0;
2595
2595
  var compositionCaptionsOneStyleRegionWMax = 1;
2596
2596
  var compositionCaptionsOneStyleRegionHExclusiveMin = 0;
2597
2597
  var compositionCaptionsOneStyleRegionHMax = 1;
2598
+ var compositionCaptionsOneStyleLetterSpacingMin = -5;
2599
+ var compositionCaptionsOneStyleLetterSpacingMax = 20;
2600
+ var compositionCaptionsOneStyleWordGapEmMin = 0;
2601
+ var compositionCaptionsOneStyleWordGapEmMax = 2;
2602
+ var compositionCaptionsOneStyleLineGapEmMin = 0;
2603
+ var compositionCaptionsOneStyleLineGapEmMax = 2;
2598
2604
  var compositionCaptionsOneStyleEmphasisScaleExclusiveMin = 0;
2599
2605
  var compositionCaptionsOneStyleEmphasisFontWeightMin = 100;
2600
2606
  var compositionCaptionsOneStyleEmphasisFontWeightMax = 900;
@@ -2602,6 +2608,8 @@ var compositionCaptionsOneStyleEntranceMsMin = 0;
2602
2608
  var compositionCaptionsOneStyleEntranceStaggerMsMin = 0;
2603
2609
  var compositionCaptionsOneStyleExitMsMin = 0;
2604
2610
  var compositionCaptionsOneStyleEmphasisPlateRadiusMin = 0;
2611
+ var compositionCaptionsOneStyleAnnotationStrokeWidthMin = 0.5;
2612
+ var compositionCaptionsOneStyleAnnotationStrokeWidthMax = 12;
2605
2613
  var compositionCaptionsOneStyleMaxWidthPercentExclusiveMin = 0;
2606
2614
  var compositionCaptionsOneStyleMaxWidthPercentMax = 100;
2607
2615
  var compositionCaptionsOneLayoutsItemSegmentIndexMin = 0;
@@ -2625,10 +2633,18 @@ var compositionCaptionsOneLayoutsItemRotationMax = 45;
2625
2633
  var compositionCaptionsOneLayoutsItemStyleFontSizeMax = 15;
2626
2634
  var compositionCaptionsOneLayoutsItemStyleFontWeightMin = 100;
2627
2635
  var compositionCaptionsOneLayoutsItemStyleFontWeightMax = 900;
2636
+ var compositionCaptionsOneLayoutsItemStyleLetterSpacingMin = -5;
2637
+ var compositionCaptionsOneLayoutsItemStyleLetterSpacingMax = 20;
2638
+ var compositionCaptionsOneLayoutsItemStyleWordGapEmMin = 0;
2639
+ var compositionCaptionsOneLayoutsItemStyleWordGapEmMax = 2;
2640
+ var compositionCaptionsOneLayoutsItemStyleLineGapEmMin = 0;
2641
+ var compositionCaptionsOneLayoutsItemStyleLineGapEmMax = 2;
2628
2642
  var compositionCaptionsOneLayoutsItemStyleEmphasisScaleExclusiveMin = 0;
2629
2643
  var compositionCaptionsOneLayoutsItemStyleEmphasisFontWeightMin = 100;
2630
2644
  var compositionCaptionsOneLayoutsItemStyleEmphasisFontWeightMax = 900;
2631
2645
  var compositionCaptionsOneLayoutsItemStyleEmphasisPlateRadiusMin = 0;
2646
+ var compositionCaptionsOneLayoutsItemStyleAnnotationStrokeWidthMin = 0.5;
2647
+ var compositionCaptionsOneLayoutsItemStyleAnnotationStrokeWidthMax = 12;
2632
2648
  var compositionCaptionsOneLayoutsItemStyleEntranceMsMin = 0;
2633
2649
  var compositionCaptionsOneLayoutsItemStyleEntranceStaggerMsMin = 0;
2634
2650
  var compositionCaptionsOneLayoutsItemStyleExitMsMin = 0;
@@ -2650,6 +2666,12 @@ var compositionCaptionsTwoStyleRegionWExclusiveMin = 0;
2650
2666
  var compositionCaptionsTwoStyleRegionWMax = 1;
2651
2667
  var compositionCaptionsTwoStyleRegionHExclusiveMin = 0;
2652
2668
  var compositionCaptionsTwoStyleRegionHMax = 1;
2669
+ var compositionCaptionsTwoStyleLetterSpacingMin = -5;
2670
+ var compositionCaptionsTwoStyleLetterSpacingMax = 20;
2671
+ var compositionCaptionsTwoStyleWordGapEmMin = 0;
2672
+ var compositionCaptionsTwoStyleWordGapEmMax = 2;
2673
+ var compositionCaptionsTwoStyleLineGapEmMin = 0;
2674
+ var compositionCaptionsTwoStyleLineGapEmMax = 2;
2653
2675
  var compositionCaptionsTwoStyleEmphasisScaleExclusiveMin = 0;
2654
2676
  var compositionCaptionsTwoStyleEmphasisFontWeightMin = 100;
2655
2677
  var compositionCaptionsTwoStyleEmphasisFontWeightMax = 900;
@@ -2657,6 +2679,8 @@ var compositionCaptionsTwoStyleEntranceMsMin = 0;
2657
2679
  var compositionCaptionsTwoStyleEntranceStaggerMsMin = 0;
2658
2680
  var compositionCaptionsTwoStyleExitMsMin = 0;
2659
2681
  var compositionCaptionsTwoStyleEmphasisPlateRadiusMin = 0;
2682
+ var compositionCaptionsTwoStyleAnnotationStrokeWidthMin = 0.5;
2683
+ var compositionCaptionsTwoStyleAnnotationStrokeWidthMax = 12;
2660
2684
  var compositionCaptionsTwoStyleMaxWidthPercentExclusiveMin = 0;
2661
2685
  var compositionCaptionsTwoStyleMaxWidthPercentMax = 100;
2662
2686
  var compositionCaptionsTwoLayoutsItemSegmentIndexMin = 0;
@@ -2680,10 +2704,18 @@ var compositionCaptionsTwoLayoutsItemRotationMax = 45;
2680
2704
  var compositionCaptionsTwoLayoutsItemStyleFontSizeMax = 15;
2681
2705
  var compositionCaptionsTwoLayoutsItemStyleFontWeightMin = 100;
2682
2706
  var compositionCaptionsTwoLayoutsItemStyleFontWeightMax = 900;
2707
+ var compositionCaptionsTwoLayoutsItemStyleLetterSpacingMin = -5;
2708
+ var compositionCaptionsTwoLayoutsItemStyleLetterSpacingMax = 20;
2709
+ var compositionCaptionsTwoLayoutsItemStyleWordGapEmMin = 0;
2710
+ var compositionCaptionsTwoLayoutsItemStyleWordGapEmMax = 2;
2711
+ var compositionCaptionsTwoLayoutsItemStyleLineGapEmMin = 0;
2712
+ var compositionCaptionsTwoLayoutsItemStyleLineGapEmMax = 2;
2683
2713
  var compositionCaptionsTwoLayoutsItemStyleEmphasisScaleExclusiveMin = 0;
2684
2714
  var compositionCaptionsTwoLayoutsItemStyleEmphasisFontWeightMin = 100;
2685
2715
  var compositionCaptionsTwoLayoutsItemStyleEmphasisFontWeightMax = 900;
2686
2716
  var compositionCaptionsTwoLayoutsItemStyleEmphasisPlateRadiusMin = 0;
2717
+ var compositionCaptionsTwoLayoutsItemStyleAnnotationStrokeWidthMin = 0.5;
2718
+ var compositionCaptionsTwoLayoutsItemStyleAnnotationStrokeWidthMax = 12;
2687
2719
  var compositionCaptionsTwoLayoutsItemStyleEntranceMsMin = 0;
2688
2720
  var compositionCaptionsTwoLayoutsItemStyleEntranceStaggerMsMin = 0;
2689
2721
  var compositionCaptionsTwoLayoutsItemStyleExitMsMin = 0;
@@ -2824,7 +2856,7 @@ var Composition = zod58.strictObject({
2824
2856
  "h": zod58.number().gt(compositionTracksItemContentsItemOneRegionHExclusiveMin).max(compositionTracksItemContentsItemOneRegionHMax)
2825
2857
  }).optional(),
2826
2858
  "fit": zod58.enum(["cover", "contain"]).optional(),
2827
- "captionVisibility": zod58.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
2859
+ "captionVisibility": zod58.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
2828
2860
  "effects": zod58.array(zod58.strictObject({
2829
2861
  "primitiveId": zod58.string().min(1),
2830
2862
  "params": zod58.record(zod58.string(), zod58.unknown()).optional()
@@ -2890,6 +2922,9 @@ var Composition = zod58.strictObject({
2890
2922
  "h": zod58.number().gt(compositionCaptionsOneStyleRegionHExclusiveMin).max(compositionCaptionsOneStyleRegionHMax)
2891
2923
  }).optional().describe("Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height."),
2892
2924
  "textTransform": zod58.enum(["none", "uppercase", "capitalize"]).optional(),
2925
+ "letterSpacing": zod58.number().min(compositionCaptionsOneStyleLetterSpacingMin).max(compositionCaptionsOneStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
2926
+ "wordGapEm": zod58.number().min(compositionCaptionsOneStyleWordGapEmMin).max(compositionCaptionsOneStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
2927
+ "lineGapEm": zod58.number().min(compositionCaptionsOneStyleLineGapEmMin).max(compositionCaptionsOneStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
2893
2928
  "emphasisColor": zod58.string().optional(),
2894
2929
  "emphasisGradient": zod58.string().optional(),
2895
2930
  "emphasisScale": zod58.number().gt(compositionCaptionsOneStyleEmphasisScaleExclusiveMin).optional(),
@@ -2910,7 +2945,9 @@ var Composition = zod58.strictObject({
2910
2945
  "emphasisPlateRadius": zod58.number().min(compositionCaptionsOneStyleEmphasisPlateRadiusMin).optional(),
2911
2946
  "emphasisPlatePadX": zod58.number().optional(),
2912
2947
  "emphasisPlatePadY": zod58.number().optional(),
2948
+ "emphasisPlateReveal": zod58.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
2913
2949
  "annotationColor": zod58.string().optional(),
2950
+ "annotationStrokeWidth": zod58.number().min(compositionCaptionsOneStyleAnnotationStrokeWidthMin).max(compositionCaptionsOneStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
2914
2951
  "maxWidthPercent": zod58.number().gt(compositionCaptionsOneStyleMaxWidthPercentExclusiveMin).max(compositionCaptionsOneStyleMaxWidthPercentMax).optional()
2915
2952
  }).optional(),
2916
2953
  "layouts": zod58.array(zod58.strictObject({
@@ -2934,6 +2971,9 @@ var Composition = zod58.strictObject({
2934
2971
  "backgroundColor": zod58.string().optional(),
2935
2972
  "plate": zod58.enum(["glass", "solid", "none"]).optional(),
2936
2973
  "textTransform": zod58.enum(["none", "uppercase", "capitalize"]).optional(),
2974
+ "letterSpacing": zod58.number().min(compositionCaptionsOneLayoutsItemStyleLetterSpacingMin).max(compositionCaptionsOneLayoutsItemStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
2975
+ "wordGapEm": zod58.number().min(compositionCaptionsOneLayoutsItemStyleWordGapEmMin).max(compositionCaptionsOneLayoutsItemStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
2976
+ "lineGapEm": zod58.number().min(compositionCaptionsOneLayoutsItemStyleLineGapEmMin).max(compositionCaptionsOneLayoutsItemStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
2937
2977
  "emphasisColor": zod58.string().optional(),
2938
2978
  "emphasisScale": zod58.number().gt(compositionCaptionsOneLayoutsItemStyleEmphasisScaleExclusiveMin).optional(),
2939
2979
  "emphasisFontFamily": zod58.string().optional(),
@@ -2949,7 +2989,9 @@ var Composition = zod58.strictObject({
2949
2989
  "emphasisPlateRadius": zod58.number().min(compositionCaptionsOneLayoutsItemStyleEmphasisPlateRadiusMin).optional(),
2950
2990
  "emphasisPlatePadX": zod58.number().optional(),
2951
2991
  "emphasisPlatePadY": zod58.number().optional(),
2992
+ "emphasisPlateReveal": zod58.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
2952
2993
  "annotationColor": zod58.string().optional(),
2994
+ "annotationStrokeWidth": zod58.number().min(compositionCaptionsOneLayoutsItemStyleAnnotationStrokeWidthMin).max(compositionCaptionsOneLayoutsItemStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
2953
2995
  "entrance": zod58.enum(["none", "fade", "word-pop", "stagger-up"]).optional(),
2954
2996
  "entranceMs": zod58.number().min(compositionCaptionsOneLayoutsItemStyleEntranceMsMin).optional(),
2955
2997
  "entranceStaggerMs": zod58.number().min(compositionCaptionsOneLayoutsItemStyleEntranceStaggerMsMin).optional(),
@@ -2991,6 +3033,9 @@ var Composition = zod58.strictObject({
2991
3033
  "h": zod58.number().gt(compositionCaptionsTwoStyleRegionHExclusiveMin).max(compositionCaptionsTwoStyleRegionHMax)
2992
3034
  }).optional().describe("Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height."),
2993
3035
  "textTransform": zod58.enum(["none", "uppercase", "capitalize"]).optional(),
3036
+ "letterSpacing": zod58.number().min(compositionCaptionsTwoStyleLetterSpacingMin).max(compositionCaptionsTwoStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
3037
+ "wordGapEm": zod58.number().min(compositionCaptionsTwoStyleWordGapEmMin).max(compositionCaptionsTwoStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
3038
+ "lineGapEm": zod58.number().min(compositionCaptionsTwoStyleLineGapEmMin).max(compositionCaptionsTwoStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
2994
3039
  "emphasisColor": zod58.string().optional(),
2995
3040
  "emphasisGradient": zod58.string().optional(),
2996
3041
  "emphasisScale": zod58.number().gt(compositionCaptionsTwoStyleEmphasisScaleExclusiveMin).optional(),
@@ -3011,7 +3056,9 @@ var Composition = zod58.strictObject({
3011
3056
  "emphasisPlateRadius": zod58.number().min(compositionCaptionsTwoStyleEmphasisPlateRadiusMin).optional(),
3012
3057
  "emphasisPlatePadX": zod58.number().optional(),
3013
3058
  "emphasisPlatePadY": zod58.number().optional(),
3059
+ "emphasisPlateReveal": zod58.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
3014
3060
  "annotationColor": zod58.string().optional(),
3061
+ "annotationStrokeWidth": zod58.number().min(compositionCaptionsTwoStyleAnnotationStrokeWidthMin).max(compositionCaptionsTwoStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
3015
3062
  "maxWidthPercent": zod58.number().gt(compositionCaptionsTwoStyleMaxWidthPercentExclusiveMin).max(compositionCaptionsTwoStyleMaxWidthPercentMax).optional()
3016
3063
  }).optional(),
3017
3064
  "layouts": zod58.array(zod58.strictObject({
@@ -3035,6 +3082,9 @@ var Composition = zod58.strictObject({
3035
3082
  "backgroundColor": zod58.string().optional(),
3036
3083
  "plate": zod58.enum(["glass", "solid", "none"]).optional(),
3037
3084
  "textTransform": zod58.enum(["none", "uppercase", "capitalize"]).optional(),
3085
+ "letterSpacing": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleLetterSpacingMin).max(compositionCaptionsTwoLayoutsItemStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
3086
+ "wordGapEm": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleWordGapEmMin).max(compositionCaptionsTwoLayoutsItemStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
3087
+ "lineGapEm": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleLineGapEmMin).max(compositionCaptionsTwoLayoutsItemStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
3038
3088
  "emphasisColor": zod58.string().optional(),
3039
3089
  "emphasisScale": zod58.number().gt(compositionCaptionsTwoLayoutsItemStyleEmphasisScaleExclusiveMin).optional(),
3040
3090
  "emphasisFontFamily": zod58.string().optional(),
@@ -3050,7 +3100,9 @@ var Composition = zod58.strictObject({
3050
3100
  "emphasisPlateRadius": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleEmphasisPlateRadiusMin).optional(),
3051
3101
  "emphasisPlatePadX": zod58.number().optional(),
3052
3102
  "emphasisPlatePadY": zod58.number().optional(),
3103
+ "emphasisPlateReveal": zod58.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
3053
3104
  "annotationColor": zod58.string().optional(),
3105
+ "annotationStrokeWidth": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleAnnotationStrokeWidthMin).max(compositionCaptionsTwoLayoutsItemStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
3054
3106
  "entrance": zod58.enum(["none", "fade", "word-pop", "stagger-up"]).optional(),
3055
3107
  "entranceMs": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleEntranceMsMin).optional(),
3056
3108
  "entranceStaggerMs": zod58.number().min(compositionCaptionsTwoLayoutsItemStyleEntranceStaggerMsMin).optional(),
@@ -6278,6 +6330,12 @@ var compositionOpOnethreeStyleRegionWExclusiveMin = 0;
6278
6330
  var compositionOpOnethreeStyleRegionWMax = 1;
6279
6331
  var compositionOpOnethreeStyleRegionHExclusiveMin = 0;
6280
6332
  var compositionOpOnethreeStyleRegionHMax = 1;
6333
+ var compositionOpOnethreeStyleLetterSpacingMin = -5;
6334
+ var compositionOpOnethreeStyleLetterSpacingMax = 20;
6335
+ var compositionOpOnethreeStyleWordGapEmMin = 0;
6336
+ var compositionOpOnethreeStyleWordGapEmMax = 2;
6337
+ var compositionOpOnethreeStyleLineGapEmMin = 0;
6338
+ var compositionOpOnethreeStyleLineGapEmMax = 2;
6281
6339
  var compositionOpOnethreeStyleEmphasisScaleExclusiveMin = 0;
6282
6340
  var compositionOpOnethreeStyleEmphasisFontWeightMin = 100;
6283
6341
  var compositionOpOnethreeStyleEmphasisFontWeightMax = 900;
@@ -6285,6 +6343,8 @@ var compositionOpOnethreeStyleEntranceMsMin = 0;
6285
6343
  var compositionOpOnethreeStyleEntranceStaggerMsMin = 0;
6286
6344
  var compositionOpOnethreeStyleExitMsMin = 0;
6287
6345
  var compositionOpOnethreeStyleEmphasisPlateRadiusMin = 0;
6346
+ var compositionOpOnethreeStyleAnnotationStrokeWidthMin = 0.5;
6347
+ var compositionOpOnethreeStyleAnnotationStrokeWidthMax = 12;
6288
6348
  var compositionOpOnethreeStyleMaxWidthPercentExclusiveMin = 0;
6289
6349
  var compositionOpOnethreeStyleMaxWidthPercentMax = 100;
6290
6350
  var compositionOpOnefourLayoutsItemSegmentIndexMin = 0;
@@ -6308,10 +6368,18 @@ var compositionOpOnefourLayoutsItemRotationMax = 45;
6308
6368
  var compositionOpOnefourLayoutsItemStyleFontSizeMax = 15;
6309
6369
  var compositionOpOnefourLayoutsItemStyleFontWeightMin = 100;
6310
6370
  var compositionOpOnefourLayoutsItemStyleFontWeightMax = 900;
6371
+ var compositionOpOnefourLayoutsItemStyleLetterSpacingMin = -5;
6372
+ var compositionOpOnefourLayoutsItemStyleLetterSpacingMax = 20;
6373
+ var compositionOpOnefourLayoutsItemStyleWordGapEmMin = 0;
6374
+ var compositionOpOnefourLayoutsItemStyleWordGapEmMax = 2;
6375
+ var compositionOpOnefourLayoutsItemStyleLineGapEmMin = 0;
6376
+ var compositionOpOnefourLayoutsItemStyleLineGapEmMax = 2;
6311
6377
  var compositionOpOnefourLayoutsItemStyleEmphasisScaleExclusiveMin = 0;
6312
6378
  var compositionOpOnefourLayoutsItemStyleEmphasisFontWeightMin = 100;
6313
6379
  var compositionOpOnefourLayoutsItemStyleEmphasisFontWeightMax = 900;
6314
6380
  var compositionOpOnefourLayoutsItemStyleEmphasisPlateRadiusMin = 0;
6381
+ var compositionOpOnefourLayoutsItemStyleAnnotationStrokeWidthMin = 0.5;
6382
+ var compositionOpOnefourLayoutsItemStyleAnnotationStrokeWidthMax = 12;
6315
6383
  var compositionOpOnefourLayoutsItemStyleEntranceMsMin = 0;
6316
6384
  var compositionOpOnefourLayoutsItemStyleEntranceStaggerMsMin = 0;
6317
6385
  var compositionOpOnefourLayoutsItemStyleExitMsMin = 0;
@@ -6332,6 +6400,12 @@ var compositionOpOnesixStyleRegionWExclusiveMin = 0;
6332
6400
  var compositionOpOnesixStyleRegionWMax = 1;
6333
6401
  var compositionOpOnesixStyleRegionHExclusiveMin = 0;
6334
6402
  var compositionOpOnesixStyleRegionHMax = 1;
6403
+ var compositionOpOnesixStyleLetterSpacingMin = -5;
6404
+ var compositionOpOnesixStyleLetterSpacingMax = 20;
6405
+ var compositionOpOnesixStyleWordGapEmMin = 0;
6406
+ var compositionOpOnesixStyleWordGapEmMax = 2;
6407
+ var compositionOpOnesixStyleLineGapEmMin = 0;
6408
+ var compositionOpOnesixStyleLineGapEmMax = 2;
6335
6409
  var compositionOpOnesixStyleEmphasisScaleExclusiveMin = 0;
6336
6410
  var compositionOpOnesixStyleEmphasisFontWeightMin = 100;
6337
6411
  var compositionOpOnesixStyleEmphasisFontWeightMax = 900;
@@ -6339,6 +6413,8 @@ var compositionOpOnesixStyleEntranceMsMin = 0;
6339
6413
  var compositionOpOnesixStyleEntranceStaggerMsMin = 0;
6340
6414
  var compositionOpOnesixStyleExitMsMin = 0;
6341
6415
  var compositionOpOnesixStyleEmphasisPlateRadiusMin = 0;
6416
+ var compositionOpOnesixStyleAnnotationStrokeWidthMin = 0.5;
6417
+ var compositionOpOnesixStyleAnnotationStrokeWidthMax = 12;
6342
6418
  var compositionOpOnesixStyleMaxWidthPercentExclusiveMin = 0;
6343
6419
  var compositionOpOnesixStyleMaxWidthPercentMax = 100;
6344
6420
  var compositionOpOnesevenWindowStartSecMin = 0;
@@ -6484,7 +6560,7 @@ var CompositionOp = zod67.union([zod67.strictObject({
6484
6560
  "h": zod67.number().gt(compositionOpThreeClipRegionHExclusiveMin).max(compositionOpThreeClipRegionHMax)
6485
6561
  }).optional(),
6486
6562
  "fit": zod67.enum(["cover", "contain"]).optional(),
6487
- "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
6563
+ "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
6488
6564
  "effects": zod67.array(zod67.strictObject({
6489
6565
  "primitiveId": zod67.string().min(1),
6490
6566
  "params": zod67.record(zod67.string(), zod67.unknown()).optional()
@@ -6634,7 +6710,7 @@ var CompositionOp = zod67.union([zod67.strictObject({
6634
6710
  "h": zod67.number().gt(compositionOpFivePatchRegionHExclusiveMin).max(compositionOpFivePatchRegionHMax)
6635
6711
  }).optional(),
6636
6712
  "fit": zod67.enum(["cover", "contain"]).optional(),
6637
- "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
6713
+ "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
6638
6714
  "effects": zod67.array(zod67.strictObject({
6639
6715
  "primitiveId": zod67.string().min(1),
6640
6716
  "params": zod67.record(zod67.string(), zod67.unknown()).optional()
@@ -6780,7 +6856,7 @@ var CompositionOp = zod67.union([zod67.strictObject({
6780
6856
  "h": zod67.number().gt(compositionOpSevenClipsItemRegionHExclusiveMin).max(compositionOpSevenClipsItemRegionHMax)
6781
6857
  }).optional(),
6782
6858
  "fit": zod67.enum(["cover", "contain"]).optional(),
6783
- "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."),
6859
+ "captionVisibility": zod67.enum(["visible", "hidden"]).optional().describe("Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."),
6784
6860
  "effects": zod67.array(zod67.strictObject({
6785
6861
  "primitiveId": zod67.string().min(1),
6786
6862
  "params": zod67.record(zod67.string(), zod67.unknown()).optional()
@@ -6884,6 +6960,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
6884
6960
  "h": zod67.number().gt(compositionOpOnethreeStyleRegionHExclusiveMin).max(compositionOpOnethreeStyleRegionHMax)
6885
6961
  }).optional().describe("Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height."),
6886
6962
  "textTransform": zod67.enum(["none", "uppercase", "capitalize"]).optional(),
6963
+ "letterSpacing": zod67.number().min(compositionOpOnethreeStyleLetterSpacingMin).max(compositionOpOnethreeStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
6964
+ "wordGapEm": zod67.number().min(compositionOpOnethreeStyleWordGapEmMin).max(compositionOpOnethreeStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
6965
+ "lineGapEm": zod67.number().min(compositionOpOnethreeStyleLineGapEmMin).max(compositionOpOnethreeStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
6887
6966
  "emphasisColor": zod67.string().optional(),
6888
6967
  "emphasisGradient": zod67.string().optional(),
6889
6968
  "emphasisScale": zod67.number().gt(compositionOpOnethreeStyleEmphasisScaleExclusiveMin).optional(),
@@ -6904,7 +6983,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
6904
6983
  "emphasisPlateRadius": zod67.number().min(compositionOpOnethreeStyleEmphasisPlateRadiusMin).optional(),
6905
6984
  "emphasisPlatePadX": zod67.number().optional(),
6906
6985
  "emphasisPlatePadY": zod67.number().optional(),
6986
+ "emphasisPlateReveal": zod67.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
6907
6987
  "annotationColor": zod67.string().optional(),
6988
+ "annotationStrokeWidth": zod67.number().min(compositionOpOnethreeStyleAnnotationStrokeWidthMin).max(compositionOpOnethreeStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
6908
6989
  "maxWidthPercent": zod67.number().gt(compositionOpOnethreeStyleMaxWidthPercentExclusiveMin).max(compositionOpOnethreeStyleMaxWidthPercentMax).optional()
6909
6990
  })
6910
6991
  }).describe("Merge style overrides (font/color/position/emphasis) onto the composition's caption layer. Partial \u2014 omitted fields keep their current value; creates the caption container if absent."), zod67.strictObject({
@@ -6930,6 +7011,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
6930
7011
  "backgroundColor": zod67.string().optional(),
6931
7012
  "plate": zod67.enum(["glass", "solid", "none"]).optional(),
6932
7013
  "textTransform": zod67.enum(["none", "uppercase", "capitalize"]).optional(),
7014
+ "letterSpacing": zod67.number().min(compositionOpOnefourLayoutsItemStyleLetterSpacingMin).max(compositionOpOnefourLayoutsItemStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
7015
+ "wordGapEm": zod67.number().min(compositionOpOnefourLayoutsItemStyleWordGapEmMin).max(compositionOpOnefourLayoutsItemStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
7016
+ "lineGapEm": zod67.number().min(compositionOpOnefourLayoutsItemStyleLineGapEmMin).max(compositionOpOnefourLayoutsItemStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
6933
7017
  "emphasisColor": zod67.string().optional(),
6934
7018
  "emphasisScale": zod67.number().gt(compositionOpOnefourLayoutsItemStyleEmphasisScaleExclusiveMin).optional(),
6935
7019
  "emphasisFontFamily": zod67.string().optional(),
@@ -6945,7 +7029,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
6945
7029
  "emphasisPlateRadius": zod67.number().min(compositionOpOnefourLayoutsItemStyleEmphasisPlateRadiusMin).optional(),
6946
7030
  "emphasisPlatePadX": zod67.number().optional(),
6947
7031
  "emphasisPlatePadY": zod67.number().optional(),
7032
+ "emphasisPlateReveal": zod67.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
6948
7033
  "annotationColor": zod67.string().optional(),
7034
+ "annotationStrokeWidth": zod67.number().min(compositionOpOnefourLayoutsItemStyleAnnotationStrokeWidthMin).max(compositionOpOnefourLayoutsItemStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
6949
7035
  "entrance": zod67.enum(["none", "fade", "word-pop", "stagger-up"]).optional(),
6950
7036
  "entranceMs": zod67.number().min(compositionOpOnefourLayoutsItemStyleEntranceMsMin).optional(),
6951
7037
  "entranceStaggerMs": zod67.number().min(compositionOpOnefourLayoutsItemStyleEntranceStaggerMsMin).optional(),
@@ -6988,6 +7074,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
6988
7074
  "h": zod67.number().gt(compositionOpOnesixStyleRegionHExclusiveMin).max(compositionOpOnesixStyleRegionHMax)
6989
7075
  }).optional().describe("Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height."),
6990
7076
  "textTransform": zod67.enum(["none", "uppercase", "capitalize"]).optional(),
7077
+ "letterSpacing": zod67.number().min(compositionOpOnesixStyleLetterSpacingMin).max(compositionOpOnesixStyleLetterSpacingMax).optional().describe("Base caption glyph spacing in pixels."),
7078
+ "wordGapEm": zod67.number().min(compositionOpOnesixStyleWordGapEmMin).max(compositionOpOnesixStyleWordGapEmMax).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
7079
+ "lineGapEm": zod67.number().min(compositionOpOnesixStyleLineGapEmMin).max(compositionOpOnesixStyleLineGapEmMax).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
6991
7080
  "emphasisColor": zod67.string().optional(),
6992
7081
  "emphasisGradient": zod67.string().optional(),
6993
7082
  "emphasisScale": zod67.number().gt(compositionOpOnesixStyleEmphasisScaleExclusiveMin).optional(),
@@ -7008,7 +7097,9 @@ var CompositionOp = zod67.union([zod67.strictObject({
7008
7097
  "emphasisPlateRadius": zod67.number().min(compositionOpOnesixStyleEmphasisPlateRadiusMin).optional(),
7009
7098
  "emphasisPlatePadX": zod67.number().optional(),
7010
7099
  "emphasisPlatePadY": zod67.number().optional(),
7100
+ "emphasisPlateReveal": zod67.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
7011
7101
  "annotationColor": zod67.string().optional(),
7102
+ "annotationStrokeWidth": zod67.number().min(compositionOpOnesixStyleAnnotationStrokeWidthMin).max(compositionOpOnesixStyleAnnotationStrokeWidthMax).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
7012
7103
  "maxWidthPercent": zod67.number().gt(compositionOpOnesixStyleMaxWidthPercentExclusiveMin).max(compositionOpOnesixStyleMaxWidthPercentMax).optional()
7013
7104
  }).optional()
7014
7105
  }).describe("Replace the caption SEGMENTS wholesale \u2014 author the word-timed caption layer directly (each segment = one sentence/page of `words` with timeline-ms `startMs`/`endMs`, optional `emphasis`). This is how a client with its OWN word timings (e.g. a generated VO take) gets word-synced captions without a source transcript; the compose lane's transcript slice writes the same layer. `style`, when given, merges with setCaptionStyle semantics; an omitted style keeps the existing one. Renderer paginates within a segment and never pools words across two \u2014 keep segments sentence-bounded."), zod67.strictObject({
@@ -170,7 +170,7 @@ var TimelineClip = z2.object({
170
170
  region: Region.optional(),
171
171
  fit: ClipFit.optional(),
172
172
  captionVisibility: CaptionVisibility.optional().describe(
173
- "Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."
173
+ "Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over."
174
174
  ),
175
175
  effects: z2.array(PerClipEffect).optional(),
176
176
  transitionIn: Transition.optional(),
@@ -267,6 +267,9 @@ var CaptionStyle = z2.object({
267
267
  "Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height."
268
268
  ),
269
269
  textTransform: z2.enum(["none", "uppercase", "capitalize"]).optional(),
270
+ letterSpacing: z2.number().min(-5).max(20).optional().describe("Base caption glyph spacing in pixels."),
271
+ wordGapEm: z2.number().min(0).max(2).optional().describe("Gap between caption runs as a multiple of base font size; default 0.35."),
272
+ lineGapEm: z2.number().min(0).max(2).optional().describe("Gap between caption lines as a multiple of base font size; default 0.25."),
270
273
  emphasisColor: z2.string().optional(),
271
274
  emphasisGradient: z2.string().optional(),
272
275
  emphasisScale: z2.number().positive().optional(),
@@ -287,7 +290,9 @@ var CaptionStyle = z2.object({
287
290
  emphasisPlateRadius: z2.number().nonnegative().optional(),
288
291
  emphasisPlatePadX: z2.number().optional(),
289
292
  emphasisPlatePadY: z2.number().optional(),
293
+ emphasisPlateReveal: z2.boolean().optional().describe("Grow a shared emphasis plate as saved words appear while reserving its final layout width."),
290
294
  annotationColor: z2.string().optional(),
295
+ annotationStrokeWidth: z2.number().min(0.5).max(12).optional().describe("Annotation stroke width in its 100\xD7100 SVG coordinate system; default 4."),
291
296
  maxWidthPercent: z2.number().positive().max(100, "captions style.maxWidthPercent is % of composition width (max 100)").optional()
292
297
  });
293
298
  var CaptionLayoutStyle = CaptionStyle.pick({
@@ -299,6 +304,9 @@ var CaptionLayoutStyle = CaptionStyle.pick({
299
304
  backgroundColor: true,
300
305
  plate: true,
301
306
  textTransform: true,
307
+ letterSpacing: true,
308
+ wordGapEm: true,
309
+ lineGapEm: true,
302
310
  emphasisColor: true,
303
311
  emphasisScale: true,
304
312
  emphasisFontFamily: true,
@@ -314,7 +322,9 @@ var CaptionLayoutStyle = CaptionStyle.pick({
314
322
  emphasisPlateRadius: true,
315
323
  emphasisPlatePadX: true,
316
324
  emphasisPlatePadY: true,
325
+ emphasisPlateReveal: true,
317
326
  annotationColor: true,
327
+ annotationStrokeWidth: true,
318
328
  entrance: true,
319
329
  entranceMs: true,
320
330
  entranceStaggerMs: true,
@@ -5,7 +5,7 @@ import {
5
5
  isOk,
6
6
  opById,
7
7
  safeParse
8
- } from "./chunk-46DGDPXR.js";
8
+ } from "./chunk-V6GL37RZ.js";
9
9
 
10
10
  // ../mcp/src/wait.ts
11
11
  var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bodySchemaFor,
3
3
  opById
4
- } from "./chunk-46DGDPXR.js";
4
+ } from "./chunk-V6GL37RZ.js";
5
5
 
6
6
  // ../mcp/src/generated/sceneContract.ts
7
7
  function deepFreeze(value) {