quicklook-pptx-renderer 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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +175 -0
  5. package/dist/diff/compare.d.ts +17 -0
  6. package/dist/diff/compare.js +71 -0
  7. package/dist/index.d.ts +29 -0
  8. package/dist/index.js +72 -0
  9. package/dist/lint.d.ts +27 -0
  10. package/dist/lint.js +328 -0
  11. package/dist/mapper/bleed-map.d.ts +6 -0
  12. package/dist/mapper/bleed-map.js +1 -0
  13. package/dist/mapper/constants.d.ts +2 -0
  14. package/dist/mapper/constants.js +4 -0
  15. package/dist/mapper/drawable-mapper.d.ts +16 -0
  16. package/dist/mapper/drawable-mapper.js +1464 -0
  17. package/dist/mapper/html-generator.d.ts +13 -0
  18. package/dist/mapper/html-generator.js +539 -0
  19. package/dist/mapper/image-mapper.d.ts +14 -0
  20. package/dist/mapper/image-mapper.js +70 -0
  21. package/dist/mapper/nano-malloc.d.ts +130 -0
  22. package/dist/mapper/nano-malloc.js +197 -0
  23. package/dist/mapper/ql-bleed.d.ts +35 -0
  24. package/dist/mapper/ql-bleed.js +254 -0
  25. package/dist/mapper/shape-mapper.d.ts +41 -0
  26. package/dist/mapper/shape-mapper.js +2384 -0
  27. package/dist/mapper/slide-mapper.d.ts +4 -0
  28. package/dist/mapper/slide-mapper.js +112 -0
  29. package/dist/mapper/style-builder.d.ts +12 -0
  30. package/dist/mapper/style-builder.js +30 -0
  31. package/dist/mapper/text-mapper.d.ts +14 -0
  32. package/dist/mapper/text-mapper.js +302 -0
  33. package/dist/model/enums.d.ts +25 -0
  34. package/dist/model/enums.js +2 -0
  35. package/dist/model/types.d.ts +482 -0
  36. package/dist/model/types.js +7 -0
  37. package/dist/package/content-types.d.ts +1 -0
  38. package/dist/package/content-types.js +4 -0
  39. package/dist/package/package.d.ts +10 -0
  40. package/dist/package/package.js +52 -0
  41. package/dist/package/relationships.d.ts +6 -0
  42. package/dist/package/relationships.js +25 -0
  43. package/dist/package/zip.d.ts +6 -0
  44. package/dist/package/zip.js +17 -0
  45. package/dist/reader/color.d.ts +3 -0
  46. package/dist/reader/color.js +79 -0
  47. package/dist/reader/drawing.d.ts +17 -0
  48. package/dist/reader/drawing.js +403 -0
  49. package/dist/reader/effects.d.ts +2 -0
  50. package/dist/reader/effects.js +83 -0
  51. package/dist/reader/fill.d.ts +2 -0
  52. package/dist/reader/fill.js +94 -0
  53. package/dist/reader/presentation.d.ts +5 -0
  54. package/dist/reader/presentation.js +127 -0
  55. package/dist/reader/slide-layout.d.ts +2 -0
  56. package/dist/reader/slide-layout.js +28 -0
  57. package/dist/reader/slide-master.d.ts +4 -0
  58. package/dist/reader/slide-master.js +49 -0
  59. package/dist/reader/slide.d.ts +2 -0
  60. package/dist/reader/slide.js +26 -0
  61. package/dist/reader/text-list-style.d.ts +2 -0
  62. package/dist/reader/text-list-style.js +9 -0
  63. package/dist/reader/text.d.ts +5 -0
  64. package/dist/reader/text.js +295 -0
  65. package/dist/reader/theme.d.ts +2 -0
  66. package/dist/reader/theme.js +109 -0
  67. package/dist/reader/transform.d.ts +2 -0
  68. package/dist/reader/transform.js +21 -0
  69. package/dist/render/image-renderer.d.ts +3 -0
  70. package/dist/render/image-renderer.js +33 -0
  71. package/dist/render/renderer.d.ts +9 -0
  72. package/dist/render/renderer.js +178 -0
  73. package/dist/render/shape-renderer.d.ts +3 -0
  74. package/dist/render/shape-renderer.js +175 -0
  75. package/dist/render/text-renderer.d.ts +3 -0
  76. package/dist/render/text-renderer.js +152 -0
  77. package/dist/resolve/color-resolver.d.ts +18 -0
  78. package/dist/resolve/color-resolver.js +321 -0
  79. package/dist/resolve/font-map.d.ts +2 -0
  80. package/dist/resolve/font-map.js +66 -0
  81. package/dist/resolve/inheritance.d.ts +5 -0
  82. package/dist/resolve/inheritance.js +106 -0
  83. package/package.json +74 -0
