@scenar/core 0.10.0 → 0.11.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/index.d.ts +17 -1
- package/index.d.ts.map +1 -1
- package/index.js +9 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/presenter/derive-presenter-timeline.d.ts +36 -0
- package/presenter/derive-presenter-timeline.d.ts.map +1 -0
- package/presenter/derive-presenter-timeline.js +31 -0
- package/presenter/derive-presenter-timeline.js.map +1 -0
- package/presenter/presenter-opacity.d.ts +32 -0
- package/presenter/presenter-opacity.d.ts.map +1 -0
- package/presenter/presenter-opacity.js +40 -0
- package/presenter/presenter-opacity.js.map +1 -0
- package/presenter/types.d.ts +45 -0
- package/presenter/types.d.ts.map +1 -0
- package/presenter/types.js +16 -0
- package/presenter/types.js.map +1 -0
- package/scenario/apply-title-cards.d.ts +53 -0
- package/scenario/apply-title-cards.d.ts.map +1 -0
- package/scenario/apply-title-cards.js +113 -0
- package/scenario/apply-title-cards.js.map +1 -0
- package/scenario/bundle.d.ts +15 -0
- package/scenario/bundle.d.ts.map +1 -1
- package/scenario/soundtrack.d.ts +46 -0
- package/scenario/soundtrack.d.ts.map +1 -0
- package/scenario/soundtrack.js +11 -0
- package/scenario/soundtrack.js.map +1 -0
- package/scenario/title-cards.d.ts +64 -0
- package/scenario/title-cards.d.ts.map +1 -0
- package/scenario/title-cards.js +20 -0
- package/scenario/title-cards.js.map +1 -0
- package/scenario/types.d.ts +36 -2
- package/scenario/types.d.ts.map +1 -1
- package/src/index.ts +32 -1
- package/src/presenter/derive-presenter-timeline.test.ts +138 -0
- package/src/presenter/derive-presenter-timeline.ts +54 -0
- package/src/presenter/presenter-opacity.test.ts +47 -0
- package/src/presenter/presenter-opacity.ts +43 -0
- package/src/presenter/types.ts +46 -0
- package/src/scenario/apply-title-cards.test.ts +268 -0
- package/src/scenario/apply-title-cards.ts +141 -0
- package/src/scenario/bundle.ts +15 -0
- package/src/scenario/soundtrack.ts +47 -0
- package/src/scenario/title-cards.ts +67 -0
- package/src/scenario/types.ts +36 -2
- package/src/timeline/compute-step-timeline.test.ts +21 -0
- package/src/timeline/compute-step-timeline.ts +30 -7
- package/src/timeline/derive-action-events.test.ts +144 -0
- package/src/timeline/derive-action-events.ts +116 -0
- package/src/timeline/derive-sfx-timeline.test.ts +114 -0
- package/src/timeline/derive-sfx-timeline.ts +79 -0
- package/src/timeline/music-envelope.test.ts +141 -0
- package/src/timeline/music-envelope.ts +131 -0
- package/timeline/compute-step-timeline.d.ts +28 -3
- package/timeline/compute-step-timeline.d.ts.map +1 -1
- package/timeline/compute-step-timeline.js +11 -3
- package/timeline/compute-step-timeline.js.map +1 -1
- package/timeline/derive-action-events.d.ts +40 -0
- package/timeline/derive-action-events.d.ts.map +1 -0
- package/timeline/derive-action-events.js +71 -0
- package/timeline/derive-action-events.js.map +1 -0
- package/timeline/derive-sfx-timeline.d.ts +36 -0
- package/timeline/derive-sfx-timeline.d.ts.map +1 -0
- package/timeline/derive-sfx-timeline.js +49 -0
- package/timeline/derive-sfx-timeline.js.map +1 -0
- package/timeline/music-envelope.d.ts +69 -0
- package/timeline/music-envelope.d.ts.map +1 -0
- package/timeline/music-envelope.js +95 -0
- package/timeline/music-envelope.js.map +1 -0
package/index.d.ts
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
export type { ScenarioStep } from "./scenario/types.js";
|
|
2
2
|
export type { ScenarioBundle } from "./scenario/bundle.js";
|
|
3
3
|
export type { ActionType, StepAction, UseStepInteractionsOptions, } from "./scenario/step-action.js";
|
|
4
|
+
export type { Soundtrack } from "./scenario/soundtrack.js";
|
|
5
|
+
export { MUSIC_VOLUME_DEFAULT, DUCKING_VOLUME_DEFAULT, } from "./scenario/soundtrack.js";
|
|
6
|
+
export type { TitleCard, TitleCards, StepCard } from "./scenario/title-cards.js";
|
|
7
|
+
export { TITLE_CARD_DURATION_DEFAULT_MS } from "./scenario/title-cards.js";
|
|
8
|
+
export type { AppliedTitleCards } from "./scenario/apply-title-cards.js";
|
|
9
|
+
export { applyTitleCards } from "./scenario/apply-title-cards.js";
|
|
4
10
|
export type { NarrationEntry, NarrationManifest } from "./narration/types.js";
|
|
11
|
+
export type { PresenterEntry, PresenterManifest } from "./presenter/types.js";
|
|
12
|
+
export type { PresenterWindow } from "./presenter/derive-presenter-timeline.js";
|
|
13
|
+
export { derivePresenterTimeline } from "./presenter/derive-presenter-timeline.js";
|
|
14
|
+
export { PRESENTER_FADE_MS, presenterOpacityAt } from "./presenter/presenter-opacity.js";
|
|
5
15
|
export type { ViewportTransform, ViewportCameraMove } from "./viewport/transform.js";
|
|
6
16
|
export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
|
|
7
17
|
export type { Position } from "./cursor/compute-position.js";
|
|
8
18
|
export { computeCursorPosition } from "./cursor/compute-position.js";
|
|
9
19
|
export type { StepTimeline } from "./timeline/compute-step-timeline.js";
|
|
10
|
-
export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
20
|
+
export { FINAL_DWELL_MS, computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
11
21
|
export { deriveStepFromTime } from "./timeline/derive-step.js";
|
|
12
22
|
export { getStepDurationMs } from "./timeline/step-duration.js";
|
|
23
|
+
export type { ActionEvent, ActionEventKind } from "./timeline/derive-action-events.js";
|
|
24
|
+
export { deriveActionEvents } from "./timeline/derive-action-events.js";
|
|
25
|
+
export type { SfxEvent, SfxSound } from "./timeline/derive-sfx-timeline.js";
|
|
26
|
+
export { deriveSfxTimeline } from "./timeline/derive-sfx-timeline.js";
|
|
27
|
+
export type { DuckingWindow, MusicEnvelope } from "./timeline/music-envelope.js";
|
|
28
|
+
export { MUSIC_FADE_IN_MS, MUSIC_FADE_OUT_MS, DUCKING_RAMP_MS, computeMusicEnvelope, musicGainAt, } from "./timeline/music-envelope.js";
|
|
13
29
|
export type { ScenarioShot } from "./timeline/collect-shots.js";
|
|
14
30
|
export { SHOT_NAME_PATTERN, collectScenarioShots, collectShotNames, } from "./timeline/collect-shots.js";
|
|
15
31
|
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,UAAU,EACV,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
// @scenar/core — public API
|
|
2
2
|
// Pure TypeScript types, timing, and utilities for scenario playback.
|
|
3
|
+
export { MUSIC_VOLUME_DEFAULT, DUCKING_VOLUME_DEFAULT, } from "./scenario/soundtrack.js";
|
|
4
|
+
export { TITLE_CARD_DURATION_DEFAULT_MS } from "./scenario/title-cards.js";
|
|
5
|
+
export { applyTitleCards } from "./scenario/apply-title-cards.js";
|
|
6
|
+
export { derivePresenterTimeline } from "./presenter/derive-presenter-timeline.js";
|
|
7
|
+
export { PRESENTER_FADE_MS, presenterOpacityAt } from "./presenter/presenter-opacity.js";
|
|
3
8
|
export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
|
|
4
9
|
export { computeCursorPosition } from "./cursor/compute-position.js";
|
|
5
|
-
export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
10
|
+
export { FINAL_DWELL_MS, computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
6
11
|
export { deriveStepFromTime } from "./timeline/derive-step.js";
|
|
7
12
|
export { getStepDurationMs } from "./timeline/step-duration.js";
|
|
13
|
+
export { deriveActionEvents } from "./timeline/derive-action-events.js";
|
|
14
|
+
export { deriveSfxTimeline } from "./timeline/derive-sfx-timeline.js";
|
|
15
|
+
export { MUSIC_FADE_IN_MS, MUSIC_FADE_OUT_MS, DUCKING_RAMP_MS, computeMusicEnvelope, musicGainAt, } from "./timeline/music-envelope.js";
|
|
8
16
|
export { SHOT_NAME_PATTERN, collectScenarioShots, collectShotNames, } from "./timeline/collect-shots.js";
|
|
9
17
|
// Timing constants
|
|
10
18
|
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;AAatE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAQlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAIzF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAExE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAExC,0EAA0E;AAC1E,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAS7B,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { StepTimeline } from "../timeline/compute-step-timeline.js";
|
|
2
|
+
import type { PresenterManifest } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* One presenter clip's place on the scenario timeline: when it becomes
|
|
5
|
+
* visible (its step's start) and how long it plays.
|
|
6
|
+
*
|
|
7
|
+
* A window never outlives its step — `scenar presenter` writes clip
|
|
8
|
+
* durations from the narration manifest, and step timing already waits
|
|
9
|
+
* for narration (`max(delayMs, narration duration)`), so the clip fits
|
|
10
|
+
* by construction. When the step outlives the clip (a long `delayMs`),
|
|
11
|
+
* the frame fades out at clip end (see `presenterOpacityAt`).
|
|
12
|
+
*/
|
|
13
|
+
export interface PresenterWindow {
|
|
14
|
+
/** Index into the EXPANDED step list (same domain as `stepTimeline`). */
|
|
15
|
+
readonly stepIndex: number;
|
|
16
|
+
/** Clip start in scenario time — the step's start, in milliseconds. */
|
|
17
|
+
readonly startMs: number;
|
|
18
|
+
/** Clip length in milliseconds. */
|
|
19
|
+
readonly clipDurationMs: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Derive every presenter clip's timeline window from the (expanded,
|
|
23
|
+
* card-padded) presenter manifest and the step timeline computed over
|
|
24
|
+
* the same expanded steps.
|
|
25
|
+
*
|
|
26
|
+
* This is the one implementation both outputs consume: the browser
|
|
27
|
+
* player uses windows for expected-position math in its drift
|
|
28
|
+
* corrections; the video export converts `startMs` to frames for
|
|
29
|
+
* Sequence placement. Pure function — same inputs, same windows, in
|
|
30
|
+
* both time domains.
|
|
31
|
+
*
|
|
32
|
+
* Manifest entries beyond the timeline's step count are ignored (a
|
|
33
|
+
* stale manifest degrades, exactly as narration does).
|
|
34
|
+
*/
|
|
35
|
+
export declare function derivePresenterTimeline(presenterManifest: PresenterManifest | undefined, stepTimeline: StepTimeline): readonly PresenterWindow[];
|
|
36
|
+
//# sourceMappingURL=derive-presenter-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive-presenter-timeline.d.ts","sourceRoot":"","sources":["../../src/presenter/derive-presenter-timeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,YAAY,EAAE,YAAY,GACzB,SAAS,eAAe,EAAE,CAc5B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive every presenter clip's timeline window from the (expanded,
|
|
3
|
+
* card-padded) presenter manifest and the step timeline computed over
|
|
4
|
+
* the same expanded steps.
|
|
5
|
+
*
|
|
6
|
+
* This is the one implementation both outputs consume: the browser
|
|
7
|
+
* player uses windows for expected-position math in its drift
|
|
8
|
+
* corrections; the video export converts `startMs` to frames for
|
|
9
|
+
* Sequence placement. Pure function — same inputs, same windows, in
|
|
10
|
+
* both time domains.
|
|
11
|
+
*
|
|
12
|
+
* Manifest entries beyond the timeline's step count are ignored (a
|
|
13
|
+
* stale manifest degrades, exactly as narration does).
|
|
14
|
+
*/
|
|
15
|
+
export function derivePresenterTimeline(presenterManifest, stepTimeline) {
|
|
16
|
+
if (!presenterManifest)
|
|
17
|
+
return [];
|
|
18
|
+
const windows = [];
|
|
19
|
+
for (let i = 0; i < stepTimeline.stepStartTimesMs.length; i++) {
|
|
20
|
+
const entry = presenterManifest.steps[i];
|
|
21
|
+
if (!entry)
|
|
22
|
+
continue;
|
|
23
|
+
windows.push({
|
|
24
|
+
stepIndex: i,
|
|
25
|
+
startMs: stepTimeline.stepStartTimesMs[i],
|
|
26
|
+
clipDurationMs: entry.durationMs,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return windows;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=derive-presenter-timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive-presenter-timeline.js","sourceRoot":"","sources":["../../src/presenter/derive-presenter-timeline.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CACrC,iBAAgD,EAChD,YAA0B;IAE1B,IAAI,CAAC,iBAAiB;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,OAAO,CAAC,IAAI,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,OAAO,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAE;YAC1C,cAAc,EAAE,KAAK,CAAC,UAAU;SACjC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presenter frame's fade treatment, as a pure function of time —
|
|
3
|
+
* so the browser player and the video export render the identical
|
|
4
|
+
* fade from the same math (one implementation, both time domains).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Fade length at each end of a presenter clip, in milliseconds.
|
|
8
|
+
*
|
|
9
|
+
* The fade-in doubles as the swap treatment: it absorbs the measured
|
|
10
|
+
* src-swap pop-in (≤133 ms worst case across browsers), so no
|
|
11
|
+
* double-buffering machinery is needed. The fade-out is the exit
|
|
12
|
+
* grammar — the presenter finishes and steps aside, rather than
|
|
13
|
+
* freezing mid-gesture when the step outlives the clip.
|
|
14
|
+
*/
|
|
15
|
+
export declare const PRESENTER_FADE_MS = 200;
|
|
16
|
+
/**
|
|
17
|
+
* The presenter frame's opacity at `intraStepMs` milliseconds into its
|
|
18
|
+
* step, for a clip of `clipDurationMs`.
|
|
19
|
+
*
|
|
20
|
+
* Ramps 0→1 over the first {@link PRESENTER_FADE_MS}, holds 1, ramps
|
|
21
|
+
* 1→0 over the last {@link PRESENTER_FADE_MS}, and is 0 outside the
|
|
22
|
+
* clip (before its start, and for the remainder of a step that
|
|
23
|
+
* outlives it). Clips shorter than two fades never reach full
|
|
24
|
+
* opacity — the ramps intersect at the midpoint, keeping the curve
|
|
25
|
+
* continuous.
|
|
26
|
+
*
|
|
27
|
+
* Reduced-motion is a consumer concern: the browser player hides the
|
|
28
|
+
* presenter entirely under `prefers-reduced-motion`, and the export
|
|
29
|
+
* has no such media query — neither needs a flag here.
|
|
30
|
+
*/
|
|
31
|
+
export declare function presenterOpacityAt(intraStepMs: number, clipDurationMs: number): number;
|
|
32
|
+
//# sourceMappingURL=presenter-opacity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presenter-opacity.d.ts","sourceRoot":"","sources":["../../src/presenter/presenter-opacity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,MAAM,CAOR"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presenter frame's fade treatment, as a pure function of time —
|
|
3
|
+
* so the browser player and the video export render the identical
|
|
4
|
+
* fade from the same math (one implementation, both time domains).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Fade length at each end of a presenter clip, in milliseconds.
|
|
8
|
+
*
|
|
9
|
+
* The fade-in doubles as the swap treatment: it absorbs the measured
|
|
10
|
+
* src-swap pop-in (≤133 ms worst case across browsers), so no
|
|
11
|
+
* double-buffering machinery is needed. The fade-out is the exit
|
|
12
|
+
* grammar — the presenter finishes and steps aside, rather than
|
|
13
|
+
* freezing mid-gesture when the step outlives the clip.
|
|
14
|
+
*/
|
|
15
|
+
export const PRESENTER_FADE_MS = 200;
|
|
16
|
+
/**
|
|
17
|
+
* The presenter frame's opacity at `intraStepMs` milliseconds into its
|
|
18
|
+
* step, for a clip of `clipDurationMs`.
|
|
19
|
+
*
|
|
20
|
+
* Ramps 0→1 over the first {@link PRESENTER_FADE_MS}, holds 1, ramps
|
|
21
|
+
* 1→0 over the last {@link PRESENTER_FADE_MS}, and is 0 outside the
|
|
22
|
+
* clip (before its start, and for the remainder of a step that
|
|
23
|
+
* outlives it). Clips shorter than two fades never reach full
|
|
24
|
+
* opacity — the ramps intersect at the midpoint, keeping the curve
|
|
25
|
+
* continuous.
|
|
26
|
+
*
|
|
27
|
+
* Reduced-motion is a consumer concern: the browser player hides the
|
|
28
|
+
* presenter entirely under `prefers-reduced-motion`, and the export
|
|
29
|
+
* has no such media query — neither needs a flag here.
|
|
30
|
+
*/
|
|
31
|
+
export function presenterOpacityAt(intraStepMs, clipDurationMs) {
|
|
32
|
+
if (clipDurationMs <= 0)
|
|
33
|
+
return 0;
|
|
34
|
+
if (intraStepMs <= 0 || intraStepMs >= clipDurationMs)
|
|
35
|
+
return 0;
|
|
36
|
+
const fadeIn = intraStepMs / PRESENTER_FADE_MS;
|
|
37
|
+
const fadeOut = (clipDurationMs - intraStepMs) / PRESENTER_FADE_MS;
|
|
38
|
+
return Math.min(fadeIn, fadeOut, 1);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=presenter-opacity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presenter-opacity.js","sourceRoot":"","sources":["../../src/presenter/presenter-opacity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,cAAsB;IAEtB,IAAI,cAAc,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAClC,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,cAAc;QAAE,OAAO,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,WAAW,GAAG,iBAAiB,CAAC;IAC/C,MAAM,OAAO,GAAG,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,iBAAiB,CAAC;IACnE,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime presenter clip data produced by `scenar presenter`.
|
|
3
|
+
*
|
|
4
|
+
* The presenter track is structurally a second narration pipeline:
|
|
5
|
+
* generation happens at compile time (the CLI calls the avatar
|
|
6
|
+
* provider once and stores the result), and playback consumes fixed
|
|
7
|
+
* assets through a positional manifest. Playback never calls an AI
|
|
8
|
+
* service — a scenario whose clips have not been generated yet simply
|
|
9
|
+
* plays without the presenter.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately its own type, not a generic "clip manifest" shared with
|
|
12
|
+
* narration: the two are structurally identical today, but their doc
|
|
13
|
+
* contracts differ, and that difference IS the domain knowledge.
|
|
14
|
+
*/
|
|
15
|
+
/** A single presenter clip for one scenario step. */
|
|
16
|
+
export interface PresenterEntry {
|
|
17
|
+
/**
|
|
18
|
+
* URL of the clip, relative to the manifest's own location
|
|
19
|
+
* (e.g. "./step-2.mp4") — the same convention narration uses.
|
|
20
|
+
*/
|
|
21
|
+
readonly src: string;
|
|
22
|
+
/**
|
|
23
|
+
* Duration of the clip in milliseconds. Written from the narration
|
|
24
|
+
* manifest's duration for the same step (the clip is lip-synced to
|
|
25
|
+
* that audio and matches it exactly), so presenter timing and
|
|
26
|
+
* narration timing can never disagree.
|
|
27
|
+
*/
|
|
28
|
+
readonly durationMs: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Per-scenario manifest mapping step indices to presenter clips.
|
|
32
|
+
*
|
|
33
|
+
* Array position corresponds to the AUTHORED step index — like the
|
|
34
|
+
* narration manifest, it never knows about synthesized title-card
|
|
35
|
+
* steps. Bundle assembly (`applyTitleCards`) pads `null` entries at
|
|
36
|
+
* injected card positions so the expanded manifest lines up with the
|
|
37
|
+
* expanded steps; cards never show the presenter.
|
|
38
|
+
*
|
|
39
|
+
* Steps without a presenter (not opted in, or generation failed and
|
|
40
|
+
* playback degrades per-step) use `null`.
|
|
41
|
+
*/
|
|
42
|
+
export interface PresenterManifest {
|
|
43
|
+
readonly steps: readonly (PresenterEntry | null)[];
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/presenter/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC;CACpD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime presenter clip data produced by `scenar presenter`.
|
|
3
|
+
*
|
|
4
|
+
* The presenter track is structurally a second narration pipeline:
|
|
5
|
+
* generation happens at compile time (the CLI calls the avatar
|
|
6
|
+
* provider once and stores the result), and playback consumes fixed
|
|
7
|
+
* assets through a positional manifest. Playback never calls an AI
|
|
8
|
+
* service — a scenario whose clips have not been generated yet simply
|
|
9
|
+
* plays without the presenter.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately its own type, not a generic "clip manifest" shared with
|
|
12
|
+
* narration: the two are structurally identical today, but their doc
|
|
13
|
+
* contracts differ, and that difference IS the domain knowledge.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/presenter/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Card synthesis: expand a scenario's steps (and narration manifest)
|
|
3
|
+
* with its configured intro/outro title cards.
|
|
4
|
+
*
|
|
5
|
+
* This is THE one place card steps are constructed. It runs exactly
|
|
6
|
+
* once per playback surface, at bundle assembly — the generated render
|
|
7
|
+
* and pack entries, the CLI's `loadBundle`, and (for direct React
|
|
8
|
+
* integrators) one documented call between `createScenario()` and the
|
|
9
|
+
* player. Authoring surfaces (`createScenario`, `loadScenarioFromProto`)
|
|
10
|
+
* carry the `titleCards` config through untouched, exactly like
|
|
11
|
+
* `soundtrack` — so expanded output never carries the config and double
|
|
12
|
+
* expansion is impossible by data flow.
|
|
13
|
+
*
|
|
14
|
+
* The positional manifests stay keyed to AUTHORED steps everywhere
|
|
15
|
+
* (`scenar narrate` and `scenar presenter` never see cards); this
|
|
16
|
+
* function pads `null` entries at the injected positions — narration
|
|
17
|
+
* and presenter in the same single pass — so the expanded manifests
|
|
18
|
+
* line up with the expanded steps. Existing manifests therefore stay
|
|
19
|
+
* valid when an author adds cards later — no regeneration required.
|
|
20
|
+
*/
|
|
21
|
+
import type { NarrationManifest } from "../narration/types.js";
|
|
22
|
+
import type { PresenterManifest } from "../presenter/types.js";
|
|
23
|
+
import type { ScenarioStep } from "./types.js";
|
|
24
|
+
import { type TitleCards } from "./title-cards.js";
|
|
25
|
+
/** The result of card expansion: steps and manifests, index-aligned. */
|
|
26
|
+
export interface AppliedTitleCards<T> {
|
|
27
|
+
readonly steps: readonly ScenarioStep<T>[];
|
|
28
|
+
readonly narrationManifest: NarrationManifest | undefined;
|
|
29
|
+
readonly presenterManifest: PresenterManifest | undefined;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Expand `steps` (and the index-parallel narration and presenter
|
|
33
|
+
* manifests, when they exist) with the configured intro/outro cards.
|
|
34
|
+
*
|
|
35
|
+
* - **Intro**: prepended at index 0 with `delayMs: 0`; the card's
|
|
36
|
+
* visible time is encoded as the following step's transition delay
|
|
37
|
+
* (`max(authored delayMs, card duration)`), which is exactly how
|
|
38
|
+
* `computeStepTimeline` reads step 0's duration.
|
|
39
|
+
* - **Outro**: appended with `delayMs: FINAL_DWELL_MS`, so the last
|
|
40
|
+
* authored step keeps precisely the closing dwell it has today (or
|
|
41
|
+
* its narration, whichever is longer) before the card appears. The
|
|
42
|
+
* card's own visible time is its `durationMs` — `computeStepTimeline`
|
|
43
|
+
* reads a final card step's duration as the closing dwell. The outro
|
|
44
|
+
* carries two housekeeping interactions at step entry (`clear_cursor`
|
|
45
|
+
* and a viewport reset) so a scenario ending with a visible cursor or
|
|
46
|
+
* an active zoom never leaks that state onto the card. Neither action
|
|
47
|
+
* maps to a sound effect.
|
|
48
|
+
*
|
|
49
|
+
* Pure and non-mutating. When `titleCards` configures no card, the
|
|
50
|
+
* inputs are returned as-is (byte-identical no-op).
|
|
51
|
+
*/
|
|
52
|
+
export declare function applyTitleCards<T>(steps: readonly ScenarioStep<T>[], narrationManifest: NarrationManifest | undefined, titleCards: TitleCards | undefined, presenterManifest?: PresenterManifest): AppliedTitleCards<T>;
|
|
53
|
+
//# sourceMappingURL=apply-title-cards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-title-cards.d.ts","sourceRoot":"","sources":["../../src/scenario/apply-title-cards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAE1B,wEAAwE;AACxE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC3D;AAYD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,EACjC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,EAChD,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,iBAAiB,CAAC,CAAC,CAAC,CA8CtB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Card synthesis: expand a scenario's steps (and narration manifest)
|
|
3
|
+
* with its configured intro/outro title cards.
|
|
4
|
+
*
|
|
5
|
+
* This is THE one place card steps are constructed. It runs exactly
|
|
6
|
+
* once per playback surface, at bundle assembly — the generated render
|
|
7
|
+
* and pack entries, the CLI's `loadBundle`, and (for direct React
|
|
8
|
+
* integrators) one documented call between `createScenario()` and the
|
|
9
|
+
* player. Authoring surfaces (`createScenario`, `loadScenarioFromProto`)
|
|
10
|
+
* carry the `titleCards` config through untouched, exactly like
|
|
11
|
+
* `soundtrack` — so expanded output never carries the config and double
|
|
12
|
+
* expansion is impossible by data flow.
|
|
13
|
+
*
|
|
14
|
+
* The positional manifests stay keyed to AUTHORED steps everywhere
|
|
15
|
+
* (`scenar narrate` and `scenar presenter` never see cards); this
|
|
16
|
+
* function pads `null` entries at the injected positions — narration
|
|
17
|
+
* and presenter in the same single pass — so the expanded manifests
|
|
18
|
+
* line up with the expanded steps. Existing manifests therefore stay
|
|
19
|
+
* valid when an author adds cards later — no regeneration required.
|
|
20
|
+
*/
|
|
21
|
+
import { FINAL_DWELL_MS } from "../timeline/compute-step-timeline.js";
|
|
22
|
+
import { TITLE_CARD_DURATION_DEFAULT_MS, } from "./title-cards.js";
|
|
23
|
+
/**
|
|
24
|
+
* A card step's `data` placeholder. Card steps are rendered by the
|
|
25
|
+
* player's built-in card component — the integrator's render callback
|
|
26
|
+
* (the only reader of `data`) is never invoked for them, so no real
|
|
27
|
+
* `T` value is ever needed. See the `ScenarioStep.card` doc contract.
|
|
28
|
+
*/
|
|
29
|
+
function cardStepData() {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Expand `steps` (and the index-parallel narration and presenter
|
|
34
|
+
* manifests, when they exist) with the configured intro/outro cards.
|
|
35
|
+
*
|
|
36
|
+
* - **Intro**: prepended at index 0 with `delayMs: 0`; the card's
|
|
37
|
+
* visible time is encoded as the following step's transition delay
|
|
38
|
+
* (`max(authored delayMs, card duration)`), which is exactly how
|
|
39
|
+
* `computeStepTimeline` reads step 0's duration.
|
|
40
|
+
* - **Outro**: appended with `delayMs: FINAL_DWELL_MS`, so the last
|
|
41
|
+
* authored step keeps precisely the closing dwell it has today (or
|
|
42
|
+
* its narration, whichever is longer) before the card appears. The
|
|
43
|
+
* card's own visible time is its `durationMs` — `computeStepTimeline`
|
|
44
|
+
* reads a final card step's duration as the closing dwell. The outro
|
|
45
|
+
* carries two housekeeping interactions at step entry (`clear_cursor`
|
|
46
|
+
* and a viewport reset) so a scenario ending with a visible cursor or
|
|
47
|
+
* an active zoom never leaks that state onto the card. Neither action
|
|
48
|
+
* maps to a sound effect.
|
|
49
|
+
*
|
|
50
|
+
* Pure and non-mutating. When `titleCards` configures no card, the
|
|
51
|
+
* inputs are returned as-is (byte-identical no-op).
|
|
52
|
+
*/
|
|
53
|
+
export function applyTitleCards(steps, narrationManifest, titleCards, presenterManifest) {
|
|
54
|
+
const intro = titleCards?.intro;
|
|
55
|
+
const outro = titleCards?.outro;
|
|
56
|
+
if (!intro && !outro) {
|
|
57
|
+
return { steps, narrationManifest, presenterManifest };
|
|
58
|
+
}
|
|
59
|
+
const expandedSteps = [...steps];
|
|
60
|
+
let manifestEntries = narrationManifest ? [...narrationManifest.steps] : undefined;
|
|
61
|
+
let presenterEntries = presenterManifest ? [...presenterManifest.steps] : undefined;
|
|
62
|
+
if (intro && expandedSteps.length > 0) {
|
|
63
|
+
const introDurationMs = intro.durationMs ?? TITLE_CARD_DURATION_DEFAULT_MS;
|
|
64
|
+
const firstAuthored = expandedSteps[0];
|
|
65
|
+
expandedSteps[0] = {
|
|
66
|
+
...firstAuthored,
|
|
67
|
+
delayMs: Math.max(firstAuthored.delayMs, introDurationMs),
|
|
68
|
+
};
|
|
69
|
+
expandedSteps.unshift({
|
|
70
|
+
delayMs: 0,
|
|
71
|
+
data: cardStepData(),
|
|
72
|
+
card: { kind: "intro", ...pickCardContent(intro) },
|
|
73
|
+
});
|
|
74
|
+
manifestEntries?.unshift(null);
|
|
75
|
+
presenterEntries?.unshift(null);
|
|
76
|
+
}
|
|
77
|
+
if (outro) {
|
|
78
|
+
expandedSteps.push({
|
|
79
|
+
delayMs: FINAL_DWELL_MS,
|
|
80
|
+
data: cardStepData(),
|
|
81
|
+
card: { kind: "outro", ...pickCardContent(outro) },
|
|
82
|
+
interactions: [
|
|
83
|
+
{ atPercent: 0, type: "clear_cursor" },
|
|
84
|
+
{ atPercent: 0, type: "viewport_transition", viewportReset: true },
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
manifestEntries?.push(null);
|
|
88
|
+
presenterEntries?.push(null);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
steps: expandedSteps,
|
|
92
|
+
narrationManifest: manifestEntries ? { steps: manifestEntries } : undefined,
|
|
93
|
+
presenterManifest: presenterEntries ? { steps: presenterEntries } : undefined,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Copy only the known card fields, so a config object carrying strays
|
|
98
|
+
* (e.g. a loosely-typed steps.ts export) never smuggles them into the
|
|
99
|
+
* step list.
|
|
100
|
+
*/
|
|
101
|
+
function pickCardContent(card) {
|
|
102
|
+
const content = { title: card.title };
|
|
103
|
+
if (card.subtitle !== undefined)
|
|
104
|
+
content.subtitle = card.subtitle;
|
|
105
|
+
if (card.logoSrc !== undefined)
|
|
106
|
+
content.logoSrc = card.logoSrc;
|
|
107
|
+
if (card.ctaText !== undefined)
|
|
108
|
+
content.ctaText = card.ctaText;
|
|
109
|
+
if (card.durationMs !== undefined)
|
|
110
|
+
content.durationMs = card.durationMs;
|
|
111
|
+
return content;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=apply-title-cards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-title-cards.js","sourceRoot":"","sources":["../../src/scenario/apply-title-cards.ts"],"names":[],"mappings":"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"}
|
package/scenario/bundle.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* scenario into a single typed value.
|
|
8
8
|
*/
|
|
9
9
|
import type { NarrationManifest } from "../narration/types.js";
|
|
10
|
+
import type { PresenterManifest } from "../presenter/types.js";
|
|
11
|
+
import type { Soundtrack } from "./soundtrack.js";
|
|
10
12
|
import type { ScenarioStep } from "./types.js";
|
|
11
13
|
/**
|
|
12
14
|
* Everything the engine needs to play one scenario.
|
|
@@ -24,5 +26,18 @@ export interface ScenarioBundle<T> {
|
|
|
24
26
|
* narration (timing is purely delay-based).
|
|
25
27
|
*/
|
|
26
28
|
readonly narrationManifest?: NarrationManifest;
|
|
29
|
+
/**
|
|
30
|
+
* Audio treatment: background music with narration ducking and
|
|
31
|
+
* interaction sound effects. When `undefined`, the scenario plays
|
|
32
|
+
* silent apart from narration.
|
|
33
|
+
*/
|
|
34
|
+
readonly soundtrack?: Soundtrack;
|
|
35
|
+
/**
|
|
36
|
+
* Pre-built presenter manifest mapping step indices to avatar clip
|
|
37
|
+
* URLs and durations (generated by `scenar presenter`). When
|
|
38
|
+
* `undefined`, the scenario plays without the presenter — zero
|
|
39
|
+
* presenter DOM, zero fetched bytes.
|
|
40
|
+
*/
|
|
41
|
+
readonly presenterManifest?: PresenterManifest;
|
|
27
42
|
}
|
|
28
43
|
//# sourceMappingURL=bundle.d.ts.map
|
package/scenario/bundle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/scenario/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CAChD"}
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/scenario/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CAChD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The scenario's audio treatment beyond narration: optional background
|
|
3
|
+
* music with narration ducking, and optional interaction sound effects.
|
|
4
|
+
*
|
|
5
|
+
* Runtime mirror of the proto `SoundtrackConfig` (`ai.scenar.scenario.v1`),
|
|
6
|
+
* field for field, in camelCase — the same 1:1 relationship `StepAction`
|
|
7
|
+
* has with its proto message. Music and sound effects are independent:
|
|
8
|
+
* a scenario may use either without the other.
|
|
9
|
+
*/
|
|
10
|
+
export interface Soundtrack {
|
|
11
|
+
/**
|
|
12
|
+
* Background music asset reference. Like narration clip srcs, a
|
|
13
|
+
* relative path resolves against the scenario's own location; an
|
|
14
|
+
* absolute URL passes through unchanged. MP3 is the supported format.
|
|
15
|
+
* When `undefined`, the scenario has no music.
|
|
16
|
+
*/
|
|
17
|
+
readonly musicSrc?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Base music level while no narration is playing (0–1).
|
|
20
|
+
* Defaults to {@link MUSIC_VOLUME_DEFAULT}.
|
|
21
|
+
*/
|
|
22
|
+
readonly musicVolume?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Absolute music level while a narration clip plays (0–1) — the level
|
|
25
|
+
* the music ducks to, not a multiplier of {@link musicVolume}.
|
|
26
|
+
* Defaults to {@link DUCKING_VOLUME_DEFAULT}.
|
|
27
|
+
*/
|
|
28
|
+
readonly duckingVolume?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Enables the engine's built-in interaction sound effects (click and
|
|
31
|
+
* keystroke). Requires an explicit `true` — adding music alone never
|
|
32
|
+
* introduces sound effects.
|
|
33
|
+
*/
|
|
34
|
+
readonly sfx?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Default base music level. Clearly audible under silence without
|
|
38
|
+
* competing with interface sound effects.
|
|
39
|
+
*/
|
|
40
|
+
export declare const MUSIC_VOLUME_DEFAULT = 0.25;
|
|
41
|
+
/**
|
|
42
|
+
* Default ducked music level while narration plays. Present but firmly
|
|
43
|
+
* under the voice.
|
|
44
|
+
*/
|
|
45
|
+
export declare const DUCKING_VOLUME_DEFAULT = 0.08;
|
|
46
|
+
//# sourceMappingURL=soundtrack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundtrack.d.ts","sourceRoot":"","sources":["../../src/scenario/soundtrack.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default base music level. Clearly audible under silence without
|
|
3
|
+
* competing with interface sound effects.
|
|
4
|
+
*/
|
|
5
|
+
export const MUSIC_VOLUME_DEFAULT = 0.25;
|
|
6
|
+
/**
|
|
7
|
+
* Default ducked music level while narration plays. Present but firmly
|
|
8
|
+
* under the voice.
|
|
9
|
+
*/
|
|
10
|
+
export const DUCKING_VOLUME_DEFAULT = 0.08;
|
|
11
|
+
//# sourceMappingURL=soundtrack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundtrack.js","sourceRoot":"","sources":["../../src/scenario/soundtrack.ts"],"names":[],"mappings":"AAoCA;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC"}
|