documents.js 1.41.0 → 1.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6,17 +6,26 @@ let odf_js = require("odf.js");
6
6
  let fflate = require("fflate");
7
7
  //#region src/model/content.ts
8
8
  const CONTENT_FORMAT_VERSION = 1;
9
- const ContentDocumentSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
10
- kind: zod.z.literal("wordprocessing"),
11
- formatVersion: zod.z.literal(1),
12
- metadata: document_content_model.LayoutMetadataSchema,
13
- sections: zod.z.array(document_content_model.ContentSectionSchema)
14
- }), zod.z.object({
15
- kind: zod.z.literal("presentation"),
16
- formatVersion: zod.z.literal(1),
17
- metadata: document_content_model.LayoutMetadataSchema,
18
- slides: zod.z.array(document_content_model.ContentSlideSchema)
19
- })]);
9
+ const ContentDocumentSchema = zod.z.discriminatedUnion("kind", [
10
+ zod.z.object({
11
+ kind: zod.z.literal("wordprocessing"),
12
+ formatVersion: zod.z.literal(1),
13
+ metadata: document_content_model.LayoutMetadataSchema,
14
+ sections: zod.z.array(document_content_model.ContentSectionSchema)
15
+ }),
16
+ zod.z.object({
17
+ kind: zod.z.literal("presentation"),
18
+ formatVersion: zod.z.literal(1),
19
+ metadata: document_content_model.LayoutMetadataSchema,
20
+ slides: zod.z.array(document_content_model.ContentSlideSchema)
21
+ }),
22
+ zod.z.object({
23
+ kind: zod.z.literal("spreadsheet"),
24
+ formatVersion: zod.z.literal(1),
25
+ metadata: document_content_model.LayoutMetadataSchema,
26
+ sheets: zod.z.array(document_content_model.ContentSheetSchema)
27
+ })
28
+ ]);
20
29
  //#endregion
21
30
  //#region src/model/geometry.ts
