@vestra-player/sdk 1.5.13 → 1.5.14

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/commands.js CHANGED
@@ -49,6 +49,444 @@ export const MENU_IDS = [
49
49
  "screen",
50
50
  "settings",
51
51
  ];
52
+ /**
53
+ * The submenus the player's built-in plugins declare, by key path, in menu
54
+ * order (built-in menus as in {@link MENU_IDS}, then top-level submenus).
55
+ * Menu paths merge by their English key, so a command whose path starts
56
+ * with the same keys appears in the same submenu, whatever the interface
57
+ * language; the submenu's title is the declaring plugin's translation. The
58
+ * player's own submenus (`Playback ▸ Speed`, `Playback ▸ Seek`) are not
59
+ * listed. The player's tests check that this list agrees with what its
60
+ * built-in plugins declare.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { BUILTIN_SUBMENUS } from "@vestra-player/sdk/testing";
65
+ *
66
+ * const snapshot = BUILTIN_SUBMENUS.find((menu) => menu.path.at(-1) === "Snapshot")!;
67
+ * plugin.commands.add({
68
+ * id: "snapshot-to-clipboard",
69
+ * path: ["@video", ...snapshot.path.slice(1), "Copy Snapshot"],
70
+ * run: copySnapshot,
71
+ * });
72
+ * ```
73
+ *
74
+ * @since 1.5.14
75
+ */
76
+ export const BUILTIN_SUBMENUS = Object.freeze([
77
+ { path: ["Open", "Recently Played"], plugins: ["vestra.history"] },
78
+ { path: ["Playback", "A-B Loop"], plugins: ["vestra.marks"] },
79
+ { path: ["Playback", "A-B Loop", "Loop Count"], plugins: ["vestra.marks"] },
80
+ { path: ["Playback", "Chapters and Bookmarks"], plugins: ["vestra.marks"] },
81
+ { path: ["Playback", "Playlist"], plugins: ["vestra.playlist"] },
82
+ { path: ["Playback", "Playlist", "Repeat"], plugins: ["vestra.playlist"] },
83
+ {
84
+ path: ["Playback", "Playlist", "When Opening a File"],
85
+ plugins: ["vestra.playlist"],
86
+ },
87
+ { path: ["Playback", "Resume Playback"], plugins: ["vestra.history"] },
88
+ {
89
+ path: ["Subtitles", "Online Subtitles"],
90
+ plugins: ["vestra.subtitle-online"],
91
+ },
92
+ { path: ["Subtitles", "Secondary Subtitle"], plugins: ["vestra.subtitles"] },
93
+ {
94
+ path: ["Subtitles", "Secondary Subtitle", "Position"],
95
+ plugins: ["vestra.subtitles"],
96
+ },
97
+ { path: ["Subtitles", "Subtitle Style"], plugins: ["vestra.subtitles"] },
98
+ { path: ["Subtitles", "Subtitle Track"], plugins: ["vestra.subtitles"] },
99
+ { path: ["Subtitles", "Sync"], plugins: ["vestra.subtitles"] },
100
+ { path: ["Video", "Aspect"], plugins: ["vestra.video"] },
101
+ { path: ["Video", "Crop/Stretch"], plugins: ["vestra.video"] },
102
+ { path: ["Video", "Deinterlace"], plugins: ["vestra.video"] },
103
+ { path: ["Video", "Deinterlace", "Output"], plugins: ["vestra.video"] },
104
+ { path: ["Video", "Framing"], plugins: ["vestra.video"] },
105
+ { path: ["Video", "Image Processing"], plugins: ["vestra.video"] },
106
+ { path: ["Video", "Pixel Shaders"], plugins: ["vestra.video"] },
107
+ {
108
+ path: ["Video", "Pixel Shaders", "HDR Tone Mapping"],
109
+ plugins: ["vestra.video"],
110
+ },
111
+ { path: ["Video", "Rotation"], plugins: ["vestra.video"] },
112
+ { path: ["Video", "Snapshot"], plugins: ["vestra.capture"] },
113
+ { path: ["Audio", "Audio Sync"], plugins: ["vestra.audio"] },
114
+ { path: ["Audio", "Audio Track"], plugins: ["vestra.audio"] },
115
+ { path: ["Audio", "Output Device"], plugins: ["vestra.audio"] },
116
+ { path: ["Audio", "Preset"], plugins: ["vestra.audio"] },
117
+ { path: ["Audio", "Processing"], plugins: ["vestra.audio"] },
118
+ { path: ["Screen", "Always on Top"], plugins: ["vestra.window"] },
119
+ { path: ["Screen", "When Playback Starts"], plugins: ["vestra.window"] },
120
+ {
121
+ path: ["Settings", "Appearance"],
122
+ plugins: ["vestra.preferences", "vestra.visualizer"],
123
+ },
124
+ { path: ["Settings", "Language"], plugins: ["vestra.preferences"] },
125
+ { path: ["Copy to Clipboard"], plugins: ["vestra.playback"] },
126
+ { path: ["Emulator"], plugins: ["vestra.nes"] },
127
+ ]);
128
+ /** owner | id | key path, or (title) outside the menu | bindings | panel */
129
+ const BUILTIN_COMMAND_TABLE = `
130
+ vestra.playback | open | Open File… | Ctrl+O, F3
131
+ vestra.playback | open-url | Open ▸ Open URL… | Ctrl+U
132
+ vestra.playlist | playlist.open-folder | Open ▸ Open Folder… | F2
133
+ vestra.subtitles | load | Open ▸ Open Subtitle… | Alt+O
134
+ vestra.audio | audio.load | Open ▸ Load External Audio…
135
+ vestra.history | recent.empty | Open ▸ Recently Played ▸ (No Entries)
136
+ vestra.history | recent.prune | Open ▸ Recently Played ▸ Remove Invalid Entries
137
+ vestra.history | recent.clear | Open ▸ Recently Played ▸ Clear Entries
138
+ vestra.history | recent.enabled | Open ▸ Recently Played ▸ Record Playback History
139
+ vestra.subtitles | load-secondary | Open ▸ Add Secondary Subtitle…
140
+ host | stop | Close | F4
141
+ vestra.playback | reopen | Reopen Current/Last File | Ctrl+Y
142
+ vestra.playback | copy-name | Copy to Clipboard ▸ File Name
143
+ vestra.playback | copy-folder | Copy to Clipboard ▸ Folder Path
144
+ vestra.playback | copy-path | Copy to Clipboard ▸ Full Path
145
+ host | play-pause | Playback ▸ Play/Pause | Space
146
+ host | previous | Playback ▸ Previous | PageUp, Mouse:X1
147
+ host | next | Playback ▸ Next | PageDown, Mouse:X2
148
+ host | frame-back | Playback ▸ Seek ▸ Previous Frame | D
149
+ host | frame-forward | Playback ▸ Seek ▸ Next Frame | F
150
+ vestra.playback | keyframe-back | Playback ▸ Seek ▸ Previous Keyframe | Ctrl+Shift+ArrowLeft
151
+ vestra.playback | keyframe-forward | Playback ▸ Seek ▸ Next Keyframe | Ctrl+Shift+ArrowRight
152
+ host | seek-backward | Playback ▸ Seek ▸ Back 5 s | ArrowLeft
153
+ host | seek-forward | Playback ▸ Seek ▸ Forward 5 s | ArrowRight
154
+ vestra.playback | backward-2 | Playback ▸ Seek ▸ Back 30 s | Ctrl+ArrowLeft
155
+ vestra.playback | forward-2 | Playback ▸ Seek ▸ Forward 30 s | Ctrl+ArrowRight
156
+ vestra.playback | backward-3 | Playback ▸ Seek ▸ Back 60 s | Shift+ArrowLeft
157
+ vestra.playback | forward-3 | Playback ▸ Seek ▸ Forward 60 s | Shift+ArrowRight
158
+ vestra.playback | backward-4 | Playback ▸ Seek ▸ Back 300 s | Ctrl+Alt+ArrowLeft
159
+ vestra.playback | forward-4 | Playback ▸ Seek ▸ Forward 300 s | Ctrl+Alt+ArrowRight
160
+ vestra.subtitles | dialogue-previous | Playback ▸ Seek ▸ Previous Dialogue | Home
161
+ vestra.subtitles | dialogue-next | Playback ▸ Seek ▸ Next Dialogue | End
162
+ vestra.subtitles | dialogue-current | Playback ▸ Seek ▸ Current Subtitle Start | Ctrl+Home
163
+ vestra.playback | jump-start | Playback ▸ Seek ▸ Jump to Start | Backspace
164
+ vestra.playback | time-jump | Playback ▸ Seek ▸ Seek Steps…
165
+ vestra.playback | jump | Playback ▸ Jump to Time… | G
166
+ host | rate-normal | Playback ▸ Speed ▸ Normal | Z
167
+ host | rate-down | Playback ▸ Speed ▸ Slower 0.1 | X
168
+ host | rate-up | Playback ▸ Speed ▸ Faster 0.1 | C
169
+ vestra.playback | rate-05 | Playback ▸ Speed ▸ 0.5×
170
+ vestra.playback | rate-15 | Playback ▸ Speed ▸ 1.5×
171
+ vestra.playback | rate-20 | Playback ▸ Speed ▸ 2×
172
+ vestra.playback | rate-custom | Playback ▸ Speed ▸ Custom…
173
+ vestra.playlist | playlist.add | Playback ▸ Playlist ▸ Add Files…
174
+ vestra.playlist | playlist.link | Playback ▸ Playlist ▸ Add Link…
175
+ vestra.playlist | playlist.add-folder | Playback ▸ Playlist ▸ Add Folder…
176
+ vestra.playlist | playlist.repeat-none | Playback ▸ Playlist ▸ Repeat ▸ Off
177
+ vestra.playlist | playlist.repeat-all | Playback ▸ Playlist ▸ Repeat ▸ All
178
+ vestra.playlist | playlist.repeat-one | Playback ▸ Playlist ▸ Repeat ▸ One
179
+ vestra.playlist | playlist.shuffle | Playback ▸ Playlist ▸ Shuffle
180
+ vestra.playlist | playlist.open-list | Playback ▸ Playlist ▸ Open List File…
181
+ vestra.playlist | playlist.save-list | Playback ▸ Playlist ▸ Save List…
182
+ vestra.playlist | playlist.open-mode-only | Playback ▸ Playlist ▸ When Opening a File ▸ Open Only That File
183
+ vestra.playlist | playlist.open-mode-similar | Playback ▸ Playlist ▸ When Opening a File ▸ Add Similar Files
184
+ vestra.playlist | playlist.open-mode-folder | Playback ▸ Playlist ▸ When Opening a File ▸ Add All Files in the Folder
185
+ vestra.playlist | playlist.fast-advance | Playback ▸ Playlist ▸ Fast Advance to Next
186
+ vestra.playlist | playlist.remember | Playback ▸ Playlist ▸ Remember List
187
+ vestra.playlist | playlist.confirm-clear | Playback ▸ Playlist ▸ Confirm Before Removing All
188
+ vestra.playback | prevent-sleep | Playback ▸ Disable Screen Saver While Playing
189
+ vestra.window | hide-cursor | Playback ▸ Hide Pointer While Playing
190
+ vestra.playback | hover-time | Playback ▸ Show Time on Seek Bar Hover
191
+ vestra.playback | hover-thumbnail | Playback ▸ Show Thumbnail on Seek Bar Hover
192
+ vestra.history | resume.off | Playback ▸ Resume Playback ▸ Don't Resume
193
+ vestra.history | resume.auto | Playback ▸ Resume Playback ▸ Resume Automatically
194
+ vestra.history | resume.ask | Playback ▸ Resume Playback ▸ Ask Every Time
195
+ vestra.history | resume.audio | Playback ▸ Resume Playback ▸ Also Remember Audio Files
196
+ vestra.history | resume.clear | Playback ▸ Resume Playback ▸ Clear All Saved Positions
197
+ vestra.marks | marks.list | Playback ▸ Chapters and Bookmarks ▸ Chapter and Bookmark List… | H
198
+ vestra.marks | marks.add | Playback ▸ Chapters and Bookmarks ▸ Add Bookmark | P
199
+ vestra.marks | marks.previous | Playback ▸ Chapters and Bookmarks ▸ Previous Bookmark or Chapter | Shift+PageUp
200
+ vestra.marks | marks.next | Playback ▸ Chapters and Bookmarks ▸ Next Bookmark or Chapter | Shift+PageDown
201
+ vestra.marks | marks.previous-chapter | Playback ▸ Chapters and Bookmarks ▸ Previous Chapter | Ctrl+PageUp
202
+ vestra.marks | marks.next-chapter | Playback ▸ Chapters and Bookmarks ▸ Next Chapter | Ctrl+PageDown
203
+ vestra.marks | marks.seekbar | Playback ▸ Chapters and Bookmarks ▸ Show Marks on Seek Bar
204
+ vestra.marks | ab.set-a | Playback ▸ A-B Loop ▸ Set Start Point | [
205
+ vestra.marks | ab.clear-a | Playback ▸ A-B Loop ▸ Clear Start Point | {
206
+ vestra.marks | ab.a-back | Playback ▸ A-B Loop ▸ Start Point Back 0.1 s | Ctrl+[
207
+ vestra.marks | ab.a-forward | Playback ▸ A-B Loop ▸ Start Point Forward 0.1 s | Alt+[
208
+ vestra.marks | ab.set-b | Playback ▸ A-B Loop ▸ Set End Point | ]
209
+ vestra.marks | ab.clear-b | Playback ▸ A-B Loop ▸ Clear End Point | }
210
+ vestra.marks | ab.b-back | Playback ▸ A-B Loop ▸ End Point Back 0.1 s | Ctrl+]
211
+ vestra.marks | ab.b-forward | Playback ▸ A-B Loop ▸ End Point Forward 0.1 s | Alt+]
212
+ vestra.marks | ab.back | Playback ▸ A-B Loop ▸ Move Range Back 0.1 s | Ctrl+Alt+[
213
+ vestra.marks | ab.forward | Playback ▸ A-B Loop ▸ Move Range Forward 0.1 s | Ctrl+Alt+]
214
+ vestra.marks | ab.segment | Playback ▸ A-B Loop ▸ Loop Current Chapter or Bookmark Range | Alt+\\
215
+ vestra.marks | ab.toggle | Playback ▸ A-B Loop ▸ A-B Loop On/Off | \\
216
+ vestra.marks | ab.count.endless | Playback ▸ A-B Loop ▸ Loop Count ▸ Endless
217
+ vestra.marks | ab.count.1 | Playback ▸ A-B Loop ▸ Loop Count ▸ Once
218
+ vestra.marks | ab.count.2 | Playback ▸ A-B Loop ▸ Loop Count ▸ 2 Times
219
+ vestra.marks | ab.count.3 | Playback ▸ A-B Loop ▸ Loop Count ▸ 3 Times
220
+ vestra.marks | ab.count.5 | Playback ▸ A-B Loop ▸ Loop Count ▸ 5 Times
221
+ vestra.marks | ab.count.10 | Playback ▸ A-B Loop ▸ Loop Count ▸ 10 Times
222
+ vestra.subtitles | show | Subtitles ▸ Show Subtitles | Alt+H
223
+ vestra.subtitles | track-off | Subtitles ▸ Subtitle Track ▸ Off
224
+ vestra.subtitles | track-cycle | Subtitles ▸ Subtitle Track ▸ Cycle | Alt+L
225
+ vestra.subtitles | second-off | Subtitles ▸ Secondary Subtitle ▸ Off
226
+ vestra.subtitles | second-position-top | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Top
227
+ vestra.subtitles | second-position-aboveMain | Subtitles ▸ Secondary Subtitle ▸ Position ▸ Above Main Subtitle
228
+ vestra.subtitles | bold | Subtitles ▸ Subtitle Style ▸ Bold | Alt+B
229
+ vestra.subtitles | size-up | Subtitles ▸ Subtitle Style ▸ Size + | Alt+PageUp
230
+ vestra.subtitles | size-down | Subtitles ▸ Subtitle Style ▸ Size − | Alt+PageDown
231
+ vestra.subtitles | move-up | Subtitles ▸ Subtitle Style ▸ Move Up | Alt+ArrowUp
232
+ vestra.subtitles | move-down | Subtitles ▸ Subtitle Style ▸ Move Down | Alt+ArrowDown
233
+ vestra.subtitles | move-reset | Subtitles ▸ Subtitle Style ▸ Reset Position | Alt+Home
234
+ vestra.subtitles | shadow | Subtitles ▸ Subtitle Style ▸ Shadow
235
+ vestra.subtitles | box | Subtitles ▸ Subtitle Style ▸ Opaque Box
236
+ vestra.subtitles | ass-original | Subtitles ▸ Original ASS/SSA Styles
237
+ vestra.subtitles | sync-earlier | Subtitles ▸ Sync ▸ Earlier 0.5 s | .
238
+ vestra.subtitles | sync-later | Subtitles ▸ Sync ▸ Later 0.5 s | ,
239
+ vestra.subtitles | sync-reset | Subtitles ▸ Sync ▸ Reset | /
240
+ vestra.subtitles | sync-input | Subtitles ▸ Sync ▸ Adjust Sync…
241
+ vestra.subtitle-online | search | Subtitles ▸ Online Subtitles ▸ Search and Download Subtitles…
242
+ vestra.subtitle-online | settings | Subtitles ▸ Online Subtitles ▸ Online Subtitle Settings…
243
+ vestra.subtitles | reload | Subtitles ▸ Reload Subtitles | Ctrl+Alt+Y
244
+ vestra.subtitles | refresh | Subtitles ▸ Refresh Subtitle Tracks
245
+ vestra.subtitles | tune | Subtitles ▸ Subtitle Tuning…
246
+ vestra.subtitles | settings | Subtitles ▸ Subtitle Settings…
247
+ vestra.video | video.shader.use | Video ▸ Pixel Shaders ▸ Use Shaders | Shift+P
248
+ vestra.video | video.shader.list | Video ▸ Pixel Shaders ▸ Shader List…
249
+ vestra.video | video.shader.folder | Video ▸ Pixel Shaders ▸ Open Shader Folder
250
+ vestra.video | video.shader.reload | Video ▸ Pixel Shaders ▸ Reload Shaders
251
+ vestra.video | video.hdr.auto | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Auto
252
+ vestra.video | video.hdr.off | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Off
253
+ vestra.video | video.hdr.bt.2390 | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ BT.2390
254
+ vestra.video | video.hdr.hable | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Hable
255
+ vestra.video | video.hdr.mobius | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Mobius
256
+ vestra.video | video.hdr.reinhard | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Reinhard
257
+ vestra.video | video.hdr.clip | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Clip
258
+ vestra.video | video.hdr.peak | Video ▸ Pixel Shaders ▸ HDR Tone Mapping ▸ Dynamic Peak Detection
259
+ vestra.video | video.hdr.settings | Video ▸ Pixel Shaders ▸ HDR Settings…
260
+ vestra.video | video.deinterlace.cycle | Video ▸ Deinterlace ▸ Cycle | Ctrl+I
261
+ vestra.video | video.deinterlace.auto | Video ▸ Deinterlace ▸ Auto
262
+ vestra.video | video.deinterlace.on | Video ▸ Deinterlace ▸ Always
263
+ vestra.video | video.deinterlace.off | Video ▸ Deinterlace ▸ Never
264
+ vestra.video | video.deinterlace.output.frame | Video ▸ Deinterlace ▸ Output ▸ By Frame
265
+ vestra.video | video.deinterlace.output.field | Video ▸ Deinterlace ▸ Output ▸ By Field (Double Rate)
266
+ vestra.video | video.fit.keep | Video ▸ Aspect ▸ Keep Aspect Ratio
267
+ vestra.video | video.fit.stretch | Video ▸ Aspect ▸ Ignore Aspect Ratio
268
+ vestra.video | video.fit.fill | Video ▸ Aspect ▸ Fill Window (Crop Excess)
269
+ vestra.video | video.aspect.cycle | Video ▸ Aspect ▸ Cycle Aspect Ratio | Shift+F6
270
+ vestra.video | video.aspect.default | Video ▸ Aspect ▸ Default (Source)
271
+ vestra.video | video.aspect.0 | Video ▸ Aspect ▸ 4:3
272
+ vestra.video | video.aspect.1 | Video ▸ Aspect ▸ 16:9
273
+ vestra.video | video.aspect.2 | Video ▸ Aspect ▸ 16:10
274
+ vestra.video | video.aspect.3 | Video ▸ Aspect ▸ 1.85:1
275
+ vestra.video | video.aspect.4 | Video ▸ Aspect ▸ 2.35:1
276
+ vestra.video | video.aspect.custom | Video ▸ Aspect ▸ Custom (x:y)
277
+ vestra.video | video.aspect.edit | Video ▸ Aspect ▸ Custom Aspect Ratio…
278
+ vestra.video | video.reframe.none | Video ▸ Crop/Stretch ▸ None
279
+ vestra.video | video.reframe.pad.0 | Video ▸ Crop/Stretch ▸ Stretch to 4:3
280
+ vestra.video | video.reframe.pad.1 | Video ▸ Crop/Stretch ▸ Stretch to 16:9
281
+ vestra.video | video.reframe.pad.2 | Video ▸ Crop/Stretch ▸ Stretch to 16:10
282
+ vestra.video | video.reframe.pad.3 | Video ▸ Crop/Stretch ▸ Stretch to 1.85:1
283
+ vestra.video | video.reframe.pad.4 | Video ▸ Crop/Stretch ▸ Stretch to 2.35:1
284
+ vestra.video | video.reframe.crop.0 | Video ▸ Crop/Stretch ▸ Crop to 4:3
285
+ vestra.video | video.reframe.crop.1 | Video ▸ Crop/Stretch ▸ Crop to 16:9
286
+ vestra.video | video.reframe.crop.2 | Video ▸ Crop/Stretch ▸ Crop to 16:10
287
+ vestra.video | video.reframe.crop.3 | Video ▸ Crop/Stretch ▸ Crop to 1.85:1
288
+ vestra.video | video.reframe.crop.4 | Video ▸ Crop/Stretch ▸ Crop to 2.35:1
289
+ vestra.video | video.reframe.reset | Video ▸ Crop/Stretch ▸ Reset Position
290
+ vestra.video | video.reframe.left | Video ▸ Crop/Stretch ▸ Move Left
291
+ vestra.video | video.reframe.right | Video ▸ Crop/Stretch ▸ Move Right
292
+ vestra.video | video.reframe.up | Video ▸ Crop/Stretch ▸ Move Up
293
+ vestra.video | video.reframe.down | Video ▸ Crop/Stretch ▸ Move Down
294
+ vestra.video | video.frame.reset | Video ▸ Framing ▸ Reset Framing | Numpad5, Alt+Backspace
295
+ vestra.video | video.frame.zoom-in | Video ▸ Framing ▸ Zoom In | Numpad9, Alt+Plus
296
+ vestra.video | video.frame.zoom-out | Video ▸ Framing ▸ Zoom Out | Numpad1, Alt+-
297
+ vestra.video | video.frame.right | Video ▸ Framing ▸ Pan → | Ctrl+Numpad6, Alt+ArrowRight
298
+ vestra.video | video.frame.left | Video ▸ Framing ▸ Pan ← | Ctrl+Numpad4, Alt+ArrowLeft
299
+ vestra.video | video.frame.up | Video ▸ Framing ▸ Pan ↑ | Ctrl+Numpad8, Alt+ArrowUp
300
+ vestra.video | video.frame.down | Video ▸ Framing ▸ Pan ↓ | Ctrl+Numpad2, Alt+ArrowDown
301
+ vestra.video | video.frame.centre | Video ▸ Framing ▸ Center Frame | Ctrl+Numpad5
302
+ vestra.video | video.flip.vertical | Video ▸ Image Processing ▸ Flip Vertically | Ctrl+P
303
+ vestra.video | video.flip.horizontal | Video ▸ Image Processing ▸ Flip Horizontally | Ctrl+Z
304
+ vestra.video | video.gaussian | Video ▸ Image Processing ▸ Gaussian Blur | Ctrl+B
305
+ vestra.video | video.sharpen | Video ▸ Image Processing ▸ Sharpen | Ctrl+R
306
+ vestra.video | video.edge | Video ▸ Image Processing ▸ Edge Sharpen
307
+ vestra.video | video.deblock | Video ▸ Image Processing ▸ Deblock | Ctrl+H
308
+ vestra.video | video.deband | Video ▸ Image Processing ▸ Deband
309
+ vestra.video | video.denoise.d3 | Video ▸ Image Processing ▸ 3D Denoise | Ctrl+N
310
+ vestra.video | video.denoise.gradual | Video ▸ Image Processing ▸ Gradual Denoise
311
+ vestra.video | video.denoise.temporal | Video ▸ Image Processing ▸ Temporal Denoise | Ctrl+M
312
+ vestra.video | video.frame-blend | Video ▸ Image Processing ▸ Frame Doubling
313
+ vestra.video | video.interpolation | Video ▸ Image Processing ▸ Motion Interpolation
314
+ vestra.video | video.rotate.cycle | Video ▸ Rotation ▸ Cycle | Alt+K
315
+ vestra.video | video.rotate.0 | Video ▸ Rotation ▸ No Rotation
316
+ vestra.video | video.rotate.90 | Video ▸ Rotation ▸ 90°
317
+ vestra.video | video.rotate.180 | Video ▸ Rotation ▸ 180°
318
+ vestra.video | video.rotate.270 | Video ▸ Rotation ▸ 270°
319
+ vestra.capture | capture.save | Video ▸ Snapshot ▸ Save Current Frame | Ctrl+E
320
+ vestra.capture | capture.saveAs | Video ▸ Snapshot ▸ Save Current Frame As…
321
+ vestra.capture | capture.copy | Video ▸ Snapshot ▸ Copy Current Frame | Ctrl+C
322
+ vestra.capture | capture.saveScreen | Video ▸ Snapshot ▸ Save Rendered Frame | Ctrl+Alt+E
323
+ vestra.capture | capture.saveScreenAs | Video ▸ Snapshot ▸ Save Rendered Frame As…
324
+ vestra.capture | capture.copyScreen | Video ▸ Snapshot ▸ Copy Rendered Frame | Ctrl+Alt+C
325
+ vestra.capture | capture.burst | Video ▸ Snapshot ▸ Burst… | Ctrl+G
326
+ vestra.capture | capture.clip | Video ▸ Snapshot ▸ Export Clip…
327
+ vestra.capture | capture.tasks | Video ▸ Snapshot ▸ Export Tasks…
328
+ vestra.capture | capture.format.png | Video ▸ Snapshot ▸ Capture as PNG
329
+ vestra.capture | capture.format.jpeg | Video ▸ Snapshot ▸ Capture as JPEG
330
+ vestra.capture | capture.format.bmp | Video ▸ Snapshot ▸ Capture as BMP
331
+ vestra.capture | capture.screenSubtitles | Video ▸ Snapshot ▸ Include Subtitles in Rendered Frame
332
+ vestra.capture | capture.settings | Video ▸ Snapshot ▸ Snapshot Settings…
333
+ vestra.capture | capture.folder | Video ▸ Snapshot ▸ Snapshot Folder…
334
+ vestra.capture | capture.openFolder | Video ▸ Snapshot ▸ Open Snapshot Folder
335
+ vestra.video | video.picture | Video ▸ Picture Adjustments…
336
+ vestra.video | video.reset | Video ▸ Reset | Q
337
+ vestra.video | video.brightness.down | Video ▸ Brightness -1% | W
338
+ vestra.video | video.brightness.up | Video ▸ Brightness +1% | E
339
+ vestra.video | video.contrast.down | Video ▸ Contrast -1% | R
340
+ vestra.video | video.contrast.up | Video ▸ Contrast +1% | T
341
+ vestra.video | video.saturation.down | Video ▸ Saturation -1% | Y
342
+ vestra.video | video.saturation.up | Video ▸ Saturation +1% | U
343
+ vestra.video | video.hue.down | Video ▸ Hue -1% | I
344
+ vestra.video | video.hue.up | Video ▸ Hue +1% | O
345
+ host | volume-up | Audio ▸ Volume + | ArrowUp, Mouse:WheelUp
346
+ host | volume-down | Audio ▸ Volume − | ArrowDown, Mouse:WheelDown
347
+ host | mute | Audio ▸ Mute | M
348
+ vestra.audio | audio.workbench | Audio ▸ Audio Workbench…
349
+ vestra.audio | audio.track.none | Audio ▸ Audio Track ▸ No Audio Tracks
350
+ vestra.audio | audio.track.cycle | Audio ▸ Audio Track ▸ Cycle Tracks | Alt+A
351
+ vestra.audio | audio.channels.stereo | Audio ▸ Audio Track ▸ Stereo
352
+ vestra.audio | audio.channels.left | Audio ▸ Audio Track ▸ Left Channel
353
+ vestra.audio | audio.channels.right | Audio ▸ Audio Track ▸ Right Channel
354
+ vestra.audio | audio.channels.mono | Audio ▸ Audio Track ▸ Mono Mix
355
+ vestra.audio | audio.channels.swap | Audio ▸ Audio Track ▸ Swap Left and Right
356
+ vestra.audio | audio.device.none | Audio ▸ Output Device ▸ No Output Devices
357
+ vestra.audio | audio.equalizer | Audio ▸ Equalizer | Shift+E
358
+ vestra.audio | audio.preset.0 | Audio ▸ Preset ▸ Flat
359
+ vestra.audio | audio.preset.1 | Audio ▸ Preset ▸ Voice
360
+ vestra.audio | audio.preset.2 | Audio ▸ Preset ▸ Music
361
+ vestra.audio | audio.preset.3 | Audio ▸ Preset ▸ Cinema
362
+ vestra.audio | audio.sync.earlier | Audio ▸ Audio Sync ▸ 50 ms Earlier | >
363
+ vestra.audio | audio.sync.later | Audio ▸ Audio Sync ▸ 50 ms Later | <
364
+ vestra.audio | audio.sync.reset | Audio ▸ Audio Sync ▸ Reset | ?
365
+ vestra.audio | audio.sync.keep.none | Audio ▸ Audio Sync ▸ Don't Keep
366
+ vestra.audio | audio.sync.keep.session | Audio ▸ Audio Sync ▸ Keep for This Run
367
+ vestra.audio | audio.sync.keep.always | Audio ▸ Audio Sync ▸ Always Keep
368
+ vestra.audio | audio.normalize | Audio ▸ Processing ▸ Normalize | Shift+N
369
+ vestra.audio | audio.clarity | Audio ▸ Processing ▸ Crystalizer | Shift+C
370
+ vestra.audio | audio.reset | Audio ▸ Reset
371
+ vestra.visualizer | audio-cover | Audio ▸ Show Album Cover for Audio Only
372
+ vestra.nes | nes.open | Emulator ▸ Open NES ROM…
373
+ vestra.nes | nes.stop | Emulator ▸ Stop NES
374
+ vestra.nes | nes.window | Emulator ▸ NES Tools…
375
+ host | fullscreen | Toggle Fullscreen | Enter, Alt+Enter, F11, Mouse:LeftDoubleClick
376
+ vestra.window | pip | Screen ▸ Picture-in-Picture
377
+ vestra.window | mini | Screen ▸ Mini Size | \`
378
+ vestra.window | size.0.5 | Screen ▸ 0.5× | 1
379
+ vestra.window | size.1 | Screen ▸ 1× | 2
380
+ vestra.window | size.1.5 | Screen ▸ 1.5× | 3
381
+ vestra.window | size.2 | Screen ▸ 2× | 4
382
+ vestra.window | fit | Screen ▸ Fit to Video Aspect Ratio | 8
383
+ vestra.window | auto.off | Screen ▸ When Playback Starts ▸ Don't Resize
384
+ vestra.window | auto.0.5 | Screen ▸ When Playback Starts ▸ 0.5×
385
+ vestra.window | auto.1 | Screen ▸ When Playback Starts ▸ 1×
386
+ vestra.window | auto.1.5 | Screen ▸ When Playback Starts ▸ 1.5×
387
+ vestra.window | auto.2 | Screen ▸ When Playback Starts ▸ 2×
388
+ vestra.window | auto.fit | Screen ▸ When Playback Starts ▸ Fit to Video Aspect Ratio
389
+ vestra.window | auto.once | Screen ▸ When Playback Starts ▸ Only Once
390
+ vestra.window | top.cycle | Screen ▸ Always on Top ▸ Cycle Mode | Ctrl+T
391
+ vestra.window | top.never | Screen ▸ Always on Top ▸ Never
392
+ vestra.window | top.always | Screen ▸ Always on Top ▸ Always
393
+ vestra.window | top.playing | Screen ▸ Always on Top ▸ While Playing
394
+ vestra.window | top.fullscreen | Screen ▸ Always on Top ▸ While Playing in Fullscreen
395
+ vestra.playlist | playlist.visibility | Playlist | F6
396
+ vestra.info | info.toggle | Playback Info | Tab
397
+ vestra.info | info.properties | Playback Properties… | Ctrl+F1
398
+ vestra.workshop | workshop.open | Vestra Player AI…
399
+ vestra.store | open | Plugin Store…
400
+ vestra.preferences | options | Settings ▸ Options… | F5
401
+ vestra.hotkeys | keys | Settings ▸ Keyboard Shortcuts…
402
+ vestra.hotkeys | mouse | Settings ▸ Mouse…
403
+ vestra.hotkeys | ignore-defaults | Settings ▸ Ignore Default Shortcuts
404
+ vestra.plugins | manage | Settings ▸ Plugin Manager…
405
+ vestra.preferences | theme.vestra | Settings ▸ Appearance ▸ Vestra Dark
406
+ vestra.preferences | theme.vestra-light | Settings ▸ Appearance ▸ Vestra Light
407
+ vestra.visualizer | idle-logo | Settings ▸ Appearance ▸ Show Logo When Idle
408
+ vestra.visualizer | choose-logo | Settings ▸ Appearance ▸ Choose Logo Image…
409
+ vestra.visualizer | reset-logo | Settings ▸ Appearance ▸ Restore Default Logo
410
+ vestra.preferences | language.system | Settings ▸ Language ▸ Follow System
411
+ vestra.preferences | language.en | Settings ▸ Language ▸ English
412
+ vestra.preferences | language.zh-Hans | Settings ▸ Language ▸ 简体中文
413
+ vestra.preferences | language.ja | Settings ▸ Language ▸ 日本語
414
+ vestra.preferences | language.ko | Settings ▸ Language ▸ 한국어
415
+ vestra.preferences | language.de | Settings ▸ Language ▸ Deutsch
416
+ vestra.preferences | language.fr | Settings ▸ Language ▸ Français
417
+ vestra.preferences | language.es | Settings ▸ Language ▸ Español
418
+ vestra.info | info.about | About Vestra Player… | F1
419
+ host | quit | Quit | Cmd+Q
420
+ host | exit-fullscreen | (Leave Fullscreen) | Escape
421
+ vestra.info | info.brief | (Brief Info) | Shift+Tab
422
+ vestra.playlist | playlist.play | (Play) | Enter, P | panel
423
+ vestra.playlist | playlist.list-add | (Add Files…) | Ctrl+I | panel
424
+ vestra.playlist | playlist.list-add-folder | (Add Folder…) | Ctrl+O | panel
425
+ vestra.playlist | playlist.list-link | (Add Link…) | Ctrl+U | panel
426
+ vestra.playlist | playlist.remove | (Remove Selected) | Delete, Backspace | panel
427
+ vestra.playlist | playlist.remove-unselected | (Remove Unselected) | Ctrl+Delete | panel
428
+ vestra.playlist | playlist.remove-invalid | (Remove Invalid Items) | Ctrl+T | panel
429
+ vestra.playlist | playlist.clear | (Remove All) | Alt+Delete | panel
430
+ vestra.playlist | playlist.reveal | (Show in Finder) | Ctrl+F | panel
431
+ vestra.playlist | playlist.move-top | (Move to Top) | Ctrl+Home | panel
432
+ vestra.playlist | playlist.move-up | (Move Up) | Ctrl+ArrowUp | panel
433
+ vestra.playlist | playlist.move-down | (Move Down) | Ctrl+ArrowDown | panel
434
+ vestra.playlist | playlist.move-bottom | (Move to Bottom) | Ctrl+End | panel
435
+ vestra.playlist | playlist.sort-ascending | (Ascending) | Ctrl+1 | panel
436
+ vestra.playlist | playlist.sort-descending | (Descending) | Ctrl+2 | panel
437
+ vestra.playlist | playlist.sort-title | (By Title) | Ctrl+3 | panel
438
+ vestra.playlist | playlist.sort-filename | (By File Name) | Ctrl+4 | panel
439
+ vestra.playlist | playlist.sort-extension | (By Extension) | Ctrl+5 | panel
440
+ vestra.playlist | playlist.sort-size | (By Size) | Ctrl+6 | panel
441
+ vestra.playlist | playlist.sort-duration | (By Duration) | Ctrl+7 | panel
442
+ vestra.playlist | playlist.sort-date | (By Date) | Ctrl+8 | panel
443
+ vestra.playlist | playlist.sort-shuffle | (Random Order) | Ctrl+9 | panel
444
+ vestra.playlist | playlist.sort-folder | (By Folder) | Ctrl+0 | panel
445
+ vestra.playlist | playlist.sort-path | (Sort by Path)
446
+ vestra.playlist | playlist.sort-reverse | (Reverse Current Order)
447
+ vestra.playlist | playlist.select-all | (Select All) | Ctrl+A | panel
448
+ vestra.playlist | playlist.search | (Search) | Ctrl+S | panel
449
+ vestra.playlist | playlist.list-open-list | (Open List File…) | F3 | panel
450
+ vestra.playlist | playlist.list-save-list | (Save List…) | F2 | panel
451
+ vestra.playlist | playlist.close | (Close List) | F6 | panel
452
+ vestra.playlist | playlist.settings | (Playlist Settings…) | F5 | panel
453
+ `;
454
+ /**
455
+ * The commands the player and its built-in plugins register when the
456
+ * player starts with nothing open, in menu order (commands outside the main
457
+ * menu last): their key paths, default bindings and owners. Use it to pick
458
+ * a menu place and default keys that do not collide with the player's (the
459
+ * user's own changes come on top; see {@link @vestra-player/sdk!Bindings | Bindings}). Menu items built
460
+ * from content (tracks, recent files, output devices) are not listed; their
461
+ * placeholders (`No Audio Tracks`) are. The player's tests check that this
462
+ * list agrees with what the player and its built-in plugins register.
463
+ *
464
+ * @example
465
+ * ```ts
466
+ * import assert from "node:assert/strict";
467
+ * import { BUILTIN_COMMANDS } from "@vestra-player/sdk/testing";
468
+ *
469
+ * const taken = BUILTIN_COMMANDS.filter((command) => command.focus === null)
470
+ * .flatMap((command) => command.bindings);
471
+ * assert.ok(!taken.includes("Ctrl+K"));
472
+ * ```
473
+ *
474
+ * @since 1.5.14
475
+ */
476
+ export const BUILTIN_COMMANDS = Object.freeze(BUILTIN_COMMAND_TABLE.trim()
477
+ .split("\n")
478
+ .map((line) => {
479
+ const [owner = "", id = "", menu = "", keys = "", focus = ""] = line.split(" | ");
480
+ const path = menu.startsWith("(") ? [] : menu.split(" ▸ ");
481
+ return Object.freeze({
482
+ owner,
483
+ id,
484
+ path: Object.freeze(path),
485
+ title: path.at(-1) ?? menu.slice(1, -1),
486
+ bindings: Object.freeze(keys ? keys.split(", ") : []),
487
+ focus: focus === "panel" ? "panel" : null,
488
+ });
489
+ }));
52
490
  export function commandClient(transport) {
53
491
  return {
54
492
  register: (id, revision, declaration, state) => transport.request("commands.register", {
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The colours of the player's palettes, by `Theme` colour token (without the
3
+ * `Theme.` prefix): `vestra`, the dark default, and `vestra-light` (player
4
+ * 0.4.0). The player sets one of them on every view; a plugin reads the
5
+ * colours through `Theme` in its Slint files and never needs these values.
6
+ * They are here for the documentation (Reference: theme) and for tests that
7
+ * check a design against both palettes.
8
+ *
9
+ * Current values: a later player may adjust them, a token keeps its
10
+ * meaning. The `vestra` values are also the defaults of the SDK's copy of
11
+ * the palette (`slint/palette.slint`); the player's tests check both
12
+ * palettes against its own.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { THEME_PALETTES } from "@vestra-player/sdk/testing";
17
+ *
18
+ * const accent = THEME_PALETTES["vestra-light"].accent; // "#d4128a"
19
+ * ```
20
+ *
21
+ * @since 1.5.14
22
+ */
23
+ export declare const THEME_PALETTES: Readonly<Record<"vestra" | "vestra-light", Readonly<Record<string, string>>>>;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * The colours of the player's palettes, by `Theme` colour token (without the
3
+ * `Theme.` prefix): `vestra`, the dark default, and `vestra-light` (player
4
+ * 0.4.0). The player sets one of them on every view; a plugin reads the
5
+ * colours through `Theme` in its Slint files and never needs these values.
6
+ * They are here for the documentation (Reference: theme) and for tests that
7
+ * check a design against both palettes.
8
+ *
9
+ * Current values: a later player may adjust them, a token keeps its
10
+ * meaning. The `vestra` values are also the defaults of the SDK's copy of
11
+ * the palette (`slint/palette.slint`); the player's tests check both
12
+ * palettes against its own.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { THEME_PALETTES } from "@vestra-player/sdk/testing";
17
+ *
18
+ * const accent = THEME_PALETTES["vestra-light"].accent; // "#d4128a"
19
+ * ```
20
+ *
21
+ * @since 1.5.14
22
+ */
23
+ export const THEME_PALETTES = Object.freeze({
24
+ vestra: Object.freeze({
25
+ "bg-bar": "#16141c",
26
+ "bg-video": "#0a090e",
27
+ "bg-list": "#1a1821",
28
+ "bg-panel": "#201d28",
29
+ line: "#2b2734",
30
+ "hover-bg": "#28232f",
31
+ "press-bg": "#110f16",
32
+ "selected-bg": "#2f2840",
33
+ text: "#f5f3fa",
34
+ "text-dim": "#8e88a0",
35
+ "text-list": "#bdb8cb",
36
+ "text-played": "#6e6980",
37
+ accent: "#f72aa6",
38
+ "accent-press": "#c41a83",
39
+ "accent-disabled": "#5a1d48",
40
+ "icon-disabled": "#3b3646",
41
+ playing: "#2bb6ff",
42
+ "button-bg": "#2f2a3b",
43
+ "button-hover": "#3a3448",
44
+ "button-press": "#25202e",
45
+ "button-disabled": "#1b1922",
46
+ danger: "#ff5a5f",
47
+ }),
48
+ "vestra-light": Object.freeze({
49
+ "bg-bar": "#f7f6fa",
50
+ "bg-video": "#0e0d12",
51
+ "bg-list": "#ffffff",
52
+ "bg-panel": "#f1eff5",
53
+ line: "#dcd8e4",
54
+ "hover-bg": "#e9e6f0",
55
+ "press-bg": "#dcd8e6",
56
+ "selected-bg": "#efe4fb",
57
+ text: "#1c1924",
58
+ "text-dim": "#6f6a7f",
59
+ "text-list": "#3b3748",
60
+ "text-played": "#9a95a8",
61
+ accent: "#d4128a",
62
+ "accent-press": "#a80d6c",
63
+ "accent-disabled": "#ecbcd9",
64
+ "icon-disabled": "#c9c5d2",
65
+ playing: "#0773ba",
66
+ "button-bg": "#e6e3ec",
67
+ "button-hover": "#dcd8e4",
68
+ "button-press": "#cfcadb",
69
+ "button-disabled": "#efedf3",
70
+ danger: "#c42b2b",
71
+ }),
72
+ });
@@ -11,8 +11,12 @@ export { createPlugin } from "./plugin/index.ts";
11
11
  export type { PluginInstance, PluginManifest } from "./plugin/index.ts";
12
12
  export { HostError } from "./wire.ts";
13
13
  export type { Json, Transport } from "./wire.ts";
14
- export { API_VERSION, CAPABILITIES } from "./capabilities.ts";
15
- export { COMMAND_LIMITS, MENU_IDS } from "./commands.ts";
14
+ export { API_VERSION, CAPABILITIES, CAPABILITY_INFO, MESSAGE_LIMIT, } from "./capabilities.ts";
15
+ export { BUILTIN_COMMANDS, BUILTIN_SUBMENUS, COMMAND_LIMITS, MENU_IDS, } from "./commands.ts";
16
+ export { BINDING_INPUTS } from "./plugin/bindings.ts";
17
+ export { OSD_LIMITS } from "./plugin/osd.ts";
18
+ export { SECRET_LIMITS } from "./plugin/services.ts";
19
+ export { THEME_PALETTES } from "./palettes.ts";
16
20
  export { Catalog, HOST_ZH_HANS, LIST_SEPARATORS, LOCALES, MENU_KEYS, matchLocale, parsePo, rewriteSlint, renderText, scanSlint, TEXT_LIMITS, textKey, textProblem, } from "./i18n.ts";
17
21
  export { MANIFEST_FIELDS, MANIFEST_LIMITS } from "./manifest.ts";
18
22
  export { MARKDOWN_LIMITS } from "./plugin/markdown.ts";
@@ -9,8 +9,12 @@
9
9
  */
10
10
  export { createPlugin } from "./plugin/index.js";
11
11
  export { HostError } from "./wire.js";
12
- export { API_VERSION, CAPABILITIES } from "./capabilities.js";
13
- export { COMMAND_LIMITS, MENU_IDS } from "./commands.js";
12
+ export { API_VERSION, CAPABILITIES, CAPABILITY_INFO, MESSAGE_LIMIT, } from "./capabilities.js";
13
+ export { BUILTIN_COMMANDS, BUILTIN_SUBMENUS, COMMAND_LIMITS, MENU_IDS, } from "./commands.js";
14
+ export { BINDING_INPUTS } from "./plugin/bindings.js";
15
+ export { OSD_LIMITS } from "./plugin/osd.js";
16
+ export { SECRET_LIMITS } from "./plugin/services.js";
17
+ export { THEME_PALETTES } from "./palettes.js";
14
18
  export { Catalog, HOST_ZH_HANS, LIST_SEPARATORS, LOCALES, MENU_KEYS, matchLocale, parsePo, rewriteSlint, renderText, scanSlint, TEXT_LIMITS, textKey, textProblem, } from "./i18n.js";
15
19
  export { MANIFEST_FIELDS, MANIFEST_LIMITS } from "./manifest.js";
16
20
  export { MARKDOWN_LIMITS } from "./plugin/markdown.js";
@@ -1,5 +1,50 @@
1
1
  import type { ScopeImpl } from "./scope.ts";
2
2
  import type { Bindings } from "./types.ts";
3
+ /**
4
+ * The names a binding (`CommandOptions.bindings`, `Bindings.set`) is made
5
+ * of, as the player's binding parser accepts them. A binding is
6
+ * `{ modifier "+" } input`: modifiers in the order of `modifiers`, each at
7
+ * most once, then one input. An input is a name of `letters`, `digits`,
8
+ * `functionKeys`, `named` or `mouse`, or one other printable character that
9
+ * is not a letter, digit, space or `+` (`">"`, `"["`, `"/"`), written as
10
+ * typed, never with `Shift` (`">"`, not `"Shift+."`; `"!"`, not
11
+ * `"Shift+1"`). Anything else fails with code `invalid`. The player's tests
12
+ * check that these agree with the player.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { BINDING_INPUTS } from "@vestra-player/sdk/testing";
17
+ *
18
+ * assert.ok(BINDING_INPUTS.named.includes("PageUp"));
19
+ * assert.ok(BINDING_INPUTS.mouse.includes("Mouse:WheelUp"));
20
+ * ```
21
+ *
22
+ * @since 1.5.14
23
+ */
24
+ export declare const BINDING_INPUTS: Readonly<{
25
+ /**
26
+ * Modifiers, in the order a binding writes them. `Cmd` is ⌘ on macOS and
27
+ * the Windows logo key on Windows; on macOS `Ctrl` also matches ⌘.
28
+ */
29
+ readonly modifiers: readonly ["Ctrl", "Alt", "Shift", "Cmd"];
30
+ /** Letter keys, by key name whatever the case: `A` to `Z`. */
31
+ readonly letters: readonly string[];
32
+ /** Digit keys of the main keyboard: `0` to `9`. */
33
+ readonly digits: readonly string[];
34
+ /** Function keys: `F1` to `F24`. */
35
+ readonly functionKeys: string[];
36
+ /**
37
+ * Other named keys, matched by the physical key. `Plus` is the `+` key
38
+ * however it is typed; the `Numpad…` names are the numeric keypad only,
39
+ * never the main keyboard.
40
+ */
41
+ readonly named: readonly ["Space", "Enter", "Tab", "Escape", "Backspace", "Delete", "Insert", "Home", "End", "PageUp", "PageDown", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Plus", ...string[], "NumpadPlus", "NumpadMinus", "NumpadMultiply", "NumpadDivide", "NumpadEnter", "NumpadDecimal"];
42
+ /**
43
+ * Mouse inputs on the video area. `:LeftHalf` and `:RightHalf` tell the
44
+ * halves of the video apart for a double click.
45
+ */
46
+ readonly mouse: readonly ["Mouse:LeftClick", "Mouse:LeftDoubleClick", "Mouse:LeftDoubleClick:LeftHalf", "Mouse:LeftDoubleClick:RightHalf", "Mouse:MiddleClick", "Mouse:X1", "Mouse:X2", "Mouse:WheelUp", "Mouse:WheelDown", "Mouse:WheelLeft", "Mouse:WheelRight"];
47
+ }>;
3
48
  /** Throws `invalid` unless `text` is a canonical binding; returns it unchanged. */
4
49
  export declare function canonical(text: string): string;
5
50
  export declare function checkBindings(bindings: readonly string[]): string[];