@superdoc-dev/mcp 0.8.0-next.1 → 0.8.0-next.3

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 +429 -132
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -51891,7 +51891,7 @@ var init_remark_gfm_BhnWr3yf_es = __esm(() => {
51891
51891
  emptyOptions2 = {};
51892
51892
  });
51893
51893
 
51894
- // ../../packages/superdoc/dist/chunks/SuperConverter-opYK-HD4.es.js
51894
+ // ../../packages/superdoc/dist/chunks/SuperConverter-zMJ6NmqZ.es.js
51895
51895
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
51896
51896
  const fieldValue = extension$1.config[field];
51897
51897
  if (typeof fieldValue === "function")
@@ -73566,6 +73566,36 @@ function updateSectionMargins(target, updates = {}) {
73566
73566
  }
73567
73567
  throw new Error(`updateSectionMargins: unsupported target type: ${target.type}`);
73568
73568
  }
73569
+ function binaryStringToBase64(binary) {
73570
+ if (typeof globalThis.btoa === "function")
73571
+ return globalThis.btoa(binary);
73572
+ if (typeof Buffer3 !== "undefined")
73573
+ return Buffer3.from(binary, "latin1").toString("base64");
73574
+ throw new Error("[base64] encode requires btoa (browser) or Buffer (Node)");
73575
+ }
73576
+ function base64ToBinaryString(b64) {
73577
+ if (typeof globalThis.atob === "function")
73578
+ return globalThis.atob(b64);
73579
+ if (typeof Buffer3 !== "undefined")
73580
+ return Buffer3.from(b64, "base64").toString("latin1");
73581
+ throw new Error("[base64] decode requires atob (browser) or Buffer (Node)");
73582
+ }
73583
+ function encodeUtf8Base64(input) {
73584
+ return binaryStringToBase64(encodeURIComponent(input).replace(/%([0-9A-F]{2})/g, (_, hex3) => String.fromCharCode(parseInt(hex3, 16))));
73585
+ }
73586
+ function decodeUtf8Base64(b64) {
73587
+ if (!b64)
73588
+ return "";
73589
+ try {
73590
+ const bin = base64ToBinaryString(b64);
73591
+ let pct = "";
73592
+ for (let i$1 = 0;i$1 < bin.length; i$1 += 1)
73593
+ pct += `%${bin.charCodeAt(i$1).toString(16).padStart(2, "0")}`;
73594
+ return decodeURIComponent(pct);
73595
+ } catch {
73596
+ return "";
73597
+ }
73598
+ }
73569
73599
  function collectReferencedImageMediaForClipboard(sliceJsonString, editor) {
73570
73600
  if (!sliceJsonString || !editor?.storage?.image?.media)
73571
73601
  return "";
@@ -73700,36 +73730,6 @@ function applySuperdocClipboardMedia(editor, clipboardData, sliceJson = null, me
73700
73730
  }
73701
73731
  return outSlice;
73702
73732
  }
