odf.js 1.2.0 → 1.3.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
@@ -449,6 +449,17 @@ function txt(value) {
449
449
  function encodeXmlText(value) {
450
450
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
451
451
  }
452
+ const XML_ENTITY_PATTERN = /&(?:amp|lt|gt|quot|apos);/g;
453
+ const XML_ENTITY_DECODE = {
454
+ "&amp;": "&",
455
+ "&lt;": "<",
456
+ "&gt;": ">",
457
+ "&quot;": "\"",
458
+ "&apos;": "'"
459
+ };
460
+ function decodeXmlText(value) {
461
+ return value.replace(XML_ENTITY_PATTERN, (entity) => XML_ENTITY_DECODE[entity]);
462
+ }
452
463
  //#endregion
453
464
  //#region src/manifest.ts
454
465
  const ManifestEntrySchema = zod.z.object({
@@ -472,26 +483,26 @@ const STANDARD_XML_PART_NAMES = /* @__PURE__ */ new Set([
472
483
  "meta.xml",
473
484
  "settings.xml"
474
485
  ]);
475
- function findChildElement(nodes, tag) {
486
+ function findChildElement$1(nodes, tag) {
476
487
  for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
477
488
  }
478
- function attrValue$1(element, name) {
489
+ function attrValue$2(element, name) {
479
490
  return element.attributes.find((attribute) => attribute.name === name)?.value;
480
491
  }
481
492
  function readManifest(pkg) {
482
493
  const part = pkg.parts[MANIFEST_PART];
483
494
  if (part?.kind !== "xml") throw new Error(`package has no ${MANIFEST_PART} XML part to read`);
484
- const root = findChildElement(part.nodes, "manifest:manifest");
495
+ const root = findChildElement$1(part.nodes, "manifest:manifest");
485
496
  if (root === void 0) throw new Error(`${MANIFEST_PART} has no manifest:manifest root element`);
486
- const version = attrValue$1(root, "manifest:version");
497
+ const version = attrValue$2(root, "manifest:version");
487
498
  if (version === void 0) throw new Error(`${MANIFEST_PART}'s manifest:manifest root is missing the required manifest:version attribute`);
488
499
  const entries = [];
489
500
  for (const child of root.children) {
490
501
  if (child.type !== "element" || child.tag !== "manifest:file-entry") continue;
491
- const fullPath = attrValue$1(child, "manifest:full-path");
492
- const mediaType = attrValue$1(child, "manifest:media-type");
502
+ const fullPath = attrValue$2(child, "manifest:full-path");
503
+ const mediaType = attrValue$2(child, "manifest:media-type");
493
504
  if (fullPath === void 0 || mediaType === void 0) throw new Error(`${MANIFEST_PART} has a manifest:file-entry missing manifest:full-path or manifest:media-type`);
494
- const entryVersion = attrValue$1(child, "manifest:version");
505
+ const entryVersion = attrValue$2(child, "manifest:version");
495
506
  entries.push(entryVersion === void 0 ? {
496
507
  fullPath,
497
508
  mediaType
@@ -601,7 +612,7 @@ function validateManifest(pkg) {
601
612
  });
602
613
  return problems;
603
614
  }
604
- const root = findChildElement(manifestPart.nodes, "manifest:manifest");
615
+ const root = findChildElement$1(manifestPart.nodes, "manifest:manifest");
605
616
  if (root === void 0) {
606
617
  problems.push({
607
618
  severity: "error",
@@ -650,7 +661,7 @@ function validateManifest(pkg) {
650
661
  for (const child of root.children) {
651
662
  if (child.type !== "element" || child.tag !== "manifest:file-entry") continue;
652
663
  if (!child.children.some((grandchild) => grandchild.type === "element" && grandchild.tag === "manifest:encryption-data")) continue;
653
- const fullPath = attrValue$1(child, "manifest:full-path");
664
+ const fullPath = attrValue$2(child, "manifest:full-path");
654
665
  if (fullPath === void 0) continue;
655
666
  problems.push({
656
667
  severity: "warning",
@@ -682,6 +693,48 @@ function setDocumentMediaType(pkg, mediaType, version = DEFAULT_MANIFEST_VERSION
682
693
  });
683
694
  }
684
695
  //#endregion
696
+ //#region src/typed/shared/units.ts
697
+ const LENGTH_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(cm|mm|in|pt|pc|px)$/;
698
+ const POINTS_PER_INCH = 72;
699
+ const POINTS_PER_PICA = 12;
700
+ const CM_PER_INCH = 2.54;
701
+ const MM_PER_INCH = 25.4;
702
+ const CSS_REFERENCE_PIXELS_PER_INCH = 96;
703
+ function unitToPtFactor(unit) {
704
+ switch (unit) {
705
+ case "pt": return 1;
706
+ case "in": return POINTS_PER_INCH;
707
+ case "cm": return POINTS_PER_INCH / CM_PER_INCH;
708
+ case "mm": return POINTS_PER_INCH / MM_PER_INCH;
709
+ case "pc": return POINTS_PER_PICA;
710
+ case "px": return POINTS_PER_INCH / CSS_REFERENCE_PIXELS_PER_INCH;
711
+ }
712
+ }
713
+ function isLengthUnit(value) {
714
+ return value === "cm" || value === "mm" || value === "in" || value === "pt" || value === "pc" || value === "px";
715
+ }
716
+ function parseOdfLength(value) {
717
+ const match = LENGTH_PATTERN.exec(value);
718
+ if (match === null) return;
719
+ const numeric = match[1];
720
+ const unit = match[2];
721
+ if (numeric === void 0 || unit === void 0 || !isLengthUnit(unit)) return;
722
+ return Number(numeric) * unitToPtFactor(unit);
723
+ }
724
+ function formatOdfLength(pt, unit = "pt") {
725
+ return `${pt / unitToPtFactor(unit)}${unit}`;
726
+ }
727
+ //#endregion
728
+ //#region src/typed/shared/color.ts
729
+ const ODF_COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
730
+ function parseOdfColor(value) {
731
+ if (!ODF_COLOR_PATTERN.test(value)) return;
732
+ return (0, document_content_model.rgbHexToColor)(value);
733
+ }
734
+ function formatOdfColor(color) {
735
+ return `#${(0, document_content_model.colorToRgbHex)(color)}`;
736
+ }
737
+ //#endregion
685
738
  //#region src/styles/properties.ts
686
739
  const StylePropertiesSchema = zod.z.object({
687
740
  bold: zod.z.boolean().optional(),
@@ -741,30 +794,9 @@ function attributeMap(element) {
741
794
  for (const attribute of element.attributes) map.set(attribute.name, attribute.value);
742
795
  return map;
743
796
  }
744
- const LENGTH_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(cm|mm|in|pt|pc|px)$/;
745
- function unitToPtFactor(unit) {
746
- switch (unit) {
747
- case "pt": return 1;
748
- case "in": return 72;
749
- case "cm": return 72 / 2.54;
750
- case "mm": return 72 / 25.4;
751
- case "pc": return 12;
752
- case "px": return .75;
753
- }
754
- }
755
- function isLengthUnit(value) {
756
- return value === "cm" || value === "mm" || value === "in" || value === "pt" || value === "pc" || value === "px";
757
- }
758
- function parseLength(value) {
759
- const match = LENGTH_PATTERN.exec(value);
760
- if (match === null) return;
761
- const numeric = match[1];
762
- const unit = match[2];
763
- if (numeric === void 0 || unit === void 0 || !isLengthUnit(unit)) return;
764
- return Number(numeric) * unitToPtFactor(unit);
765
- }
797
+ const parseLength = parseOdfLength;
766
798
  function formatPt(valuePt) {
767
- return `${valuePt}pt`;
799
+ return formatOdfLength(valuePt, "pt");
768
800
  }
769
801
  const PERCENTAGE_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))%$/;
770
802
  function parsePercentageMultiplier(value) {
@@ -777,14 +809,8 @@ function parsePercentageMultiplier(value) {
777
809
  function formatPercentageMultiplier(multiplier) {
778
810
  return `${multiplier * 100}%`;
779
811
  }
780
- const COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
781
- function parseColor(value) {
782
- if (!COLOR_PATTERN.test(value)) return;
783
- return (0, document_content_model.rgbHexToColor)(value);
784
- }
785
- function formatColor(color) {
786
- return `#${(0, document_content_model.colorToRgbHex)(color)}`;
787
- }
812
+ const parseColor = parseOdfColor;
813
+ const formatColor = formatOdfColor;
788
814
  function parseLineDecoration(style, companionA, companionAOnValue, companionB, companionBOnValue) {
789
815
  if (style === void 0 && companionA === void 0 && companionB === void 0) return;
790
816
  if (style === "solid" && (companionA === void 0 || companionA === companionAOnValue) && (companionB === void 0 || companionB === companionBOnValue)) return true;
@@ -1049,7 +1075,7 @@ function emptyFamilySets() {
1049
1075
  graphic: /* @__PURE__ */ new Set()
1050
1076
  };
1051
1077
  }
1052
- function attrValue(element, name) {
1078
+ function attrValue$1(element, name) {
1053
1079
  return element.attributes.find((attribute) => attribute.name === name)?.value;
1054
1080
  }
1055
1081
  function findDirectChild(nodes, tag) {
@@ -1077,8 +1103,8 @@ function ensureAutomaticStyles(root) {
1077
1103
  function reserveStyleNames(container, reserved) {
1078
1104
  for (const child of container.children) {
1079
1105
  if (child.type !== "element" || child.tag !== "style:style") continue;
1080
- const name = attrValue(child, "style:name");
1081
- const family = attrValue(child, "style:family");
1106
+ const name = attrValue$1(child, "style:name");
1107
+ const family = attrValue$1(child, "style:family");
1082
1108
  if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
1083
1109
  reserved[family].add(name);
1084
1110
  }
@@ -1124,14 +1150,14 @@ var StyleRegistry = class StyleRegistry {
1124
1150
  const registry = new StyleRegistry(automaticStyles, prefixes, reservedByFamily);
1125
1151
  for (const child of automaticStyles.children) {
1126
1152
  if (child.type !== "element" || child.tag !== "style:style") continue;
1127
- const name = attrValue(child, "style:name");
1128
- const family = attrValue(child, "style:family");
1153
+ const name = attrValue$1(child, "style:name");
1154
+ const family = attrValue$1(child, "style:family");
1129
1155
  if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
1130
1156
  registry.knownStyles.set(name, child);
1131
1157
  reservedByFamily[family].add(name);
1132
1158
  const parsed = parseStyleElementProperties(child);
1133
1159
  if (!parsed.hasUnknown) {
1134
- const parentStyleName = attrValue(child, "style:parent-style-name");
1160
+ const parentStyleName = attrValue$1(child, "style:parent-style-name");
1135
1161
  const fingerprint = computeFingerprint(family, parsed.properties, parentStyleName);
1136
1162
  if (!registry.fingerprintToName.has(fingerprint)) {
1137
1163
  registry.fingerprintToName.set(fingerprint, name);
@@ -1205,10 +1231,62 @@ var StyleRegistry = class StyleRegistry {
1205
1231
  }
1206
1232
  };
1207
1233
  //#endregion
1234
+ //#region src/xml/query.ts
1235
+ function rootElement(nodes) {
1236
+ for (const node of nodes) if (node.type === "element") return node;
1237
+ }
1238
+ function findChildElement(nodes, tag) {
1239
+ for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
1240
+ }
1241
+ function childrenWithTag(element, tag) {
1242
+ const out = [];
1243
+ for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
1244
+ return out;
1245
+ }
1246
+ function attrValue(element, name) {
1247
+ return element.attributes.find((attribute) => attribute.name === name)?.value;
1248
+ }
1249
+ //#endregion
1250
+ //#region src/typed/shared/text.ts
1251
+ function getOdfSpaceCount(element) {
1252
+ const raw = attrValue(element, "text:c");
1253
+ if (raw === void 0) return 1;
1254
+ const parsed = Number.parseInt(raw, 10);
1255
+ if (!Number.isInteger(parsed) || parsed < 0 || String(parsed) !== raw) throw new Error(`getOdfSpaceCount: text:s has a malformed text:c attribute: "${raw}"`);
1256
+ return parsed;
1257
+ }
1258
+ function measureOdfNodeLength(node) {
1259
+ if (node.type === "text") return node.value.length;
1260
+ if (node.type !== "element") return 0;
1261
+ if (node.tag === "text:s") return getOdfSpaceCount(node);
1262
+ if (node.tag === "text:tab" || node.tag === "text:line-break") return 1;
1263
+ if (node.tag === "text:span") return sumOdfNodeLength(node.children);
1264
+ return 0;
1265
+ }
1266
+ function sumOdfNodeLength(nodes) {
1267
+ let total = 0;
1268
+ for (const node of nodes) total += measureOdfNodeLength(node);
1269
+ return total;
1270
+ }
1271
+ function decodeOdfNode(node) {
1272
+ if (node.type === "text") return decodeXmlText(node.value);
1273
+ if (node.type !== "element") return "";
1274
+ if (node.tag === "text:s") return " ".repeat(getOdfSpaceCount(node));
1275
+ if (node.tag === "text:tab") return " ";
1276
+ if (node.tag === "text:line-break") return "\n";
1277
+ if (node.tag === "text:span") return decodeOdfText(node);
1278
+ return "";
1279
+ }
1280
+ function decodeOdfText(container) {
1281
+ let text = "";
1282
+ for (const child of container.children) text += decodeOdfNode(child);
1283
+ return text;
1284
+ }
1285
+ //#endregion
1208
1286
  //#region src/styles/span.ts
1209
1287
  function ensureSpan(paragraph, start, end, styleName) {
1210
1288
  if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) throw new Error(`ensureSpan: invalid range [${start}, ${end})`);
1211
- const total = sumLength(paragraph.children);
1289
+ const total = sumOdfNodeLength(paragraph.children);
1212
1290
  if (end > total) throw new Error(`ensureSpan: range end ${end} exceeds the container's total character length ${total}`);
1213
1291
  const { before, after: rest } = splitChildrenAt(paragraph.children, start);
1214
1292
  const { before: middle, after } = splitChildrenAt(rest, end - start);
@@ -1240,29 +1318,9 @@ function setStyleName(span, styleName) {
1240
1318
  value: encoded
1241
1319
  });
1242
1320
  }
1243
- function getSpaceCount(spaceElement) {
1244
- const raw = spaceElement.attributes.find((attribute) => attribute.name === "text:c")?.value;
1245
- if (raw === void 0) return 1;
1246
- const parsed = Number.parseInt(raw, 10);
1247
- if (!Number.isInteger(parsed) || parsed < 0 || String(parsed) !== raw) throw new Error(`ensureSpan: text:s has a malformed text:c attribute: "${raw}"`);
1248
- return parsed;
1249
- }
1250
1321
  function buildSpaceRun(count) {
1251
1322
  return count === 1 ? el("text:s") : el("text:s", { "text:c": String(count) });
1252
1323
  }
1253
- function measureLength(node) {
1254
- if (node.type === "text") return node.value.length;
1255
- if (node.type !== "element") return 0;
1256
- if (node.tag === "text:s") return getSpaceCount(node);
1257
- if (node.tag === "text:tab" || node.tag === "text:line-break") return 1;
1258
- if (node.tag === "text:span") return sumLength(node.children);
1259
- return 0;
1260
- }
1261
- function sumLength(nodes) {
1262
- let total = 0;
1263
- for (const node of nodes) total += measureLength(node);
1264
- return total;
1265
- }
1266
1324
  function splitNode(node, offset) {
1267
1325
  if (node.type === "text") return {
1268
1326
  left: {
@@ -1275,7 +1333,7 @@ function splitNode(node, offset) {
1275
1333
  }
1276
1334
  };
1277
1335
  if (node.type === "element" && node.tag === "text:s") {
1278
- const count = getSpaceCount(node);
1336
+ const count = getOdfSpaceCount(node);
1279
1337
  return {
1280
1338
  left: buildSpaceRun(offset),
1281
1339
  right: buildSpaceRun(count - offset)
@@ -1312,7 +1370,7 @@ function splitChildrenAt(children, offset) {
1312
1370
  after: children.slice(index)
1313
1371
  };
1314
1372
  const node = children[index];
1315
- const length = measureLength(node);
1373
+ const length = measureOdfNodeLength(node);
1316
1374
  if (remaining >= length) {
1317
1375
  before.push(node);
1318
1376
  remaining -= length;
@@ -1334,9 +1392,227 @@ function splitChildrenAt(children, offset) {
1334
1392
  };
1335
1393
  }
1336
1394
  //#endregion
1395
+ //#region src/typed/shared/a1.ts
1396
+ const ALPHABET_SIZE = 26;
1397
+ const ALPHABET_START_CODE = "A".charCodeAt(0);
1398
+ function columnIndexToLetters(index) {
1399
+ if (!Number.isInteger(index) || index < 0) throw new Error(`columnIndexToLetters: index must be a non-negative integer, got ${index}`);
1400
+ let remaining = index + 1;
1401
+ let letters = "";
1402
+ while (remaining > 0) {
1403
+ const digit = (remaining - 1) % ALPHABET_SIZE;
1404
+ letters = String.fromCharCode(ALPHABET_START_CODE + digit) + letters;
1405
+ remaining = Math.floor((remaining - 1) / ALPHABET_SIZE);
1406
+ }
1407
+ return letters;
1408
+ }
1409
+ function cellReference(columnIndex, rowIndex) {
1410
+ if (!Number.isInteger(rowIndex) || rowIndex < 0) throw new Error(`cellReference: rowIndex must be a non-negative integer, got ${rowIndex}`);
1411
+ return `${columnIndexToLetters(columnIndex)}${rowIndex + 1}`;
1412
+ }
1413
+ function validateRepeatCount(repeatCount, caller) {
1414
+ if (!Number.isInteger(repeatCount) || repeatCount < 1) throw new Error(`${caller}: repeatCount must be a positive integer, got ${repeatCount}`);
1415
+ }
1416
+ var TableCursor = class {
1417
+ columnCursor = 0;
1418
+ rowCursor = 0;
1419
+ get columnIndex() {
1420
+ return this.columnCursor;
1421
+ }
1422
+ get rowIndex() {
1423
+ return this.rowCursor;
1424
+ }
1425
+ nextCell(repeatCount = 1) {
1426
+ validateRepeatCount(repeatCount, "TableCursor.nextCell");
1427
+ const reference = cellReference(this.columnCursor, this.rowCursor);
1428
+ this.columnCursor += repeatCount;
1429
+ return reference;
1430
+ }
1431
+ nextRow(repeatCount = 1) {
1432
+ validateRepeatCount(repeatCount, "TableCursor.nextRow");
1433
+ this.rowCursor += repeatCount;
1434
+ this.columnCursor = 0;
1435
+ }
1436
+ };
1437
+ //#endregion
1438
+ //#region src/typed/shared/geometry.ts
1439
+ function parsePageSize(pageLayoutProperties) {
1440
+ const widthValue = attrValue(pageLayoutProperties, "fo:page-width");
1441
+ const heightValue = attrValue(pageLayoutProperties, "fo:page-height");
1442
+ if (widthValue === void 0 || heightValue === void 0) return;
1443
+ const widthPt = parseOdfLength(widthValue);
1444
+ const heightPt = parseOdfLength(heightValue);
1445
+ if (widthPt === void 0 || heightPt === void 0) return;
1446
+ return {
1447
+ widthPt,
1448
+ heightPt
1449
+ };
1450
+ }
1451
+ function parseMargins(pageLayoutProperties) {
1452
+ const topValue = attrValue(pageLayoutProperties, "fo:margin-top");
1453
+ const rightValue = attrValue(pageLayoutProperties, "fo:margin-right");
1454
+ const bottomValue = attrValue(pageLayoutProperties, "fo:margin-bottom");
1455
+ const leftValue = attrValue(pageLayoutProperties, "fo:margin-left");
1456
+ if (topValue === void 0 || rightValue === void 0 || bottomValue === void 0 || leftValue === void 0) return;
1457
+ const topPt = parseOdfLength(topValue);
1458
+ const rightPt = parseOdfLength(rightValue);
1459
+ const bottomPt = parseOdfLength(bottomValue);
1460
+ const leftPt = parseOdfLength(leftValue);
1461
+ if (topPt === void 0 || rightPt === void 0 || bottomPt === void 0 || leftPt === void 0) return;
1462
+ return {
1463
+ topPt,
1464
+ rightPt,
1465
+ bottomPt,
1466
+ leftPt
1467
+ };
1468
+ }
1469
+ function parseBox(element) {
1470
+ const xValue = attrValue(element, "svg:x");
1471
+ const yValue = attrValue(element, "svg:y");
1472
+ const widthValue = attrValue(element, "svg:width");
1473
+ const heightValue = attrValue(element, "svg:height");
1474
+ if (xValue === void 0 || yValue === void 0 || widthValue === void 0 || heightValue === void 0) return;
1475
+ const xPt = parseOdfLength(xValue);
1476
+ const yPt = parseOdfLength(yValue);
1477
+ const widthPt = parseOdfLength(widthValue);
1478
+ const heightPt = parseOdfLength(heightValue);
1479
+ if (xPt === void 0 || yPt === void 0 || widthPt === void 0 || heightPt === void 0) return;
1480
+ return {
1481
+ xPt,
1482
+ yPt,
1483
+ widthPt,
1484
+ heightPt
1485
+ };
1486
+ }
1487
+ //#endregion
1488
+ //#region src/typed/shared/cascade.ts
1489
+ const STYLE_PARTS = ["content.xml", "styles.xml"];
1490
+ const NAME_KEY_SEPARATOR = "\0";
1491
+ function nameKey(family, name) {
1492
+ return `${family}${NAME_KEY_SEPARATOR}${name}`;
1493
+ }
1494
+ function collectStyles(pkg) {
1495
+ const byName = /* @__PURE__ */ new Map();
1496
+ const defaultByFamily = /* @__PURE__ */ new Map();
1497
+ for (const partPath of STYLE_PARTS) {
1498
+ const part = pkg.parts[partPath];
1499
+ if (part?.kind !== "xml") continue;
1500
+ const root = rootElement(part.nodes);
1501
+ if (root === void 0) continue;
1502
+ for (const containerTag of ["office:automatic-styles", "office:styles"]) {
1503
+ const container = findChildElement(root.children, containerTag);
1504
+ if (container === void 0) continue;
1505
+ for (const child of container.children) {
1506
+ if (child.type !== "element") continue;
1507
+ if (child.tag === "style:style") {
1508
+ const name = attrValue(child, "style:name");
1509
+ const family = attrValue(child, "style:family");
1510
+ if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
1511
+ byName.set(nameKey(family, name), child);
1512
+ } else if (child.tag === "style:default-style") {
1513
+ const family = attrValue(child, "style:family");
1514
+ if (family === void 0 || !isStyleFamily(family)) continue;
1515
+ if (!defaultByFamily.has(family)) defaultByFamily.set(family, child);
1516
+ }
1517
+ }
1518
+ }
1519
+ }
1520
+ return {
1521
+ byName,
1522
+ defaultByFamily
1523
+ };
1524
+ }
1525
+ function resolveStyle(styleName, family, pkg) {
1526
+ const { byName, defaultByFamily } = collectStyles(pkg);
1527
+ const diagnostics = [];
1528
+ const defaultElement = defaultByFamily.get(family);
1529
+ let properties = defaultElement === void 0 ? {} : parseStyleElementProperties(defaultElement).properties;
1530
+ if (styleName === void 0) return {
1531
+ properties,
1532
+ diagnostics
1533
+ };
1534
+ const chain = [];
1535
+ const visited = /* @__PURE__ */ new Set();
1536
+ let currentName = styleName;
1537
+ while (currentName !== void 0) {
1538
+ const key = nameKey(family, currentName);
1539
+ if (visited.has(key)) {
1540
+ diagnostics.push({
1541
+ severity: "warning",
1542
+ message: `cyclic style:parent-style-name chain detected at style "${currentName}" (family "${family}") -- breaking the cycle and stopping cascade resolution at this point`
1543
+ });
1544
+ break;
1545
+ }
1546
+ visited.add(key);
1547
+ const element = byName.get(key);
1548
+ if (element === void 0) {
1549
+ diagnostics.push({
1550
+ severity: "warning",
1551
+ message: `style "${currentName}" (family "${family}") was not found in content.xml or styles.xml -- stopping cascade resolution at this point`
1552
+ });
1553
+ break;
1554
+ }
1555
+ chain.push(element);
1556
+ currentName = attrValue(element, "style:parent-style-name");
1557
+ }
1558
+ chain.reverse();
1559
+ for (const element of chain) properties = {
1560
+ ...properties,
1561
+ ...parseStyleElementProperties(element).properties
1562
+ };
1563
+ return {
1564
+ properties,
1565
+ diagnostics
1566
+ };
1567
+ }
1568
+ //#endregion
1569
+ //#region src/typed/shared/metadata.ts
1570
+ const META_PART = "meta.xml";
1571
+ function elementText(element) {
1572
+ let text = "";
1573
+ for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
1574
+ return text;
1575
+ }
1576
+ function firstElementText(container, tag) {
1577
+ const element = childrenWithTag(container, tag)[0];
1578
+ if (element === void 0) return;
1579
+ const text = elementText(element);
1580
+ return text.length > 0 ? text : void 0;
1581
+ }
1582
+ function readOdfMetadata(pkg) {
1583
+ const part = pkg.parts[META_PART];
1584
+ if (part?.kind !== "xml") return {};
1585
+ const root = rootElement(part.nodes);
1586
+ const meta = root === void 0 ? void 0 : findChildElement(root.children, "office:meta");
1587
+ if (meta === void 0) return {};
1588
+ const metadata = {};
1589
+ const title = firstElementText(meta, "dc:title");
1590
+ if (title !== void 0) metadata.title = title;
1591
+ const author = firstElementText(meta, "meta:initial-creator");
1592
+ if (author !== void 0) metadata.author = author;
1593
+ const subject = firstElementText(meta, "dc:subject");
1594
+ if (subject !== void 0) metadata.subject = subject;
1595
+ const keywords = childrenWithTag(meta, "meta:keyword").map(elementText).filter((keyword) => keyword.length > 0);
1596
+ if (keywords.length > 0) metadata.keywords = keywords;
1597
+ const creator = firstElementText(meta, "meta:generator");
1598
+ if (creator !== void 0) metadata.creator = creator;
1599
+ const createdIso = firstElementText(meta, "meta:creation-date");
1600
+ if (createdIso !== void 0) metadata.createdIso = createdIso;
1601
+ const modifiedIso = firstElementText(meta, "dc:date");
1602
+ if (modifiedIso !== void 0) metadata.modifiedIso = modifiedIso;
1603
+ return metadata;
1604
+ }
1605
+ //#endregion
1606
+ Object.defineProperty(exports, "AlignmentSchema", {
1607
+ enumerable: true,
1608
+ get: function() {
1609
+ return document_content_model.AlignmentSchema;
1610
+ }
1611
+ });
1337
1612
  exports.AttributeSchema = AttributeSchema;
1338
1613
  exports.BinaryPartSchema = BinaryPartSchema;
1339
1614
  exports.MANIFEST_PART = MANIFEST_PART;
1615
+ exports.META_PART = META_PART;
1340
1616
  exports.MIMETYPE_PART = MIMETYPE_PART;
1341
1617
  exports.ManifestEntrySchema = ManifestEntrySchema;
1342
1618
  exports.ManifestProblemSchema = ManifestProblemSchema;
@@ -1348,6 +1624,7 @@ exports.PartSchema = PartSchema;
1348
1624
  exports.STYLE_FAMILIES = STYLE_FAMILIES;
1349
1625
  exports.StylePropertiesSchema = StylePropertiesSchema;
1350
1626
  exports.StyleRegistry = StyleRegistry;
1627
+ exports.TableCursor = TableCursor;
1351
1628
  exports.XmlCdataSchema = XmlCdataSchema;
1352
1629
  exports.XmlCommentSchema = XmlCommentSchema;
1353
1630
  exports.XmlDeclarationSchema = XmlDeclarationSchema;
@@ -1356,34 +1633,55 @@ exports.XmlNodeSchema = XmlNodeSchema;
1356
1633
  exports.XmlPartSchema = XmlPartSchema;
1357
1634
  exports.XmlPiSchema = XmlPiSchema;
1358
1635
  exports.XmlTextSchema = XmlTextSchema;
1636
+ exports.attrValue = attrValue;
1359
1637
  exports.base64ToBytes = base64ToBytes;
1360
1638
  exports.buildManifest = buildManifest;
1361
1639
  exports.buildStylePropertyElements = buildStylePropertyElements;
1362
1640
  exports.buildXml = buildXml;
1363
1641
  exports.bytesToBase64 = bytesToBase64;
1364
1642
  exports.canonicalPropertiesString = canonicalPropertiesString;
1643
+ exports.cellReference = cellReference;
1644
+ exports.childrenWithTag = childrenWithTag;
1645
+ exports.columnIndexToLetters = columnIndexToLetters;
1646
+ exports.decodeOdfText = decodeOdfText;
1365
1647
  exports.decodePackage = decodePackage;
1648
+ exports.decodeXmlText = decodeXmlText;
1366
1649
  exports.el = el;
1367
1650
  exports.encodePackage = encodePackage;
1368
1651
  exports.encodeXmlText = encodeXmlText;
1369
1652
  exports.ensureSpan = ensureSpan;
1653
+ exports.findChildElement = findChildElement;
1654
+ exports.formatOdfColor = formatOdfColor;
1655
+ exports.formatOdfLength = formatOdfLength;
1370
1656
  exports.formatPercentageMultiplier = formatPercentageMultiplier;
1371
1657
  exports.formatPt = formatPt;
1658
+ exports.getOdfSpaceCount = getOdfSpaceCount;
1659
+ exports.isStyleFamily = isStyleFamily;
1372
1660
  exports.isXmlNode = isXmlNode;
1661
+ exports.measureOdfNodeLength = measureOdfNodeLength;
1373
1662
  exports.mediaTypeForExtension = mediaTypeForExtension;
1374
1663
  exports.packageCodec = packageCodec;
1375
1664
  exports.paragraphPropertiesToAttributes = paragraphPropertiesToAttributes;
1665
+ exports.parseBox = parseBox;
1376
1666
  exports.parseLength = parseLength;
1667
+ exports.parseMargins = parseMargins;
1668
+ exports.parseOdfColor = parseOdfColor;
1669
+ exports.parseOdfLength = parseOdfLength;
1377
1670
  exports.parsePackage = parsePackage;
1671
+ exports.parsePageSize = parsePageSize;
1378
1672
  exports.parseParagraphProperties = parseParagraphProperties;
1379
1673
  exports.parseStyleElementProperties = parseStyleElementProperties;
1380
1674
  exports.parseTextProperties = parseTextProperties;
1381
1675
  exports.parseXml = parseXml;
1382
1676
  exports.readManifest = readManifest;
1383
1677
  exports.readMimetype = readMimetype;
1678
+ exports.readOdfMetadata = readOdfMetadata;
1679
+ exports.resolveStyle = resolveStyle;
1680
+ exports.rootElement = rootElement;
1384
1681
  exports.serializePackage = serializePackage;
1385
1682
  exports.setDocumentMediaType = setDocumentMediaType;
1386
1683
  exports.sniffImageFormat = sniffImageFormat;
1684
+ exports.sumOdfNodeLength = sumOdfNodeLength;
1387
1685
  exports.syncManifest = syncManifest;
1388
1686
  exports.textPropertiesToAttributes = textPropertiesToAttributes;
1389
1687
  exports.txt = txt;