@markdy/core 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +100 -8
- package/dist/index.js +328 -73
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,66 @@ type LayoutDirection = "LR" | "RL" | "TB" | "BT";
|
|
|
6
6
|
type EdgeKind = "request" | "response" | "event" | "dependency";
|
|
7
7
|
type DiagramType = "architecture" | "flowchart" | "tree" | "state" | "sequence" | "constellation" | "loop" | "flywheel" | "medallion" | "quadrant" | "swimlane" | "pyramid" | "radar" | "timeline" | "gantt" | "venn" | "layers" | "nested";
|
|
8
8
|
type NodeShape = "card" | "rounded" | "diamond" | "circle" | "pill" | "terminal" | "container";
|
|
9
|
+
type PlayerProgress = "none" | "bar" | "boundary";
|
|
10
|
+
/** When and how fast the timeline runs. */
|
|
11
|
+
type PlayerPlaybackConfig = {
|
|
12
|
+
autoplay?: boolean;
|
|
13
|
+
loop?: boolean;
|
|
14
|
+
rate?: number;
|
|
15
|
+
};
|
|
16
|
+
/** Which toolbar affordances are mounted. Declaring the group opts in. */
|
|
17
|
+
type PlayerControlsConfig = {
|
|
18
|
+
play?: boolean;
|
|
19
|
+
restart?: boolean;
|
|
20
|
+
prevBeat?: boolean;
|
|
21
|
+
nextBeat?: boolean;
|
|
22
|
+
seek?: boolean;
|
|
23
|
+
speed?: boolean;
|
|
24
|
+
fit?: boolean;
|
|
25
|
+
resetView?: boolean;
|
|
26
|
+
fullscreen?: boolean;
|
|
27
|
+
svg?: boolean;
|
|
28
|
+
share?: boolean;
|
|
29
|
+
/** Speed multipliers offered by the speed buttons. */
|
|
30
|
+
speeds?: number[];
|
|
31
|
+
};
|
|
32
|
+
/** What pointer and key input do. Declaring the group opts in. */
|
|
33
|
+
type PlayerInteractionConfig = {
|
|
34
|
+
zoom?: boolean;
|
|
35
|
+
pan?: boolean;
|
|
36
|
+
clickToPlay?: boolean;
|
|
37
|
+
doubleClickToReset?: boolean;
|
|
38
|
+
/** Window-level shortcuts; opt-in because they capture space and arrows. */
|
|
39
|
+
keyboard?: boolean;
|
|
40
|
+
};
|
|
41
|
+
/** Non-interactive decoration drawn around the scene. */
|
|
42
|
+
type PlayerChromeConfig = {
|
|
43
|
+
badge?: boolean;
|
|
44
|
+
progress?: PlayerProgress;
|
|
45
|
+
progressColor?: string;
|
|
46
|
+
};
|
|
47
|
+
type PlayerConfig = {
|
|
48
|
+
playback?: PlayerPlaybackConfig;
|
|
49
|
+
controls?: PlayerControlsConfig;
|
|
50
|
+
interaction?: PlayerInteractionConfig;
|
|
51
|
+
chrome?: PlayerChromeConfig;
|
|
52
|
+
};
|
|
53
|
+
/** Fully defaulted player behavior produced by `resolvePlayer`. `enabled` is
|
|
54
|
+
* derived: a group is on when at least one of its affordances is on. */
|
|
55
|
+
type ResolvedPlayer = {
|
|
56
|
+
playback: Required<PlayerPlaybackConfig>;
|
|
57
|
+
controls: Required<PlayerControlsConfig> & {
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
};
|
|
60
|
+
interaction: Required<PlayerInteractionConfig> & {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
};
|
|
63
|
+
chrome: {
|
|
64
|
+
badge: boolean;
|
|
65
|
+
progress: PlayerProgress;
|
|
66
|
+
progressColor?: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
9
69
|
type SceneMeta = {
|
|
10
70
|
title?: string;
|
|
11
71
|
width: number;
|
|
@@ -16,19 +76,21 @@ type SceneMeta = {
|
|
|
16
76
|
duration?: number;
|
|
17
77
|
/** Opt-in diagram mode; defaults to architecture. */
|
|
18
78
|
type?: DiagramType;
|
|
19
|
-
/**
|
|
79
|
+
/** Playback, controls, interaction, and chrome behavior. Source of truth. */
|
|
80
|
+
player?: PlayerConfig;
|
|
81
|
+
/** @deprecated Mirror of `player.chrome.progressColor`. */
|
|
20
82
|
progressColor?: string;
|
|
21
|
-
/**
|
|
83
|
+
/** @deprecated Mirror of `player.controls.enabled`. */
|
|
22
84
|
controls?: boolean;
|
|
23
|
-
/**
|
|
85
|
+
/** @deprecated Mirror of `player.interaction.enabled`. */
|
|
24
86
|
interactiveViewport?: boolean;
|
|
25
|
-
/**
|
|
87
|
+
/** @deprecated Mirror of `player.playback.autoplay`. */
|
|
26
88
|
autoplay?: boolean;
|
|
27
|
-
/**
|
|
89
|
+
/** @deprecated Mirror of `player.playback.loop`. */
|
|
28
90
|
loop?: boolean;
|
|
29
|
-
/**
|
|
91
|
+
/** @deprecated Mirror of `player.chrome.badge`. */
|
|
30
92
|
copyright?: boolean;
|
|
31
|
-
/**
|
|
93
|
+
/** @deprecated Mirror of `player.playback.rate`. */
|
|
32
94
|
playbackRate?: number;
|
|
33
95
|
};
|
|
34
96
|
type NodeDecl = {
|
|
@@ -326,6 +388,36 @@ declare function parse(source: string, opts?: ParseOptions): DiagramAST;
|
|
|
326
388
|
declare function compile(ast: DiagramAST): RenderPlan;
|
|
327
389
|
declare function parseAndCompile(source: string): ParseResult;
|
|
328
390
|
|
|
391
|
+
/**
|
|
392
|
+
* Single source of truth for player configuration: schema, aliases, parsing,
|
|
393
|
+
* and default resolution. Hosts (DOM renderer, Astro, MDX, CLI) resolve
|
|
394
|
+
* behavior through `resolvePlayer` instead of re-deriving defaults.
|
|
395
|
+
*/
|
|
396
|
+
|
|
397
|
+
/** Groups own their own alias table, so `speed` can mean rate at the player
|
|
398
|
+
* root and the speed buttons inside `controls:`. */
|
|
399
|
+
type PlayerScope = "player" | "playback" | "controls" | "interaction" | "chrome";
|
|
400
|
+
declare const PLAYER_GROUPS: readonly ["playback", "controls", "interaction", "chrome"];
|
|
401
|
+
/** Keys usable as `scene` props and top-level directives. */
|
|
402
|
+
declare const PLAYER_FLAT_KEYS: string[];
|
|
403
|
+
/**
|
|
404
|
+
* Applies one `key value` pair into `config`. Returns an error message when the
|
|
405
|
+
* key is unknown or the value does not fit the setting type.
|
|
406
|
+
*/
|
|
407
|
+
declare function applyPlayerSetting(config: PlayerConfig, scope: PlayerScope, key: string, rawValue: string): string | undefined;
|
|
408
|
+
/** Host-supplied overrides always win over script configuration. */
|
|
409
|
+
type PlayerOverrides = {
|
|
410
|
+
autoplay?: boolean;
|
|
411
|
+
loop?: boolean;
|
|
412
|
+
playbackRate?: number;
|
|
413
|
+
copyright?: boolean;
|
|
414
|
+
controls?: boolean;
|
|
415
|
+
interactiveViewport?: boolean;
|
|
416
|
+
progress?: PlayerProgress;
|
|
417
|
+
progressColor?: string;
|
|
418
|
+
};
|
|
419
|
+
declare function resolvePlayer(config?: PlayerConfig, overrides?: PlayerOverrides): ResolvedPlayer;
|
|
420
|
+
|
|
329
421
|
declare const THEMES: Record<string, ThemeTokens>;
|
|
330
422
|
declare function resolveTheme(name: string): ThemeTokens;
|
|
331
423
|
|
|
@@ -537,4 +629,4 @@ declare function resolveOutputPreset(name: string): OutputPreset;
|
|
|
537
629
|
/** List all available preset names. */
|
|
538
630
|
declare function listOutputPresets(): string[];
|
|
539
631
|
|
|
540
|
-
export { ARCH_RULE_PRESETS, type AnnotationDecl, type ArchRuleType, type ArchitecturePreset, type ArchitectureRule, type ArchitectureViolation, BEAT_CUE_KEYWORDS, type BeatDecl, type BeatRange, type Box, CUE_ALIASES, type CardinalPort, type Cue, DIAGRAM_TYPES, type Diagnostic, type DiagramAST, type DiagramDiffResult, type DiagramType, type DiffChangeType, EDGE_OPERATORS, type EdgeDecl, type EdgeDiff, type EdgeKind, type EdgeSelector, type FlowSegment, type GroupBoundary, type GroupDecl, type LayoutDirection, type MarkdyConfig, NODE_ALIASES, NODE_KINDS, type NodeDecl, type NodeDiff, type NodeSelector, type NodeShape, OUTPUT_PRESETS, type OutputPreset, ParseError, type ParseOptions, type ParseResult, type PatternDecl, type Point, type PositionedNode, type RenderPlan, type RepairPromptBundle, type RoutedEdge, type RoutedPath, type RuleSeverity, SCENE_KEYS, type SceneMeta, type SemanticProfile, type SequenceActivation, type SequenceMessage, type StyleDecl, TECHNICAL_NODE_KINDS, TECHNICAL_NODE_TYPES, THEMES, type ThemeGeneratorOptions, type ThemeTokens, type TimedCue, type TreeBus, VISUAL_PRIMITIVE_TYPES, analyzeAndBuildRepairPrompt, canonicalNodeKind, classifyTechnology, compile, compilePlan, compressMarkdyToUrlHash, decompressMarkdyFromUrlHash, diffDiagramASTs, generateThemeFromBrand, getBoxPortPosition, humanizeId, listOutputPresets, nodeRole, parse, parseAndCompile, resolveArchitectureConfig, resolveOutputPreset, resolveTheme, routeOrthogonalEdge, selectOptimalPorts, validateArchitecture };
|
|
632
|
+
export { ARCH_RULE_PRESETS, type AnnotationDecl, type ArchRuleType, type ArchitecturePreset, type ArchitectureRule, type ArchitectureViolation, BEAT_CUE_KEYWORDS, type BeatDecl, type BeatRange, type Box, CUE_ALIASES, type CardinalPort, type Cue, DIAGRAM_TYPES, type Diagnostic, type DiagramAST, type DiagramDiffResult, type DiagramType, type DiffChangeType, EDGE_OPERATORS, type EdgeDecl, type EdgeDiff, type EdgeKind, type EdgeSelector, type FlowSegment, type GroupBoundary, type GroupDecl, type LayoutDirection, type MarkdyConfig, NODE_ALIASES, NODE_KINDS, type NodeDecl, type NodeDiff, type NodeSelector, type NodeShape, OUTPUT_PRESETS, type OutputPreset, PLAYER_FLAT_KEYS, PLAYER_GROUPS, ParseError, type ParseOptions, type ParseResult, type PatternDecl, type PlayerChromeConfig, type PlayerConfig, type PlayerControlsConfig, type PlayerInteractionConfig, type PlayerOverrides, type PlayerPlaybackConfig, type PlayerProgress, type PlayerScope, type Point, type PositionedNode, type RenderPlan, type RepairPromptBundle, type ResolvedPlayer, type RoutedEdge, type RoutedPath, type RuleSeverity, SCENE_KEYS, type SceneMeta, type SemanticProfile, type SequenceActivation, type SequenceMessage, type StyleDecl, TECHNICAL_NODE_KINDS, TECHNICAL_NODE_TYPES, THEMES, type ThemeGeneratorOptions, type ThemeTokens, type TimedCue, type TreeBus, VISUAL_PRIMITIVE_TYPES, analyzeAndBuildRepairPrompt, applyPlayerSetting, canonicalNodeKind, classifyTechnology, compile, compilePlan, compressMarkdyToUrlHash, decompressMarkdyFromUrlHash, diffDiagramASTs, generateThemeFromBrand, getBoxPortPosition, humanizeId, listOutputPresets, nodeRole, parse, parseAndCompile, resolveArchitectureConfig, resolveOutputPreset, resolvePlayer, resolveTheme, routeOrthogonalEdge, selectOptimalPorts, validateArchitecture };
|
package/dist/index.js
CHANGED
|
@@ -378,6 +378,270 @@ var TECHNICAL_NODE_KINDS = {
|
|
|
378
378
|
lock: "distributed"
|
|
379
379
|
};
|
|
380
380
|
|
|
381
|
+
// src/player.ts
|
|
382
|
+
function parseBooleanToken(raw) {
|
|
383
|
+
if (typeof raw === "boolean") return raw;
|
|
384
|
+
const s = String(raw).trim().toLowerCase();
|
|
385
|
+
if (["true", "on", "yes", "1"].includes(s)) return true;
|
|
386
|
+
if (["false", "off", "no", "0"].includes(s)) return false;
|
|
387
|
+
return void 0;
|
|
388
|
+
}
|
|
389
|
+
var CONTROL_KEYS = [
|
|
390
|
+
"play",
|
|
391
|
+
"restart",
|
|
392
|
+
"prevBeat",
|
|
393
|
+
"nextBeat",
|
|
394
|
+
"seek",
|
|
395
|
+
"speed",
|
|
396
|
+
"fit",
|
|
397
|
+
"resetView",
|
|
398
|
+
"fullscreen",
|
|
399
|
+
"svg",
|
|
400
|
+
"share"
|
|
401
|
+
];
|
|
402
|
+
var INTERACTION_KEYS = ["zoom", "pan", "doubleClickToReset"];
|
|
403
|
+
var PLAYBACK = {
|
|
404
|
+
autoplay: { group: "playback", key: "autoplay", type: "boolean" },
|
|
405
|
+
loop: { group: "playback", key: "loop", type: "boolean" },
|
|
406
|
+
rate: { group: "playback", key: "rate", type: "rate" },
|
|
407
|
+
speed: { group: "playback", key: "rate", type: "rate" },
|
|
408
|
+
playbackRate: { group: "playback", key: "rate", type: "rate" },
|
|
409
|
+
playback_rate: { group: "playback", key: "rate", type: "rate" }
|
|
410
|
+
};
|
|
411
|
+
var CONTROLS = {
|
|
412
|
+
controls: { group: "controls", key: "*", type: "group" },
|
|
413
|
+
play: { group: "controls", key: "play", type: "boolean" },
|
|
414
|
+
playButton: { group: "controls", key: "play", type: "boolean" },
|
|
415
|
+
play_button: { group: "controls", key: "play", type: "boolean" },
|
|
416
|
+
restart: { group: "controls", key: "restart", type: "boolean" },
|
|
417
|
+
restartButton: { group: "controls", key: "restart", type: "boolean" },
|
|
418
|
+
restart_button: { group: "controls", key: "restart", type: "boolean" },
|
|
419
|
+
prevBeat: { group: "controls", key: "prevBeat", type: "boolean" },
|
|
420
|
+
prev_beat: { group: "controls", key: "prevBeat", type: "boolean" },
|
|
421
|
+
nextBeat: { group: "controls", key: "nextBeat", type: "boolean" },
|
|
422
|
+
next_beat: { group: "controls", key: "nextBeat", type: "boolean" },
|
|
423
|
+
speeds: { group: "controls", key: "speeds", type: "rates" },
|
|
424
|
+
speedOptions: { group: "controls", key: "speeds", type: "rates" },
|
|
425
|
+
speed_options: { group: "controls", key: "speeds", type: "rates" },
|
|
426
|
+
seek: { group: "controls", key: "seek", type: "boolean" },
|
|
427
|
+
seekBar: { group: "controls", key: "seek", type: "boolean" },
|
|
428
|
+
seek_bar: { group: "controls", key: "seek", type: "boolean" },
|
|
429
|
+
speed: { group: "controls", key: "speed", type: "boolean" },
|
|
430
|
+
speedControls: { group: "controls", key: "speed", type: "boolean" },
|
|
431
|
+
speed_controls: { group: "controls", key: "speed", type: "boolean" },
|
|
432
|
+
fit: { group: "controls", key: "fit", type: "boolean" },
|
|
433
|
+
fitView: { group: "controls", key: "fit", type: "boolean" },
|
|
434
|
+
fit_view: { group: "controls", key: "fit", type: "boolean" },
|
|
435
|
+
fitViewButton: { group: "controls", key: "fit", type: "boolean" },
|
|
436
|
+
fit_view_button: { group: "controls", key: "fit", type: "boolean" },
|
|
437
|
+
resetView: { group: "controls", key: "resetView", type: "boolean" },
|
|
438
|
+
reset_view: { group: "controls", key: "resetView", type: "boolean" },
|
|
439
|
+
resetViewButton: { group: "controls", key: "resetView", type: "boolean" },
|
|
440
|
+
reset_view_button: { group: "controls", key: "resetView", type: "boolean" },
|
|
441
|
+
fullscreen: { group: "controls", key: "fullscreen", type: "boolean" },
|
|
442
|
+
fullScreen: { group: "controls", key: "fullscreen", type: "boolean" },
|
|
443
|
+
full_screen: { group: "controls", key: "fullscreen", type: "boolean" },
|
|
444
|
+
fullscreenButton: { group: "controls", key: "fullscreen", type: "boolean" },
|
|
445
|
+
fullscreen_button: { group: "controls", key: "fullscreen", type: "boolean" },
|
|
446
|
+
svg: { group: "controls", key: "svg", type: "boolean" },
|
|
447
|
+
exportSvg: { group: "controls", key: "svg", type: "boolean" },
|
|
448
|
+
export_svg: { group: "controls", key: "svg", type: "boolean" },
|
|
449
|
+
share: { group: "controls", key: "share", type: "boolean" },
|
|
450
|
+
shareLink: { group: "controls", key: "share", type: "boolean" },
|
|
451
|
+
share_link: { group: "controls", key: "share", type: "boolean" }
|
|
452
|
+
};
|
|
453
|
+
var INTERACTION = {
|
|
454
|
+
interactive: { group: "interaction", key: "*", type: "group" },
|
|
455
|
+
interactiveViewport: { group: "interaction", key: "*", type: "group" },
|
|
456
|
+
interactive_viewport: { group: "interaction", key: "*", type: "group" },
|
|
457
|
+
zoom: { group: "interaction", key: "zoom", type: "boolean" },
|
|
458
|
+
allowZoom: { group: "interaction", key: "zoom", type: "boolean" },
|
|
459
|
+
allow_zoom: { group: "interaction", key: "zoom", type: "boolean" },
|
|
460
|
+
pan: { group: "interaction", key: "pan", type: "boolean" },
|
|
461
|
+
allowPan: { group: "interaction", key: "pan", type: "boolean" },
|
|
462
|
+
allow_pan: { group: "interaction", key: "pan", type: "boolean" },
|
|
463
|
+
clickToPlay: { group: "interaction", key: "clickToPlay", type: "boolean" },
|
|
464
|
+
click_to_play: { group: "interaction", key: "clickToPlay", type: "boolean" },
|
|
465
|
+
keyboard: { group: "interaction", key: "keyboard", type: "boolean" },
|
|
466
|
+
shortcuts: { group: "interaction", key: "keyboard", type: "boolean" },
|
|
467
|
+
doubleClickToReset: { group: "interaction", key: "doubleClickToReset", type: "boolean" },
|
|
468
|
+
double_click_to_reset: { group: "interaction", key: "doubleClickToReset", type: "boolean" }
|
|
469
|
+
};
|
|
470
|
+
var CHROME = {
|
|
471
|
+
badge: { group: "chrome", key: "badge", type: "boolean" },
|
|
472
|
+
copyright: { group: "chrome", key: "badge", type: "boolean" },
|
|
473
|
+
progress: { group: "chrome", key: "progress", type: "progress" },
|
|
474
|
+
progressBar: { group: "chrome", key: "progress", type: "progress" },
|
|
475
|
+
progress_bar: { group: "chrome", key: "progress", type: "progress" },
|
|
476
|
+
sceneBoundaryProgress: { group: "chrome", key: "progress", type: "progress" },
|
|
477
|
+
progressColor: { group: "chrome", key: "progressColor", type: "color" },
|
|
478
|
+
progress_color: { group: "chrome", key: "progressColor", type: "color" },
|
|
479
|
+
progressBarColor: { group: "chrome", key: "progressColor", type: "color" },
|
|
480
|
+
progress_bar_color: { group: "chrome", key: "progressColor", type: "color" }
|
|
481
|
+
};
|
|
482
|
+
var FLAT = {
|
|
483
|
+
...PLAYBACK,
|
|
484
|
+
...CHROME,
|
|
485
|
+
controls: CONTROLS.controls,
|
|
486
|
+
playButton: CONTROLS.playButton,
|
|
487
|
+
play_button: CONTROLS.play_button,
|
|
488
|
+
restartButton: CONTROLS.restartButton,
|
|
489
|
+
restart_button: CONTROLS.restart_button,
|
|
490
|
+
seek: CONTROLS.seek,
|
|
491
|
+
seekBar: CONTROLS.seekBar,
|
|
492
|
+
seek_bar: CONTROLS.seek_bar,
|
|
493
|
+
speedControls: CONTROLS.speedControls,
|
|
494
|
+
speed_controls: CONTROLS.speed_controls,
|
|
495
|
+
speeds: CONTROLS.speeds,
|
|
496
|
+
speedOptions: CONTROLS.speedOptions,
|
|
497
|
+
speed_options: CONTROLS.speed_options,
|
|
498
|
+
prevBeat: CONTROLS.prevBeat,
|
|
499
|
+
prev_beat: CONTROLS.prev_beat,
|
|
500
|
+
nextBeat: CONTROLS.nextBeat,
|
|
501
|
+
next_beat: CONTROLS.next_beat,
|
|
502
|
+
keyboard: INTERACTION.keyboard,
|
|
503
|
+
shortcuts: INTERACTION.shortcuts,
|
|
504
|
+
fitView: CONTROLS.fitView,
|
|
505
|
+
fit_view: CONTROLS.fit_view,
|
|
506
|
+
fitViewButton: CONTROLS.fitViewButton,
|
|
507
|
+
fit_view_button: CONTROLS.fit_view_button,
|
|
508
|
+
resetViewButton: CONTROLS.resetViewButton,
|
|
509
|
+
reset_view_button: CONTROLS.reset_view_button,
|
|
510
|
+
fullscreen: CONTROLS.fullscreen,
|
|
511
|
+
fullScreen: CONTROLS.fullScreen,
|
|
512
|
+
full_screen: CONTROLS.full_screen,
|
|
513
|
+
fullscreenButton: CONTROLS.fullscreenButton,
|
|
514
|
+
fullscreen_button: CONTROLS.fullscreen_button,
|
|
515
|
+
exportSvg: CONTROLS.exportSvg,
|
|
516
|
+
export_svg: CONTROLS.export_svg,
|
|
517
|
+
shareLink: CONTROLS.shareLink,
|
|
518
|
+
share_link: CONTROLS.share_link,
|
|
519
|
+
interactive: INTERACTION.interactive,
|
|
520
|
+
interactiveViewport: INTERACTION.interactiveViewport,
|
|
521
|
+
interactive_viewport: INTERACTION.interactive_viewport,
|
|
522
|
+
allowZoom: INTERACTION.allowZoom,
|
|
523
|
+
allow_zoom: INTERACTION.allow_zoom,
|
|
524
|
+
allowPan: INTERACTION.allowPan,
|
|
525
|
+
allow_pan: INTERACTION.allow_pan,
|
|
526
|
+
clickToPlay: INTERACTION.clickToPlay,
|
|
527
|
+
click_to_play: INTERACTION.click_to_play,
|
|
528
|
+
doubleClickToReset: INTERACTION.doubleClickToReset,
|
|
529
|
+
double_click_to_reset: INTERACTION.double_click_to_reset
|
|
530
|
+
};
|
|
531
|
+
var SCOPES = {
|
|
532
|
+
player: FLAT,
|
|
533
|
+
playback: PLAYBACK,
|
|
534
|
+
controls: CONTROLS,
|
|
535
|
+
interaction: INTERACTION,
|
|
536
|
+
// `color` is unambiguous inside the block, but too generic at the root.
|
|
537
|
+
chrome: { ...CHROME, color: CHROME.progressColor }
|
|
538
|
+
};
|
|
539
|
+
var PLAYER_GROUPS = ["playback", "controls", "interaction", "chrome"];
|
|
540
|
+
var PLAYER_FLAT_KEYS = Object.keys(FLAT);
|
|
541
|
+
function applyPlayerSetting(config, scope, key, rawValue) {
|
|
542
|
+
const setting = SCOPES[scope][key];
|
|
543
|
+
if (!setting) return `unknown player property '${key}'`;
|
|
544
|
+
const value = unquote(rawValue).trim();
|
|
545
|
+
const group = config[setting.group] ??= {};
|
|
546
|
+
if (setting.type === "boolean" || setting.type === "group") {
|
|
547
|
+
const parsed = value ? parseBooleanToken(value) : true;
|
|
548
|
+
if (parsed === void 0) return `player property '${key}' expects true or false`;
|
|
549
|
+
if (setting.type === "boolean") group[setting.key] = parsed;
|
|
550
|
+
else for (const child of setting.group === "controls" ? CONTROL_KEYS : INTERACTION_KEYS) group[child] = parsed;
|
|
551
|
+
return void 0;
|
|
552
|
+
}
|
|
553
|
+
if (setting.type === "rate") {
|
|
554
|
+
const rate = Number(value);
|
|
555
|
+
if (!Number.isFinite(rate) || rate <= 0) return `player property '${key}' expects a positive number`;
|
|
556
|
+
group[setting.key] = rate;
|
|
557
|
+
return void 0;
|
|
558
|
+
}
|
|
559
|
+
if (setting.type === "rates") {
|
|
560
|
+
const rates = value.split(/[\s,]+/).filter(Boolean).map(Number);
|
|
561
|
+
if (!rates.length || rates.some((rate) => !Number.isFinite(rate) || rate <= 0)) {
|
|
562
|
+
return `player property '${key}' expects a list of positive numbers`;
|
|
563
|
+
}
|
|
564
|
+
group[setting.key] = rates;
|
|
565
|
+
return void 0;
|
|
566
|
+
}
|
|
567
|
+
if (setting.type === "color") {
|
|
568
|
+
if (value) group[setting.key] = value;
|
|
569
|
+
return void 0;
|
|
570
|
+
}
|
|
571
|
+
const mode = toProgressMode(value);
|
|
572
|
+
if (mode) group.progress = mode;
|
|
573
|
+
else if (value) group.progressColor = value;
|
|
574
|
+
return void 0;
|
|
575
|
+
}
|
|
576
|
+
function toProgressMode(value) {
|
|
577
|
+
const lower = value.toLowerCase();
|
|
578
|
+
if (lower === "none" || lower === "bar" || lower === "boundary") return lower;
|
|
579
|
+
const bool = parseBooleanToken(lower);
|
|
580
|
+
if (bool === true) return "boundary";
|
|
581
|
+
if (bool === false) return "none";
|
|
582
|
+
return void 0;
|
|
583
|
+
}
|
|
584
|
+
function unquote(raw) {
|
|
585
|
+
const value = raw.trim();
|
|
586
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
587
|
+
return value.slice(1, -1);
|
|
588
|
+
}
|
|
589
|
+
return value;
|
|
590
|
+
}
|
|
591
|
+
function resolvePlayer(config = {}, overrides = {}) {
|
|
592
|
+
const playback = config.playback ?? {};
|
|
593
|
+
const interaction = config.interaction ?? {};
|
|
594
|
+
const chrome = config.chrome ?? {};
|
|
595
|
+
const controlsOn = overrides.controls !== false && (overrides.controls === true || config.controls !== void 0);
|
|
596
|
+
const controls = {
|
|
597
|
+
play: controlsOn && (config.controls?.play ?? true),
|
|
598
|
+
restart: controlsOn && (config.controls?.restart ?? true),
|
|
599
|
+
prevBeat: controlsOn && (config.controls?.prevBeat ?? true),
|
|
600
|
+
nextBeat: controlsOn && (config.controls?.nextBeat ?? true),
|
|
601
|
+
seek: controlsOn && (config.controls?.seek ?? true),
|
|
602
|
+
speed: controlsOn && (config.controls?.speed ?? true),
|
|
603
|
+
fit: controlsOn && (config.controls?.fit ?? true),
|
|
604
|
+
resetView: controlsOn && (config.controls?.resetView ?? true),
|
|
605
|
+
fullscreen: controlsOn && (config.controls?.fullscreen ?? true),
|
|
606
|
+
svg: controlsOn && (config.controls?.svg ?? true),
|
|
607
|
+
share: controlsOn && (config.controls?.share ?? true)
|
|
608
|
+
};
|
|
609
|
+
const interactionOn = overrides.interactiveViewport !== false && (overrides.interactiveViewport === true || config.interaction !== void 0 || overrides.controls === true);
|
|
610
|
+
const gestures = {
|
|
611
|
+
zoom: interactionOn && (interaction.zoom ?? true),
|
|
612
|
+
pan: interactionOn && (interaction.pan ?? true),
|
|
613
|
+
doubleClickToReset: interactionOn && (interaction.doubleClickToReset ?? true)
|
|
614
|
+
};
|
|
615
|
+
const interactionEnabled = gestures.zoom || gestures.pan || gestures.doubleClickToReset;
|
|
616
|
+
const resetView = controls.resetView && interactionEnabled;
|
|
617
|
+
const controlsEnabled = controls.play || controls.restart || controls.prevBeat || controls.nextBeat || controls.seek || controls.speed || controls.fit || controls.resetView || controls.fullscreen || controls.svg || controls.share || resetView;
|
|
618
|
+
const rate = overrides.playbackRate ?? playback.rate ?? 1;
|
|
619
|
+
return {
|
|
620
|
+
playback: {
|
|
621
|
+
autoplay: overrides.autoplay ?? playback.autoplay ?? true,
|
|
622
|
+
loop: overrides.loop ?? playback.loop ?? true,
|
|
623
|
+
rate: Number.isFinite(rate) && rate > 0 ? rate : 1
|
|
624
|
+
},
|
|
625
|
+
controls: {
|
|
626
|
+
...controls,
|
|
627
|
+
resetView,
|
|
628
|
+
enabled: controlsEnabled,
|
|
629
|
+
speeds: config.controls?.speeds?.length ? config.controls.speeds : [0.5, 1, 2]
|
|
630
|
+
},
|
|
631
|
+
interaction: {
|
|
632
|
+
...gestures,
|
|
633
|
+
enabled: interactionEnabled,
|
|
634
|
+
clickToPlay: interaction.clickToPlay ?? true,
|
|
635
|
+
keyboard: interaction.keyboard ?? false
|
|
636
|
+
},
|
|
637
|
+
chrome: {
|
|
638
|
+
badge: overrides.copyright ?? chrome.badge ?? true,
|
|
639
|
+
progress: overrides.progress ?? chrome.progress ?? "boundary",
|
|
640
|
+
progressColor: overrides.progressColor ?? chrome.progressColor
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
|
|
381
645
|
// src/registry.ts
|
|
382
646
|
var NODE_KINDS = /* @__PURE__ */ new Set([
|
|
383
647
|
...TECHNICAL_NODE_TYPES,
|
|
@@ -433,23 +697,7 @@ var SCENE_KEYS = /* @__PURE__ */ new Set([
|
|
|
433
697
|
"direction",
|
|
434
698
|
"layout",
|
|
435
699
|
"type",
|
|
436
|
-
|
|
437
|
-
"progressBarColor",
|
|
438
|
-
"progress_color",
|
|
439
|
-
"progress_bar_color",
|
|
440
|
-
"progress",
|
|
441
|
-
"progressBar",
|
|
442
|
-
"sceneBoundaryProgress",
|
|
443
|
-
"controls",
|
|
444
|
-
"interactive",
|
|
445
|
-
"interactiveViewport",
|
|
446
|
-
"interactive_viewport",
|
|
447
|
-
"autoplay",
|
|
448
|
-
"loop",
|
|
449
|
-
"copyright",
|
|
450
|
-
"playbackRate",
|
|
451
|
-
"playback_rate",
|
|
452
|
-
"speed"
|
|
700
|
+
...PLAYER_FLAT_KEYS
|
|
453
701
|
]);
|
|
454
702
|
function nodeRole(kind) {
|
|
455
703
|
const canonical = canonicalNodeKind(kind);
|
|
@@ -2357,14 +2605,30 @@ function readIndentedBody(blocks, startIdx, parentIndent) {
|
|
|
2357
2605
|
}
|
|
2358
2606
|
return { body, nextIdx: i };
|
|
2359
2607
|
}
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2608
|
+
var PLAYER_KEYWORDS = [...PLAYER_FLAT_KEYS].sort((a, b) => b.length - a.length).join("|");
|
|
2609
|
+
var TOP_LEVEL_KEYWORDS_RE = new RegExp(
|
|
2610
|
+
`^(scene|player|layout|pattern|group|annotation|edge|beat|var|style|${PLAYER_KEYWORDS})\\b`
|
|
2611
|
+
);
|
|
2612
|
+
var PLAYER_DIRECTIVE_RE = new RegExp(`^(${PLAYER_KEYWORDS})\\b(?:\\s*[:=]?\\s*(.+))?$`);
|
|
2613
|
+
var PLAYER_GROUP_RE = /^(playback|controls|interaction|chrome)\s*:\s*$/;
|
|
2614
|
+
var PLAYER_SETTING_RE = /^(\w+)(?:\s*[:=]\s*|\s+)?(.*)$/;
|
|
2615
|
+
var PLAYER_FLAT_KEY_SET = new Set(PLAYER_FLAT_KEYS);
|
|
2616
|
+
function mirrorLegacySceneMeta(meta) {
|
|
2617
|
+
const player = meta.player;
|
|
2618
|
+
if (!player) return meta;
|
|
2619
|
+
const { playback, controls, interaction, chrome } = player;
|
|
2620
|
+
if (playback?.autoplay !== void 0) meta.autoplay = playback.autoplay;
|
|
2621
|
+
if (playback?.loop !== void 0) meta.loop = playback.loop;
|
|
2622
|
+
if (playback?.rate !== void 0) meta.playbackRate = playback.rate;
|
|
2623
|
+
if (controls) meta.controls = Object.values(controls).some(Boolean);
|
|
2624
|
+
if (interaction) {
|
|
2625
|
+
meta.interactiveViewport = Boolean(interaction.zoom ?? true) || Boolean(interaction.pan ?? true);
|
|
2626
|
+
}
|
|
2627
|
+
if (chrome?.badge !== void 0) meta.copyright = chrome.badge;
|
|
2628
|
+
if (chrome?.progress === "none") meta.progressColor = "none";
|
|
2629
|
+
else if (chrome?.progressColor !== void 0) meta.progressColor = chrome.progressColor;
|
|
2630
|
+
return meta;
|
|
2366
2631
|
}
|
|
2367
|
-
var TOP_LEVEL_KEYWORDS_RE = /^(scene|layout|pattern|group|annotation|edge|beat|var|style|controls|interactive|interactiveViewport|interactive_viewport|autoplay|loop|copyright|playbackRate|playback_rate|speed|progressColor|progressBarColor|progress_color|progress_bar_color|progress|progressBar)\b/;
|
|
2368
2632
|
function isTopLevelStatement(line) {
|
|
2369
2633
|
if (line === "}") return true;
|
|
2370
2634
|
if (TOP_LEVEL_KEYWORDS_RE.test(line)) return true;
|
|
@@ -2617,6 +2881,35 @@ function parse(source, opts = {}) {
|
|
|
2617
2881
|
const lineNo = block.line;
|
|
2618
2882
|
const unsupportedMessage = unsupportedSyntaxMessage(line);
|
|
2619
2883
|
if (unsupportedMessage) throw new ParseError(unsupportedMessage, lineNo);
|
|
2884
|
+
if (/^player\s*:\s*$/.test(line)) {
|
|
2885
|
+
const { body, nextIdx } = readIndentedBody(blocks, i + 1, block.indent);
|
|
2886
|
+
if (body.length === 0) throw new ParseError("player block requires at least one setting", lineNo);
|
|
2887
|
+
const player = meta.player ??= {};
|
|
2888
|
+
const applySetting = (scope, setting) => {
|
|
2889
|
+
const match = setting.text.match(PLAYER_SETTING_RE);
|
|
2890
|
+
const error = applyPlayerSetting(player, scope, match?.[1] ?? "", match?.[2] ?? "");
|
|
2891
|
+
if (error) diagnostics.push({ severity: "warning", message: error, line: setting.line });
|
|
2892
|
+
};
|
|
2893
|
+
let settingIdx = 0;
|
|
2894
|
+
while (settingIdx < body.length) {
|
|
2895
|
+
const setting = body[settingIdx];
|
|
2896
|
+
const groupMatch = setting.text.match(PLAYER_GROUP_RE);
|
|
2897
|
+
if (groupMatch) {
|
|
2898
|
+
const scope = groupMatch[1];
|
|
2899
|
+
const { body: childBody, nextIdx: childNextIdx } = readIndentedBody(body, settingIdx + 1, setting.indent);
|
|
2900
|
+
if (childBody.length === 0) {
|
|
2901
|
+
throw new ParseError(`player ${scope} block requires at least one setting`, setting.line);
|
|
2902
|
+
}
|
|
2903
|
+
for (const child of childBody) applySetting(scope, child);
|
|
2904
|
+
settingIdx = childNextIdx;
|
|
2905
|
+
continue;
|
|
2906
|
+
}
|
|
2907
|
+
applySetting("player", setting);
|
|
2908
|
+
settingIdx++;
|
|
2909
|
+
}
|
|
2910
|
+
i = nextIdx;
|
|
2911
|
+
continue;
|
|
2912
|
+
}
|
|
2620
2913
|
if (line.startsWith("scene")) {
|
|
2621
2914
|
const rest2 = line.slice(5).trim();
|
|
2622
2915
|
if (line.endsWith("{")) {
|
|
@@ -2643,28 +2936,9 @@ function parse(source, opts = {}) {
|
|
|
2643
2936
|
else if (k === "duration") meta.duration = Number(v);
|
|
2644
2937
|
else if (k === "theme") meta.theme = String(v);
|
|
2645
2938
|
else if (k === "direction" || k === "layout") meta.direction = String(v).toUpperCase();
|
|
2646
|
-
else if (k
|
|
2647
|
-
meta.
|
|
2648
|
-
|
|
2649
|
-
const bool = parseBooleanToken(v);
|
|
2650
|
-
if (bool !== void 0) {
|
|
2651
|
-
if (!bool) meta.progressColor = "none";
|
|
2652
|
-
} else {
|
|
2653
|
-
meta.progressColor = String(v);
|
|
2654
|
-
}
|
|
2655
|
-
} else if (k === "controls") {
|
|
2656
|
-
meta.controls = parseBooleanToken(v) ?? true;
|
|
2657
|
-
} else if (k === "interactive" || k === "interactiveViewport" || k === "interactive_viewport") {
|
|
2658
|
-
meta.interactiveViewport = parseBooleanToken(v) ?? true;
|
|
2659
|
-
} else if (k === "autoplay") {
|
|
2660
|
-
meta.autoplay = parseBooleanToken(v) ?? true;
|
|
2661
|
-
} else if (k === "loop") {
|
|
2662
|
-
meta.loop = parseBooleanToken(v) ?? true;
|
|
2663
|
-
} else if (k === "copyright") {
|
|
2664
|
-
meta.copyright = parseBooleanToken(v) ?? true;
|
|
2665
|
-
} else if (k === "playbackRate" || k === "playback_rate" || k === "speed") {
|
|
2666
|
-
const r = Number(v);
|
|
2667
|
-
if (!Number.isNaN(r) && r > 0) meta.playbackRate = r;
|
|
2939
|
+
else if (PLAYER_FLAT_KEY_SET.has(k)) {
|
|
2940
|
+
const error = applyPlayerSetting(meta.player ??= {}, "player", k, String(v));
|
|
2941
|
+
if (error) diagnostics.push({ severity: "warning", message: error, line: lineNo });
|
|
2668
2942
|
} else if (k === "type") {
|
|
2669
2943
|
const t = String(v).toLowerCase();
|
|
2670
2944
|
if (!DIAGRAM_TYPES.has(t)) {
|
|
@@ -2677,33 +2951,10 @@ function parse(source, opts = {}) {
|
|
|
2677
2951
|
i++;
|
|
2678
2952
|
continue;
|
|
2679
2953
|
}
|
|
2680
|
-
const directiveMatch = line.match(
|
|
2681
|
-
/^(controls|interactive|interactiveViewport|interactive_viewport|autoplay|loop|copyright|playbackRate|playback_rate|speed|progressColor|progressBarColor|progress_color|progress_bar_color|progress|progressBar)\b(?:\s*[:=]?\s*(.+))?$/
|
|
2682
|
-
);
|
|
2954
|
+
const directiveMatch = line.match(PLAYER_DIRECTIVE_RE);
|
|
2683
2955
|
if (directiveMatch) {
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2686
|
-
const val = rawVal.startsWith('"') && rawVal.endsWith('"') || rawVal.startsWith("'") && rawVal.endsWith("'") ? rawVal.slice(1, -1) : rawVal;
|
|
2687
|
-
if (keyword === "controls") {
|
|
2688
|
-
meta.controls = val ? parseBooleanToken(val) ?? true : true;
|
|
2689
|
-
} else if (keyword === "interactive" || keyword === "interactiveViewport" || keyword === "interactive_viewport") {
|
|
2690
|
-
meta.interactiveViewport = val ? parseBooleanToken(val) ?? true : true;
|
|
2691
|
-
} else if (keyword === "autoplay") {
|
|
2692
|
-
meta.autoplay = val ? parseBooleanToken(val) ?? true : true;
|
|
2693
|
-
} else if (keyword === "loop") {
|
|
2694
|
-
meta.loop = val ? parseBooleanToken(val) ?? true : true;
|
|
2695
|
-
} else if (keyword === "copyright") {
|
|
2696
|
-
meta.copyright = val ? parseBooleanToken(val) ?? true : true;
|
|
2697
|
-
} else if (keyword === "playbackRate" || keyword === "playback_rate" || keyword === "speed") {
|
|
2698
|
-
const r = Number(val);
|
|
2699
|
-
if (!Number.isNaN(r) && r > 0) meta.playbackRate = r;
|
|
2700
|
-
} else if (keyword === "progressColor" || keyword === "progressBarColor" || keyword === "progress_color" || keyword === "progress_bar_color" || keyword === "progress") {
|
|
2701
|
-
if (val) meta.progressColor = val;
|
|
2702
|
-
} else if (keyword === "progressBar") {
|
|
2703
|
-
const bool = parseBooleanToken(val);
|
|
2704
|
-
if (bool === false) meta.progressColor = "none";
|
|
2705
|
-
else if (val) meta.progressColor = val;
|
|
2706
|
-
}
|
|
2956
|
+
const error = applyPlayerSetting(meta.player ??= {}, "player", directiveMatch[1], directiveMatch[2] ?? "");
|
|
2957
|
+
if (error) diagnostics.push({ severity: "warning", message: error, line: lineNo });
|
|
2707
2958
|
i++;
|
|
2708
2959
|
continue;
|
|
2709
2960
|
}
|
|
@@ -2859,7 +3110,7 @@ function parse(source, opts = {}) {
|
|
|
2859
3110
|
throw new ParseError(`unexpected statement`, lineNo);
|
|
2860
3111
|
}
|
|
2861
3112
|
const ast = {
|
|
2862
|
-
meta: { ...meta, title: title || void 0 },
|
|
3113
|
+
meta: { ...mirrorLegacySceneMeta(meta), title: title || void 0 },
|
|
2863
3114
|
styles,
|
|
2864
3115
|
nodes,
|
|
2865
3116
|
edges,
|
|
@@ -3947,6 +4198,8 @@ export {
|
|
|
3947
4198
|
NODE_ALIASES,
|
|
3948
4199
|
NODE_KINDS,
|
|
3949
4200
|
OUTPUT_PRESETS,
|
|
4201
|
+
PLAYER_FLAT_KEYS,
|
|
4202
|
+
PLAYER_GROUPS,
|
|
3950
4203
|
ParseError,
|
|
3951
4204
|
SCENE_KEYS,
|
|
3952
4205
|
TECHNICAL_NODE_KINDS,
|
|
@@ -3954,6 +4207,7 @@ export {
|
|
|
3954
4207
|
THEMES,
|
|
3955
4208
|
VISUAL_PRIMITIVE_TYPES,
|
|
3956
4209
|
analyzeAndBuildRepairPrompt,
|
|
4210
|
+
applyPlayerSetting,
|
|
3957
4211
|
canonicalNodeKind,
|
|
3958
4212
|
classifyTechnology,
|
|
3959
4213
|
compile,
|
|
@@ -3970,6 +4224,7 @@ export {
|
|
|
3970
4224
|
parseAndCompile,
|
|
3971
4225
|
resolveArchitectureConfig,
|
|
3972
4226
|
resolveOutputPreset,
|
|
4227
|
+
resolvePlayer,
|
|
3973
4228
|
resolveTheme,
|
|
3974
4229
|
routeOrthogonalEdge,
|
|
3975
4230
|
selectOptimalPorts,
|
package/package.json
CHANGED