22
31
  function flipY(box, containerHeightPt) {
@@ -521,7 +530,7 @@ function needsSpacePreserve(text) {
521
530
  }
522
531
  //#endregion
523
532
  //#region src/edit/docx/run.ts
524
- function directChild$8(parent, tag) {
533
+ function directChild$9(parent, tag) {
525
534
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
526
535
  }
527
536
  function appendUElement(rPr, value) {
@@ -530,7 +539,7 @@ function appendUElement(rPr, value) {
530
539
  return created;
531
540
  }
532
541
  function findOrCreateT(run) {
533
- const existing = directChild$8(run, "w:t");
542
+ const existing = directChild$9(run, "w:t");
534
543
  if (existing !== void 0) return existing;
535
544
  const created = el("w:t");
536
545
  run.children.push(created);
@@ -550,7 +559,7 @@ var DocxRun = class {
550
559
  }
551
560
  rPr(create) {
552
561
  const node = this.live();
553
- return create ? ensureFirstChild(node, "w:rPr") : directChild$8(node, "w:rPr");
562
+ return create ? ensureFirstChild(node, "w:rPr") : directChild$9(node, "w:rPr");
554
563
  }
555
564
  get text() {
556
565
  return (0, ooxml_js.textContent)(this.live());
@@ -574,14 +583,14 @@ var DocxRun = class {
574
583
  }
575
584
  get underline() {
576
585
  const rPr = this.rPr(false);
577
- const uElement = rPr === void 0 ? void 0 : directChild$8(rPr, "w:u");
586
+ const uElement = rPr === void 0 ? void 0 : directChild$9(rPr, "w:u");
578
587
  if (uElement === void 0) return false;
579
588
  for (const a of uElement.attributes) if (a.name === "w:val") return a.value !== "none";
580
589
  return true;
581
590
  }
582
591
  set underline(value) {
583
592
  const rPr = this.rPr(true);
584
- const existing = directChild$8(rPr, "w:u");
593
+ const existing = directChild$9(rPr, "w:u");
585
594
  if (existing === void 0) {
586
595
  appendUElement(rPr, value);
587
596
  return;
@@ -655,7 +664,7 @@ function buildRun$1(init = {}) {
655
664
  }
656
665
  //#endregion
657
666
  //#region src/edit/docx/paragraph.ts
658
- function directChild$7(parent, tag) {
667
+ function directChild$8(parent, tag) {
659
668
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
660
669
  }
661
670
  var DocxParagraph = class {
@@ -674,7 +683,7 @@ var DocxParagraph = class {
674
683
  }
675
684
  pPr(create) {
676
685
  const node = this.live();
677
- return create ? ensureFirstChild(node, "w:pPr") : directChild$7(node, "w:pPr");
686
+ return create ? ensureFirstChild(node, "w:pPr") : directChild$8(node, "w:pPr");
678
687
  }
679
688
  get text() {
680
689
  return (0, ooxml_js.textContent)(this.live());
@@ -711,7 +720,7 @@ var DocxParagraph = class {
711
720
  set styleId(value) {
712
721
  if (value === void 0) {
713
722
  const pPr = this.pPr(false);
714
- const existing = pPr === void 0 ? void 0 : directChild$7(pPr, "w:pStyle");
723
+ const existing = pPr === void 0 ? void 0 : directChild$8(pPr, "w:pStyle");
715
724
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
716
725
  return;
717
726
  }
@@ -723,7 +732,7 @@ var DocxParagraph = class {
723
732
  set alignment(value) {
724
733
  if (value === void 0) {
725
734
  const pPr = this.pPr(false);
726
- const existing = pPr === void 0 ? void 0 : directChild$7(pPr, "w:jc");
735
+ const existing = pPr === void 0 ? void 0 : directChild$8(pPr, "w:jc");
727
736
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
728
737
  return;
729
738
  }
@@ -731,12 +740,12 @@ var DocxParagraph = class {
731
740
  }
732
741
  get list() {
733
742
  const pPr = this.pPr(false);
734
- const numPr = pPr === void 0 ? void 0 : directChild$7(pPr, "w:numPr");
743
+ const numPr = pPr === void 0 ? void 0 : directChild$8(pPr, "w:numPr");
735
744
  if (numPr === void 0) return;
736
- const numIdElement = directChild$7(numPr, "w:numId");
745
+ const numIdElement = directChild$8(numPr, "w:numId");
737
746
  const numId = numIdElement === void 0 ? void 0 : (0, ooxml_js.attr)(numIdElement, "w:val");
738
747
  if (numId === void 0) return;
739
- const ilvlElement = directChild$7(numPr, "w:ilvl");
748
+ const ilvlElement = directChild$8(numPr, "w:ilvl");
740
749
  const ilvl = ilvlElement === void 0 ? void 0 : (0, ooxml_js.attr)(ilvlElement, "w:val");
741
750
  return {
742
751
  numId,
@@ -746,7 +755,7 @@ var DocxParagraph = class {
746
755
  set list(value) {
747
756
  const pPr = this.pPr(true);
748
757
  if (value === void 0) {
749
- const existing = directChild$7(pPr, "w:numPr");
758
+ const existing = directChild$8(pPr, "w:numPr");
750
759
  if (existing !== void 0) removeChild(pPr.children, existing);
751
760
  return;
752
761
  }
@@ -780,7 +789,7 @@ function buildParagraph$1(init = {}) {
780
789
  const CONTENT_TYPES_NS$1 = "http://schemas.openxmlformats.org/package/2006/content-types";
781
790
  const RELS_NS$1 = "http://schemas.openxmlformats.org/package/2006/relationships";
782
791
  const WORDML_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
783
- function declaration$3() {
792
+ function declaration$4() {
784
793
  return {
785
794
  type: "declaration",
786
795
  attributes: [
@@ -849,23 +858,23 @@ function createEmptyDocxPackage() {
849
858
  return { parts: {
850
859
  "[Content_Types].xml": {
851
860
  kind: "xml",
852
- nodes: [declaration$3(), contentTypes]
861
+ nodes: [declaration$4(), contentTypes]
853
862
  },
854
863
  "_rels/.rels": {
855
864
  kind: "xml",
856
- nodes: [declaration$3(), rootRels]
865
+ nodes: [declaration$4(), rootRels]
857
866
  },
858
867
  "word/document.xml": {
859
868
  kind: "xml",
860
- nodes: [declaration$3(), document]
869
+ nodes: [declaration$4(), document]
861
870
  },
862
871
  "word/_rels/document.xml.rels": {
863
872
  kind: "xml",
864
- nodes: [declaration$3(), documentRels]
873
+ nodes: [declaration$4(), documentRels]
865
874
  },
866
875
  "word/styles.xml": {
867
876
  kind: "xml",
868
- nodes: [declaration$3(), styles]
877
+ nodes: [declaration$4(), styles]
869
878
  }
870
879
  } };
871
880
  }
@@ -1156,7 +1165,7 @@ const SLIDE_LAYOUT_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/
1156
1165
  const THEME_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
1157
1166
  const NOTES_MASTER_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster";
1158
1167
  const MIN_MASTER_OR_LAYOUT_ID = 2147483648;
1159
- function declaration$2() {
1168
+ function declaration$3() {
1160
1169
  return {
1161
1170
  type: "declaration",
1162
1171
  attributes: [
@@ -1306,7 +1315,7 @@ function ensureNotesMaster(pkg) {
1306
1315
  });
1307
1316
  pkg.parts[NOTES_MASTER_PART_PATH] = {
1308
1317
  kind: "xml",
1309
- nodes: [declaration$2(), buildNotesMaster()]
1318
+ nodes: [declaration$3(), buildNotesMaster()]
1310
1319
  };
1311
1320
  ensureContentTypeOverride(pkg, NOTES_MASTER_PART_PATH, NOTES_MASTER_CONTENT_TYPE);
1312
1321
  const presentationToNotesMasterTarget = buildRelativeTarget(PRESENTATION_PART_PATH$1, NOTES_MASTER_PART_PATH);
@@ -1345,15 +1354,15 @@ function createEmptyPptxPackage() {
1345
1354
  const pkg = { parts: {
1346
1355
  "[Content_Types].xml": {
1347
1356
  kind: "xml",
1348
- nodes: [declaration$2(), contentTypes]
1357
+ nodes: [declaration$3(), contentTypes]
1349
1358
  },
1350
1359
  "_rels/.rels": {
1351
1360
  kind: "xml",
1352
- nodes: [declaration$2(), rootRels]
1361
+ nodes: [declaration$3(), rootRels]
1353
1362
  },
1354
1363
  [PRESENTATION_PART_PATH$1]: {
1355
1364
  kind: "xml",
1356
- nodes: [declaration$2(), el("p:presentation", {
1365
+ nodes: [declaration$3(), el("p:presentation", {
1357
1366
  "xmlns:p": PML_NS,
1358
1367
  "xmlns:r": R_NS
1359
1368
  })]
@@ -1366,7 +1375,7 @@ function createEmptyPptxPackage() {
1366
1375
  });
1367
1376
  pkg.parts[SLIDE_LAYOUT_PART_PATH] = {
1368
1377
  kind: "xml",
1369
- nodes: [declaration$2(), buildSlideLayout()]
1378
+ nodes: [declaration$3(), buildSlideLayout()]
1370
1379
  };
1371
1380
  ensureContentTypeOverride(pkg, SLIDE_LAYOUT_PART_PATH, SLIDE_LAYOUT_CONTENT_TYPE);
1372
1381
  const masterToLayoutTarget = buildRelativeTarget(SLIDE_MASTER_PART_PATH, SLIDE_LAYOUT_PART_PATH);
@@ -1381,12 +1390,12 @@ function createEmptyPptxPackage() {
1381
1390
  });
1382
1391
  pkg.parts[SLIDE_MASTER_PART_PATH] = {
1383
1392
  kind: "xml",
1384
- nodes: [declaration$2(), buildSlideMaster(masterToLayoutRelId)]
1393
+ nodes: [declaration$3(), buildSlideMaster(masterToLayoutRelId)]
1385
1394
  };
1386
1395
  ensureContentTypeOverride(pkg, SLIDE_MASTER_PART_PATH, SLIDE_MASTER_CONTENT_TYPE);
1387
1396
  pkg.parts[THEME_PART_PATH] = {
1388
1397
  kind: "xml",
1389
- nodes: [declaration$2(), buildTheme()]
1398
+ nodes: [declaration$3(), buildTheme()]
1390
1399
  };
1391
1400
  ensureContentTypeOverride(pkg, THEME_PART_PATH, THEME_CONTENT_TYPE);
1392
1401
  const presentationToMasterTarget = buildRelativeTarget(PRESENTATION_PART_PATH$1, SLIDE_MASTER_PART_PATH);
@@ -1411,7 +1420,7 @@ function createEmptyPptxPackage() {
1411
1420
  }
1412
1421
  //#endregion
1413
1422
  //#region src/edit/pptx/shape.ts
1414
- function directChild$6(parent, tag) {
1423
+ function directChild$7(parent, tag) {
1415
1424
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1416
1425
  }
1417
1426
  function parseEmuAttr(element, name) {
@@ -1432,7 +1441,7 @@ var PptxShape = class {
1432
1441
  }
1433
1442
  spPrElement(create) {
1434
1443
  const node = this.live();
1435
- const existing = directChild$6(node, "p:spPr");
1444
+ const existing = directChild$7(node, "p:spPr");
1436
1445
  if (existing !== void 0 || !create) return existing;
1437
1446
  const created = el("p:spPr");
1438
1447
  node.children.push(created);
@@ -1440,10 +1449,10 @@ var PptxShape = class {
1440
1449
  }
1441
1450
  get frame() {
1442
1451
  const spPr = this.spPrElement(false);
1443
- const xfrm = spPr === void 0 ? void 0 : directChild$6(spPr, "a:xfrm");
1452
+ const xfrm = spPr === void 0 ? void 0 : directChild$7(spPr, "a:xfrm");
1444
1453
  if (xfrm === void 0) return;
1445
- const off = directChild$6(xfrm, "a:off");
1446
- const ext = directChild$6(xfrm, "a:ext");
1454
+ const off = directChild$7(xfrm, "a:off");
1455
+ const ext = directChild$7(xfrm, "a:ext");
1447
1456
  if (off === void 0 || ext === void 0) return;
1448
1457
  const x = parseEmuAttr(off, "x");
1449
1458
  const y = parseEmuAttr(off, "y");
@@ -1459,7 +1468,7 @@ var PptxShape = class {
1459
1468
  }
1460
1469
  set frame(value) {
1461
1470
  const spPr = this.spPrElement(true);
1462
- let xfrm = directChild$6(spPr, "a:xfrm");
1471
+ let xfrm = directChild$7(spPr, "a:xfrm");
1463
1472
  if (xfrm === void 0) {
1464
1473
  xfrm = el("a:xfrm");
1465
1474
  spPr.children.unshift(xfrm);
@@ -1473,12 +1482,12 @@ var PptxShape = class {
1473
1482
  })];
1474
1483
  }
1475
1484
  get text() {
1476
- const txBody = directChild$6(this.live(), "p:txBody");
1485
+ const txBody = directChild$7(this.live(), "p:txBody");
1477
1486
  return txBody === void 0 ? "" : (0, ooxml_js.textContent)(txBody);
1478
1487
  }
1479
1488
  set text(value) {
1480
1489
  const node = this.live();
1481
- let txBody = directChild$6(node, "p:txBody");
1490
+ let txBody = directChild$7(node, "p:txBody");
1482
1491
  if (txBody === void 0) {
1483
1492
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1484
1493
  node.children.push(txBody);
@@ -1489,7 +1498,7 @@ var PptxShape = class {
1489
1498
  }
1490
1499
  setParagraphs(paragraphs) {
1491
1500
  const node = this.live();
1492
- let txBody = directChild$6(node, "p:txBody");
1501
+ let txBody = directChild$7(node, "p:txBody");
1493
1502
  if (txBody === void 0) {
1494
1503
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1495
1504
  node.children.push(txBody);
@@ -1600,12 +1609,12 @@ function insertPictureShapeMedia(context, slideRoot, frame, image) {
1600
1609
  }
1601
1610
  //#endregion
1602
1611
  //#region src/edit/pptx/slide.ts
1603
- function directChild$5(parent, tag) {
1612
+ function directChild$6(parent, tag) {
1604
1613
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1605
1614
  }
1606
1615
  function findSpTree(slideRoot) {
1607
- const cSld = directChild$5(slideRoot, "p:cSld");
1608
- const spTree = cSld === void 0 ? void 0 : directChild$5(cSld, "p:spTree");
1616
+ const cSld = directChild$6(slideRoot, "p:cSld");
1617
+ const spTree = cSld === void 0 ? void 0 : directChild$6(cSld, "p:spTree");
1609
1618
  if (spTree === void 0) throw new Error("slide has no p:cSld/p:spTree element");
1610
1619
  return spTree;
1611
1620
  }
@@ -1737,7 +1746,7 @@ const PRESENTATION_PART_PATH = "ppt/presentation.xml";
1737
1746
  const MEDIA_DIR = "ppt/media";
1738
1747
  const SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
1739
1748
  const SLIDE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
1740
- function directChild$4(parent, tag) {
1749
+ function directChild$5(parent, tag) {
1741
1750
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1742
1751
  }
1743
1752
  function attrValue(element, name) {
@@ -1749,12 +1758,12 @@ function findPresentationRoot(pkg) {
1749
1758
  return root;
1750
1759
  }
1751
1760
  function findSldIdLst(presentationRoot) {
1752
- const sldIdLst = directChild$4(presentationRoot, "p:sldIdLst");
1761
+ const sldIdLst = directChild$5(presentationRoot, "p:sldIdLst");
1753
1762
  if (sldIdLst === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldIdLst element`);
1754
1763
  return sldIdLst;
1755
1764
  }
1756
1765
  function findSldSz(presentationRoot) {
1757
- const sldSz = directChild$4(presentationRoot, "p:sldSz");
1766
+ const sldSz = directChild$5(presentationRoot, "p:sldSz");
1758
1767
  if (sldSz === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldSz element`);
1759
1768
  return sldSz;
1760
1769
  }
@@ -1953,12 +1962,12 @@ function appendShape$1(slide, shape) {
1953
1962
  }
1954
1963
  //#endregion
1955
1964
  //#region src/edit/odt/automatic-styles.ts
1956
- const CONTENT_PART_PATH$2 = "content.xml";
1965
+ const CONTENT_PART_PATH$3 = "content.xml";
1957
1966
  function ensureAutomaticStyles(pkg) {
1958
- const part = pkg.parts[CONTENT_PART_PATH$2];
1959
- if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$2} part`);
1967
+ const part = pkg.parts[CONTENT_PART_PATH$3];
1968
+ if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$3} part`);
1960
1969
  const root = part.nodes.find((n) => n.type === "element");
1961
- if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$2} has no root element`);
1970
+ if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$3} has no root element`);
1962
1971
  for (const child of root.children) if (child.type === "element" && child.tag === "office:automatic-styles") return child;
1963
1972
  const created = el("office:automatic-styles");
1964
1973
  const insertBeforeTags = /* @__PURE__ */ new Set([
@@ -2052,7 +2061,7 @@ function applyStyleChange(pkg, element, family, change) {
2052
2061
  ...readCurrentStyleProperties(pkg, element, family),
2053
2062
  ...change
2054
2063
  };
2055
- const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$2).intern({
2064
+ const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$3).intern({
2056
2065
  family,
2057
2066
  properties: merged
2058
2067
  });
@@ -2283,7 +2292,7 @@ function buildList(pkg) {
2283
2292
  }
2284
2293
  //#endregion
2285
2294
  //#region src/edit/odt/scaffold.ts
2286
- const CONTENT_NS_PREFIXES$1 = [
2295
+ const CONTENT_NS_PREFIXES$2 = [
2287
2296
  "office",
2288
2297
  "style",
2289
2298
  "text",
@@ -2293,7 +2302,7 @@ const CONTENT_NS_PREFIXES$1 = [
2293
2302
  "svg",
2294
2303
  "xlink"
2295
2304
  ];
2296
- const STYLES_NS_PREFIXES$1 = [
2305
+ const STYLES_NS_PREFIXES$2 = [
2297
2306
  "office",
2298
2307
  "style",
2299
2308
  "text",
@@ -2303,16 +2312,16 @@ const STYLES_NS_PREFIXES$1 = [
2303
2312
  "svg",
2304
2313
  "xlink"
2305
2314
  ];
2306
- const META_NS_PREFIXES$1 = [
2315
+ const META_NS_PREFIXES$2 = [
2307
2316
  "office",
2308
2317
  "meta",
2309
2318
  "dc"
2310
2319
  ];
2311
- const ODF_VERSION$1 = "1.3";
2312
- const PAGE_LAYOUT_NAME$1 = "PM1";
2313
- const MASTER_PAGE_NAME$1 = "Standard";
2320
+ const ODF_VERSION$2 = "1.3";
2321
+ const PAGE_LAYOUT_NAME$2 = "PM1";
2322
+ const MASTER_PAGE_NAME$2 = "Standard";
2314
2323
  const DEFAULT_MARGIN_PT = 72;
2315
- function declaration$1() {
2324
+ function declaration$2() {
2316
2325
  return {
2317
2326
  type: "declaration",
2318
2327
  attributes: [
@@ -2331,8 +2340,8 @@ function declaration$1() {
2331
2340
  ]
2332
2341
  };
2333
2342
  }
2334
- function buildPageLayout$1() {
2335
- return el("style:page-layout", { "style:name": PAGE_LAYOUT_NAME$1 }, [el("style:page-layout-properties", {
2343
+ function buildPageLayout$2() {
2344
+ return el("style:page-layout", { "style:name": PAGE_LAYOUT_NAME$2 }, [el("style:page-layout-properties", {
2336
2345
  "fo:page-width": `${document_content_model.PAGE_SIZE_LETTER.widthPt}pt`,
2337
2346
  "fo:page-height": `${document_content_model.PAGE_SIZE_LETTER.heightPt}pt`,
2338
2347
  "fo:margin-top": `${DEFAULT_MARGIN_PT}pt`,
@@ -2341,44 +2350,44 @@ function buildPageLayout$1() {
2341
2350
  "fo:margin-left": `${DEFAULT_MARGIN_PT}pt`
2342
2351
  })]);
2343
2352
  }
2344
- function buildStylesXml$1() {
2353
+ function buildStylesXml$2() {
2345
2354
  return el("office:document-styles", {
2346
- ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES$1]),
2347
- "office:version": ODF_VERSION$1
2355
+ ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES$2]),
2356
+ "office:version": ODF_VERSION$2
2348
2357
  }, [
2349
2358
  el("office:styles"),
2350
- el("office:automatic-styles", {}, [buildPageLayout$1()]),
2359
+ el("office:automatic-styles", {}, [buildPageLayout$2()]),
2351
2360
  el("office:master-styles", {}, [el("style:master-page", {
2352
- "style:name": MASTER_PAGE_NAME$1,
2353
- "style:page-layout-name": PAGE_LAYOUT_NAME$1
2361
+ "style:name": MASTER_PAGE_NAME$2,
2362
+ "style:page-layout-name": PAGE_LAYOUT_NAME$2
2354
2363
  })])
2355
2364
  ]);
2356
2365
  }
2357
- function buildContentXml$1() {
2366
+ function buildContentXml$2() {
2358
2367
  return el("office:document-content", {
2359
- ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES$1]),
2360
- "office:version": ODF_VERSION$1
2368
+ ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES$2]),
2369
+ "office:version": ODF_VERSION$2
2361
2370
  }, [el("office:automatic-styles"), el("office:body", {}, [el("office:text")])]);
2362
2371
  }
2363
- function buildMetaXml$1() {
2372
+ function buildMetaXml$2() {
2364
2373
  return el("office:document-meta", {
2365
- ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES$1]),
2366
- "office:version": ODF_VERSION$1
2374
+ ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES$2]),
2375
+ "office:version": ODF_VERSION$2
2367
2376
  }, [el("office:meta")]);
2368
2377
  }
2369
2378
  function createEmptyOdtPackage() {
2370
2379
  const pkg = { parts: {
2371
2380
  "content.xml": {
2372
2381
  kind: "xml",
2373
- nodes: [declaration$1(), buildContentXml$1()]
2382
+ nodes: [declaration$2(), buildContentXml$2()]
2374
2383
  },
2375
2384
  "styles.xml": {
2376
2385
  kind: "xml",
2377
- nodes: [declaration$1(), buildStylesXml$1()]
2386
+ nodes: [declaration$2(), buildStylesXml$2()]
2378
2387
  },
2379
2388
  "meta.xml": {
2380
2389
  kind: "xml",
2381
- nodes: [declaration$1(), buildMetaXml$1()]
2390
+ nodes: [declaration$2(), buildMetaXml$2()]
2382
2391
  }
2383
2392
  } };
2384
2393
  (0, odf_js.setDocumentMediaType)(pkg, odf_js.ODF_MEDIA_TYPES.odt);
@@ -2499,20 +2508,20 @@ function buildTable(pkg, init) {
2499
2508
  }
2500
2509
  //#endregion
2501
2510
  //#region src/edit/odt/editor.ts
2502
- const CONTENT_PART_PATH$1 = "content.xml";
2511
+ const CONTENT_PART_PATH$2 = "content.xml";
2503
2512
  function findContentRoot(pkg) {
2504
- const part = pkg.parts[CONTENT_PART_PATH$1];
2513
+ const part = pkg.parts[CONTENT_PART_PATH$2];
2505
2514
  const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2506
- if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH$1}`);
2515
+ if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH$2}`);
2507
2516
  return root;
2508
2517
  }
2509
- function directChild$3(parent, tag) {
2518
+ function directChild$4(parent, tag) {
2510
2519
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2511
2520
  }
2512
2521
  function findOfficeText(contentRoot) {
2513
- const body = directChild$3(contentRoot, "office:body");
2514
- const text = body === void 0 ? void 0 : directChild$3(body, "office:text");
2515
- if (text === void 0) throw new Error(`${CONTENT_PART_PATH$1} has no office:body/office:text element`);
2522
+ const body = directChild$4(contentRoot, "office:body");
2523
+ const text = body === void 0 ? void 0 : directChild$4(body, "office:text");
2524
+ if (text === void 0) throw new Error(`${CONTENT_PART_PATH$2} has no office:body/office:text element`);
2516
2525
  return text;
2517
2526
  }
2518
2527
  var OdtBodyImpl = class {
@@ -2644,7 +2653,7 @@ function appendBlock(body, block) {
2644
2653
  }
2645
2654
  //#endregion
2646
2655
  //#region src/edit/odp/scaffold.ts
2647
- const CONTENT_NS_PREFIXES = [
2656
+ const CONTENT_NS_PREFIXES$1 = [
2648
2657
  "office",
2649
2658
  "style",
2650
2659
  "text",
@@ -2655,7 +2664,7 @@ const CONTENT_NS_PREFIXES = [
2655
2664
  "svg",
2656
2665
  "xlink"
2657
2666
  ];
2658
- const STYLES_NS_PREFIXES = [
2667
+ const STYLES_NS_PREFIXES$1 = [
2659
2668
  "office",
2660
2669
  "style",
2661
2670
  "text",
@@ -2666,14 +2675,14 @@ const STYLES_NS_PREFIXES = [
2666
2675
  "svg",
2667
2676
  "xlink"
2668
2677
  ];
2669
- const META_NS_PREFIXES = [
2678
+ const META_NS_PREFIXES$1 = [
2670
2679
  "office",
2671
2680
  "meta",
2672
2681
  "dc"
2673
2682
  ];
2674
- const ODF_VERSION = "1.3";
2675
- const MASTER_PAGE_NAME = "Standard";
2676
- function declaration() {
2683
+ const ODF_VERSION$1 = "1.3";
2684
+ const MASTER_PAGE_NAME$1 = "Standard";
2685
+ function declaration$1() {
2677
2686
  return {
2678
2687
  type: "declaration",
2679
2688
  attributes: [
@@ -2692,50 +2701,50 @@ function declaration() {
2692
2701
  ]
2693
2702
  };
2694
2703
  }
2695
- function buildPageLayout() {
2704
+ function buildPageLayout$1() {
2696
2705
  return el("style:page-layout", { "style:name": "PM1" }, [el("style:page-layout-properties", {
2697
2706
  "fo:page-width": `${document_content_model.SLIDE_SIZE_WIDESCREEN.widthPt}pt`,
2698
2707
  "fo:page-height": `${document_content_model.SLIDE_SIZE_WIDESCREEN.heightPt}pt`
2699
2708
  })]);
2700
2709
  }
2701
- function buildStylesXml() {
2710
+ function buildStylesXml$1() {
2702
2711
  return el("office:document-styles", {
2703
- ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES]),
2704
- "office:version": ODF_VERSION
2712
+ ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES$1]),
2713
+ "office:version": ODF_VERSION$1
2705
2714
  }, [
2706
2715
  el("office:styles"),
2707
- el("office:automatic-styles", {}, [buildPageLayout()]),
2716
+ el("office:automatic-styles", {}, [buildPageLayout$1()]),
2708
2717
  el("office:master-styles", {}, [el("style:master-page", {
2709
- "style:name": MASTER_PAGE_NAME,
2718
+ "style:name": MASTER_PAGE_NAME$1,
2710
2719
  "style:page-layout-name": "PM1"
2711
2720
  })])
2712
2721
  ]);
2713
2722
  }
2714
- function buildContentXml() {
2723
+ function buildContentXml$1() {
2715
2724
  return el("office:document-content", {
2716
- ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES]),
2717
- "office:version": ODF_VERSION
2725
+ ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES$1]),
2726
+ "office:version": ODF_VERSION$1
2718
2727
  }, [el("office:automatic-styles"), el("office:body", {}, [el("office:presentation")])]);
2719
2728
  }
2720
- function buildMetaXml() {
2729
+ function buildMetaXml$1() {
2721
2730
  return el("office:document-meta", {
2722
- ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES]),
2723
- "office:version": ODF_VERSION
2731
+ ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES$1]),
2732
+ "office:version": ODF_VERSION$1
2724
2733
  }, [el("office:meta")]);
2725
2734
  }
2726
2735
  function createEmptyOdpPackage() {
2727
2736
  const pkg = { parts: {
2728
2737
  "content.xml": {
2729
2738
  kind: "xml",
2730
- nodes: [declaration(), buildContentXml()]
2739
+ nodes: [declaration$1(), buildContentXml$1()]
2731
2740
  },
2732
2741
  "styles.xml": {
2733
2742
  kind: "xml",
2734
- nodes: [declaration(), buildStylesXml()]
2743
+ nodes: [declaration$1(), buildStylesXml$1()]
2735
2744
  },
2736
2745
  "meta.xml": {
2737
2746
  kind: "xml",
2738
- nodes: [declaration(), buildMetaXml()]
2747
+ nodes: [declaration$1(), buildMetaXml$1()]
2739
2748
  }
2740
2749
  } };
2741
2750
  (0, odf_js.setDocumentMediaType)(pkg, odf_js.ODF_MEDIA_TYPES.odp);
@@ -2775,7 +2784,7 @@ function addImageMedia(pkg, imageBytes, format) {
2775
2784
  }
2776
2785
  //#endregion
2777
2786
  //#region src/edit/odp/shape.ts
2778
- function directChild$2(parent, tag) {
2787
+ function directChild$3(parent, tag) {
2779
2788
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2780
2789
  }
2781
2790
  function buildTransformAttr(frame, rotationDeg) {
@@ -2843,7 +2852,7 @@ var OdpShape = class {
2843
2852
  }
2844
2853
  textBox(create) {
2845
2854
  const node = this.live();
2846
- const existing = directChild$2(node, "draw:text-box");
2855
+ const existing = directChild$3(node, "draw:text-box");
2847
2856
  if (existing !== void 0 || !create) return existing;
2848
2857
  const created = el("draw:text-box");
2849
2858
  node.children.push(created);
@@ -2904,7 +2913,7 @@ function insertImageFrameMedia(context, frame, image) {
2904
2913
  }
2905
2914
  //#endregion
2906
2915
  //#region src/edit/odp/slide.ts
2907
- function directChild$1(parent, tag) {
2916
+ function directChild$2(parent, tag) {
2908
2917
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2909
2918
  }
2910
2919
  const NOTES_FRAME_X_PT = 20;
@@ -2953,13 +2962,13 @@ var OdpSlide = class {
2953
2962
  return new OdpShape(node.children, frameElement, this.context.pkg);
2954
2963
  }
2955
2964
  get notes() {
2956
- const notesElement = directChild$1(this.live(), "presentation:notes");
2965
+ const notesElement = directChild$2(this.live(), "presentation:notes");
2957
2966
  if (notesElement === void 0) return "";
2958
2967
  return (0, ooxml_js.elementsWithTag)(notesElement.children, "text:p").map((p) => decodeOdfText(p.children)).join("\n");
2959
2968
  }
2960
2969
  set notes(value) {
2961
2970
  const node = this.live();
2962
- const existing = directChild$1(node, "presentation:notes");
2971
+ const existing = directChild$2(node, "presentation:notes");
2963
2972
  const notesElement = buildNotesElement(this.context.pkg, value);
2964
2973
  if (existing === void 0) node.children.push(notesElement);
2965
2974
  else existing.children = notesElement.children;
@@ -2971,26 +2980,26 @@ var OdpSlide = class {
2971
2980
  };
2972
2981
  //#endregion
2973
2982
  //#region src/edit/odp/editor.ts
2974
- const CONTENT_PART_PATH = "content.xml";
2983
+ const CONTENT_PART_PATH$1 = "content.xml";
2975
2984
  const STYLES_PART_PATH = "styles.xml";
2976
- function directChild(parent, tag) {
2985
+ function directChild$1(parent, tag) {
2977
2986
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2978
2987
  }
2979
- function findRoot(pkg, partPath) {
2988
+ function findRoot$1(pkg, partPath) {
2980
2989
  const part = pkg.parts[partPath];
2981
2990
  const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2982
2991
  if (root === void 0) throw new Error(`package has no root element at ${partPath}`);
2983
2992
  return root;
2984
2993
  }
2985
2994
  function findOfficePresentation(pkg) {
2986
- const body = directChild(findRoot(pkg, CONTENT_PART_PATH), "office:body");
2987
- const presentation = body === void 0 ? void 0 : directChild(body, "office:presentation");
2988
- if (presentation === void 0) throw new Error(`${CONTENT_PART_PATH} has no office:body/office:presentation element`);
2995
+ const body = directChild$1(findRoot$1(pkg, CONTENT_PART_PATH$1), "office:body");
2996
+ const presentation = body === void 0 ? void 0 : directChild$1(body, "office:presentation");
2997
+ if (presentation === void 0) throw new Error(`${CONTENT_PART_PATH$1} has no office:body/office:presentation element`);
2989
2998
  return presentation;
2990
2999
  }
2991
3000
  function findPageLayoutProperties(pkg) {
2992
- const pageLayout = directChild(findRoot(pkg, STYLES_PART_PATH), "office:automatic-styles")?.children.find((c) => c.type === "element" && c.tag === "style:page-layout" && (0, ooxml_js.attr)(c, "style:name") === "PM1");
2993
- const properties = pageLayout === void 0 ? void 0 : directChild(pageLayout, "style:page-layout-properties");
3001
+ const pageLayout = directChild$1(findRoot$1(pkg, STYLES_PART_PATH), "office:automatic-styles")?.children.find((c) => c.type === "element" && c.tag === "style:page-layout" && (0, ooxml_js.attr)(c, "style:name") === "PM1");
3002
+ const properties = pageLayout === void 0 ? void 0 : directChild$1(pageLayout, "style:page-layout-properties");
2994
3003
  if (properties === void 0) throw new Error(`${STYLES_PART_PATH} has no style:page-layout[style:name="PM1"]/style:page-layout-properties element`);
2995
3004
  return properties;
2996
3005
  }
@@ -3010,7 +3019,7 @@ var OdpEditor = class {
3010
3019
  }
3011
3020
  addSlide() {
3012
3021
  const presentation = findOfficePresentation(this.pkg);
3013
- const pageElement = el("draw:page", { "draw:master-page-name": MASTER_PAGE_NAME });
3022
+ const pageElement = el("draw:page", { "draw:master-page-name": MASTER_PAGE_NAME$1 });
3014
3023
  presentation.children.push(pageElement);
3015
3024
  const context = { pkg: this.pkg };
3016
3025
  return new OdpSlide(presentation.children, pageElement, context);
@@ -3111,6 +3120,539 @@ function appendShape(slide, shape) {
3111
3120
  }
3112
3121
  }
3113
3122
  //#endregion
3123
+ //#region src/edit/ods/scaffold.ts
3124
+ const CONTENT_NS_PREFIXES = [
3125
+ "office",
3126
+ "style",
3127
+ "text",
3128
+ "table",
3129
+ "fo"
3130
+ ];
3131
+ const STYLES_NS_PREFIXES = [
3132
+ "office",
3133
+ "style",
3134
+ "table",
3135
+ "fo"
3136
+ ];
3137
+ const META_NS_PREFIXES = [
3138
+ "office",
3139
+ "meta",
3140
+ "dc"
3141
+ ];
3142
+ const OF_NAMESPACE_ATTR = { "xmlns:of": "urn:oasis:names:tc:opendocument:xmlns:of:1.2" };
3143
+ const ODF_VERSION = "1.3";
3144
+ const MASTER_PAGE_NAME = "Standard";
3145
+ const SHEET_TABLE_STYLE_NAME = "OdsTable";
3146
+ const DEFAULT_SHEET_NAME = "Sheet1";
3147
+ const DEFAULT_MARGIN = "2cm";
3148
+ function declaration() {
3149
+ return {
3150
+ type: "declaration",
3151
+ attributes: [
3152
+ {
3153
+ name: "version",
3154
+ value: "1.0"
3155
+ },
3156
+ {
3157
+ name: "encoding",
3158
+ value: "UTF-8"
3159
+ },
3160
+ {
3161
+ name: "standalone",
3162
+ value: "yes"
3163
+ }
3164
+ ]
3165
+ };
3166
+ }
3167
+ function buildPageLayout() {
3168
+ return el("style:page-layout", { "style:name": "PM1" }, [el("style:page-layout-properties", {
3169
+ "fo:page-width": `${document_content_model.PAGE_SIZE_A4.widthPt}pt`,
3170
+ "fo:page-height": `${document_content_model.PAGE_SIZE_A4.heightPt}pt`,
3171
+ "fo:margin-top": DEFAULT_MARGIN,
3172
+ "fo:margin-right": DEFAULT_MARGIN,
3173
+ "fo:margin-bottom": DEFAULT_MARGIN,
3174
+ "fo:margin-left": DEFAULT_MARGIN
3175
+ })]);
3176
+ }
3177
+ function buildStylesXml() {
3178
+ return el("office:document-styles", {
3179
+ ...(0, odf_js.xmlnsAttributes)([...STYLES_NS_PREFIXES]),
3180
+ "office:version": ODF_VERSION
3181
+ }, [
3182
+ el("office:styles"),
3183
+ el("office:automatic-styles", {}, [buildPageLayout()]),
3184
+ el("office:master-styles", {}, [el("style:master-page", {
3185
+ "style:name": MASTER_PAGE_NAME,
3186
+ "style:page-layout-name": "PM1"
3187
+ })])
3188
+ ]);
3189
+ }
3190
+ function buildSheetTableStyle() {
3191
+ return el("style:style", {
3192
+ "style:name": SHEET_TABLE_STYLE_NAME,
3193
+ "style:family": "table",
3194
+ "style:master-page-name": MASTER_PAGE_NAME
3195
+ });
3196
+ }
3197
+ function buildCalculationSettings() {
3198
+ return el("table:calculation-settings", {
3199
+ "table:automatic-find-labels": "false",
3200
+ "table:use-regular-expressions": "false",
3201
+ "table:use-wildcards": "true",
3202
+ "table:null-year": "1950"
3203
+ });
3204
+ }
3205
+ function buildContentXml() {
3206
+ const table = el("table:table", {
3207
+ "table:name": DEFAULT_SHEET_NAME,
3208
+ "table:style-name": SHEET_TABLE_STYLE_NAME
3209
+ });
3210
+ return el("office:document-content", {
3211
+ ...(0, odf_js.xmlnsAttributes)([...CONTENT_NS_PREFIXES]),
3212
+ ...OF_NAMESPACE_ATTR,
3213
+ "office:version": ODF_VERSION
3214
+ }, [el("office:automatic-styles", {}, [buildSheetTableStyle()]), el("office:body", {}, [el("office:spreadsheet", {}, [buildCalculationSettings(), table])])]);
3215
+ }
3216
+ function buildMetaXml() {
3217
+ return el("office:document-meta", {
3218
+ ...(0, odf_js.xmlnsAttributes)([...META_NS_PREFIXES]),
3219
+ "office:version": ODF_VERSION
3220
+ }, [el("office:meta")]);
3221
+ }
3222
+ function createEmptyOdsPackage() {
3223
+ const pkg = { parts: {
3224
+ "content.xml": {
3225
+ kind: "xml",
3226
+ nodes: [declaration(), buildContentXml()]
3227
+ },
3228
+ "styles.xml": {
3229
+ kind: "xml",
3230
+ nodes: [declaration(), buildStylesXml()]
3231
+ },
3232
+ "meta.xml": {
3233
+ kind: "xml",
3234
+ nodes: [declaration(), buildMetaXml()]
3235
+ }
3236
+ } };
3237
+ (0, odf_js.setDocumentMediaType)(pkg, odf_js.ODF_MEDIA_TYPES.ods);
3238
+ (0, odf_js.syncManifest)(pkg);
3239
+ return pkg;
3240
+ }
3241
+ //#endregion
3242
+ //#region src/edit/ods/address.ts
3243
+ const ROW_TAG = "table:table-row";
3244
+ const COLUMN_TAG = "table:table-column";
3245
+ const CELL_TAG = "table:table-cell";
3246
+ const COVERED_CELL_TAG = "table:covered-table-cell";
3247
+ const ROW_REPEAT_ATTR = "table:number-rows-repeated";
3248
+ const COLUMN_REPEAT_ATTR = "table:number-columns-repeated";
3249
+ function isElementWithTag(tag) {
3250
+ return (node) => node.type === "element" && node.tag === tag;
3251
+ }
3252
+ function isCellOrCoveredCell(node) {
3253
+ return node.type === "element" && (node.tag === "table:table-cell" || node.tag === "table:covered-table-cell");
3254
+ }
3255
+ function validateIndex(value, label) {
3256
+ if (!Number.isInteger(value) || value < 0) throw new Error(`${label} must be a non-negative integer, got ${value}`);
3257
+ }
3258
+ function readRepeatCount(node, attrName) {
3259
+ const raw = node.attributes.find((attribute) => attribute.name === attrName)?.value;
3260
+ if (raw === void 0) return 1;
3261
+ const parsed = Number.parseInt(raw, 10);
3262
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
3263
+ }
3264
+ function withRepeatCount(node, attrName, count) {
3265
+ const clone = structuredClone(node);
3266
+ clone.attributes = clone.attributes.filter((attribute) => attribute.name !== attrName);
3267
+ if (count > 1) clone.attributes.push({
3268
+ name: attrName,
3269
+ value: String(count)
3270
+ });
3271
+ return clone;
3272
+ }
3273
+ function replaceRun(children, isMember, targetIndex, repeatAttr, buildEmpty) {
3274
+ validateIndex(targetIndex, "targetIndex");
3275
+ const members = [];
3276
+ children.forEach((node, position) => {
3277
+ if (isMember(node)) members.push({
3278
+ node,
3279
+ position
3280
+ });
3281
+ });
3282
+ let cursor = 0;
3283
+ for (const member of members) {
3284
+ const count = readRepeatCount(member.node, repeatAttr);
3285
+ if (targetIndex < cursor + count) {
3286
+ const offset = targetIndex - cursor;
3287
+ if (count === 1) return member.node;
3288
+ const before = offset > 0 ? withRepeatCount(member.node, repeatAttr, offset) : void 0;
3289
+ const target = withRepeatCount(member.node, repeatAttr, 1);
3290
+ const replacement = [
3291
+ before,
3292
+ target,
3293
+ count - offset - 1 > 0 ? withRepeatCount(member.node, repeatAttr, count - offset - 1) : void 0
3294
+ ].filter((candidate) => candidate !== void 0);
3295
+ children.splice(member.position, 1, ...replacement);
3296
+ return target;
3297
+ }
3298
+ cursor += count;
3299
+ }
3300
+ const gap = targetIndex - cursor;
3301
+ const lastMember = members[members.length - 1];
3302
+ const insertAt = lastMember === void 0 ? children.length : lastMember.position + 1;
3303
+ const toInsert = [];
3304
+ if (gap > 0) toInsert.push(withRepeatCount(buildEmpty(), repeatAttr, gap));
3305
+ const target = buildEmpty();
3306
+ toInsert.push(target);
3307
+ children.splice(insertAt, 0, ...toInsert);
3308
+ return target;
3309
+ }
3310
+ function ensureColumnCoverage(tableElement, minCount) {
3311
+ if (minCount <= 0) return;
3312
+ const columnMembers = [];
3313
+ tableElement.children.forEach((node, position) => {
3314
+ if (isElementWithTag("table:table-column")(node)) columnMembers.push({
3315
+ node,
3316
+ position
3317
+ });
3318
+ });
3319
+ const covered = columnMembers.reduce((sum, member) => sum + readRepeatCount(member.node, COLUMN_REPEAT_ATTR), 0);
3320
+ if (covered >= minCount) return;
3321
+ const additional = minCount - covered;
3322
+ const newColumn = withRepeatCount(el(COLUMN_TAG), COLUMN_REPEAT_ATTR, additional);
3323
+ const lastColumn = columnMembers[columnMembers.length - 1];
3324
+ if (lastColumn === void 0) {
3325
+ const firstRowPosition = tableElement.children.findIndex(isElementWithTag(ROW_TAG));
3326
+ const insertAt = firstRowPosition === -1 ? tableElement.children.length : firstRowPosition;
3327
+ tableElement.children.splice(insertAt, 0, newColumn);
3328
+ } else tableElement.children.splice(lastColumn.position + 1, 0, newColumn);
3329
+ }
3330
+ function resolveCellNode(tableElement, row, column) {
3331
+ validateIndex(row, "row");
3332
+ validateIndex(column, "column");
3333
+ ensureColumnCoverage(tableElement, column + 1);
3334
+ return replaceRun(replaceRun(tableElement.children, isElementWithTag(ROW_TAG), row, ROW_REPEAT_ATTR, () => el(ROW_TAG)).children, isCellOrCoveredCell, column, COLUMN_REPEAT_ATTR, () => el(CELL_TAG));
3335
+ }
3336
+ //#endregion
3337
+ //#region src/edit/ods/cell.ts
3338
+ const VALUE_TYPE_ATTR = "office:value-type";
3339
+ const VALUE_ATTR = "office:value";
3340
+ const BOOLEAN_VALUE_ATTR = "office:boolean-value";
3341
+ const DATE_VALUE_ATTR = "office:date-value";
3342
+ const TIME_VALUE_ATTR = "office:time-value";
3343
+ const STRING_VALUE_ATTR = "office:string-value";
3344
+ const CURRENCY_ATTR = "office:currency";
3345
+ const FORMULA_ATTR = "table:formula";
3346
+ const VALUE_ATTRS = [
3347
+ VALUE_TYPE_ATTR,
3348
+ VALUE_ATTR,
3349
+ BOOLEAN_VALUE_ATTR,
3350
+ DATE_VALUE_ATTR,
3351
+ TIME_VALUE_ATTR,
3352
+ STRING_VALUE_ATTR,
3353
+ CURRENCY_ATTR
3354
+ ];
3355
+ function parseNumber(raw) {
3356
+ if (raw === void 0) return;
3357
+ const value = Number(raw);
3358
+ return Number.isNaN(value) ? void 0 : value;
3359
+ }
3360
+ var OdsCell = class {
3361
+ node;
3362
+ pkg;
3363
+ constructor(node, pkg) {
3364
+ this.node = node;
3365
+ this.pkg = pkg;
3366
+ }
3367
+ get value() {
3368
+ const valueType = (0, ooxml_js.attr)(this.node, VALUE_TYPE_ATTR);
3369
+ const displayText = this.displayText;
3370
+ switch (valueType) {
3371
+ case "float": {
3372
+ const value = parseNumber((0, ooxml_js.attr)(this.node, VALUE_ATTR));
3373
+ return value === void 0 ? {
3374
+ kind: "string",
3375
+ value: displayText
3376
+ } : {
3377
+ kind: "number",
3378
+ value
3379
+ };
3380
+ }
3381
+ case "percentage": {
3382
+ const value = parseNumber((0, ooxml_js.attr)(this.node, VALUE_ATTR));
3383
+ return value === void 0 ? {
3384
+ kind: "string",
3385
+ value: displayText
3386
+ } : {
3387
+ kind: "percentage",
3388
+ value
3389
+ };
3390
+ }
3391
+ case "currency": {
3392
+ const value = parseNumber((0, ooxml_js.attr)(this.node, VALUE_ATTR));
3393
+ if (value === void 0) return {
3394
+ kind: "string",
3395
+ value: displayText
3396
+ };
3397
+ const currency = (0, ooxml_js.attr)(this.node, CURRENCY_ATTR);
3398
+ return currency === void 0 ? {
3399
+ kind: "currency",
3400
+ value
3401
+ } : {
3402
+ kind: "currency",
3403
+ value,
3404
+ currency
3405
+ };
3406
+ }
3407
+ case "boolean": {
3408
+ const raw = (0, ooxml_js.attr)(this.node, BOOLEAN_VALUE_ATTR);
3409
+ return raw === void 0 ? {
3410
+ kind: "string",
3411
+ value: displayText
3412
+ } : {
3413
+ kind: "boolean",
3414
+ value: raw === "true"
3415
+ };
3416
+ }
3417
+ case "date": return {
3418
+ kind: "date",
3419
+ value: (0, ooxml_js.attr)(this.node, DATE_VALUE_ATTR) ?? displayText
3420
+ };
3421
+ case "time": return {
3422
+ kind: "time",
3423
+ value: (0, ooxml_js.attr)(this.node, TIME_VALUE_ATTR) ?? displayText
3424
+ };
3425
+ case "string": return {
3426
+ kind: "string",
3427
+ value: (0, ooxml_js.attr)(this.node, STRING_VALUE_ATTR) ?? displayText
3428
+ };
3429
+ default: return { kind: "empty" };
3430
+ }
3431
+ }
3432
+ set value(value) {
3433
+ for (const name of VALUE_ATTRS) removeAttr(this.node, name);
3434
+ switch (value.kind) {
3435
+ case "number":
3436
+ setAttr(this.node, VALUE_TYPE_ATTR, "float");
3437
+ setAttr(this.node, VALUE_ATTR, String(value.value));
3438
+ this.displayText = String(value.value);
3439
+ break;
3440
+ case "percentage":
3441
+ setAttr(this.node, VALUE_TYPE_ATTR, "percentage");
3442
+ setAttr(this.node, VALUE_ATTR, String(value.value));
3443
+ this.displayText = `${value.value * 100}%`;
3444
+ break;
3445
+ case "currency":
3446
+ setAttr(this.node, VALUE_TYPE_ATTR, "currency");
3447
+ setAttr(this.node, VALUE_ATTR, String(value.value));
3448
+ if (value.currency !== void 0) setAttr(this.node, CURRENCY_ATTR, value.currency);
3449
+ this.displayText = value.currency === void 0 ? String(value.value) : `${value.value} ${value.currency}`;
3450
+ break;
3451
+ case "boolean":
3452
+ setAttr(this.node, VALUE_TYPE_ATTR, "boolean");
3453
+ setAttr(this.node, BOOLEAN_VALUE_ATTR, value.value ? "true" : "false");
3454
+ this.displayText = value.value ? "TRUE" : "FALSE";
3455
+ break;
3456
+ case "date":
3457
+ setAttr(this.node, VALUE_TYPE_ATTR, "date");
3458
+ setAttr(this.node, DATE_VALUE_ATTR, value.value);
3459
+ this.displayText = value.value;
3460
+ break;
3461
+ case "time":
3462
+ setAttr(this.node, VALUE_TYPE_ATTR, "time");
3463
+ setAttr(this.node, TIME_VALUE_ATTR, value.value);
3464
+ this.displayText = value.value;
3465
+ break;
3466
+ case "string":
3467
+ setAttr(this.node, VALUE_TYPE_ATTR, "string");
3468
+ setAttr(this.node, STRING_VALUE_ATTR, value.value);
3469
+ this.displayText = value.value;
3470
+ break;
3471
+ case "error":
3472
+ setAttr(this.node, VALUE_TYPE_ATTR, "string");
3473
+ setAttr(this.node, STRING_VALUE_ATTR, value.value);
3474
+ this.displayText = value.value;
3475
+ break;
3476
+ case "empty": this.displayText = "";
3477
+ }
3478
+ }
3479
+ get formula() {
3480
+ return (0, ooxml_js.attr)(this.node, FORMULA_ATTR);
3481
+ }
3482
+ set formula(value) {
3483
+ if (value === void 0) {
3484
+ removeAttr(this.node, FORMULA_ATTR);
3485
+ return;
3486
+ }
3487
+ setAttr(this.node, FORMULA_ATTR, value);
3488
+ }
3489
+ get displayText() {
3490
+ return this.node.children.filter((child) => child.type === "element" && child.tag === "text:p").map((paragraph) => decodeOdfText(paragraph.children)).join("\n");
3491
+ }
3492
+ set displayText(value) {
3493
+ this.node.children = [el("text:p", {}, encodeOdfText(value))];
3494
+ }
3495
+ setStyledRuns(runs) {
3496
+ const textParagraph = el("text:p");
3497
+ this.node.children = [textParagraph];
3498
+ populateParagraph(new OdtParagraph(this.node.children, textParagraph, this.pkg), {
3499
+ kind: "paragraph",
3500
+ runs: [...runs]
3501
+ });
3502
+ }
3503
+ };
3504
+ //#endregion
3505
+ //#region src/edit/ods/sheet.ts
3506
+ const NAME_ATTR = "table:name";
3507
+ var OdsSheet = class {
3508
+ container;
3509
+ node;
3510
+ pkg;
3511
+ removed = false;
3512
+ constructor(container, node, pkg) {
3513
+ this.container = container;
3514
+ this.node = node;
3515
+ this.pkg = pkg;
3516
+ }
3517
+ live() {
3518
+ if (this.removed) throw new Error("this OdsSheet has been removed from the spreadsheet and can no longer be used");
3519
+ return this.node;
3520
+ }
3521
+ get name() {
3522
+ const value = (0, ooxml_js.attr)(this.live(), NAME_ATTR);
3523
+ if (value === void 0) throw new Error("this table:table element has no table:name attribute");
3524
+ return value;
3525
+ }
3526
+ set name(value) {
3527
+ setAttr(this.live(), NAME_ATTR, value);
3528
+ }
3529
+ cell(row, column) {
3530
+ const node = resolveCellNode(this.live(), row, column);
3531
+ if (node.tag === "table:covered-table-cell") throw new Error(`cell (${row}, ${column}) is covered by a merged range -- address the merge's own anchor cell instead`);
3532
+ return new OdsCell(node, this.pkg);
3533
+ }
3534
+ cellAt(reference) {
3535
+ const parsed = (0, odf_js.parseCellReference)(reference);
3536
+ if (parsed === void 0) throw new Error(`cellAt: "${reference}" is not a valid A1-style cell reference`);
3537
+ return this.cell(parsed.row, parsed.column);
3538
+ }
3539
+ mergeCells(startRow, startColumn, rowSpan, colSpan) {
3540
+ if (!Number.isInteger(rowSpan) || rowSpan < 1 || !Number.isInteger(colSpan) || colSpan < 1) throw new Error(`mergeCells: rowSpan and colSpan must be positive integers, got rowSpan=${rowSpan}, colSpan=${colSpan}`);
3541
+ const tableElement = this.live();
3542
+ const anchorNode = resolveCellNode(tableElement, startRow, startColumn);
3543
+ if (anchorNode.tag === "table:covered-table-cell") throw new Error(`mergeCells: (${startRow}, ${startColumn}) is already covered by another merged range`);
3544
+ if (rowSpan > 1) setAttr(anchorNode, "table:number-rows-spanned", String(rowSpan));
3545
+ if (colSpan > 1) setAttr(anchorNode, "table:number-columns-spanned", String(colSpan));
3546
+ for (let rowOffset = 0; rowOffset < rowSpan; rowOffset++) for (let columnOffset = 0; columnOffset < colSpan; columnOffset++) {
3547
+ if (rowOffset === 0 && columnOffset === 0) continue;
3548
+ const coveredNode = resolveCellNode(tableElement, startRow + rowOffset, startColumn + columnOffset);
3549
+ coveredNode.tag = COVERED_CELL_TAG;
3550
+ coveredNode.attributes = [];
3551
+ coveredNode.children = [];
3552
+ }
3553
+ return new OdsCell(anchorNode, this.pkg);
3554
+ }
3555
+ remove() {
3556
+ removeChild(this.container, this.live());
3557
+ this.removed = true;
3558
+ }
3559
+ };
3560
+ //#endregion
3561
+ //#region src/edit/ods/editor.ts
3562
+ const CONTENT_PART_PATH = "content.xml";
3563
+ function directChild(parent, tag) {
3564
+ for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
3565
+ }
3566
+ function findRoot(pkg) {
3567
+ const part = pkg.parts[CONTENT_PART_PATH];
3568
+ const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
3569
+ if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH}`);
3570
+ return root;
3571
+ }
3572
+ function findOfficeSpreadsheet(pkg) {
3573
+ const body = directChild(findRoot(pkg), "office:body");
3574
+ const spreadsheet = body === void 0 ? void 0 : directChild(body, "office:spreadsheet");
3575
+ if (spreadsheet === void 0) throw new Error(`${CONTENT_PART_PATH} has no office:body/office:spreadsheet element`);
3576
+ return spreadsheet;
3577
+ }
3578
+ function ensureSheetTableStyleName(pkg) {
3579
+ const automaticStyles = ensureAutomaticStyles(pkg);
3580
+ if (automaticStyles.children.find((child) => child.type === "element" && child.tag === "style:style" && (0, ooxml_js.attr)(child, "style:name") === "OdsTable") !== void 0) return SHEET_TABLE_STYLE_NAME;
3581
+ automaticStyles.children.push(el("style:style", {
3582
+ "style:name": SHEET_TABLE_STYLE_NAME,
3583
+ "style:family": "table",
3584
+ "style:master-page-name": MASTER_PAGE_NAME
3585
+ }));
3586
+ return SHEET_TABLE_STYLE_NAME;
3587
+ }
3588
+ var OdsEditor = class {
3589
+ pkg;
3590
+ constructor(pkg) {
3591
+ this.pkg = pkg;
3592
+ }
3593
+ sheets() {
3594
+ const spreadsheet = findOfficeSpreadsheet(this.pkg);
3595
+ const out = [];
3596
+ for (const child of spreadsheet.children) if (child.type === "element" && child.tag === "table:table") out.push(new OdsSheet(spreadsheet.children, child, this.pkg));
3597
+ return out;
3598
+ }
3599
+ sheet(name) {
3600
+ const found = this.sheets().find((candidate) => candidate.name === name);
3601
+ if (found === void 0) throw new Error(`no sheet named "${name}" exists in this spreadsheet`);
3602
+ return found;
3603
+ }
3604
+ addSheet(name) {
3605
+ const spreadsheet = findOfficeSpreadsheet(this.pkg);
3606
+ const tableElement = el("table:table", {
3607
+ "table:name": name,
3608
+ "table:style-name": ensureSheetTableStyleName(this.pkg)
3609
+ });
3610
+ spreadsheet.children.push(tableElement);
3611
+ return new OdsSheet(spreadsheet.children, tableElement, this.pkg);
3612
+ }
3613
+ removeSheetAt(index) {
3614
+ const spreadsheet = findOfficeSpreadsheet(this.pkg);
3615
+ const target = spreadsheet.children.filter((child) => child.type === "element" && child.tag === "table:table")[index];
3616
+ if (target === void 0) throw new Error(`sheet index ${index} does not exist`);
3617
+ const listIndex = spreadsheet.children.indexOf(target);
3618
+ spreadsheet.children.splice(listIndex, 1);
3619
+ }
3620
+ toPackage() {
3621
+ return this.pkg;
3622
+ }
3623
+ toBytes() {
3624
+ return (0, odf_js.encodePackage)(this.pkg);
3625
+ }
3626
+ };
3627
+ function openOds(bytes) {
3628
+ return new OdsEditor((0, odf_js.decodePackage)(bytes));
3629
+ }
3630
+ function createOds() {
3631
+ return new OdsEditor(createEmptyOdsPackage());
3632
+ }
3633
+ //#endregion
3634
+ //#region src/edit/ods/content.ts
3635
+ function buildOdsPackage(content) {
3636
+ if (content.kind !== "spreadsheet") throw new Error("buildOdsPackage requires a spreadsheet ContentDocument");
3637
+ const editor = createOds();
3638
+ if (content.sheets.length > 0) editor.removeSheetAt(0);
3639
+ for (const sheet of content.sheets) {
3640
+ const odsSheet = editor.addSheet(sheet.name);
3641
+ for (const cell of sheet.cells) appendCell(odsSheet, cell);
3642
+ }
3643
+ return editor.toPackage();
3644
+ }
3645
+ function appendCell(odsSheet, cell) {
3646
+ const odsCell = odsSheet.cell(cell.row, cell.column);
3647
+ odsCell.value = cell.value;
3648
+ if (cell.formula !== void 0) odsCell.formula = cell.formula;
3649
+ if (cell.runs !== void 0 && cell.runs.length > 0) odsCell.setStyledRuns(cell.runs);
3650
+ else odsCell.displayText = cell.displayText;
3651
+ const rowSpan = cell.rowSpan ?? 1;
3652
+ const colSpan = cell.colSpan ?? 1;
3653
+ if (rowSpan > 1 || colSpan > 1) odsSheet.mergeCells(cell.row, cell.column, rowSpan, colSpan);
3654
+ }
3655
+ //#endregion
3114
3656
  //#region src/bytes/crc32.ts
3115
3657
  const CRC32_POLYNOMIAL = 3988292384;
3116
3658
  const BYTE_VALUES = 256;
@@ -7916,6 +8458,17 @@ function readOdpContent(pkg) {
7916
8458
  };
7917
8459
  }
7918
8460
  //#endregion
8461
+ //#region src/odf/ods/read.ts
8462
+ function readOdsContent(pkg) {
8463
+ const odsDoc = (0, odf_js.readOds)(pkg);
8464
+ return {
8465
+ kind: "spreadsheet",
8466
+ formatVersion: 1,
8467
+ metadata: { ...odsDoc.metadata },
8468
+ sheets: odsDoc.sheets
8469
+ };
8470
+ }
8471
+ //#endregion
7919
8472
  //#region src/pdf/text-layout.ts
7920
8473
  const WORD_OR_WHITESPACE_PATTERN = /\n|\s+|\S+/g;
7921
8474
  function atomizeRuns(runs, measurer) {
@@ -8543,6 +9096,410 @@ function convertPresentationToLayout(doc, options) {
8543
9096
  };
8544
9097
  }
8545
9098
  //#endregion
9099
+ //#region src/layout/sheets.ts
9100
+ const DEFAULT_COLUMN_WIDTH_PT = 64;
9101
+ const DEFAULT_ROW_HEIGHT_PT = 15;
9102
+ const NOMINAL_CELL_TEXT_SIZE_PT = 10;
9103
+ const HEADER_LABEL_SIZE_PT = 8;
9104
+ const CELL_TEXT_PADDING_PT = 2;
9105
+ const HEADER_LABEL_PADDING_PT = 2;
9106
+ const MINIMUM_SCALE = .01;
9107
+ const NUMERIC_OVERFLOW_TEXT = "###";
9108
+ const GRIDLINE_COLOR = (0, document_content_model.rgbHexToColor)("#D0D0D0");
9109
+ const GRIDLINE_WIDTH_PT = .5;
9110
+ const HEADER_LABEL_COLOR = (0, document_content_model.rgbHexToColor)("#606060");
9111
+ function columnLetters(index) {
9112
+ let n = index + 1;
9113
+ let letters = "";
9114
+ while (n > 0) {
9115
+ const remainder = (n - 1) % 26;
9116
+ letters = String.fromCharCode(65 + remainder) + letters;
9117
+ n = Math.floor((n - 1) / 26);
9118
+ }
9119
+ return letters;
9120
+ }
9121
+ function resolvePrintRange(sheet) {
9122
+ if (sheet.printSettings.printRange !== void 0) return sheet.printSettings.printRange;
9123
+ if (sheet.cells.length === 0) return;
9124
+ let startRow = Number.POSITIVE_INFINITY;
9125
+ let startColumn = Number.POSITIVE_INFINITY;
9126
+ let endRow = Number.NEGATIVE_INFINITY;
9127
+ let endColumn = Number.NEGATIVE_INFINITY;
9128
+ for (const cell of sheet.cells) {
9129
+ startRow = Math.min(startRow, cell.row);
9130
+ startColumn = Math.min(startColumn, cell.column);
9131
+ endRow = Math.max(endRow, cell.row + (cell.rowSpan ?? 1) - 1);
9132
+ endColumn = Math.max(endColumn, cell.column + (cell.colSpan ?? 1) - 1);
9133
+ }
9134
+ return {
9135
+ startRow,
9136
+ startColumn,
9137
+ endRow,
9138
+ endColumn
9139
+ };
9140
+ }
9141
+ function resolveAxis(entries, start, end, defaultSizePt) {
9142
+ const sorted = [...entries].sort((a, b) => a.index - b.index);
9143
+ const resolved = [];
9144
+ let pointer = 0;
9145
+ let currentSizePt = defaultSizePt;
9146
+ let currentHidden = false;
9147
+ for (let index = start; index <= end; index++) {
9148
+ while (pointer < sorted.length && sorted[pointer].index <= index) {
9149
+ currentSizePt = sorted[pointer].sizePt;
9150
+ currentHidden = sorted[pointer].hidden ?? false;
9151
+ pointer++;
9152
+ }
9153
+ resolved.push({
9154
+ index,
9155
+ sizePt: currentHidden ? 0 : currentSizePt,
9156
+ hidden: currentHidden
9157
+ });
9158
+ }
9159
+ return resolved;
9160
+ }
9161
+ function computeHeaderGutter(printSettings, range, measurer) {
9162
+ if (!printSettings.headers) return {
9163
+ widthPt: 0,
9164
+ heightPt: 0
9165
+ };
9166
+ const widestRowLabel = String(range.endRow + 1);
9167
+ return {
9168
+ widthPt: measurer.widthOfTextAtSize(widestRowLabel, document_content_model.DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT) + 4,
9169
+ heightPt: measurer.lineHeightAtSize(document_content_model.DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT)
9170
+ };
9171
+ }
9172
+ function resolveScale(printSettings, availableWidthPt, availableHeightPt, totalContentWidthPt, totalContentHeightPt) {
9173
+ if (printSettings.scale !== void 0) return Math.max(printSettings.scale / 100, MINIMUM_SCALE);
9174
+ if (printSettings.fitToPages !== void 0) {
9175
+ const budgetWidthPt = availableWidthPt * printSettings.fitToPages.width;
9176
+ const budgetHeightPt = availableHeightPt * printSettings.fitToPages.height;
9177
+ const widthRatio = totalContentWidthPt > 0 ? budgetWidthPt / totalContentWidthPt : 1;
9178
+ const heightRatio = totalContentHeightPt > 0 ? budgetHeightPt / totalContentHeightPt : 1;
9179
+ return Math.max(Math.min(widthRatio, heightRatio, 1), MINIMUM_SCALE);
9180
+ }
9181
+ return 1;
9182
+ }
9183
+ function partitionIndices(indices, sizeOf, availablePt, manualBreaks) {
9184
+ const bands = [];
9185
+ let current = [];
9186
+ let currentSizePt = 0;
9187
+ for (const index of indices) {
9188
+ if (manualBreaks.has(index) && current.length > 0) {
9189
+ bands.push(current);
9190
+ current = [];
9191
+ currentSizePt = 0;
9192
+ }
9193
+ const sizePt = sizeOf(index);
9194
+ if (current.length > 0 && currentSizePt + sizePt > availablePt) {
9195
+ bands.push(current);
9196
+ current = [];
9197
+ currentSizePt = 0;
9198
+ }
9199
+ current.push(index);
9200
+ currentSizePt += sizePt;
9201
+ }
9202
+ if (current.length > 0) bands.push(current);
9203
+ return bands;
9204
+ }
9205
+ function cellStyledRuns(cell) {
9206
+ if (cell.runs !== void 0 && cell.runs.length > 0) return toStyledRuns(cell.runs.map((run) => run.sizePt === void 0 ? {
9207
+ ...run,
9208
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT
9209
+ } : run));
9210
+ return [{
9211
+ text: cell.displayText,
9212
+ font: document_content_model.DEFAULT_LAYOUT_FONT,
9213
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT,
9214
+ color: document_content_model.COLOR_BLACK
9215
+ }];
9216
+ }
9217
+ function isNumericLikeValue(kind) {
9218
+ return kind === "number" || kind === "percentage" || kind === "currency" || kind === "date" || kind === "time";
9219
+ }
9220
+ function defaultAlignmentForValue(kind) {
9221
+ if (isNumericLikeValue(kind)) return "right";
9222
+ if (kind === "boolean" || kind === "error") return "center";
9223
+ return "left";
9224
+ }
9225
+ function isCellVisuallyEmpty(cell) {
9226
+ return cell === void 0 || cell.value.kind === "empty" && cell.displayText.length === 0;
9227
+ }
9228
+ function truncateFragmentsToWidth(fragments, measurer, maxWidthPt) {
9229
+ const result = [];
9230
+ for (const fragment of fragments) {
9231
+ if (fragment.xOffsetPt >= maxWidthPt) break;
9232
+ const remainingWidthPt = maxWidthPt - fragment.xOffsetPt;
9233
+ if (measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt) <= remainingWidthPt) {
9234
+ result.push(fragment);
9235
+ continue;
9236
+ }
9237
+ const chars = Array.from(fragment.text);
9238
+ let width = 0;
9239
+ let fitCount = 0;
9240
+ for (const char of chars) {
9241
+ const charWidthPt = measurer.widthOfTextAtSize(char, fragment.font, fragment.sizePt);
9242
+ if (width + charWidthPt > remainingWidthPt) break;
9243
+ width += charWidthPt;
9244
+ fitCount++;
9245
+ }
9246
+ if (fitCount > 0) result.push({
9247
+ ...fragment,
9248
+ text: chars.slice(0, fitCount).join("")
9249
+ });
9250
+ break;
9251
+ }
9252
+ return result;
9253
+ }
9254
+ function buildPositionedAxis(repeatIndices, repeatSizePtOf, bandIndices, bandSizePtOf) {
9255
+ const indices = [...repeatIndices, ...bandIndices];
9256
+ const sizesPt = [...repeatIndices.map(repeatSizePtOf), ...bandIndices.map(bandSizePtOf)];
9257
+ const offsetsPt = [0];
9258
+ let running = 0;
9259
+ for (const size of sizesPt) {
9260
+ running += size;
9261
+ offsetsPt.push(running);
9262
+ }
9263
+ return {
9264
+ indices,
9265
+ sizesPt,
9266
+ offsetsPt,
9267
+ positionByIndex: new Map(indices.map((index, position) => [index, position]))
9268
+ };
9269
+ }
9270
+ function axisSpanSizePt(axis, startIndex, span) {
9271
+ const startPosition = axis.positionByIndex.get(startIndex);
9272
+ if (startPosition === void 0) return 0;
9273
+ return sumColumnWidthsPt(axis.sizesPt, startPosition, span);
9274
+ }
9275
+ function renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
9276
+ const columnPosition = columnAxis.positionByIndex.get(cell.column);
9277
+ const rowPosition = rowAxis.positionByIndex.get(cell.row);
9278
+ if (columnPosition === void 0 || rowPosition === void 0) return;
9279
+ const ownWidthPt = axisSpanSizePt(columnAxis, cell.column, cell.colSpan ?? 1);
9280
+ const heightPt = axisSpanSizePt(rowAxis, cell.row, cell.rowSpan ?? 1);
9281
+ const xLeftPt = gridLeftXPt + columnAxis.offsetsPt[columnPosition];
9282
+ const yTopDownPt = gridTopYDownPt + rowAxis.offsetsPt[rowPosition];
9283
+ const alignment = defaultAlignmentForValue(cell.value.kind);
9284
+ const numericLike = isNumericLikeValue(cell.value.kind);
9285
+ const styledRuns = cellStyledRuns(cell);
9286
+ const naturalLine = wrapRunsToWidth(styledRuns, measurer, Number.POSITIVE_INFINITY)[0];
9287
+ let availableWidthPt = Math.max(0, ownWidthPt - 4);
9288
+ let fragments = naturalLine.fragments;
9289
+ let lineWidthPt = naturalLine.widthPt;
9290
+ if (lineWidthPt > availableWidthPt) if (numericLike) {
9291
+ const overflowLine = wrapRunsToWidth([{
9292
+ text: NUMERIC_OVERFLOW_TEXT,
9293
+ font: styledRuns[0].font,
9294
+ sizePt: styledRuns[0].sizePt,
9295
+ color: styledRuns[0].color
9296
+ }], measurer, Number.POSITIVE_INFINITY)[0];
9297
+ fragments = overflowLine.fragments;
9298
+ lineWidthPt = overflowLine.widthPt;
9299
+ } else if (cell.value.kind === "string") {
9300
+ let spillColumn = cell.column + (cell.colSpan ?? 1);
9301
+ while (lineWidthPt > availableWidthPt) {
9302
+ const neighborPosition = columnAxis.positionByIndex.get(spillColumn);
9303
+ if (neighborPosition === void 0 || !isCellVisuallyEmpty(rowCells?.get(spillColumn))) break;
9304
+ availableWidthPt += columnAxis.sizesPt[neighborPosition];
9305
+ spillColumn++;
9306
+ }
9307
+ if (lineWidthPt > availableWidthPt) fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
9308
+ } else fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
9309
+ const alignOffsetPt = alignmentOffsetPt(alignment, availableWidthPt, lineWidthPt);
9310
+ const textStartXPt = xLeftPt + CELL_TEXT_PADDING_PT + alignOffsetPt;
9311
+ const lineHeightPt = lineNaturalHeightPt(naturalLine, measurer, styledRuns[0]);
9312
+ const baselineYDownPt = yTopDownPt + Math.max(CELL_TEXT_PADDING_PT, heightPt - CELL_TEXT_PADDING_PT - lineHeightPt) + naturalLine.ascentPt;
9313
+ for (const fragment of fragments) {
9314
+ const textItem = {
9315
+ kind: "text",
9316
+ text: fragment.text,
9317
+ xPt: textStartXPt + fragment.xOffsetPt,
9318
+ yPt: pageHeightPt - baselineYDownPt,
9319
+ font: fragment.font,
9320
+ sizePt: fragment.sizePt,
9321
+ color: fragment.color,
9322
+ underline: fragment.underline,
9323
+ sourcePath: fragment.sourcePath
9324
+ };
9325
+ out.push(textItem);
9326
+ }
9327
+ }
9328
+ function renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
9329
+ const labelFont = document_content_model.DEFAULT_LAYOUT_FONT;
9330
+ const lineHeightPt = measurer.lineHeightAtSize(labelFont, HEADER_LABEL_SIZE_PT);
9331
+ const ascentPt = measurer.ascenderAtSize(labelFont, HEADER_LABEL_SIZE_PT);
9332
+ columnAxis.indices.forEach((columnIndex, position) => {
9333
+ const label = columnLetters(columnIndex);
9334
+ const widthPt = columnAxis.sizesPt[position];
9335
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
9336
+ const xPt = gridLeftXPt + columnAxis.offsetsPt[position] + alignmentOffsetPt("center", widthPt, labelWidthPt);
9337
+ const baselineYDownPt = gridTopYDownPt - gutter.heightPt + (gutter.heightPt - lineHeightPt) / 2 + ascentPt;
9338
+ out.push({
9339
+ kind: "text",
9340
+ text: label,
9341
+ xPt,
9342
+ yPt: pageHeightPt - baselineYDownPt,
9343
+ font: labelFont,
9344
+ sizePt: HEADER_LABEL_SIZE_PT,
9345
+ color: HEADER_LABEL_COLOR
9346
+ });
9347
+ });
9348
+ rowAxis.indices.forEach((rowIndex, position) => {
9349
+ const label = String(rowIndex + 1);
9350
+ const heightPt = rowAxis.sizesPt[position];
9351
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
9352
+ const xPt = gridLeftXPt - gutter.widthPt + Math.max(HEADER_LABEL_PADDING_PT, gutter.widthPt - HEADER_LABEL_PADDING_PT - labelWidthPt);
9353
+ const baselineYDownPt = gridTopYDownPt + rowAxis.offsetsPt[position] + Math.max(0, (heightPt - lineHeightPt) / 2) + ascentPt;
9354
+ out.push({
9355
+ kind: "text",
9356
+ text: label,
9357
+ xPt,
9358
+ yPt: pageHeightPt - baselineYDownPt,
9359
+ font: labelFont,
9360
+ sizePt: HEADER_LABEL_SIZE_PT,
9361
+ color: HEADER_LABEL_COLOR
9362
+ });
9363
+ });
9364
+ }
9365
+ function renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnOffsetsPt, rowOffsetsPt, pageHeightPt, out) {
9366
+ for (const offsetPt of columnOffsetsPt) {
9367
+ const xPt = gridLeftXPt + offsetPt;
9368
+ const line = {
9369
+ kind: "line",
9370
+ x1Pt: xPt,
9371
+ y1Pt: pageHeightPt - gridTopYDownPt,
9372
+ x2Pt: xPt,
9373
+ y2Pt: pageHeightPt - (gridTopYDownPt + gridHeightPt),
9374
+ color: GRIDLINE_COLOR,
9375
+ widthPt: GRIDLINE_WIDTH_PT
9376
+ };
9377
+ out.push(line);
9378
+ }
9379
+ for (const offsetPt of rowOffsetsPt) {
9380
+ const yDownPt = gridTopYDownPt + offsetPt;
9381
+ const line = {
9382
+ kind: "line",
9383
+ x1Pt: gridLeftXPt,
9384
+ y1Pt: pageHeightPt - yDownPt,
9385
+ x2Pt: gridLeftXPt + gridWidthPt,
9386
+ y2Pt: pageHeightPt - yDownPt,
9387
+ color: GRIDLINE_COLOR,
9388
+ widthPt: GRIDLINE_WIDTH_PT
9389
+ };
9390
+ out.push(line);
9391
+ }
9392
+ }
9393
+ function bandableIndices(start, end, repeat) {
9394
+ const indices = [];
9395
+ for (let i = start; i <= end; i++) {
9396
+ if (repeat !== void 0 && i >= repeat.start && i <= repeat.end) continue;
9397
+ indices.push(i);
9398
+ }
9399
+ return indices;
9400
+ }
9401
+ function rangeIndices(start, end) {
9402
+ const indices = [];
9403
+ for (let i = start; i <= end; i++) indices.push(i);
9404
+ return indices;
9405
+ }
9406
+ function convertSheetToPages(sheet, measurer, signal, out) {
9407
+ throwIfAborted(signal);
9408
+ const range = resolvePrintRange(sheet);
9409
+ if (range === void 0) return;
9410
+ const { printSettings } = sheet;
9411
+ const { pageSize, margins } = printSettings;
9412
+ const pageContentWidthPt = Math.max(0, pageSize.widthPt - margins.leftPt - margins.rightPt);
9413
+ const pageContentHeightPt = Math.max(0, pageSize.heightPt - margins.topPt - margins.bottomPt);
9414
+ const columnEntries = resolveAxis(sheet.columns.map((c) => ({
9415
+ index: c.index,
9416
+ sizePt: c.widthPt,
9417
+ hidden: c.hidden
9418
+ })), range.startColumn, range.endColumn, DEFAULT_COLUMN_WIDTH_PT);
9419
+ const rowEntries = resolveAxis(sheet.rows.map((r) => ({
9420
+ index: r.index,
9421
+ sizePt: r.heightPt,
9422
+ hidden: r.hidden
9423
+ })), range.startRow, range.endRow, DEFAULT_ROW_HEIGHT_PT);
9424
+ const columnSizeByIndex = new Map(columnEntries.map((e) => [e.index, e.sizePt]));
9425
+ const rowSizeByIndex = new Map(rowEntries.map((e) => [e.index, e.sizePt]));
9426
+ const hiddenColumnIndices = new Set(columnEntries.filter((e) => e.hidden).map((e) => e.index));
9427
+ const hiddenRowIndices = new Set(rowEntries.filter((e) => e.hidden).map((e) => e.index));
9428
+ const gutter = computeHeaderGutter(printSettings, range, measurer);
9429
+ const repeatColumns = printSettings.repeatColumns;
9430
+ const repeatRows = printSettings.repeatRows;
9431
+ const repeatColumnIndices = repeatColumns === void 0 ? [] : rangeIndices(repeatColumns.start, repeatColumns.end);
9432
+ const repeatRowIndices = repeatRows === void 0 ? [] : rangeIndices(repeatRows.start, repeatRows.end);
9433
+ const repeatColumnsWidthPt = repeatColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0);
9434
+ const repeatRowsHeightPt = repeatRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0);
9435
+ const bandableColumnIndices = bandableIndices(range.startColumn, range.endColumn, repeatColumns);
9436
+ const bandableRowIndices = bandableIndices(range.startRow, range.endRow, repeatRows);
9437
+ const availableWidthPt = Math.max(0, pageContentWidthPt - gutter.widthPt - repeatColumnsWidthPt);
9438
+ const availableHeightPt = Math.max(0, pageContentHeightPt - gutter.heightPt - repeatRowsHeightPt);
9439
+ const scale = resolveScale(printSettings, availableWidthPt, availableHeightPt, bandableColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0), bandableRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0));
9440
+ const descaledAvailableWidthPt = availableWidthPt / scale;
9441
+ const descaledAvailableHeightPt = availableHeightPt / scale;
9442
+ const manualBreakColumns = new Set(printSettings.manualBreaks?.columns ?? []);
9443
+ const manualBreakRows = new Set(printSettings.manualBreaks?.rows ?? []);
9444
+ throwIfAborted(signal);
9445
+ const columnBands = partitionIndices(bandableColumnIndices, (i) => columnSizeByIndex.get(i) ?? 0, descaledAvailableWidthPt, manualBreakColumns);
9446
+ const rowBands = partitionIndices(bandableRowIndices, (i) => rowSizeByIndex.get(i) ?? 0, descaledAvailableHeightPt, manualBreakRows);
9447
+ const cellsByRow = /* @__PURE__ */ new Map();
9448
+ for (const cell of sheet.cells) {
9449
+ let row = cellsByRow.get(cell.row);
9450
+ if (row === void 0) {
9451
+ row = /* @__PURE__ */ new Map();
9452
+ cellsByRow.set(cell.row, row);
9453
+ }
9454
+ row.set(cell.column, cell);
9455
+ }
9456
+ const scaledSizeOf = (sizeByIndex) => (index) => (sizeByIndex.get(index) ?? 0) * scale;
9457
+ const unscaledSizeOf = (sizeByIndex) => (index) => sizeByIndex.get(index) ?? 0;
9458
+ const bandPairs = printSettings.pageOrder === "overThenDown" ? rowBands.flatMap((rowBand) => columnBands.map((columnBand) => ({
9459
+ columnBand,
9460
+ rowBand
9461
+ }))) : columnBands.flatMap((columnBand) => rowBands.map((rowBand) => ({
9462
+ columnBand,
9463
+ rowBand
9464
+ })));
9465
+ for (const { columnBand, rowBand } of bandPairs) {
9466
+ throwIfAborted(signal);
9467
+ const columnAxis = buildPositionedAxis(repeatColumnIndices, unscaledSizeOf(columnSizeByIndex), columnBand, scaledSizeOf(columnSizeByIndex));
9468
+ const rowAxis = buildPositionedAxis(repeatRowIndices, unscaledSizeOf(rowSizeByIndex), rowBand, scaledSizeOf(rowSizeByIndex));
9469
+ const gridLeftXPt = margins.leftPt + gutter.widthPt;
9470
+ const gridTopYDownPt = margins.topPt + gutter.heightPt;
9471
+ const gridWidthPt = columnAxis.offsetsPt[columnAxis.offsetsPt.length - 1];
9472
+ const gridHeightPt = rowAxis.offsetsPt[rowAxis.offsetsPt.length - 1];
9473
+ const items = [];
9474
+ if (printSettings.gridlines) renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnAxis.offsetsPt, rowAxis.offsetsPt, pageSize.heightPt, items);
9475
+ if (printSettings.headers) renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
9476
+ for (const rowIndex of rowAxis.indices) {
9477
+ const rowCells = cellsByRow.get(rowIndex);
9478
+ if (rowCells === void 0) continue;
9479
+ for (const [columnIndex, cell] of rowCells) {
9480
+ throwIfAborted(signal);
9481
+ if (!columnAxis.positionByIndex.has(columnIndex) || hiddenColumnIndices.has(columnIndex) || hiddenRowIndices.has(cell.row)) continue;
9482
+ renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
9483
+ }
9484
+ }
9485
+ out.push({
9486
+ widthPt: pageSize.widthPt,
9487
+ heightPt: pageSize.heightPt,
9488
+ items
9489
+ });
9490
+ }
9491
+ }
9492
+ function convertSpreadsheetToLayout(doc, options) {
9493
+ const pages = [];
9494
+ for (const sheet of doc.sheets) convertSheetToPages(sheet, options.measurer, options.signal, pages);
9495
+ return {
9496
+ formatVersion: document_content_model.LAYOUT_FORMAT_VERSION,
9497
+ metadata: doc.metadata,
9498
+ pages,
9499
+ images: {}
9500
+ };
9501
+ }
9502
+ //#endregion
8546
9503
  //#region src/layout/reconstruct.ts
8547
9504
  const ZERO_MARGINS = {
8548
9505
  topPt: 0,
@@ -8911,6 +9868,17 @@ function odpToPdf(bytes, options) {
8911
9868
  onSubstitution: options?.onSubstitution
8912
9869
  });
8913
9870
  }
9871
+ function odsToPdf(bytes, options) {
9872
+ const content = readOdsContent((0, odf_js.decodePackage)(bytes));
9873
+ if (content.kind !== "spreadsheet") throw new Error("readOdsContent returned a non-spreadsheet ContentDocument");
9874
+ return writePdf(convertSpreadsheetToLayout(content, {
9875
+ measurer: createStandardFontMeasurer(),
9876
+ signal: options?.signal
9877
+ }), {
9878
+ signal: options?.signal,
9879
+ onSubstitution: options?.onSubstitution
9880
+ });
9881
+ }
8914
9882
  function pdfToDocx(bytes, options) {
8915
9883
  const content = reconstructWordprocessing(readPdf(bytes, {
8916
9884
  signal: options?.signal,
@@ -8976,6 +9944,10 @@ const SUPPORTED_CONVERSIONS = [
8976
9944
  source: "odp",
8977
9945
  target: "pdf"
8978
9946
  },
9947
+ {
9948
+ source: "ods",
9949
+ target: "pdf"
9950
+ },
8979
9951
  {
8980
9952
  source: "pdf",
8981
9953
  target: "docx"
@@ -9068,6 +10040,19 @@ function createLocalDocumentConverter() {
9068
10040
  diagnostics
9069
10041
  });
9070
10042
  }
10043
+ if (source.format === "ods" && targetFormat === "pdf") {
10044
+ const bytes = odsToPdf(source.bytes, {
10045
+ signal: options.signal,
10046
+ onSubstitution: (s, c) => diagnostics.push(substitutionDiagnostic(s, c))
10047
+ });
10048
+ return Promise.resolve({
10049
+ document: {
10050
+ format: "pdf",
10051
+ bytes
10052
+ },
10053
+ diagnostics
10054
+ });
10055
+ }
9071
10056
  if (source.format === "pdf" && targetFormat === "docx") {
9072
10057
  const bytes = pdfToDocx(source.bytes, {
9073
10058
  signal: options.signal,
@@ -9180,6 +10165,12 @@ Object.defineProperty(exports, "ContentBlockSchema", {
9180
10165
  return document_content_model.ContentBlockSchema;
9181
10166
  }
9182
10167
  });
10168
+ Object.defineProperty(exports, "ContentCellValueSchema", {
10169
+ enumerable: true,
10170
+ get: function() {
10171
+ return document_content_model.ContentCellValueSchema;
10172
+ }
10173
+ });
9183
10174
  exports.ContentDocumentSchema = ContentDocumentSchema;
9184
10175
  Object.defineProperty(exports, "ContentImageBlockSchema", {
9185
10176
  enumerable: true,
@@ -9217,6 +10208,48 @@ Object.defineProperty(exports, "ContentShapeSchema", {
9217
10208
  return document_content_model.ContentShapeSchema;
9218
10209
  }
9219
10210
  });
10211
+ Object.defineProperty(exports, "ContentSheetCellSchema", {
10212
+ enumerable: true,
10213
+ get: function() {
10214
+ return document_content_model.ContentSheetCellSchema;
10215
+ }
10216
+ });
10217
+ Object.defineProperty(exports, "ContentSheetColumnSchema", {
10218
+ enumerable: true,
10219
+ get: function() {
10220
+ return document_content_model.ContentSheetColumnSchema;
10221
+ }
10222
+ });
10223
+ Object.defineProperty(exports, "ContentSheetPrintRangeSchema", {
10224
+ enumerable: true,
10225
+ get: function() {
10226
+ return document_content_model.ContentSheetPrintRangeSchema;
10227
+ }
10228
+ });
10229
+ Object.defineProperty(exports, "ContentSheetPrintSettingsSchema", {
10230
+ enumerable: true,
10231
+ get: function() {
10232
+ return document_content_model.ContentSheetPrintSettingsSchema;
10233
+ }
10234
+ });
10235
+ Object.defineProperty(exports, "ContentSheetRepeatRangeSchema", {
10236
+ enumerable: true,
10237
+ get: function() {
10238
+ return document_content_model.ContentSheetRepeatRangeSchema;
10239
+ }
10240
+ });
10241
+ Object.defineProperty(exports, "ContentSheetRowSchema", {
10242
+ enumerable: true,
10243
+ get: function() {
10244
+ return document_content_model.ContentSheetRowSchema;
10245
+ }
10246
+ });
10247
+ Object.defineProperty(exports, "ContentSheetSchema", {
10248
+ enumerable: true,
10249
+ get: function() {
10250
+ return document_content_model.ContentSheetSchema;
10251
+ }
10252
+ });
9220
10253
  Object.defineProperty(exports, "ContentSlideSchema", {
9221
10254
  enumerable: true,
9222
10255
  get: function() {
@@ -9273,6 +10306,9 @@ exports.OdpEditor = OdpEditor;
9273
10306
  exports.OdpShape = OdpShape;
9274
10307
  exports.OdpSlide = OdpSlide;
9275
10308
  exports.OdsBytesSchema = OdsBytesSchema;
10309
+ exports.OdsCell = OdsCell;
10310
+ exports.OdsEditor = OdsEditor;
10311
+ exports.OdsSheet = OdsSheet;
9276
10312
  exports.OdtBytesSchema = OdtBytesSchema;
9277
10313
  exports.OdtEditor = OdtEditor;
9278
10314
  exports.OdtList = OdtList;
@@ -9387,6 +10423,7 @@ Object.defineProperty(exports, "base64ToBytes", {
9387
10423
  });
9388
10424
  exports.buildDocxPackage = buildDocxPackage;
9389
10425
  exports.buildOdpPackage = buildOdpPackage;
10426
+ exports.buildOdsPackage = buildOdsPackage;
9390
10427
  exports.buildOdtPackage = buildOdtPackage;
9391
10428
  exports.buildPptxPackage = buildPptxPackage;
9392
10429
  Object.defineProperty(exports, "buildXml", {
@@ -9420,10 +10457,12 @@ Object.defineProperty(exports, "compactPackageCodec", {
9420
10457
  }
9421
10458
  });
9422
10459
  exports.convertPresentationToLayout = convertPresentationToLayout;
10460
+ exports.convertSpreadsheetToLayout = convertSpreadsheetToLayout;
9423
10461
  exports.convertWordprocessingToLayout = convertWordprocessingToLayout;
9424
10462
  exports.createDocx = createDocx;
9425
10463
  exports.createLocalDocumentConverter = createLocalDocumentConverter;
9426
10464
  exports.createOdp = createOdp;
10465
+ exports.createOds = createOds;
9427
10466
  exports.createOdt = createOdt;
9428
10467
  exports.createPptx = createPptx;
9429
10468
  Object.defineProperty(exports, "decodeCompactPackage", {
@@ -9492,10 +10531,12 @@ Object.defineProperty(exports, "isXmlNode", {
9492
10531
  });
9493
10532
  exports.odpPdfCodec = odpPdfCodec;
9494
10533
  exports.odpToPdf = odpToPdf;
10534
+ exports.odsToPdf = odsToPdf;
9495
10535
  exports.odtPdfCodec = odtPdfCodec;
9496
10536
  exports.odtToPdf = odtToPdf;
9497
10537
  exports.openDocx = openDocx;
9498
10538
  exports.openOdp = openOdp;
10539
+ exports.openOds = openOds;
9499
10540
  exports.openOdt = openOdt;
9500
10541
  exports.openPptx = openPptx;
9501
10542
  Object.defineProperty(exports, "packageCodec", {
@@ -9525,6 +10566,7 @@ exports.pptxPdfCodec = pptxPdfCodec;
9525
10566
  exports.pptxToPdf = pptxToPdf;
9526
10567
  exports.readDocxContent = readDocxContent;
9527
10568
  exports.readOdpContent = readOdpContent;
10569
+ exports.readOdsContent = readOdsContent;
9528
10570
  exports.readOdtContent = readOdtContent;
9529
10571
  exports.readPdf = readPdf;
9530
10572
  exports.readPptxContent = readPptxContent;