@real-music-packages/web-core 0.22.0 → 0.23.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 CHANGED
@@ -78,10 +78,16 @@ npm install @real-music-packages/web-core
78
78
  ## Dev
79
79
  ```
80
80
  npm install
81
- npm test # vitest
82
- npm run build # tsup → dist/ (ESM + .d.ts)
81
+ npm test # vitest
82
+ npm run build # tsup → dist/ (ESM + .d.ts)
83
+ npm run build:watch # tsup --watch → rebuild dist/ on every edit (fast dev loop)
83
84
  ```
84
85
 
86
+ **Iterating against a live app without a publish/re-pin?** See
87
+ [DEVELOPMENT.md](./DEVELOPMENT.md) — `build:watch` + `tools/dev-link.sh <app>`
88
+ links the local web-core into an app so its vite dev server reflects your edits
89
+ directly; `tools/dev-unlink.sh <app>` restores the published pin.
90
+
85
91
  ## Publishing — auto-publishes from GitHub (no local `npm publish`)
86
92
 
87
93
  **To release: bump `version` in `package.json` and push to `main`.** That's it.
@@ -0,0 +1,24 @@
1
+ // src/intervals.ts
2
+ var INTERVALS = [
3
+ { semitones: 1, label: "m2", mnemonic: "Jaws theme" },
4
+ { semitones: 2, label: "M2", mnemonic: "Happy Birthday opening" },
5
+ { semitones: 3, label: "m3", mnemonic: "Brahms' Lullaby" },
6
+ { semitones: 4, label: "M3", mnemonic: "When the Saints" },
7
+ { semitones: 5, label: "P4", mnemonic: "Here Comes the Bride" },
8
+ { semitones: 6, label: "TT", mnemonic: "The Simpsons theme" },
9
+ { semitones: 7, label: "P5", mnemonic: "Twinkle Twinkle" },
10
+ { semitones: 8, label: "m6", mnemonic: "Love Story theme" },
11
+ { semitones: 9, label: "M6", mnemonic: "NBC chimes" },
12
+ { semitones: 10, label: "m7", mnemonic: "Somewhere (West Side Story)" },
13
+ { semitones: 11, label: "M7", mnemonic: "Take On Me chorus" },
14
+ { semitones: 12, label: "P8", mnemonic: "Somewhere Over the Rainbow" }
15
+ ];
16
+ function intervalBySemitones(semitones) {
17
+ return INTERVALS.find((i) => i.semitones === semitones);
18
+ }
19
+
20
+ export {
21
+ INTERVALS,
22
+ intervalBySemitones
23
+ };
24
+ //# sourceMappingURL=chunk-N56UTMWA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/intervals.ts"],"sourcesContent":["export interface IntervalDef { semitones: number; label: string; mnemonic: string }\n\nexport const INTERVALS: IntervalDef[] = [\n { semitones: 1, label: 'm2', mnemonic: 'Jaws theme' },\n { semitones: 2, label: 'M2', mnemonic: 'Happy Birthday opening' },\n { semitones: 3, label: 'm3', mnemonic: \"Brahms' Lullaby\" },\n { semitones: 4, label: 'M3', mnemonic: 'When the Saints' },\n { semitones: 5, label: 'P4', mnemonic: 'Here Comes the Bride' },\n { semitones: 6, label: 'TT', mnemonic: 'The Simpsons theme' },\n { semitones: 7, label: 'P5', mnemonic: 'Twinkle Twinkle' },\n { semitones: 8, label: 'm6', mnemonic: 'Love Story theme' },\n { semitones: 9, label: 'M6', mnemonic: 'NBC chimes' },\n { semitones: 10, label: 'm7', mnemonic: 'Somewhere (West Side Story)' },\n { semitones: 11, label: 'M7', mnemonic: 'Take On Me chorus' },\n { semitones: 12, label: 'P8', mnemonic: 'Somewhere Over the Rainbow' },\n];\n\nexport function intervalBySemitones(semitones: number): IntervalDef | undefined {\n return INTERVALS.find(i => i.semitones === semitones);\n}\n"],"mappings":";AAEO,IAAM,YAA2B;AAAA,EACtC,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,aAAa;AAAA,EACrD,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,yBAAyB;AAAA,EACjE,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,uBAAuB;AAAA,EAC/D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,qBAAqB;AAAA,EAC7D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,mBAAmB;AAAA,EAC3D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,aAAa;AAAA,EACrD,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,8BAA8B;AAAA,EACtE,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,oBAAoB;AAAA,EAC5D,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,6BAA6B;AACvE;AAEO,SAAS,oBAAoB,WAA4C;AAC9E,SAAO,UAAU,KAAK,OAAK,EAAE,cAAc,SAAS;AACtD;","names":[]}
package/dist/index.js CHANGED
@@ -14,31 +14,16 @@ import {
14
14
  useFlatsForKeyFifths,
15
15
  useFlatsForKeyName
16
16
  } from "./chunk-LLMDQM4C.js";
