ooxml-core 0.10.0 → 0.12.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 +10 -6
- package/dist/automation/docx.d.ts +13 -0
- package/dist/automation/docx.d.ts.map +1 -0
- package/dist/automation/index.cjs +36953 -0
- package/dist/automation/index.d.ts +6 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.mjs +36939 -0
- package/dist/automation/node.cjs +103 -0
- package/dist/automation/node.d.ts +16 -0
- package/dist/automation/node.d.ts.map +1 -0
- package/dist/automation/node.mjs +101 -0
- package/dist/automation/visio.d.ts +30 -0
- package/dist/automation/visio.d.ts.map +1 -0
- package/dist/automation/xlsx.d.ts +25 -0
- package/dist/automation/xlsx.d.ts.map +1 -0
- package/dist/pptx/automation/index.cjs +149047 -0
- package/dist/pptx/automation/index.d.ts +1474 -0
- package/dist/pptx/automation/index.d.ts.map +1 -0
- package/dist/pptx/automation/index.mjs +148926 -0
- package/dist/pptx/chunks/{index-BWUBPGgv.d.ts → index-BWRd8p4y.d.ts} +2 -2
- package/dist/pptx/chunks/{index-BWUBPGgv.d.ts.map → index-BWRd8p4y.d.ts.map} +1 -1
- package/dist/pptx/chunks/index-LoCVDu8Z.d.ts +9644 -0
- package/dist/pptx/chunks/index-LoCVDu8Z.d.ts.map +1 -0
- package/dist/pptx/chunks/{text-operations-IlJiffp7.d.ts → text-operations-2tKzrY5o.d.ts} +7381 -7381
- package/dist/pptx/chunks/text-operations-2tKzrY5o.d.ts.map +1 -0
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/index.d.ts +4 -9644
- package/dist/visio/edit-geometry-admission.d.ts +6 -3
- package/dist/visio/edit-geometry-admission.d.ts.map +1 -1
- package/dist/visio/edit-geometry.d.ts +2 -1
- package/dist/visio/edit-geometry.d.ts.map +1 -1
- package/dist/visio/edit-master-index.d.ts +1 -1
- package/dist/visio/edit-master-index.d.ts.map +1 -1
- package/dist/visio/edit-master-move.d.ts +20 -0
- package/dist/visio/edit-master-move.d.ts.map +1 -0
- package/dist/visio/edit-master-scope.d.ts +2 -1
- package/dist/visio/edit-master-scope.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-index.d.ts +2 -0
- package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
- package/dist/visio/edit-scope.d.ts +2 -1
- package/dist/visio/edit-scope.d.ts.map +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +250 -36
- package/dist/visio/index.mjs +250 -36
- package/dist/xlsx/formula/area-index.d.ts +3 -3
- package/dist/xlsx/formula/area-index.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-core.d.ts +4 -1
- package/dist/xlsx/formula/engine-core.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-host.d.ts +2 -0
- package/dist/xlsx/formula/engine-host.d.ts.map +1 -1
- package/dist/xlsx/formula/engine-order.d.ts +11 -0
- package/dist/xlsx/formula/engine-order.d.ts.map +1 -0
- package/dist/xlsx/formula/spill.d.ts.map +1 -1
- package/dist/xlsx/formula/store.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +102 -64
- package/dist/xlsx/index.mjs +102 -64
- package/package.json +21 -3
- package/dist/pptx/chunks/text-operations-IlJiffp7.d.ts.map +0 -1
- package/dist/pptx/index.d.ts.map +0 -1
package/dist/visio/index.cjs
CHANGED
|
@@ -6183,7 +6183,7 @@ function recalculateVisioCells(roots, changed, options = {}) {
|
|
|
6183
6183
|
if (active.size >= maxDepth)
|
|
6184
6184
|
fail("LIMIT_FORMULA_DEPTH", "ShapeSheet dependency depth limit exceeded.");
|
|
6185
6185
|
const item = cells3.get(id);
|
|
6186
|
-
if (!item || item.unsafe)
|
|
6186
|
+
if (!item || item.unsafe && (!item.node || !options.masterMovePins?.has(item.node)))
|
|
6187
6187
|
fail(
|
|
6188
6188
|
"EDIT_UNSUPPORTED_DEPENDENCY",
|
|
6189
6189
|
"Affected formula references missing, inherited or grouped cells."
|
|
@@ -6336,7 +6336,7 @@ function setCell(shape, name, value, formula) {
|
|
|
6336
6336
|
if (formula) node.setAttribute("F", formula);
|
|
6337
6337
|
else if (attribute2(node, "F") !== "No Formula") node.removeAttribute("F");
|
|
6338
6338
|
}
|
|
6339
|
-
function admitted(root, shapeId) {
|
|
6339
|
+
function admitted(root, shapeId, masterMovePins = /* @__PURE__ */ new Set(), masterDimensions = /* @__PURE__ */ new Map()) {
|
|
6340
6340
|
const containers = children(root, "Shapes");
|
|
6341
6341
|
if (containers.length !== 1)
|
|
6342
6342
|
fail("UNSUPPORTED_GEOMETRY_EDIT", "One local Shapes container is required.");
|
|
@@ -6346,7 +6346,10 @@ function admitted(root, shapeId) {
|
|
|
6346
6346
|
if (candidates.length !== 1)
|
|
6347
6347
|
fail("EDIT_TARGET_NOT_FOUND", "A unique top-level local shape is required.");
|
|
6348
6348
|
const shape = candidates[0];
|
|
6349
|
-
if (shape.hasAttribute("Master") || shape.hasAttribute("MasterShape")
|
|
6349
|
+
if ((shape.hasAttribute("Master") || shape.hasAttribute("MasterShape")) && !["PinX", "PinY"].every((name) => {
|
|
6350
|
+
const cell = cells(shape).get(name);
|
|
6351
|
+
return cell && masterMovePins.has(cell);
|
|
6352
|
+
}) || ["1", "true"].includes(attribute2(shape, "Del") ?? "") || children(shape, "Shapes").length || children(shape, "ForeignData").length || children(shape, "Rel").length || attribute2(shape, "Type") && attribute2(shape, "Type") !== "Shape")
|
|
6350
6353
|
fail(
|
|
6351
6354
|
"UNSUPPORTED_GEOMETRY_EDIT",
|
|
6352
6355
|
"Master, group, foreign, deleted and non-shape operations are unsupported."
|
|
@@ -6362,12 +6365,17 @@ function admitted(root, shapeId) {
|
|
|
6362
6365
|
"UNSUPPORTED_GEOMETRY_EDIT",
|
|
6363
6366
|
"Only local 2D shapes are admitted; line routing and glue are unsupported."
|
|
6364
6367
|
);
|
|
6365
|
-
|
|
6366
|
-
|
|
6368
|
+
const proven = masterDimensions.get(shape);
|
|
6369
|
+
if (!(numeric3(local.get("Width"), proven?.width) > 0) || !(numeric3(local.get("Height"), proven?.height) > 0))
|
|
6370
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Positive proven Width and Height caches are required.");
|
|
6367
6371
|
return shape;
|
|
6368
6372
|
}
|
|
6369
|
-
function protectedShape(shape, document) {
|
|
6373
|
+
function protectedShape(shape, document, masterMovePins = /* @__PURE__ */ new Set()) {
|
|
6370
6374
|
const local = cells(shape);
|
|
6375
|
+
const certifiedMove = shape.hasAttribute("Master") && ["PinX", "PinY"].every((name) => {
|
|
6376
|
+
const node = local.get(name);
|
|
6377
|
+
return node !== void 0 && masterMovePins.has(node);
|
|
6378
|
+
});
|
|
6371
6379
|
const styles = /* @__PURE__ */ new Map();
|
|
6372
6380
|
for (const container of children(document, "StyleSheets"))
|
|
6373
6381
|
for (const node of children(container, "StyleSheet")) {
|
|
@@ -6375,9 +6383,13 @@ function protectedShape(shape, document) {
|
|
|
6375
6383
|
if (!id || styles.has(id)) fail("EDIT_PROTECTED_CELL", "Ambiguous protection style IDs.");
|
|
6376
6384
|
styles.set(id, node);
|
|
6377
6385
|
}
|
|
6378
|
-
const
|
|
6386
|
+
const validateProtection = (cell) => {
|
|
6379
6387
|
try {
|
|
6380
|
-
|
|
6388
|
+
const cached2 = numeric3(cell);
|
|
6389
|
+
const operationIndependent = certifiedMove && ["LockWidth", "LockHeight", "LockAspect", "LockDelete"].includes(
|
|
6390
|
+
attribute2(cell, "N") ?? ""
|
|
6391
|
+
);
|
|
6392
|
+
if (cell.hasAttribute("E") || visioFormulaCachedValue(attribute2(cell, "V") ?? "", attribute2(cell, "U")).unit !== "scalar" || !(cached2 === 0 || operationIndependent && cached2 === 1))
|
|
6381
6393
|
fail("EDIT_PROTECTED_CELL", "Inherited protection is active or invalid.");
|
|
6382
6394
|
const source = executableCellFormula(attribute2(cell, "F"));
|
|
6383
6395
|
if (!source) return;
|
|
@@ -6388,12 +6400,12 @@ function protectedShape(shape, document) {
|
|
|
6388
6400
|
source,
|
|
6389
6401
|
() => fail("EDIT_PROTECTED_CELL", "Inherited protection has dependencies.")
|
|
6390
6402
|
);
|
|
6391
|
-
if (result.unit !== "scalar" || result.value !==
|
|
6392
|
-
fail("EDIT_PROTECTED_CELL", "Inherited protection formula is
|
|
6403
|
+
if (result.unit !== "scalar" || result.value !== cached2)
|
|
6404
|
+
fail("EDIT_PROTECTED_CELL", "Inherited protection formula cache is stale.");
|
|
6393
6405
|
} catch (error) {
|
|
6394
6406
|
fail(
|
|
6395
6407
|
"EDIT_PROTECTED_CELL",
|
|
6396
|
-
`Inherited protection cannot be proven
|
|
6408
|
+
`Inherited protection cannot be proven safe for this operation: ${error instanceof Error ? error.message : "invalid cache"}`
|
|
6397
6409
|
);
|
|
6398
6410
|
}
|
|
6399
6411
|
};
|
|
@@ -6405,16 +6417,18 @@ function protectedShape(shape, document) {
|
|
|
6405
6417
|
if (!style) fail("EDIT_PROTECTED_CELL", "Protection style ancestry cannot be resolved.");
|
|
6406
6418
|
const cell = cells(style).get(lock), parent = attribute2(style, category);
|
|
6407
6419
|
if (cell && attribute2(cell, "F") !== "Inh") {
|
|
6408
|
-
|
|
6420
|
+
validateProtection(cell);
|
|
6409
6421
|
return cell;
|
|
6410
6422
|
}
|
|
6411
6423
|
if (cell) {
|
|
6412
|
-
|
|
6424
|
+
validateProtection(cell);
|
|
6413
6425
|
if (parent === void 0 || parent === id)
|
|
6414
6426
|
fail("EDIT_PROTECTED_CELL", "Inherited protection has no provable parent.");
|
|
6415
6427
|
const inherited = resolve(parent, category, lock, seen);
|
|
6416
6428
|
if (!inherited)
|
|
6417
|
-
fail("EDIT_PROTECTED_CELL", "Inherited protection has no explicit
|
|
6429
|
+
fail("EDIT_PROTECTED_CELL", "Inherited protection has no explicit provable ancestor.");
|
|
6430
|
+
if (numeric3(cell) !== numeric3(inherited))
|
|
6431
|
+
fail("EDIT_PROTECTED_CELL", "Delegated protection cache disagrees with its ancestor.");
|
|
6418
6432
|
return inherited;
|
|
6419
6433
|
}
|
|
6420
6434
|
return parent !== void 0 && parent !== id ? resolve(parent, category, lock, seen) : void 0;
|
|
@@ -6491,6 +6505,130 @@ function resizeGeometry(shape, roots, edit, check) {
|
|
|
6491
6505
|
}
|
|
6492
6506
|
}
|
|
6493
6507
|
|
|
6508
|
+
// src/visio/edit-master-move.ts
|
|
6509
|
+
var protection = [
|
|
6510
|
+
"LockMoveX",
|
|
6511
|
+
"LockMoveY",
|
|
6512
|
+
"LockWidth",
|
|
6513
|
+
"LockHeight",
|
|
6514
|
+
"LockAspect",
|
|
6515
|
+
"LockDelete"
|
|
6516
|
+
];
|
|
6517
|
+
var dimensions2 = ["PinX", "PinY", "Width", "Height", "LocPinX", "LocPinY"];
|
|
6518
|
+
var emptyMasterMoveProof = () => ({
|
|
6519
|
+
pins: /* @__PURE__ */ new Set(),
|
|
6520
|
+
dimensions: /* @__PURE__ */ new Map()
|
|
6521
|
+
});
|
|
6522
|
+
function prepareMasterMovePins(roots, commands, bindings, check) {
|
|
6523
|
+
const result = /* @__PURE__ */ new Set();
|
|
6524
|
+
const provenDimensions = /* @__PURE__ */ new Map();
|
|
6525
|
+
let work = 1e5;
|
|
6526
|
+
const charge = (amount = 1) => {
|
|
6527
|
+
check();
|
|
6528
|
+
work -= amount;
|
|
6529
|
+
if (work < 0)
|
|
6530
|
+
fail("EDIT_UNSUPPORTED_PACKAGE_DEPENDENCY", "Master move preparation budget exceeded.");
|
|
6531
|
+
};
|
|
6532
|
+
const analyze = (formula) => {
|
|
6533
|
+
charge(formula.length);
|
|
6534
|
+
return analyzeVisioFormula(formula);
|
|
6535
|
+
};
|
|
6536
|
+
for (const command2 of commands) {
|
|
6537
|
+
charge();
|
|
6538
|
+
const root = roots.get(command2.pageId);
|
|
6539
|
+
const instance = children(children(root, "Shapes")[0], "Shape").find(
|
|
6540
|
+
(shape) => attribute2(shape, "ID") === command2.shapeId
|
|
6541
|
+
);
|
|
6542
|
+
if (!instance?.hasAttribute("Master")) continue;
|
|
6543
|
+
if (command2.type !== "move-shape")
|
|
6544
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Master-linked resizing and deletion remain unsupported.");
|
|
6545
|
+
const binding = bindings.find((candidate) => candidate.instance === instance);
|
|
6546
|
+
if (!binding) fail("UNSUPPORTED_GEOMETRY_EDIT", "A unique effective master root is required.");
|
|
6547
|
+
for (const node of [instance, binding.template]) {
|
|
6548
|
+
charge();
|
|
6549
|
+
if (attribute2(node, "Type") !== "Shape" || children(node, "Shapes").length || children(node, "ForeignData").length || children(node, "Rel").length || ["1", "true"].includes(attribute2(node, "Del") ?? ""))
|
|
6550
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Master moves require top-level local 2D shape roots.");
|
|
6551
|
+
}
|
|
6552
|
+
for (const name of ["BeginX", "BeginY", "EndX", "EndY"])
|
|
6553
|
+
if (binding.cells.has(name.toLowerCase()))
|
|
6554
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Master lines and endpoint routing remain unsupported.");
|
|
6555
|
+
const oneD = binding.cells.get("oned")?.node;
|
|
6556
|
+
charge();
|
|
6557
|
+
if (oneD && (numeric3(oneD) !== 0 || visioFormulaCachedValue(attribute2(oneD, "V") ?? "", attribute2(oneD, "U")).unit !== "scalar" || executableCellFormula(attribute2(oneD, "F"))))
|
|
6558
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "A static effective 2D master is required.");
|
|
6559
|
+
const local = cells(instance);
|
|
6560
|
+
for (const name of dimensions2) {
|
|
6561
|
+
const effective = binding.cells.get(name.toLowerCase())?.node;
|
|
6562
|
+
for (const node of /* @__PURE__ */ new Set([effective, ...local.has(name) ? [local.get(name)] : []])) {
|
|
6563
|
+
charge();
|
|
6564
|
+
numeric3(node);
|
|
6565
|
+
if (visioFormulaCachedValue("0", attribute2(node, "U") ?? "DL").unit !== "length")
|
|
6566
|
+
fail("EDIT_FORMULA_UNIT", "Master transform caches require length units.");
|
|
6567
|
+
}
|
|
6568
|
+
}
|
|
6569
|
+
const dimension = (name) => numeric3(local.get(name) ?? binding.cells.get(name.toLowerCase())?.node);
|
|
6570
|
+
const width = dimension("Width"), height = dimension("Height");
|
|
6571
|
+
if (width <= 0 || height <= 0)
|
|
6572
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Positive proven effective dimensions are required.");
|
|
6573
|
+
provenDimensions.set(instance, { width, height });
|
|
6574
|
+
for (const name of protection) {
|
|
6575
|
+
charge();
|
|
6576
|
+
const node = binding.cells.get(name.toLowerCase())?.node;
|
|
6577
|
+
const cached2 = node ? numeric3(node) : NaN;
|
|
6578
|
+
const moving = name === "LockMoveX" || name === "LockMoveY";
|
|
6579
|
+
if (!node || visioFormulaCachedValue(attribute2(node, "V") ?? "", attribute2(node, "U")).unit !== "scalar" || ![0, 1].includes(cached2) || moving && cached2 !== 0)
|
|
6580
|
+
fail(
|
|
6581
|
+
"EDIT_PROTECTED_CELL",
|
|
6582
|
+
"Effective master protection must be proven boolean with inactive movement locks."
|
|
6583
|
+
);
|
|
6584
|
+
const formula = executableCellFormula(attribute2(node, "F"));
|
|
6585
|
+
if (formula) {
|
|
6586
|
+
const analysis = analyze(formula);
|
|
6587
|
+
if (analysis.dynamic || analysis.references.length || analysis.unsupportedFunctions.length)
|
|
6588
|
+
fail("EDIT_PROTECTED_CELL", "Effective master protection dependencies are unsupported.");
|
|
6589
|
+
const value = evaluateVisioFormula(
|
|
6590
|
+
formula,
|
|
6591
|
+
() => fail("EDIT_PROTECTED_CELL", "Unexpected protection dependency."),
|
|
6592
|
+
{ onStep: () => charge() }
|
|
6593
|
+
);
|
|
6594
|
+
if (value.unit !== "scalar" || value.value !== cached2)
|
|
6595
|
+
fail("EDIT_PROTECTED_CELL", "Effective master protection cache is stale.");
|
|
6596
|
+
}
|
|
6597
|
+
}
|
|
6598
|
+
for (const name of ["PinX", "PinY"]) {
|
|
6599
|
+
charge();
|
|
6600
|
+
const node = local.get(name);
|
|
6601
|
+
if (!node)
|
|
6602
|
+
fail("EDIT_PROTECTED_CELL", "The rotation pin must be an explicit local override.");
|
|
6603
|
+
if (binding.cells.get(name.toLowerCase())?.node !== node)
|
|
6604
|
+
fail("EDIT_PROTECTED_CELL", "The rotation pin must be an explicit local override.");
|
|
6605
|
+
charge(executableCellFormula(attribute2(node, "F"))?.length ?? 0);
|
|
6606
|
+
editableCell(node);
|
|
6607
|
+
const inherited = binding.inheritedCells.get(name.toLowerCase())?.node;
|
|
6608
|
+
numeric3(inherited);
|
|
6609
|
+
if (visioFormulaCachedValue("0", attribute2(inherited, "U") ?? "DL").unit !== "length")
|
|
6610
|
+
fail("EDIT_FORMULA_UNIT", "Inherited rotation pins require length units.");
|
|
6611
|
+
const formula = executableCellFormula(attribute2(inherited, "F"));
|
|
6612
|
+
if (formula) {
|
|
6613
|
+
const analysis = analyze(formula);
|
|
6614
|
+
if (analysis.guarded || analysis.dynamic || analysis.unsupportedFunctions.length)
|
|
6615
|
+
fail("EDIT_PROTECTED_CELL", "Protected or redirected master pins cannot be overridden.");
|
|
6616
|
+
}
|
|
6617
|
+
result.add(node);
|
|
6618
|
+
}
|
|
6619
|
+
}
|
|
6620
|
+
if (result.size) {
|
|
6621
|
+
const indexed = indexCells(roots, { check });
|
|
6622
|
+
const pins = new Set(
|
|
6623
|
+
[...indexed.values()].filter((cell) => cell.node && result.has(cell.node)).map(key)
|
|
6624
|
+
);
|
|
6625
|
+
for (const cell of indexed.values())
|
|
6626
|
+
if (charge(), cell.dependencies.some((dependency) => pins.has(dependency)))
|
|
6627
|
+
fail("EDIT_UNSUPPORTED_DEPENDENCY", "A page cache depends on a master rotation pin.");
|
|
6628
|
+
}
|
|
6629
|
+
return { pins: result, dimensions: provenDimensions };
|
|
6630
|
+
}
|
|
6631
|
+
|
|
6494
6632
|
// src/visio/edit-geometry.ts
|
|
6495
6633
|
function createRectangle(root, edit) {
|
|
6496
6634
|
const doc = root.ownerDocument;
|
|
@@ -6553,7 +6691,8 @@ function createRectangle(root, edit) {
|
|
|
6553
6691
|
container.appendChild(shape);
|
|
6554
6692
|
return shape;
|
|
6555
6693
|
}
|
|
6556
|
-
function applyGeometryEdit(roots, document, edit, check) {
|
|
6694
|
+
function applyGeometryEdit(roots, document, edit, check, masterMoveProof = emptyMasterMoveProof()) {
|
|
6695
|
+
const masterMovePins = masterMoveProof.pins, masterDimensions = masterMoveProof.dimensions;
|
|
6557
6696
|
check();
|
|
6558
6697
|
const root = roots.get(edit.pageId);
|
|
6559
6698
|
if (!root) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
|
|
@@ -6565,8 +6704,13 @@ function applyGeometryEdit(roots, document, edit, check) {
|
|
|
6565
6704
|
expected = { width: edit.width, height: edit.height, x: edit.x, y: edit.y };
|
|
6566
6705
|
for (const name of ["Width", "Height", "PinX", "PinY"]) add(name);
|
|
6567
6706
|
} else {
|
|
6568
|
-
const shape = admitted(
|
|
6569
|
-
|
|
6707
|
+
const shape = admitted(
|
|
6708
|
+
root,
|
|
6709
|
+
edit.shapeId,
|
|
6710
|
+
edit.type === "move-shape" ? masterMovePins : /* @__PURE__ */ new Set(),
|
|
6711
|
+
edit.type === "move-shape" ? masterDimensions : /* @__PURE__ */ new Map()
|
|
6712
|
+
);
|
|
6713
|
+
protectedShape(shape, document, edit.type === "move-shape" ? masterMovePins : /* @__PURE__ */ new Set());
|
|
6570
6714
|
if (edit.type !== "delete-shape") {
|
|
6571
6715
|
for (const connections2 of children(root, "Connects"))
|
|
6572
6716
|
for (const connection of children(connections2, "Connect"))
|
|
@@ -6588,9 +6732,10 @@ function applyGeometryEdit(roots, document, edit, check) {
|
|
|
6588
6732
|
return [edit.pageId];
|
|
6589
6733
|
}
|
|
6590
6734
|
if (edit.type === "move-shape") {
|
|
6735
|
+
const proven = masterDimensions.get(shape);
|
|
6591
6736
|
expected = {
|
|
6592
|
-
width: numeric3(local.get("Width")),
|
|
6593
|
-
height: numeric3(local.get("Height")),
|
|
6737
|
+
width: numeric3(local.get("Width"), proven?.width),
|
|
6738
|
+
height: numeric3(local.get("Height"), proven?.height),
|
|
6594
6739
|
x: edit.x,
|
|
6595
6740
|
y: edit.y
|
|
6596
6741
|
};
|
|
@@ -6598,10 +6743,7 @@ function applyGeometryEdit(roots, document, edit, check) {
|
|
|
6598
6743
|
["PinX", edit.x, "LockMoveX"],
|
|
6599
6744
|
["PinY", edit.y, "LockMoveY"]
|
|
6600
6745
|
]) {
|
|
6601
|
-
if (numeric3(
|
|
6602
|
-
local.get(name),
|
|
6603
|
-
name === "PinX" ? numeric3(local.get("Width")) / 2 : numeric3(local.get("Height")) / 2
|
|
6604
|
-
) === value)
|
|
6746
|
+
if (numeric3(local.get(name), name === "PinX" ? expected.width / 2 : expected.height / 2) === value)
|
|
6605
6747
|
continue;
|
|
6606
6748
|
unlocked(lock);
|
|
6607
6749
|
editableCell(local.get(name));
|
|
@@ -6643,9 +6785,15 @@ function applyGeometryEdit(roots, document, edit, check) {
|
|
|
6643
6785
|
}
|
|
6644
6786
|
}
|
|
6645
6787
|
if (!changed.length) return [];
|
|
6646
|
-
const affectedPages = recalculateVisioCells(roots, changed, { check });
|
|
6647
|
-
const
|
|
6648
|
-
|
|
6788
|
+
const affectedPages = recalculateVisioCells(roots, changed, { check, masterMovePins });
|
|
6789
|
+
const resultShape = admitted(
|
|
6790
|
+
root,
|
|
6791
|
+
edit.shapeId,
|
|
6792
|
+
edit.type === "move-shape" ? masterMovePins : /* @__PURE__ */ new Set(),
|
|
6793
|
+
edit.type === "move-shape" ? masterDimensions : /* @__PURE__ */ new Map()
|
|
6794
|
+
);
|
|
6795
|
+
const result = cells(resultShape), provenResult = masterDimensions.get(resultShape);
|
|
6796
|
+
if (expected && (numeric3(result.get("Width"), provenResult?.width) !== expected.width || numeric3(result.get("Height"), provenResult?.height) !== expected.height || numeric3(result.get("PinX"), expected.width / 2) !== expected.x || numeric3(result.get("PinY"), expected.height / 2) !== expected.y))
|
|
6649
6797
|
fail(
|
|
6650
6798
|
"EDIT_UNSUPPORTED_DEPENDENCY",
|
|
6651
6799
|
"Dependent formulas would violate the requested geometry or fixed rotation pin."
|
|
@@ -6693,6 +6841,28 @@ function analyzeVisioMasterFormula(source, options) {
|
|
|
6693
6841
|
}
|
|
6694
6842
|
|
|
6695
6843
|
// src/visio/edit-master-index.ts
|
|
6844
|
+
function inheritedProtection(node, ancestor) {
|
|
6845
|
+
try {
|
|
6846
|
+
const boolean2 = (cell) => {
|
|
6847
|
+
if (!cell || cell.hasAttribute("E"))
|
|
6848
|
+
fail("EDIT_PROTECTED_CELL", "Inherited protection has an unresolved or error cache.");
|
|
6849
|
+
const value = visioFormulaCachedValue(attribute2(cell, "V") ?? "", attribute2(cell, "U"));
|
|
6850
|
+
if (value.unit !== "scalar" || ![0, 1].includes(value.value))
|
|
6851
|
+
fail("EDIT_PROTECTED_CELL", "Inherited protection requires scalar boolean caches.");
|
|
6852
|
+
return value.value;
|
|
6853
|
+
};
|
|
6854
|
+
if (boolean2(node) !== boolean2(ancestor))
|
|
6855
|
+
fail(
|
|
6856
|
+
"EDIT_PROTECTED_CELL",
|
|
6857
|
+
"Delegated master style protection cache disagrees with its ancestor."
|
|
6858
|
+
);
|
|
6859
|
+
} catch (error) {
|
|
6860
|
+
fail(
|
|
6861
|
+
"EDIT_PROTECTED_CELL",
|
|
6862
|
+
`Inherited master style protection cannot be proven: ${error instanceof Error ? error.message : "invalid cache"}`
|
|
6863
|
+
);
|
|
6864
|
+
}
|
|
6865
|
+
}
|
|
6696
6866
|
function masterCells(sheet, charge = () => {
|
|
6697
6867
|
}) {
|
|
6698
6868
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -6750,7 +6920,7 @@ function assertMasterMarkup(root, known, check) {
|
|
|
6750
6920
|
}
|
|
6751
6921
|
}
|
|
6752
6922
|
function masterStyleCells(document, template, instance, check, charge = () => {
|
|
6753
|
-
}) {
|
|
6923
|
+
}, verifyMovementProtection = false) {
|
|
6754
6924
|
const styles = /* @__PURE__ */ new Map();
|
|
6755
6925
|
for (const container of children(document, "StyleSheets"))
|
|
6756
6926
|
for (const style of children(container, "StyleSheet")) {
|
|
@@ -6775,6 +6945,10 @@ function masterStyleCells(document, template, instance, check, charge = () => {
|
|
|
6775
6945
|
for (const [name, node] of own) {
|
|
6776
6946
|
charge();
|
|
6777
6947
|
if (attribute2(node, "F") !== "Inh") result2.set(name, node);
|
|
6948
|
+
else if (verifyMovementProtection && /^lock(move[xy]|width|height|aspect|delete)$/.test(name)) {
|
|
6949
|
+
charge();
|
|
6950
|
+
inheritedProtection(node, result2.get(name));
|
|
6951
|
+
}
|
|
6778
6952
|
}
|
|
6779
6953
|
return result2;
|
|
6780
6954
|
};
|
|
@@ -6846,12 +7020,20 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
6846
7020
|
const instances = [...roots].flatMap(
|
|
6847
7021
|
([pageId, root]) => masterShapes(root).filter((shape) => shape.hasAttribute("Master")).map((instance) => ({ pageId, instance }))
|
|
6848
7022
|
);
|
|
6849
|
-
if (!instances.length) return;
|
|
7023
|
+
if (!instances.length) return emptyMasterMoveProof();
|
|
6850
7024
|
const documentPart = await related(pkg, "", "document");
|
|
6851
7025
|
if (!documentPart) problem("Missing master document relationship.");
|
|
6852
7026
|
const document = await visioXml(pkg, documentPart, "VisioDocument");
|
|
6853
7027
|
const mastersPart = await related(pkg, documentPart, "masters", false);
|
|
6854
|
-
if (!mastersPart)
|
|
7028
|
+
if (!mastersPart) {
|
|
7029
|
+
if (commands.some(
|
|
7030
|
+
(command2) => instances.some(
|
|
7031
|
+
(item) => item.pageId === command2.pageId && attribute2(item.instance, "ID") === command2.shapeId
|
|
7032
|
+
)
|
|
7033
|
+
))
|
|
7034
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Active master definitions are missing.");
|
|
7035
|
+
problem("Active master definitions are missing.");
|
|
7036
|
+
}
|
|
6855
7037
|
const definitions = /* @__PURE__ */ new Map();
|
|
6856
7038
|
for (const node of children(await visioXml(pkg, mastersPart, "Masters"), "Master")) {
|
|
6857
7039
|
const id = attribute2(node, "ID");
|
|
@@ -6866,6 +7048,12 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
6866
7048
|
if (--buildWork < 0) problem("Master effective-cell construction budget exceeded.");
|
|
6867
7049
|
};
|
|
6868
7050
|
const pageBindings = /* @__PURE__ */ new Map();
|
|
7051
|
+
const movingTargets = /* @__PURE__ */ new Set();
|
|
7052
|
+
for (const command2 of commands) {
|
|
7053
|
+
charge();
|
|
7054
|
+
if (command2.type === "move-shape")
|
|
7055
|
+
movingTargets.add(JSON.stringify([command2.pageId, command2.shapeId]));
|
|
7056
|
+
}
|
|
6869
7057
|
const pageShapes = /* @__PURE__ */ new Map();
|
|
6870
7058
|
for (const [pageId, root] of roots)
|
|
6871
7059
|
for (const shape of masterShapes(root)) {
|
|
@@ -6925,15 +7113,25 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
6925
7113
|
const templateId = attribute2(template, "ID");
|
|
6926
7114
|
if (!templateId || context.has(templateId)) problem("Master-local sheet IDs are ambiguous.");
|
|
6927
7115
|
const local = byTemplate.get(templateId), cells3 = /* @__PURE__ */ new Map();
|
|
6928
|
-
|
|
7116
|
+
const movedInstance = local === instance && movingTargets.has(JSON.stringify([pageId, attribute2(local, "ID")]));
|
|
7117
|
+
for (const [name, node] of masterStyleCells(
|
|
7118
|
+
document,
|
|
7119
|
+
template,
|
|
7120
|
+
local,
|
|
7121
|
+
check,
|
|
7122
|
+
charge,
|
|
7123
|
+
movedInstance
|
|
7124
|
+
))
|
|
6929
7125
|
cells3.set(name, { node, kind: "style" });
|
|
6930
7126
|
overlay(cells3, masterCells(template, charge), "template", charge);
|
|
7127
|
+
const inheritedCells = new Map(cells3);
|
|
6931
7128
|
overlay(cells3, masterCells(local, charge), "instance", charge);
|
|
6932
7129
|
const binding = {
|
|
6933
7130
|
id: `${pageId}:${attribute2(instance, "ID")}:${templateId}`,
|
|
6934
7131
|
pageId,
|
|
6935
7132
|
template,
|
|
6936
7133
|
cells: cells3,
|
|
7134
|
+
inheritedCells,
|
|
6937
7135
|
context,
|
|
6938
7136
|
...local ? { instance: local } : {}
|
|
6939
7137
|
};
|
|
@@ -6944,6 +7142,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
6944
7142
|
for (const id of byTemplate.keys())
|
|
6945
7143
|
if (!context.has(id)) problem("MasterShape refers to a missing template.");
|
|
6946
7144
|
}
|
|
7145
|
+
const movePins = prepareMasterMovePins(roots, commands, bindings, check);
|
|
6947
7146
|
const changed = commands.flatMap(
|
|
6948
7147
|
(command2) => command2.type === "delete-shape" ? [] : (command2.type === "move-shape" ? ["PinX", "PinY"] : command2.type === "resize-shape" ? ["Width", "Height"] : ["Width", "Height", "PinX", "PinY"]).map((cell) => ({ pageId: command2.pageId, shapeId: command2.shapeId, cell }))
|
|
6949
7148
|
);
|
|
@@ -6971,6 +7170,7 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
6971
7170
|
template: shape,
|
|
6972
7171
|
instance: shape,
|
|
6973
7172
|
cells: cells3,
|
|
7173
|
+
inheritedCells: /* @__PURE__ */ new Map(),
|
|
6974
7174
|
context: /* @__PURE__ */ new Map()
|
|
6975
7175
|
};
|
|
6976
7176
|
pageInputs.set(id, result);
|
|
@@ -7048,7 +7248,14 @@ async function assertVisioMasterIndependence(pkg, roots, commands, check) {
|
|
|
7048
7248
|
active.delete(id);
|
|
7049
7249
|
done.add(id);
|
|
7050
7250
|
};
|
|
7051
|
-
for (const binding of bindings)
|
|
7251
|
+
for (const binding of bindings)
|
|
7252
|
+
for (const name of binding.cells.keys()) {
|
|
7253
|
+
const source = binding.cells.get(name);
|
|
7254
|
+
if (["pinx", "piny"].includes(name) && source?.kind === "instance" && movePins.pins.has(source.node))
|
|
7255
|
+
continue;
|
|
7256
|
+
inspect2(binding, name);
|
|
7257
|
+
}
|
|
7258
|
+
return movePins;
|
|
7052
7259
|
}
|
|
7053
7260
|
|
|
7054
7261
|
// src/visio/edit-scope.ts
|
|
@@ -7168,6 +7375,7 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
|
|
|
7168
7375
|
});
|
|
7169
7376
|
}
|
|
7170
7377
|
}
|
|
7378
|
+
let movePins = emptyMasterMoveProof();
|
|
7171
7379
|
if (hasMasterInstances) {
|
|
7172
7380
|
for (const command2 of commands) {
|
|
7173
7381
|
const root = roots.get(command2.pageId);
|
|
@@ -7175,12 +7383,16 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
|
|
|
7175
7383
|
const target = Array.from(root.getElementsByTagNameNS(root.namespaceURI, "Shape")).find(
|
|
7176
7384
|
(shape) => attribute2(shape, "ID") === command2.shapeId
|
|
7177
7385
|
);
|
|
7178
|
-
if (target?.hasAttribute("
|
|
7386
|
+
if (target?.hasAttribute("MasterShape") && !target.hasAttribute("Master"))
|
|
7179
7387
|
fail("UNSUPPORTED_GEOMETRY_EDIT", "Editing master-linked shapes is unsupported.");
|
|
7388
|
+
if (target?.hasAttribute("Master") && (command2.type !== "move-shape" || !["PinX", "PinY"].every(
|
|
7389
|
+
(name) => children(target, "Cell").some((node) => attribute2(node, "N") === name)
|
|
7390
|
+
)))
|
|
7391
|
+
fail("UNSUPPORTED_GEOMETRY_EDIT", "Master moves require explicit local rotation pins.");
|
|
7180
7392
|
}
|
|
7181
|
-
await assertVisioMasterIndependence(pkg, roots, commands, check);
|
|
7393
|
+
movePins = await assertVisioMasterIndependence(pkg, roots, commands, check);
|
|
7182
7394
|
}
|
|
7183
|
-
if (!documentRoot) return;
|
|
7395
|
+
if (!documentRoot) return movePins;
|
|
7184
7396
|
const styles = /* @__PURE__ */ new Map();
|
|
7185
7397
|
for (const container of children(documentRoot, "StyleSheets"))
|
|
7186
7398
|
for (const style of children(container, "StyleSheet")) {
|
|
@@ -7245,6 +7457,7 @@ async function assertGeometryPackageScope(pkg, pagePaths, commands, check, roots
|
|
|
7245
7457
|
}
|
|
7246
7458
|
}
|
|
7247
7459
|
}
|
|
7460
|
+
return movePins;
|
|
7248
7461
|
}
|
|
7249
7462
|
|
|
7250
7463
|
// src/visio/edit.ts
|
|
@@ -7272,12 +7485,13 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
7272
7485
|
const roots = /* @__PURE__ */ new Map();
|
|
7273
7486
|
const geometry = commands.some((command2) => command2.type !== "replace-plain-text");
|
|
7274
7487
|
let document;
|
|
7488
|
+
let masterMovePins = emptyMasterMoveProof();
|
|
7275
7489
|
if (geometry) {
|
|
7276
7490
|
for (const [pageId, path2] of pages) {
|
|
7277
7491
|
const sourceRoot = await visioXml(pkg, path2, "PageContents");
|
|
7278
7492
|
roots.set(pageId, sourceRoot.ownerDocument.cloneNode(true).documentElement);
|
|
7279
7493
|
}
|
|
7280
|
-
await assertGeometryPackageScope(
|
|
7494
|
+
masterMovePins = await assertGeometryPackageScope(
|
|
7281
7495
|
pkg,
|
|
7282
7496
|
new Set(pages.values()),
|
|
7283
7497
|
commands.filter((command2) => command2.type !== "replace-plain-text"),
|
|
@@ -7304,7 +7518,7 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
7304
7518
|
textChanged = true;
|
|
7305
7519
|
}
|
|
7306
7520
|
} else {
|
|
7307
|
-
for (const pageId of applyGeometryEdit(roots, document, command2, check))
|
|
7521
|
+
for (const pageId of applyGeometryEdit(roots, document, command2, check, masterMovePins))
|
|
7308
7522
|
dirty.set(pages.get(pageId), roots.get(pageId));
|
|
7309
7523
|
}
|
|
7310
7524
|
}
|