@office-open/core 0.10.15 → 0.12.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 (93) hide show
  1. package/README.md +2 -1
  2. package/dist/chart/index.d.mts +2 -2
  3. package/dist/chart/index.mjs +2 -2
  4. package/dist/chart-DED4tXC9.mjs +2325 -0
  5. package/dist/chart-DED4tXC9.mjs.map +1 -0
  6. package/dist/color-mapping-CFF0vRSe.mjs +117 -0
  7. package/dist/color-mapping-CFF0vRSe.mjs.map +1 -0
  8. package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
  9. package/dist/descriptor/index.d.mts +2 -2
  10. package/dist/descriptor/index.mjs +1 -1
  11. package/dist/{descriptor-BjNkn5jo.mjs → descriptor-BqaNZrrZ.mjs} +43 -11
  12. package/dist/{descriptor-BjNkn5jo.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
  13. package/dist/drawing/index.d.mts +2 -0
  14. package/dist/drawing/index.mjs +2 -0
  15. package/dist/{drawingml-sj1J3lb0.mjs → drawing-BCAyrCCw.mjs} +4456 -3452
  16. package/dist/drawing-BCAyrCCw.mjs.map +1 -0
  17. package/dist/{converters-C_Y2QX1w.mjs → ext-uri-BHBcIrW7.mjs} +742 -45
  18. package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
  19. package/dist/index-BAxlDUQ1.d.mts +590 -0
  20. package/dist/index-BAxlDUQ1.d.mts.map +1 -0
  21. package/dist/index-BP541uS-.d.mts +489 -0
  22. package/dist/index-BP541uS-.d.mts.map +1 -0
  23. package/dist/{index-BVK2dv6C.d.mts → index-BQLIofaF.d.mts} +10 -4
  24. package/dist/index-BQLIofaF.d.mts.map +1 -0
  25. package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
  26. package/dist/index-CaNwM5_e.d.mts.map +1 -0
  27. package/dist/index-DPkf_CtG.d.mts +1578 -0
  28. package/dist/index-DPkf_CtG.d.mts.map +1 -0
  29. package/dist/index-DcukVskh.d.mts +31 -0
  30. package/dist/index-DcukVskh.d.mts.map +1 -0
  31. package/dist/index-Di6XPdGl.d.mts +322 -0
  32. package/dist/index-Di6XPdGl.d.mts.map +1 -0
  33. package/dist/index-L6AXewfV.d.mts +872 -0
  34. package/dist/index-L6AXewfV.d.mts.map +1 -0
  35. package/dist/index.d.mts +294 -30
  36. package/dist/index.d.mts.map +1 -1
  37. package/dist/index.mjs +1327 -112
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
  40. package/dist/output-yyxdkG0C.d.mts.map +1 -0
  41. package/dist/patch/index.d.mts +2 -2
  42. package/dist/patch/index.mjs +2 -2
  43. package/dist/{patch-BmRfghOo.mjs → patch-AkQY17CD.mjs} +73 -28
  44. package/dist/patch-AkQY17CD.mjs.map +1 -0
  45. package/dist/smartart/index.d.mts +2 -2
  46. package/dist/smartart/index.mjs +2 -2
  47. package/dist/smartart-n1kYJ6Jg.mjs +1650 -0
  48. package/dist/smartart-n1kYJ6Jg.mjs.map +1 -0
  49. package/dist/style-matrix-B6jhPAT3.mjs +123 -0
  50. package/dist/style-matrix-B6jhPAT3.mjs.map +1 -0
  51. package/dist/theme/index.d.mts +4 -2
  52. package/dist/theme/index.mjs +4 -2
  53. package/dist/theme-BKnXRmvn.mjs +426 -0
  54. package/dist/theme-BKnXRmvn.mjs.map +1 -0
  55. package/dist/theme-options-kO89NUEX.d.mts +109 -0
  56. package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
  57. package/dist/util/index.d.mts +3 -3
  58. package/dist/util/index.mjs +3 -3
  59. package/dist/{util-Tq9PSjK0.mjs → util-ptE16MEk.mjs} +237 -459
  60. package/dist/util-ptE16MEk.mjs.map +1 -0
  61. package/dist/{values-8di32lIe.d.mts → values-BECDm4zr.d.mts} +17 -31
  62. package/dist/values-BECDm4zr.d.mts.map +1 -0
  63. package/dist/vector/index.d.mts +2 -0
  64. package/dist/vector/index.mjs +2 -0
  65. package/dist/vector-DhLGZjP5.mjs +3049 -0
  66. package/dist/vector-DhLGZjP5.mjs.map +1 -0
  67. package/package.json +16 -8
  68. package/dist/chart-DIGJna_6.mjs +0 -582
  69. package/dist/chart-DIGJna_6.mjs.map +0 -1
  70. package/dist/converters-C_Y2QX1w.mjs.map +0 -1
  71. package/dist/drawingml/index.d.mts +0 -2
  72. package/dist/drawingml/index.mjs +0 -2
  73. package/dist/drawingml-sj1J3lb0.mjs.map +0 -1
  74. package/dist/index-BVK2dv6C.d.mts.map +0 -1
  75. package/dist/index-BfHfKuKy.d.mts +0 -275
  76. package/dist/index-BfHfKuKy.d.mts.map +0 -1
  77. package/dist/index-CE53SwpZ.d.mts +0 -1463
  78. package/dist/index-CE53SwpZ.d.mts.map +0 -1
  79. package/dist/index-D6VE-MnJ.d.mts +0 -43
  80. package/dist/index-D6VE-MnJ.d.mts.map +0 -1
  81. package/dist/index-DE4CLElr.d.mts +0 -145
  82. package/dist/index-DE4CLElr.d.mts.map +0 -1
  83. package/dist/index-DlPA26cw.d.mts +0 -91
  84. package/dist/index-DlPA26cw.d.mts.map +0 -1
  85. package/dist/index-k8WKLXnA.d.mts.map +0 -1
  86. package/dist/output-D_G_JR_8.d.mts.map +0 -1
  87. package/dist/patch-BmRfghOo.mjs.map +0 -1
  88. package/dist/smartart-B7ukZ-Tw.mjs +0 -305
  89. package/dist/smartart-B7ukZ-Tw.mjs.map +0 -1
  90. package/dist/theme-CiNzdl-9.mjs +0 -177
  91. package/dist/theme-CiNzdl-9.mjs.map +0 -1
  92. package/dist/util-Tq9PSjK0.mjs.map +0 -1
  93. package/dist/values-8di32lIe.d.mts.map +0 -1
@@ -1,34 +1,8 @@
1
- import { U as encodeBase64, W as Buffer } from "./converters-C_Y2QX1w.mjs";
2
- import { AsyncZipDeflate, Zip, ZipPassThrough, strFromU8, strFromU8 as strFromU8$1, unzipSync as unzipSync$1, zip, zipSync } from "fflate";
1
+ import { Ht as Buffer, Vt as encodeBase64 } from "./ext-uri-BHBcIrW7.mjs";
2
+ import { AsyncZipDeflate, Zip, ZipDeflate, ZipPassThrough, strFromU8, strFromU8 as strFromU8$1, unzipSync as unzipSync$1, zip, zipSync, zipSync as zipSync$1 } from "fflate";
3
3
  import { sha512 } from "@noble/hashes/sha2.js";
4
- //#region src/opc/output.ts
5
- /**
6
- * Output type definitions for OOXML document export.
7
- *
8
- * @module
9
- */
10
- const OoxmlMimeType = {
11
- DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
12
- PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
13
- XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
14
- };
15
- const convertOutput = (data, type, mimeType = OoxmlMimeType.DOCX) => {
16
- switch (type) {
17
- case "nodebuffer": return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
18
- case "blob": return new Blob([data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)], { type: mimeType });
19
- case "arraybuffer": return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
20
- case "uint8array": return data;
21
- case "base64": return encodeBase64(data);
22
- case "string":
23
- case "text":
24
- case "binarystring": return strFromU8(data, true);
25
- case "array": return [...data];
26
- default: return data;
27
- }
28
- };
29
- //#endregion
30
4
  //#region src/opc/zip-native.ts
