@real-music-packages/web-core 0.45.2 → 0.46.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.
@@ -2,7 +2,7 @@ import { S as Score, a as ScoreFromMusicXMLOpts, T as TempoMap, b as ScoreNote }
2
2
  export { s as scoreFromMusicXML } from '../score-CLwSiAjn.js';
3
3
  import { A as AudioClock, a as LayerFactory, R as RenderCtx } from '../waveform-CdulBoeO.js';
4
4
  export { L as Layer, S as SpectrumInput, b as SpectrumProps, W as WaveformInput, c as WaveformProps, s as spectrumFactory, w as waveformFactory } from '../waveform-CdulBoeO.js';
5
- import { PromoTheme, RecordOpts, Scene, SafeBox } from '../video.js';
5
+ import { SafeBox, PromoTheme, RecordOpts, Scene } from '../video.js';
6
6
  import { RenderedNotation, Box } from '../promo.js';
7
7
  import { N as NotationLayout } from '../notationGeometry-DqVBgL7F.js';
8
8
  export { F as FOLLOW_BARS, a as FOLLOW_PAD, b as NotationLayoutOpts, c as NotationRect, P as PlayheadLine, d as audioPlayheadLine, e as cropAroundBox, f as cubicEaseInOut, g as distinctMeasureIndices, h as distinctOnsets, i as firstMeasureBox, j as followBoxAt, k as followWindowStart, m as lerpBox, n as measureColumnsFromLayout, o as measureCount, p as measureSpanBox, q as measureSystemMap, r as notationLayout, s as playheadLine, t as systemBox, v as vstackAudioPlayheadLine, u as vstackFollowBox } from '../notationGeometry-DqVBgL7F.js';
