oasis-editor 0.0.41 → 0.0.43

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.
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as getParagraphLength, b as createEditorRun, d as getDocumentSections, e as createEditorStyledRun, f as getParagraphText, h as getActiveZone, i as getActiveSectionIndex, p as positionToParagraphOffset, j as paragraphOffsetToPosition, k as clampPosition, l as findParagraphIndex, m as createCollapsedSelection, o as isSelectionCollapsed, q as createEditorParagraph, r as getBlockParagraphs, s as findParagraphTableLocation, t as buildTableCellLayout, u as createEditorTableCell, v as createEditorTableRow, w as createEditorTable, x as underlineStyleToCssDecorationStyle, y as resolveImageSrc, z as createEditorFootnote, A as createFootnoteReferenceRun, B as renumberFootnotes, C as iterateFootnoteReferenceRuns, D as getFootnoteDisplayMarker, E as createSignal, F as createEffect, G as onCleanup, H as buildCanvasLayoutSnapshot, I as on, J as onMount, K as debounce, L as unwrap, M as getDocumentParagraphs, N as getDocumentSectionsCanonical, O as createEditorDocument, P as getPageContentWidth, Q as getDocumentPageSettings, R as getTableCellContentWidthForParagraph, S as resolveResizedDimensions, T as resolveTextBoxRenderHeight, U as resolveEffectiveParagraphStyle, V as resolveEffectiveTextStyleForParagraph, W as iterateEndnoteReferenceRuns, X as JSZip, Y as imageContentTypeDefaults, Z as imageExtensionFromMime, _ as pxToPt$1, $ as resolveFloatingObjectRect, a0 as getTextBoxFloatingGeometry, a1 as getPresetPathSegments, a2 as projectBlocksLayout, a3 as buildListLabels, a4 as textStyleToFontSizePt, a5 as PX_PER_POINT, a6 as DEFAULT_FONT_SIZE_PX, a7 as isDoubleUnderlineStyle, a8 as isWavyUnderlineStyle, a9 as underlineStyleLineWidthPx, aa as underlineStyleDashArray, ab as resolveListLabel, ac as getListLabelInset, ad as getAlignedListLabelInset, ae as getParagraphBorderInsets, af as buildSegmentTable, ag as buildCanvasTableLayout, ah as normalizeFamily, ai as ROBOTO_FONT_FILES, aj as loadFontAsset, ak as OFFICE_COMPAT_FONT_FAMILIES, al as buildSfnt, am as defaultFontDecoderRegistry, an as SfntFontProgram, ao as collectPdfFontFamilies, ap as projectDocumentLayout, aq as getPageHeaderZoneTop, ar as getPageBodyTop, as as getPageColumnRects, at as findFootnoteReference, au as FOOTNOTE_MARKER_GUTTER_PX, av as resolveImporterForFile, aw as createEditorStateFromDocument, ax as getDocumentParagraphsCanonical, ay as getToolbarStyleState, az as STANDARD_FONT_SIZES_PT, aA as fontSizePxToPt, aB as probeLocalFontFamilies, aC as createInitialEditorState, aD as parseFontSizePtToPx, aE as formatFontSizePt, aF as listKindForTag, aG as isParagraphTag, aH as collectInlineRuns, aI as parseParagraphStyle, aJ as getHeadingLevel, aK as preciseFontModeVersion, aL as isPreciseFontModeEnabled, aM as togglePreciseFontMode, aN as nextFontSizePt, aO as previousFontSizePt, aP as fontSizePtToPx, aQ as createDefaultToolbarPreset, aR as MenuRegistry, aS as createToolbarRegistry, aT as Editor, aU as resolveCommandRef, aV as commandRefName, aW as InlineShell, aX as BalloonShell, aY as DocumentShell, aZ as createMemo, a_ as getCaretRectFromSnapshot, a$ as getParagraphRectFromSnapshot, b0 as createComponent, b1 as CaretOverlay, b2 as Show, b3 as createRenderEffect, b4 as style, b5 as setAttribute, b6 as setStyleProperty, b7 as memo, b8 as template, b9 as useI18n, ba as insert, bb as use, bc as addEventListener, bd as Dialog, be as delegateEvents, bf as className, bg as For, bh as UNDERLINE_STYLE_OPTIONS, bi as Tabs, bj as measureParagraphMinContentWidthPx, bk as getEditableBlocksForZone, bl as findParagraphLocation, bm as createSectionBoundaryParagraph, bn as normalizePageSettings, bo as DEFAULT_EDITOR_PAGE_SETTINGS, bp as markStart, bq as markEnd, br as getParagraphEntries, bs as getParagraphById, bt as PluginUiHost, bu as OasisEditorEditor, bv as perfTimer, bw as OasisBrandMark, bx as setPreciseFontPreference, by as setWelcomeSeen, bz as enablePreciseFontMode, bA as createOasisEditorClient, bB as createEditorZoom, bC as startLongTaskObserver, bD as installGlobalReport, bE as applyStoredPreciseFontPreference, bF as getWelcomeSeen, bG as isLocalFontAccessSupported, bH as EDITOR_SCROLL_PADDING_PX, bI as Toolbar, bJ as OasisEditorLoading, bK as I18nProvider, bL as createEditorLogger, bM as createTranslator, bN as getCachedCanvasImage, bO as registerDomStatsSurface } from "./index-CEIWNJ4A.js";
4
+ import { n as normalizeSelection, g as getParagraphs, c as createEditorParagraphFromRuns, a as getParagraphLength, b as createEditorRun, d as getDocumentSections, e as createEditorStyledRun, f as getParagraphText, h as getActiveZone, i as getActiveSectionIndex, p as positionToParagraphOffset, j as paragraphOffsetToPosition, k as clampPosition, l as findParagraphIndex, m as createCollapsedSelection, o as isSelectionCollapsed, E as EMU_PER_PX, q as createEditorParagraph, r as getBlockParagraphs, s as findParagraphTableLocation, t as buildTableCellLayout, P as PT_PER_PX, u as createEditorTableCell, v as createEditorTableRow, w as createEditorTable, x as underlineStyleToCssDecorationStyle, y as resolveImageSrc, z as createEditorFootnote, A as createFootnoteReferenceRun, B as renumberFootnotes, C as iterateFootnoteReferenceRuns, D as getFootnoteDisplayMarker, F as createSignal, G as createEffect, H as onCleanup, I as buildCanvasLayoutSnapshot, J as on, K as onMount, L as debounce, M as unwrap, N as getDocumentParagraphs, O as getDocumentSectionsCanonical, Q as createEditorDocument, R as getPageContentWidth, S as getDocumentPageSettings, T as getTableCellContentWidthForParagraph, U as resolveResizedDimensions, V as resolveTextBoxRenderHeight, W as TWIPS_PER_POINT, X as PX_PER_INCH, Y as TWIPS_PER_INCH, Z as resolveEffectiveParagraphStyle, _ as resolveEffectiveTextStyleForParagraph, $ as EMU_PER_PT, a0 as iterateEndnoteReferenceRuns, a1 as JSZip, a2 as imageContentTypeDefaults, a3 as imageExtensionFromMime, a4 as pxToPt$1, a5 as resolveFloatingObjectRect, a6 as getTextBoxFloatingGeometry, a7 as getPresetPathSegments, a8 as projectBlocksLayout, a9 as buildListLabels, aa as textStyleToFontSizePt, ab as PX_PER_POINT, ac as DEFAULT_FONT_SIZE_PX, ad as isDoubleUnderlineStyle, ae as isWavyUnderlineStyle, af as underlineStyleLineWidthPx, ag as underlineStyleDashArray, ah as resolveListLabel, ai as getListLabelInset, aj as getAlignedListLabelInset, ak as getParagraphBorderInsets, al as buildSegmentTable, am as buildCanvasTableLayout, an as normalizeFamily, ao as ROBOTO_FONT_FILES, ap as loadFontAsset, aq as OFFICE_COMPAT_FONT_FAMILIES, ar as buildSfnt, as as defaultFontDecoderRegistry, at as SfntFontProgram, au as collectPdfFontFamilies, av as projectDocumentLayout, aw as getPageHeaderZoneTop, ax as getPageBodyTop, ay as getPageColumnRects, az as findFootnoteReference, aA as FOOTNOTE_MARKER_GUTTER_PX, aB as resolveImporterForFile, aC as createEditorStateFromDocument, aD as getDocumentParagraphsCanonical, aE as getToolbarStyleState, aF as STANDARD_FONT_SIZES_PT, aG as fontSizePxToPt, aH as probeLocalFontFamilies, aI as createInitialEditorState, aJ as parseFontSizePtToPx, aK as formatFontSizePt, aL as listKindForTag, aM as isParagraphTag, aN as collectInlineRuns, aO as parseParagraphStyle, aP as getCachedCanvasImage, aQ as getHeadingLevel, aR as preciseFontModeVersion, aS as isPreciseFontModeEnabled, aT as togglePreciseFontMode, aU as nextFontSizePt, aV as previousFontSizePt, aW as fontSizePtToPx, aX as createDefaultToolbarPreset, aY as MenuRegistry, aZ as createToolbarRegistry, a_ as Editor, a$ as resolveCommandRef, b0 as commandRefName, b1 as InlineShell, b2 as BalloonShell, b3 as DocumentShell, b4 as createMemo, b5 as getCaretRectFromSnapshot, b6 as getParagraphRectFromSnapshot, b7 as createComponent, b8 as CaretOverlay, b9 as Show, ba as createRenderEffect, bb as style, bc as setAttribute, bd as setStyleProperty, be as memo, bf as template, bg as useI18n, bh as insert, bi as use, bj as addEventListener, bk as Dialog, bl as delegateEvents, bm as className, bn as For, bo as UNDERLINE_STYLE_OPTIONS, bp as Tabs, bq as measureParagraphMinContentWidthPx, br as getEditableBlocksForZone, bs as findParagraphLocation, bt as createSectionBoundaryParagraph, bu as normalizePageSettings, bv as DEFAULT_EDITOR_PAGE_SETTINGS, bw as markStart, bx as markEnd, by as getParagraphEntries, bz as getParagraphById, bA as PluginUiHost, bB as OasisEditorEditor, bC as perfTimer, bD as OasisBrandMark, bE as setPreciseFontPreference, bF as setWelcomeSeen, bG as enablePreciseFontMode, bH as createOasisEditorClient, bI as createEditorZoom, bJ as startLongTaskObserver, bK as installGlobalReport, bL as applyStoredPreciseFontPreference, bM as getWelcomeSeen, bN as isLocalFontAccessSupported, bO as EDITOR_SCROLL_PADDING_PX, bP as Toolbar, bQ as OasisEditorLoading, bR as I18nProvider, bS as createEditorLogger, bT as createTranslator, bU as registerDomStatsSurface } from "./index-Cgq5T30U.js";
5
5
  function getSelectedObjectRun(state, predicate) {
6
6
  const normalized = normalizeSelection(state);
7
7
  if (normalized.isCollapsed || normalized.startIndex !== normalized.endIndex || normalized.endParagraphOffset - normalized.startParagraphOffset !== 1) {
@@ -1252,7 +1252,6 @@ function moveSelectedImageToPosition(state, targetPosition) {
1252
1252
  withSelection(paragraphOffsetToPosition(insertedParagraph, insertedOffset))
1253
1253
  );
1254
1254
  }
1255
- const EMU_PER_PX$1 = 9525;
1256
1255
  const MIN_TEXT_BOX_SIZE_PX = 24;
1257
1256
  function getSelectedTextBoxRun(state) {
1258
1257
  return getSelectedObjectRun(state, (run) => Boolean(run.textBox));
@@ -1266,7 +1265,7 @@ function shiftFloatingForResize(floating, widthDelta, heightDelta, growsFromWest
1266
1265
  ...next,
1267
1266
  positionH: {
1268
1267
  ...h ?? {},
1269
- offset: ((h == null ? void 0 : h.offset) ?? 0) - widthDelta * EMU_PER_PX$1
1268
+ offset: ((h == null ? void 0 : h.offset) ?? 0) - widthDelta * EMU_PER_PX
1270
1269
  }
1271
1270
  };
1272
1271
  }
@@ -1278,7 +1277,7 @@ function shiftFloatingForResize(floating, widthDelta, heightDelta, growsFromWest
1278
1277
  ...next,
1279
1278
  positionV: {
1280
1279
  ...v ?? {},
1281
- offset: ((v == null ? void 0 : v.offset) ?? 0) - heightDelta * EMU_PER_PX$1
1280
+ offset: ((v == null ? void 0 : v.offset) ?? 0) - heightDelta * EMU_PER_PX
1282
1281
  }
1283
1282
  };
1284
1283
  }
