@vosjs/studio-core 0.39.0 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,93 +1,10 @@
1
+ import { RichText, LayoutRun } from '@vosjs/elements/text';
2
+ export { CaretStop, DECORATION_THICKNESS_EM, DataRef, Fragment, HIGHLIGHT_HALF_EM, LayoutInput, LayoutLine, LayoutRun, LayoutUnit, Unit as LayoutUnitBox, MIXED, RUN_STYLE_KEYS, RichText, RunColor, RunStyle, RunStyleKey, STRIKE_OFFSET_EM, TextLayout, Measure as TextMeasure, TextRun, TextRunStyle, UNDERLINE_OFFSET_EM, caretAt, caretStops, clearStyle, commonStyle, decorationRect, diffInput, isDataRef, layoutText, lineOfOffset, normalizeRuns, offsetAtX, plainText, rangeRects, replaceRange, resolveRunColors, runsOf, setStyle, sliceRuns, snapOffset, styleAt, styleOf, toggleStyle, tokenRanges } from '@vosjs/elements/text';
1
3
  import { Segment, KeyframeTrack } from '@vosjs/timeline';
2
4
  export { Segment } from '@vosjs/timeline';
3
5
  import { TimelineEdit } from '@vosjs/shared/timelineEdits';
4
6
  import { LaneAdapter } from '@vosjs/editor';
5
7
 
6
- /** How a run departs from its layer's style. Absent = the layer's own. */
7
- interface TextRunStyle {
8
- /** Font weight, snapped to the family's hosted steps like the layer's. */
9
- weight?: number;
10
- /** Italic on, or (on an italic layer) off. */
11
- italic?: boolean;
12
- /** Fill colour. */
13
- color?: string;
14
- underline?: boolean;
15
- strike?: boolean;
16
- /** A colour behind the run. */
17
- highlight?: string;
18
- }
19
- interface TextRun extends TextRunStyle {
20
- /** The words. May hold line breaks. */
21
- text: string;
22
- }
23
- /** A text layer's words: plain, or styled. */
24
- type RichText = string | TextRun[];
25
- declare const RUN_STYLE_KEYS: readonly ["weight", "italic", "color", "underline", "strike", "highlight"];
26
- type RunStyleKey = (typeof RUN_STYLE_KEYS)[number];
27
- /** A style field's value over a selection that does not agree on it. */
28
- declare const MIXED = "mixed";
29
- /** The words alone: what a person reads, and what every label shows. */
30
- declare function plainText(text: RichText): string;
31
- /** The list form of either shape (a string is one unstyled run). */
32
- declare function runsOf(text: RichText): TextRun[];
33
- /** A run's style alone, without fields that say nothing. */
34
- declare function styleOf(run: TextRunStyle): TextRunStyle;
35
- /**
36
- * The canonical form: empty runs dropped, fields that say nothing dropped,
37
- * neighbours set alike merged, and a string when no style is left.
38
- */
39
- declare function normalizeRuns(text: RichText): RichText;
40
- /** The nearest grapheme boundary at or before (`-1`) or after (`1`) an offset. */
41
- declare function snapOffset(plain: string, offset: number, dir: -1 | 1): number;
42
- /** The runs between two offsets (unnormalized: for building, not storing). */
43
- declare function sliceRuns(text: RichText, start: number, end: number): TextRun[];
44
- /**
45
- * The style typing at a caret takes: the character before it, or the one
46
- * after it at the very start.
47
- */
48
- declare function styleAt(text: RichText, offset: number): TextRunStyle;
49
- /**
50
- * Replace `[start, end)` with `insert`: every keystroke, paste and
51
- * composition. The new text is set in `style` when one is given (the
52
- * pending style at a caret), else as the first character it replaces, else
53
- * as the character before it.
54
- */
55
- declare function replaceRange(text: RichText, start: number, end: number, insert: string, style?: TextRunStyle): RichText;
56
- /**
57
- * Set style fields over `[start, end)`. A field given as `undefined` is
58
- * REMOVED there (the words go back to the layer's own).
59
- */
60
- declare function setStyle(text: RichText, start: number, end: number, patch: {
61
- [K in RunStyleKey]?: TextRunStyle[K] | undefined;
62
- }): RichText;
63
- /** Every style off `[start, end)`. */
64
- declare function clearStyle(text: RichText, start: number, end: number): RichText;
65
- /**
66
- * What a selection agrees on, field by field: the value every character
67
- * has, `undefined` when none has one, MIXED when they differ. The format
68
- * bar's state.
69
- */
70
- declare function commonStyle(text: RichText, start: number, end: number): {
71
- [K in RunStyleKey]?: TextRunStyle[K] | typeof MIXED;
72
- };
73
- /**
74
- * The toggle a format key makes: when the whole selection already has the
75
- * field at `value`, take it off; otherwise put it on all of it.
76
- */
77
- declare function toggleStyle<K extends RunStyleKey>(text: RichText, start: number, end: number, key: K, value: NonNullable<TextRunStyle[K]>): RichText;
78
- /**
79
- * What a text field's change did, as one replacement of the old value:
80
- * the longest common tail (never past the caret, which sits at the end of
81
- * what was typed) and then the longest common head. Reads a keystroke, a
82
- * paste, an autocorrect, a dictation and a composition the same way, and
83
- * the caret settles a repeated character (`aa|` typed into `a|a`).
84
- */
85
- declare function diffInput(prev: string, next: string, caretAfter: number): {
86
- start: number;
87
- end: number;
88
- insert: string;
89
- };
90
-
91
8
  /**
92
9
  * Zoom/pan camera styles — named strategy
93
10
  * presets covering the whole auto-zoom pipeline: how the planner turns clicks
@@ -4759,110 +4676,6 @@ declare function cardPointToScreen(u: number, v: number): {
4759
4676
  sy: number;
4760
4677
  };
4761
4678
 
4762
- /**
4763
- * Styled-text layout, once.
4764
- *
4765
- * A text layer is lines of RUNS (a piece of text and how it is set). This
4766
- * module turns them into what a painter draws and what an editor points at:
4767
- * visual lines after the wrap, each a list of same-style FRAGMENTS at
4768
- * measured positions, plus the UNITS a per-unit entrance animates.
4769
- *
4770
- * It imports nothing and touches no DOM: measurement is handed in, so the
4771
- * page that paints, the host that picks and a plain node test all run the
4772
- * same function over the same rules.
4773
- *
4774
- * The rules are the text layer's own, unchanged:
4775
- * - a line breaks only between word tokens (`\S+\s*`, trailing whitespace
4776
- * kept with its word), greedily, at measured widths; a token wider than
4777
- * the budget takes a line of its own; explicit lines wrap independently;
4778
- * - a fragment is measured whole, so kerning holds inside a style and
4779
- * stops at a style boundary (as it does in CSS);
4780
- * - a unit places by the advance of what precedes it in its fragment, so
4781
- * the settled frame of an entrance is the frame without one.
4782
- */
4783
- /** How one piece of text is set. Absent fields are the layer's own. */
4784
- interface RunStyle {
4785
- /** Index into the layout's `fonts` (0, the layer's font, when absent). */
4786
- f?: number;
4787
- /** Fill colour. */
4788
- c?: string;
4789
- /** Underline. */
4790
- u?: 1;
4791
- /** Strikethrough. */
4792
- s?: 1;
4793
- /** A colour behind the text. */
4794
- h?: string;
4795
- }
4796
- interface LayoutRun extends RunStyle {
4797
- /** The text. Never holds a line break: lines are split before layout. */
4798
- t: string;
4799
- }
4800
- type LayoutUnit = 'char' | 'word' | 'line';
4801
- interface LayoutInput {
4802
- /** Source lines, each a list of runs. */
4803
- lines: LayoutRun[][];
4804
- /** Wrap budget in the measure's own px; absent or 0 = no wrap. */
4805
- maxWidth?: number;
4806
- /** Cut each visual line into units for a per-unit entrance. */
4807
- unit?: LayoutUnit;
4808
- }
4809
- /** `measure(text, fontIndex)`: the advance of `text` set in that font. */
4810
- type Measure = (text: string, font: number) => number;
4811
- /** A same-style stretch of one visual line. */
4812
- interface Fragment extends RunStyle {
4813
- t: string;
4814
- /** Left edge, from the line's left edge. */
4815
- x: number;
4816
- /** Advance. */
4817
- w: number;
4818
- /** Offset of its first character in the visual line. */
4819
- o: number;
4820
- }
4821
- /** One animated unit: the fragments (or parts of them) it draws. */
4822
- interface Unit {
4823
- x: number;
4824
- w: number;
4825
- parts: Fragment[];
4826
- }
4827
- interface LayoutLine {
4828
- /** Advance of the whole line (trailing whitespace included). */
4829
- w: number;
4830
- frags: Fragment[];
4831
- /** Present only when the input asked for a unit. */
4832
- units?: Unit[];
4833
- /** Offset of the line's first character in the whole plain text. */
4834
- a: number;
4835
- /** Characters on the line (its break, when it ends in one, not counted). */
4836
- n: number;
4837
- }
4838
- interface TextLayout {
4839
- lines: LayoutLine[];
4840
- /** The widest line. */
4841
- width: number;
4842
- }
4843
- /** `[start, end)` of each word token in a line: `\S+\s*`, or the line whole. */
4844
- declare function tokenRanges(line: string): [number, number][];
4845
- declare function layoutText(input: LayoutInput, measure: Measure): TextLayout;
4846
- /** Top of the underline, below the em box's middle. */
4847
- declare const UNDERLINE_OFFSET_EM = 0.42;
4848
- /** Thickness of the underline and the strikethrough. */
4849
- declare const DECORATION_THICKNESS_EM = 0.065;
4850
- /** Top of the strikethrough, relative to the em box's middle. */
4851
- declare const STRIKE_OFFSET_EM = 0.02;
4852
- /** The highlight's box, above and below the em box's middle. */
4853
- declare const HIGHLIGHT_HALF_EM = 0.58;
4854
- /**
4855
- * A decoration's rectangle for a stretch at `x`, `w` on a line whose em
4856
- * middle is `y`, at paint size `px`. Edges land on whole pixels, so the
4857
- * stretches of neighbouring units meet without a seam.
4858
- */
4859
- declare function decorationRect(kind: 'u' | 's' | 'h', x: number, w: number, y: number, px: number): {
4860
- x: number;
4861
- y: number;
4862
- w: number;
4863
- h: number;
4864
- };
4865
-
4866
4679
  /** Baked pill geometry: design px at the clip's resolved font size. */
