@real-music-packages/web-core 0.45.2 → 0.47.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/README.md +10 -1
- package/dist/audio.js +7 -7
- package/dist/chunk-JCDNEJBT.js +176 -0
- package/dist/chunk-JCDNEJBT.js.map +1 -0
- package/dist/notationBeams.d.ts +26 -0
- package/dist/notationBeams.js +133 -0
- package/dist/notationBeams.js.map +1 -0
- package/dist/notationPlayerVerovio.d.ts +26 -57
- package/dist/notationPlayerVerovio.js +27 -136
- package/dist/notationPlayerVerovio.js.map +1 -1
- package/dist/notationXml.d.ts +175 -0
- package/dist/notationXml.js +19 -0
- package/dist/notationXml.js.map +1 -0
- package/dist/scene/index.d.ts +410 -2
- package/dist/scene/index.js +725 -21
- package/dist/scene/index.js.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
declare function stampNoteIds(xml: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Insert `<print new-system="yes"/>` as the FIRST child of the `<measure>`
|
|
4
|
+
* at each 0-based position in `breakBeforeBarIndexes`, in EVERY `<part>`
|
|
5
|
+
* (a score's parts share one measure timeline, so a break must be encoded
|
|
6
|
+
* once per part for Verovio to line the systems up across staves). A
|
|
7
|
+
* position that is ≤ 0 or ≥ that part's own measure count is silently
|
|
8
|
+
* ignored FOR THAT PART (0 is a no-op — a part already starts a new system
|
|
9
|
+
* at its own first measure). Idempotent: a measure that already carries a
|
|
10
|
+
* `<print>` element (from a prior call, or from the source data) gets
|
|
11
|
+
* `new-system="yes"` SET on that existing element rather than gaining a
|
|
12
|
+
* second one — calling this twice with the same positions serializes
|
|
13
|
+
* identically both times. Malformed input (fails to parse) is returned
|
|
14
|
+
* unchanged, same defensive style as `stampNoteIds` above. Only ever ADDS
|
|
15
|
+
* `<print>` elements — never touches a `<note>` — so `stampNoteIds`'s
|
|
16
|
+
* position-based id scheme is unaffected by a prior or subsequent call to
|
|
17
|
+
* this function (see this file's own tests for the pinned invariant).
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* How many `<measure>` elements the FIRST `<part>` has — the `totalBars`
|
|
21
|
+
* that `barsPerLineBreaks`/`sectionAwareBreaks` plan against.
|
|
22
|
+
*
|
|
23
|
+
* The first part specifically, because that is the coordinate system
|
|
24
|
+
* `injectSystemBreaks` positions live in: a score's parts share one measure
|
|
25
|
+
* timeline, so the first part's ordinals index every part. And ORDINALS, not
|
|
26
|
+
* `<measure number>` attributes — scores skip and repeat bar numbers, so a
|
|
27
|
+
* count is the only safe answer. Malformed input, or a document with no
|
|
28
|
+
* part, returns 0 rather than throwing.
|
|
29
|
+
*/
|
|
30
|
+
declare function measureCount(xml: string): number;
|
|
31
|
+
declare function injectSystemBreaks(xml: string, breakBeforeBarIndexes: readonly number[]): string;
|
|
32
|
+
/**
|
|
33
|
+
* Evenly-spread system-break positions for `totalMeasures` measures across
|
|
34
|
+
* `systems` systems: `[per, 2·per, …]` (each strictly `< totalMeasures`),
|
|
35
|
+
* with `per = Math.ceil(totalMeasures / systems)` — `Math.ceil` naturally
|
|
36
|
+
* front-loads any remainder into the EARLIER systems (e.g. 7 measures / 2
|
|
37
|
+
* systems -> per=4 -> systems of 4+3, never 3+4), which is what keeps a
|
|
38
|
+
* later system from being the short/orphaned one. `systems <= 1` (nothing to
|
|
39
|
+
* break between) returns `[]`.
|
|
40
|
+
*/
|
|
41
|
+
declare function balancedSystemBreaks(totalMeasures: number, systems: number): number[];
|
|
42
|
+
/**
|
|
43
|
+
* Balanced system-break positions for a target BARS-PER-LINE layout — the
|
|
44
|
+
* caller-facing sibling of `balancedSystemBreaks`, which takes a system
|
|
45
|
+
* COUNT. Rather than stepping `every` bars at a time from bar 0 (which
|
|
46
|
+
* strands a short remainder — a 5-bar excerpt at `every: 4` renders 4+1, a
|
|
47
|
+
* widow of our own making), this decides how many LINES the excerpt needs
|
|
48
|
+
* (`ceil(totalBars / every)`) and hands that count to
|
|
49
|
+
* `balancedSystemBreaks`. `(5, 4)` is `[3]` (3+2) instead of `[4]` (4+1);
|
|
50
|
+
* `(9, 4)` is `[3, 6]` (3+3+3) instead of `[4, 8]` (4+4+1).
|
|
51
|
+
*
|
|
52
|
+
* WIDOW BACK-OFF: a small `every` against a small `totalBars` can make the
|
|
53
|
+
* straight `ceil(totalBars / every)` line count land on a trailing line of
|
|
54
|
+
* exactly 1 bar — the same widow this function exists to remove, reappearing
|
|
55
|
+
* at a different total/every combination (`lines = 3` on 7 bars: `per = 3`
|
|
56
|
+
* fills two 3-bar lines and leaves 1 bar for the third). The line count is
|
|
57
|
+
* therefore backed down (never below 1) until the trailing line holds at
|
|
58
|
+
* least 2 bars — 7 bars lands on 2 lines (4+3) instead of 3 (3+3+1), which
|
|
59
|
+
* is the same "fewer, fuller lines" direction `every` already asks for.
|
|
60
|
+
* This never changes the result for any total/every whose straight `ceil`
|
|
61
|
+
* count already avoids a 1-bar trailing line.
|
|
62
|
+
*
|
|
63
|
+
* `every <= 0` (the "auto — no forced breaks" sentinel callers resolve to)
|
|
64
|
+
* or a non-positive/non-finite `totalBars` returns `[]`. Never throws.
|
|
65
|
+
*
|
|
66
|
+
* Ported from stave-web-sightread (`src/lib/bach/xmlTransforms.ts`), whose
|
|
67
|
+
* copy this replaces — see the CONTRACT DUPLICATION NOTICE above. Reached by
|
|
68
|
+
* consumers through `VerovioLayoutOptions.barsPerLine` rather than called
|
|
69
|
+
* directly, so the player owns both the plan and its interaction with the
|
|
70
|
+
* widow pass and the readability floor.
|
|
71
|
+
*/
|
|
72
|
+
declare function barsPerLineBreaks(totalBars: number, every: number): number[];
|
|
73
|
+
/**
|
|
74
|
+
* Like `barsPerLineBreaks`, but each SECTION's span is balanced on its own
|
|
75
|
+
* instead of one balance running across the whole excerpt — so a line never
|
|
76
|
+
* ends part-way into a neighbouring section's opening bars, and a section's
|
|
77
|
+
* own bars are never split into a widowed last line either.
|
|
78
|
+
*
|
|
79
|
+
* `sectionStarts` are 0-BASED POSITIONS into the excerpt (the same
|
|
80
|
+
* coordinate `injectSystemBreaks` consumes), NOT MusicXML `<measure
|
|
81
|
+
* number>` attributes — scores skip bar numbers, so a caller holding
|
|
82
|
+
* bar-numbered section labels must convert first. `0` (the excerpt's own
|
|
83
|
+
* start) is never a break and is ignored if present.
|
|
84
|
+
*
|
|
85
|
+
* Every section start > 0 is a HARD break in its own right — a new section
|
|
86
|
+
* always begins its own line, not subject to balancing — unioned with
|
|
87
|
+
* `barsPerLineBreaks`' balanced positions computed WITHIN each section's
|
|
88
|
+
* span (its start up to the next section's start, or `totalBars` for the
|
|
89
|
+
* last) and offset back into excerpt-absolute positions.
|
|
90
|
+
*
|
|
91
|
+
* `every <= 0` suppresses the balanced component, matching
|
|
92
|
+
* `barsPerLineBreaks`, but section-start breaks still apply — that is the
|
|
93
|
+
* "sections only, otherwise let the engraver decide" mode. Out-of-range and
|
|
94
|
+
* non-integer starts are ignored. The result is sorted, de-duplicated, and
|
|
95
|
+
* every entry is a valid `injectSystemBreaks` position (integer, `> 0`,
|
|
96
|
+
* `< totalBars`). Never throws.
|
|
97
|
+
*/
|
|
98
|
+
declare function sectionAwareBreaks(totalBars: number, sectionStarts: readonly number[], every: number): number[];
|
|
99
|
+
/** One `<note>`'s MODEL identity — the ground truth `EngravedNote`
|
|
100
|
+
* (notationPlayerSvg.ts) needs that Verovio's rendered SVG cannot supply on
|
|
101
|
+
* its own (a rendered `g.note`/`g.rest` carries geometry, not pitch/tie/
|
|
102
|
+
* duration semantics). Keyed by the note's stamped `id` in
|
|
103
|
+
* `notePositions()`'s return of `verovioEngravedNotes`
|
|
104
|
+
* (notationPlayerVerovio.ts). */
|
|
105
|
+
interface NoteModel {
|
|
106
|
+
/** `12*(octave+1) + stepSemitone + alter` — the standard MusicXML→MIDI
|
|
107
|
+
* conversion (the same formula stave-web-sightread's own
|
|
108
|
+
* `practice/probeInputs.ts:pitchMidi` uses — a universal formula, not app
|
|
109
|
+
* logic, so this is not an owned-layer violation to restate here). `null`
|
|
110
|
+
* for a rest or an `<unpitched>` note (no `<pitch>` child) — mirrors
|
|
111
|
+
* `EngravedNote.midi`'s own "null covers both" contract. */
|
|
112
|
+
midi: number | null;
|
|
113
|
+
/** Has a `<rest/>` child. */
|
|
114
|
+
isRest: boolean;
|
|
115
|
+
/** True for the STOP half of a tie — a direct `<tie type="stop">` child OR
|
|
116
|
+
* `<notations><tied type="stop">` (exporters vary on which they emit;
|
|
117
|
+
* either counts) — matches `EngravedNote.tieContinuation`'s "continuation
|
|
118
|
+
* note of a tie, not the struck start" contract. */
|
|
119
|
+
tieContinuation: boolean;
|
|
120
|
+
/** 0-based, matching `EngravedNote.staffIndex`'s "0 = top staff of the
|
|
121
|
+
* system" contract: every `<part>` is walked in document order, and
|
|
122
|
+
* every DISTINCT staff within it (by `<attributes><staves>` when
|
|
123
|
+
* present, else the highest `<staff>` number any of its notes uses, else
|
|
124
|
+
* 1) is assigned the next index — so a single-part 2-staff piano score
|
|
125
|
+
* numbers 0/1 by `<staff>`, and a 2-part 1-staff-per-part reduction (this
|
|
126
|
+
* app's own chord+bass shape) numbers 0/1 by PART, with neither case
|
|
127
|
+
* needing different code. */
|
|
128
|
+
staffIndex: number;
|
|
129
|
+
/** Whole-note fraction (0.25 = quarter) — `duration / divisions / 4`,
|
|
130
|
+
* divisions tracked per-part from the LAST `<attributes><divisions>`
|
|
131
|
+
* seen at or before this note (MusicXML: divisions persist until
|
|
132
|
+
* overridden, default 1). 0 for a grace note (no `<duration>` child —
|
|
133
|
+
* the true, spec-correct signal; never guessed from `<type>`). */
|
|
134
|
+
durationReal: number;
|
|
135
|
+
/** 0-based position of this note's `<measure>` among its OWN `<part>`'s
|
|
136
|
+
* measure children, in document order. Informational only — the live
|
|
137
|
+
* join (`verovioOnsetColumns`/`verovioEngravedNotes`, both in
|
|
138
|
+
* notationPlayerVerovio.ts) resolves the note's RENDERED measure index
|
|
139
|
+
* from the live SVG DOM independently (Verovio's own render order, which
|
|
140
|
+
* is what geometry/hit-testing must agree with), never from this field. */
|
|
141
|
+
measureIndex: number;
|
|
142
|
+
/** `print-object="no"` on the source `<note>` (stave's `hideDoubledNotes`
|
|
143
|
+
* sets this on editorially-doubled notes/rests before handing MusicXML to
|
|
144
|
+
* this player). Verovio's importer HONORS this for `<note>` elements
|
|
145
|
+
* carrying a `<pitch>` (renders `visibility="hidden"` on its own,
|
|
146
|
+
* empirically confirmed against a real 6.2.0 render) but does NOT honor
|
|
147
|
+
* it for `<rest>` notes (the `<g class="rest">` renders fully visible
|
|
148
|
+
* regardless — same empirical check). `createVerovioNotationPlayer`
|
|
149
|
+
* reads this field to force `visibility="hidden"` after every render for
|
|
150
|
+
* ANY id where it's true — a no-op re-application on notes Verovio
|
|
151
|
+
* already hid, and the actual fix on the rests it doesn't (see that
|
|
152
|
+
* module's `applyPrintObjectHiding`). */
|
|
153
|
+
hidden: boolean;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Pure(ish) — MusicXML-in, `id → NoteModel`-out. Walks every `<part>` in
|
|
157
|
+
* document order, then every `<measure>` in document order, then every
|
|
158
|
+
* DIRECT child in document order — `<attributes>` updates the part's own
|
|
159
|
+
* `divisions` cursor; every other non-`<note>` child (`<backup>`,
|
|
160
|
+
* `<forward>`, `<direction>`, …) is a structural/timeline element this
|
|
161
|
+
* function has NO use for (it reads each note's OWN `<duration>` directly,
|
|
162
|
+
* never a cursor POSITION — see `durationReal`'s doc — so unlike
|
|
163
|
+
* `walkMeasureNotes`-style position walks, `<backup>`/`<forward>` need no
|
|
164
|
+
* special handling here beyond being correctly skipped, which plain
|
|
165
|
+
* tag-name filtering already does) — and every `<note>` becomes one model
|
|
166
|
+
* entry, keyed by its `id` attribute (a note with NO `id` — i.e. input that
|
|
167
|
+
* was never run through `stampNoteIds` — is silently skipped: it has no key
|
|
168
|
+
* to join the render against, so there is nothing useful to record).
|
|
169
|
+
*
|
|
170
|
+
* Never throws: malformed input (fails to parse, or no `<score-partwise>`
|
|
171
|
+
* root) returns an empty Map.
|
|
172
|
+
*/
|
|
173
|
+
declare function noteModelFromXml(stampedXml: string): Map<string, NoteModel>;
|
|
174
|
+
|
|
175
|
+
export { type NoteModel, balancedSystemBreaks, barsPerLineBreaks, injectSystemBreaks, measureCount, noteModelFromXml, sectionAwareBreaks, stampNoteIds };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
balancedSystemBreaks,
|
|
3
|
+
barsPerLineBreaks,
|
|
4
|
+
injectSystemBreaks,
|
|
5
|
+
measureCount,
|
|
6
|
+
noteModelFromXml,
|
|
7
|
+
sectionAwareBreaks,
|
|
8
|
+
stampNoteIds
|
|
9
|
+
} from "./chunk-JCDNEJBT.js";
|
|
10
|
+
export {
|
|
11
|
+
balancedSystemBreaks,
|
|
12
|
+
barsPerLineBreaks,
|
|
13
|
+
injectSystemBreaks,
|
|
14
|
+
measureCount,
|
|
15
|
+
noteModelFromXml,
|
|
16
|
+
sectionAwareBreaks,
|
|
17
|
+
stampNoteIds
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=notationXml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/scene/index.d.ts
CHANGED
|
@@ -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
|
|
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 };
|