31
- const CRC_TABLE = new Int32Array(256);
5
+ const CRC_TABLE = /* @__PURE__ */ new Int32Array(256);
32
6
  for (let i = 0; i < 256; i++) {
33
7
  let c = i;
34
8
  for (let k = 0; k < 8; k++) c = c & 1 ? c >>> 1 ^ -306674912 : c >>> 1;
@@ -43,19 +17,39 @@ let _nativeDeflate;
43
17
  let _nativeDeflateAsync;
44
18
  let _nativeInflate;
45
19
  let _nativeCrc32;
20
+ const bunApi = globalThis.Bun;
21
+ if (typeof bunApi?.deflateSync === "function") {
22
+ _nativeDeflate = (data, level) => bunApi.deflateSync(data, { level });
23
+ if (typeof bunApi.inflateSync === "function") _nativeInflate = (data) => bunApi.inflateSync(data);
24
+ }
46
25
  try {
47
26
  const zlib = await import("node:zlib");
48
27
  if (typeof zlib.deflateRawSync !== "function") throw new Error("no native deflate");
49
- _nativeDeflate = (data, level) => zlib.deflateRawSync(data, { level });
28
+ if (_nativeDeflate === void 0) _nativeDeflate = (data, level) => zlib.deflateRawSync(data, { level });
50
29
  _nativeDeflateAsync = (data, level) => new Promise((resolve, reject) => zlib.deflateRaw(data, { level }, (err, result) => {
51
30
  if (err) reject(err);
52
31
  else resolve(result);
53
32
  }));
54
33
  _nativeCrc32 = typeof zlib.crc32 === "function" ? (data) => zlib.crc32(data) : computeCrc32;
55
- if (typeof zlib.inflateRawSync === "function") _nativeInflate = (data) => zlib.inflateRawSync(data);
34
+ if (typeof zlib.inflateRawSync === "function" && _nativeInflate === void 0) _nativeInflate = (data) => zlib.inflateRawSync(data);
56
35
  } catch {}
57
36
  const hasNativeDeflate = () => _nativeDeflate !== void 0;
58
37
  const hasNativeInflate = () => _nativeInflate !== void 0;
38
+ const _prefersMainThreadDeflate = typeof bunApi?.deflateSync === "function";
39
+ /**
40
+ * True when DEFLATE work should run on the main thread instead of fflate's
41
+ * per-entry workers (Bun). See {@link createZipStream} in packer.ts.
42
+ */
43
+ const prefersMainThreadDeflate = () => _prefersMainThreadDeflate;
44
+ /**
45
+ * Synchronous native CRC-32 (`zlib.crc32`, Node/Bun only) — undefined where no
46
+ * native zlib resolved (browsers/Deno). Used by media dedup as a fast content
47
+ * key; callers keep their own JS fallback. ~59× faster than a JS hash on
48
+ * 100 MB inputs.
49
+ */
50
+ function nativeCrc32(data) {
51
+ return _nativeCrc32?.(data);
52
+ }
59
53
  function wU16(b, o, v) {
60
54
  b[o] = v & 255;
61
55
  b[o + 1] = v >> 8 & 255;
@@ -190,25 +184,24 @@ function nativeZip(files, level = 6) {
190
184
  return writeZipBuffer(entries);
191
185
  }
192
186
  async function nativeZipAsync(files, level = 6) {
193
- if (!_nativeDeflateAsync) throw new Error("Native async deflate not available");
187
+ const deflateAsync = _nativeDeflateAsync;
188
+ if (!deflateAsync) throw new Error("Native async deflate not available");
194
189
  const crc = _nativeCrc32 ?? computeCrc32;
195
- const entries = [];
196
- for (const key of Object.keys(files)) {
190
+ return writeZipBuffer((await Promise.all(Object.keys(files).map(async (key) => {
197
191
  const raw = files[key];
198
- if (raw === void 0) continue;
192
+ if (raw === void 0) return null;
199
193
  const { data, level: entryLevel } = resolveEntryData(raw, level);
200
194
  const c = crc(data);
201
- const { compressed, method } = await compressOneAsync(data, entryLevel, _nativeDeflateAsync);
202
- entries.push({
195
+ const { compressed, method } = await compressOneAsync(data, entryLevel, deflateAsync);
196
+ return {
203
197
  filename: textEncoder.encode(key),
204
198
  data: compressed,
205
199
  uncompressedSize: data.length,
206
200
  crc: c,
207
201
  method,
208
202
  localOffset: 0
209
- });
210
- }
211
- return writeZipBuffer(entries);
203
+ };
204
+ }))).filter((e) => e !== null));
212
205
  }
213
206
  function rU16(b, o) {
214
207
  return b[o] | b[o + 1] << 8;
@@ -274,6 +267,32 @@ function nativeUnzip(buf) {
274
267
  return out;
275
268
  }
276
269
  //#endregion
270
+ //#region src/opc/output.ts
271
+ /**
272
+ * Output type definitions for OOXML document export.
273
+ *
274
+ * @module
275
+ */
276
+ const OoxmlMimeType = {
277
+ DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
278
+ PPTX: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
279
+ XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
280
+ };
281
+ const convertOutput = (data, type, mimeType = OoxmlMimeType.DOCX) => {
282
+ switch (type) {
283
+ case "nodebuffer": return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
284
+ case "blob": return new Blob([data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength)], { type: mimeType });
285
+ case "arraybuffer": return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
286
+ case "uint8array": return data;
287
+ case "base64": return encodeBase64(data);
288
+ case "string":
289
+ case "text":
290
+ case "binarystring": return strFromU8(data, true);
291
+ case "array": return [...data];
292
+ default: return data;
293
+ }
294
+ };
295
+ //#endregion
277
296
  //#region src/opc/packer.ts
278
297
  /**
279
298
  * Shared packer utilities for OOXML document generation.
@@ -286,15 +305,26 @@ const ZIP_DEFLATE_LEVEL = 1;
286
305
  const ZIP_STORED_LEVEL = 0;
287
306
  /**
288
307
  * Media formats already compressed internally (DEFLATE for PNG, DCT for JPEG,
289
- * LZW for GIF). Re-compressing via zip DEFLATE wastes CPU and often inflates
290
- * the data, so MS Office STORE-s these (CompressionOption.NotCompressed zip
291
- * method 0). Everything else (EMF/WMF/BMP/TIFF/SVG/…) is compressible DEFLATE.
292
- */
293
- const PRECOMPRESSED_MEDIA_EXT = new Set([
308
+ * LZW for GIF; video/audio containers carry their own codec streams).
309
+ * Re-compressing via zip DEFLATE wastes CPU and often inflates the data, so
310
+ * MS Office STORE-s these (CompressionOption.NotCompressed zip method 0).
311
+ * Everything else (EMF/WMF/BMP/TIFF/SVG/WAV…) is compressible → DEFLATE —
312
+ * measured on a real Office package, EMF at zlib level 6 matches Office
313
+ * output where SuperFast inflates ~15%.
314
+ */
315
+ const PRECOMPRESSED_MEDIA_EXT = /* @__PURE__ */ new Set([
294
316
  "jpg",
295
317
  "jpeg",
296
318
  "png",
297
- "gif"
319
+ "gif",
320
+ "mp4",
321
+ "mov",
322
+ "wmv",
323
+ "mpg",
324
+ "mpeg",
325
+ "mp3",
326
+ "wma",
327
+ "aac"
298
328
  ]);
299
329
  /**
300
330
  * Resolve the ZIP level for a media entry by file-name extension, matching MS
@@ -311,14 +341,15 @@ const levelForMediaName = (fileName, mediaLevel) => {
311
341
  /**
312
342
  * Asynchronously compress files and convert to the requested output format.
313
343
  *
314
- * Uses fflate Web Workers for non-blocking DEFLATE compression.
344
+ * Where a native zlib resolved (Node/Bun), entries deflate in parallel on the
345
+ * libuv thread pool; elsewhere fflate compresses off the main thread.
315
346
  * XML entries use DEFLATE level 1 (SuperFast) by default. Media entries are
316
347
  * split by type, matching MS Office: already-compressed formats (PNG/JPEG/GIF)
317
348
  * are STOREd, everything else uses the `media` level (default Normal).
318
349
  * Set `{ media: ZIP_STORED_LEVEL }` to STORE all compressible media too.
319
350
  */
320
351
  const zipAndConvert = async (files, type, mimeType, level = 1) => {
321
- return convertOutput(hasNativeDeflate() ? await nativeZipAsync(files, level) : await new Promise((resolve, reject) => {
352
+ const zipped = hasNativeDeflate() ? await nativeZipAsync(files, level) : await new Promise((resolve, reject) => {
322
353
  zip(files, {
323
354
  level,
324
355
  consume: true
@@ -326,7 +357,8 @@ const zipAndConvert = async (files, type, mimeType, level = 1) => {
326
357
  if (err) reject(err);
327
358
  else resolve(data);
328
359
  });
329
- }), type, mimeType);
360
+ });
361
+ return convertOutput(zipped, type, mimeType);
330
362
  };
331
363
  /**
332
364
  * Synchronously compress files and convert to the requested output format.
@@ -335,7 +367,8 @@ const zipAndConvert = async (files, type, mimeType, level = 1) => {
335
367
  * Blocks the event loop — prefer {@link zipAndConvert} in server contexts.
336
368
  */
337
369
  const zipSyncAndConvert = (files, type, mimeType, level = 1) => {
338
- return convertOutput(hasNativeDeflate() ? nativeZip(files, level) : zipSync(files, { level }), type, mimeType);
370
+ const zipped = hasNativeDeflate() ? nativeZip(files, level) : zipSync(files, { level });
371
+ return convertOutput(zipped, type, mimeType);
339
372
  };
340
373
  /**
341
374
  * Create a `ReadableStream<Uint8Array>` from compressed file entries.
@@ -345,6 +378,7 @@ const zipSyncAndConvert = (files, type, mimeType, level = 1) => {
345
378
  * Works in both Node.js and browsers (Web Streams API).
346
379
  */
347
380
  const createZipStream = (files, defaultLevel = 1) => {
381
+ const mainThread = prefersMainThreadDeflate();
348
382
  return new ReadableStream({ start(controller) {
349
383
  try {
350
384
  const zip = new Zip((err, chunk, _final) => {
@@ -358,9 +392,10 @@ const createZipStream = (files, defaultLevel = 1) => {
358
392
  for (const [name, data] of Object.entries(files)) {
359
393
  const raw = Array.isArray(data) ? data[0] : data;
360
394
  const level = Array.isArray(data) ? data[1].level ?? defaultLevel : defaultLevel;
361
- const entry = level === 0 ? new ZipPassThrough(name) : new AsyncZipDeflate(name, { level });
395
+ const workerPath = level !== 0 && !mainThread;
396
+ const entry = level === 0 ? new ZipPassThrough(name) : workerPath ? new AsyncZipDeflate(name, { level }) : new ZipDeflate(name, { level });
362
397
  zip.add(entry);
363
- entry.push(raw, true);
398
+ entry.push(workerPath ? raw.slice() : raw, true);
364
399
  }
365
400
  zip.end();
366
401
  } catch (err) {
@@ -369,6 +404,47 @@ const createZipStream = (files, defaultLevel = 1) => {
369
404
  } });
370
405
  };
371
406
  /**
407
+ * Incremental ZIP archive writer over fflate's streaming `Zip` — parts are
408
+ * added and completed one at a time; compressed output flows to `ondata` as
409
+ * it is produced. This is the constant-memory counterpart to
410
+ * {@link createZipStream} (which requires the complete `Zippable` up front):
411
+ * serialize each part chunk-wise into the returned sink instead of building
412
+ * the full part string.
413
+ *
414
+ * Parts must be added in order — `[Content_Types].xml` first per OPC. The
415
+ * whole archive finishes when {@link ZipStreamWriter.end} is called.
416
+ */
417
+ var ZipStreamWriter = class {
418
+ defaultLevel;
419
+ zip;
420
+ current;
421
+ mainThread = prefersMainThreadDeflate();
422
+ constructor(ondata, defaultLevel = 1) {
423
+ this.defaultLevel = defaultLevel;
424
+ this.zip = new Zip(ondata);
425
+ }
426
+ /** Add a part and return its incremental sink. `end()` the previous first. */
427
+ addPart(name, level = this.defaultLevel) {
428
+ if (this.current) throw new Error(`ZipStreamWriter: previous part not finalized`);
429
+ const workerPath = level !== 0 && !this.mainThread;
430
+ const entry = level === 0 ? new ZipPassThrough(name) : workerPath ? new AsyncZipDeflate(name, { level }) : new ZipDeflate(name, { level });
431
+ this.zip.add(entry);
432
+ this.current = entry;
433
+ return {
434
+ push: (chunk) => entry.push(workerPath ? chunk.slice() : chunk, false),
435
+ end: (lastChunk) => {
436
+ entry.push((workerPath ? lastChunk?.slice() : lastChunk) ?? /* @__PURE__ */ new Uint8Array(0), true);
437
+ this.current = void 0;
438
+ }
439
+ };
440
+ }
441
+ /** Finish the archive (central directory + EOCD). */
442
+ end() {
443
+ if (this.current) throw new Error(`ZipStreamWriter: unclosed part at end()`);
444
+ this.zip.end();
445
+ }
446
+ };
447
+ /**
372
448
  * Create a Packer object with all output format methods.
373
449
  *
374
450
  * Centralises the ZIP → convert pipeline and the streaming implementation
@@ -379,7 +455,8 @@ const createPacker = (options) => {
379
455
  const { compile, mimeType } = options;
380
456
  const pack = async (file, opts) => {
381
457
  const type = opts?.type ?? "nodebuffer";
382
- return zipAndConvert(compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6), type, mimeType, opts?.compression?.xml ?? 1);
458
+ const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6);
459
+ return zipAndConvert(files, type, mimeType, opts?.compression?.xml ?? 1);
383
460
  };
384
461
  const toBytes = (file, opts) => pack(file, {
385
462
  ...opts,
@@ -407,7 +484,8 @@ const createPacker = (options) => {
407
484
  });
408
485
  const packSync = (file, opts) => {
409
486
  const type = opts?.type ?? "nodebuffer";
410
- return zipSyncAndConvert(compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6), type, mimeType, opts?.compression?.xml ?? 1);
487
+ const files = compile(file, opts?.overrides ?? [], opts?.compression?.media ?? 6);
488
+ return zipSyncAndConvert(files, type, mimeType, opts?.compression?.xml ?? 1);
411
489
  };
412
490
  const toBytesSync = (file, opts) => packSync(file, {
413
491
  ...opts,
@@ -473,16 +551,25 @@ const createPacker = (options) => {
473
551
  */
474
552
  /** Reusable TextEncoder instance (stateless, safe to share). */
475
553
  const encoder = new TextEncoder();
554
+ /** Add one binary ZIP entry using the shared media compression policy. */
555
+ function addBinaryFile(files, path, data, mediaLevel) {
556
+ files[path] = [data, { level: levelForMediaName(path, mediaLevel) }];
557
+ }
476
558
  /**
477
- * Convert a mapping of XML files + overrides + media into a Zippable structure.
559
+ * Convert XML files, overrides, and media into a Zippable structure.
478
560
  *
479
- * Centralises the mapping→Zippable conversion shared by all three compilers.
561
+ * Mapping values may be optional arrays so package compilers can pass their
562
+ * natural part mappings without reimplementing flattening and byte encoding.
480
563
  */
481
564
  function compileMapping(mapping, overrides, media, mediaLevel = 0) {
482
565
  const files = {};
483
- for (const entry of Object.values(mapping)) files[entry.path] = encoder.encode(entry.data);
484
- if (overrides) for (const o of overrides) files[o.path] = typeof o.data === "string" ? encoder.encode(o.data) : o.data;
485
- if (media) for (const m of media) files[m.path] = [m.data, { level: levelForMediaName(m.path, mediaLevel) }];
566
+ for (const entry of Object.values(mapping)) {
567
+ if (entry === void 0) continue;
568
+ const entries = Array.isArray(entry) ? entry : [entry];
569
+ for (const file of entries) files[file.path] = typeof file.data === "string" ? encoder.encode(file.data) : file.data;
570
+ }
571
+ for (const override of overrides ?? []) files[override.path] = typeof override.data === "string" ? encoder.encode(override.data) : override.data;
572
+ for (const file of media ?? []) addBinaryFile(files, file.path, file.data, mediaLevel);
486
573
  return files;
487
574
  }
488
575
  //#endregion
@@ -493,7 +580,7 @@ function compileMapping(mapping, overrides, media, mediaLevel = 0) {
493
580
  * Implements ECMA-376 Agile Encryption password derivation.
494
581
  * Passwords are encoded as UTF-16LE per the OOXML specification.
495
582
  *
496
- * Uses @noble/hashes for SHA-512 — audited, cross-platform,
583
+ * Uses `@noble`/hashes for SHA-512 — audited, cross-platform,
497
584
  * and comparable in speed to node:crypto for this workload.
498
585
  *
499
586
  * @module
@@ -554,19 +641,46 @@ function derivePasswordHash(password, spinCount = 1e5) {
554
641
  //#endregion
555
642
  //#region src/util/placeholder.ts
556
643
  const formatId = (offset, index, style) => style === "rId" ? `rId${offset + index}` : `${offset + index}`;
557
- /** Single-pass regex replacement for `{key}` placeholders using a Map lookup. */
558
- const PLACEHOLDER_RE = /\{([^{}]+)\}/g;
644
+ /**
645
+ * Find the next `{key}` placeholder at/after `from`. Returns `[open, close]`
646
+ * brace indices, or undefined when none remain. Mirrors the semantics of
647
+ * `/\{([^{}]+)\}/g`: empty keys and keys containing `{` are skipped (the scan
648
+ * restarts after the nested brace), matching what the regex would accept.
649
+ */
650
+ function nextPlaceholder(xml, from) {
651
+ let pos = from;
652
+ for (;;) {
653
+ const open = xml.indexOf("{", pos);
654
+ if (open === -1) return void 0;
655
+ const close = xml.indexOf("}", open + 1);
656
+ if (close === -1) return void 0;
657
+ if (close - open - 1 === 0) {
658
+ pos = open + 1;
659
+ continue;
660
+ }
661
+ const nextOpen = xml.indexOf("{", open + 1);
662
+ if (nextOpen !== -1 && nextOpen < close) {
663
+ pos = open + 1;
664
+ continue;
665
+ }
666
+ return [open, close];
667
+ }
668
+ }
669
+ /** Replace `{name}` placeholders with the given values (missing keys stay). */
559
670
  function replacePlaceholders(xml, map) {
560
671
  const parts = [];
561
672
  let last = 0;
562
- for (const m of xml.matchAll(PLACEHOLDER_RE)) {
563
- const key = m[1];
564
- if (key === void 0) continue;
565
- const replacement = map.get(key);
673
+ let pos = 0;
674
+ for (;;) {
675
+ const found = nextPlaceholder(xml, pos);
676
+ if (found === void 0) break;
677
+ const [open, close] = found;
678
+ const replacement = map.get(xml.substring(open + 1, close));
566
679
  if (replacement !== void 0) {
567
- parts.push(xml.substring(last, m.index), replacement);
568
- last = m.index + m[0].length;
680
+ parts.push(xml.substring(last, open), replacement);
681
+ last = close + 1;
569
682
  }
683
+ pos = close + 1;
570
684
  }
571
685
  if (last === 0) return xml;
572
686
  parts.push(xml.substring(last));
@@ -605,7 +719,7 @@ function getReferencedMedia(xml, mediaArray) {
605
719
  * and returns the list of referenced media items for relationship registration.
606
720
  * More efficient than calling getReferencedMedia() + replaceImagePlaceholders() separately.
607
721
  */
608
- function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rId") {
722
+ function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rId", sourceRids) {
609
723
  if (mediaArray.length === 0 || !hasPlaceholders(xml)) return {
610
724
  xml,
611
725
  referenced: []
@@ -616,18 +730,24 @@ function findAndReplaceImagePlaceholders(xml, mediaArray, offset, idFormat = "rI
616
730
  const replaceMap = /* @__PURE__ */ new Map();
617
731
  const parts = [];
618
732
  let last = 0;
619
- for (const m of xml.matchAll(PLACEHOLDER_RE)) {
620
- const key = m[1];
621
- if (key === void 0) continue;
733
+ let pos = 0;
734
+ for (;;) {
735
+ const found = nextPlaceholder(xml, pos);
736
+ if (found === void 0) break;
737
+ const [open, close] = found;
738
+ const key = xml.substring(open + 1, close);
622
739
  const item = itemMap.get(key);
623
740
  if (item !== void 0) {
624
- if (!replaceMap.has(key)) {
625
- replaceMap.set(key, formatId(offset, referenced.length, idFormat));
741
+ let id = replaceMap.get(key);
742
+ if (id === void 0) {
743
+ id = sourceRids?.get(key) ?? formatId(offset, referenced.length, idFormat);
744
+ replaceMap.set(key, id);
626
745
  referenced.push(item);
627
746
  }
628
- parts.push(xml.substring(last, m.index), replaceMap.get(key));
629
- last = m.index + m[0].length;
747
+ parts.push(xml.substring(last, open), id);
748
+ last = close + 1;
630
749
  }
750
+ pos = close + 1;
631
751
  }
632
752
  if (last === 0) return {
633
753
  xml,
@@ -674,7 +794,7 @@ function replaceSmartArtPlaceholders(xml, keys, dataOffset, idFormat = "rId") {
674
794
  return replacePlaceholders(xml, map);
675
795
  }
676
796
  function addSmartArtRelationships(keys, addRel, baseOffset, globalStartIndex, options) {
677
- const { pathPrefix, styleRelType } = options;
797
+ const { pathPrefix, styleRelType, hasDrawing } = options;
678
798
  const count = keys.length;
679
799
  const loOffset = baseOffset + count;
680
800
  const qsOffset = loOffset + count;
@@ -685,7 +805,7 @@ function addSmartArtRelationships(keys, addRel, baseOffset, globalStartIndex, op
685
805
  addRel(loOffset + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout", `${pathPrefix}diagrams/layout${gi + 1}.xml`);
686
806
  addRel(qsOffset + i, styleRelType, `${pathPrefix}diagrams/quickStyle${gi + 1}.xml`);
687
807
  addRel(csOffset + i, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors", `${pathPrefix}diagrams/colors${gi + 1}.xml`);
688
- addRel(csOffset + count + i, "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing", `${pathPrefix}diagrams/drawing${gi + 1}.xml`);
808
+ if (hasDrawing === void 0 || hasDrawing(keys[i])) addRel(csOffset + count + i, "http://schemas.microsoft.com/office/2007/relationships/diagramDrawing", `${pathPrefix}diagrams/drawing${gi + 1}.xml`);
689
809
  }
690
810
  }
691
811
  /** Replace `{reference-instance}` placeholders with numId values. */
@@ -697,16 +817,24 @@ function replaceNumberingPlaceholders(xml, concreteNumberings) {
697
817
  }
698
818
  /** Replace `{media:fileName}` placeholders with relationship IDs. */
699
819
  function replaceMediaPlaceholders(xml, mediaData, offset) {
700
- if (mediaData.length === 0) return xml;
701
- const map = /* @__PURE__ */ new Map();
702
- for (const [i, item] of mediaData.entries()) map.set(`media:${item.fileName}`, formatId(offset, i, "rId"));
703
- return replacePlaceholders(xml, map);
820
+ return replacePrefixedPlaceholders(xml, mediaData, offset, "media:");
704
821
  }
705
822
  /** Replace `{video:fileName}` placeholders with relationship IDs. */
706
823
  function replaceVideoPlaceholders(xml, mediaData, offset) {
824
+ return replacePrefixedPlaceholders(xml, mediaData, offset, "video:");
825
+ }
826
+ /** Replace `{audio:fileName}` placeholders with relationship IDs. */
827
+ function replaceAudioPlaceholders(xml, mediaData, offset) {
828
+ return replacePrefixedPlaceholders(xml, mediaData, offset, "audio:");
829
+ }
830
+ /** Replace `{ole:fileName}` placeholders with relationship IDs. */
831
+ function replaceOlePlaceholders(xml, embeddings, offset) {
832
+ return replacePrefixedPlaceholders(xml, embeddings, offset, "ole:");
833
+ }
834
+ function replacePrefixedPlaceholders(xml, mediaData, offset, prefix) {
707
835
  if (mediaData.length === 0) return xml;
708
836
  const map = /* @__PURE__ */ new Map();
709
- for (const [i, item] of mediaData.entries()) map.set(`video:${item.fileName}`, formatId(offset, i, "rId"));
837
+ for (const [i, item] of mediaData.entries()) map.set(`${prefix}${item.fileName}`, formatId(offset, i, "rId"));
710
838
  return replacePlaceholders(xml, map);
711
839
  }
712
840
  /** Collect media items referenced by `{media:...}` placeholders in XML. */
@@ -717,6 +845,14 @@ function getMediaRefs(xml, mediaArray) {
717
845
  function getVideoRefs(xml, mediaArray) {
718
846
  return collectPrefixedRefs(xml, "video:", mediaArray);
719
847
  }
848
+ /** Collect media items referenced by `{audio:...}` placeholders in XML. */
849
+ function getAudioRefs(xml, mediaArray) {
850
+ return collectPrefixedRefs(xml, "audio:", mediaArray);
851
+ }
852
+ /** Collect OLE embeddings referenced by `{ole:...}` placeholders in XML. */
853
+ function getOleRefs(xml, embeddings) {
854
+ return collectPrefixedRefs(xml, "ole:", embeddings);
855
+ }
720
856
  function collectPrefixedRefs(xml, prefix, mediaArray) {
721
857
  const keys = /* @__PURE__ */ new Set();
722
858
  const search = `{${prefix}`;
@@ -730,384 +866,26 @@ function collectPrefixedRefs(xml, prefix, mediaArray) {
730
866
  }
731
867
  return mediaArray.filter((m) => keys.has(m.fileName));
732
868
  }
733
- /** Replace `{hlink:key}` placeholders with relationship IDs. */
734
- function replaceHyperlinkPlaceholders(xml, hyperlinks, offset) {
735
- if (hyperlinks.length === 0) return xml;
869
+ /** Replace `{prefix:key}` placeholders with relationship IDs. */
870
+ function replaceKeyedPlaceholders(xml, items, offset, prefix) {
871
+ if (items.length === 0) return xml;
736
872
  const map = /* @__PURE__ */ new Map();
737
- for (const [i, h] of hyperlinks.entries()) map.set(`hlink:${h.key}`, formatId(offset, i, "rId"));
873
+ for (const [i, item] of items.entries()) map.set(`${prefix}${item.key}`, formatId(offset, i, "rId"));
738
874
  return replacePlaceholders(xml, map);
739
875
  }
876
+ /** Replace `{hlink:key}` placeholders with relationship IDs. */
877
+ function replaceHyperlinkPlaceholders(xml, hyperlinks, offset) {
878
+ return replaceKeyedPlaceholders(xml, hyperlinks, offset, "hlink:");
879
+ }
880
+ /** Replace `{img-link:key}` placeholders with relationship IDs. */
881
+ function replaceImageLinkPlaceholders(xml, links, offset) {
882
+ return replaceKeyedPlaceholders(xml, links, offset, "img-link:");
883
+ }
884
+ /** Replace `{ole-link:key}` placeholders with relationship IDs. */
885
+ function replaceOleLinkPlaceholders(xml, links, offset) {
886
+ return replaceKeyedPlaceholders(xml, links, offset, "ole-link:");
887
+ }
740
888
  //#endregion
741
- //#region src/util/values.ts
742
- /**
743
- * Validates and converts a number to an integer (decimal number).
744
- *
745
- * Reference: ST_DecimalNumber in OOXML specification
746
- *
747
- * @param val - The number to validate and convert
748
- * @returns The floored integer value
749
- * @throws Error if the value is NaN
750
- *
751
- * @example
752
- * ```typescript
753
- * const num = decimalNumber(10.7); // Returns 10
754
- * const negative = decimalNumber(-5.3); // Returns -5
755
- * ```
756
- */
757
- const decimalNumber = (val) => {
758
- if (!Number.isFinite(val)) throw new Error(`Invalid value '${val}' specified. Must be a finite number.`);
759
- return Math.floor(val);
760
- };
761
- /**
762
- * Validates and converts a number to a positive integer (unsigned decimal number).
763
- *
764
- * Reference: ST_UnsignedDecimalNumber in OOXML specification
765
- *
766
- * @param val - The number to validate and convert
767
- * @returns The floored positive integer value
768
- * @throws Error if the value is NaN or negative
769
- *
770
- * @example
771
- * ```typescript
772
- * const num = unsignedDecimalNumber(10.7); // Returns 10
773
- * const invalid = unsignedDecimalNumber(-5); // Throws Error
774
- * ```
775
- */
776
- const unsignedDecimalNumber = (val) => {
777
- const value = decimalNumber(val);
778
- if (value < 0) throw new Error(`Invalid value '${val}' specified. Must be a positive integer.`);
779
- return value;
780
- };
781
- /**
782
- * Validates and normalizes a hexadecimal binary value.
783
- *
784
- * The xsd:hexBinary type represents binary data as a sequence of binary octets
785
- * using hexadecimal encoding, where each binary octet is a two-character
786
- * hexadecimal number. Both lowercase and uppercase letters A-F are permitted.
787
- *
788
- * @param val - The hexadecimal string to validate
789
- * @param length - The expected length in bytes (not characters)
790
- * @returns The validated hexadecimal string
791
- * @throws Error if the value is not a valid hex string of the expected length
792
- *
793
- * @example
794
- * ```typescript
795
- * hexBinary("0FB8", 2); // Valid: 2 bytes = 4 characters
796
- * hexBinary("ABC", 2); // Invalid: wrong length
797
- * ```
798
- */
799
- const hexBinary = (val, length) => {
800
- const expectedLength = length * 2;
801
- if (val.length !== expectedLength || isNaN(Number(`0x${val}`))) throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);
802
- return val;
803
- };
804
- /**
805
- * Validates a long hexadecimal number (4 bytes / 8 characters).
806
- *
807
- * Reference: ST_LongHexNumber in OOXML specification
808
- *
809
- * @param val - The hexadecimal string to validate
810
- * @returns The validated hexadecimal string
811
- * @throws Error if the value is not a valid 8-character hex string
812
- *
813
- * @example
814
- * ```typescript
815
- * const hex = longHexNumber("ABCD1234"); // Valid
816
- * ```
817
- */
818
- const longHexNumber = (val) => hexBinary(val, 4);
819
- /**
820
- * Validates a short hexadecimal number (2 bytes / 4 characters).
821
- *
822
- * Reference: ST_ShortHexNumber in OOXML specification
823
- *
824
- * @param val - The hexadecimal string to validate
825
- * @returns The validated hexadecimal string
826
- * @throws Error if the value is not a valid 4-character hex string
827
- *
828
- * @example
829
- * ```typescript
830
- * const hex = shortHexNumber("AB12"); // Valid
831
- * ```
832
- */
833
- const shortHexNumber = (val) => hexBinary(val, 2);
834
- /**
835
- * Validates a single-byte hexadecimal number (1 byte / 2 characters).
836
- *
837
- * Reference: ST_UcharHexNumber in OOXML specification
838
- *
839
- * @param val - The hexadecimal string to validate
840
- * @returns The validated hexadecimal string
841
- * @throws Error if the value is not a valid 2-character hex string
842
- *
843
- * @example
844
- * ```typescript
845
- * const hex = uCharHexNumber("FF"); // Valid
846
- * ```
847
- */
848
- const uCharHexNumber = (val) => hexBinary(val, 1);
849
- /**
850
- * Normalizes a universal measure value by parsing and reformatting.
851
- *
852
- * Ensures the numeric portion is properly formatted while preserving the unit.
853
- *
854
- * Reference: ST_UniversalMeasure in OOXML specification
855
- *
856
- * @param val - The universal measure string to normalize
857
- * @returns The normalized universal measure
858
- *
859
- * @example
860
- * ```typescript
861
- * const measure = universalMeasureValue("10.500mm"); // Returns "10.5mm"
862
- * ```
863
- */
864
- const universalMeasureValue = (val) => {
865
- const unit = val.slice(-2);
866
- const amount = val.substring(0, val.length - 2);
867
- return `${Number(amount)}${unit}`;
868
- };
869
- /**
870
- * Validates and normalizes a positive universal measure value.
871
- *
872
- * Reference: ST_PositiveUniversalMeasure in OOXML specification
873
- *
874
- * @param val - The positive universal measure string to validate
875
- * @returns The normalized positive universal measure
876
- * @throws Error if the value is negative
877
- *
878
- * @example
879
- * ```typescript
880
- * const measure = positiveUniversalMeasureValue("10.5mm"); // Valid
881
- * const invalid = positiveUniversalMeasureValue("-5mm"); // Throws Error
882
- * ```
883
- */
884
- const positiveUniversalMeasureValue = (val) => {
885
- const value = universalMeasureValue(val);
886
- if (parseFloat(value) < 0) throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);
887
- return value;
888
- };
889
- /**
890
- * Validates and normalizes a hexadecimal color value.
891
- *
892
- * Accepts either "auto" or a 6-character RGB hex value (with or without # prefix).
893
- * The # prefix is commonly used but technically invalid in OOXML, so it is stripped
894
- * for strict compliance.
895
- *
896
- * Reference: ST_HexColor in OOXML specification
897
- *
898
- * @param val - The color value to validate ("auto" or hex color)
899
- * @returns The normalized color value
900
- * @throws Error if the hex color is invalid
901
- *
902
- * @example
903
- * ```typescript
904
- * const color1 = hexColorValue("auto"); // Returns "auto"
905
- * const color2 = hexColorValue("FF0000"); // Returns "FF0000"
906
- * const color3 = hexColorValue("#00FF00"); // Returns "00FF00" (# stripped)
907
- * ```
908
- */
909
- const hexColorValue = (val) => {
910
- if (val === "auto") return val;
911
- return hexBinary(val.charAt(0) === "#" ? val.substring(1) : val, 3);
912
- };
913
- /**
914
- * Validates a signed TWIP measurement value.
915
- *
916
- * Accepts either a universal measure string or a numeric TWIP value.
917
- *
918
- * Reference: ST_SignedTwipsMeasure in OOXML specification
919
- *
920
- * @param val - The measurement value (universal measure or number)
921
- * @returns The normalized measurement value
922
- *
923
- * @example
924
- * ```typescript
925
- * const measure1 = signedTwipsMeasureValue("10mm");
926
- * const measure2 = signedTwipsMeasureValue(1440); // 1 inch in TWIP
927
- * ```
928
- */
929
- const signedTwipsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
930
- /**
931
- * Validates a half-point (HPS) measurement value.
932
- *
933
- * Accepts either a positive universal measure string or a positive number.
934
- * HPS (half-points) are commonly used for font sizes.
935
- *
936
- * Reference: ST_HpsMeasure in OOXML specification
937
- *
938
- * @param val - The measurement value (positive universal measure or number)
939
- * @returns The normalized measurement value
940
- *
941
- * @example
942
- * ```typescript
943
- * const fontSize1 = hpsMeasureValue("12pt");
944
- * const fontSize2 = hpsMeasureValue(24); // 12pt in half-points
945
- * ```
946
- */
947
- const hpsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
948
- /**
949
- * Validates a signed half-point (HPS) measurement value.
950
- *
951
- * Accepts either a universal measure string or a numeric value.
952
- *
953
- * Reference: ST_SignedHpsMeasure in OOXML specification
954
- *
955
- * @param val - The measurement value (universal measure or number)
956
- * @returns The normalized measurement value
957
- *
958
- * @example
959
- * ```typescript
960
- * const spacing1 = signedHpsMeasureValue("6pt");
961
- * const spacing2 = signedHpsMeasureValue(-12); // Negative spacing
962
- * ```
963
- */
964
- const signedHpsMeasureValue = (val) => typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
965
- /**
966
- * Validates a positive TWIP measurement value.
967
- *
968
- * Accepts either a positive universal measure string or a positive number.
969
- *
970
- * Reference: ST_TwipsMeasure in OOXML specification
971
- *
972
- * @param val - The measurement value (positive universal measure or number)
973
- * @returns The normalized measurement value
974
- *
975
- * @example
976
- * ```typescript
977
- * const width1 = twipsMeasureValue("25.4mm");
978
- * const width2 = twipsMeasureValue(1440); // 1 inch in TWIP
979
- * ```
980
- */
981
- const twipsMeasureValue = (val) => typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
982
- /**
983
- * Normalizes a percentage value by parsing and reformatting.
984
- *
985
- * Reference: ST_Percentage in OOXML specification
986
- *
987
- * @param val - The percentage string to normalize
988
- * @returns The normalized percentage
989
- *
990
- * @example
991
- * ```typescript
992
- * const percent = percentageValue("50.000%"); // Returns "50%"
993
- * ```
994
- */
995
- const percentageValue = (val) => {
996
- const percent = val.substring(0, val.length - 1);
997
- return `${Number(percent)}%`;
998
- };
999
- /**
1000
- * Validates a measurement value that can be expressed as a number, percentage, or universal measure.
1001
- *
1002
- * Reference: ST_MeasurementOrPercent in OOXML specification
1003
- *
1004
- * @param val - The measurement value (number, percentage, or universal measure)
1005
- * @returns The normalized measurement value
1006
- *
1007
- * @example
1008
- * ```typescript
1009
- * const measure1 = measurementOrPercentValue(100); // Unqualified number
1010
- * const measure2 = measurementOrPercentValue("50%"); // Percentage
1011
- * const measure3 = measurementOrPercentValue("10mm"); // Universal measure
1012
- * ```
1013
- */
1014
- const measurementOrPercentValue = (val) => {
1015
- if (typeof val === "number") return decimalNumber(val);
1016
- if (val.slice(-1) === "%") return percentageValue(val);
1017
- return universalMeasureValue(val);
1018
- };
1019
- /**
1020
- * Validates an eighth-point measurement value.
1021
- *
1022
- * Eighth-points are used for fine-grained measurements in text formatting.
1023
- *
1024
- * Reference: ST_EighthPointMeasure in OOXML specification
1025
- *
1026
- * @param val - The measurement value in eighth-points
1027
- * @returns The validated positive integer value
1028
- *
1029
- * @example
1030
- * ```typescript
1031
- * const measure = eighthPointMeasureValue(16); // 2 points
1032
- * ```
1033
- */
1034
- const eighthPointMeasureValue = unsignedDecimalNumber;
1035
- /**
1036
- * Validates a point measurement value.
1037
- *
1038
- * Reference: ST_PointMeasure in OOXML specification
1039
- *
1040
- * @param val - The measurement value in points
1041
- * @returns The validated positive integer value
1042
- *
1043
- * @example
1044
- * ```typescript
1045
- * const fontSize = pointMeasureValue(12); // 12pt
1046
- * ```
1047
- */
1048
- const pointMeasureValue = unsignedDecimalNumber;
1049
- /**
1050
- * Converts a JavaScript Date object to an ISO 8601 date-time string.
1051
- *
1052
- * The format is CCYY-MM-DDThh:mm:ss.sssZ where T is a literal and Z indicates UTC.
1053
- * This matches the xsd:dateTime format required by OOXML.
1054
- *
1055
- * Reference: ST_DateTime in OOXML specification
1056
- *
1057
- * @param val - The Date object to convert
1058
- * @returns An ISO 8601 formatted date-time string
1059
- *
1060
- * @example
1061
- * ```typescript
1062
- * const now = new Date();
1063
- * const timestamp = dateTimeValue(now); // Returns "2024-01-15T10:30:00.000Z"
1064
- * ```
1065
- */
1066
- const dateTimeValue = (val) => val.toISOString();
1067
- /**
1068
- * Theme color values used throughout OOXML for referencing document theme colors.
1069
- *
1070
- * Reference: ST_ThemeColor in OOXML specification
1071
- *
1072
- * @publicApi
1073
- */
1074
- const ThemeColor = {
1075
- DARK1: "dark1",
1076
- LIGHT1: "light1",
1077
- DARK2: "dark2",
1078
- LIGHT2: "light2",
1079
- ACCENT1: "accent1",
1080
- ACCENT2: "accent2",
1081
- ACCENT3: "accent3",
1082
- ACCENT4: "accent4",
1083
- ACCENT5: "accent5",
1084
- ACCENT6: "accent6",
1085
- HYPERLINK: "hyperlink",
1086
- FOLLOWED_HYPERLINK: "followedHyperlink",
1087
- NONE: "none",
1088
- BACKGROUND1: "background1",
1089
- TEXT1: "text1",
1090
- BACKGROUND2: "background2",
1091
- TEXT2: "text2"
1092
- };
1093
- /**
1094
- * Theme font values used for referencing document theme fonts.
1095
- *
1096
- * Reference: ST_Theme in OOXML specification
1097
- *
1098
- * @publicApi
1099
- */
1100
- const ThemeFont = {
1101
- MAJOR_EAST_ASIA: "majorEastAsia",
1102
- MAJOR_BIDI: "majorBidi",
1103
- MAJOR_ASCII: "majorAscii",
1104
- MAJOR_H_ANSI: "majorHAnsi",
1105
- MINOR_EAST_ASIA: "minorEastAsia",
1106
- MINOR_BIDI: "minorBidi",
1107
- MINOR_ASCII: "minorAscii",
1108
- MINOR_H_ANSI: "minorHAnsi"
1109
- };
1110
- //#endregion
1111
- export { convertOutput as $, replaceChartPlaceholders as A, compileMapping as B, findAndReplaceImagePlaceholders as C, getVideoRefs as D, getReferencedMedia as E, replaceSmartArtPlaceholders as F, levelForMediaName as G, ZIP_STORED_LEVEL as H, replaceVideoPlaceholders as I, zipAndConvert as J, strFromU8$1 as K, derivePasswordHash as L, replaceImagePlaceholders as M, replaceMediaPlaceholders as N, hasPlaceholders as O, replaceNumberingPlaceholders as P, OoxmlMimeType as Q, hashPasswordAgile as R, collectPlaceholderKeys as S, getMediaRefs as T, createPacker as U, ZIP_DEFLATE_LEVEL as V, createZipStream as W, hasNativeInflate as X, zipSyncAndConvert as Y, nativeUnzip as Z, twipsMeasureValue as _, eighthPointMeasureValue as a, unsignedDecimalNumber as b, hpsMeasureValue as c, percentageValue as d, pointMeasureValue as f, signedTwipsMeasureValue as g, signedHpsMeasureValue as h, decimalNumber as i, replaceHyperlinkPlaceholders as j, replaceAllPlaceholders as k, longHexNumber as l, shortHexNumber as m, ThemeFont as n, hexBinary as o, positiveUniversalMeasureValue as p, unzipSync$1 as q, dateTimeValue as r, hexColorValue as s, ThemeColor as t, measurementOrPercentValue as u, uCharHexNumber as v, formatId as w, addSmartArtRelationships as x, universalMeasureValue as y, randomBytes as z };
889
+ export { ZIP_STORED_LEVEL as A, OoxmlMimeType as B, replaceVideoPlaceholders as C, addBinaryFile as D, randomBytes as E, strFromU8$1 as F, hasNativeInflate as H, unzipSync$1 as I, zipAndConvert as L, createPacker as M, createZipStream as N, compileMapping as O, levelForMediaName as P, zipSync$1 as R, replaceSmartArtPlaceholders as S, hashPasswordAgile as T, nativeCrc32 as U, convertOutput as V, nativeUnzip as W, replaceMediaPlaceholders as _, getAudioRefs as a, replaceOlePlaceholders as b, getReferencedMedia as c, replaceAllPlaceholders as d, replaceAudioPlaceholders as f, replaceImagePlaceholders as g, replaceImageLinkPlaceholders as h, formatId as i, ZipStreamWriter as j, ZIP_DEFLATE_LEVEL as k, getVideoRefs as l, replaceHyperlinkPlaceholders as m, collectPlaceholderKeys as n, getMediaRefs as o, replaceChartPlaceholders as p, findAndReplaceImagePlaceholders as r, getOleRefs as s, addSmartArtRelationships as t, hasPlaceholders as u, replaceNumberingPlaceholders as v, derivePasswordHash as w, replacePlaceholders as x, replaceOleLinkPlaceholders as y, zipSyncAndConvert as z };
1112
890
 
1113
- //# sourceMappingURL=util-Tq9PSjK0.mjs.map
891
+ //# sourceMappingURL=util-ptE16MEk.mjs.map