ooxml-core 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/dist/automation/index.cjs +3058 -1968
  2. package/dist/automation/index.mjs +3058 -1968
  3. package/dist/automation/node.d.ts.map +1 -1
  4. package/dist/collab/emitter.d.ts.map +1 -1
  5. package/dist/collab/ordering.d.ts.map +1 -1
  6. package/dist/crypto/detect.d.ts.map +1 -1
  7. package/dist/crypto/errors.d.ts +3 -3
  8. package/dist/crypto/errors.d.ts.map +1 -1
  9. package/dist/crypto/index.cjs +6 -6
  10. package/dist/crypto/index.mjs +6 -6
  11. package/dist/crypto/key-derivation.d.ts.map +1 -1
  12. package/dist/diagram/drawing.d.ts.map +1 -1
  13. package/dist/diagram/relationships.d.ts.map +1 -1
  14. package/dist/digest/sha512.d.ts.map +1 -1
  15. package/dist/docx/block-parser.d.ts.map +1 -1
  16. package/dist/docx/diagram.d.ts.map +1 -1
  17. package/dist/docx/docpr-ids.d.ts.map +1 -1
  18. package/dist/docx/embedded.cjs +11 -0
  19. package/dist/docx/embedded.mjs +11 -0
  20. package/dist/docx/field-runs.d.ts.map +1 -1
  21. package/dist/docx/generated/wml-simple-types.d.ts +99 -99
  22. package/dist/docx/generated/wml-simple-types.d.ts.map +1 -1
  23. package/dist/docx/heading-list-kinds.d.ts.map +1 -1
  24. package/dist/docx/highlight.d.ts +1 -1
  25. package/dist/docx/highlight.d.ts.map +1 -1
  26. package/dist/docx/index.cjs +59 -4
  27. package/dist/docx/index.mjs +59 -4
  28. package/dist/docx/layout/index.cjs +1 -0
  29. package/dist/docx/layout/index.mjs +1 -0
  30. package/dist/docx/layout/page-cursor.d.ts.map +1 -1
  31. package/dist/docx/ligatures.d.ts +1 -1
  32. package/dist/docx/ligatures.d.ts.map +1 -1
  33. package/dist/docx/load/index.cjs +29 -18
  34. package/dist/docx/load/index.mjs +29 -18
  35. package/dist/docx/load/legacy-doc.d.ts.map +1 -1
  36. package/dist/docx/model-paragraph.d.ts +6 -1
  37. package/dist/docx/model-paragraph.d.ts.map +1 -1
  38. package/dist/docx/paragraph-styles.d.ts +3 -1
  39. package/dist/docx/paragraph-styles.d.ts.map +1 -1
  40. package/dist/docx/relationship-allocator.d.ts.map +1 -1
  41. package/dist/docx/revision-commands.d.ts.map +1 -1
  42. package/dist/docx/simple-types.d.ts.map +1 -1
  43. package/dist/docx/table-of-contents.d.ts.map +1 -1
  44. package/dist/docx/table-of-figures.d.ts.map +1 -1
  45. package/dist/docx/test-support/restart-fixture.d.ts +3 -3
  46. package/dist/docx/test-support/restart-fixture.d.ts.map +1 -1
  47. package/dist/docx/toc-switches.d.ts +16 -0
  48. package/dist/docx/toc-switches.d.ts.map +1 -0
  49. package/dist/docx/validate-issues.d.ts.map +1 -1
  50. package/dist/docx/write-revisions.d.ts.map +1 -1
  51. package/dist/docx/xml.d.ts.map +1 -1
  52. package/dist/docx/zip-parts.d.ts.map +1 -1
  53. package/dist/opc/properties/types.d.ts +6 -6
  54. package/dist/opc/properties/types.d.ts.map +1 -1
  55. package/dist/opc/relationship-types.d.ts +6 -6
  56. package/dist/opc/relationship-types.d.ts.map +1 -1
  57. package/dist/opc/relationships.d.ts.map +1 -1
  58. package/dist/pptx/automation/index.cjs +138 -138
  59. package/dist/pptx/automation/index.d.ts +3 -3
  60. package/dist/pptx/automation/index.mjs +138 -138
  61. package/dist/pptx/chunks/{index-BWRd8p4y.d.ts → index-BtBj3VG1.d.ts} +3 -3
  62. package/dist/pptx/chunks/index-BtBj3VG1.d.ts.map +1 -0
  63. package/dist/pptx/chunks/{index-CT9y69AZ.d.ts → index-D0yGoLyw.d.ts} +136 -136
  64. package/dist/pptx/chunks/index-D0yGoLyw.d.ts.map +1 -0
  65. package/dist/pptx/chunks/{text-operations-2tKzrY5o.d.ts → text-operations-GuisjlbR.d.ts} +2 -2
  66. package/dist/pptx/chunks/{text-operations-2tKzrY5o.d.ts.map → text-operations-GuisjlbR.d.ts.map} +1 -1
  67. package/dist/pptx/cli/index.cjs +104 -104
  68. package/dist/pptx/cli/index.d.ts +1 -1
  69. package/dist/pptx/cli/index.mjs +104 -104
  70. package/dist/pptx/converter/index.d.ts +1 -1
  71. package/dist/pptx/index.cjs +138 -138
  72. package/dist/pptx/index.d.ts +3 -3
  73. package/dist/pptx/index.mjs +138 -138
  74. package/dist/teams/call.d.ts +61 -0
  75. package/dist/teams/call.d.ts.map +1 -0
  76. package/dist/teams/chat.d.ts +34 -0
  77. package/dist/teams/chat.d.ts.map +1 -0
  78. package/dist/teams/index.cjs +2207 -0
  79. package/dist/teams/index.d.ts +10 -0
  80. package/dist/teams/index.d.ts.map +1 -0
  81. package/dist/teams/index.mjs +2153 -0
  82. package/dist/teams/model.d.ts +49 -0
  83. package/dist/teams/model.d.ts.map +1 -0
  84. package/dist/teams/peer.d.ts +76 -0
  85. package/dist/teams/peer.d.ts.map +1 -0
  86. package/dist/teams/server-config.d.ts +27 -0
  87. package/dist/teams/server-config.d.ts.map +1 -0
  88. package/dist/teams/signaling.d.ts +81 -0
  89. package/dist/teams/signaling.d.ts.map +1 -0
  90. package/dist/teams/store.d.ts +113 -0
  91. package/dist/teams/store.d.ts.map +1 -0
  92. package/dist/teams/view.d.ts +77 -0
  93. package/dist/teams/view.d.ts.map +1 -0
  94. package/dist/teams/workspace.d.ts +51 -0
  95. package/dist/teams/workspace.d.ts.map +1 -0
  96. package/dist/units/units.d.ts.map +1 -1
  97. package/dist/visio/edit-geometry-admission.d.ts.map +1 -1
  98. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  99. package/dist/visio/emf-admission-context.d.ts +1 -1
  100. package/dist/visio/emf-admission-context.d.ts.map +1 -1
  101. package/dist/visio/foreign-vector-types.d.ts.map +1 -1
  102. package/dist/visio/formula-master.d.ts +2 -2
  103. package/dist/visio/formula.d.ts.map +1 -1
  104. package/dist/visio/index.cjs +2048 -290
  105. package/dist/visio/index.mjs +2048 -290
  106. package/dist/visio/media.d.ts.map +1 -1
  107. package/dist/visio/package-common.d.ts.map +1 -1
  108. package/dist/visio/package.d.ts.map +1 -1
  109. package/dist/visio/sheet.d.ts.map +1 -1
  110. package/dist/visio/theme-color.d.ts.map +1 -1
  111. package/dist/xlsx/address.d.ts.map +1 -1
  112. package/dist/xlsx/cell-styles.d.ts.map +1 -1
  113. package/dist/xlsx/cells.d.ts.map +1 -1
  114. package/dist/xlsx/edit/calc-mode.d.ts.map +1 -1
  115. package/dist/xlsx/edit/clipboard-html.d.ts.map +1 -1
  116. package/dist/xlsx/edit/columns.d.ts.map +1 -1
  117. package/dist/xlsx/edit/context.d.ts.map +1 -1
  118. package/dist/xlsx/edit/fill-series.d.ts.map +1 -1
  119. package/dist/xlsx/edit/history.d.ts.map +1 -1
  120. package/dist/xlsx/edit/outline.d.ts.map +1 -1
  121. package/dist/xlsx/edit/range-math.d.ts.map +1 -1
  122. package/dist/xlsx/edit/session-calc.d.ts.map +1 -1
  123. package/dist/xlsx/edit/structure.d.ts.map +1 -1
  124. package/dist/xlsx/formula/area-index.d.ts.map +1 -1
  125. package/dist/xlsx/formula/ast.d.ts.map +1 -1
  126. package/dist/xlsx/formula/date-serial.d.ts.map +1 -1
  127. package/dist/xlsx/formula/engine-core.d.ts.map +1 -1
  128. package/dist/xlsx/formula/engine-host.d.ts.map +1 -1
  129. package/dist/xlsx/formula/engine-util.d.ts.map +1 -1
  130. package/dist/xlsx/formula/functions/complex.d.ts +14 -0
  131. package/dist/xlsx/formula/functions/complex.d.ts.map +1 -0
  132. package/dist/xlsx/formula/functions/convert.d.ts +4 -0
  133. package/dist/xlsx/formula/functions/convert.d.ts.map +1 -0
  134. package/dist/xlsx/formula/functions/criteria.d.ts.map +1 -1
  135. package/dist/xlsx/formula/functions/database.d.ts +4 -0
  136. package/dist/xlsx/formula/functions/database.d.ts.map +1 -0
  137. package/dist/xlsx/formula/functions/dist-core.d.ts.map +1 -1
  138. package/dist/xlsx/formula/functions/distributions-f.d.ts +6 -0
  139. package/dist/xlsx/formula/functions/distributions-f.d.ts.map +1 -0
  140. package/dist/xlsx/formula/functions/distributions.d.ts.map +1 -1
  141. package/dist/xlsx/formula/functions/engineering.d.ts.map +1 -1
  142. package/dist/xlsx/formula/functions/helpers.d.ts.map +1 -1
  143. package/dist/xlsx/formula/functions/hypothesis-tests.d.ts +4 -0
  144. package/dist/xlsx/formula/functions/hypothesis-tests.d.ts.map +1 -0
  145. package/dist/xlsx/formula/functions/math-combin.d.ts.map +1 -1
  146. package/dist/xlsx/formula/functions/matrix.d.ts +5 -0
  147. package/dist/xlsx/formula/functions/matrix.d.ts.map +1 -1
  148. package/dist/xlsx/formula/functions/registry.d.ts.map +1 -1
  149. package/dist/xlsx/formula/functions/regression-core.d.ts +34 -0
  150. package/dist/xlsx/formula/functions/regression-core.d.ts.map +1 -0
  151. package/dist/xlsx/formula/functions/regression.d.ts +4 -0
  152. package/dist/xlsx/formula/functions/regression.d.ts.map +1 -0
  153. package/dist/xlsx/formula/functions/statistical.d.ts.map +1 -1
  154. package/dist/xlsx/formula/functions/stats-core.d.ts.map +1 -1
  155. package/dist/xlsx/formula/functions/text-case.d.ts.map +1 -1
  156. package/dist/xlsx/formula/functions/types.d.ts.map +1 -1
  157. package/dist/xlsx/formula/graph-index.d.ts.map +1 -1
  158. package/dist/xlsx/formula/lexemes.d.ts +1 -1
  159. package/dist/xlsx/formula/lexemes.d.ts.map +1 -1
  160. package/dist/xlsx/formula/references.d.ts.map +1 -1
  161. package/dist/xlsx/formula/spill.d.ts.map +1 -1
  162. package/dist/xlsx/formula/test-helpers.d.ts.map +1 -1
  163. package/dist/xlsx/formula/tokenizer.d.ts.map +1 -1
  164. package/dist/xlsx/formula/values.d.ts +2 -1
  165. package/dist/xlsx/formula/values.d.ts.map +1 -1
  166. package/dist/xlsx/index.cjs +2835 -1756
  167. package/dist/xlsx/index.mjs +2835 -1756
  168. package/dist/xlsx/layout/axis-metrics.d.ts.map +1 -1
  169. package/dist/xlsx/layout/chart-svg-util.d.ts.map +1 -1
  170. package/dist/xlsx/layout/colors.d.ts +1 -1
  171. package/dist/xlsx/layout/colors.d.ts.map +1 -1
  172. package/dist/xlsx/layout/tint.d.ts.map +1 -1
  173. package/dist/xlsx/layout/units.d.ts.map +1 -1
  174. package/dist/xlsx/load/errors.d.ts.map +1 -1
  175. package/dist/xlsx/load/index.cjs +2320 -1241
  176. package/dist/xlsx/load/index.mjs +2320 -1241
  177. package/dist/xlsx/load/legacy-xls-sheet.d.ts.map +1 -1
  178. package/dist/xlsx/load/legacy-xls.d.ts.map +1 -1
  179. package/dist/xlsx/model.d.ts +1 -1
  180. package/dist/xlsx/model.d.ts.map +1 -1
  181. package/dist/xlsx/numfmt/decimal.d.ts.map +1 -1
  182. package/dist/xlsx/read/package.d.ts +22 -22
  183. package/dist/xlsx/read/package.d.ts.map +1 -1
  184. package/dist/xlsx/read/password-hash.d.ts.map +1 -1
  185. package/dist/xlsx/read/sheet-props.d.ts +7 -7
  186. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  187. package/dist/xlsx/read/theme.d.ts +2 -2
  188. package/dist/xlsx/read/theme.d.ts.map +1 -1
  189. package/dist/xlsx/read/worksheet.d.ts +1 -1
  190. package/dist/xlsx/read/worksheet.d.ts.map +1 -1
  191. package/dist/xlsx/read/xml-util.d.ts.map +1 -1
  192. package/dist/xlsx/workbook.d.ts.map +1 -1
  193. package/dist/xlsx/write/carried-refs.d.ts.map +1 -1
  194. package/dist/xlsx/write/comments.d.ts.map +1 -1
  195. package/dist/xlsx/write/doc-props.d.ts.map +1 -1
  196. package/dist/xlsx/write/drawing.d.ts.map +1 -1
  197. package/dist/xlsx/write/dynamic-array.d.ts.map +1 -1
  198. package/dist/xlsx/write/metadata.d.ts.map +1 -1
  199. package/dist/xlsx/write/package-writer.d.ts.map +1 -1
  200. package/dist/xlsx/write/shared-strings.d.ts.map +1 -1
  201. package/dist/xlsx/write/snapshot.d.ts.map +1 -1
  202. package/dist/xlsx/write/style-xml.d.ts.map +1 -1
  203. package/dist/xlsx/write/styles.d.ts.map +1 -1
  204. package/dist/xlsx/write/vml-ids.d.ts.map +1 -1
  205. package/dist/xlsx/write/xml-out.d.ts.map +1 -1
  206. package/dist/xml/namespaces.d.ts +31 -31
  207. package/dist/xml/namespaces.d.ts.map +1 -1
  208. package/dist/xml/xml.d.ts.map +1 -1
  209. package/package.json +19 -14
  210. package/dist/pptx/chunks/index-BWRd8p4y.d.ts.map +0 -1
  211. package/dist/pptx/chunks/index-CT9y69AZ.d.ts.map +0 -1
@@ -2252,7 +2252,7 @@ function sanitize(root, limits) {
2252
2252
  }
2253
2253
  return { tag: data2.tag, attrs, children: data2.children };
2254
2254
  }
