@segnavia/format 0.3.0 → 0.5.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/dist/deck.d.ts ADDED
@@ -0,0 +1,522 @@
1
+ import { z } from "zod";
2
+ //#region src/deck.d.ts
3
+ export declare const Size: z.ZodObject<{
4
+ width: z.ZodNumber;
5
+ height: z.ZodNumber;
6
+ }, z.core.$strip>;
7
+ export type Size = z.infer<typeof Size>;
8
+ export declare const Box: z.ZodObject<{
9
+ x: z.ZodNumber;
10
+ y: z.ZodNumber;
11
+ width: z.ZodNumber;
12
+ height: z.ZodNumber;
13
+ }, z.core.$strip>;
14
+ export type Box = z.infer<typeof Box>;
15
+ export declare const Point: z.ZodObject<{
16
+ x: z.ZodNumber;
17
+ y: z.ZodNumber;
18
+ }, z.core.$strip>;
19
+ export declare const Annotation: z.ZodObject<{
20
+ ring: z.ZodNullable<z.ZodObject<{
21
+ x: z.ZodNumber;
22
+ y: z.ZodNumber;
23
+ width: z.ZodNumber;
24
+ height: z.ZodNumber;
25
+ }, z.core.$strip>>;
26
+ badge: z.ZodNullable<z.ZodObject<{
27
+ center: z.ZodObject<{
28
+ x: z.ZodNumber;
29
+ y: z.ZodNumber;
30
+ }, z.core.$strip>;
31
+ number: z.ZodNumber;
32
+ }, z.core.$strip>>;
33
+ arrow: z.ZodNullable<z.ZodObject<{
34
+ head: z.ZodObject<{
35
+ x: z.ZodNumber;
36
+ y: z.ZodNumber;
37
+ }, z.core.$strip>;
38
+ tail: z.ZodObject<{
39
+ x: z.ZodNumber;
40
+ y: z.ZodNumber;
41
+ }, z.core.$strip>;
42
+ label: z.ZodNullable<z.ZodString>;
43
+ }, z.core.$strip>>;
44
+ }, z.core.$strip>;
45
+ export type Annotation = z.infer<typeof Annotation>;
46
+ export declare const SHOT_KEY: RegExp;
47
+ export declare const Shot: z.ZodObject<{
48
+ key: z.ZodString;
49
+ title: z.ZodString;
50
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
51
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
52
+ file: z.ZodString;
53
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
54
+ size: z.ZodObject<{
55
+ width: z.ZodNumber;
56
+ height: z.ZodNumber;
57
+ }, z.core.$strip>;
58
+ scale: z.ZodNumber;
59
+ dir: z.ZodDefault<z.ZodEnum<{
60
+ ltr: "ltr";
61
+ rtl: "rtl";
62
+ }>>;
63
+ annotations: z.ZodArray<z.ZodObject<{
64
+ ring: z.ZodNullable<z.ZodObject<{
65
+ x: z.ZodNumber;
66
+ y: z.ZodNumber;
67
+ width: z.ZodNumber;
68
+ height: z.ZodNumber;
69
+ }, z.core.$strip>>;
70
+ badge: z.ZodNullable<z.ZodObject<{
71
+ center: z.ZodObject<{
72
+ x: z.ZodNumber;
73
+ y: z.ZodNumber;
74
+ }, z.core.$strip>;
75
+ number: z.ZodNumber;
76
+ }, z.core.$strip>>;
77
+ arrow: z.ZodNullable<z.ZodObject<{
78
+ head: z.ZodObject<{
79
+ x: z.ZodNumber;
80
+ y: z.ZodNumber;
81
+ }, z.core.$strip>;
82
+ tail: z.ZodObject<{
83
+ x: z.ZodNumber;
84
+ y: z.ZodNumber;
85
+ }, z.core.$strip>;
86
+ label: z.ZodNullable<z.ZodString>;
87
+ }, z.core.$strip>>;
88
+ }, z.core.$strip>>;
89
+ capturedAt: z.ZodString;
90
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
91
+ }, z.core.$strip>;
92
+ export type Shot = z.infer<typeof Shot>;
93
+ export declare const PublishedShot: z.ZodObject<{
94
+ src: z.ZodString;
95
+ shot: z.ZodObject<{
96
+ key: z.ZodString;
97
+ title: z.ZodString;
98
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
99
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
100
+ file: z.ZodString;
101
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
102
+ size: z.ZodObject<{
103
+ width: z.ZodNumber;
104
+ height: z.ZodNumber;
105
+ }, z.core.$strip>;
106
+ scale: z.ZodNumber;
107
+ dir: z.ZodDefault<z.ZodEnum<{
108
+ ltr: "ltr";
109
+ rtl: "rtl";
110
+ }>>;
111
+ annotations: z.ZodArray<z.ZodObject<{
112
+ ring: z.ZodNullable<z.ZodObject<{
113
+ x: z.ZodNumber;
114
+ y: z.ZodNumber;
115
+ width: z.ZodNumber;
116
+ height: z.ZodNumber;
117
+ }, z.core.$strip>>;
118
+ badge: z.ZodNullable<z.ZodObject<{
119
+ center: z.ZodObject<{
120
+ x: z.ZodNumber;
121
+ y: z.ZodNumber;
122
+ }, z.core.$strip>;
123
+ number: z.ZodNumber;
124
+ }, z.core.$strip>>;
125
+ arrow: z.ZodNullable<z.ZodObject<{
126
+ head: z.ZodObject<{
127
+ x: z.ZodNumber;
128
+ y: z.ZodNumber;
129
+ }, z.core.$strip>;
130
+ tail: z.ZodObject<{
131
+ x: z.ZodNumber;
132
+ y: z.ZodNumber;
133
+ }, z.core.$strip>;
134
+ label: z.ZodNullable<z.ZodString>;
135
+ }, z.core.$strip>>;
136
+ }, z.core.$strip>>;
137
+ capturedAt: z.ZodString;
138
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
139
+ }, z.core.$strip>;
140
+ }, z.core.$strip>;
141
+ export type PublishedShot = z.infer<typeof PublishedShot>;
142
+ export declare const Word: z.ZodObject<{
143
+ text: z.ZodString;
144
+ startMs: z.ZodNumber;
145
+ endMs: z.ZodNumber;
146
+ }, z.core.$strip>;
147
+ export type Word = z.infer<typeof Word>;
148
+ export declare const Cue: z.ZodObject<{
149
+ word: z.ZodNumber;
150
+ annotation: z.ZodNumber;
151
+ untilWord: z.ZodOptional<z.ZodNumber>;
152
+ }, z.core.$strip>;
153
+ export type Cue = z.infer<typeof Cue>;
154
+ export declare const Narration: z.ZodObject<{
155
+ text: z.ZodString;
156
+ lang: z.ZodOptional<z.ZodString>;
157
+ dir: z.ZodOptional<z.ZodEnum<{
158
+ ltr: "ltr";
159
+ rtl: "rtl";
160
+ auto: "auto";
161
+ }>>;
162
+ voice: z.ZodOptional<z.ZodString>;
163
+ words: z.ZodArray<z.ZodObject<{
164
+ text: z.ZodString;
165
+ startMs: z.ZodNumber;
166
+ endMs: z.ZodNumber;
167
+ }, z.core.$strip>>;
168
+ durationMs: z.ZodNumber;
169
+ audio: z.ZodNullable<z.ZodString>;
170
+ live: z.ZodDefault<z.ZodBoolean>;
171
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
172
+ word: z.ZodNumber;
173
+ annotation: z.ZodNumber;
174
+ untilWord: z.ZodOptional<z.ZodNumber>;
175
+ }, z.core.$strip>>>;
176
+ }, z.core.$strip>;
177
+ export type Narration = z.infer<typeof Narration>;
178
+ export declare const SlideContent: z.ZodDiscriminatedUnion<[z.ZodObject<{
179
+ kind: z.ZodLiteral<"html">;
180
+ html: z.ZodString;
181
+ }, z.core.$strip>, z.ZodObject<{
182
+ kind: z.ZodLiteral<"url">;
183
+ src: z.ZodString;
184
+ }, z.core.$strip>, z.ZodObject<{
185
+ kind: z.ZodLiteral<"shot">;
186
+ src: z.ZodString;
187
+ shot: z.ZodObject<{
188
+ key: z.ZodString;
189
+ title: z.ZodString;
190
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
191
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
192
+ file: z.ZodString;
193
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
194
+ size: z.ZodObject<{
195
+ width: z.ZodNumber;
196
+ height: z.ZodNumber;
197
+ }, z.core.$strip>;
198
+ scale: z.ZodNumber;
199
+ dir: z.ZodDefault<z.ZodEnum<{
200
+ ltr: "ltr";
201
+ rtl: "rtl";
202
+ }>>;
203
+ annotations: z.ZodArray<z.ZodObject<{
204
+ ring: z.ZodNullable<z.ZodObject<{
205
+ x: z.ZodNumber;
206
+ y: z.ZodNumber;
207
+ width: z.ZodNumber;
208
+ height: z.ZodNumber;
209
+ }, z.core.$strip>>;
210
+ badge: z.ZodNullable<z.ZodObject<{
211
+ center: z.ZodObject<{
212
+ x: z.ZodNumber;
213
+ y: z.ZodNumber;
214
+ }, z.core.$strip>;
215
+ number: z.ZodNumber;
216
+ }, z.core.$strip>>;
217
+ arrow: z.ZodNullable<z.ZodObject<{
218
+ head: z.ZodObject<{
219
+ x: z.ZodNumber;
220
+ y: z.ZodNumber;
221
+ }, z.core.$strip>;
222
+ tail: z.ZodObject<{
223
+ x: z.ZodNumber;
224
+ y: z.ZodNumber;
225
+ }, z.core.$strip>;
226
+ label: z.ZodNullable<z.ZodString>;
227
+ }, z.core.$strip>>;
228
+ }, z.core.$strip>>;
229
+ capturedAt: z.ZodString;
230
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
231
+ }, z.core.$strip>;
232
+ }, z.core.$strip>, z.ZodObject<{
233
+ kind: z.ZodLiteral<"shot-ref">;
234
+ href: z.ZodString;
235
+ }, z.core.$strip>, z.ZodObject<{
236
+ kind: z.ZodLiteral<"image">;
237
+ src: z.ZodString;
238
+ alt: z.ZodString;
239
+ }, z.core.$strip>], "kind">;
240
+ export type SlideContent = z.infer<typeof SlideContent>;
241
+ export declare const Slide: z.ZodObject<{
242
+ id: z.ZodString;
243
+ content: z.ZodDiscriminatedUnion<[z.ZodObject<{
244
+ kind: z.ZodLiteral<"html">;
245
+ html: z.ZodString;
246
+ }, z.core.$strip>, z.ZodObject<{
247
+ kind: z.ZodLiteral<"url">;
248
+ src: z.ZodString;
249
+ }, z.core.$strip>, z.ZodObject<{
250
+ kind: z.ZodLiteral<"shot">;
251
+ src: z.ZodString;
252
+ shot: z.ZodObject<{
253
+ key: z.ZodString;
254
+ title: z.ZodString;
255
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
256
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
257
+ file: z.ZodString;
258
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
259
+ size: z.ZodObject<{
260
+ width: z.ZodNumber;
261
+ height: z.ZodNumber;
262
+ }, z.core.$strip>;
263
+ scale: z.ZodNumber;
264
+ dir: z.ZodDefault<z.ZodEnum<{
265
+ ltr: "ltr";
266
+ rtl: "rtl";
267
+ }>>;
268
+ annotations: z.ZodArray<z.ZodObject<{
269
+ ring: z.ZodNullable<z.ZodObject<{
270
+ x: z.ZodNumber;
271
+ y: z.ZodNumber;
272
+ width: z.ZodNumber;
273
+ height: z.ZodNumber;
274
+ }, z.core.$strip>>;
275
+ badge: z.ZodNullable<z.ZodObject<{
276
+ center: z.ZodObject<{
277
+ x: z.ZodNumber;
278
+ y: z.ZodNumber;
279
+ }, z.core.$strip>;
280
+ number: z.ZodNumber;
281
+ }, z.core.$strip>>;
282
+ arrow: z.ZodNullable<z.ZodObject<{
283
+ head: z.ZodObject<{
284
+ x: z.ZodNumber;
285
+ y: z.ZodNumber;
286
+ }, z.core.$strip>;
287
+ tail: z.ZodObject<{
288
+ x: z.ZodNumber;
289
+ y: z.ZodNumber;
290
+ }, z.core.$strip>;
291
+ label: z.ZodNullable<z.ZodString>;
292
+ }, z.core.$strip>>;
293
+ }, z.core.$strip>>;
294
+ capturedAt: z.ZodString;
295
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
296
+ }, z.core.$strip>;
297
+ }, z.core.$strip>, z.ZodObject<{
298
+ kind: z.ZodLiteral<"shot-ref">;
299
+ href: z.ZodString;
300
+ }, z.core.$strip>, z.ZodObject<{
301
+ kind: z.ZodLiteral<"image">;
302
+ src: z.ZodString;
303
+ alt: z.ZodString;
304
+ }, z.core.$strip>], "kind">;
305
+ notes: z.ZodOptional<z.ZodString>;
306
+ narration: z.ZodOptional<z.ZodObject<{
307
+ text: z.ZodString;
308
+ lang: z.ZodOptional<z.ZodString>;
309
+ dir: z.ZodOptional<z.ZodEnum<{
310
+ ltr: "ltr";
311
+ rtl: "rtl";
312
+ auto: "auto";
313
+ }>>;
314
+ voice: z.ZodOptional<z.ZodString>;
315
+ words: z.ZodArray<z.ZodObject<{
316
+ text: z.ZodString;
317
+ startMs: z.ZodNumber;
318
+ endMs: z.ZodNumber;
319
+ }, z.core.$strip>>;
320
+ durationMs: z.ZodNumber;
321
+ audio: z.ZodNullable<z.ZodString>;
322
+ live: z.ZodDefault<z.ZodBoolean>;
323
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
324
+ word: z.ZodNumber;
325
+ annotation: z.ZodNumber;
326
+ untilWord: z.ZodOptional<z.ZodNumber>;
327
+ }, z.core.$strip>>>;
328
+ }, z.core.$strip>>;
329
+ beforeMs: z.ZodOptional<z.ZodNumber>;
330
+ afterMs: z.ZodOptional<z.ZodNumber>;
331
+ holdMs: z.ZodOptional<z.ZodNumber>;
332
+ }, z.core.$strip>;
333
+ export type Slide = z.infer<typeof Slide>;
334
+ export declare const DECK_SIZE: {
335
+ readonly width: 1280;
336
+ readonly height: 720;
337
+ };
338
+ export declare function annotationCueIssues(narration: Slide['narration'], annotations: number): string[];
339
+ export declare const Deck: z.ZodObject<{
340
+ title: z.ZodString;
341
+ size: z.ZodDefault<z.ZodObject<{
342
+ width: z.ZodNumber;
343
+ height: z.ZodNumber;
344
+ }, z.core.$strip>>;
345
+ scripts: z.ZodDefault<z.ZodEnum<{
346
+ refuse: "refuse";
347
+ sandboxed: "sandboxed";
348
+ }>>;
349
+ dir: z.ZodOptional<z.ZodEnum<{
350
+ ltr: "ltr";
351
+ rtl: "rtl";
352
+ auto: "auto";
353
+ }>>;
354
+ lang: z.ZodOptional<z.ZodString>;
355
+ transition: z.ZodOptional<z.ZodObject<{
356
+ kind: z.ZodEnum<{
357
+ none: "none";
358
+ fade: "fade";
359
+ slide: "slide";
360
+ }>;
361
+ duration: z.ZodDefault<z.ZodNumber>;
362
+ }, z.core.$strip>>;
363
+ playback: z.ZodOptional<z.ZodEnum<{
364
+ continuous: "continuous";
365
+ step: "step";
366
+ }>>;
367
+ captions: z.ZodOptional<z.ZodEnum<{
368
+ on: "on";
369
+ off: "off";
370
+ viewer: "viewer";
371
+ }>>;
372
+ slides: z.ZodArray<z.ZodObject<{
373
+ id: z.ZodString;
374
+ content: z.ZodDiscriminatedUnion<[z.ZodObject<{
375
+ kind: z.ZodLiteral<"html">;
376
+ html: z.ZodString;
377
+ }, z.core.$strip>, z.ZodObject<{
378
+ kind: z.ZodLiteral<"url">;
379
+ src: z.ZodString;
380
+ }, z.core.$strip>, z.ZodObject<{
381
+ kind: z.ZodLiteral<"shot">;
382
+ src: z.ZodString;
383
+ shot: z.ZodObject<{
384
+ key: z.ZodString;
385
+ title: z.ZodString;
386
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
387
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
388
+ file: z.ZodString;
389
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
390
+ size: z.ZodObject<{
391
+ width: z.ZodNumber;
392
+ height: z.ZodNumber;
393
+ }, z.core.$strip>;
394
+ scale: z.ZodNumber;
395
+ dir: z.ZodDefault<z.ZodEnum<{
396
+ ltr: "ltr";
397
+ rtl: "rtl";
398
+ }>>;
399
+ annotations: z.ZodArray<z.ZodObject<{
400
+ ring: z.ZodNullable<z.ZodObject<{
401
+ x: z.ZodNumber;
402
+ y: z.ZodNumber;
403
+ width: z.ZodNumber;
404
+ height: z.ZodNumber;
405
+ }, z.core.$strip>>;
406
+ badge: z.ZodNullable<z.ZodObject<{
407
+ center: z.ZodObject<{
408
+ x: z.ZodNumber;
409
+ y: z.ZodNumber;
410
+ }, z.core.$strip>;
411
+ number: z.ZodNumber;
412
+ }, z.core.$strip>>;
413
+ arrow: z.ZodNullable<z.ZodObject<{
414
+ head: z.ZodObject<{
415
+ x: z.ZodNumber;
416
+ y: z.ZodNumber;
417
+ }, z.core.$strip>;
418
+ tail: z.ZodObject<{
419
+ x: z.ZodNumber;
420
+ y: z.ZodNumber;
421
+ }, z.core.$strip>;
422
+ label: z.ZodNullable<z.ZodString>;
423
+ }, z.core.$strip>>;
424
+ }, z.core.$strip>>;
425
+ capturedAt: z.ZodString;
426
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
427
+ }, z.core.$strip>;
428
+ }, z.core.$strip>, z.ZodObject<{
429
+ kind: z.ZodLiteral<"shot-ref">;
430
+ href: z.ZodString;
431
+ }, z.core.$strip>, z.ZodObject<{
432
+ kind: z.ZodLiteral<"image">;
433
+ src: z.ZodString;
434
+ alt: z.ZodString;
435
+ }, z.core.$strip>], "kind">;
436
+ notes: z.ZodOptional<z.ZodString>;
437
+ narration: z.ZodOptional<z.ZodObject<{
438
+ text: z.ZodString;
439
+ lang: z.ZodOptional<z.ZodString>;
440
+ dir: z.ZodOptional<z.ZodEnum<{
441
+ ltr: "ltr";
442
+ rtl: "rtl";
443
+ auto: "auto";
444
+ }>>;
445
+ voice: z.ZodOptional<z.ZodString>;
446
+ words: z.ZodArray<z.ZodObject<{
447
+ text: z.ZodString;
448
+ startMs: z.ZodNumber;
449
+ endMs: z.ZodNumber;
450
+ }, z.core.$strip>>;
451
+ durationMs: z.ZodNumber;
452
+ audio: z.ZodNullable<z.ZodString>;
453
+ live: z.ZodDefault<z.ZodBoolean>;
454
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
455
+ word: z.ZodNumber;
456
+ annotation: z.ZodNumber;
457
+ untilWord: z.ZodOptional<z.ZodNumber>;
458
+ }, z.core.$strip>>>;
459
+ }, z.core.$strip>>;
460
+ beforeMs: z.ZodOptional<z.ZodNumber>;
461
+ afterMs: z.ZodOptional<z.ZodNumber>;
462
+ holdMs: z.ZodOptional<z.ZodNumber>;
463
+ }, z.core.$strip>>;
464
+ }, z.core.$strip>;
465
+ export type Deck = z.infer<typeof Deck>;
466
+ export type DeckInput = z.input<typeof Deck>;
467
+ export declare const Manifest: z.ZodObject<{
468
+ shots: z.ZodRecord<z.ZodString, z.ZodObject<{
469
+ key: z.ZodString;
470
+ title: z.ZodString;
471
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
472
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
473
+ file: z.ZodString;
474
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
475
+ size: z.ZodObject<{
476
+ width: z.ZodNumber;
477
+ height: z.ZodNumber;
478
+ }, z.core.$strip>;
479
+ scale: z.ZodNumber;
480
+ dir: z.ZodDefault<z.ZodEnum<{
481
+ ltr: "ltr";
482
+ rtl: "rtl";
483
+ }>>;
484
+ annotations: z.ZodArray<z.ZodObject<{
485
+ ring: z.ZodNullable<z.ZodObject<{
486
+ x: z.ZodNumber;
487
+ y: z.ZodNumber;
488
+ width: z.ZodNumber;
489
+ height: z.ZodNumber;
490
+ }, z.core.$strip>>;
491
+ badge: z.ZodNullable<z.ZodObject<{
492
+ center: z.ZodObject<{
493
+ x: z.ZodNumber;
494
+ y: z.ZodNumber;
495
+ }, z.core.$strip>;
496
+ number: z.ZodNumber;
497
+ }, z.core.$strip>>;
498
+ arrow: z.ZodNullable<z.ZodObject<{
499
+ head: z.ZodObject<{
500
+ x: z.ZodNumber;
501
+ y: z.ZodNumber;
502
+ }, z.core.$strip>;
503
+ tail: z.ZodObject<{
504
+ x: z.ZodNumber;
505
+ y: z.ZodNumber;
506
+ }, z.core.$strip>;
507
+ label: z.ZodNullable<z.ZodString>;
508
+ }, z.core.$strip>>;
509
+ }, z.core.$strip>>;
510
+ capturedAt: z.ZodString;
511
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
512
+ }, z.core.$strip>>;
513
+ updatedAt: z.ZodString;
514
+ }, z.core.$strip>;
515
+ export type Manifest = z.infer<typeof Manifest>;
516
+ export interface DeckLimits {
517
+ maxSlides?: number;
518
+ maxSlideBytes?: number;
519
+ maxNotesBytes?: number;
520
+ }
521
+ export declare function exceedsLimits(deck: Deck, limits: DeckLimits): string[];
522
+ //#endregion
package/dist/deck.js ADDED
@@ -0,0 +1,196 @@
1
+ import { Direction } from "./direction.js";
2
+ import { Scripts } from "./scripts.js";
3
+ import { SlideTiming, slideTimingIssues } from "./timing.js";
4
+ import { Transition } from "./transition.js";
5
+ import { z } from "zod";
6
+ //#region src/deck.ts
7
+ const Size = z.object({
8
+ width: z.number().int().positive(),
9
+ height: z.number().int().positive()
10
+ });
11
+ const Box = z.object({
12
+ x: z.number(),
13
+ y: z.number(),
14
+ width: z.number(),
15
+ height: z.number()
16
+ });
17
+ const Point = z.object({
18
+ x: z.number(),
19
+ y: z.number()
20
+ });
21
+ const Annotation = z.object({
22
+ ring: Box.nullable(),
23
+ badge: z.object({
24
+ center: Point,
25
+ number: z.number().int()
26
+ }).nullable(),
27
+ arrow: z.object({
28
+ head: Point,
29
+ tail: Point,
30
+ label: z.string().nullable()
31
+ }).nullable()
32
+ });
33
+ const SHOT_KEY = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
34
+ const Shot = z.object({
35
+ key: z.string().regex(SHOT_KEY),
36
+ title: z.string(),
37
+ description: z.string().nullable().default(null),
38
+ tags: z.array(z.string()).default([]),
39
+ file: z.string(),
40
+ annotatedFile: z.string().nullable().default(null),
41
+ size: Size,
42
+ scale: z.number().positive(),
43
+ dir: z.enum(["ltr", "rtl"]).default("ltr"),
44
+ annotations: z.array(Annotation),
45
+ capturedAt: z.string(),
46
+ meta: z.record(z.string(), z.unknown()).default({})
47
+ });
48
+ const PublishedShot = z.object({
49
+ src: z.string(),
50
+ shot: Shot
51
+ });
52
+ const Word = z.object({
53
+ text: z.string(),
54
+ startMs: z.number().nonnegative(),
55
+ endMs: z.number().nonnegative()
56
+ });
57
+ const Cue = z.object({
58
+ word: z.number().int().nonnegative(),
59
+ annotation: z.number().int().nonnegative(),
60
+ untilWord: z.number().int().nonnegative().optional()
61
+ });
62
+ const Narration = z.object({
63
+ text: z.string(),
64
+ lang: z.string().optional(),
65
+ dir: Direction.optional(),
66
+ voice: z.string().optional(),
67
+ words: z.array(Word),
68
+ durationMs: z.number().nonnegative(),
69
+ audio: z.string().nullable(),
70
+ live: z.boolean().default(false),
71
+ cues: z.array(Cue).default([])
72
+ });
73
+ const SlideContent = z.discriminatedUnion("kind", [
74
+ z.object({
75
+ kind: z.literal("html"),
76
+ html: z.string()
77
+ }),
78
+ z.object({
79
+ kind: z.literal("url"),
80
+ src: z.string()
81
+ }),
82
+ z.object({
83
+ kind: z.literal("shot"),
84
+ src: z.string(),
85
+ shot: Shot
86
+ }),
87
+ z.object({
88
+ kind: z.literal("shot-ref"),
89
+ href: z.string()
90
+ }),
91
+ z.object({
92
+ kind: z.literal("image"),
93
+ src: z.string(),
94
+ alt: z.string()
95
+ })
96
+ ]);
97
+ const Slide = z.object({
98
+ id: z.string(),
99
+ content: SlideContent,
100
+ notes: z.string().optional(),
101
+ narration: Narration.optional(),
102
+ beforeMs: SlideTiming.optional(),
103
+ afterMs: SlideTiming.optional(),
104
+ holdMs: SlideTiming.optional()
105
+ });
106
+ const DECK_SIZE = {
107
+ width: 1280,
108
+ height: 720
109
+ };
110
+ const DeckShape = z.object({
111
+ title: z.string(),
112
+ size: Size.default(DECK_SIZE),
113
+ scripts: Scripts.default("refuse"),
114
+ dir: Direction.optional(),
115
+ lang: z.string().optional(),
116
+ transition: Transition.optional(),
117
+ playback: z.enum(["step", "continuous"]).optional(),
118
+ captions: z.enum([
119
+ "on",
120
+ "off",
121
+ "viewer"
122
+ ]).optional(),
123
+ slides: z.array(Slide).min(1)
124
+ });
125
+ function annotationCueIssues(narration, annotations) {
126
+ if (!narration) return [];
127
+ return narration.cues.filter((cue) => cue.annotation >= annotations).map((cue) => `a cue names annotation ${cue.annotation}, but the slide has ${annotations}`);
128
+ }
129
+ function cueIssues(slide) {
130
+ const narration = slide.narration;
131
+ if (!narration) return [];
132
+ const annotations = slide.content.kind === "shot" ? slide.content.shot.annotations.length : null;
133
+ const words = narration.live ? null : narration.words.length;
134
+ const issues = [];
135
+ for (const cue of narration.cues) {
136
+ for (const word of [cue.word, cue.untilWord]) if (word !== void 0 && words !== null && word >= words) issues.push(`a cue names word ${word}, but the narration has ${words} words`);
137
+ if (slide.content.kind !== "shot" && slide.content.kind !== "shot-ref") issues.push("a cue names an annotation, but only a shot carries annotations");
138
+ }
139
+ if (annotations !== null) issues.push(...annotationCueIssues(narration, annotations));
140
+ return issues;
141
+ }
142
+ const Deck = DeckShape.superRefine((deck, ctx) => {
143
+ deck.slides.forEach((slide, index) => {
144
+ for (const message of cueIssues(slide)) ctx.addIssue({
145
+ code: "custom",
146
+ path: [
147
+ "slides",
148
+ index,
149
+ "narration",
150
+ "cues"
151
+ ],
152
+ message
153
+ });
154
+ for (const field of slideTimingIssues(slide)) {
155
+ const kind = field === "holdMs" ? "without" : "with";
156
+ ctx.addIssue({
157
+ code: "custom",
158
+ path: [
159
+ "slides",
160
+ index,
161
+ field
162
+ ],
163
+ message: `${field} is allowed only ${kind} narration`
164
+ });
165
+ }
166
+ });
167
+ const ids = /* @__PURE__ */ new Set();
168
+ deck.slides.forEach((slide, index) => {
169
+ if (ids.has(slide.id)) ctx.addIssue({
170
+ code: "custom",
171
+ path: [
172
+ "slides",
173
+ index,
174
+ "id"
175
+ ],
176
+ message: `slide id "${slide.id}" is used twice`
177
+ });
178
+ ids.add(slide.id);
179
+ });
180
+ });
181
+ const Manifest = z.object({
182
+ shots: z.record(z.string(), Shot),
183
+ updatedAt: z.string()
184
+ });
185
+ function exceedsLimits(deck, limits) {
186
+ const reasons = [];
187
+ const bytes = (text) => new TextEncoder().encode(text).length;
188
+ if (limits.maxSlides !== void 0 && deck.slides.length > limits.maxSlides) reasons.push(`the deck has ${deck.slides.length} slides; the limit is ${limits.maxSlides}`);
189
+ deck.slides.forEach((slide, index) => {
190
+ if (limits.maxSlideBytes !== void 0 && slide.content.kind === "html" && bytes(slide.content.html) > limits.maxSlideBytes) reasons.push(`slide ${index + 1} is ${bytes(slide.content.html)} bytes; the limit is ${limits.maxSlideBytes}`);
191
+ if (limits.maxNotesBytes !== void 0 && slide.notes && bytes(slide.notes) > limits.maxNotesBytes) reasons.push(`slide ${index + 1} has ${bytes(slide.notes)} bytes of notes; the limit is ${limits.maxNotesBytes}`);
192
+ });
193
+ return reasons;
194
+ }
195
+ //#endregion
196
+ export { Annotation, Box, Cue, DECK_SIZE, Deck, DeckShape, Manifest, Narration, Point, PublishedShot, SHOT_KEY, Shot, Size, Slide, SlideContent, Word, annotationCueIssues, exceedsLimits };