4867
4680
  interface ResolvedOverlayBox {
4868
4681
  color: string;
@@ -5011,37 +4824,6 @@ mediaAspect?: number | null): OverlayRect;
5011
4824
  /** Point-in-overlay test (design px), rotation-aware (point → local space). */
5012
4825
  declare function overlayHit(rect: OverlayRect, px: number, py: number, padPx?: number): boolean;
5013
4826
 
5014
- interface CaretStop {
5015
- /** Offset in the whole plain text. */
5016
- o: number;
5017
- /** Distance from the line's left edge. */
5018
- x: number;
5019
- }
5020
- /** Every place a caret can stand on a line, left to right. */
5021
- declare function caretStops(line: LayoutLine, measure: Measure): CaretStop[];
5022
- /**
5023
- * The line an offset is on. An offset at a wrap point belongs to the line
5024
- * that STARTS there (the caret sits before the next word, not after the
5025
- * trailing space), except at the very end of the text.
5026
- */
5027
- declare function lineOfOffset(layout: TextLayout, offset: number): number;
5028
- declare function caretAt(layout: TextLayout, offset: number, measure: Measure): {
5029
- line: number;
5030
- x: number;
5031
- };
5032
- /** The offset nearest to `x` on a line (a press lands on the closer edge). */
5033
- declare function offsetAtX(line: LayoutLine, x: number, measure: Measure): number;
5034
- /**
5035
- * The stretches a selection `[start, end)` covers, one per line it touches.
5036
- * A line whose break the selection takes gets a small tail, so a selected
5037
- * line break is visible.
5038
- */
5039
- declare function rangeRects(layout: TextLayout, start: number, end: number, measure: Measure, breakTail?: number): {
5040
- line: number;
5041
- x: number;
5042
- w: number;
5043
- }[];
5044
-
5045
4827
  /** Does a legacy text mark any word? (The CLI's lint asks.) */
5046
4828
  declare function marksEmphasis(text: string): boolean;
5047
4829
  /** One layer: its `emphasis` read into runs. Others come back as they are. */
@@ -5457,4 +5239,4 @@ declare function rejectSpan(rejected: RejectedSpan[] | undefined, lane: Rejected
5457
5239
  anchor?: StepAnchor;
5458
5240
  }, note?: string): RejectedSpan;
5459
5241
 