2255
- function children3(value, optional = false) {
2255
+ function children4(value, optional = false) {
2256
2256
  if (value === void 0 && optional) return [];
2257
2257
  if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype)
2258
2258
  unsafe("Expected plain child array.");
@@ -2283,7 +2283,7 @@ function sanitize(root, limits) {
2283
2283
  return target;
2284
2284
  }
2285
2285
  function leaf(data2) {
2286
- if (children3(data2.children, true).length !== 0) unsafe("Path cannot contain child elements.");
2286
+ if (children4(data2.children, true).length !== 0) unsafe("Path cannot contain child elements.");
2287
2287
  return pathCommands(data2.attrs.d, limits, pathBudget);
2288
2288
  }
2289
2289
  function item(value, depth) {
@@ -2296,7 +2296,7 @@ function sanitize(root, limits) {
2296
2296
  paint: paint(data2.attrs)
2297
2297
  }) : Object.assign(target, {
2298
2298
  kind: "group",
2299
- items: Object.freeze(children3(data2.children).map((child2) => item(child2, depth + 1)))
2299
+ items: Object.freeze(children4(data2.children).map((child2) => item(child2, depth + 1)))
2300
2300
  });
2301
2301
  freezeLater.push(result);
2302
2302
  return result;
@@ -2313,7 +2313,7 @@ function sanitize(root, limits) {
2313
2313
  ids.set(id, clips.length);
2314
2314
  const target = base(data2.attrs);
2315
2315
  const paths = [];
2316
- for (const child2 of children3(data2.children)) {
2316
+ for (const child2 of children4(data2.children)) {
2317
2317
  const part = node(child2, depth + 1, true);
2318
2318
  if (part.tag !== "path") unsafe("Clip content must be a path.");
2319
2319
  const path = Object.assign(base(part.attrs), {
@@ -2338,11 +2338,11 @@ function sanitize(root, limits) {
2338
2338
  if (viewBox[0] !== 0 || viewBox[1] !== 0 || viewBox[2] !== width || viewBox[3] !== height)
2339
2339
  unsafe("Viewport differs from dimensions.");
2340
2340
  const items = [];
2341
- for (const child2 of children3(data.children)) {
2341
+ for (const child2 of children4(data.children)) {
2342
2342
  const peek = record(child2, ["tag", "attrs", "children"]);
2343
2343
  if (peek.tag === "defs") {
2344
2344
  const defs = node(child2, 1);
2345
- for (const value of children3(defs.children)) definition(value, 2);
2345
+ for (const value of children4(defs.children)) definition(value, 2);
2346
2346
  } else items.push(item(child2, 1));
2347
2347
  }
2348
2348
  for (const { target, id } of pending) {
@@ -5134,7 +5134,7 @@ function getVisioPageLayers(document, pageId) {
5134
5134
  return result.reverse();
5135
5135
  }
5136
5136
 
5137
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
5137
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
5138
5138
  var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 177, 26, 225]);
5139
5139
  var ENDOFCHAIN = 4294967294;
5140
5140
  var FREESECT = 4294967295;
@@ -5152,7 +5152,7 @@ var Ole2ParseError = class extends Error {
5152
5152
  }
5153
5153
  };
5154
5154
 
5155
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
5155
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
5156
5156
  function parseOle2(buffer) {
5157
5157
  const data = new Uint8Array(buffer);
5158
5158
  const view2 = new DataView(buffer);
@@ -5382,7 +5382,7 @@ function parseOle2(buffer) {
5382
5382
  return { entries, getStream };
5383
5383
  }
5384
5384
 
5385
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-document-base.js
5385
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-document-base.js
5386
5386
  var Ole2DocumentError = class extends Error {
5387
5387
  code;
5388
5388
  constructor(code, message) {
@@ -5447,7 +5447,7 @@ var Ole2DocumentBase = class {
5447
5447
  }
5448
5448
  };
5449
5449
 
5450
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js
5450
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js
5451
5451
  var END = 4294967294;
5452
5452
  var MAX = 4294967290;
5453
5453
  var NIL = 4294967295;
@@ -5607,11 +5607,11 @@ function processCompoundFileStream(input, path, replacement) {
5607
5607
  if (!workbook)
5608
5608
  continue;
5609
5609
  for (let p = 0; p + 4 <= workbook.length; ) {
5610
- const record4 = workbook[p] | workbook[p + 1] << 8;
5610
+ const record5 = workbook[p] | workbook[p + 1] << 8;
5611
5611
  const length = workbook[p + 2] | workbook[p + 3] << 8;
5612
- if (record4 === 47)
5612
+ if (record5 === 47)
5613
5613
  return reject2();
5614
- if (p + 4 + length > workbook.length || record4 === 10)
5614
+ if (p + 4 + length > workbook.length || record5 === 10)
5615
5615
  break;
5616
5616
  p += 4 + length;
5617
5617
  }
@@ -5720,7 +5720,7 @@ function replaceCompoundFileStream(input, path, replacement) {
5720
5720
  return processCompoundFileStream(input, path, replacement) ?? input;
5721
5721
  }
5722
5722
 
5723
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-v4.js
5723
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-v4.js
5724
5724
  var END2 = 4294967294;
5725
5725
  var FREE = 4294967295;
5726
5726
  var FAT = 4294967293;
@@ -5792,49 +5792,49 @@ function validateHierarchy(slots) {
5792
5792
  throw new Error("Unreachable directory entries");
5793
5793
  }
5794
5794
  function resizeCompoundFileStreamV4(input, path, replacement) {
5795
- const fail2 = (reason) => ({ ok: false, bytes: input, reason });
5795
+ const fail3 = (reason) => ({ ok: false, bytes: input, reason });
5796
5796
  try {
5797
5797
  if (input.length < 512 || !path.length || path.some((part) => !part))
5798
- return fail2("invalid-or-missing-stream");
5798
+ return fail3("invalid-or-missing-stream");
5799
5799
  const view2 = new DataView(input.buffer, input.byteOffset, input.byteLength);
5800
5800
  const read = (offset) => view2.getUint32(offset, true);
5801
5801
  const version = view2.getUint16(26, true);
5802
5802
  if (version !== 4)
5803
- return fail2("unsupported-version");
5803
+ return fail3("unsupported-version");
5804
5804
  const SECTOR3 = 4096, FAT_ENTRIES2 = SECTOR3 / 4, DIRECTORY_ENTRIES = SECTOR3 / 128;
5805
5805
  if (read(72) !== 0 || read(44) > 109)
5806
- return fail2("unsupported-difat");
5806
+ return fail3("unsupported-difat");
5807
5807
  const cutoff = read(56);
5808
5808
  if (cutoff !== 0 && cutoff !== 4096)
5809
- return fail2("unsupported-layout");
5809
+ return fail3("unsupported-layout");
5810
5810
  const original = readCompoundFileStream(input, path);
5811
5811
  if (!original)
5812
- return fail2("invalid-or-missing-stream");
5812
+ return fail3("invalid-or-missing-stream");
5813
5813
  const name = path[path.length - 1].toLocaleLowerCase();
5814
5814
  if (name === "worddocument" && original.length >= 12 && (original[10] | original[11] << 8) & 33024)
5815
- return fail2("unsafe-edit");
5815
+ return fail3("unsafe-edit");
5816
5816
  if (name === "book" || name === "workbook") {
5817
5817
  for (let offset = 0; offset + 4 <= original.length; ) {
5818
- const record4 = original[offset] | original[offset + 1] << 8;
5818
+ const record5 = original[offset] | original[offset + 1] << 8;
5819
5819
  const length = original[offset + 2] | original[offset + 3] << 8;
5820
- if (record4 === 47)
5821
- return fail2("unsafe-edit");
5822
- if (record4 === 10 || offset + 4 + length > original.length)
5820
+ if (record5 === 47)
5821
+ return fail3("unsafe-edit");
5822
+ if (record5 === 10 || offset + 4 + length > original.length)
5823
5823
  break;
5824
5824
  offset += 4 + length;
5825
5825
  }
5826
5826
  }
5827
5827
  const validated = replaceCompoundFileStream(input, path, original);
5828
5828
  if (validated === input)
5829
- return fail2("unsafe-edit");
5829
+ return fail3("unsafe-edit");
5830
5830
  const sameLength = replacement.length === original.length;
5831
5831
  if (!sameLength && original.length < cutoff)
5832
- return fail2("unsupported-mini-stream");
5832
+ return fail3("unsupported-mini-stream");
5833
5833
  if (!sameLength && replacement.length < cutoff)
5834
- return fail2("unsupported-mini-transition");
5834
+ return fail3("unsupported-mini-transition");
5835
5835
  const sectorCount = input.length / SECTOR3 - 1, fatCount = read(44);
5836
5836
  if (sectorCount > fatCount * FAT_ENTRIES2)
5837
- return fail2("unsafe-edit");
5837
+ return fail3("unsafe-edit");
5838
5838
  const fatIds = Array.from({ length: fatCount }, (_, i) => read(76 + 4 * i));
5839
5839
  const fat = [];
5840
5840
  for (const id of fatIds) {
@@ -5842,11 +5842,11 @@ function resizeCompoundFileStreamV4(input, path, replacement) {
5842
5842
  fat.push(read((id + 1) * SECTOR3 + i * 4));
5843
5843
  }
5844
5844
  if (fatIds.some((id) => fat[id] !== FAT))
5845
- return fail2("unsafe-edit");
5845
+ return fail3("unsafe-edit");
5846
5846
  const slots = /* @__PURE__ */ new Map();
5847
5847
  const directoryChain = follow(fat, read(48));
5848
5848
  if (read(40) !== directoryChain.length)
5849
- return fail2("unsafe-edit");
5849
+ return fail3("unsafe-edit");
5850
5850
  for (const [block, sector] of directoryChain.entries()) {
5851
5851
  for (let entry = 0; entry < DIRECTORY_ENTRIES; entry++) {
5852
5852
  const offset = (sector + 1) * SECTOR3 + entry * 128, type = view2.getUint8(offset + 66);
@@ -5854,33 +5854,33 @@ function resizeCompoundFileStreamV4(input, path, replacement) {
5854
5854
  continue;
5855
5855
  const nameLength = view2.getUint16(offset + 64, true);
5856
5856
  if (![1, 2, 5].includes(type) || nameLength < 2 || nameLength > 64 || nameLength % 2 || view2.getUint16(offset + nameLength - 2, true))
5857
- return fail2("unsafe-edit");
5857
+ return fail3("unsafe-edit");
5858
5858
  let name2 = "";
5859
5859
  for (let i = 0; i < nameLength - 2; i += 2)
5860
5860
  name2 += String.fromCharCode(view2.getUint16(offset + i, true));
5861
5861
  if (read(offset + 124) !== 0)
5862
- return fail2("unsafe-edit");
5862
+ return fail3("unsafe-edit");
5863
5863
  const id = block * DIRECTORY_ENTRIES + entry;
5864
5864
  slots.set(id, { id, name: name2, type, left: read(offset + 68), right: read(offset + 72), child: read(offset + 76), start: read(offset + 116), size: read(offset + 120), offset });
5865
5865
  }
5866
5866
  }
5867
5867
  if ([...slots.values()].filter((slot) => slot.type === 5).length !== 1)
5868
- return fail2("unsafe-edit");
5868
+ return fail3("unsafe-edit");
5869
5869
  const target = findSlot(slots, path);
5870
5870
  validateHierarchy(slots);
5871
5871
  if (sameLength) {
5872
5872
  const bytes = replaceCompoundFileStream(input, path, replacement);
5873
- return bytes === input ? fail2("unsafe-edit") : { ok: true, bytes };
5873
+ return bytes === input ? fail3("unsafe-edit") : { ok: true, bytes };
5874
5874
  }
5875
5875
  const oldChain = follow(fat, target.start);
5876
5876
  if (target.size !== original.length || oldChain.length !== Math.ceil(target.size / SECTOR3))
5877
- return fail2("unsafe-edit");
5877
+ return fail3("unsafe-edit");
5878
5878
  const payloadSectors = Math.ceil(replacement.length / SECTOR3);
5879
5879
  let newFatCount = fatCount;
5880
5880
  while (sectorCount + payloadSectors + newFatCount - fatCount > newFatCount * FAT_ENTRIES2)
5881
5881
  newFatCount++;
5882
5882
  if (newFatCount > 109)
5883
- return fail2("allocation-limit");
5883
+ return fail3("allocation-limit");
5884
5884
  const totalSectors = sectorCount + payloadSectors + newFatCount - fatCount;
5885
5885
  const output = new Uint8Array((totalSectors + 1) * SECTOR3);
5886
5886
  output.set(input);
@@ -5904,11 +5904,11 @@ function resizeCompoundFileStreamV4(input, path, replacement) {
5904
5904
  outView.setUint32(target.offset + 120, replacement.length, true);
5905
5905
  return { ok: true, bytes: output };
5906
5906
  } catch {
5907
- return fail2("unsafe-edit");
5907
+ return fail3("unsafe-edit");
5908
5908
  }
5909
5909
  }
5910
5910
 
5911
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-allocation.js
5911
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-allocation.js
5912
5912
  function appendCompoundAllocations(input, existingFatIds, payloads, sectorSize = 512) {
5913
5913
  const sectorCount = input.length / sectorSize - 1;
5914
5914
  const entriesPerFat = sectorSize / 4;
@@ -5955,7 +5955,7 @@ function followCompoundAllocation(table, start) {
5955
5955
  return ids;
5956
5956
  }
5957
5957
 
5958
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-mini.js
5958
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-mini.js
5959
5959
  var END3 = 4294967294;
5960
5960
  var FREE2 = 4294967295;
5961
5961
  var SECTOR = 512;
@@ -6027,7 +6027,7 @@ function resizeMiniCompoundStream(input, fat, fatIds, root, target, replacement,
6027
6027
  return output.bytes;
6028
6028
  }
6029
6029
 
6030
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize.js
6030
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize.js
6031
6031
  var END4 = 4294967294;
6032
6032
  var FREE3 = 4294967295;
6033
6033
  var FAT2 = 4294967293;
@@ -6103,43 +6103,43 @@ function validateHierarchy2(slots) {
6103
6103
  function resizeCompoundFileStream(input, path, replacement) {
6104
6104
  if (input.length >= 512 && new DataView(input.buffer, input.byteOffset, input.byteLength).getUint16(26, true) === 4)
6105
6105
  return resizeCompoundFileStreamV4(input, path, replacement);
6106
- const fail2 = (reason) => ({ ok: false, bytes: input, reason });
6106
+ const fail3 = (reason) => ({ ok: false, bytes: input, reason });
6107
6107
  try {
6108
6108
  if (input.length < SECTOR2 || !path.length || path.some((part) => !part))
6109
- return fail2("invalid-or-missing-stream");
6109
+ return fail3("invalid-or-missing-stream");
6110
6110
  const view2 = new DataView(input.buffer, input.byteOffset, input.byteLength);
6111
6111
  const read = (offset) => view2.getUint32(offset, true);
6112
6112
  if (view2.getUint16(26, true) !== 3)
6113
- return fail2("unsupported-version");
6113
+ return fail3("unsupported-version");
6114
6114
  if (read(72) !== 0 || read(44) > 109)
6115
- return fail2("unsupported-difat");
6115
+ return fail3("unsupported-difat");
6116
6116
  const cutoff = read(56);
6117
6117
  if (cutoff !== 0 && cutoff !== 4096)
6118
- return fail2("unsupported-layout");
6118
+ return fail3("unsupported-layout");
6119
6119
  const original = readCompoundFileStream(input, path);
6120
6120
  if (!original)
6121
- return fail2("invalid-or-missing-stream");
6121
+ return fail3("invalid-or-missing-stream");
6122
6122
  const name = path[path.length - 1].toLocaleLowerCase();
6123
6123
  if (name === "worddocument" && original.length >= 12 && (original[10] | original[11] << 8) & 33024)
6124
- return fail2("unsafe-edit");
6124
+ return fail3("unsafe-edit");
6125
6125
  if (name === "book" || name === "workbook") {
6126
6126
  for (let offset = 0; offset + 4 <= original.length; ) {
6127
- const record4 = original[offset] | original[offset + 1] << 8;
6127
+ const record5 = original[offset] | original[offset + 1] << 8;
6128
6128
  const length = original[offset + 2] | original[offset + 3] << 8;
6129
- if (record4 === 47)
6130
- return fail2("unsafe-edit");
6131
- if (record4 === 10 || offset + 4 + length > original.length)
6129
+ if (record5 === 47)
6130
+ return fail3("unsafe-edit");
6131
+ if (record5 === 10 || offset + 4 + length > original.length)
6132
6132
  break;
6133
6133
  offset += 4 + length;
6134
6134
  }
6135
6135
  }
6136
6136
  const validated = replaceCompoundFileStream(input, path, original);
6137
6137
  if (validated === input)
6138
- return fail2("unsafe-edit");
6138
+ return fail3("unsafe-edit");
6139
6139
  const sameLength = replacement.length === original.length;
6140
6140
  const sectorCount = input.length / SECTOR2 - 1, fatCount = read(44);
6141
6141
  if (sectorCount > fatCount * FAT_ENTRIES)
6142
- return fail2("unsafe-edit");
6142
+ return fail3("unsafe-edit");
6143
6143
  const fatIds = Array.from({ length: fatCount }, (_, i) => read(76 + 4 * i));
6144
6144
  const fat = [];
6145
6145
  for (const id of fatIds) {
@@ -6147,7 +6147,7 @@ function resizeCompoundFileStream(input, path, replacement) {
6147
6147
  fat.push(read((id + 1) * SECTOR2 + i * 4));
6148
6148
  }
6149
6149
  if (fatIds.some((id) => fat[id] !== FAT2))
6150
- return fail2("unsafe-edit");
6150
+ return fail3("unsafe-edit");
6151
6151
  const slots = /* @__PURE__ */ new Map();
6152
6152
  for (const [block, sector] of follow2(fat, read(48)).entries()) {
6153
6153
  for (let entry = 0; entry < 4; entry++) {
@@ -6156,7 +6156,7 @@ function resizeCompoundFileStream(input, path, replacement) {
6156
6156
  continue;
6157
6157
  const nameLength = view2.getUint16(offset + 64, true);
6158
6158
  if (![1, 2, 5].includes(type) || nameLength < 2 || nameLength > 64 || nameLength % 2 || view2.getUint16(offset + nameLength - 2, true))
6159
- return fail2("unsafe-edit");
6159
+ return fail3("unsafe-edit");
6160
6160
  let name2 = "";
6161
6161
  for (let i = 0; i < nameLength - 2; i += 2)
6162
6162
  name2 += String.fromCharCode(view2.getUint16(offset + i, true));
@@ -6165,34 +6165,34 @@ function resizeCompoundFileStream(input, path, replacement) {
6165
6165
  }
6166
6166
  }
6167
6167
  if ([...slots.values()].filter((slot) => slot.type === 5).length !== 1)
6168
- return fail2("unsafe-edit");
6168
+ return fail3("unsafe-edit");
6169
6169
  const target = findSlot2(slots, path);
6170
6170
  validateHierarchy2(slots);
6171
6171
  if (sameLength) {
6172
6172
  const bytes = replaceCompoundFileStream(input, path, replacement);
6173
- return bytes === input ? fail2("unsafe-edit") : { ok: true, bytes };
6173
+ return bytes === input ? fail3("unsafe-edit") : { ok: true, bytes };
6174
6174
  }
6175
6175
  if (original.length < cutoff || replacement.length < cutoff) {
6176
6176
  const bytes = resizeMiniCompoundStream(input, fat, fatIds, slots.get(0), target, replacement, cutoff);
6177
- return bytes ? { ok: true, bytes } : fail2("allocation-limit");
6177
+ return bytes ? { ok: true, bytes } : fail3("allocation-limit");
6178
6178
  }
6179
6179
  const oldChain = follow2(fat, target.start);
6180
6180
  if (target.size !== original.length || oldChain.length !== Math.ceil(target.size / SECTOR2))
6181
- return fail2("unsafe-edit");
6181
+ return fail3("unsafe-edit");
6182
6182
  const output = appendCompoundAllocations(input, fatIds, [replacement]);
6183
6183
  if (!output)
6184
- return fail2("allocation-limit");
6184
+ return fail3("allocation-limit");
6185
6185
  for (const id of oldChain)
6186
6186
  output.writeFat(id, FREE3);
6187
6187
  output.view.setUint32(target.offset + 116, output.chains[0][0] ?? END4, true);
6188
6188
  output.view.setUint32(target.offset + 120, replacement.length, true);
6189
6189
  return { ok: true, bytes: output.bytes };
6190
6190
  } catch {
6191
- return fail2("unsafe-edit");
6191
+ return fail3("unsafe-edit");
6192
6192
  }
6193
6193
  }
6194
6194
 
6195
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js
6195
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js
6196
6196
  var FC_LCB_INDEX = {
6197
6197
  plcfbteChpx: 12,
6198
6198
  plcfbtePapx: 13,
@@ -6288,7 +6288,7 @@ function patchDocFib(wordDoc, fib, patch) {
6288
6288
  view2.setUint32(papxOff + 4, patch.plcfbtePapx.lcb, true);
6289
6289
  }
6290
6290
 
6291
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js
6291
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js
6292
6292
  var DocCfbRewriteError = class extends Error {
6293
6293
  constructor(message) {
6294
6294
  super(message);
@@ -6343,7 +6343,7 @@ function unwrapDocBytes(bytes) {
6343
6343
  }
6344
6344
  }
6345
6345
 
6346
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js
6346
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js
6347
6347
  var PAGE_SIZE = 512;
6348
6348
  function parseBteTable(tableStream, at) {
6349
6349
  const view2 = new DataView(tableStream.buffer, tableStream.byteOffset, tableStream.byteLength);
@@ -6484,7 +6484,7 @@ function buildSingleRunChpxPage(fcStart, fcEnd, blob) {
6484
6484
  return page;
6485
6485
  }
6486
6486
 
6487
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js
6487
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js
6488
6488
  var CP1252_HIGH_BLOCK = [
6489
6489
  8364,
6490
6490
  129,
@@ -6552,7 +6552,7 @@ function encodeCp1252(text) {
6552
6552
  return Uint8Array.from(bytes);
6553
6553
  }
6554
6554
 
6555
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js
6555
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js
6556
6556
  var CLXT_PRC = 1;
6557
6557
  var CLXT_PCDT = 2;
6558
6558
  var DocResourceLimitError = class extends Error {
@@ -6764,7 +6764,7 @@ function buildClxBytes(pieces, prcBytes = new Uint8Array()) {
6764
6764
  return result;
6765
6765
  }
6766
6766
 
6767
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fields.js
6767
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fields.js
6768
6768
  var UnsupportedDocFieldEditError = class extends Error {
6769
6769
  constructor(message) {
6770
6770
  super(message);
@@ -6848,7 +6848,7 @@ function shiftDocMainFieldCps(table, at, body, editStart, editEnd, delta, maxFie
6848
6848
  return result;
6849
6849
  }
6850
6850
 
6851
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js
6851
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js
6852
6852
  var RISKY_PLCF_INDICES = [2, 3, 4, 5, 17, 18, 19, 20, 40, 41, 42, 43, 46, 47, 48, 54, 55, 56, 57, 58, 59, 75, 76, 89, 90];
6853
6853
  var RISKY_STTB_INDICES = [21, 22, 23];
6854
6854
  var SAFE_EXTENDED_FC_LCB_INDICES = /* @__PURE__ */ new Set([93, 94, 113, 181, 182]);
@@ -7117,7 +7117,7 @@ function tryWriteOleDocParagraphEdit(docBytes, paragraphIndex, text, limits) {
7117
7117
  }
7118
7118
  }
7119
7119
 
7120
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-runs.js
7120
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-runs.js
7121
7121
  var LIMIT = 65536;
7122
7122
  var SAFE_OPERANDS = /* @__PURE__ */ new Set([
7123
7123
  2101,
@@ -7145,9 +7145,12 @@ var SAFE_OPERANDS = /* @__PURE__ */ new Set([
7145
7145
  26646,
7146
7146
  26647
7147
7147
  ]);
7148
- function parsePrls(word, start, end) {
7148
+ function parsePrls(word, start, end, budget) {
7149
7149
  const view2 = new DataView(word.buffer, word.byteOffset, word.byteLength), out = [];
7150
7150
  for (let at = start; at < end; ) {
7151
+ if (budget.remaining <= 0)
7152
+ throw new Error("Formatting SPRM limit");
7153
+ budget.remaining--;
7151
7154
  if (at + 2 > end)
7152
7155
  throw new Error("Truncated SPRM");
7153
7156
  const opcode = view2.getUint16(at, true), spra = opcode >>> 13;
@@ -7167,9 +7170,9 @@ function parsePrls(word, start, end) {
7167
7170
  function parsePhysicalRuns(word, table) {
7168
7171
  if (table.pns.length > LIMIT)
7169
7172
  throw new Error("Formatting page limit");
7170
- const view2 = new DataView(word.buffer, word.byteOffset, word.byteLength), out = [];
7173
+ const view2 = new DataView(word.buffer, word.byteOffset, word.byteLength), out = [], budget = { remaining: 262144 };
7171
7174
  for (let bte = 0; bte < table.pns.length; bte++) {
7172
- const page = table.pns[bte] * 512;
7175
+ const page = (table.pns[bte] & 4194303) * 512;
7173
7176
  if (page > word.length - 512)
7174
7177
  throw new Error("Truncated CHPX page");
7175
7178
  const count = word[page + 511], header = (count + 1) * 4 + count;
@@ -7183,7 +7186,7 @@ function parsePhysicalRuns(word, table) {
7183
7186
  if (offset && (offset < header || offset + 1 + word[page + offset] > 511))
7184
7187
  throw new Error("Invalid CHPX blob");
7185
7188
  const blob = offset ? page + offset : 0, blobEnd = blob ? blob + 1 + word[blob] : 0;
7186
- out.push({ start, end, blob, blobEnd, prls: blob ? parsePrls(word, blob + 1, blobEnd) : [] });
7189
+ out.push({ start, end, blob, blobEnd, prls: blob ? parsePrls(word, blob + 1, blobEnd, budget) : [] });
7187
7190
  }
7188
7191
  }
7189
7192
  out.sort((a, b) => a.start - b.start);
@@ -7207,7 +7210,9 @@ function inspect2(input) {
7207
7210
  if (fib.plcfbteChpx.lcb > LIMIT * 8 + 4 || fib.plcfbtePapx.lcb > LIMIT * 8 + 4)
7208
7211
  throw new Error("Formatting table limit");
7209
7212
  const chpx = parseBteTable(doc.tableBytes, fib.plcfbteChpx), papx = parseBteTable(doc.tableBytes, fib.plcfbtePapx);
7213
+ papx.pns = papx.pns.map((pn) => pn & 4194303);
7210
7214
  const physical = parsePhysicalRuns(word, chpx), runs = [];
7215
+ const snapshots = /* @__PURE__ */ new Map();
7211
7216
  for (const piece of pieces) {
7212
7217
  if (piece.cpStart >= fib.ccpText)
7213
7218
  break;
@@ -7234,16 +7239,24 @@ function inspect2(input) {
7234
7239
  const values = row.prls.filter((p) => p.opcode === opcode);
7235
7240
  return values.length === 1 && values[0].operand[0] <= 1 ? values[0].operand[0] === 1 : void 0;
7236
7241
  };
7242
+ const underline = row.prls.filter((p) => p.opcode === 10814);
7243
+ const kul = underline.length === 1 ? underline[0].operand[0] : void 0;
7237
7244
  const size = row.prls.filter((p) => p.opcode === 19011);
7238
7245
  const halfPoints = size.length === 1 ? size[0].operand[0] + size[0].operand[1] * 256 : void 0;
7246
+ let sprms = snapshots.get(row);
7247
+ if (!sprms) {
7248
+ sprms = Object.freeze(row.prls.map((p) => Object.freeze({ opcode: p.opcode, operand: Object.freeze(p.operand.slice()) })));
7249
+ snapshots.set(row, sprms);
7250
+ }
7239
7251
  runs.push({
7240
7252
  cpStart: cp,
7241
7253
  cpEnd: end,
7242
7254
  text: text.slice(cp, end),
7243
7255
  directBold: direct(2101),
7244
7256
  directItalic: direct(2102),
7257
+ directUnderline: piece.prm === 0 && row.prls.every((p) => SAFE_OPERANDS.has(p.opcode)) ? kul === 0 ? "none" : kul === 1 ? "single" : kul === 3 ? "double" : void 0 : void 0,
7245
7258
  directFontSizePoints: piece.prm === 0 && halfPoints !== void 0 && halfPoints >= 2 && halfPoints <= 3276 && row.prls.every((p) => SAFE_OPERANDS.has(p.opcode)) ? halfPoints / 2 : void 0,
7246
- sprms: Object.freeze(row.prls.map((p) => Object.freeze({ opcode: p.opcode, operand: Object.freeze(p.operand.slice()) }))),
7259
+ sprms,
7247
7260
  physical: row,
7248
7261
  prm: piece.prm
7249
7262
  });
@@ -7276,10 +7289,23 @@ function readDocParagraphStyleIndices(input) {
7276
7289
  function writeDocCharacterRunFlag(input, cpStart, cpEnd, flag, value) {
7277
7290
  if (typeof value !== "boolean" || !Number.isSafeInteger(cpStart) || !Number.isSafeInteger(cpEnd) || flag !== "bold" && flag !== "italic")
7278
7291
  throw new Error("invalid-formatting");
7292
+ return writeExclusiveOperand(input, cpStart, cpEnd, flag === "bold" ? 2101 : 2102, Number(value));
7293
+ }
7294
+ function writeDocCharacterRunFontSize(input, cpStart, cpEnd, points) {
7295
+ if (typeof points !== "number" || !Number.isFinite(points) || !Number.isInteger(points * 2) || points < 1 || points > 1638 || !Number.isSafeInteger(cpStart) || !Number.isSafeInteger(cpEnd))
7296
+ throw new Error("invalid-formatting");
7297
+ return writeExclusiveOperand(input, cpStart, cpEnd, 19011, points * 2);
7298
+ }
7299
+ function writeDocCharacterRunUnderline(input, cpStart, cpEnd, value) {
7300
+ if (typeof value !== "string" || !["none", "single", "double"].includes(value) || !Number.isSafeInteger(cpStart) || !Number.isSafeInteger(cpEnd))
7301
+ throw new Error("invalid-formatting");
7302
+ return writeExclusiveOperand(input, cpStart, cpEnd, 10814, value === "none" ? 0 : value === "single" ? 1 : 3);
7303
+ }
7304
+ function writeExclusiveOperand(input, cpStart, cpEnd, opcode, value) {
7279
7305
  const parsed = inspect2(input), target = parsed.runs.find((run) => run.cpStart === cpStart && run.cpEnd === cpEnd);
7280
7306
  if (!target || target.prm !== 0 || /[\x00-\x1f]/u.test(target.text))
7281
7307
  throw new Error("unsupported-formatting");
7282
- const row = target.physical, opcode = flag === "bold" ? 2101 : 2102;
7308
+ const row = target.physical;
7283
7309
  const extension2 = parsed.fib.fibRgFcLcbOffset + parsed.fib.fibRgFcLcbCount * 8;
7284
7310
  const fibEnd = extension2 + 2 + new DataView(parsed.word.buffer, parsed.word.byteOffset, parsed.word.byteLength).getUint16(extension2, true) * 2;
7285
7311
  if (row.blob < fibEnd)
@@ -7287,7 +7313,11 @@ function writeDocCharacterRunFlag(input, cpStart, cpEnd, flag, value) {
7287
7313
  if (row.prls.some((p) => !SAFE_OPERANDS.has(p.opcode)))
7288
7314
  throw new Error("opaque-formatting");
7289
7315
  const operands = row.prls.filter((p) => p.opcode === opcode);
7290
- if (operands.length !== 1 || ![0, 1, 128, 129].includes(operands[0].operand[0]))
7316
+ if (operands.length !== 1)
7317
+ throw new Error("inherited-formatting");
7318
+ const operand = operands[0], size = opcode === 19011;
7319
+ const previous = operand.operand[0] + (size ? operand.operand[1] * 256 : 0);
7320
+ if (size ? operand.operand.length !== 2 || previous < 2 || previous > 3276 : opcode === 10814 ? ![0, 1, 3].includes(previous) : ![0, 1, 128, 129].includes(previous))
7291
7321
  throw new Error("inherited-formatting");
7292
7322
  const piece = parsed.pieces.find((p) => p.cpStart <= cpStart && p.cpEnd >= cpEnd);
7293
7323
  const unit = piece.compressed ? 1 : 2, start = piece.fc + (cpStart - piece.cpStart) * unit;
@@ -7295,25 +7325,241 @@ function writeDocCharacterRunFlag(input, cpStart, cpEnd, flag, value) {
7295
7325
  throw new Error("shared-formatting");
7296
7326
  if (parsed.physical.some((r) => r !== row && r.blob && r.blob < row.blobEnd && row.blob < r.blobEnd) || parsed.papx.pns.includes(Math.floor(row.blob / 512)) || parsed.pieces.some((p) => p.fc < row.blobEnd && row.blob < p.fc + (p.cpEnd - p.cpStart) * (p.compressed ? 1 : 2)))
7297
7327
  throw new Error("aliased-formatting");
7298
- if (operands[0].operand[0] === Number(value))
7328
+ const sed = parsed.fib.sed;
7329
+ if (sed.lcb > LIMIT * 16 + 4)
7330
+ throw new Error("resource-limit");
7331
+ if (sed.lcb) {
7332
+ if (sed.lcb < 4 || (sed.lcb - 4) % 16 || sed.fc > parsed.doc.tableBytes.length - sed.lcb)
7333
+ throw new Error("invalid-formatting");
7334
+ const n = (sed.lcb - 4) / 16, tableView = new DataView(parsed.doc.tableBytes.buffer, parsed.doc.tableBytes.byteOffset, parsed.doc.tableBytes.byteLength);
7335
+ const wordView = new DataView(parsed.word.buffer, parsed.word.byteOffset, parsed.word.byteLength);
7336
+ for (let i = 0; i < n; i++) {
7337
+ const at = tableView.getInt32(sed.fc + (n + 1) * 4 + i * 12 + 2, true);
7338
+ if (at === -1)
7339
+ continue;
7340
+ if (at < 0 || at > parsed.word.length - 2)
7341
+ throw new Error("invalid-formatting");
7342
+ const end = at + 2 + wordView.getUint16(at, true);
7343
+ if (end > parsed.word.length)
7344
+ throw new Error("invalid-formatting");
7345
+ if (at < row.blobEnd && row.blob < end)
7346
+ throw new Error("aliased-formatting");
7347
+ }
7348
+ }
7349
+ if (previous === value)
7350
+ return input;
7351
+ const word = parsed.word.slice();
7352
+ word[operand.at] = value & 255;
7353
+ if (size)
7354
+ word[operand.at + 1] = value >>> 8;
7355
+ return parsed.doc.rewrap(word, parsed.doc.tableBytes);
7356
+ }
7357
+
7358
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole-document-doc-paragraph-format.js
7359
+ var LIMIT2 = 65536;
7360
+ var SPRM_LIMIT = 262144;
7361
+ var PAGE_NUMBER_MASK = 4194303;
7362
+ var ALIGNMENTS = ["start", "center", "end", "justify"];
7363
+ var SAFE = /* @__PURE__ */ new Set([
7364
+ 9219,
7365
+ 9313,
7366
+ 25703,
7367
+ 9221,
7368
+ 9222,
7369
+ 9223,
7370
+ 9228,
7371
+ 25618,
7372
+ 42003,
7373
+ 42004,
7374
+ 9307,
7375
+ 9308,
7376
+ 33885,
7377
+ 33886,
7378
+ 33888,
7379
+ 9281,
7380
+ 9325
7381
+ ]);
7382
+ function alignmentOperands(row) {
7383
+ const values = row.prls.filter((p) => p.opcode === 9313), mirrors = row.prls.filter((p) => p.opcode === 9219);
7384
+ if (values.length !== 1 || values[0].operand[0] > 3 || mirrors.length > 1)
7385
+ return void 0;
7386
+ const value = values[0], mirror = mirrors[0];
7387
+ if (mirror && (mirror.at > value.at || mirror.operand[0] !== value.operand[0]))
7388
+ return void 0;
7389
+ return { value, mirror };
7390
+ }
7391
+ function parsePrls2(word, start, end, budget) {
7392
+ const view2 = new DataView(word.buffer, word.byteOffset, word.byteLength), out = [];
7393
+ for (let at = start; at < end; ) {
7394
+ if (at + 2 > end)
7395
+ throw new Error("invalid-formatting");
7396
+ const opcode = view2.getUint16(at, true), spra = opcode >>> 13;
7397
+ let length = [1, 1, 2, 4, 2, 2, 0, 3][spra];
7398
+ if (spra === 6) {
7399
+ if (opcode === 54792 || opcode === 50709 || at + 3 > end)
7400
+ throw new Error("unsupported-formatting");
7401
+ length = 1 + word[at + 2];
7402
+ }
7403
+ if (at + 2 + length > end)
7404
+ throw new Error("invalid-formatting");
7405
+ if (budget.remaining === 0)
7406
+ throw new Error("resource-limit");
7407
+ budget.remaining--;
7408
+ out.push({ opcode, at: at + 2, operand: word.subarray(at + 2, at + 2 + length) });
7409
+ at += 2 + length;
7410
+ }
7411
+ return out;
7412
+ }
7413
+ function inspect3(input) {
7414
+ const doc = unwrapDocBytes(input);
7415
+ if (!doc)
7416
+ throw new Error("unsupported-formatting");
7417
+ const word = doc.wordDocBytes, fib = readDocFib(word), limits = DEFAULT_OLE_DOC_PROCESSING_LIMITS;
7418
+ if (fib.ccpText > limits.maxCharacters)
7419
+ throw new Error("resource-limit");
7420
+ const pieces = parseDocClx(doc.tableBytes, fib.clx, limits.maxPieces).pieces;
7421
+ const total = pieces.at(-1)?.cpEnd ?? 0;
7422
+ if (total < fib.ccpText || total > fib.ccpText + fib.ccpOtherStories + 1)
7423
+ throw new Error("invalid-formatting");
7424
+ const text = decodePiecesText(word, pieces, fib.ccpText);
7425
+ if (fib.plcfbtePapx.lcb > LIMIT2 * 8 + 4 || fib.plcfbteChpx.lcb > LIMIT2 * 8 + 4)
7426
+ throw new Error("resource-limit");
7427
+ const papx = parseBteTable(doc.tableBytes, fib.plcfbtePapx), chpx = parseBteTable(doc.tableBytes, fib.plcfbteChpx);
7428
+ const view2 = new DataView(word.buffer, word.byteOffset, word.byteLength), rows = [];
7429
+ const sprmBudget = { remaining: SPRM_LIMIT };
7430
+ for (let pageIndex = 0; pageIndex < papx.pns.length; pageIndex++) {
7431
+ const page = (papx.pns[pageIndex] & PAGE_NUMBER_MASK) * 512;
7432
+ if (page > word.length - 512)
7433
+ throw new Error("invalid-formatting");
7434
+ const count = word[page + 511], header = (count + 1) * 4 + count * 13;
7435
+ if (!count || header > 511 || rows.length + count > LIMIT2)
7436
+ throw new Error("resource-limit");
7437
+ for (let i = 0; i < count; i++) {
7438
+ const start = view2.getInt32(page + i * 4, true), end = view2.getInt32(page + (i + 1) * 4, true);
7439
+ if (start < papx.fcs[pageIndex] || end > papx.fcs[pageIndex + 1] || end <= start)
7440
+ throw new Error("invalid-formatting");
7441
+ const offset = word[page + (count + 1) * 4 + i * 13] * 2;
7442
+ if (!offset) {
7443
+ rows.push({ start, end, blob: 0, blobEnd: 0, prls: [] });
7444
+ continue;
7445
+ }
7446
+ if (offset < header || offset + 2 > 511)
7447
+ throw new Error("invalid-formatting");
7448
+ const blob = page + offset, cb = word[blob], prefix = cb === 0 ? 2 : 1;
7449
+ const length = cb === 0 ? 2 + word[blob + 1] * 2 : cb * 2;
7450
+ if (cb === 0 && !word[blob + 1] || length < prefix + 2 || offset + length > 511)
7451
+ throw new Error("invalid-formatting");
7452
+ const blobEnd = blob + length;
7453
+ rows.push({ start, end, blob, blobEnd, prls: parsePrls2(word, blob + prefix + 2, blobEnd, sprmBudget) });
7454
+ }
7455
+ }
7456
+ rows.sort((a, b) => a.start - b.start);
7457
+ for (let i = 1; i < rows.length; i++)
7458
+ if (rows[i].start < rows[i - 1].end)
7459
+ throw new Error("invalid-formatting");
7460
+ const paragraphs = [];
7461
+ let cpStart = 0, pieceIndex = 0;
7462
+ for (let cp = 0; cp < text.length; cp++) {
7463
+ if (text[cp] !== "\r" && cp !== text.length - 1)
7464
+ continue;
7465
+ if (paragraphs.length >= LIMIT2)
7466
+ throw new Error("resource-limit");
7467
+ while (pieces[pieceIndex].cpEnd <= cp)
7468
+ pieceIndex++;
7469
+ const piece = pieces[pieceIndex], fc = piece.fc + (cp - piece.cpStart) * (piece.compressed ? 1 : 2);
7470
+ let lo = 0, hi = rows.length;
7471
+ while (lo < hi) {
7472
+ const middle = lo + hi >>> 1;
7473
+ if (rows[middle].end <= fc)
7474
+ lo = middle + 1;
7475
+ else
7476
+ hi = middle;
7477
+ }
7478
+ const row = rows[lo];
7479
+ if (!row || fc < row.start || fc >= row.end)
7480
+ throw new Error("invalid-formatting");
7481
+ const operands = alignmentOperands(row);
7482
+ const directAlignment = piece.prm === 0 && row.prls.every((p) => SAFE.has(p.opcode)) && operands ? ALIGNMENTS[operands.value.operand[0]] : void 0;
7483
+ paragraphs.push({ cpStart, cpEnd: cp + 1, mark: text[cp] === "\r", row, prm: piece.prm, directAlignment });
7484
+ cpStart = cp + 1;
7485
+ }
7486
+ return { doc, word, fib, pieces, rows, chpx, paragraphs, text };
7487
+ }
7488
+ function readDocParagraphAlignments(input) {
7489
+ return Object.freeze(inspect3(input).paragraphs.map((p) => p.directAlignment));
7490
+ }
7491
+ function writeDocParagraphAlignment(input, index, alignment) {
7492
+ if (!Number.isSafeInteger(index) || index < 0 || typeof alignment !== "string" || !ALIGNMENTS.includes(alignment))
7493
+ throw new Error("invalid-formatting");
7494
+ const parsed = inspect3(input), target = parsed.paragraphs[index];
7495
+ if (!target?.mark || target.prm !== 0 || /[\x00-\x1f]/u.test(parsed.text.slice(target.cpStart, target.cpEnd - 1)))
7496
+ throw new Error("unsupported-formatting");
7497
+ const row = target.row;
7498
+ if (row.prls.some((p) => !SAFE.has(p.opcode)))
7499
+ throw new Error("opaque-formatting");
7500
+ const operands = alignmentOperands(row);
7501
+ if (!operands)
7502
+ throw new Error("inherited-formatting");
7503
+ if (operands.mirror && alignment !== "center" && alignment !== "justify")
7504
+ throw new Error("direction-dependent-alignment");
7505
+ const piece = parsed.pieces.find((p) => p.cpStart <= target.cpStart && p.cpEnd >= target.cpEnd);
7506
+ if (!piece || piece.prm !== 0)
7507
+ throw new Error("unsupported-formatting");
7508
+ const unit = piece.compressed ? 1 : 2, start = piece.fc + (target.cpStart - piece.cpStart) * unit;
7509
+ if (start !== row.start || start + (target.cpEnd - target.cpStart) * unit !== row.end || parsed.paragraphs.some((p) => p !== target && p.row === row) || parsed.pieces.some((p) => p !== piece && p.fc < row.end && row.start < p.fc + (p.cpEnd - p.cpStart) * (p.compressed ? 1 : 2)))
7510
+ throw new Error("shared-formatting");
7511
+ const extension2 = parsed.fib.fibRgFcLcbOffset + parsed.fib.fibRgFcLcbCount * 8;
7512
+ const fibEnd = extension2 + 2 + new DataView(parsed.word.buffer, parsed.word.byteOffset, parsed.word.byteLength).getUint16(extension2, true) * 2;
7513
+ if (row.blob < fibEnd || parsed.rows.some((r) => r !== row && r.blob && r.blob < row.blobEnd && row.blob < r.blobEnd) || parsed.chpx.pns.some((pn) => (pn & PAGE_NUMBER_MASK) === Math.floor(row.blob / 512)) || parsed.pieces.some((p) => p.fc < row.blobEnd && row.blob < p.fc + (p.cpEnd - p.cpStart) * (p.compressed ? 1 : 2)))
7514
+ throw new Error("aliased-formatting");
7515
+ const sed = parsed.fib.sed;
7516
+ if (sed.lcb > LIMIT2 * 16 + 4)
7517
+ throw new Error("resource-limit");
7518
+ if (sed.lcb) {
7519
+ if (sed.lcb < 4 || (sed.lcb - 4) % 16 || sed.fc > parsed.doc.tableBytes.length - sed.lcb)
7520
+ throw new Error("invalid-formatting");
7521
+ const n = (sed.lcb - 4) / 16, tableView = new DataView(parsed.doc.tableBytes.buffer, parsed.doc.tableBytes.byteOffset, parsed.doc.tableBytes.byteLength);
7522
+ const wordView = new DataView(parsed.word.buffer, parsed.word.byteOffset, parsed.word.byteLength);
7523
+ for (let i = 0; i < n; i++) {
7524
+ const at = tableView.getInt32(sed.fc + (n + 1) * 4 + i * 12 + 2, true);
7525
+ if (at === -1)
7526
+ continue;
7527
+ if (at < 0 || at > parsed.word.length - 2)
7528
+ throw new Error("invalid-formatting");
7529
+ const end = at + 2 + wordView.getUint16(at, true);
7530
+ if (end > parsed.word.length)
7531
+ throw new Error("invalid-formatting");
7532
+ if (at < row.blobEnd && row.blob < end)
7533
+ throw new Error("aliased-formatting");
7534
+ }
7535
+ }
7536
+ const value = ALIGNMENTS.indexOf(alignment);
7537
+ if (operands.value.operand[0] === value)
7299
7538
  return input;
7300
7539
  const word = parsed.word.slice();
7301
- word[operands[0].at] = Number(value);
7540
+ word[operands.value.at] = value;
7541
+ if (operands.mirror)
7542
+ word[operands.mirror.at] = value;
7302
7543
  return parsed.doc.rewrap(word, parsed.doc.tableBytes);
7303
7544
  }
7304
7545
 
7305
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/doc-document.js
7546
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/doc-document.js
7306
7547
  var DOC_CAPABILITIES = Object.freeze({
7307
- read: Object.freeze(["paragraph-text", "character-runs", "direct-character-formatting", "paragraph-style-index", "compound-streams"]),
7308
- write: Object.freeze(["paragraph-text", "existing-direct-bold-italic"]),
7548
+ read: Object.freeze(["paragraph-text", "character-runs", "direct-character-formatting", "paragraph-style-index", "direct-paragraph-alignment", "compound-streams"]),
7549
+ write: Object.freeze(["paragraph-text", "existing-direct-bold-italic", "existing-direct-font-size", "existing-direct-underline", "existing-direct-paragraph-alignment"]),
7309
7550
  limitations: Object.freeze([
7310
7551
  "Paragraph insertion, removal and embedded paragraph breaks are unsupported.",
7311
7552
  "Character formatting reports direct CHPX exceptions, without resolving styles or piece PRMs.",
7312
7553
  "Bold/italic setters force an absolute value in an existing exclusive understood CHPX run. Run handles expire after edits.",
7554
+ "Underline setters replace an existing exclusive sprmCKul byte with none, single or double; inherited and other styles refuse.",
7555
+ "Font-size setters replace an existing exclusive sprmCHps slot with 1..1638 points in exact half-point increments.",
7313
7556
  "Fields, tables, objects and inherited styles are preserved where supported; their models are not editable.",
7314
7557
  "Unsupported edits and processing limits throw without changing the document.",
7315
7558
  "Text uses the bounded DOC codec defaults: 16,777,216 main-story characters and 65,536 pieces or field records.",
7316
- "Rich formatting is bounded to 65,536 physical/mapped runs and paragraph style records."
7559
+ "Character run inspection is bounded to 262,144 SPRM records before allocation, including shared or stale formatting runs.",
7560
+ "Rich formatting is bounded to 65,536 physical/mapped runs and paragraph style records.",
7561
+ "Logical paragraph alignment replaces a sole existing exclusive sprmPJc slot. Matching legacy mirrors support center/justify only, with both slots updated. Styles, legacy-only alignment, tables and opaque formatting refuse.",
7562
+ "Paragraph alignment inspection is bounded to 262,144 SPRM records before allocation, including shared or stale formatting runs."
7317
7563
  ])
7318
7564
  });
7319
7565
  var DocDocument = class extends Ole2DocumentBase {
@@ -7327,6 +7573,7 @@ var DocDocument = class extends Ole2DocumentBase {
7327
7573
  #text;
7328
7574
  #runsCache;
7329
7575
  #stylesCache;
7576
+ #alignmentsCache;
7330
7577
  constructor(input) {
7331
7578
  super(input);
7332
7579
  const text = readOleDocParagraphs(this.getBytes());
@@ -7343,6 +7590,16 @@ var DocDocument = class extends Ole2DocumentBase {
7343
7590
  set text(value) {
7344
7591
  owner.#setParagraphText(index, value);
7345
7592
  },
7593
+ get directAlignment() {
7594
+ try {
7595
+ return owner.#paragraphAlignments()[index];
7596
+ } catch {
7597
+ throw new UnsupportedOle2EditError("unsupported-formatting");
7598
+ }
7599
+ },
7600
+ set directAlignment(value) {
7601
+ owner.#setParagraphAlignment(index, value);
7602
+ },
7346
7603
  get runs() {
7347
7604
  return owner.#paragraphRuns(index);
7348
7605
  },
@@ -7359,6 +7616,25 @@ var DocDocument = class extends Ole2DocumentBase {
7359
7616
  get paragraphs() {
7360
7617
  return this.#paragraphs;
7361
7618
  }
7619
+ #paragraphAlignments() {
7620
+ if (this.#alignmentsCache?.revision !== this.revision)
7621
+ this.#alignmentsCache = { revision: this.revision, alignments: readDocParagraphAlignments(this.getBytes()) };
7622
+ return this.#alignmentsCache.alignments;
7623
+ }
7624
+ #setParagraphAlignment(index, value) {
7625
+ if (typeof value !== "string")
7626
+ throw new UnsupportedOle2EditError("invalid-formatting");
7627
+ let bytes;
7628
+ try {
7629
+ bytes = writeDocParagraphAlignment(this.getBytes(), index, value);
7630
+ } catch (error) {
7631
+ throw new UnsupportedOle2EditError(error instanceof Error ? error.message : "unsupported-formatting");
7632
+ }
7633
+ const text = readOleDocParagraphs(bytes), alignments = readDocParagraphAlignments(bytes);
7634
+ if (!text || text.length !== this.#text.length || text.some((t, i) => t !== this.#text[i]) || alignments[index] !== value)
7635
+ throw new UnsupportedOle2EditError("invalid-document");
7636
+ this.commitBytes(bytes);
7637
+ }
7362
7638
  #currentRuns() {
7363
7639
  if (this.#runsCache?.revision !== this.revision)
7364
7640
  this.#runsCache = { revision: this.revision, runs: readDocCharacterRuns(this.getBytes()) };
@@ -7377,15 +7653,15 @@ var DocDocument = class extends Ole2DocumentBase {
7377
7653
  try {
7378
7654
  return Object.freeze(this.#currentRuns().filter((r) => r.cpStart < end && r.cpEnd > start).map((run) => {
7379
7655
  const cpStart = Math.max(start, run.cpStart), cpEnd = Math.min(end, run.cpEnd);
7380
- let bold = run.directBold, italic = run.directItalic, sprms = run.sprms;
7656
+ let bold = run.directBold, italic = run.directItalic, size = run.directFontSizePoints, underline = run.directUnderline, sprms = run.sprms;
7381
7657
  const set = (flag, value) => {
7382
7658
  if (owner.revision !== revision)
7383
7659
  throw new UnsupportedOle2EditError("stale-run");
7384
- if (typeof value !== "boolean")
7660
+ if (flag === "underline" ? typeof value !== "string" : flag === "size" ? typeof value !== "number" : typeof value !== "boolean")
7385
7661
  throw new UnsupportedOle2EditError("invalid-formatting");
7386
7662
  let bytes;
7387
7663
  try {
7388
- bytes = writeDocCharacterRunFlag(owner.getBytes(), cpStart, cpEnd, flag, value);
7664
+ bytes = flag === "underline" ? writeDocCharacterRunUnderline(owner.getBytes(), cpStart, cpEnd, value) : flag === "size" ? writeDocCharacterRunFontSize(owner.getBytes(), cpStart, cpEnd, value) : writeDocCharacterRunFlag(owner.getBytes(), cpStart, cpEnd, flag, value);
7389
7665
  } catch (error) {
7390
7666
  throw new UnsupportedOle2EditError(error instanceof Error ? error.message : "unsupported-formatting");
7391
7667
  }
@@ -7396,15 +7672,26 @@ var DocDocument = class extends Ole2DocumentBase {
7396
7672
  owner.commitBytes(bytes);
7397
7673
  if (flag === "bold")
7398
7674
  bold = value;
7399
- else
7675
+ else if (flag === "italic")
7400
7676
  italic = value;
7401
- sprms = Object.freeze(sprms.map((p) => p.opcode === (flag === "bold" ? 2101 : 2102) ? Object.freeze({ opcode: p.opcode, operand: Object.freeze([Number(value)]) }) : p));
7677
+ else if (flag === "underline")
7678
+ underline = value;
7679
+ else
7680
+ size = value;
7681
+ const opcode = flag === "bold" ? 2101 : flag === "italic" ? 2102 : flag === "underline" ? 10814 : 19011;
7682
+ const operand = flag === "size" ? [value * 2 & 255, value * 2 >>> 8] : flag === "underline" ? [value === "none" ? 0 : value === "single" ? 1 : 3] : [Number(value)];
7683
+ sprms = Object.freeze(sprms.map((p) => p.opcode === opcode ? Object.freeze({ opcode: p.opcode, operand: Object.freeze(operand) }) : p));
7402
7684
  };
7403
7685
  return Object.freeze({
7404
7686
  cpStart,
7405
7687
  cpEnd,
7406
7688
  text: run.text.slice(cpStart - run.cpStart, cpEnd - run.cpStart),
7407
- directFontSizePoints: run.directFontSizePoints,
7689
+ get directFontSizePoints() {
7690
+ return size;
7691
+ },
7692
+ set directFontSizePoints(value) {
7693
+ set("size", value);
7694
+ },
7408
7695
  get sprms() {
7409
7696
  return sprms;
7410
7697
  },
@@ -7414,6 +7701,12 @@ var DocDocument = class extends Ole2DocumentBase {
7414
7701
  set directBold(value) {
7415
7702
  set("bold", value);
7416
7703
  },
7704
+ get directUnderline() {
7705
+ return underline;
7706
+ },
7707
+ set directUnderline(value) {
7708
+ set("underline", value);
7709
+ },
7417
7710
  get directItalic() {
7418
7711
  return italic;
7419
7712
  },
@@ -7446,7 +7739,7 @@ var DocDocument = class extends Ole2DocumentBase {
7446
7739
  }
7447
7740
  };
7448
7741
 
7449
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
7742
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
7450
7743
  function compareDirEntryNames(a, b) {
7451
7744
  const ua = a.toUpperCase();
7452
7745
  const ub = b.toUpperCase();
@@ -7513,7 +7806,7 @@ function writeInt32Sectors(outBytes, int32Data, firstSector, numSectors, sectorS
7513
7806
  }
7514
7807
  }
7515
7808
 
7516
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
7809
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
7517
7810
  function writeHeader(outView, outBytes, params) {
7518
7811
  outBytes.set(OLE_MAGIC, 0);
7519
7812
  outView.setUint16(24, 62, true);
@@ -7606,7 +7899,7 @@ function writeStreamSectors(outBytes, streamData, chain2, sectorSize) {
7606
7899
  }
7607
7900
  }
7608
7901
 
7609
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
7902
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
7610
7903
  function buildOle2(streams, rootClsid, miniStreamCutoff = 4096) {
7611
7904
  const sectorSize = 512;
7612
7905
  const miniSectorSize = 64;
@@ -7787,7 +8080,7 @@ function buildOle2(streams, rootClsid, miniStreamCutoff = 4096) {
7787
8080
  return output;
7788
8081
  }
7789
8082
 
7790
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js
8083
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js
7791
8084
  var WORKBOOK_STREAM_NAMES = ["workbook", "book"];
7792
8085
  function unwrapXlsBytes(bytes) {
7793
8086
  if (!isCfb(bytes)) {
@@ -7854,7 +8147,7 @@ function isCfb(bytes) {
7854
8147
  return OLE_MAGIC.every((value, index) => bytes[index] === value);
7855
8148
  }
7856
8149
 
7857
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-functions.js
8150
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-functions.js
7858
8151
  var TABLE = `0 COUNT -1|1 IF -1|2 ISNA 1|3 ISERROR 1|4 SUM -1|5 AVERAGE -1|6 MIN -1|7 MAX -1|8 ROW -1|9 COLUMN -1|10 NA 0|11 NPV -1|12 STDEV -1|13 DOLLAR -1|14 FIXED -1|15 SIN 1|16 COS 1|17 TAN 1|18 ATAN 1|19 PI 0|20 SQRT 1|21 EXP 1|22 LN 1|23 LOG10 1|24 ABS 1|25 INT 1|26 SIGN 1|27 ROUND 2|28 LOOKUP -1|29 INDEX -1|30 REPT 2|31 MID 3|32 LEN 1|33 VALUE 1|34 TRUE 0|35 FALSE 0|36 AND -1|37 OR -1|38 NOT 1|39 MOD 2|40 DCOUNT 3|41 DSUM 3|42 DAVERAGE 3|43 DMIN 3|44 DMAX 3|45 DSTDEV 3|46 VAR -1|47 DVAR 3|48 TEXT 2|49 LINEST -1|50 TREND -1|51 LOGEST -1|52 GROWTH -1|56 PV -1|57 FV -1|58 NPER -1|59 PMT -1|60 RATE -1|61 MIRR 3|62 IRR -1|63 RAND 0|64 MATCH -1|65 DATE 3|66 TIME 3|67 DAY 1|68 MONTH 1|69 YEAR 1|70 WEEKDAY -1|71 HOUR 1|72 MINUTE 1|73 SECOND 1|74 NOW 0|75 AREAS 1|76 ROWS 1|77 COLUMNS 1|78 OFFSET -1|82 SEARCH -1|83 TRANSPOSE 1|86 TYPE 1|97 ATAN2 2|98 ASIN 1|99 ACOS 1|100 CHOOSE -1|101 HLOOKUP -1|102 VLOOKUP -1|105 ISREF 1|109 LOG -1|111 CHAR 1|112 LOWER 1|113 UPPER 1|114 PROPER 1|115 LEFT -1|116 RIGHT -1|117 EXACT 2|118 TRIM 1|119 REPLACE 4|120 SUBSTITUTE -1|121 CODE 1|124 FIND -1|125 CELL -1|126 ISERR 1|127 ISTEXT 1|128 ISNUMBER 1|129 ISBLANK 1|130 T 1|131 N 1|140 DATEVALUE 1|141 TIMEVALUE 1|142 SLN 3|143 SYD 4|144 DDB -1|148 INDIRECT -1|150 CALL -1|162 CLEAN 1|163 MDETERM 1|164 MINVERSE 1|165 MMULT 2|167 IPMT -1|168 PPMT -1|169 COUNTA -1|183 PRODUCT -1|184 FACT 1|189 DPRODUCT 3|190 ISNONTEXT 1|193 STDEVP -1|194 VARP -1|195 DSTDEVP 3|196 DVARP 3|197 TRUNC -1|198 ISLOGICAL 1|199 DCOUNTA 3|204 USDOLLAR -1|205 FINDB -1|206 SEARCHB -1|207 REPLACEB 4|208 LEFTB -1|209 RIGHTB -1|210 MIDB 3|211 LENB 1|212 ROUNDUP 2|213 ROUNDDOWN 2|214 ASC 1|215 DBCS 1|216 RANK -1|219 ADDRESS -1|220 DAYS360 -1|221 TODAY 0|222 VDB -1|227 MEDIAN -1|228 SUMPRODUCT -1|229 SINH 1|230 COSH 1|231 TANH 1|232 ASINH 1|233 ACOSH 1|234 ATANH 1|235 DGET 3|244 INFO 1|247 DB -1|252 FREQUENCY 2|261 ERROR.TYPE 1|269 AVEDEV -1|270 BETADIST -1|271 GAMMALN 1|272 BETAINV -1|273 BINOMDIST 4|274 CHIDIST 2|275 CHIINV 2|276 COMBIN 2|277 CONFIDENCE 3|278 CRITBINOM 3|279 EVEN 1|280 EXPONDIST 3|281 FDIST 3|282 FINV 3|283 FISHER 1|284 FISHERINV 1|285 FLOOR 2|286 GAMMADIST 4|287 GAMMAINV 3|288 CEILING 2|289 HYPGEOMDIST 4|290 LOGNORMDIST 3|291 LOGINV 3|292 NEGBINOMDIST 3|293 NORMDIST 4|294 NORMSDIST 1|295 NORMINV 3|296 NORMSINV 1|297 STANDARDIZE 3|298 ODD 1|299 PERMUT 2|300 POISSON 3|301 TDIST 3|302 WEIBULL 4|303 SUMXMY2 2|304 SUMX2MY2 2|305 SUMX2PY2 2|306 CHITEST 2|307 CORREL 2|308 COVAR 2|309 FORECAST 3|310 FTEST 2|311 INTERCEPT 2|312 PEARSON 2|313 RSQ 2|314 STEYX 2|315 SLOPE 2|316 TTEST 4|317 PROB -1|318 DEVSQ -1|319 GEOMEAN -1|320 HARMEAN -1|321 SUMSQ -1|322 KURT -1|323 SKEW -1|324 ZTEST -1|325 LARGE 2|326 SMALL 2|327 QUARTILE 2|328 PERCENTILE 2|329 PERCENTRANK -1|330 MODE -1|331 TRIMMEAN 2|332 TINV 2|336 CONCATENATE -1|337 POWER 2|342 RADIANS 1|343 DEGREES 1|344 SUBTOTAL -1|345 SUMIF -1|346 COUNTIF 2|347 COUNTBLANK 1|350 ISPMT 4|351 DATEDIF 3|352 DATESTRING 1|353 NUMBERSTRING 2|354 ROMAN -1|358 GETPIVOTDATA -1|359 HYPERLINK -1|360 PHONETIC 1|361 AVERAGEA -1|362 MAXA -1|363 MINA -1|364 STDEVPA -1|365 VARPA -1|366 STDEVA -1|367 VARA -1|368 BAHTTEXT 1`;
7859
8152
  var XLS_FUNCTIONS = new Map(TABLE.split("|").map((entry) => {
7860
8153
  const [id, name, argc] = entry.split(" ");
@@ -7862,7 +8155,7 @@ var XLS_FUNCTIONS = new Map(TABLE.split("|").map((entry) => {
7862
8155
  }));
7863
8156
  var XLS_USER_FUNCTION_ID = 255;
7864
8157
 
7865
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-ptg-text.js
8158
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-ptg-text.js
7866
8159
  var BIFF_ERRORS = {
7867
8160
  0: "#NULL!",
7868
8161
  7: "#DIV/0!",
@@ -7957,7 +8250,7 @@ function readArrayConstant(extra) {
7957
8250
  return `{${lines.join(";")}}`;
7958
8251
  }
7959
8252
 
7960
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-records.js
8253
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-records.js
7961
8254
  var RT_CONTINUE = 60;
7962
8255
  function readXlsRecords(bytes, start = 0, end = bytes.length) {
7963
8256
  const records = [];
@@ -8049,8 +8342,8 @@ var SegmentReader = class _SegmentReader {
8049
8342
  constructor(segments) {
8050
8343
  this.segments = segments;
8051
8344
  }
8052
- static of(record4) {
8053
- return new _SegmentReader([record4.data, ...record4.continues]);
8345
+ static of(record5) {
8346
+ return new _SegmentReader([record5.data, ...record5.continues]);
8054
8347
  }
8055
8348
  get done() {
8056
8349
  this.normalize();
@@ -8109,21 +8402,21 @@ var SegmentReader = class _SegmentReader {
8109
8402
  return this.continuedChars(count, (flags & 1) !== 0);
8110
8403
  }
8111
8404
  };
8112
- function joinedData(record4) {
8113
- if (record4.continues.length === 0)
8114
- return record4.data;
8115
- const total = record4.continues.reduce((sum, part) => sum + part.length, record4.data.length);
8405
+ function joinedData(record5) {
8406
+ if (record5.continues.length === 0)
8407
+ return record5.data;
8408
+ const total = record5.continues.reduce((sum, part) => sum + part.length, record5.data.length);
8116
8409
  const out = new Uint8Array(total);
8117
- out.set(record4.data, 0);
8118
- let at = record4.data.length;
8119
- for (const part of record4.continues) {
8410
+ out.set(record5.data, 0);
8411
+ let at = record5.data.length;
8412
+ for (const part of record5.continues) {
8120
8413
  out.set(part, at);
8121
8414
  at += part.length;
8122
8415
  }
8123
8416
  return out;
8124
8417
  }
8125
8418
 
8126
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-ptg.js
8419
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-ptg.js
8127
8420
  function decodeFormula(rgce, extra, context, options) {
8128
8421
  try {
8129
8422
  return decode(rgce, new ByteReader(extra), context, options);
@@ -8354,9 +8647,9 @@ function readAttr(reader, stack, whitespace) {
8354
8647
  }
8355
8648
  }
8356
8649
 
8357
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sst.js
8358
- function parseSharedStrings(record4) {
8359
- const reader = SegmentReader.of(record4);
8650
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sst.js
8651
+ function parseSharedStrings(record5) {
8652
+ const reader = SegmentReader.of(record5);
8360
8653
  reader.u32();
8361
8654
  const unique = reader.u32();
8362
8655
  const strings = [];
@@ -8371,7 +8664,7 @@ function parseSharedStrings(record4) {
8371
8664
  return strings;
8372
8665
  }
8373
8666
 
8374
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-styles.js
8667
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-styles.js
8375
8668
  var DEFAULT_XLS_PALETTE = "000000 FFFFFF FF0000 00FF00 0000FF FFFF00 FF00FF 00FFFF 000000 FFFFFF FF0000 00FF00 0000FF FFFF00 FF00FF 00FFFF 800000 008000 000080 808000 800080 008080 C0C0C0 808080 9999FF 993366 FFFFCC CCFFFF 660066 FF8080 0066CC CCCCFF 000080 FF00FF FFFF00 00FFFF 800080 800000 008080 0000FF 00CCFF CCFFFF CCFFCC FFFF99 99CCFF FF99CC CC99FF FFCC99 3366FF 33CCCC 99CC00 FFCC00 FF9900 FF6600 666699 969696 003366 339966 003300 333300 993300 993366 333399 333333".split(" ");
8376
8669
  var XLS_BUILTIN_FORMATS = {
8377
8670
  0: "General",
@@ -8628,7 +8921,7 @@ function applyXfExt(data, xfs, palette) {
8628
8921
  }
8629
8922
  }
8630
8923
 
8631
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-types.js
8924
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-types.js
8632
8925
  var XlsReadError = class extends Error {
8633
8926
  code;
8634
8927
  constructor(code, message) {
@@ -8638,7 +8931,7 @@ var XlsReadError = class extends Error {
8638
8931
  }
8639
8932
  };
8640
8933
 
8641
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-globals.js
8934
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-globals.js
8642
8935
  var RT = {
8643
8936
  BOF: 2057,
8644
8937
  EOF: 10,
@@ -8737,17 +9030,17 @@ function parseGlobals(records) {
8737
9030
  const version = first.data[0] | first.data[1] << 8;
8738
9031
  if (version !== 1536)
8739
9032
  throw new XlsReadError("unsupported-version", "Only Excel 97-2003 (BIFF8) workbooks are supported; this file uses an older Excel format.");
8740
- const end = records.findIndex((record4) => record4.opcode === RT.EOF);
9033
+ const end = records.findIndex((record5) => record5.opcode === RT.EOF);
8741
9034
  const globals = end >= 0 ? records.slice(0, end) : records;
8742
- if (globals.some((record4) => record4.opcode === RT.FILEPASS))
9035
+ if (globals.some((record5) => record5.opcode === RT.FILEPASS))
8743
9036
  throw new XlsReadError("encrypted", "The workbook is password protected (encrypted).");
8744
- const paletteRecord = globals.find((record4) => record4.opcode === RT.PALETTE);
9037
+ const paletteRecord = globals.find((record5) => record5.opcode === RT.PALETTE);
8745
9038
  const palette = paletteRecord ? parsePalette(paletteRecord.data) : [...DEFAULT_XLS_PALETTE];
8746
9039
  const numberFormats = /* @__PURE__ */ new Map();
8747
- for (const record4 of globals) {
8748
- if (record4.opcode !== RT.FORMAT)
9040
+ for (const record5 of globals) {
9041
+ if (record5.opcode !== RT.FORMAT)
8749
9042
  continue;
8750
- const format = parseFormat(joinedData(record4));
9043
+ const format = parseFormat(joinedData(record5));
8751
9044
  numberFormats.set(format.id, format.code);
8752
9045
  }
8753
9046
  const formatCode = (id) => numberFormats.get(id) ?? XLS_BUILTIN_FORMATS[id] ?? "General";
@@ -8768,17 +9061,17 @@ function parseGlobals(records) {
8768
9061
  const supbooks = [];
8769
9062
  const xtis = [];
8770
9063
  const rawNames = [];
8771
- for (const record4 of globals) {
8772
- const r = new ByteReader(record4.data);
8773
- switch (record4.opcode) {
9064
+ for (const record5 of globals) {
9065
+ const r = new ByteReader(record5.data);
9066
+ switch (record5.opcode) {
8774
9067
  case RT.FONT:
8775
- out.fonts.push(parseFont(record4.data, palette));
9068
+ out.fonts.push(parseFont(record5.data, palette));
8776
9069
  break;
8777
9070
  case RT.XF:
8778
- out.xfs.push(parseXf(record4.data, palette, formatCode));
9071
+ out.xfs.push(parseXf(record5.data, palette, formatCode));
8779
9072
  break;
8780
9073
  case RT.XFEXT:
8781
- applyXfExt(record4.data, out.xfs, palette);
9074
+ applyXfExt(record5.data, out.xfs, palette);
8782
9075
  break;
8783
9076
  case RT.DATEMODE:
8784
9077
  out.date1904 = r.u16() === 1;
@@ -8801,26 +9094,26 @@ function parseGlobals(records) {
8801
9094
  break;
8802
9095
  }
8803
9096
  case RT.SST:
8804
- out.sst = parseSharedStrings(record4);
9097
+ out.sst = parseSharedStrings(record5);
8805
9098
  break;
8806
9099
  case RT.SUPBOOK:
8807
- supbooks.push(parseSupBook(joinedData(record4)));
9100
+ supbooks.push(parseSupBook(joinedData(record5)));
8808
9101
  break;
8809
9102
  case RT.EXTERNNAME: {
8810
9103
  const book = supbooks[supbooks.length - 1];
8811
- const nr = new ByteReader(joinedData(record4), 6);
9104
+ const nr = new ByteReader(joinedData(record5), 6);
8812
9105
  book?.externNames.push(nr.shortXlString());
8813
9106
  break;
8814
9107
  }
8815
9108
  case RT.EXTERNSHEET: {
8816
- const xr = new ByteReader(joinedData(record4));
9109
+ const xr = new ByteReader(joinedData(record5));
8817
9110
  const count = xr.u16();
8818
9111
  for (let i = 0; i < count; i++)
8819
9112
  xtis.push({ book: xr.u16(), first: xr.i16(), last: xr.i16() });
8820
9113
  break;
8821
9114
  }
8822
9115
  case RT.NAME:
8823
- rawNames.push(parseName(joinedData(record4)));
9116
+ rawNames.push(parseName(joinedData(record5)));
8824
9117
  break;
8825
9118
  case RT.OBPROJ:
8826
9119
  out.unsupported.push("VBA macros");
@@ -8876,7 +9169,7 @@ function parseGlobals(records) {
8876
9169
  return out;
8877
9170
  }
8878
9171
 
8879
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-edit.js
9172
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-edit.js
8880
9173
  function encodeRkExact(value) {
8881
9174
  if (!Number.isFinite(value))
8882
9175
  return void 0;
@@ -8904,19 +9197,19 @@ function worksheetRanges(bytes) {
8904
9197
  const ranges = [];
8905
9198
  let depth = 0;
8906
9199
  let start;
8907
- for (const record4 of records) {
8908
- if (record4.opcode === 2057) {
8909
- if (record4.length < 4 || view2.getUint16(record4.dataOffset, true) !== 1536 || depth >= 64)
9200
+ for (const record5 of records) {
9201
+ if (record5.opcode === 2057) {
9202
+ if (record5.length < 4 || view2.getUint16(record5.dataOffset, true) !== 1536 || depth >= 64)
8910
9203
  return void 0;
8911
- if (depth === 0 && view2.getUint16(record4.dataOffset + 2, true) === 16)
8912
- start = record4.headerOffset;
9204
+ if (depth === 0 && view2.getUint16(record5.dataOffset + 2, true) === 16)
9205
+ start = record5.headerOffset;
8913
9206
  depth++;
8914
- } else if (record4.opcode === 10) {
8915
- if (depth === 0 || record4.length !== 0)
9207
+ } else if (record5.opcode === 10) {
9208
+ if (depth === 0 || record5.length !== 0)
8916
9209
  return void 0;
8917
9210
  depth--;
8918
9211
  if (depth === 0 && start !== void 0) {
8919
- ranges.push({ start, end: record4.dataOffset });
9212
+ ranges.push({ start, end: record5.dataOffset });
8920
9213
  start = void 0;
8921
9214
  }
8922
9215
  }
@@ -8971,24 +9264,24 @@ function editXlsNumericCell(input, edit) {
8971
9264
  let packed = false;
8972
9265
  let depth = 0;
8973
9266
  let matches = 0;
8974
- for (const record4 of readRecords(bytes, range.start, range.end)) {
8975
- if (record4.opcode === 2057) {
9267
+ for (const record5 of readRecords(bytes, range.start, range.end)) {
9268
+ if (record5.opcode === 2057) {
8976
9269
  depth++;
8977
9270
  continue;
8978
9271
  }
8979
- if (record4.opcode === 10) {
9272
+ if (record5.opcode === 10) {
8980
9273
  depth--;
8981
9274
  continue;
8982
9275
  }
8983
9276
  if (depth !== 1)
8984
9277
  continue;
8985
- const p = record4.dataOffset;
8986
- if (record4.opcode === 189) {
8987
- if (record4.length < 12 || (record4.length - 6) % 6 !== 0)
9278
+ const p = record5.dataOffset;
9279
+ if (record5.opcode === 189) {
9280
+ if (record5.length < 12 || (record5.length - 6) % 6 !== 0)
8988
9281
  return unchanged("malformed-records");
8989
9282
  const first = view2.getUint16(p + 2, true);
8990
- const lastCol = view2.getUint16(p + record4.length - 2, true);
8991
- if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record4.length - 6) / 6)
9283
+ const lastCol = view2.getUint16(p + record5.length - 2, true);
9284
+ if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record5.length - 6) / 6)
8992
9285
  return unchanged("malformed-records");
8993
9286
  if (view2.getUint16(p, true) === edit.row && edit.col >= first && edit.col <= lastCol) {
8994
9287
  if (++matches > 1)
@@ -8996,26 +9289,26 @@ function editXlsNumericCell(input, edit) {
8996
9289
  payload = p + 6 + (edit.col - first) * 6;
8997
9290
  packed = true;
8998
9291
  }
8999
- } else if (record4.opcode === 515 || record4.opcode === 638) {
9000
- if (record4.length !== (record4.opcode === 515 ? 14 : 10))
9292
+ } else if (record5.opcode === 515 || record5.opcode === 638) {
9293
+ if (record5.length !== (record5.opcode === 515 ? 14 : 10))
9001
9294
  return unchanged("malformed-records");
9002
9295
  if (view2.getUint16(p, true) === edit.row && view2.getUint16(p + 2, true) === edit.col) {
9003
9296
  if (++matches > 1)
9004
9297
  return unchanged("ambiguous-cell");
9005
9298
  payload = p + 6;
9006
- packed = record4.opcode === 638;
9299
+ packed = record5.opcode === 638;
9007
9300
  }
9008
- } else if ([6, 513, 516, 517, 253, 214].includes(record4.opcode)) {
9009
- if (record4.length < 6)
9301
+ } else if ([6, 513, 516, 517, 253, 214].includes(record5.opcode)) {
9302
+ if (record5.length < 6)
9010
9303
  return unchanged("malformed-records");
9011
9304
  if (view2.getUint16(p, true) === edit.row && view2.getUint16(p + 2, true) === edit.col && ++matches > 1)
9012
9305
  return unchanged("ambiguous-cell");
9013
- } else if (record4.opcode === 190) {
9014
- if (record4.length < 8 || (record4.length - 6) % 2 !== 0)
9306
+ } else if (record5.opcode === 190) {
9307
+ if (record5.length < 8 || (record5.length - 6) % 2 !== 0)
9015
9308
  return unchanged("malformed-records");
9016
9309
  const first = view2.getUint16(p + 2, true);
9017
- const lastCol = view2.getUint16(p + record4.length - 2, true);
9018
- if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record4.length - 6) / 2)
9310
+ const lastCol = view2.getUint16(p + record5.length - 2, true);
9311
+ if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record5.length - 6) / 2)
9019
9312
  return unchanged("malformed-records");
9020
9313
  if (view2.getUint16(p, true) === edit.row && edit.col >= first && edit.col <= lastCol && ++matches > 1)
9021
9314
  return unchanged("ambiguous-cell");
@@ -9041,7 +9334,7 @@ function editXlsNumericCell(input, edit) {
9041
9334
  }
9042
9335
  }
9043
9336
 
9044
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js
9337
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js
9045
9338
  var OPCODE_BOF = 2057;
9046
9339
  var OPCODE_EOF = 10;
9047
9340
  var OPCODE_FILEPASS = 47;
@@ -9069,8 +9362,8 @@ function isSupportedBiff8Workbook(bytes) {
9069
9362
  const view2 = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
9070
9363
  if (view2.getUint16(bof.dataOffset, true) !== 1536 || view2.getUint16(bof.dataOffset + 2, true) !== 5)
9071
9364
  return false;
9072
- const globalsEnd = records.find((record4) => record4.opcode === OPCODE_EOF)?.headerOffset ?? bytes.length;
9073
- return !records.some((record4) => record4.opcode === OPCODE_FILEPASS && record4.headerOffset < globalsEnd);
9365
+ const globalsEnd = records.find((record5) => record5.opcode === OPCODE_EOF)?.headerOffset ?? bytes.length;
9366
+ return !records.some((record5) => record5.opcode === OPCODE_FILEPASS && record5.headerOffset < globalsEnd);
9074
9367
  }
9075
9368
  function decodeRk(rk) {
9076
9369
  const isInt = (rk & 2) !== 0;
@@ -9088,7 +9381,7 @@ function decodeRk(rk) {
9088
9381
  return isDiv100 ? value / 100 : value;
9089
9382
  }
9090
9383
 
9091
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-formulas.js
9384
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-formulas.js
9092
9385
  function readRefU(r) {
9093
9386
  return { firstRow: r.u16(), lastRow: r.u16(), firstCol: r.u8(), lastCol: r.u8() };
9094
9387
  }
@@ -9146,7 +9439,7 @@ function resolveFormulas(formulas, shared, arrays, globals) {
9146
9439
  }
9147
9440
  }
9148
9441
 
9149
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sheet-extras.js
9442
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sheet-extras.js
9150
9443
  function parseMergedCells(data) {
9151
9444
  const r = new ByteReader(data);
9152
9445
  const count = r.u16();
@@ -9324,11 +9617,11 @@ function parseObj(data) {
9324
9617
  r.skip(2);
9325
9618
  return { type: r.u16(), id: r.u16() };
9326
9619
  }
9327
- function parseTxoText(record4) {
9328
- const count = new ByteReader(record4.data, 10).u16();
9329
- if (count === 0 || record4.continues.length === 0)
9620
+ function parseTxoText(record5) {
9621
+ const count = new ByteReader(record5.data, 10).u16();
9622
+ if (count === 0 || record5.continues.length === 0)
9330
9623
  return "";
9331
- const reader = new SegmentReader(record4.continues);
9624
+ const reader = new SegmentReader(record5.continues);
9332
9625
  const wide = (reader.u8() & 1) !== 0;
9333
9626
  return reader.continuedChars(count, wide).replace(/\r\n?/g, "\n");
9334
9627
  }
@@ -9341,7 +9634,7 @@ function parseNote(data) {
9341
9634
  return { row, col, visible: (flags & 2) !== 0, id, author: r.xlString() };
9342
9635
  }
9343
9636
 
9344
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sheet.js
9637
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook-sheet.js
9345
9638
  var UNSUPPORTED = {
9346
9639
  432: "conditional formatting",
9347
9640
  2169: "conditional formatting",
@@ -9391,8 +9684,8 @@ function parseSheet(bound2, records, start, globals) {
9391
9684
  return result;
9392
9685
  };
9393
9686
  for (let index = start; index < records.length; index++) {
9394
- const record4 = records[index];
9395
- const { opcode, data } = record4;
9687
+ const record5 = records[index];
9688
+ const { opcode, data } = record5;
9396
9689
  if (opcode === 2057) {
9397
9690
  depth++;
9398
9691
  if (depth > 1)
@@ -9444,7 +9737,7 @@ function parseSheet(bound2, records, start, globals) {
9444
9737
  case 516:
9445
9738
  case 214: {
9446
9739
  const target = cell(r, "");
9447
- const reader = SegmentReader.of({ ...record4, data: data.subarray(6) });
9740
+ const reader = SegmentReader.of({ ...record5, data: data.subarray(6) });
9448
9741
  target.value = reader.xlString();
9449
9742
  break;
9450
9743
  }
@@ -9468,7 +9761,7 @@ function parseSheet(bound2, records, start, globals) {
9468
9761
  }
9469
9762
  case 519:
9470
9763
  if (stringTarget)
9471
- stringTarget.value = SegmentReader.of(record4).xlString();
9764
+ stringTarget.value = SegmentReader.of(record5).xlString();
9472
9765
  stringTarget = void 0;
9473
9766
  break;
9474
9767
  case 1212: {
@@ -9548,7 +9841,7 @@ function parseSheet(bound2, records, start, globals) {
9548
9841
  }
9549
9842
  case 438:
9550
9843
  if (lastObject?.type === 25)
9551
- texts.set(lastObject.id, parseTxoText(record4));
9844
+ texts.set(lastObject.id, parseTxoText(record5));
9552
9845
  break;
9553
9846
  case 28:
9554
9847
  notes.push(parseNote(data));
@@ -9597,7 +9890,7 @@ function parseSheet(bound2, records, start, globals) {
9597
9890
  return sheet;
9598
9891
  }
9599
9892
 
9600
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook.js
9893
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-workbook.js
9601
9894
  function compoundStreamNames(bytes) {
9602
9895
  if (!OLE_MAGIC.every((value, index) => bytes[index] === value))
9603
9896
  return [];
@@ -9611,12 +9904,12 @@ function compoundStreamNames(bytes) {
9611
9904
  function topLevelSubstreams(records) {
9612
9905
  const starts = [];
9613
9906
  let depth = 0;
9614
- records.forEach((record4, index) => {
9615
- if (record4.opcode === 2057) {
9907
+ records.forEach((record5, index) => {
9908
+ if (record5.opcode === 2057) {
9616
9909
  if (depth === 0 && index > 0)
9617
9910
  starts.push(index);
9618
9911
  depth++;
9619
- } else if (record4.opcode === 10)
9912
+ } else if (record5.opcode === 10)
9620
9913
  depth = Math.max(0, depth - 1);
9621
9914
  });
9622
9915
  return starts;
@@ -9639,7 +9932,7 @@ function readXlsWorkbook(bytes) {
9639
9932
  unsupported2.push("VBA macros");
9640
9933
  if (streams.some((name) => name === "_SX_DB_CUR") && !unsupported2.includes("pivot caches"))
9641
9934
  unsupported2.push("pivot caches");
9642
- const byOffset = new Map(records.map((record4, index) => [record4.offset, index]));
9935
+ const byOffset = new Map(records.map((record5, index) => [record5.offset, index]));
9643
9936
  const substreams = topLevelSubstreams(records);
9644
9937
  const sheets = globals.sheets.map((bound2, position) => {
9645
9938
  const start = byOffset.get(bound2.offset) ?? substreams[position];
@@ -9667,7 +9960,7 @@ function readXlsWorkbook(bytes) {
9667
9960
  };
9668
9961
  }
9669
9962
 
9670
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-sst.js
9963
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-sst.js
9671
9964
  var SstCursor = class {
9672
9965
  segments;
9673
9966
  segment = 0;
@@ -9790,7 +10083,7 @@ function appendXlsSstString(value) {
9790
10083
  return Uint8Array.from(records);
9791
10084
  }
9792
10085
 
9793
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-cell-record-splices.js
10086
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-cell-record-splices.js
9794
10087
  var CELL_OPS = /* @__PURE__ */ new Set([6, 513, 515, 516, 517, 638, 253, 189, 190, 214]);
9795
10088
  function record2(opcode, data) {
9796
10089
  const out = new Uint8Array(data.length + 4), view2 = new DataView(out.buffer);
@@ -9882,7 +10175,7 @@ function relocateXlsDbCells(input, out, records, replacement, map) {
9882
10175
  }
9883
10176
  }
9884
10177
 
9885
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-known-records.js
10178
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-known-records.js
9886
10179
  var KNOWN_XLS_RECORDS = /* @__PURE__ */ new Set([
9887
10180
  6,
9888
10181
  10,
@@ -10240,7 +10533,7 @@ var KNOWN_XLS_RECORDS = /* @__PURE__ */ new Set([
10240
10533
  ]);
10241
10534
  var XLS_FRT_WRAPPER = 2129;
10242
10535
 
10243
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-record-edit-model.js
10536
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-record-edit-model.js
10244
10537
  var EditError = class extends Error {
10245
10538
  reason;
10246
10539
  constructor(reason) {
@@ -10341,6 +10634,8 @@ function findTarget(bytes, m, edit, allowed = [253, 638, 515, 189]) {
10341
10634
  const first = view2.getUint16(p + 2, true), last = view2.getUint16(p + r.length - 2, true);
10342
10635
  if (last > 255 || last < first || last - first + 1 !== (r.length - 6) / stride)
10343
10636
  reject("malformed-records");
10637
+ if (r.opcode === 190 && (first > 254 || last <= first))
10638
+ reject("malformed-records");
10344
10639
  if (view2.getUint16(p, true) === edit.row && edit.col >= first && edit.col <= last)
10345
10640
  targets.push(r);
10346
10641
  }
@@ -10350,19 +10645,19 @@ function findTarget(bytes, m, edit, allowed = [253, 638, 515, 189]) {
10350
10645
  const target = targets[0];
10351
10646
  if (!target || !allowed.includes(target.opcode))
10352
10647
  reject("cell-not-supported");
10353
- if (target.opcode !== 189 && target.length !== (target.opcode === 515 ? 14 : target.opcode === 517 ? 8 : 10))
10648
+ if (target.opcode !== 189 && target.opcode !== 190 && target.length !== (target.opcode === 515 ? 14 : target.opcode === 517 ? 8 : target.opcode === 513 ? 6 : 10))
10354
10649
  reject("malformed-records");
10355
- for (const record4 of m.records.filter((r) => r.headerOffset >= range.start && r.headerOffset < range.end && r.depth === 1 && [545, 1212, 566].includes(r.opcode))) {
10356
- if (record4.length < 6)
10650
+ for (const record5 of m.records.filter((r) => r.headerOffset >= range.start && r.headerOffset < range.end && r.depth === 1 && [545, 1212, 566].includes(r.opcode))) {
10651
+ if (record5.length < 6)
10357
10652
  reject("malformed-records");
10358
- const p = record4.dataOffset;
10653
+ const p = record5.dataOffset;
10359
10654
  if (edit.row >= view2.getUint16(p, true) && edit.row <= view2.getUint16(p + 2, true) && edit.col >= view2.getUint8(p + 4) && edit.col <= view2.getUint8(p + 5))
10360
10655
  reject("cell-not-supported");
10361
10656
  }
10362
10657
  return target;
10363
10658
  }
10364
10659
 
10365
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-string-edit.js
10660
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-string-edit.js
10366
10661
  function extSst(entries, map) {
10367
10662
  const interval = Math.max(Math.floor(entries.length / 128) + 1, 8);
10368
10663
  const count = Math.ceil(entries.length / interval);
@@ -10474,18 +10769,18 @@ function editXlsStringWorkbookStream(input, edit) {
10474
10769
  view2.setUint32(map(sst.start) + 8, sst.entries.length + (index === sst.entries.length ? 1 : 0), true);
10475
10770
  if (splices.length) {
10476
10771
  const byOffset = new Map(m.records.map((r) => [r.headerOffset, r]));
10477
- for (const record4 of m.records) {
10478
- if (record4.opcode === 133 && (record4.headerOffset >= m.globalsEnd || record4.depth !== 1))
10772
+ for (const record5 of m.records) {
10773
+ if (record5.opcode === 133 && (record5.headerOffset >= m.globalsEnd || record5.depth !== 1))
10479
10774
  reject("malformed-records");
10480
- if (record4.opcode === 133)
10481
- view2.setUint32(map(record4.dataOffset), map(sourceView.getUint32(record4.dataOffset, true)), true);
10482
- if (record4.opcode === 523) {
10483
- if (record4.length < 16 || (record4.length - 16) % 4 !== 0)
10775
+ if (record5.opcode === 133)
10776
+ view2.setUint32(map(record5.dataOffset), map(sourceView.getUint32(record5.dataOffset, true)), true);
10777
+ if (record5.opcode === 523) {
10778
+ if (record5.length < 16 || (record5.length - 16) % 4 !== 0)
10484
10779
  reject("malformed-records");
10485
- for (let p = record4.dataOffset + 12; p < record4.dataOffset + record4.length; p += 4) {
10780
+ for (let p = record5.dataOffset + 12; p < record5.dataOffset + record5.length; p += 4) {
10486
10781
  const address = sourceView.getUint32(p, true);
10487
10782
  const pointed = byOffset.get(address);
10488
- if (!pointed || pointed.opcode !== (p === record4.dataOffset + 12 ? 85 : 215))
10783
+ if (!pointed || pointed.opcode !== (p === record5.dataOffset + 12 ? 85 : 215))
10489
10784
  reject("malformed-records");
10490
10785
  view2.setUint32(map(p), map(address), true);
10491
10786
  }
@@ -10498,7 +10793,7 @@ function editXlsStringWorkbookStream(input, edit) {
10498
10793
  }
10499
10794
  }
10500
10795
 
10501
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-string-cell.js
10796
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-preserved-string-cell.js
10502
10797
  function editXlsPreservedStringCell(input, edit) {
10503
10798
  if (!OLE_MAGIC.every((value, index) => input[index] === value))
10504
10799
  return editXlsStringWorkbookStream(input, edit);
@@ -10517,7 +10812,7 @@ function editXlsPreservedStringCell(input, edit) {
10517
10812
  return resized.ok ? { ...result, bytes: resized.bytes } : { status: "unchanged", bytes: input, reason: "container-not-writable" };
10518
10813
  }
10519
10814
 
10520
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-bool-error-edit.js
10815
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-bool-error-edit.js
10521
10816
  var ERRORS = Object.freeze({
10522
10817
  "#NULL!": 0,
10523
10818
  "#DIV/0!": 7,
@@ -10528,6 +10823,9 @@ var ERRORS = Object.freeze({
10528
10823
  "#N/A": 42,
10529
10824
  "#GETTING_DATA": 43
10530
10825
  });
10826
+ function isValidXlsBoolErrorRecordValue(flag, value) {
10827
+ return flag === 0 && (value === 0 || value === 1) || flag === 1 && Object.values(ERRORS).includes(value);
10828
+ }
10531
10829
  function normalizeXlsErrorValue(value) {
10532
10830
  try {
10533
10831
  if (!value || typeof value !== "object" || Array.isArray(value))
@@ -10555,7 +10853,7 @@ function editXlsBoolErrorWorkbookStream(input, edit) {
10555
10853
  const source = new DataView(input.buffer, input.byteOffset, input.byteLength);
10556
10854
  if (target.opcode === 517) {
10557
10855
  const flag = source.getUint8(target.dataOffset + 7), value2 = source.getUint8(target.dataOffset + 6);
10558
- if (flag > 1 || (flag === 0 ? value2 > 1 : !Object.values(ERRORS).includes(value2)))
10856
+ if (!isValidXlsBoolErrorRecordValue(flag, value2))
10559
10857
  reject("malformed-records");
10560
10858
  }
10561
10859
  const data = new Uint8Array(12), view2 = new DataView(data.buffer);
@@ -10632,7 +10930,175 @@ function editXlsBoolErrorCell(input, edit) {
10632
10930
  return resized.ok ? { ...result, bytes: resized.bytes } : { status: "unchanged", bytes: input, reason: "container-not-writable" };
10633
10931
  }
10634
10932
 
10635
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/xls-document.js
10933
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-blank-record.js
10934
+ function record3(opcode, data) {
10935
+ const out = new Uint8Array(4 + data.length), view2 = new DataView(out.buffer);
10936
+ view2.setUint16(0, opcode, true);
10937
+ view2.setUint16(2, data.length, true);
10938
+ out.set(data, 4);
10939
+ return out;
10940
+ }
10941
+ function replaceXlsBlankRecord(input, target, col, value) {
10942
+ if (!Number.isInteger(col) || col < 0 || col > 255 || !Number.isFinite(value) || !Number.isSafeInteger(target.headerOffset) || target.headerOffset < 0 || target.dataOffset !== target.headerOffset + 4 || !Number.isInteger(target.length) || target.length < 6 || target.dataOffset + target.length > input.length || ![513, 190].includes(target.opcode))
10943
+ throw new Error("Invalid blank record replacement");
10944
+ const view2 = new DataView(input.buffer, input.byteOffset, input.byteLength), p = target.dataOffset;
10945
+ if (view2.getUint16(target.headerOffset, true) !== target.opcode || view2.getUint16(target.headerOffset + 2, true) !== target.length)
10946
+ throw new Error("Blank record framing mismatch");
10947
+ const packed = target.opcode === 190;
10948
+ if (packed ? target.length < 10 || (target.length - 6) % 2 !== 0 : target.length !== 6)
10949
+ throw new Error("Invalid blank record length");
10950
+ const row = view2.getUint16(p, true), first = view2.getUint16(p + 2, true), count = packed ? (target.length - 6) / 2 : 1;
10951
+ const selected = col - first;
10952
+ if (first > 255 || first + count - 1 > 255 || selected < 0 || selected >= count || packed && view2.getUint16(p + target.length - 2, true) !== first + count - 1)
10953
+ throw new Error("Invalid blank column range");
10954
+ const data = new Uint8Array(14), cell = new DataView(data.buffer);
10955
+ cell.setUint16(0, row, true);
10956
+ cell.setUint16(2, col, true);
10957
+ cell.setUint16(4, view2.getUint16(p + 4 + (packed ? selected * 2 : 0), true), true);
10958
+ cell.setFloat64(6, value, true);
10959
+ const number2 = record3(515, data);
10960
+ const group = (start, size) => {
10961
+ if (!size)
10962
+ return new Uint8Array();
10963
+ const data2 = new Uint8Array(size === 1 ? 6 : 6 + size * 2), groupView = new DataView(data2.buffer);
10964
+ groupView.setUint16(0, row, true);
10965
+ groupView.setUint16(2, first + start, true);
10966
+ data2.set(input.subarray(p + 4 + start * 2, p + 4 + (start + size) * 2), 4);
10967
+ if (size > 1)
10968
+ groupView.setUint16(data2.length - 2, first + start + size - 1, true);
10969
+ return record3(size === 1 ? 513 : 190, data2);
10970
+ };
10971
+ const prefix = packed ? group(0, selected) : new Uint8Array(), suffix = packed ? group(selected + 1, count - selected - 1) : new Uint8Array();
10972
+ const bytes = new Uint8Array(prefix.length + number2.length + suffix.length);
10973
+ bytes.set(prefix);
10974
+ bytes.set(number2, prefix.length);
10975
+ bytes.set(suffix, prefix.length + number2.length);
10976
+ return { start: target.headerOffset, end: p + target.length, bytes };
10977
+ }
10978
+
10979
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-stored-cell-edit.js
10980
+ function applyXlsCellRecordReplacement(input, m, replacement) {
10981
+ if (!Number.isSafeInteger(replacement.start) || !Number.isSafeInteger(replacement.end) || replacement.start < 0 || replacement.end <= replacement.start || replacement.end > input.length || !(replacement.bytes instanceof Uint8Array))
10982
+ reject("malformed-records");
10983
+ const target = m.records.find((r) => r.headerOffset === replacement.start);
10984
+ if (!target || target.dataOffset + target.length !== replacement.end || ![513, 190, 517].includes(target.opcode))
10985
+ reject("malformed-records");
10986
+ const delta = replacement.bytes.length - (replacement.end - replacement.start);
10987
+ if (delta !== 0 && m.records.some((r) => !KNOWN_XLS_RECORDS.has(r.opcode) || r.opcode === XLS_FRT_WRAPPER))
10988
+ reject("unsupported-pointer-record");
10989
+ const map = (address) => {
10990
+ if (!Number.isSafeInteger(address) || address < 0 || address > input.length || address > replacement.start && address < replacement.end)
10991
+ reject("malformed-records");
10992
+ return address >= replacement.end ? address + delta : address;
10993
+ };
10994
+ const out = new Uint8Array(input.length + delta);
10995
+ out.set(input.subarray(0, replacement.start));
10996
+ out.set(replacement.bytes, replacement.start);
10997
+ out.set(input.subarray(replacement.end), replacement.start + replacement.bytes.length);
10998
+ if (delta !== 0) {
10999
+ relocateXlsDbCells(input, out, m.records, replacement, map);
11000
+ const source = new DataView(input.buffer, input.byteOffset, input.byteLength), dest = new DataView(out.buffer), byOffset = new Map(m.records.map((r) => [r.headerOffset, r]));
11001
+ for (const r of m.records) {
11002
+ if (r.opcode === 133) {
11003
+ if (r.headerOffset >= m.globalsEnd || r.depth !== 1)
11004
+ reject("malformed-records");
11005
+ dest.setUint32(map(r.dataOffset), map(source.getUint32(r.dataOffset, true)), true);
11006
+ }
11007
+ if (r.opcode === 523) {
11008
+ if (r.length < 16 || (r.length - 16) % 4 !== 0)
11009
+ reject("malformed-records");
11010
+ const owner = m.worksheets.find((sheet) => r.depth === 1 && r.headerOffset >= sheet.start && r.headerOffset < sheet.end);
11011
+ if (!owner)
11012
+ reject("malformed-records");
11013
+ const pointers = /* @__PURE__ */ new Set();
11014
+ for (let p = r.dataOffset + 12; p < r.dataOffset + r.length; p += 4) {
11015
+ const address = source.getUint32(p, true);
11016
+ const pointed = byOffset.get(address);
11017
+ if (pointed?.opcode !== (p === r.dataOffset + 12 ? 85 : 215) || pointed.depth !== 1 || address < owner.start || address >= owner.end)
11018
+ reject("malformed-records");
11019
+ if (pointers.has(address))
11020
+ reject("malformed-records");
11021
+ pointers.add(address);
11022
+ dest.setUint32(map(p), map(address), true);
11023
+ }
11024
+ }
11025
+ }
11026
+ }
11027
+ return out;
11028
+ }
11029
+ function editXlsStoredCellWorkbookStream(input, edit, sourceKind) {
11030
+ const unchanged = (reason) => ({ status: "unchanged", bytes: input, reason });
11031
+ const row = edit.row, col = edit.col, worksheetIndex = edit.worksheetIndex ?? 0, supplied = edit.value;
11032
+ const value = supplied !== null && typeof supplied === "object" ? normalizeXlsErrorValue(supplied) : supplied;
11033
+ if (!["blank", "bool-error"].includes(sourceKind) || !Number.isInteger(row) || row < 0 || row > 65535 || !Number.isInteger(col) || col < 0 || col > 255 || !Number.isInteger(worksheetIndex) || worksheetIndex < 0 || sourceKind === "bool-error" && typeof value !== "number" && typeof value !== "string" || (typeof value === "number" ? !Number.isFinite(value) : typeof value !== "string" && typeof value !== "boolean" && (value === void 0 || value === null || typeof value !== "object")))
11034
+ return unchanged("invalid-edit");
11035
+ try {
11036
+ const m = model(input), target = findTarget(input, m, { row, col, worksheetIndex }, sourceKind === "blank" ? [513, 190] : [517]);
11037
+ const range = m.worksheets[worksheetIndex], source = new DataView(input.buffer, input.byteOffset, input.byteLength);
11038
+ for (const record5 of m.records.filter((r) => r.opcode === 229 && r.depth === 1 && r.headerOffset >= range.start && r.headerOffset < range.end)) {
11039
+ if (record5.length < 2)
11040
+ reject("malformed-records");
11041
+ const count = source.getUint16(record5.dataOffset, true);
11042
+ if (record5.length !== 2 + count * 8)
11043
+ reject("malformed-records");
11044
+ for (let p = record5.dataOffset + 2; p < record5.dataOffset + record5.length; p += 8) {
11045
+ const firstRow = source.getUint16(p, true), lastRow = source.getUint16(p + 2, true), firstCol = source.getUint16(p + 4, true), lastCol = source.getUint16(p + 6, true);
11046
+ if (firstRow > lastRow || firstCol > lastCol || lastCol > 255)
11047
+ reject("malformed-records");
11048
+ if (row >= firstRow && row <= lastRow && col >= firstCol && col <= lastCol && (row !== firstRow || col !== firstCol))
11049
+ reject("cell-not-supported");
11050
+ }
11051
+ }
11052
+ let replacement;
11053
+ if (sourceKind === "blank")
11054
+ replacement = replaceXlsBlankRecord(input, target, col, typeof value === "number" ? value : 0);
11055
+ else {
11056
+ if (!isValidXlsBoolErrorRecordValue(source.getUint8(target.dataOffset + 7), source.getUint8(target.dataOffset + 6)))
11057
+ reject("malformed-records");
11058
+ const bytes = new Uint8Array(18), number2 = new DataView(bytes.buffer);
11059
+ number2.setUint16(0, 515, true);
11060
+ number2.setUint16(2, 14, true);
11061
+ bytes.set(input.subarray(target.dataOffset, target.dataOffset + 6), 4);
11062
+ number2.setFloat64(10, typeof value === "number" ? value : 0, true);
11063
+ replacement = { start: target.headerOffset, end: target.dataOffset + target.length, bytes };
11064
+ }
11065
+ const staged = applyXlsCellRecordReplacement(input, m, replacement);
11066
+ if (typeof value === "number")
11067
+ return { status: "edited", bytes: staged, recalculationRequired: true };
11068
+ const result = typeof value === "string" ? editXlsStringWorkbookStream(staged, { row, col, worksheetIndex, value }) : editXlsBoolErrorWorkbookStream(staged, { row, col, worksheetIndex, value });
11069
+ return result.status === "edited" ? result : { ...result, bytes: input };
11070
+ } catch (error) {
11071
+ return unchanged(error instanceof EditError ? error.reason : "malformed-records");
11072
+ }
11073
+ }
11074
+ function editXlsStoredCell(input, edit, sourceKind) {
11075
+ if (!OLE_MAGIC.every((value, index) => input[index] === value))
11076
+ return editXlsStoredCellWorkbookStream(input, edit, sourceKind);
11077
+ const streams = ["Workbook", "Book"].map((name) => ({ name, bytes: readCompoundFileStream(input, [name]) })).filter((s) => s.bytes !== void 0);
11078
+ if (streams.length !== 1)
11079
+ return { status: "unchanged", bytes: input, reason: "unsupported-workbook" };
11080
+ const stream = streams[0], result = editXlsStoredCellWorkbookStream(stream.bytes, edit, sourceKind);
11081
+ if (result.status !== "edited")
11082
+ return { ...result, bytes: input };
11083
+ if (result.bytes.length === stream.bytes.length) {
11084
+ const bytes = replaceCompoundFileStream(input, [stream.name], result.bytes);
11085
+ return bytes === input ? { status: "unchanged", bytes: input, reason: "container-not-writable" } : { ...result, bytes };
11086
+ }
11087
+ const resized = resizeCompoundFileStream(input, [stream.name], result.bytes);
11088
+ return resized.ok ? { ...result, bytes: resized.bytes } : { status: "unchanged", bytes: input, reason: "container-not-writable" };
11089
+ }
11090
+
11091
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-blank-edit.js
11092
+ function editXlsBlankCell(input, edit) {
11093
+ return editXlsStoredCell(input, edit, "blank");
11094
+ }
11095
+
11096
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-excel-bool-error-conversion.js
11097
+ function editXlsBoolErrorScalarCell(input, edit) {
11098
+ return editXlsStoredCell(input, edit, "bool-error");
11099
+ }
11100
+
11101
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/xls-document.js
10636
11102
  function cellType(cell) {
10637
11103
  if (cell.formula !== void 0 || cell.formulaUndecoded || cell.arrayRange || cell.sharedFormula)
10638
11104
  return "formula";
@@ -10732,8 +11198,8 @@ var XlsSheetNode = class {
10732
11198
  };
10733
11199
  var XLS_CAPABILITIES = Object.freeze({
10734
11200
  read: Object.freeze(["BIFF8 worksheets", "cell values and cached formulas", "styles and merges", "opaque compound streams"]),
10735
- write: Object.freeze(["existing NUMBER/RK/MULRK numeric values", "existing LABELSST/NUMBER/RK/MULRK plain string values", "existing NUMBER/RK/MULRK/BOOLERR boolean and error values"]),
10736
- limitations: Object.freeze(["No cell creation, formula editing or recalculation", "Numeric writes require exact original encoding", "Resizing writes reject unsupported relocation records and container layouts", "Plain string replacement removes selected rich text runs", "String-to-boolean/error and boolean/error-to-number/string conversions unsupported"])
11201
+ write: Object.freeze(["existing NUMBER/RK/MULRK numeric values", "existing LABELSST/NUMBER/RK/MULRK plain string values", "existing NUMBER/RK/MULRK/BOOLERR boolean and error values", "existing BLANK/MULBLANK cells to number, plain string, boolean or error values", "existing BOOLERR cells to finite number or plain string values"]),
11202
+ limitations: Object.freeze(["No implicit cell creation, formula editing or recalculation", "Numeric replacement of existing numeric cells requires exact original encoding", "Resizing writes reject unsupported relocation records and container layouts", "Plain string replacement removes selected rich text runs", "String-to-boolean/error conversions unsupported"])
10737
11203
  });
10738
11204
  var XlsDocument = class extends Ole2DocumentBase {
10739
11205
  get kind() {
@@ -10748,6 +11214,7 @@ var XlsDocument = class extends Ole2DocumentBase {
10748
11214
  }
10749
11215
  #model;
10750
11216
  #needsRecalculation = false;
11217
+ #settingCellValue = false;
10751
11218
  constructor(input) {
10752
11219
  super(input);
10753
11220
  const bytes = this.getBytes();
@@ -10778,6 +11245,16 @@ var XlsDocument = class extends Ole2DocumentBase {
10778
11245
  }
10779
11246
  /** @internal All changes are validated and parsed before committing bytes. */
10780
11247
  setCellValue(sheetIndex, row, col, value) {
11248
+ if (this.#settingCellValue)
11249
+ throw new UnsupportedOle2EditError("reentrant-cell-edit");
11250
+ this.#settingCellValue = true;
11251
+ try {
11252
+ this.#applyCellValue(sheetIndex, row, col, value);
11253
+ } finally {
11254
+ this.#settingCellValue = false;
11255
+ }
11256
+ }
11257
+ #applyCellValue(sheetIndex, row, col, value) {
10781
11258
  if (value !== null && typeof value === "object") {
10782
11259
  const normalized = normalizeXlsErrorValue(value);
10783
11260
  if (!normalized)
@@ -10790,13 +11267,14 @@ var XlsDocument = class extends Ole2DocumentBase {
10790
11267
  const sheet = this.#model.sheets[sheetIndex];
10791
11268
  if (sheet?.kind !== "worksheet")
10792
11269
  throw new UnsupportedOle2EditError("sheet-not-supported");
10793
- if (cell.value === null)
10794
- throw new UnsupportedOle2EditError("cell-type-not-supported");
11270
+ if (cell.value === null && value === null)
11271
+ return;
10795
11272
  if (typeof value !== "number" && typeof value !== "string" && typeof value !== "boolean" && !isXlsErrorValue(value))
10796
11273
  throw new UnsupportedOle2EditError("value-type-not-supported");
10797
- if (typeof value === "number" && (typeof cell.value !== "number" || !Number.isFinite(value)))
11274
+ const boolError = typeof cell.value === "boolean" || isXlsErrorValue(cell.value);
11275
+ if (typeof value === "number" && (cell.value !== null && typeof cell.value !== "number" && !boolError || !Number.isFinite(value)))
10798
11276
  throw new UnsupportedOle2EditError("numeric-type-change-not-supported");
10799
- if (typeof value === "string" && typeof cell.value !== "number" && typeof cell.value !== "string")
11277
+ if (typeof value === "string" && cell.value !== null && typeof cell.value !== "number" && typeof cell.value !== "string" && !boolError)
10800
11278
  throw new UnsupportedOle2EditError("string-type-change-not-supported");
10801
11279
  if ((typeof value === "boolean" || isXlsErrorValue(value)) && typeof cell.value === "string")
10802
11280
  throw new UnsupportedOle2EditError("bool-error-type-change-not-supported");
@@ -10804,7 +11282,7 @@ var XlsDocument = class extends Ole2DocumentBase {
10804
11282
  return;
10805
11283
  const worksheetIndex = this.#model.sheets.slice(0, sheetIndex).filter((s) => s.kind === "worksheet").length;
10806
11284
  const edit = { row, col, value, worksheetIndex };
10807
- const result = typeof value === "number" ? editXlsNumericCell(this.getBytes(), { ...edit, value }) : typeof value === "string" ? editXlsPreservedStringCell(this.getBytes(), { ...edit, value }) : editXlsBoolErrorCell(this.getBytes(), { ...edit, value });
11285
+ const result = cell.value === null ? editXlsBlankCell(this.getBytes(), { ...edit, value }) : boolError && (typeof value === "number" || typeof value === "string") ? editXlsBoolErrorScalarCell(this.getBytes(), { ...edit, value }) : typeof value === "number" ? editXlsNumericCell(this.getBytes(), { ...edit, value }) : typeof value === "string" ? editXlsPreservedStringCell(this.getBytes(), { ...edit, value }) : editXlsBoolErrorCell(this.getBytes(), { ...edit, value });
10808
11286
  if (result.status !== "edited")
10809
11287
  throw new UnsupportedOle2EditError(result.reason);
10810
11288
  const next = readXlsWorkbook(result.bytes);
@@ -10817,7 +11295,7 @@ var XlsDocument = class extends Ole2DocumentBase {
10817
11295
  }
10818
11296
  };
10819
11297
 
10820
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js
11298
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js
10821
11299
  var PptParseError = class extends Error {
10822
11300
  constructor(message) {
10823
11301
  super(message);
@@ -10851,18 +11329,88 @@ function readRecordOrThrow(view2, offset) {
10851
11329
  return rec;
10852
11330
  }
10853
11331
 
10854
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js
11332
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js
10855
11333
  var RT2 = {
10856
11334
  Document: 1e3,
11335
+ DocumentAtom: 1001,
11336
+ EndDocumentAtom: 1002,
10857
11337
  Slide: 1006,
11338
+ SlideAtom: 1007,
11339
+ Notes: 1008,
11340
+ NotesAtom: 1009,
11341
+ Environment: 1010,
10858
11342
  SlidePersistAtom: 1011,
11343
+ MainMaster: 1016,
11344
+ SlideShowSlideInfoAtom: 1017,
11345
+ SlideViewInfo: 1018,
11346
+ ExternalObjectList: 1033,
11347
+ ExternalObjectListAtom: 1034,
11348
+ DrawingGroup: 1035,
11349
+ Drawing: 1036,
11350
+ List: 2e3,
11351
+ FontCollection: 2005,
11352
+ SoundCollection: 2020,
11353
+ SoundCollectionAtom: 2021,
11354
+ Sound: 2022,
11355
+ SoundDataBlob: 2023,
11356
+ ColorSchemeAtom: 2032,
11357
+ ExternalObjectRefAtom: 3009,
11358
+ OEPlaceholderAtom: 3011,
11359
+ RoundTripSlideSyncInfo12: 3012,
10859
11360
  OutlineTextRefAtom: 3998,
11361
+ TextHeaderAtom: 3999,
10860
11362
  TextCharsAtom: 4e3,
11363
+ StyleTextPropAtom: 4001,
11364
+ MasterTextPropAtom: 4002,
11365
+ TextMasterStyleAtom: 4003,
10861
11366
  TextBytesAtom: 4008,
11367
+ TextSpecInfoAtom: 4010,
11368
+ CString: 4026,
11369
+ ExternalOleObjectAtom: 4035,
11370
+ ExternalOleEmbed: 4044,
11371
+ ExternalOleEmbedAtom: 4045,
11372
+ ExternalHyperlinkAtom: 4051,
11373
+ ExternalHyperlink: 4055,
11374
+ ExternalOleObjectStg: 4113,
11375
+ /** [MS-PPT] 2.10.6: information about external audio/video data (exObjId + loop/rewind/narration flags). */
11376
+ ExternalMediaAtom: 4100,
11377
+ /** [MS-PPT] 2.10.5: wraps an ExMediaAtom + optional UncOrLocalPathAtom for a linked video file. */
11378
+ ExternalVideo: 4101,
11379
+ /** [MS-PPT] 2.10.4: wraps an ExVideoContainer for a linked AVI movie. */
11380
+ ExternalAviMovie: 4102,
11381
+ /** [MS-PPT] 2.10.3: wraps an ExVideoContainer for a linked (generic/MCI-played) movie; what real
11382
+ * PowerPoint 16.0 writes for a linked non-AVI video file (COM-verified). */
11383
+ ExternalMciMovie: 4103,
11384
+ /** [MS-PPT] 2.10.8: wraps an ExMediaAtom + ExWAVAudioEmbeddedAtom referencing a SoundCollection entry. */
11385
+ ExternalWavAudioEmbedded: 4111,
11386
+ /** [MS-PPT] 2.10.9: soundIdRef (into SoundCollectionContainer) + soundLength (ms). recVer/recInstance = 0x1/0x001. */
11387
+ ExternalWavAudioEmbeddedAtom: 4115,
11388
+ TextInteractiveInfoAtom: 4063,
10862
11389
  SlideListWithText: 4080,
11390
+ InteractiveInfo: 4082,
11391
+ InteractiveInfoAtom: 4083,
10863
11392
  UserEditAtom: 4085,
10864
11393
  CurrentUserAtom: 4086,
10865
- PersistDirectoryAtom: 6002};
11394
+ FontEntityAtom: 4023,
11395
+ CryptSession10Container: 12052,
11396
+ PersistDirectoryAtom: 6002,
11397
+ HeadersFooters: 4057,
11398
+ HeadersFootersAtom: 4058,
11399
+ ProgTags: 5e3,
11400
+ ProgBinaryTag: 5002,
11401
+ BinaryTagDataBlob: 5003,
11402
+ RoundTripCustomTableStyles12Atom: 17036,
11403
+ /** [MS-PPT] 2.11.21: a master's theme as a zipped OOXML package. */
11404
+ RoundTripTheme12Atom: 1038,
11405
+ /** [MS-PPT] 2.11.19: a master's `a:clrMap` as an XML string. */
11406
+ RoundTripColorMapping12Atom: 1039,
11407
+ /** [MS-PPT] 2.11.22: a master's `p:txStyles` as a zipped OOXML package. */
11408
+ RoundTripOArtTextStyles12Atom: 1059,
11409
+ /** [MS-PPT] 2.9.28: a date field (`*`) in a master date placeholder. */
11410
+ GenericDateMCAtom: 4088,
11411
+ /** [MS-PPT] 2.9.25: a slide-number field (`*`) in a placeholder. */
11412
+ SlideNumberMCAtom: 4056
11413
+ };
10866
11414
  var OA = {
10867
11415
  SpgrContainer: 61443,
10868
11416
  SpContainer: 61444,
@@ -10876,7 +11424,7 @@ var OA = {
10876
11424
  var HEADER_TOKEN_PLAIN = 3817979999;
10877
11425
  var HEADER_TOKEN_ENCRYPTED = 4090610911;
10878
11426
 
10879
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js
11427
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js
10880
11428
  var DEFAULT_MAX_EDITS = 1e4;
10881
11429
  var DEFAULT_MAX_ENTRIES = 1e6;
10882
11430
  function checkedLimit(value) {
@@ -10993,7 +11541,7 @@ function buildPersistDirectory(view2, offsetToCurrentEdit, limits = {}) {
10993
11541
  return { currentEdit: edits[0], directory };
10994
11542
  }
10995
11543
 
10996
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-text.js
11544
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-text.js
10997
11545
  var PptTextError = class extends PptParseError {
10998
11546
  code;
10999
11547
  constructor(code, message) {
@@ -11068,7 +11616,7 @@ function inlineText(view2, parent) {
11068
11616
  }
11069
11617
  return { texts: result.sort((a, b) => a.headerOffset - b.headerOffset), mirrors };
11070
11618
  }
11071
- function inspect3(input) {
11619
+ function inspect4(input) {
11072
11620
  const current = readCompoundFileStream(input, ["Current User"]);
11073
11621
  const stream = readCompoundFileStream(input, ["PowerPoint Document"]);
11074
11622
  if (!current || !stream)
@@ -11146,19 +11694,69 @@ function inspect3(input) {
11146
11694
  }
11147
11695
  function readPptSlideTexts(input) {
11148
11696
  try {
11149
- return inspect3(input).model;
11697
+ return inspect4(input).model;
11150
11698
  } catch (error) {
11151
11699
  if (error instanceof PptTextError)
11152
11700
  throw error;
11153
11701
  throw new PptTextError("corrupt", error instanceof Error ? error.message : "Malformed PPT");
11154
11702
  }
11155
11703
  }
11704
+ function textOwnershipRefusal(input, stream, persistId, atom) {
11705
+ const user = readCompoundFileStream(input, ["Current User"]);
11706
+ if (!user)
11707
+ throw new PptParseError("Missing Current User stream");
11708
+ const view2 = viewOf(stream), uv = viewOf(user), cu = readRecordOrThrow(uv, 0);
11709
+ const editOffset = uv.getUint32(cu.dataOffset + 8, true);
11710
+ const { directory, currentEdit } = buildPersistDirectory(view2, editOffset);
11711
+ const slideOffset = directory.get(persistId);
11712
+ if (slideOffset === void 0)
11713
+ return "Missing active slide persist object";
11714
+ const slide = readRecordOrThrow(view2, slideOffset), text = readRecordOrThrow(view2, atom.headerOffset);
11715
+ const textEnd = text.dataOffset + text.recLen;
11716
+ const owners = [persistId];
11717
+ if (atom.headerOffset < slide.dataOffset || textEnd > slide.dataOffset + slide.recLen) {
11718
+ const docOffset = directory.get(currentEdit.docPersistIdRef);
11719
+ if (docOffset === void 0)
11720
+ return "Missing outline text owner";
11721
+ const doc = readRecordOrThrow(view2, docOffset);
11722
+ if (atom.headerOffset < doc.dataOffset || textEnd > doc.dataOffset + doc.recLen)
11723
+ return "Text is outside its active owning containers";
11724
+ owners.push(currentEdit.docPersistIdRef);
11725
+ }
11726
+ for (const ownerId of owners) {
11727
+ const owned = readRecordOrThrow(view2, directory.get(ownerId));
11728
+ const start = owned.headerOffset, end = owned.dataOffset + owned.recLen;
11729
+ if (end > view2.byteLength)
11730
+ return "Unbounded text owning persist object";
11731
+ const overlaps = (offset) => {
11732
+ const other = readRecordOrThrow(view2, offset), otherEnd = other.dataOffset + other.recLen;
11733
+ if (otherEnd > view2.byteLength)
11734
+ throw new PptParseError("Unbounded live persist object prevents safe text edit");
11735
+ return start < otherEnd && other.headerOffset < end;
11736
+ };
11737
+ for (const [id, offset] of directory)
11738
+ if (id !== ownerId && overlaps(offset))
11739
+ return "Text owning container overlaps another live persist object";
11740
+ const visited = /* @__PURE__ */ new Set();
11741
+ for (let offset = editOffset; offset; ) {
11742
+ if (visited.has(offset) || visited.size >= 1e4)
11743
+ return "Invalid text save-history ownership";
11744
+ visited.add(offset);
11745
+ const edit = parseUserEditAtom(view2, offset);
11746
+ if (overlaps(offset) || overlaps(edit.offsetPersistDirectory))
11747
+ return "Text owning container overlaps save-history metadata";
11748
+ offset = edit.offsetLastEdit;
11749
+ }
11750
+ }
11751
+ return void 0;
11752
+ }
11156
11753
  function editPptSlideText(input, edit) {
11157
11754
  const reject2 = (reason) => ({ status: "unsupported", bytes: input, reason });
11158
11755
  try {
11756
+ edit = { slideIndex: edit.slideIndex, textIndex: edit.textIndex, expectedText: edit.expectedText, text: edit.text };
11159
11757
  if (!Number.isSafeInteger(edit.slideIndex) || !Number.isSafeInteger(edit.textIndex) || edit.slideIndex < 0 || edit.textIndex < 0)
11160
11758
  return reject2("Invalid text location");
11161
- const { stream, model: model2, mirroredAtoms } = inspect3(input);
11759
+ const { stream, model: model2, mirroredAtoms } = inspect4(input);
11162
11760
  const atom = model2.slides[edit.slideIndex]?.texts[edit.textIndex];
11163
11761
  if (!atom || atom.text !== edit.expectedText)
11164
11762
  return reject2("Text location or expected text does not match");
@@ -11181,6 +11779,9 @@ function editPptSlideText(input, edit) {
11181
11779
  if (value >= 56320 && value <= 57343 && !(edit.text.charCodeAt(i - 1) >= 55296 && edit.text.charCodeAt(i - 1) <= 56319))
11182
11780
  return reject2("Unpaired UTF-16 surrogate");
11183
11781
  }
11782
+ const ownership = textOwnershipRefusal(input, stream, model2.slides[edit.slideIndex].persistId, atom);
11783
+ if (ownership)
11784
+ return reject2(ownership);
11184
11785
  const output = stream.slice(), view2 = viewOf(output), start = atom.headerOffset + 8;
11185
11786
  for (let i = 0; i < edit.text.length; i++) {
11186
11787
  if (atom.encoding === "utf16")
@@ -11195,7 +11796,7 @@ function editPptSlideText(input, edit) {
11195
11796
  }
11196
11797
  }
11197
11798
 
11198
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-shape-reader.js
11799
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-shape-reader.js
11199
11800
  var DEFAULT_LIMITS = { maxRecords: 1e5, maxShapes: 1e4, maxProperties: 1e5, maxNameChars: 1e6, maxTextBytes: 16 * 1024 * 1024 };
11200
11801
  var GEOMETRY_PROPERTY_IDS = /* @__PURE__ */ new Set([4, 127, 128, 191, 385, 447, 448, 459, 511, 896, 959]);
11201
11802
  function pptShapeChildren(view2, parent) {
@@ -11235,13 +11836,13 @@ function readPptSlideShapes(input, limits = {}) {
11235
11836
  if (documentOffset === void 0)
11236
11837
  throw new PptTextError("corrupt", "Missing active document");
11237
11838
  const documentRecord = readRecordOrThrow(view2, documentOffset);
11238
- const slideOffsets = [], activeLists = pptShapeChildren(view2, documentRecord).filter((record4) => record4.recType === RT2.SlideListWithText && record4.recInstance === 0);
11839
+ const slideOffsets = [], activeLists = pptShapeChildren(view2, documentRecord).filter((record5) => record5.recType === RT2.SlideListWithText && record5.recInstance === 0);
11239
11840
  for (const list of activeLists)
11240
- for (const record4 of pptShapeChildren(view2, list))
11241
- if (record4.recType === RT2.SlidePersistAtom) {
11242
- if (record4.recLen !== 20)
11841
+ for (const record5 of pptShapeChildren(view2, list))
11842
+ if (record5.recType === RT2.SlidePersistAtom) {
11843
+ if (record5.recLen !== 20)
11243
11844
  throw new PptTextError("corrupt", "Invalid slide persist atom");
11244
- const offset = chain2.directory.get(view2.getUint32(record4.dataOffset, true));
11845
+ const offset = chain2.directory.get(view2.getUint32(record5.dataOffset, true));
11245
11846
  if (offset === void 0)
11246
11847
  throw new PptTextError("corrupt", "Missing active slide");
11247
11848
  slideOffsets.push(offset);
@@ -11286,9 +11887,9 @@ function readPptSlideShapes(input, limits = {}) {
11286
11887
  const item = stack.pop();
11287
11888
  if (item.depth > 128)
11288
11889
  throw new PptTextError("corrupt", "Shape nesting exceeds limit");
11289
- const children3 = pptShapeChildren(view2, item.rec);
11890
+ const children4 = pptShapeChildren(view2, item.rec);
11290
11891
  if (item.rec.recType === OA.SpContainer) {
11291
- const fsps = children3.filter((rec) => rec.recType === OA.FSP);
11892
+ const fsps = children4.filter((rec) => rec.recType === OA.FSP);
11292
11893
  if (fsps.length !== 1 || fsps[0].recVer !== 2 || fsps[0].recLen !== 8)
11293
11894
  throw new PptTextError("corrupt", "Missing or ambiguous OfficeArtFSP");
11294
11895
  const fsp = fsps[0], shapeId = view2.getUint32(fsp.dataOffset, true), flags = view2.getUint32(fsp.dataOffset + 4, true);
@@ -11313,7 +11914,7 @@ function readPptSlideShapes(input, limits = {}) {
11313
11914
  };
11314
11915
  let propertyAmbiguity = false, unknownProperties = false, protectedGeometry = false, unknownTextFit = false;
11315
11916
  const seenProperties = /* @__PURE__ */ new Set();
11316
- const anchors = children3.filter((rec) => rec.recType === OA.ClientAnchor || rec.recType === OA.ChildAnchor);
11917
+ const anchors = children4.filter((rec) => rec.recType === OA.ClientAnchor || rec.recType === OA.ChildAnchor);
11317
11918
  if (anchors.length === 1) {
11318
11919
  const rec = anchors[0];
11319
11920
  if (rec.recVer !== 0 || rec.recInstance !== 0 || (rec.recType === OA.ClientAnchor ? rec.recLen !== 8 && rec.recLen !== 16 : rec.recLen !== 16))
@@ -11327,13 +11928,13 @@ function readPptSlideShapes(input, limits = {}) {
11327
11928
  };
11328
11929
  shape.coordinateSpace = largeClient ? "unknown" : rec.recType === OA.ChildAnchor ? "group-child-master-units" : item.group !== void 0 || flags & 2 ? "unknown" : "slide-master-units";
11329
11930
  }
11330
- const group = children3.find((rec) => rec.recType === OA.FSPGR);
11931
+ const group = children4.find((rec) => rec.recType === OA.FSPGR);
11331
11932
  if (group) {
11332
11933
  if (group.recVer !== 1 || group.recLen !== 16)
11333
11934
  throw new PptTextError("corrupt", "Invalid group coordinate space");
11334
11935
  shape.groupBounds = bounds(view2, group);
11335
11936
  }
11336
- for (const rec of children3.filter((rec2) => rec2.recType === OA.FOPT || rec2.recType === OA.TertiaryFOPT || rec2.recType === 61729)) {
11937
+ for (const rec of children4.filter((rec2) => rec2.recType === OA.FOPT || rec2.recType === OA.TertiaryFOPT || rec2.recType === 61729)) {
11337
11938
  if (rec.recVer !== 3 || rec.recInstance * 6 > rec.recLen)
11338
11939
  throw new PptTextError("corrupt", "Invalid shape property table");
11339
11940
  let complexOffset = rec.dataOffset + rec.recInstance * 6;
@@ -11371,7 +11972,7 @@ function readPptSlideShapes(input, limits = {}) {
11371
11972
  shape.textIndexes = slide.texts.flatMap((atom, index) => atom.headerOffset >= item.rec.dataOffset && atom.headerOffset < shape.recordEnd ? [index] : []);
11372
11973
  if (shape.textIndexes.length)
11373
11974
  shape.textReference = "inline";
11374
- for (const textbox of children3.filter((rec) => rec.recType === OA.ClientTextbox))
11975
+ for (const textbox of children4.filter((rec) => rec.recType === OA.ClientTextbox))
11375
11976
  if (pptShapeChildren(view2, textbox).some((rec) => rec.recType === RT2.OutlineTextRefAtom))
11376
11977
  shape.textReference = "unresolved";
11377
11978
  if (shape.mirrored)
@@ -11395,7 +11996,7 @@ function readPptSlideShapes(input, limits = {}) {
11395
11996
  }
11396
11997
  let parentGroup = item.group;
11397
11998
  if (item.rec.recType === OA.SpgrContainer) {
11398
- const head = children3[0];
11999
+ const head = children4[0];
11399
12000
  if (!head || head.recType !== OA.SpContainer)
11400
12001
  throw new PptTextError("corrupt", "Group has no shape container");
11401
12002
  const fsp = pptShapeChildren(view2, head).find((rec) => rec.recType === OA.FSP);
@@ -11404,8 +12005,8 @@ function readPptSlideShapes(input, limits = {}) {
11404
12005
  if (!(view2.getUint32(fsp.dataOffset + 4, true) & 4))
11405
12006
  parentGroup = view2.getUint32(fsp.dataOffset, true);
11406
12007
  }
11407
- for (let i = children3.length - 1; i >= 0; i--) {
11408
- const rec = children3[i];
12008
+ for (let i = children4.length - 1; i >= 0; i--) {
12009
+ const rec = children4[i];
11409
12010
  if (rec.recVer === 15 || rec.recType === OA.ClientTextbox)
11410
12011
  stack.push({ rec, depth: item.depth + 1, group: item.rec.recType === OA.SpgrContainer && i === 0 ? item.group : parentGroup });
11411
12012
  }
@@ -11414,10 +12015,44 @@ function readPptSlideShapes(input, limits = {}) {
11414
12015
  });
11415
12016
  }
11416
12017
 
11417
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-shape-edit.js
12018
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-shape-edit.js
11418
12019
  function equalPptShapeBounds(a, b) {
11419
12020
  return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
11420
12021
  }
12022
+ function slideOwnershipRefusal(input, stream, persistId) {
12023
+ const user = readCompoundFileStream(input, ["Current User"]);
12024
+ if (!user)
12025
+ throw new PptParseError("Missing Current User stream");
12026
+ const view2 = new DataView(stream.buffer, stream.byteOffset, stream.byteLength), uv = new DataView(user.buffer, user.byteOffset, user.byteLength);
12027
+ const cu = readRecordOrThrow(uv, 0), editOffset = uv.getUint32(cu.dataOffset + 8, true);
12028
+ const { directory } = buildPersistDirectory(view2, editOffset), ownedOffset = directory.get(persistId);
12029
+ if (ownedOffset === void 0)
12030
+ return "Missing active slide persist object";
12031
+ const owned = readRecordOrThrow(view2, ownedOffset), start = owned.headerOffset, end = owned.dataOffset + owned.recLen;
12032
+ if (end > view2.byteLength)
12033
+ return "Unbounded slide persist object";
12034
+ const overlaps = (offset) => {
12035
+ const other = readRecordOrThrow(view2, offset), otherEnd = other.dataOffset + other.recLen;
12036
+ if (otherEnd > view2.byteLength)
12037
+ throw new PptParseError("Unbounded live persist object prevents safe geometry edit");
12038
+ return start < otherEnd && other.headerOffset < end;
12039
+ };
12040
+ for (const [id, offset] of directory) {
12041
+ if (id !== persistId && overlaps(offset))
12042
+ return "Slide container overlaps another live persist object";
12043
+ }
12044
+ const visited = /* @__PURE__ */ new Set();
12045
+ for (let offset = editOffset; offset; ) {
12046
+ if (visited.has(offset) || visited.size >= 1e4)
12047
+ return "Invalid geometry save-history ownership";
12048
+ visited.add(offset);
12049
+ const edit = parseUserEditAtom(view2, offset);
12050
+ if (overlaps(offset) || overlaps(edit.offsetPersistDirectory))
12051
+ return "Slide container overlaps save-history metadata";
12052
+ offset = edit.offsetLastEdit;
12053
+ }
12054
+ return void 0;
12055
+ }
11421
12056
  function editPptShapeBounds(input, edit) {
11422
12057
  const reject2 = (reason) => ({ status: "unsupported", bytes: input, reason });
11423
12058
  try {
@@ -11450,7 +12085,11 @@ function editPptShapeBounds(input, edit) {
11450
12085
  const edges = [next.y, next.x, next.x + next.width, next.y + next.height];
11451
12086
  if (!edges.every((value) => Number.isSafeInteger(value) && value >= -32768 && value <= 32767))
11452
12087
  return reject2("Geometry exceeds the existing small anchor encoding");
11453
- const stream = readCompoundFileStream(input, ["PowerPoint Document"]), out = stream.slice(), view2 = new DataView(out.buffer);
12088
+ const stream = readCompoundFileStream(input, ["PowerPoint Document"]);
12089
+ const ownership = slideOwnershipRefusal(input, stream, persistId);
12090
+ if (ownership)
12091
+ return reject2(ownership);
12092
+ const out = stream.slice(), view2 = new DataView(out.buffer);
11454
12093
  for (let i = 0; i < edges.length; i++)
11455
12094
  view2.setInt16(anchor + 8 + i * 2, edges[i], true);
11456
12095
  const bytes = replaceCompoundFileStream(input, ["PowerPoint Document"], out);
@@ -11465,12 +12104,604 @@ function editPptShapeBounds(input, edit) {
11465
12104
  }
11466
12105
  }
11467
12106
 
11468
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt-document.js
12107
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-notes.js
12108
+ var viewOf2 = (bytes) => new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
12109
+ function fail2(message) {
12110
+ throw new PptTextError("corrupt", message);
12111
+ }
12112
+ function inspect5(input, limits = {}) {
12113
+ const maxRecords = limits.maxRecords ?? 1e5, maxNotes = limits.maxNotes ?? 1e4, maxTextBytes = limits.maxTextBytes ?? 16 * 1024 * 1024;
12114
+ for (const value of [maxRecords, maxNotes, maxTextBytes])
12115
+ if (!Number.isSafeInteger(value) || value < 1)
12116
+ fail2("Invalid notes resource limit");
12117
+ const stream = readCompoundFileStream(input, ["PowerPoint Document"]), user = readCompoundFileStream(input, ["Current User"]);
12118
+ if (!stream || !user)
12119
+ fail2("Missing PowerPoint streams");
12120
+ const view2 = viewOf2(stream), uv = viewOf2(user);
12121
+ const record5 = (offset, type) => {
12122
+ const r = readRecordOrThrow(view2, offset);
12123
+ if (r.dataOffset + r.recLen > view2.byteLength || type !== void 0 && r.recType !== type)
12124
+ fail2("Invalid notes record bounds/type");
12125
+ return r;
12126
+ };
12127
+ const cu = readRecordOrThrow(uv, 0);
12128
+ if (cu.recType !== RT2.CurrentUserAtom || cu.recVer !== 0 || cu.recInstance !== 0 || cu.recLen < 24 || cu.dataOffset + cu.recLen > uv.byteLength)
12129
+ fail2("Invalid CurrentUserAtom");
12130
+ const token = uv.getUint32(cu.dataOffset + 4, true);
12131
+ if (token === HEADER_TOKEN_ENCRYPTED)
12132
+ throw new PptTextError("encrypted", "Encrypted PPT notes are unsupported");
12133
+ if (token !== HEADER_TOKEN_PLAIN)
12134
+ fail2("Unknown encryption token");
12135
+ const { currentEdit, directory } = buildPersistDirectory(view2, uv.getUint32(cu.dataOffset + 8, true), { maxEntries: maxRecords });
12136
+ if (currentEdit.encryptSessionPersistIdRef !== void 0)
12137
+ throw new PptTextError("encrypted", "Encrypted notes persist objects are unsupported");
12138
+ let recordCount = 0, textBytes = 0;
12139
+ const children4 = (r) => {
12140
+ const result = [], end = r.dataOffset + r.recLen;
12141
+ for (let pos = r.dataOffset; pos < end; ) {
12142
+ if (++recordCount > maxRecords)
12143
+ fail2("Notes record budget exceeded");
12144
+ if (end - pos < 8)
12145
+ fail2("Truncated notes child header");
12146
+ const child2 = record5(pos);
12147
+ if (child2.dataOffset + child2.recLen > end)
12148
+ fail2("Notes child exceeds parent");
12149
+ result.push(child2);
12150
+ pos = child2.dataOffset + child2.recLen;
12151
+ }
12152
+ return result;
12153
+ };
12154
+ const docOffset = directory.get(currentEdit.docPersistIdRef);
12155
+ if (docOffset === void 0)
12156
+ fail2("Missing active document");
12157
+ const doc = record5(docOffset, RT2.Document);
12158
+ if (doc.recVer !== 15)
12159
+ fail2("Invalid document container");
12160
+ const docChildren = children4(doc), refs = /* @__PURE__ */ new Map(), persistIds = /* @__PURE__ */ new Set();
12161
+ const notesLists = docChildren.filter((r) => r.recType === RT2.SlideListWithText && r.recInstance === 2);
12162
+ if (notesLists.length > 1)
12163
+ fail2("Ambiguous notes list");
12164
+ for (const list of notesLists) {
12165
+ if (list.recVer !== 15)
12166
+ fail2("Invalid notes list");
12167
+ for (const r of children4(list)) {
12168
+ if (r.recType !== RT2.SlidePersistAtom || r.recVer !== 0 || r.recInstance !== 0 || r.recLen !== 20)
12169
+ fail2("Invalid NotesPersistAtom");
12170
+ const persistId = view2.getUint32(r.dataOffset, true), notesId = view2.getUint32(r.dataOffset + 12, true);
12171
+ if (!notesId || !persistId || refs.has(notesId) || persistIds.has(persistId))
12172
+ fail2("Duplicate or null notes identity");
12173
+ if (refs.size >= maxNotes)
12174
+ fail2("Notes count budget exceeded");
12175
+ refs.set(notesId, persistId);
12176
+ persistIds.add(persistId);
12177
+ }
12178
+ }
12179
+ const slides = readPptSlideShapes(input, { maxRecords, maxTextBytes, maxShapes: maxRecords });
12180
+ if (slides.length > maxNotes)
12181
+ fail2("Active slide budget exceeded");
12182
+ const links = /* @__PURE__ */ new Map(), linkedNotes = /* @__PURE__ */ new Set();
12183
+ for (const slide of slides) {
12184
+ const offset = directory.get(slide.persistId);
12185
+ if (offset === void 0)
12186
+ fail2("Missing active slide");
12187
+ const sr = record5(offset, RT2.Slide), slideAtoms = children4(sr).filter((r) => r.recType === RT2.SlideAtom);
12188
+ if (slideAtoms.length !== 1 || slideAtoms[0].recVer !== 2 || slideAtoms[0].recInstance !== 0 || slideAtoms[0].recLen !== 24)
12189
+ fail2("Invalid SlideAtom notes linkage");
12190
+ const notesId = view2.getUint32(slideAtoms[0].dataOffset + 16, true);
12191
+ if (notesId && linkedNotes.has(notesId))
12192
+ fail2("Notes linked by multiple active slides");
12193
+ if (notesId)
12194
+ linkedNotes.add(notesId);
12195
+ links.set(slide.slideId, notesId);
12196
+ }
12197
+ const activeNotes = new Set(links.values());
12198
+ const raw = /* @__PURE__ */ new Map();
12199
+ for (const [notesId, persistId] of refs) {
12200
+ if (!activeNotes.has(notesId))
12201
+ continue;
12202
+ const offset = directory.get(persistId);
12203
+ if (offset === void 0)
12204
+ fail2("Missing notes persist object");
12205
+ const header = record5(offset, RT2.Notes);
12206
+ if (header.recVer !== 15 || header.recInstance !== 0)
12207
+ fail2("Invalid NotesContainer");
12208
+ const direct = children4(header), atoms = direct.filter((r) => r.recType === RT2.NotesAtom);
12209
+ if (atoms.length !== 1 || atoms[0].recVer !== 1 || atoms[0].recInstance !== 0 || atoms[0].recLen !== 8)
12210
+ fail2("Invalid NotesAtom");
12211
+ const records = [...direct], stack = direct.filter((r) => r.recVer === 15 || r.recType === OA.ClientTextbox).map((r) => ({ r, depth: 1 }));
12212
+ while (stack.length) {
12213
+ const item = stack.pop();
12214
+ if (item.depth > 128)
12215
+ fail2("Notes nesting budget exceeded");
12216
+ for (const r of children4(item.r)) {
12217
+ records.push(r);
12218
+ if (r.recType === RT2.TextCharsAtom || r.recType === RT2.TextBytesAtom) {
12219
+ textBytes += r.recLen;
12220
+ if (textBytes > maxTextBytes)
12221
+ fail2("Notes text byte budget exceeded");
12222
+ if (r.recVer !== 0 || r.recInstance !== 0 || r.recType === RT2.TextCharsAtom && r.recLen % 2)
12223
+ fail2("Invalid notes text atom");
12224
+ }
12225
+ if (r.recVer === 15 || r.recType === OA.ClientTextbox)
12226
+ stack.push({ r, depth: item.depth + 1 });
12227
+ }
12228
+ }
12229
+ raw.set(notesId, { header, backref: view2.getUint32(atoms[0].dataOffset, true), records });
12230
+ }
12231
+ const notes = [];
12232
+ for (const slide of slides) {
12233
+ const notesId = links.get(slide.slideId);
12234
+ if (!notesId)
12235
+ continue;
12236
+ const info = raw.get(notesId), persistId = refs.get(notesId);
12237
+ if (!info || persistId === void 0 || info.backref !== slide.slideId)
12238
+ fail2("Notes ID or slide back-reference mismatch");
12239
+ const all = info.records;
12240
+ let notesMirror = false;
12241
+ for (const r of all.filter((r2) => [OA.FOPT, OA.TertiaryFOPT, 61729].includes(r2.recType))) {
12242
+ if (r.recVer !== 3 || r.recInstance * 6 > r.recLen)
12243
+ fail2("Invalid notes property table");
12244
+ for (let i = 0; i < r.recInstance; i++)
12245
+ if ((view2.getUint16(r.dataOffset + i * 6, true) & 16383) === 937)
12246
+ notesMirror = true;
12247
+ }
12248
+ const texts = [], shapeIds = /* @__PURE__ */ new Set();
12249
+ const shapeRecords = [];
12250
+ let activeShape;
12251
+ for (const r of all.sort((a, b) => a.headerOffset - b.headerOffset)) {
12252
+ if (activeShape && r.headerOffset >= activeShape.shape.dataOffset + activeShape.shape.recLen)
12253
+ activeShape = void 0;
12254
+ if (r.recType === OA.SpContainer) {
12255
+ if (activeShape)
12256
+ fail2("Nested notes shape containers");
12257
+ activeShape = { shape: r, within: [] };
12258
+ shapeRecords.push(activeShape);
12259
+ } else if (activeShape)
12260
+ activeShape.within.push(r);
12261
+ }
12262
+ for (const { shape, within } of shapeRecords) {
12263
+ const fsps = within.filter((r) => r.recType === OA.FSP);
12264
+ if (fsps.length !== 1 || fsps[0].recVer !== 2 || fsps[0].recLen !== 8)
12265
+ fail2("Invalid notes shape identity");
12266
+ const shapeId = view2.getUint32(fsps[0].dataOffset, true);
12267
+ if (!shapeId || shapeIds.has(shapeId))
12268
+ fail2("Duplicate notes shape identity");
12269
+ shapeIds.add(shapeId);
12270
+ const placeholders = within.filter((r) => r.recType === RT2.OEPlaceholderAtom);
12271
+ if (placeholders.some((r) => r.recVer !== 0 || r.recInstance !== 0 || r.recLen !== 8))
12272
+ fail2("Invalid notes PlaceholderAtom");
12273
+ const placeholderId = placeholders.length === 1 ? view2.getUint8(placeholders[0].dataOffset + 4) : void 0;
12274
+ const atoms = within.filter((r) => r.recType === RT2.TextCharsAtom || r.recType === RT2.TextBytesAtom);
12275
+ const headers = within.filter((r) => r.recType === RT2.TextHeaderAtom);
12276
+ const textboxes = within.filter((r) => r.recType === OA.ClientTextbox);
12277
+ const body = placeholderId === 12 && headers.length === 1 && headers[0].recVer === 0 && headers[0].recInstance === 0 && headers[0].recLen === 4 && view2.getUint32(headers[0].dataOffset, true) === 2;
12278
+ for (const atom of atoms) {
12279
+ const wide = atom.recType === RT2.TextCharsAtom;
12280
+ let text = "";
12281
+ for (let p = atom.dataOffset; p < atom.dataOffset + atom.recLen; p += wide ? 2 : 1) {
12282
+ const value = wide ? view2.getUint16(p, true) : view2.getUint8(p);
12283
+ if (!value)
12284
+ fail2("NUL in notes text atom");
12285
+ text += String.fromCharCode(value);
12286
+ }
12287
+ texts.push({
12288
+ shapeId,
12289
+ shapeHeaderOffset: shape.headerOffset,
12290
+ placeholderId,
12291
+ role: body ? "body" : "other",
12292
+ text,
12293
+ headerOffset: atom.headerOffset,
12294
+ encoding: wide ? "utf16" : "compressed-unicode",
12295
+ editRefusal: notesMirror ? "Notes have an OOXML mirror" : !body ? "Not a validated notes body placeholder" : atoms.length !== 1 || placeholders.length !== 1 || textboxes.length !== 1 || headers[0].headerOffset < textboxes[0].dataOffset || headers[0].headerOffset > atom.headerOffset || atom.dataOffset + atom.recLen > textboxes[0].dataOffset + textboxes[0].recLen ? "Ambiguous notes text slot" : void 0
12296
+ });
12297
+ }
12298
+ }
12299
+ notes.push({ slideId: slide.slideId, slidePersistId: slide.persistId, notesId, persistId, headerOffset: info.header.headerOffset, texts });
12300
+ }
12301
+ return { stream, notes };
12302
+ }
12303
+ function readPptSlideNotes(input, limits = {}) {
12304
+ return inspect5(input, limits).notes;
12305
+ }
12306
+ function ownershipRefusal(input, stream, note) {
12307
+ const view2 = viewOf2(stream), user = readCompoundFileStream(input, ["Current User"]);
12308
+ const uv = viewOf2(user), cu = readRecordOrThrow(uv, 0), editOffset = uv.getUint32(cu.dataOffset + 8, true);
12309
+ const { directory } = buildPersistDirectory(view2, editOffset);
12310
+ const owned = readRecordOrThrow(view2, note.headerOffset), start = owned.headerOffset, end = owned.dataOffset + owned.recLen;
12311
+ const overlaps = (offset2) => {
12312
+ const other = readRecordOrThrow(view2, offset2), otherEnd = other.dataOffset + other.recLen;
12313
+ if (otherEnd > view2.byteLength)
12314
+ fail2("Unbounded live persist object prevents safe notes edit");
12315
+ return start < otherEnd && other.headerOffset < end;
12316
+ };
12317
+ for (const [persistId, offset2] of directory) {
12318
+ if (persistId !== note.persistId && overlaps(offset2))
12319
+ return "Notes container overlaps another live persist object";
12320
+ }
12321
+ let offset = editOffset;
12322
+ const visited = /* @__PURE__ */ new Set();
12323
+ while (offset) {
12324
+ if (visited.has(offset) || visited.size >= 1e4)
12325
+ return "Invalid notes save-history ownership";
12326
+ visited.add(offset);
12327
+ const edit = parseUserEditAtom(view2, offset);
12328
+ if (overlaps(offset) || overlaps(edit.offsetPersistDirectory))
12329
+ return "Notes container overlaps save-history metadata";
12330
+ offset = edit.offsetLastEdit;
12331
+ }
12332
+ return void 0;
12333
+ }
12334
+ function editPptNotesText(input, edit) {
12335
+ const reject2 = (reason) => ({ status: "unsupported", bytes: input, reason });
12336
+ try {
12337
+ const { slideId, slidePersistId, notesId, persistId, shapeId, expectedHeaderOffset, expectedText, text } = edit;
12338
+ if (typeof text !== "string" || typeof expectedText !== "string")
12339
+ return reject2("Notes replacement must be a string");
12340
+ const { stream, notes } = inspect5(input);
12341
+ const selected = notes.filter((n) => n.slideId === slideId && n.slidePersistId === slidePersistId && n.notesId === notesId && n.persistId === persistId);
12342
+ const matches = selected.length === 1 ? selected[0].texts.filter((t) => t.shapeId === shapeId && t.headerOffset === expectedHeaderOffset) : [];
12343
+ const atom = matches[0];
12344
+ if (matches.length !== 1 || !atom || atom.text !== expectedText)
12345
+ return reject2("Notes identity or expected text no longer matches");
12346
+ if (text === atom.text)
12347
+ return { status: "unchanged", bytes: input };
12348
+ if (atom.editRefusal)
12349
+ return reject2(atom.editRefusal);
12350
+ const ownership = ownershipRefusal(input, stream, selected[0]);
12351
+ if (ownership)
12352
+ return reject2(ownership);
12353
+ if (notes.reduce((n, note) => n + note.texts.filter((t) => t.headerOffset === atom.headerOffset).length, 0) !== 1)
12354
+ return reject2("Notes text atom is shared by active locations");
12355
+ const start = atom.headerOffset, end = start + 8 + atom.text.length * (atom.encoding === "utf16" ? 2 : 1);
12356
+ for (const slide of readPptSlideTexts(input).slides)
12357
+ for (const text2 of slide.texts) {
12358
+ const textEnd = text2.headerOffset + 8 + text2.text.length * (text2.encoding === "utf16" ? 2 : 1);
12359
+ if (start < textEnd && text2.headerOffset < end)
12360
+ return reject2("Notes slot overlaps active slide text");
12361
+ }
12362
+ if (text.length !== atom.text.length)
12363
+ return reject2("Notes replacement must keep the UTF-16 character count");
12364
+ for (let i = 0; i < text.length; i++) {
12365
+ const old = atom.text.charCodeAt(i), value = text.charCodeAt(i);
12366
+ if (!value || (old < 32 || value < 32 || old === 42 || value === 42) && old !== value)
12367
+ return reject2("Notes controls and field markers must remain at the same offsets");
12368
+ if (atom.encoding === "compressed-unicode" && value > 255)
12369
+ return reject2("Notes character does not fit existing encoding");
12370
+ if (value >= 55296 && value <= 56319 && !(text.charCodeAt(i + 1) >= 56320 && text.charCodeAt(i + 1) <= 57343) || value >= 56320 && value <= 57343 && !(text.charCodeAt(i - 1) >= 55296 && text.charCodeAt(i - 1) <= 56319))
12371
+ return reject2("Unpaired notes UTF-16 surrogate");
12372
+ }
12373
+ const next = stream.slice(), view2 = viewOf2(next);
12374
+ for (let i = 0; i < text.length; i++) {
12375
+ if (atom.encoding === "utf16")
12376
+ view2.setUint16(atom.headerOffset + 8 + i * 2, text.charCodeAt(i), true);
12377
+ else
12378
+ next[atom.headerOffset + 8 + i] = text.charCodeAt(i);
12379
+ }
12380
+ const bytes = replaceCompoundFileStream(input, ["PowerPoint Document"], next);
12381
+ if (bytes === input)
12382
+ return reject2("Notes compound stream cannot be safely replaced");
12383
+ const candidate = inspect5(bytes).notes.find((n) => n.slideId === slideId && n.notesId === notesId && n.persistId === persistId);
12384
+ const confirmed = candidate?.texts.filter((t) => t.shapeId === shapeId && t.headerOffset === expectedHeaderOffset);
12385
+ if (confirmed?.length !== 1 || confirmed[0].text !== text)
12386
+ return reject2("Candidate notes revalidation failed");
12387
+ return { status: "edited", bytes };
12388
+ } catch (error) {
12389
+ return reject2(error instanceof Error ? error.message : "Malformed PPT notes");
12390
+ }
12391
+ }
12392
+
12393
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/legacy-ppt-text-style.js
12394
+ var viewOf3 = (bytes) => new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
12395
+ var MAX_RECORDS = 1e5;
12396
+ var MAX_RUNS = 2e4;
12397
+ var MAX_STYLE_BYTES = 16 * 1024 * 1024;
12398
+ function children3(view2, parent) {
12399
+ const result = [], end = parent.dataOffset + parent.recLen;
12400
+ if (end > view2.byteLength)
12401
+ throw new Error("Unbounded formatting parent");
12402
+ for (let offset = parent.dataOffset; offset < end; ) {
12403
+ if (result.length >= MAX_RECORDS || end - offset < 8)
12404
+ throw new Error("Formatting record bounds exceeded");
12405
+ const record5 = readRecordOrThrow(view2, offset);
12406
+ if (record5.dataOffset + record5.recLen > end)
12407
+ throw new Error("Formatting child exceeds its parent");
12408
+ result.push(record5);
12409
+ offset = record5.dataOffset + record5.recLen;
12410
+ }
12411
+ return result;
12412
+ }
12413
+ function decodeStyle(view2, style, textLength, budget) {
12414
+ if (style.recVer !== 0 || style.recInstance !== 0)
12415
+ throw new Error("Invalid StyleTextPropAtom header");
12416
+ let pos = style.dataOffset;
12417
+ const end = pos + style.recLen, total = textLength + 1;
12418
+ const take = (bytes) => {
12419
+ if (bytes > end - pos)
12420
+ throw new Error("Truncated formatting exception");
12421
+ const offset = pos;
12422
+ pos += bytes;
12423
+ return offset;
12424
+ };
12425
+ const u16 = () => view2.getUint16(take(2), true), u32 = () => view2.getUint32(take(4), true);
12426
+ const count = (sum) => {
12427
+ if (++budget.runs > budget.maxRuns)
12428
+ throw new Error("Character/paragraph run budget exceeded");
12429
+ const value = u32();
12430
+ if (value === 0 || value > total - sum)
12431
+ throw new Error("Invalid formatting run count");
12432
+ return value;
12433
+ };
12434
+ for (let sum = 0; sum < total; ) {
12435
+ sum += count(sum);
12436
+ if (u16() > 4)
12437
+ throw new Error("Invalid paragraph indentation");
12438
+ const mask = u32();
12439
+ if (mask & -3111680)
12440
+ throw new Error("Unsupported paragraph formatting mask");
12441
+ if (mask & 15)
12442
+ take(2);
12443
+ for (const bit of [128, 16, 64])
12444
+ if (mask & bit)
12445
+ take(2);
12446
+ if (mask & 32)
12447
+ take(4);
12448
+ for (const bit of [2048, 4096, 8192, 16384, 65536])
12449
+ if (mask & bit)
12450
+ take(2);
12451
+ if (mask & 917504)
12452
+ take(2);
12453
+ if (mask & 2097152)
12454
+ take(2);
12455
+ }
12456
+ const result = [];
12457
+ for (let sum = 0; sum < total; ) {
12458
+ const runOffset = pos, rawCount = count(sum), start = sum;
12459
+ sum += rawCount;
12460
+ const mask = u32();
12461
+ if (mask & -15728640)
12462
+ throw new Error("Unsupported character formatting mask");
12463
+ if (mask & 16055)
12464
+ take(2);
12465
+ for (const bit of [65536, 2097152, 4194304, 8388608])
12466
+ if (mask & bit)
12467
+ take(2);
12468
+ let fontSizeOffset, directFontSizePoints;
12469
+ if (mask & 131072) {
12470
+ fontSizeOffset = take(2);
12471
+ directFontSizePoints = view2.getInt16(fontSizeOffset, true);
12472
+ if (directFontSizePoints < 1 || directFontSizePoints > 4e3)
12473
+ throw new Error("Invalid literal font size");
12474
+ }
12475
+ if (mask & 262144)
12476
+ take(4);
12477
+ if (mask & 524288) {
12478
+ const position = view2.getInt16(take(2), true);
12479
+ if (position < -100 || position > 100)
12480
+ throw new Error("Invalid baseline position");
12481
+ }
12482
+ result.push({
12483
+ start: Math.min(start, textLength),
12484
+ end: Math.min(sum, textLength),
12485
+ rawCount,
12486
+ mask,
12487
+ styleHeaderOffset: style.headerOffset,
12488
+ runOffset,
12489
+ fontSizeOffset,
12490
+ directFontSizePoints
12491
+ });
12492
+ }
12493
+ if (pos !== end)
12494
+ throw new Error("Unconsumed StyleTextPropAtom bytes");
12495
+ return result;
12496
+ }
12497
+ function textOwnershipRefusal2(input, stream, persistId, atom) {
12498
+ const user = readCompoundFileStream(input, ["Current User"]);
12499
+ if (!user)
12500
+ throw new PptParseError("Missing Current User stream");
12501
+ const view2 = viewOf3(stream), uv = viewOf3(user), cu = readRecordOrThrow(uv, 0);
12502
+ const editOffset = uv.getUint32(cu.dataOffset + 8, true);
12503
+ const { directory, currentEdit } = buildPersistDirectory(view2, editOffset);
12504
+ const slideOffset = directory.get(persistId);
12505
+ if (slideOffset === void 0)
12506
+ return "Missing active slide persist object";
12507
+ const slide = readRecordOrThrow(view2, slideOffset), text = readRecordOrThrow(view2, atom.headerOffset);
12508
+ const textEnd = text.dataOffset + text.recLen;
12509
+ const owners = [persistId];
12510
+ if (atom.headerOffset < slide.dataOffset || textEnd > slide.dataOffset + slide.recLen) {
12511
+ const docOffset = directory.get(currentEdit.docPersistIdRef);
12512
+ if (docOffset === void 0)
12513
+ return "Missing outline text owner";
12514
+ const doc = readRecordOrThrow(view2, docOffset);
12515
+ if (atom.headerOffset < doc.dataOffset || textEnd > doc.dataOffset + doc.recLen)
12516
+ return "Text is outside its active owning containers";
12517
+ owners.push(currentEdit.docPersistIdRef);
12518
+ }
12519
+ for (const ownerId of owners) {
12520
+ const owned = readRecordOrThrow(view2, directory.get(ownerId));
12521
+ const start = owned.headerOffset, end = owned.dataOffset + owned.recLen;
12522
+ if (end > view2.byteLength)
12523
+ return "Unbounded text owning persist object";
12524
+ const overlaps = (offset) => {
12525
+ const other = readRecordOrThrow(view2, offset), otherEnd = other.dataOffset + other.recLen;
12526
+ if (otherEnd > view2.byteLength)
12527
+ throw new PptParseError("Unbounded live persist object prevents safe text edit");
12528
+ return start < otherEnd && other.headerOffset < end;
12529
+ };
12530
+ for (const [id, offset] of directory)
12531
+ if (id !== ownerId && overlaps(offset))
12532
+ return "Text owning container overlaps another live persist object";
12533
+ const visited = /* @__PURE__ */ new Set();
12534
+ for (let offset = editOffset; offset; ) {
12535
+ if (visited.has(offset) || visited.size >= 1e4)
12536
+ return "Invalid text save-history ownership";
12537
+ visited.add(offset);
12538
+ const edit = parseUserEditAtom(view2, offset);
12539
+ if (overlaps(offset) || overlaps(edit.offsetPersistDirectory))
12540
+ return "Text owning container overlaps save-history metadata";
12541
+ offset = edit.offsetLastEdit;
12542
+ }
12543
+ }
12544
+ return void 0;
12545
+ }
12546
+ function readPptCharacterRuns(input, limits = {}) {
12547
+ const maxRecords = limits.maxRecords ?? MAX_RECORDS, maxRuns = limits.maxRuns ?? MAX_RUNS, maxStyleBytes = limits.maxStyleBytes ?? MAX_STYLE_BYTES;
12548
+ if (![maxRecords, maxRuns, maxStyleBytes].every((value) => Number.isSafeInteger(value) && value > 0))
12549
+ throw new Error("Invalid character-format resource limit");
12550
+ readPptSlideShapes(input, { maxRecords });
12551
+ const texts = readPptSlideTexts(input), stream = readCompoundFileStream(input, ["PowerPoint Document"]), user = readCompoundFileStream(input, ["Current User"]);
12552
+ const view2 = viewOf3(stream), uv = viewOf3(user), cu = readRecordOrThrow(uv, 0);
12553
+ const { directory, currentEdit } = buildPersistDirectory(view2, uv.getUint32(cu.dataOffset + 8, true));
12554
+ const associations = /* @__PURE__ */ new Map();
12555
+ let records = 0, styleBytes = 0;
12556
+ const scan = (root) => {
12557
+ const stack = [{ record: root, depth: 0 }];
12558
+ while (stack.length) {
12559
+ const { record: record5, depth } = stack.pop();
12560
+ if (depth > 128)
12561
+ throw new Error("Formatting nesting exceeds limit");
12562
+ const list = children3(view2, record5);
12563
+ records += list.length;
12564
+ if (records > maxRecords)
12565
+ throw new Error("Formatting record budget exceeded");
12566
+ let group;
12567
+ const textParent = record5.recType === OA.ClientTextbox || record5.recType === RT2.SlideListWithText && record5.recInstance === 0;
12568
+ const finish = () => {
12569
+ if (group)
12570
+ for (const atom of group.atoms) {
12571
+ if (associations.has(atom))
12572
+ throw new Error("Ambiguous formatting parent");
12573
+ associations.set(atom, { styles: group.styles, textCount: group.atoms.length });
12574
+ }
12575
+ };
12576
+ for (const child2 of list) {
12577
+ if (textParent && (child2.recType === RT2.TextHeaderAtom || child2.recType === RT2.SlidePersistAtom)) {
12578
+ finish();
12579
+ group = child2.recType === RT2.TextHeaderAtom ? { atoms: [], styles: [] } : void 0;
12580
+ if (group && (child2.recVer !== 0 || child2.recInstance > (record5.recType === OA.ClientTextbox ? 0 : 5) || child2.recLen !== 4))
12581
+ throw new Error("Invalid formatting TextHeaderAtom");
12582
+ } else if (group && (child2.recType === RT2.TextCharsAtom || child2.recType === RT2.TextBytesAtom))
12583
+ group.atoms.push(child2.headerOffset);
12584
+ else if (group && child2.recType === RT2.StyleTextPropAtom) {
12585
+ styleBytes += child2.recLen;
12586
+ if (styleBytes > maxStyleBytes)
12587
+ throw new Error("Formatting payload budget exceeded");
12588
+ group.styles.push(child2);
12589
+ }
12590
+ if (child2.recVer === 15 || child2.recType === OA.ClientTextbox)
12591
+ stack.push({ record: child2, depth: depth + 1 });
12592
+ }
12593
+ finish();
12594
+ }
12595
+ };
12596
+ let scanDiagnostic;
12597
+ try {
12598
+ const doc = readRecordOrThrow(view2, directory.get(currentEdit.docPersistIdRef));
12599
+ for (const list of children3(view2, doc))
12600
+ if (list.recType === RT2.SlideListWithText && list.recInstance === 0)
12601
+ scan(list);
12602
+ const visited = /* @__PURE__ */ new Set();
12603
+ for (const slide of texts.slides) {
12604
+ const offset = directory.get(slide.persistId);
12605
+ if (!visited.has(offset)) {
12606
+ visited.add(offset);
12607
+ scan(readRecordOrThrow(view2, offset));
12608
+ }
12609
+ }
12610
+ } catch (error) {
12611
+ scanDiagnostic = error instanceof Error ? error.message : "Unsupported formatting graph";
12612
+ }
12613
+ const budget = { runs: 0, maxRuns };
12614
+ return texts.slides.flatMap((slide) => slide.texts.map((atom) => {
12615
+ const base = { slideId: slide.slideId, persistId: slide.persistId, headerOffset: atom.headerOffset, text: atom.text };
12616
+ if (scanDiagnostic)
12617
+ return { ...base, status: "unsupported", diagnostic: scanDiagnostic, runs: [] };
12618
+ const group = associations.get(atom.headerOffset);
12619
+ if (!group)
12620
+ return { ...base, status: "unsupported", diagnostic: "Text has no unambiguous TextHeader formatting parent", runs: [] };
12621
+ if (!group.styles.length)
12622
+ return { ...base, status: "absent", runs: [] };
12623
+ if (group.textCount !== 1 || group.styles.length !== 1)
12624
+ return { ...base, status: "unsupported", diagnostic: "Text or style atom association is ambiguous", runs: [] };
12625
+ try {
12626
+ return { ...base, status: "decoded", runs: decodeStyle(view2, group.styles[0], atom.text.length, budget) };
12627
+ } catch (error) {
12628
+ return { ...base, status: "unsupported", diagnostic: error instanceof Error ? error.message : "Unsupported formatting", runs: [] };
12629
+ }
12630
+ }));
12631
+ }
12632
+ function editPptCharacterFontSize(input, edit) {
12633
+ const reject2 = (reason) => ({ status: "unsupported", bytes: input, reason });
12634
+ try {
12635
+ const { slideId, persistId, headerOffset, runOffset, styleHeaderOffset, start, end, expectedFontSizePoints, fontSizePoints } = edit;
12636
+ const matches = readPptCharacterRuns(input).filter((text) => text.slideId === slideId && text.persistId === persistId && text.headerOffset === headerOffset);
12637
+ const record5 = matches.length === 1 ? matches[0] : void 0;
12638
+ const runs = record5?.status === "decoded" ? record5.runs.filter((run2) => run2.runOffset === runOffset && run2.styleHeaderOffset === styleHeaderOffset && run2.start === start && run2.end === end) : [];
12639
+ const run = runs.length === 1 ? runs[0] : void 0;
12640
+ if (!run || run.directFontSizePoints !== expectedFontSizePoints)
12641
+ return reject2(record5?.diagnostic ?? "Character run identity or expected font size does not match");
12642
+ if (fontSizePoints === run.directFontSizePoints)
12643
+ return { status: "unchanged", bytes: input };
12644
+ if (run.start === run.end)
12645
+ return reject2("Run covers only the implicit paragraph mark");
12646
+ if (run.fontSizeOffset === void 0)
12647
+ return reject2("Font size is inherited; no existing literal slot");
12648
+ if (!Number.isSafeInteger(fontSizePoints) || fontSizePoints < 1 || fontSizePoints > 4e3)
12649
+ return reject2("Literal font size must be an integer from 1 to 4000 points");
12650
+ const textModel = readPptSlideTexts(input), slides = textModel.slides.filter((slide) => slide.slideId === slideId && slide.persistId === persistId);
12651
+ const indexes = slides.length === 1 ? slides[0].texts.flatMap((atom, index) => atom.headerOffset === headerOffset ? [index] : []) : [];
12652
+ if (indexes.length !== 1 || textModel.slides.reduce((count, slide) => count + slide.texts.filter((atom) => atom.headerOffset === headerOffset).length, 0) !== 1)
12653
+ return reject2("Text atom is shared by multiple active slide positions");
12654
+ const shapeSlides = readPptSlideShapes(input).filter((slide) => slide.slideId === slideId && slide.persistId === persistId);
12655
+ const shapes = shapeSlides.length === 1 ? shapeSlides[0].shapes.filter((shape) => shape.textReference === "inline" && shape.textIndexes.includes(indexes[0])) : [];
12656
+ if (shapes.length !== 1 || shapes[0].kind !== "text-box")
12657
+ return reject2("Font-size edits require uniquely linked inline text-box text");
12658
+ if (shapes[0].geometryRefusal)
12659
+ return reject2(`Unsupported text-box formatting context: ${shapes[0].geometryRefusal}`);
12660
+ const originalStream = readCompoundFileStream(input, ["PowerPoint Document"]);
12661
+ const refusal = textOwnershipRefusal2(input, originalStream, persistId, slides[0].texts[indexes[0]]);
12662
+ if (refusal)
12663
+ return reject2(refusal);
12664
+ const stream = readCompoundFileStream(input, ["PowerPoint Document"]).slice();
12665
+ viewOf3(stream).setInt16(run.fontSizeOffset, fontSizePoints, true);
12666
+ const bytes = replaceCompoundFileStream(input, ["PowerPoint Document"], stream);
12667
+ if (bytes === input)
12668
+ return reject2("Compound stream cannot be safely replaced");
12669
+ const candidate = readPptCharacterRuns(bytes).filter((text) => text.slideId === slideId && text.persistId === persistId && text.headerOffset === headerOffset);
12670
+ const next = candidate.length === 1 && candidate[0].status === "decoded" ? candidate[0].runs.find((item) => item.runOffset === runOffset && item.styleHeaderOffset === styleHeaderOffset && item.start === start && item.end === end) : void 0;
12671
+ if (!next || next.directFontSizePoints !== fontSizePoints || candidate[0].text !== record5.text)
12672
+ return reject2("Edited character run failed candidate validation");
12673
+ return { status: "edited", bytes };
12674
+ } catch (error) {
12675
+ return reject2(error instanceof Error ? error.message : "Malformed PPT formatting");
12676
+ }
12677
+ }
12678
+
12679
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ppt-document.js
11469
12680
  var PPT_CAPABILITIES = Object.freeze({
11470
- read: Object.freeze(["active-slide-ids", "active-outline-and-inline-text", "text-encoding", "active-shape-ids-and-flags", "primitive-shape-kind", "explicit-anchor-geometry", "validated-inline-shape-text", "opaque-streams"]),
11471
- write: Object.freeze(["existing-text-fixed-utf16-length", "unmirrored-top-level-small-anchor-bounds"]),
11472
- limitations: Object.freeze(["unresolved-outline-shape-text", "rich-text-runs", "notes", "variable-length-text", "OOXML-mirrored-text-and-shapes", "group-transforms-and-geometry", "large-anchor-writes", "inherited-rotated-or-flipped-geometry", "animations", "masters", "embedded-objects"])
12681
+ read: Object.freeze(["active-slide-ids", "active-outline-and-inline-text", "text-encoding", "direct-character-run-spans-and-font-size", "active-shape-ids-and-flags", "primitive-shape-kind", "explicit-anchor-geometry", "validated-inline-shape-text", "active-notes-identities-and-inline-text", "opaque-streams"]),
12682
+ write: Object.freeze(["existing-text-fixed-utf16-length", "existing-literal-inline-text-box-font-size", "unmirrored-top-level-small-anchor-bounds", "existing-notes-body-fixed-utf16-length"]),
12683
+ limitations: Object.freeze(["unresolved-outline-shape-text", "inherited-character-formatting", "run-splitting-and-style-insertion", "character-properties-except-existing-font-size", "outline-and-unsupported-shape-font-size-edits", "notes-creation-and-inherited-fields", "variable-length-text", "OOXML-mirrored-text-and-shapes", "group-transforms-and-geometry", "large-anchor-writes", "inherited-rotated-or-flipped-geometry", "animations", "masters", "embedded-objects"])
11473
12684
  });
12685
+ var RUN_LOOKUPS = /* @__PURE__ */ new WeakMap();
12686
+ function resolveCharacterRun(record5, original) {
12687
+ let lookup = RUN_LOOKUPS.get(record5);
12688
+ if (!lookup) {
12689
+ lookup = /* @__PURE__ */ new Map();
12690
+ for (const run2 of record5.runs) {
12691
+ const bucket = lookup.get(run2.runOffset);
12692
+ if (bucket)
12693
+ bucket.push(run2);
12694
+ else
12695
+ lookup.set(run2.runOffset, [run2]);
12696
+ }
12697
+ RUN_LOOKUPS.set(record5, lookup);
12698
+ }
12699
+ const matches = record5.status === "decoded" ? lookup.get(original.runOffset) : void 0, run = matches?.[0];
12700
+ if (matches?.length !== 1 || !run || run.styleHeaderOffset !== original.styleHeaderOffset || run.start !== original.start || run.end !== original.end || run.rawCount !== original.rawCount || run.mask !== original.mask || run.fontSizeOffset !== original.fontSizeOffset)
12701
+ throw new UnsupportedOle2EditError("PPT character run identity no longer matches or is ambiguous");
12702
+ return run;
12703
+ }
12704
+ var textRunKey = (node) => `${node.slideId}:${node.persistId}:${node.headerOffset}`;
11474
12705
  var PptText = class {
11475
12706
  slideId;
11476
12707
  persistId;
@@ -11480,7 +12711,10 @@ var PptText = class {
11480
12711
  headerOffset;
11481
12712
  #text;
11482
12713
  #write;
11483
- constructor(identity, atom, write) {
12714
+ #readRuns;
12715
+ #writeRun;
12716
+ #runs;
12717
+ constructor(identity, atom, write, readRuns, writeRun) {
11484
12718
  this.slideId = identity.slideId;
11485
12719
  this.persistId = identity.persistId;
11486
12720
  this.textIndex = identity.textIndex;
@@ -11488,6 +12722,10 @@ var PptText = class {
11488
12722
  this.headerOffset = atom.headerOffset;
11489
12723
  this.#text = atom.text;
11490
12724
  this.#write = write;
12725
+ this.#readRuns = readRuns ?? (() => ({ ...identity, headerOffset: atom.headerOffset, text: this.#text, status: "unsupported", diagnostic: "Text has no document formatting owner", runs: [] }));
12726
+ this.#writeRun = writeRun ?? (() => {
12727
+ throw new UnsupportedOle2EditError("Text has no document formatting owner");
12728
+ });
11491
12729
  Object.freeze(this);
11492
12730
  }
11493
12731
  get text() {
@@ -11499,8 +12737,50 @@ var PptText = class {
11499
12737
  this.#write(this, value);
11500
12738
  this.#text = value;
11501
12739
  }
12740
+ get runsStatus() {
12741
+ return this.#readRuns(this).status;
12742
+ }
12743
+ get runsDiagnostic() {
12744
+ return this.#readRuns(this).diagnostic;
12745
+ }
12746
+ /** Direct character exceptions only; inherited/effective formatting is unresolved. */
11502
12747
  get runs() {
11503
- throw new UnsupportedOle2EditError("PPT rich-text runs are not decoded by this adapter");
12748
+ if (!this.#runs) {
12749
+ const model2 = this.#readRuns(this);
12750
+ this.#runs = Object.freeze(model2.runs.map((run) => new PptCharacterRun(run, () => {
12751
+ const current = this.#readRuns(this);
12752
+ return { text: current.text, run: resolveCharacterRun(current, run) };
12753
+ }, (value) => this.#writeRun(this, run, value))));
12754
+ }
12755
+ return this.#runs;
12756
+ }
12757
+ };
12758
+ var PptCharacterRun = class {
12759
+ start;
12760
+ end;
12761
+ styleHeaderOffset;
12762
+ runOffset;
12763
+ #read;
12764
+ #write;
12765
+ constructor(record5, read, write) {
12766
+ this.start = record5.start;
12767
+ this.end = record5.end;
12768
+ this.styleHeaderOffset = record5.styleHeaderOffset;
12769
+ this.runOffset = record5.runOffset;
12770
+ this.#read = read;
12771
+ this.#write = write;
12772
+ Object.freeze(this);
12773
+ }
12774
+ get text() {
12775
+ return this.#read().text.slice(this.start, this.end);
12776
+ }
12777
+ get directFontSizePoints() {
12778
+ return this.#read().run.directFontSizePoints;
12779
+ }
12780
+ set directFontSizePoints(value) {
12781
+ if (value !== void 0 && typeof value !== "number")
12782
+ throw new UnsupportedOle2EditError("PPT direct font size must be numeric");
12783
+ this.#write(value);
11504
12784
  }
11505
12785
  };
11506
12786
  var PptSlide = class {
@@ -11511,15 +12791,71 @@ var PptSlide = class {
11511
12791
  /** Flat OfficeArt preorder, including group descendants with parentGroupId.
11512
12792
  * Canvas patriarchs/background structures remain preserved outside this list. */
11513
12793
  shapes;
11514
- constructor(slideId, persistId, texts, shapes = []) {
12794
+ /** Existing active notes; undefined when the slide has a null notes reference. */
12795
+ notes;
12796
+ notesStatus;
12797
+ /** A decode refusal is distinct from a null notes reference. Bytes remain opaque. */
12798
+ notesDiagnostic;
12799
+ constructor(slideId, persistId, texts, shapes = [], notes, notesDiagnostic) {
11515
12800
  this.slideId = slideId;
11516
12801
  this.persistId = persistId;
11517
12802
  this.texts = Object.freeze([...texts]);
11518
12803
  this.shapes = Object.freeze([...shapes]);
12804
+ this.notes = notes;
12805
+ this.notesDiagnostic = notesDiagnostic;
12806
+ this.notesStatus = notesDiagnostic ? "unsupported" : notes ? "present" : "absent";
12807
+ Object.freeze(this);
12808
+ }
12809
+ };
12810
+ var PptNoteText = class {
12811
+ shapeId;
12812
+ headerOffset;
12813
+ #read;
12814
+ #write;
12815
+ constructor(atom, read, write) {
12816
+ this.shapeId = atom.shapeId;
12817
+ this.headerOffset = atom.headerOffset;
12818
+ this.#read = read;
12819
+ this.#write = write;
11519
12820
  Object.freeze(this);
11520
12821
  }
11521
- get notes() {
11522
- throw new UnsupportedOle2EditError("PPT notes are preserved but are not decoded by this adapter");
12822
+ get text() {
12823
+ return this.#read().text;
12824
+ }
12825
+ set text(value) {
12826
+ if (typeof value !== "string")
12827
+ throw new UnsupportedOle2EditError("Notes replacement must be a string");
12828
+ this.#write(value);
12829
+ }
12830
+ get role() {
12831
+ return this.#read().role;
12832
+ }
12833
+ get placeholderId() {
12834
+ return this.#read().placeholderId;
12835
+ }
12836
+ get encoding() {
12837
+ return this.#read().encoding;
12838
+ }
12839
+ get editRefusal() {
12840
+ return this.#read().editRefusal;
12841
+ }
12842
+ get runs() {
12843
+ throw new UnsupportedOle2EditError("PPT notes rich-text runs are preserved but not decoded");
12844
+ }
12845
+ };
12846
+ var PptNotes = class {
12847
+ slideId;
12848
+ slidePersistId;
12849
+ notesId;
12850
+ persistId;
12851
+ texts;
12852
+ constructor(record5, texts) {
12853
+ this.slideId = record5.slideId;
12854
+ this.slidePersistId = record5.slidePersistId;
12855
+ this.notesId = record5.notesId;
12856
+ this.persistId = record5.persistId;
12857
+ this.texts = Object.freeze([...texts]);
12858
+ Object.freeze(this);
11523
12859
  }
11524
12860
  };
11525
12861
  var PptShape = class {
@@ -11532,13 +12868,13 @@ var PptShape = class {
11532
12868
  texts;
11533
12869
  #read;
11534
12870
  #write;
11535
- constructor(identity, record4, texts, read, write) {
12871
+ constructor(identity, record5, texts, read, write) {
11536
12872
  this.slideId = identity.slideId;
11537
12873
  this.persistId = identity.persistId;
11538
- this.shapeId = record4.shapeId;
11539
- this.headerOffset = record4.headerOffset;
11540
- this.flags = record4.flags;
11541
- this.shapeType = record4.shapeType;
12874
+ this.shapeId = record5.shapeId;
12875
+ this.headerOffset = record5.headerOffset;
12876
+ this.flags = record5.flags;
12877
+ this.shapeType = record5.shapeType;
11542
12878
  this.texts = Object.freeze([...texts]);
11543
12879
  this.#read = read;
11544
12880
  this.#write = write;
@@ -11628,6 +12964,9 @@ var PptDocument = class extends Ole2DocumentBase {
11628
12964
  #slides;
11629
12965
  #unsupported;
11630
12966
  #shapeCache;
12967
+ #notesCache;
12968
+ #runsCache;
12969
+ #validatedTextRuns = /* @__PURE__ */ new WeakMap();
11631
12970
  get slides() {
11632
12971
  return this.#slides;
11633
12972
  }
@@ -11638,14 +12977,102 @@ var PptDocument = class extends Ole2DocumentBase {
11638
12977
  super(input);
11639
12978
  const shapeModel = readPptSlideShapes(this.getBytes());
11640
12979
  const model2 = readPptSlideTexts(this.getBytes());
12980
+ let notesModel = [], notesDiagnostic;
12981
+ try {
12982
+ notesModel = readPptSlideNotes(this.getBytes());
12983
+ } catch (error) {
12984
+ notesDiagnostic = error instanceof Error ? error.message : "Notes decoding unsupported";
12985
+ }
11641
12986
  this.#shapeCache = { revision: this.revision, slides: shapeModel };
11642
- this.#unsupported = Object.freeze(["formatting", "group-transforms", "pictures-content", "masters", "notes", "animations", "embedded-objects", "unresolved-outline-shape-text", "variable-length-text"]);
12987
+ this.#notesCache = { revision: this.revision, notes: notesModel };
12988
+ this.#unsupported = Object.freeze(["formatting", "group-transforms", "pictures-content", "masters", "notes-creation-and-inherited-fields", "animations", "embedded-objects", "unresolved-outline-shape-text", "variable-length-text", ...notesDiagnostic ? ["notes-decoding"] : []]);
11643
12989
  this.#slides = Object.freeze(model2.slides.map((slide, index) => {
11644
- const texts = slide.texts.map((atom, textIndex) => new PptText({ slideId: slide.slideId, persistId: slide.persistId, textIndex }, atom, (node, value) => this.#edit(node, value)));
11645
- const shapes = shapeModel[index].shapes.map((record4) => new PptShape(slide, record4, record4.textIndexes.map((textIndex) => texts[textIndex]), () => this.#readShape(slide.slideId, slide.persistId, record4), (value) => this.#editShape(slide.slideId, slide.persistId, record4, value)));
11646
- return new PptSlide(slide.slideId, slide.persistId, texts, shapes);
12990
+ const texts = slide.texts.map((atom, textIndex) => new PptText({ slideId: slide.slideId, persistId: slide.persistId, textIndex }, atom, (node, value) => this.#edit(node, value), (node) => this.#readTextRuns(node), (node, run, value) => this.#editRun(node, run, value)));
12991
+ const shapes = shapeModel[index].shapes.map((record6) => new PptShape(slide, record6, record6.textIndexes.map((textIndex) => texts[textIndex]), () => this.#readShape(slide.slideId, slide.persistId, record6), (value) => this.#editShape(slide.slideId, slide.persistId, record6, value)));
12992
+ const record5 = notesModel.find((note) => note.slideId === slide.slideId && note.slidePersistId === slide.persistId);
12993
+ const notes = record5 && new PptNotes(record5, record5.texts.map((atom) => new PptNoteText(atom, () => this.#readNote(record5, atom), (value) => this.#editNote(record5, atom, value))));
12994
+ return new PptSlide(slide.slideId, slide.persistId, texts, shapes, notes, notesDiagnostic);
11647
12995
  }));
11648
12996
  }
12997
+ #readTextRuns(node) {
12998
+ if (!this.#runsCache || this.#runsCache.revision !== this.revision) {
12999
+ const revision = this.revision;
13000
+ const byIdentity = /* @__PURE__ */ new Map();
13001
+ for (const record6 of readPptCharacterRuns(this.getBytes())) {
13002
+ const key2 = textRunKey(record6), bucket = byIdentity.get(key2);
13003
+ if (bucket)
13004
+ bucket.push(record6);
13005
+ else
13006
+ byIdentity.set(key2, [record6]);
13007
+ }
13008
+ if (this.revision !== revision)
13009
+ throw new UnsupportedOle2EditError("Document changed during character formatting read");
13010
+ this.#runsCache = { revision, byIdentity };
13011
+ }
13012
+ const matches = this.#runsCache.byIdentity.get(textRunKey(node)), record5 = matches?.[0];
13013
+ if (matches?.length !== 1 || !record5)
13014
+ throw new UnsupportedOle2EditError("PPT text formatting identity no longer matches or is ambiguous");
13015
+ if (this.#validatedTextRuns.get(node) !== record5) {
13016
+ if (record5.text !== node.text)
13017
+ throw new UnsupportedOle2EditError("PPT text formatting identity no longer matches or is ambiguous");
13018
+ this.#validatedTextRuns.set(node, record5);
13019
+ }
13020
+ return record5;
13021
+ }
13022
+ #editRun(node, original, fontSizePoints) {
13023
+ const revision = this.revision, current = this.#readTextRuns(node);
13024
+ const run = resolveCharacterRun(current, original);
13025
+ const result = editPptCharacterFontSize(this.getBytes(), {
13026
+ slideId: node.slideId,
13027
+ persistId: node.persistId,
13028
+ headerOffset: node.headerOffset,
13029
+ runOffset: run.runOffset,
13030
+ styleHeaderOffset: run.styleHeaderOffset,
13031
+ start: run.start,
13032
+ end: run.end,
13033
+ expectedFontSizePoints: run.directFontSizePoints,
13034
+ fontSizePoints
13035
+ });
13036
+ if (this.revision !== revision)
13037
+ throw new UnsupportedOle2EditError("Document changed during character formatting edit");
13038
+ if (result.status === "unsupported")
13039
+ throw new UnsupportedOle2EditError(result.reason);
13040
+ if (result.status === "edited")
13041
+ this.commitBytes(result.bytes);
13042
+ }
13043
+ #readNote(original, atom) {
13044
+ if (this.#notesCache.revision !== this.revision) {
13045
+ try {
13046
+ this.#notesCache = { revision: this.revision, notes: readPptSlideNotes(this.getBytes()) };
13047
+ } catch (error) {
13048
+ throw new UnsupportedOle2EditError(error instanceof Error ? error.message : "Notes decoding unsupported");
13049
+ }
13050
+ }
13051
+ const notes = this.#notesCache.notes.filter((note) => note.slideId === original.slideId && note.slidePersistId === original.slidePersistId && note.notesId === original.notesId && note.persistId === original.persistId && note.headerOffset === original.headerOffset);
13052
+ const matches = notes.length === 1 ? notes[0].texts.filter((text) => text.shapeId === atom.shapeId && text.headerOffset === atom.headerOffset && text.shapeHeaderOffset === atom.shapeHeaderOffset && text.encoding === atom.encoding && text.placeholderId === atom.placeholderId) : [];
13053
+ if (matches.length !== 1)
13054
+ throw new UnsupportedOle2EditError("PPT notes identity no longer matches or is ambiguous");
13055
+ return matches[0];
13056
+ }
13057
+ #editNote(note, atom, text) {
13058
+ const revision = this.revision, current = this.#readNote(note, atom);
13059
+ const result = editPptNotesText(this.getBytes(), {
13060
+ slideId: note.slideId,
13061
+ slidePersistId: note.slidePersistId,
13062
+ notesId: note.notesId,
13063
+ persistId: note.persistId,
13064
+ shapeId: atom.shapeId,
13065
+ expectedHeaderOffset: atom.headerOffset,
13066
+ expectedText: current.text,
13067
+ text
13068
+ });
13069
+ if (this.revision !== revision)
13070
+ throw new UnsupportedOle2EditError("Document changed during notes edit");
13071
+ if (result.status === "unsupported")
13072
+ throw new UnsupportedOle2EditError(result.reason);
13073
+ if (result.status === "edited")
13074
+ this.commitBytes(result.bytes);
13075
+ }
11649
13076
  #readShape(slideId, persistId, original) {
11650
13077
  if (this.#shapeCache.revision !== this.revision)
11651
13078
  this.#shapeCache = { revision: this.revision, slides: readPptSlideShapes(this.getBytes()) };
@@ -11685,7 +13112,7 @@ var PptDocument = class extends Ole2DocumentBase {
11685
13112
  }
11686
13113
  };
11687
13114
 
11688
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/vsd-compression.js
13115
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/vsd-compression.js
11689
13116
  function decodeVsdBlock(input, limit3 = 32 * 1024 * 1024) {
11690
13117
  if (!Number.isSafeInteger(limit3) || limit3 < 0 || limit3 > 64 * 1024 * 1024)
11691
13118
  throw new Error("Invalid VSD decompression limit");
@@ -11732,7 +13159,7 @@ function encodeVsdBlock(input) {
11732
13159
  return output;
11733
13160
  }
11734
13161
 
11735
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/vsd-reader.js
13162
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/vsd-reader.js
11736
13163
  var VsdError = class extends Error {
11737
13164
  reason;
11738
13165
  constructor(reason) {
@@ -11780,6 +13207,8 @@ function readVsdDrawing(input) {
11780
13207
  if (size < 54 || size > stream.length)
11781
13208
  throw new VsdError("document-size");
11782
13209
  const data = { stream, streamPath, version: 11, pages: [], blocks: [], writable: true };
13210
+ const shapeOrders = /* @__PURE__ */ new Map(), sheetIds = /* @__PURE__ */ new Map();
13211
+ let orderElements = 0;
11783
13212
  const active = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set();
11784
13213
  let decodedBudget = MAX_BYTES, records = 0;
11785
13214
  function visit(ownerBytes, pointerOffset, parent, page, shape, depth = 0, id = 0) {
@@ -11853,7 +13282,7 @@ function readVsdDrawing(input) {
11853
13282
  for (const idx of indexes)
11854
13283
  visit(bytes, table + 12 + idx * 18, block, page, shape, depth + 1, idx);
11855
13284
  } else if (page && [8, 12, 13].includes(mode)) {
11856
- const stack = [];
13285
+ const stack = [], orderStack = [];
11857
13286
  let cursor = 0;
11858
13287
  while (cursor < bytes.length) {
11859
13288
  while (cursor < bytes.length && bytes[cursor] === 0)
@@ -11881,6 +13310,57 @@ function readVsdDrawing(input) {
11881
13310
  let current = stack[stack.length - 1]?.shape ?? shape;
11882
13311
  if (current && [70, 74].includes(chunk))
11883
13312
  throw new VsdError("unsupported-sheet-owner");
13313
+ while (orderStack.length && level <= orderStack[orderStack.length - 1].level)
13314
+ orderStack.pop();
13315
+ if (page && chunk === 70) {
13316
+ if (sheetIds.has(page))
13317
+ page.shapeOrderIssue = "ambiguous-page-owner";
13318
+ sheetIds.set(page, length2 >= 54 && level === 1 && [10, 18, 26].every((o) => cv.getUint32(start + o, true) === 4294967295) ? chunkId : void 0);
13319
+ }
13320
+ if (page && chunk === 101) {
13321
+ const orders = shapeOrders.get(page) ?? /* @__PURE__ */ new Map();
13322
+ shapeOrders.set(page, orders);
13323
+ const order = { owner: current, elements: [], ids: /* @__PURE__ */ new Map(), level };
13324
+ if (orders.has(current))
13325
+ order.issue = "duplicate-shape-order";
13326
+ orders.set(current, order);
13327
+ orderStack.push(order);
13328
+ const end = start + length2 + trailer - 4;
13329
+ if (end - start < 8)
13330
+ order.issue = "shape-order-bounds";
13331
+ else {
13332
+ const subHeader = cv.getUint32(start, true), childrenBytes = cv.getUint32(start + 4, true), children4 = start + 8 + subHeader;
13333
+ if (children4 > end || childrenBytes > end - children4 || childrenBytes % 4)
13334
+ order.issue = "shape-order-bounds";
13335
+ else {
13336
+ const count = childrenBytes / 4;
13337
+ orderElements += count;
13338
+ if (orderElements > 1e5)
13339
+ throw new VsdError("shape-order-budget");
13340
+ const seen2 = /* @__PURE__ */ new Set();
13341
+ for (let i = 0; i < count; i++) {
13342
+ const id2 = cv.getUint32(children4 + i * 4, true);
13343
+ if (seen2.has(id2))
13344
+ order.issue = "duplicate-order-element";
13345
+ seen2.add(id2);
13346
+ order.elements.push(id2);
13347
+ }
13348
+ }
13349
+ }
13350
+ }
13351
+ if (page && chunk === 131) {
13352
+ const order = orderStack[orderStack.length - 1];
13353
+ if (!order)
13354
+ page.shapeOrderIssue = "orphan-shape-id";
13355
+ else if (level !== order.level + 1)
13356
+ order.issue = "shape-id-owner-level";
13357
+ else if (length2 < 4)
13358
+ order.issue = "shape-id-bounds";
13359
+ else if (order.ids.has(chunkId))
13360
+ order.issue = "duplicate-shape-id-map";
13361
+ else
13362
+ order.ids.set(chunkId, cv.getUint32(start, true));
13363
+ }
11884
13364
  if (page && [71, 72, 78].includes(chunk)) {
11885
13365
  current = { id: chunkId, kind: chunk === 71 ? "group" : chunk === 78 ? "foreign" : "shape", coordinateSpace: "shape-local", unsupportedGeometry: false, unsafeTransform: false, geometry: [], unsafeText: false };
11886
13366
  if (length2 < 54)
@@ -11955,42 +13435,304 @@ function readVsdDrawing(input) {
11955
13435
  ids.add(shape.id);
11956
13436
  }
11957
13437
  }
13438
+ for (const page of data.pages) {
13439
+ const shapes = new Map(page.shapes.map((s) => [s.id, s])), orders = shapeOrders.get(page), sheet = sheetIds.get(page);
13440
+ if (sheet !== void 0 && shapes.has(sheet))
13441
+ page.shapeOrderIssue = "ambiguous-page-owner";
13442
+ const rootParent = (s) => s.parentId === 4294967295 || sheet !== void 0 && s.parentId === sheet;
13443
+ const rootIds = /* @__PURE__ */ new Set(), childrenByParent = /* @__PURE__ */ new Map(), emptyIds = /* @__PURE__ */ new Set();
13444
+ for (const shape of page.shapes) {
13445
+ if (rootParent(shape))
13446
+ rootIds.add(shape.id);
13447
+ if (shape.parentId !== void 0) {
13448
+ const children4 = childrenByParent.get(shape.parentId) ?? /* @__PURE__ */ new Set();
13449
+ children4.add(shape.id);
13450
+ childrenByParent.set(shape.parentId, children4);
13451
+ }
13452
+ }
13453
+ const resolve = (owner) => {
13454
+ const order = orders?.get(owner);
13455
+ let issue2 = order?.issue;
13456
+ if (!order)
13457
+ issue2 = "missing-shape-order";
13458
+ if (owner && owner.kind !== "group" && order?.elements.length)
13459
+ issue2 = "unsupported-child-owner";
13460
+ const result = [], seen2 = /* @__PURE__ */ new Set();
13461
+ if (order && !issue2) {
13462
+ for (const element of order.elements) {
13463
+ const id = order.ids.get(element), shape = id === void 0 ? void 0 : shapes.get(id);
13464
+ if (!shape) {
13465
+ issue2 = "unresolved-shape-id";
13466
+ break;
13467
+ }
13468
+ if (seen2.has(id)) {
13469
+ issue2 = "duplicate-shape-reference";
13470
+ break;
13471
+ }
13472
+ seen2.add(id);
13473
+ if (owner ? shape.parentId !== owner.id : !rootParent(shape)) {
13474
+ issue2 = "contradictory-shape-owner";
13475
+ break;
13476
+ }
13477
+ result.push(id);
13478
+ }
13479
+ if (!issue2) {
13480
+ const expected = owner ? childrenByParent.get(owner.id) ?? emptyIds : rootIds;
13481
+ if (expected.size !== result.length || [...expected].some((id) => !seen2.has(id)))
13482
+ issue2 = "incomplete-shape-order";
13483
+ }
13484
+ }
13485
+ if (issue2) {
13486
+ if (owner)
13487
+ owner.shapeOrderIssue = issue2;
13488
+ else
13489
+ page.shapeOrderIssue ??= issue2;
13490
+ return void 0;
13491
+ }
13492
+ return result;
13493
+ };
13494
+ const root = resolve(void 0);
13495
+ for (const shape of page.shapes)
13496
+ if (shape.kind === "group" || orders?.has(shape))
13497
+ shape.childShapeIds = resolve(shape);
13498
+ let issue = page.shapeOrderIssue;
13499
+ const queue = (root ?? []).map((id) => ({ id, depth: 0 })), visited = /* @__PURE__ */ new Set();
13500
+ if (root && !issue) {
13501
+ for (let i = 0; i < queue.length; i++) {
13502
+ const item = queue[i];
13503
+ if (item.depth > 64) {
13504
+ issue = "shape-order-depth";
13505
+ break;
13506
+ }
13507
+ if (visited.has(item.id)) {
13508
+ issue = "cyclic-shape-order";
13509
+ break;
13510
+ }
13511
+ visited.add(item.id);
13512
+ const shape = shapes.get(item.id);
13513
+ if (shape.shapeOrderIssue) {
13514
+ issue = "unresolved-child-order";
13515
+ break;
13516
+ }
13517
+ for (const id of shape.childShapeIds ?? [])
13518
+ queue.push({ id, depth: item.depth + 1 });
13519
+ }
13520
+ if (!issue && visited.size !== page.shapes.length)
13521
+ issue = "unreachable-shape-order";
13522
+ }
13523
+ if (issue) {
13524
+ page.shapeOrderIssue = issue;
13525
+ for (const shape of page.shapes)
13526
+ if (shape.childShapeIds) {
13527
+ shape.childShapeIds = void 0;
13528
+ shape.shapeOrderIssue ??= "unresolved-page-order";
13529
+ }
13530
+ } else
13531
+ page.topLevelShapeIds = root;
13532
+ }
11958
13533
  return data;
11959
13534
  }
11960
13535
 
11961
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/vsd-writer.js
11962
- function replaceRecord(input, drawing, record4, replacement) {
13536
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/vsd-compression-fit.js
13537
+ var VSD_COMPRESSION_FIT_MAX_BYTES = 8 * 1024 * 1024;
13538
+ var MAX_INPUT = VSD_COMPRESSION_FIT_MAX_BYTES;
13539
+ var MAX_GAP = 4096;
13540
+ var MAX_PROBES = 16 * 1024 * 1024;
13541
+ var VsdCompressionFitError = class extends Error {
13542
+ reason;
13543
+ constructor(reason) {
13544
+ super(`VSD compression ${reason}`);
13545
+ this.reason = reason;
13546
+ this.name = "VsdCompressionFitError";
13547
+ }
13548
+ };
13549
+ function encodeVsdBlockToSize(input, capacity) {
13550
+ if (!(input instanceof Uint8Array) || input.length > MAX_INPUT || !Number.isSafeInteger(capacity) || capacity < 0 || capacity > MAX_INPUT)
13551
+ throw new VsdCompressionFitError("input-budget");
13552
+ const output = new Uint8Array(capacity), heads = new Int32Array(65536).fill(-1), previous = new Int32Array(input.length).fill(-1);
13553
+ let cursor = 0, flagOffset = -1, bit = 8, tokens = 0, probes = 0;
13554
+ const tailSize = 4096, positions = new Int32Array(tailSize), lengths = new Uint8Array(tailSize), sources = new Int32Array(tailSize), starts = new Int32Array(tailSize);
13555
+ function emit(literal2, a, b) {
13556
+ const size = (bit === 8 ? 1 : 0) + (literal2 ? 1 : 2);
13557
+ if (size > capacity - cursor)
13558
+ return false;
13559
+ if (bit === 8) {
13560
+ flagOffset = cursor++;
13561
+ output[flagOffset] = 0;
13562
+ bit = 0;
13563
+ }
13564
+ if (literal2)
13565
+ output[flagOffset] |= 1 << bit;
13566
+ output[cursor++] = a;
13567
+ if (!literal2)
13568
+ output[cursor++] = b;
13569
+ bit++;
13570
+ tokens++;
13571
+ return true;
13572
+ }
13573
+ const hash2 = (p) => (input[p] * 251 + input[p + 1]) * 251 + input[p + 2] & 65535;
13574
+ function remember(p) {
13575
+ if (p + 2 < input.length) {
13576
+ const h = hash2(p);
13577
+ previous[p] = heads[h];
13578
+ heads[h] = p;
13579
+ }
13580
+ }
13581
+ function match(position) {
13582
+ let length = 0, source = -1;
13583
+ if (position < 4060) {
13584
+ while (length < 18 && position + length < input.length && input[position + length] === 0)
13585
+ length++;
13586
+ if (length >= 3)
13587
+ source = -18;
13588
+ else
13589
+ length = 0;
13590
+ }
13591
+ if (position + 2 < input.length) {
13592
+ let candidate = heads[hash2(position)], attempts = 0;
13593
+ while (candidate >= Math.max(0, position - 4096) && candidate < position && attempts++ < 512) {
13594
+ let n = 0;
13595
+ while (n < 18 && position + n < input.length) {
13596
+ if (++probes > MAX_PROBES)
13597
+ throw new VsdCompressionFitError("work-limit");
13598
+ if (input[candidate + n] !== input[position + n])
13599
+ break;
13600
+ n++;
13601
+ }
13602
+ if (n >= 3 && n > length) {
13603
+ length = n;
13604
+ source = candidate;
13605
+ if (n === 18)
13606
+ break;
13607
+ }
13608
+ candidate = previous[candidate];
13609
+ }
13610
+ }
13611
+ return { length, source };
13612
+ }
13613
+ for (let position = 0; position < input.length; ) {
13614
+ let { length, source } = match(position);
13615
+ if (length >= 3 && length < 18 && position + 1 < input.length && match(position + 1).length > length + 1)
13616
+ length = 0;
13617
+ const slot = tokens % tailSize;
13618
+ positions[slot] = position;
13619
+ lengths[slot] = length >= 3 ? length : 1;
13620
+ sources[slot] = source;
13621
+ starts[slot] = cursor;
13622
+ if (length >= 3) {
13623
+ const address = source - 18 & 4095;
13624
+ if (!emit(false, address & 255, address >> 4 & 240 | length - 3))
13625
+ return void 0;
13626
+ } else {
13627
+ length = 1;
13628
+ if (!emit(true, input[position]))
13629
+ return void 0;
13630
+ }
13631
+ for (let i = 0; i < length; i++)
13632
+ remember(position + i);
13633
+ position += length;
13634
+ }
13635
+ const remaining = capacity - cursor;
13636
+ if (remaining) {
13637
+ if (remaining > MAX_GAP || !tokens)
13638
+ return void 0;
13639
+ const baseTokens = tokens, tailStart = Math.ceil(Math.max(0, tokens - tailSize) / 8) * 8;
13640
+ let states2 = [{ extra: 0, count: 0, cost: 0, index: -1, k: 0 }], answer, planningWork = 0, nodes = 0, references = 0;
13641
+ for (let index = tokens - 1; index >= tailStart && !answer; index--) {
13642
+ const length = lengths[index % tailSize];
13643
+ if (length < 3)
13644
+ continue;
13645
+ if (++references > 512)
13646
+ break;
13647
+ const next = /* @__PURE__ */ new Map();
13648
+ for (const state of states2)
13649
+ next.set(state.cost * 8 + (baseTokens + state.count) % 8, state);
13650
+ for (const state of states2) {
13651
+ for (let k = 1; k <= length; k++) {
13652
+ if (++planningWork > 1024 * 1024 || nodes >= 65536)
13653
+ throw new VsdCompressionFitError("work-limit");
13654
+ if (k > length - 3 && k !== length)
13655
+ continue;
13656
+ const count = state.count + (k === length ? k - 1 : k), extra = state.extra + (k === length ? k - 2 : k), cost = extra + Math.ceil((baseTokens + count) / 8) - Math.ceil(baseTokens / 8);
13657
+ if (cost > remaining)
13658
+ continue;
13659
+ const key2 = cost * 8 + (baseTokens + count) % 8;
13660
+ if (next.has(key2))
13661
+ continue;
13662
+ const node = { extra, count, cost, parent: state, index, k };
13663
+ nodes++;
13664
+ if (cost === remaining) {
13665
+ answer = node;
13666
+ break;
13667
+ }
13668
+ next.set(key2, node);
13669
+ }
13670
+ if (answer)
13671
+ break;
13672
+ }
13673
+ states2 = [...next.values()].sort((a, b) => b.cost - a.cost).slice(0, 63);
13674
+ if (!states2.some((p) => p.cost === 0))
13675
+ states2.push({ extra: 0, count: 0, cost: 0, index: -1, k: 0 });
13676
+ }
13677
+ if (!answer)
13678
+ return void 0;
13679
+ const changes = /* @__PURE__ */ new Map();
13680
+ for (let node = answer; node?.parent; node = node.parent)
13681
+ changes.set(node.index, node.k);
13682
+ cursor = starts[tailStart % tailSize];
13683
+ bit = 8;
13684
+ flagOffset = -1;
13685
+ tokens = tailStart;
13686
+ for (let index = tailStart; index < baseTokens; index++) {
13687
+ const slot = index % tailSize, position = positions[slot], length = lengths[slot], k = changes.get(index) ?? 0;
13688
+ for (let j = 0; j < k; j++)
13689
+ if (!emit(true, input[position + j]))
13690
+ return void 0;
13691
+ if (k < length) {
13692
+ if (length === 1) {
13693
+ if (!emit(true, input[position]))
13694
+ return void 0;
13695
+ } else {
13696
+ const address = sources[slot] + k - 18 & 4095;
13697
+ if (!emit(false, address & 255, address >> 4 & 240 | length - k - 3))
13698
+ return void 0;
13699
+ }
13700
+ }
13701
+ }
13702
+ }
13703
+ if (cursor !== capacity)
13704
+ return void 0;
13705
+ const decoded = decodeVsdBlock(output, input.length);
13706
+ if (decoded.length !== input.length || !input.every((v, i) => decoded[i] === v))
13707
+ throw new VsdCompressionFitError("verification");
13708
+ return { bytes: output, paddingBytes: 0 };
13709
+ }
13710
+
13711
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/vsd-writer.js
13712
+ function replaceRecord(input, drawing, record5, replacement) {
11963
13713
  if (!drawing.writable)
11964
13714
  throw new VsdError("shared-or-overlapping-allocation");
11965
- let block = record4.block, decoded = block.bytes.slice();
11966
- decoded.set(replacement, record4.offset);
11967
- const appended = [];
11968
- let size = drawing.stream.length;
11969
- const header = drawing.stream.slice();
11970
- for (; ; ) {
11971
- const stored = block.format & 2 ? encodeVsdBlock(decoded) : decoded;
11972
- if (stored.length > VSD_MAX_BYTES - size)
11973
- throw new VsdError("writer-size-limit");
11974
- const offset2 = size;
11975
- appended.push(stored);
11976
- size += stored.length;
11977
- const owner = block.parent ? block.parent.bytes.slice() : header;
11978
- const view2 = new DataView(owner.buffer, owner.byteOffset, owner.byteLength);
11979
- view2.setUint32(block.pointerOffset + 8, offset2, true);
11980
- view2.setUint32(block.pointerOffset + 12, stored.length, true);
11981
- if (!block.parent)
11982
- break;
11983
- block = block.parent;
11984
- decoded = owner;
11985
- }
11986
- const stream = new Uint8Array(size);
11987
- stream.set(header);
11988
- let offset = header.length;
11989
- for (const bytes of appended) {
11990
- stream.set(bytes, offset);
11991
- offset += bytes.length;
13715
+ if (record5.block.format & 2 && (record5.block.bytes.length > VSD_COMPRESSION_FIT_MAX_BYTES || record5.block.length > VSD_COMPRESSION_FIT_MAX_BYTES))
13716
+ throw new VsdError("compression-input-budget");
13717
+ const block = record5.block, decoded = block.bytes.slice();
13718
+ decoded.set(replacement, record5.offset);
13719
+ let stored = block.format & 2 ? encodeVsdBlock(decoded) : decoded;
13720
+ if (stored.length !== block.length) {
13721
+ if (!(block.format & 2) || ![8, 12, 13].includes(block.format >>> 4))
13722
+ throw new VsdError("unsafe-block-relocation");
13723
+ try {
13724
+ const fit = encodeVsdBlockToSize(decoded, block.length);
13725
+ if (!fit)
13726
+ throw new VsdError("unsafe-block-relocation");
13727
+ stored = fit.bytes;
13728
+ } catch (error) {
13729
+ if (error instanceof VsdCompressionFitError)
13730
+ throw new VsdError(`compression-${error.reason}`);
13731
+ throw error;
13732
+ }
11992
13733
  }
11993
- new DataView(stream.buffer).setUint32(28, stream.length, true);
13734
+ const stream = drawing.stream.slice();
13735
+ stream.set(stored, block.offset);
11994
13736
  const result = resizeCompoundFileStream(input, drawing.streamPath, stream);
11995
13737
  if (!result.ok)
11996
13738
  throw new VsdError(`compound-resize-${result.reason}`);
@@ -12050,7 +13792,7 @@ function replaceVsdShapeTransform(input, pageId, shapeId, transform2) {
12050
13792
  return candidate;
12051
13793
  }
12052
13794
 
12053
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/vsd-document.js
13795
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/vsd-document.js
12054
13796
  var VsdShape = class {
12055
13797
  id;
12056
13798
  #read;
@@ -12097,6 +13839,14 @@ var VsdShape = class {
12097
13839
  set transform(value) {
12098
13840
  this.#editTransform(value);
12099
13841
  }
13842
+ /** Validated drawing order of this owner's explicit children; undefined when unresolved. */
13843
+ get childShapeIds() {
13844
+ const ids = this.#read().childShapeIds;
13845
+ return ids && Object.freeze([...ids]);
13846
+ }
13847
+ get shapeOrderIssue() {
13848
+ return this.#read().shapeOrderIssue;
13849
+ }
12100
13850
  get geometry() {
12101
13851
  return Object.freeze(this.#read().geometry.map((row) => Object.freeze({ ...row })));
12102
13852
  }
@@ -12111,6 +13861,14 @@ var VsdPage = class {
12111
13861
  this.shapes = Object.freeze(shapes);
12112
13862
  Object.freeze(this);
12113
13863
  }
13864
+ /** Validated top-level drawing order. The existing shapes array remains flat. */
13865
+ get topLevelShapeIds() {
13866
+ const ids = this.#read().topLevelShapeIds;
13867
+ return ids && Object.freeze([...ids]);
13868
+ }
13869
+ get shapeOrderIssue() {
13870
+ return this.#read().shapeOrderIssue;
13871
+ }
12114
13872
  get background() {
12115
13873
  return this.#read().background;
12116
13874
  }
@@ -12125,7 +13883,7 @@ var VsdPage = class {
12125
13883
  return this.#read().scale;
12126
13884
  }
12127
13885
  };
12128
- var CAPABILITIES = Object.freeze({ read: Object.freeze(["v11-pages", "explicit-shape-transform", "utf16-shape-text", "move-to-line-to"]), write: Object.freeze(["equal-length-shape-text", "literal-shape-transform"]), limitations: Object.freeze(["Version 11 only; stored values without master/style/formula evaluation.", "No added/deleted shapes, text length changes or text field edits.", "Shared/overlapping VSD blocks cannot be edited; no native Visio fidelity claim."]) });
13886
+ var CAPABILITIES = Object.freeze({ read: Object.freeze(["v11-pages", "validated-page-and-group-order", "explicit-shape-transform", "utf16-shape-text", "move-to-line-to"]), write: Object.freeze(["equal-length-shape-text", "literal-shape-transform"]), limitations: Object.freeze(["Version 11 only; stored values without master/style/formula evaluation.", "Drawing order may be unresolved; flat shape arrays retain physical order and group coordinates stay local.", "Edits require an exact stored-block fit at the original offset; relocation is refused. Bounded compression preserves exact decoded length and supports at most 8 MiB decoded leaf/allocation, with bounded token-fit search and no added decoded bytes.", "No added/deleted shapes, text length changes or text field edits.", "Shared/overlapping VSD blocks cannot be edited; native evidence covers only declared fixture edits, not full Visio fidelity."]) });
12129
13887
  var VsdDocument = class extends Ole2DocumentBase {
12130
13888
  #drawing;
12131
13889
  #pages;
@@ -12185,7 +13943,7 @@ var VsdDocument = class extends Ole2DocumentBase {
12185
13943
  }
12186
13944
  };
12187
13945
 
12188
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-document.js
13946
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/ole2-document.js
12189
13947
  var CfbDocument = class extends Ole2DocumentBase {
12190
13948
  get kind() {
12191
13949
  return "cfb";
@@ -12298,7 +14056,7 @@ function parseVsd(input) {
12298
14056
  return parseOle22(input, { expect: "vsd" });
12299
14057
  }
12300
14058
 
12301
- // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js
14059
+ // node_modules/.bun/@christophervr+ole2@0.12.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js
12302
14060
  (() => {
12303
14061
  const table = new Uint32Array(256);
12304
14062
  for (let n = 0; n < 256; n++) {
@@ -14546,7 +16304,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
14546
16304
  return result;
14547
16305
  };
14548
16306
  let steps = 1e5;
14549
- const inspect4 = (binding, name) => {
16307
+ const inspect6 = (binding, name) => {
14550
16308
  check();
14551
16309
  if (--steps < 0) problem("Master dependency proof exceeded its cell budget.");
14552
16310
  name = name.toLowerCase();
@@ -14571,7 +16329,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
14571
16329
  txtlocpiny: "txtheight"
14572
16330
  };
14573
16331
  const dimension = defaults[name];
14574
- if (dimension) inspect4(binding, dimension);
16332
+ if (dimension) inspect6(binding, dimension);
14575
16333
  else if (!themeCell.test(name)) problem(`Missing effective master reference ${name}.`);
14576
16334
  } else {
14577
16335
  const formula = executableCellFormula(attribute2(source.node, "F"));
@@ -14592,17 +16350,17 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
14592
16350
  for (const ref of analysis.references) {
14593
16351
  if (analysis.readsText && ref.shapeId === void 0 && ref.cell.toLowerCase() === "thetext")
14594
16352
  continue;
14595
- if (ref.shapeId === void 0) inspect4(binding, ref.cell);
16353
+ if (ref.shapeId === void 0) inspect6(binding, ref.cell);
14596
16354
  else if (source.kind === "template") {
14597
16355
  const target = binding.context.get(ref.shapeId);
14598
16356
  if (!target) problem("Missing master-local Sheet reference.");
14599
- inspect4(target, ref.cell);
16357
+ inspect6(target, ref.cell);
14600
16358
  } else {
14601
16359
  if (source.kind === "style")
14602
16360
  problem("Explicit sheet references in inherited master styles are ambiguous.");
14603
16361
  if (directAffected(binding.pageId, ref.shapeId, ref.cell) || query({ pageId: binding.pageId, shapeId: ref.shapeId, cell: ref.cell }, changed))
14604
16362
  problem("Effective master cache depends on an edited page shape.");
14605
- inspect4(pageInput(binding.pageId, ref.shapeId), ref.cell);
16363
+ inspect6(pageInput(binding.pageId, ref.shapeId), ref.cell);
14606
16364
  }
14607
16365
  }
14608
16366
  if (analysis.readsText) {
@@ -14610,7 +16368,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
14610
16368
  if (/^(character\.|paragraph\.|tabs\.|leftmargin$|rightmargin$|topmargin$|bottommargin$)/i.test(
14611
16369
  cell
14612
16370
  ))
14613
- inspect4(binding, cell);
16371
+ inspect6(binding, cell);
14614
16372
  }
14615
16373
  }
14616
16374
  }
@@ -14622,7 +16380,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
14622
16380
  const source = binding.cells.get(name);
14623
16381
  if (["pinx", "piny"].includes(name) && source?.kind === "instance" && movePins.pins.has(source.node))
14624
16382
  continue;
14625
- inspect4(binding, name);
16383
+ inspect6(binding, name);
14626
16384
  }
14627
16385
  return movePins;
14628
16386
  }