stickyflow 0.5.0 → 0.6.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/binding/index.cjs +9 -9
  3. package/dist/binding/index.d.cts +4 -4
  4. package/dist/binding/index.d.ts +4 -4
  5. package/dist/binding/index.js +3 -3
  6. package/dist/{chunk-IEHE6WVN.js → chunk-4G2R7PEL.js} +319 -45
  7. package/dist/chunk-4G2R7PEL.js.map +1 -0
  8. package/dist/{chunk-L3VJXZFD.cjs → chunk-4LENHH6C.cjs} +15 -15
  9. package/dist/{chunk-L3VJXZFD.cjs.map → chunk-4LENHH6C.cjs.map} +1 -1
  10. package/dist/{chunk-LTGF5OHP.js → chunk-FVHVOJS2.js} +395 -89
  11. package/dist/chunk-FVHVOJS2.js.map +1 -0
  12. package/dist/{chunk-TWDLOXRM.cjs → chunk-JIJMZMGY.cjs} +18 -18
  13. package/dist/{chunk-TWDLOXRM.cjs.map → chunk-JIJMZMGY.cjs.map} +1 -1
  14. package/dist/{chunk-VK3T6O5Z.cjs → chunk-KTNCDNDB.cjs} +33 -33
  15. package/dist/{chunk-VK3T6O5Z.cjs.map → chunk-KTNCDNDB.cjs.map} +1 -1
  16. package/dist/{chunk-BODZN3ZI.js → chunk-MFNUJA26.js} +4 -4
  17. package/dist/{chunk-BODZN3ZI.js.map → chunk-MFNUJA26.js.map} +1 -1
  18. package/dist/{chunk-7VW2XKVB.js → chunk-ULQZ6CZW.js} +3 -3
  19. package/dist/{chunk-7VW2XKVB.js.map → chunk-ULQZ6CZW.js.map} +1 -1
  20. package/dist/{chunk-ZMLQIMJK.cjs → chunk-WQRT5PVT.cjs} +993 -687
  21. package/dist/chunk-WQRT5PVT.cjs.map +1 -0
  22. package/dist/{chunk-G7NRK5AG.js → chunk-WRDVNMFS.js} +5 -5
  23. package/dist/{chunk-G7NRK5AG.js.map → chunk-WRDVNMFS.js.map} +1 -1
  24. package/dist/{chunk-XY2GZUHC.cjs → chunk-XJ4W6TW4.cjs} +326 -44
  25. package/dist/chunk-XJ4W6TW4.cjs.map +1 -0
  26. package/dist/index.cjs +49 -29
  27. package/dist/index.d.cts +52 -7
  28. package/dist/index.d.ts +52 -7
  29. package/dist/index.js +5 -5
  30. package/dist/interaction/index.cjs +245 -235
  31. package/dist/interaction/index.cjs.map +1 -1
  32. package/dist/interaction/index.d.cts +3 -2
  33. package/dist/interaction/index.d.ts +3 -2
  34. package/dist/interaction/index.js +17 -7
  35. package/dist/interaction/index.js.map +1 -1
  36. package/dist/{render-CgX_y15a.d.ts → render-Db0eSz_s.d.cts} +36 -15
  37. package/dist/{render-CgX_y15a.d.cts → render-Db0eSz_s.d.ts} +36 -15
  38. package/dist/{runtime-reWgr7MP.d.cts → runtime-BhivvBeL.d.cts} +2 -2
  39. package/dist/{runtime-DnUxca3Y.d.ts → runtime-n2yG-_j-.d.ts} +2 -2
  40. package/dist/{runtimeTypes-D60w6nyF.d.cts → runtimeTypes-CrkMHvVi.d.cts} +2 -2
  41. package/dist/{runtimeTypes-CEBGueYM.d.ts → runtimeTypes-DnI7mRF5.d.ts} +2 -2
  42. package/dist/stickyflow-diagram.global.js +35 -35
  43. package/dist/stickyflow-diagram.global.js.map +1 -1
  44. package/dist/{types-DvhMpqrL.d.cts → types-BHfUKT4s.d.cts} +1 -1
  45. package/dist/{types-DYLC_lsk.d.ts → types-D4cH4f1a.d.ts} +1 -1
  46. package/dist/viewer/index.cjs +9 -9
  47. package/dist/viewer/index.d.cts +4 -4
  48. package/dist/viewer/index.d.ts +4 -4
  49. package/dist/viewer/index.js +4 -4
  50. package/dist/web-component/index.cjs +6 -6
  51. package/dist/web-component/index.d.cts +2 -2
  52. package/dist/web-component/index.d.ts +2 -2
  53. package/dist/web-component/index.js +4 -4
  54. package/package.json +1 -1
  55. package/dist/chunk-IEHE6WVN.js.map +0 -1
  56. package/dist/chunk-LTGF5OHP.js.map +0 -1
  57. package/dist/chunk-XY2GZUHC.cjs.map +0 -1
  58. package/dist/chunk-ZMLQIMJK.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -17,6 +17,22 @@ Two things count as breaking here that are easy to overlook:
17
17
 
18
18
  ## [Unreleased]
19
19
 
