@vosjs/studio-core 0.24.1 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +145 -16
- package/dist/index.js +269 -20
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1894,6 +1894,126 @@ type Media = ProjectDoc['source'] & {
|
|
|
1894
1894
|
frame?: MediaFrame;
|
|
1895
1895
|
};
|
|
1896
1896
|
|
|
1897
|
+
/**
|
|
1898
|
+
* The callout grammar — three shapes a viewer learns once, composed from the
|
|
1899
|
+
* product's own register so the card is unmistakably the video's and still
|
|
1900
|
+
* the product's.
|
|
1901
|
+
*
|
|
1902
|
+
* The rule set (the distinguishability principle: share the product's hue
|
|
1903
|
+
* and type, contrast in value, elevation, scale and place):
|
|
1904
|
+
* - VALUE INVERSION: a light app gets a dark card in the product's hue, a
|
|
1905
|
+
* dark app a light one; the accent is kept for the kicker and the dot.
|
|
1906
|
+
* - ELEVATION: a real shadow plus a hairline of light on the edge.
|
|
1907
|
+
* - SCALE: the title is set for the render, CALLOUT_TYPE_RATIO times the
|
|
1908
|
+
* app's body as it appears on screen at the layer's start (the camera
|
|
1909
|
+
* scales the app, so the caller passes that scale), never the app's own
|
|
1910
|
+
* size.
|
|
1911
|
+
* - MOTION: a rise in, a fade out.
|
|
1912
|
+
* - PLACE is the pin's (lower/pin.ts), not the card's.
|
|
1913
|
+
*
|
|
1914
|
+
* Pure: hex in, markup and CSS out. The starters are this grammar in the
|
|
1915
|
+
* house register; `vos callout` is it in the take's BRAND.md.
|
|
1916
|
+
*/
|
|
1917
|
+
|
|
1918
|
+
type CalloutShape = 'tag' | 'note' | 'code';
|
|
1919
|
+
declare const CALLOUT_SHAPES: readonly CalloutShape[];
|
|
1920
|
+
/** The title's size over the app's body size as seen on screen. */
|
|
1921
|
+
declare const CALLOUT_TYPE_RATIO = 1.35;
|
|
1922
|
+
/** The app's body size when nothing says otherwise (CSS px at the viewport). */
|
|
1923
|
+
declare const CALLOUT_DEFAULT_BODY_PX = 14;
|
|
1924
|
+
/** The product's register: what a card shares with the app. */
|
|
1925
|
+
interface CalloutRegister {
|
|
1926
|
+
/** The app's ground (its page background), a hex. Decides the inversion. */
|
|
1927
|
+
ground: string;
|
|
1928
|
+
/** The product's accent, a hex: the kicker, the dot, the bar. */
|
|
1929
|
+
accent: string;
|
|
1930
|
+
/** The words face: a hosted catalog family or a system stack. */
|
|
1931
|
+
face?: string;
|
|
1932
|
+
/** The code face. */
|
|
1933
|
+
mono?: string;
|
|
1934
|
+
/** The app's body type size in CSS px at the recorded viewport. */
|
|
1935
|
+
body?: number;
|
|
1936
|
+
}
|
|
1937
|
+
interface CalloutWords {
|
|
1938
|
+
/** A short label above the title, set in the accent (a tag is only this). */
|
|
1939
|
+
kicker?: string;
|
|
1940
|
+
title?: string;
|
|
1941
|
+
/** One or two lines under the title. */
|
|
1942
|
+
body?: string;
|
|
1943
|
+
/** The payload, kept as typed (lines break on \n). */
|
|
1944
|
+
code?: string;
|
|
1945
|
+
}
|
|
1946
|
+
/** The resolved look: colours and sizes in design px. */
|
|
1947
|
+
interface CalloutLook {
|
|
1948
|
+
light: boolean;
|
|
1949
|
+
cardGround: string;
|
|
1950
|
+
cardInk: string;
|
|
1951
|
+
cardMuted: string;
|
|
1952
|
+
hairline: string;
|
|
1953
|
+
accent: string;
|
|
1954
|
+
shadow: string;
|
|
1955
|
+
face: string;
|
|
1956
|
+
mono: string;
|
|
1957
|
+
kickerPx: number;
|
|
1958
|
+
titlePx: number;
|
|
1959
|
+
bodyPx: number;
|
|
1960
|
+
codePx: number;
|
|
1961
|
+
radius: number;
|
|
1962
|
+
padX: number;
|
|
1963
|
+
padY: number;
|
|
1964
|
+
}
|
|
1965
|
+
declare const HOUSE_REGISTER: CalloutRegister;
|
|
1966
|
+
/**
|
|
1967
|
+
* Resolve a register into a look. `scale` is design px per CSS px of the
|
|
1968
|
+
* app as it appears at the layer's start (the card's footage scale times
|
|
1969
|
+
* the camera's level); 1 when unknown.
|
|
1970
|
+
*/
|
|
1971
|
+
declare function calloutLook(register: CalloutRegister, scale?: number): CalloutLook;
|
|
1972
|
+
interface CalloutBox {
|
|
1973
|
+
width: number;
|
|
1974
|
+
height: number;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* The design box a shape needs for its words: one line for a tag, the
|
|
1978
|
+
* kicker, title and wrapped body for a note, the lines for code. Widths
|
|
1979
|
+
* estimate glyphs at 0.56 em for words and 0.62 em for mono.
|
|
1980
|
+
*/
|
|
1981
|
+
declare function calloutBox(shape: CalloutShape, look: CalloutLook, words: CalloutWords): CalloutBox;
|
|
1982
|
+
/** The markup and CSS for a shape in a look, sized to a box. */
|
|
1983
|
+
declare function calloutSource(shape: CalloutShape, look: CalloutLook, words: CalloutWords, box: CalloutBox): {
|
|
1984
|
+
html: string;
|
|
1985
|
+
css: string;
|
|
1986
|
+
};
|
|
1987
|
+
interface CalloutClipOptions {
|
|
1988
|
+
id: string;
|
|
1989
|
+
/** OUTPUT seconds. */
|
|
1990
|
+
start: number;
|
|
1991
|
+
duration: number;
|
|
1992
|
+
/** Design px per CSS px of the app on screen at `start` (1 = unknown). */
|
|
1993
|
+
scale?: number;
|
|
1994
|
+
pin?: OverlayPin;
|
|
1995
|
+
/** The fallback place when the pin cannot resolve (frame fractions). */
|
|
1996
|
+
at?: {
|
|
1997
|
+
x: number;
|
|
1998
|
+
y: number;
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
/** A callout as an html overlay clip: the grammar applied to a register. */
|
|
2002
|
+
declare function calloutClip(shape: CalloutShape, register: CalloutRegister, words: CalloutWords, opts: CalloutClipOptions): HtmlOverlayClip;
|
|
2003
|
+
/**
|
|
2004
|
+
* The card's ground as its CSS declares it (the root rule's background),
|
|
2005
|
+
* for the picture check that compares it with the footage it covers. Null
|
|
2006
|
+
* when the CSS names none in a form a hex can be read from.
|
|
2007
|
+
*/
|
|
2008
|
+
declare function calloutGroundOf(css: string): string | null;
|
|
2009
|
+
type Rgb = [number, number, number];
|
|
2010
|
+
declare function hexToRgb(hex: string): Rgb | null;
|
|
2011
|
+
declare function rgbToHex([r, g, b]: Rgb): string;
|
|
2012
|
+
declare function parseCssColour(s: string): Rgb | null;
|
|
2013
|
+
declare function relativeLuminance([r, g, b]: Rgb): number;
|
|
2014
|
+
/** CIE76 colour difference between two sRGB colours. */
|
|
2015
|
+
declare function deltaE(a: Rgb, b: Rgb): number;
|
|
2016
|
+
|
|
1897
2017
|
/**
|
|
1898
2018
|
* Capture-space normalization — the single seam that makes window/monitor
|
|
1899
2019
|
* recordings look like tab recordings to everything downstream.
|
|
@@ -2992,6 +3112,19 @@ interface PinReferent {
|
|
|
2992
3112
|
* second. A `rect` is taken as written. Null when nothing names a rect.
|
|
2993
3113
|
*/
|
|
2994
3114
|
declare function pinReferent(doc: ProjectDoc, pin: OverlayPin): PinReferent | null;
|
|
3115
|
+
/** A step a layer could be pinned to: it has an element, and its window overlaps the layer's. */
|
|
3116
|
+
interface PinCandidate {
|
|
3117
|
+
step: string | number;
|
|
3118
|
+
do: string;
|
|
3119
|
+
selector?: string;
|
|
3120
|
+
/** The step's OUTPUT window. */
|
|
3121
|
+
output: {
|
|
3122
|
+
start: number;
|
|
3123
|
+
end: number;
|
|
3124
|
+
};
|
|
3125
|
+
/** Seconds of the layer's window the step's covers. */
|
|
3126
|
+
overlap: number;
|
|
3127
|
+
}
|
|
2995
3128
|
/** The step a pin names: its id first, then its record-time index. */
|
|
2996
3129
|
declare function findStep(steps: readonly StepSpan[], ref: string | number): StepSpan | undefined;
|
|
2997
3130
|
/**
|
|
@@ -3299,6 +3432,16 @@ declare function docZoomTrack(input: ProjectDoc): KeyframeTrack<number[]> | unde
|
|
|
3299
3432
|
* and the layer keeps its `transform` — the lint says why.
|
|
3300
3433
|
*/
|
|
3301
3434
|
declare function resolvePins(doc: ProjectDoc, layout: CardLayout, camera: CameraModel, zoomTrack: KeyframeTrack<number[]> | undefined): Map<string, PinPlacement>;
|
|
3435
|
+
/**
|
|
3436
|
+
* The steps an unpinned layer could name: every step with an element (a
|
|
3437
|
+
* rect, or presses inside its window) whose output window overlaps the
|
|
3438
|
+
* layer's, most overlap first. The studio's Pin-to select and the lint's
|
|
3439
|
+
* advice read this.
|
|
3440
|
+
*/
|
|
3441
|
+
declare function pinCandidates(doc: ProjectDoc, clip: {
|
|
3442
|
+
start: number;
|
|
3443
|
+
duration: number;
|
|
3444
|
+
}): PinCandidate[];
|
|
3302
3445
|
/**
|
|
3303
3446
|
* A pinned layer's effective [x, y, scale, rotation, opacity] at CLIP-LOCAL
|
|
3304
3447
|
* time t — the host-side mirror the picking layer substitutes into the
|
|
@@ -3645,22 +3788,8 @@ declare function htmlLayerPayload(clip: HtmlOverlayClip): {
|
|
|
3645
3788
|
html: HtmlLayerPayload;
|
|
3646
3789
|
};
|
|
3647
3790
|
|
|
3648
|
-
/**
|
|
3649
|
-
* The house starters for an HTML layer: what one press of the studio's HTML
|
|
3650
|
-
* verb puts on the canvas, and what its panel's Starter select swaps in.
|
|
3651
|
-
* Product defaults the way the three text presets are (code, not shelf
|
|
3652
|
-
* data), five and not fifty: a LIBRARY of components is an official project
|
|
3653
|
-
* on the shelf that an agent applies as a template.
|
|
3654
|
-
*
|
|
3655
|
-
* Each is real, readable markup and CSS a person can retune, in the house
|
|
3656
|
-
* look (a dark card, Inter for words, JetBrains Mono for code, both hosted so
|
|
3657
|
-
* the faces resolve from the CSS alone), with a `box-shadow` so the derived
|
|
3658
|
-
* bleed is exercised. `htmlStarters.test.ts` proves every one passes the
|
|
3659
|
-
* gate with no problem and no warning.
|
|
3660
|
-
*/
|
|
3661
|
-
|
|
3662
3791
|
interface HtmlStarter {
|
|
3663
|
-
id: '
|
|
3792
|
+
id: 'note' | 'tag' | 'code' | 'terminal' | 'keys' | 'badge';
|
|
3664
3793
|
name: string;
|
|
3665
3794
|
html: string;
|
|
3666
3795
|
css: string;
|
|
@@ -4694,4 +4823,4 @@ declare function rejectSpan(rejected: RejectedSpan[] | undefined, lane: Rejected
|
|
|
4694
4823
|
anchor?: StepAnchor;
|
|
4695
4824
|
}, note?: string): RejectedSpan;
|
|
4696
4825
|
|
|
4697
|
-
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, 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_PAIR_MAX, CLICK_PULSE_DUR, CLICK_RECT_MAX_FRAC, CLICK_RIPPLE_DUR, CLICK_SYNTH_RELEASE, 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 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, 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, HOUSE_GRADIENT, 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, 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, type RecordingArtifact, type RecordingMeta, type Rect, type RejectedLane, type RejectedSpan, type ResolvedOverlayBox, type ResolvedOverlayStyle, 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, 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 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 ZoomSpan, type ZoomStyleName, type ZoomStyleParams, type ZoomView, type ZoomWindow, anchorKindOf, anchorSourceDuration, animStep, applyLook, applyTemplate, aspectRatioValue, audioLane, backdropMedia, buildDigest, 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, cursorIdleFade, deriveViewportCrop, destinationById, destinationsForChannel, docCardLayout, docFreezes, docMediaList, docOutputDuration, docRestTime, docStillTime, docToCropSpace, docToFullSpace, docTransitions, docZoomTrack, dragsFromTrack, dropTemplate, duckCurve, effectiveSegments, endCardClips, enterKey, enterOf, entranceSeconds, envelopeAt, envelopeValueAt, exitKey, exitOf, exitSeconds, expandEndCard, expectedFrameSize, exportSizeFor, extractClicks, findStep, focusBounds, focusForViewportCentre, followFocusEvents, frameGeometry, freezeLane, freezeOutputExtents, 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, lookFromBrand, lookKindForGround, lowerProgramDoc, lowerStudioDoc, lowerToComposition, mediaAtOutput, mediaDuration, mediaFrame, mediaKey, mediaRef, mediaRefId, mediaSource, micLane, migrateHostedDoc, migrateMotion, momentsFromDoc, motionTrack, musicBedClip, nextMediaId, normalizeCaptureSpace, objectMotionBase, objectMotionPoseAt, objectsLane, outputDurationOf, outputEnd, outputRangeToSource, overlapFraction, overlayFaceFor, overlayFontFaces, overlayFontString, overlayFxSpec, overlayHit, overlayLines, overlayMotionBase, overlayMotionPoseAt, overlayPinPoseAt, overlayRect, overlaysLane, ownFreezes, pageDisplayUrl, parsePoseId, pickStyle, pinBox, pinPlacement, pinRectOnScreen, pinReferent, pinReferentAt, placeFreezes, planAutoSpeed, planAutoTilt, planAutoZoom, planForDigest, planeSizeAtDepth, platformBarKind, programDuration, projectFromArtifact, ratedSegments, recommendedExportResolution, refillAudioBeds, rejectSpan, removeSourceRange, removeSpeedInRange, resolveExportSize, resolveOverlayBox, resolveOverlayStyle, resolvePins, resolveText3dAsset, resolveZoomStyle, restLeanOf, restSpansThroughTransitions, sameMedia, sceneChanges, scrollRuns, segmentOutputExtents, outputLen as segmentOutputLen, segmentStarts, setSpeedInRange, slideSide, smoothCursor, spanOutputExtent, speedLane, studioAudioPlan, studioEntry, studioLayerData, tiltLane, tiltTrackFromDoc, transitionMult, transitionSeconds, videoLane, voiceKey, wellFormedXml, withBackdrop, withFreezes, withHolds, withoutRejected, wrapProgramLength, zoomCoversRect, zoomLane, zoomSpanForRange, zoomTrackFromDoc, zoomView, zoomViewport, zoomWindow };
|
|
4826
|
+
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_PAIR_MAX, CLICK_PULSE_DUR, CLICK_RECT_MAX_FRAC, CLICK_RIPPLE_DUR, CLICK_SYNTH_RELEASE, 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, 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, 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, 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, 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, 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 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 ZoomSpan, type ZoomStyleName, type ZoomStyleParams, type ZoomView, type ZoomWindow, anchorKindOf, anchorSourceDuration, animStep, applyLook, applyTemplate, aspectRatioValue, audioLane, backdropMedia, 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, cursorIdleFade, deltaE, deriveViewportCrop, destinationById, destinationsForChannel, docCardLayout, docFreezes, docMediaList, docOutputDuration, docRestTime, docStillTime, docToCropSpace, docToFullSpace, docTransitions, docZoomTrack, dragsFromTrack, dropTemplate, duckCurve, effectiveSegments, endCardClips, enterKey, enterOf, 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, lookFromBrand, lookKindForGround, lowerProgramDoc, lowerStudioDoc, lowerToComposition, mediaAtOutput, mediaDuration, mediaFrame, mediaKey, mediaRef, mediaRefId, mediaSource, micLane, migrateHostedDoc, migrateMotion, momentsFromDoc, motionTrack, musicBedClip, nextMediaId, normalizeCaptureSpace, objectMotionBase, objectMotionPoseAt, objectsLane, outputDurationOf, outputEnd, outputRangeToSource, overlapFraction, overlayFaceFor, overlayFontFaces, overlayFontString, overlayFxSpec, overlayHit, overlayLines, overlayMotionBase, overlayMotionPoseAt, overlayPinPoseAt, overlayRect, overlaysLane, ownFreezes, pageDisplayUrl, parseCssColour, parsePoseId, pickStyle, pinBox, pinCandidates, pinPlacement, pinRectOnScreen, pinReferent, pinReferentAt, placeFreezes, planAutoSpeed, planAutoTilt, planAutoZoom, planForDigest, planeSizeAtDepth, platformBarKind, programDuration, projectFromArtifact, 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, spanOutputExtent, speedLane, studioAudioPlan, studioEntry, studioLayerData, tiltLane, tiltTrackFromDoc, transitionMult, transitionSeconds, videoLane, voiceKey, wellFormedXml, withBackdrop, withFreezes, withHolds, withoutRejected, wrapProgramLength, zoomCoversRect, zoomLane, zoomSpanForRange, zoomTrackFromDoc, zoomView, zoomViewport, zoomWindow };
|
package/dist/index.js
CHANGED
|
@@ -236,6 +236,210 @@ var MEDIA_FRAME_KEYS = [
|
|
|
236
236
|
"focusFollow"
|
|
237
237
|
];
|
|
238
238
|
|
|
239
|
+
// src/callout.ts
|
|
240
|
+
var CALLOUT_SHAPES = ["tag", "note", "code"];
|
|
241
|
+
var CALLOUT_TYPE_RATIO = 1.35;
|
|
242
|
+
var CALLOUT_DEFAULT_BODY_PX = 14;
|
|
243
|
+
var HOUSE_REGISTER = {
|
|
244
|
+
ground: "#ffffff",
|
|
245
|
+
accent: "#7c3aed"
|
|
246
|
+
};
|
|
247
|
+
var DEFAULT_FACE = "'Inter',-apple-system,system-ui,sans-serif";
|
|
248
|
+
var DEFAULT_MONO = "'JetBrains Mono',ui-monospace,monospace";
|
|
249
|
+
function calloutLook(register, scale = 1) {
|
|
250
|
+
const ground = hexToRgb(register.ground) ?? [255, 255, 255];
|
|
251
|
+
const accent = hexToRgb(register.accent) ?? [124, 58, 237];
|
|
252
|
+
const light = relativeLuminance(ground) > 0.4;
|
|
253
|
+
const [h, s] = rgbToHsl(accent);
|
|
254
|
+
const cardGround = light ? hslToHex(h, Math.min(0.35, s * 0.6), 0.07) : hslToHex(h, Math.min(0.25, s * 0.35), 0.97);
|
|
255
|
+
const bodyPx = register.body ?? CALLOUT_DEFAULT_BODY_PX;
|
|
256
|
+
const titlePx = Math.max(20, Math.round(CALLOUT_TYPE_RATIO * bodyPx * scale));
|
|
257
|
+
return {
|
|
258
|
+
light,
|
|
259
|
+
cardGround,
|
|
260
|
+
cardInk: light ? "#fafafa" : "#101012",
|
|
261
|
+
cardMuted: light ? "rgba(255,255,255,0.64)" : "rgba(16,16,18,0.6)",
|
|
262
|
+
hairline: light ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.1)",
|
|
263
|
+
accent: rgbToHex(accent),
|
|
264
|
+
shadow: "0 24px 60px rgba(0,0,0,0.35), 0 2px 6px rgba(0,0,0,0.16)",
|
|
265
|
+
face: register.face ? quoteFamily(register.face) : DEFAULT_FACE,
|
|
266
|
+
mono: register.mono ? quoteFamily(register.mono) : DEFAULT_MONO,
|
|
267
|
+
kickerPx: Math.max(11, Math.round(titlePx * 0.55)),
|
|
268
|
+
titlePx,
|
|
269
|
+
bodyPx: Math.max(15, Math.round(titlePx * 0.75)),
|
|
270
|
+
codePx: Math.max(14, Math.round(titlePx * 0.68)),
|
|
271
|
+
radius: 16,
|
|
272
|
+
padX: 24,
|
|
273
|
+
padY: 20
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function calloutBox(shape, look, words) {
|
|
277
|
+
const em = (px, chars, adv) => Math.ceil(px * adv * chars);
|
|
278
|
+
if (shape === "tag") {
|
|
279
|
+
const text = words.kicker ?? words.title ?? "";
|
|
280
|
+
const w = em(look.kickerPx * 1.1, text.length, 0.62) + 14 + 18 * 2;
|
|
281
|
+
return {
|
|
282
|
+
width: clamp(w, 120, 720),
|
|
283
|
+
height: Math.max(36, Math.round(look.kickerPx * 1.1 * 2.6))
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (shape === "code") {
|
|
287
|
+
const lines = (words.code ?? "").split("\n");
|
|
288
|
+
const longest = Math.max(1, ...lines.map((l) => l.length));
|
|
289
|
+
const lineH = Math.round(look.codePx * 1.7);
|
|
290
|
+
const w = em(look.codePx, longest, 0.62) + look.padX * 2;
|
|
291
|
+
const h = lines.length * lineH + look.padY * 2 + (words.kicker ? look.kickerPx * 2 : 0);
|
|
292
|
+
return { width: clamp(w, 360, 820), height: clamp(h, 72, 640) };
|
|
293
|
+
}
|
|
294
|
+
const title = words.title ?? "";
|
|
295
|
+
const body = words.body ?? "";
|
|
296
|
+
const titleW = em(look.titlePx, title.length, 0.56);
|
|
297
|
+
const width = clamp(Math.max(titleW, 320) + look.padX * 2, 360, 640);
|
|
298
|
+
const inner = width - look.padX * 2;
|
|
299
|
+
const bodyLines = body ? Math.max(1, Math.ceil(em(look.bodyPx, body.length, 0.54) / inner)) : 0;
|
|
300
|
+
const titleLines = Math.max(1, Math.ceil(titleW / inner));
|
|
301
|
+
const height = look.padY * 2 + (words.kicker ? Math.round(look.kickerPx * 1.6) : 0) + titleLines * Math.round(look.titlePx * 1.25) + (bodyLines ? 8 + bodyLines * Math.round(look.bodyPx * 1.5) : 0);
|
|
302
|
+
return { width, height: clamp(height, 64, 480) };
|
|
303
|
+
}
|
|
304
|
+
function calloutSource(shape, look, words, box) {
|
|
305
|
+
const base = `box-sizing:border-box;width:${box.width}px;height:${box.height}px;background:${look.cardGround};color:${look.cardInk};border:1px solid ${look.hairline};border-radius:${look.radius}px;box-shadow:${look.shadow};-webkit-font-smoothing:antialiased;`;
|
|
306
|
+
if (shape === "tag") {
|
|
307
|
+
const text = esc(words.kicker ?? words.title ?? "");
|
|
308
|
+
return {
|
|
309
|
+
html: `<div class="tag"><span class="dot"></span><span class="t">${text}</span></div>`,
|
|
310
|
+
css: `.tag{font-family:${look.face};display:flex;align-items:center;gap:10px;${base}border-radius:999px;padding:0 18px;background:${look.accent};color:#fff;border-color:rgba(255,255,255,0.18);font-size:${Math.round(look.kickerPx * 1.1)}px;font-weight:600;letter-spacing:0.02em;text-transform:uppercase;white-space:nowrap}.dot{width:8px;height:8px;border-radius:99px;background:#fff;opacity:0.9;flex:none}`
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
if (shape === "code") {
|
|
314
|
+
const lines = (words.code ?? "").split("\n").map(
|
|
315
|
+
(l) => /^\s*(\/\/|#|\$)/.test(l) ? `<span class="mut">${esc(l)}</span>` : esc(l)
|
|
316
|
+
).join("\n");
|
|
317
|
+
const kicker2 = words.kicker ? `<div class="k">${esc(words.kicker)}</div>` : "";
|
|
318
|
+
return {
|
|
319
|
+
html: `<div class="code">${kicker2}<pre class="p">${lines}</pre></div>`,
|
|
320
|
+
css: `.code{font-family:${look.mono};${base}padding:${look.padY}px ${look.padX}px;font-size:${look.codePx}px;line-height:1.7;letter-spacing:-0.01em}.k{font-family:${look.face};font-size:${look.kickerPx}px;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:${look.accent};margin:0 0 ${Math.round(look.kickerPx * 0.9)}px}.p{margin:0;white-space:pre;font:inherit}.mut{color:${look.cardMuted}}`
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const kicker = words.kicker ? `<div class="k"><span class="dot"></span>${esc(words.kicker)}</div>` : "";
|
|
324
|
+
const body = words.body ? `<div class="b">${esc(words.body)}</div>` : "";
|
|
325
|
+
return {
|
|
326
|
+
html: `<div class="note">${kicker}<div class="t">${esc(words.title ?? "")}</div>${body}</div>`,
|
|
327
|
+
css: `.note{font-family:${look.face};${base}padding:${look.padY}px ${look.padX}px;display:flex;flex-direction:column;justify-content:center}.k{display:flex;align-items:center;gap:8px;font-size:${look.kickerPx}px;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:${look.accent};margin-bottom:${Math.round(look.kickerPx * 0.6)}px}.dot{width:7px;height:7px;border-radius:99px;background:${look.accent};box-shadow:0 0 10px ${look.accent}}.t{font-size:${look.titlePx}px;font-weight:600;line-height:1.25;letter-spacing:-0.01em}.b{margin-top:8px;font-size:${look.bodyPx}px;line-height:1.5;color:${look.cardMuted}}`
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function calloutClip(shape, register, words, opts) {
|
|
331
|
+
const look = calloutLook(register, opts.scale ?? 1);
|
|
332
|
+
const box = calloutBox(shape, look, words);
|
|
333
|
+
const { html, css } = calloutSource(shape, look, words, box);
|
|
334
|
+
return {
|
|
335
|
+
id: opts.id,
|
|
336
|
+
kind: "html",
|
|
337
|
+
start: opts.start,
|
|
338
|
+
duration: opts.duration,
|
|
339
|
+
html,
|
|
340
|
+
css,
|
|
341
|
+
box,
|
|
342
|
+
transform: {
|
|
343
|
+
x: opts.at?.x ?? 0.5,
|
|
344
|
+
y: opts.at?.y ?? 0.5,
|
|
345
|
+
scale: 1,
|
|
346
|
+
rotation: 0
|
|
347
|
+
},
|
|
348
|
+
anim: { enter: "rise", exit: "fade" },
|
|
349
|
+
...opts.pin ? { pin: opts.pin } : {}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function calloutGroundOf(css) {
|
|
353
|
+
const m = /background(?:-color)?\s*:\s*(#[0-9a-fA-F]{3,8}|rgba?\([^)]*\))/.exec(css);
|
|
354
|
+
if (!m) return null;
|
|
355
|
+
const rgb = parseCssColour(m[1]);
|
|
356
|
+
return rgb ? rgbToHex(rgb) : null;
|
|
357
|
+
}
|
|
358
|
+
function hexToRgb(hex) {
|
|
359
|
+
const m = /^#?([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(hex.trim());
|
|
360
|
+
if (!m) return null;
|
|
361
|
+
let h = m[1];
|
|
362
|
+
if (h.length === 3)
|
|
363
|
+
h = h.split("").map((c) => c + c).join("");
|
|
364
|
+
return [
|
|
365
|
+
parseInt(h.slice(0, 2), 16),
|
|
366
|
+
parseInt(h.slice(2, 4), 16),
|
|
367
|
+
parseInt(h.slice(4, 6), 16)
|
|
368
|
+
];
|
|
369
|
+
}
|
|
370
|
+
function rgbToHex([r, g, b]) {
|
|
371
|
+
const c = (v) => Math.round(clamp(v, 0, 255)).toString(16).padStart(2, "0");
|
|
372
|
+
return `#${c(r)}${c(g)}${c(b)}`;
|
|
373
|
+
}
|
|
374
|
+
function parseCssColour(s) {
|
|
375
|
+
const hex = hexToRgb(s);
|
|
376
|
+
if (hex) return hex;
|
|
377
|
+
const m = /rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)/.exec(s);
|
|
378
|
+
if (!m) return null;
|
|
379
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
380
|
+
}
|
|
381
|
+
function relativeLuminance([r, g, b]) {
|
|
382
|
+
const lin = (v) => {
|
|
383
|
+
const c = v / 255;
|
|
384
|
+
return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
385
|
+
};
|
|
386
|
+
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
387
|
+
}
|
|
388
|
+
function rgbToHsl([r, g, b]) {
|
|
389
|
+
const rr = r / 255;
|
|
390
|
+
const gg = g / 255;
|
|
391
|
+
const bb = b / 255;
|
|
392
|
+
const max = Math.max(rr, gg, bb);
|
|
393
|
+
const min = Math.min(rr, gg, bb);
|
|
394
|
+
const l = (max + min) / 2;
|
|
395
|
+
if (max === min) return [0, 0, l];
|
|
396
|
+
const d = max - min;
|
|
397
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
398
|
+
let h = 0;
|
|
399
|
+
if (max === rr) h = (gg - bb) / d + (gg < bb ? 6 : 0);
|
|
400
|
+
else if (max === gg) h = (bb - rr) / d + 2;
|
|
401
|
+
else h = (rr - gg) / d + 4;
|
|
402
|
+
return [h / 6, s, l];
|
|
403
|
+
}
|
|
404
|
+
function hslToHex(h, s, l) {
|
|
405
|
+
const f = (n) => {
|
|
406
|
+
const k = (n + h * 12) % 12;
|
|
407
|
+
const a = s * Math.min(l, 1 - l);
|
|
408
|
+
return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
|
|
409
|
+
};
|
|
410
|
+
return rgbToHex([f(0) * 255, f(8) * 255, f(4) * 255]);
|
|
411
|
+
}
|
|
412
|
+
function deltaE(a, b) {
|
|
413
|
+
const la = rgbToLab(a);
|
|
414
|
+
const lb = rgbToLab(b);
|
|
415
|
+
return Math.hypot(la[0] - lb[0], la[1] - lb[1], la[2] - lb[2]);
|
|
416
|
+
}
|
|
417
|
+
function rgbToLab([r, g, b]) {
|
|
418
|
+
const lin = (v) => {
|
|
419
|
+
const c = v / 255;
|
|
420
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
421
|
+
};
|
|
422
|
+
const R = lin(r);
|
|
423
|
+
const G = lin(g);
|
|
424
|
+
const B = lin(b);
|
|
425
|
+
const x = (R * 0.4124 + G * 0.3576 + B * 0.1805) / 0.95047;
|
|
426
|
+
const y = R * 0.2126 + G * 0.7152 + B * 0.0722;
|
|
427
|
+
const z = (R * 0.0193 + G * 0.1192 + B * 0.9505) / 1.08883;
|
|
428
|
+
const f = (t) => t > 8856e-6 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
|
|
429
|
+
return [116 * f(y) - 16, 500 * (f(x) - f(y)), 200 * (f(y) - f(z))];
|
|
430
|
+
}
|
|
431
|
+
function quoteFamily(family) {
|
|
432
|
+
const first = family.split(",")[0].trim().replace(/^['"]|['"]$/g, "");
|
|
433
|
+
const rest = family.includes(",") ? family.slice(family.indexOf(",") + 1).trim() : /mono/i.test(first) ? "ui-monospace,monospace" : "-apple-system,system-ui,sans-serif";
|
|
434
|
+
return /^[a-z-]+$/i.test(first) && /^(ui-|system-ui|sans-serif|serif|monospace)/.test(first) ? `${first},${rest}` : `'${first}',${rest}`;
|
|
435
|
+
}
|
|
436
|
+
function esc(s) {
|
|
437
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
438
|
+
}
|
|
439
|
+
function clamp(v, lo, hi) {
|
|
440
|
+
return Math.max(lo, Math.min(hi, v));
|
|
441
|
+
}
|
|
442
|
+
|
|
239
443
|
// src/capture.ts
|
|
240
444
|
var CHROME_TOP_MIN = 20;
|
|
241
445
|
var CHROME_TOP_MAX = 220;
|
|
@@ -1102,7 +1306,7 @@ function sampleAt(points, t) {
|
|
|
1102
1306
|
return { x: last.x, y: last.y };
|
|
1103
1307
|
}
|
|
1104
1308
|
function smoothCursor(track, options = {}) {
|
|
1105
|
-
const factor =
|
|
1309
|
+
const factor = clamp2(options.factor ?? 0.15, 0.01, 1);
|
|
1106
1310
|
const fps = options.fps ?? 60;
|
|
1107
1311
|
const raw = track.filter((e) => e.type === "move" || e.type === "down" || e.type === "up").map((e) => ({ t: e.t / 1e3, x: e.x, y: e.y }));
|
|
1108
1312
|
if (raw.length === 0) return [];
|
|
@@ -1121,7 +1325,7 @@ function smoothCursor(track, options = {}) {
|
|
|
1121
1325
|
if (clicks.length) {
|
|
1122
1326
|
while (ci < clicks.length - 1 && t > clicks[ci].t + SNAP_AFTER) ci++;
|
|
1123
1327
|
const ck = clicks[ci];
|
|
1124
|
-
const u =
|
|
1328
|
+
const u = clamp2(
|
|
1125
1329
|
(t - (ck.t - SNAP_BEFORE)) / SNAP_BEFORE,
|
|
1126
1330
|
0,
|
|
1127
1331
|
t <= ck.t + SNAP_AFTER ? 1 : 0
|
|
@@ -1136,7 +1340,7 @@ function smoothCursor(track, options = {}) {
|
|
|
1136
1340
|
}
|
|
1137
1341
|
return out;
|
|
1138
1342
|
}
|
|
1139
|
-
function
|
|
1343
|
+
function clamp2(v, lo, hi) {
|
|
1140
1344
|
return Math.max(lo, Math.min(hi, v));
|
|
1141
1345
|
}
|
|
1142
1346
|
|
|
@@ -1782,7 +1986,7 @@ function focusFor(cluster, width, height, targetFill, minLevel, maxLevel) {
|
|
|
1782
1986
|
const cx = clamp012(sx / n / width);
|
|
1783
1987
|
const cy = clamp012(sy / n / height);
|
|
1784
1988
|
const level = fitLevel({ x: 0, y: 0, w: maxW, h: maxH }, width, height, targetFill) ?? maxLevel;
|
|
1785
|
-
return { cx, cy, level:
|
|
1989
|
+
return { cx, cy, level: clamp3(level, minLevel, maxLevel) };
|
|
1786
1990
|
}
|
|
1787
1991
|
function clusterFocus(events, width, height) {
|
|
1788
1992
|
let sx = 0;
|
|
@@ -1815,11 +2019,11 @@ function clusterFocus(events, width, height) {
|
|
|
1815
2019
|
} : null;
|
|
1816
2020
|
return { cx: clamp012(sx / n / width), cy: clamp012(sy / n / height), rect };
|
|
1817
2021
|
}
|
|
1818
|
-
function
|
|
2022
|
+
function clamp3(v, lo, hi) {
|
|
1819
2023
|
return Math.max(lo, Math.min(hi, v));
|
|
1820
2024
|
}
|
|
1821
2025
|
function clamp012(v) {
|
|
1822
|
-
return
|
|
2026
|
+
return clamp3(v, 0, 1);
|
|
1823
2027
|
}
|
|
1824
2028
|
function round(v) {
|
|
1825
2029
|
return Math.round(v * 1e3) / 1e3;
|
|
@@ -7532,6 +7736,29 @@ function resolvePins(doc, layout, camera, zoomTrack) {
|
|
|
7532
7736
|
}
|
|
7533
7737
|
return out;
|
|
7534
7738
|
}
|
|
7739
|
+
function pinCandidates(doc, clip) {
|
|
7740
|
+
const rated = ratedSegments(doc);
|
|
7741
|
+
const out = [];
|
|
7742
|
+
const a0 = clip.start;
|
|
7743
|
+
const a1 = clip.start + clip.duration;
|
|
7744
|
+
for (const s of doc.source.meta.steps ?? []) {
|
|
7745
|
+
if (s.skipped) continue;
|
|
7746
|
+
const ref = pinReferent(doc, { step: s.id ?? s.step });
|
|
7747
|
+
if (!ref) continue;
|
|
7748
|
+
const ext = spanOutputExtent(rated, s.tStart, s.tEnd);
|
|
7749
|
+
if (!ext) continue;
|
|
7750
|
+
const overlap = Math.min(a1, ext.end) - Math.max(a0, ext.start);
|
|
7751
|
+
if (overlap <= 0) continue;
|
|
7752
|
+
out.push({
|
|
7753
|
+
step: s.id ?? s.step,
|
|
7754
|
+
do: s.do,
|
|
7755
|
+
...s.selector ? { selector: s.selector } : {},
|
|
7756
|
+
output: { start: round7(ext.start), end: round7(ext.end) },
|
|
7757
|
+
overlap: round7(overlap)
|
|
7758
|
+
});
|
|
7759
|
+
}
|
|
7760
|
+
return out.sort((x, y) => y.overlap - x.overlap);
|
|
7761
|
+
}
|
|
7535
7762
|
function overlayPinPoseAt(doc, o, t) {
|
|
7536
7763
|
if (!o.pin) return null;
|
|
7537
7764
|
const layout = docCardLayout(doc);
|
|
@@ -9079,24 +9306,31 @@ function destinationsForChannel(channel) {
|
|
|
9079
9306
|
}
|
|
9080
9307
|
|
|
9081
9308
|
// src/htmlStarters.ts
|
|
9309
|
+
function grammarStarter(id, name, words) {
|
|
9310
|
+
const clip = calloutClip(id, HOUSE_REGISTER, words, {
|
|
9311
|
+
id,
|
|
9312
|
+
start: 0,
|
|
9313
|
+
duration: 1,
|
|
9314
|
+
scale: 1.4
|
|
9315
|
+
});
|
|
9316
|
+
return { id, name, html: clip.html, css: clip.css ?? "", box: clip.box };
|
|
9317
|
+
}
|
|
9082
9318
|
var WORDS = "font-family:'Inter',-apple-system,system-ui,sans-serif;color:#fafafa;-webkit-font-smoothing:antialiased;";
|
|
9083
9319
|
var MONO = "font-family:'JetBrains Mono',ui-monospace,monospace;";
|
|
9084
9320
|
var CARD = "background:#0b0b0d;border:1px solid rgba(255,255,255,.08);border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.45);";
|
|
9085
9321
|
var HTML_STARTERS = [
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
},
|
|
9093
|
-
{
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
css: `.code{${MONO}${CARD}color:#e8e8ec;box-sizing:border-box;width:460px;height:168px;padding:22px 24px;font-size:14px;line-height:1.8;white-space:pre;letter-spacing:-0.01em}.kw{color:#c4b5fd}.fn{color:#7dd3fc}.tag{color:#f0abfc}.mut{color:#5b5b66}`
|
|
9099
|
-
},
|
|
9322
|
+
// The callout grammar (three shapes a viewer learns once), in the house
|
|
9323
|
+
// register: a dark card in the house hue over a light app.
|
|
9324
|
+
grammarStarter("note", "Note", {
|
|
9325
|
+
kicker: "Presets",
|
|
9326
|
+
title: "One of 43, picked here.",
|
|
9327
|
+
body: "One line that says what this is about."
|
|
9328
|
+
}),
|
|
9329
|
+
grammarStarter("tag", "Tag", { kicker: "New in 2.0" }),
|
|
9330
|
+
grammarStarter("code", "Code", {
|
|
9331
|
+
kicker: "index.css",
|
|
9332
|
+
code: ":root {\n --primary: oklch(0.63 0.06 4.6);\n --radius: 2.25rem;\n}"
|
|
9333
|
+
}),
|
|
9100
9334
|
{
|
|
9101
9335
|
id: "terminal",
|
|
9102
9336
|
name: "Terminal",
|
|
@@ -10637,6 +10871,9 @@ export {
|
|
|
10637
10871
|
AUDIO_PLAN_STEP,
|
|
10638
10872
|
BACKGROUND_Z,
|
|
10639
10873
|
BASE_FRAME_STYLE,
|
|
10874
|
+
CALLOUT_DEFAULT_BODY_PX,
|
|
10875
|
+
CALLOUT_SHAPES,
|
|
10876
|
+
CALLOUT_TYPE_RATIO,
|
|
10640
10877
|
CAMERA_CENTRE_RAMP,
|
|
10641
10878
|
CAMERA_COVER_MIN,
|
|
10642
10879
|
CAMERA_FAR,
|
|
@@ -10711,6 +10948,7 @@ export {
|
|
|
10711
10948
|
FREEZE_SECONDS_MAX,
|
|
10712
10949
|
FREEZE_SECONDS_MIN,
|
|
10713
10950
|
HOUSE_GRADIENT,
|
|
10951
|
+
HOUSE_REGISTER,
|
|
10714
10952
|
HTML_LAYER_FOREIGN_FIELDS,
|
|
10715
10953
|
HTML_LAYER_MAX_BYTES,
|
|
10716
10954
|
HTML_LAYER_SVG_CODE,
|
|
@@ -10802,6 +11040,11 @@ export {
|
|
|
10802
11040
|
audioLane,
|
|
10803
11041
|
backdropMedia,
|
|
10804
11042
|
buildDigest,
|
|
11043
|
+
calloutBox,
|
|
11044
|
+
calloutClip,
|
|
11045
|
+
calloutGroundOf,
|
|
11046
|
+
calloutLook,
|
|
11047
|
+
calloutSource,
|
|
10805
11048
|
camBubbleRect,
|
|
10806
11049
|
camBubbleRectAt,
|
|
10807
11050
|
camLane,
|
|
@@ -10836,6 +11079,7 @@ export {
|
|
|
10836
11079
|
cssFamilies,
|
|
10837
11080
|
cssWeights,
|
|
10838
11081
|
cursorIdleFade,
|
|
11082
|
+
deltaE,
|
|
10839
11083
|
deriveViewportCrop,
|
|
10840
11084
|
destinationById,
|
|
10841
11085
|
destinationsForChannel,
|
|
@@ -10873,6 +11117,7 @@ export {
|
|
|
10873
11117
|
frameGeometry,
|
|
10874
11118
|
freezeLane,
|
|
10875
11119
|
freezeOutputExtents,
|
|
11120
|
+
hexToRgb,
|
|
10876
11121
|
hexToRgbTriplet,
|
|
10877
11122
|
houseLook,
|
|
10878
11123
|
htmlLayerBleed,
|
|
@@ -10943,9 +11188,11 @@ export {
|
|
|
10943
11188
|
overlaysLane,
|
|
10944
11189
|
ownFreezes,
|
|
10945
11190
|
pageDisplayUrl,
|
|
11191
|
+
parseCssColour,
|
|
10946
11192
|
parsePoseId,
|
|
10947
11193
|
pickStyle,
|
|
10948
11194
|
pinBox,
|
|
11195
|
+
pinCandidates,
|
|
10949
11196
|
pinPlacement,
|
|
10950
11197
|
pinRectOnScreen,
|
|
10951
11198
|
pinReferent,
|
|
@@ -10963,6 +11210,7 @@ export {
|
|
|
10963
11210
|
recommendedExportResolution,
|
|
10964
11211
|
refillAudioBeds,
|
|
10965
11212
|
rejectSpan,
|
|
11213
|
+
relativeLuminance,
|
|
10966
11214
|
removeSourceRange,
|
|
10967
11215
|
removeSpeedInRange,
|
|
10968
11216
|
resolveExportSize,
|
|
@@ -10973,6 +11221,7 @@ export {
|
|
|
10973
11221
|
resolveZoomStyle,
|
|
10974
11222
|
restLeanOf,
|
|
10975
11223
|
restSpansThroughTransitions,
|
|
11224
|
+
rgbToHex,
|
|
10976
11225
|
sameMedia,
|
|
10977
11226
|
sceneChanges,
|
|
10978
11227
|
scrollRuns,
|