@@ -0,0 +1,482 @@
1
+ import type { SchemeColorName, ColorMapIndex, ColorTransformType, PresetGeometry, TextAlignment, TextAnchorType, WrapType, FlowType, TextAutoFitType, UnderlineType, StrikeThroughType, CapsType, DashType, LineCapType, LineJoinType, CompoundType, LineEndType, LineEndSize, FontReferenceIndex, PlaceholderType, SlideLayoutType, BulletType, AutoNumberScheme, PatternType, ShadowAlignment } from "./enums.js";
2
+ export interface Presentation {
3
+ slides: Slide[];
4
+ slideMasters: SlideMaster[];
5
+ slideSize: Size;
6
+ notesSize: Size;
7
+ defaultTextStyle?: TextListStyle;
8
+ }
9
+ export interface SlideBase {
10
+ name?: string;
11
+ background?: Background;
12
+ drawables: Drawable[];
13
+ }
14
+ export interface SlideMaster extends SlideBase {
15
+ theme: Theme;
16
+ colorMap: ColorMap;
17
+ slideLayouts: SlideLayout[];
18
+ bodyTextStyle?: TextListStyle;
19
+ titleTextStyle?: TextListStyle;
20
+ otherTextStyle?: TextListStyle;
21
+ }
22
+ export interface SlideLayout extends SlideBase {
23
+ slideMaster: SlideMaster;
24
+ layoutType?: SlideLayoutType;
25
+ colorMapOverride?: ColorMap;
26
+ }
27
+ export interface Slide extends SlideBase {
28
+ slideLayout: SlideLayout;
29
+ colorMapOverride?: ColorMap;
30
+ }
31
+ export interface Theme {
32
+ name: string;
33
+ colorScheme: ColorScheme;
34
+ fontScheme: FontScheme;
35
+ styleMatrix: StyleMatrix;
36
+ }
37
+ export interface ColorScheme {
38
+ name: string;
39
+ colors: Record<string, Color>;
40
+ }
41
+ export interface ColorMap {
42
+ mappings: Record<ColorMapIndex, SchemeColorName>;
43
+ }
44
+ export interface FontScheme {
45
+ name: string;
46
+ majorFont: FontCollection;
47
+ minorFont: FontCollection;
48
+ }
49
+ export interface FontCollection {
50
+ latin: string;
51
+ eastAsian: string;
52
+ complexScript: string;
53
+ scriptFonts: Record<string, string>;
54
+ }
55
+ export interface StyleMatrix {
56
+ fillStyles: Fill[];
57
+ lineStyles: Stroke[];
58
+ effectStyles: Effect[][];
59
+ bgFillStyles: Fill[];
60
+ }
61
+ export type Color = RgbColor | SchemeColor | SystemColor | HslColor | PresetColor | ScRgbColor;
62
+ export interface RgbColor {
63
+ type: "rgb";
64
+ r: number;
65
+ g: number;
66
+ b: number;
67
+ transforms?: ColorTransform[];
68
+ }
69
+ export interface SchemeColor {
70
+ type: "scheme";
71
+ val: SchemeColorName;
72
+ transforms?: ColorTransform[];
73
+ }
74
+ export interface SystemColor {
75
+ type: "system";
76
+ val: string;
77
+ lastClr?: string;
78
+ transforms?: ColorTransform[];
79
+ }
80
+ export interface HslColor {
81
+ type: "hsl";
82
+ hue: number;
83
+ sat: number;
84
+ lum: number;
85
+ transforms?: ColorTransform[];
86
+ }
87
+ export interface PresetColor {
88
+ type: "preset";
89
+ val: string;
90
+ transforms?: ColorTransform[];
91
+ }
92
+ export interface ScRgbColor {
93
+ type: "scRgb";
94
+ r: number;
95
+ g: number;
96
+ b: number;
97
+ transforms?: ColorTransform[];
98
+ }
99
+ export interface ColorTransform {
100
+ type: ColorTransformType;
101
+ val?: number;
102
+ }
103
+ export type Fill = SolidFill | GradientFill | ImageFill | PatternFill | NullFill | GroupFill | BackgroundFill;
104
+ export interface SolidFill {
105
+ type: "solid";
106
+ color: Color;
107
+ }
108
+ export interface GradientFill {
109
+ type: "gradient";
110
+ stops: GradientStop[];
111
+ linear?: {
112
+ angle: number;
113
+ scaled: boolean;
114
+ };
115
+ path?: {
116
+ type: "circle" | "rect" | "shape";
117
+ fillToRect?: RelativeRect;
118
+ };
119
+ rotateWithShape?: boolean;
120
+ }
121
+ export interface GradientStop {
122
+ position: number;
123
+ color: Color;
124
+ }
125
+ export interface ImageFill {
126
+ type: "image";
127
+ blipRId?: string;
128
+ blipData?: Buffer;
129
+ stretch?: {
130
+ fillRect?: RelativeRect;
131
+ };
132
+ tile?: {
133
+ tx: number;
134
+ ty: number;
135
+ sx: number;
136
+ sy: number;
137
+ flip?: string;
138
+ algn?: string;
139
+ };
140
+ }
141
+ export interface PatternFill {
142
+ type: "pattern";
143
+ preset: PatternType;
144
+ foreground?: Color;
145
+ background?: Color;
146
+ }
147
+ export interface NullFill {
148
+ type: "noFill";
149
+ }
150
+ export interface GroupFill {
151
+ type: "grpFill";
152
+ }
153
+ export interface BackgroundFill {
154
+ type: "bgFill";
155
+ }
156
+ export interface Stroke {
157
+ width?: number;
158
+ fill?: Fill;
159
+ dash?: DashType;
160
+ cap?: LineCapType;
161
+ join?: LineJoinType;
162
+ miterLimit?: number;
163
+ compound?: CompoundType;
164
+ headEnd?: LineEnd;
165
+ tailEnd?: LineEnd;
166
+ }
167
+ export interface LineEnd {
168
+ type: LineEndType;
169
+ width?: LineEndSize;
170
+ length?: LineEndSize;
171
+ }
172
+ export type Effect = OuterShadow | InnerShadow | Glow | Reflection | Blur;
173
+ export interface OuterShadow {
174
+ type: "outerShdw";
175
+ blurRad?: number;
176
+ dist?: number;
177
+ dir?: number;
178
+ sx?: number;
179
+ sy?: number;
180
+ kx?: number;
181
+ ky?: number;
182
+ algn?: ShadowAlignment;
183
+ rotWithShape?: boolean;
184
+ color?: Color;
185
+ }
186
+ export interface InnerShadow {
187
+ type: "innerShdw";
188
+ blurRad?: number;
189
+ dist?: number;
190
+ dir?: number;
191
+ color?: Color;
192
+ }
193
+ export interface Glow {
194
+ type: "glow";
195
+ rad?: number;
196
+ color?: Color;
197
+ }
198
+ export interface Reflection {
199
+ type: "reflection";
200
+ blurRad?: number;
201
+ stA?: number;
202
+ endA?: number;
203
+ dist?: number;
204
+ dir?: number;
205
+ fadeDir?: number;
206
+ sx?: number;
207
+ sy?: number;
208
+ kx?: number;
209
+ ky?: number;
210
+ algn?: string;
211
+ rotWithShape?: boolean;
212
+ }
213
+ export interface Blur {
214
+ type: "blur";
215
+ rad?: number;
216
+ grow?: boolean;
217
+ }
218
+ export type Drawable = Shape | Picture | Group | Connector | GraphicFrame;
219
+ export interface DrawableBase {
220
+ id: number;
221
+ name: string;
222
+ description?: string;
223
+ hidden?: boolean;
224
+ placeholder?: PlaceholderInfo;
225
+ hyperlink?: string;
226
+ }
227
+ export interface PlaceholderInfo {
228
+ type?: PlaceholderType;
229
+ idx?: number;
230
+ }
231
+ export interface OrientedBounds {
232
+ x: number;
233
+ y: number;
234
+ cx: number;
235
+ cy: number;
236
+ rot?: number;
237
+ flipH?: boolean;
238
+ flipV?: boolean;
239
+ }
240
+ export interface Shape extends DrawableBase {
241
+ drawableType: "sp";
242
+ bounds?: OrientedBounds;
243
+ geometry?: ShapeGeometry;
244
+ fill?: Fill;
245
+ stroke?: Stroke;
246
+ effects?: Effect[];
247
+ textBody?: TextBody;
248
+ shapeStyle?: ShapeStyle;
249
+ }
250
+ export interface Picture extends DrawableBase {
251
+ drawableType: "pic";
252
+ bounds?: OrientedBounds;
253
+ blipRId?: string;
254
+ blipData?: Buffer;
255
+ fill?: Fill;
256
+ geometry?: ShapeGeometry;
257
+ shapeProperties?: {
258
+ fill?: Fill;
259
+ stroke?: Stroke;
260
+ effects?: Effect[];
261
+ };
262
+ }
263
+ export interface Group extends DrawableBase {
264
+ drawableType: "grpSp";
265
+ bounds?: OrientedBounds;
266
+ childBounds?: OrientedBounds;
267
+ children: Drawable[];
268
+ }
269
+ export interface Connector extends DrawableBase {
270
+ drawableType: "cxnSp";
271
+ bounds?: OrientedBounds;
272
+ geometry?: ShapeGeometry;
273
+ stroke?: Stroke;
274
+ fill?: Fill;
275
+ }
276
+ export interface GraphicFrame extends DrawableBase {
277
+ drawableType: "graphicFrame";
278
+ bounds?: OrientedBounds;
279
+ chartRId?: string;
280
+ smartArtRId?: string;
281
+ oleRId?: string;
282
+ fallbackImageData?: Buffer;
283
+ chartData?: ChartData;
284
+ tableData?: TableData;
285
+ }
286
+ export interface ChartSeries {
287
+ name: string;
288
+ values: number[];
289
+ }
290
+ export interface ChartData {
291
+ type: "bar" | "line" | "pie" | "area" | "scatter";
292
+ direction?: "col" | "bar";
293
+ grouping?: string;
294
+ categories: string[];
295
+ series: ChartSeries[];
296
+ legendPos?: "r" | "l" | "t" | "b" | "tr";
297
+ }
298
+ export interface ShapeGeometry {
299
+ preset?: PresetGeometry;
300
+ adjustValues?: Record<string, string>;
301
+ }
302
+ export interface ShapeStyle {
303
+ fillRef?: StyleMatrixReference;
304
+ lnRef?: StyleMatrixReference;
305
+ effectRef?: StyleMatrixReference;
306
+ fontRef?: FontReference;
307
+ }
308
+ export interface StyleMatrixReference {
309
+ idx: number;
310
+ color?: Color;
311
+ }
312
+ export interface FontReference {
313
+ idx: FontReferenceIndex;
314
+ color?: Color;
315
+ }
316
+ export interface TextBody {
317
+ paragraphs: Paragraph[];
318
+ properties?: TextBodyProperties;
319
+ listStyle?: TextListStyle;
320
+ }
321
+ export interface TextBodyProperties {
322
+ wrap?: WrapType;
323
+ lIns?: number;
324
+ tIns?: number;
325
+ rIns?: number;
326
+ bIns?: number;
327
+ anchor?: TextAnchorType;
328
+ anchorCtr?: boolean;
329
+ rtlCol?: boolean;
330
+ autoFit?: TextAutoFitType;
331
+ fontScale?: number;
332
+ lnSpcReduction?: number;
333
+ numCol?: number;
334
+ spcCol?: number;
335
+ rot?: number;
336
+ vert?: FlowType;
337
+ }
338
+ export interface TextListStyle {
339
+ levels: (ParagraphProperties | undefined)[];
340
+ }
341
+ export interface Paragraph {
342
+ runs: TextRun[];
343
+ properties?: ParagraphProperties;
344
+ endParaRPr?: CharacterProperties;
345
+ }
346
+ export type TextRun = RegularRun | LineBreak | TextField;
347
+ export interface RegularRun {
348
+ type: "r";
349
+ text: string;
350
+ properties?: CharacterProperties;
351
+ }
352
+ export interface LineBreak {
353
+ type: "br";
354
+ properties?: CharacterProperties;
355
+ }
356
+ export interface TextField {
357
+ type: "fld";
358
+ fieldType?: string;
359
+ text: string;
360
+ properties?: CharacterProperties;
361
+ }
362
+ export interface CharacterProperties {
363
+ latinFont?: string;
364
+ eastAsianFont?: string;
365
+ complexScriptFont?: string;
366
+ hAnsiFont?: string;
367
+ symbolFont?: string;
368
+ fontSize?: number;
369
+ bold?: boolean;
370
+ italic?: boolean;
371
+ fill?: Fill;
372
+ stroke?: Stroke;
373
+ spacing?: number;
374
+ kerning?: number;
375
+ underline?: UnderlineType;
376
+ underlineFill?: Fill;
377
+ strikethrough?: StrikeThroughType;
378
+ caps?: CapsType;
379
+ baseline?: number;
380
+ highlight?: Color;
381
+ effects?: Effect[];
382
+ hyperlink?: string;
383
+ lang?: string;
384
+ opacity?: number;
385
+ dirty?: boolean;
386
+ }
387
+ export interface ParagraphProperties extends CharacterProperties {
388
+ level?: number;
389
+ align?: TextAlignment;
390
+ marL?: number;
391
+ marR?: number;
392
+ indent?: number;
393
+ lineSpacing?: TextSpacing;
394
+ spaceBefore?: TextSpacing;
395
+ spaceAfter?: TextSpacing;
396
+ bullet?: BulletProperties;
397
+ bulletColor?: Color;
398
+ bulletFont?: string;
399
+ bulletSizePercent?: number;
400
+ bulletSizePoints?: number;
401
+ defTabSz?: number;
402
+ rtl?: boolean;
403
+ }
404
+ export interface TextSpacing {
405
+ type: "pct" | "pts";
406
+ val: number;
407
+ }
408
+ export interface BulletProperties {
409
+ type: BulletType;
410
+ char?: string;
411
+ autoNumScheme?: AutoNumberScheme;
412
+ startAt?: number;
413
+ blipRId?: string;
414
+ }
415
+ export interface Background {
416
+ fill?: Fill;
417
+ shadeToTitle?: boolean;
418
+ }
419
+ export interface TableData {
420
+ rows: TableRow[];
421
+ gridCols: number[];
422
+ properties?: {
423
+ firstRow?: boolean;
424
+ lastRow?: boolean;
425
+ bandRow?: boolean;
426
+ bandCol?: boolean;
427
+ };
428
+ tableStyleId?: string;
429
+ }
430
+ export interface TableRow {
431
+ height: number;
432
+ cells: TableCell[];
433
+ }
434
+ export interface TableCell {
435
+ textBody?: TextBody;
436
+ fill?: Fill;
437
+ borders?: {
438
+ left?: Stroke;
439
+ right?: Stroke;
440
+ top?: Stroke;
441
+ bottom?: Stroke;
442
+ };
443
+ gridSpan?: number;
444
+ rowSpan?: number;
445
+ hMerge?: boolean;
446
+ vMerge?: boolean;
447
+ anchor?: string;
448
+ }
449
+ export interface Size {
450
+ cx: number;
451
+ cy: number;
452
+ }
453
+ export interface RelativeRect {
454
+ l?: number;
455
+ t?: number;
456
+ r?: number;
457
+ b?: number;
458
+ }
459
+ export interface BleedEntry {
460
+ /** The <img> style value (position:absolute; top:...; ...) */
461
+ style: string;
462
+ /** Insert after this many own elements (0-indexed count) */
463
+ afterOwnElement: number;
464
+ }
465
+ export interface BleedRemoval {
466
+ pos: {
467
+ top: number;
468
+ left: number;
469
+ width: number;
470
+ height: number;
471
+ };
472
+ /** Element type that was replaced */
473
+ type: "img" | "div" | "table" | "other";
474
+ }
475
+ export interface QLBleedData {
476
+ /** Bleed entries per slide (0-indexed) — elements to ADD */
477
+ entries: Map<number, BleedEntry[]>;
478
+ /** Own elements per slide that were replaced by bleed — elements to REMOVE */
479
+ removals: Map<number, BleedRemoval[]>;
480
+ /** PDF buffers keyed by the style string (unique identifier) */
481
+ pdfs: Map<string, Buffer>;
482
+ }
@@ -0,0 +1,7 @@
1
+ // Domain model — mirrors Apple's OAD*/PD* class hierarchy from OfficeImport.framework
2
+ // All measurements in OOXML native units unless noted:
3
+ // positions/sizes: EMU (914400 EMU = 1 inch)
4
+ // font sizes: hundredths of a point (1800 = 18pt)
5
+ // angles: 60000ths of a degree (5400000 = 90°)
6
+ // color transform values: 1000ths of a percent (100000 = 100%)
7
+ export {};
@@ -0,0 +1 @@
1
+ export declare function parseContentTypes(_xml: string): Map<string, string>;
@@ -0,0 +1,4 @@
1
+ // Stub — will be fleshed out when needed.
2
+ export function parseContentTypes(_xml) {
3
+ return new Map();
4
+ }
@@ -0,0 +1,10 @@
1
+ import { type Relationship } from "./relationships.js";
2
+ export declare class PptxPackage {
3
+ private zip;
4
+ private constructor();
5
+ static open(data: Buffer | ArrayBuffer): Promise<PptxPackage>;
6
+ getPartXml(path: string): Promise<any>;
7
+ getPartBuffer(path: string): Promise<Buffer | null>;
8
+ getRelationships(partPath: string): Promise<Map<string, Relationship>>;
9
+ resolveRelTarget(partPath: string, relTarget: string): string;
10
+ }
@@ -0,0 +1,52 @@
1
+ import { XMLParser } from "fast-xml-parser";
2
+ import { openZip } from "./zip.js";
3
+ import { parseRelationships } from "./relationships.js";
4
+ import { posix } from "node:path";
5
+ const ARRAY_ELEMENTS = new Set([
6
+ "sldId", "sldMasterId", "notesMasterId",
7
+ "sp", "pic", "grpSp", "cxnSp", "graphicFrame",
8
+ "AlternateContent",
9
+ "p", "r", "br", "fld",
10
+ "tr", "tc", "gridCol",
11
+ "gs", "gd", "font",
12
+ "effectStyle",
13
+ "Relationship", "Default", "Override",
14
+ ]);
15
+ const xmlParser = new XMLParser({
16
+ ignoreAttributes: false,
17
+ attributeNamePrefix: "@_",
18
+ removeNSPrefix: true,
19
+ parseTagValue: false, // Don't coerce "04" → 4
20
+ parseAttributeValue: false, // Don't coerce attribute values
21
+ trimValues: false, // Preserve whitespace in text
22
+ isArray: (name) => ARRAY_ELEMENTS.has(name),
23
+ });
24
+ export class PptxPackage {
25
+ zip;
26
+ constructor(zip) {
27
+ this.zip = zip;
28
+ }
29
+ static async open(data) {
30
+ return new PptxPackage(await openZip(data));
31
+ }
32
+ async getPartXml(path) {
33
+ const xml = await this.zip.getText(path);
34
+ return xml ? xmlParser.parse(xml) : null;
35
+ }
36
+ async getPartBuffer(path) {
37
+ return this.zip.getBuffer(path);
38
+ }
39
+ async getRelationships(partPath) {
40
+ const dir = posix.dirname(partPath);
41
+ const base = posix.basename(partPath);
42
+ const relsPath = `${dir}/_rels/${base}.rels`;
43
+ const xml = await this.zip.getText(relsPath);
44
+ return xml ? parseRelationships(xml) : new Map();
45
+ }
46
+ resolveRelTarget(partPath, relTarget) {
47
+ if (relTarget.startsWith("/"))
48
+ return relTarget.slice(1);
49
+ const dir = posix.dirname(partPath);
50
+ return posix.normalize(`${dir}/${relTarget}`);
51
+ }
52
+ }
@@ -0,0 +1,6 @@
1
+ export interface Relationship {
2
+ id: string;
3
+ type: string;
4
+ target: string;
5
+ }
6
+ export declare function parseRelationships(xml: string): Map<string, Relationship>;
@@ -0,0 +1,25 @@
1
+ import { XMLParser } from "fast-xml-parser";
2
+ const parser = new XMLParser({
3
+ ignoreAttributes: false,
4
+ attributeNamePrefix: "@_",
5
+ isArray: (name) => name === "Relationship",
6
+ });
7
+ function shortType(typeUrl) {
8
+ const last = typeUrl.split("/").pop() ?? typeUrl;
9
+ // handle camelCase names like "slideLayout" directly
10
+ return last;
11
+ }
12
+ export function parseRelationships(xml) {
13
+ const doc = parser.parse(xml);
14
+ const rels = doc?.Relationships?.Relationship ?? [];
15
+ const map = new Map();
16
+ for (const r of rels) {
17
+ const rel = {
18
+ id: r["@_Id"],
19
+ type: shortType(r["@_Type"]),
20
+ target: r["@_Target"],
21
+ };
22
+ map.set(rel.id, rel);
23
+ }
24
+ return map;
25
+ }
@@ -0,0 +1,6 @@
1
+ export interface ZipPackage {
2
+ getText(path: string): Promise<string | null>;
3
+ getBuffer(path: string): Promise<Buffer | null>;
4
+ paths(): string[];
5
+ }
6
+ export declare function openZip(data: Buffer | ArrayBuffer): Promise<ZipPackage>;
@@ -0,0 +1,17 @@
1
+ import JSZip from "jszip";
2
+ export async function openZip(data) {
3
+ const zip = await JSZip.loadAsync(data);
4
+ return {
5
+ async getText(path) {
6
+ const file = zip.file(path);
7
+ return file ? file.async("string") : null;
8
+ },
9
+ async getBuffer(path) {
10
+ const file = zip.file(path);
11
+ return file ? Buffer.from(await file.async("arraybuffer")) : null;
12
+ },
13
+ paths() {
14
+ return Object.keys(zip.files).filter((p) => !zip.files[p].dir);
15
+ },
16
+ };
17
+ }
@@ -0,0 +1,3 @@
1
+ import type { Color, ColorTransform } from "../model/types.js";
2
+ export declare function readColorTransforms(node: any): ColorTransform[];
3
+ export declare function readColor(node: any): Color | undefined;
@@ -0,0 +1,79 @@
1
+ function toArray(val) {
2
+ return val == null ? [] : Array.isArray(val) ? val : [val];
3
+ }
4
+ const TRANSFORM_NAMES = [
5
+ "tint", "shade", "comp", "inv", "gray",
6
+ "alpha", "alphaOff", "alphaMod",
7
+ "hue", "hueOff", "hueMod",
8
+ "sat", "satOff", "satMod",
9
+ "lum", "lumOff", "lumMod",
10
+ "red", "redOff", "redMod",
11
+ "green", "greenOff", "greenMod",
12
+ "blue", "blueOff", "blueMod",
13
+ ];
14
+ export function readColorTransforms(node) {
15
+ const transforms = [];
16
+ for (const name of TRANSFORM_NAMES) {
17
+ const el = node[name];
18
+ if (el == null)
19
+ continue;
20
+ const t = { type: name };
21
+ if (el["@_val"] != null)
22
+ t.val = Number(el["@_val"]);
23
+ transforms.push(t);
24
+ }
25
+ return transforms;
26
+ }
27
+ function withTransforms(color, node) {
28
+ const t = readColorTransforms(node);
29
+ if (t.length)
30
+ color.transforms = t;
31
+ return color;
32
+ }
33
+ function parseHex(hex) {
34
+ const n = parseInt(hex, 16);
35
+ return { r: (n >> 16) & 0xff, g: (n >> 8) & 0xff, b: n & 0xff };
36
+ }
37
+ export function readColor(node) {
38
+ if (node == null)
39
+ return undefined;
40
+ if (node.srgbClr) {
41
+ const c = node.srgbClr;
42
+ const { r, g, b } = parseHex(c["@_val"]);
43
+ return withTransforms({ type: "rgb", r, g, b }, c);
44
+ }
45
+ if (node.schemeClr) {
46
+ const c = node.schemeClr;
47
+ return withTransforms({ type: "scheme", val: c["@_val"] }, c);
48
+ }
49
+ if (node.sysClr) {
50
+ const c = node.sysClr;
51
+ const color = { type: "system", val: c["@_val"] };
52
+ if (c["@_lastClr"])
53
+ color.lastClr = c["@_lastClr"];
54
+ return withTransforms(color, c);
55
+ }
56
+ if (node.hslClr) {
57
+ const c = node.hslClr;
58
+ return withTransforms({
59
+ type: "hsl",
60
+ hue: Number(c["@_hue"]),
61
+ sat: Number(c["@_sat"]),
62
+ lum: Number(c["@_lum"]),
63
+ }, c);
64
+ }
65
+ if (node.prstClr) {
66
+ const c = node.prstClr;
67
+ return withTransforms({ type: "preset", val: c["@_val"] }, c);
68
+ }
69
+ if (node.scrgbClr ?? node.scRgbClr) {
70
+ const c = node.scrgbClr ?? node.scRgbClr;
71
+ return withTransforms({
72
+ type: "scRgb",
73
+ r: Number(c["@_r"]),
74
+ g: Number(c["@_g"]),
75
+ b: Number(c["@_b"]),
76
+ }, c);
77
+ }
78
+ return undefined;
79
+ }