@leafer-in/linker 2.3.3 → 2.3.4

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.
@@ -224,7 +224,7 @@ function getPolylineDirectionIndex(direction) {
224
224
  }
225
225
  }
226
226
 
227
- function getPolylinePorts(direction, point, target, bounds, targetBounds, ports) {
227
+ function getPolylinePorts(direction, point, target, bounds, targetBounds) {
228
228
  const data = directionData[getPolylineDirectionIndex(direction)];
229
229
  const dx = Math.sign(data.x - .5), dy = Math.sign(data.y - .5);
230
230
  const cx = bounds ? bounds.x + bounds.width / 2 : point.x;
@@ -232,39 +232,27 @@ function getPolylinePorts(direction, point, target, bounds, targetBounds, ports)
232
232
  const tx = targetBounds ? targetBounds.x + targetBounds.width / 2 : target.x;
233
233
  const ty = targetBounds ? targetBounds.y + targetBounds.height / 2 : target.y;
234
234
  const deltaX = tx - cx, deltaY = ty - cy;
235
- const xSign = dx || (deltaX >= 0 ? 1 : -1);
236
- const ySign = dy || (deltaY >= 0 ? 1 : -1);
237
- const xPort = POLYLINE_X * 2 + (xSign > 0 ? 1 : 0);
238
- const yPort = POLYLINE_Y * 2 + (ySign > 0 ? 1 : 0);
239
- if (dx && !dy) {
240
- ports[0] = xPort;
241
- return 1;
242
- }
243
- if (dy && !dx) {
244
- ports[0] = yPort;
245
- return 1;
246
- }
247
- if (Math.abs(deltaX) >= Math.abs(deltaY)) {
248
- ports[0] = xPort;
249
- ports[1] = yPort;
250
- } else {
251
- ports[0] = yPort;
252
- ports[1] = xPort;
253
- }
254
- return 2;
235
+ const xPort = (dx || (deltaX >= 0 ? 1 : -1)) > 0 ? 1 : 0;
236
+ const yPort = (dy || (deltaY >= 0 ? 1 : -1)) > 0 ? 3 : 2;
237
+ if (dx && !dy) return [ xPort ];
238
+ if (dy && !dx) return [ yPort ];
239
+ return Math.abs(deltaX) >= Math.abs(deltaY) ? [ xPort, yPort ] : [ yPort, xPort ];
255
240
  }
256
241
 
257
- function getPolylineExit(point, bounds, port, clearance, result) {
242
+ function getPolylineExit(point, bounds, port, clearance) {
258
243
  const axis = port >> 1, sign = port & 1 ? 1 : -1;
259
244
  if (axis === POLYLINE_X) {
260
- const boundary = bounds ? sign > 0 ? bounds.x + bounds.width : bounds.x : point.x;
261
- result[0] = boundary + sign * clearance;
262
- result[1] = point.y;
263
- } else {
264
- const boundary = bounds ? sign > 0 ? bounds.y + bounds.height : bounds.y : point.y;
265
- result[0] = point.x;
266
- result[1] = boundary + sign * clearance;
267
- }
245
+ const x = bounds ? bounds.x + (sign > 0 ? bounds.width : 0) : point.x;
246
+ return {
247
+ x: x + sign * clearance,
248
+ y: point.y
249
+ };
250
+ }
251
+ const y = bounds ? bounds.y + (sign > 0 ? bounds.height : 0) : point.y;
252
+ return {
253
+ x: point.x,
254
+ y: y + sign * clearance
255
+ };
268
256
  }
269
257
 
270
258
  function isPolylinePointBlocked(x, y, bounds, clearance) {
@@ -318,45 +306,69 @@ function getPolylineMidpointAxis(startPort, endPort, sx, sy, ex, ey) {
318
306
  return Math.abs(ex - sx) >= Math.abs(ey - sy) ? POLYLINE_X : POLYLINE_Y;
319
307
  }
320
308
 
321
- function getPolylineMidpointRoute(result, startPoint, endPoint, sx, sy, ex, ey, midpointAxis, startBounds, endBounds, clearance) {
322
- const midpointX = (sx + ex) / 2, midpointY = (sy + ey) / 2;
323
- result.length = 0;
324
- result.push(startPoint.x, startPoint.y, sx, sy);
325
- if (midpointAxis === POLYLINE_X) {
326
- result.push(midpointX, sy, midpointX, ey);
327
- } else {
328
- result.push(sx, midpointY, ex, midpointY);
329
- }
330
- result.push(ex, ey, endPoint.x, endPoint.y);
331
- for (let i = 4; i < result.length - 2; i += 2) {
332
- const x1 = result[i - 2], y1 = result[i - 1];
333
- const x2 = result[i], y2 = result[i + 1];
334
- if (isPolylineSegmentBlocked(x1, y1, x2, y2, startBounds, clearance) || isPolylineSegmentBlocked(x1, y1, x2, y2, endBounds, clearance)) return Infinity;
335
- }
336
- return getPolylineScore(result, clearance);
309
+ function isPolylinePortAligned(port, stub, dx, dy) {
310
+ const offset = port >> 1 === POLYLINE_X ? dx : dy;
311
+ const sign = port & 1 ? 1 : -1;
312
+ return Math.abs(offset) <= POLYLINE_EPSILON ? stub > POLYLINE_EPSILON : offset * sign > 0;
337
313
  }
338
314
 
339
- function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, startBounds, endBounds, clearance) {
340
- const startExit = [], endExit = [];
341
- getPolylineExit(startPoint, startBounds, startPort, clearance, startExit);
342
- getPolylineExit(endPoint, endBounds, endPort, clearance, endExit);
343
- const sx = startExit[0], sy = startExit[1], ex = endExit[0], ey = endExit[1];
344
- const startAxis = startPort >> 1, endAxis = endPort >> 1;
345
- const startSign = startPort & 1 ? 1 : -1, endSign = endPort & 1 ? 1 : -1;
315
+ function isPolylineMidpointAligned(port, stub, dx, dy, axis) {
316
+ if (port === undefined) return true;
317
+ if (axis === POLYLINE_X && Math.abs(dx / 2) > POLYLINE_EPSILON) return isPolylinePortAligned(port, stub, dx, 0);
318
+ if (axis === POLYLINE_Y && Math.abs(dy / 2) > POLYLINE_EPSILON) return isPolylinePortAligned(port, stub, 0, dy);
319
+ if (Math.abs(dx) <= POLYLINE_EPSILON && Math.abs(dy) <= POLYLINE_EPSILON) return true;
320
+ return isPolylinePortAligned(port, stub, dx, dy);
321
+ }
322
+
323
+ function isPolylineApproachAligned(points, port) {
324
+ if (port === undefined) return true;
325
+ const last = points.length - 2, x = points[last], y = points[last + 1];
326
+ for (let i = last - 2; i >= 0; i -= 2) {
327
+ const dx = points[i] - x, dy = points[i + 1] - y;
328
+ if (Math.abs(dx) > POLYLINE_EPSILON || Math.abs(dy) > POLYLINE_EPSILON) return isPolylinePortAligned(port, 1, dx, dy);
329
+ }
330
+ return true;
331
+ }
332
+
333
+ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, startBounds, endBounds, clearance, strictPorts, approachPort) {
334
+ const startExit = getPolylineExit(startPoint, startBounds, startPort, clearance);
335
+ const endExit = endPort === undefined ? endPoint : getPolylineExit(endPoint, endBounds, endPort, clearance);
336
+ const {x: sx, y: sy} = startExit, {x: ex, y: ey} = endExit;
346
337
  const startStub = Math.abs(sx - startPoint.x) + Math.abs(sy - startPoint.y);
347
338
  const endStub = Math.abs(ex - endPoint.x) + Math.abs(ey - endPoint.y);
348
339
  if (isPolylineSegmentBlocked(startPoint.x, startPoint.y, sx, sy, endBounds, clearance) || isPolylineSegmentBlocked(endPoint.x, endPoint.y, ex, ey, startBounds, clearance)) return Infinity;
349
- const midpointAxis = getPolylineMidpointAxis(startPort, endPort, sx, sy, ex, ey);
350
- const midpointScore = getPolylineMidpointRoute(result, startPoint, endPoint, sx, sy, ex, ey, midpointAxis, startBounds, endBounds, clearance);
351
- if (midpointScore < Infinity) return midpointScore;
340
+ if (endPort === undefined && (isPolylinePointBlocked(ex, ey, startBounds, clearance) || isPolylinePointBlocked(ex, ey, endBounds, clearance))) return Infinity;
341
+ const axis = endPort === undefined ? startPort >> 1 : getPolylineMidpointAxis(startPort, endPort, sx, sy, ex, ey);
342
+ const dx = ex - sx, dy = ey - sy;
343
+ result.length = 0;
344
+ result.push(startPoint.x, startPoint.y, sx, sy);
345
+ if ((!strictPorts || isPolylineMidpointAligned(startPort, startStub, dx, dy, axis) && isPolylineMidpointAligned(endPort, endStub, -dx, -dy, axis)) && isPolylineMidpointAligned(approachPort, 1, -dx, -dy, axis)) {
346
+ const mx = (sx + ex) / 2, my = (sy + ey) / 2;
347
+ if (axis === POLYLINE_X) result.push(mx, sy, mx, ey); else result.push(sx, my, ex, my);
348
+ result.push(ex, ey, endPoint.x, endPoint.y);
349
+ for (let i = 4; i < result.length - 2; i += 2) {
350
+ if (isPolylineSegmentBlocked(result[i - 2], result[i - 1], result[i], result[i + 1], startBounds, clearance) || isPolylineSegmentBlocked(result[i - 2], result[i - 1], result[i], result[i + 1], endBounds, clearance)) {
351
+ result.length = 4;
352
+ break;
353
+ }
354
+ }
355
+ if (result.length > 4 && isPolylineApproachAligned(result, approachPort)) return getPolylineScore(result, clearance);
356
+ result.length = 4;
357
+ }
358
+ const score = findPolylineGridRoute(result, startExit, endExit, startPort, endPort, startBounds, endBounds, clearance, axis, startStub, endStub, strictPorts, approachPort);
359
+ if (score === Infinity) return score;
360
+ result.push(endPoint.x, endPoint.y);
361
+ return isPolylineApproachAligned(result, approachPort) ? score + startStub + endStub : Infinity;
362
+ }
363
+
364
+ function findPolylineGridRoute(result, startExit, endExit, startPort, endPort, startBounds, endBounds, clearance, midpointAxis, startStub, endStub, strictPorts, approachPort) {
365
+ const {x: sx, y: sy} = startExit, {x: ex, y: ey} = endExit;
352
366
  const margin = Math.max(clearance, POLYLINE_MIN_SEGMENT) * 2;
353
367
  const xs = [ sx, ex, (sx + ex) / 2 ], ys = [ sy, ey, (sy + ey) / 2 ];
354
368
  addPolylineBoundsCoordinates(xs, ys, startBounds, clearance, margin);
355
369
  addPolylineBoundsCoordinates(xs, ys, endBounds, clearance, margin);
356
- let minX = Math.min(...xs), maxX = Math.max(...xs);
357
- let minY = Math.min(...ys), maxY = Math.max(...ys);
358
- xs.push(minX - margin * 2, maxX + margin * 2);
359
- ys.push(minY - margin * 2, maxY + margin * 2);
370
+ xs.push(Math.min(...xs) - margin * 2, Math.max(...xs) + margin * 2);
371
+ ys.push(Math.min(...ys) - margin * 2, Math.max(...ys) + margin * 2);
360
372
  sortPolylineCoordinates(xs);
361
373
  sortPolylineCoordinates(ys);
362
374
  const nx = xs.length, ny = ys.length;
@@ -370,53 +382,49 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
370
382
  previous.fill(-1);
371
383
  const startState = startNode * 3;
372
384
  distance[startState] = 0;
385
+ const pending = [ startState ];
373
386
  const turnCost = Math.max(POLYLINE_MIN_SEGMENT, clearance * POLYLINE_TURN_WEIGHT);
387
+ const preferredCoordinate = midpointAxis === POLYLINE_X ? (sx + ex) / 2 : (sy + ey) / 2;
374
388
  let currentState = -1, currentNode = -1, currentAxis = 0;
375
389
  let currentX = 0, currentY = 0, currentDistance = 0;
376
- const relax = (nextXIndex, nextYIndex, axis, sign) => {
390
+ const relax = (nextXIndex, nextYIndex, axis) => {
377
391
  const nextX = xs[nextXIndex], nextY = ys[nextYIndex];
378
392
  const nextNode = nextYIndex * nx + nextXIndex;
379
- if (isPolylinePointBlocked(nextX, nextY, startBounds, clearance) || isPolylinePointBlocked(nextX, nextY, endBounds, clearance)) return;
380
- if (isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, startBounds, clearance) || isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, endBounds, clearance)) return;
381
- if (currentState === startState) {
382
- if (axis === startAxis + 1) {
383
- if (sign !== startSign) return;
384
- } else if (startStub <= POLYLINE_EPSILON) return;
385
- }
386
- if (nextNode === endNode) {
387
- if (axis === endAxis + 1) {
388
- if (sign !== -endSign) return;
389
- } else if (endStub <= POLYLINE_EPSILON) return;
390
- }
393
+ const dx = nextX - currentX, dy = nextY - currentY;
394
+ if (nextNode === startNode) return;
395
+ if (approachPort !== undefined && nextNode === endNode && !isPolylinePortAligned(approachPort, 1, -dx, -dy)) return;
396
+ if (strictPorts && (currentState === startState && !isPolylinePortAligned(startPort, startStub, dx, dy) || endPort !== undefined && nextNode === endNode && !isPolylinePortAligned(endPort, endStub, -dx, -dy))) return;
397
+ if (isPolylinePointBlocked(nextX, nextY, startBounds, clearance) || isPolylinePointBlocked(nextX, nextY, endBounds, clearance) || isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, startBounds, clearance) || isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, endBounds, clearance)) return;
391
398
  const nextState = nextNode * 3 + axis;
392
399
  if (visited[nextState]) return;
393
- const segmentLength = Math.abs(nextX - currentX) + Math.abs(nextY - currentY);
394
- let cost = currentDistance + segmentLength;
400
+ let cost = currentDistance + (Math.abs(dx) + Math.abs(dy));
395
401
  if (currentAxis && currentAxis !== axis) {
396
402
  cost += turnCost;
397
403
  const turnCoordinate = currentAxis === POLYLINE_X + 1 ? currentX : currentY;
398
- const preferredCoordinate = midpointAxis === POLYLINE_X ? (sx + ex) / 2 : (sy + ey) / 2;
399
404
  if (Math.abs(turnCoordinate - preferredCoordinate) > POLYLINE_EPSILON) cost += turnCost * 2;
400
405
  }
401
406
  if (cost < distance[nextState]) {
407
+ if (distance[nextState] === Infinity) pending.push(nextState);
402
408
  distance[nextState] = cost;
403
409
  previous[nextState] = currentState;
404
410
  }
405
411
  };
