stickyflow 0.3.0 → 0.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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/interaction/index.cjs +252 -83
- package/dist/interaction/index.cjs.map +1 -1
- package/dist/interaction/index.d.cts +9 -1
- package/dist/interaction/index.d.ts +9 -1
- package/dist/interaction/index.js +253 -85
- package/dist/interaction/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,12 @@ Two things count as breaking here that are easy to overlook:
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.4.0] - 2026-10-17
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- `applyQuickDuplicateChange(source, event, { shapeId, linkId, gap? })` in `stickyflow/interaction` carries out a quick duplicate. It adds a copy of the object with its look, beyond the edge that was dragged, and a link to it that looks like the other links of the document. For an isometric object it adds a copy and a connection between the touching faces. The ids come from the caller, and `gap` is 200 for a shape and 40 for an isometric object by default.
|
|
25
|
+
|
|
20
26
|
## [0.3.0] - 2026-10-17
|
|
21
27
|
|
|
22
28
|
### Added
|
package/README.md
CHANGED
|
@@ -155,7 +155,7 @@ npm run ci # lint, typecheck, tests, build, smoke
|
|
|
155
155
|
npm run build # tsup
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
Adding a new placeable object: [docs/ADDING_CANVAS_OBJECT.md](docs/ADDING_CANVAS_OBJECT.md). Changes: [CHANGELOG.md](CHANGELOG.md).
|
|
158
|
+
How the package and its neighbours fit together: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Adding a new placeable object: [docs/ADDING_CANVAS_OBJECT.md](docs/ADDING_CANVAS_OBJECT.md). Changes: [CHANGELOG.md](CHANGELOG.md).
|
|
159
159
|
|
|
160
160
|
## More
|
|
161
161
|
|
|
@@ -7288,6 +7288,257 @@ function shouldQuote(current, quote, indexed) {
|
|
|
7288
7288
|
return indexed && trimmed === "none";
|
|
7289
7289
|
}
|
|
7290
7290
|
|
|
7291
|
+
// src/runtime/interaction/sflPatch/connectionPatch/blockText.ts
|
|
7292
|
+
function buildConnectionBlock(options, baseIndent) {
|
|
7293
|
+
const bodyIndent = `${baseIndent} `;
|
|
7294
|
+
const block = [
|
|
7295
|
+
`${baseIndent}Connection ${options.id} {`,
|
|
7296
|
+
`${bodyIndent}from: ${options.fromId}`,
|
|
7297
|
+
`${bodyIndent}to: ${options.toId}`,
|
|
7298
|
+
`${bodyIndent}fromFace: "${options.fromFace}"`,
|
|
7299
|
+
`${bodyIndent}toFace: "${options.toFace}"`
|
|
7300
|
+
];
|
|
7301
|
+
if (options.body) {
|
|
7302
|
+
block.push(...indentBlock(options.body, bodyIndent));
|
|
7303
|
+
}
|
|
7304
|
+
block.push(`${baseIndent}}`);
|
|
7305
|
+
return block;
|
|
7306
|
+
}
|
|
7307
|
+
|
|
7308
|
+
// src/runtime/interaction/sflPatch/connectionPatch/insertionTarget.ts
|
|
7309
|
+
function resolveConnectionInsertionTarget(sfl, lines, options) {
|
|
7310
|
+
if (!VALID_IDENT.test(options.id) || nameExists(lines, options.id)) {
|
|
7311
|
+
return null;
|
|
7312
|
+
}
|
|
7313
|
+
const canvasObjects = chunkCXL254BT_cjs.sflToCanvasState(sfl).canvasObjects;
|
|
7314
|
+
const hasSource = canvasObjects.some((canvasObject) => canvasObject.id === options.fromId);
|
|
7315
|
+
const hasTarget = canvasObjects.some((canvasObject) => canvasObject.id === options.toId);
|
|
7316
|
+
if (!hasSource || !hasTarget) {
|
|
7317
|
+
return null;
|
|
7318
|
+
}
|
|
7319
|
+
return findFirstBlockOfKind(lines, "Model");
|
|
7320
|
+
}
|
|
7321
|
+
|
|
7322
|
+
// src/runtime/interaction/sflPatch/connectionPatch/insert.ts
|
|
7323
|
+
function insertConnection(sfl, options) {
|
|
7324
|
+
const lines = sfl.split("\n");
|
|
7325
|
+
const modelRange = resolveConnectionInsertionTarget(sfl, lines, options);
|
|
7326
|
+
if (!modelRange) {
|
|
7327
|
+
return sfl;
|
|
7328
|
+
}
|
|
7329
|
+
insertBlockLines(lines, modelRange, (baseIndent) => buildConnectionBlock(options, baseIndent));
|
|
7330
|
+
return lines.join("\n");
|
|
7331
|
+
}
|
|
7332
|
+
|
|
7333
|
+
// src/runtime/interaction/sflPatch/changes/quickDuplicate/styleBlock.ts
|
|
7334
|
+
var QUOTED_KEYS = /* @__PURE__ */ new Set(["fill", "stroke", "textColor", "fontFamily", "shadow", "labelBackground"]);
|
|
7335
|
+
function styleLine(key, value) {
|
|
7336
|
+
return QUOTED_KEYS.has(key) ? ` ${key}: "${value.replace(/"/g, '\\"')}"` : ` ${key}: ${value}`;
|
|
7337
|
+
}
|
|
7338
|
+
function styleBlock(props, keys, leading = []) {
|
|
7339
|
+
const copied = keys.flatMap((key) => {
|
|
7340
|
+
const value = props?.[key];
|
|
7341
|
+
return value === void 0 ? [] : [styleLine(key, value)];
|
|
7342
|
+
});
|
|
7343
|
+
const lines = [...leading, ...copied];
|
|
7344
|
+
return lines.length > 0 ? `style {
|
|
7345
|
+
${lines.join("\n")}
|
|
7346
|
+
}` : void 0;
|
|
7347
|
+
}
|
|
7348
|
+
|
|
7349
|
+
// src/runtime/interaction/sflPatch/changes/quickDuplicate/isometricDuplicate.ts
|
|
7350
|
+
var ISOMETRIC_GAP = 40;
|
|
7351
|
+
var ISOMETRIC_STYLE_KEYS = [
|
|
7352
|
+
"fill",
|
|
7353
|
+
"stroke",
|
|
7354
|
+
"strokeWidth",
|
|
7355
|
+
"cornerRadius",
|
|
7356
|
+
"shadow",
|
|
7357
|
+
"labelOffsetX",
|
|
7358
|
+
"labelOffsetY",
|
|
7359
|
+
"labelBackground"
|
|
7360
|
+
];
|
|
7361
|
+
var TOUCHING_FACES = {
|
|
7362
|
+
"iso-width-pos": { fromFace: "right", toFace: "left" },
|
|
7363
|
+
"iso-width-neg": { fromFace: "left", toFace: "right" },
|
|
7364
|
+
"iso-depth-pos": { fromFace: "front", toFace: "back" },
|
|
7365
|
+
"iso-depth-neg": { fromFace: "back", toFace: "front" },
|
|
7366
|
+
"iso-height-pos": { fromFace: "bottom", toFace: "top" },
|
|
7367
|
+
"iso-height-neg": { fromFace: "top", toFace: "bottom" }
|
|
7368
|
+
};
|
|
7369
|
+
function isIsometricDirection2(direction) {
|
|
7370
|
+
return direction.startsWith("iso-");
|
|
7371
|
+
}
|
|
7372
|
+
function isometricOffset(direction, object, gap) {
|
|
7373
|
+
const { width, height } = object;
|
|
7374
|
+
const { depth } = object.isometric;
|
|
7375
|
+
switch (direction) {
|
|
7376
|
+
case "iso-width-pos":
|
|
7377
|
+
return { dx: (width + gap) * chunkCXL254BT_cjs.AXIS_COS, dy: (width + gap) * chunkCXL254BT_cjs.AXIS_SIN };
|
|
7378
|
+
case "iso-width-neg":
|
|
7379
|
+
return { dx: -(width + gap) * chunkCXL254BT_cjs.AXIS_COS, dy: -(width + gap) * chunkCXL254BT_cjs.AXIS_SIN };
|
|
7380
|
+
case "iso-depth-pos":
|
|
7381
|
+
return { dx: -(depth + gap) * chunkCXL254BT_cjs.AXIS_COS, dy: (depth + gap) * chunkCXL254BT_cjs.AXIS_SIN };
|
|
7382
|
+
case "iso-depth-neg":
|
|
7383
|
+
return { dx: (depth + gap) * chunkCXL254BT_cjs.AXIS_COS, dy: -(depth + gap) * chunkCXL254BT_cjs.AXIS_SIN };
|
|
7384
|
+
case "iso-height-pos":
|
|
7385
|
+
return { dx: 0, dy: height + gap };
|
|
7386
|
+
case "iso-height-neg":
|
|
7387
|
+
return { dx: 0, dy: -(height + gap) };
|
|
7388
|
+
}
|
|
7389
|
+
}
|
|
7390
|
+
function copyStyle(object, direction) {
|
|
7391
|
+
if (!direction.startsWith("iso-height-")) {
|
|
7392
|
+
return styleBlock(object.props, ISOMETRIC_STYLE_KEYS);
|
|
7393
|
+
}
|
|
7394
|
+
return styleBlock(
|
|
7395
|
+
object.props,
|
|
7396
|
+
ISOMETRIC_STYLE_KEYS.filter((key) => key !== "shadow"),
|
|
7397
|
+
[' shadow: "off"']
|
|
7398
|
+
);
|
|
7399
|
+
}
|
|
7400
|
+
function copyOf(object, direction, options) {
|
|
7401
|
+
const { dx, dy } = isometricOffset(direction, object, options.gap ?? ISOMETRIC_GAP);
|
|
7402
|
+
return {
|
|
7403
|
+
id: options.shapeId,
|
|
7404
|
+
kind: "isometric",
|
|
7405
|
+
text: object.text ?? "",
|
|
7406
|
+
x: object.x + dx,
|
|
7407
|
+
y: object.y + dy,
|
|
7408
|
+
width: object.width,
|
|
7409
|
+
height: object.height,
|
|
7410
|
+
depth: object.isometric.depth,
|
|
7411
|
+
parentId: object.parentFrameId,
|
|
7412
|
+
body: copyStyle(object, direction)
|
|
7413
|
+
};
|
|
7414
|
+
}
|
|
7415
|
+
function duplicateIsometricObject(sfl, object, direction, options) {
|
|
7416
|
+
const withCopy = insertCanvasObject(sfl, copyOf(object, direction, options));
|
|
7417
|
+
return insertConnection(withCopy, {
|
|
7418
|
+
id: options.linkId,
|
|
7419
|
+
fromId: object.id,
|
|
7420
|
+
toId: options.shapeId,
|
|
7421
|
+
...TOUCHING_FACES[direction]
|
|
7422
|
+
});
|
|
7423
|
+
}
|
|
7424
|
+
|
|
7425
|
+
// src/runtime/interaction/sflPatch/linkPatch/blockText.ts
|
|
7426
|
+
function buildLinkBlock(options, baseIndent) {
|
|
7427
|
+
const bodyIndent = `${baseIndent} `;
|
|
7428
|
+
const from = formatLinkEndpoint({ id: options.fromId, side: options.fromSide, fraction: options.fromFraction });
|
|
7429
|
+
const to = formatLinkEndpoint({ id: options.toId, side: options.toSide, fraction: options.toFraction });
|
|
7430
|
+
const block = [`${baseIndent}Link ${options.id} {`, `${bodyIndent}from: ${from}`, `${bodyIndent}to: ${to}`];
|
|
7431
|
+
if (options.text !== void 0) {
|
|
7432
|
+
block.push(`${bodyIndent}text: "${escapeSflString(options.text)}"`);
|
|
7433
|
+
}
|
|
7434
|
+
if (options.body) {
|
|
7435
|
+
block.push(...indentBlock(options.body, bodyIndent));
|
|
7436
|
+
}
|
|
7437
|
+
block.push(`${baseIndent}}`);
|
|
7438
|
+
return block;
|
|
7439
|
+
}
|
|
7440
|
+
|
|
7441
|
+
// src/runtime/interaction/sflPatch/linkPatch/insertionTarget.ts
|
|
7442
|
+
function resolveLinkInsertionTarget(sfl, lines, options) {
|
|
7443
|
+
if (!VALID_IDENT.test(options.id) || nameExists(lines, options.id)) {
|
|
7444
|
+
return null;
|
|
7445
|
+
}
|
|
7446
|
+
const canvasObjects = chunkCXL254BT_cjs.sflToCanvasState(sfl).canvasObjects;
|
|
7447
|
+
const hasSource = canvasObjects.some((canvasObject) => canvasObject.id === options.fromId);
|
|
7448
|
+
const hasTarget = canvasObjects.some((canvasObject) => canvasObject.id === options.toId);
|
|
7449
|
+
if (!hasSource || !hasTarget) {
|
|
7450
|
+
return null;
|
|
7451
|
+
}
|
|
7452
|
+
return findFirstBlockOfKind(lines, "Model");
|
|
7453
|
+
}
|
|
7454
|
+
|
|
7455
|
+
// src/runtime/interaction/sflPatch/linkPatch/insert.ts
|
|
7456
|
+
function insertLink(sfl, options) {
|
|
7457
|
+
const lines = sfl.split("\n");
|
|
7458
|
+
const modelRange = resolveLinkInsertionTarget(sfl, lines, options);
|
|
7459
|
+
if (!modelRange) {
|
|
7460
|
+
return sfl;
|
|
7461
|
+
}
|
|
7462
|
+
insertBlockLines(lines, modelRange, (baseIndent) => buildLinkBlock(options, baseIndent));
|
|
7463
|
+
return lines.join("\n");
|
|
7464
|
+
}
|
|
7465
|
+
|
|
7466
|
+
// src/runtime/interaction/sflPatch/changes/quickDuplicate/shapeDuplicate.ts
|
|
7467
|
+
var SHAPE_GAP = 200;
|
|
7468
|
+
var OPPOSITE_SIDE = { top: "bottom", right: "left", bottom: "top", left: "right" };
|
|
7469
|
+
var SHAPE_STYLE_KEYS = [
|
|
7470
|
+
"fill",
|
|
7471
|
+
"stroke",
|
|
7472
|
+
"strokeWidth",
|
|
7473
|
+
"strokeStyle",
|
|
7474
|
+
"textColor",
|
|
7475
|
+
"fontSize",
|
|
7476
|
+
"fontFamily",
|
|
7477
|
+
"cornerRadius",
|
|
7478
|
+
"opacity",
|
|
7479
|
+
"shadow"
|
|
7480
|
+
];
|
|
7481
|
+
var LINK_STYLE_KEYS = ["stroke", "strokeWidth", "strokeStyle", "markerStart", "markerEnd", "route"];
|
|
7482
|
+
function shapeOffset(side, object, gap) {
|
|
7483
|
+
switch (side) {
|
|
7484
|
+
case "top":
|
|
7485
|
+
return { dx: 0, dy: -(object.height + gap) };
|
|
7486
|
+
case "bottom":
|
|
7487
|
+
return { dx: 0, dy: object.height + gap };
|
|
7488
|
+
case "left":
|
|
7489
|
+
return { dx: -(object.width + gap), dy: 0 };
|
|
7490
|
+
case "right":
|
|
7491
|
+
return { dx: object.width + gap, dy: 0 };
|
|
7492
|
+
}
|
|
7493
|
+
}
|
|
7494
|
+
function copyOf2(object, side, options) {
|
|
7495
|
+
const { dx, dy } = shapeOffset(side, object, options.gap ?? SHAPE_GAP);
|
|
7496
|
+
const shape = object.shapeType ? [` shape: ${object.shapeType}`] : [];
|
|
7497
|
+
return {
|
|
7498
|
+
id: options.shapeId,
|
|
7499
|
+
kind: "shape",
|
|
7500
|
+
text: object.text ?? "",
|
|
7501
|
+
x: object.x + dx,
|
|
7502
|
+
y: object.y + dy,
|
|
7503
|
+
width: object.width,
|
|
7504
|
+
height: object.height,
|
|
7505
|
+
parentId: object.parentFrameId,
|
|
7506
|
+
body: styleBlock(object.props, SHAPE_STYLE_KEYS, shape)
|
|
7507
|
+
};
|
|
7508
|
+
}
|
|
7509
|
+
function linkStyleReference(links, objectId) {
|
|
7510
|
+
return links.find((link) => link.fromId === objectId) ?? links[0];
|
|
7511
|
+
}
|
|
7512
|
+
function linkToCopy(object, links, side, options) {
|
|
7513
|
+
return {
|
|
7514
|
+
id: options.linkId,
|
|
7515
|
+
fromId: object.id,
|
|
7516
|
+
toId: options.shapeId,
|
|
7517
|
+
fromSide: side,
|
|
7518
|
+
toSide: OPPOSITE_SIDE[side],
|
|
7519
|
+
body: styleBlock(linkStyleReference(links, object.id)?.props, LINK_STYLE_KEYS)
|
|
7520
|
+
};
|
|
7521
|
+
}
|
|
7522
|
+
function duplicateShape(sfl, input) {
|
|
7523
|
+
const { object, links, side, options } = input;
|
|
7524
|
+
const withCopy = insertCanvasObject(sfl, copyOf2(object, side, options));
|
|
7525
|
+
return insertLink(withCopy, linkToCopy(object, links, side, options));
|
|
7526
|
+
}
|
|
7527
|
+
|
|
7528
|
+
// src/runtime/interaction/sflPatch/changes/quickDuplicateChange.ts
|
|
7529
|
+
function applyQuickDuplicateChange(sfl, event, options) {
|
|
7530
|
+
const state = chunkCXL254BT_cjs.sflToCanvasState(sfl);
|
|
7531
|
+
const object = state.canvasObjects.find((candidate) => candidate.id === event.owner.id);
|
|
7532
|
+
if (!object) {
|
|
7533
|
+
return sfl;
|
|
7534
|
+
}
|
|
7535
|
+
const { direction } = event;
|
|
7536
|
+
if (isIsometricDirection2(direction)) {
|
|
7537
|
+
return chunkCXL254BT_cjs.isIsometricObject(object) ? duplicateIsometricObject(sfl, object, direction, options) : sfl;
|
|
7538
|
+
}
|
|
7539
|
+
return chunkCXL254BT_cjs.isIsometricObject(object) ? sfl : duplicateShape(sfl, { object, links: state.links, side: direction, options });
|
|
7540
|
+
}
|
|
7541
|
+
|
|
7291
7542
|
// src/runtime/interaction/sflPatch/changes/resizeChange.ts
|
|
7292
7543
|
function applyResizeChange(sfl, event) {
|
|
7293
7544
|
const state = chunkCXL254BT_cjs.sflToCanvasState(sfl);
|
|
@@ -7412,89 +7663,6 @@ function applyTextChange(sfl, event) {
|
|
|
7412
7663
|
return lines.join("\n");
|
|
7413
7664
|
}
|
|
7414
7665
|
|
|
7415
|
-
// src/runtime/interaction/sflPatch/connectionPatch/blockText.ts
|
|
7416
|
-
function buildConnectionBlock(options, baseIndent) {
|
|
7417
|
-
const bodyIndent = `${baseIndent} `;
|
|
7418
|
-
const block = [
|
|
7419
|
-
`${baseIndent}Connection ${options.id} {`,
|
|
7420
|
-
`${bodyIndent}from: ${options.fromId}`,
|
|
7421
|
-
`${bodyIndent}to: ${options.toId}`,
|
|
7422
|
-
`${bodyIndent}fromFace: "${options.fromFace}"`,
|
|
7423
|
-
`${bodyIndent}toFace: "${options.toFace}"`
|
|
7424
|
-
];
|
|
7425
|
-
if (options.body) {
|
|
7426
|
-
block.push(...indentBlock(options.body, bodyIndent));
|
|
7427
|
-
}
|
|
7428
|
-
block.push(`${baseIndent}}`);
|
|
7429
|
-
return block;
|
|
7430
|
-
}
|
|
7431
|
-
|
|
7432
|
-
// src/runtime/interaction/sflPatch/connectionPatch/insertionTarget.ts
|
|
7433
|
-
function resolveConnectionInsertionTarget(sfl, lines, options) {
|
|
7434
|
-
if (!VALID_IDENT.test(options.id) || nameExists(lines, options.id)) {
|
|
7435
|
-
return null;
|
|
7436
|
-
}
|
|
7437
|
-
const canvasObjects = chunkCXL254BT_cjs.sflToCanvasState(sfl).canvasObjects;
|
|
7438
|
-
const hasSource = canvasObjects.some((canvasObject) => canvasObject.id === options.fromId);
|
|
7439
|
-
const hasTarget = canvasObjects.some((canvasObject) => canvasObject.id === options.toId);
|
|
7440
|
-
if (!hasSource || !hasTarget) {
|
|
7441
|
-
return null;
|
|
7442
|
-
}
|
|
7443
|
-
return findFirstBlockOfKind(lines, "Model");
|
|
7444
|
-
}
|
|
7445
|
-
|
|
7446
|
-
// src/runtime/interaction/sflPatch/connectionPatch/insert.ts
|
|
7447
|
-
function insertConnection(sfl, options) {
|
|
7448
|
-
const lines = sfl.split("\n");
|
|
7449
|
-
const modelRange = resolveConnectionInsertionTarget(sfl, lines, options);
|
|
7450
|
-
if (!modelRange) {
|
|
7451
|
-
return sfl;
|
|
7452
|
-
}
|
|
7453
|
-
insertBlockLines(lines, modelRange, (baseIndent) => buildConnectionBlock(options, baseIndent));
|
|
7454
|
-
return lines.join("\n");
|
|
7455
|
-
}
|
|
7456
|
-
|
|
7457
|
-
// src/runtime/interaction/sflPatch/linkPatch/blockText.ts
|
|
7458
|
-
function buildLinkBlock(options, baseIndent) {
|
|
7459
|
-
const bodyIndent = `${baseIndent} `;
|
|
7460
|
-
const from = formatLinkEndpoint({ id: options.fromId, side: options.fromSide, fraction: options.fromFraction });
|
|
7461
|
-
const to = formatLinkEndpoint({ id: options.toId, side: options.toSide, fraction: options.toFraction });
|
|
7462
|
-
const block = [`${baseIndent}Link ${options.id} {`, `${bodyIndent}from: ${from}`, `${bodyIndent}to: ${to}`];
|
|
7463
|
-
if (options.text !== void 0) {
|
|
7464
|
-
block.push(`${bodyIndent}text: "${escapeSflString(options.text)}"`);
|
|
7465
|
-
}
|
|
7466
|
-
if (options.body) {
|
|
7467
|
-
block.push(...indentBlock(options.body, bodyIndent));
|
|
7468
|
-
}
|
|
7469
|
-
block.push(`${baseIndent}}`);
|
|
7470
|
-
return block;
|
|
7471
|
-
}
|
|
7472
|
-
|
|
7473
|
-
// src/runtime/interaction/sflPatch/linkPatch/insertionTarget.ts
|
|
7474
|
-
function resolveLinkInsertionTarget(sfl, lines, options) {
|
|
7475
|
-
if (!VALID_IDENT.test(options.id) || nameExists(lines, options.id)) {
|
|
7476
|
-
return null;
|
|
7477
|
-
}
|
|
7478
|
-
const canvasObjects = chunkCXL254BT_cjs.sflToCanvasState(sfl).canvasObjects;
|
|
7479
|
-
const hasSource = canvasObjects.some((canvasObject) => canvasObject.id === options.fromId);
|
|
7480
|
-
const hasTarget = canvasObjects.some((canvasObject) => canvasObject.id === options.toId);
|
|
7481
|
-
if (!hasSource || !hasTarget) {
|
|
7482
|
-
return null;
|
|
7483
|
-
}
|
|
7484
|
-
return findFirstBlockOfKind(lines, "Model");
|
|
7485
|
-
}
|
|
7486
|
-
|
|
7487
|
-
// src/runtime/interaction/sflPatch/linkPatch/insert.ts
|
|
7488
|
-
function insertLink(sfl, options) {
|
|
7489
|
-
const lines = sfl.split("\n");
|
|
7490
|
-
const modelRange = resolveLinkInsertionTarget(sfl, lines, options);
|
|
7491
|
-
if (!modelRange) {
|
|
7492
|
-
return sfl;
|
|
7493
|
-
}
|
|
7494
|
-
insertBlockLines(lines, modelRange, (baseIndent) => buildLinkBlock(options, baseIndent));
|
|
7495
|
-
return lines.join("\n");
|
|
7496
|
-
}
|
|
7497
|
-
|
|
7498
7666
|
// src/runtime/interaction/sflPatch/linkPatch/remove.ts
|
|
7499
7667
|
function removeLink(sfl, id) {
|
|
7500
7668
|
const lines = sfl.split("\n");
|
|
@@ -7565,6 +7733,7 @@ exports.applyLinkSegmentChange = applyLinkSegmentChange;
|
|
|
7565
7733
|
exports.applyMoveChange = applyMoveChange;
|
|
7566
7734
|
exports.applyPathPointChange = applyPathPointChange;
|
|
7567
7735
|
exports.applyPropertyChange = applyPropertyChange;
|
|
7736
|
+
exports.applyQuickDuplicateChange = applyQuickDuplicateChange;
|
|
7568
7737
|
exports.applyResizeChange = applyResizeChange;
|
|
7569
7738
|
exports.applySankeyNodeMoveChange = applySankeyNodeMoveChange;
|
|
7570
7739
|
exports.applySankeyNodeRenameChange = applySankeyNodeRenameChange;
|