@forevka/wordcanvas 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +48 -1
  2. package/dist-lib/assets/{worker-BsOsK39A.js → worker-4HYrkNrG.js} +12276 -11981
  3. package/dist-lib/assets/worker-CJpwUzKh.js +2403 -0
  4. package/dist-lib/blockFactory-B_CLnkUh.js +106 -0
  5. package/dist-lib/browser-p_rkUcqE.js +1339 -0
  6. package/dist-lib/builder.js +365 -109
  7. package/dist-lib/editorApp-mTD0YNv-.js +9863 -0
  8. package/dist-lib/export.js +4670 -4567
  9. package/dist-lib/generate-toc.js +5 -5
  10. package/dist-lib/import.js +4 -1538
  11. package/dist-lib/{lists-BegzmTmD.js → lists-Sc5I40JO.js} +2 -2
  12. package/dist-lib/measure.js +2 -2
  13. package/dist-lib/{measureHost-CMiJKdlk.js → measureHost-B2aKX7lF.js} +1 -1
  14. package/dist-lib/metrics-BUMIC9Mv.js +164 -0
  15. package/dist-lib/pipeline-DD0nxAYM.js +1850 -0
  16. package/dist-lib/recalc-docx.js +2 -2
  17. package/dist-lib/recalcToc-CFCGCgij.js +3985 -0
  18. package/dist-lib/styleProps-DhqDEfvc.js +149 -0
  19. package/dist-lib/stylesheet-B6oczA-L.js +141 -0
  20. package/dist-lib/toc-Dj57zdz-.js +213 -0
  21. package/dist-lib/{webmcp-B7Gvd58E.js → webmcp-CXghUon_.js} +2 -2
  22. package/dist-lib/{wordcanvas-BAxBeErX.js → wordcanvas-D5DI9ZR1.js} +49 -23
  23. package/dist-lib/wordcanvas.js +1 -1
  24. package/dist-node/{chunk-GXFDF7UY.js → chunk-57L5XMCL.js} +327 -59
  25. package/dist-node/chunk-57L5XMCL.js.map +7 -0
  26. package/dist-node/{chunk-TBSXA2I4.js → chunk-EGSAVPCC.js} +1 -1
  27. package/dist-node/chunk-EGSAVPCC.js.map +7 -0
  28. package/dist-node/{chunk-4PDVRJF6.js → chunk-EMY2P524.js} +32 -2
  29. package/dist-node/chunk-EMY2P524.js.map +7 -0
  30. package/dist-node/{chunk-2RCPB7UZ.js → chunk-KJV7GJ3H.js} +1 -1
  31. package/dist-node/chunk-KJV7GJ3H.js.map +7 -0
  32. package/dist-node/{chunk-XDUDPPJW.js → chunk-PIMVQULL.js} +93 -24
  33. package/dist-node/chunk-PIMVQULL.js.map +7 -0
  34. package/dist-node/{chunk-BRAPV465.js → chunk-SA26UVIJ.js} +2 -2
  35. package/dist-node/{chunk-IJLL6IFJ.js → chunk-T3253N22.js} +202 -13
  36. package/dist-node/{chunk-IJLL6IFJ.js.map → chunk-T3253N22.js.map} +2 -2
  37. package/dist-node/{chunk-4ICCHZX4.js → chunk-U27EBKBG.js} +37 -1
  38. package/dist-node/chunk-U27EBKBG.js.map +7 -0
  39. package/dist-node/{engine-FRCX7PXF.js → engine-5F7DUU4W.js} +4 -4
  40. package/dist-node/export.js +178 -52
  41. package/dist-node/export.js.map +2 -2
  42. package/dist-node/generate-toc.js +7 -7
  43. package/dist-node/import.js +3 -3
  44. package/dist-node/measure.js +2 -2
  45. package/dist-node/recalc-docx.js +5 -5
  46. package/dist-node/recalc-docx.js.map +1 -1
  47. package/package.json +1 -1
  48. package/types/model.d.ts +277 -225
  49. package/types/recalc-docx.d.ts +27 -27
  50. package/types/wordcanvas.d.ts +212 -157
  51. package/dist-lib/assets/worker-BbFAIxdy.js +0 -2163
  52. package/dist-lib/blockFactory-Bcy0U40y.js +0 -178
  53. package/dist-lib/browser-5Sv4CuNy.js +0 -1284
  54. package/dist-lib/editorApp-DvjFPHiy.js +0 -7582
  55. package/dist-lib/metrics-CkAo4zh8.js +0 -143
  56. package/dist-lib/recalcToc-uaLWt59L.js +0 -3835
  57. package/dist-lib/styleProps-Db5pEkG8.js +0 -127
  58. package/dist-lib/toc-CZel_Kk3.js +0 -127
  59. package/dist-node/chunk-2RCPB7UZ.js.map +0 -7
  60. package/dist-node/chunk-4ICCHZX4.js.map +0 -7
  61. package/dist-node/chunk-4PDVRJF6.js.map +0 -7
  62. package/dist-node/chunk-GXFDF7UY.js.map +0 -7
  63. package/dist-node/chunk-TBSXA2I4.js.map +0 -7
  64. package/dist-node/chunk-XDUDPPJW.js.map +0 -7
  65. /package/dist-node/{chunk-BRAPV465.js.map → chunk-SA26UVIJ.js.map} +0 -0
  66. /package/dist-node/{engine-FRCX7PXF.js.map → engine-5F7DUU4W.js.map} +0 -0