5460
- export { ASPECT_RATIOS, AUDIO_PLAN_STEP, type AnchorKind, type Anim, type AnimKind, type AnimSide, type AnimStep, type AppliedTemplate, type ApplyTemplateOptions, type AspectRatioOption, type AudioClip, type AudioPlanPoint, type AudioPlanTrack, BACKGROUND_Z, BASE_FRAME_STYLE, type Backdrop, type BackgroundMedia, type BakedText3dAsset, type BakedText3dMaterial, type BrowserBarStyle, type BuildDigestInput, CALLOUT_DEFAULT_BODY_PX, CALLOUT_SHAPES, CALLOUT_TYPE_RATIO, CAMERA_CENTRE_RAMP, CAMERA_COVER_MIN, CAMERA_FAR, CAMERA_NEAR, CAM_CHAIN_GAP, CAM_EASE, CAM_PAN, CAM_PAN_EASE, CAM_RAMP_IN, CAM_RAMP_OUT, CAM_SIZE_MAX, CAM_SIZE_MIN, CAM_SPAN_MIN, CAPTURE_COVERAGE_MIN, CARD_EDGE_OVERDRAW, CARD_ENTER_KINDS, CARD_EXIT_KINDS, CARD_FADE_SECONDS, CARD_FOV, CARD_Z, CHANNEL_SPECS_HASH, CHANNEL_SPECS_VERIFIED, CLICK_FX_INTENSITY, CLICK_FX_PRE, CLICK_HIGHLIGHT_FADE, CLICK_HOLD_MS, CLICK_PAIR_MAX, CLICK_PULSE_DUR, CLICK_RECT_MAX_FRAC, CLICK_RIPPLE_DUR, CLICK_SYNTH_RELEASE, CLUSTER_FILL, CROP_MAX_PX, CROP_MIN_FRAC, CROP_MIN_PX, CROP_PAD, CURSOR_IDLE_EPS_FRAC, CURSOR_IDLE_FADE_IN, CURSOR_IDLE_FADE_OUT, CURSOR_IDLE_HOLD, type CalloutBox, type CalloutClipOptions, type CalloutLook, type CalloutRegister, type CalloutShape, type CalloutWords, type CamBubbleRect, type CamPoseSpan, type CamStyle, type CameraModel, type CaptureNormalization, type CardLayout, type CaretStop, type ClickFxStyle, type CopiedLayout, type CopyLayoutOptions, type CopyStyleOptions, type CursorEvent, type CursorFadeKey, type CursorIdleOptions, type CursorStyle, type CursorTrack, DARK_GROUND, DECORATION_THICKNESS_EM, DEFAULT_BROWSER_BAR, DEFAULT_CAM_POSE, DEFAULT_CAM_STYLE, DEFAULT_CLICK_FX, DEFAULT_CURSOR_STYLE, DEFAULT_DUCK, DEFAULT_FRAME_STYLE, DEFAULT_SPEED_PARAMS, DEFAULT_TILT_POSE, DEFAULT_ZOOM_LEVEL, DEFAULT_ZOOM_STYLE, DESIGN_FRAME_WIDTH, DESTINATIONS, DIGEST_CROP_MAX, DIGEST_FULL_MAX, DIGEST_VERSION, DOC_SCHEMA_VERSION, DRAG_FIT_LEVEL, DRAG_MIN_S, DRAG_MIN_TRAVEL_FRAC, type Destination, type Digest, type DigestImageRef, type DigestPlan, type DigestTakeFacts, type DocSegment, type Drag, type DuckOptions, END_CARD_FROM, END_CARD_RECEDE, END_CARD_SECONDS, ENTRANCE_SECONDS, EXPORT_RESOLUTION_OPTIONS, EXPORT_SHORT_EDGE, type EndCard, type EnvelopePoint, type ExportResolution, type ExtractClickOptions, FOLLOW_RECENTER, FOLLOW_SAFE_RATIO, FOOTAGE_FRAME_STYLE, FRAME_BORDER_COLOR_DEFAULT, FRAME_BORDER_DEFAULT, FRAME_BORDER_WIDTH_DEFAULT, FREEZE_DEFAULT_SECONDS, FREEZE_SECONDS_MAX, FREEZE_SECONDS_MIN, type FocusBounds, type FollowEvent, type FollowOptions, type Fragment, type FrameEntrance, type FrameGeometry, type FrameStyle, type FreezeExtent, type FreezeSpan, HIGHLIGHT_HALF_EM, HOLD_DRIFT_MAX, HOUSE_GRADIENT, HOUSE_REGISTER, HTML_LAYER_FOREIGN_FIELDS, HTML_LAYER_MAX_BYTES, HTML_LAYER_SVG_CODE, HTML_LAYER_WARN_BYTES, HTML_STARTERS, type HtmlLayerFace, type HtmlLayerInlineFace, type HtmlLayerPayload, type HtmlLayerProblem, type HtmlLayerProblemCode, type HtmlLayerSource, type HtmlOverlayClip, type HtmlOverlayFont, type HtmlStarter, IDLE_KINDS, type IdleKind, type IngestOptions, LAYER_CARD_SHADOW, LAYOUT_FRAME_FIELDS, LOOK_KINDS, type LayerCard, type LayoutInput, type LayoutLine, type LayoutParts, type LayoutRun, type LayoutUnit, type Unit as LayoutUnitBox, type Look, type LookBrand, type LookKind, type LookPlacement, type LowerProgramOptions, type LoweredAudioClip, type LoweredClick, type LoweredComposition, type LoweredZoomSpan, MEDIA_ENTER_KINDS, MEDIA_EXIT_KINDS, MEDIA_FRAME_KEYS, MEDIA_KEY_PREFIX, MINIMAL_BAR_THEMES, MIXED, MOTION_DELTA, MOTION_EASE, type Media, type MediaFrame, type MediaFrameKey, type MediaOverlayClip, type MediaSegment, type MicRms, type MinimalBarTheme, type Moment, type MomentKind, type MomentsOptions, type MotionKey, type MotionPose, type MotionPose3D, type MusicBedInput, type NormRect, OBJECT_DEFAULT_SCALE, OVERLAY_FONT_FACES, OVERLAY_LINE_HEIGHT, OVERLAY_MEDIA_DEFAULT_RADIUS, OVERLAY_MEDIA_DEFAULT_WIDTH, OVERLAY_MIN_DURATION, OVERLAY_SCALE_MAX, OVERLAY_SIZE_MAX, OVERLAY_SIZE_MIN, OVERLAY_TRANSITION_DUR, OVERLAY_Z, type ObjectAnimation, type ObjectAsset, type ObjectClip, type ObjectPrimitiveShape, type OverlayClip, type OverlayFontFace, type OverlayKind, type OverlayPin, type OverlayPresetStyle, type OverlayRect, type OverlayTransform, type OverlayTransition, PIN_GAP, PIN_MARGIN, PLATE_GROUND, PLAYBACK_ACTIVITY, PRIMARY_MEDIA, PROGRAM_RETIME, PUMP_REST, type PinCandidate, type PinCarry, type PinMark, type PinPlacement, type PinPlacementInput, type PinReferent, type PinSide, type PinSideResolved, type PlanOptions, type PlanTiltOptions, type PlaneSize, type ProgramAnchorDoc, type ProgramTweenEdit, type ProjectDoc, type PxRect, REJECT_OVERLAP, REST_TILT_ID, RETIRED_ZOOM_STYLES, RUN_STYLE_KEYS, type RecordingArtifact, type RecordingMeta, type Rect, type RejectedLane, type RejectedSpan, type ResolvedOverlayBox, type ResolvedOverlayStyle, type Rgb, type RichText, type RunStyle, type RunStyleKey, SCENE_MOTION, SCENE_QUIET, SEGMENT_ENTER_KINDS, SEGMENT_EXIT_KINDS, SPEED_RATE_MAX, SPEED_RATE_MIN, SPEED_SPAN_MIN, STAGE_CLIP_PREFIX, STILL_DEFAULT, STRIKE_OFFSET_EM, STUDIO_ENTRY_ID, STYLE_FIELDS, type SegmentExtent, type SmoothOptions, type SmoothPoint, type SpeedParams, type SpeedSpan, type StepAnchor, type StepSpan, type StudioAudioPlan, type StudioDoc, type StudioEntry, type StyleField, type StyledText, TEXT3D_DEPTH_DEFAULT, TEXT3D_DEPTH_MAX, TEXT3D_DEPTH_MIN, TEXT_ENTER_KINDS, TEXT_EXIT_KINDS, TEXT_PRESETS, TILT_AUTO_DEAD_ZONE, TILT_AUTO_MIN, TILT_CHAIN_GAP, TILT_DEG_MAX, TILT_EASE, TILT_INTENSITY_MAX, TILT_PAN, TILT_PAN_EASE, TILT_RAMP_IN, TILT_RAMP_OUT, TILT_SPAN_MIN, TILT_UI_DEG_MAX, TRANSITION_SECONDS, TRANSITION_SECONDS_MAX, TRANSITION_SECONDS_MIN, TRANSITION_SPEED_MULT, type TemplateAnchor, type Text3dMaterial, type TextFxDirection, type TextFxKind, type TextFxSpec, type TextFxUnit, type TextLayout, type Measure as TextMeasure, type TextOverlayBox, type TextOverlayClip, type TextOverlayPreset, type TextOverlayStroke, type TextRun, type TextRunStyle, type TiltPersonality, type TiltSpan, type TiltStyleName, type TraceFileKind, type TraceOptions, type TraceResult, type TranscriptSegment, type Transition, type TransitionKind, type TransitionMove, type TransitionOut, type TransitionSpeed, UNDERLINE_OFFSET_EM, WINDOW_FOCUS_MIN, ZOOM_CHAIN_GAP, ZOOM_EASE, ZOOM_LEVELS, ZOOM_LEVEL_MAX, ZOOM_LEVEL_MIN, ZOOM_PAN, ZOOM_PAN_EASE, ZOOM_RAMP_IN, ZOOM_RAMP_IN_OVERLAP, ZOOM_RAMP_OUT, ZOOM_SPAN_MIN, ZOOM_STYLES, ZOOM_STYLE_OPTIONS, type ZipEntry, type ZoomScreen, type ZoomSpan, type ZoomStyleName, type ZoomStyleParams, type ZoomView, type ZoomWindow, anchorKindOf, anchorSourceDuration, animStep, applyLook, applyTemplate, aspectRatioValue, audioLane, backdropMedia, boldWeightFor, buildDigest, calloutBox, calloutClip, calloutGroundOf, calloutLook, calloutSource, camBubbleRect, camBubbleRectAt, camLane, camMoveLane, camRectFromPose, camRestPose, camTrackFromDoc, cameraCentring, cameraModel, cardEnter, cardExit, cardFields, cardInset, cardPointToScreen, cardPoseTrack, caretAt, caretStops, clampCamFrac, clampCamSize, clampFocus, clampFreezeSeconds, clampSpeedRate, clampTiltDeg, clampZoomLevel, clearStyle, clipEnvelope, clipLength, clipsFrom, commonStyle, computeCardLayout, computeMicRms, computePeaks, copyLayout, copyStyle, cropBox, cssFamilies, cssWeights, cursorFromCsv, cursorFromPlaywrightTrace, cursorFromRecords, cursorFromTrace, cursorIdleFade, decorationRect, deltaE, deriveViewportCrop, destinationById, destinationsForChannel, diffInput, docCardLayout, docFreezes, docMediaList, docOutputDuration, docRestTime, docStillTime, docToCropSpace, docToFullSpace, docTransitions, docZoomTrack, dragsFromTrack, dropTemplate, duckCurve, effectiveSegments, endCardClips, enterKey, enterOf, entranceAt, entranceEnd, entranceSeconds, envelopeAt, envelopeValueAt, exitKey, exitOf, exitSeconds, expandEndCard, expectedFrameSize, exportSizeFor, extractClicks, findStep, focusBounds, focusForViewportCentre, followFocusEvents, frameGeometry, freezeLane, freezeOutputExtents, hexToRgb, hexToRgbTriplet, houseLook, htmlLayerBleed, htmlLayerBleedFor, htmlLayerFaces, htmlLayerKey, htmlLayerLabel, htmlLayerPayload, htmlLayerPictureBox, htmlLayerProblems, htmlLayerSvg, htmlLayerText, htmlLayerUnhostedFamilies, htmlLayerWidth, htmlStarterClip, idleGaps, idleKey, isKeyedOverlay, isLookKind, isMusicBed, isPlayback, isProgramDoc, isRecordingDoc, isRejected, isStageClip, isUnitStep, lastLayerEnd, layerMedia, layoutOf, layoutText, levelForFocusFraction, lineOfOffset, liveZoomStyleName, lookFromBrand, lookKindForGround, lowerProgramDoc, lowerStudioDoc, lowerToComposition, marksEmphasis, mediaAtOutput, mediaDuration, mediaFrame, mediaKey, mediaRef, mediaRefId, mediaSource, micLane, migrateHostedDoc, migrateMotion, migrateText, migrateTextClip, migrateZoomStyle, momentsFromDoc, motionTrack, musicBedClip, nextMediaId, normalizeCaptureSpace, normalizeRuns, objectMotionBase, objectMotionPoseAt, objectsLane, offsetAtX, outputDurationOf, outputEnd, outputRangeToSource, overlapFraction, overlayFaceFor, overlayFontFaces, overlayFontString, overlayFxSpec, overlayHit, overlayLines, overlayMotionBase, overlayMotionPoseAt, overlayPinPoseAt, overlayPlainText, overlayRect, overlaysLane, ownFreezes, pageDisplayUrl, parseCssColour, parsePoseId, pickStyle, pinBox, pinCandidates, pinPlacement, pinRectOnScreen, pinReferent, pinReferentAt, placeFreezes, plainText, planAutoSpeed, planAutoTilt, planAutoZoom, planForDigest, planeSizeAtDepth, platformBarKind, playwrightTraceEntry, programDuration, programStillTime, projectFromArtifact, pumpFreeChainGap, rangeRects, ratedSegments, recommendedExportResolution, refillAudioBeds, rejectSpan, relativeLuminance, removeSourceRange, removeSpeedInRange, replaceRange, resolveExportSize, resolveOverlayBox, resolveOverlayStyle, resolvePins, resolveText3dAsset, resolveZoomStyle, restLeanOf, restSpansThroughTransitions, rgbToHex, runsOf, sameMedia, sceneChanges, scrollRuns, segmentOutputExtents, outputLen as segmentOutputLen, segmentStarts, setSpeedInRange, setStyle, sliceRuns, slideSide, smoothCursor, snapOffset, snapRunWeight, spanOutputExtent, speedLane, studioAudioPlan, studioEntry, studioLayerData, styleAt, styleOf, styledTextOf, textRunsOf, tiltLane, tiltTrackFromDoc, toggleStyle, tokenRanges, traceKindOf, transitionMult, transitionSeconds, unionFitLevel, unionRect, videoLane, voiceKey, wellFormedXml, withBackdrop, withFreezes, withHolds, withoutRejected, wrapProgramLength, zipEntries, zipEntryBytes, zoomCoversRect, zoomLane, zoomSpanForRange, zoomTrackFromDoc, zoomView, zoomViewport, zoomWindow };
5242
+ export { ASPECT_RATIOS, AUDIO_PLAN_STEP, type AnchorKind, type Anim, type AnimKind, type AnimSide, type AnimStep, type AppliedTemplate, type ApplyTemplateOptions, type AspectRatioOption, type AudioClip, type AudioPlanPoint, type AudioPlanTrack, BACKGROUND_Z, BASE_FRAME_STYLE, type Backdrop, type BackgroundMedia, type BakedText3dAsset, type BakedText3dMaterial, type BrowserBarStyle, type BuildDigestInput, CALLOUT_DEFAULT_BODY_PX, CALLOUT_SHAPES, CALLOUT_TYPE_RATIO, CAMERA_CENTRE_RAMP, CAMERA_COVER_MIN, CAMERA_FAR, CAMERA_NEAR, CAM_CHAIN_GAP, CAM_EASE, CAM_PAN, CAM_PAN_EASE, CAM_RAMP_IN, CAM_RAMP_OUT, CAM_SIZE_MAX, CAM_SIZE_MIN, CAM_SPAN_MIN, CAPTURE_COVERAGE_MIN, CARD_EDGE_OVERDRAW, CARD_ENTER_KINDS, CARD_EXIT_KINDS, CARD_FADE_SECONDS, CARD_FOV, CARD_Z, CHANNEL_SPECS_HASH, CHANNEL_SPECS_VERIFIED, CLICK_FX_INTENSITY, CLICK_FX_PRE, CLICK_HIGHLIGHT_FADE, CLICK_HOLD_MS, CLICK_PAIR_MAX, CLICK_PULSE_DUR, CLICK_RECT_MAX_FRAC, CLICK_RIPPLE_DUR, CLICK_SYNTH_RELEASE, CLUSTER_FILL, CROP_MAX_PX, CROP_MIN_FRAC, CROP_MIN_PX, CROP_PAD, CURSOR_IDLE_EPS_FRAC, CURSOR_IDLE_FADE_IN, CURSOR_IDLE_FADE_OUT, CURSOR_IDLE_HOLD, type CalloutBox, type CalloutClipOptions, type CalloutLook, type CalloutRegister, type CalloutShape, type CalloutWords, type CamBubbleRect, type CamPoseSpan, type CamStyle, type CameraModel, type CaptureNormalization, type CardLayout, type ClickFxStyle, type CopiedLayout, type CopyLayoutOptions, type CopyStyleOptions, type CursorEvent, type CursorFadeKey, type CursorIdleOptions, type CursorStyle, type CursorTrack, DARK_GROUND, DEFAULT_BROWSER_BAR, DEFAULT_CAM_POSE, DEFAULT_CAM_STYLE, DEFAULT_CLICK_FX, DEFAULT_CURSOR_STYLE, DEFAULT_DUCK, DEFAULT_FRAME_STYLE, DEFAULT_SPEED_PARAMS, DEFAULT_TILT_POSE, DEFAULT_ZOOM_LEVEL, DEFAULT_ZOOM_STYLE, DESIGN_FRAME_WIDTH, DESTINATIONS, DIGEST_CROP_MAX, DIGEST_FULL_MAX, DIGEST_VERSION, DOC_SCHEMA_VERSION, DRAG_FIT_LEVEL, DRAG_MIN_S, DRAG_MIN_TRAVEL_FRAC, type Destination, type Digest, type DigestImageRef, type DigestPlan, type DigestTakeFacts, type DocSegment, type Drag, type DuckOptions, END_CARD_FROM, END_CARD_RECEDE, END_CARD_SECONDS, ENTRANCE_SECONDS, EXPORT_RESOLUTION_OPTIONS, EXPORT_SHORT_EDGE, type EndCard, type EnvelopePoint, type ExportResolution, type ExtractClickOptions, FOLLOW_RECENTER, FOLLOW_SAFE_RATIO, FOOTAGE_FRAME_STYLE, FRAME_BORDER_COLOR_DEFAULT, FRAME_BORDER_DEFAULT, FRAME_BORDER_WIDTH_DEFAULT, FREEZE_DEFAULT_SECONDS, FREEZE_SECONDS_MAX, FREEZE_SECONDS_MIN, type FocusBounds, type FollowEvent, type FollowOptions, type FrameEntrance, type FrameGeometry, type FrameStyle, type FreezeExtent, type FreezeSpan, HOLD_DRIFT_MAX, HOUSE_GRADIENT, HOUSE_REGISTER, HTML_LAYER_FOREIGN_FIELDS, HTML_LAYER_MAX_BYTES, HTML_LAYER_SVG_CODE, HTML_LAYER_WARN_BYTES, HTML_STARTERS, type HtmlLayerFace, type HtmlLayerInlineFace, type HtmlLayerPayload, type HtmlLayerProblem, type HtmlLayerProblemCode, type HtmlLayerSource, type HtmlOverlayClip, type HtmlOverlayFont, type HtmlStarter, IDLE_KINDS, type IdleKind, type IngestOptions, LAYER_CARD_SHADOW, LAYOUT_FRAME_FIELDS, LOOK_KINDS, type LayerCard, type LayoutParts, type Look, type LookBrand, type LookKind, type LookPlacement, type LowerProgramOptions, type LoweredAudioClip, type LoweredClick, type LoweredComposition, type LoweredZoomSpan, MEDIA_ENTER_KINDS, MEDIA_EXIT_KINDS, MEDIA_FRAME_KEYS, MEDIA_KEY_PREFIX, MINIMAL_BAR_THEMES, MOTION_DELTA, MOTION_EASE, type Media, type MediaFrame, type MediaFrameKey, type MediaOverlayClip, type MediaSegment, type MicRms, type MinimalBarTheme, type Moment, type MomentKind, type MomentsOptions, type MotionKey, type MotionPose, type MotionPose3D, type MusicBedInput, type NormRect, OBJECT_DEFAULT_SCALE, OVERLAY_FONT_FACES, OVERLAY_LINE_HEIGHT, OVERLAY_MEDIA_DEFAULT_RADIUS, OVERLAY_MEDIA_DEFAULT_WIDTH, OVERLAY_MIN_DURATION, OVERLAY_SCALE_MAX, OVERLAY_SIZE_MAX, OVERLAY_SIZE_MIN, OVERLAY_TRANSITION_DUR, OVERLAY_Z, type ObjectAnimation, type ObjectAsset, type ObjectClip, type ObjectPrimitiveShape, type OverlayClip, type OverlayFontFace, type OverlayKind, type OverlayPin, type OverlayPresetStyle, type OverlayRect, type OverlayTransform, type OverlayTransition, PIN_GAP, PIN_MARGIN, PLATE_GROUND, PLAYBACK_ACTIVITY, PRIMARY_MEDIA, PROGRAM_RETIME, PUMP_REST, type PinCandidate, type PinCarry, type PinMark, type PinPlacement, type PinPlacementInput, type PinReferent, type PinSide, type PinSideResolved, type PlanOptions, type PlanTiltOptions, type PlaneSize, type ProgramAnchorDoc, type ProgramTweenEdit, type ProjectDoc, type PxRect, REJECT_OVERLAP, REST_TILT_ID, RETIRED_ZOOM_STYLES, type RecordingArtifact, type RecordingMeta, type Rect, type RejectedLane, type RejectedSpan, type ResolvedOverlayBox, type ResolvedOverlayStyle, type Rgb, SCENE_MOTION, SCENE_QUIET, SEGMENT_ENTER_KINDS, SEGMENT_EXIT_KINDS, SPEED_RATE_MAX, SPEED_RATE_MIN, SPEED_SPAN_MIN, STAGE_CLIP_PREFIX, STILL_DEFAULT, STUDIO_ENTRY_ID, STYLE_FIELDS, type SegmentExtent, type SmoothOptions, type SmoothPoint, type SpeedParams, type SpeedSpan, type StepAnchor, type StepSpan, type StudioAudioPlan, type StudioDoc, type StudioEntry, type StyleField, type StyledText, TEXT3D_DEPTH_DEFAULT, TEXT3D_DEPTH_MAX, TEXT3D_DEPTH_MIN, TEXT_ENTER_KINDS, TEXT_EXIT_KINDS, TEXT_PRESETS, TILT_AUTO_DEAD_ZONE, TILT_AUTO_MIN, TILT_CHAIN_GAP, TILT_DEG_MAX, TILT_EASE, TILT_INTENSITY_MAX, TILT_PAN, TILT_PAN_EASE, TILT_RAMP_IN, TILT_RAMP_OUT, TILT_SPAN_MIN, TILT_UI_DEG_MAX, TRANSITION_SECONDS, TRANSITION_SECONDS_MAX, TRANSITION_SECONDS_MIN, TRANSITION_SPEED_MULT, type TemplateAnchor, type Text3dMaterial, type TextFxDirection, type TextFxKind, type TextFxSpec, type TextFxUnit, type TextOverlayBox, type TextOverlayClip, type TextOverlayPreset, type TextOverlayStroke, type TiltPersonality, type TiltSpan, type TiltStyleName, type TraceFileKind, type TraceOptions, type TraceResult, type TranscriptSegment, type Transition, type TransitionKind, type TransitionMove, type TransitionOut, type TransitionSpeed, WINDOW_FOCUS_MIN, ZOOM_CHAIN_GAP, ZOOM_EASE, ZOOM_LEVELS, ZOOM_LEVEL_MAX, ZOOM_LEVEL_MIN, ZOOM_PAN, ZOOM_PAN_EASE, ZOOM_RAMP_IN, ZOOM_RAMP_IN_OVERLAP, ZOOM_RAMP_OUT, ZOOM_SPAN_MIN, ZOOM_STYLES, ZOOM_STYLE_OPTIONS, type ZipEntry, type ZoomScreen, type ZoomSpan, type ZoomStyleName, type ZoomStyleParams, type ZoomView, type ZoomWindow, anchorKindOf, anchorSourceDuration, animStep, applyLook, applyTemplate, aspectRatioValue, audioLane, backdropMedia, boldWeightFor, buildDigest, calloutBox, calloutClip, calloutGroundOf, calloutLook, calloutSource, camBubbleRect, camBubbleRectAt, camLane, camMoveLane, camRectFromPose, camRestPose, camTrackFromDoc, cameraCentring, cameraModel, cardEnter, cardExit, cardFields, cardInset, cardPointToScreen, cardPoseTrack, clampCamFrac, clampCamSize, clampFocus, clampFreezeSeconds, clampSpeedRate, clampTiltDeg, clampZoomLevel, clipEnvelope, clipLength, clipsFrom, computeCardLayout, computeMicRms, computePeaks, copyLayout, copyStyle, cropBox, cssFamilies, cssWeights, cursorFromCsv, cursorFromPlaywrightTrace, cursorFromRecords, cursorFromTrace, cursorIdleFade, deltaE, deriveViewportCrop, destinationById, destinationsForChannel, docCardLayout, docFreezes, docMediaList, docOutputDuration, docRestTime, docStillTime, docToCropSpace, docToFullSpace, docTransitions, docZoomTrack, dragsFromTrack, dropTemplate, duckCurve, effectiveSegments, endCardClips, enterKey, enterOf, entranceAt, entranceEnd, entranceSeconds, envelopeAt, envelopeValueAt, exitKey, exitOf, exitSeconds, expandEndCard, expectedFrameSize, exportSizeFor, extractClicks, findStep, focusBounds, focusForViewportCentre, followFocusEvents, frameGeometry, freezeLane, freezeOutputExtents, hexToRgb, hexToRgbTriplet, houseLook, htmlLayerBleed, htmlLayerBleedFor, htmlLayerFaces, htmlLayerKey, htmlLayerLabel, htmlLayerPayload, htmlLayerPictureBox, htmlLayerProblems, htmlLayerSvg, htmlLayerText, htmlLayerUnhostedFamilies, htmlLayerWidth, htmlStarterClip, idleGaps, idleKey, isKeyedOverlay, isLookKind, isMusicBed, isPlayback, isProgramDoc, isRecordingDoc, isRejected, isStageClip, isUnitStep, lastLayerEnd, layerMedia, layoutOf, levelForFocusFraction, liveZoomStyleName, lookFromBrand, lookKindForGround, lowerProgramDoc, lowerStudioDoc, lowerToComposition, marksEmphasis, mediaAtOutput, mediaDuration, mediaFrame, mediaKey, mediaRef, mediaRefId, mediaSource, micLane, migrateHostedDoc, migrateMotion, migrateText, migrateTextClip, migrateZoomStyle, momentsFromDoc, motionTrack, musicBedClip, nextMediaId, normalizeCaptureSpace, objectMotionBase, objectMotionPoseAt, objectsLane, outputDurationOf, outputEnd, outputRangeToSource, overlapFraction, overlayFaceFor, overlayFontFaces, overlayFontString, overlayFxSpec, overlayHit, overlayLines, overlayMotionBase, overlayMotionPoseAt, overlayPinPoseAt, overlayPlainText, overlayRect, overlaysLane, ownFreezes, pageDisplayUrl, parseCssColour, parsePoseId, pickStyle, pinBox, pinCandidates, pinPlacement, pinRectOnScreen, pinReferent, pinReferentAt, placeFreezes, planAutoSpeed, planAutoTilt, planAutoZoom, planForDigest, planeSizeAtDepth, platformBarKind, playwrightTraceEntry, programDuration, programStillTime, projectFromArtifact, pumpFreeChainGap, ratedSegments, recommendedExportResolution, refillAudioBeds, rejectSpan, relativeLuminance, removeSourceRange, removeSpeedInRange, resolveExportSize, resolveOverlayBox, resolveOverlayStyle, resolvePins, resolveText3dAsset, resolveZoomStyle, restLeanOf, restSpansThroughTransitions, rgbToHex, sameMedia, sceneChanges, scrollRuns, segmentOutputExtents, outputLen as segmentOutputLen, segmentStarts, setSpeedInRange, slideSide, smoothCursor, snapRunWeight, spanOutputExtent, speedLane, studioAudioPlan, studioEntry, studioLayerData, styledTextOf, textRunsOf, tiltLane, tiltTrackFromDoc, traceKindOf, transitionMult, transitionSeconds, unionFitLevel, unionRect, videoLane, voiceKey, wellFormedXml, withBackdrop, withFreezes, withHolds, withoutRejected, wrapProgramLength, zipEntries, zipEntryBytes, zoomCoversRect, zoomLane, zoomSpanForRange, zoomTrackFromDoc, zoomView, zoomViewport, zoomWindow };
package/dist/index.js CHANGED
@@ -2213,7 +2213,7 @@ function htmlLayerPayload(clip) {
2213
2213
  };