406
412
  let bestState = -1;
407
- for (let iteration = 0; iteration < total; iteration++) {
408
- let minDistance = Infinity, state = -1;
409
- for (let i = 0; i < total; i++) {
410
- if (!visited[i] && distance[i] < minDistance) {
411
- minDistance = distance[i];
412
- state = i;
413
+ while (pending.length) {
414
+ let index = 0, state = pending[0];
415
+ for (let i = 1; i < pending.length; i++) {
416
+ const next = pending[i];
417
+ if (distance[next] < distance[state] || distance[next] === distance[state] && next < state) {
418
+ index = i;
419
+ state = next;
413
420
  }
414
421
  }
415
- if (state < 0) break;
422
+ pending[index] = pending[pending.length - 1];
423
+ pending.pop();
416
424
  currentState = state;
417
425
  currentNode = Math.floor(state / 3);
418
426
  currentAxis = state % 3;
419
- currentDistance = minDistance;
427
+ currentDistance = distance[state];
420
428
  visited[state] = 1;
421
429
  if (currentNode === endNode) {
422
430
  bestState = state;
@@ -425,10 +433,10 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
425
433
  const xIndex = currentNode % nx, yIndex = Math.floor(currentNode / nx);
426
434
  currentX = xs[xIndex];
427
435
  currentY = ys[yIndex];
428
- if (xIndex > 0) relax(xIndex - 1, yIndex, POLYLINE_X + 1, -1);
429
- if (xIndex < nx - 1) relax(xIndex + 1, yIndex, POLYLINE_X + 1, 1);
430
- if (yIndex > 0) relax(xIndex, yIndex - 1, POLYLINE_Y + 1, -1);
431
- if (yIndex < ny - 1) relax(xIndex, yIndex + 1, POLYLINE_Y + 1, 1);
436
+ if (xIndex > 0) relax(xIndex - 1, yIndex, POLYLINE_X + 1);
437
+ if (xIndex < nx - 1) relax(xIndex + 1, yIndex, POLYLINE_X + 1);
438
+ if (yIndex > 0) relax(xIndex, yIndex - 1, POLYLINE_Y + 1);
439
+ if (yIndex < ny - 1) relax(xIndex, yIndex + 1, POLYLINE_Y + 1);
432
440
  }
433
441
  if (bestState < 0) return Infinity;
434
442
  const reverse = [];
@@ -440,59 +448,83 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
440
448
  state = previous[state];
441
449
  }
442
450
  if (state !== startState) return Infinity;
443
- result.length = 0;
444
- result.push(startPoint.x, startPoint.y, sx, sy);
445
451
  for (let i = reverse.length - 4; i >= 0; i -= 2) result.push(reverse[i], reverse[i + 1]);
446
- result.push(endPoint.x, endPoint.y);
447
- return distance[bestState] + startStub + endStub;
452
+ return distance[bestState];
448
453
  }
449
454
 
450
- function appendPolylinePoint(points, x, y) {
451
- const length = points.length;
452
- if (length >= 2 && Math.abs(points[length - 2] - x) <= POLYLINE_EPSILON && Math.abs(points[length - 1] - y) <= POLYLINE_EPSILON) return;
453
- points.push(x, y);
455
+ function getPolylineFallback(start, end, port, startBounds, endBounds) {
456
+ const {x: sx, y: sy} = start, {x: ex, y: ey} = end;
457
+ if (sx === ex || sy === ey) return [ sx, sy, ex, ey ];
458
+ const horizontal = port >> 1 === POLYLINE_X;
459
+ const crosses = (x, y) => {
460
+ let count = 0;
461
+ if (isPolylineSegmentBlocked(sx, sy, x, y, startBounds, 0)) count++;
462
+ if (isPolylineSegmentBlocked(x, y, ex, ey, startBounds, 0)) count++;
463
+ if (isPolylineSegmentBlocked(sx, sy, x, y, endBounds, 0)) count++;
464
+ if (isPolylineSegmentBlocked(x, y, ex, ey, endBounds, 0)) count++;
465
+ return count;
466
+ };
467
+ const xy = crosses(ex, sy), yx = crosses(sx, ey);
468
+ return xy < yx || xy === yx && horizontal ? [ sx, sy, ex, sy, ex, ey ] : [ sx, sy, sx, ey, ex, ey ];
454
469
  }
455
470
 
456
- function appendPolylineOrthogonal(points, x1, y1, x2, y2, firstAxis = POLYLINE_X) {
457
- if (Math.abs(x1 - x2) > POLYLINE_EPSILON && Math.abs(y1 - y2) > POLYLINE_EPSILON) {
458
- if (firstAxis === POLYLINE_X) {
459
- const midX = (x1 + x2) / 2;
460
- appendPolylinePoint(points, midX, y1);
461
- appendPolylinePoint(points, midX, y2);
462
- } else {
463
- const midY = (y1 + y2) / 2;
464
- appendPolylinePoint(points, x1, midY);
465
- appendPolylinePoint(points, x2, midY);
471
+ function getBestPolyline(startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, approachPort) {
472
+ const startPorts = getPolylinePorts(startDirection, startPoint, endPoint, startBounds, endDirection === undefined ? undefined : endBounds);
473
+ const endPorts = endDirection === undefined ? [ undefined ] : getPolylinePorts(endDirection, endPoint, startPoint, endBounds, startBounds);
474
+ let candidate = [], best = [], bestScore = Infinity;
475
+ for (let pass = clearance ? 0 : 1; pass < 3 && !best.length; pass++) {
476
+ const gap = pass ? 0 : clearance;
477
+ for (let i = 0; i < startPorts.length; i++) {
478
+ for (let j = 0; j < endPorts.length; j++) {
479
+ const score = getPolylineRoute(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, gap, pass < 2, approachPort);
480
+ if (score < bestScore) {
481
+ bestScore = score;
482
+ const previous = best;
483
+ best = candidate;
484
+ candidate = previous;
485
+ }
486
+ }
466
487
  }
467
488
  }
468
- appendPolylinePoint(points, x2, y2);
489
+ if (!best.length) return getPolylineFallback(startPoint, endPoint, startPorts[0], startBounds, endBounds);
490
+ simplifyPolyline(best);
491
+ const last = best.length - 2;
492
+ if (best[last] !== endPoint.x || best[last + 1] !== endPoint.y) best.push(endPoint.x, endPoint.y);
493
+ return best;
469
494
  }
470
495
 
471
- function getPolylineEditPath(result, startPoint, endPoint, startPort, endPort, startBounds, endBounds, points, clearance) {
472
- if (points.length % 2) return Infinity;
473
- for (let i = 0; i < points.length; i++) if (!Number.isFinite(points[i])) return Infinity;
474
- const startExit = [], endExit = [];
475
- getPolylineExit(startPoint, startBounds, startPort, clearance, startExit);
476
- getPolylineExit(endPoint, endBounds, endPort, clearance, endExit);
477
- const sx = startExit[0], sy = startExit[1], ex = endExit[0], ey = endExit[1];
478
- if (isPolylineSegmentBlocked(startPoint.x, startPoint.y, sx, sy, endBounds, clearance) || isPolylineSegmentBlocked(endPoint.x, endPoint.y, ex, ey, startBounds, clearance)) return Infinity;
479
- result.length = 0;
480
- appendPolylinePoint(result, startPoint.x, startPoint.y);
481
- appendPolylinePoint(result, sx, sy);
482
- let x = sx, y = sy;
483
- for (let i = 0; i < points.length; i += 2) {
484
- const nx = points[i], ny = points[i + 1];
485
- appendPolylineOrthogonal(result, x, y, nx, ny, i === 0 && clearance === 0 ? startPort >> 1 : POLYLINE_X);
486
- x = nx;
487
- y = ny;
488
- }
489
- const endAxis = endPort >> 1;
490
- if (Math.abs(x - ex) > POLYLINE_EPSILON && Math.abs(y - ey) > POLYLINE_EPSILON) {
491
- if (endAxis === POLYLINE_X) appendPolylinePoint(result, x, ey); else appendPolylinePoint(result, ex, y);
492
- }
493
- appendPolylinePoint(result, ex, ey);
494
- appendPolylinePoint(result, endPoint.x, endPoint.y);
495
- return getPolylineScore(result, clearance);
496
+ function getPolylineEditSide(point, waypoint, direction, bounds, otherBounds, clearance, points, index, step) {
497
+ if (point.x === waypoint.x && point.y === waypoint.y) return [];
498
+ let approachPort;
499
+ for (let i = index + step; i >= 0 && i < points.length; i += step) {
500
+ const dx = points[i] - waypoint.x, dy = points[i + 1] - waypoint.y;
501
+ if (Math.abs(dx) <= POLYLINE_EPSILON && Math.abs(dy) <= POLYLINE_EPSILON) continue;
502
+ if (Math.abs(dy) <= POLYLINE_EPSILON) approachPort = dx > 0 ? 0 : 1; else if (Math.abs(dx) <= POLYLINE_EPSILON) approachPort = dy > 0 ? 2 : 3;
503
+ break;
504
+ }
505
+ const side = getBestPolyline(point, waypoint, direction, undefined, bounds, otherBounds, clearance, approachPort);
506
+ side.length -= 2;
507
+ return side;
508
+ }
509
+
510
+ function drawPolylineEditPath(path, startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, points) {
511
+ const length = points.length, last = length - 2;
512
+ if (length % 2) return false;
513
+ for (let i = 0; i < length; i++) if (!Number.isFinite(points[i])) return false;
514
+ const start = getPolylineEditSide(startPoint, {
515
+ x: points[0],
516
+ y: points[1]
517
+ }, startDirection, startBounds, endBounds, clearance, points, 0, 2);
518
+ const end = getPolylineEditSide(endPoint, {
519
+ x: points[last],
520
+ y: points[last + 1]
521
+ }, endDirection, endBounds, startBounds, clearance, points, last, -2);
522
+ const first = start.length ? start : points;
523
+ moveTo$1(path, first[0], first[1]);
524
+ for (let i = 2; i < start.length; i += 2) lineTo$1(path, start[i], start[i + 1]);
525
+ for (let i = start.length ? 0 : 2; i < length; i += 2) lineTo$1(path, points[i], points[i + 1]);
526
+ for (let i = end.length - 2; i >= 0; i -= 2) lineTo$1(path, end[i], end[i + 1]);
527
+ return true;
496
528
  }
497
529
 
498
530
  function getPolylineScore(points, clearance) {
@@ -535,26 +567,8 @@ function drawPolyline(path, startPoint, endPoint, startDirection, endDirection,
535
567
  if (startBounds && (!Number.isFinite(startBounds.x) || !Number.isFinite(startBounds.y) || !Number.isFinite(startBounds.width) || !Number.isFinite(startBounds.height) || startBounds.width < 0 || startBounds.height < 0)) return false;
536
568
  if (endBounds && (!Number.isFinite(endBounds.x) || !Number.isFinite(endBounds.y) || !Number.isFinite(endBounds.width) || !Number.isFinite(endBounds.height) || endBounds.width < 0 || endBounds.height < 0)) return false;
537
569
  clearance = Number.isFinite(clearance) ? Math.max(0, clearance) : 8;
538
- const startPorts = [], endPorts = [];
539
- const startCount = getPolylinePorts(startDirection, startPoint, endPoint, startBounds, endBounds, startPorts);
540
- const endCount = getPolylinePorts(endDirection, endPoint, startPoint, endBounds, startBounds, endPorts);
541
- const candidate = [], best = [];
542
- let bestScore = Infinity;
543
- for (let pass = 0; pass < 2 && bestScore === Infinity; pass++) {
544
- const currentClearance = pass === 0 ? clearance : 0;
545
- for (let i = 0; i < startCount; i++) {
546
- for (let j = 0; j < endCount; j++) {
547
- const score = points !== undefined ? getPolylineEditPath(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, points, currentClearance) : getPolylineRoute(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, currentClearance);
548
- if (score < bestScore) {
549
- bestScore = score;
550
- best.length = 0;
551
- for (let k = 0; k < candidate.length; k++) best.push(candidate[k]);
552
- }
553
- }
554
- }
555
- }
556
- if (!best.length) return false;
557
- if (points === undefined) simplifyPolyline(best);
570
+ if (points === null || points === void 0 ? void 0 : points.length) return drawPolylineEditPath(path, startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, points);
571
+ const best = getBestPolyline(startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance);
558
572
  moveTo$1(path, best[0], best[1]);
559
573
  for (let i = 2; i < best.length; i += 2) lineTo$1(path, best[i], best[i + 1]);
560
574
  return true;
@@ -1,2 +1,2 @@
1
- import{LineData as t,AroundHelper as e,PointHelper as n,Direction9 as i,BoundsHelper as o,decorateLeafAttr as r,attr as s,doBoundsType as a,doStrokeType as h,PathCommandDataHelper as c,dataProcessor as u,boundsType as d,pathType as f,registerUI as l,Line as p,BoundsEvent as y,LeafHelper as x,isString as g,isObject as b,Plugin as M,registerPointsCurve as m}from"@leafer-ui/draw";import{PointHelper as N,PathCommandMap as P}from"@leafer-ui/core";function k(t,e,n,i){var o,r=arguments.length,s=r<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,i);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(s=(r<3?o(s):r>3?o(e,n,s):o(e,n))||s);return r>3&&s&&Object.defineProperty(e,n,s),s}"function"==typeof SuppressedError&&SuppressedError;class L extends t{get __usePathBox(){return this.path||this.__pathInputed}}const{directionData:C}=e,_=["top-left","top","top-right","right","bottom-right","bottom","bottom-left","left","center"],w={getCtrlPoint(t,e,n,i,o,r){let s;switch(e&&(n=e.getBoxPoint(n,t)),i){case"left":case"top-left":case"bottom-left":s={x:n.x-o.x,y:n.y};break;case"top":s={x:n.x,y:n.y-o.y};break;case"right":case"top-right":case"bottom-right":s={x:n.x+o.x,y:n.y};break;case"bottom":s={x:n.x,y:n.y+o.y};break;default:s={x:n.x,y:n.y}}return r&&(r=r/180*Math.PI,s={x:(s.x-n.x)*Math.cos(r)-(s.y-n.y)*Math.sin(r)+n.x,y:(s.x-n.x)*Math.sin(r)+(s.y-n.y)*Math.cos(r)+n.y}),e&&e.getWorldPointByBox(s,t,void 0,!0),s},isOppositeDirection(t,e){switch(t){case"left":return"right"==e;case"top":return"bottom"==e;case"right":return"left"==e;case"bottom":return"top"==e;case"center":return"center"==e;default:return!1}},getDirectionForFromPoint(t,e){const n=t.x-e.x,i=t.y-e.y;let o,r=180*Math.atan2(i,n)/Math.PI;return r<0&&(r=360+r),o=r>315||r<45?"left":r>45&&r<135?"top":r>135&&r<225?"right":"bottom",o},getRotateDirection(t,e,n=8){let o=i[t];return o=(o+Math.round(e/(360/n)))%n,o<0&&(o+=n),_[o]},getDirection:function(t,e,n){const{width:i,height:r}=e,s=o.getPoint(e,"center",!0),a=t.x-s.x,h=t.y-s.y;if(!n&&Math.abs(a)<i/4&&Math.abs(h)<r/4)return"center";const c=Math.abs(a)*r,u=Math.abs(h)*i;if(c>u)return a>0?"right":"left";return h>0?"bottom":"top"},getPointDirection:function(t,e,n){const{width:i,height:o}=e,r=i/4,s=o/4;for(let e=0;e<C.length;e++){const a=C[e],h=a.x*i,c=a.y*o,u=t.x-h,d=t.y-c;if(Math.abs(u)<=r&&Math.abs(d)<=s){if(!n)return _[e];if("center"!==_[e])return _[e]}}return},autoRotatePoint(t,e,i){const{rotation:o,scaleX:r,scaleY:s}=i,a=r*s<0;(o||a)&&n.rotate(t,a?-o:o,e)}};function D(t){return r(t,t=>s({set(e){if(this.__setAttr(t,e)){const t=this.__layout;t.linkerChanged||(a(this),h(this),t.linkerChanged=!0)}}}))}const{directionData:v}=e,{moveTo:F,lineTo:B}=c,E=.001;function R(t,e,n,i,o,r){const s=v[function(t){switch(t){case"top-left":return 0;case"top":return 1;case"top-right":return 2;case"right":return 3;case"bottom-right":return 4;case"bottom":return 5;case"bottom-left":return 6;case"left":return 7;default:return 8}}(t)],a=Math.sign(s.x-.5),h=Math.sign(s.y-.5),c=i?i.x+i.width/2:e.x,u=i?i.y+i.height/2:e.y,d=(o?o.x+o.width/2:n.x)-c,f=(o?o.y+o.height/2:n.y)-u,l=0+((a||(d>=0?1:-1))>0?1:0),p=2+((h||(f>=0?1:-1))>0?1:0);return a&&!h?(r[0]=l,1):h&&!a?(r[0]=p,1):(Math.abs(d)>=Math.abs(f)?(r[0]=l,r[1]=p):(r[0]=p,r[1]=l),2)}function O(t,e,n,i,o){const r=1&n?1:-1;if(0===n>>1){const n=e?r>0?e.x+e.width:e.x:t.x;o[0]=n+r*i,o[1]=t.y}else{const n=e?r>0?e.y+e.height:e.y:t.y;o[0]=t.x,o[1]=n+r*i}}function S(t,e,n,i){if(!n)return!1;const o=n.x-i,r=n.x+n.width+i,s=n.y-i,a=n.y+n.height+i;return t>o+E&&t<r-E&&e>s+E&&e<a-E}function T(t,e,n,i,o,r){if(!o)return!1;const s=o.x-r,a=o.x+o.width+r,h=o.y-r,c=o.y+o.height+r;return Math.abs(e-i)<=E?e>h+E&&e<c-E&&Math.max(Math.min(t,n),s+E)<Math.min(Math.max(t,n),a-E):!(Math.abs(t-n)<=E)||t>s+E&&t<a-E&&Math.max(Math.min(e,i),h+E)<Math.min(Math.max(e,i),c-E)}function W(t,e,n,i,o){if(!n)return;const r=n.x-i,s=n.x+n.width+i,a=n.y-i,h=n.y+n.height+i;t.push(r,s,r-o,s+o),e.push(a,h,a-o,h+o)}function q(t){t.sort((t,e)=>t-e);let e=0;for(let n=0;n<t.length;n++)(!e||Math.abs(t[n]-t[e-1])>E)&&(t[e++]=t[n]);t.length=e}function I(t,e){for(let n=0;n<t.length;n++)if(Math.abs(t[n]-e)<=E)return n;return-1}function A(t,e,n,i,o,r,s,a){const h=[],c=[];O(e,r,i,a,h),O(n,s,o,a,c);const u=h[0],d=h[1],f=c[0],l=c[1],p=i>>1,y=o>>1,x=1&i?1:-1,g=1&o?1:-1,b=Math.abs(u-e.x)+Math.abs(d-e.y),M=Math.abs(f-n.x)+Math.abs(l-n.y);if(T(e.x,e.y,u,d,s,a)||T(n.x,n.y,f,l,r,a))return 1/0;const m=function(t,e,n,i,o,r){const s=t>>1;return s===e>>1&&(1&t?1:-1)==-(1&e?1:-1)?s:Math.abs(o-n)>=Math.abs(r-i)?0:1}(i,o,u,d,f,l),N=function(t,e,n,i,o,r,s,a,h,c,u){const d=(i+r)/2,f=(o+s)/2;t.length=0,t.push(e.x,e.y,i,o),0===a?t.push(d,o,d,s):t.push(i,f,r,f),t.push(r,s,n.x,n.y);for(let e=4;e<t.length-2;e+=2){const n=t[e-2],i=t[e-1],o=t[e],r=t[e+1];if(T(n,i,o,r,h,u)||T(n,i,o,r,c,u))return 1/0}return U(t,u)}(t,e,n,u,d,f,l,m,r,s,a);if(N<1/0)return N;const P=2*Math.max(a,4),k=[u,f,(u+f)/2],L=[d,l,(d+l)/2];W(k,L,r,a,P),W(k,L,s,a,P);let C=Math.min(...k),_=Math.max(...k),w=Math.min(...L),D=Math.max(...L);k.push(C-2*P,_+2*P),L.push(w-2*P,D+2*P),q(k),q(L);const v=k.length,F=L.length,B=I(k,u),R=I(L,d),A=I(k,f),j=I(L,l);if(B<0||R<0||A<0||j<0)return 1/0;const z=R*v+B,H=j*v+A,X=v*F*3,Y=new Float64Array(X),Z=new Int32Array(X),G=new Uint8Array(X);Y.fill(1/0),Z.fill(-1);const J=3*z;Y[J]=0;const K=Math.max(4,1.5*a);let Q=-1,V=-1,$=0,tt=0,et=0,nt=0;const it=(t,e,n,i)=>{const o=k[t],h=L[e],c=e*v+t;if(S(o,h,r,a)||S(o,h,s,a))return;if(T(tt,et,o,h,r,a)||T(tt,et,o,h,s,a))return;if(Q===J)if(n===p+1){if(i!==x)return}else if(b<=E)return;if(c===H)if(n===y+1){if(i!==-g)return}else if(M<=E)return;const N=3*c+n;if(G[N])return;const P=Math.abs(o-tt)+Math.abs(h-et);let C=nt+P;if($&&$!==n){C+=K;const t=1===$?tt:et,e=0===m?(u+f)/2:(d+l)/2;Math.abs(t-e)>E&&(C+=2*K)}C<Y[N]&&(Y[N]=C,Z[N]=Q)};let ot=-1;for(let t=0;t<X;t++){let t=1/0,e=-1;for(let n=0;n<X;n++)!G[n]&&Y[n]<t&&(t=Y[n],e=n);if(e<0)break;if(Q=e,V=Math.floor(e/3),$=e%3,nt=t,G[e]=1,V===H){ot=e;break}const n=V%v,i=Math.floor(V/v);tt=k[n],et=L[i],n>0&&it(n-1,i,1,-1),n<v-1&&it(n+1,i,1,1),i>0&&it(n,i-1,2,-1),i<F-1&&it(n,i+1,2,1)}if(ot<0)return 1/0;const rt=[];let st=ot;for(;st>=0;){const t=Math.floor(st/3);if(rt.push(k[t%v],L[Math.floor(t/v)]),st===J)break;st=Z[st]}if(st!==J)return 1/0;t.length=0,t.push(e.x,e.y,u,d);for(let e=rt.length-4;e>=0;e-=2)t.push(rt[e],rt[e+1]);return t.push(n.x,n.y),Y[ot]+b+M}function j(t,e,n){const i=t.length;i>=2&&Math.abs(t[i-2]-e)<=E&&Math.abs(t[i-1]-n)<=E||t.push(e,n)}function z(t,e,n,i,o,r=0){if(Math.abs(e-i)>E&&Math.abs(n-o)>E)if(0===r){const r=(e+i)/2;j(t,r,n),j(t,r,o)}else{const r=(n+o)/2;j(t,e,r),j(t,i,r)}j(t,i,o)}function H(t,e,n,i,o,r,s,a,h){if(a.length%2)return 1/0;for(let t=0;t<a.length;t++)if(!Number.isFinite(a[t]))return 1/0;const c=[],u=[];O(e,r,i,h,c),O(n,s,o,h,u);const d=c[0],f=c[1],l=u[0],p=u[1];if(T(e.x,e.y,d,f,s,h)||T(n.x,n.y,l,p,r,h))return 1/0;t.length=0,j(t,e.x,e.y),j(t,d,f);let y=d,x=f;for(let e=0;e<a.length;e+=2){const n=a[e],o=a[e+1];z(t,y,x,n,o,0===e&&0===h?i>>1:0),y=n,x=o}const g=o>>1;return Math.abs(y-l)>E&&Math.abs(x-p)>E&&(0===g?j(t,y,p):j(t,l,x)),j(t,l,p),j(t,n.x,n.y),U(t,h)}function U(t,e){let n=0,i=0,o=-1;for(let e=2;e<t.length;e+=2){const r=t[e]-t[e-2],s=t[e+1]-t[e-1];if(Math.abs(r)<=E&&Math.abs(s)<=E)continue;const a=Math.abs(r)>E?0:1;n+=Math.abs(r)+Math.abs(s),-1!==o&&o!==a&&i++,o=a}return n+i*Math.max(e,4)*1.5}function X(t,e,n,i,o,r,s,a=8,h){if(!(Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(n.x)&&Number.isFinite(n.y)))return!1;if(r&&(!Number.isFinite(r.x)||!Number.isFinite(r.y)||!Number.isFinite(r.width)||!Number.isFinite(r.height)||r.width<0||r.height<0))return!1;if(s&&(!Number.isFinite(s.x)||!Number.isFinite(s.y)||!Number.isFinite(s.width)||!Number.isFinite(s.height)||s.width<0||s.height<0))return!1;a=Number.isFinite(a)?Math.max(0,a):8;const c=[],u=[],d=R(i,e,n,r,s,c),f=R(o,n,e,s,r,u),l=[],p=[];let y=1/0;for(let t=0;t<2&&y===1/0;t++){const i=0===t?a:0;for(let t=0;t<d;t++)for(let o=0;o<f;o++){const a=void 0!==h?H(l,e,n,c[t],u[o],r,s,h,i):A(l,e,n,c[t],u[o],r,s,i);if(a<y){y=a,p.length=0;for(let t=0;t<l.length;t++)p.push(l[t])}}}if(!p.length)return!1;void 0===h&&function(t){let e=2;for(let n=2;n<t.length;n+=2){const i=t[n],o=t[n+1],r=t[e-2],s=t[e-1];if(!(Math.abs(i-r)<=E&&Math.abs(o-s)<=E)){if(e>=4){const n=t[e-4],a=t[e-3],h=Math.abs(a-s)<=E&&Math.abs(s-o)<=E&&(r-n)*(i-r)>=0,c=Math.abs(n-r)<=E&&Math.abs(r-i)<=E&&(s-a)*(o-s)>=0;if(h||c){t[e-2]=i,t[e-1]=o;continue}}t[e++]=i,t[e++]=o}}t.length=e}(p),F(t,p[0],p[1]);for(let e=2;e<p.length;e+=2)B(t,p[e],p[e+1]);return!0}const{moveTo:Y,lineTo:Z,bezierCurveTo:G,drawPoints:J}=c,{isEmpty:K,getPoint:Q}=o,{getDistance:V}=n,{getCtrlPoint:$,getDirectionForFromPoint:tt,isOppositeDirection:et}=w,{max:nt,min:it,abs:ot}=Math;let rt=class extends p{get __tag(){return"Linker"}constructor(t){super(t),this.onStartNodeChange=this.onStartNodeChange.bind(this),this.onEndNodeChange=this.onEndNodeChange.bind(this)}__updatePath(){const t=this.__layout,{startNode:e,endNode:n}=this;t.linkerChanged&&(this.updateLinkerNode("start"),this.updateLinkerNode("end"),this.updateLinkerPoint("start"),this.updateLinkerPoint("end"),e!==this.startNode&&this.listenLinkerNode(this.startNode,e,"start"),n!==this.endNode&&this.listenLinkerNode(this.endNode,n,"end"),t.linkerChanged=!1),this.updateLinkerPath()}listenLinkerNode(t,e,n){if(e){e.off(y.WORLD,"end"===n?this.onEndNodeChange:this.onStartNodeChange);const t="end"===n?e.endLinker:e.startLinker;if(t){const e=t.indexOf(this);e>-1&&t.splice(e,1)}}if(t){t.on(y.WORLD,"end"===n?this.onEndNodeChange:this.onStartNodeChange);("end"===n?t.endLinker||(t.endLinker=[]):t.startLinker||(t.startLinker=[])).push(this)}}onStartNodeChange(){this.onLinkerNodeChange("start")}onEndNodeChange(){this.onLinkerNodeChange("end")}onLinkerNodeChange(t){if(this.leaferIsCreated){const{layouter:t,zoomLayer:e}=this.leafer;if(t.__updatedList.has(e))return;t.addExtra(this,!0)}const{startData:e,endData:n}=this;"start"==t?(this.updateLinkerPoint("start"),n&&n.auto&&this.updateLinkerPoint("end")):(e&&e.auto&&this.updateLinkerPoint("start"),this.updateLinkerPoint("end")),this.__layout.boxChange(),x.updateBounds(this)}updateLinkerNode(t){const{startPoint:e,endPoint:n}=this,i="end"===t?n:e;if(i){const{id:e}=i,n=e&&(g(e)?this.app.findId(e):e);"end"===t?this.endNode=n:this.startNode=n}}getLinkerNodeCenter(t){const{startPoint:e,endPoint:n,startNode:i,endNode:o,startData:r,endData:s}=this,a="end"===t?o:i,h="end"===t?s||n:r||e;if(a){const{worldRenderBounds:t}=a;return K(t)&&x.updateBounds(a),Q(a.worldRenderBounds,"center")}return h&&b(h.point)&&this.getWorldPointByLocal(h.point)}updateLinkerPoint(t){const{startPoint:e,endPoint:i,lineType:o}=this,r="end"===t?i:e;if(r){const e={},{id:i,offset:s}=r;let{direction:a,point:h}=r;if("center"===a||!a&&i&&!h){const n=this.getLinkerNodeCenter("start"),i=this.getLinkerNodeCenter("end"),o="end"===t?i:n,r="end"===t?n:i;o&&r&&(a=tt(o,r)),e.auto=!0}!a&&g(h)&&(a=h),e.direction=a;const c="end"===t?this.endNode:this.startNode;let u;if(c){if(h||(h=a),h){const{boxBounds:t}=c;K(t)&&x.updateBounds(c),u=Q(t,h,!0),c.getWorldPointByBox(u,this,!1,!0),"polyline"===o&&(e.bounds=c.getBounds("box",this.parent))}}else b(h)&&(u=h);if(u&&s){const t=Object.assign({},s);s.x||(t.x=0),s.y||(t.y=0),c&&c.getWorldPoint(t,this,!0,!0),n.move(u,t)}e.point=u,"end"===t?this.endData=u&&e:this.startData=u&&e}}updateLinkerPath(){const t=this.__,e=t.path=[],i=t.points&&t.points.length,{startData:o,endData:r,startNode:s,endNode:a}=this;if(!o||!r)return;const h=o.point,c=r.point,u=o.direction,d=r.direction,f=8*this.__.strokeWidth;switch(t.lineType){case"straight":Y(e,h.x,h.y),Z(e,c.x,c.y);break;case"polyline":X(e,h,c,u,d,o.bounds,r.bounds,f,i&&n.toNumberPoints(t.points));break;default:const l={x:ot((h.x-c.x)/2),y:ot((h.y-c.y)/2)};let p;if(this.__.__useArrow){const t=it(V(h,c)/(25*f),1);p=nt(f*t*12,3*f)}else p=2*f;if(d&&et(u,d)&&u===tt(h,c)&&(p=2*f),l.x=nt(p,l.x),l.y=nt(p,l.y),i){p*=.6;const i=n.toNumberPoints(t.points);if(J(e,[h.x,h.y,...i,c.x,c.y],t.curve,!1,t),u){const t=e[4],n=e[5];l.x=nt(p,ot(t-h.x)),l.y=nt(p,ot(n-h.y));const i=$(this,s,h,u,l);e[4]=i.x,e[5]=i.y}const o=e.length;if(d){const t=e[o-4],n=e[o-3];l.x=nt(p,ot(t-c.x)),l.y=nt(p,ot(n-c.y));const i=$(this,a,c,d,l);e[o-4]=i.x,e[o-3]=i.y}else e[o-4]=c.x,e[o-3]=c.y}else{const t=u?$(this,s,h,u,l):h,n=d?$(this,a,c,d,l):c;Y(e,h.x,h.y),G(e,t.x,t.y,n.x,n.y,c.x,c.y)}}}createStartPoint(t,e,n){const i=this.createLinkerPoint(t,e,n);return this.startPoint=i,i}createEndPoint(t,e,n){const i=this.createLinkerPoint(t,e,n);return this.endPoint=i,i}createLinkerPoint(t,e,n){const i={};if(e&&e.id){const r=e.getBoxPoint(t),{boxBounds:s}=e,a=n&&n.mode,h="edge"===a||!a,c="four"===a,u="free"===a;if(!("auto"===a))if(c)i.point=w.getDirection(r,s,c);else if(i.direction=w.getDirection(r,s,h),i.point=w.getPointDirection(r,s,h)||i.direction,i.point===i.direction&&delete i.direction,u||h){const t=o.getPoint(s,i.point),e=r.x-t.x,a=r.y-t.y,c=n&&n.snapRadius||10;if(Math.abs(e)>c||Math.abs(a)>c){const t=i.offset={x:Math.abs(e)>c?e:0,y:Math.abs(a)>c?a:0};if(h&&(t.x||t.y))switch(i.direction||i.point){case"top":case"bottom":t.y=0;break;case"right":case"left":t.x=0;break;default:t.x>t.y?t.y=0:t.x=0}}}i.id=e.id}else i.point=this.getLocalPoint(t);return i}};k([u(L)],rt.prototype,"__",void 0),k([d("curve")],rt.prototype,"lineType",void 0),k([D()],rt.prototype,"startPoint",void 0),k([D()],rt.prototype,"endPoint",void 0),k([f({type:"C",value:.5})],rt.prototype,"curve",void 0),rt=k([l()],rt);const{toNumberPoints:st}=N,{M:at,L:ht,C:ct,Z:ut}=P;M.add("linker"),m("C",function(t,e,n,i){const o=st(e),r=o.length>>1;if(r<2)return;if(t.push(at,o[0],o[1]),!n||r<3){for(let e=1;e<r;e++)t.push(ht,o[2*e],o[2*e+1]);return void(i&&t.push(ut))}let s=!0===n?.5:n;s<0?s=0:s>1&&(s=1);const a=i?r:r-1;let h=o[0],c=o[1];{const t=o[2]-o[0],e=o[3]-o[1],n=Math.sqrt(t*t+e*e);n&&(h=o[0]+t/n*n*s,c=o[1]+e/n*n*s)}for(let e=0;e<a;e++){const n=e+1===r?0:e+1,i=o[2*n],a=o[2*n+1],u=0===n?r-1:n-1,d=n+1===r?0:n+1;let f=o[2*u]-i,l=o[2*u+1]-a,p=o[2*d]-i,y=o[2*d+1]-a;const x=Math.sqrt(f*f+l*l),g=Math.sqrt(p*p+y*y);let b=i,M=a,m=i,N=a;if(x||g){let t=0,e=0;x&&(t+=f/x,e+=l/x),g&&(t+=p/g,e+=y/g);let n=Math.sqrt(t*t+e*e);n||(g?(t=p/g,e=y/g):(t=f/x,e=l/x),n=1),t/=n,e/=n;let o=-e,r=t;g&&o*p+r*y<0&&(o=-o,r=-r);let h=0;x&&g&&(h=(f*p+l*y)/(x*g),h>1?h=1:h<-1&&(h=-1));let c=Math.sqrt(Math.sqrt(Math.max(0,1-h*h)));c<.15&&(c=.15);let u=x*s*c,d=g*s*c;const P=.5*Math.min(x||g,g||x);u>P&&(u=P),d>P&&(d=P),b=i-o*u,M=a-r*u,m=i+o*d,N=a+r*d}t.push(ct,h,c,b,M,i,a),h=m,c=N}i&&t.push(ut)});export{rt as Linker,L as LinkerData};
1
+ import{LineData as t,AroundHelper as e,PointHelper as n,Direction9 as i,BoundsHelper as o,decorateLeafAttr as r,attr as s,doBoundsType as a,doStrokeType as h,PathCommandDataHelper as c,dataProcessor as u,boundsType as d,pathType as l,registerUI as f,Line as y,BoundsEvent as x,LeafHelper as g,isString as p,isObject as b,Plugin as M,registerPointsCurve as m}from"@leafer-ui/draw";import{PointHelper as N,PathCommandMap as P}from"@leafer-ui/core";function k(t,e,n,i){var o,r=arguments.length,s=r<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,n,i);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(s=(r<3?o(s):r>3?o(e,n,s):o(e,n))||s);return r>3&&s&&Object.defineProperty(e,n,s),s}"function"==typeof SuppressedError&&SuppressedError;class L extends t{get __usePathBox(){return this.path||this.__pathInputed}}const{directionData:v}=e,C=["top-left","top","top-right","right","bottom-right","bottom","bottom-left","left","center"],_={getCtrlPoint(t,e,n,i,o,r){let s;switch(e&&(n=e.getBoxPoint(n,t)),i){case"left":case"top-left":case"bottom-left":s={x:n.x-o.x,y:n.y};break;case"top":s={x:n.x,y:n.y-o.y};break;case"right":case"top-right":case"bottom-right":s={x:n.x+o.x,y:n.y};break;case"bottom":s={x:n.x,y:n.y+o.y};break;default:s={x:n.x,y:n.y}}return r&&(r=r/180*Math.PI,s={x:(s.x-n.x)*Math.cos(r)-(s.y-n.y)*Math.sin(r)+n.x,y:(s.x-n.x)*Math.sin(r)+(s.y-n.y)*Math.cos(r)+n.y}),e&&e.getWorldPointByBox(s,t,void 0,!0),s},isOppositeDirection(t,e){switch(t){case"left":return"right"==e;case"top":return"bottom"==e;case"right":return"left"==e;case"bottom":return"top"==e;case"center":return"center"==e;default:return!1}},getDirectionForFromPoint(t,e){const n=t.x-e.x,i=t.y-e.y;let o,r=180*Math.atan2(i,n)/Math.PI;return r<0&&(r=360+r),o=r>315||r<45?"left":r>45&&r<135?"top":r>135&&r<225?"right":"bottom",o},getRotateDirection(t,e,n=8){let o=i[t];return o=(o+Math.round(e/(360/n)))%n,o<0&&(o+=n),C[o]},getDirection:function(t,e,n){const{width:i,height:r}=e,s=o.getPoint(e,"center",!0),a=t.x-s.x,h=t.y-s.y;if(!n&&Math.abs(a)<i/4&&Math.abs(h)<r/4)return"center";const c=Math.abs(a)*r,u=Math.abs(h)*i;if(c>u)return a>0?"right":"left";return h>0?"bottom":"top"},getPointDirection:function(t,e,n){const{width:i,height:o}=e,r=i/4,s=o/4;for(let e=0;e<v.length;e++){const a=v[e],h=a.x*i,c=a.y*o,u=t.x-h,d=t.y-c;if(Math.abs(u)<=r&&Math.abs(d)<=s){if(!n)return C[e];if("center"!==C[e])return C[e]}}return},autoRotatePoint(t,e,i){const{rotation:o,scaleX:r,scaleY:s}=i,a=r*s<0;(o||a)&&n.rotate(t,a?-o:o,e)}};function w(t){return r(t,t=>s({set(e){if(this.__setAttr(t,e)){const t=this.__layout;t.linkerChanged||(a(this),h(this),t.linkerChanged=!0)}}}))}const{directionData:D}=e,{moveTo:F,lineTo:B}=c,E=.001,R=1.5;function O(t,e,n,i,o){const r=D[function(t){switch(t){case"top-left":return 0;case"top":return 1;case"top-right":return 2;case"right":return 3;case"bottom-right":return 4;case"bottom":return 5;case"bottom-left":return 6;case"left":return 7;default:return 8}}(t)],s=Math.sign(r.x-.5),a=Math.sign(r.y-.5),h=i?i.x+i.width/2:e.x,c=i?i.y+i.height/2:e.y,u=(o?o.x+o.width/2:n.x)-h,d=(o?o.y+o.height/2:n.y)-c,l=(s||(u>=0?1:-1))>0?1:0,f=(a||(d>=0?1:-1))>0?3:2;return s&&!a?[l]:a&&!s?[f]:Math.abs(u)>=Math.abs(d)?[l,f]:[f,l]}function S(t,e,n,i){const o=1&n?1:-1;if(0===n>>1){return{x:(e?e.x+(o>0?e.width:0):t.x)+o*i,y:t.y}}const r=e?e.y+(o>0?e.height:0):t.y;return{x:t.x,y:r+o*i}}function T(t,e,n,i){if(!n)return!1;const o=n.x-i,r=n.x+n.width+i,s=n.y-i,a=n.y+n.height+i;return t>o+E&&t<r-E&&e>s+E&&e<a-E}function W(t,e,n,i,o,r){if(!o)return!1;const s=o.x-r,a=o.x+o.width+r,h=o.y-r,c=o.y+o.height+r;return Math.abs(e-i)<=E?e>h+E&&e<c-E&&Math.max(Math.min(t,n),s+E)<Math.min(Math.max(t,n),a-E):!(Math.abs(t-n)<=E)||t>s+E&&t<a-E&&Math.max(Math.min(e,i),h+E)<Math.min(Math.max(e,i),c-E)}function q(t,e,n,i,o){if(!n)return;const r=n.x-i,s=n.x+n.width+i,a=n.y-i,h=n.y+n.height+i;t.push(r,s,r-o,s+o),e.push(a,h,a-o,h+o)}function I(t){t.sort((t,e)=>t-e);let e=0;for(let n=0;n<t.length;n++)(!e||Math.abs(t[n]-t[e-1])>E)&&(t[e++]=t[n]);t.length=e}function A(t,e){for(let n=0;n<t.length;n++)if(Math.abs(t[n]-e)<=E)return n;return-1}function j(t,e,n,i){const o=t>>1?i:n,r=1&t?1:-1;return Math.abs(o)<=E?e>E:o*r>0}function z(t,e,n,i,o){return void 0===t||(0===o&&Math.abs(n/2)>E?j(t,e,n,0):1===o&&Math.abs(i/2)>E?j(t,e,0,i):Math.abs(n)<=E&&Math.abs(i)<=E||j(t,e,n,i))}function H(t,e){if(void 0===e)return!0;const n=t.length-2,i=t[n],o=t[n+1];for(let r=n-2;r>=0;r-=2){const n=t[r]-i,s=t[r+1]-o;if(Math.abs(n)>E||Math.abs(s)>E)return j(e,1,n,s)}return!0}function U(t,e,n,i,o,r,s,a,h,c){const u=S(e,r,i,a),d=void 0===o?n:S(n,s,o,a),{x:l,y:f}=u,{x:y,y:x}=d,g=Math.abs(l-e.x)+Math.abs(f-e.y),p=Math.abs(y-n.x)+Math.abs(x-n.y);if(W(e.x,e.y,l,f,s,a)||W(n.x,n.y,y,x,r,a))return 1/0;if(void 0===o&&(T(y,x,r,a)||T(y,x,s,a)))return 1/0;const b=void 0===o?i>>1:function(t,e,n,i,o,r){const s=t>>1;return s===e>>1&&(1&t?1:-1)==-(1&e?1:-1)?s:Math.abs(o-n)>=Math.abs(r-i)?0:1}(i,o,l,f,y,x),M=y-l,m=x-f;if(t.length=0,t.push(e.x,e.y,l,f),(!h||z(i,g,M,m,b)&&z(o,p,-M,-m,b))&&z(c,1,-M,-m,b)){const e=(l+y)/2,i=(f+x)/2;0===b?t.push(e,f,e,x):t.push(l,i,y,i),t.push(y,x,n.x,n.y);for(let e=4;e<t.length-2;e+=2)if(W(t[e-2],t[e-1],t[e],t[e+1],r,a)||W(t[e-2],t[e-1],t[e],t[e+1],s,a)){t.length=4;break}if(t.length>4&&H(t,c))return function(t,e){let n=0,i=0,o=-1;for(let e=2;e<t.length;e+=2){const r=t[e]-t[e-2],s=t[e+1]-t[e-1];if(Math.abs(r)<=E&&Math.abs(s)<=E)continue;const a=Math.abs(r)>E?0:1;n+=Math.abs(r)+Math.abs(s),-1!==o&&o!==a&&i++,o=a}return n+i*Math.max(e,4)*1.5}(t,a);t.length=4}const N=function(t,e,n,i,o,r,s,a,h,c,u,d,l){const{x:f,y:y}=e,{x:x,y:g}=n,p=2*Math.max(a,4),b=[f,x,(f+x)/2],M=[y,g,(y+g)/2];q(b,M,r,a,p),q(b,M,s,a,p),b.push(Math.min(...b)-2*p,Math.max(...b)+2*p),M.push(Math.min(...M)-2*p,Math.max(...M)+2*p),I(b),I(M);const m=b.length,N=M.length,P=A(b,f),k=A(M,y),L=A(b,x),v=A(M,g);if(P<0||k<0||L<0||v<0)return 1/0;const C=k*m+P,_=v*m+L,w=m*N*3,D=new Float64Array(w),F=new Int32Array(w),B=new Uint8Array(w);D.fill(1/0),F.fill(-1);const O=3*C;D[O]=0;const S=[O],z=Math.max(4,a*R),H=0===h?(f+x)/2:(y+g)/2;let U=-1,X=-1,Y=0,Z=0,G=0,J=0;const K=(t,e,n)=>{const h=b[t],f=M[e],y=e*m+t,x=h-Z,g=f-G;if(y===C)return;if(void 0!==l&&y===_&&!j(l,1,-x,-g))return;if(d&&(U===O&&!j(i,c,x,g)||void 0!==o&&y===_&&!j(o,u,-x,-g)))return;if(T(h,f,r,a)||T(h,f,s,a)||W(Z,G,h,f,r,a)||W(Z,G,h,f,s,a))return;const p=3*y+n;if(B[p])return;let N=J+(Math.abs(x)+Math.abs(g));if(Y&&Y!==n){N+=z;const t=1===Y?Z:G;Math.abs(t-H)>E&&(N+=2*z)}N<D[p]&&(D[p]===1/0&&S.push(p),D[p]=N,F[p]=U)};let Q=-1;for(;S.length;){let t=0,e=S[0];for(let n=1;n<S.length;n++){const i=S[n];(D[i]<D[e]||D[i]===D[e]&&i<e)&&(t=n,e=i)}if(S[t]=S[S.length-1],S.pop(),U=e,X=Math.floor(e/3),Y=e%3,J=D[e],B[e]=1,X===_){Q=e;break}const n=X%m,i=Math.floor(X/m);Z=b[n],G=M[i],n>0&&K(n-1,i,1),n<m-1&&K(n+1,i,1),i>0&&K(n,i-1,2),i<N-1&&K(n,i+1,2)}if(Q<0)return 1/0;const V=[];let $=Q;for(;$>=0;){const t=Math.floor($/3);if(V.push(b[t%m],M[Math.floor(t/m)]),$===O)break;$=F[$]}if($!==O)return 1/0;for(let e=V.length-4;e>=0;e-=2)t.push(V[e],V[e+1]);return D[Q]}(t,u,d,i,o,r,s,a,b,g,p,h,c);return N===1/0?N:(t.push(n.x,n.y),H(t,c)?N+g+p:1/0)}function X(t,e,n,i,o,r,s,a){const h=O(n,t,e,o,void 0===i?void 0:r),c=void 0===i?[void 0]:O(i,e,t,r,o);let u=[],d=[],l=1/0;for(let n=s?0:1;n<3&&!d.length;n++){const i=n?0:s;for(let s=0;s<h.length;s++)for(let f=0;f<c.length;f++){const y=U(u,t,e,h[s],c[f],o,r,i,n<2,a);if(y<l){l=y;const t=d;d=u,u=t}}}if(!d.length)return function(t,e,n,i,o){const{x:r,y:s}=t,{x:a,y:h}=e;if(r===a||s===h)return[r,s,a,h];const c=!(n>>1),u=(t,e)=>{let n=0;return W(r,s,t,e,i,0)&&n++,W(t,e,a,h,i,0)&&n++,W(r,s,t,e,o,0)&&n++,W(t,e,a,h,o,0)&&n++,n},d=u(a,s),l=u(r,h);return d<l||d===l&&c?[r,s,a,s,a,h]:[r,s,r,h,a,h]}(t,e,h[0],o,r);!function(t){let e=2;for(let n=2;n<t.length;n+=2){const i=t[n],o=t[n+1],r=t[e-2],s=t[e-1];if(!(Math.abs(i-r)<=E&&Math.abs(o-s)<=E)){if(e>=4){const n=t[e-4],a=t[e-3],h=Math.abs(a-s)<=E&&Math.abs(s-o)<=E&&(r-n)*(i-r)>=0,c=Math.abs(n-r)<=E&&Math.abs(r-i)<=E&&(s-a)*(o-s)>=0;if(h||c){t[e-2]=i,t[e-1]=o;continue}}t[e++]=i,t[e++]=o}}t.length=e}(d);const f=d.length-2;return d[f]===e.x&&d[f+1]===e.y||d.push(e.x,e.y),d}function Y(t,e,n,i,o,r,s,a,h){if(t.x===e.x&&t.y===e.y)return[];let c;for(let t=a+h;t>=0&&t<s.length;t+=h){const n=s[t]-e.x,i=s[t+1]-e.y;if(!(Math.abs(n)<=E&&Math.abs(i)<=E)){Math.abs(i)<=E?c=n>0?0:1:Math.abs(n)<=E&&(c=i>0?2:3);break}}const u=X(t,e,n,void 0,i,o,r,c);return u.length-=2,u}function Z(t,e,n,i,o,r,s,a=8,h){if(!(Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(n.x)&&Number.isFinite(n.y)))return!1;if(r&&(!Number.isFinite(r.x)||!Number.isFinite(r.y)||!Number.isFinite(r.width)||!Number.isFinite(r.height)||r.width<0||r.height<0))return!1;if(s&&(!Number.isFinite(s.x)||!Number.isFinite(s.y)||!Number.isFinite(s.width)||!Number.isFinite(s.height)||s.width<0||s.height<0))return!1;if(a=Number.isFinite(a)?Math.max(0,a):8,null==h?void 0:h.length)return function(t,e,n,i,o,r,s,a,h){const c=h.length,u=c-2;if(c%2)return!1;for(let t=0;t<c;t++)if(!Number.isFinite(h[t]))return!1;const d=Y(e,{x:h[0],y:h[1]},i,r,s,a,h,0,2),l=Y(n,{x:h[u],y:h[u+1]},o,s,r,a,h,u,-2),f=d.length?d:h;F(t,f[0],f[1]);for(let e=2;e<d.length;e+=2)B(t,d[e],d[e+1]);for(let e=d.length?0:2;e<c;e+=2)B(t,h[e],h[e+1]);for(let e=l.length-2;e>=0;e-=2)B(t,l[e],l[e+1]);return!0}(t,e,n,i,o,r,s,a,h);const c=X(e,n,i,o,r,s,a);F(t,c[0],c[1]);for(let e=2;e<c.length;e+=2)B(t,c[e],c[e+1]);return!0}const{moveTo:G,lineTo:J,bezierCurveTo:K,drawPoints:Q}=c,{isEmpty:V,getPoint:$}=o,{getDistance:tt}=n,{getCtrlPoint:et,getDirectionForFromPoint:nt,isOppositeDirection:it}=_,{max:ot,min:rt,abs:st}=Math;let at=class extends y{get __tag(){return"Linker"}constructor(t){super(t),this.onStartNodeChange=this.onStartNodeChange.bind(this),this.onEndNodeChange=this.onEndNodeChange.bind(this)}__updatePath(){const t=this.__layout,{startNode:e,endNode:n}=this;t.linkerChanged&&(this.updateLinkerNode("start"),this.updateLinkerNode("end"),this.updateLinkerPoint("start"),this.updateLinkerPoint("end"),e!==this.startNode&&this.listenLinkerNode(this.startNode,e,"start"),n!==this.endNode&&this.listenLinkerNode(this.endNode,n,"end"),t.linkerChanged=!1),this.updateLinkerPath()}listenLinkerNode(t,e,n){if(e){e.off(x.WORLD,"end"===n?this.onEndNodeChange:this.onStartNodeChange);const t="end"===n?e.endLinker:e.startLinker;if(t){const e=t.indexOf(this);e>-1&&t.splice(e,1)}}if(t){t.on(x.WORLD,"end"===n?this.onEndNodeChange:this.onStartNodeChange);("end"===n?t.endLinker||(t.endLinker=[]):t.startLinker||(t.startLinker=[])).push(this)}}onStartNodeChange(){this.onLinkerNodeChange("start")}onEndNodeChange(){this.onLinkerNodeChange("end")}onLinkerNodeChange(t){if(this.leaferIsCreated){const{layouter:t,zoomLayer:e}=this.leafer;if(t.__updatedList.has(e))return;t.addExtra(this,!0)}const{startData:e,endData:n}=this;"start"==t?(this.updateLinkerPoint("start"),n&&n.auto&&this.updateLinkerPoint("end")):(e&&e.auto&&this.updateLinkerPoint("start"),this.updateLinkerPoint("end")),this.__layout.boxChange(),g.updateBounds(this)}updateLinkerNode(t){const{startPoint:e,endPoint:n}=this,i="end"===t?n:e;if(i){const{id:e}=i,n=e&&(p(e)?this.app.findId(e):e);"end"===t?this.endNode=n:this.startNode=n}}getLinkerNodeCenter(t){const{startPoint:e,endPoint:n,startNode:i,endNode:o,startData:r,endData:s}=this,a="end"===t?o:i,h="end"===t?s||n:r||e;if(a){const{worldRenderBounds:t}=a;return V(t)&&g.updateBounds(a),$(a.worldRenderBounds,"center")}return h&&b(h.point)&&this.getWorldPointByLocal(h.point)}updateLinkerPoint(t){const{startPoint:e,endPoint:i,lineType:o}=this,r="end"===t?i:e;if(r){const e={},{id:i,offset:s}=r;let{direction:a,point:h}=r;if("center"===a||!a&&i&&!h){const n=this.getLinkerNodeCenter("start"),i=this.getLinkerNodeCenter("end"),o="end"===t?i:n,r="end"===t?n:i;o&&r&&(a=nt(o,r)),e.auto=!0}!a&&p(h)&&(a=h),e.direction=a;const c="end"===t?this.endNode:this.startNode;let u;if(c){if(h||(h=a),h){const{boxBounds:t}=c;V(t)&&g.updateBounds(c),u=$(t,h,!0),c.getWorldPointByBox(u,this,!1,!0),"polyline"===o&&(e.bounds=c.getBounds("box",this.parent))}}else b(h)&&(u=h);if(u&&s){const t=Object.assign({},s);s.x||(t.x=0),s.y||(t.y=0),c&&c.getWorldPoint(t,this,!0,!0),n.move(u,t)}e.point=u,"end"===t?this.endData=u&&e:this.startData=u&&e}}updateLinkerPath(){const t=this.__,e=t.path=[],i=t.points&&t.points.length,{startData:o,endData:r,startNode:s,endNode:a}=this;if(!o||!r)return;const h=o.point,c=r.point,u=o.direction,d=r.direction,l=8*this.__.strokeWidth;switch(t.lineType){case"straight":G(e,h.x,h.y),J(e,c.x,c.y);break;case"polyline":Z(e,h,c,u,d,o.bounds,r.bounds,l,i&&n.toNumberPoints(t.points));break;default:const f={x:st((h.x-c.x)/2),y:st((h.y-c.y)/2)};let y;if(this.__.__useArrow){const t=rt(tt(h,c)/(25*l),1);y=ot(l*t*12,3*l)}else y=2*l;if(d&&it(u,d)&&u===nt(h,c)&&(y=2*l),f.x=ot(y,f.x),f.y=ot(y,f.y),i){y*=.6;const i=n.toNumberPoints(t.points);if(Q(e,[h.x,h.y,...i,c.x,c.y],t.curve,!1,t),u){const t=e[4],n=e[5];f.x=ot(y,st(t-h.x)),f.y=ot(y,st(n-h.y));const i=et(this,s,h,u,f);e[4]=i.x,e[5]=i.y}const o=e.length;if(d){const t=e[o-4],n=e[o-3];f.x=ot(y,st(t-c.x)),f.y=ot(y,st(n-c.y));const i=et(this,a,c,d,f);e[o-4]=i.x,e[o-3]=i.y}else e[o-4]=c.x,e[o-3]=c.y}else{const t=u?et(this,s,h,u,f):h,n=d?et(this,a,c,d,f):c;G(e,h.x,h.y),K(e,t.x,t.y,n.x,n.y,c.x,c.y)}}}createStartPoint(t,e,n){const i=this.createLinkerPoint(t,e,n);return this.startPoint=i,i}createEndPoint(t,e,n){const i=this.createLinkerPoint(t,e,n);return this.endPoint=i,i}createLinkerPoint(t,e,n){const i={};if(e&&e.id){const r=e.getBoxPoint(t),{boxBounds:s}=e,a=n&&n.mode,h="edge"===a||!a,c="four"===a,u="free"===a;if(!("auto"===a))if(c)i.point=_.getDirection(r,s,c);else if(i.direction=_.getDirection(r,s,h),i.point=_.getPointDirection(r,s,h)||i.direction,i.point===i.direction&&delete i.direction,u||h){const t=o.getPoint(s,i.point),e=r.x-t.x,a=r.y-t.y,c=n&&n.snapRadius||10;if(Math.abs(e)>c||Math.abs(a)>c){const t=i.offset={x:Math.abs(e)>c?e:0,y:Math.abs(a)>c?a:0};if(h&&(t.x||t.y))switch(i.direction||i.point){case"top":case"bottom":t.y=0;break;case"right":case"left":t.x=0;break;default:t.x>t.y?t.y=0:t.x=0}}}i.id=e.id}else i.point=this.getLocalPoint(t);return i}};k([u(L)],at.prototype,"__",void 0),k([d("curve")],at.prototype,"lineType",void 0),k([w()],at.prototype,"startPoint",void 0),k([w()],at.prototype,"endPoint",void 0),k([l({type:"C",value:.5})],at.prototype,"curve",void 0),at=k([f()],at);const{toNumberPoints:ht}=N,{M:ct,L:ut,C:dt,Z:lt}=P;M.add("linker"),m("C",function(t,e,n,i){const o=ht(e),r=o.length>>1;if(r<2)return;if(t.push(ct,o[0],o[1]),!n||r<3){for(let e=1;e<r;e++)t.push(ut,o[2*e],o[2*e+1]);return void(i&&t.push(lt))}let s=!0===n?.5:n;s<0?s=0:s>1&&(s=1);const a=i?r:r-1;let h=o[0],c=o[1];{const t=o[2]-o[0],e=o[3]-o[1],n=Math.sqrt(t*t+e*e);n&&(h=o[0]+t/n*n*s,c=o[1]+e/n*n*s)}for(let e=0;e<a;e++){const n=e+1===r?0:e+1,i=o[2*n],a=o[2*n+1],u=0===n?r-1:n-1,d=n+1===r?0:n+1;let l=o[2*u]-i,f=o[2*u+1]-a,y=o[2*d]-i,x=o[2*d+1]-a;const g=Math.sqrt(l*l+f*f),p=Math.sqrt(y*y+x*x);let b=i,M=a,m=i,N=a;if(g||p){let t=0,e=0;g&&(t+=l/g,e+=f/g),p&&(t+=y/p,e+=x/p);let n=Math.sqrt(t*t+e*e);n||(p?(t=y/p,e=x/p):(t=l/g,e=f/g),n=1),t/=n,e/=n;let o=-e,r=t;p&&o*y+r*x<0&&(o=-o,r=-r);let h=0;g&&p&&(h=(l*y+f*x)/(g*p),h>1?h=1:h<-1&&(h=-1));let c=Math.sqrt(Math.sqrt(Math.max(0,1-h*h)));c<.15&&(c=.15);let u=g*s*c,d=p*s*c;const P=.5*Math.min(g||p,p||g);u>P&&(u=P),d>P&&(d=P),b=i-o*u,M=a-r*u,m=i+o*d,N=a+r*d}t.push(dt,h,c,b,M,i,a),h=m,c=N}i&&t.push(lt)});export{at as Linker,L as LinkerData};
2
2
  //# sourceMappingURL=linker.esm.min.js.map