@@ -153,6 +153,52 @@ declare function applyToContext(ctx: CanvasRenderingContext2D, cam: CameraState,
153
153
  /** The identity (no pan/zoom) camera: world == viewport. */
154
154
  declare function identityCamera(W: number, H: number): CameraState;
155
155
 
156
+ /** A sub-rect of the frame, in fractions of W/H (0..1, top-left origin). */
157
+ interface Region {
158
+ x: number;
159
+ y: number;
160
+ w: number;
161
+ h: number;
162
+ }
163
+ /** The whole frame. A layer with this region renders exactly as an unregioned one. */
164
+ declare const FULL_REGION: Region;
165
+ /** True when `r` covers the entire frame (the runner then skips the transform). */
166
+ declare function isFullRegion(r: Region): boolean;
167
+ /** A region's pixel rect in FRAME space. */
168
+ declare function regionRect(r: Region, W: number, H: number): {
169
+ x: number;
170
+ y: number;
171
+ w: number;
172
+ h: number;
173
+ };
174
+ /**
175
+ * Structural validation for a region (used by buildScene + the gate so a bad
176
+ * pane fails before capture rather than rendering off-frame).
177
+ * Returns [] when valid.
178
+ */
179
+ declare function validateRegion(r: unknown): string[];
180
+ /**
181
+ * The usable content rect for a layer drawing inside `r`, in PANE-LOCAL px.
182
+ *
183
+ * This is `safeBox(W, H)` clipped to the pane and shifted into pane
184
+ * coordinates — NOT `safeBox(r.w*W, r.h*H)`, which re-applies the frame's
185
+ * percentage insets to the pane and silently invents room that phone chrome
186
+ * covers.
187
+ *
188
+ * Worked example, 1080x1920, bottom pane {y:0.42, h:0.58} (pane top 806.4,
189
+ * pane height 1113.6):
190
+ * naive safeBox(1080, 1113.6).bottom = 801.8 pane-local = 1608.2 frame-space
191
+ * paneSafeBox(...).bottom = 576.0 pane-local = 1382.4 frame-space
192
+ * The frame's real bottom-safe line is 0.72*1920 = 1382.4, so the naive value
193
+ * hands the layer ~226px of content area underneath TikTok's caption + action
194
+ * rail. The top pane fails inverted (naive top-safe 121 vs the real 288),
195
+ * putting a title under the search bar.
196
+ *
197
+ * A pane that misses the frame safe box entirely yields a zero-size box (w/h 0)
198
+ * anchored at the clamped edge, rather than a negative-size one.
199
+ */
200
+ declare function paneSafeBox(r: Region, W: number, H: number): SafeBox;
201
+
156
202
  /** A timeline endpoint: a number (ms? no — seconds), "end", or "end-N" (N s before end). */
157
203
  type TimeAnchor = number | 'end' | `end-${number}`;
158
204
  interface SpecLayer {
@@ -160,6 +206,19 @@ interface SpecLayer {
160
206
  k: string;
161
207
  /** Props passed to the layer's init(). */
162
208
  p?: unknown;
209
+ /**
210
+ * Optional sub-rect of the frame to draw this layer into (fractions of W/H).
211
+ * The layer is clipped + translated into the pane and sees a RenderCtx whose
212
+ * `W`/`H` are the PANE's size and whose `safeBox` is `paneSafeBox` (the frame
213
+ * safe box intersected with the pane) — so any existing layer composites into
214
+ * a split-screen pane unchanged. Omit (or pass the full frame) for today's
215
+ * behavior; a full-frame region is detected and short-circuited so the op
216
+ * stream stays byte-for-byte identical.
217
+ *
218
+ * The camera transform is FRAME-space and is applied before the region
219
+ * transform, so the camera pans a pane's CONTENTS, not the pane itself.
220
+ */
221
+ region?: Region;
163
222
  }
164
223
  /**
165
224
  * Optional per-segment audio. Lets a segment SCHEDULE sound at its own start
@@ -374,6 +433,355 @@ interface RecordSceneSpecOpts {
374
433
  */
375
434
  declare function recordSceneSpec(opts: RecordSceneSpecOpts): Promise<Blob>;
376
435
 
436
+ type VideoFit = 'cover' | 'contain';
437
+ type VideoClockMode = 'play' | 'seek';
438
+ interface VideoSourceProps {
439
+ /** A URL (loaded + awaited in init) or any ready CanvasImageSource. */
440
+ src: string | CanvasImageSource;
441
+ /** How the source fills the box. Default 'cover'. */
442
+ fit?: VideoFit;
443
+ /**
444
+ * Focal point of the source for `cover` cropping, in source fractions.
445
+ * Default {x: 0.5, y: 0.38} — faces sit above the vertical centre, and a
446
+ * centred crop of a portrait clip cuts the forehead off.
447
+ */
448
+ focus?: {
449
+ x: number;
450
+ y: number;
451
+ };
452
+ /** Absolute clip time (ms) at which this source starts playing. Default 0. */
453
+ startMs?: number;
454
+ /** In-point within the SOURCE (ms). Default 0. */
455
+ sourceStartMs?: number;
456
+ /** Loop [sourceStartMs, duration) when the segment outlasts the source. Default true. */
457
+ loop?: boolean;
458
+ /** Playback rate. Default 1. */
459
+ rate?: number;
460
+ /** Mute the element. Default true — reaction audio is discarded in v1. */
461
+ mute?: boolean;
462
+ /** Constant alpha. Default 1. */
463
+ opacity?: number;
464
+ /** 'play' (real-time capture, default) or 'seek' (offline; not yet supported). */
465
+ clockMode?: VideoClockMode;
466
+ /** Drift past which `play` mode issues a corrective seek, ms. Default 120. */
467
+ driftTolMs?: number;
468
+ /**
469
+ * Source duration in ms. Read from the element when it can be; required when
470
+ * `src` is a bare CanvasImageSource AND `loop` is on (nothing to read it from).
471
+ */
472
+ durationMs?: number;
473
+ }
474
+ /** Source-crop + destination rects for one drawImage call. */
475
+ interface FitBoxes {
476
+ sx: number;
477
+ sy: number;
478
+ sw: number;
479
+ sh: number;
480
+ dx: number;
481
+ dy: number;
482
+ dw: number;
483
+ dh: number;
484
+ }
485
+ /**
486
+ * Fit a source (iW×iH) into a box (bw×bh at the origin).
487
+ * - 'cover' : fills the box, crops the source around `focus` (clamped so the
488
+ * crop window never runs off the source).
489
+ * - 'contain' : whole source visible, letterboxed and centred in the box.
490
+ */
491
+ declare function fitBoxes(iW: number, iH: number, bw: number, bh: number, mode: VideoFit, focus: {
492
+ x: number;
493
+ y: number;
494
+ }): FitBoxes;
495
+ /**
496
+ * The source position (ms) to show at absolute clip time `tMs`.
497
+ * Before `startMs` the in-point is held. When `loop`, playback wraps within
498
+ * [sourceStartMs, durationMs); otherwise the last frame is held.
499
+ */
500
+ declare function sourceTimeMs(tMs: number, o: {
501
+ startMs: number;
502
+ sourceStartMs: number;
503
+ rate: number;
504
+ loop: boolean;
505
+ durationMs: number;
506
+ }): number;
507
+ /** Whether `play` mode should issue a corrective seek this frame. */
508
+ declare function needsSeek(currentMs: number, wantMs: number, tolMs: number): boolean;
509
+ /** Intrinsic size of any CanvasImageSource we might be handed. */
510
+ declare function sourceSize(src: unknown): {
511
+ w: number;
512
+ h: number;
513
+ };
514
+ declare const videoSourceFactory: LayerFactory<VideoSourceProps>;
515
+
516
+ type SeamStyle = 'line' | 'shadow';
517
+ interface PaneSeamProps {
518
+ /** Where the seam sits, as a fraction of the frame (H for 'h', W for 'v'). */
519
+ atFrac: number;
520
+ /** Seam axis. 'h' = a horizontal rule between stacked panes. Default 'h'. */
521
+ orientation?: 'h' | 'v';
522
+ /** 'line' = a hard rule; 'shadow' = a rule plus a soft falloff either side. */
523
+ style?: SeamStyle;
524
+ /** Rule colour. Default theme.ink. */
525
+ color?: string;
526
+ /** Rule thickness in px. Default 4. */
527
+ thicknessPx?: number;
528
+ /** Falloff depth either side for 'shadow', px. Default 28. */
529
+ shadowPx?: number;
530
+ /** Rule alpha. Default 0.9. */
531
+ opacity?: number;
532
+ }
533
+ declare const paneSeamFactory: LayerFactory<PaneSeamProps>;
534
+
535
+ interface ReactionSplitOpts {
536
+ /** The top pane: a reaction clip. */
537
+ reaction: VideoSourceProps;
538
+ /**
539
+ * The bottom pane: ANY layers from the registry. A live music scene
540
+ * (`notation` + `scroll-cursor`, `falling-notes` + `keyboard`) and a
541
+ * pre-recorded app screen capture (another `video-source`) are both just
542
+ * SpecLayers — the region machinery does not care which.
543
+ */
544
+ app: SpecLayer[];
545
+ /** The text hook, drawn over BOTH panes and pinned to the frame. */
546
+ hook: string;
547
+ /** Top-pane height as a fraction of the frame. Default 0.42. */
548
+ split?: number;
549
+ /** Clip length. Default 8. */
550
+ durationSec?: number;
551
+ /** Divider treatment between the panes. Default 'line'. */
552
+ seam?: SeamStyle | 'none';
553
+ /** Optional follow/CTA card, entering at `atSec`. */
554
+ endCard?: {
555
+ text?: string;
556
+ handle?: string;
557
+ atSec: number;
558
+ };
559
+ /** Frame size. Default [1080, 1920]. */
560
+ size?: [number, number];
561
+ /** Theme key. Default 'default'. */
562
+ theme?: string;
563
+ /** Capture fps. Default 30. */
564
+ fps?: number;
565
+ /** Hook vertical centre as a fraction of the frame. Default just below the
566
+ * frame's top-safe line, so it clears the platform's tabs/search row. */
567
+ hookCenterFrac?: number;
568
+ /** Hook font px. Default 84. */
569
+ hookFontPx?: number;
570
+ /** Hook colour. Default the theme's paper (hooks sit over footage). */
571
+ hookColor?: string;
572
+ }
573
+ /** Default hook centre: inside the safe area, high enough to read as a caption. */
574
+ declare const DEFAULT_HOOK_CENTER_FRAC: number;
575
+ /**
576
+ * The reaction-overlay short-form layout: a reaction clip above, the app doing
577
+ * one small thing below, a text hook over both.
578
+ *
579
+ * Throws on a structurally impossible split so the caller fails here rather
580
+ * than at buildScene.
581
+ */
582
+ declare function reactionSplitSpec(o: ReactionSplitOpts): SceneSpec;
583
+
584
+ /** The emotional register a clip reads as — the axis variants are drawn along. */
585
+ type ReactionEmotion = 'confused' | 'shocked' | 'impressed' | 'delighted' | 'deadpan' | 'skeptical';
586
+ declare const REACTION_EMOTIONS: readonly ReactionEmotion[];
587
+ interface ReactionClip {
588
+ /** Stable id, unique within the manifest. */
589
+ id: string;
590
+ /** File name / path, resolved against the manifest's base URL. */
591
+ file: string;
592
+ emotion: ReactionEmotion;
593
+ durationMs: number;
594
+ /** [x, y, w, h] in source fractions — where the face sits. Drives the crop. */
595
+ faceBox?: [number, number, number, number];
596
+ /** REQUIRED provenance: where the footage came from (e.g. "envato-elements"). */
597
+ source: string;
598
+ /** REQUIRED provenance: the licence/receipt id proving the right to use it. */
599
+ licenseId: string;
600
+ /** ISO date the licence was obtained. */
601
+ acquiredAt?: string;
602
+ notes?: string;
603
+ }
604
+ interface ReactionManifest {
605
+ clips: ReactionClip[];
606
+ }
607
+ /** Focus used when a clip declares no faceBox — faces sit above centre. */
608
+ declare const DEFAULT_FOCUS: {
609
+ x: number;
610
+ y: number;
611
+ };
612
+ /**
613
+ * Validate a parsed manifest. Returns [] when valid; every problem is reported,
614
+ * not just the first, so one audit run fixes the whole file.
615
+ */
616
+ declare function validateReactionManifest(json: unknown): string[];
617
+ /** Throwing form, for a build script. */
618
+ declare function assertReactionManifest(json: unknown): ReactionManifest;
619
+ /** The cover-crop focal point for a clip: its face centre, or the default. */
620
+ declare function clipFocus(clip: Pick<ReactionClip, 'faceBox'>): {
621
+ x: number;
622
+ y: number;
623
+ };
624
+ interface ReactionPropsOpts {
625
+ /** Prefix joined to `clip.file` (e.g. "/assets/reactions/"). Default "". */
626
+ baseUrl?: string;
627
+ /** Absolute clip time the reaction starts at. Default 0. */
628
+ startMs?: number;
629
+ /** In-point within the source. Default 0. */
630
+ sourceStartMs?: number;
631
+ loop?: boolean;
632
+ rate?: number;
633
+ }
634
+ /** Turn a manifest entry into `video-source` props, focus already aimed. */
635
+ declare function reactionProps(clip: ReactionClip, o?: ReactionPropsOpts): VideoSourceProps;
636
+ /** Clips matching an emotion (all of them when `emotion` is omitted). */
637
+ declare function pickClips(m: ReactionManifest, emotion?: ReactionEmotion): ReactionClip[];
638
+
639
+ interface CheckFrame {
640
+ w: number;
641
+ h: number;
642
+ data: Uint8Array | Uint8ClampedArray | number[];
643
+ }
644
+ interface SampledFrames {
645
+ show: {
646
+ tSec: number;
647
+ f: CheckFrame;
648
+ }[];
649
+ /** Frame size the samples were decoded at (may differ from the source size). */
650
+ frameW: number;
651
+ frameH: number;
652
+ }
653
+ interface CheckResult {
654
+ name: string;
655
+ pass: boolean;
656
+ detail: string;
657
+ }
658
+ /** Luminance floor below which a pixel counts as ink on a paper background. */
659
+ declare const PAPER_LUM_FLOOR = 200;
660
+ /**
661
+ * Fraction of a row's [x0,x1) span that reads as content rather than paper:
662
+ * clearly darker than paper, or clearly chromatic. Mirrors the heuristic the
663
+ * existing promo checks use so thresholds carry over.
664
+ */
665
+ declare function inkFractionInRow(f: CheckFrame, y: number, x0: number, x1: number): number;
666
+ interface PaneSafetyOpts {
667
+ /** The content pane to enforce (usually the app pane). */
668
+ region: Region;
669
+ /** Source-space frame size the region fractions refer to. Default 1080x1920. */
670
+ srcW?: number;
671
+ srcH?: number;
672
+ /** Ink fraction tolerated in the unsafe strip. Default 0.08. */
673
+ maxInkFrac?: number;
674
+ }
675
+ /**
676
+ * The regression guard for the paneSafeBox trap: a layer handed a pane must not
677
+ * draw content BELOW the frame's bottom-safe line, where the platform's caption
678
+ * and action rail sit. Computing a pane's safe box as `safeBox(paneW, paneH)`
679
+ * instead of intersecting with the frame silently grants ~226px of that strip,
680
+ * and the resulting clip only looks wrong once it is posted.
681
+ *
682
+ * Only meaningful for panes whose content is meant to be READ (notation, text,
683
+ * a keyboard). A full-bleed footage pane fills its whole rect by design and
684
+ * should not be enforced.
685
+ */
686
+ declare function checkPaneSafety(frames: SampledFrames, o: PaneSafetyOpts): CheckResult;
687
+ interface SeamPresentOpts {
688
+ /** Where the seam should be, as a fraction of the frame height. */
689
+ splitFrac: number;
690
+ srcH?: number;
691
+ /** Rows either side to search for the rule. Default 6 (source px). */
692
+ tolPx?: number;
693
+ /** Minimum span of the row that must read as seam ink. Default 0.9. */
694
+ minSpan?: number;
695
+ }
696
+ /**
697
+ * A composition regression guard: if the split silently collapsed (one pane
698
+ * covering the frame, a preset emitting no seam), the divider row disappears.
699
+ * Cheap to check and it fails loudly on the whole-layout failure mode that the
700
+ * per-layer checks cannot see.
701
+ */
702
+ declare function checkSeamPresent(frames: SampledFrames, o: SeamPresentOpts): CheckResult;
703
+ interface FaceInPaneOpts {
704
+ /** [x, y, w, h] fractions of the SOURCE. */
705
+ faceBox: [number, number, number, number];
706
+ /** Intrinsic source size. */
707
+ srcW: number;
708
+ srcH: number;
709
+ /** The pane the source is drawn into. */
710
+ region: Region;
711
+ frameW?: number;
712
+ frameH?: number;
713
+ fit?: VideoFit;
714
+ focus: {
715
+ x: number;
716
+ y: number;
717
+ };
718
+ }
719
+ interface FaceInPaneResult {
720
+ ok: boolean;
721
+ /** How much of the declared face box survives the crop, 0..1. */
722
+ visibleFrac: number;
723
+ /** The face's rect in FRAME pixels (empty when fully cropped out). */
724
+ frameRect: {
725
+ x: number;
726
+ y: number;
727
+ w: number;
728
+ h: number;
729
+ };
730
+ reason?: string;
731
+ }
732
+ /**
733
+ * Whether the face a clip declares actually lands inside its pane after the
734
+ * cover-crop. This is pure geometry, not pixel face detection — the manifest
735
+ * already states where the face is, so the honest check is "did our own crop
736
+ * math keep it", which is exact rather than heuristic.
737
+ */
738
+ declare function faceLandsInPane(o: FaceInPaneOpts): FaceInPaneResult;
739
+
740
+ /** One ending treatment. `null` means "no end card on this variant". */
741
+ type VariantEnding = NonNullable<ReactionSplitOpts['endCard']> | null;
742
+ interface ReactionVariantsOpts {
743
+ /** Text hooks to rotate through. At least one. */
744
+ hooks: string[];
745
+ /** Reaction clips to rotate through. At least one. */
746
+ clips: ReactionClip[];
747
+ /** Ending treatments. Default `[null]` (no end card). */
748
+ endings?: VariantEnding[];
749
+ /** Everything the layout needs that is NOT a variant axis (app layers, split…). */
750
+ base: Omit<ReactionSplitOpts, 'reaction' | 'hook' | 'endCard'>;
751
+ /** How many variants to emit. Default: the full product (every combination). */
752
+ n?: number;
753
+ /** Prefix joined to each clip's file. */
754
+ baseUrl?: string;
755
+ /** Deterministic starting offset — change it to get a different ordering. */
756
+ seed?: number;
757
+ }
758
+ interface ReactionVariant {
759
+ /** Stable id derived from the axis picks; the same picks always yield it. */
760
+ id: string;
761
+ hook: string;
762
+ clipId: string;
763
+ endingIndex: number;
764
+ spec: SceneSpec;
765
+ }
766
+ /**
767
+ * A step size co-prime to `total`, near the golden-ratio fraction of it so the
768
+ * walk spreads rather than marching. Co-primality is what guarantees the walk
769
+ * visits every index exactly once before repeating.
770
+ */
771
+ declare function coprimeStride(total: number): number;
772
+ /**
773
+ * `n` index tuples over axes of the given `sizes`, distinct until the product is
774
+ * exhausted. Exported so the decorrelation is testable without building specs.
775
+ */
776
+ declare function variantIndices(n: number, sizes: number[], seed?: number): number[][];
777
+ /** Lowercase, hyphenated, ascii-ish slug for a variant id. */
778
+ declare function slugify(s: string, max?: number): string;
779
+ /**
780
+ * Generate `n` distinct reaction-split clips across the hook / clip / ending
781
+ * axes. Throws on an empty axis rather than silently emitting nothing.
782
+ */
783
+ declare function reactionVariants(o: ReactionVariantsOpts): ReactionVariant[];
784
+
377
785
  /** Register (or replace) a layer factory under its key. */
378
786
  declare function registerLayer(factory: LayerFactory<any>): void;
379
787
  /** Look up a factory by key, or undefined if not registered. */
@@ -1802,4 +2210,4 @@ interface HandIndicatorProps {
1802
2210
  }
1803
2211
  declare const handIndicatorFactory: LayerFactory<HandIndicatorProps>;
1804
2212
 
1805
- export { type Affine, AudioClock, type AudioEvent, type BackgroundProps, type BeatGridOpts, type BeatPulseProps, type BeatTick, type BrandingProps, type BufferFactory, type BuildSceneOpts, type BuiltScene, type CameraState, type CaptionCue, type CaptionProps, type CaptionScript, type CaptionStyle, type ChordRibbonProps, type ChordSpan, type CircleOfFifthsProps, type CirclePoint, type ClickTrackOpts, type ColorBy, type CompositeRhythmProps, type ContourPlot, type ContourPoint, type CountInOpts, type CountdownProps, type CountingTrackProps, type CtaProps, DEFAULT_FUNCTION_COLORS, type DegreeLabel, type DegreeLabelsProps, type DroneOpts, type DuckWindow, type Easing, type EndCardProps, type ExtendedDemoOpts, FIFTHS_MAJOR, FIFTHS_MINOR, type FallingKeyboardDemoOpts, type FallingNotesProps, type FretboardProps, type FunctionColors, type FunctionalHarmonyProps, type GateError, type GateInput, type HandColors, type HandIndicatorProps, type HarmonicFunction, type HarmonyMode, type HighlightRegion, type HookProps, type ImageRevealMode, type ImageRevealProps, type IntervalArcsProps, type KaraokeCaptionProps, type KaraokeWord, type KeyRect, type KeyboardLayout, type KeyboardLayoutOpts, type KeyboardProps, type KineticMode, type KineticTextProps, type LabelMode, LayerFactory, type McqCardProps, type NotationEngraving, NotationLayout, type NotationProps, type OutputProbe, PIANO_HIGH, PIANO_LOW, type ParticleBurstProps, type PitchContourProps, type Placement, type PortraitProps, type ProgressRingProps, type PromoCardsDemoOpts, type PulseStyle, type Quiz, type QuizOption, type QuizPhase, type RadialSpectrumProps, type RayEndpoints, type RecordSceneSpecOpts, type Rect, RenderCtx, type ResolvedSegment, type RevealEasing, type RevealProps, SCALE_INTERVALS, type SafeGuidesProps, type ScaleHighlightProps, type SceneSpec, type ScheduleTarget, Score, ScoreFromMusicXMLOpts, ScoreNote, type ScrollCursorProps, type Section, type SectionMinimapProps, type SegmentAudio, type SegmentAudioCtx, type SegmentTransition, type SpecLayer, type StaffKeyboardRayProps, type StatCounterProps, TempoMap, type TensionGraphProps, type TensionPoint, type TextureProps, type TimeAnchor, type TimelineSegment, activeChord, activeCue, activeSection, animatedSlot, applySchedule, applyToContext, assertGate, ballArc, ballX, beatGrid, beatPhase, beatPulseFactory, blackKeys, bpmOf, brandingFactory, buildScene, cameraForFollow, cameraTransform, chordRibbonFactory, circleOfFifthsDemoSpec, circleOfFifthsFactory, clamp, clickTrackSchedule, compositeRhythmFactory, contourMinimapDemoSpec, contourPoints, contourPolyline, countInLeadSec, countInSchedule, countdownFactory, countdownRemaining, countdownSeconds, countingDegreeDemoSpec, countingTrackFactory, ctaFactory, cueOpacity, degreeLabel, degreeLabelsFactory, dotAt, drawCaption, drawHighlight, droneSchedule, duckGainAt, easeIn, easeInOut, easeOut, endCardFactory, fallingKeyboardDemoScore, fallingKeyboardDemoSpec, fallingNotesFactory, followSrcBox, fracSlotPoint, frameRect, fretboardFactory, functionColor, functionalHarmonyFactory, getKeyboardLayout, getLayerFactory, getNotationEngraving, handIndicatorFactory, harmonyDemoSpec, highlightIntensity, hookFactory, identityCamera, imageRevealFactory, inRange, intervalArcsFactory, invLerp, isBlackKey, karaokeCaptionFactory, kenBurns, keyCenterX, keyColumnWidth, keyRect, keySlot, keyboardFactory, keyboardLayout, kineticTextFactory, lerp, lerpCamera, linear, mapBoxThroughLayout, mcqCardFactory, mcqDemoSpec, measureSpans, timeToX as minimapTimeToX, msPerBeat, notationFactory, noteColor, noteSetXRange, parseKey, parseTimeSig, particleBurstFactory, pcToSlot, pitchAt, pitchContourFactory, pitchRange, portraitFactory, progress01, progressRingFactory, projectPoint, promoCardsDemoSpec, pulseAt, quizPhase, radialSpectrumFactory, rayEndpoints, rayPointAt, recordSceneSpec, registerLayer, registeredKeys, resolveAnchor, resolveKeyboardLayout, resolveTimeline, revealFactory, revealProgress, runGate, safeGuidesFactory, scaleHighlightFactory, scorePitchSpan, scrollCursorFactory, sectionMinimapFactory, setFollowLayoutProvider, setKeyboardLayout, setNotationEngraving, slotAngle, slotPc, slotPoint, staffAnchor, staffKeyboardRayFactory, staffRayDemoSpec, statCounterFactory, tensionGraphFactory, textureFactory, transitionProgress, validateChordTrack, validateQuiz, validateSections, visualTimelineMs, whiteKeys, worldToViewport };
2213
+ export { type Affine, AudioClock, type AudioEvent, type BackgroundProps, type BeatGridOpts, type BeatPulseProps, type BeatTick, type BrandingProps, type BufferFactory, type BuildSceneOpts, type BuiltScene, type CameraState, type CaptionCue, type CaptionProps, type CaptionScript, type CaptionStyle, type CheckFrame, type CheckResult, type ChordRibbonProps, type ChordSpan, type CircleOfFifthsProps, type CirclePoint, type ClickTrackOpts, type ColorBy, type CompositeRhythmProps, type ContourPlot, type ContourPoint, type CountInOpts, type CountdownProps, type CountingTrackProps, type CtaProps, DEFAULT_FOCUS, DEFAULT_FUNCTION_COLORS, DEFAULT_HOOK_CENTER_FRAC, type DegreeLabel, type DegreeLabelsProps, type DroneOpts, type DuckWindow, type Easing, type EndCardProps, type ExtendedDemoOpts, FIFTHS_MAJOR, FIFTHS_MINOR, FULL_REGION, type FaceInPaneOpts, type FaceInPaneResult, type FallingKeyboardDemoOpts, type FallingNotesProps, type FitBoxes, type FretboardProps, type FunctionColors, type FunctionalHarmonyProps, type GateError, type GateInput, type HandColors, type HandIndicatorProps, type HarmonicFunction, type HarmonyMode, type HighlightRegion, type HookProps, type ImageRevealMode, type ImageRevealProps, type IntervalArcsProps, type KaraokeCaptionProps, type KaraokeWord, type KeyRect, type KeyboardLayout, type KeyboardLayoutOpts, type KeyboardProps, type KineticMode, type KineticTextProps, type LabelMode, LayerFactory, type McqCardProps, type NotationEngraving, NotationLayout, type NotationProps, type OutputProbe, PAPER_LUM_FLOOR, PIANO_HIGH, PIANO_LOW, type PaneSafetyOpts, type PaneSeamProps, type ParticleBurstProps, type PitchContourProps, type Placement, type PortraitProps, type ProgressRingProps, type PromoCardsDemoOpts, type PulseStyle, type Quiz, type QuizOption, type QuizPhase, REACTION_EMOTIONS, type RadialSpectrumProps, type RayEndpoints, type ReactionClip, type ReactionEmotion, type ReactionManifest, type ReactionPropsOpts, type ReactionSplitOpts, type ReactionVariant, type ReactionVariantsOpts, type RecordSceneSpecOpts, type Rect, type Region, RenderCtx, type ResolvedSegment, type RevealEasing, type RevealProps, SCALE_INTERVALS, type SafeGuidesProps, type SampledFrames, type ScaleHighlightProps, type SceneSpec, type ScheduleTarget, Score, ScoreFromMusicXMLOpts, ScoreNote, type ScrollCursorProps, type SeamPresentOpts, type SeamStyle, type Section, type SectionMinimapProps, type SegmentAudio, type SegmentAudioCtx, type SegmentTransition, type SpecLayer, type StaffKeyboardRayProps, type StatCounterProps, TempoMap, type TensionGraphProps, type TensionPoint, type TextureProps, type TimeAnchor, type TimelineSegment, type VariantEnding, type VideoClockMode, type VideoFit, type VideoSourceProps, activeChord, activeCue, activeSection, animatedSlot, applySchedule, applyToContext, assertGate, assertReactionManifest, ballArc, ballX, beatGrid, beatPhase, beatPulseFactory, blackKeys, bpmOf, brandingFactory, buildScene, cameraForFollow, cameraTransform, checkPaneSafety, checkSeamPresent, chordRibbonFactory, circleOfFifthsDemoSpec, circleOfFifthsFactory, clamp, clickTrackSchedule, clipFocus, compositeRhythmFactory, contourMinimapDemoSpec, contourPoints, contourPolyline, coprimeStride, countInLeadSec, countInSchedule, countdownFactory, countdownRemaining, countdownSeconds, countingDegreeDemoSpec, countingTrackFactory, ctaFactory, cueOpacity, degreeLabel, degreeLabelsFactory, dotAt, drawCaption, drawHighlight, droneSchedule, duckGainAt, easeIn, easeInOut, easeOut, endCardFactory, faceLandsInPane, fallingKeyboardDemoScore, fallingKeyboardDemoSpec, fallingNotesFactory, fitBoxes, followSrcBox, fracSlotPoint, frameRect, fretboardFactory, functionColor, functionalHarmonyFactory, getKeyboardLayout, getLayerFactory, getNotationEngraving, handIndicatorFactory, harmonyDemoSpec, highlightIntensity, hookFactory, identityCamera, imageRevealFactory, inRange, inkFractionInRow, intervalArcsFactory, invLerp, isBlackKey, isFullRegion, karaokeCaptionFactory, kenBurns, keyCenterX, keyColumnWidth, keyRect, keySlot, keyboardFactory, keyboardLayout, kineticTextFactory, lerp, lerpCamera, linear, mapBoxThroughLayout, mcqCardFactory, mcqDemoSpec, measureSpans, timeToX as minimapTimeToX, msPerBeat, needsSeek, notationFactory, noteColor, noteSetXRange, paneSafeBox, paneSeamFactory, parseKey, parseTimeSig, particleBurstFactory, pcToSlot, pickClips, pitchAt, pitchContourFactory, pitchRange, portraitFactory, progress01, progressRingFactory, projectPoint, promoCardsDemoSpec, pulseAt, quizPhase, radialSpectrumFactory, rayEndpoints, rayPointAt, reactionProps, reactionSplitSpec, reactionVariants, recordSceneSpec, regionRect, registerLayer, registeredKeys, resolveAnchor, resolveKeyboardLayout, resolveTimeline, revealFactory, revealProgress, runGate, safeGuidesFactory, scaleHighlightFactory, scorePitchSpan, scrollCursorFactory, sectionMinimapFactory, setFollowLayoutProvider, setKeyboardLayout, setNotationEngraving, slotAngle, slotPc, slotPoint, slugify, sourceSize, sourceTimeMs, staffAnchor, staffKeyboardRayFactory, staffRayDemoSpec, statCounterFactory, tensionGraphFactory, textureFactory, transitionProgress, validateChordTrack, validateQuiz, validateReactionManifest, validateRegion, validateSections, variantIndices, videoSourceFactory, visualTimelineMs, whiteKeys, worldToViewport };