73703
- function binaryStringToBase64(binary) {
73704
- if (typeof globalThis.btoa === "function")
73705
- return globalThis.btoa(binary);
73706
- if (typeof Buffer3 !== "undefined")
73707
- return Buffer3.from(binary, "latin1").toString("base64");
73708
- throw new Error("[superdocClipboardSlice] base64 encode requires btoa (browser) or Buffer (Node)");
73709
- }
73710
- function base64ToBinaryString(b64) {
73711
- if (typeof globalThis.atob === "function")
73712
- return globalThis.atob(b64);
73713
- if (typeof Buffer3 !== "undefined")
73714
- return Buffer3.from(b64, "base64").toString("latin1");
73715
- throw new Error("[superdocClipboardSlice] base64 decode requires atob (browser) or Buffer (Node)");
73716
- }
73717
- function encodeUtf8Base64(input) {
73718
- return binaryStringToBase64(encodeURIComponent(input).replace(/%([0-9A-F]{2})/g, (_, hex3) => String.fromCharCode(parseInt(hex3, 16))));
73719
- }
73720
- function decodeUtf8Base64(b64) {
73721
- if (!b64)
73722
- return "";
73723
- try {
73724
- const bin = base64ToBinaryString(b64);
73725
- let pct = "";
73726
- for (let i$1 = 0;i$1 < bin.length; i$1 += 1)
73727
- pct += `%${bin.charCodeAt(i$1).toString(16).padStart(2, "0")}`;
73728
- return decodeURIComponent(pct);
73729
- } catch {
73730
- return "";
73731
- }
73732
- }
73733
73733
  function bodySectPrShouldEmbed(bodySectPr) {
73734
73734
  if (!bodySectPr || typeof bodySectPr !== "object")
73735
73735
  return false;
@@ -82007,8 +82007,12 @@ function handleShapeTextWatermarkImport({ pict }) {
82007
82007
  marginTop: styleObj["margin-top"] || "0"
82008
82008
  };
82009
82009
  const rotation = parseFloat(styleObj.rotation) || 0;
82010
- const hPosition = styleObj["mso-position-horizontal"] || "center";
82011
- const vPosition = styleObj["mso-position-vertical"] || "center";
82010
+ const explicitHPosition = styleObj["mso-position-horizontal"];
82011
+ const explicitVPosition = styleObj["mso-position-vertical"];
82012
+ const hasExplicitMarginLeft = styleObj["margin-left"] != null;
82013
+ const hasExplicitMarginTop = styleObj["margin-top"] != null;
82014
+ const hPosition = explicitHPosition || (hasExplicitMarginLeft ? undefined : DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT);
82015
+ const vPosition = explicitVPosition || (hasExplicitMarginTop ? undefined : DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT);
82012
82016
  const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
82013
82017
  const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
82014
82018
  const textAnchor = styleObj["v-text-anchor"] || "middle";
@@ -82017,7 +82021,7 @@ function handleShapeTextWatermarkImport({ pict }) {
82017
82021
  const rawFillColor2 = fillAttrs.color2 || "#3f3f3f";
82018
82022
  const fillColor = sanitizeColor(rawFillColor, "silver");
82019
82023
  const fillColor2 = sanitizeColor(rawFillColor2, "#3f3f3f");
82020
- const opacity = fillAttrs.opacity || "0.5";
82024
+ const opacity = fillAttrs.opacity ?? String(DEFAULT_VML_TEXT_WATERMARK_OPACITY);
82021
82025
  const fillType = fillAttrs.type || "solid";
82022
82026
  const strokeAttrs = shape.elements?.find((el) => el.name === "v:stroke")?.attributes || {};
82023
82027
  const stroked = shapeAttrs.stroked || "f";
@@ -82025,10 +82029,9 @@ function handleShapeTextWatermarkImport({ pict }) {
82025
82029
  const strokeJoinstyle = strokeAttrs.joinstyle || "round";
82026
82030
  const strokeEndcap = strokeAttrs.endcap || "flat";
82027
82031
  const textStyleObj = parseVmlStyle(textpathAttrs.style || "");
82028
- const rawFontFamily = textStyleObj["font-family"]?.replace(/['"]/g, "");
82029
- const fontFamily = sanitizeFontFamily(rawFontFamily);
82032
+ const fontFamily = sanitizeFontFamily(decodeXmlEntities(textStyleObj["font-family"] || "").replace(/['"]/g, ""));
82030
82033
  const fontSize = textStyleObj["font-size"] || "1pt";
82031
- const fitshape = textpathAttrs.fitshape || "t";
82034
+ const shouldFitShape = (textpathAttrs.fitshape || "t") === "t";
82032
82035
  const trim = textpathAttrs.trim || "t";
82033
82036
  const textpathOn = textpathAttrs.on || "t";
82034
82037
  const pathAttrs = shape.elements?.find((el) => el.name === "v:path")?.attributes || {};
@@ -82037,7 +82040,7 @@ function handleShapeTextWatermarkImport({ pict }) {
82037
82040
  const wrapType = wrapAttrs.type || "none";
82038
82041
  const widthPx = convertToPixels(width);
82039
82042
  const heightPx = convertToPixels(height);
82040
- const sanitizedOpacity = sanitizeNumeric(parseFloat(opacity), 0.5, 0, 1);
82043
+ const sanitizedOpacity = sanitizeNumeric(parseVmlOpacity(opacity), DEFAULT_VML_TEXT_WATERMARK_OPACITY, 0, 1);
82041
82044
  const sanitizedRotation = sanitizeNumeric(rotation, 0, -360, 360);
82042
82045
  const svgResult = generateTextWatermarkSVG({
82043
82046
  text: watermarkText,
@@ -82051,12 +82054,44 @@ function handleShapeTextWatermarkImport({ pict }) {
82051
82054
  textStyle: {
82052
82055
  fontFamily,
82053
82056
  fontSize
82054
- }
82057
+ },
82058
+ fitShape: shouldFitShape
82059
+ });
82060
+ const svgDataUri = svgResult.dataUri;
82061
+ const centerOffsetTop = getTextWatermarkCenterOffset({
82062
+ hPosition,
82063
+ vPosition,
82064
+ hRelativeTo,
82065
+ vRelativeTo,
82066
+ height: heightPx,
82067
+ rotation: sanitizedRotation
82068
+ });
82069
+ const marginOffset = resolveTextWatermarkMarginOffset({
82070
+ hPosition,
82071
+ vPosition,
82072
+ hRelativeTo,
82073
+ vRelativeTo,
82074
+ marginLeft: convertToPixels(position2.marginLeft),
82075
+ marginTop: convertToPixels(position2.marginTop),
82076
+ width: widthPx,
82077
+ height: heightPx,
82078
+ svgWidth: svgResult.svgWidth,
82079
+ svgHeight: svgResult.svgHeight,
82080
+ centerOffsetTop,
82081
+ rotation: sanitizedRotation
82055
82082
  });
82083
+ const anchorData = {
82084
+ hRelativeFrom: hRelativeTo,
82085
+ vRelativeFrom: vRelativeTo
82086
+ };
82087
+ if (hPosition)
82088
+ anchorData.alignH = hPosition;
82089
+ if (vPosition)
82090
+ anchorData.alignV = vPosition;
82056
82091
  return {
82057
82092
  type: "image",
82058
82093
  attrs: {
82059
- src: svgResult.dataUri,
82094
+ src: svgDataUri,
82060
82095
  alt: watermarkText,
82061
82096
  title: watermarkText,
82062
82097
  extension: "svg",
@@ -82075,20 +82110,12 @@ function handleShapeTextWatermarkImport({ pict }) {
82075
82110
  type: wrapType === "none" ? "None" : wrapType,
82076
82111
  attrs: { behindDoc: true }
82077
82112
  },
82078
- anchorData: {
82079
- hRelativeFrom: hRelativeTo,
82080
- vRelativeFrom: vRelativeTo,
82081
- alignH: hPosition,
82082
- alignV: vPosition
82083
- },
82113
+ anchorData,
82084
82114
  size: {
82085
82115
  width: svgResult.svgWidth,
82086
82116
  height: svgResult.svgHeight
82087
82117
  },
82088
- marginOffset: {
82089
- horizontal: hPosition === "center" && hRelativeTo === "margin" ? 0 : convertToPixels(position2.marginLeft),
82090
- top: vPosition === "center" && vRelativeTo === "margin" ? 0 : convertToPixels(position2.marginTop)
82091
- },
82118
+ marginOffset,
82092
82119
  textWatermarkData: {
82093
82120
  text: watermarkText,
82094
82121
  rotation: sanitizedRotation,
@@ -82111,7 +82138,7 @@ function handleShapeTextWatermarkImport({ pict }) {
82111
82138
  },
82112
82139
  textpath: {
82113
82140
  on: textpathOn === "t",
82114
- fitshape: fitshape === "t",
82141
+ fitshape: shouldFitShape,
82115
82142
  trim: trim === "t",
82116
82143
  textpathok: textpathok === "t"
82117
82144
  }
@@ -82122,21 +82149,84 @@ function handleShapeTextWatermarkImport({ pict }) {
82122
82149
  function sanitizeFontFamily(fontFamily) {
82123
82150
  if (!fontFamily || typeof fontFamily !== "string")
82124
82151
  return "Arial";
82125
- return fontFamily.replace(/[^a-zA-Z0-9\s,\-]/g, "").trim() || "Arial";
82152
+ return fontFamily.replace(/[^a-zA-Z0-9\s,-]/g, "").trim() || "Arial";
82126
82153
  }
82127
82154
  function sanitizeColor(color2, defaultColor = "silver") {
82128
82155
  if (!color2 || typeof color2 !== "string")
82129
82156
  return defaultColor;
82130
82157
  return color2.replace(/[^a-zA-Z0-9#%(),.]/g, "").trim() || defaultColor;
82131
82158
  }
82159
+ function normalizeVmlColor(color2) {
82160
+ return {
82161
+ black: "#000000",
82162
+ blue: "#0000FF",
82163
+ gray: "#808080",
82164
+ green: "#008000",
82165
+ lime: "#00FF00",
82166
+ red: "#FF0000",
82167
+ silver: "#C0C0C0",
82168
+ white: "#FFFFFF",
82169
+ yellow: "#FFFF00"
82170
+ }[typeof color2 === "string" ? color2.trim().toLowerCase() : ""] || color2;
82171
+ }
82172
+ function decodeXmlEntities(value) {
82173
+ return value.replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&#(\d+);/g, (_, code$1) => decodeCodePoint(Number(code$1))).replace(/&#x([0-9a-fA-F]+);/g, (_, code$1) => decodeCodePoint(Number.parseInt(code$1, 16)));
82174
+ }
82175
+ function decodeCodePoint(codePoint) {
82176
+ if (!Number.isInteger(codePoint) || codePoint < 0 || codePoint > 1114111)
82177
+ return "";
82178
+ return String.fromCodePoint(codePoint);
82179
+ }
82132
82180
  function sanitizeNumeric(value, defaultValue, min = -Infinity, max = Infinity) {
82133
82181
  const num = typeof value === "number" ? value : parseFloat(value);
82134
82182
  if (isNaN(num) || !isFinite(num))
82135
82183
  return defaultValue;
82136
82184
  return Math.max(min, Math.min(max, num));
82137
82185
  }
82138
- function generateTextWatermarkSVG({ text: text$2, width, height, rotation, fill, textStyle }) {
82139
- let fontSize = height * 0.9;
82186
+ function parseVmlOpacity(value) {
82187
+ if (typeof value === "number")
82188
+ return value;
82189
+ if (!value || typeof value !== "string")
82190
+ return NaN;
82191
+ const normalized = value.trim().toLowerCase();
82192
+ if (normalized.endsWith("%"))
82193
+ return Number.parseFloat(normalized.slice(0, -1)) / 100;
82194
+ if (normalized.endsWith("f"))
82195
+ return Number.parseInt(normalized.slice(0, -1), 10) / 65536;
82196
+ return Number.parseFloat(normalized);
82197
+ }
82198
+ function getTextWatermarkCenterOffset({ hPosition, vPosition, hRelativeTo, vRelativeTo, height, rotation }) {
82199
+ if (!(hPosition === "center" && vPosition === "center" && hRelativeTo === "margin" && vRelativeTo === "margin") || rotation === 0)
82200
+ return 0;
82201
+ return sanitizeNumeric(height, 0, 0, MAX_ROTATED_CENTERED_WATERMARK_OFFSET_HEIGHT_PX) * ROTATED_CENTERED_WATERMARK_TOP_OFFSET_RATIO;
82202
+ }
82203
+ function resolveTextWatermarkMarginOffset({ hPosition, vPosition, hRelativeTo, vRelativeTo, marginLeft, marginTop, width, height, svgWidth, svgHeight, centerOffsetTop, rotation }) {
82204
+ const isCenteredHorizontally = hPosition === "center" && hRelativeTo === "margin";
82205
+ const isCenteredVertically = vPosition === "center" && vRelativeTo === "margin";
82206
+ return {
82207
+ horizontal: isCenteredHorizontally ? 0 : getAbsoluteShapeOffset({
82208
+ position: hPosition,
82209
+ margin: marginLeft,
82210
+ shapeSize: width,
82211
+ svgSize: svgWidth,
82212
+ rotation
82213
+ }),
82214
+ top: isCenteredVertically ? centerOffsetTop : getAbsoluteShapeOffset({
82215
+ position: vPosition,
82216
+ margin: marginTop,
82217
+ shapeSize: height,
82218
+ svgSize: svgHeight,
82219
+ rotation
82220
+ })
82221
+ };
82222
+ }
82223
+ function getAbsoluteShapeOffset({ position: position2, margin, shapeSize, svgSize, rotation }) {
82224
+ if (position2 || rotation === 0)
82225
+ return margin;
82226
+ return margin + shapeSize / 2 - svgSize / 2;
82227
+ }
82228
+ function generateTextWatermarkSVG({ text: text$2, width, height, rotation, fill, textStyle, fitShape }) {
82229
+ let fontSize = height * 1.12;
82140
82230
  if (textStyle?.fontSize && textStyle.fontSize.trim() !== "1pt") {
82141
82231
  const match = textStyle.fontSize.match(/^([\d.]+)(pt|px)?$/);
82142
82232
  if (match) {
@@ -82145,9 +82235,9 @@ function generateTextWatermarkSVG({ text: text$2, width, height, rotation, fill,
82145
82235
  }
82146
82236
  }
82147
82237
  fontSize = Math.max(fontSize, 48);
82148
- const color2 = sanitizeColor(fill?.color, "silver");
82149
- const opacity = sanitizeNumeric(fill?.opacity, 0.5, 0, 1);
82150
- const fontFamily = sanitizeFontFamily(textStyle?.fontFamily);
82238
+ const color2 = normalizeVmlColor(sanitizeColor(fill?.color, "silver"));
82239
+ const opacity = sanitizeNumeric(fill?.opacity, DEFAULT_VML_TEXT_WATERMARK_OPACITY, 0, 1);
82240
+ const fontFamily = resolveSvgFontFamily(sanitizeFontFamily(textStyle?.fontFamily));
82151
82241
  const sanitizedRotation = sanitizeNumeric(rotation, 0, -360, 360);
82152
82242
  const sanitizedWidth = sanitizeNumeric(width, 100, 1, 1e4);
82153
82243
  const sanitizedHeight = sanitizeNumeric(height, 100, 1, 1e4);
@@ -82161,24 +82251,40 @@ function generateTextWatermarkSVG({ text: text$2, width, height, rotation, fill,
82161
82251
  const svgHeight = Math.max(sanitizedHeight, rotatedHeight) * 1.1;
82162
82252
  const centerX = svgWidth / 2;
82163
82253
  const centerY = svgHeight / 2;
82164
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${svgWidth}" height="${svgHeight}" viewBox="0 0 ${svgWidth} ${svgHeight}" style="overflow: visible;">
82165
- <text
82166
- x="${centerX}"
82167
- y="${centerY}"
82168
- text-anchor="middle"
82169
- dominant-baseline="middle"
82170
- font-family="${fontFamily}"
82171
- font-size="${sanitizedFontSize}px"
82172
- fill="${color2}"
82173
- opacity="${opacity}"
82174
- transform="rotate(${sanitizedRotation} ${centerX} ${centerY})">${escapeXml(text$2)}</text>
82175
- </svg>`;
82176
82254
  return {
82177
- dataUri: `data:image/svg+xml,${encodeURIComponent(svg)}`,
82255
+ dataUri: `data:image/svg+xml;base64,${encodeUtf8Base64(`<svg xmlns="http://www.w3.org/2000/svg" width="${svgWidth}" height="${svgHeight}" viewBox="0 0 ${svgWidth} ${svgHeight}" style="overflow: visible;">
82256
+ <text ${[
82257
+ `x="${centerX}"`,
82258
+ `y="${centerY}"`,
82259
+ 'text-anchor="middle"',
82260
+ 'dominant-baseline="middle"',
82261
+ `font-family="${fontFamily}"`,
82262
+ `font-size="${sanitizedFontSize}px"`,
82263
+ ...fitShape ? [`textLength="${sanitizedWidth}"`, 'lengthAdjust="spacingAndGlyphs"'] : [],
82264
+ `fill="${color2}"`,
82265
+ `fill-opacity="${opacity}"`,
82266
+ `transform="rotate(${sanitizedRotation} ${centerX} ${centerY})"`
82267
+ ].map((attribute) => ` ${attribute}`).join(`
82268
+ `)}>${escapeXml(text$2)}</text>
82269
+ </svg>`)}`,
82178
82270
  svgWidth,
82179
82271
  svgHeight
82180
82272
  };
82181
82273
  }
82274
+ function resolveSvgFontFamily(fontFamily) {
82275
+ if (!fontFamily || typeof fontFamily !== "string")
82276
+ return "Arial, sans-serif";
82277
+ const normalized = fontFamily.trim();
82278
+ if (normalized.includes(","))
82279
+ return normalized;
82280
+ return `${normalized}, ${new Set([
82281
+ "cambria",
82282
+ "constantia",
82283
+ "georgia",
82284
+ "times new roman",
82285
+ "times"
82286
+ ]).has(normalized.toLowerCase()) ? "serif" : "Arial, sans-serif"}`;
82287
+ }
82182
82288
  function escapeXml(text$2) {
82183
82289
  return text$2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
82184
82290
  }
@@ -82186,7 +82292,7 @@ function parseVmlStyle(style) {
82186
82292
  const result = {};
82187
82293
  if (!style)
82188
82294
  return result;
82189
- const declarations = style.split(";").filter((s) => s.trim());
82295
+ const declarations = decodeXmlEntities(style).split(";").filter((s) => s.trim());
82190
82296
  for (const decl of declarations) {
82191
82297
  const colonIndex = decl.indexOf(":");
82192
82298
  if (colonIndex === -1)
@@ -104986,7 +105092,7 @@ var isRegExp = (value) => {
104986
105092
  if (!settings)
104987
105093
  return false;
104988
105094
  return resolveEvenAndOddHeadersFromSettingsPart(settings) ?? false;
104989
- }, FULL_WIDTH_PT = "468pt", FULL_WIDTH_PT_VALUE = 468, PX_PER_PT = 1.33, XML_NODE_NAME = "w:pict", SD_NODE_NAME, validXmlAttributes, config2, translator$29, DEFAULT_SECTION_PROPS_TWIPS, ensureSectionLayoutDefaults = (sectPr, converter) => {
105095
+ }, ROTATED_CENTERED_WATERMARK_TOP_OFFSET_RATIO = 0.25, MAX_ROTATED_CENTERED_WATERMARK_OFFSET_HEIGHT_PX = 1e4, DEFAULT_VML_TEXT_WATERMARK_OPACITY = 1, DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT = "center", FULL_WIDTH_PT = "468pt", FULL_WIDTH_PT_VALUE = 468, PX_PER_PT = 1.33, XML_NODE_NAME = "w:pict", SD_NODE_NAME, validXmlAttributes, config2, translator$29, DEFAULT_SECTION_PROPS_TWIPS, ensureSectionLayoutDefaults = (sectPr, converter) => {
104990
105096
  if (!sectPr)
104991
105097
  return {
104992
105098
  type: "element",
@@ -105867,7 +105973,7 @@ var isRegExp = (value) => {
105867
105973
  state.kern = kernNode.attributes["w:val"];
105868
105974
  }
105869
105975
  }, SuperConverter;
105870
- var init_SuperConverter_opYK_HD4_es = __esm(() => {
105976
+ var init_SuperConverter_zMJ6NmqZ_es = __esm(() => {
105871
105977
  init_rolldown_runtime_Bg48TavK_es();
105872
105978
  init_jszip_C49i9kUs_es();
105873
105979
  init_xml_js_CqGKpaft_es();
@@ -144047,7 +144153,7 @@ var init_SuperConverter_opYK_HD4_es = __esm(() => {
144047
144153
  };
144048
144154
  });
144049
144155
 
144050
- // ../../packages/superdoc/dist/chunks/create-headless-toolbar-xjqjtPWl.es.js
144156
+ // ../../packages/superdoc/dist/chunks/create-headless-toolbar-CoZdlJbj.es.js
144051
144157
  function parseSizeUnit(val = "0") {
144052
144158
  const length = val.toString() || "0";
144053
144159
  const value = Number.parseFloat(length);
@@ -151846,6 +151952,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
151846
151952
  const src = node2.attrs?.src;
151847
151953
  if (typeof src !== "string" || src.length === 0)
151848
151954
  return false;
151955
+ if (node2.attrs?.vmlTextWatermark)
151956
+ return false;
151849
151957
  if (src.startsWith("word/media"))
151850
151958
  return false;
151851
151959
  if (src.startsWith("data:") && node2.attrs?.rId)
@@ -154070,8 +154178,8 @@ var CSS_DIMENSION_REGEX, DOM_SIZE_UNITS, Extension = class Extension2 {
154070
154178
  }
154071
154179
  };
154072
154180
  };
154073
- var init_create_headless_toolbar_xjqjtPWl_es = __esm(() => {
154074
- init_SuperConverter_opYK_HD4_es();
154181
+ var init_create_headless_toolbar_CoZdlJbj_es = __esm(() => {
154182
+ init_SuperConverter_zMJ6NmqZ_es();
154075
154183
  init_uuid_qzgm05fK_es();
154076
154184
  init_constants_DrU4EASo_es();
154077
154185
  init_dist_B8HfvhaK_es();
@@ -163022,7 +163130,7 @@ var require_decode_codepoint = __commonJS((exports) => {
163022
163130
  Object.defineProperty(exports, "__esModule", { value: true });
163023
163131
  exports.fromCodePoint = undefined;
163024
163132
  exports.replaceCodePoint = replaceCodePoint;
163025
- exports.decodeCodePoint = decodeCodePoint;
163133
+ exports.decodeCodePoint = decodeCodePoint2;
163026
163134
  var decodeMap = new Map([
163027
163135
  [0, 65533],
163028
163136
  [128, 8364],
@@ -163070,7 +163178,7 @@ var require_decode_codepoint = __commonJS((exports) => {
163070
163178
  }
163071
163179
  return (_a3 = decodeMap.get(codePoint)) !== null && _a3 !== undefined ? _a3 : codePoint;
163072
163180
  }
163073
- function decodeCodePoint(codePoint) {
163181
+ function decodeCodePoint2(codePoint) {
163074
163182
  return (0, exports.fromCodePoint)(replaceCodePoint(codePoint));
163075
163183
  }
163076
163184
  });
@@ -208797,7 +208905,7 @@ var init_remark_gfm_eZN6yzWQ_es = __esm(() => {
208797
208905
  init_remark_gfm_BhnWr3yf_es();
208798
208906
  });
208799
208907
 
208800
- // ../../packages/superdoc/dist/chunks/src-CZSemHps.es.js
208908
+ // ../../packages/superdoc/dist/chunks/src-QKGB098Q.es.js
208801
208909
  function deleteProps(obj, propOrProps) {
208802
208910
  const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
208803
208911
  const removeNested = (target, pathParts, index2 = 0) => {
@@ -285502,7 +285610,7 @@ menclose::after {
285502
285610
  menclose.setAttribute("notation", notations.join(" "));
285503
285611
  menclose.appendChild(innerMrow);
285504
285612
  return menclose;
285505
- }, MATHML_NS = "http://www.w3.org/1998/Math/MathML", MATH_OBJECT_REGISTRY, ARGUMENT_ELEMENTS, resolveOrBuildFragmentIdentity = (fragment, story, existing) => buildLayoutSourceIdentityForFragment(existing ? {
285613
+ }, MATHML_NS = "http://www.w3.org/1998/Math/MathML", MATH_OBJECT_REGISTRY, ARGUMENT_ELEMENTS, ACTIVE_HEADER_FOOTER_WATERMARK_PREVIEW_OPACITY = "1", INACTIVE_HEADER_FOOTER_WATERMARK_PREVIEW_OPACITY = "0.5", resolveOrBuildFragmentIdentity = (fragment, story, existing) => buildLayoutSourceIdentityForFragment(existing ? {
285506
285614
  ...fragment,
285507
285615
  layoutSourceIdentity: existing,
285508
285616
  sourceAnchor: fragment.sourceAnchor ?? existing.sourceAnchor
@@ -296067,6 +296175,8 @@ menclose::after {
296067
296175
  this.#emitModeChanged();
296068
296176
  this.#emitEditingContext(editor);
296069
296177
  this.#deps?.notifyInputBridgeTargetChanged();
296178
+ this.#deps?.setPendingDocChange();
296179
+ this.#deps?.scheduleRerender();
296070
296180
  return editor;
296071
296181
  } catch (error48) {
296072
296182
  console.error("[HeaderFooterSessionManager] Unexpected error in enterMode:", error48);
@@ -296182,6 +296292,13 @@ menclose::after {
296182
296292
  this.#updateModeBanner();
296183
296293
  this.#syncActiveBorder();
296184
296294
  }
296295
+ #isActiveDecoration(kind, headerFooterRefId, pageNumber) {
296296
+ if (this.#session.mode !== kind)
296297
+ return false;
296298
+ if (headerFooterRefId && this.#session.headerFooterRefId)
296299
+ return headerFooterRefId === this.#session.headerFooterRefId;
296300
+ return this.#session.pageNumber === pageNumber;
296301
+ }
296185
296302
  #emitEditingContext(editor) {
296186
296303
  this.#callbacks.onEditingContext?.({
296187
296304
  kind: this.#session.mode,
@@ -296869,9 +296986,12 @@ menclose::after {
296869
296986
  const rawLayoutHeight$1 = rIdLayout.layout.height ?? 0;
296870
296987
  const metrics$1 = this.#computeMetrics(kind, rawLayoutHeight$1, box$1, pageHeight$1, margins$1?.footer ?? 0);
296871
296988
  const layoutMinY$1 = rIdLayout.layout.minY ?? 0;
296989
+ const normalizedFragments$1 = normalizeDecorationFragments(fragments$1, layoutMinY$1);
296990
+ const normalizedItems$1 = normalizeDecorationItems(alignedItems, layoutMinY$1);
296991
+ const isActiveHeaderFooter$1 = this.#isActiveDecoration(kind, sectionRId, pageNumber);
296872
296992
  return {
296873
- fragments: normalizeDecorationFragments(fragments$1, layoutMinY$1),
296874
- items: normalizeDecorationItems(alignedItems, layoutMinY$1),
296993
+ fragments: normalizedFragments$1,
296994
+ items: normalizedItems$1,
296875
296995
  height: metrics$1.containerHeight,
296876
296996
  contentHeight: metrics$1.layoutHeight > 0 ? metrics$1.layoutHeight : metrics$1.containerHeight,
296877
296997
  offset: metrics$1.offset,
@@ -296879,6 +296999,7 @@ menclose::after {
296879
296999
  contentWidth: effectiveWidth,
296880
297000
  headerFooterRefId: sectionRId,
296881
297001
  sectionType: headerFooterType,
297002
+ isActiveHeaderFooter: isActiveHeaderFooter$1,
296882
297003
  minY: layoutMinY$1,
296883
297004
  box: {
296884
297005
  x: box$1.x,
@@ -296919,9 +297040,12 @@ menclose::after {
296919
297040
  const rawLayoutHeight = variant.layout.height ?? 0;
296920
297041
  const metrics = this.#computeMetrics(kind, rawLayoutHeight, box, pageHeight, margins?.footer ?? 0);
296921
297042
  const layoutMinY = variant.layout.minY ?? 0;
297043
+ const normalizedFragments = normalizeDecorationFragments(fragments, layoutMinY);
297044
+ const normalizedItems = normalizeDecorationItems(alignedVariantItems, layoutMinY);
297045
+ const isActiveHeaderFooter = this.#isActiveDecoration(kind, finalHeaderId, pageNumber);
296922
297046
  return {
296923
- fragments: normalizeDecorationFragments(fragments, layoutMinY),
296924
- items: normalizeDecorationItems(alignedVariantItems, layoutMinY),
297047
+ fragments: normalizedFragments,
297048
+ items: normalizedItems,
296925
297049
  height: metrics.containerHeight,
296926
297050
  contentHeight: metrics.layoutHeight > 0 ? metrics.layoutHeight : metrics.containerHeight,
296927
297051
  offset: metrics.offset,
@@ -296929,6 +297053,7 @@ menclose::after {
296929
297053
  contentWidth: box.width,
296930
297054
  headerFooterRefId: finalHeaderId,
296931
297055
  sectionType: headerFooterType,
297056
+ isActiveHeaderFooter,
296932
297057
  minY: layoutMinY,
296933
297058
  box: {
296934
297059
  x: box.x,
@@ -297219,13 +297344,13 @@ menclose::after {
297219
297344
  return;
297220
297345
  console.log(...args$1);
297221
297346
  }, 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;
297222
- var init_src_CZSemHps_es = __esm(() => {
297347
+ var init_src_QKGB098Q_es = __esm(() => {
297223
297348
  init_rolldown_runtime_Bg48TavK_es();
297224
- init_SuperConverter_opYK_HD4_es();
297349
+ init_SuperConverter_zMJ6NmqZ_es();
297225
297350
  init_jszip_C49i9kUs_es();
297226
297351
  init_xml_js_CqGKpaft_es();
297227
297352
  init_uuid_qzgm05fK_es();
297228
- init_create_headless_toolbar_xjqjtPWl_es();
297353
+ init_create_headless_toolbar_CoZdlJbj_es();
297229
297354
  init_constants_DrU4EASo_es();
297230
297355
  init_dist_B8HfvhaK_es();
297231
297356
  init_unified_Dsuw2be5_es();
@@ -303089,8 +303214,16 @@ ${err.toString()}`);
303089
303214
  },
303090
303215
  isAnchor: { rendered: false },
303091
303216
  vmlWatermark: { rendered: false },
303217
+ vmlTextWatermark: { rendered: false },
303218
+ textWatermarkData: { rendered: false },
303219
+ vmlStyle: { rendered: false },
303092
303220
  vmlAttributes: { rendered: false },
303093
303221
  vmlImagedata: { rendered: false },
303222
+ vmlTextpathAttributes: { rendered: false },
303223
+ vmlPathAttributes: { rendered: false },
303224
+ vmlFillAttributes: { rendered: false },
303225
+ vmlStrokeAttributes: { rendered: false },
303226
+ vmlWrapAttributes: { rendered: false },
303094
303227
  transformData: {
303095
303228
  default: {},
303096
303229
  renderDOM: ({ transformData }) => {
@@ -324608,6 +324741,7 @@ function print() { __p += __j.call(arguments, '') }
324608
324741
  behindDocFragments.forEach(({ fragment, originalIndex }) => {
324609
324742
  const resolvedItem = data.items?.[originalIndex];
324610
324743
  const fragEl = this.renderFragment(fragment, context, undefined, betweenBorderFlags.get(originalIndex), resolvedItem);
324744
+ this.applyHeaderFooterTextWatermarkPreviewOpacity(fragEl, data.isActiveHeaderFooter === true);
324611
324745
  const isPageRelative = this.isPageRelativeAnchoredFragment(fragment, resolvedItem);
324612
324746
  let pageY;
324613
324747
  if (isPageRelative && kind === "footer")
@@ -324625,6 +324759,7 @@ function print() { __p += __j.call(arguments, '') }
324625
324759
  normalFragments.forEach(({ fragment, originalIndex }) => {
324626
324760
  const resolvedItem = data.items?.[originalIndex];
324627
324761
  const fragEl = this.renderFragment(fragment, context, undefined, betweenBorderFlags.get(originalIndex), resolvedItem);
324762
+ this.applyHeaderFooterTextWatermarkPreviewOpacity(fragEl, data.isActiveHeaderFooter === true);
324628
324763
  const isPageRelative = this.isPageRelativeAnchoredFragment(fragment, resolvedItem);
324629
324764
  if (isPageRelative && kind === "footer")
324630
324765
  fragEl.style.top = `${fragment.y + footerAnchorContainerOffsetY}px`;
@@ -325379,6 +325514,8 @@ function print() { __p += __j.call(arguments, '') }
325379
325514
  }
325380
325515
  this.applySdtDataset(fragmentEl, block.attrs?.sdt);
325381
325516
  this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
325517
+ if (this.isVmlTextWatermarkImage(block))
325518
+ fragmentEl.dataset.vmlTextWatermark = "true";
325382
325519
  if (block.id)
325383
325520
  fragmentEl.setAttribute("data-sd-block-id", block.id);
325384
325521
  const imgPmStart = resolvedItem?.pmStart;
@@ -327466,7 +327603,11 @@ function print() { __p += __j.call(arguments, '') }
327466
327603
  shouldRenderBehindPageContent(fragment, section, resolvedItem) {
327467
327604
  if (fragment.behindDoc === true || fragment.behindDoc == null && "zIndex" in fragment && fragment.zIndex === 0)
327468
327605
  return true;
327469
- return section === "header" && fragment.kind === "drawing" && this.isHeaderWordArtWatermark(resolvedItem?.block);
327606
+ if (section !== "header")
327607
+ return false;
327608
+ if (fragment.kind === "drawing")
327609
+ return this.isHeaderWordArtWatermark(resolvedItem?.block);
327610
+ return this.isVmlTextWatermarkImage(resolvedItem?.block);
327470
327611
  }
327471
327612
  isHeaderWordArtWatermark(block) {
327472
327613
  if (!block || block.kind !== "drawing" || block.drawingKind !== "vectorShape")
@@ -327475,6 +327616,14 @@ function print() { __p += __j.call(arguments, '') }
327475
327616
  const hasTextContent = Array.isArray(block.textContent?.parts) && block.textContent.parts.length > 0;
327476
327617
  return attrs.isWordArt === true && attrs.isTextBox === true && hasTextContent && block.anchor?.isAnchored === true && block.anchor.hRelativeFrom === "page" && block.anchor.alignH === "center" && block.anchor.vRelativeFrom === "page" && block.anchor.alignV === "center" && block.wrap?.type === "None";
327477
327618
  }
327619
+ isVmlTextWatermarkImage(block) {
327620
+ return block?.kind === "image" && block.attrs?.vmlTextWatermark === true;
327621
+ }
327622
+ applyHeaderFooterTextWatermarkPreviewOpacity(el, isActiveHeaderFooter) {
327623
+ if (el.dataset.vmlTextWatermark !== "true")
327624
+ return;
327625
+ el.style.opacity = isActiveHeaderFooter ? ACTIVE_HEADER_FOOTER_WATERMARK_PREVIEW_OPACITY : INACTIVE_HEADER_FOOTER_WATERMARK_PREVIEW_OPACITY;
327626
+ }
327478
327627
  resolveFragmentWrapperZIndex(fragment, resolvedZIndex) {
327479
327628
  if (!this.isAnchoredMediaFragment(fragment))
327480
327629
  return "";
@@ -334998,11 +335147,11 @@ function print() { __p += __j.call(arguments, '') }
334998
335147
  ];
334999
335148
  });
335000
335149
 
335001
- // ../../packages/superdoc/dist/chunks/create-super-doc-ui-DqYtj3Jy.es.js
335150
+ // ../../packages/superdoc/dist/chunks/create-super-doc-ui-DM_6uPhc.es.js
335002
335151
  var 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;
335003
- var init_create_super_doc_ui_DqYtj3Jy_es = __esm(() => {
335004
- init_SuperConverter_opYK_HD4_es();
335005
- init_create_headless_toolbar_xjqjtPWl_es();
335152
+ var init_create_super_doc_ui_DM_6uPhc_es = __esm(() => {
335153
+ init_SuperConverter_zMJ6NmqZ_es();
335154
+ init_create_headless_toolbar_CoZdlJbj_es();
335006
335155
  MOD_ALIASES = new Set([
335007
335156
  "Mod",
335008
335157
  "Meta",
@@ -335044,16 +335193,16 @@ var init_zipper_yaJVJ4z9_es = __esm(() => {
335044
335193
 
335045
335194
  // ../../packages/superdoc/dist/super-editor.es.js
335046
335195
  var init_super_editor_es = __esm(() => {
335047
- init_src_CZSemHps_es();
335048
- init_SuperConverter_opYK_HD4_es();
335196
+ init_src_QKGB098Q_es();
335197
+ init_SuperConverter_zMJ6NmqZ_es();
335049
335198
  init_jszip_C49i9kUs_es();
335050
335199
  init_xml_js_CqGKpaft_es();
335051
- init_create_headless_toolbar_xjqjtPWl_es();
335200
+ init_create_headless_toolbar_CoZdlJbj_es();
335052
335201
  init_constants_DrU4EASo_es();
335053
335202
  init_dist_B8HfvhaK_es();
335054
335203
  init_unified_Dsuw2be5_es();
335055
335204
  init_DocxZipper_CZMPWpOp_es();
335056
- init_create_super_doc_ui_DqYtj3Jy_es();
335205
+ init_create_super_doc_ui_DM_6uPhc_es();
335057
335206
  init_ui_C5PAS9hY_es();
335058
335207
  init_eventemitter3_BnGqBE_Q_es();
335059
335208
  init_errors_CNaD6vcg_es();
@@ -418716,6 +418865,21 @@ var init_section_properties = __esm(() => {
418716
418865
  init_helpers();
418717
418866
  });
418718
418867
 
418868
+ // ../../packages/super-editor/src/editors/v1/core/helpers/base64.js
418869
+ function binaryStringToBase642(binary) {
418870
+ if (typeof globalThis.btoa === "function") {
418871
+ return globalThis.btoa(binary);
418872
+ }
418873
+ if (typeof Buffer !== "undefined") {
418874
+ return Buffer.from(binary, "latin1").toString("base64");
418875
+ }
418876
+ throw new Error("[base64] encode requires btoa (browser) or Buffer (Node)");
418877
+ }
418878
+ function encodeUtf8Base642(input2) {
418879
+ const binary = encodeURIComponent(input2).replace(/%([0-9A-F]{2})/g, (_3, hex3) => String.fromCharCode(parseInt(hex3, 16)));
418880
+ return binaryStringToBase642(binary);
418881
+ }
418882
+
418719
418883
  // ../../packages/super-editor/src/editors/v1/core/helpers/superdocClipboardSlice.js
418720
418884
  var init_superdocClipboardSlice = __esm(() => {
418721
418885
  init_section_properties();
@@ -427178,8 +427342,12 @@ function handleShapeTextWatermarkImport2({ pict }) {
427178
427342
  marginTop: styleObj["margin-top"] || "0"
427179
427343
  };
427180
427344
  const rotation = parseFloat(styleObj.rotation) || 0;
427181
- const hPosition = styleObj["mso-position-horizontal"] || "center";
427182
- const vPosition = styleObj["mso-position-vertical"] || "center";
427345
+ const explicitHPosition = styleObj["mso-position-horizontal"];
427346
+ const explicitVPosition = styleObj["mso-position-vertical"];
427347
+ const hasExplicitMarginLeft = styleObj["margin-left"] != null;
427348
+ const hasExplicitMarginTop = styleObj["margin-top"] != null;
427349
+ const hPosition = explicitHPosition || (hasExplicitMarginLeft ? undefined : DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT2);
427350
+ const vPosition = explicitVPosition || (hasExplicitMarginTop ? undefined : DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT2);
427183
427351
  const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
427184
427352
  const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
427185
427353
  const textAnchor = styleObj["v-text-anchor"] || "middle";
@@ -427189,7 +427357,7 @@ function handleShapeTextWatermarkImport2({ pict }) {
427189
427357
  const rawFillColor2 = fillAttrs.color2 || "#3f3f3f";
427190
427358
  const fillColor = sanitizeColor2(rawFillColor, "silver");
427191
427359
  const fillColor2 = sanitizeColor2(rawFillColor2, "#3f3f3f");
427192
- const opacity = fillAttrs.opacity || "0.5";
427360
+ const opacity = fillAttrs.opacity ?? String(DEFAULT_VML_TEXT_WATERMARK_OPACITY2);
427193
427361
  const fillType = fillAttrs.type || "solid";
427194
427362
  const stroke = shape.elements?.find((el) => el.name === "v:stroke");
427195
427363
  const strokeAttrs = stroke?.attributes || {};
@@ -427199,10 +427367,11 @@ function handleShapeTextWatermarkImport2({ pict }) {
427199
427367
  const strokeEndcap = strokeAttrs.endcap || "flat";
427200
427368
  const textpathStyle = textpathAttrs.style || "";
427201
427369
  const textStyleObj = parseVmlStyle3(textpathStyle);
427202
- const rawFontFamily = textStyleObj["font-family"]?.replace(/['"]/g, "");
427370
+ const rawFontFamily = decodeXmlEntities2(textStyleObj["font-family"] || "").replace(/['"]/g, "");
427203
427371
  const fontFamily = sanitizeFontFamily3(rawFontFamily);
427204
427372
  const fontSize = textStyleObj["font-size"] || "1pt";
427205
427373
  const fitshape = textpathAttrs.fitshape || "t";
427374
+ const shouldFitShape = fitshape === "t";
427206
427375
  const trim = textpathAttrs.trim || "t";
427207
427376
  const textpathOn = textpathAttrs.on || "t";
427208
427377
  const path3 = shape.elements?.find((el) => el.name === "v:path");
@@ -427213,7 +427382,7 @@ function handleShapeTextWatermarkImport2({ pict }) {
427213
427382
  const wrapType = wrapAttrs.type || "none";
427214
427383
  const widthPx = convertToPixels3(width);
427215
427384
  const heightPx = convertToPixels3(height);
427216
- const sanitizedOpacity = sanitizeNumeric2(parseFloat(opacity), 0.5, 0, 1);
427385
+ const sanitizedOpacity = sanitizeNumeric2(parseVmlOpacity2(opacity), DEFAULT_VML_TEXT_WATERMARK_OPACITY2, 0, 1);
427217
427386
  const sanitizedRotation = sanitizeNumeric2(rotation, 0, -360, 360);
427218
427387
  const svgResult = generateTextWatermarkSVG2({
427219
427388
  text: watermarkText,
@@ -427227,9 +427396,40 @@ function handleShapeTextWatermarkImport2({ pict }) {
427227
427396
  textStyle: {
427228
427397
  fontFamily,
427229
427398
  fontSize
427230
- }
427399
+ },
427400
+ fitShape: shouldFitShape
427231
427401
  });
427232
427402
  const svgDataUri = svgResult.dataUri;
427403
+ const centerOffsetTop = getTextWatermarkCenterOffset2({
427404
+ hPosition,
427405
+ vPosition,
427406
+ hRelativeTo,
427407
+ vRelativeTo,
427408
+ height: heightPx,
427409
+ rotation: sanitizedRotation
427410
+ });
427411
+ const marginOffset = resolveTextWatermarkMarginOffset2({
427412
+ hPosition,
427413
+ vPosition,
427414
+ hRelativeTo,
427415
+ vRelativeTo,
427416
+ marginLeft: convertToPixels3(position5.marginLeft),
427417
+ marginTop: convertToPixels3(position5.marginTop),
427418
+ width: widthPx,
427419
+ height: heightPx,
427420
+ svgWidth: svgResult.svgWidth,
427421
+ svgHeight: svgResult.svgHeight,
427422
+ centerOffsetTop,
427423
+ rotation: sanitizedRotation
427424
+ });
427425
+ const anchorData = {
427426
+ hRelativeFrom: hRelativeTo,
427427
+ vRelativeFrom: vRelativeTo
427428
+ };
427429
+ if (hPosition)
427430
+ anchorData.alignH = hPosition;
427431
+ if (vPosition)
427432
+ anchorData.alignV = vPosition;
427233
427433
  const imageWatermarkNode = {
427234
427434
  type: "image",
427235
427435
  attrs: {
@@ -427254,20 +427454,12 @@ function handleShapeTextWatermarkImport2({ pict }) {
427254
427454
  behindDoc: true
427255
427455
  }
427256
427456
  },
427257
- anchorData: {
427258
- hRelativeFrom: hRelativeTo,
427259
- vRelativeFrom: vRelativeTo,
427260
- alignH: hPosition,
427261
- alignV: vPosition
427262
- },
427457
+ anchorData,
427263
427458
  size: {
427264
427459
  width: svgResult.svgWidth,
427265
427460
  height: svgResult.svgHeight
427266
427461
  },
427267
- marginOffset: {
427268
- horizontal: hPosition === "center" && hRelativeTo === "margin" ? 0 : convertToPixels3(position5.marginLeft),
427269
- top: vPosition === "center" && vRelativeTo === "margin" ? 0 : convertToPixels3(position5.marginTop)
427270
- },
427462
+ marginOffset,
427271
427463
  textWatermarkData: {
427272
427464
  text: watermarkText,
427273
427465
  rotation: sanitizedRotation,
@@ -427290,7 +427482,7 @@ function handleShapeTextWatermarkImport2({ pict }) {
427290
427482
  },
427291
427483
  textpath: {
427292
427484
  on: textpathOn === "t",
427293
- fitshape: fitshape === "t",
427485
+ fitshape: shouldFitShape,
427294
427486
  trim: trim === "t",
427295
427487
  textpathok: textpathok === "t"
427296
427488
  }
@@ -427303,7 +427495,7 @@ function sanitizeFontFamily3(fontFamily) {
427303
427495
  if (!fontFamily || typeof fontFamily !== "string") {
427304
427496
  return "Arial";
427305
427497
  }
427306
- const sanitized = fontFamily.replace(/[^a-zA-Z0-9\s,\-]/g, "").trim();
427498
+ const sanitized = fontFamily.replace(/[^a-zA-Z0-9\s,-]/g, "").trim();
427307
427499
  return sanitized || "Arial";
427308
427500
  }
427309
427501
  function sanitizeColor2(color3, defaultColor = "silver") {
@@ -427313,6 +427505,30 @@ function sanitizeColor2(color3, defaultColor = "silver") {
427313
427505
  const sanitized = color3.replace(/[^a-zA-Z0-9#%(),.]/g, "").trim();
427314
427506
  return sanitized || defaultColor;
427315
427507
  }
427508
+ function normalizeVmlColor2(color3) {
427509
+ const namedColors = {
427510
+ black: "#000000",
427511
+ blue: "#0000FF",
427512
+ gray: "#808080",
427513
+ green: "#008000",
427514
+ lime: "#00FF00",
427515
+ red: "#FF0000",
427516
+ silver: "#C0C0C0",
427517
+ white: "#FFFFFF",
427518
+ yellow: "#FFFF00"
427519
+ };
427520
+ const key2 = typeof color3 === "string" ? color3.trim().toLowerCase() : "";
427521
+ return namedColors[key2] || color3;
427522
+ }
427523
+ function decodeXmlEntities2(value) {
427524
+ return value.replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&#(\d+);/g, (_3, code10) => decodeCodePoint2(Number(code10))).replace(/&#x([0-9a-fA-F]+);/g, (_3, code10) => decodeCodePoint2(Number.parseInt(code10, 16)));
427525
+ }
427526
+ function decodeCodePoint2(codePoint) {
427527
+ if (!Number.isInteger(codePoint) || codePoint < 0 || codePoint > 1114111) {
427528
+ return "";
427529
+ }
427530
+ return String.fromCodePoint(codePoint);
427531
+ }
427316
427532
  function sanitizeNumeric2(value, defaultValue, min3 = -Infinity, max3 = Infinity) {
427317
427533
  const num = typeof value === "number" ? value : parseFloat(value);
427318
427534
  if (isNaN(num) || !isFinite(num)) {
@@ -427320,8 +427536,70 @@ function sanitizeNumeric2(value, defaultValue, min3 = -Infinity, max3 = Infinity
427320
427536
  }
427321
427537
  return Math.max(min3, Math.min(max3, num));
427322
427538
  }
427323
- function generateTextWatermarkSVG2({ text: text7, width, height, rotation, fill, textStyle }) {
427324
- let fontSize = height * 0.9;
427539
+ function parseVmlOpacity2(value) {
427540
+ if (typeof value === "number") {
427541
+ return value;
427542
+ }
427543
+ if (!value || typeof value !== "string") {
427544
+ return NaN;
427545
+ }
427546
+ const normalized = value.trim().toLowerCase();
427547
+ if (normalized.endsWith("%")) {
427548
+ return Number.parseFloat(normalized.slice(0, -1)) / 100;
427549
+ }
427550
+ if (normalized.endsWith("f")) {
427551
+ return Number.parseInt(normalized.slice(0, -1), 10) / 65536;
427552
+ }
427553
+ return Number.parseFloat(normalized);
427554
+ }
427555
+ function getTextWatermarkCenterOffset2({ hPosition, vPosition, hRelativeTo, vRelativeTo, height, rotation }) {
427556
+ const isCenteredMarginWatermark = hPosition === "center" && vPosition === "center" && hRelativeTo === "margin" && vRelativeTo === "margin";
427557
+ if (!isCenteredMarginWatermark || rotation === 0) {
427558
+ return 0;
427559
+ }
427560
+ return sanitizeNumeric2(height, 0, 0, MAX_ROTATED_CENTERED_WATERMARK_OFFSET_HEIGHT_PX2) * ROTATED_CENTERED_WATERMARK_TOP_OFFSET_RATIO2;
427561
+ }
427562
+ function resolveTextWatermarkMarginOffset2({
427563
+ hPosition,
427564
+ vPosition,
427565
+ hRelativeTo,
427566
+ vRelativeTo,
427567
+ marginLeft,
427568
+ marginTop,
427569
+ width,
427570
+ height,
427571
+ svgWidth,
427572
+ svgHeight,
427573
+ centerOffsetTop,
427574
+ rotation
427575
+ }) {
427576
+ const isCenteredHorizontally = hPosition === "center" && hRelativeTo === "margin";
427577
+ const isCenteredVertically = vPosition === "center" && vRelativeTo === "margin";
427578
+ return {
427579
+ horizontal: isCenteredHorizontally ? 0 : getAbsoluteShapeOffset2({
427580
+ position: hPosition,
427581
+ margin: marginLeft,
427582
+ shapeSize: width,
427583
+ svgSize: svgWidth,
427584
+ rotation
427585
+ }),
427586
+ top: isCenteredVertically ? centerOffsetTop : getAbsoluteShapeOffset2({
427587
+ position: vPosition,
427588
+ margin: marginTop,
427589
+ shapeSize: height,
427590
+ svgSize: svgHeight,
427591
+ rotation
427592
+ })
427593
+ };
427594
+ }
427595
+ function getAbsoluteShapeOffset2({ position: position5, margin, shapeSize, svgSize, rotation }) {
427596
+ if (position5 || rotation === 0) {
427597
+ return margin;
427598
+ }
427599
+ return margin + shapeSize / 2 - svgSize / 2;
427600
+ }
427601
+ function generateTextWatermarkSVG2({ text: text7, width, height, rotation, fill, textStyle, fitShape }) {
427602
+ let fontSize = height * 1.12;
427325
427603
  if (textStyle?.fontSize && textStyle.fontSize.trim() !== "1pt") {
427326
427604
  const match2 = textStyle.fontSize.match(/^([\d.]+)(pt|px)?$/);
427327
427605
  if (match2) {
@@ -427331,9 +427609,9 @@ function generateTextWatermarkSVG2({ text: text7, width, height, rotation, fill,
427331
427609
  }
427332
427610
  }
427333
427611
  fontSize = Math.max(fontSize, 48);
427334
- const color3 = sanitizeColor2(fill?.color, "silver");
427335
- const opacity = sanitizeNumeric2(fill?.opacity, 0.5, 0, 1);
427336
- const fontFamily = sanitizeFontFamily3(textStyle?.fontFamily);
427612
+ const color3 = normalizeVmlColor2(sanitizeColor2(fill?.color, "silver"));
427613
+ const opacity = sanitizeNumeric2(fill?.opacity, DEFAULT_VML_TEXT_WATERMARK_OPACITY2, 0, 1);
427614
+ const fontFamily = resolveSvgFontFamily2(sanitizeFontFamily3(textStyle?.fontFamily));
427337
427615
  const sanitizedRotation = sanitizeNumeric2(rotation, 0, -360, 360);
427338
427616
  const sanitizedWidth = sanitizeNumeric2(width, 100, 1, 1e4);
427339
427617
  const sanitizedHeight = sanitizeNumeric2(height, 100, 1, 1e4);
@@ -427347,24 +427625,40 @@ function generateTextWatermarkSVG2({ text: text7, width, height, rotation, fill,
427347
427625
  const svgHeight = Math.max(sanitizedHeight, rotatedHeight) * 1.1;
427348
427626
  const centerX = svgWidth / 2;
427349
427627
  const centerY = svgHeight / 2;
427628
+ const textAttributes = [
427629
+ `x="${centerX}"`,
427630
+ `y="${centerY}"`,
427631
+ 'text-anchor="middle"',
427632
+ 'dominant-baseline="middle"',
427633
+ `font-family="${fontFamily}"`,
427634
+ `font-size="${sanitizedFontSize}px"`,
427635
+ ...fitShape ? [`textLength="${sanitizedWidth}"`, 'lengthAdjust="spacingAndGlyphs"'] : [],
427636
+ `fill="${color3}"`,
427637
+ `fill-opacity="${opacity}"`,
427638
+ `transform="rotate(${sanitizedRotation} ${centerX} ${centerY})"`
427639
+ ].map((attribute) => ` ${attribute}`).join(`
427640
+ `);
427350
427641
  const svg2 = `<svg xmlns="http://www.w3.org/2000/svg" width="${svgWidth}" height="${svgHeight}" viewBox="0 0 ${svgWidth} ${svgHeight}" style="overflow: visible;">
427351
- <text
427352
- x="${centerX}"
427353
- y="${centerY}"
427354
- text-anchor="middle"
427355
- dominant-baseline="middle"
427356
- font-family="${fontFamily}"
427357
- font-size="${sanitizedFontSize}px"
427358
- fill="${color3}"
427359
- opacity="${opacity}"
427360
- transform="rotate(${sanitizedRotation} ${centerX} ${centerY})">${escapeXml2(text7)}</text>
427361
- </svg>`;
427642
+ <text ${textAttributes}>${escapeXml2(text7)}</text>
427643
+ </svg>`;
427362
427644
  return {
427363
- dataUri: `data:image/svg+xml,${encodeURIComponent(svg2)}`,
427645
+ dataUri: `data:image/svg+xml;base64,${encodeUtf8Base642(svg2)}`,
427364
427646
  svgWidth,
427365
427647
  svgHeight
427366
427648
  };
427367
427649
  }
427650
+ function resolveSvgFontFamily2(fontFamily) {
427651
+ if (!fontFamily || typeof fontFamily !== "string") {
427652
+ return "Arial, sans-serif";
427653
+ }
427654
+ const normalized = fontFamily.trim();
427655
+ if (normalized.includes(",")) {
427656
+ return normalized;
427657
+ }
427658
+ const serifFonts = new Set(["cambria", "constantia", "georgia", "times new roman", "times"]);
427659
+ const generic = serifFonts.has(normalized.toLowerCase()) ? "serif" : "Arial, sans-serif";
427660
+ return `${normalized}, ${generic}`;
427661
+ }
427368
427662
  function escapeXml2(text7) {
427369
427663
  return text7.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
427370
427664
  }
@@ -427372,7 +427666,7 @@ function parseVmlStyle3(style2) {
427372
427666
  const result = {};
427373
427667
  if (!style2)
427374
427668
  return result;
427375
- const declarations = style2.split(";").filter((s2) => s2.trim());
427669
+ const declarations = decodeXmlEntities2(style2).split(";").filter((s2) => s2.trim());
427376
427670
  for (const decl of declarations) {
427377
427671
  const colonIndex = decl.indexOf(":");
427378
427672
  if (colonIndex === -1)
@@ -427412,6 +427706,8 @@ function convertToPixels3(value) {
427412
427706
  return num;
427413
427707
  }
427414
427708
  }
427709
+ var ROTATED_CENTERED_WATERMARK_TOP_OFFSET_RATIO2 = 0.25, MAX_ROTATED_CENTERED_WATERMARK_OFFSET_HEIGHT_PX2 = 1e4, DEFAULT_VML_TEXT_WATERMARK_OPACITY2 = 1, DEFAULT_VML_TEXT_WATERMARK_ALIGNMENT2 = "center";
427710
+ var init_handle_shape_text_watermark_import = () => {};
427415
427711
 
427416
427712
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/w/pict/helpers/pict-node-type-strategy.js
427417
427713
  function pictNodeTypeStrategy2(node4) {
@@ -427447,6 +427743,7 @@ var init_pict_node_type_strategy = __esm(() => {
427447
427743
  init_handle_v_rect_import();
427448
427744
  init_handle_shape_textbox_import();
427449
427745
  init_handle_shape_image_watermark_import();
427746
+ init_handle_shape_text_watermark_import();
427450
427747
  });
427451
427748
 
427452
427749
  // ../../packages/super-editor/src/editors/v1/core/super-converter/v3/handlers/w/pict/helpers/translate-shape-container.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/mcp",
3
- "version": "0.8.0-next.1",
3
+ "version": "0.8.0-next.3",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=20"