2214
2214
  }
2215
2215
 
2216
- // src/richText/layout.ts
2216
+ // ../elements/dist/chunk-ZHIPLA3M.js
2217
2217
  var sameStyle = (a, b) => (a.f || 0) === (b.f || 0) && a.c === b.c && a.u === b.u && a.s === b.s && a.h === b.h;
2218
2218
  function graphemesOf(text) {
2219
2219
  if (typeof Intl !== "undefined" && typeof Intl.Segmenter === "function") {
@@ -2375,8 +2375,9 @@ function decorationRect(kind, x, w, y, px) {
2375
2375
  );
2376
2376
  return { x: x0, y: top, w: x1 - x0, h: t };
2377
2377
  }
2378
-
2379
- // src/richText/runs.ts
2378
+ function isDataRef(value) {
2379
+ return typeof value === "object" && value !== null && typeof value.$data === "string" && value.$data.length > 0;
2380
+ }
2380
2381
  var RUN_STYLE_KEYS = [
2381
2382
  "weight",
2382
2383
  "italic",
@@ -2395,17 +2396,24 @@ function plainText(text) {
2395
2396
  function runsOf(text) {
2396
2397
  return typeof text === "string" ? text ? [{ text }] : [] : text;
2397
2398
  }
2399
+ function colorOf(value) {
2400
+ if (typeof value === "string") return value || void 0;
2401
+ return isDataRef(value) ? { $data: value.$data } : void 0;
2402
+ }
2403
+ var sameValue = (a, b) => a === b || isDataRef(a) && isDataRef(b) && a.$data === b.$data;
2398
2404
  function styleOf(run) {
2399
2405
  const out = {};
2400
2406
  if (typeof run.weight === "number") out.weight = run.weight;
2401
2407
  if (typeof run.italic === "boolean") out.italic = run.italic;
2402
- if (run.color) out.color = run.color;
2408
+ const color = colorOf(run.color);
2409
+ if (color) out.color = color;
2403
2410
  if (run.underline) out.underline = true;
2404
2411
  if (run.strike) out.strike = true;
2405
- if (run.highlight) out.highlight = run.highlight;
2412
+ const highlight = colorOf(run.highlight);
2413
+ if (highlight) out.highlight = highlight;
2406
2414
  return out;
2407
2415
  }
2408
- var sameStyle2 = (a, b) => RUN_STYLE_KEYS.every((k) => a[k] === b[k]);
2416
+ var sameStyle2 = (a, b) => RUN_STYLE_KEYS.every((k) => sameValue(a[k], b[k]));
2409
2417
  var isStyled = (s) => RUN_STYLE_KEYS.some((k) => s[k] !== void 0);
2410
2418
  function normalizeRuns(text) {
2411
2419
  if (typeof text === "string") return text;
@@ -2421,6 +2429,44 @@ function normalizeRuns(text) {
2421
2429
  if (out.length === 1 && !isStyled(out[0])) return out[0].text;
2422
2430
  return out;
2423
2431
  }
2432
+ function resolveRunColors(text, data) {
2433
+ if (typeof text === "string") return text;
2434
+ const read = (value) => {
2435
+ if (!isDataRef(value)) return value;
2436
+ const v = data?.[value.$data];
2437
+ return typeof v === "string" && v ? v : void 0;
2438
+ };
2439
+ return normalizeRuns(
2440
+ text.map((run) => {
2441
+ const { color, highlight, ...rest } = run;
2442
+ const c = read(color);
2443
+ const h = read(highlight);
2444
+ return {
2445
+ ...rest,
2446
+ ...c ? { color: c } : {},
2447
+ ...h ? { highlight: h } : {}
2448
+ };
2449
+ })
2450
+ );
2451
+ }
2452
+ function layoutLines(text, fontOf) {
2453
+ const lines = [[]];
2454
+ for (const run of runsOf(text)) {
2455
+ const f = fontOf(run);
2456
+ const set = {
2457
+ ...f ? { f } : {},
2458
+ ...typeof run.color === "string" && run.color ? { c: run.color } : {},
2459
+ ...run.underline ? { u: 1 } : {},
2460
+ ...run.strike ? { s: 1 } : {},
2461
+ ...typeof run.highlight === "string" && run.highlight ? { h: run.highlight } : {}
2462
+ };
2463
+ run.text.split("\n").forEach((part, i) => {
2464
+ if (i > 0) lines.push([]);
2465
+ if (part) lines[lines.length - 1].push({ t: part, ...set });
2466
+ });
2467
+ }
2468
+ return lines;
2469
+ }
2424
2470
  function snapOffset(plain, offset, dir) {
2425
2471
  const o = Math.max(0, Math.min(plain.length, offset));
2426
2472
  let at = 0;
@@ -2504,7 +2550,7 @@ function commonStyle(text, start, end) {
2504
2550
  if (!runs.length) return styleAt(text, start);
2505
2551
  for (const k of RUN_STYLE_KEYS) {
2506
2552
  const first = styleOf(runs[0])[k];
2507
- const agree = runs.every((run) => styleOf(run)[k] === first);
2553
+ const agree = runs.every((run) => sameValue(styleOf(run)[k], first));
2508
2554
  if (!agree) out[k] = MIXED;
2509
2555
  else if (first !== void 0) out[k] = first;
2510
2556
  }
@@ -2530,6 +2576,68 @@ function diffInput(prev, next, caretAfter) {
2530
2576
  };
2531
2577
  }
2532
2578
 
2579
+ // ../elements/dist/text/index.js
2580
+ function caretStops(line, measure) {
2581
+ const stops = [{ o: line.a, x: 0 }];
2582
+ for (const fr of line.frags) {
2583
+ let at = 0;
2584
+ for (const g of graphemesOf(fr.t)) {
2585
+ at += g.length;
2586
+ stops.push({
2587
+ o: line.a + fr.o + at,
2588
+ x: fr.x + measure(fr.t.slice(0, at), fr.f || 0)
2589
+ });
2590
+ }
2591
+ }
2592
+ return stops;
2593
+ }
2594
+ function lineOfOffset(layout, offset) {
2595
+ const lines = layout.lines;
2596
+ for (let i = lines.length - 1; i >= 0; i--) {
2597
+ if (offset >= lines[i].a) return i;
2598
+ }
2599
+ return 0;
2600
+ }
2601
+ function caretAt(layout, offset, measure) {
2602
+ const li = lineOfOffset(layout, offset);
2603
+ const stops = caretStops(layout.lines[li], measure);
2604
+ let x = stops[stops.length - 1].x;
2605
+ for (const s of stops) {
2606
+ if (s.o >= offset) {
2607
+ x = s.x;
2608
+ break;
2609
+ }
2610
+ }
2611
+ return { line: li, x };
2612
+ }
2613
+ function offsetAtX(line, x, measure) {
2614
+ const stops = caretStops(line, measure);
2615
+ let best = stops[0];
2616
+ for (const s of stops) {
2617
+ if (Math.abs(s.x - x) < Math.abs(best.x - x)) best = s;
2618
+ }
2619
+ return best.o;
2620
+ }
2621
+ function rangeRects(layout, start, end, measure, breakTail = 0) {
2622
+ const out = [];
2623
+ if (end <= start) return out;
2624
+ layout.lines.forEach((line, i) => {
2625
+ const lineEnd = line.a + line.n;
2626
+ if (end <= line.a || start > lineEnd) return;
2627
+ const stops = caretStops(line, measure);
2628
+ const xOf = (o) => {
2629
+ for (const s of stops) if (s.o >= o) return s.x;
2630
+ return stops[stops.length - 1].x;
2631
+ };
2632
+ const x0 = xOf(Math.max(start, line.a));
2633
+ const x1 = xOf(Math.min(end, lineEnd));
2634
+ const next = layout.lines[i + 1];
2635
+ const tail = next && next.a > lineEnd && end > lineEnd ? breakTail : 0;
2636
+ if (x1 + tail > x0) out.push({ line: i, x: x0, w: x1 - x0 + tail });
2637
+ });
2638
+ return out;
2639
+ }
2640
+
2533
2641
  // src/overlayText.ts
2534
2642
  var OVERLAY_BOX_PAD_X = 0.6;
2535
2643
  var OVERLAY_BOX_PAD_Y = 0.35;
@@ -2699,24 +2807,13 @@ function styledTextOf(clip) {
2699
2807
  }
2700
2808
  return at;
2701
2809
  };
2702
- const l = [[]];
2703
- for (const run of runs) {
2704
- const f = fontOf(
2810
+ const l = layoutLines(
2811
+ runs,
2812
+ (run) => fontOf(
2705
2813
  run.weight !== void 0 ? snapRunWeight(clip, run.weight) : style.weight,
2706
2814
  run.italic ?? italic
2707
- );
2708
- const set = {
2709
- ...f ? { f } : {},
2710
- ...run.color ? { c: run.color } : {},
2711
- ...run.underline ? { u: 1 } : {},
2712
- ...run.strike ? { s: 1 } : {},
2713
- ...run.highlight ? { h: run.highlight } : {}
2714
- };
2715
- run.text.split("\n").forEach((part, i) => {
2716
- if (i > 0) l.push([]);
2717
- if (part) l[l.length - 1].push({ t: part, ...set });
2718
- });
2719
- }
2815
+ )
2816
+ );
2720
2817
  const entry = familyEntryOf(clip);
2721
2818
  const faces = [];
2722
2819
  for (const font of fs.slice(1)) {
@@ -5068,7 +5165,7 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
5068
5165
  var s = H / 1080 // scale design-px controls to comp px
5069
5166
  var ns = window.__vos__ || {}
5070
5167
  var playing = ns.isPaused === false
5071
- // The styled-text layout (richText/layout.ts, generated), installed once:
5168
+ // The styled-text layout (the engine's text/layout.ts, generated), installed once:
5072
5169
  // the page lays a text layer out with the code the host picks with.
5073
5170
  if (!ns.textLayout) { ${textLayoutCode}; ns.textLayout = __vosTextLayout }
5074
5171
  var TXL = ns.textLayout
@@ -10797,68 +10894,6 @@ function applyLook(frame, look, size, video, placement) {
10797
10894
  return out;
10798
10895
  }
10799
10896
 
10800
- // src/richText/caret.ts
10801
- function caretStops(line, measure) {
10802
- const stops = [{ o: line.a, x: 0 }];
10803
- for (const fr of line.frags) {
10804
- let at = 0;
10805
- for (const g of graphemesOf(fr.t)) {
10806
- at += g.length;
10807
- stops.push({
10808
- o: line.a + fr.o + at,
10809
- x: fr.x + measure(fr.t.slice(0, at), fr.f || 0)
10810
- });
10811
- }
10812
- }
10813
- return stops;
10814
- }
10815
- function lineOfOffset(layout, offset) {
10816
- const lines = layout.lines;
10817
- for (let i = lines.length - 1; i >= 0; i--) {
10818
- if (offset >= lines[i].a) return i;
10819
- }
10820
- return 0;
10821
- }
10822
- function caretAt(layout, offset, measure) {
10823
- const li = lineOfOffset(layout, offset);
10824
- const stops = caretStops(layout.lines[li], measure);
10825
- let x = stops[stops.length - 1].x;
10826
- for (const s of stops) {
10827
- if (s.o >= offset) {
10828
- x = s.x;
10829
- break;
10830
- }
10831
- }
10832
- return { line: li, x };
10833
- }
10834
- function offsetAtX(line, x, measure) {
10835
- const stops = caretStops(line, measure);
10836
- let best = stops[0];
10837
- for (const s of stops) {
10838
- if (Math.abs(s.x - x) < Math.abs(best.x - x)) best = s;
10839
- }
10840
- return best.o;
10841
- }
10842
- function rangeRects(layout, start, end, measure, breakTail = 0) {
10843
- const out = [];
10844
- if (end <= start) return out;
10845
- layout.lines.forEach((line, i) => {
10846
- const lineEnd = line.a + line.n;
10847
- if (end <= line.a || start > lineEnd) return;
10848
- const stops = caretStops(line, measure);
10849
- const xOf = (o) => {
10850
- for (const s of stops) if (s.o >= o) return s.x;
10851
- return stops[stops.length - 1].x;
10852
- };
10853
- const x0 = xOf(Math.max(start, line.a));
10854
- const x1 = xOf(Math.min(end, lineEnd));
10855
- const next = layout.lines[i + 1];
10856
- const tail = next && next.a > lineEnd && end > lineEnd ? breakTail : 0;
10857
- if (x1 + tail > x0) out.push({ line: i, x: x0, w: x1 - x0 + tail });
10858
- });
10859
- return out;
10860
- }
10861
-
10862
10897
  // src/timeline/lanes.ts
10863
10898
  import {
10864
10899
  mapTime as mapTime3,
@@ -12484,6 +12519,7 @@ export {
12484
12519
  htmlStarterClip,
12485
12520
  idleGaps,
12486
12521
  idleKey,
12522
+ isDataRef,
12487
12523
  isKeyedOverlay,
12488
12524
  isLookKind,
12489
12525
  isMusicBed,
@@ -12582,6 +12618,7 @@ export {
12582
12618
  resolveOverlayBox,
12583
12619
  resolveOverlayStyle,
12584
12620
  resolvePins,
12621
+ resolveRunColors,
12585
12622
  resolveText3dAsset,
12586
12623
  resolveZoomStyle,
12587
12624
  restLeanOf,