ooxml-core 0.12.0 → 0.13.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.
@@ -15377,10 +15377,10 @@ var init_ole_utils = __esm({
15377
15377
  }
15378
15378
  });
15379
15379
 
15380
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
15380
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
15381
15381
  var OLE_MAGIC, ENDOFCHAIN, FREESECT, FATSECT, DIFSECT, MAXREGSECT, ENTRY_TYPE_EMPTY, ENTRY_TYPE_STREAM, ENTRY_TYPE_ROOT, DIR_ENTRY_SIZE, Ole2ParseError;
15382
15382
  var init_ole2_parser_types = __esm({
15383
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js"() {
15383
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js"() {
15384
15384
  OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 177, 26, 225]);
15385
15385
  ENDOFCHAIN = 4294967294;
15386
15386
  FREESECT = 4294967295;
@@ -15400,10 +15400,13 @@ var init_ole2_parser_types = __esm({
15400
15400
  }
15401
15401
  });
15402
15402
 
15403
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
15403
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
15404
15404
  function parseOle2(buffer) {
15405
15405
  const data = new Uint8Array(buffer);
15406
15406
  const view = new DataView(buffer);
15407
+ if (data.length < 512) {
15408
+ throw new Ole2ParseError("Truncated OLE2 compound file header");
15409
+ }
15407
15410
  for (let i = 0; i < OLE_MAGIC.length; i++) {
15408
15411
  if (data[i] !== OLE_MAGIC[i]) {
15409
15412
  throw new Ole2ParseError("Not a valid OLE2 compound file");
@@ -15417,8 +15420,15 @@ function parseOle2(buffer) {
15417
15420
  }
15418
15421
  const sectorSizePower = view.getUint16(30, true);
15419
15422
  const miniSectorSizePower = view.getUint16(32, true);
15423
+ if (majorVersion !== 3 && majorVersion !== 4 || sectorSizePower !== (majorVersion === 3 ? 9 : 12) || miniSectorSizePower !== 6) {
15424
+ throw new Ole2ParseError("Unsupported OLE2 version or sector size");
15425
+ }
15420
15426
  const sectorSize = 1 << sectorSizePower;
15421
15427
  const miniSectorSize = 1 << miniSectorSizePower;
15428
+ if (data.length < sectorSize || data.length % sectorSize !== 0) {
15429
+ throw new Ole2ParseError("Truncated OLE2 sector");
15430
+ }
15431
+ const sectorCount = data.length / sectorSize - 1;
15422
15432
  const totalFATSectors = view.getUint32(44, true);
15423
15433
  const firstDirectorySector = view.getUint32(48, true);
15424
15434
  const miniStreamCutoff = view.getUint32(56, true);
@@ -15426,6 +15436,9 @@ function parseOle2(buffer) {
15426
15436
  const totalMiniFATSectors = view.getUint32(64, true);
15427
15437
  const firstDIFATSector = view.getUint32(68, true);
15428
15438
  const totalDIFATSectors = view.getUint32(72, true);
15439
+ if (totalFATSectors > sectorCount || totalMiniFATSectors > sectorCount || totalDIFATSectors > sectorCount) {
15440
+ throw new Ole2ParseError("Allocation table count exceeds file size");
15441
+ }
15429
15442
  function sectorOffset(sector) {
15430
15443
  return (sector + 1) * sectorSize;
15431
15444
  }
@@ -15444,7 +15457,11 @@ function parseOle2(buffer) {
15444
15457
  }
15445
15458
  }
15446
15459
  let difatSector = firstDIFATSector;
15460
+ const difatSeen = /* @__PURE__ */ new Set();
15447
15461
  for (let d = 0; d < totalDIFATSectors && difatSector <= MAXREGSECT; d++) {
15462
+ if (difatSeen.has(difatSector))
15463
+ throw new Ole2ParseError("Circular DIFAT chain");
15464
+ difatSeen.add(difatSector);
15448
15465
  const difatData = readSector(difatSector);
15449
15466
  const difatView = new DataView(difatData.buffer, difatData.byteOffset, difatData.byteLength);
15450
15467
  const entriesPerSector = (sectorSize - 4) / 4;
@@ -15456,11 +15473,14 @@ function parseOle2(buffer) {
15456
15473
  }
15457
15474
  difatSector = difatView.getUint32(sectorSize - 4, true);
15458
15475
  }
15476
+ if (difatSeen.size !== totalDIFATSectors || fatSectors.length !== totalFATSectors || new Set(fatSectors).size !== fatSectors.length || fatSectors.some((id) => difatSeen.has(id))) {
15477
+ throw new Ole2ParseError("Invalid DIFAT allocation table");
15478
+ }
15459
15479
  const fatEntries = [];
15460
15480
  for (const fatSector of fatSectors) {
15461
15481
  const fatData = readSector(fatSector);
15462
15482
  const fatView = new DataView(fatData.buffer, fatData.byteOffset, fatData.byteLength);
15463
- for (let i = 0; i < sectorSize / 4; i++) {
15483
+ for (let i = 0; i < sectorSize / 4 && fatEntries.length < sectorCount; i++) {
15464
15484
  fatEntries.push(fatView.getUint32(i * 4, true));
15465
15485
  }
15466
15486
  }
@@ -15474,8 +15494,12 @@ function parseOle2(buffer) {
15474
15494
  }
15475
15495
  visited.add(current);
15476
15496
  sectors.push(readSector(current));
15477
- current = fatEntries[current] ?? ENDOFCHAIN;
15497
+ if (fatEntries[current] === void 0)
15498
+ throw new Ole2ParseError("Missing FAT chain entry");
15499
+ current = fatEntries[current];
15478
15500
  }
15501
+ if (current !== ENDOFCHAIN)
15502
+ throw new Ole2ParseError("Invalid FAT chain terminator");
15479
15503
  const totalLength = sectors.length * sectorSize;
15480
15504
  const result = new Uint8Array(totalLength);
15481
15505
  let offset = 0;
@@ -15486,16 +15510,14 @@ function parseOle2(buffer) {
15486
15510
  return result;
15487
15511
  }
15488
15512
  function readStream(startSector, size) {
15513
+ if (size === 0)
15514
+ return new Uint8Array(0);
15515
+ if (size > sectorCount * sectorSize)
15516
+ throw new Ole2ParseError("Stream size exceeds file size");
15489
15517
  const raw = readSectorChain(startSector);
15490
- return raw.subarray(0, Math.min(size, raw.length));
15491
- }
15492
- const miniFatEntries = [];
15493
- if (firstMiniFATSector <= MAXREGSECT && totalMiniFATSectors > 0) {
15494
- const miniFatRaw = readSectorChain(firstMiniFATSector);
15495
- const miniFatView = new DataView(miniFatRaw.buffer, miniFatRaw.byteOffset, miniFatRaw.byteLength);
15496
- for (let i = 0; i < miniFatRaw.length / 4; i++) {
15497
- miniFatEntries.push(miniFatView.getUint32(i * 4, true));
15498
- }
15518
+ if (raw.length < size)
15519
+ throw new Ole2ParseError("Truncated stream sector chain");
15520
+ return raw.subarray(0, size);
15499
15521
  }
15500
15522
  const dirRaw = readSectorChain(firstDirectorySector);
15501
15523
  const numEntries = Math.floor(dirRaw.length / DIR_ENTRY_SIZE);
@@ -15508,6 +15530,9 @@ function parseOle2(buffer) {
15508
15530
  if (objectType === ENTRY_TYPE_EMPTY) {
15509
15531
  continue;
15510
15532
  }
15533
+ if (nameLen < 2 || nameLen > 64 || nameLen % 2 !== 0 || entryView.getUint16(nameLen - 2, true) !== 0) {
15534
+ throw new Ole2ParseError("Invalid directory entry name");
15535
+ }
15511
15536
  const nameBytes = Math.max(0, nameLen - 2);
15512
15537
  let name = "";
15513
15538
  for (let j = 0; j < nameBytes; j += 2) {
@@ -15521,8 +15546,11 @@ function parseOle2(buffer) {
15521
15546
  const sizeLow = entryView.getUint32(120, true);
15522
15547
  let size = sizeLow;
15523
15548
  if (majorVersion === 4) {
15524
- entryView.getUint32(124, true);
15525
- size = sizeLow;
15549
+ const sizeHigh = entryView.getUint32(124, true);
15550
+ size = sizeLow + sizeHigh * 4294967296;
15551
+ if (!Number.isSafeInteger(size) || size > sectorCount * sectorSize) {
15552
+ throw new Ole2ParseError("Stream size exceeds supported file bounds");
15553
+ }
15526
15554
  }
15527
15555
  entries.push({
15528
15556
  name,
@@ -15536,11 +15564,28 @@ function parseOle2(buffer) {
15536
15564
  });
15537
15565
  }
15538
15566
  const rootEntry = entries.find((e) => e.type === ENTRY_TYPE_ROOT);
15567
+ if (!rootEntry || entries.filter((e) => e.type === ENTRY_TYPE_ROOT).length !== 1) {
15568
+ throw new Ole2ParseError("Invalid root directory entry");
15569
+ }
15539
15570
  let miniStreamData;
15540
15571
  if (rootEntry && rootEntry.startSector <= MAXREGSECT) {
15541
- miniStreamData = readSectorChain(rootEntry.startSector);
15572
+ miniStreamData = readStream(rootEntry.startSector, rootEntry.size);
15573
+ }
15574
+ const miniFatEntries = [];
15575
+ if (firstMiniFATSector <= MAXREGSECT && totalMiniFATSectors > 0) {
15576
+ const miniFatRaw = readSectorChain(firstMiniFATSector);
15577
+ if (miniFatRaw.length !== totalMiniFATSectors * sectorSize) {
15578
+ throw new Ole2ParseError("Unexpected mini FAT chain length");
15579
+ }
15580
+ const miniFatView = new DataView(miniFatRaw.buffer, miniFatRaw.byteOffset, miniFatRaw.byteLength);
15581
+ const miniCapacity = Math.floor((miniStreamData?.length ?? 0) / miniSectorSize);
15582
+ for (let i = 0; i < miniFatRaw.length / 4 && i < miniCapacity; i++) {
15583
+ miniFatEntries.push(miniFatView.getUint32(i * 4, true));
15584
+ }
15542
15585
  }
15543
15586
  function readMiniStream(startSector, size) {
15587
+ if (size === 0)
15588
+ return new Uint8Array(0);
15544
15589
  if (!miniStreamData) {
15545
15590
  throw new Ole2ParseError("Mini stream container not found");
15546
15591
  }
@@ -15553,17 +15598,24 @@ function parseOle2(buffer) {
15553
15598
  }
15554
15599
  visited.add(current);
15555
15600
  const offset2 = current * miniSectorSize;
15601
+ if (offset2 + miniSectorSize > miniStreamData.length || miniFatEntries[current] === void 0) {
15602
+ throw new Ole2ParseError("Mini stream sector exceeds allocation bounds");
15603
+ }
15556
15604
  sectors.push(miniStreamData.subarray(offset2, offset2 + miniSectorSize));
15557
- current = miniFatEntries[current] ?? ENDOFCHAIN;
15605
+ current = miniFatEntries[current];
15558
15606
  }
15607
+ if (current !== ENDOFCHAIN)
15608
+ throw new Ole2ParseError("Invalid mini FAT chain terminator");
15559
15609
  const totalLength = sectors.length * miniSectorSize;
15610
+ if (totalLength < size)
15611
+ throw new Ole2ParseError("Truncated mini stream sector chain");
15560
15612
  const result = new Uint8Array(totalLength);
15561
15613
  let offset = 0;
15562
15614
  for (const sector of sectors) {
15563
15615
  result.set(sector, offset);
15564
15616
  offset += miniSectorSize;
15565
15617
  }
15566
- return result.subarray(0, Math.min(size, result.length));
15618
+ return result.subarray(0, size);
15567
15619
  }
15568
15620
  function getStream(name) {
15569
15621
  const entry = entries.find((e) => (e.type === ENTRY_TYPE_STREAM || e.type === ENTRY_TYPE_ROOT) && e.name === name);
@@ -15578,7 +15630,7 @@ function parseOle2(buffer) {
15578
15630
  return { entries, getStream };
15579
15631
  }
15580
15632
  var init_ole2_parser_read = __esm({
15581
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js"() {
15633
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js"() {
15582
15634
  init_ole2_parser_types();
15583
15635
  }
15584
15636
  });
@@ -15718,13 +15770,16 @@ var init_ole_embedded_extract = __esm({
15718
15770
  }
15719
15771
  });
15720
15772
 
15721
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
15773
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
15722
15774
  function compareDirEntryNames(a, b) {
15775
+ const ua = a.toUpperCase();
15776
+ const ub = b.toUpperCase();
15777
+ if (ua.length !== a.length || ub.length !== b.length) {
15778
+ throw new Error("CFB stream names with expanding uppercase mappings are unsupported");
15779
+ }
15723
15780
  if (a.length !== b.length) {
15724
15781
  return a.length - b.length;
15725
15782
  }
15726
- const ua = a.toUpperCase();
15727
- const ub = b.toUpperCase();
15728
15783
  for (let i = 0; i < ua.length; i++) {
15729
15784
  const diff = ua.charCodeAt(i) - ub.charCodeAt(i);
15730
15785
  if (diff !== 0) {
@@ -15741,6 +15796,24 @@ function encodeName(name) {
15741
15796
  }
15742
15797
  return bytes;
15743
15798
  }
15799
+ function buildDirectoryTree(entryCount) {
15800
+ const links = /* @__PURE__ */ new Map();
15801
+ let redLevel = 0;
15802
+ for (let remaining = entryCount - 2; remaining >= 0; remaining = Math.floor(remaining / 2) - 1)
15803
+ redLevel++;
15804
+ const build = (low, high, level2) => {
15805
+ if (low > high)
15806
+ return 4294967295;
15807
+ const id = Math.floor((low + high) / 2);
15808
+ links.set(id, {
15809
+ left: build(low, id - 1, level2 + 1),
15810
+ right: build(id + 1, high, level2 + 1),
15811
+ color: level2 === redLevel ? 0 : 1
15812
+ });
15813
+ return id;
15814
+ };
15815
+ return { root: build(1, entryCount - 1, 0), links };
15816
+ }
15744
15817
  function writeFatChain(fat, chain2) {
15745
15818
  for (let i = 0; i < chain2.sectors.length; i++) {
15746
15819
  fat[chain2.sectors[i]] = i < chain2.sectors.length - 1 ? chain2.sectors[i + 1] : ENDOFCHAIN;
@@ -15764,12 +15837,12 @@ function writeInt32Sectors(outBytes, int32Data, firstSector, numSectors, sectorS
15764
15837
  }
15765
15838
  }
15766
15839
  var init_ole2_parser_write_helpers = __esm({
15767
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js"() {
15840
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js"() {
15768
15841
  init_ole2_parser_types();
15769
15842
  }
15770
15843
  });
15771
15844
 
15772
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
15845
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
15773
15846
  function writeHeader(outView, outBytes, params) {
15774
15847
  outBytes.set(OLE_MAGIC, 0);
15775
15848
  outView.setUint16(24, 62, true);
@@ -15826,6 +15899,7 @@ function writeDifatSectors(outView, params) {
15826
15899
  function serializeDirectoryEntries(dirEntries, numDirSectors, sectorSize) {
15827
15900
  const dirData = new Uint8Array(numDirSectors * sectorSize);
15828
15901
  const dirView = new DataView(dirData.buffer);
15902
+ const tree = buildDirectoryTree(dirEntries.length);
15829
15903
  for (let i = 0; i < dirEntries.length; i++) {
15830
15904
  const entry = dirEntries[i];
15831
15905
  const entryOffset = i * DIR_ENTRY_SIZE;
@@ -15833,17 +15907,17 @@ function serializeDirectoryEntries(dirEntries, numDirSectors, sectorSize) {
15833
15907
  dirData.set(nameBytes.subarray(0, Math.min(nameBytes.length, 64)), entryOffset);
15834
15908
  dirView.setUint16(entryOffset + 64, Math.min((entry.name.length + 1) * 2, 64), true);
15835
15909
  dirData[entryOffset + 66] = entry.type;
15836
- dirData[entryOffset + 67] = 1;
15910
+ dirData[entryOffset + 67] = i === 0 ? 1 : tree.links.get(i).color;
15837
15911
  if (entry.clsid) {
15838
15912
  dirData.set(entry.clsid.subarray(0, 16), entryOffset + 80);
15839
15913
  }
15840
15914
  if (i === 0) {
15841
15915
  dirView.setUint32(entryOffset + 68, 4294967295, true);
15842
15916
  dirView.setUint32(entryOffset + 72, 4294967295, true);
15843
- dirView.setUint32(entryOffset + 76, dirEntries.length > 1 ? 1 : 4294967295, true);
15917
+ dirView.setUint32(entryOffset + 76, tree.root, true);
15844
15918
  } else {
15845
- dirView.setUint32(entryOffset + 68, 4294967295, true);
15846
- dirView.setUint32(entryOffset + 72, i + 1 < dirEntries.length ? i + 1 : 4294967295, true);
15919
+ dirView.setUint32(entryOffset + 68, tree.links.get(i).left, true);
15920
+ dirView.setUint32(entryOffset + 72, tree.links.get(i).right, true);
15847
15921
  dirView.setUint32(entryOffset + 76, 4294967295, true);
15848
15922
  }
15849
15923
  dirView.setUint32(entryOffset + 116, entry.startSector, true);
@@ -15861,17 +15935,32 @@ function writeStreamSectors(outBytes, streamData, chain2, sectorSize) {
15861
15935
  }
15862
15936
  var HEADER_DIFAT_ENTRIES;
15863
15937
  var init_ole2_parser_write_serialize = __esm({
15864
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js"() {
15938
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js"() {
15865
15939
  init_ole2_parser_types();
15866
15940
  init_ole2_parser_write_helpers();
15867
15941
  HEADER_DIFAT_ENTRIES = 109;
15868
15942
  }
15869
15943
  });
15870
15944
 
15871
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
15945
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
15872
15946
  function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
15873
15947
  const sectorSize = 512;
15874
15948
  const miniSectorSize = 64;
15949
+ if (rootClsid && rootClsid.length !== 16)
15950
+ throw new Error("Root CLSID must contain 16 bytes");
15951
+ const names = [...streams2.keys()].sort(compareDirEntryNames);
15952
+ for (let i = 0; i < names.length; i++) {
15953
+ const name = names[i];
15954
+ if (name.toUpperCase().length !== name.length) {
15955
+ throw new Error("CFB stream names with expanding uppercase mappings are unsupported");
15956
+ }
15957
+ if (!name.length || name.length > 31 || /[\x00\\/:!]/.test(name)) {
15958
+ throw new Error("CFB stream names must be 1-31 UTF-16 code units without NUL, \\, /, :, or !");
15959
+ }
15960
+ if (i > 0 && compareDirEntryNames(names[i - 1], name) === 0) {
15961
+ throw new Error("Duplicate CFB stream names");
15962
+ }
15963
+ }
15875
15964
  const regularStreams = [];
15876
15965
  const miniStreams = [];
15877
15966
  for (const [name, data] of streams2) {
@@ -15889,7 +15978,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
15889
15978
  for (let i = 0; i < numSectors; i++) {
15890
15979
  sectors.push(nextSector++);
15891
15980
  }
15892
- fatChains.set(stream.name, { start: sectors[0] ?? 0, sectors });
15981
+ fatChains.set(stream.name, { start: sectors[0] ?? ENDOFCHAIN, sectors });
15893
15982
  }
15894
15983
  let miniStreamContainer = new Uint8Array(0);
15895
15984
  const miniFatChains = /* @__PURE__ */ new Map();
@@ -15912,7 +16001,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
15912
16001
  miniOffset += miniSectorSize;
15913
16002
  }
15914
16003
  miniFatChains.set(stream.name, {
15915
- start: miniSectors[0] ?? 0,
16004
+ start: miniSectors[0] ?? ENDOFCHAIN,
15916
16005
  sectors: miniSectors
15917
16006
  });
15918
16007
  }
@@ -15960,7 +16049,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
15960
16049
  nextSector += numDirSectors;
15961
16050
  let firstMiniFATSector = ENDOFCHAIN;
15962
16051
  let numMiniFATSectors = 0;
15963
- if (miniStreams.length > 0) {
16052
+ if (nextMiniSector > 0) {
15964
16053
  numMiniFATSectors = Math.ceil(nextMiniSector * 4 / sectorSize);
15965
16054
  firstMiniFATSector = nextSector;
15966
16055
  nextSector += numMiniFATSectors;
@@ -16034,7 +16123,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
16034
16123
  return output;
16035
16124
  }
16036
16125
  var init_ole2_parser_write = __esm({
16037
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js"() {
16126
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js"() {
16038
16127
  init_ole2_parser_types();
16039
16128
  init_ole2_parser_write_helpers();
16040
16129
  init_ole2_parser_write_serialize();
@@ -16736,7 +16825,7 @@ var init_ole_sheet_xlsx_editor = __esm({
16736
16825
  }
16737
16826
  });
16738
16827
 
16739
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js
16828
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js
16740
16829
  function chain(table, start, limit) {
16741
16830
  if (start === END && limit === 0)
16742
16831
  return [];
@@ -16815,7 +16904,7 @@ function processCompoundFileStream(input, path, replacement) {
16815
16904
  const fat = [];
16816
16905
  for (const id of fatIds) {
16817
16906
  const bytes = sector(id), dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
16818
- for (let j = 0; j < sectorSize / 4; j++)
16907
+ for (let j = 0; j < sectorSize / 4 && fat.length < sectorCount; j++)
16819
16908
  fat.push(dv.getUint32(j * 4, true));
16820
16909
  }
16821
16910
  const exactChain = (table, start, bytes, unit) => chain(table, start, Math.ceil(bytes / unit));
@@ -16912,9 +17001,10 @@ function processCompoundFileStream(input, path, replacement) {
16912
17001
  if (new Set(metadataSectors).size !== metadataSectors.length)
16913
17002
  return reject();
16914
17003
  const miniFat = [];
17004
+ const miniCapacity = Math.floor(Math.min(root.size, sectorCount * sectorSize) / miniSize);
16915
17005
  for (const id of miniFatSectors) {
16916
17006
  const bytes = sector(id), dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
16917
- for (let j = 0; j < sectorSize / 4; j++)
17007
+ for (let j = 0; j < sectorSize / 4 && miniFat.length < miniCapacity; j++)
16918
17008
  miniFat.push(dv.getUint32(j * 4, true));
16919
17009
  }
16920
17010
  const reserved = /* @__PURE__ */ new Set([...fatIds, ...difatIds, ...dirSectors, ...miniFatSectors]);
@@ -16938,7 +17028,7 @@ function processCompoundFileStream(input, path, replacement) {
16938
17028
  continue;
16939
17029
  const ids = exactChain(miniFat, entry.start, entry.size, miniSize);
16940
17030
  for (const id of ids) {
16941
- if (id * miniSize >= rootMini.size || miniUsed.has(id))
17031
+ if ((id + 1) * miniSize > rootMini.size || miniUsed.has(id))
16942
17032
  return reject();
16943
17033
  miniUsed.add(id);
16944
17034
  }
@@ -16963,6 +17053,8 @@ function processCompoundFileStream(input, path, replacement) {
16963
17053
  });
16964
17054
  return result.slice(0, target.size);
16965
17055
  }
17056
+ if (replacement.length === 0)
17057
+ return input.slice();
16966
17058
  const output = input.slice();
16967
17059
  if (target.size >= miniCutoff) {
16968
17060
  const sectors = exactChain(fat, target.start, target.size, sectorSize);
@@ -17003,7 +17095,7 @@ function replaceCompoundFileStream(input, path, replacement) {
17003
17095
  }
17004
17096
  var END, MAX, NIL, SIZE;
17005
17097
  var init_ole2_stream_edit = __esm({
17006
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js"() {
17098
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-edit.js"() {
17007
17099
  END = 4294967294;
17008
17100
  MAX = 4294967290;
17009
17101
  NIL = 4294967295;
@@ -17011,7 +17103,7 @@ var init_ole2_stream_edit = __esm({
17011
17103
  }
17012
17104
  });
17013
17105
 
17014
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js
17106
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js
17015
17107
  function unwrapXlsBytes(bytes) {
17016
17108
  if (!isCfb(bytes)) {
17017
17109
  return { workbookBytes: bytes };
@@ -17078,7 +17170,7 @@ function isCfb(bytes) {
17078
17170
  }
17079
17171
  var WORKBOOK_STREAM_NAMES;
17080
17172
  var init_legacy_excel_cfb = __esm({
17081
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js"() {
17173
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-cfb.js"() {
17082
17174
  init_ole2_parser_read();
17083
17175
  init_ole2_parser_types();
17084
17176
  init_ole2_parser_write();
@@ -17087,7 +17179,178 @@ var init_legacy_excel_cfb = __esm({
17087
17179
  }
17088
17180
  });
17089
17181
 
17090
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js
17182
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-edit.js
17183
+ function encodeRkExact(value) {
17184
+ if (!Number.isFinite(value))
17185
+ return void 0;
17186
+ for (const scale of [1, 100]) {
17187
+ const scaled = value * scale;
17188
+ if (Number.isInteger(scaled) && scaled >= -536870912 && scaled < 536870912) {
17189
+ const rk2 = (scaled << 2 | 2 | (scale === 100 ? 1 : 0)) >>> 0;
17190
+ if (Object.is(decodeRk(rk2), value))
17191
+ return rk2;
17192
+ }
17193
+ const view = new DataView(new ArrayBuffer(8));
17194
+ view.setFloat64(0, scaled, true);
17195
+ const rk = (view.getUint32(4, true) & 4294967292 | (scale === 100 ? 1 : 0)) >>> 0;
17196
+ if (Object.is(decodeRk(rk), value))
17197
+ return rk;
17198
+ }
17199
+ return void 0;
17200
+ }
17201
+ function worksheetRanges(bytes) {
17202
+ const records = readRecords(bytes, 0, bytes.length);
17203
+ const last = records.at(-1);
17204
+ if (!last || bytes.subarray(last.dataOffset + last.length).some((b) => b !== 0))
17205
+ return void 0;
17206
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17207
+ const ranges = [];
17208
+ let depth = 0;
17209
+ let start;
17210
+ for (const record2 of records) {
17211
+ if (record2.opcode === 2057) {
17212
+ if (record2.length < 4 || view.getUint16(record2.dataOffset, true) !== 1536 || depth >= 64)
17213
+ return void 0;
17214
+ if (depth === 0 && view.getUint16(record2.dataOffset + 2, true) === 16)
17215
+ start = record2.headerOffset;
17216
+ depth++;
17217
+ } else if (record2.opcode === 10) {
17218
+ if (depth === 0 || record2.length !== 0)
17219
+ return void 0;
17220
+ depth--;
17221
+ if (depth === 0 && start !== void 0) {
17222
+ ranges.push({ start, end: record2.dataOffset });
17223
+ start = void 0;
17224
+ }
17225
+ }
17226
+ }
17227
+ if (depth !== 0)
17228
+ return void 0;
17229
+ const globalsEnd = records.find((r) => r.opcode === 10)?.headerOffset ?? 0;
17230
+ const bounds = records.filter((r) => r.opcode === 133 && r.headerOffset < globalsEnd);
17231
+ if (bounds.length === 0)
17232
+ return ranges;
17233
+ const ordered4 = [];
17234
+ const used = /* @__PURE__ */ new Set();
17235
+ for (const bound of bounds) {
17236
+ if (bound.length < 8)
17237
+ return void 0;
17238
+ const p = bound.dataOffset;
17239
+ const nameLength = view.getUint8(p + 6);
17240
+ const width = view.getUint8(p + 7) & 1 ? 2 : 1;
17241
+ if (nameLength < 1 || nameLength > 31 || bound.length !== 8 + nameLength * width)
17242
+ return void 0;
17243
+ const kind = view.getUint8(p + 5);
17244
+ if (![0, 1, 2, 6].includes(kind))
17245
+ return void 0;
17246
+ if (kind !== 0)
17247
+ continue;
17248
+ const offset = view.getUint32(p, true);
17249
+ const range = ranges.find((r) => r.start === offset);
17250
+ if (!range || used.has(offset))
17251
+ return void 0;
17252
+ used.add(offset);
17253
+ ordered4.push(range);
17254
+ }
17255
+ return ordered4.length === ranges.length ? ordered4 : void 0;
17256
+ }
17257
+ function editXlsNumericCell(input, edit) {
17258
+ const unchanged2 = (reason) => ({ status: "unchanged", bytes: input, reason });
17259
+ const sheet = edit.worksheetIndex ?? 0;
17260
+ if (!Number.isInteger(edit.row) || edit.row < 0 || edit.row > 65535 || !Number.isInteger(edit.col) || edit.col < 0 || edit.col > 255 || !Number.isInteger(sheet) || sheet < 0 || !Number.isFinite(edit.value))
17261
+ return unchanged2("invalid-edit");
17262
+ try {
17263
+ const { workbookBytes: bytes, rewrap } = unwrapXlsBytes(input);
17264
+ if (!isSupportedBiff8Workbook(bytes))
17265
+ return unchanged2("unsupported-workbook");
17266
+ const ranges = worksheetRanges(bytes);
17267
+ if (!ranges)
17268
+ return unchanged2("malformed-records");
17269
+ const range = ranges[sheet];
17270
+ if (!range)
17271
+ return unchanged2("sheet-not-found");
17272
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17273
+ let payload;
17274
+ let packed = false;
17275
+ let depth = 0;
17276
+ let matches = 0;
17277
+ for (const record2 of readRecords(bytes, range.start, range.end)) {
17278
+ if (record2.opcode === 2057) {
17279
+ depth++;
17280
+ continue;
17281
+ }
17282
+ if (record2.opcode === 10) {
17283
+ depth--;
17284
+ continue;
17285
+ }
17286
+ if (depth !== 1)
17287
+ continue;
17288
+ const p = record2.dataOffset;
17289
+ if (record2.opcode === 189) {
17290
+ if (record2.length < 12 || (record2.length - 6) % 6 !== 0)
17291
+ return unchanged2("malformed-records");
17292
+ const first = view.getUint16(p + 2, true);
17293
+ const lastCol = view.getUint16(p + record2.length - 2, true);
17294
+ if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record2.length - 6) / 6)
17295
+ return unchanged2("malformed-records");
17296
+ if (view.getUint16(p, true) === edit.row && edit.col >= first && edit.col <= lastCol) {
17297
+ if (++matches > 1)
17298
+ return unchanged2("ambiguous-cell");
17299
+ payload = p + 6 + (edit.col - first) * 6;
17300
+ packed = true;
17301
+ }
17302
+ } else if (record2.opcode === 515 || record2.opcode === 638) {
17303
+ if (record2.length !== (record2.opcode === 515 ? 14 : 10))
17304
+ return unchanged2("malformed-records");
17305
+ if (view.getUint16(p, true) === edit.row && view.getUint16(p + 2, true) === edit.col) {
17306
+ if (++matches > 1)
17307
+ return unchanged2("ambiguous-cell");
17308
+ payload = p + 6;
17309
+ packed = record2.opcode === 638;
17310
+ }
17311
+ } else if ([6, 513, 516, 517, 253, 214].includes(record2.opcode)) {
17312
+ if (record2.length < 6)
17313
+ return unchanged2("malformed-records");
17314
+ if (view.getUint16(p, true) === edit.row && view.getUint16(p + 2, true) === edit.col && ++matches > 1)
17315
+ return unchanged2("ambiguous-cell");
17316
+ } else if (record2.opcode === 190) {
17317
+ if (record2.length < 8 || (record2.length - 6) % 2 !== 0)
17318
+ return unchanged2("malformed-records");
17319
+ const first = view.getUint16(p + 2, true);
17320
+ const lastCol = view.getUint16(p + record2.length - 2, true);
17321
+ if (lastCol > 255 || lastCol < first || lastCol - first + 1 !== (record2.length - 6) / 2)
17322
+ return unchanged2("malformed-records");
17323
+ if (view.getUint16(p, true) === edit.row && edit.col >= first && edit.col <= lastCol && ++matches > 1)
17324
+ return unchanged2("ambiguous-cell");
17325
+ }
17326
+ }
17327
+ if (payload === void 0)
17328
+ return unchanged2("cell-not-supported");
17329
+ const rk = packed ? encodeRkExact(edit.value) : void 0;
17330
+ if (packed && rk === void 0)
17331
+ return unchanged2("inexact-rk");
17332
+ const out = bytes.slice();
17333
+ const outView = new DataView(out.buffer, out.byteOffset, out.byteLength);
17334
+ if (packed)
17335
+ outView.setUint32(payload, rk, true);
17336
+ else
17337
+ outView.setFloat64(payload, edit.value, true);
17338
+ const result = rewrap ? rewrap(out) : out;
17339
+ if (result === input)
17340
+ return unchanged2("container-not-writable");
17341
+ return { status: "edited", bytes: result, recalculationRequired: true };
17342
+ } catch {
17343
+ return unchanged2("malformed-records");
17344
+ }
17345
+ }
17346
+ var init_legacy_excel_biff8_edit = __esm({
17347
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-edit.js"() {
17348
+ init_legacy_excel_biff8();
17349
+ init_legacy_excel_cfb();
17350
+ }
17351
+ });
17352
+
17353
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js
17091
17354
  function readRecords(bytes, start, end) {
17092
17355
  const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17093
17356
  const records = [];
@@ -17141,7 +17404,7 @@ function findFirstWorksheetRange(bytes) {
17141
17404
  function parseSstSingleRecord(bytes) {
17142
17405
  const records = readRecords(bytes, 0, bytes.length);
17143
17406
  const sst = records.find((r) => r.opcode === OPCODE_SST);
17144
- if (!sst) {
17407
+ if (!sst || sst.length < 8) {
17145
17408
  return [];
17146
17409
  }
17147
17410
  const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
@@ -17149,7 +17412,8 @@ function parseSstSingleRecord(bytes) {
17149
17412
  let offset = sst.dataOffset + 8;
17150
17413
  const end = sst.dataOffset + sst.length;
17151
17414
  try {
17152
- while (offset + 3 <= end) {
17415
+ const unique = view.getUint32(sst.dataOffset + 4, true);
17416
+ while (strings2.length < unique && offset + 3 <= end) {
17153
17417
  const charCount = view.getUint16(offset, true);
17154
17418
  const flags = view.getUint8(offset + 2);
17155
17419
  offset += 3;
@@ -17159,13 +17423,19 @@ function parseSstSingleRecord(bytes) {
17159
17423
  let richRuns = 0;
17160
17424
  let extLen = 0;
17161
17425
  if (isRich) {
17426
+ if (offset + 2 > end)
17427
+ break;
17162
17428
  richRuns = view.getUint16(offset, true);
17163
17429
  offset += 2;
17164
17430
  }
17165
17431
  if (hasExt) {
17432
+ if (offset + 4 > end)
17433
+ break;
17166
17434
  extLen = view.getUint32(offset, true);
17167
17435
  offset += 4;
17168
17436
  }
17437
+ if (offset + charCount * (isWide ? 2 : 1) + richRuns * 4 + extLen > end)
17438
+ break;
17169
17439
  let text2 = "";
17170
17440
  for (let i = 0; i < charCount; i++) {
17171
17441
  if (isWide) {
@@ -17246,52 +17516,13 @@ function decodeRk(rk) {
17246
17516
  }
17247
17517
  return isDiv100 ? value / 100 : value;
17248
17518
  }
17249
- function encodeRk(value) {
17250
- if (Number.isInteger(value) && Math.abs(value) < 536870912) {
17251
- return (value << 2 | 2) >>> 0;
17252
- }
17253
- const buffer = new ArrayBuffer(8);
17254
- const view = new DataView(buffer);
17255
- view.setFloat64(0, value, false);
17256
- const high32 = view.getUint32(0, false);
17257
- return high32 & 4294967292;
17258
- }
17259
17519
  function writeOleXlsNumericCellEdit(inputBytes, edit) {
17260
- if (!Number.isFinite(edit.value)) {
17261
- return inputBytes;
17262
- }
17263
- const { workbookBytes: xlsBytes, rewrap } = unwrapXlsBytes(inputBytes);
17264
- if (!isSupportedBiff8Workbook(xlsBytes))
17265
- return inputBytes;
17266
- const range = findFirstWorksheetRange(xlsBytes);
17267
- if (!range) {
17268
- return inputBytes;
17269
- }
17270
- const out = new Uint8Array(xlsBytes);
17271
- const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
17272
- for (const record2 of readRecords(out, range.start, range.end)) {
17273
- if (record2.length < 6) {
17274
- continue;
17275
- }
17276
- const row = view.getUint16(record2.dataOffset, true);
17277
- const col = view.getUint16(record2.dataOffset + 2, true);
17278
- if (row !== edit.row || col !== edit.col) {
17279
- continue;
17280
- }
17281
- if (record2.opcode === OPCODE_NUMBER && record2.length >= 14) {
17282
- view.setFloat64(record2.dataOffset + 6, edit.value, true);
17283
- return rewrap ? rewrap(out) : out;
17284
- }
17285
- if (record2.opcode === OPCODE_RK && record2.length >= 10) {
17286
- view.setInt32(record2.dataOffset + 6, encodeRk(edit.value), true);
17287
- return rewrap ? rewrap(out) : out;
17288
- }
17289
- }
17290
- return inputBytes;
17520
+ return editXlsNumericCell(inputBytes, edit).bytes;
17291
17521
  }
17292
17522
  var OPCODE_BOF, OPCODE_EOF, OPCODE_FILEPASS, OPCODE_NUMBER, OPCODE_RK, OPCODE_LABELSST, OPCODE_LABEL, OPCODE_SST, OPCODE_EXTSST, OPCODE_ROW, OPCODE_DBCELL, OPCODE_DIMENSIONS, OPCODE_BLANK, OPCODE_BOUNDSHEET, WORKSHEET_DT, DEFAULT_MAX_ROWS2, DEFAULT_MAX_COLS2;
17293
17523
  var init_legacy_excel_biff8 = __esm({
17294
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js"() {
17524
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8.js"() {
17525
+ init_legacy_excel_biff8_edit();
17295
17526
  init_legacy_excel_cfb();
17296
17527
  OPCODE_BOF = 2057;
17297
17528
  OPCODE_EOF = 10;
@@ -17320,7 +17551,7 @@ var init_ole_sheet_xls_biff8 = __esm({
17320
17551
  }
17321
17552
  });
17322
17553
 
17323
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-grid.js
17554
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-grid.js
17324
17555
  function biffRecord(opcode, data) {
17325
17556
  return [
17326
17557
  opcode & 255,
@@ -17393,7 +17624,7 @@ function buildXlsRowCellRegion(grid) {
17393
17624
  const colFirst = cols[0] ?? 0;
17394
17625
  const colLast = cols.length > 0 ? cols[cols.length - 1] + 1 : 0;
17395
17626
  rowRecordOffsets.push(bytesOut.length);
17396
- const extra = row.extraRowBytes ?? [255, 0, 0, 0, 0, 1, 15, 0];
17627
+ const extra = row.extraRowBytes ?? [255, 0, 0, 0, 0, 1, 15, 0, 0, 0];
17397
17628
  bytesOut.push(...biffRecord(OPCODE_ROW, [...u16le(r), ...u16le(colFirst), ...u16le(colLast), ...extra]));
17398
17629
  }
17399
17630
  for (const r of rows) {
@@ -17428,8 +17659,12 @@ function buildXlsRowCellRegion(grid) {
17428
17659
  if (rows.length > 0) {
17429
17660
  const dbCellOffset = bytesOut.length;
17430
17661
  const dbData = [0, 0, 0, 0];
17431
- for (const off of firstCellOffsetPerRow) {
17432
- dbData.push(...u16le(dbCellOffset - off));
17662
+ for (let i = 0; i < firstCellOffsetPerRow.length; i++) {
17663
+ const base = i === 0 ? rowRecordOffsets[0] + 20 : firstCellOffsetPerRow[i - 1];
17664
+ const offset = firstCellOffsetPerRow[i] - base;
17665
+ if (offset < 0 || offset > 65535)
17666
+ throw new Error("DBCELL offset exceeds UInt16");
17667
+ dbData.push(...u16le(offset));
17433
17668
  }
17434
17669
  const backToFirstRow = dbCellOffset - rowRecordOffsets[0];
17435
17670
  dbData[0] = backToFirstRow & 255;
@@ -17441,28 +17676,39 @@ function buildXlsRowCellRegion(grid) {
17441
17676
  return Uint8Array.from(bytesOut);
17442
17677
  }
17443
17678
  var init_legacy_excel_biff8_grid = __esm({
17444
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-grid.js"() {
17679
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-grid.js"() {
17445
17680
  init_legacy_excel_biff8();
17446
17681
  }
17447
17682
  });
17448
17683
 
17449
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-writer.js
17450
- function resolveSstIndex(sharedStrings, value) {
17684
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-writer.js
17685
+ function resolveSstIndex(sharedStrings, value, bytes) {
17451
17686
  const existing = sharedStrings.indexOf(value);
17452
- if (existing !== -1) {
17687
+ if (existing !== -1)
17453
17688
  return { index: existing };
17454
- }
17455
- const next = [...sharedStrings, value];
17456
- const data = [];
17457
- data.push(...u16le(next.length & 65535), 0, 0);
17458
- data.push(...u16le(next.length & 65535), 0, 0);
17459
- for (const s of next) {
17460
- data.push(...u16le(s.length), 0);
17461
- for (const ch of s) {
17462
- data.push(ch.charCodeAt(0) & 255);
17463
- }
17464
- }
17465
- return { index: next.length - 1, rebuilt: biffRecord(OPCODE_SST, data) };
17689
+ const records = readRecords(bytes, 0, bytes.length);
17690
+ const sst = records.find((r) => r.opcode === OPCODE_SST);
17691
+ if (!sst || sst.length < 8 || value.length > 32767)
17692
+ throw new Error("Unsupported SST");
17693
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17694
+ const unique = view.getUint32(sst.dataOffset + 4, true);
17695
+ if (unique !== sharedStrings.length || records[records.indexOf(sst) + 1]?.opcode === 60)
17696
+ throw new Error("Continued or incomplete SST");
17697
+ const data = Array.from(bytes.subarray(sst.dataOffset, sst.dataOffset + sst.length));
17698
+ const wide = Array.from({ length: value.length }, (_, i) => value.charCodeAt(i)).some((c) => c > 255);
17699
+ data.push(...u16le(value.length), wide ? 1 : 0);
17700
+ for (let i = 0; i < value.length; i++) {
17701
+ const c = value.charCodeAt(i);
17702
+ data.push(c & 255);
17703
+ if (wide)
17704
+ data.push(c >> 8);
17705
+ }
17706
+ if (data.length > 8224)
17707
+ throw new Error("SST continuation required");
17708
+ const counts = new DataView(new Uint8Array(data).buffer);
17709
+ counts.setUint32(0, view.getUint32(sst.dataOffset, true) + 1, true);
17710
+ counts.setUint32(4, unique + 1, true);
17711
+ return { index: unique, rebuilt: biffRecord(OPCODE_SST, Array.from(new Uint8Array(counts.buffer))) };
17466
17712
  }
17467
17713
  function tryInPlaceStringEdit(bytes, range, edit, sstIndex) {
17468
17714
  const out = new Uint8Array(bytes);
@@ -17509,18 +17755,27 @@ function patchBoundsheetOffsets(bytes, delta2) {
17509
17755
  return out;
17510
17756
  }
17511
17757
  function writeOleXlsStringCellEdit(inputBytes, edit) {
17758
+ if (!Number.isInteger(edit.row) || edit.row < 0 || edit.row > 65535 || !Number.isInteger(edit.col) || edit.col < 0 || edit.col > 255 || edit.value.length > 32767)
17759
+ return inputBytes;
17512
17760
  try {
17513
17761
  const { workbookBytes: xlsBytes, rewrap } = unwrapXlsBytes(inputBytes);
17514
17762
  if (!isSupportedBiff8Workbook(xlsBytes))
17515
17763
  return inputBytes;
17516
- const finish2 = (result) => rewrap ? rewrap(result) : result;
17764
+ const finish2 = (result2) => {
17765
+ const records = readRecords(result2, 0, result2.length);
17766
+ const sst = records.find((r) => r.opcode === OPCODE_SST);
17767
+ if (sst && sst.length >= 8) {
17768
+ new DataView(result2.buffer, result2.byteOffset, result2.byteLength).setUint32(sst.dataOffset, records.filter((r) => r.opcode === OPCODE_LABELSST).length, true);
17769
+ }
17770
+ return rewrap ? rewrap(result2) : result2;
17771
+ };
17517
17772
  const ranges = findAllWorksheetRanges(xlsBytes);
17518
17773
  const target = ranges[0];
17519
17774
  if (!target) {
17520
17775
  return inputBytes;
17521
17776
  }
17522
17777
  const sharedStrings = parseSstSingleRecord(xlsBytes);
17523
- const { index: sstIndex, rebuilt: newSstRecord } = resolveSstIndex(sharedStrings, edit.value);
17778
+ const { index: sstIndex, rebuilt: newSstRecord } = resolveSstIndex(sharedStrings, edit.value, xlsBytes);
17524
17779
  if (!newSstRecord) {
17525
17780
  const inPlace = tryInPlaceStringEdit(xlsBytes, target, edit, sstIndex);
17526
17781
  if (inPlace) {
@@ -17533,10 +17788,22 @@ function writeOleXlsStringCellEdit(inputBytes, edit) {
17533
17788
  const allRecords = readRecords(xlsBytes, 0, xlsBytes.length);
17534
17789
  const sstRecord = allRecords.find((r) => r.opcode === OPCODE_SST);
17535
17790
  const extSstRecord = allRecords.find((r) => r.opcode === OPCODE_EXTSST);
17791
+ if (allRecords.filter((r) => r.opcode === OPCODE_BOUNDSHEET).length > 1)
17792
+ return inputBytes;
17793
+ if (sstRecord && extSstRecord && extSstRecord.headerOffset !== sstRecord.dataOffset + sstRecord.length)
17794
+ return inputBytes;
17536
17795
  if (!sstRecord) {
17537
17796
  return inputBytes;
17538
17797
  }
17798
+ const region = findRowCellRegion(xlsBytes, target);
17799
+ const sheetRecords = readRecords(xlsBytes, target.start, target.end);
17800
+ if (sheetRecords.some((r) => [523, 6, 517, 189, 190, OPCODE_LABEL, 214].includes(r.opcode)) || sheetRecords.filter((r) => r.opcode === 2057).length !== 1)
17801
+ return inputBytes;
17802
+ if (readRecords(xlsBytes, region.start, region.end).some((r) => !(r.opcode === OPCODE_ROW || r.opcode === OPCODE_DBCELL || r.opcode === OPCODE_NUMBER || r.opcode === OPCODE_RK || r.opcode === OPCODE_LABELSST || r.opcode === OPCODE_BLANK)))
17803
+ return inputBytes;
17539
17804
  const grid = parseXlsGrid(xlsBytes, target);
17805
+ if ((/* @__PURE__ */ new Set([...grid.keys(), edit.row])).size > 32)
17806
+ return inputBytes;
17540
17807
  const row = grid.get(edit.row) ?? { cells: /* @__PURE__ */ new Map() };
17541
17808
  row.cells.set(edit.col, {
17542
17809
  ixfe: row.cells.get(edit.col)?.ixfe ?? 15,
@@ -17545,8 +17812,7 @@ function writeOleXlsStringCellEdit(inputBytes, edit) {
17545
17812
  });
17546
17813
  grid.set(edit.row, row);
17547
17814
  const newRegion = buildXlsRowCellRegion(grid);
17548
- const region = findRowCellRegion(xlsBytes, target);
17549
- const sstEnd = extSstRecord ? extSstRecord.dataOffset + extSstRecord.length : sstRecord.dataOffset + sstRecord.length;
17815
+ const sstEnd = extSstRecord && extSstRecord.headerOffset === sstRecord.dataOffset + sstRecord.length ? extSstRecord.dataOffset + extSstRecord.length : sstRecord.dataOffset + sstRecord.length;
17550
17816
  const oldSstSpanLength = sstEnd - sstRecord.headerOffset;
17551
17817
  const newSstSpanLength = newSstRecord ? newSstRecord.length : oldSstSpanLength;
17552
17818
  const patchedXlsBytes = patchBoundsheetOffsets(xlsBytes, newSstSpanLength - oldSstSpanLength);
@@ -17558,13 +17824,26 @@ function writeOleXlsStringCellEdit(inputBytes, edit) {
17558
17824
  ...newRegion,
17559
17825
  ...patchedXlsBytes.subarray(region.end)
17560
17826
  ];
17561
- return finish2(Uint8Array.from(out));
17827
+ const result = Uint8Array.from(out);
17828
+ const dimensions = readRecords(result, 0, result.length).find((r) => r.opcode === OPCODE_DIMENSIONS);
17829
+ if (dimensions) {
17830
+ if (dimensions.length !== 14)
17831
+ return inputBytes;
17832
+ const view = new DataView(result.buffer);
17833
+ const rows = [...grid.keys()];
17834
+ const cols = [...grid.values()].flatMap((row2) => [...row2.cells.keys()]);
17835
+ view.setUint32(dimensions.dataOffset, Math.min(...rows), true);
17836
+ view.setUint32(dimensions.dataOffset + 4, Math.max(...rows) + 1, true);
17837
+ view.setUint16(dimensions.dataOffset + 8, Math.min(...cols), true);
17838
+ view.setUint16(dimensions.dataOffset + 10, Math.max(...cols) + 1, true);
17839
+ }
17840
+ return finish2(result);
17562
17841
  } catch {
17563
17842
  return inputBytes;
17564
17843
  }
17565
17844
  }
17566
17845
  var init_legacy_excel_biff8_writer = __esm({
17567
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-writer.js"() {
17846
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-excel-biff8-writer.js"() {
17568
17847
  init_legacy_excel_biff8();
17569
17848
  init_legacy_excel_biff8_grid();
17570
17849
  init_legacy_excel_cfb();
@@ -17670,15 +17949,20 @@ var init_ole_document_docx_editor = __esm({
17670
17949
  }
17671
17950
  });
17672
17951
 
17673
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js
17952
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js
17674
17953
  function readDocFib(wordDoc) {
17675
17954
  const view = new DataView(wordDoc.buffer, wordDoc.byteOffset, wordDoc.byteLength);
17676
17955
  const wIdent = view.getUint16(0, true);
17677
17956
  if (wIdent !== 42476) {
17678
17957
  throw new Error("Not a WordDocument FIB (bad wIdent)");
17679
17958
  }
17959
+ const nFibBase = view.getUint16(2, true);
17960
+ if (![193, 217, 257, 268, 274].includes(nFibBase))
17961
+ throw new Error("Unsupported Word FIB version");
17680
17962
  const flags1Offset = 10;
17681
17963
  const flags1 = view.getUint16(flags1Offset, true);
17964
+ if ((flags1 & 33024) !== 0)
17965
+ throw new Error("Encrypted or obfuscated Word document");
17682
17966
  const fWhichTblStm = flags1 >> 9 & 1;
17683
17967
  const csw = view.getUint16(32, true);
17684
17968
  const fibRgW97Offset = 34;
@@ -17687,6 +17971,21 @@ function readDocFib(wordDoc) {
17687
17971
  const fibRgLw97Offset = cslwOffset + 2;
17688
17972
  const cbRgFcLcbCountOffset = fibRgLw97Offset + cslw * 4;
17689
17973
  const fibRgFcLcbOffset = cbRgFcLcbCountOffset + 2;
17974
+ const fibRgFcLcbCount = view.getUint16(cbRgFcLcbCountOffset, true);
17975
+ if (csw !== 14 || cslw !== 22 || fibRgFcLcbOffset + fibRgFcLcbCount * 8 + 2 > wordDoc.length)
17976
+ throw new Error("Truncated Word FIB arrays");
17977
+ const cswNewOffset = fibRgFcLcbOffset + fibRgFcLcbCount * 8;
17978
+ const cswNew = view.getUint16(cswNewOffset, true);
17979
+ if (cswNewOffset + 2 + cswNew * 2 > wordDoc.length)
17980
+ throw new Error("Truncated Word FIB extension");
17981
+ const nFib = cswNew === 0 ? nFibBase : view.getUint16(cswNewOffset + 2, true);
17982
+ const expectedCounts = /* @__PURE__ */ new Map([[193, 93], [217, 108], [257, 136], [268, 164], [274, 183]]);
17983
+ if (expectedCounts.get(nFib) !== fibRgFcLcbCount || cswNew !== 0 && cswNew !== (nFib === 274 ? 5 : 2))
17984
+ throw new Error("Word FIB version and array counts disagree");
17985
+ const ccpText = view.getInt32(fibRgLw97Offset + 12, true);
17986
+ const otherStories = [4, 5, 7, 8, 9, 10].map((i) => view.getInt32(fibRgLw97Offset + i * 4, true));
17987
+ if (ccpText < 0 || otherStories.some((cp) => cp < 0))
17988
+ throw new Error("Negative Word story length");
17690
17989
  function fcLcbPair(index) {
17691
17990
  const off = fibRgFcLcbOffset + index * 8;
17692
17991
  return { fc: view.getUint32(off, true), lcb: view.getUint32(off + 4, true) };
@@ -17694,18 +17993,22 @@ function readDocFib(wordDoc) {
17694
17993
  const cbMacOffset = fibRgLw97Offset + 0;
17695
17994
  const ccpTextOffset = fibRgLw97Offset + 12;
17696
17995
  return {
17996
+ nFib,
17997
+ nFibBase,
17697
17998
  flags1Offset,
17698
17999
  flags1,
17699
18000
  tableStreamName: fWhichTblStm ? "1Table" : "0Table",
17700
18001
  cbMacOffset,
17701
18002
  cbMac: view.getUint32(cbMacOffset, true),
17702
18003
  ccpTextOffset,
17703
- ccpText: view.getInt32(ccpTextOffset, true),
18004
+ ccpText,
18005
+ ccpOtherStories: otherStories.reduce((sum, cp) => sum + cp, 0),
17704
18006
  plcfbteChpx: fcLcbPair(FC_LCB_INDEX.plcfbteChpx),
17705
18007
  plcfbtePapx: fcLcbPair(FC_LCB_INDEX.plcfbtePapx),
17706
18008
  sed: fcLcbPair(FC_LCB_INDEX.sed),
17707
18009
  clx: fcLcbPair(FC_LCB_INDEX.clx),
17708
- fibRgFcLcbOffset
18010
+ fibRgFcLcbOffset,
18011
+ fibRgFcLcbCount
17709
18012
  };
17710
18013
  }
17711
18014
  function fcLcbFieldOffset(fib, key2) {
@@ -17713,6 +18016,9 @@ function fcLcbFieldOffset(fib, key2) {
17713
18016
  }
17714
18017
  function readFcLcbAt(wordDoc, fib, index) {
17715
18018
  const view = new DataView(wordDoc.buffer, wordDoc.byteOffset, wordDoc.byteLength);
18019
+ const count = view.getUint16(fib.fibRgFcLcbOffset - 2, true);
18020
+ if (!Number.isInteger(index) || index < 0 || index >= count || fib.fibRgFcLcbCount !== void 0 && fib.fibRgFcLcbCount !== count)
18021
+ throw new Error("FIB fc/lcb index outside declared array");
17716
18022
  const off = fib.fibRgFcLcbOffset + index * 8;
17717
18023
  return { fc: view.getUint32(off, true), lcb: view.getUint32(off + 4, true) };
17718
18024
  }
@@ -17733,7 +18039,7 @@ function patchDocFib(wordDoc, fib, patch) {
17733
18039
  }
17734
18040
  var FC_LCB_INDEX, F_COMPLEX_BIT;
17735
18041
  var init_ole_document_doc_fib = __esm({
17736
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js"() {
18042
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fib.js"() {
17737
18043
  FC_LCB_INDEX = {
17738
18044
  plcfbteChpx: 12,
17739
18045
  plcfbtePapx: 13,
@@ -17744,62 +18050,578 @@ var init_ole_document_doc_fib = __esm({
17744
18050
  }
17745
18051
  });
17746
18052
 
17747
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js
18053
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-v4.js
18054
+ function follow(table, start) {
18055
+ const ids = [], seen = /* @__PURE__ */ new Set();
18056
+ for (let id = start; id !== END2; id = table[id]) {
18057
+ if (id >= table.length || seen.has(id))
18058
+ throw new Error("Invalid allocation chain");
18059
+ seen.add(id);
18060
+ ids.push(id);
18061
+ }
18062
+ return ids;
18063
+ }
18064
+ function findSlot(slots, path) {
18065
+ let parent = slots.get(0);
18066
+ if (!parent || parent.type !== 5)
18067
+ throw new Error("Invalid root");
18068
+ const parents = /* @__PURE__ */ new Set();
18069
+ for (let part = 0; part < path.length; part++) {
18070
+ if (parents.has(parent.id))
18071
+ throw new Error("Cyclic storage hierarchy");
18072
+ parents.add(parent.id);
18073
+ const stack = [parent.child], seen = /* @__PURE__ */ new Set(), matches = [];
18074
+ while (stack.length) {
18075
+ const id = stack.pop();
18076
+ if (id === FREE)
18077
+ continue;
18078
+ if (seen.has(id))
18079
+ throw new Error("Invalid directory tree");
18080
+ seen.add(id);
18081
+ const slot = slots.get(id);
18082
+ if (!slot)
18083
+ throw new Error("Missing directory slot");
18084
+ if (slot.name.toLocaleLowerCase() === path[part].toLocaleLowerCase())
18085
+ matches.push(slot);
18086
+ stack.push(slot.left, slot.right);
18087
+ }
18088
+ if (matches.length !== 1)
18089
+ throw new Error("Missing or ambiguous stream");
18090
+ parent = matches[0];
18091
+ if (parent.type !== (part === path.length - 1 ? 2 : 1))
18092
+ throw new Error("Invalid storage path");
18093
+ }
18094
+ return parent;
18095
+ }
18096
+ function validateHierarchy(slots) {
18097
+ const owners = /* @__PURE__ */ new Set(), storages = [0];
18098
+ while (storages.length) {
18099
+ const storage = slots.get(storages.pop());
18100
+ const stack = [storage.child], names = /* @__PURE__ */ new Set();
18101
+ while (stack.length) {
18102
+ const id = stack.pop();
18103
+ if (id === FREE)
18104
+ continue;
18105
+ const slot = slots.get(id);
18106
+ if (!slot || slot.type !== 1 && slot.type !== 2 || owners.has(id))
18107
+ throw new Error("Ambiguous directory ownership");
18108
+ const name = slot.name.toLocaleLowerCase();
18109
+ if (names.has(name))
18110
+ throw new Error("Duplicate sibling name");
18111
+ names.add(name);
18112
+ owners.add(id);
18113
+ stack.push(slot.left, slot.right);
18114
+ if (slot.type === 1)
18115
+ storages.push(id);
18116
+ }
18117
+ }
18118
+ if (owners.size !== slots.size - 1)
18119
+ throw new Error("Unreachable directory entries");
18120
+ }
18121
+ function resizeCompoundFileStreamV4(input, path, replacement) {
18122
+ const fail2 = (reason) => ({ ok: false, bytes: input, reason });
18123
+ try {
18124
+ if (input.length < 512 || !path.length || path.some((part) => !part))
18125
+ return fail2("invalid-or-missing-stream");
18126
+ const view = new DataView(input.buffer, input.byteOffset, input.byteLength);
18127
+ const read = (offset) => view.getUint32(offset, true);
18128
+ const version = view.getUint16(26, true);
18129
+ if (version !== 4)
18130
+ return fail2("unsupported-version");
18131
+ const SECTOR3 = 4096, FAT_ENTRIES2 = SECTOR3 / 4, DIRECTORY_ENTRIES = SECTOR3 / 128;
18132
+ if (read(72) !== 0 || read(44) > 109)
18133
+ return fail2("unsupported-difat");
18134
+ const cutoff = read(56);
18135
+ if (cutoff !== 0 && cutoff !== 4096)
18136
+ return fail2("unsupported-layout");
18137
+ const original = readCompoundFileStream(input, path);
18138
+ if (!original)
18139
+ return fail2("invalid-or-missing-stream");
18140
+ const name = path[path.length - 1].toLocaleLowerCase();
18141
+ if (name === "worddocument" && original.length >= 12 && (original[10] | original[11] << 8) & 33024)
18142
+ return fail2("unsafe-edit");
18143
+ if (name === "book" || name === "workbook") {
18144
+ for (let offset = 0; offset + 4 <= original.length; ) {
18145
+ const record2 = original[offset] | original[offset + 1] << 8;
18146
+ const length = original[offset + 2] | original[offset + 3] << 8;
18147
+ if (record2 === 47)
18148
+ return fail2("unsafe-edit");
18149
+ if (record2 === 10 || offset + 4 + length > original.length)
18150
+ break;
18151
+ offset += 4 + length;
18152
+ }
18153
+ }
18154
+ const validated = replaceCompoundFileStream(input, path, original);
18155
+ if (validated === input)
18156
+ return fail2("unsafe-edit");
18157
+ const sameLength = replacement.length === original.length;
18158
+ if (!sameLength && original.length < cutoff)
18159
+ return fail2("unsupported-mini-stream");
18160
+ if (!sameLength && replacement.length < cutoff)
18161
+ return fail2("unsupported-mini-transition");
18162
+ const sectorCount = input.length / SECTOR3 - 1, fatCount = read(44);
18163
+ if (sectorCount > fatCount * FAT_ENTRIES2)
18164
+ return fail2("unsafe-edit");
18165
+ const fatIds = Array.from({ length: fatCount }, (_, i) => read(76 + 4 * i));
18166
+ const fat = [];
18167
+ for (const id of fatIds) {
18168
+ for (let i = 0; i < FAT_ENTRIES2 && fat.length < sectorCount; i++)
18169
+ fat.push(read((id + 1) * SECTOR3 + i * 4));
18170
+ }
18171
+ if (fatIds.some((id) => fat[id] !== FAT))
18172
+ return fail2("unsafe-edit");
18173
+ const slots = /* @__PURE__ */ new Map();
18174
+ const directoryChain = follow(fat, read(48));
18175
+ if (read(40) !== directoryChain.length)
18176
+ return fail2("unsafe-edit");
18177
+ for (const [block, sector] of directoryChain.entries()) {
18178
+ for (let entry = 0; entry < DIRECTORY_ENTRIES; entry++) {
18179
+ const offset = (sector + 1) * SECTOR3 + entry * 128, type = view.getUint8(offset + 66);
18180
+ if (!type)
18181
+ continue;
18182
+ const nameLength = view.getUint16(offset + 64, true);
18183
+ if (![1, 2, 5].includes(type) || nameLength < 2 || nameLength > 64 || nameLength % 2 || view.getUint16(offset + nameLength - 2, true))
18184
+ return fail2("unsafe-edit");
18185
+ let name2 = "";
18186
+ for (let i = 0; i < nameLength - 2; i += 2)
18187
+ name2 += String.fromCharCode(view.getUint16(offset + i, true));
18188
+ if (read(offset + 124) !== 0)
18189
+ return fail2("unsafe-edit");
18190
+ const id = block * DIRECTORY_ENTRIES + entry;
18191
+ 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 });
18192
+ }
18193
+ }
18194
+ if ([...slots.values()].filter((slot) => slot.type === 5).length !== 1)
18195
+ return fail2("unsafe-edit");
18196
+ const target = findSlot(slots, path);
18197
+ validateHierarchy(slots);
18198
+ if (sameLength) {
18199
+ const bytes = replaceCompoundFileStream(input, path, replacement);
18200
+ return bytes === input ? fail2("unsafe-edit") : { ok: true, bytes };
18201
+ }
18202
+ const oldChain = follow(fat, target.start);
18203
+ if (target.size !== original.length || oldChain.length !== Math.ceil(target.size / SECTOR3))
18204
+ return fail2("unsafe-edit");
18205
+ const payloadSectors = Math.ceil(replacement.length / SECTOR3);
18206
+ let newFatCount = fatCount;
18207
+ while (sectorCount + payloadSectors + newFatCount - fatCount > newFatCount * FAT_ENTRIES2)
18208
+ newFatCount++;
18209
+ if (newFatCount > 109)
18210
+ return fail2("allocation-limit");
18211
+ const totalSectors = sectorCount + payloadSectors + newFatCount - fatCount;
18212
+ const output = new Uint8Array((totalSectors + 1) * SECTOR3);
18213
+ output.set(input);
18214
+ output.set(replacement, (sectorCount + 1) * SECTOR3);
18215
+ const outView = new DataView(output.buffer);
18216
+ for (let i = fatCount; i < newFatCount; i++) {
18217
+ const id = sectorCount + payloadSectors + i - fatCount;
18218
+ fatIds.push(id);
18219
+ output.fill(255, (id + 1) * SECTOR3, (id + 2) * SECTOR3);
18220
+ outView.setUint32(76 + i * 4, id, true);
18221
+ }
18222
+ outView.setUint32(44, newFatCount, true);
18223
+ const writeFat = (id, value) => outView.setUint32((fatIds[Math.floor(id / FAT_ENTRIES2)] + 1) * SECTOR3 + id % FAT_ENTRIES2 * 4, value, true);
18224
+ for (const id of oldChain)
18225
+ writeFat(id, FREE);
18226
+ for (let i = 0; i < payloadSectors; i++)
18227
+ writeFat(sectorCount + i, i + 1 === payloadSectors ? END2 : sectorCount + i + 1);
18228
+ for (const id of fatIds)
18229
+ writeFat(id, FAT);
18230
+ outView.setUint32(target.offset + 116, payloadSectors ? sectorCount : END2, true);
18231
+ outView.setUint32(target.offset + 120, replacement.length, true);
18232
+ return { ok: true, bytes: output };
18233
+ } catch {
18234
+ return fail2("unsafe-edit");
18235
+ }
18236
+ }
18237
+ var END2, FREE, FAT;
18238
+ var init_ole2_stream_resize_v4 = __esm({
18239
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-v4.js"() {
18240
+ init_ole2_stream_edit();
18241
+ END2 = 4294967294;
18242
+ FREE = 4294967295;
18243
+ FAT = 4294967293;
18244
+ }
18245
+ });
18246
+
18247
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-allocation.js
18248
+ function appendCompoundAllocations(input, existingFatIds, payloads, sectorSize = 512) {
18249
+ const sectorCount = input.length / sectorSize - 1;
18250
+ const entriesPerFat = sectorSize / 4;
18251
+ const counts = payloads.map((payload) => Math.ceil(payload.length / sectorSize));
18252
+ const payloadSectors = counts.reduce((sum, count) => sum + count, 0);
18253
+ let fatCount = existingFatIds.length;
18254
+ while (sectorCount + payloadSectors + fatCount - existingFatIds.length > fatCount * entriesPerFat)
18255
+ fatCount++;
18256
+ if (fatCount > 109)
18257
+ return void 0;
18258
+ const totalSectors = sectorCount + payloadSectors + fatCount - existingFatIds.length;
18259
+ const bytes = new Uint8Array((totalSectors + 1) * sectorSize);
18260
+ bytes.set(input);
18261
+ const view = new DataView(bytes.buffer), fatIds = [...existingFatIds];
18262
+ for (let i = existingFatIds.length; i < fatCount; i++) {
18263
+ const id = sectorCount + payloadSectors + i - existingFatIds.length;
18264
+ fatIds.push(id);
18265
+ bytes.fill(255, (id + 1) * sectorSize, (id + 2) * sectorSize);
18266
+ view.setUint32(76 + i * 4, id, true);
18267
+ }
18268
+ view.setUint32(44, fatCount, true);
18269
+ const writeFat = (id, value) => view.setUint32((fatIds[Math.floor(id / entriesPerFat)] + 1) * sectorSize + id % entriesPerFat * 4, value, true);
18270
+ const chains = [];
18271
+ let next = sectorCount;
18272
+ for (let payload = 0; payload < payloads.length; payload++) {
18273
+ bytes.set(payloads[payload], (next + 1) * sectorSize);
18274
+ const chain2 = Array.from({ length: counts[payload] }, (_, i) => next + i);
18275
+ chain2.forEach((id, i) => writeFat(id, chain2[i + 1] ?? 4294967294));
18276
+ chains.push(chain2);
18277
+ next += counts[payload];
18278
+ }
18279
+ for (const id of fatIds)
18280
+ writeFat(id, 4294967293);
18281
+ return { bytes, view, chains, writeFat };
18282
+ }
18283
+ function followCompoundAllocation(table, start) {
18284
+ const ids = [], seen = /* @__PURE__ */ new Set();
18285
+ for (let id = start; id !== 4294967294; id = table[id]) {
18286
+ if (id >= table.length || seen.has(id))
18287
+ throw new Error("Invalid allocation chain");
18288
+ seen.add(id);
18289
+ ids.push(id);
18290
+ }
18291
+ return ids;
18292
+ }
18293
+ var init_ole2_stream_resize_allocation = __esm({
18294
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-allocation.js"() {
18295
+ }
18296
+ });
18297
+
18298
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-mini.js
18299
+ function resizeMiniCompoundStream(input, fat, fatIds, root, target, replacement, cutoff) {
18300
+ const inputView = new DataView(input.buffer, input.byteOffset, input.byteLength);
18301
+ const miniFatCount = inputView.getUint32(64, true);
18302
+ const miniFatSectors = miniFatCount ? followCompoundAllocation(fat, inputView.getUint32(60, true)) : [];
18303
+ if (miniFatSectors.length !== miniFatCount)
18304
+ throw new Error("Invalid mini FAT count");
18305
+ const rootSectors = root.size ? followCompoundAllocation(fat, root.start) : [];
18306
+ if (rootSectors.length !== Math.ceil(root.size / SECTOR))
18307
+ throw new Error("Invalid root mini stream");
18308
+ const miniCapacity = Math.floor(root.size / MINI), miniFat = [];
18309
+ for (const id of miniFatSectors) {
18310
+ for (let slot = 0; slot < SECTOR / 4 && miniFat.length < miniCapacity; slot++)
18311
+ miniFat.push(inputView.getUint32((id + 1) * SECTOR + slot * 4, true));
18312
+ }
18313
+ const wasMini = target.size < cutoff;
18314
+ const oldChain = followCompoundAllocation(wasMini ? miniFat : fat, target.start);
18315
+ if (oldChain.length !== Math.ceil(target.size / (wasMini ? MINI : SECTOR)))
18316
+ throw new Error("Invalid stream allocation");
18317
+ if (!replacement.length) {
18318
+ const bytes = input.slice(), view = new DataView(bytes.buffer);
18319
+ for (const id of oldChain) {
18320
+ const table = wasMini ? miniFatSectors : fatIds;
18321
+ view.setUint32((table[Math.floor(id / 128)] + 1) * SECTOR + id % 128 * 4, FREE2, true);
18322
+ }
18323
+ view.setUint32(target.offset + 116, END3, true);
18324
+ view.setUint32(target.offset + 120, 0, true);
18325
+ return bytes;
18326
+ }
18327
+ if (replacement.length >= cutoff) {
18328
+ const output2 = appendCompoundAllocations(input, fatIds, [replacement]);
18329
+ if (!output2)
18330
+ return void 0;
18331
+ for (const id of oldChain)
18332
+ output2.view.setUint32((miniFatSectors[Math.floor(id / 128)] + 1) * SECTOR + id % 128 * 4, FREE2, true);
18333
+ output2.view.setUint32(target.offset + 116, output2.chains[0][0] ?? END3, true);
18334
+ output2.view.setUint32(target.offset + 120, replacement.length, true);
18335
+ return output2.bytes;
18336
+ }
18337
+ const firstMini = Math.ceil(root.size / MINI), count = Math.ceil(replacement.length / MINI);
18338
+ const newRootSize = count ? (firstMini + count) * MINI : root.size;
18339
+ const newRoot = new Uint8Array(newRootSize);
18340
+ rootSectors.forEach((id, i) => newRoot.set(input.subarray((id + 1) * SECTOR, (id + 1) * SECTOR + Math.min(SECTOR, root.size - i * SECTOR)), i * SECTOR));
18341
+ if (count)
18342
+ newRoot.set(replacement, firstMini * MINI);
18343
+ const newMiniFatCount = Math.max(miniFatCount, Math.ceil((firstMini + count) / 128));
18344
+ const newMiniFat = new Uint8Array(newMiniFatCount * SECTOR).fill(255);
18345
+ miniFatSectors.forEach((id, i) => newMiniFat.set(input.subarray((id + 1) * SECTOR, (id + 2) * SECTOR), i * SECTOR));
18346
+ const miniView = new DataView(newMiniFat.buffer);
18347
+ if (wasMini)
18348
+ for (const id of oldChain)
18349
+ miniView.setUint32(id * 4, FREE2, true);
18350
+ for (let i = 0; i < count; i++)
18351
+ miniView.setUint32((firstMini + i) * 4, i + 1 === count ? END3 : firstMini + i + 1, true);
18352
+ const output = appendCompoundAllocations(input, fatIds, [newRoot, newMiniFat]);
18353
+ if (!output)
18354
+ return void 0;
18355
+ for (const id of [...rootSectors, ...miniFatSectors, ...wasMini ? [] : oldChain])
18356
+ output.writeFat(id, FREE2);
18357
+ output.view.setUint32(root.offset + 116, output.chains[0][0] ?? END3, true);
18358
+ output.view.setUint32(root.offset + 120, newRootSize, true);
18359
+ output.view.setUint32(60, output.chains[1][0] ?? END3, true);
18360
+ output.view.setUint32(64, newMiniFatCount, true);
18361
+ output.view.setUint32(target.offset + 116, count ? firstMini : END3, true);
18362
+ output.view.setUint32(target.offset + 120, replacement.length, true);
18363
+ return output.bytes;
18364
+ }
18365
+ var END3, FREE2, SECTOR, MINI;
18366
+ var init_ole2_stream_resize_mini = __esm({
18367
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize-mini.js"() {
18368
+ init_ole2_stream_resize_allocation();
18369
+ END3 = 4294967294;
18370
+ FREE2 = 4294967295;
18371
+ SECTOR = 512;
18372
+ MINI = 64;
18373
+ }
18374
+ });
18375
+
18376
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize.js
18377
+ function follow2(table, start) {
18378
+ const ids = [], seen = /* @__PURE__ */ new Set();
18379
+ for (let id = start; id !== END4; id = table[id]) {
18380
+ if (id >= table.length || seen.has(id))
18381
+ throw new Error("Invalid allocation chain");
18382
+ seen.add(id);
18383
+ ids.push(id);
18384
+ }
18385
+ return ids;
18386
+ }
18387
+ function findSlot2(slots, path) {
18388
+ let parent = slots.get(0);
18389
+ if (!parent || parent.type !== 5)
18390
+ throw new Error("Invalid root");
18391
+ const parents = /* @__PURE__ */ new Set();
18392
+ for (let part = 0; part < path.length; part++) {
18393
+ if (parents.has(parent.id))
18394
+ throw new Error("Cyclic storage hierarchy");
18395
+ parents.add(parent.id);
18396
+ const stack = [parent.child], seen = /* @__PURE__ */ new Set(), matches = [];
18397
+ while (stack.length) {
18398
+ const id = stack.pop();
18399
+ if (id === FREE3)
18400
+ continue;
18401
+ if (seen.has(id))
18402
+ throw new Error("Invalid directory tree");
18403
+ seen.add(id);
18404
+ const slot = slots.get(id);
18405
+ if (!slot)
18406
+ throw new Error("Missing directory slot");
18407
+ if (slot.name.toLocaleLowerCase() === path[part].toLocaleLowerCase())
18408
+ matches.push(slot);
18409
+ stack.push(slot.left, slot.right);
18410
+ }
18411
+ if (matches.length !== 1)
18412
+ throw new Error("Missing or ambiguous stream");
18413
+ parent = matches[0];
18414
+ if (parent.type !== (part === path.length - 1 ? 2 : 1))
18415
+ throw new Error("Invalid storage path");
18416
+ }
18417
+ return parent;
18418
+ }
18419
+ function validateHierarchy2(slots) {
18420
+ const owners = /* @__PURE__ */ new Set(), storages = [0];
18421
+ while (storages.length) {
18422
+ const storage = slots.get(storages.pop());
18423
+ const stack = [storage.child], names = /* @__PURE__ */ new Set();
18424
+ while (stack.length) {
18425
+ const id = stack.pop();
18426
+ if (id === FREE3)
18427
+ continue;
18428
+ const slot = slots.get(id);
18429
+ if (!slot || slot.type !== 1 && slot.type !== 2 || owners.has(id))
18430
+ throw new Error("Ambiguous directory ownership");
18431
+ const name = slot.name.toLocaleLowerCase();
18432
+ if (names.has(name))
18433
+ throw new Error("Duplicate sibling name");
18434
+ names.add(name);
18435
+ owners.add(id);
18436
+ stack.push(slot.left, slot.right);
18437
+ if (slot.type === 1)
18438
+ storages.push(id);
18439
+ }
18440
+ }
18441
+ if (owners.size !== slots.size - 1)
18442
+ throw new Error("Unreachable directory entries");
18443
+ }
18444
+ function resizeCompoundFileStream(input, path, replacement) {
18445
+ if (input.length >= 512 && new DataView(input.buffer, input.byteOffset, input.byteLength).getUint16(26, true) === 4)
18446
+ return resizeCompoundFileStreamV4(input, path, replacement);
18447
+ const fail2 = (reason) => ({ ok: false, bytes: input, reason });
18448
+ try {
18449
+ if (input.length < SECTOR2 || !path.length || path.some((part) => !part))
18450
+ return fail2("invalid-or-missing-stream");
18451
+ const view = new DataView(input.buffer, input.byteOffset, input.byteLength);
18452
+ const read = (offset) => view.getUint32(offset, true);
18453
+ if (view.getUint16(26, true) !== 3)
18454
+ return fail2("unsupported-version");
18455
+ if (read(72) !== 0 || read(44) > 109)
18456
+ return fail2("unsupported-difat");
18457
+ const cutoff = read(56);
18458
+ if (cutoff !== 0 && cutoff !== 4096)
18459
+ return fail2("unsupported-layout");
18460
+ const original = readCompoundFileStream(input, path);
18461
+ if (!original)
18462
+ return fail2("invalid-or-missing-stream");
18463
+ const name = path[path.length - 1].toLocaleLowerCase();
18464
+ if (name === "worddocument" && original.length >= 12 && (original[10] | original[11] << 8) & 33024)
18465
+ return fail2("unsafe-edit");
18466
+ if (name === "book" || name === "workbook") {
18467
+ for (let offset = 0; offset + 4 <= original.length; ) {
18468
+ const record2 = original[offset] | original[offset + 1] << 8;
18469
+ const length = original[offset + 2] | original[offset + 3] << 8;
18470
+ if (record2 === 47)
18471
+ return fail2("unsafe-edit");
18472
+ if (record2 === 10 || offset + 4 + length > original.length)
18473
+ break;
18474
+ offset += 4 + length;
18475
+ }
18476
+ }
18477
+ const validated = replaceCompoundFileStream(input, path, original);
18478
+ if (validated === input)
18479
+ return fail2("unsafe-edit");
18480
+ const sameLength = replacement.length === original.length;
18481
+ const sectorCount = input.length / SECTOR2 - 1, fatCount = read(44);
18482
+ if (sectorCount > fatCount * FAT_ENTRIES)
18483
+ return fail2("unsafe-edit");
18484
+ const fatIds = Array.from({ length: fatCount }, (_, i) => read(76 + 4 * i));
18485
+ const fat = [];
18486
+ for (const id of fatIds) {
18487
+ for (let i = 0; i < FAT_ENTRIES && fat.length < sectorCount; i++)
18488
+ fat.push(read((id + 1) * SECTOR2 + i * 4));
18489
+ }
18490
+ if (fatIds.some((id) => fat[id] !== FAT2))
18491
+ return fail2("unsafe-edit");
18492
+ const slots = /* @__PURE__ */ new Map();
18493
+ for (const [block, sector] of follow2(fat, read(48)).entries()) {
18494
+ for (let entry = 0; entry < 4; entry++) {
18495
+ const offset = (sector + 1) * SECTOR2 + entry * 128, type = view.getUint8(offset + 66);
18496
+ if (!type)
18497
+ continue;
18498
+ const nameLength = view.getUint16(offset + 64, true);
18499
+ if (![1, 2, 5].includes(type) || nameLength < 2 || nameLength > 64 || nameLength % 2 || view.getUint16(offset + nameLength - 2, true))
18500
+ return fail2("unsafe-edit");
18501
+ let name2 = "";
18502
+ for (let i = 0; i < nameLength - 2; i += 2)
18503
+ name2 += String.fromCharCode(view.getUint16(offset + i, true));
18504
+ const id = block * 4 + entry;
18505
+ 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 });
18506
+ }
18507
+ }
18508
+ if ([...slots.values()].filter((slot) => slot.type === 5).length !== 1)
18509
+ return fail2("unsafe-edit");
18510
+ const target = findSlot2(slots, path);
18511
+ validateHierarchy2(slots);
18512
+ if (sameLength) {
18513
+ const bytes = replaceCompoundFileStream(input, path, replacement);
18514
+ return bytes === input ? fail2("unsafe-edit") : { ok: true, bytes };
18515
+ }
18516
+ if (original.length < cutoff || replacement.length < cutoff) {
18517
+ const bytes = resizeMiniCompoundStream(input, fat, fatIds, slots.get(0), target, replacement, cutoff);
18518
+ return bytes ? { ok: true, bytes } : fail2("allocation-limit");
18519
+ }
18520
+ const oldChain = follow2(fat, target.start);
18521
+ if (target.size !== original.length || oldChain.length !== Math.ceil(target.size / SECTOR2))
18522
+ return fail2("unsafe-edit");
18523
+ const output = appendCompoundAllocations(input, fatIds, [replacement]);
18524
+ if (!output)
18525
+ return fail2("allocation-limit");
18526
+ for (const id of oldChain)
18527
+ output.writeFat(id, FREE3);
18528
+ output.view.setUint32(target.offset + 116, output.chains[0][0] ?? END4, true);
18529
+ output.view.setUint32(target.offset + 120, replacement.length, true);
18530
+ return { ok: true, bytes: output.bytes };
18531
+ } catch {
18532
+ return fail2("unsafe-edit");
18533
+ }
18534
+ }
18535
+ var END4, FREE3, FAT2, SECTOR2, FAT_ENTRIES;
18536
+ var init_ole2_stream_resize = __esm({
18537
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-stream-resize.js"() {
18538
+ init_ole2_stream_edit();
18539
+ init_ole2_stream_resize_v4();
18540
+ init_ole2_stream_resize_allocation();
18541
+ init_ole2_stream_resize_mini();
18542
+ END4 = 4294967294;
18543
+ FREE3 = 4294967295;
18544
+ FAT2 = 4294967293;
18545
+ SECTOR2 = 512;
18546
+ FAT_ENTRIES = SECTOR2 / 4;
18547
+ }
18548
+ });
18549
+
18550
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js
17748
18551
  function unwrapDocBytes(bytes) {
17749
18552
  if (bytes.length < 8 || bytes[0] !== 208 || bytes[1] !== 207 || bytes[2] !== 17 || bytes[3] !== 224 || bytes[4] !== 161 || bytes[5] !== 177 || bytes[6] !== 26 || bytes[7] !== 225) {
17750
18553
  return void 0;
17751
18554
  }
17752
18555
  try {
17753
- const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
17754
- const ole = parseOle2(buffer);
17755
- const wordDocBytes = ole.getStream("WordDocument");
18556
+ const wordDocBytes = readCompoundFileStream(bytes, ["WordDocument"]);
17756
18557
  if (!wordDocBytes) {
17757
18558
  return void 0;
17758
18559
  }
17759
18560
  const fib = readDocFib(wordDocBytes);
17760
- const tableBytes = ole.getStream(fib.tableStreamName);
18561
+ const tableBytes = readCompoundFileStream(bytes, [fib.tableStreamName]);
17761
18562
  if (!tableBytes) {
17762
18563
  return void 0;
17763
18564
  }
17764
- const rootClsid = ole.entries.find((e) => e.type === ENTRY_TYPE_ROOT)?.clsid;
18565
+ const header = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
18566
+ const cutoff = header.getUint32(56, true);
18567
+ const canRewrite = header.getUint16(26, true) === 3 && header.getUint32(72, true) === 0 && header.getUint32(44, true) <= 109 && (cutoff === 0 || cutoff === 4096) && wordDocBytes.length >= cutoff && tableBytes.length >= cutoff;
17765
18568
  return {
17766
18569
  wordDocBytes,
17767
18570
  tableStreamName: fib.tableStreamName,
17768
18571
  tableBytes,
18572
+ canRewrite,
17769
18573
  rewrap: (editedWordDocBytes, editedTableBytes) => {
17770
- const streams2 = /* @__PURE__ */ new Map();
17771
- for (const entry of ole.entries) {
17772
- if (entry.type !== ENTRY_TYPE_STREAM) {
17773
- continue;
17774
- }
17775
- const data = entry.name === "WordDocument" ? editedWordDocBytes : entry.name === fib.tableStreamName ? editedTableBytes : ole.getStream(entry.name);
17776
- if (data) {
17777
- streams2.set(entry.name, data);
17778
- }
17779
- }
17780
- return new Uint8Array(buildOle2(streams2, rootClsid));
18574
+ if (editedWordDocBytes.length === wordDocBytes.length && editedTableBytes.length === tableBytes.length) {
18575
+ const patchedWord = replaceCompoundFileStream(bytes, ["WordDocument"], editedWordDocBytes);
18576
+ if (patchedWord === bytes)
18577
+ throw new DocCfbRewriteError("Cannot safely patch WordDocument");
18578
+ if (editedTableBytes.every((value, i) => value === tableBytes[i]))
18579
+ return patchedWord;
18580
+ const patchedTable = replaceCompoundFileStream(patchedWord, [fib.tableStreamName], editedTableBytes);
18581
+ if (patchedTable === patchedWord)
18582
+ throw new DocCfbRewriteError("Cannot safely patch DOC table stream");
18583
+ return patchedTable;
18584
+ }
18585
+ const word = resizeCompoundFileStream(bytes, ["WordDocument"], editedWordDocBytes);
18586
+ if (!word.ok)
18587
+ throw new DocCfbRewriteError(`Cannot resize WordDocument: ${word.reason}`);
18588
+ const table = resizeCompoundFileStream(word.bytes, [fib.tableStreamName], editedTableBytes);
18589
+ if (!table.ok)
18590
+ throw new DocCfbRewriteError(`Cannot resize DOC table stream: ${table.reason}`);
18591
+ return table.bytes;
17781
18592
  }
17782
18593
  };
17783
18594
  } catch {
17784
18595
  return void 0;
17785
18596
  }
17786
18597
  }
18598
+ var DocCfbRewriteError;
17787
18599
  var init_ole_document_doc_cfb = __esm({
17788
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js"() {
18600
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cfb.js"() {
17789
18601
  init_ole_document_doc_fib();
17790
- init_ole2_parser_read();
17791
- init_ole2_parser_types();
17792
- init_ole2_parser_write();
18602
+ init_ole2_stream_edit();
18603
+ init_ole2_stream_resize();
18604
+ DocCfbRewriteError = class extends Error {
18605
+ constructor(message) {
18606
+ super(message);
18607
+ this.name = "DocCfbRewriteError";
18608
+ }
18609
+ };
17793
18610
  }
17794
18611
  });
17795
18612
 
17796
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js
18613
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js
17797
18614
  function parseBteTable(tableStream, at2) {
17798
18615
  const view = new DataView(tableStream.buffer, tableStream.byteOffset, tableStream.byteLength);
17799
- const n = Math.floor((at2.lcb - 4) / (4 + 4));
18616
+ if (!Number.isInteger(at2.fc) || !Number.isInteger(at2.lcb) || at2.fc < 0 || at2.lcb < 4 || (at2.lcb - 4) % 8 !== 0 || at2.fc > tableStream.length - at2.lcb)
18617
+ throw new Error("Invalid BTE table bounds");
18618
+ const n = (at2.lcb - 4) / 8;
17800
18619
  const fcs = [];
17801
18620
  for (let i = 0; i <= n; i++) {
17802
- fcs.push(view.getInt32(at2.fc + i * 4, true));
18621
+ const fc = view.getInt32(at2.fc + i * 4, true);
18622
+ if (fc < 0 || i > 0 && fc <= fcs[i - 1])
18623
+ throw new Error("Invalid BTE FC boundaries");
18624
+ fcs.push(fc);
17803
18625
  }
17804
18626
  const pns = [];
17805
18627
  for (let i = 0; i < n; i++) {
@@ -17820,10 +18642,17 @@ function buildBteTableBytes(table) {
17820
18642
  return bytes;
17821
18643
  }
17822
18644
  function findBteRangeIndex(table, fc) {
17823
- for (let i = 0; i < table.pns.length; i++) {
17824
- if (fc >= table.fcs[i] && fc < table.fcs[i + 1]) {
17825
- return i;
17826
- }
18645
+ let low = 0, high = table.pns.length;
18646
+ while (low < high) {
18647
+ const middle = low + Math.floor((high - low) / 2);
18648
+ if (fc < table.fcs[middle])
18649
+ high = middle;
18650
+ else if (fc >= table.fcs[middle + 1])
18651
+ low = middle + 1;
18652
+ else if (fc >= table.fcs[middle])
18653
+ return middle;
18654
+ else
18655
+ break;
17827
18656
  }
17828
18657
  throw new Error(`FC ${fc} is not covered by any BTE range`);
17829
18658
  }
@@ -17839,7 +18668,11 @@ function extractPapxBlob(wordDoc, papxBte, fc) {
17839
18668
  const rangeIndex = findBteRangeIndex(papxBte, fc);
17840
18669
  const pageOffset = papxBte.pns[rangeIndex] * PAGE_SIZE;
17841
18670
  const page = wordDoc.subarray(pageOffset, pageOffset + PAGE_SIZE);
18671
+ if (page.length !== PAGE_SIZE)
18672
+ throw new Error("Truncated PAPX page");
17842
18673
  const crun = page[PAGE_SIZE - 1];
18674
+ if (crun === 0 || (crun + 1) * 4 + crun * 13 > 511)
18675
+ throw new Error("Invalid PAPX run count");
17843
18676
  const pageView = new DataView(page.buffer, page.byteOffset, page.byteLength);
17844
18677
  const rgbxOffset = (crun + 1) * 4;
17845
18678
  for (let i = 0; i < crun; i++) {
@@ -17847,8 +18680,13 @@ function extractPapxBlob(wordDoc, papxBte, fc) {
17847
18680
  const runFcEnd = pageView.getInt32((i + 1) * 4, true);
17848
18681
  if (fc >= runFcStart && fc < runFcEnd) {
17849
18682
  const bOffsetWord = page[rgbxOffset + i * 13];
18683
+ if (bOffsetWord === 0)
18684
+ return new Uint8Array();
17850
18685
  const blobOffset = bOffsetWord * 2;
17851
- return page.slice(blobOffset, blobOffset + papxBlobLength(page, blobOffset));
18686
+ const blobLength = papxBlobLength(page, blobOffset);
18687
+ if (blobOffset < rgbxOffset + crun * 13 || !Number.isInteger(blobLength) || blobOffset + blobLength > 511)
18688
+ throw new Error("Invalid PAPX blob bounds");
18689
+ return page.slice(blobOffset, blobOffset + blobLength);
17852
18690
  }
17853
18691
  }
17854
18692
  throw new Error(`FC ${fc} is not covered by any run in PAPX page ${papxBte.pns[rangeIndex]}`);
@@ -17857,7 +18695,11 @@ function extractChpxBlob(wordDoc, chpxBte, fc) {
17857
18695
  const rangeIndex = findBteRangeIndex(chpxBte, fc);
17858
18696
  const pageOffset = chpxBte.pns[rangeIndex] * PAGE_SIZE;
17859
18697
  const page = wordDoc.subarray(pageOffset, pageOffset + PAGE_SIZE);
18698
+ if (page.length !== PAGE_SIZE)
18699
+ throw new Error("Truncated CHPX page");
17860
18700
  const crun = page[PAGE_SIZE - 1];
18701
+ if (crun === 0 || (crun + 1) * 4 + crun > 511)
18702
+ throw new Error("Invalid CHPX run count");
17861
18703
  const pageView = new DataView(page.buffer, page.byteOffset, page.byteLength);
17862
18704
  const rgbOffset = (crun + 1) * 4;
17863
18705
  for (let i = 0; i < crun; i++) {
@@ -17870,6 +18712,8 @@ function extractChpxBlob(wordDoc, chpxBte, fc) {
17870
18712
  }
17871
18713
  const blobOffset = bOffsetWord * 2;
17872
18714
  const cb = page[blobOffset];
18715
+ if (blobOffset < rgbOffset + crun || blobOffset + 1 + cb > 511)
18716
+ throw new Error("Invalid CHPX blob bounds");
17873
18717
  return page.slice(blobOffset, blobOffset + 1 + cb);
17874
18718
  }
17875
18719
  }
@@ -17881,8 +18725,12 @@ function buildSingleRunPapxPage(fcStart, fcEnd, blob) {
17881
18725
  view.setInt32(0, fcStart, true);
17882
18726
  view.setInt32(4, fcEnd, true);
17883
18727
  const blobByteOffset = 22;
17884
- page[8] = blobByteOffset / 2;
17885
- page.set(blob, blobByteOffset);
18728
+ if (blob.length > 511 - blobByteOffset)
18729
+ throw new Error("PAPX blob exceeds page capacity");
18730
+ if (blob.length > 0) {
18731
+ page[8] = blobByteOffset / 2;
18732
+ page.set(blob, blobByteOffset);
18733
+ }
17886
18734
  page[PAGE_SIZE - 1] = 1;
17887
18735
  return page;
17888
18736
  }
@@ -17893,6 +18741,8 @@ function buildSingleRunChpxPage(fcStart, fcEnd, blob) {
17893
18741
  view.setInt32(4, fcEnd, true);
17894
18742
  if (blob.length > 0) {
17895
18743
  const blobByteOffset = 10;
18744
+ if (blob.length > 511 - blobByteOffset)
18745
+ throw new Error("CHPX blob exceeds page capacity");
17896
18746
  page[8] = blobByteOffset / 2;
17897
18747
  page.set(blob, blobByteOffset);
17898
18748
  }
@@ -17901,12 +18751,12 @@ function buildSingleRunChpxPage(fcStart, fcEnd, blob) {
17901
18751
  }
17902
18752
  var PAGE_SIZE;
17903
18753
  var init_ole_document_doc_fkp = __esm({
17904
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js"() {
18754
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fkp.js"() {
17905
18755
  PAGE_SIZE = 512;
17906
18756
  }
17907
18757
  });
17908
18758
 
17909
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js
18759
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js
17910
18760
  function decodeCp1252Byte(byte) {
17911
18761
  if (byte >= 128 && byte <= 159) {
17912
18762
  return CP1252_HIGH_BLOCK[byte - 128];
@@ -17940,7 +18790,7 @@ function encodeCp1252(text2) {
17940
18790
  }
17941
18791
  var CP1252_HIGH_BLOCK, CP1252_HIGH_BLOCK_REVERSE;
17942
18792
  var init_ole_document_doc_cp1252 = __esm({
17943
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js"() {
18793
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-cp1252.js"() {
17944
18794
  CP1252_HIGH_BLOCK = [
17945
18795
  8364,
17946
18796
  129,
@@ -17979,21 +18829,42 @@ var init_ole_document_doc_cp1252 = __esm({
17979
18829
  }
17980
18830
  });
17981
18831
 
17982
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js
17983
- function parsePieceTable(tableStream, clx) {
18832
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js
18833
+ function parseDocClx(tableStream, clx, maxPieces) {
18834
+ if (maxPieces !== void 0 && (!Number.isSafeInteger(maxPieces) || maxPieces < 0))
18835
+ throw new Error("Invalid DOC piece limit");
17984
18836
  const view = new DataView(tableStream.buffer, tableStream.byteOffset, tableStream.byteLength);
18837
+ if (!Number.isInteger(clx.fc) || !Number.isInteger(clx.lcb) || clx.fc < 0 || clx.lcb < 5 || clx.fc > tableStream.length - clx.lcb)
18838
+ throw new Error("Clx is outside the table stream");
17985
18839
  let off = clx.fc;
17986
18840
  const end = clx.fc + clx.lcb;
18841
+ let prcCount = 0;
17987
18842
  while (off < end) {
17988
18843
  const clxt = view.getUint8(off);
17989
18844
  if (clxt === CLXT_PRC) {
18845
+ if (off + 3 > end)
18846
+ throw new Error("Truncated Prc header");
17990
18847
  const cb = view.getUint16(off + 1, true);
18848
+ if (cb > end - off - 3)
18849
+ throw new Error("Prc extends beyond Clx");
17991
18850
  off += 1 + 2 + cb;
18851
+ prcCount++;
17992
18852
  continue;
17993
18853
  }
17994
18854
  if (clxt === CLXT_PCDT) {
18855
+ if (off + 5 > end)
18856
+ throw new Error("Truncated Pcdt header");
17995
18857
  const lcb = view.getInt32(off + 1, true);
17996
- return parsePlcPcd(view, off + 1 + 4, lcb);
18858
+ if (lcb < 4 || (lcb - 4) % 12 !== 0 || lcb !== end - off - 5)
18859
+ throw new Error("Invalid PlcPcd length");
18860
+ if (maxPieces !== void 0 && (lcb - 4) / 12 > maxPieces)
18861
+ throw new DocResourceLimitError("DOC piece count exceeds the processing limit");
18862
+ const pieces = parsePlcPcd(view, off + 5, lcb);
18863
+ for (const piece of pieces) {
18864
+ if ((piece.prm & 1) !== 0 && piece.prm >>> 1 >= prcCount)
18865
+ throw new Error("Prm1 references a missing Prc");
18866
+ }
18867
+ return { pieces, prcBytes: tableStream.slice(clx.fc, off) };
17997
18868
  }
17998
18869
  throw new Error(`Unrecognised Clx entry type ${clxt} at ${off}`);
17999
18870
  }
@@ -18003,7 +18874,10 @@ function parsePlcPcd(view, plcStart, lcb) {
18003
18874
  const n = Math.floor((lcb - 4) / (4 + 8));
18004
18875
  const cps = [];
18005
18876
  for (let i = 0; i <= n; i++) {
18006
- cps.push(view.getInt32(plcStart + i * 4, true));
18877
+ const cp = view.getInt32(plcStart + i * 4, true);
18878
+ if (i === 0 && cp !== 0 || i > 0 && cp <= cps[i - 1])
18879
+ throw new Error("Piece CPs must start at zero and increase");
18880
+ cps.push(cp);
18007
18881
  }
18008
18882
  const pcdStart = plcStart + (n + 1) * 4;
18009
18883
  const pieces = [];
@@ -18011,6 +18885,8 @@ function parsePlcPcd(view, plcStart, lcb) {
18011
18885
  const pOff = pcdStart + i * 8;
18012
18886
  const flagsWord = view.getUint16(pOff, true);
18013
18887
  const fcRaw = view.getUint32(pOff + 2, true);
18888
+ if ((fcRaw & 2147483648) !== 0)
18889
+ throw new Error("Reserved FcCompressed bit is set");
18014
18890
  const prm = view.getUint16(pOff + 6, true);
18015
18891
  const compressed = (fcRaw >>> 30 & 1) === 1;
18016
18892
  const fcField = fcRaw & 1073741823;
@@ -18027,6 +18903,9 @@ function parsePlcPcd(view, plcStart, lcb) {
18027
18903
  }
18028
18904
  function decodePieceText(wordDoc, piece) {
18029
18905
  const charLen = piece.cpEnd - piece.cpStart;
18906
+ const byteLen = charLen * (piece.compressed ? 1 : 2);
18907
+ if (!Number.isInteger(charLen) || charLen < 0 || !Number.isInteger(piece.fc) || piece.fc < 0 || piece.fc > wordDoc.length - byteLen)
18908
+ throw new Error("Piece text is outside WordDocument");
18030
18909
  if (piece.compressed) {
18031
18910
  return decodeCp1252(wordDoc.subarray(piece.fc, piece.fc + charLen));
18032
18911
  }
@@ -18037,8 +18916,19 @@ function decodePieceText(wordDoc, piece) {
18037
18916
  }
18038
18917
  return out;
18039
18918
  }
18040
- function decodePiecesText(wordDoc, pieces) {
18041
- return pieces.map((piece) => decodePieceText(wordDoc, piece)).join("");
18919
+ function decodePiecesText(wordDoc, pieces, maxChars) {
18920
+ if (maxChars !== void 0 && (!Number.isInteger(maxChars) || maxChars < 0))
18921
+ throw new Error("Invalid text character limit");
18922
+ const out = [];
18923
+ for (const piece of pieces) {
18924
+ const bytes = (piece.cpEnd - piece.cpStart) * (piece.compressed ? 1 : 2);
18925
+ if (piece.cpEnd < piece.cpStart || piece.fc < 0 || piece.fc > wordDoc.length - bytes)
18926
+ throw new Error("Piece text is outside WordDocument");
18927
+ const end = Math.min(piece.cpEnd, maxChars ?? piece.cpEnd);
18928
+ if (end > piece.cpStart)
18929
+ out.push(decodePieceText(wordDoc, { ...piece, cpEnd: end }));
18930
+ }
18931
+ return out.join("");
18042
18932
  }
18043
18933
  function encodePieceText(text2) {
18044
18934
  const compressedBytes = encodeCp1252(text2);
@@ -18076,7 +18966,7 @@ function replacePieceRange(pieces, cpStart, cpEnd, newPiece) {
18076
18966
  fc: newPiece.fc,
18077
18967
  compressed: newPiece.compressed,
18078
18968
  flagsWord: newPiece.flagsWord,
18079
- prm: 0,
18969
+ prm: newPiece.prm ?? 0,
18080
18970
  charLength: newPiece.charLength
18081
18971
  });
18082
18972
  inserted = true;
@@ -18097,7 +18987,7 @@ function replacePieceRange(pieces, cpStart, cpEnd, newPiece) {
18097
18987
  fc: newPiece.fc,
18098
18988
  compressed: newPiece.compressed,
18099
18989
  flagsWord: newPiece.flagsWord,
18100
- prm: 0,
18990
+ prm: newPiece.prm ?? 0,
18101
18991
  charLength: newPiece.charLength
18102
18992
  });
18103
18993
  }
@@ -18115,7 +19005,7 @@ function replacePieceRange(pieces, cpStart, cpEnd, newPiece) {
18115
19005
  };
18116
19006
  });
18117
19007
  }
18118
- function buildClxBytes(pieces) {
19008
+ function buildClxBytes(pieces, prcBytes = new Uint8Array()) {
18119
19009
  const n = pieces.length;
18120
19010
  const plcLcb = (n + 1) * 4 + n * 8;
18121
19011
  const bytes = new Uint8Array(1 + 4 + plcLcb);
@@ -18136,20 +19026,138 @@ function buildClxBytes(pieces) {
18136
19026
  view.setUint16(off + 6, piece.prm, true);
18137
19027
  off += 8;
18138
19028
  }
18139
- return bytes;
19029
+ const result = new Uint8Array(prcBytes.length + bytes.length);
19030
+ result.set(prcBytes);
19031
+ result.set(bytes, prcBytes.length);
19032
+ parseDocClx(result, { fc: 0, lcb: result.length });
19033
+ return result;
18140
19034
  }
18141
- var CLXT_PRC, CLXT_PCDT;
19035
+ var CLXT_PRC, CLXT_PCDT, DocResourceLimitError;
18142
19036
  var init_ole_document_doc_pieces = __esm({
18143
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js"() {
19037
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-pieces.js"() {
18144
19038
  init_ole_document_doc_cp1252();
18145
19039
  CLXT_PRC = 1;
18146
19040
  CLXT_PCDT = 2;
19041
+ DocResourceLimitError = class extends Error {
19042
+ constructor(message) {
19043
+ super(message);
19044
+ this.name = "DocResourceLimitError";
19045
+ }
19046
+ };
19047
+ }
19048
+ });
19049
+
19050
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fields.js
19051
+ function checkFieldRanges(markers, editStart, editEnd, maxDepth2) {
19052
+ const stack = [];
19053
+ for (const { cp, ch } of markers) {
19054
+ if (ch === 19) {
19055
+ if (stack.length >= maxDepth2)
19056
+ throw new DocResourceLimitError("DOC field nesting exceeds the processing limit");
19057
+ stack.push({ start: cp, separated: false });
19058
+ } else if (ch === 20) {
19059
+ const field = stack.at(-1);
19060
+ if (!field || field.separated)
19061
+ throw new Error("Invalid DOC field separator nesting");
19062
+ field.separated = true;
19063
+ } else if (ch === 21) {
19064
+ const field = stack.pop();
19065
+ if (!field)
19066
+ throw new Error("Unmatched DOC field end");
19067
+ if (field.start < editEnd && cp + 1 > editStart)
19068
+ throw new UnsupportedDocFieldEditError("Paragraph overlaps a field code/result range");
19069
+ }
19070
+ }
19071
+ if (stack.length)
19072
+ throw new Error("Unterminated DOC field");
19073
+ }
19074
+ function* bodyMarkers(body) {
19075
+ for (let cp = 0; cp < body.length; cp++) {
19076
+ const ch = body.charCodeAt(cp);
19077
+ if (ch >= 19 && ch <= 21)
19078
+ yield { cp, ch };
19079
+ }
19080
+ }
19081
+ function shiftDocMainFieldCps(table, at2, body, editStart, editEnd, delta2, maxFields) {
19082
+ if (![editStart, editEnd, delta2, maxFields].every(Number.isSafeInteger) || editStart < 0 || editEnd <= editStart || editEnd > body.length || maxFields < 0 || body.length + delta2 < 0)
19083
+ throw new Error("Invalid field edit bounds or budget");
19084
+ checkFieldRanges(bodyMarkers(body), editStart, editEnd, maxFields);
19085
+ if (at2.lcb === 0)
19086
+ return void 0;
19087
+ if (!Number.isSafeInteger(at2.fc) || at2.fc < 0 || at2.lcb < 4 || (at2.lcb - 4) % 6 !== 0 || at2.fc > table.length - at2.lcb)
19088
+ throw new Error("Invalid main-story field PLC bounds");
19089
+ const n = (at2.lcb - 4) / 6;
19090
+ if (n > maxFields)
19091
+ throw new DocResourceLimitError("DOC field count exceeds the processing limit");
19092
+ const source = table.subarray(at2.fc, at2.fc + at2.lcb);
19093
+ const view = new DataView(source.buffer, source.byteOffset, source.byteLength);
19094
+ const markers = [];
19095
+ let previous = -1;
19096
+ for (let i = 0; i < n; i++) {
19097
+ const cp = view.getInt32(i * 4, true);
19098
+ const ch = source[(n + 1) * 4 + i * 2] & 31;
19099
+ if (cp <= previous || cp >= body.length || ![19, 20, 21].includes(ch) || body.charCodeAt(cp) !== ch)
19100
+ throw new Error("Invalid main-story field marker");
19101
+ markers.push({ cp, ch });
19102
+ previous = cp;
19103
+ }
19104
+ checkFieldRanges(markers, editStart, editEnd, maxFields);
19105
+ const sentinel = view.getInt32(n * 4, true);
19106
+ if (sentinel < 0 || sentinel <= previous)
19107
+ throw new Error("Invalid field PLC sentinel");
19108
+ const result = source.slice();
19109
+ const out = new DataView(result.buffer);
19110
+ let shiftedLast = -1;
19111
+ for (let i = 0; i < n; i++) {
19112
+ const cp = markers[i].cp;
19113
+ const shifted = cp >= editEnd ? cp + delta2 : cp;
19114
+ if (shifted < 0 || shifted >= body.length + delta2 || shifted <= shiftedLast)
19115
+ throw new Error("Field position shifts outside the main story");
19116
+ out.setInt32(i * 4, shifted, true);
19117
+ shiftedLast = shifted;
19118
+ }
19119
+ let shiftedSentinel = sentinel >= editEnd ? sentinel + delta2 : sentinel;
19120
+ if (shiftedSentinel > 2147483647 || shiftedSentinel <= shiftedLast)
19121
+ shiftedSentinel = sentinel;
19122
+ if (shiftedSentinel <= shiftedLast)
19123
+ throw new Error("No representable field PLC sentinel");
19124
+ out.setInt32(n * 4, shiftedSentinel, true);
19125
+ return result;
19126
+ }
19127
+ var UnsupportedDocFieldEditError;
19128
+ var init_ole_document_doc_fields = __esm({
19129
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-fields.js"() {
19130
+ init_ole_document_doc_pieces();
19131
+ UnsupportedDocFieldEditError = class extends Error {
19132
+ constructor(message) {
19133
+ super(message);
19134
+ this.name = "UnsupportedDocFieldEditError";
19135
+ }
19136
+ };
18147
19137
  }
18148
19138
  });
18149
19139
 
18150
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js
19140
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js
19141
+ function processingLimits(limits) {
19142
+ const resolved = {
19143
+ maxCharacters: DEFAULT_OLE_DOC_PROCESSING_LIMITS.maxCharacters,
19144
+ maxPieces: DEFAULT_OLE_DOC_PROCESSING_LIMITS.maxPieces,
19145
+ maxFieldRecords: DEFAULT_OLE_DOC_PROCESSING_LIMITS.maxFieldRecords
19146
+ };
19147
+ if (!Number.isSafeInteger(resolved.maxCharacters) || resolved.maxCharacters < 0 || !Number.isSafeInteger(resolved.maxPieces) || resolved.maxPieces < 0 || !Number.isSafeInteger(resolved.maxFieldRecords) || resolved.maxFieldRecords < 0)
19148
+ throw new Error("DOC processing limits must be nonnegative safe integers");
19149
+ return resolved;
19150
+ }
18151
19151
  function hasUnsupportedFeatures(wordDoc, fib) {
19152
+ if (fib.ccpOtherStories > 0)
19153
+ return true;
19154
+ for (let index = 93; index < fib.fibRgFcLcbCount; index++) {
19155
+ if (!SAFE_EXTENDED_FC_LCB_INDICES.has(index) && readFcLcbAt(wordDoc, fib, index).lcb !== 0)
19156
+ return true;
19157
+ }
18152
19158
  for (const index of RISKY_PLCF_INDICES) {
19159
+ if (index >= fib.fibRgFcLcbCount)
19160
+ continue;
18153
19161
  if (readFcLcbAt(wordDoc, fib, index).lcb > 4) {
18154
19162
  return true;
18155
19163
  }
@@ -18182,15 +19190,30 @@ function paragraphBoundaries(bodyText) {
18182
19190
  }
18183
19191
  return boundaries;
18184
19192
  }
18185
- function readOleDocParagraphs(docBytes) {
19193
+ function encodePieceTextUtf16(text2) {
19194
+ const bytes = new Uint8Array(text2.length * 2);
19195
+ const view = new DataView(bytes.buffer);
19196
+ for (let i = 0; i < text2.length; i++)
19197
+ view.setUint16(i * 2, text2.charCodeAt(i), true);
19198
+ return bytes;
19199
+ }
19200
+ function readOleDocParagraphs(docBytes, limits) {
18186
19201
  try {
19202
+ const budget = processingLimits(limits);
18187
19203
  const cfb = unwrapDocBytes(docBytes);
18188
19204
  if (!cfb) {
18189
19205
  return void 0;
18190
19206
  }
18191
19207
  const fib = readDocFib(cfb.wordDocBytes);
18192
- const pieces = parsePieceTable(cfb.tableBytes, fib.clx);
18193
- const fullText = decodePiecesText(cfb.wordDocBytes, pieces);
19208
+ if (fib.ccpText > budget.maxCharacters)
19209
+ return void 0;
19210
+ const pieces = parseDocClx(cfb.tableBytes, fib.clx, budget.maxPieces).pieces;
19211
+ const totalCp = pieces.at(-1)?.cpEnd ?? 0;
19212
+ if (totalCp > fib.ccpText + fib.ccpOtherStories + 1)
19213
+ return void 0;
19214
+ const fullText = decodePiecesText(cfb.wordDocBytes, pieces, fib.ccpText);
19215
+ if (fullText.length < fib.ccpText)
19216
+ return void 0;
18194
19217
  const bodyText = fullText.slice(0, fib.ccpText);
18195
19218
  const boundaries = paragraphBoundaries(bodyText);
18196
19219
  let start = 0;
@@ -18207,7 +19230,9 @@ function readOleDocParagraphs(docBytes) {
18207
19230
  }
18208
19231
  function shiftSectionTableCps(tableBytes, sed, editEndCp, delta2) {
18209
19232
  const view = new DataView(tableBytes.buffer, tableBytes.byteOffset, tableBytes.byteLength);
18210
- const n = Math.floor((sed.lcb - 4) / (4 + 12));
19233
+ if (sed.lcb < 4 || (sed.lcb - 4) % 16 !== 0 || sed.fc > tableBytes.length - sed.lcb)
19234
+ throw new Error("Invalid section table");
19235
+ const n = (sed.lcb - 4) / 16;
18211
19236
  for (let i = 0; i <= n; i++) {
18212
19237
  const off = sed.fc + i * 4;
18213
19238
  const cp = view.getInt32(off, true);
@@ -18216,31 +19241,101 @@ function shiftSectionTableCps(tableBytes, sed, editEndCp, delta2) {
18216
19241
  }
18217
19242
  }
18218
19243
  }
18219
- function writeOleDocParagraphEdit(docBytes, paragraphIndex, text2) {
19244
+ function writeOleDocParagraphEdit(docBytes, paragraphIndex, text2, limits) {
19245
+ return tryWriteOleDocParagraphEdit(docBytes, paragraphIndex, text2, limits).bytes;
19246
+ }
19247
+ function tryWriteOleDocParagraphEdit(docBytes, paragraphIndex, text2, limits) {
19248
+ const rejected = (reason) => ({ status: "rejected", bytes: docBytes, reason });
19249
+ let budget;
19250
+ try {
19251
+ budget = processingLimits(limits);
19252
+ } catch {
19253
+ return rejected("invalid-limits");
19254
+ }
19255
+ if (text2.length > budget.maxCharacters)
19256
+ return rejected("resource-limit");
19257
+ if (!Number.isInteger(paragraphIndex) || paragraphIndex < 0)
19258
+ return rejected("invalid-paragraph-index");
19259
+ if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/u.test(text2))
19260
+ return rejected("invalid-text");
18220
19261
  try {
18221
19262
  const cfb = unwrapDocBytes(docBytes);
18222
19263
  if (!cfb) {
18223
- return docBytes;
19264
+ return rejected("invalid-payload");
18224
19265
  }
18225
19266
  const fib = readDocFib(cfb.wordDocBytes);
18226
- if (hasUnsupportedFeatures(cfb.wordDocBytes, fib)) {
18227
- return docBytes;
18228
- }
18229
- const pieces = parsePieceTable(cfb.tableBytes, fib.clx);
18230
- const fullText = decodePiecesText(cfb.wordDocBytes, pieces);
19267
+ if (fib.ccpText > budget.maxCharacters)
19268
+ return rejected("resource-limit");
19269
+ const { pieces, prcBytes } = parseDocClx(cfb.tableBytes, fib.clx, budget.maxPieces);
19270
+ const totalCp = pieces.at(-1)?.cpEnd ?? 0;
19271
+ if (totalCp > fib.ccpText + fib.ccpOtherStories + 1)
19272
+ return rejected("invalid-document");
19273
+ const fullText = decodePiecesText(cfb.wordDocBytes, pieces, fib.ccpText);
19274
+ if (fullText.length < fib.ccpText)
19275
+ return rejected("invalid-document");
18231
19276
  const bodyText = fullText.slice(0, fib.ccpText);
18232
19277
  const boundaries = paragraphBoundaries(bodyText);
18233
19278
  const paragraphEndCp = boundaries[paragraphIndex];
18234
19279
  if (paragraphEndCp === void 0) {
18235
- return docBytes;
19280
+ return rejected("invalid-paragraph-index");
18236
19281
  }
18237
19282
  const paragraphStartCp = paragraphIndex === 0 ? 0 : boundaries[paragraphIndex - 1];
19283
+ if (/[\u0000-\u0008\u000b\u000c\u000e-\u001f]/u.test(bodyText.slice(paragraphStartCp, paragraphEndCp)))
19284
+ return rejected("unsupported-features");
19285
+ const sanitizedText = text2.replaceAll(/[\r\n]+/gu, " ");
19286
+ if (fib.ccpText - (paragraphEndCp - paragraphStartCp) + sanitizedText.length + 1 > budget.maxCharacters)
19287
+ return rejected("resource-limit");
19288
+ if (sanitizedText.length + 1 === paragraphEndCp - paragraphStartCp && bodyText[paragraphEndCp - 1] === "\r") {
19289
+ const replacement = `${sanitizedText}\r`;
19290
+ const patched = cfb.wordDocBytes.slice();
19291
+ let canPatch = true;
19292
+ for (const piece of pieces) {
19293
+ const start = Math.max(paragraphStartCp, piece.cpStart);
19294
+ const end = Math.min(paragraphEndCp, piece.cpEnd);
19295
+ if (start >= end)
19296
+ continue;
19297
+ const part = replacement.slice(start - paragraphStartCp, end - paragraphStartCp);
19298
+ const unit = piece.compressed ? 1 : 2;
19299
+ const fc = piece.fc + (start - piece.cpStart) * unit;
19300
+ const fcEnd = fc + part.length * unit;
19301
+ if (pieces.some((other) => other !== piece && other.fc < fcEnd && other.fc + (other.cpEnd - other.cpStart) * (other.compressed ? 1 : 2) > fc)) {
19302
+ canPatch = false;
19303
+ break;
19304
+ }
19305
+ const encoded = piece.compressed ? encodeCp1252(part) : encodePieceTextUtf16(part);
19306
+ if (!encoded) {
19307
+ canPatch = false;
19308
+ break;
19309
+ }
19310
+ patched.set(encoded, fc);
19311
+ }
19312
+ if (canPatch)
19313
+ return { status: "edited", strategy: "preserved-runs", bytes: cfb.rewrap(patched, cfb.tableBytes) };
19314
+ }
19315
+ if (!cfb.canRewrite)
19316
+ return rejected("unsupported-container");
19317
+ if (hasUnsupportedFeatures(cfb.wordDocBytes, fib))
19318
+ return rejected("unsupported-features");
19319
+ const delta2 = sanitizedText.length + 1 - (paragraphEndCp - paragraphStartCp);
19320
+ const mainFields = readFcLcbAt(cfb.wordDocBytes, fib, 16);
19321
+ if (mainFields.lcb > 0) {
19322
+ for (let index = 0; index < fib.fibRgFcLcbCount; index++) {
19323
+ if (index === 16 || index === 87)
19324
+ continue;
19325
+ const other = readFcLcbAt(cfb.wordDocBytes, fib, index);
19326
+ if (other.lcb > 0 && other.fc < mainFields.fc + mainFields.lcb && other.fc + other.lcb > mainFields.fc)
19327
+ return rejected("invalid-document");
19328
+ }
19329
+ }
19330
+ const shiftedFields = shiftDocMainFieldCps(cfb.tableBytes, mainFields, bodyText, paragraphStartCp, paragraphEndCp, delta2, budget.maxFieldRecords);
18238
19331
  const { piece: startPiece, fc: startFc } = pieceAndFcAtCp(pieces, paragraphStartCp);
19332
+ if (pieces.some((piece) => piece.cpStart < paragraphEndCp && piece.cpEnd > paragraphStartCp && piece.prm !== startPiece.prm))
19333
+ return rejected("unsupported-features");
19334
+ const { fc: paragraphMarkFc } = pieceAndFcAtCp(pieces, paragraphEndCp - 1);
18239
19335
  const papxBte = parseBteTable(cfb.tableBytes, fib.plcfbtePapx);
18240
19336
  const chpxBte = parseBteTable(cfb.tableBytes, fib.plcfbteChpx);
18241
- const papxBlob = extractPapxBlob(cfb.wordDocBytes, papxBte, startFc);
19337
+ const papxBlob = extractPapxBlob(cfb.wordDocBytes, papxBte, paragraphMarkFc);
18242
19338
  const chpxBlob = extractChpxBlob(cfb.wordDocBytes, chpxBte, startFc);
18243
- const sanitizedText = text2.replaceAll(/[\r\n]+/gu, " ");
18244
19339
  const { bytes: textBytes, compressed } = encodePieceText(`${sanitizedText}\r`);
18245
19340
  const originalLen = cfb.wordDocBytes.length;
18246
19341
  const newTextFc = originalLen;
@@ -18268,15 +19363,19 @@ function writeOleDocParagraphEdit(docBytes, paragraphIndex, text2) {
18268
19363
  fc: newTextFc,
18269
19364
  compressed,
18270
19365
  charLength: sanitizedText.length + 1,
18271
- flagsWord: startPiece.flagsWord
19366
+ flagsWord: startPiece.flagsWord,
19367
+ prm: startPiece.prm
18272
19368
  });
18273
- const delta2 = sanitizedText.length + 1 - (paragraphEndCp - paragraphStartCp);
19369
+ if (newPieces.length > budget.maxPieces)
19370
+ return rejected("resource-limit");
18274
19371
  const newCcpText = fib.ccpText + delta2;
18275
- const clxBytes = buildClxBytes(newPieces);
19372
+ const clxBytes = buildClxBytes(newPieces, prcBytes);
18276
19373
  const papxBteBytes = buildBteTableBytes(newPapxBte);
18277
19374
  const chpxBteBytes = buildBteTableBytes(newChpxBte);
18278
19375
  const newTableBytes = new Uint8Array(cfb.tableBytes.length + clxBytes.length + papxBteBytes.length + chpxBteBytes.length);
18279
19376
  newTableBytes.set(cfb.tableBytes, 0);
19377
+ if (shiftedFields)
19378
+ newTableBytes.set(shiftedFields, mainFields.fc);
18280
19379
  let tableOff = cfb.tableBytes.length;
18281
19380
  const newClx = { fc: tableOff, lcb: clxBytes.length };
18282
19381
  newTableBytes.set(clxBytes, tableOff);
@@ -18294,20 +19393,30 @@ function writeOleDocParagraphEdit(docBytes, paragraphIndex, text2) {
18294
19393
  plcfbteChpx: newChpxBteFcLcb,
18295
19394
  plcfbtePapx: newPapxBteFcLcb
18296
19395
  });
18297
- return cfb.rewrap(newWordDoc, newTableBytes);
18298
- } catch {
18299
- return docBytes;
19396
+ return { status: "edited", strategy: "piece-append", bytes: cfb.rewrap(newWordDoc, newTableBytes) };
19397
+ } catch (error) {
19398
+ if (error instanceof UnsupportedDocFieldEditError)
19399
+ return rejected("unsupported-features");
19400
+ if (error instanceof DocResourceLimitError)
19401
+ return rejected("resource-limit");
19402
+ if (error instanceof DocCfbRewriteError)
19403
+ return rejected("unsupported-container");
19404
+ return rejected("invalid-document");
18300
19405
  }
18301
19406
  }
18302
- var RISKY_PLCF_INDICES, RISKY_STTB_INDICES;
19407
+ var RISKY_PLCF_INDICES, RISKY_STTB_INDICES, SAFE_EXTENDED_FC_LCB_INDICES, DEFAULT_OLE_DOC_PROCESSING_LIMITS;
18303
19408
  var init_ole_document_doc_editor = __esm({
18304
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js"() {
19409
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole-document-doc-editor.js"() {
18305
19410
  init_ole_document_doc_cfb();
18306
19411
  init_ole_document_doc_fib();
18307
19412
  init_ole_document_doc_fkp();
18308
19413
  init_ole_document_doc_pieces();
18309
- RISKY_PLCF_INDICES = [3, 4, 5, 16, 17, 18, 19, 20];
19414
+ init_ole_document_doc_cp1252();
19415
+ init_ole_document_doc_fields();
19416
+ 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];
18310
19417
  RISKY_STTB_INDICES = [21, 22, 23];
19418
+ SAFE_EXTENDED_FC_LCB_INDICES = /* @__PURE__ */ new Set([93, 94, 113, 181, 182]);
19419
+ DEFAULT_OLE_DOC_PROCESSING_LIMITS = Object.freeze({ maxCharacters: 16777216, maxPieces: 65536, maxFieldRecords: 65536 });
18311
19420
  }
18312
19421
  });
18313
19422
 
@@ -18401,7 +19510,7 @@ var init_ole_nested_deck_editor = __esm({
18401
19510
  }
18402
19511
  });
18403
19512
 
18404
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js
19513
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js
18405
19514
  function crc32(bytes) {
18406
19515
  let crc = 4294967295;
18407
19516
  for (let i = 0; i < bytes.length; i++) {
@@ -18497,7 +19606,7 @@ function encodePng(width, height, rgba) {
18497
19606
  }
18498
19607
  var CRC_TABLE, PNG_SIGNATURE;
18499
19608
  var init_png_encoder = __esm({
18500
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js"() {
19609
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/png-encoder.js"() {
18501
19610
  CRC_TABLE = (() => {
18502
19611
  const table = new Uint32Array(256);
18503
19612
  for (let n = 0; n < 256; n++) {
@@ -37799,7 +38908,7 @@ var init_encryption_detection = __esm({
37799
38908
  }
37800
38909
  });
37801
38910
 
37802
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js
38911
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js
37803
38912
  function getSubtle() {
37804
38913
  if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
37805
38914
  return globalThis.crypto.subtle;
@@ -37917,7 +39026,7 @@ async function hmac(algorithm, key2, data) {
37917
39026
  return new Uint8Array(result);
37918
39027
  }
37919
39028
  var init_ooxml_crypto_primitives = __esm({
37920
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js"() {
39029
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js"() {
37921
39030
  }
37922
39031
  });
37923
39032
 
@@ -39115,7 +40224,7 @@ var init_ole2_parser = __esm({
39115
40224
  }
39116
40225
  });
39117
40226
 
39118
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/digests/bit-ops.js
40227
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/digests/bit-ops.js
39119
40228
  function rotl32(x, n) {
39120
40229
  return (x << n | x >>> 32 - n) >>> 0;
39121
40230
  }
@@ -39164,11 +40273,11 @@ function mdStyleDigest(message, initialState, transform2) {
39164
40273
  return out;
39165
40274
  }
39166
40275
  var init_bit_ops = __esm({
39167
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/digests/bit-ops.js"() {
40276
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/digests/bit-ops.js"() {
39168
40277
  }
39169
40278
  });
39170
40279
 
39171
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/digests/md4.js
40280
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/digests/md4.js
39172
40281
  function f1(x, y, z) {
39173
40282
  return x & y | ~x & z;
39174
40283
  }
@@ -39192,7 +40301,7 @@ function md4(message) {
39192
40301
  }
39193
40302
  var INITIAL_STATE, K22, K3, ROUND1, ROUND2, ROUND3;
39194
40303
  var init_md4 = __esm({
39195
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/digests/md4.js"() {
40304
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/digests/md4.js"() {
39196
40305
  init_bit_ops();
39197
40306
  INITIAL_STATE = [1732584193, 4023233417, 2562383102, 271733878];
39198
40307
  K22 = 1518500249;
@@ -94875,7 +95984,7 @@ var init_metro_blob_collect = __esm({
94875
95984
  }
94876
95985
  });
94877
95986
 
94878
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/byte-writer.js
95987
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/byte-writer.js
94879
95988
  function record(recType, data, recInstance = 0, isContainer2 = false, recVer = 0) {
94880
95989
  const header = new Uint8Array(8);
94881
95990
  const view = new DataView(header.buffer);
@@ -94890,7 +95999,7 @@ function record(recType, data, recInstance = 0, isContainer2 = false, recVer = 0
94890
95999
  }
94891
96000
  var ByteWriter;
94892
96001
  var init_byte_writer = __esm({
94893
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/byte-writer.js"() {
96002
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/byte-writer.js"() {
94894
96003
  ByteWriter = class {
94895
96004
  chunks = [];
94896
96005
  length = 0;
@@ -94973,13 +96082,13 @@ var init_byte_writer = __esm({
94973
96082
  }
94974
96083
  });
94975
96084
 
94976
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js
96085
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js
94977
96086
  function masterToEmu(mu) {
94978
96087
  return Math.round(mu * EMU_PER_MASTER);
94979
96088
  }
94980
96089
  var RT, OA, TEXT_TYPE, HEADER_TOKEN_PLAIN, HEADER_TOKEN_ENCRYPTED, EMU_PER_MASTER;
94981
96090
  var init_legacy_ppt_record_types = __esm({
94982
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js"() {
96091
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-types.js"() {
94983
96092
  RT = {
94984
96093
  Document: 1e3,
94985
96094
  DocumentAtom: 1001,
@@ -95108,14 +96217,14 @@ var init_legacy_ppt_record_types = __esm({
95108
96217
  }
95109
96218
  });
95110
96219
 
95111
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/record-types.js
96220
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/record-types.js
95112
96221
  var init_record_types = __esm({
95113
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/record-types.js"() {
96222
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/record-types.js"() {
95114
96223
  init_legacy_ppt_record_types();
95115
96224
  }
95116
96225
  });
95117
96226
 
95118
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/current-user-writer.js
96227
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/current-user-writer.js
95119
96228
  function buildCurrentUserStream(offsetToCurrentEdit, encrypted) {
95120
96229
  const nameBytes = new ByteWriter().ansi(USER_NAME).toBytes();
95121
96230
  const data = new ByteWriter().u32(20).u32(encrypted ? HEADER_TOKEN_ENCRYPTED : HEADER_TOKEN_PLAIN).u32(offsetToCurrentEdit).u16(nameBytes.length).u16(1012).u8(3).u8(0).bytes(new Uint8Array(2)).bytes(nameBytes).u32(8).toBytes();
@@ -95129,7 +96238,7 @@ function buildCurrentUserStream(offsetToCurrentEdit, encrypted) {
95129
96238
  }
95130
96239
  var USER_NAME, CURRENT_USER_STREAM_SIZE;
95131
96240
  var init_current_user_writer = __esm({
95132
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/current-user-writer.js"() {
96241
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/current-user-writer.js"() {
95133
96242
  init_record_types();
95134
96243
  init_byte_writer();
95135
96244
  USER_NAME = "pptx-viewer";
@@ -95137,7 +96246,7 @@ var init_current_user_writer = __esm({
95137
96246
  }
95138
96247
  });
95139
96248
 
95140
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/blip-writer.js
96249
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/blip-writer.js
95141
96250
  function pictureUid(picture) {
95142
96251
  return md4(picture.bytes);
95143
96252
  }
@@ -95160,7 +96269,7 @@ function buildFbse(picture, uid, foDelay, size) {
95160
96269
  }
95161
96270
  var MSOBLIP_PICT, BLIP_INFO;
95162
96271
  var init_blip_writer = __esm({
95163
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/blip-writer.js"() {
96272
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/blip-writer.js"() {
95164
96273
  init_md4();
95165
96274
  init_png_encoder();
95166
96275
  init_record_types();
@@ -95176,7 +96285,7 @@ var init_blip_writer = __esm({
95176
96285
  }
95177
96286
  });
95178
96287
 
95179
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/fopt-writer.js
96288
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/fopt-writer.js
95180
96289
  function boolPropValue(flag, bit, useBit) {
95181
96290
  return useBit | (flag ? bit : 0);
95182
96291
  }
@@ -95212,7 +96321,7 @@ function buildMetroBlobTertiaryFopt(metroBlob) {
95212
96321
  }
95213
96322
  var OPT, FBID_FLAG, METRO_BLOB_OPID;
95214
96323
  var init_fopt_writer = __esm({
95215
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/fopt-writer.js"() {
96324
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/fopt-writer.js"() {
95216
96325
  init_record_types();
95217
96326
  init_byte_writer();
95218
96327
  OPT = {
@@ -95240,7 +96349,7 @@ var init_fopt_writer = __esm({
95240
96349
  }
95241
96350
  });
95242
96351
 
95243
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/bstore-writer.js
96352
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/bstore-writer.js
95244
96353
  function buildDggDefaultProperties() {
95245
96354
  return buildFopt([
95246
96355
  { id: 385, value: 134217732 },
@@ -95298,7 +96407,7 @@ function buildPictureStore(pictures, shapesPerDrawing) {
95298
96407
  }
95299
96408
  var SHAPE_ID_CLUSTER_SIZE;
95300
96409
  var init_bstore_writer = __esm({
95301
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/bstore-writer.js"() {
96410
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/bstore-writer.js"() {
95302
96411
  init_record_types();
95303
96412
  init_blip_writer();
95304
96413
  init_byte_writer();
@@ -95307,7 +96416,7 @@ var init_bstore_writer = __esm({
95307
96416
  }
95308
96417
  });
95309
96418
 
95310
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/font-collection-writer.js
96419
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/font-collection-writer.js
95311
96420
  function buildFontEntityAtom(name, index) {
95312
96421
  const nameBytes = new ByteWriter().utf16(name.slice(0, 31)).u16(0).toBytes();
95313
96422
  const padded = new Uint8Array(LF_FACE_NAME_BYTES);
@@ -95335,14 +96444,14 @@ function buildEnvironment(fonts, otherTextStyle) {
95335
96444
  }
95336
96445
  var LF_FACE_NAME_BYTES;
95337
96446
  var init_font_collection_writer = __esm({
95338
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/font-collection-writer.js"() {
96447
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/font-collection-writer.js"() {
95339
96448
  init_record_types();
95340
96449
  init_byte_writer();
95341
96450
  LF_FACE_NAME_BYTES = 64;
95342
96451
  }
95343
96452
  });
95344
96453
 
95345
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-writer.js
96454
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-writer.js
95346
96455
  function emuToMaster(emu2) {
95347
96456
  return Math.round(emu2 / EMU_PER_MASTER);
95348
96457
  }
@@ -95398,7 +96507,7 @@ function buildDocumentContainer(input) {
95398
96507
  }
95399
96508
  var MASTER_SLIDE_ID_SENTINEL, RT_CSTRING, RT_BINARY_TAG_DATA_BLOB;
95400
96509
  var init_document_writer = __esm({
95401
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-writer.js"() {
96510
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-writer.js"() {
95402
96511
  init_record_types();
95403
96512
  init_byte_writer();
95404
96513
  init_font_collection_writer();
@@ -95408,7 +96517,7 @@ var init_document_writer = __esm({
95408
96517
  }
95409
96518
  });
95410
96519
 
95411
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/hyperlink-writer.js
96520
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/hyperlink-writer.js
95412
96521
  function buildCString(text2, recInstance) {
95413
96522
  return record(RT.CString, new ByteWriter().utf16(text2).toBytes(), recInstance, false, 0);
95414
96523
  }
@@ -95544,7 +96653,7 @@ function buildTextInteractiveInfoAtom(beginChar, endChar) {
95544
96653
  }
95545
96654
  var II_ACTION, II_JUMP, LT, FLAG_CUSTOM_SHOW_RETURN, HyperlinkCollector;
95546
96655
  var init_hyperlink_writer = __esm({
95547
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/hyperlink-writer.js"() {
96656
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/hyperlink-writer.js"() {
95548
96657
  init_record_types();
95549
96658
  init_byte_writer();
95550
96659
  II_ACTION = {
@@ -95607,7 +96716,7 @@ var init_hyperlink_writer = __esm({
95607
96716
  }
95608
96717
  });
95609
96718
 
95610
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/media-writer.js
96719
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/media-writer.js
95611
96720
  function buildCString2(text2, recInstance) {
95612
96721
  return record(RT.CString, new ByteWriter().utf16(text2).toBytes(), recInstance, false, 0);
95613
96722
  }
@@ -95643,7 +96752,7 @@ function buildMediaExObjEntries(media) {
95643
96752
  }
95644
96753
  var MediaCollector, SOUND_EXTENSION_WAV, SOUND_LENGTH_UNKNOWN;
95645
96754
  var init_media_writer = __esm({
95646
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/media-writer.js"() {
96755
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/media-writer.js"() {
95647
96756
  init_record_types();
95648
96757
  init_byte_writer();
95649
96758
  MediaCollector = class {
@@ -95679,7 +96788,7 @@ var init_media_writer = __esm({
95679
96788
  }
95680
96789
  });
95681
96790
 
95682
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ole-writer.js
96791
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ole-writer.js
95683
96792
  function hexToBytes(hex3) {
95684
96793
  const out = new Uint8Array(hex3.length / 2);
95685
96794
  for (let i = 0; i < out.length; i++) {
@@ -95741,7 +96850,7 @@ function buildExObjRefAtom(exObjId) {
95741
96850
  }
95742
96851
  var PACKAGE_ROOT_CLSID, COMP_OBJ_HEX, EX_OLE_EMBEDDED, DV_ASPECT_ICON, EX_OLE_SUB_DEFAULT, PACKAGER_MENU_NAME, OleCollector;
95743
96852
  var init_ole_writer = __esm({
95744
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ole-writer.js"() {
96853
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ole-writer.js"() {
95745
96854
  init_ole2_parser_write();
95746
96855
  init_record_types();
95747
96856
  init_byte_writer();
@@ -95801,7 +96910,7 @@ var init_ole_writer = __esm({
95801
96910
  }
95802
96911
  });
95803
96912
 
95804
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ex-obj-list-writer.js
96913
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ex-obj-list-writer.js
95805
96914
  function buildExObjList(hyperlinks, ole, media) {
95806
96915
  const oleEntries = ole?.all ?? [];
95807
96916
  const mediaEntries = media?.all ?? [];
@@ -95828,7 +96937,7 @@ function buildExObjList(hyperlinks, ole, media) {
95828
96937
  return record(RT.ExternalObjectList, w.toBytes(), 0, true);
95829
96938
  }
95830
96939
  var init_ex_obj_list_writer = __esm({
95831
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ex-obj-list-writer.js"() {
96940
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ex-obj-list-writer.js"() {
95832
96941
  init_record_types();
95833
96942
  init_byte_writer();
95834
96943
  init_hyperlink_writer();
@@ -95837,7 +96946,7 @@ var init_ex_obj_list_writer = __esm({
95837
96946
  }
95838
96947
  });
95839
96948
 
95840
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/anchor-writer.js
96949
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/anchor-writer.js
95841
96950
  function emuToMaster2(emu2) {
95842
96951
  return Math.round(emu2 / EMU_PER_MASTER);
95843
96952
  }
@@ -95882,7 +96991,7 @@ function buildChildAnchor(rect2) {
95882
96991
  }
95883
96992
  var INT16_MIN, INT16_MAX;
95884
96993
  var init_anchor_writer = __esm({
95885
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/anchor-writer.js"() {
96994
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/anchor-writer.js"() {
95886
96995
  init_record_types();
95887
96996
  init_byte_writer();
95888
96997
  INT16_MIN = -32768;
@@ -95890,7 +96999,7 @@ var init_anchor_writer = __esm({
95890
96999
  }
95891
97000
  });
95892
97001
 
95893
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/colors.js
97002
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/colors.js
95894
97003
  function parseHex(rgb2) {
95895
97004
  const hex3 = (rgb2 ?? DEFAULT_RGB).replace(/^#/u, "");
95896
97005
  if (!/^[0-9a-fA-F]{6}$/u.test(hex3)) {
@@ -95912,12 +97021,12 @@ function encodeColorIndex(rgb2) {
95912
97021
  }
95913
97022
  var DEFAULT_RGB;
95914
97023
  var init_colors = __esm({
95915
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/colors.js"() {
97024
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/colors.js"() {
95916
97025
  DEFAULT_RGB = "000000";
95917
97026
  }
95918
97027
  });
95919
97028
 
95920
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-exception-writer.js
97029
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-exception-writer.js
95921
97030
  function writePfException(w, para) {
95922
97031
  let mask = 0;
95923
97032
  if (para.hasBullet !== void 0) {
@@ -96007,7 +97116,7 @@ function writeCfException(w, run, fontIndex) {
96007
97116
  }
96008
97117
  var ALIGN_CODE, EMU_PER_MASTER_UNIT;
96009
97118
  var init_text_exception_writer = __esm({
96010
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-exception-writer.js"() {
97119
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-exception-writer.js"() {
96011
97120
  init_colors();
96012
97121
  ALIGN_CODE = {
96013
97122
  l: 0,
@@ -96019,7 +97128,7 @@ var init_text_exception_writer = __esm({
96019
97128
  }
96020
97129
  });
96021
97130
 
96022
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-atom-writer.js
97131
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-atom-writer.js
96023
97132
  function joinParagraphText(body) {
96024
97133
  return body.paragraphs.map((p) => p.runs.map((r) => r.text).join("")).join("\r");
96025
97134
  }
@@ -96080,7 +97189,7 @@ function buildTextAtoms(body, fonts, hyperlinks) {
96080
97189
  return new ByteWriter().bytes(buildTextHeaderAtom(body.textType)).bytes(buildTextCharsAtom(text2)).bytes(buildStyleTextPropAtom(body, fontIndex)).bytes(buildRunHyperlinks(body, hyperlinks)).toBytes();
96081
97190
  }
96082
97191
  var init_text_atom_writer = __esm({
96083
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-atom-writer.js"() {
97192
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/text-atom-writer.js"() {
96084
97193
  init_record_types();
96085
97194
  init_byte_writer();
96086
97195
  init_hyperlink_writer();
@@ -96088,7 +97197,7 @@ var init_text_atom_writer = __esm({
96088
97197
  }
96089
97198
  });
96090
97199
 
96091
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-placeholders-writer.js
97200
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-placeholders-writer.js
96092
97201
  function utf16z(text2) {
96093
97202
  return new ByteWriter().utf16(text2).u16(0).toBytes();
96094
97203
  }
@@ -96185,7 +97294,7 @@ function buildMasterPlaceholders(placeholders, allocator, fieldFontIndex) {
96185
97294
  }
96186
97295
  var FSP_FLAGS, RECTANGLE_SPT, TEXT_TYPE_TITLE, TEXT_TYPE_BODY, TEXT_TYPE_OTHER, SPECS, MASTER_PLACEHOLDER_ORDER, TITLE_PROMPT, BODY_PROMPT, DEFAULT_FRAMES;
96187
97296
  var init_master_placeholders_writer = __esm({
96188
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-placeholders-writer.js"() {
97297
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-placeholders-writer.js"() {
96189
97298
  init_record_types();
96190
97299
  init_anchor_writer();
96191
97300
  init_byte_writer();
@@ -96252,18 +97361,18 @@ var init_master_placeholders_writer = __esm({
96252
97361
  }
96253
97362
  });
96254
97363
 
96255
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-style-fonts.js
97364
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-style-fonts.js
96256
97365
  function masterStyleFonts(styles) {
96257
97366
  if (!styles)
96258
97367
  return [];
96259
97368
  return [styles.title, styles.body, styles.other].flatMap((levels) => levels ?? []).map((level2) => level2.run.fontName).filter((name) => Boolean(name));
96260
97369
  }
96261
97370
  var init_master_style_fonts = __esm({
96262
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-style-fonts.js"() {
97371
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-style-fonts.js"() {
96263
97372
  }
96264
97373
  });
96265
97374
 
96266
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-text-styles-writer.js
97375
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-text-styles-writer.js
96267
97376
  function buildMasterStyleAtom(recInstance, levels, fontIndex) {
96268
97377
  const w = new ByteWriter().u16(levels.length);
96269
97378
  for (const level2 of levels) {
@@ -96294,7 +97403,7 @@ function buildMasterTextStyles(styles, fontIndex) {
96294
97403
  }
96295
97404
  var EMPTY_LEVELS, FIXED_INSTANCE_DATA;
96296
97405
  var init_master_text_styles_writer = __esm({
96297
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-text-styles-writer.js"() {
97406
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-text-styles-writer.js"() {
96298
97407
  init_record_types();
96299
97408
  init_byte_writer();
96300
97409
  init_text_exception_writer();
@@ -96310,7 +97419,7 @@ var init_master_text_styles_writer = __esm({
96310
97419
  }
96311
97420
  });
96312
97421
 
96313
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-props-writer.js
97422
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-props-writer.js
96314
97423
  function fillEntries(fill) {
96315
97424
  if (!fill || fill.kind === "none") {
96316
97425
  return [{ id: OPT.fNoFillHitTest, value: boolPropValue(false, 16, 1048576) }];
@@ -96365,7 +97474,7 @@ function buildShapeFoptProps(input) {
96365
97474
  }
96366
97475
  var DASH_CODE;
96367
97476
  var init_shape_props_writer = __esm({
96368
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-props-writer.js"() {
97477
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-props-writer.js"() {
96369
97478
  init_colors();
96370
97479
  init_fopt_writer();
96371
97480
  DASH_CODE = {
@@ -96380,7 +97489,7 @@ var init_shape_props_writer = __esm({
96380
97489
  }
96381
97490
  });
96382
97491
 
96383
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-writer.js
97492
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-writer.js
96384
97493
  function buildShapeAnchor(rect2, inGroup) {
96385
97494
  return inGroup ? buildChildAnchor(rect2) : buildClientAnchor(rect2);
96386
97495
  }
@@ -96482,7 +97591,7 @@ function buildMediaShapeContainer(media, allocator, hyperlinks, mediaEmbeds, inG
96482
97591
  }
96483
97592
  var FSP_FLAG_FLIPH, FSP_FLAG_FLIPV, FSP_FLAG_OLE_SHAPE, FSP_FLAG_CHILD, PLACEHOLDER_ID;
96484
97593
  var init_shape_writer = __esm({
96485
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-writer.js"() {
97594
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-writer.js"() {
96486
97595
  init_record_types();
96487
97596
  init_anchor_writer();
96488
97597
  init_byte_writer();
@@ -96504,7 +97613,7 @@ var init_shape_writer = __esm({
96504
97613
  }
96505
97614
  });
96506
97615
 
96507
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/group-writer.js
97616
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/group-writer.js
96508
97617
  function buildFspgr(childRect) {
96509
97618
  return record(OA.FSPGR, buildChildAnchorData(childRect), 0, false, 1);
96510
97619
  }
@@ -96545,7 +97654,7 @@ function buildGroupContainer(group, fonts, allocator, hyperlinks, oleEmbeds, med
96545
97654
  }
96546
97655
  var FSP_FLAG_GROUP, FSP_FLAG_PATRIARCH, FSP_FLAG_HAVE_ANCHOR, ZERO_RECT;
96547
97656
  var init_group_writer = __esm({
96548
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/group-writer.js"() {
97657
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/group-writer.js"() {
96549
97658
  init_record_types();
96550
97659
  init_anchor_writer();
96551
97660
  init_byte_writer();
@@ -96557,10 +97666,10 @@ var init_group_writer = __esm({
96557
97666
  }
96558
97667
  });
96559
97668
 
96560
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-id-allocator.js
97669
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-id-allocator.js
96561
97670
  var ShapeIdAllocator2;
96562
97671
  var init_shape_id_allocator = __esm({
96563
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-id-allocator.js"() {
97672
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/shape-id-allocator.js"() {
96564
97673
  ShapeIdAllocator2 = class {
96565
97674
  current;
96566
97675
  constructor(drawingId, clusterSize) {
@@ -96586,7 +97695,7 @@ var init_shape_id_allocator = __esm({
96586
97695
  }
96587
97696
  });
96588
97697
 
96589
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/drawing-writer.js
97698
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/drawing-writer.js
96590
97699
  function buildDg(drawingId, shapeCount, lastShapeId) {
96591
97700
  const data = new ByteWriter().u32(shapeCount + 1).u32(lastShapeId).toBytes();
96592
97701
  return record(OA.Dg, data, drawingId, false, 0);
@@ -96617,7 +97726,7 @@ function buildDrawing(canvasRect, shapes, backgroundRgb, fonts, drawingId, hyper
96617
97726
  }
96618
97727
  var FSP_FLAG_BACKGROUND, BACKGROUND_RECT_SPT, SHAPE_ID_CLUSTER_SIZE2;
96619
97728
  var init_drawing_writer = __esm({
96620
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/drawing-writer.js"() {
97729
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/drawing-writer.js"() {
96621
97730
  init_record_types();
96622
97731
  init_byte_writer();
96623
97732
  init_colors();
@@ -96630,7 +97739,7 @@ var init_drawing_writer = __esm({
96630
97739
  }
96631
97740
  });
96632
97741
 
96633
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/notes-writer.js
97742
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/notes-writer.js
96634
97743
  function buildNotesAtom(slidePersistIdRef) {
96635
97744
  const data = new ByteWriter().i32(slidePersistIdRef).u16(0).u16(0).toBytes();
96636
97745
  return record(RT.NotesAtom, data, 0, false, 1);
@@ -96648,16 +97757,16 @@ function buildNotesContainer(paragraphs, notesRect, slidePersistIdRef, fonts, dr
96648
97757
  return record(RT.Notes, data, 0, true);
96649
97758
  }
96650
97759
  var init_notes_writer = __esm({
96651
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/notes-writer.js"() {
97760
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/notes-writer.js"() {
96652
97761
  init_record_types();
96653
97762
  init_byte_writer();
96654
97763
  init_drawing_writer();
96655
97764
  }
96656
97765
  });
96657
97766
 
96658
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js
97767
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js
96659
97768
  function readRecord(view, offset) {
96660
- if (offset < 0 || offset + RECORD_HEADER_SIZE > view.byteLength) {
97769
+ if (!Number.isSafeInteger(offset) || offset < 0 || offset + RECORD_HEADER_SIZE > view.byteLength) {
96661
97770
  return void 0;
96662
97771
  }
96663
97772
  const verAndInstance = view.getUint16(offset, true);
@@ -96685,6 +97794,9 @@ function isContainer(rec) {
96685
97794
  return rec.recVer === 15;
96686
97795
  }
96687
97796
  function* iterateRecords(view, start, end) {
97797
+ if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start) {
97798
+ return;
97799
+ }
96688
97800
  let offset = start;
96689
97801
  const limit = Math.min(end, view.byteLength);
96690
97802
  while (offset + RECORD_HEADER_SIZE <= limit) {
@@ -96711,16 +97823,19 @@ function findChild4(view, container2, recType, recInstance) {
96711
97823
  return void 0;
96712
97824
  }
96713
97825
  function findDescendant(view, container2, recType, recInstance) {
96714
- for (const child27 of iterateChildren(view, container2)) {
97826
+ const stack = [iterateChildren(view, container2)];
97827
+ while (stack.length > 0) {
97828
+ const next = stack[stack.length - 1].next();
97829
+ if (next.done) {
97830
+ stack.pop();
97831
+ continue;
97832
+ }
97833
+ const child27 = next.value;
96715
97834
  if (child27.recType === recType && (recInstance === void 0)) {
96716
97835
  return child27;
96717
97836
  }
96718
- if (isContainer(child27)) {
96719
- const found = findDescendant(view, child27, recType, recInstance);
96720
- if (found) {
96721
- return found;
96722
- }
96723
- }
97837
+ if (isContainer(child27))
97838
+ stack.push(iterateChildren(view, child27));
96724
97839
  }
96725
97840
  return void 0;
96726
97841
  }
@@ -96729,7 +97844,7 @@ function recordBytes(data, rec) {
96729
97844
  }
96730
97845
  var PptParseError, RECORD_HEADER_SIZE;
96731
97846
  var init_legacy_ppt_record_stream = __esm({
96732
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js"() {
97847
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-record-stream.js"() {
96733
97848
  PptParseError = class extends Error {
96734
97849
  constructor(message) {
96735
97850
  super(message);
@@ -96740,14 +97855,14 @@ var init_legacy_ppt_record_stream = __esm({
96740
97855
  }
96741
97856
  });
96742
97857
 
96743
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/record-stream.js
97858
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/record-stream.js
96744
97859
  var init_record_stream = __esm({
96745
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/record-stream.js"() {
97860
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/record-stream.js"() {
96746
97861
  init_legacy_ppt_record_stream();
96747
97862
  }
96748
97863
  });
96749
97864
 
96750
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/color-scheme.js
97865
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/color-scheme.js
96751
97866
  function toHex3(r, g, b) {
96752
97867
  return [r, g, b].map((v) => (v & 255).toString(16).padStart(2, "0").toUpperCase()).join("");
96753
97868
  }
@@ -96798,7 +97913,7 @@ function resolveEscherColor(colorRef, scheme) {
96798
97913
  }
96799
97914
  var SCHEME, DEFAULT_SCHEME;
96800
97915
  var init_color_scheme = __esm({
96801
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/color-scheme.js"() {
97916
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/color-scheme.js"() {
96802
97917
  init_record_stream();
96803
97918
  init_record_types();
96804
97919
  SCHEME = {
@@ -96824,7 +97939,7 @@ var init_color_scheme = __esm({
96824
97939
  }
96825
97940
  });
96826
97941
 
96827
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/color-scheme-writer.js
97942
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/color-scheme-writer.js
96828
97943
  function buildColorSchemeAtom(recInstance = 1, colors) {
96829
97944
  const w = new ByteWriter();
96830
97945
  for (const rgb2 of colors?.length === 8 ? colors : DEFAULT_SCHEME) {
@@ -96833,7 +97948,7 @@ function buildColorSchemeAtom(recInstance = 1, colors) {
96833
97948
  return record(RT.ColorSchemeAtom, w.toBytes(), recInstance, false, 0);
96834
97949
  }
96835
97950
  var init_color_scheme_writer = __esm({
96836
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/color-scheme-writer.js"() {
97951
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/color-scheme-writer.js"() {
96837
97952
  init_color_scheme();
96838
97953
  init_record_types();
96839
97954
  init_byte_writer();
@@ -96841,7 +97956,7 @@ var init_color_scheme_writer = __esm({
96841
97956
  }
96842
97957
  });
96843
97958
 
96844
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/slide-writer.js
97959
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/slide-writer.js
96845
97960
  function buildSlideAtomRaw(geom, masterIdRef, notesIdRef, flags) {
96846
97961
  const data = new ByteWriter().i32(geom).bytes(new Uint8Array(8)).u32(masterIdRef).i32(notesIdRef).u16(flags).u16(0).toBytes();
96847
97962
  return record(RT.SlideAtom, data, 0, false, 2);
@@ -96878,7 +97993,7 @@ function buildMainMasterContainer(slideRect, drawingId, hyperlinks, oleEmbeds, m
96878
97993
  }
96879
97994
  var SLIDE_FLAG_MASTER_OBJECTS, SLIDE_FLAG_MASTER_SCHEME, SLIDE_FLAG_MASTER_BACKGROUND, SLIDE_MASTER_ID_SENTINEL, MASTER_FIRST_COLOR_SCHEME_INSTANCE;
96880
97995
  var init_slide_writer = __esm({
96881
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/slide-writer.js"() {
97996
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/slide-writer.js"() {
96882
97997
  init_record_types();
96883
97998
  init_byte_writer();
96884
97999
  init_color_scheme_writer();
@@ -96893,7 +98008,7 @@ var init_slide_writer = __esm({
96893
98008
  }
96894
98009
  });
96895
98010
 
96896
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-stream-layout.js
98011
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-stream-layout.js
96897
98012
  function masterSlideId(index) {
96898
98013
  return MASTER_SLIDE_ID_SENTINEL + index;
96899
98014
  }
@@ -97017,7 +98132,7 @@ function ensureMinimumDocumentStreamSize(contentSizeWithoutPadding, maxPersistId
97017
98132
  }
97018
98133
  var DOC_ID, MASTER_ID;
97019
98134
  var init_document_stream_layout = __esm({
97020
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-stream-layout.js"() {
98135
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/document-stream-layout.js"() {
97021
98136
  init_bstore_writer();
97022
98137
  init_byte_writer();
97023
98138
  init_document_writer();
@@ -97035,15 +98150,15 @@ var init_document_stream_layout = __esm({
97035
98150
  }
97036
98151
  });
97037
98152
 
97038
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/crypto-constants.js
98153
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/crypto-constants.js
97039
98154
  var RC4_ALG_ID2;
97040
98155
  var init_crypto_constants = __esm({
97041
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/crypto-constants.js"() {
98156
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/crypto-constants.js"() {
97042
98157
  RC4_ALG_ID2 = 26625;
97043
98158
  }
97044
98159
  });
97045
98160
 
97046
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/rc4-cipher.js
98161
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/rc4-cipher.js
97047
98162
  function rc4Cipher(key2, data) {
97048
98163
  if (key2.length === 0) {
97049
98164
  throw new Error("RC4 key must not be empty.");
@@ -97074,11 +98189,11 @@ function rc4Cipher(key2, data) {
97074
98189
  return out;
97075
98190
  }
97076
98191
  var init_rc4_cipher = __esm({
97077
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/rc4-cipher.js"() {
98192
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/rc4-cipher.js"() {
97078
98193
  }
97079
98194
  });
97080
98195
 
97081
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-key.js
98196
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-key.js
97082
98197
  async function rc4CryptoApiKeyBase(password, salt) {
97083
98198
  return hash("SHA-1", concatArrays(salt, encodePasswordUtf16LE(password)));
97084
98199
  }
@@ -97119,14 +98234,14 @@ async function rc4CryptoApiEncryptVerifier(key0, verifier) {
97119
98234
  }
97120
98235
  var PADDED_40_BIT_KEY_BYTES;
97121
98236
  var init_rc4_cryptoapi_key = __esm({
97122
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-key.js"() {
98237
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-key.js"() {
97123
98238
  init_ooxml_crypto_primitives();
97124
98239
  init_rc4_cipher();
97125
98240
  PADDED_40_BIT_KEY_BYTES = 16;
97126
98241
  }
97127
98242
  });
97128
98243
 
97129
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-streams.js
98244
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-streams.js
97130
98245
  function readHeader(bytes) {
97131
98246
  const view = new DataView(bytes.buffer, bytes.byteOffset, RECORD_HEADER_SIZE);
97132
98247
  return {
@@ -97195,7 +98310,7 @@ async function cipherPicturesStream(stream, keyFor2, mode) {
97195
98310
  }
97196
98311
  var UID_SIZE, METAFILE_HEADER_SIZE, BITMAP_TAG_SIZE, METAFILE_BLIPS, BITMAP_BLIPS;
97197
98312
  var init_rc4_cryptoapi_streams = __esm({
97198
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-streams.js"() {
98313
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/rc4-cryptoapi-streams.js"() {
97199
98314
  init_rc4_cipher();
97200
98315
  init_record_stream();
97201
98316
  UID_SIZE = 16;
@@ -97206,7 +98321,7 @@ var init_rc4_cryptoapi_streams = __esm({
97206
98321
  }
97207
98322
  });
97208
98323
 
97209
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/encrypt-writer.js
98324
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/encrypt-writer.js
97210
98325
  async function buildCryptSession(password) {
97211
98326
  const salt = new Uint8Array(SALT_SIZE);
97212
98327
  crypto.getRandomValues(salt);
@@ -97234,7 +98349,7 @@ async function encryptPicturesStream(stream, ctx) {
97234
98349
  }
97235
98350
  var CSP_NAME, KEY_SIZE_BITS, SALT_SIZE, VERIFIER_SIZE, VERIFIER_HASH_SIZE, ENCRYPTION_FLAGS;
97236
98351
  var init_encrypt_writer = __esm({
97237
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/encrypt-writer.js"() {
98352
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/encrypt-writer.js"() {
97238
98353
  init_crypto_constants();
97239
98354
  init_rc4_cryptoapi_key();
97240
98355
  init_rc4_cryptoapi_streams();
@@ -97249,7 +98364,7 @@ var init_encrypt_writer = __esm({
97249
98364
  }
97250
98365
  });
97251
98366
 
97252
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-relative-runs.js
98367
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-relative-runs.js
97253
98368
  function levelsFor(styles, textType) {
97254
98369
  switch (textType) {
97255
98370
  case 0:
@@ -97315,12 +98430,12 @@ function withMasterRelativeRunStyles(deck) {
97315
98430
  }
97316
98431
  var STYLE_KEYS;
97317
98432
  var init_master_relative_runs = __esm({
97318
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-relative-runs.js"() {
98433
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/master-relative-runs.js"() {
97319
98434
  STYLE_KEYS = ["bold", "italic", "underline"];
97320
98435
  }
97321
98436
  });
97322
98437
 
97323
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/persist-writer.js
98438
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/persist-writer.js
97324
98439
  function buildPersistDirectoryAtom(entries) {
97325
98440
  const sorted = [...entries].sort((a, b) => a[0] - b[0]);
97326
98441
  const w = new ByteWriter();
@@ -97350,17 +98465,17 @@ function buildEncryptedUserEditAtom(input) {
97350
98465
  }
97351
98466
  var MAX_RUN;
97352
98467
  var init_persist_writer = __esm({
97353
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/persist-writer.js"() {
98468
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/persist-writer.js"() {
97354
98469
  init_record_types();
97355
98470
  init_byte_writer();
97356
98471
  MAX_RUN = 4095;
97357
98472
  }
97358
98473
  });
97359
98474
 
97360
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ppt-clsid.js
98475
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ppt-clsid.js
97361
98476
  var PPT_STORAGE_CLSID;
97362
98477
  var init_ppt_clsid = __esm({
97363
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/ppt-clsid.js"() {
98478
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/ppt-clsid.js"() {
97364
98479
  PPT_STORAGE_CLSID = new Uint8Array([
97365
98480
  16,
97366
98481
  141,
@@ -97382,7 +98497,7 @@ var init_ppt_clsid = __esm({
97382
98497
  }
97383
98498
  });
97384
98499
 
97385
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/write-ppt.js
98500
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/write-ppt.js
97386
98501
  async function finishUnencrypted(layout, lastSlideId) {
97387
98502
  const w = new ByteWriter().append(layout.bytes);
97388
98503
  const dirAtom = buildPersistDirectoryAtom(layout.offsets);
@@ -97436,7 +98551,7 @@ async function buildPptFile(deck, options = {}) {
97436
98551
  return new Uint8Array(buildOle2(streams2, PPT_STORAGE_CLSID, 0));
97437
98552
  }
97438
98553
  var init_write_ppt = __esm({
97439
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/writer/write-ppt.js"() {
98554
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/writer/write-ppt.js"() {
97440
98555
  init_ole2_parser_write();
97441
98556
  init_byte_writer();
97442
98557
  init_current_user_writer();
@@ -97448,9 +98563,9 @@ var init_write_ppt = __esm({
97448
98563
  }
97449
98564
  });
97450
98565
 
97451
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-writer.js
98566
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-writer.js
97452
98567
  var init_legacy_ppt_writer = __esm({
97453
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/legacy-ppt-writer.js"() {
98568
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/legacy-ppt-writer.js"() {
97454
98569
  init_write_ppt();
97455
98570
  init_master_style_fonts();
97456
98571
  }
@@ -136980,61 +138095,115 @@ var init_deflate_utils = __esm({
136980
138095
  }
136981
138096
  });
136982
138097
 
136983
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js
136984
- function parseUserEditAtom(view, offset) {
138098
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js
138099
+ function checkedLimit(value) {
138100
+ if (!Number.isSafeInteger(value) || value < 1)
138101
+ throw new PptParseError("Invalid persist directory resource limit");
138102
+ return value;
138103
+ }
138104
+ function boundedAtom(view, offset, type) {
136985
138105
  const rec = readRecordOrThrow(view, offset);
136986
- if (rec.recType !== RT.UserEditAtom) {
136987
- throw new PptParseError(`Expected UserEditAtom at offset ${offset}, found recType 0x${rec.recType.toString(16)}`);
138106
+ if (rec.recType !== type || rec.recVer !== 0 || rec.recInstance !== 0) {
138107
+ throw new PptParseError(`Invalid persist atom header at offset ${offset}`);
138108
+ }
138109
+ if (rec.recLen > view.byteLength - rec.dataOffset) {
138110
+ throw new PptParseError(`Persist atom payload out of bounds at offset ${offset}`);
136988
138111
  }
138112
+ return rec;
138113
+ }
138114
+ function parseUserEditAtom(view, offset) {
138115
+ const rec = boundedAtom(view, offset, RT.UserEditAtom);
136989
138116
  if (rec.recLen !== 28 && rec.recLen !== 32) {
136990
138117
  throw new PptParseError(`UserEditAtom has invalid length ${rec.recLen}`);
136991
138118
  }
136992
138119
  const d = rec.dataOffset;
136993
- return {
138120
+ const edit = {
136994
138121
  offsetLastEdit: view.getUint32(d + 8, true),
136995
138122
  offsetPersistDirectory: view.getUint32(d + 12, true),
136996
138123
  docPersistIdRef: view.getUint32(d + 16, true),
136997
138124
  encryptSessionPersistIdRef: rec.recLen === 32 ? view.getUint32(d + 28, true) : void 0
136998
138125
  };
136999
- }
137000
- function parsePersistDirectoryAtom(view, offset) {
137001
- const rec = readRecordOrThrow(view, offset);
137002
- if (rec.recType !== RT.PersistDirectoryAtom) {
137003
- throw new PptParseError(`Expected PersistDirectoryAtom at offset ${offset}, found recType 0x${rec.recType.toString(16)}`);
138126
+ if (view.getUint8(d + 6) !== 0 || view.getUint8(d + 7) !== 3) {
138127
+ throw new PptParseError("Unsupported UserEditAtom storage version");
138128
+ }
138129
+ if (edit.offsetLastEdit >= offset || edit.offsetPersistDirectory <= edit.offsetLastEdit || edit.offsetPersistDirectory >= offset) {
138130
+ throw new PptParseError("Invalid UserEditAtom save history offsets");
137004
138131
  }
138132
+ if (edit.docPersistIdRef !== 1)
138133
+ throw new PptParseError("Invalid document persist identifier");
138134
+ return edit;
138135
+ }
138136
+ function parsePersistDirectoryAtom(view, offset, maxEntries = DEFAULT_MAX_ENTRIES) {
138137
+ checkedLimit(maxEntries);
138138
+ const rec = boundedAtom(view, offset, RT.PersistDirectoryAtom);
137005
138139
  const pairs = [];
137006
138140
  let pos2 = rec.dataOffset;
137007
138141
  const end = rec.dataOffset + rec.recLen;
137008
- while (pos2 + 4 <= end) {
138142
+ const seen = /* @__PURE__ */ new Set();
138143
+ while (pos2 < end) {
138144
+ if (end - pos2 < 4)
138145
+ throw new PptParseError("Truncated persist directory entry");
137009
138146
  const packed = view.getUint32(pos2, true);
137010
138147
  const persistId = packed & 1048575;
137011
138148
  const cPersist = packed >>> 20 & 4095;
137012
138149
  pos2 += 4;
137013
- for (let i = 0; i < cPersist && pos2 + 4 <= end; i++, pos2 += 4) {
137014
- pairs.push([persistId + i, view.getUint32(pos2, true)]);
138150
+ if (persistId > 1048574 || cPersist === 0 || persistId + cPersist - 1 > 1048575) {
138151
+ throw new PptParseError("Invalid persist identifier run");
138152
+ }
138153
+ if (cPersist * 4 > end - pos2)
138154
+ throw new PptParseError("Truncated persist offset run");
138155
+ if (pairs.length + cPersist > maxEntries)
138156
+ throw new PptParseError("Persist directory entry limit exceeded");
138157
+ for (let i = 0; i < cPersist; i++, pos2 += 4) {
138158
+ const id = persistId + i;
138159
+ if (seen.has(id))
138160
+ throw new PptParseError("Duplicate persist identifier");
138161
+ seen.add(id);
138162
+ const objectOffset = view.getUint32(pos2, true);
138163
+ if (objectOffset >= offset || objectOffset + 8 > view.byteLength)
138164
+ throw new PptParseError("Persist object offset out of bounds");
138165
+ pairs.push([id, objectOffset]);
137015
138166
  }
137016
138167
  }
137017
138168
  return pairs;
137018
138169
  }
137019
- function buildPersistDirectory(view, offsetToCurrentEdit) {
138170
+ function buildPersistDirectory(view, offsetToCurrentEdit, limits = {}) {
138171
+ const maxEdits = checkedLimit(limits.maxEdits ?? DEFAULT_MAX_EDITS);
138172
+ const maxEntries = checkedLimit(limits.maxEntries ?? DEFAULT_MAX_ENTRIES);
137020
138173
  const edits = [];
138174
+ const editOffsets = [];
137021
138175
  const seen = /* @__PURE__ */ new Set();
137022
138176
  let offset = offsetToCurrentEdit;
137023
138177
  while (offset !== 0) {
138178
+ if (edits.length >= maxEdits)
138179
+ throw new PptParseError("User edit chain limit exceeded");
137024
138180
  if (seen.has(offset)) {
137025
138181
  throw new PptParseError(`Circular UserEditAtom chain at offset ${offset}`);
137026
138182
  }
137027
138183
  seen.add(offset);
137028
138184
  const edit = parseUserEditAtom(view, offset);
137029
138185
  edits.push(edit);
138186
+ editOffsets.push(offset);
137030
138187
  offset = edit.offsetLastEdit;
137031
138188
  }
137032
138189
  if (edits.length === 0) {
137033
138190
  throw new PptParseError("No UserEditAtom found");
137034
138191
  }
137035
138192
  const directory = /* @__PURE__ */ new Map();
138193
+ let entryCount = 0;
137036
138194
  for (let i = edits.length - 1; i >= 0; i--) {
137037
- for (const [id, off] of parsePersistDirectoryAtom(view, edits[i].offsetPersistDirectory)) {
138195
+ const edit = edits[i];
138196
+ const dirAtom = boundedAtom(view, edit.offsetPersistDirectory, RT.PersistDirectoryAtom);
138197
+ const editOffset = editOffsets[i];
138198
+ if (dirAtom.dataOffset + dirAtom.recLen > editOffset)
138199
+ throw new PptParseError("Persist directory overlaps user edit");
138200
+ const entries = parsePersistDirectoryAtom(view, edit.offsetPersistDirectory, maxEntries);
138201
+ entryCount += entries.length;
138202
+ if (entryCount > maxEntries)
138203
+ throw new PptParseError("Save history persist entry limit exceeded");
138204
+ for (const [id, off] of entries) {
138205
+ if (off < edit.offsetLastEdit)
138206
+ throw new PptParseError("Persist object precedes corresponding user edit");
137038
138207
  directory.set(id, off);
137039
138208
  }
137040
138209
  }
@@ -137045,12 +138214,18 @@ function readPersistRecord(view, directory, persistId) {
137045
138214
  if (offset === void 0) {
137046
138215
  return void 0;
137047
138216
  }
137048
- return readRecordOrThrow(view, offset);
138217
+ const rec = readRecordOrThrow(view, offset);
138218
+ if (rec.recLen > view.byteLength - rec.dataOffset)
138219
+ throw new PptParseError("Persist object payload out of bounds");
138220
+ return rec;
137049
138221
  }
138222
+ var DEFAULT_MAX_EDITS, DEFAULT_MAX_ENTRIES;
137050
138223
  var init_persist_directory = __esm({
137051
- "node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js"() {
138224
+ "node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ppt/persist-directory.js"() {
137052
138225
  init_record_stream();
137053
138226
  init_record_types();
138227
+ DEFAULT_MAX_EDITS = 1e4;
138228
+ DEFAULT_MAX_ENTRIES = 1e6;
137054
138229
  }
137055
138230
  });
137056
138231