@superdoc-dev/cli 0.17.0-next.15 → 0.17.0-next.17

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 (2) hide show
  1. package/dist/index.js +1427 -412
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -68327,7 +68327,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
68327
68327
  emptyOptions2 = {};
68328
68328
  });
68329
68329
 
68330
- // ../../packages/superdoc/dist/chunks/SuperConverter-BTGVElJO.es.js
68330
+ // ../../packages/superdoc/dist/chunks/SuperConverter-CUxtXQFf.es.js
68331
68331
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
68332
68332
  const fieldValue = extension$1.config[field];
68333
68333
  if (typeof fieldValue === "function")
@@ -84415,6 +84415,61 @@ function parseStyleId(chartSpace) {
84415
84415
  const val = getAttr(findChild$1(chartSpace, "c:style"), "val");
84416
84416
  return val != null ? Number(val) : undefined;
84417
84417
  }
84418
+ function stripRunNodeMarks(nodes) {
84419
+ if (!Array.isArray(nodes))
84420
+ return nodes;
84421
+ return nodes.map((node3) => {
84422
+ if (!node3 || typeof node3 !== "object")
84423
+ return node3;
84424
+ const stripped = node3.type === "run" && Array.isArray(node3.marks) && node3.marks.length > 0 ? {
84425
+ ...node3,
84426
+ marks: []
84427
+ } : node3;
84428
+ if (Array.isArray(stripped.content))
84429
+ return {
84430
+ ...stripped,
84431
+ content: stripRunNodeMarks(stripped.content)
84432
+ };
84433
+ return stripped;
84434
+ });
84435
+ }
84436
+ function importDrawingMLTextbox({ params: params3, drawingNode, textBoxContent, bodyPr, baseAttrs = {}, paragraphImporter }) {
84437
+ if (!textBoxContent)
84438
+ return null;
84439
+ const textboxParagraphs = collectTextBoxParagraphs(preProcessTextBoxContent(textBoxContent, params3)?.elements || []);
84440
+ const importParagraph = typeof paragraphImporter === "function" ? paragraphImporter : (paragraph2) => {
84441
+ return handleParagraphNode$1({
84442
+ ...params3,
84443
+ nodes: [paragraph2]
84444
+ })?.nodes || [];
84445
+ };
84446
+ const contentNodes = stripRunNodeMarks(textboxParagraphs.flatMap((paragraph2) => {
84447
+ const imported = importParagraph(paragraph2);
84448
+ return Array.isArray(imported) ? imported : imported ? [imported] : [];
84449
+ }));
84450
+ const { verticalAlign, insets } = extractBodyPrProperties(bodyPr);
84451
+ return {
84452
+ type: "shapeContainer",
84453
+ attrs: {
84454
+ ...baseAttrs,
84455
+ drawingContent: drawingNode
84456
+ },
84457
+ content: [{
84458
+ type: "shapeTextbox",
84459
+ attrs: {
84460
+ textInsets: {
84461
+ top: insets.top,
84462
+ right: insets.right,
84463
+ bottom: insets.bottom,
84464
+ left: insets.left
84465
+ },
84466
+ textVerticalAlign: verticalAlign,
84467
+ attributes: {}
84468
+ },
84469
+ content: contentNodes
84470
+ }]
84471
+ };
84472
+ }
84418
84473
  function handleImageNode$1(node3, params3, isAnchor) {
84419
84474
  if (!node3)
84420
84475
  return null;
@@ -84886,6 +84941,122 @@ function extractTextFromTextBox(textBoxContent, bodyPr, params3 = {}) {
84886
84941
  wrap: wrap$1
84887
84942
  };
84888
84943
  }