17
+ import {
18
+ INTERVALS,
19
+ intervalBySemitones
20
+ } from "./chunk-N56UTMWA.js";
17
21
 
18
22
  // src/frequency.ts
19
23
  function midiToFrequency(midi) {
20
24
  return 440 * Math.pow(2, (midi - 69) / 12);
21
25
  }
22
26
 
23
- // src/intervals.ts
24
- var INTERVALS = [
25
- { semitones: 1, label: "m2", mnemonic: "Jaws theme" },
26
- { semitones: 2, label: "M2", mnemonic: "Happy Birthday opening" },
27
- { semitones: 3, label: "m3", mnemonic: "Brahms' Lullaby" },
28
- { semitones: 4, label: "M3", mnemonic: "When the Saints" },
29
- { semitones: 5, label: "P4", mnemonic: "Here Comes the Bride" },
30
- { semitones: 6, label: "TT", mnemonic: "The Simpsons theme" },
31
- { semitones: 7, label: "P5", mnemonic: "Twinkle Twinkle" },
32
- { semitones: 8, label: "m6", mnemonic: "Love Story theme" },
33
- { semitones: 9, label: "M6", mnemonic: "NBC chimes" },
34
- { semitones: 10, label: "m7", mnemonic: "Somewhere (West Side Story)" },
35
- { semitones: 11, label: "M7", mnemonic: "Take On Me chorus" },
36
- { semitones: 12, label: "P8", mnemonic: "Somewhere Over the Rainbow" }
37
- ];
38
- function intervalBySemitones(semitones) {
39
- return INTERVALS.find((i) => i.semitones === semitones);
40
- }
41
-
42
27
  // src/chords.ts