@@ -9,12 +9,12 @@ import {
9
9
  formatListNumber,
10
10
  isHiddenParagraph,
11
11
  markerText
12
- } from "./chunk-XDUDPPJW.js";
12
+ } from "./chunk-PIMVQULL.js";
13
13
  import {
14
14
  charStyleToFont,
15
15
  fontMetrics,
16
16
  measureTextWidth
17
- } from "./chunk-4ICCHZX4.js";
17
+ } from "./chunk-U27EBKBG.js";
18
18
 
19
19
  // ../node_modules/@chenglou/pretext/dist/generated/bidi-data.js
20
20
  var latin1BidiTypes = [
@@ -3868,6 +3868,12 @@ var PrepareCache = class {
3868
3868
  evict(blockId) {
3869
3869
  this.map.delete(blockId);
3870
3870
  }
3871
+ /** Drop every entry — used when the whole document is replaced (the importer
3872
+ * re-mints block ids from i0, so a stale entry at the same id+revision would
3873
+ * otherwise leak the previous document's prepared text into the new one). */
3874
+ clear() {
3875
+ this.map.clear();
3876
+ }
3871
3877
  /** Drop every entry whose id is NOT in `keep` (paragraphs no longer in the
3872
3878
  * document). Called after a full layout to bound the cache to live blocks. */
3873
3879
  retainOnly(keep) {
@@ -3910,6 +3916,10 @@ function createLayoutEngine() {
3910
3916
  evict(blockId) {
3911
3917
  prepCache.evict(blockId);
3912
3918
  linesCache.delete(blockId);
3919
+ },
3920
+ reset() {
3921
+ prepCache.clear();
3922
+ linesCache.clear();
3913
3923
  }
3914
3924
  };
3915
3925
  }
@@ -4058,6 +4068,7 @@ function layoutTabbedSegment(p, segRuns, segStart, contentWidth, firstIndent) {
4058
4068
  const out = [];
4059
4069
  let curFrags = [];
4060
4070
  let curLeaders = [];
4071
+ let curArrows = [];
4061
4072
  let curX = firstIndent;
4062
4073
  let maxH = 0;
4063
4074
  let maxA = 0;
@@ -4079,10 +4090,12 @@ function layoutTabbedSegment(p, segRuns, segStart, contentWidth, firstIndent) {
4079
4090
  // A tab-positioned line stays ragged (its manual x must not be re-justified);
4080
4091
  // pure wrapped continuation lines justify normally when the paragraph does.
4081
4092
  lastOfSegment: isLast || hasTab,
4082
- ...curLeaders.length > 0 ? { leaders: curLeaders } : {}
4093
+ ...curLeaders.length > 0 ? { leaders: curLeaders } : {},
4094
+ ...curArrows.length > 0 ? { tabArrows: curArrows } : {}
4083
4095
  });
4084
4096
  curFrags = [];
4085
4097
  curLeaders = [];
4098
+ curArrows = [];
4086
4099
  curX = 0;
4087
4100
  maxH = 0;
4088
4101
  maxA = 0;
@@ -4102,6 +4115,7 @@ function layoutTabbedSegment(p, segRuns, segStart, contentWidth, firstIndent) {
4102
4115
  if ((stop.leader ?? "none") !== "none" && targetX > curX + 1 && baseStyle) {
4103
4116
  curLeaders.push({ x1: curX, x2: targetX, kind: stop.leader ?? "none", color: baseStyle.color, fontSizePx: baseStyle.fontSizePx });
4104
4117
  }
4118
+ curArrows.push({ x1: curX, x2: Math.max(targetX, curX) });
4105
4119
  curX = targetX;
4106
4120
  hasTab = true;
4107
4121
  }
@@ -4154,10 +4168,13 @@ function paragraphLines(p, contentWidth, cache) {
4154
4168
  const lines = [];
4155
4169
  const raw = [];
4156
4170
  let first = true;
4157
- for (const seg of segments) {
4171
+ const segLastLine = [];
4172
+ for (let si = 0; si < segments.length; si++) {
4173
+ const seg = segments[si];
4158
4174
  if (seg.runs.some((r) => r.text.includes(" "))) {
4159
4175
  raw.push(...layoutTabbedSegment(p, seg.runs, seg.startOffset, contentWidth, first ? p.style.indentFirstLinePx : 0));
4160
4176
  first = false;
4177
+ segLastLine[si] = raw.length - 1;
4161
4178
  continue;
4162
4179
  }
4163
4180
  const runStarts = segRunOffsets(seg.runs, seg.startOffset);
@@ -4198,6 +4215,13 @@ function paragraphLines(p, contentWidth, cache) {
4198
4215
  } else {
4199
4216
  raw[raw.length - 1].lastOfSegment = true;
4200
4217
  }
4218
+ segLastLine[si] = raw.length - 1;
4219
+ }
4220
+ for (let si = 0; si < segLastLine.length; si++) {
4221
+ const idx = segLastLine[si];
4222
+ if (idx === void 0) continue;
4223
+ if (si === segments.length - 1) raw[idx].paragraphEnd = true;
4224
+ else raw[idx].lineBreak = true;
4201
4225
  }
4202
4226
  let y = 0;
4203
4227
  for (const rl of raw) {
@@ -4212,6 +4236,11 @@ function paragraphLines(p, contentWidth, cache) {
4212
4236
  if (rl.leaders && rl.leaders.length > 0) {
4213
4237
  box.leaders = rl.leaders.map((l) => ({ ...l, x1: l.x1 + startX, x2: l.x2 + startX }));
4214
4238
  }
4239
+ if (rl.tabArrows && rl.tabArrows.length > 0) {
4240
+ box.tabArrows = rl.tabArrows.map((a) => ({ x1: a.x1 + startX, x2: a.x2 + startX }));
4241
+ }
4242
+ if (rl.paragraphEnd) box.paragraphEnd = true;
4243
+ if (rl.lineBreak) box.lineBreak = true;
4215
4244
  lines.push(box);
4216
4245
  y += rl.height;
4217
4246
  }
@@ -4234,6 +4263,10 @@ function effectiveSection(base, patch) {
4234
4263
  if (headerDist !== void 0) out.headerDistancePx = headerDist;
4235
4264
  const footerDist = patch.footerDistancePx ?? base.footerDistancePx;
4236
4265
  if (footerDist !== void 0) out.footerDistancePx = footerDist;
4266
+ const pageColorHex = patch.pageColorHex ?? base.pageColorHex;
4267
+ if (pageColorHex !== void 0) out.pageColorHex = pageColorHex;
4268
+ const pageBorders = patch.pageBorders ?? base.pageBorders;
4269
+ if (pageBorders !== void 0) out.pageBorders = pageBorders;
4237
4270
  for (const key of BAND_KEYS) {
4238
4271
  const blocks = patch[key] ?? base[key];
4239
4272
  if (blocks) out[key] = blocks;
@@ -4311,8 +4344,9 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4311
4344
  let contentBottom = 0;
4312
4345
  let contentWidth = 0;
4313
4346
  let colCount = 1;
4314
- let colGap = 0;
4315
4347
  let colWidth = 0;
4348
+ let colBoxes = [];
4349
+ let colSeparatorsX = [];
4316
4350
  const applySection = (props) => {
4317
4351
  sec = props;
4318
4352
  const box = contentBoxOf(sec);
@@ -4321,8 +4355,27 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4321
4355
  contentBottom = box.bottom;
4322
4356
  contentWidth = sec.pageWidthPx - sec.marginPx.left - sec.marginPx.right;
4323
4357
  colCount = Math.max(1, sec.columns?.count ?? 1);
4324
- colGap = sec.columns?.gapPx ?? 24;
4325
- colWidth = colCount > 1 ? (contentWidth - (colCount - 1) * colGap) / colCount : contentWidth;
4358
+ const gap = sec.columns?.gapPx ?? 24;
4359
+ const cols = sec.columns?.cols;
4360
+ if (colCount > 1 && cols && cols.length === colCount) {
4361
+ let x = contentX;
4362
+ colBoxes = cols.map((c, i) => {
4363
+ const b = { x, width: c.widthPx };
4364
+ x += c.widthPx + (i < colCount - 1 ? c.spaceAfterPx : 0);
4365
+ return b;
4366
+ });
4367
+ colWidth = Math.min(...cols.map((c) => c.widthPx));
4368
+ } else if (colCount > 1) {
4369
+ colWidth = (contentWidth - (colCount - 1) * gap) / colCount;
4370
+ colBoxes = Array.from({ length: colCount }, (_, i) => ({
4371
+ x: contentX + i * (colWidth + gap),
4372
+ width: colWidth
4373
+ }));
4374
+ } else {
4375
+ colWidth = contentWidth;
4376
+ colBoxes = [{ x: contentX, width: contentWidth }];
4377
+ }
4378
+ colSeparatorsX = sec.columns?.sep ? colBoxes.slice(0, -1).map((b, i) => (b.x + b.width + colBoxes[i + 1].x) / 2) : [];
4326
4379
  };
4327
4380
  applySection(sec);
4328
4381
  const lists = doc.lists ?? {};
@@ -4379,7 +4432,7 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4379
4432
  lines: getLines(block, colWidth - indentOf(block) - rightIndentOf(block) - gutter)
4380
4433
  });
4381
4434
  } else if (block.kind === "image") {
4382
- measured.push({ kind: "image", block, height: block.heightPx });
4435
+ measured.push({ kind: "image", block, height: block.anchor ? 0 : block.heightPx });
4383
4436
  } else {
4384
4437
  const t = measureTable(block, colWidth, getLines, cellListCtx);
4385
4438
  measured.push({ kind: "table", block, ...t });
@@ -4390,7 +4443,7 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4390
4443
  const pageSections = [];
4391
4444
  const mkPage = () => {
4392
4445
  pageSections.push(sec);
4393
- return {
4446
+ const p = {
4394
4447
  index: pageSections.length - 1,
4395
4448
  number: pageSections.length,
4396
4449
  // provisional; the post-pass sets the real value
@@ -4401,6 +4454,10 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4401
4454
  contentTopPx: contentTop,
4402
4455
  contentBottomPx: contentBottom
4403
4456
  };
4457
+ if (sec.pageColorHex !== void 0) p.pageColorHex = sec.pageColorHex;
4458
+ if (sec.pageBorders !== void 0) p.pageBorders = sec.pageBorders;
4459
+ if (colSeparatorsX.length) p.columnSeparatorsX = colSeparatorsX.slice();
4460
+ return p;
4404
4461
  };
4405
4462
  const pages = [mkPage()];
4406
4463
  let page = pages[0];
@@ -4440,7 +4497,7 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4440
4497
  };
4441
4498
  let colIdx = 0;
4442
4499
  let colStartCount = 0;
4443
- const colX = () => contentX + colIdx * (colWidth + colGap);
4500
+ const colX = () => colBoxes[colIdx]?.x ?? contentX;
4444
4501
  const colHasContent = () => page.blocks.length > colStartCount;
4445
4502
  const hardPage = () => {
4446
4503
  colIdx = 0;
@@ -4470,6 +4527,12 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4470
4527
  page.marginPx = sec.marginPx;
4471
4528
  page.contentTopPx = contentTop;
4472
4529
  page.contentBottomPx = contentBottom;
4530
+ if (sec.pageColorHex !== void 0) page.pageColorHex = sec.pageColorHex;
4531
+ else delete page.pageColorHex;
4532
+ if (sec.pageBorders !== void 0) page.pageBorders = sec.pageBorders;
4533
+ else delete page.pageBorders;
4534
+ if (colSeparatorsX.length) page.columnSeparatorsX = colSeparatorsX.slice();
4535
+ else delete page.columnSeparatorsX;
4473
4536
  pageSections[page.index] = sec;
4474
4537
  colIdx = 0;
4475
4538
  colStartCount = 0;
@@ -4610,7 +4673,59 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4610
4673
  return { x0, width: Math.max(40, x1 - x0) };
4611
4674
  };
4612
4675
  const floatsActiveAt = (yy) => floats.some((f) => f.bottom > yy);
4676
+ const placeAnchoredImage = (img) => {
4677
+ const a = img.anchor;
4678
+ let ox;
4679
+ switch (a.relFromH) {
4680
+ case "page":
4681
+ case "leftMargin":
4682
+ ox = 0;
4683
+ break;
4684
+ case "rightMargin":
4685
+ ox = sec.pageWidthPx - sec.marginPx.right;
4686
+ break;
4687
+ case "column":
4688
+ ox = colX();
4689
+ break;
4690
+ default:
4691
+ ox = sec.marginPx.left;
4692
+ break;
4693
+ }
4694
+ let oy;
4695
+ switch (a.relFromV) {
4696
+ case "page":
4697
+ case "topMargin":
4698
+ oy = 0;
4699
+ break;
4700
+ case "bottomMargin":
4701
+ oy = sec.pageHeightPx - sec.marginPx.bottom;
4702
+ break;
4703
+ case "paragraph":
4704
+ case "line":
4705
+ oy = y;
4706
+ break;
4707
+ // current flow position
4708
+ default:
4709
+ oy = sec.marginPx.top;
4710
+ break;
4711
+ }
4712
+ const placedImage = { src: img.src, width: img.widthPx, height: img.heightPx, z: a.z ?? 0 };
4713
+ if (a.behind) placedImage.behind = true;
4714
+ else placedImage.front = true;
4715
+ page.blocks.push({
4716
+ blockId: img.id,
4717
+ x: ox + a.offsetXPx,
4718
+ y: oy + a.offsetYPx,
4719
+ firstLineIndex: 0,
4720
+ lines: [],
4721
+ image: placedImage
4722
+ });
4723
+ };
4613
4724
  const placeImage = (img) => {
4725
+ if (img.anchor) {
4726
+ placeAnchoredImage(img);
4727
+ return;
4728
+ }
4614
4729
  if (y + img.heightPx > bottomY() && colHasContent()) newPage();
4615
4730
  const floating = img.wrap === "square" && img.align !== "center";
4616
4731
  const slack = colWidth - img.widthPx;
@@ -4638,7 +4753,10 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4638
4753
  if (placed === null) {
4639
4754
  placed = { blockId: p.id, x: colX() + indentOf(p), y, firstLineIndex: lineIdx, lines: [] };
4640
4755
  const marker = lineIdx === 0 ? markers.get(p.id) : void 0;
4641
- if (marker) placed.marker = { text: marker.text, style: marker.style, x: placed.x - marker.hangingPx };
4756
+ if (marker) {
4757
+ const firstX = frags[0]?.frag.x ?? 0;
4758
+ placed.marker = { text: marker.text, style: marker.style, x: placed.x + firstX - marker.hangingPx };
4759
+ }
4642
4760
  page.blocks.push(placed);
4643
4761
  }
4644
4762
  const box = { y: y - placed.y, height, ascent, fragments: frags.map((rf) => rf.frag) };
@@ -4752,10 +4870,14 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4752
4870
  startSectionPage();
4753
4871
  }
4754
4872
  const m = measured[bi];
4755
- const atomicKind = (x) => x?.kind === "table" || x?.kind === "image";
4873
+ const atomicKind = (x) => x?.kind === "table" || x?.kind === "image" && x.block.anchor === void 0;
4756
4874
  const prevAtomic = atomicKind(measured[bi - 1]);
4757
4875
  const nextAtomic = atomicKind(measured[bi + 1]);
4758
4876
  if (m.kind === "image") {
4877
+ if (m.block.anchor) {
4878
+ placeImage(m.block);
4879
+ continue;
4880
+ }
4759
4881
  if (!prevAtomic) y += ATOMIC_GAP;
4760
4882
  placeImage(m.block);
4761
4883
  if (!nextAtomic && (m.block.wrap !== "square" || m.block.align === "center")) y += ATOMIC_GAP;
@@ -4860,6 +4982,23 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4860
4982
  }
4861
4983
  }
4862
4984
  }
4985
+ const reorderAnchoredLayers = (blocks) => {
4986
+ for (const b of blocks) {
4987
+ if (b.table) for (const row of b.table.rows) for (const cell of row.cells) cell.blocks = reorderAnchoredLayers(cell.blocks);
4988
+ }
4989
+ if (!blocks.some((b) => b.image?.behind || b.image?.front)) return blocks;
4990
+ const layer = (b) => b.image?.behind ? 0 : b.image?.front ? 2 : 1;
4991
+ return blocks.map((b, i) => ({ b, i })).sort((p, q) => {
4992
+ const dl = layer(p.b) - layer(q.b);
4993
+ if (dl !== 0) return dl;
4994
+ if (layer(p.b) !== 1) {
4995
+ const dz = (p.b.image.z ?? 0) - (q.b.image.z ?? 0);
4996
+ if (dz !== 0) return dz;
4997
+ }
4998
+ return p.i - q.i;
4999
+ }).map((x) => x.b);
5000
+ };
5001
+ for (const pg of pages) pg.blocks = reorderAnchoredLayers(pg.blocks);
4863
5002
  const pageNumbers = [];
4864
5003
  {
4865
5004
  let n = 0;
@@ -4872,6 +5011,35 @@ function layoutDocument(doc, getLines, getPrepared, rawBand) {
4872
5011
  pages[i].number = n;
4873
5012
  }
4874
5013
  }
5014
+ const fieldDefs = doc.fields;
5015
+ if (fieldDefs) {
5016
+ const isPageNumField = (fid) => {
5017
+ if (fid === void 0) return false;
5018
+ const def = fieldDefs[fid];
5019
+ const t = def && def.kind === "builtin" ? def.spec?.type : void 0;
5020
+ return t === "PAGE" || t === "NUMPAGES";
5021
+ };
5022
+ const resolveLineTokens = (line, pageNum) => {
5023
+ let dx = 0;
5024
+ for (const frag of line.fragments) {
5025
+ if (dx !== 0) frag.x += dx;
5026
+ if (!isPageNumField(frag.style.fieldId)) continue;
5027
+ const sub = substituteTokens(frag.text, pageNum, pages.length);
5028
+ if (sub === frag.text) continue;
5029
+ const modelLen = frag.endOffset - frag.startOffset;
5030
+ const oldWidth = frag.width;
5031
+ frag.text = sub;
5032
+ frag.width = measureTextWidth(sub, charStyleToFont(frag.style));
5033
+ frag.offsetMap = Array.from({ length: sub.length + 1 }, (_v, i) => i === sub.length ? modelLen : 0);
5034
+ dx += frag.width - oldWidth;
5035
+ }
5036
+ };
5037
+ const resolveBlockTokens = (b, pageNum) => {
5038
+ for (const line of b.lines) resolveLineTokens(line, pageNum);
5039
+ if (b.table) for (const row of b.table.rows) for (const cell of row.cells) for (const cb of cell.blocks) resolveBlockTokens(cb, pageNum);
5040
+ };
5041
+ for (const pg of pages) for (const b of pg.blocks) resolveBlockTokens(b, pageNumbers[pg.index]);
5042
+ }
4875
5043
  if (tocPlacements.size > 0) {
4876
5044
  const firstPageOf = /* @__PURE__ */ new Map();
4877
5045
  const mapPage = (blocks, num) => {
@@ -5062,6 +5230,7 @@ function measureTable(t, contentWidth, getLines, listCtx) {
5062
5230
  return { kind: "para", block: b, lines };
5063
5231
  }
5064
5232
  if (b.kind === "image") {
5233
+ if (b.anchor) return { kind: "image", block: b, width: b.widthPx, height: b.heightPx };
5065
5234
  const scale = Math.min(1, innerWidth / Math.max(1, b.widthPx));
5066
5235
  const w = b.widthPx * scale;
5067
5236
  const ih = b.heightPx * scale;
@@ -5132,6 +5301,26 @@ function placeTable(t, rows, colWidths, x, y, width, firstRowIndex, listCtx) {
5132
5301
  blocks.push(placedPara);
5133
5302
  py += totalLinesHeight(it.lines) + it.block.style.spaceAfterPx;
5134
5303
  } else if (it.kind === "image") {
5304
+ const anchor = it.block.anchor;
5305
+ if (anchor) {
5306
+ const placedImage = {
5307
+ src: it.block.src,
5308
+ width: it.block.widthPx,
5309
+ height: it.block.heightPx,
5310
+ z: anchor.z ?? 0
5311
+ };
5312
+ if (anchor.behind) placedImage.behind = true;
5313
+ else placedImage.front = true;
5314
+ blocks.push({
5315
+ blockId: it.block.id,
5316
+ x: cx + mgn.left + anchor.offsetXPx,
5317
+ y: ry + mgn.top + anchor.offsetYPx,
5318
+ firstLineIndex: 0,
5319
+ lines: [],
5320
+ image: placedImage
5321
+ });
5322
+ continue;
5323
+ }
5135
5324
  const innerH = cellHeight - mgn.top - mgn.bottom;
5136
5325
  if (mc.items.length === 1 && innerH > it.height + 8) {
5137
5326
  const scale = Math.max(innerWidth / it.block.widthPx, innerH / it.block.heightPx);
@@ -5200,4 +5389,4 @@ export {
5200
5389
  effectiveSection,
5201
5390
  resolveSections
5202
5391
  };
5203
- //# sourceMappingURL=chunk-IJLL6IFJ.js.map
5392
+ //# sourceMappingURL=chunk-T3253N22.js.map