84944
+ function extractFieldInlineNodes(node3) {
84945
+ if (node3?.name === "sd:autoPageNumber")
84946
+ return [{
84947
+ type: "page-number",
84948
+ attrs: {
84949
+ marksAsAttrs: [],
84950
+ instruction: "PAGE"
84951
+ }
84952
+ }];
84953
+ if (node3?.name === "sd:totalPageNumber")
84954
+ return [{
84955
+ type: "total-page-number",
84956
+ attrs: {
84957
+ marksAsAttrs: [],
84958
+ instruction: "NUMPAGES"
84959
+ }
84960
+ }];
84961
+ if (node3?.name === "sd:sectionPageCount") {
84962
+ const cachedText = node3?.attributes?.resolvedText ?? node3?.attributes?.importedCachedText ?? "";
84963
+ if (!cachedText)
84964
+ return [];
84965
+ return [{
84966
+ type: "text",
84967
+ text: cachedText
84968
+ }];
84969
+ }
84970
+ return [];
84971
+ }
84972
+ function extractInlineNodesFromRun(run$1, params3) {
84973
+ if (!run$1?.elements)
84974
+ return [];
84975
+ const nodes = [];
84976
+ run$1.elements.forEach((el) => {
84977
+ if (el.name === "w:t" || el.name === "w:delText") {
84978
+ const textNode = el.elements?.find((n) => n.type === "text");
84979
+ if (!textNode || typeof textNode.text !== "string")
84980
+ return;
84981
+ const cleanedText = textNode.text.replace(/\[\[sdspace\]\]/g, " ");
84982
+ if (cleanedText.length > 0)
84983
+ nodes.push({
84984
+ type: "text",
84985
+ text: cleanedText
84986
+ });
84987
+ } else if (el.name === "w:tab")
84988
+ nodes.push({
84989
+ type: "text",
84990
+ text: "\t"
84991
+ });
84992
+ else if (el.name === "w:br")
84993
+ nodes.push({
84994
+ type: "lineBreak",
84995
+ attrs: {}
84996
+ });
84997
+ else if (el.name === "sd:autoPageNumber" || el.name === "sd:totalPageNumber" || el.name === "sd:sectionPageCount")
84998
+ nodes.push(...extractFieldInlineNodes(el));
84999
+ else if (el.name === "w:drawing") {
85000
+ const inline = el.elements?.find((child) => child?.name === "wp:inline");
85001
+ if (!inline)
85002
+ return;
85003
+ const imagePm = handleImageNode$1(inline, {
85004
+ ...params3,
85005
+ nodes: [el]
85006
+ }, false);
85007
+ if (imagePm?.type === "image" && imagePm.attrs?.hidden !== true)
85008
+ nodes.push(imagePm);
85009
+ }
85010
+ });
85011
+ return nodes;
85012
+ }
85013
+ function paragraphToPmParagraph(paragraph2, params3) {
85014
+ const paragraphNode = collectTextBoxParagraphs([paragraph2])[0];
85015
+ if (!paragraphNode)
85016
+ return null;
85017
+ const paragraphProperties = resolveParagraphPropertiesForTextBox(paragraphNode, params3);
85018
+ const alignment = extractParagraphAlignment(paragraphNode) || "left";
85019
+ const content$2 = [];
85020
+ let pendingRunContent = [];
85021
+ const flushPendingRun = () => {
85022
+ if (pendingRunContent.length === 0)
85023
+ return;
85024
+ content$2.push({
85025
+ type: "run",
85026
+ attrs: {},
85027
+ content: pendingRunContent
85028
+ });
85029
+ pendingRunContent = [];
85030
+ };
85031
+ (paragraphNode.elements || []).forEach((element) => {
85032
+ if (element?.name === "w:r") {
85033
+ extractInlineNodesFromRun(element, params3).forEach((part) => {
85034
+ if (part?.type === "image") {
85035
+ flushPendingRun();
85036
+ content$2.push(part);
85037
+ return;
85038
+ }
85039
+ pendingRunContent.push(part);
85040
+ });
85041
+ return;
85042
+ }
85043
+ if (element?.name?.startsWith("sd:")) {
85044
+ const runContent = extractFieldInlineNodes(element);
85045
+ if (runContent.length > 0)
85046
+ pendingRunContent.push(...runContent);
85047
+ }
85048
+ });
85049
+ flushPendingRun();
85050
+ return {
85051
+ type: "paragraph",
85052
+ attrs: {
85053
+ paragraphProperties,
85054
+ textAlign: alignment
85055
+ },
85056
+ content: content$2,
85057
+ marks: []
85058
+ };
85059
+ }
84889
85060
  function getVectorShape({ params: params3, node: node3, graphicData, size: size2, marginOffset, anchorData, wrap: wrap$1, isAnchor, customGeometry }) {
84890
85061
  const schemaAttrs = {};
84891
85062
  const drawingNode = params3.nodes?.[0];
@@ -84921,14 +85092,45 @@ function getVectorShape({ params: params3, node: node3, graphicData, size: size2
84921
85092
  const textBoxContent = wsp.elements?.find((el) => el.name === "wps:txbx")?.elements?.find((el) => el.name === "w:txbxContent");
84922
85093
  const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
84923
85094
  const nonVisualShapeProps = wsp.elements?.find((el) => el.name === "wps:cNvSpPr");
85095
+ const isWordArt = bodyPr?.attributes?.["fromWordArt"] === "1";
85096
+ const isTextBox = nonVisualShapeProps?.attributes?.["txBox"] === "1";
85097
+ if (isTextBox && textBoxContent)
85098
+ return importDrawingMLTextbox({
85099
+ params: params3,
85100
+ drawingNode: drawingNode?.name === "w:drawing" ? drawingNode : null,
85101
+ textBoxContent,
85102
+ bodyPr,
85103
+ baseAttrs: {
85104
+ ...schemaAttrs,
85105
+ width,
85106
+ height,
85107
+ rotation,
85108
+ flipH,
85109
+ flipV,
85110
+ fillColor,
85111
+ strokeColor,
85112
+ strokeWidth,
85113
+ lineEnds,
85114
+ effectExtent,
85115
+ marginOffset,
85116
+ anchorData,
85117
+ wrap: wrap$1,
85118
+ isAnchor,
85119
+ isWordArt,
85120
+ isTextBox,
85121
+ originalAttributes: node3?.attributes
85122
+ },
85123
+ paragraphImporter: params3?.nodeListHandler != null ? undefined : (paragraph2) => {
85124
+ const imported = paragraphToPmParagraph(paragraph2, params3);
85125
+ return Array.isArray(imported) ? imported : imported ? [imported] : [];
85126
+ }
85127
+ });
84924
85128
  let textContent = null;
84925
85129
  let textAlign = "left";
84926
85130
  if (textBoxContent) {
84927
85131
  textContent = extractTextFromTextBox(textBoxContent, bodyPr, params3);
84928
85132
  textAlign = textContent?.horizontalAlign || "left";
84929
85133
  }
84930
- const isWordArt = bodyPr?.attributes?.["fromWordArt"] === "1";
84931
- const isTextBox = nonVisualShapeProps?.attributes?.["txBox"] === "1";
84932
85134
  return {
84933
85135
  type: "vectorShape",
84934
85136
  attrs: {
@@ -101152,9 +101354,15 @@ function handleShapeTextboxImport({ params: params3, pict }) {
101152
101354
  schemaAttrs.attributes = shapeAttrs;
101153
101355
  if (shapeAttrs.fillcolor)
101154
101356
  schemaAttrs.fillcolor = shapeAttrs.fillcolor;
101155
- const shapeStyle = buildStyles(parseInlineStyles(shapeAttrs.style));
101357
+ const parsedStyle = parseInlineStyles(shapeAttrs.style);
101358
+ const shapeStyle = buildStyles(parsedStyle);
101359
+ const positionData = extractPositionData(parsedStyle);
101156
101360
  if (shapeStyle)
101157
101361
  schemaAttrs.style = shapeStyle;
101362
+ if (positionData.anchorData)
101363
+ schemaAttrs.anchorData = positionData.anchorData;
101364
+ if (positionData.marginOffset)
101365
+ schemaAttrs.marginOffset = positionData.marginOffset;
101158
101366
  const textbox = shape.elements?.find((el) => el.name === "v:textbox");
101159
101367
  const wrap$1 = shape.elements?.find((el) => el.name === "w10:wrap");
101160
101368
  if (wrap$1?.attributes)
@@ -101184,6 +101392,38 @@ function buildStyles(styleObject) {
101184
101392
  style += `${prop}: ${value};`;
101185
101393
  return style;
101186
101394
  }
101395
+ function extractPositionData(styleObject) {
101396
+ const anchorData = {};
101397
+ const marginOffset = {};
101398
+ if (styleObject["mso-position-horizontal"])
101399
+ anchorData.alignH = styleObject["mso-position-horizontal"];
101400
+ if (styleObject["mso-position-horizontal-relative"])
101401
+ anchorData.hRelativeFrom = styleObject["mso-position-horizontal-relative"];
101402
+ if (styleObject["mso-position-vertical"])
101403
+ anchorData.alignV = styleObject["mso-position-vertical"];
101404
+ if (styleObject["mso-position-vertical-relative"])
101405
+ anchorData.vRelativeFrom = styleObject["mso-position-vertical-relative"];
101406
+ if (styleObject["margin-left"] != null)
101407
+ marginOffset.horizontal = convertToPixels$2(styleObject["margin-left"]);
101408
+ if (styleObject["margin-top"] != null)
101409
+ marginOffset.top = convertToPixels$2(styleObject["margin-top"]);
101410
+ return {
101411
+ ...Object.keys(anchorData).length > 0 ? { anchorData } : {},
101412
+ ...Object.keys(marginOffset).length > 0 ? { marginOffset } : {}
101413
+ };
101414
+ }
101415
+ function convertToPixels$2(value) {
101416
+ const num = parseFloat(value);
101417
+ if (Number.isNaN(num))
101418
+ return 0;
101419
+ if (value.endsWith("pt"))
101420
+ return num * 96 / 72;
101421
+ if (value.endsWith("in"))
101422
+ return num * 96;
101423
+ if (value.endsWith("px"))
101424
+ return num;
101425
+ return num;
101426
+ }
101187
101427
  function handleShapeImageWatermarkImport({ params: params3, pict }) {
101188
101428
  const shape = pict.elements?.find((el) => el.name === "v:shape");
101189
101429
  if (!shape)
@@ -101704,15 +101944,69 @@ function pictNodeTypeStrategy(node3) {
101704
101944
  handler: null
101705
101945
  };
101706
101946
  }
101947
+ function translateDrawingMLTextbox(params3) {
101948
+ const { node: node3 } = params3;
101949
+ const drawingContent = node3?.attrs?.drawingContent;
101950
+ const shapeTextbox = node3?.content?.find((child) => child?.type === "shapeTextbox");
101951
+ if (!drawingContent || !shapeTextbox)
101952
+ return null;
101953
+ const drawing = carbonCopy(drawingContent);
101954
+ const liveParagraphs = translateChildNodes({
101955
+ ...params3,
101956
+ node: shapeTextbox
101957
+ });
101958
+ const txbxContent = findTextboxContentNode(drawing);
101959
+ if (!txbxContent)
101960
+ return null;
101961
+ txbxContent.elements = liveParagraphs;
101962
+ return wrapTextInRun({
101963
+ name: "mc:AlternateContent",
101964
+ elements: [{
101965
+ name: "mc:Choice",
101966
+ attributes: { Requires: "wps" },
101967
+ elements: [drawing]
101968
+ }]
101969
+ });
101970
+ }
101971
+ function findTextboxContentNode(node3) {
101972
+ if (!node3 || typeof node3 !== "object")
101973
+ return null;
101974
+ if (node3.name === "w:txbxContent")
101975
+ return node3;
101976
+ if (!Array.isArray(node3.elements))
101977
+ return null;
101978
+ for (const child of node3.elements) {
101979
+ const found$1 = findTextboxContentNode(child);
101980
+ if (found$1)
101981
+ return found$1;
101982
+ }
101983
+ return null;
101984
+ }
101707
101985
  function translateShapeContainer(params3) {
101708
101986
  const { node: node3 } = params3;
101987
+ if (node3?.attrs?.drawingContent) {
101988
+ const run$1 = translateDrawingMLTextbox(params3);
101989
+ if (run$1)
101990
+ return {
101991
+ name: "w:p",
101992
+ elements: [run$1]
101993
+ };
101994
+ return {
101995
+ name: "w:p",
101996
+ elements: [wrapTextInRun(node3.attrs.drawingContent)]
101997
+ };
101998
+ }
101709
101999
  const elements = translateChildNodes(params3);
102000
+ const shapeAttributes = {
102001
+ ...node3.attrs.attributes,
102002
+ fillcolor: node3.attrs.fillcolor
102003
+ };
102004
+ const style = buildShapeStyle(node3.attrs);
102005
+ if (style)
102006
+ shapeAttributes.style = style;
101710
102007
  const shape = {
101711
102008
  name: "v:shape",
101712
- attributes: {
101713
- ...node3.attrs.attributes,
101714
- fillcolor: node3.attrs.fillcolor
101715
- },
102009
+ attributes: shapeAttributes,
101716
102010
  elements: [...elements, ...node3.attrs.wrapAttributes ? [{
101717
102011
  name: "w10:wrap",
101718
102012
  attributes: { ...node3.attrs.wrapAttributes }
@@ -101727,6 +102021,33 @@ function translateShapeContainer(params3) {
101727
102021
  })]
101728
102022
  };
101729
102023
  }
102024
+ function buildShapeStyle(attrs) {
102025
+ const originalStyle = parseInlineStyles(attrs.attributes?.style);
102026
+ const managedStyle = parseInlineStyles(attrs.style);
102027
+ const style = {
102028
+ ...originalStyle,
102029
+ ...managedStyle
102030
+ };
102031
+ if (attrs.marginOffset?.horizontal !== undefined)
102032
+ style["margin-left"] = `${convertToPt$2(attrs.marginOffset.horizontal)}pt`;
102033
+ if (attrs.marginOffset?.top !== undefined)
102034
+ style["margin-top"] = `${convertToPt$2(attrs.marginOffset.top)}pt`;
102035
+ if (attrs.anchorData?.alignH)
102036
+ style["mso-position-horizontal"] = attrs.anchorData.alignH;
102037
+ if (attrs.anchorData?.hRelativeFrom)
102038
+ style["mso-position-horizontal-relative"] = attrs.anchorData.hRelativeFrom;
102039
+ if (attrs.anchorData?.alignV)
102040
+ style["mso-position-vertical"] = attrs.anchorData.alignV;
102041
+ if (attrs.anchorData?.vRelativeFrom)
102042
+ style["mso-position-vertical-relative"] = attrs.anchorData.vRelativeFrom;
102043
+ const entries2 = Object.entries(style);
102044
+ if (entries2.length === 0)
102045
+ return;
102046
+ return entries2.map(([prop, value]) => `${prop}:${value}`).join(";");
102047
+ }
102048
+ function convertToPt$2(pixels) {
102049
+ return pixels * 72 / 96;
102050
+ }
101730
102051
  function translateShapeTextbox(params3) {
101731
102052
  const { node: node3 } = params3;
101732
102053
  const textboxContent = {
@@ -104103,7 +104424,7 @@ function hydrateImageBlocks(blocks, mediaFiles) {
104103
104424
  }
104104
104425
  if (blk.kind === "drawing") {
104105
104426
  const drawingBlock = blk;
104106
- if (drawingBlock.drawingKind === "vectorShape") {
104427
+ if (drawingBlock.drawingKind === "vectorShape" || drawingBlock.drawingKind === "textboxShape") {
104107
104428
  const parts = drawingBlock.textContent?.parts;
104108
104429
  if (!parts || parts.length === 0)
104109
104430
  return blk;
@@ -106158,6 +106479,14 @@ function lineBreakNodeToRun({ node: node3, positions, sdtMetadata }) {
106158
106479
  lineBreakRun.sdt = sdtMetadata;
106159
106480
  return lineBreakRun;
106160
106481
  }
106482
+ function hydrateTextboxDrawingContent(node3, drawingBlock, context) {
106483
+ if (drawingBlock.drawingKind !== "textboxShape")
106484
+ return drawingBlock;
106485
+ return {
106486
+ ...drawingBlock,
106487
+ contentBlocks: toTextboxParagraphBlocks(node3, context)
106488
+ };
106489
+ }
106161
106490
  function vectorShapeNodeToDrawingBlock(node3, nextBlockId, positions) {
106162
106491
  const rawAttrs = getAttrs$2(node3);
106163
106492
  if (isHiddenDrawing$1(rawAttrs))
@@ -106202,25 +106531,43 @@ function shapeContainerNodeToDrawingBlock(node3, nextBlockId, positions) {
106202
106531
  const rawAttrs = getAttrs$2(node3);
106203
106532
  if (isHiddenDrawing$1(rawAttrs))
106204
106533
  return null;
106205
- return buildDrawingBlock(rawAttrs, nextBlockId, positions, node3, {
106534
+ const geometry = {
106206
106535
  width: coercePositiveNumber(rawAttrs.width, 1),
106207
106536
  height: coercePositiveNumber(rawAttrs.height, 1),
106208
106537
  rotation: coerceNumber(rawAttrs.rotation) ?? 0,
106209
106538
  flipH: coerceBoolean(rawAttrs.flipH) ?? false,
106210
106539
  flipV: coerceBoolean(rawAttrs.flipV) ?? false
106211
- }, "vectorShape");
106540
+ };
106541
+ const shapeTextboxNode = resolveNestedShapeTextboxNode(node3);
106542
+ const textboxAttrs = shapeTextboxNode ? getAttrs$2(shapeTextboxNode) : {};
106543
+ const textContent = shapeTextboxNode ? extractTextboxTextContent(shapeTextboxNode) : undefined;
106544
+ return buildDrawingBlock({
106545
+ ...rawAttrs,
106546
+ ...textContent ? { textContent } : {},
106547
+ ...rawAttrs.textAlign == null && textContent?.horizontalAlign ? { textAlign: textContent.horizontalAlign } : {},
106548
+ ...rawAttrs.textInsets == null ? { textInsets: resolveTextboxInsetsFromAttrs(textboxAttrs) } : {},
106549
+ ...rawAttrs.textVerticalAlign == null ? { textVerticalAlign: resolveTextboxVerticalAlignFromAttrs(textboxAttrs) } : {}
106550
+ }, nextBlockId, positions, node3, geometry, "textboxShape", { contentBlocks: [] });
106212
106551
  }
106213
106552
  function shapeTextboxNodeToDrawingBlock(node3, nextBlockId, positions) {
106214
106553
  const rawAttrs = getAttrs$2(node3);
106215
106554
  if (isHiddenDrawing$1(rawAttrs))
106216
106555
  return null;
106217
- return buildDrawingBlock(rawAttrs, nextBlockId, positions, node3, {
106556
+ const geometry = {
106218
106557
  width: coercePositiveNumber(rawAttrs.width, 1),
106219
106558
  height: coercePositiveNumber(rawAttrs.height, 1),
106220
106559
  rotation: coerceNumber(rawAttrs.rotation) ?? 0,
106221
106560
  flipH: coerceBoolean(rawAttrs.flipH) ?? false,
106222
106561
  flipV: coerceBoolean(rawAttrs.flipV) ?? false
106223
- }, "vectorShape");
106562
+ };
106563
+ const textContent = extractTextboxTextContent(node3);
106564
+ return buildDrawingBlock({
106565
+ ...rawAttrs,
106566
+ ...textContent ? { textContent } : {},
106567
+ ...rawAttrs.textAlign == null && textContent?.horizontalAlign ? { textAlign: textContent.horizontalAlign } : {},
106568
+ ...rawAttrs.textInsets == null ? { textInsets: resolveTextboxInsetsFromAttrs(rawAttrs) } : {},
106569
+ ...rawAttrs.textVerticalAlign == null ? { textVerticalAlign: resolveTextboxVerticalAlignFromAttrs(rawAttrs) } : {}
106570
+ }, nextBlockId, positions, node3, geometry, "textboxShape", { contentBlocks: [] });
106224
106571
  }
106225
106572
  function handleVectorShapeNode(node3, context) {
106226
106573
  const { blocks, recordBlockKind, nextBlockId, positions } = context;
@@ -106242,7 +106589,7 @@ function handleShapeContainerNode(node3, context) {
106242
106589
  const { blocks, recordBlockKind, nextBlockId, positions } = context;
106243
106590
  const drawingBlock = shapeContainerNodeToDrawingBlock(node3, nextBlockId, positions);
106244
106591
  if (drawingBlock) {
106245
- blocks.push(drawingBlock);
106592
+ blocks.push(hydrateTextboxDrawingContent(node3, drawingBlock, context));
106246
106593
  recordBlockKind?.(drawingBlock.kind);
106247
106594
  }
106248
106595
  }
@@ -106250,7 +106597,7 @@ function handleShapeTextboxNode(node3, context) {
106250
106597
  const { blocks, recordBlockKind, nextBlockId, positions } = context;
106251
106598
  const drawingBlock = shapeTextboxNodeToDrawingBlock(node3, nextBlockId, positions);
106252
106599
  if (drawingBlock) {
106253
- blocks.push(drawingBlock);
106600
+ blocks.push(hydrateTextboxDrawingContent(node3, drawingBlock, context));
106254
106601
  recordBlockKind?.(drawingBlock.kind);
106255
106602
  }
106256
106603
  }
@@ -107007,8 +107354,14 @@ function paragraphToFlowBlocks({ para, nextBlockId, positions, storyKey, tracked
107007
107354
  const converter = SHAPE_CONVERTERS_REGISTRY[node3.type];
107008
107355
  const drawingBlock = converter(node3, stableNextBlockId, positions);
107009
107356
  if (drawingBlock) {
107010
- attachInlineShapeGroupAlignment(drawingBlock);
107011
- blocks.push(attachAnchorParagraphId(drawingBlock, anchorParagraphId));
107357
+ const hydratedBlock = hydrateTextboxDrawingContent(node3, drawingBlock, {
107358
+ converterContext,
107359
+ converters: converters$1,
107360
+ nextBlockId: stableNextBlockId,
107361
+ positions
107362
+ });
107363
+ attachInlineShapeGroupAlignment(hydratedBlock);
107364
+ blocks.push(attachAnchorParagraphId(hydratedBlock, anchorParagraphId));
107012
107365
  }
107013
107366
  return;
107014
107367
  }
@@ -116166,7 +116519,7 @@ var isRegExp = (value) => {
116166
116519
  return attributes["w:rsidDel"];
116167
116520
  }, decode$52 = (attrs) => {
116168
116521
  return attrs.rsidDel;
116169
- }, attributes_default$4, STYLES_KEY = "word/styles.xml", XML_NODE_NAME$32 = "w:r", SD_KEY_NAME = "run", REFERENCE_RUN_STYLE_BY_XML_NAME, hasXmlNodeNamed = (node3, targetName) => {
116522
+ }, attributes_default$4, STYLES_KEY = "word/styles.xml", XML_NODE_NAME$32 = "w:r", SD_KEY_NAME = "run", REFERENCE_RUN_STYLE_BY_XML_NAME, BLOCK_HOIST_TYPES, hasXmlNodeNamed = (node3, targetName) => {
116170
116523
  if (!node3 || typeof node3 !== "object")
116171
116524
  return false;
116172
116525
  if (node3.name === targetName)
@@ -116299,6 +116652,11 @@ var isRegExp = (value) => {
116299
116652
  nodes: contentElements
116300
116653
  };
116301
116654
  const content$2 = nodeListHandler?.handler(childParams) || [];
116655
+ if (Array.isArray(content$2) && content$2.length > 0 && content$2.every((child) => BLOCK_HOIST_TYPES.has(child?.type)))
116656
+ return content$2.filter(Boolean).map((child) => ({
116657
+ ...child,
116658
+ marks: Array.isArray(child?.marks) ? child.marks : []
116659
+ }));
116302
116660
  const filtered = (Array.isArray(content$2) ? content$2 : []).map((child) => {
116303
116661
  if (!child || typeof child !== "object")
116304
116662
  return child;
@@ -122001,7 +122359,86 @@ var isRegExp = (value) => {
122001
122359
  i$1++;
122002
122360
  }
122003
122361
  return { processedNodes };
122004
- }, HEADER_FOOTER_FILENAME_PATTERN, CHART_TYPE_MAP, CHART_TYPE_NAMES, findChild$1 = (node3, name) => node3?.elements?.find((el) => el.name === name), findChildren$2 = (node3, name) => node3?.elements?.filter((el) => el.name === name) ?? [], getAttr = (node3, attr) => node3?.attributes?.[attr], DRAWING_XML_TAG = "w:drawing", SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup", SD_IMAGE_ID_NAMESPACE = "7c9e6679-7425-40de-944b-e07fc1f90ae7", normalizeTargetPath$1 = (targetPath = "") => {
122362
+ }, HEADER_FOOTER_FILENAME_PATTERN, CHART_TYPE_MAP, CHART_TYPE_NAMES, findChild$1 = (node3, name) => node3?.elements?.find((el) => el.name === name), findChildren$2 = (node3, name) => node3?.elements?.filter((el) => el.name === name) ?? [], getAttr = (node3, attr) => node3?.attributes?.[attr], PARAGRAPH_PROPERTIES_XML_NAME = "w:pPr", hasMeaningfulParagraphContent = (elements = []) => elements.some((element) => element?.name && element.name !== PARAGRAPH_PROPERTIES_XML_NAME), findParagraphProperties = (elements = []) => elements.find((element) => element?.name === PARAGRAPH_PROPERTIES_XML_NAME) ?? null, hasParagraphProperties = (elements = []) => elements.some((element) => element?.name === PARAGRAPH_PROPERTIES_XML_NAME), cloneParagraphPropertiesForRenderedResult = (paragraphProperties) => {
122363
+ const elements = (paragraphProperties.elements || []).filter((element) => element?.name !== "w:sectPr").map((element) => carbonCopy(element));
122364
+ if (elements.length === 0)
122365
+ return null;
122366
+ return {
122367
+ ...carbonCopy(paragraphProperties),
122368
+ elements
122369
+ };
122370
+ }, inheritWrapperParagraphProperties = (blockFieldElement, paragraphProperties) => {
122371
+ if (!paragraphProperties)
122372
+ return blockFieldElement;
122373
+ const fieldElements = Array.isArray(blockFieldElement?.elements) ? blockFieldElement.elements : [];
122374
+ const firstParagraphIndex = fieldElements.findIndex((element) => element?.name === "w:p");
122375
+ if (firstParagraphIndex < 0)
122376
+ return blockFieldElement;
122377
+ const firstParagraph = fieldElements[firstParagraphIndex];
122378
+ const firstParagraphElements = Array.isArray(firstParagraph.elements) ? firstParagraph.elements : [];
122379
+ if (hasParagraphProperties(firstParagraphElements))
122380
+ return blockFieldElement;
122381
+ const renderedParagraphProperties = cloneParagraphPropertiesForRenderedResult(paragraphProperties);
122382
+ const inheritedFirstParagraph = {
122383
+ ...firstParagraph,
122384
+ elements: renderedParagraphProperties ? [renderedParagraphProperties, ...firstParagraphElements] : firstParagraphElements
122385
+ };
122386
+ return {
122387
+ ...blockFieldElement,
122388
+ attributes: {
122389
+ ...blockFieldElement.attributes || {},
122390
+ wrapperParagraphProperties: carbonCopy(paragraphProperties)
122391
+ },
122392
+ elements: fieldElements.map((element, index2) => index2 === firstParagraphIndex ? inheritedFirstParagraph : element)
122393
+ };
122394
+ }, hoistBlockFieldNodes = (params3, paragraphNode) => {
122395
+ const paragraphElements = Array.isArray(paragraphNode?.elements) ? paragraphNode.elements : [];
122396
+ const blockFieldElements = paragraphElements.filter((element) => BLOCK_FIELD_XML_NAMES.has(element?.name));
122397
+ if (blockFieldElements.length === 0)
122398
+ return null;
122399
+ const nodes = [];
122400
+ const remainingElements = paragraphElements.filter((element) => !BLOCK_FIELD_XML_NAMES.has(element?.name));
122401
+ const wrapperParagraphProperties = findParagraphProperties(remainingElements);
122402
+ const shouldTransferWrapperProperties = !hasMeaningfulParagraphContent(remainingElements);
122403
+ if (hasMeaningfulParagraphContent(remainingElements)) {
122404
+ const paragraph2 = translator.encode({
122405
+ ...params3,
122406
+ nodes: [{
122407
+ ...paragraphNode,
122408
+ elements: remainingElements
122409
+ }]
122410
+ });
122411
+ if (paragraph2)
122412
+ nodes.push(paragraph2);
122413
+ }
122414
+ blockFieldElements.forEach((blockFieldElement) => {
122415
+ const fieldElement = shouldTransferWrapperProperties ? inheritWrapperParagraphProperties(blockFieldElement, wrapperParagraphProperties) : blockFieldElement;
122416
+ nodes.push(...params3.nodeListHandler.handler({
122417
+ ...params3,
122418
+ nodes: [fieldElement],
122419
+ path: [...params3.path || [], paragraphNode]
122420
+ }));
122421
+ });
122422
+ return nodes;
122423
+ }, handleParagraphNode$1 = (params3) => {
122424
+ const { nodes } = params3;
122425
+ if (nodes.length === 0 || nodes[0].name !== "w:p")
122426
+ return {
122427
+ nodes: [],
122428
+ consumed: 0
122429
+ };
122430
+ const hoistedNodes = hoistBlockFieldNodes(params3, nodes[0]);
122431
+ if (hoistedNodes)
122432
+ return {
122433
+ nodes: hoistedNodes,
122434
+ consumed: 1
122435
+ };
122436
+ const schemaNode = translator.encode(params3);
122437
+ return {
122438
+ nodes: Array.isArray(schemaNode) ? schemaNode : schemaNode ? [schemaNode] : [],
122439
+ consumed: 1
122440
+ };
122441
+ }, paragraphNodeHandlerEntity, DRAWING_XML_TAG = "w:drawing", SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup", SD_IMAGE_ID_NAMESPACE = "7c9e6679-7425-40de-944b-e07fc1f90ae7", normalizeTargetPath$1 = (targetPath = "") => {
122005
122442
  if (!targetPath)
122006
122443
  return targetPath;
122007
122444
  const trimmed = targetPath.replace(/^\/+/, "");
@@ -122104,6 +122541,35 @@ var isRegExp = (value) => {
122104
122541
  if (result)
122105
122542
  return result;
122106
122543
  }
122544
+ if (wsp.elements?.find((el) => el.name === "wps:cNvSpPr")?.attributes?.["txBox"] === "1" && textBoxContent) {
122545
+ const bodyPr = wsp.elements?.find((el) => el.name === "wps:bodyPr");
122546
+ const drawingNode = params3.nodes?.[0];
122547
+ const result = importDrawingMLTextbox({
122548
+ params: params3,
122549
+ drawingNode: drawingNode?.name === "w:drawing" ? drawingNode : null,
122550
+ textBoxContent,
122551
+ bodyPr,
122552
+ baseAttrs: {
122553
+ width: size2?.width,
122554
+ height: size2?.height,
122555
+ marginOffset,
122556
+ anchorData,
122557
+ wrap: wrap$1,
122558
+ isAnchor,
122559
+ isTextBox: true,
122560
+ originalAttributes: node3?.attributes,
122561
+ ...params3.nodes?.[0]?.name === "w:drawing" ? { drawingContent: params3.nodes[0] } : {}
122562
+ },
122563
+ paragraphImporter: params3?.nodeListHandler != null ? undefined : (paragraph2) => {
122564
+ const imported = paragraphToPmParagraph(paragraph2, params3);
122565
+ return Array.isArray(imported) ? imported : imported ? [imported] : [];
122566
+ }
122567
+ });
122568
+ if (result?.attrs && isHidden)
122569
+ result.attrs.hidden = true;
122570
+ if (result)
122571
+ return result;
122572
+ }
122107
122573
  const placeholder = buildShapePlaceholder(node3, size2, padding, marginOffset, textBoxContent ? "textbox" : "drawing");
122108
122574
  if (placeholder?.attrs && isHidden)
122109
122575
  placeholder.attrs.hidden = true;
@@ -128097,86 +128563,7 @@ var isRegExp = (value) => {
128097
128563
  nodes: [resultNode],
128098
128564
  consumed: 1
128099
128565
  };
128100
- }, textNodeHandlerEntity, PARAGRAPH_PROPERTIES_XML_NAME = "w:pPr", hasMeaningfulParagraphContent = (elements = []) => elements.some((element) => element?.name && element.name !== PARAGRAPH_PROPERTIES_XML_NAME), findParagraphProperties = (elements = []) => elements.find((element) => element?.name === PARAGRAPH_PROPERTIES_XML_NAME) ?? null, hasParagraphProperties = (elements = []) => elements.some((element) => element?.name === PARAGRAPH_PROPERTIES_XML_NAME), cloneParagraphPropertiesForRenderedResult = (paragraphProperties) => {
128101
- const elements = (paragraphProperties.elements || []).filter((element) => element?.name !== "w:sectPr").map((element) => carbonCopy(element));
128102
- if (elements.length === 0)
128103
- return null;
128104
- return {
128105
- ...carbonCopy(paragraphProperties),
128106
- elements
128107
- };
128108
- }, inheritWrapperParagraphProperties = (blockFieldElement, paragraphProperties) => {
128109
- if (!paragraphProperties)
128110
- return blockFieldElement;
128111
- const fieldElements = Array.isArray(blockFieldElement?.elements) ? blockFieldElement.elements : [];
128112
- const firstParagraphIndex = fieldElements.findIndex((element) => element?.name === "w:p");
128113
- if (firstParagraphIndex < 0)
128114
- return blockFieldElement;
128115
- const firstParagraph = fieldElements[firstParagraphIndex];
128116
- const firstParagraphElements = Array.isArray(firstParagraph.elements) ? firstParagraph.elements : [];
128117
- if (hasParagraphProperties(firstParagraphElements))
128118
- return blockFieldElement;
128119
- const renderedParagraphProperties = cloneParagraphPropertiesForRenderedResult(paragraphProperties);
128120
- const inheritedFirstParagraph = {
128121
- ...firstParagraph,
128122
- elements: renderedParagraphProperties ? [renderedParagraphProperties, ...firstParagraphElements] : firstParagraphElements
128123
- };
128124
- return {
128125
- ...blockFieldElement,
128126
- attributes: {
128127
- ...blockFieldElement.attributes || {},
128128
- wrapperParagraphProperties: carbonCopy(paragraphProperties)
128129
- },
128130
- elements: fieldElements.map((element, index2) => index2 === firstParagraphIndex ? inheritedFirstParagraph : element)
128131
- };
128132
- }, hoistBlockFieldNodes = (params3, paragraphNode) => {
128133
- const paragraphElements = Array.isArray(paragraphNode?.elements) ? paragraphNode.elements : [];
128134
- const blockFieldElements = paragraphElements.filter((element) => BLOCK_FIELD_XML_NAMES.has(element?.name));
128135
- if (blockFieldElements.length === 0)
128136
- return null;
128137
- const nodes = [];
128138
- const remainingElements = paragraphElements.filter((element) => !BLOCK_FIELD_XML_NAMES.has(element?.name));
128139
- const wrapperParagraphProperties = findParagraphProperties(remainingElements);
128140
- const shouldTransferWrapperProperties = !hasMeaningfulParagraphContent(remainingElements);
128141
- if (hasMeaningfulParagraphContent(remainingElements)) {
128142
- const paragraph2 = translator.encode({
128143
- ...params3,
128144
- nodes: [{
128145
- ...paragraphNode,
128146
- elements: remainingElements
128147
- }]
128148
- });
128149
- if (paragraph2)
128150
- nodes.push(paragraph2);
128151
- }
128152
- blockFieldElements.forEach((blockFieldElement) => {
128153
- const fieldElement = shouldTransferWrapperProperties ? inheritWrapperParagraphProperties(blockFieldElement, wrapperParagraphProperties) : blockFieldElement;
128154
- nodes.push(...params3.nodeListHandler.handler({
128155
- ...params3,
128156
- nodes: [fieldElement],
128157
- path: [...params3.path || [], paragraphNode]
128158
- }));
128159
- });
128160
- return nodes;
128161
- }, handleParagraphNode$1 = (params3) => {
128162
- const { nodes } = params3;
128163
- if (nodes.length === 0 || nodes[0].name !== "w:p")
128164
- return {
128165
- nodes: [],
128166
- consumed: 0
128167
- };
128168
- const hoistedNodes = hoistBlockFieldNodes(params3, nodes[0]);
128169
- if (hoistedNodes)
128170
- return {
128171
- nodes: hoistedNodes,
128172
- consumed: 1
128173
- };
128174
- const schemaNode = translator.encode(params3);
128175
- return {
128176
- nodes: Array.isArray(schemaNode) ? schemaNode : schemaNode ? [schemaNode] : [],
128177
- consumed: 1
128178
- };
128179
- }, paragraphNodeHandlerEntity, handleSdtNode = (params3) => {
128566
+ }, textNodeHandlerEntity, handleSdtNode = (params3) => {
128180
128567
  const { nodes } = params3;
128181
128568
  if (nodes.length === 0 || nodes[0].name !== "w:sdt")
128182
128569
  return {
@@ -133044,7 +133431,186 @@ var isRegExp = (value) => {
133044
133431
  if (toBoolean(attrs.hidden) === true)
133045
133432
  return true;
133046
133433
  return typeof attrs.visibility === "string" && attrs.visibility.toLowerCase() === "hidden";
133047
- }, normalizeWrapType$1 = (value) => {
133434
+ }, TEXTBOX_CONTAINER_TYPES, resolveTextFormattingFromMarks = (marks) => {
133435
+ if (!Array.isArray(marks) || marks.length === 0)
133436
+ return;
133437
+ const formatting = {};
133438
+ marks.forEach((mark) => {
133439
+ if (!mark || typeof mark.type !== "string")
133440
+ return;
133441
+ const attrs = isPlainObject3(mark.attrs) ? mark.attrs : {};
133442
+ if (mark.type === "bold")
133443
+ formatting.bold = true;
133444
+ if (mark.type === "italic")
133445
+ formatting.italic = true;
133446
+ const color2 = typeof attrs.color === "string" ? attrs.color.replace(/^#/, "") : undefined;
133447
+ if (color2)
133448
+ formatting.color = color2;
133449
+ const fontFamily = typeof attrs.fontFamily === "string" ? attrs.fontFamily : undefined;
133450
+ if (fontFamily)
133451
+ formatting.fontFamily = fontFamily;
133452
+ const fontSize = pickNumber(attrs.fontSize);
133453
+ if (fontSize != null)
133454
+ formatting.fontSize = fontSize;
133455
+ });
133456
+ return Object.keys(formatting).length > 0 ? formatting : undefined;
133457
+ }, pushTextPart = (parts, part) => {
133458
+ if (!part.text && !part.fieldType && !part.isLineBreak)
133459
+ return;
133460
+ parts.push(part);
133461
+ }, extractTextPartsFromTextboxInline = (node3, parts) => {
133462
+ if (!node3)
133463
+ return;
133464
+ const formatting = resolveTextFormattingFromMarks(node3.marks);
133465
+ if (typeof node3.text === "string") {
133466
+ pushTextPart(parts, {
133467
+ text: node3.text,
133468
+ ...formatting ? { formatting } : {}
133469
+ });
133470
+ return;
133471
+ }
133472
+ switch (node3.type) {
133473
+ case "text":
133474
+ pushTextPart(parts, {
133475
+ text: "",
133476
+ ...formatting ? { formatting } : {}
133477
+ });
133478
+ return;
133479
+ case "tab":
133480
+ pushTextPart(parts, {
133481
+ text: "\t",
133482
+ ...formatting ? { formatting } : {}
133483
+ });
133484
+ return;
133485
+ case "lineBreak":
133486
+ pushTextPart(parts, {
133487
+ text: `
133488
+ `,
133489
+ isLineBreak: true,
133490
+ ...formatting ? { formatting } : {}
133491
+ });
133492
+ return;
133493
+ case "page-number":
133494
+ pushTextPart(parts, {
133495
+ text: "",
133496
+ fieldType: "PAGE",
133497
+ pageNumberFormat: typeof node3.attrs?.pageNumberFormat === "string" ? node3.attrs.pageNumberFormat : undefined,
133498
+ ...formatting ? { formatting } : {}
133499
+ });
133500
+ return;
133501
+ case "total-page-number":
133502
+ pushTextPart(parts, {
133503
+ text: typeof node3.attrs?.resolvedText === "string" ? node3.attrs.resolvedText : typeof node3.attrs?.importedCachedText === "string" ? node3.attrs.importedCachedText : "",
133504
+ fieldType: "NUMPAGES",
133505
+ pageNumberFormat: typeof node3.attrs?.pageNumberFormat === "string" ? node3.attrs.pageNumberFormat : undefined,
133506
+ ...formatting ? { formatting } : {}
133507
+ });
133508
+ return;
133509
+ default:
133510
+ break;
133511
+ }
133512
+ if (Array.isArray(node3.content) && (TEXTBOX_CONTAINER_TYPES.has(node3.type) || node3.content.length > 0))
133513
+ node3.content.forEach((child) => extractTextPartsFromTextboxInline(child, parts));
133514
+ }, extractTextboxTextContent = (node3) => {
133515
+ if (!Array.isArray(node3.content) || node3.content.length === 0)
133516
+ return;
133517
+ const parts = [];
133518
+ let horizontalAlign;
133519
+ const paragraphs = node3.content.filter((child) => child?.type === "paragraph");
133520
+ const paragraphHasRenderableContent = (paragraph2) => Array.isArray(paragraph2.content) && paragraph2.content.length > 0;
133521
+ paragraphs.forEach((paragraph2, paragraphIndex) => {
133522
+ const justification = paragraph2.attrs?.paragraphProperties;
133523
+ if (!horizontalAlign && isPlainObject3(justification)) {
133524
+ const value = justification.justification;
133525
+ if (value === "left" || value === "center" || value === "right")
133526
+ horizontalAlign = value;
133527
+ }
133528
+ paragraph2.content?.forEach((child) => extractTextPartsFromTextboxInline(child, parts));
133529
+ if (paragraphIndex < paragraphs.length - 1) {
133530
+ const nextParagraph = paragraphs[paragraphIndex + 1];
133531
+ parts.push({
133532
+ text: `
133533
+ `,
133534
+ isLineBreak: true,
133535
+ isEmptyParagraph: !paragraphHasRenderableContent(paragraph2) || !paragraphHasRenderableContent(nextParagraph)
133536
+ });
133537
+ }
133538
+ });
133539
+ return parts.length > 0 ? {
133540
+ parts,
133541
+ ...horizontalAlign ? { horizontalAlign } : {}
133542
+ } : undefined;
133543
+ }, isParagraphNode = (node3) => node3?.type === "paragraph", toTextboxParagraphBlocks = (node3, context) => {
133544
+ const shapeTextboxNode = node3.type === "shapeTextbox" ? node3 : resolveNestedShapeTextboxNode(node3);
133545
+ const paragraphToFlowBlocks$1 = context.converters?.paragraphToFlowBlocks;
133546
+ if (!shapeTextboxNode || !paragraphToFlowBlocks$1 || !Array.isArray(shapeTextboxNode.content))
133547
+ return [];
133548
+ const textboxBlocks = [];
133549
+ for (const child of shapeTextboxNode.content) {
133550
+ if (!isParagraphNode(child))
133551
+ continue;
133552
+ const convertedBlocks = paragraphToFlowBlocks$1({
133553
+ para: child,
133554
+ nextBlockId: context.nextBlockId,
133555
+ positions: context.positions,
133556
+ storyKey: context.storyKey,
133557
+ trackedChangesConfig: context.trackedChangesConfig,
133558
+ bookmarks: context.bookmarks,
133559
+ hyperlinkConfig: context.hyperlinkConfig,
133560
+ themeColors: context.themeColors,
133561
+ converters: context.converters,
133562
+ converterContext: context.converterContext,
133563
+ enableComments: context.enableComments,
133564
+ previousParagraphFont: getLastParagraphFont(textboxBlocks)
133565
+ });
133566
+ textboxBlocks.push(...convertedBlocks);
133567
+ }
133568
+ return textboxBlocks.filter((block) => block.kind === "paragraph");
133569
+ }, parseTextboxInsetValue = (value) => {
133570
+ const trimmed = value.trim();
133571
+ if (!trimmed)
133572
+ return;
133573
+ if (trimmed.endsWith("pt"))
133574
+ return ptToPx(parseFloat(trimmed.slice(0, -2)));
133575
+ if (trimmed.endsWith("px"))
133576
+ return pickNumber(trimmed.slice(0, -2));
133577
+ if (trimmed.endsWith("in")) {
133578
+ const inches = parseFloat(trimmed.slice(0, -2));
133579
+ return Number.isFinite(inches) ? inches * 96 : undefined;
133580
+ }
133581
+ return pickNumber(trimmed);
133582
+ }, resolveTextboxInsetsFromAttrs = (attrs) => {
133583
+ const explicitInsets = normalizeTextInsets(attrs.textInsets);
133584
+ if (explicitInsets)
133585
+ return explicitInsets;
133586
+ const textboxAttrs = isPlainObject3(attrs.attributes) ? attrs.attributes : undefined;
133587
+ const inset = typeof textboxAttrs?.inset === "string" ? textboxAttrs.inset : undefined;
133588
+ if (!inset)
133589
+ return;
133590
+ const values = inset.split(",").map((entry) => parseTextboxInsetValue(entry));
133591
+ if (values.length !== 4 || values.some((entry) => entry == null))
133592
+ return;
133593
+ return {
133594
+ top: values[1],
133595
+ right: values[2],
133596
+ bottom: values[3],
133597
+ left: values[0]
133598
+ };
133599
+ }, resolveTextboxVerticalAlignFromAttrs = (attrs) => {
133600
+ const explicitAlign = normalizeTextVerticalAlign(attrs.textVerticalAlign);
133601
+ if (explicitAlign)
133602
+ return explicitAlign;
133603
+ const textboxAttrs = isPlainObject3(attrs.attributes) ? attrs.attributes : undefined;
133604
+ const style = typeof textboxAttrs?.style === "string" ? textboxAttrs.style : undefined;
133605
+ if (!style)
133606
+ return;
133607
+ const match = style.match(/v-text-anchor\s*:\s*(top|middle|bottom)/i);
133608
+ if (!match)
133609
+ return;
133610
+ if (match[1].toLowerCase() === "middle")
133611
+ return "center";
133612
+ return match[1].toLowerCase();
133613
+ }, resolveNestedShapeTextboxNode = (node3) => Array.isArray(node3.content) ? node3.content.find((child) => child?.type === "shapeTextbox") : undefined, normalizeWrapType$1 = (value) => {
133048
133614
  if (typeof value !== "string")
133049
133615
  return;
133050
133616
  return WRAP_TYPES$2.has(value) ? value : undefined;
@@ -133761,13 +134327,13 @@ var isRegExp = (value) => {
133761
134327
  if (childNode.type === "shapeContainer" && context.converters?.shapeContainerNodeToDrawingBlock) {
133762
134328
  const drawingBlock = context.converters.shapeContainerNodeToDrawingBlock(childNode, context.nextBlockId, context.positions);
133763
134329
  if (drawingBlock && drawingBlock.kind === "drawing")
133764
- blocks.push(drawingBlock);
134330
+ blocks.push(hydrateTextboxDrawingContent(childNode, drawingBlock, context));
133765
134331
  continue;
133766
134332
  }
133767
134333
  if (childNode.type === "shapeTextbox" && context.converters?.shapeTextboxNodeToDrawingBlock) {
133768
134334
  const drawingBlock = context.converters.shapeTextboxNodeToDrawingBlock(childNode, context.nextBlockId, context.positions);
133769
134335
  if (drawingBlock && drawingBlock.kind === "drawing")
133770
- blocks.push(drawingBlock);
134336
+ blocks.push(hydrateTextboxDrawingContent(childNode, drawingBlock, context));
133771
134337
  continue;
133772
134338
  }
133773
134339
  }
@@ -134327,7 +134893,7 @@ var isRegExp = (value) => {
134327
134893
  state.kern = kernNode.attributes["w:val"];
134328
134894
  }
134329
134895
  }, SuperConverter;
134330
- var init_SuperConverter_BTGVElJO_es = __esm(() => {
134896
+ var init_SuperConverter_CUxtXQFf_es = __esm(() => {
134331
134897
  init_rolldown_runtime_Bg48TavK_es();
134332
134898
  init_jszip_C49i9kUs_es();
134333
134899
  init_xml_js_CqGKpaft_es();
@@ -151088,6 +151654,7 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
151088
151654
  "w:footnoteReference": "FootnoteReference",
151089
151655
  "w:endnoteReference": "EndnoteReference"
151090
151656
  };
151657
+ BLOCK_HOIST_TYPES = new Set(["shapeContainer"]);
151091
151658
  COMPLEX_SCRIPT_CODEPOINT_RANGES = [
151092
151659
  [1424, 2303],
151093
151660
  [2304, 4255],
@@ -163173,6 +163740,10 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
163173
163740
  "c:surface3DChart": "surfaceChart"
163174
163741
  };
163175
163742
  CHART_TYPE_NAMES = new Set(Object.keys(CHART_TYPE_MAP));
163743
+ paragraphNodeHandlerEntity = {
163744
+ handlerName: "paragraphNodeHandler",
163745
+ handler: handleParagraphNode$1
163746
+ };
163176
163747
  atomElements = /^(img|br|input|textarea|hr)$/i;
163177
163748
  nav = typeof navigator != "undefined" ? navigator : null;
163178
163749
  doc = typeof document != "undefined" ? document : null;
@@ -170909,10 +171480,6 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
170909
171480
  handlerName: "textNodeHandler",
170910
171481
  handler: handleTextNode
170911
171482
  };
170912
- paragraphNodeHandlerEntity = {
170913
- handlerName: "paragraphNodeHandler",
170914
- handler: handleParagraphNode$1
170915
- };
170916
171483
  sdtNodeHandlerEntity = {
170917
171484
  handlerName: "sdtNodeHandler",
170918
171485
  handler: handleSdtNode
@@ -172610,6 +173177,11 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
172610
173177
  style: "normal",
172611
173178
  file: "Caprasimo-Regular.woff2"
172612
173179
  }]),
173180
+ familyWithFaces("Archivo Black", "OFL-1.1", [{
173181
+ weight: "normal",
173182
+ style: "normal",
173183
+ file: "ArchivoBlack-Regular.woff2"
173184
+ }]),
172613
173185
  familyWithFaces("C059", "AGPL-3.0-only WITH PS-or-PDF-font-exception-20170817", [
172614
173186
  {
172615
173187
  weight: "normal",
@@ -172679,7 +173251,16 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
172679
173251
  style: "normal",
172680
173252
  file: "NotoSansMono-Bold.woff2"
172681
173253
  }]),
172682
- family("PT Sans", "PTSans", "OFL-1.1")
173254
+ family("PT Sans", "PTSans", "OFL-1.1"),
173255
+ familyWithFaces("PT Sans Narrow", "OFL-1.1", [{
173256
+ weight: "normal",
173257
+ style: "normal",
173258
+ file: "PTSansNarrow-Regular.woff2"
173259
+ }, {
173260
+ weight: "bold",
173261
+ style: "normal",
173262
+ file: "PTSansNarrow-Bold.woff2"
173263
+ }])
172683
173264
  ]);
172684
173265
  SUBSTITUTION_EVIDENCE = SUBSTITUTION_EVIDENCE$1;
172685
173266
  bundledFamilies = new Set(BUNDLED_MANIFEST.map((f2) => f2.family));
@@ -172696,6 +173277,7 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
172696
173277
  registriesByFontSet = /* @__PURE__ */ new WeakMap;
172697
173278
  BUNDLED_FAMILIES = new Set(BUNDLED_MANIFEST.map((f2) => f2.family));
172698
173279
  ADVERTISED_BUILT_IN_TOOLBAR_FAMILIES = new Set([
173280
+ "Arial Black",
172699
173281
  "Arial Narrow",
172700
173282
  "Baskerville Old Face",
172701
173283
  "Brush Script MT",
@@ -172704,6 +173286,7 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
172704
173286
  "Comic Sans MS",
172705
173287
  "Garamond",
172706
173288
  "Georgia",
173289
+ "Gill Sans MT Condensed",
172707
173290
  "Lucida Console",
172708
173291
  "Tahoma",
172709
173292
  "Trebuchet MS"
@@ -172993,6 +173576,14 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
172993
173576
  "center",
172994
173577
  "bottom"
172995
173578
  ]);
173579
+ TEXTBOX_CONTAINER_TYPES = new Set([
173580
+ "run",
173581
+ "link",
173582
+ "hyperlink",
173583
+ "structuredContent",
173584
+ "fieldAnnotation",
173585
+ "smartTag"
173586
+ ]);
172996
173587
  WRAP_TYPES$1 = new Set([
172997
173588
  "None",
172998
173589
  "Square",
@@ -174495,7 +175086,7 @@ var init_SuperConverter_BTGVElJO_es = __esm(() => {
174495
175086
  };
174496
175087
  });
174497
175088
 
174498
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-DYbkX05s.es.js
175089
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-DutCjfp2.es.js
174499
175090
  function parseSizeUnit(val = "0") {
174500
175091
  const length3 = val.toString() || "0";
174501
175092
  const value = Number.parseFloat(length3);
@@ -184890,8 +185481,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, normalizeActorId = (value) => {
184890
185481
  }
184891
185482
  };
184892
185483
  };
184893
- var init_create_headless_toolbar_DYbkX05s_es = __esm(() => {
184894
- init_SuperConverter_BTGVElJO_es();
185484
+ var init_create_headless_toolbar_DutCjfp2_es = __esm(() => {
185485
+ init_SuperConverter_CUxtXQFf_es();
184895
185486
  init_uuid_B2wVPhPi_es();
184896
185487
  init_constants_D9qj59G2_es();
184897
185488
  init_dist_B8HfvhaK_es();
@@ -234060,7 +234651,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
234060
234651
  init_remark_gfm_BhnWr3yf_es();
234061
234652
  });
234062
234653
 
234063
- // ../../packages/superdoc/dist/chunks/src-CRJcfbIa.es.js
234654
+ // ../../packages/superdoc/dist/chunks/src-BBtIMpLJ.es.js
234064
234655
  function deleteProps(obj, propOrProps) {
234065
234656
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
234066
234657
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -275175,7 +275766,7 @@ function hasPageContextTokenInBlock(block) {
275175
275766
  return true;
275176
275767
  } else if (block.kind === "drawing") {
275177
275768
  const drawing = block;
275178
- if (drawing.drawingKind === "vectorShape")
275769
+ if (drawing.drawingKind === "vectorShape" || drawing.drawingKind === "textboxShape")
275179
275770
  return hasPageContextTokenInShapeText(drawing.textContent);
275180
275771
  if (drawing.drawingKind === "shapeGroup")
275181
275772
  return hasPageContextTokenInShapeGroup(drawing.shapes);
@@ -276832,6 +277423,18 @@ function computeParagraphLayoutStartY(input2) {
276832
277423
  const effectiveSpacingBefore = input2.suppressSpacingBefore ? 0 : input2.spacingBefore;
276833
277424
  return computeParagraphContentStartY(y$1, effectiveSpacingBefore, effectiveSpacingBefore === 0, trailingForCollapse);
276834
277425
  }
277426
+ function layoutTextboxContent(block, remeasureParagraph$1) {
277427
+ if (!Array.isArray(block.contentBlocks) || block.contentBlocks.length === 0)
277428
+ return [];
277429
+ const insets = block.textInsets ?? {
277430
+ top: 0,
277431
+ right: 0,
277432
+ bottom: 0,
277433
+ left: 0
277434
+ };
277435
+ const contentWidth = Math.max(1, block.geometry.width - insets.left - insets.right);
277436
+ return block.contentBlocks.map((paragraphBlock) => remeasureParagraph$1(paragraphBlock, contentWidth));
277437
+ }
276835
277438
  function describeCellRenderBlocks(cellMeasure, cellBlock, cellPadding) {
276836
277439
  const measuredBlocks = cellMeasure.blocks;
276837
277440
  const blockDataArray = cellBlock?.blocks;
@@ -278296,6 +278899,7 @@ function layoutParagraphBlock(ctx$1, anchors) {
278296
278899
  fragment2.pmEnd = pmRange.pmEnd;
278297
278900
  state.page.fragments.push(fragment2);
278298
278901
  } else if (entry.block.kind === "drawing" && entry.measure.kind === "drawing") {
278902
+ const contentMeasures = entry.block.drawingKind === "textboxShape" && typeof remeasureParagraph$1 === "function" ? layoutTextboxContent(entry.block, remeasureParagraph$1) : undefined;
278299
278903
  const fragment2 = {
278300
278904
  kind: "drawing",
278301
278905
  blockId: entry.block.id,
@@ -278312,6 +278916,8 @@ function layoutParagraphBlock(ctx$1, anchors) {
278312
278916
  drawingContentId: entry.block.drawingContentId,
278313
278917
  sourceAnchor: entry.block.sourceAnchor
278314
278918
  };
278919
+ if (contentMeasures)
278920
+ fragment2.contentMeasures = contentMeasures;
278315
278921
  if (pmRange.pmStart != null)
278316
278922
  fragment2.pmStart = pmRange.pmStart;
278317
278923
  if (pmRange.pmEnd != null)
@@ -278720,7 +279326,7 @@ function layoutImageBlock({ block, measure, columns, ensurePage, advanceColumn,
278720
279326
  state.cursorY += requiredHeight;
278721
279327
  state.maxCursorY = Math.max(state.maxCursorY, state.cursorY);
278722
279328
  }
278723
- function layoutDrawingBlock({ block, measure, columns, ensurePage, advanceColumn, columnX }) {
279329
+ function layoutDrawingBlock({ block, measure, columns, ensurePage, advanceColumn, columnX, textboxContentMeasures }) {
278724
279330
  if (block.anchor?.isAnchored)
278725
279331
  return;
278726
279332
  const marginTop = Math.max(0, block.margin?.top ?? 0);
@@ -278777,6 +279383,8 @@ function layoutDrawingBlock({ block, measure, columns, ensurePage, advanceColumn
278777
279383
  pmEnd: pmRange.pmEnd,
278778
279384
  sourceAnchor: block.sourceAnchor
278779
279385
  };
279386
+ if (textboxContentMeasures)
279387
+ fragment2.contentMeasures = textboxContentMeasures;
278780
279388
  state.page.fragments.push(fragment2);
278781
279389
  state.cursorY += requiredHeight;
278782
279390
  state.maxCursorY = Math.max(state.maxCursorY, state.cursorY);
@@ -281210,6 +281818,7 @@ function layoutDocument(blocks2, measures, options = {}) {
281210
281818
  const state = paginator.ensurePage();
281211
281819
  const drawBlock = block;
281212
281820
  const drawMeasure = measure;
281821
+ const contentMeasures = drawBlock.drawingKind === "textboxShape" && typeof options.remeasureParagraph === "function" ? layoutTextboxContent(drawBlock, options.remeasureParagraph) : undefined;
281213
281822
  const fragment2 = {
281214
281823
  kind: "drawing",
281215
281824
  blockId: drawBlock.id,
@@ -281226,6 +281835,8 @@ function layoutDocument(blocks2, measures, options = {}) {
281226
281835
  drawingContentId: drawBlock.drawingContentId,
281227
281836
  sourceAnchor: drawBlock.sourceAnchor
281228
281837
  };
281838
+ if (contentMeasures)
281839
+ fragment2.contentMeasures = contentMeasures;
281229
281840
  const attrs = drawBlock.attrs;
281230
281841
  if (attrs?.pmStart != null)
281231
281842
  fragment2.pmStart = attrs.pmStart;
@@ -281241,7 +281852,8 @@ function layoutDocument(blocks2, measures, options = {}) {
281241
281852
  columns: getCurrentColumns(),
281242
281853
  ensurePage: paginator.ensurePage,
281243
281854
  advanceColumn: paginator.advanceColumn,
281244
- columnX
281855
+ columnX,
281856
+ textboxContentMeasures: block.drawingKind === "textboxShape" && typeof options.remeasureParagraph === "function" ? layoutTextboxContent(block, options.remeasureParagraph) : undefined
281245
281857
  });
281246
281858
  continue;
281247
281859
  }
@@ -281517,7 +282129,7 @@ function shouldExcludeFromMeasurement(fragment2, block, fragmentBottom, canvasHe
281517
282129
  return true;
281518
282130
  return false;
281519
282131
  }
281520
- function layoutHeaderFooter(blocks2, measures, constraints, kind) {
282132
+ function layoutHeaderFooter(blocks2, measures, constraints, kind, remeasureParagraph$1) {
281521
282133
  if (blocks2.length !== measures.length)
281522
282134
  throw new Error(`layoutHeaderFooter expected measures for every block (blocks=${blocks2.length}, measures=${measures.length})`);
281523
282135
  const width = Number(constraints?.width);
@@ -281541,7 +282153,8 @@ function layoutHeaderFooter(blocks2, measures, constraints, kind) {
281541
282153
  left: 0
281542
282154
  },
281543
282155
  allowParagraphlessAnchoredTableFallback: false,
281544
- allowSectionBreakOnlyPageFallback: false
282156
+ allowSectionBreakOnlyPageFallback: false,
282157
+ remeasureParagraph: remeasureParagraph$1
281545
282158
  });
281546
282159
  if (kind === "footer" && constraints.pageHeight != null)
281547
282160
  normalizeFragmentsForRegion(layout.pages, blocks2, measures, kind, constraints);
@@ -282320,7 +282933,7 @@ function hasPageNumberTokensRequiringPerPageLayout(blocks2) {
282320
282933
  }
282321
282934
  return false;
282322
282935
  }
282323
- async function layoutHeaderFooterWithCache(sections, constraints, measureBlock$1, cache$2 = sharedHeaderFooterCache, totalPages, pageResolver, kind, fontSignature = "") {
282936
+ async function layoutHeaderFooterWithCache(sections, constraints, measureBlock$1, cache$2 = sharedHeaderFooterCache, totalPages, pageResolver, kind, fontSignature = "", remeasureParagraph$1) {
282324
282937
  const result = {};
282325
282938
  if (!pageResolver) {
282326
282939
  const numPages = totalPages ?? 1;
@@ -282333,7 +282946,7 @@ async function layoutHeaderFooterWithCache(sections, constraints, measureBlock$1
282333
282946
  result[type] = {
282334
282947
  blocks: clonedBlocks,
282335
282948
  measures,
282336
- layout: layoutHeaderFooter(clonedBlocks, measures, constraints, kind)
282949
+ layout: layoutHeaderFooter(clonedBlocks, measures, constraints, kind, remeasureParagraph$1)
282337
282950
  };
282338
282951
  }
282339
282952
  return result;
@@ -282350,7 +282963,7 @@ async function layoutHeaderFooterWithCache(sections, constraints, measureBlock$1
282350
282963
  result[type] = {
282351
282964
  blocks: blocks2,
282352
282965
  measures,
282353
- layout: layoutHeaderFooter(blocks2, measures, constraints, kind)
282966
+ layout: layoutHeaderFooter(blocks2, measures, constraints, kind, remeasureParagraph$1)
282354
282967
  };
282355
282968
  continue;
282356
282969
  }
@@ -282372,7 +282985,7 @@ async function layoutHeaderFooterWithCache(sections, constraints, measureBlock$1
282372
282985
  const { displayText, displayNumber, totalPages: totalPagesForPage, sectionPageCount, pageFormat, chapterNumberText, chapterSeparator } = pageResolver(pageNum);
282373
282986
  resolveHeaderFooterTokens(clonedBlocks, pageNum, totalPagesForPage, displayText, displayNumber, sectionPageCount, pageFormat, chapterNumberText, chapterSeparator);
282374
282987
  const measures = await cache$2.measureBlocks(clonedBlocks, constraints, measureBlock$1, fontSignature);
282375
- const pageLayout = layoutHeaderFooter(clonedBlocks, measures, constraints, kind);
282988
+ const pageLayout = layoutHeaderFooter(clonedBlocks, measures, constraints, kind, remeasureParagraph$1);
282376
282989
  const measuresById = /* @__PURE__ */ new Map;
282377
282990
  for (let i4 = 0;i4 < clonedBlocks.length; i4 += 1)
282378
282991
  measuresById.set(clonedBlocks[i4].id, measures[i4]);
@@ -283235,7 +283848,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
283235
283848
  const blocks2 = blocksByRId.get(group.rId);
283236
283849
  if (!blocks2 || blocks2.length === 0)
283237
283850
  continue;
283238
- const layout$1 = (await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, measureFn, headerMeasureCache, 1, pageResolver, kind)).default?.layout;
283851
+ const layout$1 = (await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, measureFn, headerMeasureCache, 1, pageResolver, kind, undefined, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent))).default?.layout;
283239
283852
  if (!layout$1 || !(layout$1.height > 0))
283240
283853
  continue;
283241
283854
  const nextHeight = Math.max(0, layout$1.height);
@@ -283252,7 +283865,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
283252
283865
  for (const [rId, blocks2] of blocksByRId) {
283253
283866
  if (!blocks2 || blocks2.length === 0)
283254
283867
  continue;
283255
- const layout$1 = (await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, measureFn, headerMeasureCache, 1, pageResolver, kind)).default?.layout;
283868
+ const layout$1 = (await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, measureFn, headerMeasureCache, 1, pageResolver, kind, undefined, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent))).default?.layout;
283256
283869
  if (layout$1 && layout$1.height > 0)
283257
283870
  heightsByRId.set(rId, layout$1.height);
283258
283871
  }
@@ -283274,7 +283887,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
283274
283887
  };
283275
283888
  headerContentHeights = {};
283276
283889
  if (hasHeaderBlocks && headerFooter.headerBlocks) {
283277
- const preHeaderLayouts = await layoutHeaderFooterWithCache(headerFooter.headerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT, prelayoutPageResolver, "header", fontSignature);
283890
+ const preHeaderLayouts = await layoutHeaderFooterWithCache(headerFooter.headerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT, prelayoutPageResolver, "header", fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent));
283278
283891
  for (const [type, value] of Object.entries(preHeaderLayouts)) {
283279
283892
  if (!isValidHeaderType(type))
283280
283893
  continue;
@@ -283315,7 +283928,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
283315
283928
  footerContentHeights = {};
283316
283929
  try {
283317
283930
  if (hasFooterBlocks && headerFooter.footerBlocks) {
283318
- const preFooterLayouts = await layoutHeaderFooterWithCache(headerFooter.footerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT, prelayoutPageResolver, "footer", fontSignature);
283931
+ const preFooterLayouts = await layoutHeaderFooterWithCache(headerFooter.footerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT, prelayoutPageResolver, "footer", fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent));
283319
283932
  for (const [type, value] of Object.entries(preFooterLayouts)) {
283320
283933
  if (!isValidFooterType(type))
283321
283934
  continue;
@@ -283404,6 +284017,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
283404
284017
  console.warn(`[incrementalLayout] Page token resolution did not converge after ${maxIterations} iterations - stopping`);
283405
284018
  }
283406
284019
  }
284020
+ hydrateTableTextboxMeasures(currentBlocks, (block, maxWidth) => remeasureParagraph(block, maxWidth));
283407
284021
  const totalTokenTime = performance.now() - pageTokenStart;
283408
284022
  if (iteration > 0) {
283409
284023
  perfLog$1(`[Perf] 4.3 Total page token resolution time: ${totalTokenTime.toFixed(2)}ms`);
@@ -284415,10 +285029,17 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
284415
285029
  chapterSeparator: displayInfo?.chapterSeparator
284416
285030
  };
284417
285031
  } : undefined;
284418
- if (headerFooter.headerBlocks)
284419
- headers = serializeHeaderFooterResults("header", await layoutHeaderFooterWithCache(headerFooter.headerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? undefined : numberingCtx.totalPages, pageResolver, "header", fontSignature));
284420
- if (headerFooter.footerBlocks)
284421
- footers = serializeHeaderFooterResults("footer", await layoutHeaderFooterWithCache(headerFooter.footerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? undefined : numberingCtx.totalPages, pageResolver, "footer", fontSignature));
285032
+ const hfRemeasure = (block, maxWidth) => remeasureParagraph(block, maxWidth);
285033
+ if (headerFooter.headerBlocks) {
285034
+ for (const blocks2 of Object.values(headerFooter.headerBlocks))
285035
+ hydrateTableTextboxMeasures(blocks2, hfRemeasure);
285036
+ headers = serializeHeaderFooterResults("header", await layoutHeaderFooterWithCache(headerFooter.headerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? undefined : numberingCtx.totalPages, pageResolver, "header", fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)));
285037
+ }
285038
+ if (headerFooter.footerBlocks) {
285039
+ for (const blocks2 of Object.values(headerFooter.footerBlocks))
285040
+ hydrateTableTextboxMeasures(blocks2, hfRemeasure);
285041
+ footers = serializeHeaderFooterResults("footer", await layoutHeaderFooterWithCache(headerFooter.footerBlocks, headerFooter.constraints, measureFn, headerMeasureCache, FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? undefined : numberingCtx.totalPages, pageResolver, "footer", fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)));
285042
+ }
284422
285043
  perfLog$1(`[Perf] 4.4 Header/footer layout: ${(performance.now() - hfStart).toFixed(2)}ms`);
284423
285044
  const cacheStats = headerMeasureCache.getStats();
284424
285045
  globalMetrics.recordHeaderFooterCacheMetrics(cacheStats);
@@ -284434,6 +285055,19 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
284434
285055
  extraMeasures
284435
285056
  };
284436
285057
  }
285058
+ function hydrateTableTextboxMeasures(blocks2, remeasure) {
285059
+ for (const block of blocks2) {
285060
+ if (block.kind !== "table")
285061
+ continue;
285062
+ for (const row2 of block.rows ?? [])
285063
+ for (const cell2 of row2.cells ?? [])
285064
+ for (const cellBlock of cell2.blocks ?? [])
285065
+ if (cellBlock.kind === "drawing" && cellBlock.drawingKind === "textboxShape")
285066
+ cellBlock.contentMeasures = layoutTextboxContent(cellBlock, remeasure);
285067
+ else if (cellBlock.kind === "table")
285068
+ hydrateTableTextboxMeasures([cellBlock], remeasure);
285069
+ }
285070
+ }
284437
285071
  function rewriteSectionBreaksForSemanticFlow(blocks2, options) {
284438
285072
  const semanticPageSize = options.pageSize;
284439
285073
  const semanticMargins = options.margins;
@@ -284712,41 +285346,6 @@ async function remeasureAffectedBlocks(blocks2, measures, affectedBlockIds, perB
284712
285346
  }
284713
285347
  return updatedMeasures;
284714
285348
  }
284715
- function calculateSummary(samples) {
284716
- if (samples.length === 0)
284717
- return {
284718
- count: 0,
284719
- min: 0,
284720
- max: 0,
284721
- avg: 0,
284722
- p50: 0,
284723
- p95: 0,
284724
- p99: 0
284725
- };
284726
- const values = samples.map((s2) => s2.value).sort((a2, b$1) => a2 - b$1);
284727
- const count2 = values.length;
284728
- const sum = values.reduce((acc, v) => acc + v, 0);
284729
- return {
284730
- count: count2,
284731
- min: values[0],
284732
- max: values[count2 - 1],
284733
- avg: sum / count2,
284734
- p50: percentile(values, 0.5),
284735
- p95: percentile(values, 0.95),
284736
- p99: percentile(values, 0.99)
284737
- };
284738
- }
284739
- function percentile(sortedValues, p$12) {
284740
- if (sortedValues.length === 0)
284741
- return 0;
284742
- if (sortedValues.length === 1)
284743
- return sortedValues[0];
284744
- const index2 = (sortedValues.length - 1) * p$12;
284745
- const lower = Math.floor(index2);
284746
- const upper = Math.ceil(index2);
284747
- const weight = index2 - lower;
284748
- return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
284749
- }
284750
285349
  function resolveColumnsForHit(layout, page, fragmentY) {
284751
285350
  if (page === undefined)
284752
285351
  return layout.columns;
@@ -285042,6 +285641,54 @@ function clickToPositionGeometry(layout, blocks2, measures, containerPoint, opti
285042
285641
  lineIndex
285043
285642
  };
285044
285643
  }
285644
+ if (fragment2.kind === "drawing" && fragment2.drawingKind === "textboxShape" && block.kind === "drawing" && block.drawingKind === "textboxShape") {
285645
+ const textboxHit = resolveTextboxContentHit(fragment2, block, measure, pageIndex, pageRelativePoint);
285646
+ if (textboxHit) {
285647
+ const { contentBlock, contentMeasure, localX, localY, pageIndex: pageIndex$1, paragraphIndex } = textboxHit;
285648
+ const lineIndex = findLineIndexAtY(contentMeasure.lines, localY, 0, contentMeasure.lines.length);
285649
+ if (lineIndex != null) {
285650
+ const line = contentMeasure.lines[lineIndex];
285651
+ const isRTL = isRtlBlock(contentBlock);
285652
+ const indentLeft = typeof contentBlock.attrs?.indent?.left === "number" ? contentBlock.attrs.indent.left : 0;
285653
+ const indentRight = typeof contentBlock.attrs?.indent?.right === "number" ? contentBlock.attrs.indent.right : 0;
285654
+ const totalIndent = (Number.isFinite(indentLeft) ? indentLeft : 0) + (Number.isFinite(indentRight) ? indentRight : 0);
285655
+ const insets = textboxHit.block.textInsets ?? {
285656
+ top: 0,
285657
+ right: 0,
285658
+ bottom: 0,
285659
+ left: 0
285660
+ };
285661
+ let availableWidth = Math.max(0, textboxHit.fragment.width - insets.left - insets.right - totalIndent);
285662
+ if (totalIndent > textboxHit.fragment.width)
285663
+ console.warn(`[clickToPosition:textbox] Paragraph indents (${totalIndent}px) exceed fragment width (${textboxHit.fragment.width}px) for block ${textboxHit.fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`);
285664
+ if (lineIndex === 0) {
285665
+ const suppressFLI = contentBlock.attrs?.suppressFirstLineIndent === true;
285666
+ const firstLineOffset = getFirstLineIndentOffset(contentBlock.attrs?.indent, suppressFLI);
285667
+ availableWidth = adjustAvailableWidthForTextIndent(availableWidth, firstLineOffset, line.maxWidth);
285668
+ }
285669
+ const pos = mapPointToPm(contentBlock, line, localX, isRTL, availableWidth);
285670
+ if (pos != null)
285671
+ return {
285672
+ pos,
285673
+ layoutEpoch,
285674
+ blockId: textboxHit.fragment.blockId,
285675
+ pageIndex: pageIndex$1,
285676
+ column: determineColumn(layout, textboxHit.fragment.x, layout.pages[pageIndex$1], textboxHit.fragment.y),
285677
+ lineIndex
285678
+ };
285679
+ }
285680
+ const firstRun = contentBlock.runs?.[0];
285681
+ if (firstRun && firstRun.pmStart != null)
285682
+ return {
285683
+ pos: firstRun.pmStart,
285684
+ layoutEpoch,
285685
+ blockId: textboxHit.fragment.blockId,
285686
+ pageIndex: pageIndex$1,
285687
+ column: determineColumn(layout, textboxHit.fragment.x, layout.pages[pageIndex$1], textboxHit.fragment.y),
285688
+ lineIndex: 0
285689
+ };
285690
+ }
285691
+ }
285045
285692
  if (isAtomicFragment(fragment2)) {
285046
285693
  const pmRange = getAtomicPmRange(fragment2, block);
285047
285694
  const pos = pmRange.pmStart ?? pmRange.pmEnd ?? null;
@@ -285119,6 +285766,41 @@ function clickToPositionGeometry(layout, blocks2, measures, containerPoint, opti
285119
285766
  }
285120
285767
  return null;
285121
285768
  }
285769
+ function calculateSummary(samples) {
285770
+ if (samples.length === 0)
285771
+ return {
285772
+ count: 0,
285773
+ min: 0,
285774
+ max: 0,
285775
+ avg: 0,
285776
+ p50: 0,
285777
+ p95: 0,
285778
+ p99: 0
285779
+ };
285780
+ const values = samples.map((s2) => s2.value).sort((a2, b$1) => a2 - b$1);
285781
+ const count2 = values.length;
285782
+ const sum = values.reduce((acc, v) => acc + v, 0);
285783
+ return {
285784
+ count: count2,
285785
+ min: values[0],
285786
+ max: values[count2 - 1],
285787
+ avg: sum / count2,
285788
+ p50: percentile(values, 0.5),
285789
+ p95: percentile(values, 0.95),
285790
+ p99: percentile(values, 0.99)
285791
+ };
285792
+ }
285793
+ function percentile(sortedValues, p$12) {
285794
+ if (sortedValues.length === 0)
285795
+ return 0;
285796
+ if (sortedValues.length === 1)
285797
+ return sortedValues[0];
285798
+ const index2 = (sortedValues.length - 1) * p$12;
285799
+ const lower = Math.floor(index2);
285800
+ const upper = Math.ceil(index2);
285801
+ const weight = index2 - lower;
285802
+ return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
285803
+ }
285122
285804
  function selectionToRects(layout, blocks2, measures, from$1, to, geometryHelper) {
285123
285805
  if (from$1 === to)
285124
285806
  return [];
@@ -288287,6 +288969,73 @@ function computeTableCaretLayoutRectFromDom({ viewportHost, visibleHost, zoom },
288287
288969
  }
288288
288970
  return null;
288289
288971
  }
288972
+ function findTextboxFragmentElement(viewportHost, blockId, pageIndex) {
288973
+ const pageEl = viewportHost.querySelector(`[data-page-index="${pageIndex}"]`) ?? viewportHost;
288974
+ return Array.from(pageEl.querySelectorAll("[data-block-id]")).find((el) => el.dataset.blockId === blockId) ?? null;
288975
+ }
288976
+ function computeTextboxCaretLayoutRectFromDom({ viewportHost, visibleHost, zoom }, pos, fragment2, _block, pageIndex) {
288977
+ const fragmentEl = findTextboxFragmentElement(viewportHost, fragment2.blockId, pageIndex);
288978
+ if (!fragmentEl)
288979
+ return null;
288980
+ const lineEls = Array.from(fragmentEl.querySelectorAll(".superdoc-line[data-pm-start][data-pm-end]"));
288981
+ if (lineEls.length === 0)
288982
+ return null;
288983
+ for (let lineIdx = 0;lineIdx < lineEls.length; lineIdx++) {
288984
+ const lineEl = lineEls[lineIdx];
288985
+ const pmStart = Number(lineEl.dataset.pmStart ?? "NaN");
288986
+ const pmEnd = Number(lineEl.dataset.pmEnd ?? "NaN");
288987
+ if (!Number.isFinite(pmStart) || !Number.isFinite(pmEnd))
288988
+ continue;
288989
+ const isLastLine = lineIdx === lineEls.length - 1;
288990
+ if (pos < pmStart || (isLastLine ? pos > pmEnd : pos >= pmEnd))
288991
+ continue;
288992
+ const spanEls = Array.from(lineEl.querySelectorAll("span[data-pm-start][data-pm-end]"));
288993
+ for (let spanIdx = 0;spanIdx < spanEls.length; spanIdx++) {
288994
+ const spanEl = spanEls[spanIdx];
288995
+ const spanStart = Number(spanEl.dataset.pmStart ?? "NaN");
288996
+ const spanEnd = Number(spanEl.dataset.pmEnd ?? "NaN");
288997
+ if (!Number.isFinite(spanStart) || !Number.isFinite(spanEnd))
288998
+ continue;
288999
+ const isLastSpan = spanIdx === spanEls.length - 1;
289000
+ if (pos < spanStart || (isLastSpan ? pos > spanEnd : pos >= spanEnd))
289001
+ continue;
289002
+ const textNode = spanEl.firstChild;
289003
+ if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
289004
+ const spanRect = spanEl.getBoundingClientRect();
289005
+ const viewportRect$2 = viewportHost.getBoundingClientRect();
289006
+ return {
289007
+ pageIndex,
289008
+ x: (spanRect.left - viewportRect$2.left + visibleHost.scrollLeft) / zoom,
289009
+ y: (spanRect.top - viewportRect$2.top + visibleHost.scrollTop) / zoom,
289010
+ height: spanRect.height / zoom
289011
+ };
289012
+ }
289013
+ const text5 = textNode.textContent ?? "";
289014
+ const charOffset = Math.max(0, Math.min(text5.length, pos - spanStart));
289015
+ const range = document.createRange();
289016
+ range.setStart(textNode, charOffset);
289017
+ range.setEnd(textNode, charOffset);
289018
+ const rangeRect = range.getBoundingClientRect();
289019
+ const viewportRect$1 = viewportHost.getBoundingClientRect();
289020
+ const lineRect$1 = lineEl.getBoundingClientRect();
289021
+ return {
289022
+ pageIndex,
289023
+ x: (rangeRect.left - viewportRect$1.left + visibleHost.scrollLeft) / zoom,
289024
+ y: (lineRect$1.top - viewportRect$1.top + visibleHost.scrollTop) / zoom,
289025
+ height: lineRect$1.height / zoom
289026
+ };
289027
+ }
289028
+ const lineRect = lineEl.getBoundingClientRect();
289029
+ const viewportRect = viewportHost.getBoundingClientRect();
289030
+ return {
289031
+ pageIndex,
289032
+ x: (lineRect.left - viewportRect.left + visibleHost.scrollLeft) / zoom,
289033
+ y: (lineRect.top - viewportRect.top + visibleHost.scrollTop) / zoom,
289034
+ height: lineRect.height / zoom
289035
+ };
289036
+ }
289037
+ return null;
289038
+ }
288290
289039
  function findLineContainingPos(block, measure, fromLine, toLine, pos) {
288291
289040
  if (measure.kind !== "paragraph" || block.kind !== "paragraph")
288292
289041
  return null;
@@ -288343,6 +289092,12 @@ function computeCaretLayoutRectGeometry({ layout, blocks: blocks2, measures, pai
288343
289092
  visibleHost,
288344
289093
  zoom
288345
289094
  }, effectivePos, hit.fragment, block, measure, hit.pageIndex);
289095
+ if (hit.fragment.kind === "drawing" && block?.kind === "drawing" && block.drawingKind === "textboxShape" && measure?.kind === "drawing")
289096
+ return computeTextboxCaretLayoutRectFromDom({
289097
+ viewportHost,
289098
+ visibleHost,
289099
+ zoom
289100
+ }, effectivePos, hit.fragment, block, hit.pageIndex);
288346
289101
  if (!block || block.kind !== "paragraph" || measure?.kind !== "paragraph")
288347
289102
  return null;
288348
289103
  if (hit.fragment.kind !== "para")
@@ -292964,7 +293719,7 @@ async function layoutBlocksByRId(kind, blocksByRId, referencedRIds, constraints,
292964
293719
  if (!blocks2 || blocks2.length === 0)
292965
293720
  continue;
292966
293721
  try {
292967
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
293722
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, constraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent));
292968
293723
  if (batchResult.default)
292969
293724
  layoutsByRId.set(rId, {
292970
293725
  kind,
@@ -293024,7 +293779,7 @@ async function layoutWithPerSectionConstraints(kind, blocksByRId, sectionMetadat
293024
293779
  if (!blocks2 || blocks2.length === 0)
293025
293780
  continue;
293026
293781
  try {
293027
- const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature);
293782
+ const batchResult = await layoutHeaderFooterWithCache({ default: blocks2 }, group.sectionConstraints, (block, c) => measureBlock(block, c, fontMeasureContext), undefined, undefined, pageResolver, kind, fontSignature, (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent));
293028
293783
  if (batchResult.default)
293029
293784
  for (const sectionIndex of group.sectionIndices) {
293030
293785
  const contentWidth = buildSectionContentWidth(sectionMetadata.find((s2) => s2.sectionIndex === sectionIndex), fallbackConstraints);
@@ -317016,6 +317771,7 @@ menclose::after {
317016
317771
  drawingWrapper.style.flexShrink = "0";
317017
317772
  drawingWrapper.style.maxWidth = "100%";
317018
317773
  drawingWrapper.style.boxSizing = "border-box";
317774
+ drawingWrapper.dataset.blockId = block.id;
317019
317775
  applySdtDataset$1(drawingWrapper, block.attrs);
317020
317776
  const drawingInner = doc$12.createElement("div");
317021
317777
  drawingInner.classList.add("superdoc-table-drawing");
@@ -317185,6 +317941,7 @@ menclose::after {
317185
317941
  drawingWrapper.style.maxWidth = "100%";
317186
317942
  drawingWrapper.style.boxSizing = "border-box";
317187
317943
  drawingWrapper.style.zIndex = String(zIndex);
317944
+ drawingWrapper.dataset.blockId = anchoredBlock.id;
317188
317945
  applySdtDataset$1(drawingWrapper, anchoredBlock.attrs);
317189
317946
  const drawingInner = doc$12.createElement("div");
317190
317947
  drawingInner.classList.add("superdoc-table-drawing");
@@ -321224,17 +321981,19 @@ menclose::after {
321224
321981
  throw new Error("DomPainter: document is not available");
321225
321982
  if (block.drawingKind === "image")
321226
321983
  return createDrawingImageElement(this.doc, block, this.buildImageHyperlinkAnchor.bind(this));
321227
- if (block.drawingKind === "vectorShape")
321228
- return this.createVectorShapeElement(block, fragment2.geometry, false, 1, 1, context);
321984
+ if (block.drawingKind === "vectorShape" || block.drawingKind === "textboxShape")
321985
+ return this.createVectorShapeElement(block, fragment2.geometry, false, 1, 1, context, fragment2);
321229
321986
  if (block.drawingKind === "shapeGroup")
321230
321987
  return this.createShapeGroupElement(block, context);
321231
321988
  if (block.drawingKind === "chart")
321232
321989
  return this.createChartElement(block);
321233
321990
  return this.createDrawingPlaceholder();
321234
321991
  }
321235
- createVectorShapeElement(block, geometry, applyTransforms = false, groupScaleX = 1, groupScaleY = 1, context) {
321992
+ createVectorShapeElement(block, geometry, applyTransforms = false, groupScaleX = 1, groupScaleY = 1, context, fragment2) {
321236
321993
  const container = this.doc.createElement("div");
321237
321994
  container.classList.add("superdoc-vector-shape");
321995
+ if (block.drawingKind === "textboxShape")
321996
+ container.classList.add("superdoc-textbox-shape");
321238
321997
  container.style.width = "100%";
321239
321998
  container.style.height = "100%";
321240
321999
  container.style.position = "relative";
@@ -321265,8 +322024,8 @@ menclose::after {
321265
322024
  }
321266
322025
  this.applyLineEnds(svgElement, block);
321267
322026
  contentContainer.appendChild(svgElement);
321268
- if (this.hasShapeTextContent(block.textContent)) {
321269
- const textElement = this.createShapeTextElement(block, innerWidth, innerHeight2, groupScaleX, groupScaleY, context);
322027
+ if (block.drawingKind === "textboxShape" || this.hasShapeTextContent(block.textContent)) {
322028
+ const textElement = block.drawingKind === "textboxShape" ? this.createTextboxContentElement(block, fragment2, innerWidth, innerHeight2, context) : this.createShapeTextElement(block, innerWidth, innerHeight2, groupScaleX, groupScaleY, context);
321270
322029
  contentContainer.appendChild(textElement);
321271
322030
  }
321272
322031
  container.appendChild(contentContainer);
@@ -321274,8 +322033,8 @@ menclose::after {
321274
322033
  }
321275
322034
  }
321276
322035
  this.applyFallbackShapeStyle(contentContainer, block);
321277
- if (this.hasShapeTextContent(block.textContent)) {
321278
- const textElement = this.createShapeTextElement(block, innerWidth, innerHeight2, groupScaleX, groupScaleY, context);
322036
+ if (block.drawingKind === "textboxShape" || this.hasShapeTextContent(block.textContent)) {
322037
+ const textElement = block.drawingKind === "textboxShape" ? this.createTextboxContentElement(block, fragment2, innerWidth, innerHeight2, context) : this.createShapeTextElement(block, innerWidth, innerHeight2, groupScaleX, groupScaleY, context);
321279
322038
  contentContainer.appendChild(textElement);
321280
322039
  }
321281
322040
  container.appendChild(contentContainer);
@@ -321315,6 +322074,47 @@ menclose::after {
321315
322074
  return this.createWordArtTextElement(textContent$1, block.textAlign ?? "center", block.textInsets, width, height, context);
321316
322075
  return this.createFallbackTextElement(textContent$1, block.textAlign ?? "center", block.textVerticalAlign, block.textInsets, groupScaleX, groupScaleY, context);
321317
322076
  }
322077
+ createTextboxContentElement(block, fragment2, width, height, context) {
322078
+ const contentMeasures = fragment2?.contentMeasures ?? block.contentMeasures;
322079
+ if (!Array.isArray(contentMeasures) || contentMeasures.length === 0)
322080
+ return this.hasShapeTextContent(block.textContent) ? this.createShapeTextElement(block, width, height, 1, 1, context) : this.doc.createElement("div");
322081
+ const contentRoot = this.doc.createElement("div");
322082
+ contentRoot.style.position = "absolute";
322083
+ contentRoot.style.top = "0";
322084
+ contentRoot.style.left = "0";
322085
+ contentRoot.style.width = "100%";
322086
+ contentRoot.style.height = "100%";
322087
+ contentRoot.style.display = "flex";
322088
+ contentRoot.style.flexDirection = "column";
322089
+ contentRoot.style.boxSizing = "border-box";
322090
+ contentRoot.style.overflow = "hidden";
322091
+ const insets = block.textInsets ?? {
322092
+ top: 0,
322093
+ right: 0,
322094
+ bottom: 0,
322095
+ left: 0
322096
+ };
322097
+ contentRoot.style.padding = `${insets.top}px ${insets.right}px ${insets.bottom}px ${insets.left}px`;
322098
+ const verticalAlign = block.textVerticalAlign ?? "top";
322099
+ contentRoot.style.justifyContent = verticalAlign === "bottom" ? "flex-end" : verticalAlign === "center" ? "center" : "flex-start";
322100
+ const linesHost = this.doc.createElement("div");
322101
+ linesHost.style.display = "flex";
322102
+ linesHost.style.flexDirection = "column";
322103
+ linesHost.style.minWidth = "0";
322104
+ linesHost.style.width = "100%";
322105
+ const renderContext = context ?? this.defaultFragmentRenderContext();
322106
+ const availableWidth = Math.max(1, width - insets.left - insets.right);
322107
+ block.contentBlocks.forEach((paragraphBlock, paragraphIndex) => {
322108
+ const measure = contentMeasures[paragraphIndex];
322109
+ if (!measure?.lines)
322110
+ return;
322111
+ measure.lines.forEach((line, lineIndex) => {
322112
+ linesHost.appendChild(this.renderLine(paragraphBlock, line, renderContext, availableWidth, lineIndex));
322113
+ });
322114
+ });
322115
+ contentRoot.appendChild(linesHost);
322116
+ return contentRoot;
322117
+ }
321318
322118
  shouldUseWordArtTextRenderer(block) {
321319
322119
  return block.attrs?.isWordArt === true && this.hasShapeTextContent(block.textContent);
321320
322120
  }
@@ -321867,7 +322667,7 @@ menclose::after {
321867
322667
  return createDrawingImageElement(this.doc, block, this.buildImageHyperlinkAnchor.bind(this));
321868
322668
  if (block.drawingKind === "shapeGroup")
321869
322669
  return this.createShapeGroupElement(block, context);
321870
- if (block.drawingKind === "vectorShape")
322670
+ if (block.drawingKind === "vectorShape" || block.drawingKind === "textboxShape")
321871
322671
  return this.createVectorShapeElement(block, block.geometry, false, 1, 1, context);
321872
322672
  if (block.drawingKind === "chart")
321873
322673
  return this.createChartElement(block);
@@ -321952,6 +322752,13 @@ menclose::after {
321952
322752
  };
321953
322753
  return runContext;
321954
322754
  }
322755
+ defaultFragmentRenderContext() {
322756
+ return {
322757
+ pageNumber: 1,
322758
+ totalPages: 1,
322759
+ section: "body"
322760
+ };
322761
+ }
321955
322762
  updateFragmentElement(el, fragment2, section, resolvedItem) {
321956
322763
  const fragmentItem = resolvedItem?.kind === "fragment" ? resolvedItem : undefined;
321957
322764
  const story = resolveSectionStory(section);
@@ -322448,6 +323255,15 @@ menclose::after {
322448
323255
  if (!lum)
322449
323256
  return "";
322450
323257
  return [lum.bright ?? "", lum.contrast ?? ""].join(":");
323258
+ }, drawingTextVersion = (block) => {
323259
+ const textboxContentBlocks = "contentBlocks" in block && Array.isArray(block.contentBlocks) ? block.contentBlocks.map((contentBlock) => deriveBlockVersion(contentBlock)).join(";") : "";
323260
+ return JSON.stringify([
323261
+ block.textAlign ?? "",
323262
+ block.textVerticalAlign ?? "",
323263
+ block.textInsets ?? null,
323264
+ block.textContent ?? null,
323265
+ textboxContentBlocks
323266
+ ]);
322451
323267
  }, renderedBlockImageVersion = (image2) => [
322452
323268
  image2.src ?? "",
322453
323269
  image2.width ?? "",
@@ -322655,10 +323471,10 @@ menclose::after {
322655
323471
  if (block.kind === "drawing") {
322656
323472
  if (block.drawingKind === "image")
322657
323473
  return ["drawing:image", renderedBlockImageVersion(block)].join("|");
322658
- if (block.drawingKind === "vectorShape") {
323474
+ if (block.drawingKind === "vectorShape" || block.drawingKind === "textboxShape") {
322659
323475
  const vector = block;
322660
323476
  return [
322661
- "drawing:vector",
323477
+ block.drawingKind === "textboxShape" ? "drawing:textbox" : "drawing:vector",
322662
323478
  vector.shapeKind ?? "",
322663
323479
  vector.fillColor ?? "",
322664
323480
  vector.strokeColor ?? "",
@@ -322667,7 +323483,8 @@ menclose::after {
322667
323483
  vector.geometry.height,
322668
323484
  vector.geometry.rotation ?? 0,
322669
323485
  vector.geometry.flipH ? 1 : 0,
322670
- vector.geometry.flipV ? 1 : 0
323486
+ vector.geometry.flipV ? 1 : 0,
323487
+ drawingTextVersion(vector)
322671
323488
  ].join("|");
322672
323489
  }
322673
323490
  if (block.drawingKind === "shapeGroup") {
@@ -323363,6 +324180,23 @@ menclose::after {
323363
324180
  block.textVerticalAlign ?? "",
323364
324181
  JSON.stringify(block.textInsets ?? null)
323365
324182
  ].join(":");
324183
+ if (block.drawingKind === "textboxShape")
324184
+ return [
324185
+ "drawing:textbox",
324186
+ hashDrawingGeometry(block.geometry),
324187
+ block.shapeKind ?? "",
324188
+ JSON.stringify(block.fillColor ?? null),
324189
+ JSON.stringify(block.strokeColor ?? null),
324190
+ block.strokeWidth ?? "",
324191
+ JSON.stringify(block.customGeometry ?? null),
324192
+ JSON.stringify(block.lineEnds ?? null),
324193
+ JSON.stringify(block.effectExtent ?? null),
324194
+ JSON.stringify(block.textContent ?? null),
324195
+ block.textAlign ?? "",
324196
+ block.textVerticalAlign ?? "",
324197
+ JSON.stringify(block.textInsets ?? null),
324198
+ block.contentBlocks.map((contentBlock) => `${contentBlock.id}:${hashRuns(contentBlock)}`).join("|")
324199
+ ].join(":");
323366
324200
  if (block.drawingKind === "shapeGroup")
323367
324201
  return [
323368
324202
  "drawing:shapeGroup",
@@ -324397,8 +325231,10 @@ menclose::after {
324397
325231
  return false;
324398
325232
  if (a2.drawingKind === "image" && b$1.drawingKind === "image")
324399
325233
  return imageBlocksEqual(a2, b$1);
324400
- if (a2.drawingKind === "vectorShape" && b$1.drawingKind === "vectorShape")
324401
- return drawingGeometryEqual(a2.geometry, b$1.geometry) && a2.shapeKind === b$1.shapeKind && a2.fillColor === b$1.fillColor && a2.strokeColor === b$1.strokeColor && a2.strokeWidth === b$1.strokeWidth;
325234
+ if ((a2.drawingKind === "vectorShape" || a2.drawingKind === "textboxShape") && (b$1.drawingKind === "vectorShape" || b$1.drawingKind === "textboxShape")) {
325235
+ const textboxContentEqual = a2.drawingKind !== "textboxShape" || b$1.drawingKind !== "textboxShape" || jsonEqual(a2.contentBlocks, b$1.contentBlocks);
325236
+ return drawingGeometryEqual(a2.geometry, b$1.geometry) && a2.shapeKind === b$1.shapeKind && a2.fillColor === b$1.fillColor && a2.strokeColor === b$1.strokeColor && a2.strokeWidth === b$1.strokeWidth && a2.textAlign === b$1.textAlign && a2.textVerticalAlign === b$1.textVerticalAlign && jsonEqual(a2.textInsets, b$1.textInsets) && jsonEqual(a2.textContent, b$1.textContent) && jsonEqual(a2.customGeometry, b$1.customGeometry) && jsonEqual(a2.lineEnds, b$1.lineEnds) && jsonEqual(a2.effectExtent, b$1.effectExtent) && textboxContentEqual;
325237
+ }
324402
325238
  if (a2.drawingKind === "shapeGroup" && b$1.drawingKind === "shapeGroup")
324403
325239
  return drawingGeometryEqual(a2.geometry, b$1.geometry) && shapeGroupTransformEqual(a2.groupTransform, b$1.groupTransform) && shapeGroupSizeEqual(a2.size, b$1.size) && shapeGroupChildrenEqual(a2.shapes, b$1.shapes);
324404
325240
  if (a2.drawingKind === "chart" && b$1.drawingKind === "chart")
@@ -325222,222 +326058,7 @@ menclose::after {
325222
326058
  });
325223
326059
  });
325224
326060
  return results;
325225
- }, PRELAYOUT_CHAPTER_MARKER_SEPARATOR_RE, PRELAYOUT_MIN_PAGE_COMPONENT = 10, PageGeometryHelper = class {
325226
- constructor(config2) {
325227
- this.cache = null;
325228
- this.config = config2;
325229
- }
325230
- updateLayout(layout, pageGap) {
325231
- this.config.layout = layout;
325232
- if (pageGap !== undefined)
325233
- this.config.pageGap = pageGap;
325234
- this.cache = null;
325235
- }
325236
- updatePageGap(pageGap) {
325237
- if (this.config.pageGap !== pageGap) {
325238
- this.config.pageGap = pageGap;
325239
- this.cache = null;
325240
- }
325241
- }
325242
- getPageTop(pageIndex) {
325243
- this.ensureCache();
325244
- if (pageIndex < 0 || pageIndex >= this.cache.cumulativeY.length)
325245
- return 0;
325246
- return this.cache.cumulativeY[pageIndex];
325247
- }
325248
- getPageHeight(pageIndex) {
325249
- this.ensureCache();
325250
- if (pageIndex < 0 || pageIndex >= this.cache.pageHeights.length)
325251
- return 0;
325252
- return this.cache.pageHeights[pageIndex];
325253
- }
325254
- getPageGap() {
325255
- this.ensureCache();
325256
- return this.cache.pageGap;
325257
- }
325258
- getTotalHeight() {
325259
- this.ensureCache();
325260
- return this.cache.totalHeight;
325261
- }
325262
- getPageCount() {
325263
- return this.config.layout.pages.length;
325264
- }
325265
- getPageIndexAtY(containerY) {
325266
- this.ensureCache();
325267
- const cache$2 = this.cache;
325268
- for (let i4 = 0;i4 < cache$2.cumulativeY.length; i4++) {
325269
- const pageTop = cache$2.cumulativeY[i4];
325270
- const pageBottom = pageTop + cache$2.pageHeights[i4];
325271
- if (containerY >= pageTop && containerY < pageBottom)
325272
- return i4;
325273
- }
325274
- return null;
325275
- }
325276
- getNearestPageIndex(containerY) {
325277
- this.ensureCache();
325278
- const cache$2 = this.cache;
325279
- const pageCount = cache$2.pageHeights.length;
325280
- if (pageCount === 0)
325281
- return null;
325282
- const direct = this.getPageIndexAtY(containerY);
325283
- if (direct !== null)
325284
- return direct;
325285
- let nearestIndex = 0;
325286
- let nearestDistance = Infinity;
325287
- for (let i4 = 0;i4 < pageCount; i4++) {
325288
- const center = cache$2.cumulativeY[i4] + cache$2.pageHeights[i4] / 2;
325289
- const distance2 = Math.abs(containerY - center);
325290
- if (distance2 < nearestDistance) {
325291
- nearestDistance = distance2;
325292
- nearestIndex = i4;
325293
- }
325294
- }
325295
- return nearestIndex;
325296
- }
325297
- ensureCache() {
325298
- if (this.cache !== null)
325299
- if (!Array.isArray(this.cache.cumulativeY) || !Array.isArray(this.cache.pageHeights)) {
325300
- console.warn("[PageGeometryHelper] Cache corruption detected, rebuilding cache");
325301
- this.cache = null;
325302
- } else
325303
- return;
325304
- this.buildCache();
325305
- }
325306
- buildCache() {
325307
- try {
325308
- const layout = this.config.layout;
325309
- if (!layout || !Array.isArray(layout.pages))
325310
- throw new Error("Invalid layout: missing or invalid pages array");
325311
- const pageGap = this.config.pageGap ?? layout.pageGap ?? 0;
325312
- const pageCount = layout.pages.length;
325313
- if (!Number.isFinite(pageGap) || pageGap < 0)
325314
- throw new Error(`Invalid pageGap: ${pageGap} (must be non-negative finite number)`);
325315
- const cumulativeY = new Array(pageCount);
325316
- const pageHeights = new Array(pageCount);
325317
- let currentY = 0;
325318
- for (let i4 = 0;i4 < pageCount; i4++) {
325319
- const page = layout.pages[i4];
325320
- if (!page)
325321
- throw new Error(`Invalid page at index ${i4}: page is null or undefined`);
325322
- const pageHeight = page.size?.h ?? layout.pageSize.h;
325323
- if (!Number.isFinite(pageHeight) || pageHeight < 0)
325324
- throw new Error(`Invalid page height at index ${i4}: ${pageHeight} (must be non-negative finite number)`);
325325
- cumulativeY[i4] = currentY;
325326
- pageHeights[i4] = pageHeight;
325327
- currentY += pageHeight;
325328
- if (i4 < pageCount - 1)
325329
- currentY += pageGap;
325330
- }
325331
- this.cache = {
325332
- cumulativeY,
325333
- pageHeights,
325334
- pageGap,
325335
- totalHeight: currentY,
325336
- layoutVersion: 0
325337
- };
325338
- } catch (error3) {
325339
- const errorMessage = error3 instanceof Error ? error3.message : String(error3);
325340
- console.error(`[PageGeometryHelper] Cache build failed: ${errorMessage}. Using fallback empty cache.`);
325341
- this.cache = {
325342
- cumulativeY: [],
325343
- pageHeights: [],
325344
- pageGap: 0,
325345
- totalHeight: 0,
325346
- layoutVersion: 0
325347
- };
325348
- }
325349
- }
325350
- clearCache() {
325351
- this.cache = null;
325352
- }
325353
- getDebugInfo() {
325354
- this.ensureCache();
325355
- return {
325356
- isCached: this.cache !== null,
325357
- pageCount: this.config.layout.pages.length,
325358
- pageGap: this.cache.pageGap,
325359
- totalHeight: this.cache.totalHeight,
325360
- cumulativeY: [...this.cache.cumulativeY],
325361
- pageHeights: [...this.cache.pageHeights]
325362
- };
325363
- }
325364
- }, PerformanceMetricsCollector = class {
325365
- constructor(budgets, maxSamples = 1000) {
325366
- this.maxSamples = maxSamples;
325367
- this.budgets = budgets || {};
325368
- this.metrics = {
325369
- cursorUpdateLatency: [],
325370
- p0LayoutDuration: [],
325371
- p1LayoutDuration: [],
325372
- workerRoundTrip: [],
325373
- layoutStaleness: [],
325374
- geometryFallbackRate: [],
325375
- cacheMissRate: [],
325376
- droppedEvents: []
325377
- };
325378
- }
325379
- record(metric, value, context) {
325380
- const sample = {
325381
- timestamp: Date.now(),
325382
- value,
325383
- context
325384
- };
325385
- this.metrics[metric].push(sample);
325386
- if (this.metrics[metric].length > this.maxSamples)
325387
- this.metrics[metric].shift();
325388
- }
325389
- startTimer(metric) {
325390
- const startTime = performance.now();
325391
- return () => {
325392
- const duration = performance.now() - startTime;
325393
- this.record(metric, duration);
325394
- };
325395
- }
325396
- getSummary(metric) {
325397
- return calculateSummary(this.metrics[metric]);
325398
- }
325399
- getAllSummaries() {
325400
- return {
325401
- cursorUpdateLatency: this.getSummary("cursorUpdateLatency"),
325402
- p0LayoutDuration: this.getSummary("p0LayoutDuration"),
325403
- p1LayoutDuration: this.getSummary("p1LayoutDuration"),
325404
- workerRoundTrip: this.getSummary("workerRoundTrip"),
325405
- layoutStaleness: this.getSummary("layoutStaleness"),
325406
- geometryFallbackRate: this.getSummary("geometryFallbackRate"),
325407
- cacheMissRate: this.getSummary("cacheMissRate"),
325408
- droppedEvents: this.getSummary("droppedEvents")
325409
- };
325410
- }
325411
- checkBudgets() {
325412
- const violations = [];
325413
- for (const [metric, budget] of Object.entries(this.budgets)) {
325414
- const summary = this.getSummary(metric);
325415
- if (summary.count > 0 && summary.p95 > budget)
325416
- violations.push({
325417
- metric,
325418
- value: summary.p95,
325419
- budget
325420
- });
325421
- }
325422
- return violations;
325423
- }
325424
- export() {
325425
- return {
325426
- cursorUpdateLatency: [...this.metrics.cursorUpdateLatency],
325427
- p0LayoutDuration: [...this.metrics.p0LayoutDuration],
325428
- p1LayoutDuration: [...this.metrics.p1LayoutDuration],
325429
- workerRoundTrip: [...this.metrics.workerRoundTrip],
325430
- layoutStaleness: [...this.metrics.layoutStaleness],
325431
- geometryFallbackRate: [...this.metrics.geometryFallbackRate],
325432
- cacheMissRate: [...this.metrics.cacheMissRate],
325433
- droppedEvents: [...this.metrics.droppedEvents]
325434
- };
325435
- }
325436
- clear() {
325437
- for (const metric of Object.keys(this.metrics))
325438
- this.metrics[metric] = [];
325439
- }
325440
- }, isAtomicFragment = (fragment2) => {
326061
+ }, PRELAYOUT_CHAPTER_MARKER_SEPARATOR_RE, PRELAYOUT_MIN_PAGE_COMPONENT = 10, isAtomicFragment = (fragment2) => {
325441
326062
  return fragment2.kind === "drawing" || fragment2.kind === "image";
325442
326063
  }, blockPmRangeFromAttrs = (block) => {
325443
326064
  const attrs = block?.attrs;
@@ -325685,6 +326306,295 @@ menclose::after {
325685
326306
  };
325686
326307
  }
325687
326308
  return null;
326309
+ }, resolveTextboxContentHit = (fragment2, block, measure, pageIndex, point5) => {
326310
+ const fragmentWithContent = fragment2;
326311
+ const contentMeasures = Array.isArray(fragmentWithContent.contentMeasures) ? fragmentWithContent.contentMeasures : Array.isArray(block.contentMeasures) ? block.contentMeasures : [];
326312
+ const contentBlocks = Array.isArray(block.contentBlocks) ? block.contentBlocks : [];
326313
+ if (contentMeasures.length === 0 || contentBlocks.length === 0)
326314
+ return null;
326315
+ const insets = block.textInsets ?? {
326316
+ top: 0,
326317
+ right: 0,
326318
+ bottom: 0,
326319
+ left: 0
326320
+ };
326321
+ const localX = Math.max(0, point5.x - fragment2.x - insets.left);
326322
+ const rawLocalY = point5.y - fragment2.y - insets.top;
326323
+ const totalContentHeight = contentMeasures.reduce((sum, m$1) => sum + (m$1?.kind === "paragraph" ? m$1.totalHeight ?? 0 : 0), 0);
326324
+ const availableHeight = Math.max(0, fragment2.height - insets.top - insets.bottom);
326325
+ const verticalAlign = block.textVerticalAlign ?? "top";
326326
+ let contentOffset = 0;
326327
+ if (verticalAlign === "center")
326328
+ contentOffset = Math.max(0, (availableHeight - totalContentHeight) / 2);
326329
+ else if (verticalAlign === "bottom")
326330
+ contentOffset = Math.max(0, availableHeight - totalContentHeight);
326331
+ const localY = rawLocalY - contentOffset;
326332
+ let paragraphStartY = 0;
326333
+ let blockStartGlobal = 0;
326334
+ let nearestParagraphHit = null;
326335
+ for (let i4 = 0;i4 < contentBlocks.length && i4 < contentMeasures.length; i4 += 1) {
326336
+ const contentBlock = contentBlocks[i4];
326337
+ const contentMeasure = contentMeasures[i4];
326338
+ if (contentBlock?.kind !== "paragraph" || contentMeasure?.kind !== "paragraph")
326339
+ continue;
326340
+ const paragraphHeight = contentMeasure.totalHeight;
326341
+ const paragraphEndY = paragraphStartY + paragraphHeight;
326342
+ if (localY >= paragraphStartY && localY < paragraphEndY)
326343
+ return {
326344
+ fragment: fragment2,
326345
+ block,
326346
+ measure,
326347
+ pageIndex,
326348
+ contentBlock,
326349
+ contentMeasure,
326350
+ paragraphIndex: i4,
326351
+ localX,
326352
+ localY: Math.max(0, Math.min(localY - paragraphStartY, Math.max(paragraphHeight, 0))),
326353
+ blockStartGlobal
326354
+ };
326355
+ const distanceToParagraph = localY < paragraphStartY ? paragraphStartY - localY : Math.max(0, localY - paragraphEndY);
326356
+ if (!nearestParagraphHit || distanceToParagraph < nearestParagraphHit.distance)
326357
+ nearestParagraphHit = {
326358
+ contentBlock,
326359
+ contentMeasure,
326360
+ paragraphIndex: i4,
326361
+ localX,
326362
+ localY: Math.max(0, Math.min(localY - paragraphStartY, Math.max(paragraphHeight, 0))),
326363
+ blockStartGlobal,
326364
+ distance: distanceToParagraph
326365
+ };
326366
+ paragraphStartY = paragraphEndY;
326367
+ blockStartGlobal += contentMeasure.lines.length;
326368
+ }
326369
+ if (nearestParagraphHit)
326370
+ return {
326371
+ fragment: fragment2,
326372
+ block,
326373
+ measure,
326374
+ pageIndex,
326375
+ contentBlock: nearestParagraphHit.contentBlock,
326376
+ contentMeasure: nearestParagraphHit.contentMeasure,
326377
+ paragraphIndex: nearestParagraphHit.paragraphIndex,
326378
+ localX: nearestParagraphHit.localX,
326379
+ localY: nearestParagraphHit.localY,
326380
+ blockStartGlobal: nearestParagraphHit.blockStartGlobal
326381
+ };
326382
+ return null;
326383
+ }, PageGeometryHelper = class {
326384
+ constructor(config2) {
326385
+ this.cache = null;
326386
+ this.config = config2;
326387
+ }
326388
+ updateLayout(layout, pageGap) {
326389
+ this.config.layout = layout;
326390
+ if (pageGap !== undefined)
326391
+ this.config.pageGap = pageGap;
326392
+ this.cache = null;
326393
+ }
326394
+ updatePageGap(pageGap) {
326395
+ if (this.config.pageGap !== pageGap) {
326396
+ this.config.pageGap = pageGap;
326397
+ this.cache = null;
326398
+ }
326399
+ }
326400
+ getPageTop(pageIndex) {
326401
+ this.ensureCache();
326402
+ if (pageIndex < 0 || pageIndex >= this.cache.cumulativeY.length)
326403
+ return 0;
326404
+ return this.cache.cumulativeY[pageIndex];
326405
+ }
326406
+ getPageHeight(pageIndex) {
326407
+ this.ensureCache();
326408
+ if (pageIndex < 0 || pageIndex >= this.cache.pageHeights.length)
326409
+ return 0;
326410
+ return this.cache.pageHeights[pageIndex];
326411
+ }
326412
+ getPageGap() {
326413
+ this.ensureCache();
326414
+ return this.cache.pageGap;
326415
+ }
326416
+ getTotalHeight() {
326417
+ this.ensureCache();
326418
+ return this.cache.totalHeight;
326419
+ }
326420
+ getPageCount() {
326421
+ return this.config.layout.pages.length;
326422
+ }
326423
+ getPageIndexAtY(containerY) {
326424
+ this.ensureCache();
326425
+ const cache$2 = this.cache;
326426
+ for (let i4 = 0;i4 < cache$2.cumulativeY.length; i4++) {
326427
+ const pageTop = cache$2.cumulativeY[i4];
326428
+ const pageBottom = pageTop + cache$2.pageHeights[i4];
326429
+ if (containerY >= pageTop && containerY < pageBottom)
326430
+ return i4;
326431
+ }
326432
+ return null;
326433
+ }
326434
+ getNearestPageIndex(containerY) {
326435
+ this.ensureCache();
326436
+ const cache$2 = this.cache;
326437
+ const pageCount = cache$2.pageHeights.length;
326438
+ if (pageCount === 0)
326439
+ return null;
326440
+ const direct = this.getPageIndexAtY(containerY);
326441
+ if (direct !== null)
326442
+ return direct;
326443
+ let nearestIndex = 0;
326444
+ let nearestDistance = Infinity;
326445
+ for (let i4 = 0;i4 < pageCount; i4++) {
326446
+ const center = cache$2.cumulativeY[i4] + cache$2.pageHeights[i4] / 2;
326447
+ const distance2 = Math.abs(containerY - center);
326448
+ if (distance2 < nearestDistance) {
326449
+ nearestDistance = distance2;
326450
+ nearestIndex = i4;
326451
+ }
326452
+ }
326453
+ return nearestIndex;
326454
+ }
326455
+ ensureCache() {
326456
+ if (this.cache !== null)
326457
+ if (!Array.isArray(this.cache.cumulativeY) || !Array.isArray(this.cache.pageHeights)) {
326458
+ console.warn("[PageGeometryHelper] Cache corruption detected, rebuilding cache");
326459
+ this.cache = null;
326460
+ } else
326461
+ return;
326462
+ this.buildCache();
326463
+ }
326464
+ buildCache() {
326465
+ try {
326466
+ const layout = this.config.layout;
326467
+ if (!layout || !Array.isArray(layout.pages))
326468
+ throw new Error("Invalid layout: missing or invalid pages array");
326469
+ const pageGap = this.config.pageGap ?? layout.pageGap ?? 0;
326470
+ const pageCount = layout.pages.length;
326471
+ if (!Number.isFinite(pageGap) || pageGap < 0)
326472
+ throw new Error(`Invalid pageGap: ${pageGap} (must be non-negative finite number)`);
326473
+ const cumulativeY = new Array(pageCount);
326474
+ const pageHeights = new Array(pageCount);
326475
+ let currentY = 0;
326476
+ for (let i4 = 0;i4 < pageCount; i4++) {
326477
+ const page = layout.pages[i4];
326478
+ if (!page)
326479
+ throw new Error(`Invalid page at index ${i4}: page is null or undefined`);
326480
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
326481
+ if (!Number.isFinite(pageHeight) || pageHeight < 0)
326482
+ throw new Error(`Invalid page height at index ${i4}: ${pageHeight} (must be non-negative finite number)`);
326483
+ cumulativeY[i4] = currentY;
326484
+ pageHeights[i4] = pageHeight;
326485
+ currentY += pageHeight;
326486
+ if (i4 < pageCount - 1)
326487
+ currentY += pageGap;
326488
+ }
326489
+ this.cache = {
326490
+ cumulativeY,
326491
+ pageHeights,
326492
+ pageGap,
326493
+ totalHeight: currentY,
326494
+ layoutVersion: 0
326495
+ };
326496
+ } catch (error3) {
326497
+ const errorMessage = error3 instanceof Error ? error3.message : String(error3);
326498
+ console.error(`[PageGeometryHelper] Cache build failed: ${errorMessage}. Using fallback empty cache.`);
326499
+ this.cache = {
326500
+ cumulativeY: [],
326501
+ pageHeights: [],
326502
+ pageGap: 0,
326503
+ totalHeight: 0,
326504
+ layoutVersion: 0
326505
+ };
326506
+ }
326507
+ }
326508
+ clearCache() {
326509
+ this.cache = null;
326510
+ }
326511
+ getDebugInfo() {
326512
+ this.ensureCache();
326513
+ return {
326514
+ isCached: this.cache !== null,
326515
+ pageCount: this.config.layout.pages.length,
326516
+ pageGap: this.cache.pageGap,
326517
+ totalHeight: this.cache.totalHeight,
326518
+ cumulativeY: [...this.cache.cumulativeY],
326519
+ pageHeights: [...this.cache.pageHeights]
326520
+ };
326521
+ }
326522
+ }, PerformanceMetricsCollector = class {
326523
+ constructor(budgets, maxSamples = 1000) {
326524
+ this.maxSamples = maxSamples;
326525
+ this.budgets = budgets || {};
326526
+ this.metrics = {
326527
+ cursorUpdateLatency: [],
326528
+ p0LayoutDuration: [],
326529
+ p1LayoutDuration: [],
326530
+ workerRoundTrip: [],
326531
+ layoutStaleness: [],
326532
+ geometryFallbackRate: [],
326533
+ cacheMissRate: [],
326534
+ droppedEvents: []
326535
+ };
326536
+ }
326537
+ record(metric, value, context) {
326538
+ const sample = {
326539
+ timestamp: Date.now(),
326540
+ value,
326541
+ context
326542
+ };
326543
+ this.metrics[metric].push(sample);
326544
+ if (this.metrics[metric].length > this.maxSamples)
326545
+ this.metrics[metric].shift();
326546
+ }
326547
+ startTimer(metric) {
326548
+ const startTime = performance.now();
326549
+ return () => {
326550
+ const duration = performance.now() - startTime;
326551
+ this.record(metric, duration);
326552
+ };
326553
+ }
326554
+ getSummary(metric) {
326555
+ return calculateSummary(this.metrics[metric]);
326556
+ }
326557
+ getAllSummaries() {
326558
+ return {
326559
+ cursorUpdateLatency: this.getSummary("cursorUpdateLatency"),
326560
+ p0LayoutDuration: this.getSummary("p0LayoutDuration"),
326561
+ p1LayoutDuration: this.getSummary("p1LayoutDuration"),
326562
+ workerRoundTrip: this.getSummary("workerRoundTrip"),
326563
+ layoutStaleness: this.getSummary("layoutStaleness"),
326564
+ geometryFallbackRate: this.getSummary("geometryFallbackRate"),
326565
+ cacheMissRate: this.getSummary("cacheMissRate"),
326566
+ droppedEvents: this.getSummary("droppedEvents")
326567
+ };
326568
+ }
326569
+ checkBudgets() {
326570
+ const violations = [];
326571
+ for (const [metric, budget] of Object.entries(this.budgets)) {
326572
+ const summary = this.getSummary(metric);
326573
+ if (summary.count > 0 && summary.p95 > budget)
326574
+ violations.push({
326575
+ metric,
326576
+ value: summary.p95,
326577
+ budget
326578
+ });
326579
+ }
326580
+ return violations;
326581
+ }
326582
+ export() {
326583
+ return {
326584
+ cursorUpdateLatency: [...this.metrics.cursorUpdateLatency],
326585
+ p0LayoutDuration: [...this.metrics.p0LayoutDuration],
326586
+ p1LayoutDuration: [...this.metrics.p1LayoutDuration],
326587
+ workerRoundTrip: [...this.metrics.workerRoundTrip],
326588
+ layoutStaleness: [...this.metrics.layoutStaleness],
326589
+ geometryFallbackRate: [...this.metrics.geometryFallbackRate],
326590
+ cacheMissRate: [...this.metrics.cacheMissRate],
326591
+ droppedEvents: [...this.metrics.droppedEvents]
326592
+ };
326593
+ }
326594
+ clear() {
326595
+ for (const metric of Object.keys(this.metrics))
326596
+ this.metrics[metric] = [];
326597
+ }
325688
326598
  }, logSelectionMapDebug = (payload) => {}, rangesOverlap2 = (startA, endA, startB, endB) => {
325689
326599
  if (startA == null)
325690
326600
  return false;
@@ -327602,10 +328512,15 @@ menclose::after {
327602
328512
  this.#focusEditorAtFirstPosition();
327603
328513
  }
327604
328514
  #handleClickInHeaderFooterMode(event, x, y$1, pageIndex, pageLocalY) {
327605
- const activeSurfaceSelector = this.#deps?.getHeaderFooterSession()?.session?.mode === "footer" ? ".superdoc-page-footer" : ".superdoc-page-header";
328515
+ const session = this.#deps?.getHeaderFooterSession();
328516
+ const activeSurfaceSelector = session?.session?.mode === "footer" ? ".superdoc-page-footer" : ".superdoc-page-header";
327606
328517
  const visiblePointerSurface = resolveVisibleSurfaceAtPointer(event.target, event.clientX, event.clientY);
327607
328518
  const clickedInsideVisibleActiveSurface = visiblePointerSurface?.kind === "headerFooter" && visiblePointerSurface.surface.closest(activeSurfaceSelector) != null;
327608
328519
  if (visiblePointerSurface?.kind === "bodyContent") {
328520
+ const behindDocSection = (event.target instanceof Element ? event.target.closest("[data-behind-doc-section]") : null)?.dataset.behindDocSection;
328521
+ const sessionMode = session?.session?.mode;
328522
+ if (behindDocSection && behindDocSection === sessionMode)
328523
+ return false;
327609
328524
  this.#callbacks.exitHeaderFooterMode?.();
327610
328525
  return false;
327611
328526
  }
@@ -327701,6 +328616,8 @@ menclose::after {
327701
328616
  return false;
327702
328617
  if (fragmentHit.fragment.kind !== "image" && fragmentHit.fragment.kind !== "drawing")
327703
328618
  return false;
328619
+ if (fragmentHit.fragment.kind === "drawing" && fragmentHit.fragment.drawingKind === "textboxShape")
328620
+ return false;
327704
328621
  const editor = this.#deps?.getEditor();
327705
328622
  try {
327706
328623
  const tr = editor.state.tr.setSelection(NodeSelection.create(doc$12, hit.pos));
@@ -330554,7 +331471,8 @@ menclose::after {
330554
331471
  const surfaceElement = pageElement.querySelector(surfaceSelector);
330555
331472
  if (!surfaceElement)
330556
331473
  return null;
330557
- const entry = findSurfaceEntryAtPos(buildSurfacePmEntries(surfaceElement), pos);
331474
+ const behindDocFragments = Array.from(pageElement.querySelectorAll(`[data-behind-doc-section="${this.#session.mode}"]`));
331475
+ const entry = findSurfaceEntryAtPos([...buildSurfacePmEntries(surfaceElement), ...behindDocFragments.flatMap((frag) => buildSurfacePmEntries(frag))].sort((a2, b$1) => a2.pmStart - b$1.pmStart || a2.pmEnd - b$1.pmEnd), pos);
330558
331476
  if (!entry)
330559
331477
  return null;
330560
331478
  const pageRect = pageElement.getBoundingClientRect();
@@ -331718,13 +332636,13 @@ menclose::after {
331718
332636
  return;
331719
332637
  console.log(...args$1);
331720
332638
  }, HEADER_FOOTER_INIT_BUDGET_MS = 200, MAX_ZOOM_WARNING_THRESHOLD = 10, MAX_SELECTION_RECTS_PER_USER = 100, SEMANTIC_RESIZE_DEBOUNCE_MS = 120, MIN_SEMANTIC_CONTENT_WIDTH_PX = 1, GLOBAL_PERFORMANCE, PresentationEditor, ICONS, TEXTS, tableActionsOptions, TRACKED_MARK_NAMES;
331721
- var init_src_CRJcfbIa_es = __esm(() => {
332639
+ var init_src_BBtIMpLJ_es = __esm(() => {
331722
332640
  init_rolldown_runtime_Bg48TavK_es();
331723
- init_SuperConverter_BTGVElJO_es();
332641
+ init_SuperConverter_CUxtXQFf_es();
331724
332642
  init_jszip_C49i9kUs_es();
331725
332643
  init_xml_js_CqGKpaft_es();
331726
332644
  init_uuid_B2wVPhPi_es();
331727
- init_create_headless_toolbar_DYbkX05s_es();
332645
+ init_create_headless_toolbar_DutCjfp2_es();
331728
332646
  init_constants_D9qj59G2_es();
331729
332647
  init_dist_B8HfvhaK_es();
331730
332648
  init_unified_Dsuw2be5_es();
@@ -338975,7 +339893,89 @@ ${err.toString()}`);
338975
339893
  return { style: attrs.style };
338976
339894
  } },
338977
339895
  wrapAttributes: { rendered: false },
338978
- attributes: { rendered: false }
339896
+ anchorData: { rendered: false },
339897
+ marginOffset: { rendered: false },
339898
+ attributes: { rendered: false },
339899
+ kind: {
339900
+ default: null,
339901
+ rendered: false
339902
+ },
339903
+ width: {
339904
+ default: null,
339905
+ renderDOM: (attrs) => {
339906
+ if (attrs.width == null)
339907
+ return {};
339908
+ return { "data-width": attrs.width };
339909
+ }
339910
+ },
339911
+ height: {
339912
+ default: null,
339913
+ renderDOM: (attrs) => {
339914
+ if (attrs.height == null)
339915
+ return {};
339916
+ return { "data-height": attrs.height };
339917
+ }
339918
+ },
339919
+ fillColor: {
339920
+ default: null,
339921
+ rendered: false
339922
+ },
339923
+ strokeColor: {
339924
+ default: null,
339925
+ rendered: false
339926
+ },
339927
+ strokeWidth: {
339928
+ default: null,
339929
+ rendered: false
339930
+ },
339931
+ rotation: {
339932
+ default: 0,
339933
+ rendered: false
339934
+ },
339935
+ flipH: {
339936
+ default: false,
339937
+ rendered: false
339938
+ },
339939
+ flipV: {
339940
+ default: false,
339941
+ rendered: false
339942
+ },
339943
+ wrap: {
339944
+ default: null,
339945
+ rendered: false
339946
+ },
339947
+ isAnchor: {
339948
+ default: false,
339949
+ rendered: false
339950
+ },
339951
+ drawingContent: {
339952
+ default: null,
339953
+ rendered: false
339954
+ },
339955
+ originalAttributes: {
339956
+ default: null,
339957
+ rendered: false
339958
+ },
339959
+ effectExtent: {
339960
+ default: null,
339961
+ rendered: false
339962
+ },
339963
+ lineEnds: {
339964
+ default: null,
339965
+ rendered: false
339966
+ },
339967
+ hidden: {
339968
+ default: false,
339969
+ rendered: false
339970
+ },
339971
+ isTextBox: {
339972
+ default: false,
339973
+ rendered: false
339974
+ },
339975
+ isWordArt: {
339976
+ default: false,
339977
+ rendered: false
339978
+ }
338979
339979
  };
338980
339980
  },
338981
339981
  parseDOM() {
@@ -339010,7 +340010,15 @@ ${err.toString()}`);
339010
340010
  return attrs.sdBlockId ? { "data-sd-block-id": attrs.sdBlockId } : {};
339011
340011
  }
339012
340012
  },
339013
- attributes: { rendered: false }
340013
+ attributes: { rendered: false },
340014
+ textInsets: {
340015
+ default: null,
340016
+ rendered: false
340017
+ },
340018
+ textVerticalAlign: {
340019
+ default: null,
340020
+ rendered: false
340021
+ }
339014
340022
  };
339015
340023
  },
339016
340024
  parseDOM() {
@@ -362417,14 +363425,21 @@ function print() { __p += __j.call(arguments, '') }
362417
363425
  return null;
362418
363426
  const localX = normalized.x - context.region.localX;
362419
363427
  const localY = (normalized.pageLocalY ?? normalized.y - context.region.pageIndex * (bodyPageHeight + pageGap)) - context.region.localY;
363428
+ const domHit = this.#resolveHeaderFooterDomHit(context, clientX, clientY);
363429
+ if (domHit) {
363430
+ const doc$3 = this.getActiveEditor().state?.doc;
363431
+ return {
363432
+ ...domHit,
363433
+ pos: doc$3 ? Math.max(0, Math.min(domHit.pos, doc$3.content.size)) : domHit.pos
363434
+ };
363435
+ }
362420
363436
  if (localX < 0 || localY < 0 || localX > context.region.width || localY > context.region.height)
362421
363437
  return null;
362422
363438
  const headerPoint = {
362423
363439
  x: localX,
362424
363440
  y: localY
362425
363441
  };
362426
- const geometryHit = clickToPositionGeometry(context.layout, context.blocks, context.measures, headerPoint) ?? null;
362427
- const hit = this.#resolveHeaderFooterDomHit(context, clientX, clientY) ?? geometryHit;
363442
+ const hit = clickToPositionGeometry(context.layout, context.blocks, context.measures, headerPoint) ?? null;
362428
363443
  if (!hit)
362429
363444
  return null;
362430
363445
  const doc$2 = this.getActiveEditor().state?.doc;
@@ -367395,11 +368410,11 @@ function print() { __p += __j.call(arguments, '') }
367395
368410
  ]);
367396
368411
  });
367397
368412
 
367398
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-DUYQPx-V.es.js
368413
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-e_ogmxkt.es.js
367399
368414
  var DEFAULT_TEXT_ALIGN_OPTIONS, DEFAULT_LINE_HEIGHT_OPTIONS, DEFAULT_ZOOM_OPTIONS, DEFAULT_DOCUMENT_MODE_OPTIONS, DEFAULT_FONT_SIZE_OPTIONS, headlessToolbarConstants, MOD_ALIASES, ALT_ALIASES, CTRL_ALIASES, SHIFT_ALIASES, BUILTIN_CONTEXT_MENU_GROUPS, BUILTIN_GROUP_ORDER, RESERVED_PROXY_PROPERTY_NAMES, ALL_TOOLBAR_COMMAND_IDS, EMPTY_ACTIVE_IDS, FONT_SIZE_OPTIONS;
367400
- var init_create_super_doc_ui_DUYQPx_V_es = __esm(() => {
367401
- init_SuperConverter_BTGVElJO_es();
367402
- init_create_headless_toolbar_DYbkX05s_es();
368415
+ var init_create_super_doc_ui_e_ogmxkt_es = __esm(() => {
368416
+ init_SuperConverter_CUxtXQFf_es();
368417
+ init_create_headless_toolbar_DutCjfp2_es();
367403
368418
  DEFAULT_TEXT_ALIGN_OPTIONS = [
367404
368419
  {
367405
368420
  label: "Left",
@@ -367690,16 +368705,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
367690
368705
 
367691
368706
  // ../../packages/superdoc/dist/super-editor.es.js
367692
368707
  var init_super_editor_es = __esm(() => {
367693
- init_src_CRJcfbIa_es();
367694
- init_SuperConverter_BTGVElJO_es();
368708
+ init_src_BBtIMpLJ_es();
368709
+ init_SuperConverter_CUxtXQFf_es();
367695
368710
  init_jszip_C49i9kUs_es();
367696
368711
  init_xml_js_CqGKpaft_es();
367697
- init_create_headless_toolbar_DYbkX05s_es();
368712
+ init_create_headless_toolbar_DutCjfp2_es();
367698
368713
  init_constants_D9qj59G2_es();
367699
368714
  init_dist_B8HfvhaK_es();
367700
368715
  init_unified_Dsuw2be5_es();
367701
368716
  init_DocxZipper_FUsfThjV_es();
367702
- init_create_super_doc_ui_DUYQPx_V_es();
368717
+ init_create_super_doc_ui_e_ogmxkt_es();
367703
368718
  init_ui_C5PAS9hY_es();
367704
368719
  init_eventemitter3_BnGqBE_Q_es();
367705
368720
  init_errors_CNaD6vcg_es();