43
28
  var CHORD_TEMPLATES = [
44
29
  { name: "maj7", intervals: [0, 4, 7, 11] },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/frequency.ts","../src/intervals.ts","../src/chords.ts"],"sourcesContent":["/** Equal-temperament MIDI → frequency (A4 = MIDI 69 = 440 Hz). */\nexport function midiToFrequency(midi: number): number {\n return 440 * Math.pow(2, (midi - 69) / 12);\n}\n","export interface IntervalDef { semitones: number; label: string; mnemonic: string }\n\nexport const INTERVALS: IntervalDef[] = [\n { semitones: 1, label: 'm2', mnemonic: 'Jaws theme' },\n { semitones: 2, label: 'M2', mnemonic: 'Happy Birthday opening' },\n { semitones: 3, label: 'm3', mnemonic: \"Brahms' Lullaby\" },\n { semitones: 4, label: 'M3', mnemonic: 'When the Saints' },\n { semitones: 5, label: 'P4', mnemonic: 'Here Comes the Bride' },\n { semitones: 6, label: 'TT', mnemonic: 'The Simpsons theme' },\n { semitones: 7, label: 'P5', mnemonic: 'Twinkle Twinkle' },\n { semitones: 8, label: 'm6', mnemonic: 'Love Story theme' },\n { semitones: 9, label: 'M6', mnemonic: 'NBC chimes' },\n { semitones: 10, label: 'm7', mnemonic: 'Somewhere (West Side Story)' },\n { semitones: 11, label: 'M7', mnemonic: 'Take On Me chorus' },\n { semitones: 12, label: 'P8', mnemonic: 'Somewhere Over the Rainbow' },\n];\n\nexport function intervalBySemitones(semitones: number): IntervalDef | undefined {\n return INTERVALS.find(i => i.semitones === semitones);\n}\n","export interface ChordTemplate { name: string; intervals: number[] }\n\n/** Chord-quality templates, richer qualities first so naming matches the\n * most specific quality (e.g. maj7 before plain major). */\nexport const CHORD_TEMPLATES: ChordTemplate[] = [\n { name: 'maj7', intervals: [0, 4, 7, 11] },\n { name: '7', intervals: [0, 4, 7, 10] },\n { name: 'm7', intervals: [0, 3, 7, 10] },\n { name: 'dim7', intervals: [0, 3, 6, 9] },\n { name: 'm7b5', intervals: [0, 3, 6, 10] },\n { name: '', intervals: [0, 4, 7] },\n { name: 'm', intervals: [0, 3, 7] },\n { name: 'dim', intervals: [0, 3, 6] },\n { name: 'aug', intervals: [0, 4, 8] },\n { name: 'sus4', intervals: [0, 5, 7] },\n { name: 'sus2', intervals: [0, 2, 7] },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;AACO,SAAS,gBAAgB,MAAsB;AACpD,SAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,EAAE;AAC3C;;;ACDO,IAAM,YAA2B;AAAA,EACtC,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,aAAa;AAAA,EACrD,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,yBAAyB;AAAA,EACjE,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,uBAAuB;AAAA,EAC/D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,qBAAqB;AAAA,EAC7D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,kBAAkB;AAAA,EAC1D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,mBAAmB;AAAA,EAC3D,EAAE,WAAW,GAAI,OAAO,MAAM,UAAU,aAAa;AAAA,EACrD,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,8BAA8B;AAAA,EACtE,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,oBAAoB;AAAA,EAC5D,EAAE,WAAW,IAAI,OAAO,MAAM,UAAU,6BAA6B;AACvE;AAEO,SAAS,oBAAoB,WAA4C;AAC9E,SAAO,UAAU,KAAK,OAAK,EAAE,cAAc,SAAS;AACtD;;;ACfO,IAAM,kBAAmC;AAAA,EAC9C,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,KAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,MAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE;AAAA,EACxC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,IAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,KAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,OAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,OAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AACvC;","names":[]}
1
+ {"version":3,"sources":["../src/frequency.ts","../src/chords.ts"],"sourcesContent":["/** Equal-temperament MIDI → frequency (A4 = MIDI 69 = 440 Hz). */\nexport function midiToFrequency(midi: number): number {\n return 440 * Math.pow(2, (midi - 69) / 12);\n}\n","export interface ChordTemplate { name: string; intervals: number[] }\n\n/** Chord-quality templates, richer qualities first so naming matches the\n * most specific quality (e.g. maj7 before plain major). */\nexport const CHORD_TEMPLATES: ChordTemplate[] = [\n { name: 'maj7', intervals: [0, 4, 7, 11] },\n { name: '7', intervals: [0, 4, 7, 10] },\n { name: 'm7', intervals: [0, 3, 7, 10] },\n { name: 'dim7', intervals: [0, 3, 6, 9] },\n { name: 'm7b5', intervals: [0, 3, 6, 10] },\n { name: '', intervals: [0, 4, 7] },\n { name: 'm', intervals: [0, 3, 7] },\n { name: 'dim', intervals: [0, 3, 6] },\n { name: 'aug', intervals: [0, 4, 8] },\n { name: 'sus4', intervals: [0, 5, 7] },\n { name: 'sus2', intervals: [0, 2, 7] },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACO,SAAS,gBAAgB,MAAsB;AACpD,SAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,EAAE;AAC3C;;;ACCO,IAAM,kBAAmC;AAAA,EAC9C,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,KAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,MAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE;AAAA,EACxC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAAA,EACzC,EAAE,MAAM,IAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,KAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,OAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,OAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EACrC,EAAE,MAAM,QAAQ,WAAW,CAAC,GAAG,GAAG,CAAC,EAAE;AACvC;","names":[]}
@@ -1628,4 +1628,133 @@ interface SectionMinimapProps {
1628
1628
  }
1629
1629
  declare const sectionMinimapFactory: LayerFactory<SectionMinimapProps>;
1630
1630
 
1631
- export { type Affine, type AudioClock, type AudioEvent, type BackgroundProps, type BeatGridOpts, type BeatTick, type BrandingProps, type BufferFactory, type BuildSceneOpts, type BuiltScene, type CameraState, type CaptionCue, type CaptionProps, type CaptionScript, type CaptionStyle, type ChordSpan, type CircleOfFifthsProps, type CirclePoint, type ClickTrackOpts, type ColorBy, type ContourPlot, type ContourPoint, type CountInOpts, type CountingTrackProps, type CtaProps, DEFAULT_FUNCTION_COLORS, type DegreeLabel, type DegreeLabelsProps, type DroneOpts, type DuckWindow, type Easing, type ExtendedDemoOpts, FIFTHS_MAJOR, FIFTHS_MINOR, FOLLOW_BARS, FOLLOW_PAD, type FallingKeyboardDemoOpts, type FallingNotesProps, type FunctionColors, type FunctionalHarmonyProps, type GateError, type GateInput, type HandColors, type HarmonicFunction, type HarmonyMode, type HighlightRegion, type HookProps, type KeyRect, type KeyboardLayout, type KeyboardLayoutOpts, type KeyboardProps, type LabelMode, type Layer, type LayerFactory, type McqCardProps, type NotationEngraving, type NotationLayout, type NotationLayoutOpts, type NotationProps, type NotationRect, type OutputProbe, PIANO_HIGH, PIANO_LOW, type PitchContourProps, type Placement, type PlayheadLine, type PortraitProps, type PromoCardsDemoOpts, type Quiz, type QuizOption, type QuizPhase, type RayEndpoints, type RecordSceneSpecOpts, type Rect, type RenderCtx, type ResolvedSegment, type RevealProps, type SafeGuidesProps, type SceneSpec, type ScheduleTarget, type Score, type ScoreFromMusicXMLOpts, type ScoreNote, type ScrollCursorProps, type Section, type SectionMinimapProps, type SegmentAudio, type SegmentAudioCtx, type SegmentTransition, type SpecLayer, type SpectrumInput, type SpectrumProps, type StaffKeyboardRayProps, type TempoMap, type TimeAnchor, type TimelineSegment, activeChord, activeCue, activeSection, animatedSlot, applySchedule, applyToContext, assertGate, audioPlayheadLine, ballArc, ballX, beatGrid, beatPhase, blackKeys, bpmOf, brandingFactory, buildScene, cameraForFollow, cameraTransform, circleOfFifthsDemoSpec, circleOfFifthsFactory, clamp, clickTrackSchedule, contourMinimapDemoSpec, contourPoints, contourPolyline, countInLeadSec, countInSchedule, countdownRemaining, countdownSeconds, countingDegreeDemoSpec, countingTrackFactory, cropAroundBox, ctaFactory, cubicEaseInOut, cueOpacity, degreeLabel, degreeLabelsFactory, distinctMeasureIndices, distinctOnsets, dotAt, drawCaption, drawHighlight, droneSchedule, duckGainAt, easeIn, easeInOut, easeOut, fallingKeyboardDemoScore, fallingKeyboardDemoSpec, fallingNotesFactory, firstMeasureBox, followBoxAt, followSrcBox, followWindowStart, fracSlotPoint, frameRect, functionColor, functionalHarmonyFactory, getKeyboardLayout, getLayerFactory, getNotationEngraving, harmonyDemoSpec, highlightIntensity, hookFactory, identityCamera, inRange, invLerp, isBlackKey, kenBurns, keyCenterX, keyColumnWidth, keyRect, keySlot, keyboardFactory, keyboardLayout, lerp, lerpBox, lerpCamera, linear, mapBoxThroughLayout, mcqCardFactory, mcqDemoSpec, measureColumnsFromLayout, measureCount, measureSpanBox, measureSpans, measureSystemMap, timeToX as minimapTimeToX, msPerBeat, notationFactory, notationLayout, noteColor, noteSetXRange, parseKey, parseTimeSig, pcToSlot, pitchAt, pitchContourFactory, pitchRange, playheadLine, portraitFactory, progress01, projectPoint, promoCardsDemoSpec, quizPhase, rayEndpoints, rayPointAt, recordSceneSpec, registerLayer, registeredKeys, resolveAnchor, resolveKeyboardLayout, resolveTimeline, revealFactory, revealProgress, runGate, safeGuidesFactory, scoreFromMusicXML, scorePitchSpan, scrollCursorFactory, sectionMinimapFactory, setFollowLayoutProvider, setKeyboardLayout, setNotationEngraving, slotAngle, slotPc, slotPoint, spectrumFactory, staffAnchor, staffKeyboardRayFactory, staffRayDemoSpec, systemBox, transitionProgress, validateChordTrack, validateQuiz, validateSections, visualTimelineMs, vstackAudioPlayheadLine, vstackFollowBox, whiteKeys, worldToViewport };
1631
+ type PulseStyle = 'bloom' | 'vignette';
1632
+ interface BeatPulseProps {
1633
+ /** Override onset times (ms). Default = distinct onsets of ctx.score.notes. */
1634
+ onsetsMs?: number[];
1635
+ /** Which renderings to draw. Default ["bloom"]. */
1636
+ styles?: PulseStyle[];
1637
+ /** Max overlay alpha at a fresh onset. Default 0.42 (subtle). */
1638
+ intensity?: number;
1639
+ /** Attack ramp to full, ms. Default 0 (snap to full on the onset). */
1640
+ attackMs?: number;
1641
+ /** Exponential decay time constant, ms. Default 170. */
1642
+ decayMs?: number;
1643
+ /** Overlay colour. Default theme.accent. */
1644
+ color?: string;
1645
+ /**
1646
+ * Canvas blend for the overlay. Default "source-over" (a tinted bloom that
1647
+ * reads on LIGHT backgrounds — most of our promos are paper/cream). Use
1648
+ * "lighter" (additive glow) on DARK backgrounds where it would otherwise just
1649
+ * wash to white.
1650
+ */
1651
+ blend?: 'source-over' | 'lighter';
1652
+ }
1653
+ /**
1654
+ * Pulse value at t = max envelope over the few most recent onsets. Pure. Exported
1655
+ * so other layers / tests can read the same heartbeat the visual draws.
1656
+ */
1657
+ declare function pulseAt(onsetsMs: number[], tMs: number, attackMs?: number, decayMs?: number): number;
1658
+ declare const beatPulseFactory: LayerFactory<BeatPulseProps>;
1659
+
1660
+ interface ChordRibbonProps {
1661
+ /** REQUIRED: timed chord spans (function + display label). Host-supplied. */
1662
+ chordTrack: ChordSpan[];
1663
+ /** Horizontal time scale, px per ms. Default 0.06 (60 px/s). */
1664
+ pxPerMs?: number;
1665
+ /** Where "now" sits, as a fraction of the safe width. Default 0.32. */
1666
+ playheadFrac?: number;
1667
+ /** Chip baseline (world y / screen y, since pinned). Default safeBox.bottom - 260. */
1668
+ y?: number;
1669
+ /** Chip height (px). Default 84. */
1670
+ height?: number;
1671
+ /** Tint chips by tonal function. Default true. */
1672
+ showFunction?: boolean;
1673
+ /** Override the function→colour map. */
1674
+ colors?: FunctionColors;
1675
+ }
1676
+ declare const chordRibbonFactory: LayerFactory<ChordRibbonProps>;
1677
+
1678
+ interface ProgressRingProps {
1679
+ /** Total length, ms. Default ctx.score.durationMs. Required if no score. */
1680
+ totalMs?: number;
1681
+ /** Ring radius (px). Default 46. */
1682
+ radius?: number;
1683
+ /** Ring stroke thickness (px). Default 9. */
1684
+ thickness?: number;
1685
+ /** Centre x (px). Default safeBox.right - radius - 16. */
1686
+ cx?: number;
1687
+ /** Centre y (px). Default safeBox.top + radius + 16. */
1688
+ cy?: number;
1689
+ /** Filled-arc colour. Default theme.gold. */
1690
+ color?: string;
1691
+ /** Unfilled track colour. Default a faint paper tint. */
1692
+ trackColor?: string;
1693
+ /** Draw seconds-remaining in the centre. Default false. */
1694
+ showCountdown?: boolean;
1695
+ }
1696
+ declare const progressRingFactory: LayerFactory<ProgressRingProps>;
1697
+
1698
+ interface RadialSpectrumProps {
1699
+ /** Number of bars around the ring. Default 64. */
1700
+ bars?: number;
1701
+ /** Center x as a fraction of W. Default 0.5. */
1702
+ cxFrac?: number;
1703
+ /** Center y as a fraction of H. Default 0.42. */
1704
+ cyFrac?: number;
1705
+ /** Inner radius (bar roots) as a fraction of min(W,H). Default 0.20. */
1706
+ innerFrac?: number;
1707
+ /** Max bar length as a fraction of min(W,H). Default 0.13. */
1708
+ maxLenFrac?: number;
1709
+ /** Bar fill at low magnitude. Default theme.accent. */
1710
+ colorLow?: string;
1711
+ /** Bar fill at high magnitude. Default theme.gold. */
1712
+ colorHigh?: string;
1713
+ /** Per-frame level provider (overrides ctx.spectrum). Pure fn of t for tests. */
1714
+ levelsFn?: (tMs: number, bands: number) => Float32Array | number[] | null;
1715
+ }
1716
+ declare const radialSpectrumFactory: LayerFactory<RadialSpectrumProps>;
1717
+
1718
+ interface KaraokeWord {
1719
+ /** The word (no surrounding spaces). */
1720
+ text: string;
1721
+ /** Time this word lights up, ms. */
1722
+ atMs: number;
1723
+ }
1724
+ interface KaraokeCaptionProps {
1725
+ /** REQUIRED: timed words, ascending by atMs. */
1726
+ words: KaraokeWord[];
1727
+ /** Vertical center as a fraction of H. Default 0.5. */
1728
+ centerFrac?: number;
1729
+ /** Font px. Default 64. */
1730
+ fontPx?: number;
1731
+ /** Colour of already-sung words. Default theme.ink. */
1732
+ sungColor?: string;
1733
+ /** Colour of not-yet-sung words. Default a faint ink. */
1734
+ upcomingColor?: string;
1735
+ /** Highlight colour of the word that just lit. Default theme.accent. */
1736
+ activeColor?: string;
1737
+ /** ms a freshly-lit word stays in the active highlight colour. Default 320. */
1738
+ activeHoldMs?: number;
1739
+ }
1740
+ declare const karaokeCaptionFactory: LayerFactory<KaraokeCaptionProps>;
1741
+
1742
+ interface IntervalArcsProps {
1743
+ /** Plot band top (world y). Default safeBox.top + safeBox.h * 0.18. */
1744
+ top?: number;
1745
+ /** Plot band height (world px). Default safeBox.h * 0.34. */
1746
+ height?: number;
1747
+ /** Arc colour for an ascending interval. Default theme.accent. */
1748
+ upColor?: string;
1749
+ /** Arc colour for a descending interval. Default theme.sepia. */
1750
+ downColor?: string;
1751
+ /** Draw the interval label on each arc. Default true. */
1752
+ showLabels?: boolean;
1753
+ /** Label font px. Default 30. */
1754
+ fontPx?: number;
1755
+ /** Note-dot radius (world px). Default 9. */
1756
+ dotRadius?: number;
1757
+ }
1758
+ declare const intervalArcsFactory: LayerFactory<IntervalArcsProps>;
1759
+
1760
+ export { type Affine, type 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 ContourPlot, type ContourPoint, type CountInOpts, type CountingTrackProps, type CtaProps, DEFAULT_FUNCTION_COLORS, type DegreeLabel, type DegreeLabelsProps, type DroneOpts, type DuckWindow, type Easing, type ExtendedDemoOpts, FIFTHS_MAJOR, FIFTHS_MINOR, FOLLOW_BARS, FOLLOW_PAD, type FallingKeyboardDemoOpts, type FallingNotesProps, type FunctionColors, type FunctionalHarmonyProps, type GateError, type GateInput, type HandColors, type HarmonicFunction, type HarmonyMode, type HighlightRegion, type HookProps, type IntervalArcsProps, type KaraokeCaptionProps, type KaraokeWord, type KeyRect, type KeyboardLayout, type KeyboardLayoutOpts, type KeyboardProps, type LabelMode, type Layer, type LayerFactory, type McqCardProps, type NotationEngraving, type NotationLayout, type NotationLayoutOpts, type NotationProps, type NotationRect, type OutputProbe, PIANO_HIGH, PIANO_LOW, type PitchContourProps, type Placement, type PlayheadLine, type PortraitProps, type ProgressRingProps, type PromoCardsDemoOpts, type PulseStyle, type Quiz, type QuizOption, type QuizPhase, type RadialSpectrumProps, type RayEndpoints, type RecordSceneSpecOpts, type Rect, type RenderCtx, type ResolvedSegment, type RevealProps, type SafeGuidesProps, type SceneSpec, type ScheduleTarget, type Score, type ScoreFromMusicXMLOpts, type ScoreNote, type ScrollCursorProps, type Section, type SectionMinimapProps, type SegmentAudio, type SegmentAudioCtx, type SegmentTransition, type SpecLayer, type SpectrumInput, type SpectrumProps, type StaffKeyboardRayProps, type TempoMap, type TimeAnchor, type TimelineSegment, activeChord, activeCue, activeSection, animatedSlot, applySchedule, applyToContext, assertGate, audioPlayheadLine, ballArc, ballX, beatGrid, beatPhase, beatPulseFactory, blackKeys, bpmOf, brandingFactory, buildScene, cameraForFollow, cameraTransform, chordRibbonFactory, circleOfFifthsDemoSpec, circleOfFifthsFactory, clamp, clickTrackSchedule, contourMinimapDemoSpec, contourPoints, contourPolyline, countInLeadSec, countInSchedule, countdownRemaining, countdownSeconds, countingDegreeDemoSpec, countingTrackFactory, cropAroundBox, ctaFactory, cubicEaseInOut, cueOpacity, degreeLabel, degreeLabelsFactory, distinctMeasureIndices, distinctOnsets, dotAt, drawCaption, drawHighlight, droneSchedule, duckGainAt, easeIn, easeInOut, easeOut, fallingKeyboardDemoScore, fallingKeyboardDemoSpec, fallingNotesFactory, firstMeasureBox, followBoxAt, followSrcBox, followWindowStart, fracSlotPoint, frameRect, functionColor, functionalHarmonyFactory, getKeyboardLayout, getLayerFactory, getNotationEngraving, harmonyDemoSpec, highlightIntensity, hookFactory, identityCamera, inRange, intervalArcsFactory, invLerp, isBlackKey, karaokeCaptionFactory, kenBurns, keyCenterX, keyColumnWidth, keyRect, keySlot, keyboardFactory, keyboardLayout, lerp, lerpBox, lerpCamera, linear, mapBoxThroughLayout, mcqCardFactory, mcqDemoSpec, measureColumnsFromLayout, measureCount, measureSpanBox, measureSpans, measureSystemMap, timeToX as minimapTimeToX, msPerBeat, notationFactory, notationLayout, noteColor, noteSetXRange, parseKey, parseTimeSig, pcToSlot, pitchAt, pitchContourFactory, pitchRange, playheadLine, portraitFactory, progress01, progressRingFactory, projectPoint, promoCardsDemoSpec, pulseAt, quizPhase, radialSpectrumFactory, rayEndpoints, rayPointAt, recordSceneSpec, registerLayer, registeredKeys, resolveAnchor, resolveKeyboardLayout, resolveTimeline, revealFactory, revealProgress, runGate, safeGuidesFactory, scoreFromMusicXML, scorePitchSpan, scrollCursorFactory, sectionMinimapFactory, setFollowLayoutProvider, setKeyboardLayout, setNotationEngraving, slotAngle, slotPc, slotPoint, spectrumFactory, staffAnchor, staffKeyboardRayFactory, staffRayDemoSpec, systemBox, transitionProgress, validateChordTrack, validateQuiz, validateSections, visualTimelineMs, vstackAudioPlayheadLine, vstackFollowBox, whiteKeys, worldToViewport };