@segnavia/format 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 modstudio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ //#region src/direction.d.ts
2
+ export type TextDirection = 'ltr' | 'rtl';
3
+ export declare function firstStrongDirection(text: string): TextDirection | null;
4
+ export declare function languageDirection(lang: string | undefined): TextDirection | null;
5
+ export declare function resolveDirection(dir: 'ltr' | 'rtl' | 'auto' | undefined, lang: string | undefined, sample: string): TextDirection;
6
+ //#endregion
@@ -0,0 +1,39 @@
1
+ //#region src/direction.ts
2
+ const RTL_LETTER = /[\p{Script=Hebrew}\p{Script=Arabic}\p{Script=Syriac}\p{Script=Thaana}\p{Script=Nko}\p{Script=Samaritan}\p{Script=Mandaic}\p{Script=Adlam}\p{Script=Hanifi_Rohingya}\p{Script=Mende_Kikakui}\p{Script=Old_Hungarian}\p{Script=Imperial_Aramaic}\p{Script=Phoenician}]/u;
3
+ const LETTER = /\p{L}/u;
4
+ const RTL_LANGUAGES = /* @__PURE__ */ new Set([
5
+ "ar",
6
+ "arc",
7
+ "ckb",
8
+ "dv",
9
+ "fa",
10
+ "he",
11
+ "iw",
12
+ "ji",
13
+ "ks",
14
+ "ku",
15
+ "nqo",
16
+ "ps",
17
+ "sd",
18
+ "syr",
19
+ "ug",
20
+ "ur",
21
+ "yi"
22
+ ]);
23
+ function firstStrongDirection(text) {
24
+ for (const char of text) {
25
+ if (RTL_LETTER.test(char)) return "rtl";
26
+ if (LETTER.test(char)) return "ltr";
27
+ }
28
+ return null;
29
+ }
30
+ function languageDirection(lang) {
31
+ if (!lang) return null;
32
+ return RTL_LANGUAGES.has(lang.toLowerCase().split("-")[0] ?? "") ? "rtl" : "ltr";
33
+ }
34
+ function resolveDirection(dir, lang, sample) {
35
+ if (dir === "ltr" || dir === "rtl") return dir;
36
+ return languageDirection(lang) ?? firstStrongDirection(sample) ?? "ltr";
37
+ }
38
+ //#endregion
39
+ export { firstStrongDirection, languageDirection, resolveDirection };
@@ -0,0 +1,885 @@
1
+ import { TextDirection, firstStrongDirection, languageDirection, resolveDirection } from "./direction.js";
2
+ import { z } from "zod";
3
+ //#region src/index.d.ts
4
+ export declare const Size: z.ZodObject<{
5
+ width: z.ZodNumber;
6
+ height: z.ZodNumber;
7
+ }, z.core.$strip>;
8
+ export type Size = z.infer<typeof Size>;
9
+ export declare const Scripts: z.ZodEnum<{
10
+ refuse: "refuse";
11
+ sandboxed: "sandboxed";
12
+ }>;
13
+ export type Scripts = z.infer<typeof Scripts>;
14
+ export declare const Direction: z.ZodEnum<{
15
+ ltr: "ltr";
16
+ rtl: "rtl";
17
+ auto: "auto";
18
+ }>;
19
+ export declare const NAMED_PAPERS: readonly ["letter", "legal", "tabloid", "a3", "a4", "a5"];
20
+ export declare const Paper: z.ZodUnion<readonly [z.ZodEnum<{
21
+ letter: "letter";
22
+ legal: "legal";
23
+ tabloid: "tabloid";
24
+ a3: "a3";
25
+ a4: "a4";
26
+ a5: "a5";
27
+ }>, z.ZodObject<{
28
+ width: z.ZodNumber;
29
+ height: z.ZodNumber;
30
+ unit: z.ZodEnum<{
31
+ mm: "mm";
32
+ in: "in";
33
+ }>;
34
+ }, z.core.$strip>]>;
35
+ export type Paper = z.infer<typeof Paper>;
36
+ export declare const Margin: z.ZodObject<{
37
+ top: z.ZodDefault<z.ZodNumber>;
38
+ right: z.ZodDefault<z.ZodNumber>;
39
+ bottom: z.ZodDefault<z.ZodNumber>;
40
+ left: z.ZodDefault<z.ZodNumber>;
41
+ }, z.core.$strip>;
42
+ export declare const Print: z.ZodObject<{
43
+ paper: z.ZodUnion<readonly [z.ZodEnum<{
44
+ letter: "letter";
45
+ legal: "legal";
46
+ tabloid: "tabloid";
47
+ a3: "a3";
48
+ a4: "a4";
49
+ a5: "a5";
50
+ }>, z.ZodObject<{
51
+ width: z.ZodNumber;
52
+ height: z.ZodNumber;
53
+ unit: z.ZodEnum<{
54
+ mm: "mm";
55
+ in: "in";
56
+ }>;
57
+ }, z.core.$strip>]>;
58
+ orientation: z.ZodDefault<z.ZodEnum<{
59
+ portrait: "portrait";
60
+ landscape: "landscape";
61
+ }>>;
62
+ margin: z.ZodOptional<z.ZodObject<{
63
+ top: z.ZodDefault<z.ZodNumber>;
64
+ right: z.ZodDefault<z.ZodNumber>;
65
+ bottom: z.ZodDefault<z.ZodNumber>;
66
+ left: z.ZodDefault<z.ZodNumber>;
67
+ }, z.core.$strip>>;
68
+ }, z.core.$strip>;
69
+ export type Print = z.infer<typeof Print>;
70
+ export declare const PageSize: z.ZodUnion<readonly [z.ZodLiteral<"fluid">, z.ZodObject<{
71
+ width: z.ZodNumber;
72
+ height: z.ZodNumber;
73
+ }, z.core.$strip>, z.ZodObject<{
74
+ width: z.ZodNumber;
75
+ height: z.ZodLiteral<"auto">;
76
+ }, z.core.$strip>]>;
77
+ export type PageSize = z.infer<typeof PageSize>;
78
+ export declare const Page: z.ZodObject<{
79
+ html: z.ZodString;
80
+ size: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"fluid">, z.ZodObject<{
81
+ width: z.ZodNumber;
82
+ height: z.ZodNumber;
83
+ }, z.core.$strip>, z.ZodObject<{
84
+ width: z.ZodNumber;
85
+ height: z.ZodLiteral<"auto">;
86
+ }, z.core.$strip>]>>;
87
+ scripts: z.ZodDefault<z.ZodEnum<{
88
+ refuse: "refuse";
89
+ sandboxed: "sandboxed";
90
+ }>>;
91
+ dir: z.ZodOptional<z.ZodEnum<{
92
+ ltr: "ltr";
93
+ rtl: "rtl";
94
+ auto: "auto";
95
+ }>>;
96
+ lang: z.ZodOptional<z.ZodString>;
97
+ print: z.ZodOptional<z.ZodObject<{
98
+ paper: z.ZodUnion<readonly [z.ZodEnum<{
99
+ letter: "letter";
100
+ legal: "legal";
101
+ tabloid: "tabloid";
102
+ a3: "a3";
103
+ a4: "a4";
104
+ a5: "a5";
105
+ }>, z.ZodObject<{
106
+ width: z.ZodNumber;
107
+ height: z.ZodNumber;
108
+ unit: z.ZodEnum<{
109
+ mm: "mm";
110
+ in: "in";
111
+ }>;
112
+ }, z.core.$strip>]>;
113
+ orientation: z.ZodDefault<z.ZodEnum<{
114
+ portrait: "portrait";
115
+ landscape: "landscape";
116
+ }>>;
117
+ margin: z.ZodOptional<z.ZodObject<{
118
+ top: z.ZodDefault<z.ZodNumber>;
119
+ right: z.ZodDefault<z.ZodNumber>;
120
+ bottom: z.ZodDefault<z.ZodNumber>;
121
+ left: z.ZodDefault<z.ZodNumber>;
122
+ }, z.core.$strip>>;
123
+ }, z.core.$strip>>;
124
+ }, z.core.$strip>;
125
+ export type Page = z.infer<typeof Page>;
126
+ export type PageInput = z.input<typeof Page>;
127
+ export declare const Box: z.ZodObject<{
128
+ x: z.ZodNumber;
129
+ y: z.ZodNumber;
130
+ width: z.ZodNumber;
131
+ height: z.ZodNumber;
132
+ }, z.core.$strip>;
133
+ export type Box = z.infer<typeof Box>;
134
+ export declare const Point: z.ZodObject<{
135
+ x: z.ZodNumber;
136
+ y: z.ZodNumber;
137
+ }, z.core.$strip>;
138
+ export declare const Annotation: z.ZodObject<{
139
+ ring: z.ZodNullable<z.ZodObject<{
140
+ x: z.ZodNumber;
141
+ y: z.ZodNumber;
142
+ width: z.ZodNumber;
143
+ height: z.ZodNumber;
144
+ }, z.core.$strip>>;
145
+ badge: z.ZodNullable<z.ZodObject<{
146
+ center: z.ZodObject<{
147
+ x: z.ZodNumber;
148
+ y: z.ZodNumber;
149
+ }, z.core.$strip>;
150
+ number: z.ZodNumber;
151
+ }, z.core.$strip>>;
152
+ arrow: z.ZodNullable<z.ZodObject<{
153
+ head: z.ZodObject<{
154
+ x: z.ZodNumber;
155
+ y: z.ZodNumber;
156
+ }, z.core.$strip>;
157
+ tail: z.ZodObject<{
158
+ x: z.ZodNumber;
159
+ y: z.ZodNumber;
160
+ }, z.core.$strip>;
161
+ label: z.ZodNullable<z.ZodString>;
162
+ }, z.core.$strip>>;
163
+ }, z.core.$strip>;
164
+ export type Annotation = z.infer<typeof Annotation>;
165
+ export declare const SHOT_KEY: RegExp;
166
+ export declare const Shot: z.ZodObject<{
167
+ key: z.ZodString;
168
+ title: z.ZodString;
169
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
170
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
171
+ file: z.ZodString;
172
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
173
+ size: z.ZodObject<{
174
+ width: z.ZodNumber;
175
+ height: z.ZodNumber;
176
+ }, z.core.$strip>;
177
+ scale: z.ZodNumber;
178
+ dir: z.ZodDefault<z.ZodEnum<{
179
+ ltr: "ltr";
180
+ rtl: "rtl";
181
+ }>>;
182
+ annotations: z.ZodArray<z.ZodObject<{
183
+ ring: z.ZodNullable<z.ZodObject<{
184
+ x: z.ZodNumber;
185
+ y: z.ZodNumber;
186
+ width: z.ZodNumber;
187
+ height: z.ZodNumber;
188
+ }, z.core.$strip>>;
189
+ badge: z.ZodNullable<z.ZodObject<{
190
+ center: z.ZodObject<{
191
+ x: z.ZodNumber;
192
+ y: z.ZodNumber;
193
+ }, z.core.$strip>;
194
+ number: z.ZodNumber;
195
+ }, z.core.$strip>>;
196
+ arrow: z.ZodNullable<z.ZodObject<{
197
+ head: z.ZodObject<{
198
+ x: z.ZodNumber;
199
+ y: z.ZodNumber;
200
+ }, z.core.$strip>;
201
+ tail: z.ZodObject<{
202
+ x: z.ZodNumber;
203
+ y: z.ZodNumber;
204
+ }, z.core.$strip>;
205
+ label: z.ZodNullable<z.ZodString>;
206
+ }, z.core.$strip>>;
207
+ }, z.core.$strip>>;
208
+ capturedAt: z.ZodString;
209
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
210
+ }, z.core.$strip>;
211
+ export type Shot = z.infer<typeof Shot>;
212
+ export declare const PublishedShot: z.ZodObject<{
213
+ src: z.ZodString;
214
+ shot: z.ZodObject<{
215
+ key: z.ZodString;
216
+ title: z.ZodString;
217
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
218
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
219
+ file: z.ZodString;
220
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
221
+ size: z.ZodObject<{
222
+ width: z.ZodNumber;
223
+ height: z.ZodNumber;
224
+ }, z.core.$strip>;
225
+ scale: z.ZodNumber;
226
+ dir: z.ZodDefault<z.ZodEnum<{
227
+ ltr: "ltr";
228
+ rtl: "rtl";
229
+ }>>;
230
+ annotations: z.ZodArray<z.ZodObject<{
231
+ ring: z.ZodNullable<z.ZodObject<{
232
+ x: z.ZodNumber;
233
+ y: z.ZodNumber;
234
+ width: z.ZodNumber;
235
+ height: z.ZodNumber;
236
+ }, z.core.$strip>>;
237
+ badge: z.ZodNullable<z.ZodObject<{
238
+ center: z.ZodObject<{
239
+ x: z.ZodNumber;
240
+ y: z.ZodNumber;
241
+ }, z.core.$strip>;
242
+ number: z.ZodNumber;
243
+ }, z.core.$strip>>;
244
+ arrow: z.ZodNullable<z.ZodObject<{
245
+ head: z.ZodObject<{
246
+ x: z.ZodNumber;
247
+ y: z.ZodNumber;
248
+ }, z.core.$strip>;
249
+ tail: z.ZodObject<{
250
+ x: z.ZodNumber;
251
+ y: z.ZodNumber;
252
+ }, z.core.$strip>;
253
+ label: z.ZodNullable<z.ZodString>;
254
+ }, z.core.$strip>>;
255
+ }, z.core.$strip>>;
256
+ capturedAt: z.ZodString;
257
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
258
+ }, z.core.$strip>;
259
+ }, z.core.$strip>;
260
+ export type PublishedShot = z.infer<typeof PublishedShot>;
261
+ export declare const Word: z.ZodObject<{
262
+ text: z.ZodString;
263
+ startMs: z.ZodNumber;
264
+ endMs: z.ZodNumber;
265
+ }, z.core.$strip>;
266
+ export type Word = z.infer<typeof Word>;
267
+ export declare const Cue: z.ZodObject<{
268
+ word: z.ZodNumber;
269
+ annotation: z.ZodNumber;
270
+ untilWord: z.ZodOptional<z.ZodNumber>;
271
+ }, z.core.$strip>;
272
+ export type Cue = z.infer<typeof Cue>;
273
+ export declare const Narration: z.ZodObject<{
274
+ text: z.ZodString;
275
+ lang: z.ZodOptional<z.ZodString>;
276
+ dir: z.ZodOptional<z.ZodEnum<{
277
+ ltr: "ltr";
278
+ rtl: "rtl";
279
+ auto: "auto";
280
+ }>>;
281
+ voice: z.ZodOptional<z.ZodString>;
282
+ words: z.ZodArray<z.ZodObject<{
283
+ text: z.ZodString;
284
+ startMs: z.ZodNumber;
285
+ endMs: z.ZodNumber;
286
+ }, z.core.$strip>>;
287
+ durationMs: z.ZodNumber;
288
+ audio: z.ZodNullable<z.ZodString>;
289
+ live: z.ZodDefault<z.ZodBoolean>;
290
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
291
+ word: z.ZodNumber;
292
+ annotation: z.ZodNumber;
293
+ untilWord: z.ZodOptional<z.ZodNumber>;
294
+ }, z.core.$strip>>>;
295
+ }, z.core.$strip>;
296
+ export type Narration = z.infer<typeof Narration>;
297
+ export declare const SlideContent: z.ZodDiscriminatedUnion<[z.ZodObject<{
298
+ kind: z.ZodLiteral<"html">;
299
+ html: z.ZodString;
300
+ }, z.core.$strip>, z.ZodObject<{
301
+ kind: z.ZodLiteral<"url">;
302
+ src: z.ZodString;
303
+ }, z.core.$strip>, z.ZodObject<{
304
+ kind: z.ZodLiteral<"shot">;
305
+ src: z.ZodString;
306
+ shot: z.ZodObject<{
307
+ key: z.ZodString;
308
+ title: z.ZodString;
309
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
310
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
311
+ file: z.ZodString;
312
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
313
+ size: z.ZodObject<{
314
+ width: z.ZodNumber;
315
+ height: z.ZodNumber;
316
+ }, z.core.$strip>;
317
+ scale: z.ZodNumber;
318
+ dir: z.ZodDefault<z.ZodEnum<{
319
+ ltr: "ltr";
320
+ rtl: "rtl";
321
+ }>>;
322
+ annotations: z.ZodArray<z.ZodObject<{
323
+ ring: z.ZodNullable<z.ZodObject<{
324
+ x: z.ZodNumber;
325
+ y: z.ZodNumber;
326
+ width: z.ZodNumber;
327
+ height: z.ZodNumber;
328
+ }, z.core.$strip>>;
329
+ badge: z.ZodNullable<z.ZodObject<{
330
+ center: z.ZodObject<{
331
+ x: z.ZodNumber;
332
+ y: z.ZodNumber;
333
+ }, z.core.$strip>;
334
+ number: z.ZodNumber;
335
+ }, z.core.$strip>>;
336
+ arrow: z.ZodNullable<z.ZodObject<{
337
+ head: z.ZodObject<{
338
+ x: z.ZodNumber;
339
+ y: z.ZodNumber;
340
+ }, z.core.$strip>;
341
+ tail: z.ZodObject<{
342
+ x: z.ZodNumber;
343
+ y: z.ZodNumber;
344
+ }, z.core.$strip>;
345
+ label: z.ZodNullable<z.ZodString>;
346
+ }, z.core.$strip>>;
347
+ }, z.core.$strip>>;
348
+ capturedAt: z.ZodString;
349
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
350
+ }, z.core.$strip>;
351
+ }, z.core.$strip>, z.ZodObject<{
352
+ kind: z.ZodLiteral<"shot-ref">;
353
+ href: z.ZodString;
354
+ }, z.core.$strip>, z.ZodObject<{
355
+ kind: z.ZodLiteral<"image">;
356
+ src: z.ZodString;
357
+ alt: z.ZodString;
358
+ }, z.core.$strip>], "kind">;
359
+ export type SlideContent = z.infer<typeof SlideContent>;
360
+ export declare const Slide: z.ZodObject<{
361
+ id: z.ZodString;
362
+ content: z.ZodDiscriminatedUnion<[z.ZodObject<{
363
+ kind: z.ZodLiteral<"html">;
364
+ html: z.ZodString;
365
+ }, z.core.$strip>, z.ZodObject<{
366
+ kind: z.ZodLiteral<"url">;
367
+ src: z.ZodString;
368
+ }, z.core.$strip>, z.ZodObject<{
369
+ kind: z.ZodLiteral<"shot">;
370
+ src: z.ZodString;
371
+ shot: z.ZodObject<{
372
+ key: z.ZodString;
373
+ title: z.ZodString;
374
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
375
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
376
+ file: z.ZodString;
377
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
378
+ size: z.ZodObject<{
379
+ width: z.ZodNumber;
380
+ height: z.ZodNumber;
381
+ }, z.core.$strip>;
382
+ scale: z.ZodNumber;
383
+ dir: z.ZodDefault<z.ZodEnum<{
384
+ ltr: "ltr";
385
+ rtl: "rtl";
386
+ }>>;
387
+ annotations: z.ZodArray<z.ZodObject<{
388
+ ring: z.ZodNullable<z.ZodObject<{
389
+ x: z.ZodNumber;
390
+ y: z.ZodNumber;
391
+ width: z.ZodNumber;
392
+ height: z.ZodNumber;
393
+ }, z.core.$strip>>;
394
+ badge: z.ZodNullable<z.ZodObject<{
395
+ center: z.ZodObject<{
396
+ x: z.ZodNumber;
397
+ y: z.ZodNumber;
398
+ }, z.core.$strip>;
399
+ number: z.ZodNumber;
400
+ }, z.core.$strip>>;
401
+ arrow: z.ZodNullable<z.ZodObject<{
402
+ head: z.ZodObject<{
403
+ x: z.ZodNumber;
404
+ y: z.ZodNumber;
405
+ }, z.core.$strip>;
406
+ tail: z.ZodObject<{
407
+ x: z.ZodNumber;
408
+ y: z.ZodNumber;
409
+ }, z.core.$strip>;
410
+ label: z.ZodNullable<z.ZodString>;
411
+ }, z.core.$strip>>;
412
+ }, z.core.$strip>>;
413
+ capturedAt: z.ZodString;
414
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
415
+ }, z.core.$strip>;
416
+ }, z.core.$strip>, z.ZodObject<{
417
+ kind: z.ZodLiteral<"shot-ref">;
418
+ href: z.ZodString;
419
+ }, z.core.$strip>, z.ZodObject<{
420
+ kind: z.ZodLiteral<"image">;
421
+ src: z.ZodString;
422
+ alt: z.ZodString;
423
+ }, z.core.$strip>], "kind">;
424
+ notes: z.ZodOptional<z.ZodString>;
425
+ narration: z.ZodOptional<z.ZodObject<{
426
+ text: z.ZodString;
427
+ lang: z.ZodOptional<z.ZodString>;
428
+ dir: z.ZodOptional<z.ZodEnum<{
429
+ ltr: "ltr";
430
+ rtl: "rtl";
431
+ auto: "auto";
432
+ }>>;
433
+ voice: z.ZodOptional<z.ZodString>;
434
+ words: z.ZodArray<z.ZodObject<{
435
+ text: z.ZodString;
436
+ startMs: z.ZodNumber;
437
+ endMs: z.ZodNumber;
438
+ }, z.core.$strip>>;
439
+ durationMs: z.ZodNumber;
440
+ audio: z.ZodNullable<z.ZodString>;
441
+ live: z.ZodDefault<z.ZodBoolean>;
442
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
443
+ word: z.ZodNumber;
444
+ annotation: z.ZodNumber;
445
+ untilWord: z.ZodOptional<z.ZodNumber>;
446
+ }, z.core.$strip>>>;
447
+ }, z.core.$strip>>;
448
+ }, z.core.$strip>;
449
+ export type Slide = z.infer<typeof Slide>;
450
+ export declare const DECK_SIZE: {
451
+ readonly width: 1280;
452
+ readonly height: 720;
453
+ };
454
+ export declare function annotationCueIssues(narration: Slide['narration'], annotations: number): string[];
455
+ export declare const Deck: z.ZodObject<{
456
+ title: z.ZodString;
457
+ size: z.ZodDefault<z.ZodObject<{
458
+ width: z.ZodNumber;
459
+ height: z.ZodNumber;
460
+ }, z.core.$strip>>;
461
+ scripts: z.ZodDefault<z.ZodEnum<{
462
+ refuse: "refuse";
463
+ sandboxed: "sandboxed";
464
+ }>>;
465
+ dir: z.ZodOptional<z.ZodEnum<{
466
+ ltr: "ltr";
467
+ rtl: "rtl";
468
+ auto: "auto";
469
+ }>>;
470
+ lang: z.ZodOptional<z.ZodString>;
471
+ slides: z.ZodArray<z.ZodObject<{
472
+ id: z.ZodString;
473
+ content: z.ZodDiscriminatedUnion<[z.ZodObject<{
474
+ kind: z.ZodLiteral<"html">;
475
+ html: z.ZodString;
476
+ }, z.core.$strip>, z.ZodObject<{
477
+ kind: z.ZodLiteral<"url">;
478
+ src: z.ZodString;
479
+ }, z.core.$strip>, z.ZodObject<{
480
+ kind: z.ZodLiteral<"shot">;
481
+ src: z.ZodString;
482
+ shot: z.ZodObject<{
483
+ key: z.ZodString;
484
+ title: z.ZodString;
485
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
486
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
487
+ file: z.ZodString;
488
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
489
+ size: z.ZodObject<{
490
+ width: z.ZodNumber;
491
+ height: z.ZodNumber;
492
+ }, z.core.$strip>;
493
+ scale: z.ZodNumber;
494
+ dir: z.ZodDefault<z.ZodEnum<{
495
+ ltr: "ltr";
496
+ rtl: "rtl";
497
+ }>>;
498
+ annotations: z.ZodArray<z.ZodObject<{
499
+ ring: z.ZodNullable<z.ZodObject<{
500
+ x: z.ZodNumber;
501
+ y: z.ZodNumber;
502
+ width: z.ZodNumber;
503
+ height: z.ZodNumber;
504
+ }, z.core.$strip>>;
505
+ badge: z.ZodNullable<z.ZodObject<{
506
+ center: z.ZodObject<{
507
+ x: z.ZodNumber;
508
+ y: z.ZodNumber;
509
+ }, z.core.$strip>;
510
+ number: z.ZodNumber;
511
+ }, z.core.$strip>>;
512
+ arrow: z.ZodNullable<z.ZodObject<{
513
+ head: z.ZodObject<{
514
+ x: z.ZodNumber;
515
+ y: z.ZodNumber;
516
+ }, z.core.$strip>;
517
+ tail: z.ZodObject<{
518
+ x: z.ZodNumber;
519
+ y: z.ZodNumber;
520
+ }, z.core.$strip>;
521
+ label: z.ZodNullable<z.ZodString>;
522
+ }, z.core.$strip>>;
523
+ }, z.core.$strip>>;
524
+ capturedAt: z.ZodString;
525
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
526
+ }, z.core.$strip>;
527
+ }, z.core.$strip>, z.ZodObject<{
528
+ kind: z.ZodLiteral<"shot-ref">;
529
+ href: z.ZodString;
530
+ }, z.core.$strip>, z.ZodObject<{
531
+ kind: z.ZodLiteral<"image">;
532
+ src: z.ZodString;
533
+ alt: z.ZodString;
534
+ }, z.core.$strip>], "kind">;
535
+ notes: z.ZodOptional<z.ZodString>;
536
+ narration: z.ZodOptional<z.ZodObject<{
537
+ text: z.ZodString;
538
+ lang: z.ZodOptional<z.ZodString>;
539
+ dir: z.ZodOptional<z.ZodEnum<{
540
+ ltr: "ltr";
541
+ rtl: "rtl";
542
+ auto: "auto";
543
+ }>>;
544
+ voice: z.ZodOptional<z.ZodString>;
545
+ words: z.ZodArray<z.ZodObject<{
546
+ text: z.ZodString;
547
+ startMs: z.ZodNumber;
548
+ endMs: z.ZodNumber;
549
+ }, z.core.$strip>>;
550
+ durationMs: z.ZodNumber;
551
+ audio: z.ZodNullable<z.ZodString>;
552
+ live: z.ZodDefault<z.ZodBoolean>;
553
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
554
+ word: z.ZodNumber;
555
+ annotation: z.ZodNumber;
556
+ untilWord: z.ZodOptional<z.ZodNumber>;
557
+ }, z.core.$strip>>>;
558
+ }, z.core.$strip>>;
559
+ }, z.core.$strip>>;
560
+ }, z.core.$strip>;
561
+ export type Deck = z.infer<typeof Deck>;
562
+ export type DeckInput = z.input<typeof Deck>;
563
+ export declare const Manifest: z.ZodObject<{
564
+ shots: z.ZodRecord<z.ZodString, z.ZodObject<{
565
+ key: z.ZodString;
566
+ title: z.ZodString;
567
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
568
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
569
+ file: z.ZodString;
570
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
571
+ size: z.ZodObject<{
572
+ width: z.ZodNumber;
573
+ height: z.ZodNumber;
574
+ }, z.core.$strip>;
575
+ scale: z.ZodNumber;
576
+ dir: z.ZodDefault<z.ZodEnum<{
577
+ ltr: "ltr";
578
+ rtl: "rtl";
579
+ }>>;
580
+ annotations: z.ZodArray<z.ZodObject<{
581
+ ring: z.ZodNullable<z.ZodObject<{
582
+ x: z.ZodNumber;
583
+ y: z.ZodNumber;
584
+ width: z.ZodNumber;
585
+ height: z.ZodNumber;
586
+ }, z.core.$strip>>;
587
+ badge: z.ZodNullable<z.ZodObject<{
588
+ center: z.ZodObject<{
589
+ x: z.ZodNumber;
590
+ y: z.ZodNumber;
591
+ }, z.core.$strip>;
592
+ number: z.ZodNumber;
593
+ }, z.core.$strip>>;
594
+ arrow: z.ZodNullable<z.ZodObject<{
595
+ head: z.ZodObject<{
596
+ x: z.ZodNumber;
597
+ y: z.ZodNumber;
598
+ }, z.core.$strip>;
599
+ tail: z.ZodObject<{
600
+ x: z.ZodNumber;
601
+ y: z.ZodNumber;
602
+ }, z.core.$strip>;
603
+ label: z.ZodNullable<z.ZodString>;
604
+ }, z.core.$strip>>;
605
+ }, z.core.$strip>>;
606
+ capturedAt: z.ZodString;
607
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
608
+ }, z.core.$strip>>;
609
+ updatedAt: z.ZodString;
610
+ }, z.core.$strip>;
611
+ export type Manifest = z.infer<typeof Manifest>;
612
+ export interface DeckLimits {
613
+ maxSlides?: number;
614
+ maxSlideBytes?: number;
615
+ maxNotesBytes?: number;
616
+ }
617
+ export declare function exceedsLimits(deck: Deck, limits: DeckLimits): string[];
618
+ export interface ShotUse {
619
+ slide: string;
620
+ key?: string;
621
+ href?: string;
622
+ }
623
+ export declare function shotsUsed(deck: Deck): ShotUse[];
624
+ export declare function jsonSchemas(): {
625
+ page: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
626
+ html: z.ZodString;
627
+ size: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"fluid">, z.ZodObject<{
628
+ width: z.ZodNumber;
629
+ height: z.ZodNumber;
630
+ }, z.core.$strip>, z.ZodObject<{
631
+ width: z.ZodNumber;
632
+ height: z.ZodLiteral<"auto">;
633
+ }, z.core.$strip>]>>;
634
+ scripts: z.ZodDefault<z.ZodEnum<{
635
+ refuse: "refuse";
636
+ sandboxed: "sandboxed";
637
+ }>>;
638
+ dir: z.ZodOptional<z.ZodEnum<{
639
+ ltr: "ltr";
640
+ rtl: "rtl";
641
+ auto: "auto";
642
+ }>>;
643
+ lang: z.ZodOptional<z.ZodString>;
644
+ print: z.ZodOptional<z.ZodObject<{
645
+ paper: z.ZodUnion<readonly [z.ZodEnum<{
646
+ letter: "letter";
647
+ legal: "legal";
648
+ tabloid: "tabloid";
649
+ a3: "a3";
650
+ a4: "a4";
651
+ a5: "a5";
652
+ }>, z.ZodObject<{
653
+ width: z.ZodNumber;
654
+ height: z.ZodNumber;
655
+ unit: z.ZodEnum<{
656
+ mm: "mm";
657
+ in: "in";
658
+ }>;
659
+ }, z.core.$strip>]>;
660
+ orientation: z.ZodDefault<z.ZodEnum<{
661
+ portrait: "portrait";
662
+ landscape: "landscape";
663
+ }>>;
664
+ margin: z.ZodOptional<z.ZodObject<{
665
+ top: z.ZodDefault<z.ZodNumber>;
666
+ right: z.ZodDefault<z.ZodNumber>;
667
+ bottom: z.ZodDefault<z.ZodNumber>;
668
+ left: z.ZodDefault<z.ZodNumber>;
669
+ }, z.core.$strip>>;
670
+ }, z.core.$strip>>;
671
+ }, z.core.$strip>>;
672
+ deck: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
673
+ title: z.ZodString;
674
+ size: z.ZodDefault<z.ZodObject<{
675
+ width: z.ZodNumber;
676
+ height: z.ZodNumber;
677
+ }, z.core.$strip>>;
678
+ scripts: z.ZodDefault<z.ZodEnum<{
679
+ refuse: "refuse";
680
+ sandboxed: "sandboxed";
681
+ }>>;
682
+ dir: z.ZodOptional<z.ZodEnum<{
683
+ ltr: "ltr";
684
+ rtl: "rtl";
685
+ auto: "auto";
686
+ }>>;
687
+ lang: z.ZodOptional<z.ZodString>;
688
+ slides: z.ZodArray<z.ZodObject<{
689
+ id: z.ZodString;
690
+ content: z.ZodDiscriminatedUnion<[z.ZodObject<{
691
+ kind: z.ZodLiteral<"html">;
692
+ html: z.ZodString;
693
+ }, z.core.$strip>, z.ZodObject<{
694
+ kind: z.ZodLiteral<"url">;
695
+ src: z.ZodString;
696
+ }, z.core.$strip>, z.ZodObject<{
697
+ kind: z.ZodLiteral<"shot">;
698
+ src: z.ZodString;
699
+ shot: z.ZodObject<{
700
+ key: z.ZodString;
701
+ title: z.ZodString;
702
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
703
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
704
+ file: z.ZodString;
705
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
706
+ size: z.ZodObject<{
707
+ width: z.ZodNumber;
708
+ height: z.ZodNumber;
709
+ }, z.core.$strip>;
710
+ scale: z.ZodNumber;
711
+ dir: z.ZodDefault<z.ZodEnum<{
712
+ ltr: "ltr";
713
+ rtl: "rtl";
714
+ }>>;
715
+ annotations: z.ZodArray<z.ZodObject<{
716
+ ring: z.ZodNullable<z.ZodObject<{
717
+ x: z.ZodNumber;
718
+ y: z.ZodNumber;
719
+ width: z.ZodNumber;
720
+ height: z.ZodNumber;
721
+ }, z.core.$strip>>;
722
+ badge: z.ZodNullable<z.ZodObject<{
723
+ center: z.ZodObject<{
724
+ x: z.ZodNumber;
725
+ y: z.ZodNumber;
726
+ }, z.core.$strip>;
727
+ number: z.ZodNumber;
728
+ }, z.core.$strip>>;
729
+ arrow: z.ZodNullable<z.ZodObject<{
730
+ head: z.ZodObject<{
731
+ x: z.ZodNumber;
732
+ y: z.ZodNumber;
733
+ }, z.core.$strip>;
734
+ tail: z.ZodObject<{
735
+ x: z.ZodNumber;
736
+ y: z.ZodNumber;
737
+ }, z.core.$strip>;
738
+ label: z.ZodNullable<z.ZodString>;
739
+ }, z.core.$strip>>;
740
+ }, z.core.$strip>>;
741
+ capturedAt: z.ZodString;
742
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
743
+ }, z.core.$strip>;
744
+ }, z.core.$strip>, z.ZodObject<{
745
+ kind: z.ZodLiteral<"shot-ref">;
746
+ href: z.ZodString;
747
+ }, z.core.$strip>, z.ZodObject<{
748
+ kind: z.ZodLiteral<"image">;
749
+ src: z.ZodString;
750
+ alt: z.ZodString;
751
+ }, z.core.$strip>], "kind">;
752
+ notes: z.ZodOptional<z.ZodString>;
753
+ narration: z.ZodOptional<z.ZodObject<{
754
+ text: z.ZodString;
755
+ lang: z.ZodOptional<z.ZodString>;
756
+ dir: z.ZodOptional<z.ZodEnum<{
757
+ ltr: "ltr";
758
+ rtl: "rtl";
759
+ auto: "auto";
760
+ }>>;
761
+ voice: z.ZodOptional<z.ZodString>;
762
+ words: z.ZodArray<z.ZodObject<{
763
+ text: z.ZodString;
764
+ startMs: z.ZodNumber;
765
+ endMs: z.ZodNumber;
766
+ }, z.core.$strip>>;
767
+ durationMs: z.ZodNumber;
768
+ audio: z.ZodNullable<z.ZodString>;
769
+ live: z.ZodDefault<z.ZodBoolean>;
770
+ cues: z.ZodDefault<z.ZodArray<z.ZodObject<{
771
+ word: z.ZodNumber;
772
+ annotation: z.ZodNumber;
773
+ untilWord: z.ZodOptional<z.ZodNumber>;
774
+ }, z.core.$strip>>>;
775
+ }, z.core.$strip>>;
776
+ }, z.core.$strip>>;
777
+ }, z.core.$strip>>;
778
+ manifest: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
779
+ shots: z.ZodRecord<z.ZodString, z.ZodObject<{
780
+ key: z.ZodString;
781
+ title: z.ZodString;
782
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
783
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
784
+ file: z.ZodString;
785
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
786
+ size: z.ZodObject<{
787
+ width: z.ZodNumber;
788
+ height: z.ZodNumber;
789
+ }, z.core.$strip>;
790
+ scale: z.ZodNumber;
791
+ dir: z.ZodDefault<z.ZodEnum<{
792
+ ltr: "ltr";
793
+ rtl: "rtl";
794
+ }>>;
795
+ annotations: z.ZodArray<z.ZodObject<{
796
+ ring: z.ZodNullable<z.ZodObject<{
797
+ x: z.ZodNumber;
798
+ y: z.ZodNumber;
799
+ width: z.ZodNumber;
800
+ height: z.ZodNumber;
801
+ }, z.core.$strip>>;
802
+ badge: z.ZodNullable<z.ZodObject<{
803
+ center: z.ZodObject<{
804
+ x: z.ZodNumber;
805
+ y: z.ZodNumber;
806
+ }, z.core.$strip>;
807
+ number: z.ZodNumber;
808
+ }, z.core.$strip>>;
809
+ arrow: z.ZodNullable<z.ZodObject<{
810
+ head: z.ZodObject<{
811
+ x: z.ZodNumber;
812
+ y: z.ZodNumber;
813
+ }, z.core.$strip>;
814
+ tail: z.ZodObject<{
815
+ x: z.ZodNumber;
816
+ y: z.ZodNumber;
817
+ }, z.core.$strip>;
818
+ label: z.ZodNullable<z.ZodString>;
819
+ }, z.core.$strip>>;
820
+ }, z.core.$strip>>;
821
+ capturedAt: z.ZodString;
822
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
823
+ }, z.core.$strip>>;
824
+ updatedAt: z.ZodString;
825
+ }, z.core.$strip>>;
826
+ publishedShot: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
827
+ src: z.ZodString;
828
+ shot: z.ZodObject<{
829
+ key: z.ZodString;
830
+ title: z.ZodString;
831
+ description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
832
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
833
+ file: z.ZodString;
834
+ annotatedFile: z.ZodDefault<z.ZodNullable<z.ZodString>>;
835
+ size: z.ZodObject<{
836
+ width: z.ZodNumber;
837
+ height: z.ZodNumber;
838
+ }, z.core.$strip>;
839
+ scale: z.ZodNumber;
840
+ dir: z.ZodDefault<z.ZodEnum<{
841
+ ltr: "ltr";
842
+ rtl: "rtl";
843
+ }>>;
844
+ annotations: z.ZodArray<z.ZodObject<{
845
+ ring: z.ZodNullable<z.ZodObject<{
846
+ x: z.ZodNumber;
847
+ y: z.ZodNumber;
848
+ width: z.ZodNumber;
849
+ height: z.ZodNumber;
850
+ }, z.core.$strip>>;
851
+ badge: z.ZodNullable<z.ZodObject<{
852
+ center: z.ZodObject<{
853
+ x: z.ZodNumber;
854
+ y: z.ZodNumber;
855
+ }, z.core.$strip>;
856
+ number: z.ZodNumber;
857
+ }, z.core.$strip>>;
858
+ arrow: z.ZodNullable<z.ZodObject<{
859
+ head: z.ZodObject<{
860
+ x: z.ZodNumber;
861
+ y: z.ZodNumber;
862
+ }, z.core.$strip>;
863
+ tail: z.ZodObject<{
864
+ x: z.ZodNumber;
865
+ y: z.ZodNumber;
866
+ }, z.core.$strip>;
867
+ label: z.ZodNullable<z.ZodString>;
868
+ }, z.core.$strip>>;
869
+ }, z.core.$strip>>;
870
+ capturedAt: z.ZodString;
871
+ meta: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
872
+ }, z.core.$strip>;
873
+ }, z.core.$strip>>;
874
+ };
875
+ export declare const PAPER_MM: Record<(typeof NAMED_PAPERS)[number], {
876
+ width: number;
877
+ height: number;
878
+ }>;
879
+ export declare function sheetMm(print: Print): {
880
+ width: number;
881
+ height: number;
882
+ };
883
+ export declare const PX_PER_MM: number;
884
+ //#endregion
885
+ export { type TextDirection, firstStrongDirection, languageDirection, resolveDirection };
package/dist/index.js ADDED
@@ -0,0 +1,283 @@
1
+ import { firstStrongDirection, languageDirection, resolveDirection } from "./direction.js";
2
+ import { z } from "zod";
3
+ //#region src/index.ts
4
+ const Size = z.object({
5
+ width: z.number().int().positive(),
6
+ height: z.number().int().positive()
7
+ });
8
+ const Scripts = z.enum(["refuse", "sandboxed"]);
9
+ const Direction = z.enum([
10
+ "ltr",
11
+ "rtl",
12
+ "auto"
13
+ ]);
14
+ const NAMED_PAPERS = [
15
+ "letter",
16
+ "legal",
17
+ "tabloid",
18
+ "a3",
19
+ "a4",
20
+ "a5"
21
+ ];
22
+ const Paper = z.union([z.enum(NAMED_PAPERS), z.object({
23
+ width: z.number().positive(),
24
+ height: z.number().positive(),
25
+ unit: z.enum(["mm", "in"])
26
+ })]);
27
+ const Margin = z.object({
28
+ top: z.number().nonnegative().default(0),
29
+ right: z.number().nonnegative().default(0),
30
+ bottom: z.number().nonnegative().default(0),
31
+ left: z.number().nonnegative().default(0)
32
+ });
33
+ const Print = z.object({
34
+ paper: Paper,
35
+ orientation: z.enum(["portrait", "landscape"]).default("portrait"),
36
+ margin: Margin.optional()
37
+ });
38
+ const PageSize = z.union([
39
+ z.literal("fluid"),
40
+ Size,
41
+ z.object({
42
+ width: z.number().int().positive(),
43
+ height: z.literal("auto")
44
+ })
45
+ ]);
46
+ const Page = z.object({
47
+ html: z.string(),
48
+ size: PageSize.default("fluid"),
49
+ scripts: Scripts.default("refuse"),
50
+ dir: Direction.optional(),
51
+ lang: z.string().optional(),
52
+ print: Print.optional()
53
+ });
54
+ const Box = z.object({
55
+ x: z.number(),
56
+ y: z.number(),
57
+ width: z.number(),
58
+ height: z.number()
59
+ });
60
+ const Point = z.object({
61
+ x: z.number(),
62
+ y: z.number()
63
+ });
64
+ const Annotation = z.object({
65
+ ring: Box.nullable(),
66
+ badge: z.object({
67
+ center: Point,
68
+ number: z.number().int()
69
+ }).nullable(),
70
+ arrow: z.object({
71
+ head: Point,
72
+ tail: Point,
73
+ label: z.string().nullable()
74
+ }).nullable()
75
+ });
76
+ const SHOT_KEY = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
77
+ const Shot = z.object({
78
+ key: z.string().regex(SHOT_KEY),
79
+ title: z.string(),
80
+ description: z.string().nullable().default(null),
81
+ tags: z.array(z.string()).default([]),
82
+ file: z.string(),
83
+ annotatedFile: z.string().nullable().default(null),
84
+ size: Size,
85
+ scale: z.number().positive(),
86
+ dir: z.enum(["ltr", "rtl"]).default("ltr"),
87
+ annotations: z.array(Annotation),
88
+ capturedAt: z.string(),
89
+ meta: z.record(z.string(), z.unknown()).default({})
90
+ });
91
+ const PublishedShot = z.object({
92
+ src: z.string(),
93
+ shot: Shot
94
+ });
95
+ const Word = z.object({
96
+ text: z.string(),
97
+ startMs: z.number().nonnegative(),
98
+ endMs: z.number().nonnegative()
99
+ });
100
+ const Cue = z.object({
101
+ word: z.number().int().nonnegative(),
102
+ annotation: z.number().int().nonnegative(),
103
+ untilWord: z.number().int().nonnegative().optional()
104
+ });
105
+ const Narration = z.object({
106
+ text: z.string(),
107
+ lang: z.string().optional(),
108
+ dir: Direction.optional(),
109
+ voice: z.string().optional(),
110
+ words: z.array(Word),
111
+ durationMs: z.number().nonnegative(),
112
+ audio: z.string().nullable(),
113
+ live: z.boolean().default(false),
114
+ cues: z.array(Cue).default([])
115
+ });
116
+ const SlideContent = z.discriminatedUnion("kind", [
117
+ z.object({
118
+ kind: z.literal("html"),
119
+ html: z.string()
120
+ }),
121
+ z.object({
122
+ kind: z.literal("url"),
123
+ src: z.string()
124
+ }),
125
+ z.object({
126
+ kind: z.literal("shot"),
127
+ src: z.string(),
128
+ shot: Shot
129
+ }),
130
+ z.object({
131
+ kind: z.literal("shot-ref"),
132
+ href: z.string()
133
+ }),
134
+ z.object({
135
+ kind: z.literal("image"),
136
+ src: z.string(),
137
+ alt: z.string()
138
+ })
139
+ ]);
140
+ const Slide = z.object({
141
+ id: z.string(),
142
+ content: SlideContent,
143
+ notes: z.string().optional(),
144
+ narration: Narration.optional()
145
+ });
146
+ const DECK_SIZE = {
147
+ width: 1280,
148
+ height: 720
149
+ };
150
+ const DeckShape = z.object({
151
+ title: z.string(),
152
+ size: Size.default(DECK_SIZE),
153
+ scripts: Scripts.default("refuse"),
154
+ dir: Direction.optional(),
155
+ lang: z.string().optional(),
156
+ slides: z.array(Slide).min(1)
157
+ });
158
+ function annotationCueIssues(narration, annotations) {
159
+ if (!narration) return [];
160
+ return narration.cues.filter((cue) => cue.annotation >= annotations).map((cue) => `a cue names annotation ${cue.annotation}, but the slide has ${annotations}`);
161
+ }
162
+ function cueIssues(slide) {
163
+ const narration = slide.narration;
164
+ if (!narration) return [];
165
+ const annotations = slide.content.kind === "shot" ? slide.content.shot.annotations.length : null;
166
+ const words = narration.live ? null : narration.words.length;
167
+ const issues = [];
168
+ for (const cue of narration.cues) {
169
+ 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`);
170
+ if (slide.content.kind !== "shot" && slide.content.kind !== "shot-ref") issues.push("a cue names an annotation, but only a shot carries annotations");
171
+ }
172
+ if (annotations !== null) issues.push(...annotationCueIssues(narration, annotations));
173
+ return issues;
174
+ }
175
+ const Deck = DeckShape.superRefine((deck, ctx) => {
176
+ deck.slides.forEach((slide, index) => {
177
+ for (const message of cueIssues(slide)) ctx.addIssue({
178
+ code: "custom",
179
+ path: [
180
+ "slides",
181
+ index,
182
+ "narration",
183
+ "cues"
184
+ ],
185
+ message
186
+ });
187
+ });
188
+ const ids = /* @__PURE__ */ new Set();
189
+ deck.slides.forEach((slide, index) => {
190
+ if (ids.has(slide.id)) ctx.addIssue({
191
+ code: "custom",
192
+ path: [
193
+ "slides",
194
+ index,
195
+ "id"
196
+ ],
197
+ message: `slide id "${slide.id}" is used twice`
198
+ });
199
+ ids.add(slide.id);
200
+ });
201
+ });
202
+ const Manifest = z.object({
203
+ shots: z.record(z.string(), Shot),
204
+ updatedAt: z.string()
205
+ });
206
+ function exceedsLimits(deck, limits) {
207
+ const reasons = [];
208
+ const bytes = (text) => new TextEncoder().encode(text).length;
209
+ if (limits.maxSlides !== void 0 && deck.slides.length > limits.maxSlides) reasons.push(`the deck has ${deck.slides.length} slides; the limit is ${limits.maxSlides}`);
210
+ deck.slides.forEach((slide, index) => {
211
+ 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}`);
212
+ 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}`);
213
+ });
214
+ return reasons;
215
+ }
216
+ function shotsUsed(deck) {
217
+ return deck.slides.flatMap((slide) => {
218
+ if (slide.content.kind === "shot") return [{
219
+ slide: slide.id,
220
+ key: slide.content.shot.key
221
+ }];
222
+ if (slide.content.kind === "shot-ref") return [{
223
+ slide: slide.id,
224
+ href: slide.content.href
225
+ }];
226
+ return [];
227
+ });
228
+ }
229
+ function jsonSchemas() {
230
+ return {
231
+ page: z.toJSONSchema(Page, { io: "input" }),
232
+ deck: z.toJSONSchema(DeckShape, { io: "input" }),
233
+ manifest: z.toJSONSchema(Manifest, { io: "input" }),
234
+ publishedShot: z.toJSONSchema(PublishedShot, { io: "input" })
235
+ };
236
+ }
237
+ const PAPER_MM = {
238
+ letter: {
239
+ width: 215.9,
240
+ height: 279.4
241
+ },
242
+ legal: {
243
+ width: 215.9,
244
+ height: 355.6
245
+ },
246
+ tabloid: {
247
+ width: 279.4,
248
+ height: 431.8
249
+ },
250
+ a3: {
251
+ width: 297,
252
+ height: 420
253
+ },
254
+ a4: {
255
+ width: 210,
256
+ height: 297
257
+ },
258
+ a5: {
259
+ width: 148,
260
+ height: 210
261
+ }
262
+ };
263
+ function sheetMm(print) {
264
+ const portrait = typeof print.paper === "string" ? PAPER_MM[print.paper] : print.paper.unit === "in" ? {
265
+ width: print.paper.width * 25.4,
266
+ height: print.paper.height * 25.4
267
+ } : {
268
+ width: print.paper.width,
269
+ height: print.paper.height
270
+ };
271
+ const [short, long] = [Math.min(portrait.width, portrait.height), Math.max(portrait.width, portrait.height)];
272
+ const round = (mm) => Math.round(mm * 100) / 100;
273
+ return print.orientation === "landscape" ? {
274
+ width: round(long),
275
+ height: round(short)
276
+ } : {
277
+ width: round(short),
278
+ height: round(long)
279
+ };
280
+ }
281
+ const PX_PER_MM = 96 / 25.4;
282
+ //#endregion
283
+ export { Annotation, Box, Cue, DECK_SIZE, Deck, Direction, Manifest, Margin, NAMED_PAPERS, Narration, PAPER_MM, PX_PER_MM, Page, PageSize, Paper, Point, Print, PublishedShot, SHOT_KEY, Scripts, Shot, Size, Slide, SlideContent, Word, annotationCueIssues, exceedsLimits, firstStrongDirection, jsonSchemas, languageDirection, resolveDirection, sheetMm, shotsUsed };
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
2
  "name": "@segnavia/format",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/modstudio/segnavia.git",
9
+ "directory": "packages/format"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "sideEffects": false,
15
+ "engines": {
16
+ "node": ">=22"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "@segnavia/source": "./src/index.ts",
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ }
27
+ },
28
+ "dependencies": {
29
+ "zod": "^4.1.0"
30
+ }
31
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.