@@ -2882,7 +2881,7 @@ function parseWidthToPt(value) {
2882
2881
  }
2883
2882
  if (trimmed.endsWith("px")) {
2884
2883
  const parsed2 = Number.parseFloat(trimmed.slice(0, -2));
2885
- return Number.isFinite(parsed2) ? parsed2 * (72 / 96) : null;
2884
+ return Number.isFinite(parsed2) ? parsed2 * PT_PER_PX : null;
2886
2885
  }
2887
2886
  if (!/^[+-]?\d+(\.\d+)?$/.test(trimmed)) {
2888
2887
  return null;
@@ -3840,186 +3839,6 @@ function insertFootnote(state) {
3840
3839
  activeFootnoteId: footnote.id
3841
3840
  };
3842
3841
  }
3843
- const RECTANGLE = [
3844
- { x: 0, y: 0 },
3845
- { x: 1, y: 0 },
3846
- { x: 1, y: 1 },
3847
- { x: 0, y: 1 }
3848
- ];
3849
- const MAX_SIDE = 256;
3850
- const ALPHA_THRESHOLD = 128;
3851
- const OPAQUE_RATIO = 0.985;
3852
- const MAX_POINTS = 40;
3853
- const contourCache = /* @__PURE__ */ new Map();
3854
- function rectangle() {
3855
- return RECTANGLE.map((point) => ({ ...point }));
3856
- }
3857
- const DIRS = [
3858
- [0, -1],
3859
- [1, -1],
3860
- [1, 0],
3861
- [1, 1],
3862
- [0, 1],
3863
- [-1, 1],
3864
- [-1, 0],
3865
- [-1, -1]
3866
- ];
3867
- function buildAlphaMask(img) {
3868
- const naturalW = img.naturalWidth || img.width;
3869
- const naturalH = img.naturalHeight || img.height;
3870
- if (!naturalW || !naturalH) {
3871
- return null;
3872
- }
3873
- const scale = Math.min(1, MAX_SIDE / Math.max(naturalW, naturalH));
3874
- const width = Math.max(1, Math.round(naturalW * scale));
3875
- const height = Math.max(1, Math.round(naturalH * scale));
3876
- const canvas = document.createElement("canvas");
3877
- canvas.width = width;
3878
- canvas.height = height;
3879
- const ctx = canvas.getContext("2d", { willReadFrequently: true });
3880
- if (!ctx) {
3881
- return null;
3882
- }
3883
- ctx.drawImage(img, 0, 0, width, height);
3884
- let pixels;
3885
- try {
3886
- pixels = ctx.getImageData(0, 0, width, height).data;
3887
- } catch {
3888
- return null;
3889
- }
3890
- const mask = new Uint8Array(width * height);
3891
- let foreground = 0;
3892
- for (let i = 0; i < mask.length; i += 1) {
3893
- if (pixels[i * 4 + 3] >= ALPHA_THRESHOLD) {
3894
- mask[i] = 1;
3895
- foreground += 1;
3896
- }
3897
- }
3898
- return { mask, width, height, foreground };
3899
- }
3900
- function traceBoundary(mask, width, height) {
3901
- const at = (x, y) => x >= 0 && x < width && y >= 0 && y < height && mask[y * width + x] === 1;
3902
- let startX = -1;
3903
- let startY = -1;
3904
- for (let y = 0; y < height && startY < 0; y += 1) {
3905
- for (let x = 0; x < width; x += 1) {
3906
- if (mask[y * width + x] === 1) {
3907
- startX = x;
3908
- startY = y;
3909
- break;
3910
- }
3911
- }
3912
- }
3913
- if (startX < 0) {
3914
- return [];
3915
- }
3916
- const contour = [];
3917
- let bx = startX;
3918
- let by = startY;
3919
- let backtrack = 6;
3920
- const maxSteps = width * height * 4;
3921
- for (let step = 0; step < maxSteps; step += 1) {
3922
- let moved = false;
3923
- for (let k = 1; k <= 8; k += 1) {
3924
- const dir = (backtrack + k) % 8;
3925
- const [dx, dy] = DIRS[dir];
3926
- const nx = bx + dx;
3927
- const ny = by + dy;
3928
- if (at(nx, ny)) {
3929
- contour.push([bx, by]);
3930
- backtrack = (dir + 4) % 8;
3931
- bx = nx;
3932
- by = ny;
3933
- moved = true;
3934
- break;
3935
- }
3936
- }
3937
- if (!moved) {
3938
- contour.push([bx, by]);
3939
- break;
3940
- }
3941
- if (bx === startX && by === startY && contour.length > 1) {
3942
- break;
3943
- }
3944
- }
3945
- return contour;
3946
- }
3947
- function perpendicularDistance(point, lineStart, lineEnd) {
3948
- const [px, py] = point;
3949
- const [ax, ay] = lineStart;
3950
- const [bx, by] = lineEnd;
3951
- const dx = bx - ax;
3952
- const dy = by - ay;
3953
- const lengthSq = dx * dx + dy * dy;
3954
- if (lengthSq === 0) {
3955
- return Math.hypot(px - ax, py - ay);
3956
- }
3957
- const cross = Math.abs(dx * (ay - py) - dy * (ax - px));
3958
- return cross / Math.sqrt(lengthSq);
3959
- }
3960
- function douglasPeucker(points, tolerance) {
3961
- if (points.length < 3) {
3962
- return points.slice();
3963
- }
3964
- let maxDist = 0;
3965
- let index = 0;
3966
- const first = points[0];
3967
- const last = points[points.length - 1];
3968
- for (let i = 1; i < points.length - 1; i += 1) {
3969
- const dist = perpendicularDistance(points[i], first, last);
3970
- if (dist > maxDist) {
3971
- maxDist = dist;
3972
- index = i;
3973
- }
3974
- }
3975
- if (maxDist <= tolerance) {
3976
- return [first, last];
3977
- }
3978
- const left = douglasPeucker(points.slice(0, index + 1), tolerance);
3979
- const right = douglasPeucker(points.slice(index), tolerance);
3980
- return [...left.slice(0, -1), ...right];
3981
- }
3982
- function traceAlphaMaskContour(mask, width, height) {
3983
- let foreground = 0;
3984
- for (let i = 0; i < mask.length; i += 1) {
3985
- if (mask[i] === 1) foreground += 1;
3986
- }
3987
- if (width <= 0 || height <= 0 || foreground === 0 || foreground / (width * height) >= OPAQUE_RATIO) {
3988
- return rectangle();
3989
- }
3990
- const boundary = traceBoundary(mask, width, height);
3991
- if (boundary.length < 3) {
3992
- return rectangle();
3993
- }
3994
- const tolerance = Math.max(width, height) * 0.012;
3995
- let simplified = douglasPeucker(boundary, tolerance);
3996
- let extraTolerance = tolerance;
3997
- while (simplified.length > MAX_POINTS) {
3998
- extraTolerance *= 1.6;
3999
- simplified = douglasPeucker(boundary, extraTolerance);
4000
- }
4001
- if (simplified.length < 3) {
4002
- return rectangle();
4003
- }
4004
- return simplified.map(([x, y]) => ({
4005
- x: Math.min(1, Math.max(0, x / width)),
4006
- y: Math.min(1, Math.max(0, y / height))
4007
- }));
4008
- }
4009
- function traceImageAlphaContour(img) {
4010
- const cacheKey = img.src;
4011
- const cached = contourCache.get(cacheKey);
4012
- if (cached) {
4013
- return cached.map((point) => ({ ...point }));
4014
- }
4015
- const built = buildAlphaMask(img);
4016
- if (!built) {
4017
- return rectangle();
4018
- }
4019
- const polygon = traceAlphaMaskContour(built.mask, built.width, built.height);
4020
- contourCache.set(cacheKey, polygon);
4021
- return polygon.map((point) => ({ ...point }));
4022
- }
4023
3842
  function cloneBlock(block) {
4024
3843
  return block.type === "paragraph" ? {
4025
3844
  ...block,
@@ -7752,9 +7571,6 @@ const WORD_NS$1 = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
7752
7571
  const PACKAGE_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
7753
7572
  const OFFICE_REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
7754
7573
  const WORD14_NS = "http://schemas.microsoft.com/office/word/2010/wordml";
7755
- const TWIPS_PER_INCH$1 = 1440;
7756
- const PX_PER_INCH$1 = 96;
7757
- const TWIPS_PER_POINT = 20;
7758
7574
  function escapeXml(text) {
7759
7575
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
7760
7576
  }
@@ -7762,19 +7578,19 @@ function pxToTwips(value, fallback) {
7762
7578
  if (!Number.isFinite(value)) {
7763
7579
  return fallback;
7764
7580
  }
7765
- return Math.max(0, Math.round(value / PX_PER_INCH$1 * TWIPS_PER_INCH$1));
7581
+ return Math.max(0, Math.round(value / PX_PER_INCH * TWIPS_PER_INCH));
7766
7582
  }
7767
7583
  function toTwips(value) {
7768
7584
  if (value === void 0 || value === null || !Number.isFinite(value)) {
7769
7585
  return null;
7770
7586
  }
7771
- return Math.round(value / PX_PER_INCH$1 * TWIPS_PER_INCH$1);
7587
+ return Math.round(value / PX_PER_INCH * TWIPS_PER_INCH);
7772
7588
  }
7773
7589
  function toHalfPoints(value) {
7774
7590
  if (value === void 0 || value === null || !Number.isFinite(value)) {
7775
7591
  return null;
7776
7592
  }
7777
- return Math.round(value / PX_PER_INCH$1 * 72 * 2);
7593
+ return Math.round(value / PX_PER_INCH * 72 * 2);
7778
7594
  }
7779
7595
  function pointsToTwips(value) {
7780
7596
  if (value === void 0 || value === null || !Number.isFinite(value)) {
@@ -8516,8 +8332,6 @@ function serializeParagraphProperties(paragraph, numberingInfo, styles, override
8516
8332
  }
8517
8333
  return parts.length > 0 ? `<w:pPr>${parts.join("")}</w:pPr>` : "";
8518
8334
  }
8519
- const EMU_PER_PX = 9525;
8520
- const EMU_PER_PT = 12700;
8521
8335
  const DOCX_HIGHLIGHT_COLORS = {
8522
8336
  black: [0, 0, 0],
8523
8337
  blue: [0, 0, 255],
@@ -10937,7 +10751,7 @@ function drawListPrefix(writer, pageIndex, paragraph, line, document2, originX,
10937
10751
  });
10938
10752
  const labelInset = getListLabelInset(paragraph, document2.styles);
10939
10753
  const fontSizePt = textStyleToFontSizePt(styles);
10940
- const estimatedLabelWidthPx = prefix.length * fontSizePt * 0.62 * (96 / 72);
10754
+ const estimatedLabelWidthPx = prefix.length * fontSizePt * 0.62 * PX_PER_POINT;
10941
10755
  const alignedInset = getAlignedListLabelInset(
10942
10756
  paragraph,
10943
10757
  document2.styles,
@@ -40916,11 +40730,251 @@ function createEditorTableContextMenuActions(deps) {
40916
40730
  )
40917
40731
  };
40918
40732
  }
40733
+ const RECTANGLE = [
40734
+ { x: 0, y: 0 },
40735
+ { x: 1, y: 0 },
40736
+ { x: 1, y: 1 },
40737
+ { x: 0, y: 1 }
40738
+ ];
40739
+ const MAX_SIDE = 256;
40740
+ const ALPHA_THRESHOLD = 128;
40741
+ const OPAQUE_RATIO = 0.985;
40742
+ const MAX_POINTS = 40;
40743
+ const contourCache = /* @__PURE__ */ new Map();
40744
+ function rectangle() {
40745
+ return RECTANGLE.map((point) => ({ ...point }));
40746
+ }
40747
+ const DIRS = [
40748
+ [0, -1],
40749
+ [1, -1],
40750
+ [1, 0],
40751
+ [1, 1],
40752
+ [0, 1],
40753
+ [-1, 1],
40754
+ [-1, 0],
40755
+ [-1, -1]
40756
+ ];
40757
+ function buildAlphaMask(img) {
40758
+ const naturalW = img.naturalWidth || img.width;
40759
+ const naturalH = img.naturalHeight || img.height;
40760
+ if (!naturalW || !naturalH) {
40761
+ return null;
40762
+ }
40763
+ const scale = Math.min(1, MAX_SIDE / Math.max(naturalW, naturalH));
40764
+ const width = Math.max(1, Math.round(naturalW * scale));
40765
+ const height = Math.max(1, Math.round(naturalH * scale));
40766
+ const canvas = document.createElement("canvas");
40767
+ canvas.width = width;
40768
+ canvas.height = height;
40769
+ const ctx = canvas.getContext("2d", { willReadFrequently: true });
40770
+ if (!ctx) {
40771
+ return null;
40772
+ }
40773
+ ctx.drawImage(img, 0, 0, width, height);
40774
+ let pixels;
40775
+ try {
40776
+ pixels = ctx.getImageData(0, 0, width, height).data;
40777
+ } catch {
40778
+ return null;
40779
+ }
40780
+ const mask = new Uint8Array(width * height);
40781
+ let foreground = 0;
40782
+ for (let i = 0; i < mask.length; i += 1) {
40783
+ if (pixels[i * 4 + 3] >= ALPHA_THRESHOLD) {
40784
+ mask[i] = 1;
40785
+ foreground += 1;
40786
+ }
40787
+ }
40788
+ return { mask, width, height, foreground };
40789
+ }
40790
+ function traceBoundary(mask, width, height) {
40791
+ const at = (x, y) => x >= 0 && x < width && y >= 0 && y < height && mask[y * width + x] === 1;
40792
+ let startX = -1;
40793
+ let startY = -1;
40794
+ for (let y = 0; y < height && startY < 0; y += 1) {
40795
+ for (let x = 0; x < width; x += 1) {
40796
+ if (mask[y * width + x] === 1) {
40797
+ startX = x;
40798
+ startY = y;
40799
+ break;
40800
+ }
40801
+ }
40802
+ }
40803
+ if (startX < 0) {
40804
+ return [];
40805
+ }
40806
+ const contour = [];
40807
+ let bx = startX;
40808
+ let by = startY;
40809
+ let backtrack = 6;
40810
+ const maxSteps = width * height * 4;
40811
+ for (let step = 0; step < maxSteps; step += 1) {
40812
+ let moved = false;
40813
+ for (let k = 1; k <= 8; k += 1) {
40814
+ const dir = (backtrack + k) % 8;
40815
+ const [dx, dy] = DIRS[dir];
40816
+ const nx = bx + dx;
40817
+ const ny = by + dy;
40818
+ if (at(nx, ny)) {
40819
+ contour.push([bx, by]);
40820
+ backtrack = (dir + 4) % 8;
40821
+ bx = nx;
40822
+ by = ny;
40823
+ moved = true;
40824
+ break;
40825
+ }
40826
+ }
40827
+ if (!moved) {
40828
+ contour.push([bx, by]);
40829
+ break;
40830
+ }
40831
+ if (bx === startX && by === startY && contour.length > 1) {
40832
+ break;
40833
+ }
40834
+ }
40835
+ return contour;
40836
+ }
40837
+ function perpendicularDistance(point, lineStart, lineEnd) {
40838
+ const [px, py] = point;
40839
+ const [ax, ay] = lineStart;
40840
+ const [bx, by] = lineEnd;
40841
+ const dx = bx - ax;
40842
+ const dy = by - ay;
40843
+ const lengthSq = dx * dx + dy * dy;
40844
+ if (lengthSq === 0) {
40845
+ return Math.hypot(px - ax, py - ay);
40846
+ }
40847
+ const cross = Math.abs(dx * (ay - py) - dy * (ax - px));
40848
+ return cross / Math.sqrt(lengthSq);
40849
+ }
40850
+ function douglasPeucker(points, tolerance) {
40851
+ if (points.length < 3) {
40852
+ return points.slice();
40853
+ }
40854
+ let maxDist = 0;
40855
+ let index = 0;
40856
+ const first = points[0];
40857
+ const last = points[points.length - 1];
40858
+ for (let i = 1; i < points.length - 1; i += 1) {
40859
+ const dist = perpendicularDistance(points[i], first, last);
40860
+ if (dist > maxDist) {
40861
+ maxDist = dist;
40862
+ index = i;
40863
+ }
40864
+ }
40865
+ if (maxDist <= tolerance) {
40866
+ return [first, last];
40867
+ }
40868
+ const left = douglasPeucker(points.slice(0, index + 1), tolerance);
40869
+ const right = douglasPeucker(points.slice(index), tolerance);
40870
+ return [...left.slice(0, -1), ...right];
40871
+ }
40872
+ function traceAlphaMaskContour(mask, width, height) {
40873
+ let foreground = 0;
40874
+ for (let i = 0; i < mask.length; i += 1) {
40875
+ if (mask[i] === 1) foreground += 1;
40876
+ }
40877
+ if (width <= 0 || height <= 0 || foreground === 0 || foreground / (width * height) >= OPAQUE_RATIO) {
40878
+ return rectangle();
40879
+ }
40880
+ const boundary = traceBoundary(mask, width, height);
40881
+ if (boundary.length < 3) {
40882
+ return rectangle();
40883
+ }
40884
+ const tolerance = Math.max(width, height) * 0.012;
40885
+ let simplified = douglasPeucker(boundary, tolerance);
40886
+ let extraTolerance = tolerance;
40887
+ while (simplified.length > MAX_POINTS) {
40888
+ extraTolerance *= 1.6;
40889
+ simplified = douglasPeucker(boundary, extraTolerance);
40890
+ }
40891
+ if (simplified.length < 3) {
40892
+ return rectangle();
40893
+ }
40894
+ return simplified.map(([x, y]) => ({
40895
+ x: Math.min(1, Math.max(0, x / width)),
40896
+ y: Math.min(1, Math.max(0, y / height))
40897
+ }));
40898
+ }
40899
+ function traceImageAlphaContour(img) {
40900
+ const cacheKey = img.src;
40901
+ const cached = contourCache.get(cacheKey);
40902
+ if (cached) {
40903
+ return cached.map((point) => ({ ...point }));
40904
+ }
40905
+ const built = buildAlphaMask(img);
40906
+ if (!built) {
40907
+ return rectangle();
40908
+ }
40909
+ const polygon = traceAlphaMaskContour(built.mask, built.width, built.height);
40910
+ contourCache.set(cacheKey, polygon);
40911
+ return polygon.map((point) => ({ ...point }));
40912
+ }
40913
+ function createEditorLayoutOptionsController(deps) {
40914
+ const { state, resetTransactionGrouping, applyTransactionalState, focusInput } = deps;
40915
+ const layoutOptionsTarget = () => {
40916
+ if (getSelectedImageRun(state())) return "image";
40917
+ if (getSelectedTextBoxRun(state())) return "textBox";
40918
+ return null;
40919
+ };
40920
+ const applyLayoutOptionPatch = (mergeKey, apply) => {
40921
+ const target = layoutOptionsTarget();
40922
+ if (!target) return;
40923
+ resetTransactionGrouping();
40924
+ applyTransactionalState((current) => apply(current, target), { mergeKey });
40925
+ focusInput();
40926
+ };
40927
+ const ensureImageWrapContour = (runId, src) => {
40928
+ const resolved = resolveImageSrc(state().document, src);
40929
+ const applyContour = (img2) => {
40930
+ const polygon = traceImageAlphaContour(img2);
40931
+ applyTransactionalState(
40932
+ (current) => setImageWrapPolygon(current, runId, polygon),
40933
+ { mergeKey: "layoutWrapPolygon" }
40934
+ );
40935
+ };
40936
+ const img = getCachedCanvasImage(resolved, () => {
40937
+ if (img.naturalWidth > 0) applyContour(img);
40938
+ });
40939
+ if (img.complete && img.naturalWidth > 0) {
40940
+ applyContour(img);
40941
+ }
40942
+ };
40943
+ return {
40944
+ target: layoutOptionsTarget,
40945
+ preset: () => {
40946
+ const target = layoutOptionsTarget();
40947
+ if (target === "image") return getSelectedImageWrapPreset(state());
40948
+ if (target === "textBox") return getSelectedTextBoxWrapPreset(state());
40949
+ return null;
40950
+ },
40951
+ fixedPosition: () => {
40952
+ const target = layoutOptionsTarget();
40953
+ if (target === "image") return isSelectedImageFixedPosition(state());
40954
+ if (target === "textBox") return isSelectedTextBoxFixedPosition(state());
40955
+ return false;
40956
+ },
40957
+ setPreset: (preset) => {
40958
+ applyLayoutOptionPatch(
40959
+ "layoutWrapPreset",
40960
+ (current, target) => target === "image" ? setSelectedImageWrapPreset(current, preset) : setSelectedTextBoxWrapPreset(current, preset)
40961
+ );
40962
+ if (preset === "tight" || preset === "through") {
40963
+ const selected = getSelectedImageRun(state());
40964
+ const image = selected == null ? void 0 : selected.run.image;
40965
+ if (image && !image.wrapPolygon) {
40966
+ ensureImageWrapContour(selected.run.id, image.src);
40967
+ }
40968
+ }
40969
+ },
40970
+ setFixedPosition: (fixed) => applyLayoutOptionPatch(
40971
+ "layoutFixedPosition",
40972
+ (current, target) => target === "image" ? setSelectedImageFixedPosition(current, fixed) : setSelectedTextBoxFixedPosition(current, fixed)
40973
+ )
40974
+ };
40975
+ }
40919
40976
  const DEFAULT_TOC_MAX_LEVEL = 3;
40920
40977
  const TOC_INSTRUCTION = ' TOC \\o "1-3" \\h \\z \\u ';
40921
- const PX_TO_PT = 72 / 96;
40922
- const TWIPS_PER_INCH = 1440;
40923
- const PX_PER_INCH = 96;
40924
40978
  const twipsToPx = (twips) => Math.round(twips / TWIPS_PER_INCH * PX_PER_INCH);
40925
40979
  function collectTocHeadings(state, maxLevel = DEFAULT_TOC_MAX_LEVEL) {
40926
40980
  var _a;
@@ -40957,7 +41011,7 @@ function buildEntryParagraph(heading, pageNumber, rightTabPositionPt) {
40957
41011
  function rightTabPositionForSection(section) {
40958
41012
  const { width, margins } = section.pageSettings;
40959
41013
  const contentWidthPx = Math.max(0, width - margins.left - margins.right);
40960
- return Math.round(contentWidthPx * PX_TO_PT * 100) / 100;
41014
+ return Math.round(contentWidthPx * PT_PER_PX * 100) / 100;
40961
41015
  }
40962
41016
  function buildStartMarkerParagraph() {
40963
41017
  return makeParagraph([
@@ -47129,62 +47183,12 @@ function OasisEditorApp(props = {}) {
47129
47183
  runtimeClient.emit("selectionChange", snapshot.selection);
47130
47184
  });
47131
47185
  const selectedImageRun = () => getSelectedImageRun(state);
47132
- const selectedTextBoxRun = () => getSelectedTextBoxRun(state);
47133
- const layoutOptionsTarget = () => {
47134
- if (selectedImageRun()) return "image";
47135
- if (selectedTextBoxRun()) return "textBox";
47136
- return null;
47137
- };
47138
- const applyLayoutOptionPatch = (mergeKey, apply) => {
47139
- const target = layoutOptionsTarget();
47140
- if (!target) return;
47141
- resetTransactionGrouping();
47142
- applyTransactionalState((current) => apply(current, target), {
47143
- mergeKey
47144
- });
47145
- focusInput();
47146
- };
47147
- const ensureImageWrapContour = (runId, src) => {
47148
- const resolved = resolveImageSrc(state.document, src);
47149
- const applyContour = (img2) => {
47150
- const polygon = traceImageAlphaContour(img2);
47151
- applyTransactionalState((current) => setImageWrapPolygon(current, runId, polygon), {
47152
- mergeKey: "layoutWrapPolygon"
47153
- });
47154
- };
47155
- const img = getCachedCanvasImage(resolved, () => {
47156
- if (img.naturalWidth > 0) applyContour(img);
47157
- });
47158
- if (img.complete && img.naturalWidth > 0) {
47159
- applyContour(img);
47160
- }
47161
- };
47162
- const layoutOptionsOverlay = {
47163
- target: layoutOptionsTarget,
47164
- preset: () => {
47165
- const target = layoutOptionsTarget();
47166
- if (target === "image") return getSelectedImageWrapPreset(state);
47167
- if (target === "textBox") return getSelectedTextBoxWrapPreset(state);
47168
- return null;
47169
- },
47170
- fixedPosition: () => {
47171
- const target = layoutOptionsTarget();
47172
- if (target === "image") return isSelectedImageFixedPosition(state);
47173
- if (target === "textBox") return isSelectedTextBoxFixedPosition(state);
47174
- return false;
47175
- },
47176
- setPreset: (preset) => {
47177
- applyLayoutOptionPatch("layoutWrapPreset", (current, target) => target === "image" ? setSelectedImageWrapPreset(current, preset) : setSelectedTextBoxWrapPreset(current, preset));
47178
- if (preset === "tight" || preset === "through") {
47179
- const selected = getSelectedImageRun(state);
47180
- const image = selected == null ? void 0 : selected.run.image;
47181
- if (image && !image.wrapPolygon) {
47182
- ensureImageWrapContour(selected.run.id, image.src);
47183
- }
47184
- }
47185
- },
47186
- setFixedPosition: (fixed) => applyLayoutOptionPatch("layoutFixedPosition", (current, target) => target === "image" ? setSelectedImageFixedPosition(current, fixed) : setSelectedTextBoxFixedPosition(current, fixed))
47187
- };
47186
+ const layoutOptionsOverlay = createEditorLayoutOptionsController({
47187
+ state: () => state,
47188
+ resetTransactionGrouping,
47189
+ applyTransactionalState,
47190
+ focusInput
47191
+ });
47188
47192
  const canvasHitResolver = createCanvasSurfaceHitResolver({
47189
47193
  state: () => state,
47190
47194
  surfaceRef: () => surfaceRef() ?? null,