20
+ ## [0.6.0] - 2026-10-22
21
+
22
+ ### Added
23
+
24
+ - An `Isometric` block takes a `symbol`. The outline of the `Symbol` is extruded by the height, and every wall that faces the viewer is shaded on its own. It works for any closed outline of three or more points that does not cross itself.
25
+ - `cornerRadius` in the style of an `Isometric` block rounds the vertical edges of the box or of an extruded symbol.
26
+ - `shape: sphere` draws an `Isometric` block as a shaded ball that sits in the center of its box.
27
+ - A point of a `Path` or a `Symbol` can carry a third value, its own tension. `0` makes the point a corner, so one outline can mix corners and curves. A point without one takes the `tension` of the whole path.
28
+ - `pathToSymbol()` turns a `Path` into a `Symbol`, and `symbolToPath()` turns it back. `pathBounds()` and `flattenPath()` give the box of a path and the points of its curve as short straight edges. The types `PathFrame`, `PathPoint` and `PathSymbol` are exported.
29
+ - The `Dimension` block draws a measure line with an arrow at each end, extension lines and a label. `start` and `end` are the two measured points, and `offset` is the distance of the line, positive to the left of the direction. Without `text` the label is the measured length, rounded to one decimal place, followed by `unit`. `isDimensionObject()` and the types `Dimension` and `SflDimensionObject` are exported, and `RenderInput` takes `dimensions`.
30
+
31
+ ### Changed
32
+
33
+ - Moving a path through `applyMoveChange` keeps the tension of its points.
34
+ - An `Isometric` block with a `symbol` that has curved points uses the curve as many short straight edges.
35
+
20
36
  ## [0.5.0] - 2026-10-18
21
37
 
22
38
  ### Added
@@ -1,34 +1,34 @@
1
1
  'use strict';
2
2
 
3
- var chunkTWDLOXRM_cjs = require('../chunk-TWDLOXRM.cjs');
4
- require('../chunk-ZMLQIMJK.cjs');
5
- require('../chunk-XY2GZUHC.cjs');
3
+ var chunkJIJMZMGY_cjs = require('../chunk-JIJMZMGY.cjs');
4
+ require('../chunk-WQRT5PVT.cjs');
5
+ require('../chunk-XJ4W6TW4.cjs');
6
6
 
7
7
 
8
8
 
9
9
  Object.defineProperty(exports, "buildBindingGraph", {
10
10
  enumerable: true,
11
- get: function () { return chunkTWDLOXRM_cjs.buildBindingGraph; }
11
+ get: function () { return chunkJIJMZMGY_cjs.buildBindingGraph; }
12
12
  });
13
13
  Object.defineProperty(exports, "collectContracts", {
14
14
  enumerable: true,
15
- get: function () { return chunkTWDLOXRM_cjs.collectContracts; }
15
+ get: function () { return chunkJIJMZMGY_cjs.collectContracts; }
16
16
  });
17
17
  Object.defineProperty(exports, "createBindingRuntime", {
18
18
  enumerable: true,
19
- get: function () { return chunkTWDLOXRM_cjs.createBindingRuntime; }
19
+ get: function () { return chunkJIJMZMGY_cjs.createBindingRuntime; }
20
20
  });
21
21
  Object.defineProperty(exports, "createDataSource", {
22
22
  enumerable: true,
23
- get: function () { return chunkTWDLOXRM_cjs.createDataSource; }
23
+ get: function () { return chunkJIJMZMGY_cjs.createDataSource; }
24
24
  });
25
25
  Object.defineProperty(exports, "interactiveElements", {
26
26
  enumerable: true,
27
- get: function () { return chunkTWDLOXRM_cjs.interactiveElements; }
27
+ get: function () { return chunkJIJMZMGY_cjs.interactiveElements; }
28
28
  });
29
29
  Object.defineProperty(exports, "renderBound", {
30
30
  enumerable: true,
31
- get: function () { return chunkTWDLOXRM_cjs.renderBound; }
31
+ get: function () { return chunkJIJMZMGY_cjs.renderBound; }
32
32
  });
33
33
  //# sourceMappingURL=index.cjs.map
34
34
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
- import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-D60w6nyF.cjs';
2
- export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-D60w6nyF.cjs';
3
- export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-reWgr7MP.cjs';
4
- import '../render-CgX_y15a.cjs';
1
+ import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-CrkMHvVi.cjs';
2
+ export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-CrkMHvVi.cjs';
3
+ export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-BhivvBeL.cjs';
4
+ import '../render-Db0eSz_s.cjs';
5
5
 
6
6
  declare function collectContracts(sflDocument: SflDocument): {
7
7
  contracts: Map<string, DataSourceContract>;
@@ -1,7 +1,7 @@
1
- import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-CEBGueYM.js';
2
- export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-CEBGueYM.js';
3
- export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-DnUxca3Y.js';
4
- import '../render-CgX_y15a.js';
1
+ import { S as SflDocument, D as DataSourceContract, B as BindingDiagnostic } from '../runtimeTypes-DnI7mRF5.js';
2
+ export { a as BindingGraph, b as BindingRuntime, c as BindingRuntimeOptions, d as BindingTarget, e as BindingType, f as BindingValue, g as BoundAssignment, h as BoundHandler, i as BoundProperty, j as DataSource, E as ElementInfo, k as ElementState, I as InteractiveElements, M as MutableDataSource, l as buildBindingGraph, m as createDataSource, n as interactiveElements } from '../runtimeTypes-DnI7mRF5.js';
3
+ export { R as RenderBoundOptions, c as createBindingRuntime, r as renderBound } from '../runtime-n2yG-_j-.js';
4
+ import '../render-Db0eSz_s.js';
5
5
 
6
6
  declare function collectContracts(sflDocument: SflDocument): {
7
7
  contracts: Map<string, DataSourceContract>;
@@ -1,5 +1,5 @@
1
- export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound } from '../chunk-BODZN3ZI.js';
2
- import '../chunk-LTGF5OHP.js';
3
- import '../chunk-IEHE6WVN.js';
1
+ export { buildBindingGraph, collectContracts, createBindingRuntime, createDataSource, interactiveElements, renderBound } from '../chunk-MFNUJA26.js';
2
+ import '../chunk-FVHVOJS2.js';
3
+ import '../chunk-4G2R7PEL.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -80,6 +80,115 @@ function isometricFaces(object) {
80
80
  };
