ooxml-core 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{PptxHandler-VQQS4VS6.mjs → PptxHandler-ZPJNHEZZ.mjs} +2 -2
- package/dist/automation/index.cjs +7972 -5580
- package/dist/automation/index.mjs +7972 -5580
- package/dist/{chunk-5U27IVB7.mjs → chunk-BB55ASTX.mjs} +3 -3
- package/dist/{chunk-V2BIGIH4.mjs → chunk-H4TPDZV4.mjs} +1 -1
- package/dist/{chunk-5VLNF4OX.mjs → chunk-IVDC75E5.mjs} +1 -1
- package/dist/{chunk-XBNSBDNT.mjs → chunk-QPQDLSJQ.mjs} +1 -1
- package/dist/{chunk-XSFHGZFH.mjs → chunk-XGLKW3JJ.mjs} +5 -3
- package/dist/pptx/automation/index.cjs +4 -2
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/cli/index.cjs +4 -2
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/index.cjs +4 -2
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +91 -33
- package/dist/teams/index.mjs +91 -33
- package/dist/visio/clipboard-resources.d.ts +11 -0
- package/dist/visio/clipboard-resources.d.ts.map +1 -0
- package/dist/visio/clipboard-types.d.ts +26 -0
- package/dist/visio/clipboard-types.d.ts.map +1 -0
- package/dist/visio/clipboard-xml.d.ts +8 -0
- package/dist/visio/clipboard-xml.d.ts.map +1 -0
- package/dist/visio/clipboard.d.ts +7 -0
- package/dist/visio/clipboard.d.ts.map +1 -0
- package/dist/visio/create-document.d.ts +8 -0
- package/dist/visio/create-document.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +29 -3
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-delete.d.ts +9 -0
- package/dist/visio/edit-delete.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-commands.d.ts +14 -0
- package/dist/visio/edit-duplicate-commands.d.ts.map +1 -0
- package/dist/visio/edit-duplicate-scope.d.ts +4 -0
- package/dist/visio/edit-duplicate-scope.d.ts.map +1 -0
- package/dist/visio/edit-duplicate.d.ts +10 -0
- package/dist/visio/edit-duplicate.d.ts.map +1 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts +3 -0
- package/dist/visio/edit-formatting-cell-admission.d.ts.map +1 -0
- package/dist/visio/edit-formatting-commands.d.ts +46 -0
- package/dist/visio/edit-formatting-commands.d.ts.map +1 -0
- package/dist/visio/edit-formatting-font.d.ts +6 -0
- package/dist/visio/edit-formatting-font.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-paint-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-paint.d.ts +6 -0
- package/dist/visio/edit-formatting-paint.d.ts.map +1 -0
- package/dist/visio/edit-formatting-rows.d.ts +14 -0
- package/dist/visio/edit-formatting-rows.d.ts.map +1 -0
- package/dist/visio/edit-formatting-scope.d.ts +6 -0
- package/dist/visio/edit-formatting-scope.d.ts.map +1 -0
- package/dist/visio/edit-formatting-text.d.ts +8 -0
- package/dist/visio/edit-formatting-text.d.ts.map +1 -0
- package/dist/visio/edit-formatting.d.ts +12 -0
- package/dist/visio/edit-formatting.d.ts.map +1 -0
- package/dist/visio/edit-geometry.d.ts.map +1 -1
- package/dist/visio/edit-page-size.d.ts +5 -0
- package/dist/visio/edit-page-size.d.ts.map +1 -0
- package/dist/visio/edit-pages.d.ts.map +1 -1
- package/dist/visio/edit-paste-commands.d.ts +15 -0
- package/dist/visio/edit-paste-commands.d.ts.map +1 -0
- package/dist/visio/edit-paste.d.ts +5 -0
- package/dist/visio/edit-paste.d.ts.map +1 -0
- package/dist/visio/edit-recalculate.d.ts +3 -1
- package/dist/visio/edit-recalculate.d.ts.map +1 -1
- package/dist/visio/edit-resize-anchor.d.ts +8 -0
- package/dist/visio/edit-resize-anchor.d.ts.map +1 -0
- package/dist/visio/edit-scope.d.ts.map +1 -1
- package/dist/visio/edit-shape-create.d.ts +1 -1
- package/dist/visio/edit-shape-create.d.ts.map +1 -1
- package/dist/visio/edit-shape-order.d.ts +7 -0
- package/dist/visio/edit-shape-order.d.ts.map +1 -0
- package/dist/visio/edit-style-admission.d.ts +17 -0
- package/dist/visio/edit-style-admission.d.ts.map +1 -0
- package/dist/visio/edit-text-range-commands.d.ts +21 -0
- package/dist/visio/edit-text-range-commands.d.ts.map +1 -0
- package/dist/visio/edit-text-range-plan.d.ts +7 -0
- package/dist/visio/edit-text-range-plan.d.ts.map +1 -0
- package/dist/visio/edit-text-ranges.d.ts +4 -0
- package/dist/visio/edit-text-ranges.d.ts.map +1 -0
- package/dist/visio/edit-text-scope.d.ts +7 -0
- package/dist/visio/edit-text-scope.d.ts.map +1 -0
- package/dist/visio/edit-text-target.d.ts +3 -0
- package/dist/visio/edit-text-target.d.ts.map +1 -0
- package/dist/visio/edit-text.d.ts +1 -1
- package/dist/visio/edit-text.d.ts.map +1 -1
- package/dist/visio/edit.d.ts +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +3612 -1076
- package/dist/visio/index.d.ts +3 -1
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +3608 -1078
- package/dist/visio/line-pattern.d.ts +1 -1
- package/dist/visio/line-pattern.d.ts.map +1 -1
- package/dist/visio/line-style.d.ts.map +1 -1
- package/dist/visio/model.d.ts +26 -3
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/plain-text.d.ts +5 -0
- package/dist/visio/plain-text.d.ts.map +1 -0
- package/dist/visio/resize-anchor.d.ts +27 -0
- package/dist/visio/resize-anchor.d.ts.map +1 -0
- package/dist/visio/source-paint.d.ts +5 -0
- package/dist/visio/source-paint.d.ts.map +1 -0
- package/dist/visio/style.d.ts.map +1 -1
- package/dist/visio/theme-root.d.ts.map +1 -1
- package/dist/visio/ui/contract.d.ts +10 -6
- package/dist/visio/ui/contract.d.ts.map +1 -1
- package/dist/visio/ui/draw-plan.d.ts +32 -0
- package/dist/visio/ui/draw-plan.d.ts.map +1 -0
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/formatting.d.ts +28 -0
- package/dist/visio/ui/formatting.d.ts.map +1 -0
- package/dist/visio/ui/index.cjs +1429 -16
- package/dist/visio/ui/index.d.ts +16 -0
- package/dist/visio/ui/index.d.ts.map +1 -1
- package/dist/visio/ui/index.mjs +1380 -17
- package/dist/visio/ui/line-dash.d.ts +4 -0
- package/dist/visio/ui/line-dash.d.ts.map +1 -0
- package/dist/visio/ui/marquee.d.ts +15 -0
- package/dist/visio/ui/marquee.d.ts.map +1 -0
- package/dist/visio/ui/page-edit.d.ts.map +1 -1
- package/dist/visio/ui/page-size.d.ts +31 -0
- package/dist/visio/ui/page-size.d.ts.map +1 -0
- package/dist/visio/ui/scene-validation.d.ts.map +1 -1
- package/dist/visio/ui/selection.d.ts +12 -0
- package/dist/visio/ui/selection.d.ts.map +1 -0
- package/dist/visio/ui/shape-arrange.d.ts +17 -0
- package/dist/visio/ui/shape-arrange.d.ts.map +1 -0
- package/dist/visio/ui/shape-clipboard.d.ts +10 -0
- package/dist/visio/ui/shape-clipboard.d.ts.map +1 -0
- package/dist/visio/ui/shape-duplicate.d.ts +5 -0
- package/dist/visio/ui/shape-duplicate.d.ts.map +1 -0
- package/dist/visio/ui/shape-formatting.d.ts +14 -0
- package/dist/visio/ui/shape-formatting.d.ts.map +1 -0
- package/dist/visio/ui/shape-move.d.ts +14 -0
- package/dist/visio/ui/shape-move.d.ts.map +1 -0
- package/dist/visio/ui/shape-order.d.ts +4 -0
- package/dist/visio/ui/shape-order.d.ts.map +1 -0
- package/dist/visio/ui/shape-resize.d.ts +61 -0
- package/dist/visio/ui/shape-resize.d.ts.map +1 -0
- package/dist/visio/ui/size-position.d.ts +19 -0
- package/dist/visio/ui/size-position.d.ts.map +1 -0
- package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
- package/dist/visio/ui/svg-stroke.d.ts +8 -0
- package/dist/visio/ui/svg-stroke.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-selection.d.ts +9 -0
- package/dist/visio/ui/text-replace-selection.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts +14 -0
- package/dist/visio/ui/text-replace-snapshot.d.ts.map +1 -0
- package/dist/visio/ui/text-replace-types.d.ts +52 -0
- package/dist/visio/ui/text-replace-types.d.ts.map +1 -0
- package/dist/visio/ui/text-replace.d.ts +17 -0
- package/dist/visio/ui/text-replace.d.ts.map +1 -0
- package/dist/visio/xml-validation.d.ts.map +1 -1
- package/dist/xlsx/collab/codec.d.ts +2 -0
- package/dist/xlsx/collab/codec.d.ts.map +1 -1
- package/dist/xlsx/collab/index.cjs +5 -0
- package/dist/xlsx/collab/index.mjs +5 -0
- package/dist/xlsx/display-text.d.ts +4 -0
- package/dist/xlsx/display-text.d.ts.map +1 -0
- package/dist/xlsx/edit/cell-values.d.ts +4 -3
- package/dist/xlsx/edit/cell-values.d.ts.map +1 -1
- package/dist/xlsx/edit/clipboard.d.ts.map +1 -1
- package/dist/xlsx/edit/context.d.ts +7 -5
- package/dist/xlsx/edit/context.d.ts.map +1 -1
- package/dist/xlsx/edit/deps.d.ts +1 -1
- package/dist/xlsx/edit/deps.d.ts.map +1 -1
- package/dist/xlsx/edit/dimensions.d.ts.map +1 -1
- package/dist/xlsx/edit/fill.d.ts.map +1 -1
- package/dist/xlsx/edit/filter.d.ts.map +1 -1
- package/dist/xlsx/edit/find.d.ts.map +1 -1
- package/dist/xlsx/edit/paste-selection.d.ts.map +1 -1
- package/dist/xlsx/edit/shift-formulas.d.ts +10 -4
- package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
- package/dist/xlsx/edit/table-header-names.d.ts +3 -0
- package/dist/xlsx/edit/table-header-names.d.ts.map +1 -0
- package/dist/xlsx/edit/tables.d.ts +1 -2
- package/dist/xlsx/edit/tables.d.ts.map +1 -1
- package/dist/xlsx/filter-rows.d.ts +8 -0
- package/dist/xlsx/filter-rows.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/math-sum.d.ts.map +1 -1
- package/dist/xlsx/formula/lexemes.d.ts.map +1 -1
- package/dist/xlsx/formula/table-refs.d.ts +2 -0
- package/dist/xlsx/formula/table-refs.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +463 -332
- package/dist/xlsx/index.mjs +463 -332
- package/dist/xlsx/load/index.cjs +7628 -7583
- package/dist/xlsx/load/index.mjs +7628 -7583
- package/dist/xlsx/model.d.ts +4 -0
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +461 -332
- package/dist/xlsx/ui/index.mjs +461 -332
- package/dist/xlsx/ui/locales/de/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/shell.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/visio/ui/index.cjs
CHANGED
|
@@ -13,7 +13,8 @@ var eventKeys = [
|
|
|
13
13
|
"document-error",
|
|
14
14
|
"page-change",
|
|
15
15
|
"zoom-change",
|
|
16
|
-
"shape-select"
|
|
16
|
+
"shape-select",
|
|
17
|
+
"selection-change"
|
|
17
18
|
];
|
|
18
19
|
|
|
19
20
|
// visio/ui/demo-document.ts
|
|
@@ -324,6 +325,298 @@ function textSearchStatus(search) {
|
|
|
324
325
|
return result + (search.indexTruncated ? " \xB7 Partial text index" : "");
|
|
325
326
|
}
|
|
326
327
|
|
|
328
|
+
// visio/package-common.ts
|
|
329
|
+
var VisioPackageError = class extends Error {
|
|
330
|
+
constructor(code, message) {
|
|
331
|
+
super(message);
|
|
332
|
+
this.code = code;
|
|
333
|
+
this.name = "VisioPackageError";
|
|
334
|
+
}
|
|
335
|
+
code;
|
|
336
|
+
};
|
|
337
|
+
function fail(code, message) {
|
|
338
|
+
throw new VisioPackageError(code, message);
|
|
339
|
+
}
|
|
340
|
+
new TextDecoder("utf-8", { fatal: true });
|
|
341
|
+
var crcTable = Uint32Array.from({ length: 256 }, (_, value) => {
|
|
342
|
+
for (let i = 0; i < 8; i++) value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
|
|
343
|
+
return value >>> 0;
|
|
344
|
+
});
|
|
345
|
+
function crc32(bytes, crc = 4294967295) {
|
|
346
|
+
for (const byte of bytes) crc = (crcTable[(crc ^ byte) & 255] ?? 0) ^ crc >>> 8;
|
|
347
|
+
return crc >>> 0;
|
|
348
|
+
}
|
|
349
|
+
function decodePath(path) {
|
|
350
|
+
try {
|
|
351
|
+
return decodeURIComponent(path);
|
|
352
|
+
} catch {
|
|
353
|
+
return fail("UNSAFE_PATH", "Invalid percent encoding in package path");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function safePath(path, directory = false) {
|
|
357
|
+
const decoded = decodePath(path);
|
|
358
|
+
if (/%(?:2f|5c)/i.test(path)) fail("UNSAFE_PATH", "Encoded path separators are unsupported");
|
|
359
|
+
if (/[\\:#?\u0000-\u001f\u007f]/.test(path) || /[\\:#?%\u0000-\u001f\u007f]/.test(decoded))
|
|
360
|
+
fail("UNSAFE_PATH", `Unsafe package path: ${path}`);
|
|
361
|
+
for (const candidate of [path, decoded]) {
|
|
362
|
+
const name = directory && candidate.endsWith("/") ? candidate.slice(0, -1) : candidate;
|
|
363
|
+
if (!name || name.split("/").some((part) => !part || part === "." || part === ".."))
|
|
364
|
+
fail("UNSAFE_PATH", `Unsafe package path: ${path}`);
|
|
365
|
+
}
|
|
366
|
+
return path;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// visio/edit-formatting-commands.ts
|
|
370
|
+
var isVisioFormatEdit = (edit) => edit.type === "format-text" || edit.type === "format-shape";
|
|
371
|
+
function snapshotFormatting(edit) {
|
|
372
|
+
const result = { type: edit.type, pageId: edit.pageId, shapeId: edit.shapeId };
|
|
373
|
+
const points = (value, minimum, maximum) => {
|
|
374
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < minimum || value > maximum)
|
|
375
|
+
fail("INVALID_EDIT", "Formatting point size is outside supported limits.");
|
|
376
|
+
return value;
|
|
377
|
+
};
|
|
378
|
+
const color = (value, allowNone = false) => {
|
|
379
|
+
if (typeof value !== "string" || !(allowNone && value === "none") && !/^#[0-9a-f]{6}$/i.test(value))
|
|
380
|
+
fail("INVALID_EDIT", "Formatting colors require six hexadecimal digits.");
|
|
381
|
+
return value.toLowerCase();
|
|
382
|
+
};
|
|
383
|
+
if (edit.type === "format-text" && result.type === "format-text") {
|
|
384
|
+
if (edit.fontSize !== void 0) result.fontSize = points(edit.fontSize, 1, 1e3);
|
|
385
|
+
if (edit.fontColor !== void 0) result.fontColor = color(edit.fontColor);
|
|
386
|
+
if (edit.indentLeft !== void 0) result.indentLeft = points(edit.indentLeft, 0, 7200);
|
|
387
|
+
if (edit.fontFamily !== void 0) {
|
|
388
|
+
if (typeof edit.fontFamily !== "string" || !edit.fontFamily.trim() || edit.fontFamily.length > 256 || /[\u0000-\u001f\u007f]/.test(edit.fontFamily))
|
|
389
|
+
fail("INVALID_EDIT", "Invalid font family.");
|
|
390
|
+
result.fontFamily = edit.fontFamily;
|
|
391
|
+
}
|
|
392
|
+
for (const name of ["bold", "italic", "underline", "strikethrough", "bullets"]) {
|
|
393
|
+
if (edit[name] === void 0) continue;
|
|
394
|
+
if (typeof edit[name] !== "boolean") fail("INVALID_EDIT", "Text styles require booleans.");
|
|
395
|
+
result[name] = edit[name];
|
|
396
|
+
}
|
|
397
|
+
if (edit.horizontalAlign !== void 0) {
|
|
398
|
+
if (!["left", "center", "right", "justify"].includes(edit.horizontalAlign))
|
|
399
|
+
fail("INVALID_EDIT", "Invalid horizontal alignment.");
|
|
400
|
+
result.horizontalAlign = edit.horizontalAlign;
|
|
401
|
+
}
|
|
402
|
+
if (edit.verticalAlign !== void 0) {
|
|
403
|
+
if (!["top", "middle", "bottom"].includes(edit.verticalAlign))
|
|
404
|
+
fail("INVALID_EDIT", "Invalid vertical alignment.");
|
|
405
|
+
result.verticalAlign = edit.verticalAlign;
|
|
406
|
+
}
|
|
407
|
+
} else if (edit.type === "format-shape" && result.type === "format-shape") {
|
|
408
|
+
if (edit.fillColor !== void 0) result.fillColor = color(edit.fillColor, true);
|
|
409
|
+
if (edit.lineColor !== void 0) result.lineColor = color(edit.lineColor);
|
|
410
|
+
if (edit.lineWeight !== void 0) result.lineWeight = points(edit.lineWeight, 0, 100);
|
|
411
|
+
for (const [name, maximum] of [
|
|
412
|
+
["linePattern", 23],
|
|
413
|
+
["fillPattern", 24]
|
|
414
|
+
]) {
|
|
415
|
+
if (edit[name] === void 0) continue;
|
|
416
|
+
const value = points(edit[name], 0, maximum);
|
|
417
|
+
if (!Number.isInteger(value)) fail("INVALID_EDIT", "Paint patterns require integers.");
|
|
418
|
+
result[name] = value;
|
|
419
|
+
}
|
|
420
|
+
for (const name of ["lineTransparency", "fillTransparency"])
|
|
421
|
+
if (edit[name] !== void 0) result[name] = Math.round(points(edit[name], 0, 100) * 2) / 2;
|
|
422
|
+
if (edit.fillBackgroundColor !== void 0)
|
|
423
|
+
result.fillBackgroundColor = color(edit.fillBackgroundColor);
|
|
424
|
+
if (result.fillColor === "none" && result.fillPattern !== void 0 && result.fillPattern !== 0)
|
|
425
|
+
fail("INVALID_EDIT", "No fill conflicts with a visible fill pattern.");
|
|
426
|
+
}
|
|
427
|
+
if (Object.keys(result).length === 3)
|
|
428
|
+
fail("INVALID_EDIT", "Formatting requires at least one property.");
|
|
429
|
+
return result;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// visio/edit-duplicate-commands.ts
|
|
433
|
+
function snapshotDuplicateShapes(edit) {
|
|
434
|
+
if (!Array.isArray(edit.copies) || !edit.copies.length || edit.copies.length > 1e3)
|
|
435
|
+
fail("INVALID_EDIT", "Duplication requires between one and 1000 shape mappings.");
|
|
436
|
+
if ([edit.offsetX, edit.offsetY].some(
|
|
437
|
+
(value) => typeof value !== "number" || !Number.isFinite(value) || Math.abs(value) > 1e6
|
|
438
|
+
))
|
|
439
|
+
fail("INVALID_EDIT", "Duplication offsets require bounded finite drawing inches.");
|
|
440
|
+
const sources = /* @__PURE__ */ new Set(), targets = /* @__PURE__ */ new Set();
|
|
441
|
+
const id = (value) => {
|
|
442
|
+
if (typeof value !== "string" || !/^(0|[1-9]\d{0,9})$/.test(value) || Number(value) > 4294967295)
|
|
443
|
+
fail("INVALID_EDIT", "Duplicate shape IDs require canonical unsigned integers.");
|
|
444
|
+
return value;
|
|
445
|
+
};
|
|
446
|
+
const copies = edit.copies.map((copy) => {
|
|
447
|
+
if (!copy || typeof copy !== "object") fail("INVALID_EDIT", "Invalid duplicate shape mapping.");
|
|
448
|
+
const shapeId = id(copy.shapeId), newShapeId = id(copy.newShapeId);
|
|
449
|
+
if (sources.has(shapeId) || targets.has(newShapeId))
|
|
450
|
+
fail("INVALID_EDIT", "Duplicate shape mappings must have unique sources and targets.");
|
|
451
|
+
sources.add(shapeId);
|
|
452
|
+
targets.add(newShapeId);
|
|
453
|
+
return { shapeId, newShapeId };
|
|
454
|
+
});
|
|
455
|
+
return {
|
|
456
|
+
type: edit.type,
|
|
457
|
+
pageId: edit.pageId,
|
|
458
|
+
copies,
|
|
459
|
+
offsetX: edit.offsetX,
|
|
460
|
+
offsetY: edit.offsetY
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// visio/clipboard-types.ts
|
|
465
|
+
var VISIO_CLIPBOARD_MAX_CHARS = 8 * 1024 * 1024;
|
|
466
|
+
function clipboardId(value) {
|
|
467
|
+
if (typeof value !== "string" || !/^(0|[1-9]\d{0,9})$/.test(value) || Number(value) > 4294967295)
|
|
468
|
+
fail("INVALID_CLIPBOARD", "Clipboard IDs require canonical unsigned integers.");
|
|
469
|
+
return value;
|
|
470
|
+
}
|
|
471
|
+
function snapshotVisioClipboard(value) {
|
|
472
|
+
if (!value || typeof value !== "object" || value.format !== "ooxml.visio-shapes" || value.version !== 1)
|
|
473
|
+
fail("INVALID_CLIPBOARD", "Unsupported Visio clipboard format or version.");
|
|
474
|
+
const sourcePageId = clipboardId(value.sourcePageId), sourceDrawingScale = value.sourceDrawingScale;
|
|
475
|
+
if (!Number.isFinite(sourceDrawingScale) || sourceDrawingScale <= 0 || sourceDrawingScale > 1e6)
|
|
476
|
+
fail("INVALID_CLIPBOARD", "Invalid clipboard drawing ratio.");
|
|
477
|
+
let characters = 0;
|
|
478
|
+
const text = (input) => {
|
|
479
|
+
if (typeof input !== "string" || (characters += input.length) > VISIO_CLIPBOARD_MAX_CHARS)
|
|
480
|
+
fail("LIMIT_CLIPBOARD", "Clipboard XML exceeds bounded text limits.");
|
|
481
|
+
if (/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/.test(input))
|
|
482
|
+
fail("INVALID_CLIPBOARD", "Clipboard XML must contain well-formed Unicode.");
|
|
483
|
+
return input;
|
|
484
|
+
};
|
|
485
|
+
const list = (input, max) => {
|
|
486
|
+
if (!Array.isArray(input) || !input.length || input.length > max)
|
|
487
|
+
fail("INVALID_CLIPBOARD", "Invalid clipboard array length.");
|
|
488
|
+
return input;
|
|
489
|
+
};
|
|
490
|
+
const selectionIds = list(value.selectionIds, 1e3).map(clipboardId);
|
|
491
|
+
const shapes = list(value.shapes, 1e3).map((shape) => {
|
|
492
|
+
if (!shape || typeof shape !== "object") fail("INVALID_CLIPBOARD", "Invalid captured shape.");
|
|
493
|
+
return { shapeId: clipboardId(shape.shapeId), xml: text(shape.xml) };
|
|
494
|
+
});
|
|
495
|
+
const resources = list(value.resources, 64).map((resource) => {
|
|
496
|
+
const path = resource?.path;
|
|
497
|
+
if (!resource || typeof resource !== "object" || typeof path !== "string" || path.length > 1024 || !/^visio\/(?:document\.xml|_rels\/document\.xml\.rels|theme\/[^/]+\.(?:xml|rels)|theme\/_rels\/[^/]+\.rels)$/.test(
|
|
498
|
+
path
|
|
499
|
+
))
|
|
500
|
+
fail("INVALID_CLIPBOARD", "Invalid clipboard resource path.");
|
|
501
|
+
return { path: text(safePath(path)), xml: text(resource.xml) };
|
|
502
|
+
});
|
|
503
|
+
if (new Set(selectionIds).size !== selectionIds.length || new Set(shapes.map((shape) => shape.shapeId)).size !== shapes.length || selectionIds.length !== shapes.length || selectionIds.some((id) => !shapes.some((shape) => shape.shapeId === id)) || new Set(resources.map((resource) => resource.path)).size !== resources.length)
|
|
504
|
+
fail("INVALID_CLIPBOARD", "Clipboard mappings and resources must be unique and complete.");
|
|
505
|
+
return {
|
|
506
|
+
format: "ooxml.visio-shapes",
|
|
507
|
+
version: 1,
|
|
508
|
+
sourcePageId,
|
|
509
|
+
sourceDrawingScale,
|
|
510
|
+
selectionIds,
|
|
511
|
+
shapes,
|
|
512
|
+
resources: resources.sort((a, b) => a.path.localeCompare(b.path)),
|
|
513
|
+
pageContext: text(value.pageContext)
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// visio/edit-paste-commands.ts
|
|
518
|
+
function snapshotPasteShapes(edit) {
|
|
519
|
+
const clipboard = snapshotVisioClipboard(edit.clipboard);
|
|
520
|
+
const copies = snapshotDuplicateShapes({
|
|
521
|
+
type: "duplicate-shapes",
|
|
522
|
+
pageId: edit.pageId,
|
|
523
|
+
copies: edit.copies,
|
|
524
|
+
offsetX: edit.offsetX,
|
|
525
|
+
offsetY: edit.offsetY
|
|
526
|
+
});
|
|
527
|
+
if (copies.copies.length !== clipboard.shapes.length || copies.copies.some((copy) => !clipboard.selectionIds.includes(copy.shapeId)))
|
|
528
|
+
fail("INVALID_CLIPBOARD", "Paste mappings must cover every captured shape exactly once.");
|
|
529
|
+
return {
|
|
530
|
+
type: "paste-shapes",
|
|
531
|
+
pageId: copies.pageId,
|
|
532
|
+
copies: copies.copies,
|
|
533
|
+
offsetX: copies.offsetX,
|
|
534
|
+
offsetY: copies.offsetY,
|
|
535
|
+
clipboard
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// visio/resize-anchor.ts
|
|
540
|
+
function snapshotResizeAnchor(value) {
|
|
541
|
+
if (value === void 0) return void 0;
|
|
542
|
+
if (!value || typeof value !== "object") fail("INVALID_EDIT", "Invalid resize anchor.");
|
|
543
|
+
const { x, y } = value;
|
|
544
|
+
if (![0, 0.5, 1].includes(x) || ![0, 0.5, 1].includes(y))
|
|
545
|
+
fail("INVALID_EDIT", "Resize anchor coordinates must be 0, 0.5 or 1.");
|
|
546
|
+
return { x, y };
|
|
547
|
+
}
|
|
548
|
+
function visioAnchoredResizeGeometry(current, size, anchor) {
|
|
549
|
+
const [a, b, c, d, e, f] = current.transform;
|
|
550
|
+
const determinant = a * d - b * c;
|
|
551
|
+
if (![0, 0.5, 1].includes(anchor.x) || ![0, 0.5, 1].includes(anchor.y) || ![
|
|
552
|
+
current.width,
|
|
553
|
+
current.height,
|
|
554
|
+
current.pinX,
|
|
555
|
+
current.pinY,
|
|
556
|
+
...current.transform,
|
|
557
|
+
size.width,
|
|
558
|
+
size.height,
|
|
559
|
+
anchor.x,
|
|
560
|
+
anchor.y
|
|
561
|
+
].every(Number.isFinite) || !(current.width > 0 && current.height > 0 && size.width > 0 && size.height > 0) || Math.abs(Math.abs(determinant) - 1) > 1e-8 || Math.abs(a * a + b * b - 1) > 1e-8 || Math.abs(c * c + d * d - 1) > 1e-8 || Math.abs(a * c + b * d) > 1e-8)
|
|
562
|
+
return void 0;
|
|
563
|
+
const offsetX = current.pinX - e, offsetY = current.pinY - f;
|
|
564
|
+
const oldX = (d * offsetX - c * offsetY) / determinant;
|
|
565
|
+
const oldY = (-b * offsetX + a * offsetY) / determinant;
|
|
566
|
+
const locPinX = oldX / current.width * size.width, locPinY = oldY / current.height * size.height;
|
|
567
|
+
const deltaX = anchor.x * (current.width - size.width) - oldX + locPinX;
|
|
568
|
+
const deltaY = anchor.y * (current.height - size.height) - oldY + locPinY;
|
|
569
|
+
const pinX = current.pinX + a * deltaX + c * deltaY, pinY = current.pinY + b * deltaX + d * deltaY;
|
|
570
|
+
const matrix2 = [
|
|
571
|
+
a,
|
|
572
|
+
b,
|
|
573
|
+
c,
|
|
574
|
+
d,
|
|
575
|
+
pinX - a * locPinX - c * locPinY,
|
|
576
|
+
pinY - b * locPinX - d * locPinY
|
|
577
|
+
];
|
|
578
|
+
return [pinX, pinY, locPinX, locPinY, ...matrix2].every(Number.isFinite) ? { pinX, pinY, locPinX, locPinY, transform: matrix2 } : void 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// visio/edit-text-range-commands.ts
|
|
582
|
+
var invalidXmlText = /[\u0000-\u0008\u000b\u000c\u000d\u000e-\u001f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/u;
|
|
583
|
+
function textRangeBoundary(text, offset) {
|
|
584
|
+
return !(offset > 0 && offset < text.length && /[\ud800-\udbff]/.test(text[offset - 1]) && /[\udc00-\udfff]/.test(text[offset]));
|
|
585
|
+
}
|
|
586
|
+
function snapshotTextRanges(edit, consume) {
|
|
587
|
+
let characters = 0;
|
|
588
|
+
const text = (value) => {
|
|
589
|
+
if (typeof value !== "string" || invalidXmlText.test(value))
|
|
590
|
+
fail("INVALID_EDIT_TEXT", "Range replacement requires valid XML text.");
|
|
591
|
+
characters += value.length;
|
|
592
|
+
if (characters > 1e6)
|
|
593
|
+
fail("LIMIT_EDIT_TEXT", "Range replacement text exceeds input limits.");
|
|
594
|
+
return consume ? consume(value) : value;
|
|
595
|
+
};
|
|
596
|
+
const pageId = edit.pageId, shapeId = edit.shapeId;
|
|
597
|
+
if ([pageId, shapeId].some((id) => typeof id !== "string" || !id || id.length > 256))
|
|
598
|
+
fail("INVALID_EDIT", "Invalid text range target.");
|
|
599
|
+
const expectedText = text(edit.expectedText), original = edit.ranges;
|
|
600
|
+
if (!Array.isArray(original)) fail("INVALID_EDIT", "Text ranges require an array.");
|
|
601
|
+
const length = original.length;
|
|
602
|
+
if (!Number.isSafeInteger(length) || length < 1 || length > 1e4)
|
|
603
|
+
fail("LIMIT_EDITS", "Range replacement requires 1-10000 ranges.");
|
|
604
|
+
const ranges = [];
|
|
605
|
+
let end = 0, output = expectedText.length;
|
|
606
|
+
for (let index = 0; index < length; index++) {
|
|
607
|
+
const input = original[index], start = input.start, nextEnd = input.end, replacement = text(input.text);
|
|
608
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(nextEnd) || start < end || nextEnd <= start || nextEnd > expectedText.length || !textRangeBoundary(expectedText, start) || !textRangeBoundary(expectedText, nextEnd))
|
|
609
|
+
fail("INVALID_EDIT", "Text ranges require ascending nonoverlapping UTF16 scalar boundaries.");
|
|
610
|
+
if (replacement.includes("\n") || expectedText.slice(start, nextEnd).includes("\n"))
|
|
611
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Range replacement across paragraph breaks is unsupported.");
|
|
612
|
+
ranges.push({ start, end: nextEnd, text: replacement });
|
|
613
|
+
end = nextEnd;
|
|
614
|
+
output += replacement.length - (nextEnd - start);
|
|
615
|
+
}
|
|
616
|
+
if (output > 1e6) fail("LIMIT_EDIT_TEXT", "Range replacement output exceeds limits.");
|
|
617
|
+
return { type: "replace-text-ranges", pageId, shapeId, expectedText, ranges };
|
|
618
|
+
}
|
|
619
|
+
|
|
327
620
|
// visio/ui/edit-commands.ts
|
|
328
621
|
function snapshotEdits(edits) {
|
|
329
622
|
if (!Array.isArray(edits) || edits.length > 1e3)
|
|
@@ -332,12 +625,26 @@ function snapshotEdits(edits) {
|
|
|
332
625
|
return edits.map((command) => {
|
|
333
626
|
if (!command || typeof command.pageId !== "string" || !command.pageId || command.pageId.length > 256)
|
|
334
627
|
throw new Error("Invalid edit command.");
|
|
628
|
+
if (command.type === "duplicate-shapes") return snapshotDuplicateShapes(command);
|
|
629
|
+
if (command.type === "paste-shapes") return snapshotPasteShapes(command);
|
|
335
630
|
if (command.type === "reorder-page") {
|
|
336
631
|
if (!Number.isSafeInteger(command.index) || command.index < 0 || command.index > 1e6)
|
|
337
632
|
throw new Error("Invalid page order index.");
|
|
338
633
|
return { type: command.type, pageId: command.pageId, index: command.index };
|
|
339
634
|
}
|
|
340
635
|
if (command.type === "delete-page") return { type: command.type, pageId: command.pageId };
|
|
636
|
+
if (command.type === "set-page-size") {
|
|
637
|
+
if (![command.width, command.height].every(
|
|
638
|
+
(value) => typeof value === "number" && Number.isFinite(value) && value > 0 && value <= 1e6
|
|
639
|
+
))
|
|
640
|
+
throw new Error("Invalid physical page dimensions.");
|
|
641
|
+
return {
|
|
642
|
+
type: command.type,
|
|
643
|
+
pageId: command.pageId,
|
|
644
|
+
width: command.width,
|
|
645
|
+
height: command.height
|
|
646
|
+
};
|
|
647
|
+
}
|
|
341
648
|
const text = (value) => {
|
|
342
649
|
if (typeof value !== "string") throw new Error("Invalid edit text.");
|
|
343
650
|
characters += value.length;
|
|
@@ -364,7 +671,23 @@ function snapshotEdits(edits) {
|
|
|
364
671
|
if (typeof command.shapeId !== "string" || !command.shapeId || command.shapeId.length > 256)
|
|
365
672
|
throw new Error("Invalid edit shape target.");
|
|
366
673
|
const target = { pageId: command.pageId, shapeId: command.shapeId };
|
|
674
|
+
if (isVisioFormatEdit(command)) return snapshotFormatting(command);
|
|
367
675
|
switch (command.type) {
|
|
676
|
+
case "create-text-box":
|
|
677
|
+
numbers(command.x, command.y, command.width, command.height);
|
|
678
|
+
return {
|
|
679
|
+
type: command.type,
|
|
680
|
+
...target,
|
|
681
|
+
x: command.x,
|
|
682
|
+
y: command.y,
|
|
683
|
+
width: command.width,
|
|
684
|
+
height: command.height,
|
|
685
|
+
text: text(command.text)
|
|
686
|
+
};
|
|
687
|
+
case "reorder-shape":
|
|
688
|
+
if (!["front", "back", "forward", "backward"].includes(command.order))
|
|
689
|
+
throw new Error("Invalid shape order.");
|
|
690
|
+
return { ...target, type: command.type, order: command.order };
|
|
368
691
|
case "create-line":
|
|
369
692
|
numbers(command.beginX, command.beginY, command.endX, command.endY);
|
|
370
693
|
return {
|
|
@@ -377,6 +700,8 @@ function snapshotEdits(edits) {
|
|
|
377
700
|
};
|
|
378
701
|
case "replace-plain-text":
|
|
379
702
|
return { type: command.type, ...target, text: text(command.text) };
|
|
703
|
+
case "replace-text-ranges":
|
|
704
|
+
return snapshotTextRanges(command, text);
|
|
380
705
|
case "delete-shape":
|
|
381
706
|
return { type: command.type, ...target };
|
|
382
707
|
case "rotate-shape":
|
|
@@ -400,9 +725,17 @@ function snapshotEdits(edits) {
|
|
|
400
725
|
x: command.x,
|
|
401
726
|
y: command.y
|
|
402
727
|
};
|
|
403
|
-
case "resize-shape":
|
|
728
|
+
case "resize-shape": {
|
|
404
729
|
numbers(command.width, command.height);
|
|
405
|
-
|
|
730
|
+
const anchor = snapshotResizeAnchor(command.anchor);
|
|
731
|
+
return {
|
|
732
|
+
type: command.type,
|
|
733
|
+
...target,
|
|
734
|
+
width: command.width,
|
|
735
|
+
height: command.height,
|
|
736
|
+
...anchor === void 0 ? {} : { anchor }
|
|
737
|
+
};
|
|
738
|
+
}
|
|
406
739
|
case "create-rectangle":
|
|
407
740
|
case "create-ellipse":
|
|
408
741
|
numbers(command.x, command.y, command.width, command.height);
|
|
@@ -430,15 +763,6 @@ function editErrorMessage(error) {
|
|
|
430
763
|
function isEditCancellation(error) {
|
|
431
764
|
return !!error && typeof error === "object" && "name" in error && error.name === "AbortError";
|
|
432
765
|
}
|
|
433
|
-
new TextDecoder("utf-8", { fatal: true });
|
|
434
|
-
var crcTable = Uint32Array.from({ length: 256 }, (_, value) => {
|
|
435
|
-
for (let i = 0; i < 8; i++) value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
|
|
436
|
-
return value >>> 0;
|
|
437
|
-
});
|
|
438
|
-
function crc32(bytes, crc = 4294967295) {
|
|
439
|
-
for (const byte of bytes) crc = (crcTable[(crc ^ byte) & 255] ?? 0) ^ crc >>> 8;
|
|
440
|
-
return crc >>> 0;
|
|
441
|
-
}
|
|
442
766
|
|
|
443
767
|
// visio/foreign-vector-types.ts
|
|
444
768
|
var VISIO_FOREIGN_VECTOR_LIMITS = Object.freeze({
|
|
@@ -1378,6 +1702,29 @@ function transform(x, y, localX, localY, angle, flipX = false, flipY = false) {
|
|
|
1378
1702
|
return [a, b, c, d, x - a * localX - c * localY, y - b * localX - d * localY];
|
|
1379
1703
|
}
|
|
1380
1704
|
|
|
1705
|
+
// visio/parser.ts
|
|
1706
|
+
function getVisioPageLayers(document, pageId) {
|
|
1707
|
+
const result = [], seen = /* @__PURE__ */ new Set();
|
|
1708
|
+
const pages = new Map(document.pages.map((page) => [page.id, page]));
|
|
1709
|
+
let current = pages.get(pageId);
|
|
1710
|
+
while (current && !seen.has(current.id)) {
|
|
1711
|
+
seen.add(current.id);
|
|
1712
|
+
result.push(current);
|
|
1713
|
+
current = current.backgroundPageId === void 0 ? void 0 : pages.get(current.backgroundPageId);
|
|
1714
|
+
}
|
|
1715
|
+
return result.reverse();
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
// visio/visibility.ts
|
|
1719
|
+
var VISIO_VISIBILITY_LIMITS = Object.freeze({
|
|
1720
|
+
maxShapes: 25e3,
|
|
1721
|
+
maxDepth: 64,
|
|
1722
|
+
maxLayers: 25e3,
|
|
1723
|
+
maxMemberships: 1e5,
|
|
1724
|
+
maxMembershipsPerShape: 1024,
|
|
1725
|
+
maxLayerIdLength: 256
|
|
1726
|
+
});
|
|
1727
|
+
|
|
1381
1728
|
// visio/ui/foreign-vector-budget.ts
|
|
1382
1729
|
var FOREIGN_VECTOR_SCENE_LIMITS = Object.freeze({
|
|
1383
1730
|
maxNodes: 1e5,
|
|
@@ -1575,6 +1922,11 @@ function assertViewableDocument(model) {
|
|
|
1575
1922
|
metadataBytes += value.length;
|
|
1576
1923
|
if (metadataBytes > 1e6) throw new Error("The scene exceeds aggregate metadata limits.");
|
|
1577
1924
|
};
|
|
1925
|
+
if (model.fontFamilies !== void 0) {
|
|
1926
|
+
if (!Array.isArray(model.fontFamilies) || model.fontFamilies.length > 1e4)
|
|
1927
|
+
throw new Error("The scene has an invalid font family list.");
|
|
1928
|
+
for (const family of model.fontFamilies) label(family, 1024);
|
|
1929
|
+
}
|
|
1578
1930
|
for (const diagnostic of model.diagnostics) {
|
|
1579
1931
|
label(diagnostic.code, 256);
|
|
1580
1932
|
label(diagnostic.message);
|
|
@@ -1601,6 +1953,9 @@ function assertViewableDocument(model) {
|
|
|
1601
1953
|
finite2(page.height, "page height", 1e-3);
|
|
1602
1954
|
if (page.drawingToPageScale !== void 0)
|
|
1603
1955
|
finite2(page.drawingToPageScale, "drawing scale", Number.MIN_VALUE, Number.MAX_VALUE);
|
|
1956
|
+
for (const mode of [page.drawingSizeType, page.drawingResizeType])
|
|
1957
|
+
if (mode !== void 0 && (!Number.isSafeInteger(mode) || mode < 0 || mode > 255))
|
|
1958
|
+
throw new Error("The scene has an invalid drawing page-size mode.");
|
|
1604
1959
|
if (!Array.isArray(page.shapes) || stack.length + page.shapes.length > MAX_SHAPES)
|
|
1605
1960
|
throw new Error("The scene exceeds safe shape count limits or has an invalid shape list.");
|
|
1606
1961
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -1620,7 +1975,9 @@ function assertViewableDocument(model) {
|
|
|
1620
1975
|
member(shape.kind, ["shape", "group", "connector", "foreign"], "shape kind");
|
|
1621
1976
|
if (shape.groupDisplayMode !== void 0)
|
|
1622
1977
|
member(shape.groupDisplayMode, [0, 1, 2], "group display mode");
|
|
1623
|
-
member(shape.text.horizontalAlign, ["left", "center", "right"], "text alignment");
|
|
1978
|
+
member(shape.text.horizontalAlign, ["left", "center", "right", "justify"], "text alignment");
|
|
1979
|
+
for (const key of ["bold", "italic", "underline", "strikethrough"])
|
|
1980
|
+
if (shape.text[key] !== void 0) member(shape.text[key], [true, false], "text style");
|
|
1624
1981
|
member(shape.text.verticalAlign, ["top", "middle", "bottom"], "text alignment");
|
|
1625
1982
|
label(shape.name);
|
|
1626
1983
|
label(shape.text.fontFamily, 1024);
|
|
@@ -1659,7 +2016,7 @@ function assertViewableDocument(model) {
|
|
|
1659
2016
|
const dash = shape.style.lineDash;
|
|
1660
2017
|
if (!Array.isArray(dash) || dash.length < 2 || dash.length > 6 || dash.length % 2 !== 0)
|
|
1661
2018
|
throw new Error("The scene has an invalid normalized line dash.");
|
|
1662
|
-
for (const value of dash) finite2(value, "line dash length", 0,
|
|
2019
|
+
for (const value of dash) finite2(value, "line dash length", 0, 40);
|
|
1663
2020
|
if (!dash.some((value) => value > 0))
|
|
1664
2021
|
throw new Error("The scene has an empty line dash pattern.");
|
|
1665
2022
|
}
|
|
@@ -1674,6 +2031,21 @@ function assertViewableDocument(model) {
|
|
|
1674
2031
|
throw new Error("The scene has an invalid normalized line cap.");
|
|
1675
2032
|
finite2(shape.style.fillOpacity, "fill opacity", 0, 1);
|
|
1676
2033
|
finite2(shape.style.lineOpacity, "line opacity", 0, 1);
|
|
2034
|
+
if (shape.style.lineDashDotLength !== void 0)
|
|
2035
|
+
finite2(shape.style.lineDashDotLength, "line dash dot length", 0, 1e6);
|
|
2036
|
+
for (const name of [
|
|
2037
|
+
"fillForegroundOpacity",
|
|
2038
|
+
"fillBackgroundOpacity",
|
|
2039
|
+
"lineColorOpacity"
|
|
2040
|
+
])
|
|
2041
|
+
if (shape.style[name] !== void 0) finite2(shape.style[name], "source paint opacity", 0, 1);
|
|
2042
|
+
if (shape.style.fillPatternIndex !== void 0) {
|
|
2043
|
+
finite2(shape.style.fillPatternIndex, "source fill pattern", 0, 65535);
|
|
2044
|
+
if (!Number.isInteger(shape.style.fillPatternIndex))
|
|
2045
|
+
throw new Error("The scene has an invalid source fill pattern.");
|
|
2046
|
+
}
|
|
2047
|
+
if (shape.style.fillBackgroundColor !== void 0 && (typeof shape.style.fillBackgroundColor !== "string" || !/^#[0-9a-f]{6}$/i.test(shape.style.fillBackgroundColor)))
|
|
2048
|
+
throw new Error("The scene has an invalid source fill background color.");
|
|
1677
2049
|
if (shape.style.fillPattern) {
|
|
1678
2050
|
const tile = shape.style.fillPattern;
|
|
1679
2051
|
finite2(tile.width, "fill pattern width", 1 / 12, 1 / 12);
|
|
@@ -1696,6 +2068,8 @@ function assertViewableDocument(model) {
|
|
|
1696
2068
|
if (!Array.isArray(shape.text.runs) || runCount + shape.text.runs.length > 1e5)
|
|
1697
2069
|
throw new Error("The scene exceeds safe text run limits or has an invalid run list.");
|
|
1698
2070
|
for (const run of shape.text.runs) {
|
|
2071
|
+
if (run.strikethrough !== void 0)
|
|
2072
|
+
member(run.strikethrough, [true, false], "strikethrough style");
|
|
1699
2073
|
label(run.fontFamily, 1024);
|
|
1700
2074
|
label(run.color, 256);
|
|
1701
2075
|
if (run.opacity !== void 0) finite2(run.opacity, "text run opacity", 0, 1);
|
|
@@ -1868,10 +2242,16 @@ function copySnapshotScene(model) {
|
|
|
1868
2242
|
const style = (source) => {
|
|
1869
2243
|
const result = fields(source, [
|
|
1870
2244
|
"fill",
|
|
2245
|
+
"fillPatternIndex",
|
|
2246
|
+
"fillForegroundOpacity",
|
|
2247
|
+
"fillBackgroundColor",
|
|
2248
|
+
"fillBackgroundOpacity",
|
|
1871
2249
|
"lineColor",
|
|
1872
2250
|
"lineWidth",
|
|
1873
2251
|
"lineCap",
|
|
1874
2252
|
"linePattern",
|
|
2253
|
+
"lineDashDotLength",
|
|
2254
|
+
"lineColorOpacity",
|
|
1875
2255
|
"fillOpacity",
|
|
1876
2256
|
"lineOpacity",
|
|
1877
2257
|
"startArrow",
|
|
@@ -1950,6 +2330,10 @@ function copySnapshotScene(model) {
|
|
|
1950
2330
|
const text = (source) => ({
|
|
1951
2331
|
...fields(source, [
|
|
1952
2332
|
"plainText",
|
|
2333
|
+
"bold",
|
|
2334
|
+
"italic",
|
|
2335
|
+
"underline",
|
|
2336
|
+
"strikethrough",
|
|
1953
2337
|
"backgroundColor",
|
|
1954
2338
|
"backgroundOpacity",
|
|
1955
2339
|
"opacity",
|
|
@@ -1967,7 +2351,8 @@ function copySnapshotScene(model) {
|
|
|
1967
2351
|
...fields(run, ["text", "fontFamily", "fontSize", "color", "opacity"]),
|
|
1968
2352
|
bold: !!run.bold,
|
|
1969
2353
|
italic: !!run.italic,
|
|
1970
|
-
underline: !!run.underline
|
|
2354
|
+
underline: !!run.underline,
|
|
2355
|
+
...run.strikethrough === void 0 ? {} : { strikethrough: !!run.strikethrough }
|
|
1971
2356
|
})),
|
|
1972
2357
|
...source.paragraphs === void 0 ? {} : { paragraphs: list(source.paragraphs, "paragraphs", 5e4, paragraph) }
|
|
1973
2358
|
});
|
|
@@ -1999,6 +2384,12 @@ function copySnapshotScene(model) {
|
|
|
1999
2384
|
};
|
|
2000
2385
|
return {
|
|
2001
2386
|
format: "vsdx",
|
|
2387
|
+
...model.fontFamilies === void 0 ? {} : {
|
|
2388
|
+
fontFamilies: list(model.fontFamilies, "font families", 1e4, (font) => {
|
|
2389
|
+
if (typeof font !== "string" || font.length > 1024) throw invalid2();
|
|
2390
|
+
return font;
|
|
2391
|
+
})
|
|
2392
|
+
},
|
|
2002
2393
|
diagnostics: list(
|
|
2003
2394
|
model.diagnostics,
|
|
2004
2395
|
"diagnostics",
|
|
@@ -2013,7 +2404,9 @@ function copySnapshotScene(model) {
|
|
|
2013
2404
|
"height",
|
|
2014
2405
|
"isBackground",
|
|
2015
2406
|
"backgroundPageId",
|
|
2016
|
-
"drawingToPageScale"
|
|
2407
|
+
"drawingToPageScale",
|
|
2408
|
+
"drawingSizeType",
|
|
2409
|
+
"drawingResizeType"
|
|
2017
2410
|
]),
|
|
2018
2411
|
shapes: shapes(page.shapes),
|
|
2019
2412
|
connectors: []
|
|
@@ -2053,6 +2446,7 @@ function visioPageEditToDrawing(page, edit) {
|
|
|
2053
2446
|
return edit;
|
|
2054
2447
|
case "create-rectangle":
|
|
2055
2448
|
case "create-ellipse":
|
|
2449
|
+
case "create-text-box":
|
|
2056
2450
|
return {
|
|
2057
2451
|
...edit,
|
|
2058
2452
|
x: coordinate(edit.x),
|
|
@@ -2100,6 +2494,103 @@ function visioNextShapeId(page) {
|
|
|
2100
2494
|
return String(max + 1);
|
|
2101
2495
|
}
|
|
2102
2496
|
|
|
2497
|
+
// visio/ui/formatting.ts
|
|
2498
|
+
function visioStyleFormattingShape(page, shapeId) {
|
|
2499
|
+
const candidates = page.shapes.filter((shape2) => shape2.id === shapeId);
|
|
2500
|
+
if (candidates.length !== 1) return void 0;
|
|
2501
|
+
const shape = candidates[0];
|
|
2502
|
+
if (shape.hidden || shape.masterId || shape.layerIds?.length || shape.children.length || !["shape", "connector"].includes(shape.kind) || shape.image || shape.foreignVector)
|
|
2503
|
+
return void 0;
|
|
2504
|
+
return shape;
|
|
2505
|
+
}
|
|
2506
|
+
function visioFormattingShape(page, shapeId) {
|
|
2507
|
+
return visioStyleFormattingShape(page, shapeId);
|
|
2508
|
+
}
|
|
2509
|
+
function visioFontFamilies(document) {
|
|
2510
|
+
return [...new Set(document.fontFamilies ?? [])].sort((left, right) => left.localeCompare(right));
|
|
2511
|
+
}
|
|
2512
|
+
function visioTextFormattingState(shapes) {
|
|
2513
|
+
const common = (values) => values.length && values.every((value) => value === values[0]) ? values[0] : void 0;
|
|
2514
|
+
const runs = shapes.flatMap(
|
|
2515
|
+
(shape) => shape.text.runs.length ? shape.text.runs : [shape.text]
|
|
2516
|
+
);
|
|
2517
|
+
const styled = (key) => !!runs.length && runs.every((run) => !!run[key]);
|
|
2518
|
+
const paragraphs = shapes.flatMap((shape) => shape.text.paragraphs ?? []);
|
|
2519
|
+
const alignment = common(
|
|
2520
|
+
shapes.flatMap(
|
|
2521
|
+
(shape) => shape.text.paragraphs?.length ? shape.text.paragraphs.map((paragraph) => paragraph.horizontalAlign) : [shape.text.horizontalAlign]
|
|
2522
|
+
)
|
|
2523
|
+
);
|
|
2524
|
+
return {
|
|
2525
|
+
bold: styled("bold"),
|
|
2526
|
+
italic: styled("italic"),
|
|
2527
|
+
underline: styled("underline"),
|
|
2528
|
+
strikethrough: styled("strikethrough"),
|
|
2529
|
+
bullets: !!shapes.length && shapes.every(
|
|
2530
|
+
(shape) => !!shape.text.paragraphs?.length && shape.text.paragraphs.every((paragraph) => !!paragraph.bullet)
|
|
2531
|
+
),
|
|
2532
|
+
fontFamily: common(runs.map((run) => run.fontFamily)),
|
|
2533
|
+
fontSize: common(runs.map((run) => run.fontSize)),
|
|
2534
|
+
fontColor: common(runs.map((run) => run.color)),
|
|
2535
|
+
horizontalAlign: alignment === "distributed" ? void 0 : alignment,
|
|
2536
|
+
verticalAlign: common(shapes.map((shape) => shape.text.verticalAlign)),
|
|
2537
|
+
canIndentDecrease: paragraphs.some((paragraph) => paragraph.indentLeft > 0)
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
function visioTextIndentCommand(page, shapeId, direction) {
|
|
2541
|
+
const shape = visioFormattingShape(page, shapeId);
|
|
2542
|
+
if (!shape || !["increase", "decrease"].includes(direction)) return void 0;
|
|
2543
|
+
const paragraphs = shape.text.paragraphs ?? [];
|
|
2544
|
+
const left = paragraphs[0]?.indentLeft ?? 0;
|
|
2545
|
+
if (!Number.isFinite(left) || left < 0 || paragraphs.some((paragraph) => paragraph.indentLeft !== left))
|
|
2546
|
+
return void 0;
|
|
2547
|
+
const points = left * 72;
|
|
2548
|
+
const indentLeft = Math.min(7200, Math.max(0, points + (direction === "increase" ? 18 : -18)));
|
|
2549
|
+
return { type: "format-text", pageId: page.id, shapeId, indentLeft };
|
|
2550
|
+
}
|
|
2551
|
+
function visioTextFontStepCommand(page, shapeId, direction) {
|
|
2552
|
+
const shape = visioFormattingShape(page, shapeId);
|
|
2553
|
+
if (!shape || !["increase", "decrease"].includes(direction)) return void 0;
|
|
2554
|
+
const sizes = shape.text.runs.length ? shape.text.runs.map((run) => run.fontSize) : [shape.text.fontSize];
|
|
2555
|
+
const size = sizes[0];
|
|
2556
|
+
if (!Number.isFinite(size) || sizes.some((value) => Math.abs(value - size) > 1e-10))
|
|
2557
|
+
return void 0;
|
|
2558
|
+
const current = size * 72;
|
|
2559
|
+
if (current < 1 || current > 1e3) return void 0;
|
|
2560
|
+
const steps = [6, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];
|
|
2561
|
+
const fontSize = direction === "increase" ? steps.find((value) => value > current + 1e-3) ?? Math.min(1e3, Math.ceil(current * 1.2)) : steps.reverse().find((value) => value < current - 1e-3) ?? Math.max(1, Math.floor(current / 1.2));
|
|
2562
|
+
return { type: "format-text", pageId: page.id, shapeId, fontSize };
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
// visio/ui/shape-duplicate.ts
|
|
2566
|
+
function visioDuplicateCommand(page, shapeIds) {
|
|
2567
|
+
if (!shapeIds.length || shapeIds.length > 1e3 || new Set(shapeIds).size !== shapeIds.length || shapeIds.some((id) => {
|
|
2568
|
+
const shape = visioStyleFormattingShape(page, id);
|
|
2569
|
+
return !shape || shape.kind !== "shape" || !(shape.width > 0) || !(shape.height > 0) || page.connectors.some(
|
|
2570
|
+
(connection) => connection.fromShapeId === id || connection.toShapeId === id
|
|
2571
|
+
);
|
|
2572
|
+
}))
|
|
2573
|
+
return void 0;
|
|
2574
|
+
let next;
|
|
2575
|
+
try {
|
|
2576
|
+
next = Number(visioNextShapeId(page));
|
|
2577
|
+
} catch {
|
|
2578
|
+
return void 0;
|
|
2579
|
+
}
|
|
2580
|
+
if (next + shapeIds.length - 1 > 4294967295) return void 0;
|
|
2581
|
+
const selected = new Set(shapeIds);
|
|
2582
|
+
const mapping = new Map(
|
|
2583
|
+
page.shapes.filter((shape) => selected.has(shape.id)).map((shape) => [shape.id, String(next++)])
|
|
2584
|
+
);
|
|
2585
|
+
return {
|
|
2586
|
+
type: "duplicate-shapes",
|
|
2587
|
+
pageId: page.id,
|
|
2588
|
+
copies: shapeIds.map((shapeId) => ({ shapeId, newShapeId: mapping.get(shapeId) })),
|
|
2589
|
+
offsetX: 0.33,
|
|
2590
|
+
offsetY: -0.33
|
|
2591
|
+
};
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2103
2594
|
// visio/ui/fill-pattern-transform.ts
|
|
2104
2595
|
function visioFillPatternTransform(world, pageHeight = 0) {
|
|
2105
2596
|
const determinant = world[0] * world[3] - world[1] * world[2];
|
|
@@ -2159,15 +2650,891 @@ function visioQuarterTurnCommand(page, shapeId, direction) {
|
|
|
2159
2650
|
};
|
|
2160
2651
|
}
|
|
2161
2652
|
|
|
2653
|
+
// visio/ui/shape-order.ts
|
|
2654
|
+
function visioOrderingShape(page, shapeId) {
|
|
2655
|
+
if (page.shapes.some(
|
|
2656
|
+
(shape2) => shape2.kind !== "shape" || shape2.masterId || shape2.children.length || shape2.image || shape2.foreignVector
|
|
2657
|
+
))
|
|
2658
|
+
return void 0;
|
|
2659
|
+
const shape = page.shapes.find((candidate) => candidate.id === shapeId);
|
|
2660
|
+
return shape && !shape.hidden && !shape.layerIds?.length ? shape : void 0;
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
// geometry/align-distribute.ts
|
|
2664
|
+
function usesSlideReference(elementCount, options) {
|
|
2665
|
+
if (!options?.slideSize) {
|
|
2666
|
+
return false;
|
|
2667
|
+
}
|
|
2668
|
+
return options.reference === "slide";
|
|
2669
|
+
}
|
|
2670
|
+
function resolveAlignReferenceBox(elements, options) {
|
|
2671
|
+
if (elements.length === 0) {
|
|
2672
|
+
return null;
|
|
2673
|
+
}
|
|
2674
|
+
if (usesSlideReference(elements.length, options)) {
|
|
2675
|
+
return { minX: 0, minY: 0, maxX: options.slideSize.width, maxY: options.slideSize.height };
|
|
2676
|
+
}
|
|
2677
|
+
if (elements.length < 2) {
|
|
2678
|
+
return null;
|
|
2679
|
+
}
|
|
2680
|
+
return {
|
|
2681
|
+
minX: Math.min(...elements.map((e) => e.x)),
|
|
2682
|
+
minY: Math.min(...elements.map((e) => e.y)),
|
|
2683
|
+
maxX: Math.max(...elements.map((e) => e.x + e.width)),
|
|
2684
|
+
maxY: Math.max(...elements.map((e) => e.y + e.height))
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2687
|
+
function alignElements(elements, edge, options) {
|
|
2688
|
+
const result = /* @__PURE__ */ new Map();
|
|
2689
|
+
const ref = resolveAlignReferenceBox(elements, options);
|
|
2690
|
+
if (!ref) {
|
|
2691
|
+
return result;
|
|
2692
|
+
}
|
|
2693
|
+
const { minX, minY, maxX, maxY } = ref;
|
|
2694
|
+
const centerX = (minX + maxX) / 2;
|
|
2695
|
+
const centerY = (minY + maxY) / 2;
|
|
2696
|
+
for (const el of elements) {
|
|
2697
|
+
switch (edge) {
|
|
2698
|
+
case "left":
|
|
2699
|
+
result.set(el.id, { x: minX });
|
|
2700
|
+
break;
|
|
2701
|
+
case "right":
|
|
2702
|
+
result.set(el.id, { x: maxX - el.width });
|
|
2703
|
+
break;
|
|
2704
|
+
case "centerH":
|
|
2705
|
+
result.set(el.id, { x: centerX - el.width / 2 });
|
|
2706
|
+
break;
|
|
2707
|
+
case "top":
|
|
2708
|
+
result.set(el.id, { y: minY });
|
|
2709
|
+
break;
|
|
2710
|
+
case "bottom":
|
|
2711
|
+
result.set(el.id, { y: maxY - el.height });
|
|
2712
|
+
break;
|
|
2713
|
+
case "middle":
|
|
2714
|
+
result.set(el.id, { y: centerY - el.height / 2 });
|
|
2715
|
+
break;
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
return result;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
// visio/ui/shape-arrange.ts
|
|
2722
|
+
function distributeBoxes(boxes, axis) {
|
|
2723
|
+
const horizontal = axis === "horizontal";
|
|
2724
|
+
const start = (box2) => horizontal ? box2.x : -box2.y - box2.height;
|
|
2725
|
+
const size = (box2) => horizontal ? box2.width : box2.height;
|
|
2726
|
+
const center = (box2) => start(box2) + size(box2) / 2;
|
|
2727
|
+
const sorted = [...boxes].sort((left, right) => center(left) - center(right));
|
|
2728
|
+
const first = sorted[0], last = sorted.at(-1);
|
|
2729
|
+
const total = sorted.reduce((sum, box2) => sum + size(box2), 0);
|
|
2730
|
+
const gap = (start(last) + size(last) - start(first) - total) / (sorted.length - 1);
|
|
2731
|
+
let cursor = start(first);
|
|
2732
|
+
const positions = /* @__PURE__ */ new Map();
|
|
2733
|
+
for (const box2 of sorted) {
|
|
2734
|
+
positions.set(box2.id, horizontal ? { x: cursor } : { y: -cursor - box2.height });
|
|
2735
|
+
cursor += size(box2) + gap;
|
|
2736
|
+
}
|
|
2737
|
+
return positions;
|
|
2738
|
+
}
|
|
2739
|
+
function alignmentBox(shape) {
|
|
2740
|
+
if (!shape.rotation || shape.kind !== "shape" || !(shape.width > 0 && shape.height > 0))
|
|
2741
|
+
return void 0;
|
|
2742
|
+
const [a, b, c, d, e, f] = shape.transform;
|
|
2743
|
+
if (![a, b, c, d, e, f, shape.rotation.pinX, shape.rotation.pinY, shape.width, shape.height].every(
|
|
2744
|
+
Number.isFinite
|
|
2745
|
+
))
|
|
2746
|
+
return void 0;
|
|
2747
|
+
const points = [
|
|
2748
|
+
[0, 0],
|
|
2749
|
+
[shape.width, 0],
|
|
2750
|
+
[0, shape.height],
|
|
2751
|
+
[shape.width, shape.height]
|
|
2752
|
+
];
|
|
2753
|
+
const xs = points.map(([x2, y]) => a * x2 + c * y + e);
|
|
2754
|
+
const ys = points.map(([x2, y]) => b * x2 + d * y + f);
|
|
2755
|
+
const x = Math.min(...xs), top = Math.max(...ys);
|
|
2756
|
+
const width = Math.max(...xs) - x, height = top - Math.min(...ys);
|
|
2757
|
+
if (![x, top, width, height].every(Number.isFinite) || width <= 0 || height <= 0)
|
|
2758
|
+
return void 0;
|
|
2759
|
+
return { id: shape.id, x, y: -top, width, height };
|
|
2760
|
+
}
|
|
2761
|
+
function visioArrangeCommands(page, shapeIds, action) {
|
|
2762
|
+
const minimum = action.type === "align" ? 2 : 3;
|
|
2763
|
+
if (shapeIds.length < minimum || shapeIds.length > 1e3 || new Set(shapeIds).size !== shapeIds.length)
|
|
2764
|
+
return void 0;
|
|
2765
|
+
if (action.type === "align" ? !["left", "center", "right", "top", "middle", "bottom"].includes(action.edge) : action.type !== "distribute" || !["horizontal", "vertical"].includes(action.axis))
|
|
2766
|
+
return void 0;
|
|
2767
|
+
const shapes = [];
|
|
2768
|
+
const boxes = [];
|
|
2769
|
+
for (const id of shapeIds) {
|
|
2770
|
+
const shape = visioStyleFormattingShape(page, id);
|
|
2771
|
+
const box2 = shape && alignmentBox(shape);
|
|
2772
|
+
if (!shape || !box2 || page.connectors.some(
|
|
2773
|
+
(connection) => connection.fromShapeId === id || connection.toShapeId === id
|
|
2774
|
+
))
|
|
2775
|
+
return void 0;
|
|
2776
|
+
shapes.push(shape);
|
|
2777
|
+
boxes.push(box2);
|
|
2778
|
+
}
|
|
2779
|
+
const reference = boxes[0];
|
|
2780
|
+
const normalized = boxes.map((box2) => ({
|
|
2781
|
+
...box2,
|
|
2782
|
+
x: box2.x - reference.x,
|
|
2783
|
+
y: box2.y - reference.y
|
|
2784
|
+
}));
|
|
2785
|
+
const edge = action.type === "align" ? action.edge === "center" ? "centerH" : action.edge : void 0;
|
|
2786
|
+
const positions = action.type === "align" ? alignElements(normalized, edge, {
|
|
2787
|
+
reference: "slide",
|
|
2788
|
+
slideSize: { width: reference.width, height: reference.height }
|
|
2789
|
+
}) : distributeBoxes(normalized, action.axis);
|
|
2790
|
+
const commands = [];
|
|
2791
|
+
try {
|
|
2792
|
+
for (let index = 0; index < shapes.length; index++) {
|
|
2793
|
+
const shape = shapes[index], box2 = normalized[index];
|
|
2794
|
+
const position = positions.get(shape.id);
|
|
2795
|
+
if (!position) return void 0;
|
|
2796
|
+
const dx = (position.x ?? box2.x) - box2.x, dy = -((position.y ?? box2.y) - box2.y);
|
|
2797
|
+
if (Math.abs(dx) < 1e-10 && Math.abs(dy) < 1e-10) continue;
|
|
2798
|
+
commands.push(
|
|
2799
|
+
visioPageEditToDrawing(page, {
|
|
2800
|
+
type: "move-shape",
|
|
2801
|
+
pageId: page.id,
|
|
2802
|
+
shapeId: shape.id,
|
|
2803
|
+
x: shape.rotation.pinX + dx,
|
|
2804
|
+
y: shape.rotation.pinY + dy
|
|
2805
|
+
})
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2808
|
+
} catch {
|
|
2809
|
+
return void 0;
|
|
2810
|
+
}
|
|
2811
|
+
return commands;
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
// visio/ui/selection.ts
|
|
2815
|
+
var EMPTY_SELECTION = Object.freeze([]);
|
|
2816
|
+
var selectionKey = (shape, pageId) => JSON.stringify([shape.pageId ?? pageId, shape.id]);
|
|
2817
|
+
function visioSelectionIsOnPage(selection, pageId) {
|
|
2818
|
+
return !!selection && (selection.pageId === void 0 || selection.pageId === pageId);
|
|
2819
|
+
}
|
|
2820
|
+
function sameSelection(left, right) {
|
|
2821
|
+
return left.length === right.length && left.every((shape, index) => {
|
|
2822
|
+
const other = right[index];
|
|
2823
|
+
return shape.id === other.id && shape.pageId === other.pageId && shape.name === other.name;
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
function snapshotSelection(model, pageIndex, input, visible) {
|
|
2827
|
+
if (!Array.isArray(input)) throw new Error("Selection requires an array.");
|
|
2828
|
+
const length = input.length;
|
|
2829
|
+
if (length > VISIO_VISIBILITY_LIMITS.maxShapes)
|
|
2830
|
+
throw new Error("Selection exceeds the supported shape count.");
|
|
2831
|
+
const page = model?.pages[pageIndex];
|
|
2832
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
2833
|
+
for (let index = 0; index < length; index++) {
|
|
2834
|
+
const item = input[index];
|
|
2835
|
+
const id = item?.id, name = item?.name, pageId = item?.pageId;
|
|
2836
|
+
if (typeof id !== "string" || typeof name !== "string" || id.length > 1024 || name.length > 4096 || pageId !== void 0 && (typeof pageId !== "string" || pageId.length > 256))
|
|
2837
|
+
throw new Error("Selection requires shape IDs, names and optional page IDs.");
|
|
2838
|
+
const copied = Object.freeze({ id, name, ...pageId === void 0 ? {} : { pageId } });
|
|
2839
|
+
const key = selectionKey(copied, page?.id ?? "");
|
|
2840
|
+
if (!candidates.has(key)) candidates.set(key, copied);
|
|
2841
|
+
}
|
|
2842
|
+
if (!model || !page || !length) return EMPTY_SELECTION;
|
|
2843
|
+
const accepted = /* @__PURE__ */ new Map();
|
|
2844
|
+
const content = /* @__PURE__ */ new WeakMap();
|
|
2845
|
+
for (const source of getVisioPageLayers(model, page.id)) {
|
|
2846
|
+
const pending = source.shapes.map((shape) => ({ shape, ancestors: [] }));
|
|
2847
|
+
while (pending.length) {
|
|
2848
|
+
const { shape, ancestors } = pending.pop();
|
|
2849
|
+
const key = selectionKey({ id: shape.id, pageId: source.id }, page.id);
|
|
2850
|
+
if (candidates.has(key) && hasVisibleShapeContent(shape, visible, content))
|
|
2851
|
+
accepted.set(key, ancestors);
|
|
2852
|
+
for (const child of shape.children)
|
|
2853
|
+
pending.push({ shape: child, ancestors: [...ancestors, key] });
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
const result = [];
|
|
2857
|
+
for (const [key, item] of candidates) {
|
|
2858
|
+
const ancestors = accepted.get(key);
|
|
2859
|
+
if (!ancestors || ancestors.some((ancestor) => accepted.has(ancestor))) continue;
|
|
2860
|
+
result.push(item);
|
|
2861
|
+
}
|
|
2862
|
+
return result.length ? Object.freeze(result) : EMPTY_SELECTION;
|
|
2863
|
+
}
|
|
2864
|
+
function hasVisibleShapeContent(shape, visible, cache = /* @__PURE__ */ new WeakMap()) {
|
|
2865
|
+
const cached = cache.get(shape);
|
|
2866
|
+
if (cached !== void 0) return cached;
|
|
2867
|
+
const own = !(shape.kind === "group" && shape.groupDisplayMode === 0) && (shape.geometry.length > 0 || !!shape.image || !!shape.foreignVector || !!shape.text.plainText || shape.kind === "foreign");
|
|
2868
|
+
const renderable = (visible?.get(shape) ?? !shape.hidden) && (own || shape.children.some((child) => hasVisibleShapeContent(child, visible, cache)));
|
|
2869
|
+
cache.set(shape, renderable);
|
|
2870
|
+
return renderable;
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
// visio/ui/shape-clipboard.ts
|
|
2874
|
+
function visioClipboardShape(page, shapeId) {
|
|
2875
|
+
const shape = visioStyleFormattingShape(page, shapeId);
|
|
2876
|
+
if (!shape || shape.kind !== "shape" || !(shape.width > 0) || !(shape.height > 0) || page.connectors.some(
|
|
2877
|
+
(connection) => connection.fromShapeId === shapeId || connection.toShapeId === shapeId
|
|
2878
|
+
))
|
|
2879
|
+
return void 0;
|
|
2880
|
+
return shape;
|
|
2881
|
+
}
|
|
2882
|
+
function visioPasteCommand(page, value, offset = { x: 0.33, y: -0.33 }) {
|
|
2883
|
+
try {
|
|
2884
|
+
const clipboard = snapshotVisioClipboard(value);
|
|
2885
|
+
if ((page.drawingToPageScale ?? 1) !== clipboard.sourceDrawingScale || [offset.x, offset.y].some((number) => !Number.isFinite(number) || Math.abs(number) > 1e6))
|
|
2886
|
+
return void 0;
|
|
2887
|
+
let next = Number(visioNextShapeId(page));
|
|
2888
|
+
if (next + clipboard.shapes.length - 1 > 4294967295) return void 0;
|
|
2889
|
+
const ids = new Map(clipboard.shapes.map((shape) => [shape.shapeId, String(next++)]));
|
|
2890
|
+
return {
|
|
2891
|
+
type: "paste-shapes",
|
|
2892
|
+
pageId: page.id,
|
|
2893
|
+
clipboard,
|
|
2894
|
+
copies: clipboard.selectionIds.map((shapeId) => ({ shapeId, newShapeId: ids.get(shapeId) })),
|
|
2895
|
+
offsetX: offset.x,
|
|
2896
|
+
offsetY: offset.y
|
|
2897
|
+
};
|
|
2898
|
+
} catch {
|
|
2899
|
+
return void 0;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
// visio/ui/shape-move.ts
|
|
2904
|
+
function visioMovementShape(page, id) {
|
|
2905
|
+
const shape = visioStyleFormattingShape(page, id);
|
|
2906
|
+
if (!shape || shape.kind !== "shape" || !shape.rotation || !(shape.width > 0 && shape.height > 0) || ![
|
|
2907
|
+
shape.width,
|
|
2908
|
+
shape.height,
|
|
2909
|
+
shape.rotation.pinX,
|
|
2910
|
+
shape.rotation.pinY,
|
|
2911
|
+
...shape.transform
|
|
2912
|
+
].every(Number.isFinite) || page.connectors.some(
|
|
2913
|
+
(connection) => connection.fromShapeId === id || connection.toShapeId === id
|
|
2914
|
+
))
|
|
2915
|
+
return void 0;
|
|
2916
|
+
return shape;
|
|
2917
|
+
}
|
|
2918
|
+
function visioPageDragDelta(start, end) {
|
|
2919
|
+
return { x: end.x - start.x, y: start.y - end.y };
|
|
2920
|
+
}
|
|
2921
|
+
function visioMovePreviewTransform(shape, delta) {
|
|
2922
|
+
if (![delta.x, delta.y, ...shape.transform].every(Number.isFinite)) return void 0;
|
|
2923
|
+
const [a, b, c, d, e, f] = shape.transform;
|
|
2924
|
+
const result = [a, b, c, d, e + delta.x, f + delta.y];
|
|
2925
|
+
return result.every(Number.isFinite) ? result : void 0;
|
|
2926
|
+
}
|
|
2927
|
+
function visioMoveCommands(page, ids, delta) {
|
|
2928
|
+
if (!ids.length || ids.length > 1e3 || new Set(ids).size !== ids.length || ![delta.x, delta.y].every(Number.isFinite))
|
|
2929
|
+
return void 0;
|
|
2930
|
+
const shapes = ids.map((id) => visioMovementShape(page, id));
|
|
2931
|
+
if (shapes.some((shape) => !shape)) return void 0;
|
|
2932
|
+
if (delta.x === 0 && delta.y === 0) return [];
|
|
2933
|
+
try {
|
|
2934
|
+
const edits = shapes.map(
|
|
2935
|
+
(shape) => visioPageEditToDrawing(page, {
|
|
2936
|
+
type: "move-shape",
|
|
2937
|
+
pageId: page.id,
|
|
2938
|
+
shapeId: shape.id,
|
|
2939
|
+
x: shape.rotation.pinX + delta.x,
|
|
2940
|
+
y: shape.rotation.pinY + delta.y
|
|
2941
|
+
})
|
|
2942
|
+
);
|
|
2943
|
+
return edits.every(
|
|
2944
|
+
(edit) => edit.type === "move-shape" && Number.isFinite(edit.x) && Number.isFinite(edit.y)
|
|
2945
|
+
) ? edits : void 0;
|
|
2946
|
+
} catch {
|
|
2947
|
+
return void 0;
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2951
|
+
// visio/ui/size-position.ts
|
|
2952
|
+
var bounded = (value) => Number.isFinite(value) && Math.abs(value) <= 1e6;
|
|
2953
|
+
function visioSizePositionState(page, id) {
|
|
2954
|
+
const shape = visioMovementShape(page, id), ratio = page.drawingToPageScale ?? 1;
|
|
2955
|
+
if (!shape || !Number.isFinite(ratio) || ratio <= 0) return void 0;
|
|
2956
|
+
const rotation = shape.rotation;
|
|
2957
|
+
const state = {
|
|
2958
|
+
pageId: page.id,
|
|
2959
|
+
shapeId: id,
|
|
2960
|
+
x: rotation.pinX / ratio,
|
|
2961
|
+
y: rotation.pinY / ratio,
|
|
2962
|
+
width: shape.width / ratio,
|
|
2963
|
+
height: shape.height / ratio,
|
|
2964
|
+
angle: rotation.angle * 180 / Math.PI
|
|
2965
|
+
};
|
|
2966
|
+
if (![state.x, state.y, state.width, state.height, rotation.angle].every(bounded) || !Number.isFinite(state.angle))
|
|
2967
|
+
return void 0;
|
|
2968
|
+
return Object.freeze(state);
|
|
2969
|
+
}
|
|
2970
|
+
function visioSizePositionCommand(page, id, field, value) {
|
|
2971
|
+
const state = visioSizePositionState(page, id);
|
|
2972
|
+
if (!state || !Number.isFinite(value)) return void 0;
|
|
2973
|
+
if (!["x", "y", "width", "height", "angle"].includes(field)) return void 0;
|
|
2974
|
+
if (value === state[field]) return [];
|
|
2975
|
+
const target = { pageId: page.id, shapeId: id };
|
|
2976
|
+
if (field === "angle") {
|
|
2977
|
+
const angle = value * Math.PI / 180;
|
|
2978
|
+
return bounded(angle) ? [{ type: "rotate-shape", ...target, angle }] : void 0;
|
|
2979
|
+
}
|
|
2980
|
+
if (!bounded(value)) return void 0;
|
|
2981
|
+
if (field === "x" || field === "y")
|
|
2982
|
+
return [
|
|
2983
|
+
{
|
|
2984
|
+
type: "move-shape",
|
|
2985
|
+
...target,
|
|
2986
|
+
x: field === "x" ? value : state.x,
|
|
2987
|
+
y: field === "y" ? value : state.y
|
|
2988
|
+
}
|
|
2989
|
+
];
|
|
2990
|
+
if (value <= 0) return void 0;
|
|
2991
|
+
return [
|
|
2992
|
+
{
|
|
2993
|
+
type: "resize-shape",
|
|
2994
|
+
...target,
|
|
2995
|
+
width: field === "width" ? value : state.width,
|
|
2996
|
+
height: field === "height" ? value : state.height
|
|
2997
|
+
}
|
|
2998
|
+
];
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
// visio/ui/marquee.ts
|
|
3002
|
+
function visioMarqueeBox(start, end) {
|
|
3003
|
+
if (![start.x, start.y, end.x, end.y].every(Number.isFinite)) return void 0;
|
|
3004
|
+
const box2 = {
|
|
3005
|
+
x: Math.min(start.x, end.x),
|
|
3006
|
+
y: Math.min(start.y, end.y),
|
|
3007
|
+
width: Math.abs(end.x - start.x),
|
|
3008
|
+
height: Math.abs(end.y - start.y)
|
|
3009
|
+
};
|
|
3010
|
+
return Object.values(box2).every(Number.isFinite) ? box2 : void 0;
|
|
3011
|
+
}
|
|
3012
|
+
function visioShapePageBox(page, shape) {
|
|
3013
|
+
if (![page.height, shape.width, shape.height, ...shape.transform].every(Number.isFinite) || shape.width < 0 || shape.height < 0)
|
|
3014
|
+
return void 0;
|
|
3015
|
+
const [a, b, c, d, e, f] = shape.transform;
|
|
3016
|
+
const corners = [
|
|
3017
|
+
[0, 0],
|
|
3018
|
+
[shape.width, 0],
|
|
3019
|
+
[0, shape.height],
|
|
3020
|
+
[shape.width, shape.height]
|
|
3021
|
+
];
|
|
3022
|
+
const xs = corners.map(([x, y]) => a * x + c * y + e), ys = corners.map(([x, y]) => b * x + d * y + f);
|
|
3023
|
+
const left = Math.min(...xs), right = Math.max(...xs), bottom = Math.min(...ys), top = Math.max(...ys);
|
|
3024
|
+
const box2 = { x: left, y: page.height - top, width: right - left, height: top - bottom };
|
|
3025
|
+
return Object.values(box2).every(Number.isFinite) ? box2 : void 0;
|
|
3026
|
+
}
|
|
3027
|
+
function visioMarqueeSelection(page, box2, visible) {
|
|
3028
|
+
if (![box2.x, box2.y, box2.width, box2.height].every(Number.isFinite) || box2.width <= 0 || box2.height <= 0)
|
|
3029
|
+
return [];
|
|
3030
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3031
|
+
return page.shapes.flatMap((shape) => {
|
|
3032
|
+
const extent = visioShapePageBox(page, shape);
|
|
3033
|
+
return extent && hasVisibleShapeContent(shape, visible, cache) && extent.x >= box2.x && extent.y >= box2.y && extent.x + extent.width <= box2.x + box2.width && extent.y + extent.height <= box2.y + box2.height ? [{ id: shape.id, name: shape.name, pageId: page.id }] : [];
|
|
3034
|
+
});
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
// visio/ui/shape-resize.ts
|
|
3038
|
+
var VISIO_RESIZE_HANDLES = [
|
|
3039
|
+
{ id: "sw", x: 0, y: 0 },
|
|
3040
|
+
{ id: "s", x: 0.5, y: 0 },
|
|
3041
|
+
{ id: "se", x: 1, y: 0 },
|
|
3042
|
+
{ id: "e", x: 1, y: 0.5 },
|
|
3043
|
+
{ id: "ne", x: 1, y: 1 },
|
|
3044
|
+
{ id: "n", x: 0.5, y: 1 },
|
|
3045
|
+
{ id: "nw", x: 0, y: 1 },
|
|
3046
|
+
{ id: "w", x: 0, y: 0.5 }
|
|
3047
|
+
];
|
|
3048
|
+
function visioResizeShape(page, id) {
|
|
3049
|
+
const shape = visioMovementShape(page, id);
|
|
3050
|
+
return shape && visioResizeFrame(shape, { width: shape.width, height: shape.height }, { x: 0, y: 0 }) ? shape : void 0;
|
|
3051
|
+
}
|
|
3052
|
+
function visioResizeFrame(shape, size, anchor) {
|
|
3053
|
+
if (!shape.rotation) return void 0;
|
|
3054
|
+
const geometry = visioAnchoredResizeGeometry(
|
|
3055
|
+
{ ...shape, pinX: shape.rotation.pinX, pinY: shape.rotation.pinY },
|
|
3056
|
+
size,
|
|
3057
|
+
anchor
|
|
3058
|
+
);
|
|
3059
|
+
return geometry ? {
|
|
3060
|
+
width: size.width,
|
|
3061
|
+
height: size.height,
|
|
3062
|
+
transform: geometry.transform,
|
|
3063
|
+
pinX: geometry.pinX,
|
|
3064
|
+
pinY: geometry.pinY
|
|
3065
|
+
} : void 0;
|
|
3066
|
+
}
|
|
3067
|
+
function visioResizeDrag(page, id, handle, start, end) {
|
|
3068
|
+
const shape = visioResizeShape(page, id), location = VISIO_RESIZE_HANDLES.find((item) => item.id === handle);
|
|
3069
|
+
if (!shape || !location) return void 0;
|
|
3070
|
+
const delta = visioPageDragDelta(start, end), [a, b, c, d] = shape.transform, determinant = a * d - b * c;
|
|
3071
|
+
const x = (d * delta.x - c * delta.y) / determinant, y = (-b * delta.x + a * delta.y) / determinant;
|
|
3072
|
+
const size = {
|
|
3073
|
+
width: location.x === 0.5 ? shape.width : Math.max(Math.min(1 / 16, shape.width), shape.width + (location.x === 1 ? x : -x)),
|
|
3074
|
+
height: location.y === 0.5 ? shape.height : Math.max(Math.min(1 / 16, shape.height), shape.height + (location.y === 1 ? y : -y))
|
|
3075
|
+
};
|
|
3076
|
+
const anchor = {
|
|
3077
|
+
x: 1 - location.x,
|
|
3078
|
+
y: 1 - location.y
|
|
3079
|
+
};
|
|
3080
|
+
const frame = visioResizeFrame(shape, size, anchor);
|
|
3081
|
+
if (!frame) return void 0;
|
|
3082
|
+
try {
|
|
3083
|
+
const command = visioPageEditToDrawing(page, {
|
|
3084
|
+
type: "resize-shape",
|
|
3085
|
+
pageId: page.id,
|
|
3086
|
+
shapeId: id,
|
|
3087
|
+
...size,
|
|
3088
|
+
anchor
|
|
3089
|
+
});
|
|
3090
|
+
return command.type === "resize-shape" && command.width <= 1e6 && command.height <= 1e6 ? { frame, command } : void 0;
|
|
3091
|
+
} catch {
|
|
3092
|
+
return void 0;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
|
|
3096
|
+
// visio/ui/draw-plan.ts
|
|
3097
|
+
var SNAP = 1 / 16;
|
|
3098
|
+
var boundedNumber = (value) => Number.isFinite(value) && Math.abs(value) <= 1e6;
|
|
3099
|
+
function visioDrawingPoint(page, point, options = {}) {
|
|
3100
|
+
if (![point.x, point.y, page.width, page.height].every(boundedNumber) || page.width <= 0 || page.height <= 0)
|
|
3101
|
+
return void 0;
|
|
3102
|
+
const coordinate = (value, maximum) => {
|
|
3103
|
+
const bounded2 = options.bounded === false ? value : Math.max(0, Math.min(maximum, value));
|
|
3104
|
+
return options.snap === false ? bounded2 : Math.round(bounded2 / SNAP) * SNAP;
|
|
3105
|
+
};
|
|
3106
|
+
return { x: coordinate(point.x, page.width), y: coordinate(point.y, page.height) };
|
|
3107
|
+
}
|
|
3108
|
+
function visioDrawBounds(start, end) {
|
|
3109
|
+
if (![start.x, start.y, end.x, end.y].every(boundedNumber))
|
|
3110
|
+
throw new Error("Invalid drawing bounds.");
|
|
3111
|
+
return {
|
|
3112
|
+
x: Math.min(start.x, end.x),
|
|
3113
|
+
y: Math.min(start.y, end.y),
|
|
3114
|
+
width: Math.abs(end.x - start.x),
|
|
3115
|
+
height: Math.abs(end.y - start.y),
|
|
3116
|
+
centerX: (start.x + end.x) / 2,
|
|
3117
|
+
centerY: (start.y + end.y) / 2,
|
|
3118
|
+
radiusX: Math.abs(end.x - start.x) / 2,
|
|
3119
|
+
radiusY: Math.abs(end.y - start.y) / 2
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
function visioBoxCreationCommand(page, kind, centre, size, text) {
|
|
3123
|
+
if (!["rectangle", "ellipse", "text"].includes(kind) || ![centre.x, centre.y, size.width, size.height].every(boundedNumber) || size.width <= 0 || size.height <= 0)
|
|
3124
|
+
throw new Error("Invalid box creation geometry or tool.");
|
|
3125
|
+
const box2 = {
|
|
3126
|
+
pageId: page.id,
|
|
3127
|
+
shapeId: visioNextShapeId(page),
|
|
3128
|
+
x: centre.x,
|
|
3129
|
+
y: page.height - centre.y,
|
|
3130
|
+
width: size.width,
|
|
3131
|
+
height: size.height
|
|
3132
|
+
};
|
|
3133
|
+
const command = kind === "text" ? { ...box2, type: "create-text-box", text: text ?? "" } : {
|
|
3134
|
+
...box2,
|
|
3135
|
+
type: kind === "ellipse" ? "create-ellipse" : "create-rectangle",
|
|
3136
|
+
...text === void 0 ? {} : { text }
|
|
3137
|
+
};
|
|
3138
|
+
return drawingCommand(page, command);
|
|
3139
|
+
}
|
|
3140
|
+
function drawingCommand(page, command) {
|
|
3141
|
+
const result = visioPageEditToDrawing(page, command);
|
|
3142
|
+
if (Object.values(result).some((value) => typeof value === "number" && !boundedNumber(value)))
|
|
3143
|
+
throw new Error("Drawing coordinates exceed finite limits.");
|
|
3144
|
+
return result;
|
|
3145
|
+
}
|
|
3146
|
+
function visioLineCreationCommand(page, begin, end) {
|
|
3147
|
+
if (![begin.x, begin.y, end.x, end.y].every(boundedNumber))
|
|
3148
|
+
throw new Error("Invalid line creation geometry.");
|
|
3149
|
+
return drawingCommand(page, {
|
|
3150
|
+
type: "create-line",
|
|
3151
|
+
pageId: page.id,
|
|
3152
|
+
shapeId: visioNextShapeId(page),
|
|
3153
|
+
beginX: begin.x,
|
|
3154
|
+
beginY: page.height - begin.y,
|
|
3155
|
+
endX: end.x,
|
|
3156
|
+
endY: page.height - end.y
|
|
3157
|
+
});
|
|
3158
|
+
}
|
|
3159
|
+
function visioDrawIsLargeEnough(kind, start, end) {
|
|
3160
|
+
if (!["rectangle", "ellipse", "line", "text"].includes(kind) || ![start.x, start.y, end.x, end.y].every(boundedNumber))
|
|
3161
|
+
return false;
|
|
3162
|
+
const bounds = visioDrawBounds(start, end);
|
|
3163
|
+
return kind === "line" ? Math.hypot(bounds.width, bounds.height) >= SNAP : bounds.width >= SNAP && bounds.height >= SNAP;
|
|
3164
|
+
}
|
|
3165
|
+
function visioDrawPlan(page, kind, start, end, text) {
|
|
3166
|
+
if (!visioDrawIsLargeEnough(kind, start, end)) return void 0;
|
|
3167
|
+
const bounds = visioDrawBounds(start, end);
|
|
3168
|
+
return kind === "line" ? visioLineCreationCommand(page, start, end) : visioBoxCreationCommand(page, kind, { x: bounds.centerX, y: bounds.centerY }, bounds, text);
|
|
3169
|
+
}
|
|
3170
|
+
|
|
3171
|
+
// visio/ui/line-dash.ts
|
|
3172
|
+
function visioLineDashLengths(style) {
|
|
3173
|
+
return style.lineDash?.map(
|
|
3174
|
+
(length, index) => length === 0 && index % 2 === 0 ? style.lineDashDotLength ?? 0 : length * style.lineWidth
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
// visio/ui/shape-formatting.ts
|
|
3179
|
+
function visioShapeFormattingState(shapes) {
|
|
3180
|
+
const common = (values) => values.length && values.every((value) => value === values[0]) ? values[0] : void 0;
|
|
3181
|
+
const percent = (opacity) => opacity === void 0 || !Number.isFinite(opacity) || opacity < 0 || opacity > 1 ? void 0 : Math.round((1 - opacity) * 200) / 2;
|
|
3182
|
+
const foreground = shapes.map(
|
|
3183
|
+
(shape) => percent(
|
|
3184
|
+
shape.style.fillForegroundOpacity ?? (shape.style.fillGradient || shape.style.fillPattern ? void 0 : shape.style.fillOpacity)
|
|
3185
|
+
)
|
|
3186
|
+
);
|
|
3187
|
+
const background = shapes.map((shape) => percent(shape.style.fillBackgroundOpacity));
|
|
3188
|
+
return {
|
|
3189
|
+
linePattern: common(shapes.map((shape) => shape.style.linePattern)),
|
|
3190
|
+
fillPatternIndex: common(shapes.map((shape) => shape.style.fillPatternIndex)),
|
|
3191
|
+
fillBackgroundColor: common(shapes.map((shape) => shape.style.fillBackgroundColor)),
|
|
3192
|
+
fillForegroundTransparency: common(foreground),
|
|
3193
|
+
fillBackgroundTransparency: common(background),
|
|
3194
|
+
fillTransparency: common([...foreground, ...background]),
|
|
3195
|
+
lineTransparency: common(
|
|
3196
|
+
shapes.map(
|
|
3197
|
+
(shape) => percent(
|
|
3198
|
+
shape.style.lineColorOpacity ?? (shape.style.lineGradient ? void 0 : shape.style.lineOpacity)
|
|
3199
|
+
)
|
|
3200
|
+
)
|
|
3201
|
+
)
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
// visio/ui/text-replace-types.ts
|
|
3206
|
+
var VISIO_TEXT_REPLACE_LIMITS = Object.freeze({
|
|
3207
|
+
query: 256,
|
|
3208
|
+
replacement: 32768,
|
|
3209
|
+
text: 2e6,
|
|
3210
|
+
names: 1e6,
|
|
3211
|
+
output: 1e6,
|
|
3212
|
+
matches: 1e4,
|
|
3213
|
+
commands: 1e3,
|
|
3214
|
+
shapes: 25e3,
|
|
3215
|
+
pages: 256,
|
|
3216
|
+
depth: 64
|
|
3217
|
+
});
|
|
3218
|
+
var textReplaceError = (message) => {
|
|
3219
|
+
throw new Error(message);
|
|
3220
|
+
};
|
|
3221
|
+
function replaceString(value, maximum, label) {
|
|
3222
|
+
if (typeof value !== "string" || value.length > maximum)
|
|
3223
|
+
return textReplaceError(`Replace ${label} exceeds supported string limits.`);
|
|
3224
|
+
return value;
|
|
3225
|
+
}
|
|
3226
|
+
function replaceIdentity(value) {
|
|
3227
|
+
const id = replaceString(value, 256, "identity");
|
|
3228
|
+
if (!id) textReplaceError("Replace requires nonempty identities.");
|
|
3229
|
+
return id;
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
// visio/ui/text-replace-snapshot.ts
|
|
3233
|
+
function snapshotReplaceScope(input) {
|
|
3234
|
+
const query = replaceString(input.query, VISIO_TEXT_REPLACE_LIMITS.query, "query");
|
|
3235
|
+
const scope = input.scope, pageId = replaceIdentity(input.pageId), matchCase = input.matchCase;
|
|
3236
|
+
if (!query || matchCase !== true || !["selection", "current-page", "all-pages"].includes(scope))
|
|
3237
|
+
textReplaceError(
|
|
3238
|
+
"Replace requires a nonempty literal query, Match case, and an explicit scope."
|
|
3239
|
+
);
|
|
3240
|
+
let selection;
|
|
3241
|
+
const original = input.selection;
|
|
3242
|
+
if (original !== void 0) {
|
|
3243
|
+
const length = original.length;
|
|
3244
|
+
if (!Array.isArray(original) || !Number.isSafeInteger(length) || length > VISIO_TEXT_REPLACE_LIMITS.shapes || length < 0)
|
|
3245
|
+
textReplaceError("Replace selection exceeds supported limits.");
|
|
3246
|
+
selection = [];
|
|
3247
|
+
for (let index = 0; index < length; index++) {
|
|
3248
|
+
const item = original[index], id = replaceIdentity(item.id), page = item.pageId;
|
|
3249
|
+
selection.push(
|
|
3250
|
+
Object.freeze({ id, ...page === void 0 ? {} : { pageId: replaceIdentity(page) } })
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
Object.freeze(selection);
|
|
3254
|
+
}
|
|
3255
|
+
return Object.freeze({ query, scope, pageId, matchCase, ...selection ? { selection } : {} });
|
|
3256
|
+
}
|
|
3257
|
+
function replaceEntries(model, scope, requirePage = true) {
|
|
3258
|
+
const pages = model.pages;
|
|
3259
|
+
const count = pages.length;
|
|
3260
|
+
if (!Array.isArray(pages) || !Number.isSafeInteger(count) || count > VISIO_TEXT_REPLACE_LIMITS.pages || count < 0)
|
|
3261
|
+
textReplaceError("Replace page list exceeds supported limits.");
|
|
3262
|
+
const all = [], identities = /* @__PURE__ */ new Map(), pageIds = /* @__PURE__ */ new Set(), seen = /* @__PURE__ */ new Set();
|
|
3263
|
+
let characters = 0, names = 0;
|
|
3264
|
+
for (let pageIndex = 0; pageIndex < count; pageIndex++) {
|
|
3265
|
+
const page = pages[pageIndex], pageId = replaceIdentity(page.id), ids = /* @__PURE__ */ new Set();
|
|
3266
|
+
if (pageIds.has(pageId)) textReplaceError("Replace page identities are ambiguous.");
|
|
3267
|
+
pageIds.add(pageId);
|
|
3268
|
+
const walk = (source, depth) => {
|
|
3269
|
+
const length = source.length;
|
|
3270
|
+
if (!Array.isArray(source) || !Number.isSafeInteger(length) || length < 0 || length > 0 && depth > VISIO_TEXT_REPLACE_LIMITS.depth || length > VISIO_TEXT_REPLACE_LIMITS.shapes)
|
|
3271
|
+
textReplaceError("Replace shape list exceeds supported limits.");
|
|
3272
|
+
for (let index = 0; index < length; index++) {
|
|
3273
|
+
const shape = source[index], shapeId = replaceIdentity(shape.id);
|
|
3274
|
+
if (seen.has(shape) || ids.has(shapeId) || seen.size >= VISIO_TEXT_REPLACE_LIMITS.shapes)
|
|
3275
|
+
textReplaceError("Replace shape identities, depth or cycles are invalid.");
|
|
3276
|
+
seen.add(shape);
|
|
3277
|
+
ids.add(shapeId);
|
|
3278
|
+
const text = replaceString(shape.text.plainText, VISIO_TEXT_REPLACE_LIMITS.text, "source text");
|
|
3279
|
+
const name = replaceString(shape.name, 4096, "shape name");
|
|
3280
|
+
names += name.length;
|
|
3281
|
+
if (names > VISIO_TEXT_REPLACE_LIMITS.names) textReplaceError("Replace shape names exceed aggregate limits.");
|
|
3282
|
+
characters += text.length;
|
|
3283
|
+
if (characters > VISIO_TEXT_REPLACE_LIMITS.text) textReplaceError("Replace text exceeds aggregate limits.");
|
|
3284
|
+
const entry = { pageId, shapeId, name, pageIndex, text, end: 0 };
|
|
3285
|
+
identities.set(JSON.stringify([pageId, shapeId]), all.length);
|
|
3286
|
+
all.push(entry);
|
|
3287
|
+
walk(shape.children, depth + 1);
|
|
3288
|
+
entry.end = all.length;
|
|
3289
|
+
}
|
|
3290
|
+
};
|
|
3291
|
+
walk(page.shapes, 0);
|
|
3292
|
+
}
|
|
3293
|
+
if (requirePage && !pageIds.has(scope.pageId))
|
|
3294
|
+
textReplaceError("Replace current page does not exist.");
|
|
3295
|
+
if (scope.scope === "all-pages") return all;
|
|
3296
|
+
if (scope.scope === "current-page") return all.filter((entry) => entry.pageId === scope.pageId);
|
|
3297
|
+
const result = [], added = /* @__PURE__ */ new Set();
|
|
3298
|
+
for (const selected of scope.selection ?? []) {
|
|
3299
|
+
const pageId = selected.pageId ?? scope.pageId;
|
|
3300
|
+
const start = identities.get(JSON.stringify([pageId, selected.id]));
|
|
3301
|
+
if (start === void 0) return textReplaceError("Replace selected shape does not exist.");
|
|
3302
|
+
for (let index = start; index < all[start].end; index++) {
|
|
3303
|
+
const entry = all[index];
|
|
3304
|
+
if (added.has(entry)) {
|
|
3305
|
+
index = entry.end - 1;
|
|
3306
|
+
continue;
|
|
3307
|
+
}
|
|
3308
|
+
result.push(entry);
|
|
3309
|
+
added.add(entry);
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
return result;
|
|
3313
|
+
}
|
|
3314
|
+
|
|
3315
|
+
// visio/ui/text-replace-selection.ts
|
|
3316
|
+
function visioTextOccurrenceSelection(model, occurrence) {
|
|
3317
|
+
const pageId = replaceIdentity(occurrence.pageId), shapeId = replaceIdentity(occurrence.shapeId), start = occurrence.start, end = occurrence.end;
|
|
3318
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end <= start)
|
|
3319
|
+
return void 0;
|
|
3320
|
+
const entries = replaceEntries(
|
|
3321
|
+
model,
|
|
3322
|
+
{ pageId, scope: "all-pages"},
|
|
3323
|
+
false
|
|
3324
|
+
);
|
|
3325
|
+
const entry = entries.find((item) => item.pageId === pageId && item.shapeId === shapeId);
|
|
3326
|
+
if (!entry || end > entry.text.length) return void 0;
|
|
3327
|
+
return Object.freeze({
|
|
3328
|
+
pageIndex: entry.pageIndex,
|
|
3329
|
+
selection: Object.freeze({ id: shapeId, name: entry.name, pageId })
|
|
3330
|
+
});
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
// visio/ui/text-replace.ts
|
|
3334
|
+
function occurrences(entries, query) {
|
|
3335
|
+
const result = [];
|
|
3336
|
+
for (const entry of entries) {
|
|
3337
|
+
let start = entry.text.indexOf(query);
|
|
3338
|
+
while (start >= 0) {
|
|
3339
|
+
if (result.length >= VISIO_TEXT_REPLACE_LIMITS.matches)
|
|
3340
|
+
textReplaceError("Replace occurrence count exceeds limits.");
|
|
3341
|
+
result.push(
|
|
3342
|
+
Object.freeze({
|
|
3343
|
+
pageId: entry.pageId,
|
|
3344
|
+
shapeId: entry.shapeId,
|
|
3345
|
+
start,
|
|
3346
|
+
end: start + query.length
|
|
3347
|
+
})
|
|
3348
|
+
);
|
|
3349
|
+
start = entry.text.indexOf(query, start + query.length);
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
return Object.freeze(result);
|
|
3353
|
+
}
|
|
3354
|
+
function visioTextReplaceOccurrences(model, input) {
|
|
3355
|
+
const scope = snapshotReplaceScope(input);
|
|
3356
|
+
return occurrences(replaceEntries(model, scope), scope.query);
|
|
3357
|
+
}
|
|
3358
|
+
function visioTextReplaceFindNext(model, input, current) {
|
|
3359
|
+
const saved = snapshotOccurrence(current);
|
|
3360
|
+
const found = visioTextReplaceOccurrences(model, input);
|
|
3361
|
+
if (saved === void 0) return found[0];
|
|
3362
|
+
const index = found.findIndex((match) => sameOccurrence(match, saved));
|
|
3363
|
+
if (index < 0) return textReplaceError("Find occurrence is stale or outside the scope.");
|
|
3364
|
+
return found[(index + 1) % found.length];
|
|
3365
|
+
}
|
|
3366
|
+
var records = /* @__PURE__ */ new WeakMap();
|
|
3367
|
+
var sameOccurrence = (a, b) => a.pageId === b.pageId && a.shapeId === b.shapeId && a.start === b.start && a.end === b.end;
|
|
3368
|
+
var sameTarget = (entry, match) => entry.pageId === match.pageId && entry.shapeId === match.shapeId;
|
|
3369
|
+
function snapshotOccurrence(original) {
|
|
3370
|
+
if (original === void 0) return void 0;
|
|
3371
|
+
const current = {
|
|
3372
|
+
pageId: replaceIdentity(original.pageId),
|
|
3373
|
+
shapeId: replaceIdentity(original.shapeId),
|
|
3374
|
+
start: original.start,
|
|
3375
|
+
end: original.end
|
|
3376
|
+
};
|
|
3377
|
+
if (!Number.isSafeInteger(current.start) || !Number.isSafeInteger(current.end) || current.start < 0 || current.end <= current.start || current.end > VISIO_TEXT_REPLACE_LIMITS.text)
|
|
3378
|
+
textReplaceError("Invalid replacement occurrence range.");
|
|
3379
|
+
return current;
|
|
3380
|
+
}
|
|
3381
|
+
function visioTextReplacePlan(model, input) {
|
|
3382
|
+
const scope = snapshotReplaceScope(input), replacement = replaceString(input.replacement, VISIO_TEXT_REPLACE_LIMITS.replacement, "replacement"), mode = input.mode, current = snapshotOccurrence(input.current);
|
|
3383
|
+
if (mode !== "current" && mode !== "all") textReplaceError("Invalid replacement mode.");
|
|
3384
|
+
if (/[\u0000-\u0008\u000b\u000c\u000d\u000e-\u001f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/u.test(
|
|
3385
|
+
replacement
|
|
3386
|
+
))
|
|
3387
|
+
textReplaceError("Replacement contains invalid XML text characters.");
|
|
3388
|
+
const entries = replaceEntries(model, scope), found = occurrences(entries, scope.query);
|
|
3389
|
+
const active = current === void 0 ? found[0] : found.find((match) => sameOccurrence(match, current));
|
|
3390
|
+
if (current !== void 0 && !active)
|
|
3391
|
+
textReplaceError("Replace occurrence is stale or outside the scope.");
|
|
3392
|
+
const selected = mode === "all" ? found : active ? [active] : [];
|
|
3393
|
+
const targets = /* @__PURE__ */ new Map();
|
|
3394
|
+
for (const match of selected) {
|
|
3395
|
+
const key = JSON.stringify([match.pageId, match.shapeId]);
|
|
3396
|
+
const list = targets.get(key) ?? [];
|
|
3397
|
+
list.push(match);
|
|
3398
|
+
targets.set(key, list);
|
|
3399
|
+
}
|
|
3400
|
+
if (targets.size > VISIO_TEXT_REPLACE_LIMITS.commands) textReplaceError("Replace command count exceeds limits.");
|
|
3401
|
+
const edits = [], updated = [];
|
|
3402
|
+
let outputCharacters = 0, commandCharacters = 0;
|
|
3403
|
+
for (const entry of entries) {
|
|
3404
|
+
const matches = targets.get(JSON.stringify([entry.pageId, entry.shapeId]));
|
|
3405
|
+
let text = entry.text;
|
|
3406
|
+
if (matches) {
|
|
3407
|
+
const length = text.length + matches.length * (replacement.length - scope.query.length);
|
|
3408
|
+
outputCharacters += length;
|
|
3409
|
+
if (length > VISIO_TEXT_REPLACE_LIMITS.output || outputCharacters > VISIO_TEXT_REPLACE_LIMITS.output)
|
|
3410
|
+
textReplaceError("Replace output exceeds aggregate command text limits.");
|
|
3411
|
+
const parts = [];
|
|
3412
|
+
let from = 0;
|
|
3413
|
+
for (const match of matches) {
|
|
3414
|
+
parts.push(text.slice(from, match.start), replacement);
|
|
3415
|
+
from = match.end;
|
|
3416
|
+
}
|
|
3417
|
+
parts.push(text.slice(from));
|
|
3418
|
+
text = parts.join("");
|
|
3419
|
+
const target = { pageId: entry.pageId, shapeId: entry.shapeId };
|
|
3420
|
+
if (replacement.includes("\n") || scope.query.includes("\n")) {
|
|
3421
|
+
commandCharacters += text.length;
|
|
3422
|
+
edits.push(Object.freeze({ type: "replace-plain-text", ...target, text }));
|
|
3423
|
+
} else {
|
|
3424
|
+
commandCharacters += entry.text.length + matches.length * replacement.length;
|
|
3425
|
+
edits.push(
|
|
3426
|
+
Object.freeze({
|
|
3427
|
+
type: "replace-text-ranges",
|
|
3428
|
+
...target,
|
|
3429
|
+
expectedText: entry.text,
|
|
3430
|
+
ranges: Object.freeze(
|
|
3431
|
+
matches.map(
|
|
3432
|
+
(match) => Object.freeze({ start: match.start, end: match.end, text: replacement })
|
|
3433
|
+
)
|
|
3434
|
+
)
|
|
3435
|
+
})
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
if (commandCharacters > VISIO_TEXT_REPLACE_LIMITS.output)
|
|
3439
|
+
textReplaceError("Replace input exceeds aggregate command text limits.");
|
|
3440
|
+
}
|
|
3441
|
+
updated.push({ ...entry, text });
|
|
3442
|
+
}
|
|
3443
|
+
const remaining = mode === "current" ? occurrences(updated, scope.query) : [];
|
|
3444
|
+
const activeEntry = active ? entries.findIndex((entry) => sameTarget(entry, active)) : -1;
|
|
3445
|
+
const entryIndices = new Map(
|
|
3446
|
+
entries.map((entry, index) => [JSON.stringify([entry.pageId, entry.shapeId]), index])
|
|
3447
|
+
);
|
|
3448
|
+
const nextOccurrence = active ? remaining.find((match) => {
|
|
3449
|
+
const index = entryIndices.get(JSON.stringify([match.pageId, match.shapeId]));
|
|
3450
|
+
return index > activeEntry || index === activeEntry && match.start >= active.start + replacement.length;
|
|
3451
|
+
}) ?? remaining[0] : remaining[0];
|
|
3452
|
+
const plan = Object.freeze({
|
|
3453
|
+
occurrences: found,
|
|
3454
|
+
replacementCount: selected.length,
|
|
3455
|
+
edits: Object.freeze(edits),
|
|
3456
|
+
nextOccurrence
|
|
3457
|
+
});
|
|
3458
|
+
records.set(plan, { scope, entries });
|
|
3459
|
+
return plan;
|
|
3460
|
+
}
|
|
3461
|
+
function visioTextReplaceCommands(model, plan) {
|
|
3462
|
+
const record2 = records.get(plan);
|
|
3463
|
+
if (!record2) return textReplaceError("Replace plan was not produced by this planner.");
|
|
3464
|
+
const current = replaceEntries(model, record2.scope);
|
|
3465
|
+
if (current.length !== record2.entries.length || current.some((entry, index) => {
|
|
3466
|
+
const saved = record2.entries[index];
|
|
3467
|
+
return entry.pageId !== saved.pageId || entry.shapeId !== saved.shapeId || entry.text !== saved.text;
|
|
3468
|
+
}))
|
|
3469
|
+
textReplaceError("Replace plan is stale. Search the current drawing again.");
|
|
3470
|
+
return plan.edits.map(
|
|
3471
|
+
(edit) => edit.type === "replace-text-ranges" ? { ...edit, ranges: edit.ranges.map((range) => ({ ...range })) } : { ...edit }
|
|
3472
|
+
);
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
// visio/ui/svg-stroke.ts
|
|
3476
|
+
function visioSvgStrokeStyle(style) {
|
|
3477
|
+
return style.lineWidth === 0 ? { ...style, lineWidth: 0.75 / 72 } : style;
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
// visio/ui/page-size.ts
|
|
3481
|
+
var VISIO_PAGE_SIZE_PRESETS = Object.freeze([
|
|
3482
|
+
Object.freeze({ id: "letter", label: "Letter", width: 8.5, height: 11 }),
|
|
3483
|
+
Object.freeze({ id: "a4", label: "A4", width: 210 / 25.4, height: 297 / 25.4 })
|
|
3484
|
+
]);
|
|
3485
|
+
var dimension = (value) => Number.isFinite(value) && value > 0 && value <= 1e6;
|
|
3486
|
+
function visioPageSizeState(page) {
|
|
3487
|
+
const { id: pageId, width, height, drawingSizeType, drawingResizeType } = page;
|
|
3488
|
+
if (!dimension(width) || !dimension(height) || !pageId || pageId.length > 256) return void 0;
|
|
3489
|
+
return Object.freeze({
|
|
3490
|
+
pageId,
|
|
3491
|
+
width,
|
|
3492
|
+
height,
|
|
3493
|
+
orientation: width === height ? "square" : width > height ? "landscape" : "portrait",
|
|
3494
|
+
...drawingSizeType === void 0 ? {} : { drawingSizeType },
|
|
3495
|
+
...drawingResizeType === void 0 ? {} : { drawingResizeType }
|
|
3496
|
+
});
|
|
3497
|
+
}
|
|
3498
|
+
function visioPageSizeCommand(page, width, height) {
|
|
3499
|
+
const state = visioPageSizeState(page);
|
|
3500
|
+
if (!state || !dimension(width) || !dimension(height)) return void 0;
|
|
3501
|
+
if (width === state.width && height === state.height && state.drawingSizeType === 3 && state.drawingResizeType === 0)
|
|
3502
|
+
return [];
|
|
3503
|
+
return [{ type: "set-page-size", pageId: state.pageId, width, height }];
|
|
3504
|
+
}
|
|
3505
|
+
function visioPageOrientationCommand(page, orientation) {
|
|
3506
|
+
const state = visioPageSizeState(page);
|
|
3507
|
+
if (!state || !["portrait", "landscape"].includes(orientation)) return void 0;
|
|
3508
|
+
const short = Math.min(state.width, state.height), long = Math.max(state.width, state.height);
|
|
3509
|
+
return visioPageSizeCommand(
|
|
3510
|
+
page,
|
|
3511
|
+
orientation === "portrait" ? short : long,
|
|
3512
|
+
orientation === "portrait" ? long : short
|
|
3513
|
+
);
|
|
3514
|
+
}
|
|
3515
|
+
function visioPageSizePresetCommand(page, id) {
|
|
3516
|
+
const state = visioPageSizeState(page), preset = VISIO_PAGE_SIZE_PRESETS.find((item) => item.id === id);
|
|
3517
|
+
if (!state || !preset) return void 0;
|
|
3518
|
+
return visioPageSizeCommand(
|
|
3519
|
+
page,
|
|
3520
|
+
state.orientation === "landscape" ? preset.height : preset.width,
|
|
3521
|
+
state.orientation === "landscape" ? preset.width : preset.height
|
|
3522
|
+
);
|
|
3523
|
+
}
|
|
3524
|
+
|
|
2162
3525
|
exports.DocumentHistory = DocumentHistory;
|
|
2163
3526
|
exports.EDIT_HISTORY_LIMITS = EDIT_HISTORY_LIMITS;
|
|
2164
3527
|
exports.EMPTY_EDIT_STATE = EMPTY_EDIT_STATE;
|
|
3528
|
+
exports.EMPTY_SELECTION = EMPTY_SELECTION;
|
|
2165
3529
|
exports.EMPTY_TEXT_SEARCH = EMPTY_TEXT_SEARCH;
|
|
2166
3530
|
exports.FOREIGN_VECTOR_SCENE_LIMITS = FOREIGN_VECTOR_SCENE_LIMITS;
|
|
2167
3531
|
exports.ForeignVectorBudget = ForeignVectorBudget;
|
|
2168
3532
|
exports.MAX_INPUT_BYTES = MAX_INPUT_BYTES;
|
|
2169
3533
|
exports.TEXT_SEARCH_LIMITS = TEXT_SEARCH_LIMITS;
|
|
2170
3534
|
exports.VISIO_IDENTITY_TRANSFORM = IDENTITY_AFFINE;
|
|
3535
|
+
exports.VISIO_PAGE_SIZE_PRESETS = VISIO_PAGE_SIZE_PRESETS;
|
|
3536
|
+
exports.VISIO_RESIZE_HANDLES = VISIO_RESIZE_HANDLES;
|
|
3537
|
+
exports.VISIO_TEXT_REPLACE_LIMITS = VISIO_TEXT_REPLACE_LIMITS;
|
|
2171
3538
|
exports.assertShapeDetails = assertShapeDetails;
|
|
2172
3539
|
exports.assertViewableDocument = assertViewableDocument;
|
|
2173
3540
|
exports.compatibilityNotes = compatibilityNotes;
|
|
@@ -2177,23 +3544,69 @@ exports.copySnapshotScene = copySnapshotScene;
|
|
|
2177
3544
|
exports.demoDocument = demoDocument;
|
|
2178
3545
|
exports.editErrorMessage = editErrorMessage;
|
|
2179
3546
|
exports.eventKeys = eventKeys;
|
|
3547
|
+
exports.hasVisibleShapeContent = hasVisibleShapeContent;
|
|
2180
3548
|
exports.indexDocumentText = indexDocumentText;
|
|
2181
3549
|
exports.inspectForeignVectorResource = inspectForeignVectorResource;
|
|
2182
3550
|
exports.isEditCancellation = isEditCancellation;
|
|
2183
3551
|
exports.propertyKeys = propertyKeys;
|
|
3552
|
+
exports.sameSelection = sameSelection;
|
|
2184
3553
|
exports.searchDocumentText = searchDocumentText;
|
|
3554
|
+
exports.selectionKey = selectionKey;
|
|
2185
3555
|
exports.snapshotEdits = snapshotEdits;
|
|
3556
|
+
exports.snapshotSelection = snapshotSelection;
|
|
2186
3557
|
exports.textSearchStatus = textSearchStatus;
|
|
2187
3558
|
exports.validateSearchQuery = validateSearchQuery;
|
|
3559
|
+
exports.visioArrangeCommands = visioArrangeCommands;
|
|
3560
|
+
exports.visioBoxCreationCommand = visioBoxCreationCommand;
|
|
3561
|
+
exports.visioClipboardShape = visioClipboardShape;
|
|
3562
|
+
exports.visioDrawBounds = visioDrawBounds;
|
|
3563
|
+
exports.visioDrawIsLargeEnough = visioDrawIsLargeEnough;
|
|
3564
|
+
exports.visioDrawPlan = visioDrawPlan;
|
|
3565
|
+
exports.visioDrawingPoint = visioDrawingPoint;
|
|
3566
|
+
exports.visioDuplicateCommand = visioDuplicateCommand;
|
|
2188
3567
|
exports.visioFillPatternTransform = visioFillPatternTransform;
|
|
3568
|
+
exports.visioFontFamilies = visioFontFamilies;
|
|
3569
|
+
exports.visioFormattingShape = visioFormattingShape;
|
|
2189
3570
|
exports.visioGradientInstances = visioGradientInstances;
|
|
3571
|
+
exports.visioLineCreationCommand = visioLineCreationCommand;
|
|
3572
|
+
exports.visioLineDashLengths = visioLineDashLengths;
|
|
2190
3573
|
exports.visioLocalRotationShape = visioLocalRotationShape;
|
|
3574
|
+
exports.visioMarqueeBox = visioMarqueeBox;
|
|
3575
|
+
exports.visioMarqueeSelection = visioMarqueeSelection;
|
|
3576
|
+
exports.visioMoveCommands = visioMoveCommands;
|
|
3577
|
+
exports.visioMovePreviewTransform = visioMovePreviewTransform;
|
|
3578
|
+
exports.visioMovementShape = visioMovementShape;
|
|
2191
3579
|
exports.visioNextShapeId = visioNextShapeId;
|
|
3580
|
+
exports.visioOrderingShape = visioOrderingShape;
|
|
3581
|
+
exports.visioPageDragDelta = visioPageDragDelta;
|
|
2192
3582
|
exports.visioPageEditToDrawing = visioPageEditToDrawing;
|
|
2193
3583
|
exports.visioPageInsertCommand = visioPageInsertCommand;
|
|
3584
|
+
exports.visioPageOrientationCommand = visioPageOrientationCommand;
|
|
3585
|
+
exports.visioPageSizeCommand = visioPageSizeCommand;
|
|
3586
|
+
exports.visioPageSizePresetCommand = visioPageSizePresetCommand;
|
|
3587
|
+
exports.visioPageSizeState = visioPageSizeState;
|
|
3588
|
+
exports.visioPasteCommand = visioPasteCommand;
|
|
2194
3589
|
exports.visioQuarterTurnCommand = visioQuarterTurnCommand;
|
|
2195
3590
|
exports.visioRenderedGradientStopCount = visioRenderedGradientStopCount;
|
|
2196
3591
|
exports.visioRenderedGradientStops = visioRenderedGradientStops;
|
|
3592
|
+
exports.visioResizeDrag = visioResizeDrag;
|
|
3593
|
+
exports.visioResizeFrame = visioResizeFrame;
|
|
3594
|
+
exports.visioResizeShape = visioResizeShape;
|
|
2197
3595
|
exports.visioRotationPreviewTransform = visioRotationPreviewTransform;
|
|
3596
|
+
exports.visioSelectionIsOnPage = visioSelectionIsOnPage;
|
|
3597
|
+
exports.visioShapeFormattingState = visioShapeFormattingState;
|
|
3598
|
+
exports.visioShapePageBox = visioShapePageBox;
|
|
3599
|
+
exports.visioSizePositionCommand = visioSizePositionCommand;
|
|
3600
|
+
exports.visioSizePositionState = visioSizePositionState;
|
|
2198
3601
|
exports.visioStraightLineHandles = visioStraightLineHandles;
|
|
2199
3602
|
exports.visioStrokeGradient = visioStrokeGradient;
|
|
3603
|
+
exports.visioStyleFormattingShape = visioStyleFormattingShape;
|
|
3604
|
+
exports.visioSvgStrokeStyle = visioSvgStrokeStyle;
|
|
3605
|
+
exports.visioTextFontStepCommand = visioTextFontStepCommand;
|
|
3606
|
+
exports.visioTextFormattingState = visioTextFormattingState;
|
|
3607
|
+
exports.visioTextIndentCommand = visioTextIndentCommand;
|
|
3608
|
+
exports.visioTextOccurrenceSelection = visioTextOccurrenceSelection;
|
|
3609
|
+
exports.visioTextReplaceCommands = visioTextReplaceCommands;
|
|
3610
|
+
exports.visioTextReplaceFindNext = visioTextReplaceFindNext;
|
|
3611
|
+
exports.visioTextReplaceOccurrences = visioTextReplaceOccurrences;
|
|
3612
|
+
exports.visioTextReplacePlan = visioTextReplacePlan;
|