81
81
  }
82
82
 
83
+ // src/model/isometricObject/footprint.ts
84
+ function signedArea(points) {
85
+ let sum = 0;
86
+ for (let i = 0; i < points.length; i += 1) {
87
+ const [x1, y1] = points[i];
88
+ const [x2, y2] = points[(i + 1) % points.length];
89
+ sum += x1 * y2 - x2 * y1;
90
+ }
91
+ return sum / 2;
92
+ }
93
+ function cleanFootprint(points) {
94
+ const clean = (points ?? []).filter(
95
+ (point) => Array.isArray(point) && Number.isFinite(point[0]) && Number.isFinite(point[1])
96
+ );
97
+ const unique = clean.filter((point, index) => {
98
+ const next = clean[(index + 1) % clean.length];
99
+ return point[0] !== next[0] || point[1] !== next[1];
100
+ });
101
+ return unique.length >= 3 ? unique : [];
102
+ }
103
+ var ARC_STEP = Math.PI / 12;
104
+ function roundFootprint(points, radius, width, depth) {
105
+ if (!(radius > 0) || width <= 0 || depth <= 0) {
106
+ return [...points];
107
+ }
108
+ const world = points.map(([u, v]) => ({ x: u * width, y: v * depth }));
109
+ const rounded = [];
110
+ for (let i = 0; i < world.length; i += 1) {
111
+ const here = world[i];
112
+ const before = world[(i - 1 + world.length) % world.length];
113
+ const after = world[(i + 1) % world.length];
114
+ const a = { x: before.x - here.x, y: before.y - here.y };
115
+ const b = { x: after.x - here.x, y: after.y - here.y };
116
+ const lengthA = Math.hypot(a.x, a.y);
117
+ const lengthB = Math.hypot(b.x, b.y);
118
+ const cos = (a.x * b.x + a.y * b.y) / (lengthA * lengthB);
119
+ const angle = Math.acos(Math.max(-1, Math.min(1, cos)));
120
+ if (!Number.isFinite(angle) || angle < 1e-3 || Math.PI - angle < 1e-3) {
121
+ rounded.push(points[i]);
122
+ continue;
123
+ }
124
+ const reach = Math.min(radius / Math.tan(angle / 2), Math.min(lengthA, lengthB) / 2);
125
+ const effective = reach * Math.tan(angle / 2);
126
+ const unitA = { x: a.x / lengthA, y: a.y / lengthA };
127
+ const unitB = { x: b.x / lengthB, y: b.y / lengthB };
128
+ const from = { x: here.x + unitA.x * reach, y: here.y + unitA.y * reach };
129
+ const to = { x: here.x + unitB.x * reach, y: here.y + unitB.y * reach };
130
+ const bisector = { x: unitA.x + unitB.x, y: unitA.y + unitB.y };
131
+ const bisectorLength = Math.hypot(bisector.x, bisector.y);
132
+ const centerDistance = effective / Math.sin(angle / 2);
133
+ const center = {
134
+ x: here.x + bisector.x / bisectorLength * centerDistance,
135
+ y: here.y + bisector.y / bisectorLength * centerDistance
136
+ };
137
+ const start = Math.atan2(from.y - center.y, from.x - center.x);
138
+ let sweep = Math.atan2(to.y - center.y, to.x - center.x) - start;
139
+ sweep -= 2 * Math.PI * Math.round(sweep / (2 * Math.PI));
140
+ const steps = Math.max(2, Math.ceil(Math.abs(sweep) / ARC_STEP));
141
+ for (let step = 0; step <= steps; step += 1) {
142
+ const t = start + sweep * step / steps;
143
+ rounded.push([(center.x + effective * Math.cos(t)) / width, (center.y + effective * Math.sin(t)) / depth]);
144
+ }
145
+ }
146
+ return rounded;
147
+ }
148
+ function extrudeFootprint(frame, footprint, cornerRadius = 0) {
149
+ const width = Math.max(0, frame.width);
150
+ const depth = Math.max(0, frame.depth);
151
+ const height = Math.max(0, frame.height);
152
+ const points = roundFootprint(cleanFootprint(footprint), cornerRadius, width, depth);
153
+ const apexX = frame.x + depth * AXIS_COS;
154
+ const project = ([u, v], z) => ({
155
+ x: apexX + (u * width - v * depth) * AXIS_COS,
156
+ y: frame.y + (u * width + v * depth) * AXIS_SIN + z
157
+ });
158
+ const top = points.map((point) => project(point, 0));
159
+ const turn = signedArea(points) >= 0 ? 1 : -1;
160
+ const edges = points.map((from, i) => {
161
+ const to = points[(i + 1) % points.length];
162
+ const edgeU = (to[0] - from[0]) * width;
163
+ const edgeV = (to[1] - from[1]) * depth;
164
+ const length = Math.hypot(edgeU, edgeV);
165
+ const normalU = length === 0 ? 0 : edgeV / length * turn;
166
+ const normalV = length === 0 ? 0 : -edgeU / length * turn;
167
+ return { from, to, length, normalU, normalV, visible: length > 0 && normalU + normalV > 1e-9 };
168
+ });
169
+ const sameWay = (a, b) => {
170
+ return a.visible && b.visible && a.normalU * b.normalU + a.normalV * b.normalV > Math.cos(0.5);
171
+ };
172
+ const sides = [];
173
+ edges.forEach((edge, i) => {
174
+ if (!edge.visible) {
175
+ return;
176
+ }
177
+ const before = edges[(i - 1 + edges.length) % edges.length];
178
+ const after = edges[(i + 1) % edges.length];
179
+ const { from, to } = edge;
180
+ sides.push({
181
+ points: [project(from, 0), project(to, 0), project(to, height), project(from, height)],
182
+ light: 0.72 + 0.28 * Math.max(0, Math.min(1, edge.normalV / (Math.abs(edge.normalU) + Math.abs(edge.normalV)))),
183
+ depth: (from[0] + to[0]) / 2 + (from[1] + to[1]) / 2,
184
+ smoothStart: sameWay(before, edge),
185
+ smoothEnd: sameWay(edge, after)
186
+ });
187
+ });
188
+ sides.sort((a, b) => a.depth - b.depth);
189
+ return { top, sides };
190
+ }
191
+
83
192
  // src/model/isometricObject/shading.ts
84
193
  function clamp255(value) {
85
194
  return Math.max(0, Math.min(255, Math.round(value)));
@@ -103,6 +212,9 @@ function multiply(hex, factor) {
103
212
  const [r, g, b] = rgb;
104
213
  return rgbToHex(r * factor, g * factor, b * factor);
105
214
  }
215
+ function shadeFill(fill, factor) {
216
+ return multiply(fill, factor);
217
+ }
106
218
  function deriveFaceFills(fill) {
107
219
  return {
108
220
  topFill: fill,
@@ -111,6 +223,102 @@ function deriveFaceFills(fill) {
111
223
  };
112
224
  }
113
225
 
226
+ // src/model/path/curve.ts
227
+ var SAMPLES_PER_SEGMENT = 8;
228
+ function pointTension(curve, point) {
229
+ return Math.max(0, point.tension ?? curve.tension);
230
+ }
231
+ function isStraight(curve) {
232
+ return curve.points.length < 3 || curve.points.every((point) => pointTension(curve, point) <= 0);
233
+ }
234
+ function pointAt(curve, index) {
235
+ const { points } = curve;
236
+ if (curve.closed) {
237
+ return points[(index + points.length) % points.length];
238
+ }
239
+ return points[Math.max(0, Math.min(points.length - 1, index))];
240
+ }
241
+ function pathSegments(curve) {
242
+ const count = curve.closed ? curve.points.length : curve.points.length - 1;
243
+ return Array.from({ length: Math.max(0, count) }, (_, index) => {
244
+ const previous = pointAt(curve, index - 1);
245
+ const from = pointAt(curve, index);
246
+ const to = pointAt(curve, index + 1);
247
+ const next = pointAt(curve, index + 2);
248
+ const fromFactor = pointTension(curve, from) / 6;
249
+ const toFactor = pointTension(curve, to) / 6;
250
+ if (fromFactor === 0 && toFactor === 0) {
251
+ return { from, to, controls: null };
252
+ }
253
+ const first = { x: from.x + (to.x - previous.x) * fromFactor, y: from.y + (to.y - previous.y) * fromFactor };
254
+ const second = { x: to.x - (next.x - from.x) * toFactor, y: to.y - (next.y - from.y) * toFactor };
255
+ return { from, to, controls: [first, second] };
256
+ });
257
+ }
258
+ function bezierAt(segment, t) {
259
+ const { from, to, controls } = segment;
260
+ const u = 1 - t;
261
+ const weights = [u * u * u, 3 * u * u * t, 3 * u * t * t, t * t * t];
262
+ const anchors = [from, controls[0], controls[1], to];
263
+ return {
264
+ x: anchors.reduce((sum, anchor, i) => sum + anchor.x * weights[i], 0),
265
+ y: anchors.reduce((sum, anchor, i) => sum + anchor.y * weights[i], 0)
266
+ };
267
+ }
268
+ function flattenPath(curve, samples = SAMPLES_PER_SEGMENT) {
269
+ if (isStraight(curve)) {
270
+ return curve.points.map((point) => ({ x: point.x, y: point.y }));
271
+ }
272
+ const flat = [];
273
+ const segments = pathSegments(curve);
274
+ segments.forEach((segment) => {
275
+ flat.push({ x: segment.from.x, y: segment.from.y });
276
+ if (segment.controls) {
277
+ const curved = { ...segment, controls: segment.controls };
278
+ for (let step = 1; step < samples; step++) {
279
+ flat.push(bezierAt(curved, step / samples));
280
+ }
281
+ }
282
+ });
283
+ const last = segments[segments.length - 1];
284
+ if (!curve.closed && last) {
285
+ flat.push({ x: last.to.x, y: last.to.y });
286
+ }
287
+ return flat;
288
+ }
289
+
290
+ // src/model/path/symbol.ts
291
+ function pathBounds(points) {
292
+ const xs = points.map((point) => point.x);
293
+ const ys = points.map((point) => point.y);
294
+ const x = Math.min(...xs);
295
+ const y = Math.min(...ys);
296
+ return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y };
297
+ }
298
+ var round = (value) => Math.round(value * 1e4) / 1e4;
299
+ function pathToSymbol(points) {
300
+ if (points.length === 0) {
301
+ return { points: [], width: 0, height: 0 };
302
+ }
303
+ const frame = pathBounds(points);
304
+ const unit = (value, size) => size === 0 ? 0 : round(value / size);
305
+ return {
306
+ width: frame.width,
307
+ height: frame.height,
308
+ points: points.map((point) => {
309
+ const x = unit(point.x - frame.x, frame.width);
310
+ const y = unit(point.y - frame.y, frame.height);
311
+ return point.tension === void 0 ? [x, y] : [x, y, point.tension];
312
+ })
313
+ };
314
+ }
315
+ function symbolToPath(points, frame) {
316
+ return points.map((point) => {
317
+ const placed = { x: frame.x + point[0] * frame.width, y: frame.y + point[1] * frame.height };
318
+ return point[2] === void 0 ? placed : { ...placed, tension: point[2] };
319
+ });
320
+ }
321
+
114
322
  // src/model/component/supportedTypes.ts
115
323
  var BUILT_IN_COMPONENT_TYPES = ["rollingNumber", "tickScale", "ruler"];
116
324
  function isBuiltInComponentType(value) {
@@ -689,6 +897,7 @@ var NAMED_BLOCK_KINDS = [
689
897
  "Shape",
690
898
  "Text",
691
899
  "Isometric",
900
+ "Dimension",
692
901
  "Link",
693
902
  "Connection",
694
903
  "Layout",
@@ -1462,6 +1671,11 @@ function isChartObject(canvasObject) {
1462
1671
  return canvasObject.objectType === "chart" && canvasObject.chart !== void 0;
1463
1672
  }
1464
1673
 
1674
+ // src/sflSemantic/canvasObjects/artifacts/dimension/types.ts
1675
+ function isDimensionObject(canvasObject) {
1676
+ return canvasObject.objectType === "dimension" && canvasObject.dimension !== void 0;
1677
+ }
1678
+
1465
1679
  // src/sflSemantic/canvasObjects/artifacts/isometric/types.ts
1466
1680
  function isIsometricObject(canvasObject) {
1467
1681
  return canvasObject.objectType === "isometric" && canvasObject.isometric !== void 0;
@@ -1599,7 +1813,8 @@ var CANVAS_OBJECT_BLOCK_KINDS = [
1599
1813
  "Chart",
1600
1814
  "Widget",
1601
1815
  "Component",
1602
- "Isometric"
1816
+ "Isometric",
1817
+ "Dimension"
1603
1818
  ];
1604
1819
  var canvasObjectBlockKinds = new Set(CANVAS_OBJECT_BLOCK_KINDS);
1605
1820
  function isCanvasObjectBlockKind(kind) {
@@ -2005,21 +2220,77 @@ function resolveChartObject(base, block2, properties, symbolDefinitions, mergedP
2005
2220
  };
2006
2221
  }
2007
2222
 
2223
+ // src/sflSemantic/canvasObjects/artifacts/dimension/reader.ts
2224
+ function readPoint(value, origin) {
2225
+ const [x, y] = tupleValues(value) ?? [];
2226
+ return { x: origin.x + (x ?? 0), y: origin.y + (y ?? 0) };
2227
+ }
2228
+ function readDimension(properties, origin) {
2229
+ return {
2230
+ start: readPoint(properties.get("start"), origin),
2231
+ end: readPoint(properties.get("end"), origin),
2232
+ offset: asNumber(properties.get("offset")) ?? 0,
2233
+ unit: asString(properties.get("unit"))
2234
+ };
2235
+ }
2236
+
2237
+ // src/sflSemantic/canvasObjects/artifacts/dimension/resolver.ts
2238
+ function resolveDimensionObject(base, properties, origin) {
2239
+ return {
2240
+ ...base,
2241
+ objectType: "dimension",
2242
+ dimension: readDimension(properties, origin)
2243
+ };
2244
+ }
2245
+
2008
2246
  // src/sflSemantic/canvasObjects/artifacts/isometric/reader.ts
2009
- function readIsometric(properties, depth) {
2247
+ function readFootprintPoint(value) {
2248
+ if (value.type !== "list" || value.values.length < 2) {
2249
+ return [];
2250
+ }
2251
+ const x = asNumber(value.values[0]);
2252
+ const y = asNumber(value.values[1]);
2253
+ const tension = value.values[2] === void 0 ? void 0 : asNumber(value.values[2]);
2254
+ if (x === void 0 || y === void 0) {
2255
+ return [];
2256
+ }
2257
+ return [tension === void 0 ? { x, y } : { x, y, tension }];
2258
+ }
2259
+ function asPolygon(points, tension) {
2260
+ const flat = flattenPath({ points, tension, closed: true });
2261
+ return flat.length >= 3 ? flat.map((point) => [point.x, point.y]) : void 0;
2262
+ }
2263
+ function readFootprint(value, symbolDefs) {
2264
+ if (value?.type === "list") {
2265
+ return asPolygon(value.values.flatMap(readFootprintPoint), 0);
2266
+ }
2267
+ const name = asString(value);
2268
+ const definition = name ? symbolDefs.get(name) : void 0;
2269
+ if (!definition) {
2270
+ return void 0;
2271
+ }
2272
+ const points = definition.points.map(([x, y], index) => {
2273
+ const tension = definition.pointTensions?.[index];
2274
+ return tension === void 0 ? { x, y } : { x, y, tension };
2275
+ });
2276
+ return asPolygon(points, definition.tension ?? 0);
2277
+ }
2278
+ function readIsometric(properties, depth, symbolDefs) {
2010
2279
  return {
2011
2280
  depth,
2012
- icon: asString(properties.get("icon"))
2281
+ icon: asString(properties.get("icon")),
2282
+ footprint: readFootprint(properties.get("symbol"), symbolDefs),
2283
+ form: asString(properties.get("shape")) === "sphere" ? "sphere" : "box"
2013
2284
  };
2014
2285
  }
2015
2286
 
2016
2287
  // src/sflSemantic/canvasObjects/artifacts/isometric/resolver.ts
2017
- function resolveIsometricObject(base, block2, properties, layoutProperty) {
2288
+ function resolveIsometricObject(base, block2, properties, layoutProperty, symbolDefinitions) {
2018
2289
  const size = tupleValues(layoutProperty(block2, "size"));
2019
2290
  return {
2020
2291
  ...base,
2021
2292
  objectType: "isometric",
2022
- isometric: readIsometric(properties, size?.[2] ?? 24)
2293
+ isometric: readIsometric(properties, size?.[2] ?? 24, symbolDefinitions)
2023
2294
  };
2024
2295
  }
2025
2296
 
@@ -2032,7 +2303,12 @@ function readPath(p, origin) {
2032
2303
  }
2033
2304
  const x = asNumber(value.values[0]);
2034
2305
  const y = asNumber(value.values[1]);
2035
- return x !== void 0 && y !== void 0 ? [{ x: origin.x + x, y: origin.y + y }] : [];
2306
+ const tension = value.values[2] === void 0 ? void 0 : asNumber(value.values[2]);
2307
+ if (x === void 0 || y === void 0) {
2308
+ return [];
2309
+ }
2310
+ const point = { x: origin.x + x, y: origin.y + y };
2311
+ return [tension === void 0 ? point : { ...point, tension }];
2036
2312
  }) : [];
2037
2313
  return {
2038
2314
  points,
@@ -2099,6 +2375,9 @@ function declaredCanvasObjectKind(block2, properties) {
2099
2375
  if (block2.kind === "Isometric") {
2100
2376
  return "isometric";
2101
2377
  }
2378
+ if (block2.kind === "Dimension") {
2379
+ return "dimension";
2380
+ }
2102
2381
  return asString(properties.get("kind")) ?? "";
2103
2382
  }
2104
2383
  function canvasObjectTypeForKind(kind) {
@@ -2120,6 +2399,9 @@ function canvasObjectTypeForKind(kind) {
2120
2399
  if (kind === "isometric") {
2121
2400
  return "isometric";
2122
2401
  }
2402
+ if (kind === "dimension") {
2403
+ return "dimension";
2404
+ }
2123
2405
  return "shape";
2124
2406
  }
2125
2407
  function classifyCanvasObject(block2, properties, symbolDefinitions) {
@@ -2182,9 +2464,11 @@ function resolveCanvasObject(block2, origin, context, frameId, positionOverride)
2182
2464
  case "chart":
2183
2465
  return resolveChartObject(base, block2, properties, symbolDefs, mergedProps);
2184
2466
  case "isometric":
2185
- return resolveIsometricObject(base, block2, properties, layoutProp);
2467
+ return resolveIsometricObject(base, block2, properties, layoutProp, symbolDefs);
2186
2468
  case "path":
2187
2469
  return resolvePathObject(base, properties, origin);
2470
+ case "dimension":
2471
+ return resolveDimensionObject(base, properties, origin);
2188
2472
  case "swimlane":
2189
2473
  return resolveSwimlaneObject(base, properties);
2190
2474
  case "frame":
@@ -2340,17 +2624,24 @@ function readShaderDefinition(block2) {
2340
2624
  // src/sflSemantic/definitions/symbols.ts
2341
2625
  function readSymbolPoints(block2) {
2342
2626
  const value = directProperties(block2).get("points");
2627
+ const points = [];
2628
+ const tensions = [];
2343
2629
  if (value?.type !== "list") {
2344
- return [];
2630
+ return { points, tensions };
2345
2631
  }
2346
- return value.values.flatMap((item) => {
2632
+ for (const item of value.values) {
2347
2633
  if (item.type !== "list" || item.values.length < 2) {
2348
- return [];
2634
+ continue;
2349
2635
  }
2350
2636
  const x = asNumber(item.values[0]);
2351
2637
  const y = asNumber(item.values[1]);
2352
- return x === void 0 || y === void 0 ? [] : [[x, y]];
2353
- });
2638
+ if (x === void 0 || y === void 0) {
2639
+ continue;
2640
+ }
2641
+ points.push([x, y]);
2642
+ tensions.push(item.values[2] === void 0 ? void 0 : asNumber(item.values[2]));
2643
+ }
2644
+ return { points, tensions };
2354
2645
  }
2355
2646
  function readSymbolPorts(block2) {
2356
2647
  const ports = childBlocks(block2).filter((child) => child.kind === "Port").flatMap((port) => {
@@ -2363,13 +2654,14 @@ function readSymbolPorts(block2) {
2363
2654
  return ports.length > 0 ? ports : void 0;
2364
2655
  }
2365
2656
  function readSymbolDefinition(block2) {
2366
- const points = readSymbolPoints(block2);
2657
+ const { points, tensions } = readSymbolPoints(block2);
2367
2658
  if (points.length < 2) {
2368
2659
  return void 0;
2369
2660
  }
2370
2661
  return {
2371
2662
  name: block2.name,
2372
2663
  points,
2664
+ pointTensions: tensions.some((tension) => tension !== void 0) ? tensions : void 0,
2373
2665
  tension: asNumber(directProperties(block2).get("tension")),
2374
2666
  ports: readSymbolPorts(block2)
2375
2667
  };
@@ -2910,43 +3202,25 @@ function freeformPathData(geometry) {
2910
3202
  if (geometry.points.length === 0) {
2911
3203
  return "";
2912
3204
  }
2913
- if (geometry.points.length < 3 || geometry.tension <= 0) {
3205
+ if (isStraight(geometry)) {
2914
3206
  return linearPathData(geometry);
2915
3207
  }
2916
- return smoothPathData(geometry);
2917
- }
2918
- function linearPathData(geometry) {
2919
- const [first, ...remaining] = geometry.points;
2920
- const segments = remaining.map((point) => `L ${point.x} ${point.y}`).join(" ");
2921
- return `M ${first.x} ${first.y} ${segments}${geometry.closed ? " Z" : ""}`;
2922
- }
2923
- function smoothPathData(geometry) {
2924
3208
  const first = geometry.points[0];
2925
- const segmentCount = geometry.closed ? geometry.points.length : geometry.points.length - 1;
2926
3209
  const commands = [`M ${first.x} ${first.y}`];
2927
- for (let index = 0; index < segmentCount; index++) {
2928
- commands.push(curveSegmentCommand(geometry, index));
3210
+ for (const { to, controls } of pathSegments(geometry)) {
3211
+ commands.push(
3212
+ controls ? `C ${controls[0].x} ${controls[0].y} ${controls[1].x} ${controls[1].y} ${to.x} ${to.y}` : `L ${to.x} ${to.y}`
3213
+ );
2929
3214
  }
2930
3215
  if (geometry.closed) {
2931
3216
  commands.push("Z");
2932
3217
  }
2933
3218
  return commands.join(" ");
2934
3219
  }
2935
- function curveSegmentCommand(geometry, index) {
2936
- const previous = freeformPointAt(geometry, index - 1);
2937
- const start = freeformPointAt(geometry, index);
2938
- const end = freeformPointAt(geometry, index + 1);
2939
- const next = freeformPointAt(geometry, index + 2);
2940
- const factor = geometry.tension / 6;
2941
- const firstControl = { x: start.x + (end.x - previous.x) * factor, y: start.y + (end.y - previous.y) * factor };
2942
- const secondControl = { x: end.x - (next.x - start.x) * factor, y: end.y - (next.y - start.y) * factor };
2943
- return `C ${firstControl.x} ${firstControl.y} ${secondControl.x} ${secondControl.y} ${end.x} ${end.y}`;
2944
- }
2945
- function freeformPointAt(geometry, index) {
2946
- if (geometry.closed) {
2947
- return geometry.points[(index + geometry.points.length) % geometry.points.length];
2948
- }
2949
- return geometry.points[Math.max(0, Math.min(geometry.points.length - 1, index))];
3220
+ function linearPathData(geometry) {
3221
+ const [first, ...remaining] = geometry.points;
3222
+ const segments = remaining.map((point) => `L ${point.x} ${point.y}`).join(" ");
3223
+ return `M ${first.x} ${first.y} ${segments}${geometry.closed ? " Z" : ""}`;
2950
3224
  }
2951
3225
 
2952
3226
  // src/renderScene/charts/primitives/radarShape.ts
@@ -3445,8 +3719,8 @@ function createRoundedCorner(previous, corner, next, maximumRadius) {
3445
3719
  const outgoing = { x: next.x - corner.x, y: next.y - corner.y };
3446
3720
  const incomingIsAxisAligned = incoming.x === 0 || incoming.y === 0;
3447
3721
  const outgoingIsAxisAligned = outgoing.x === 0 || outgoing.y === 0;
3448
- const isStraight = incoming.x === 0 && outgoing.x === 0 || incoming.y === 0 && outgoing.y === 0;
3449
- if (!incomingIsAxisAligned || !outgoingIsAxisAligned || isStraight) {
3722
+ const isStraight2 = incoming.x === 0 && outgoing.x === 0 || incoming.y === 0 && outgoing.y === 0;
3723
+ if (!incomingIsAxisAligned || !outgoingIsAxisAligned || isStraight2) {
3450
3724
  return null;
3451
3725
  }
3452
3726
  const radius = Math.min(maximumRadius, axisLength(incoming) * 0.4, axisLength(outgoing) * 0.4);
@@ -4868,6 +5142,6 @@ function localShapePath(type, x, y, width, height) {
4868
5142
  }
4869
5143
  }
4870
5144
 
4871
- export { AXIS_COS, AXIS_SIN, BAR_LABEL, CATEGORY_LABEL_ROW, CHART_COLORS, CHART_TITLE_PROP, CHART_TYPES, CORNER_RADIUS_ATTR, DEFAULT_FONT, DEFAULT_HEATMAP_ZONES, DEFAULT_HEX_RADIUS, DEFAULT_ROLLING_NUMBER_STYLE, DEFAULT_ZONE_FILL, DOM_CONTRACT_VERSION, EMPTY_BOUNDS, ISOMETRIC_LABEL_OFFSET_ATTR, ISOMETRIC_SIZE_ATTR, LABEL_WIDTH, LEADER_INSET, PATH_CLOSED_ATTR, PATH_POINTS_ATTR, PATH_POINT_INDEX_ATTR, PATH_TENSION_ATTR, SQUARE_CORNER_ATTR, SYMBOL_BOUNDS_ATTR, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR, VISIBLE_ISOMETRIC_FACES, angleForAxisValue, axisBands, axisLabelProp, barCategoryCount, barLabelSize, barPath, barShapePath, bottomRoundedRectPath, boxBounds, calculateLinkRoute, canonicalizeSource, categoryProp, chartText, chartTicks, clipSegmentToRect, colorWithAlpha, componentRegistryVersion, computeBoxplotStats, contrastTextColor, cornersRoundedRectPath, createPieGeometry, createPieSlicePath, createVerticalErrorWhiskerNode, deriveFaceFills, edgePointToward, elementCenter, ellipsizeToWidth, errorBarRange, estimateTextWidth, finite, formatBarLabel, formatFieldValue, formatRollingNumber, freeformPathData, gapInsetAngle, getComponentDescriptor, getLineMidpoint, heuristicRichMeasure, horizontalRows, interpolateHexColorStops, isBuiltInComponentType, isChartObject, isGenericComponent, isHorizontalBar, isIsometricObject, isLightColor, isPathObject, isSwimlaneObject, isometricBounds, isometricFaceCenter, isometricFaces, isometricTopFaceCenter, labelGapDash, leftRoundedRectPath, linePathData, localShapePath, mapChartValue, maxApexCornerRadius, maxPieCornerRadius, paint, parseSource, personLabelArea, pieApexRadius, pieArcPoint, pieUsesInnerArc, pillCornerRadius, pillPath, pointAtNormalizedPort, pointAtPort, radarCategoryCount, radarPointAt, radarRadius, radarRadiusForValue, radarSeriesPath, radarValueAtPoint, radarVertexPoint, registerComponentDescriptor, relativeOffsetOnRectangleSide, renderPieLabels, representativeColor, resolveChartShadow, resolvePieRadii, resolveRollingNumberStyle, rightRoundedRectPath, rotatedBounds, roundedBarPath, roundedOrthogonalPathData, roundedPolygonPath, rowTop, ruleAtProp, ruleTextProp, sameHueContrastColor, sameHueTint, segmentedBarPath, seriesColorProp, seriesLabelOffsetXProp, seriesLabelOffsetYProp, seriesLabelProp, seriesValueColorProp, seriesValueProp, sflToCanvasState, stackRank, stackSequence, stackedSegment, tag, tokenizeSource, topRoundedRectPath, wrapText, zoneColorAtValue };
4872
- //# sourceMappingURL=chunk-IEHE6WVN.js.map
4873
- //# sourceMappingURL=chunk-IEHE6WVN.js.map
5145
+ export { AXIS_COS, AXIS_SIN, BAR_LABEL, CATEGORY_LABEL_ROW, CHART_COLORS, CHART_TITLE_PROP, CHART_TYPES, CORNER_RADIUS_ATTR, DEFAULT_FONT, DEFAULT_HEATMAP_ZONES, DEFAULT_HEX_RADIUS, DEFAULT_ROLLING_NUMBER_STYLE, DEFAULT_ZONE_FILL, DOM_CONTRACT_VERSION, EMPTY_BOUNDS, ISOMETRIC_LABEL_OFFSET_ATTR, ISOMETRIC_SIZE_ATTR, LABEL_WIDTH, LEADER_INSET, PATH_CLOSED_ATTR, PATH_POINTS_ATTR, PATH_POINT_INDEX_ATTR, PATH_TENSION_ATTR, SQUARE_CORNER_ATTR, SYMBOL_BOUNDS_ATTR, SYMBOL_POINTS_ATTR, SYMBOL_TENSION_ATTR, VISIBLE_ISOMETRIC_FACES, angleForAxisValue, axisBands, axisLabelProp, barCategoryCount, barLabelSize, barPath, barShapePath, bottomRoundedRectPath, boxBounds, calculateLinkRoute, canonicalizeSource, categoryProp, chartText, chartTicks, cleanFootprint, clipSegmentToRect, colorWithAlpha, componentRegistryVersion, computeBoxplotStats, contrastTextColor, cornersRoundedRectPath, createPieGeometry, createPieSlicePath, createVerticalErrorWhiskerNode, deriveFaceFills, edgePointToward, elementCenter, ellipsizeToWidth, errorBarRange, estimateTextWidth, extrudeFootprint, finite, flattenPath, formatBarLabel, formatFieldValue, formatRollingNumber, freeformPathData, gapInsetAngle, getComponentDescriptor, getLineMidpoint, heuristicRichMeasure, horizontalRows, interpolateHexColorStops, isBuiltInComponentType, isChartObject, isDimensionObject, isGenericComponent, isHorizontalBar, isIsometricObject, isLightColor, isPathObject, isSwimlaneObject, isometricBounds, isometricFaceCenter, isometricFaces, isometricTopFaceCenter, labelGapDash, leftRoundedRectPath, linePathData, localShapePath, mapChartValue, maxApexCornerRadius, maxPieCornerRadius, paint, parseSource, pathBounds, pathToSymbol, personLabelArea, pieApexRadius, pieArcPoint, pieUsesInnerArc, pillCornerRadius, pillPath, pointAtNormalizedPort, pointAtPort, radarCategoryCount, radarPointAt, radarRadius, radarRadiusForValue, radarSeriesPath, radarValueAtPoint, radarVertexPoint, registerComponentDescriptor, relativeOffsetOnRectangleSide, renderPieLabels, representativeColor, resolveChartShadow, resolvePieRadii, resolveRollingNumberStyle, rightRoundedRectPath, rotatedBounds, roundedBarPath, roundedOrthogonalPathData, roundedPolygonPath, rowTop, ruleAtProp, ruleTextProp, sameHueContrastColor, sameHueTint, segmentedBarPath, seriesColorProp, seriesLabelOffsetXProp, seriesLabelOffsetYProp, seriesLabelProp, seriesValueColorProp, seriesValueProp, sflToCanvasState, shadeFill, stackRank, stackSequence, stackedSegment, symbolToPath, tag, tokenizeSource, topRoundedRectPath, wrapText, zoneColorAtValue };
5146
+ //# sourceMappingURL=chunk-4G2R7PEL.js.map
5147
+ //# sourceMappingURL=chunk-4G2R7PEL.js.map