stickyflow 0.5.0 → 0.7.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 (62) hide show
  1. package/CHANGELOG.md +43 -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-ZMLQIMJK.cjs → chunk-A73UJ5AQ.cjs} +1537 -738
  7. package/dist/chunk-A73UJ5AQ.cjs.map +1 -0
  8. package/dist/{chunk-VK3T6O5Z.cjs → chunk-BUOWM3LC.cjs} +745 -62
  9. package/dist/chunk-BUOWM3LC.cjs.map +1 -0
  10. package/dist/{chunk-L3VJXZFD.cjs → chunk-EKAWJFJQ.cjs} +15 -15
  11. package/dist/{chunk-L3VJXZFD.cjs.map → chunk-EKAWJFJQ.cjs.map} +1 -1
  12. package/dist/{chunk-BODZN3ZI.js → chunk-JCRPLPKV.js} +156 -23
  13. package/dist/chunk-JCRPLPKV.js.map +1 -0
  14. package/dist/{chunk-IEHE6WVN.js → chunk-JQK4IGXJ.js} +489 -51
  15. package/dist/chunk-JQK4IGXJ.js.map +1 -0
  16. package/dist/{chunk-XY2GZUHC.cjs → chunk-KXYSO6GC.cjs} +498 -50
  17. package/dist/chunk-KXYSO6GC.cjs.map +1 -0
  18. package/dist/{chunk-G7NRK5AG.js → chunk-MUKIGLR5.js} +717 -34
  19. package/dist/chunk-MUKIGLR5.js.map +1 -0
  20. package/dist/{chunk-TWDLOXRM.cjs → chunk-OWNVXKXN.cjs} +170 -37
  21. package/dist/chunk-OWNVXKXN.cjs.map +1 -0
  22. package/dist/{chunk-LTGF5OHP.js → chunk-SDMQRSRW.js} +941 -143
  23. package/dist/chunk-SDMQRSRW.js.map +1 -0
  24. package/dist/{chunk-7VW2XKVB.js → chunk-ZNHYW47T.js} +3 -3
  25. package/dist/{chunk-7VW2XKVB.js.map → chunk-ZNHYW47T.js.map} +1 -1
  26. package/dist/index.cjs +57 -29
  27. package/dist/index.d.cts +80 -7
  28. package/dist/index.d.ts +80 -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-BU2uYzjG.d.cts} +40 -16
  37. package/dist/{render-CgX_y15a.d.cts → render-BU2uYzjG.d.ts} +40 -16
  38. package/dist/{runtime-reWgr7MP.d.cts → runtime-B7KiTmn8.d.cts} +2 -2
  39. package/dist/{runtime-DnUxca3Y.d.ts → runtime-BPzyD-Nd.d.ts} +2 -2
  40. package/dist/{runtimeTypes-D60w6nyF.d.cts → runtimeTypes-BIP70z72.d.cts} +3 -2
  41. package/dist/{runtimeTypes-CEBGueYM.d.ts → runtimeTypes-DalvhScn.d.ts} +3 -2
  42. package/dist/stickyflow-diagram.global.js +387 -36
  43. package/dist/stickyflow-diagram.global.js.map +1 -1
  44. package/dist/{types-DYLC_lsk.d.ts → types-DMWs27Hn.d.ts} +1 -1
  45. package/dist/{types-DvhMpqrL.d.cts → types-D_2NZ6lL.d.cts} +1 -1
  46. package/dist/viewer/index.cjs +9 -9
  47. package/dist/viewer/index.d.cts +5 -4
  48. package/dist/viewer/index.d.ts +5 -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-BODZN3ZI.js.map +0 -1
  56. package/dist/chunk-G7NRK5AG.js.map +0 -1
  57. package/dist/chunk-IEHE6WVN.js.map +0 -1
  58. package/dist/chunk-LTGF5OHP.js.map +0 -1
  59. package/dist/chunk-TWDLOXRM.cjs.map +0 -1
  60. package/dist/chunk-VK3T6O5Z.cjs.map +0 -1
  61. package/dist/chunk-XY2GZUHC.cjs.map +0 -1
  62. package/dist/chunk-ZMLQIMJK.cjs.map +0 -1
@@ -82,6 +82,115 @@ function isometricFaces(object) {
82
82
  };
83
83
  }
84
84
 
85
+ // src/model/isometricObject/footprint.ts
86
+ function signedArea(points) {
87
+ let sum = 0;
88
+ for (let i = 0; i < points.length; i += 1) {
89
+ const [x1, y1] = points[i];
90
+ const [x2, y2] = points[(i + 1) % points.length];
91
+ sum += x1 * y2 - x2 * y1;
92
+ }
93
+ return sum / 2;
94
+ }
95
+ function cleanFootprint(points) {
96
+ const clean = (points ?? []).filter(
97
+ (point) => Array.isArray(point) && Number.isFinite(point[0]) && Number.isFinite(point[1])
98
+ );
99
+ const unique = clean.filter((point, index) => {
100
+ const next = clean[(index + 1) % clean.length];
101
+ return point[0] !== next[0] || point[1] !== next[1];
102
+ });
103
+ return unique.length >= 3 ? unique : [];
104
+ }
105
+ var ARC_STEP = Math.PI / 12;
106
+ function roundFootprint(points, radius, width, depth) {
107
+ if (!(radius > 0) || width <= 0 || depth <= 0) {
108
+ return [...points];
109
+ }
110
+ const world = points.map(([u, v]) => ({ x: u * width, y: v * depth }));
111
+ const rounded = [];
112
+ for (let i = 0; i < world.length; i += 1) {
113
+ const here = world[i];
114
+ const before = world[(i - 1 + world.length) % world.length];
115
+ const after = world[(i + 1) % world.length];
116
+ const a = { x: before.x - here.x, y: before.y - here.y };
117
+ const b = { x: after.x - here.x, y: after.y - here.y };
118
+ const lengthA = Math.hypot(a.x, a.y);
119
+ const lengthB = Math.hypot(b.x, b.y);
120
+ const cos = (a.x * b.x + a.y * b.y) / (lengthA * lengthB);
121
+ const angle = Math.acos(Math.max(-1, Math.min(1, cos)));
122
+ if (!Number.isFinite(angle) || angle < 1e-3 || Math.PI - angle < 1e-3) {
123
+ rounded.push(points[i]);
124
+ continue;
125
+ }
126
+ const reach = Math.min(radius / Math.tan(angle / 2), Math.min(lengthA, lengthB) / 2);
127
+ const effective = reach * Math.tan(angle / 2);
128
+ const unitA = { x: a.x / lengthA, y: a.y / lengthA };
129
+ const unitB = { x: b.x / lengthB, y: b.y / lengthB };
130
+ const from = { x: here.x + unitA.x * reach, y: here.y + unitA.y * reach };
131
+ const to = { x: here.x + unitB.x * reach, y: here.y + unitB.y * reach };
132
+ const bisector = { x: unitA.x + unitB.x, y: unitA.y + unitB.y };
133
+ const bisectorLength = Math.hypot(bisector.x, bisector.y);
134
+ const centerDistance = effective / Math.sin(angle / 2);
135
+ const center = {
136
+ x: here.x + bisector.x / bisectorLength * centerDistance,
137
+ y: here.y + bisector.y / bisectorLength * centerDistance
138
+ };
139
+ const start = Math.atan2(from.y - center.y, from.x - center.x);
140
+ let sweep = Math.atan2(to.y - center.y, to.x - center.x) - start;
141
+ sweep -= 2 * Math.PI * Math.round(sweep / (2 * Math.PI));
142
+ const steps = Math.max(2, Math.ceil(Math.abs(sweep) / ARC_STEP));
143
+ for (let step = 0; step <= steps; step += 1) {
144
+ const t = start + sweep * step / steps;
145
+ rounded.push([(center.x + effective * Math.cos(t)) / width, (center.y + effective * Math.sin(t)) / depth]);
146
+ }
147
+ }
148
+ return rounded;
149
+ }
150
+ function extrudeFootprint(frame, footprint, cornerRadius = 0) {
151
+ const width = Math.max(0, frame.width);
152
+ const depth = Math.max(0, frame.depth);
153
+ const height = Math.max(0, frame.height);
154
+ const points = roundFootprint(cleanFootprint(footprint), cornerRadius, width, depth);
155
+ const apexX = frame.x + depth * AXIS_COS;
156
+ const project = ([u, v], z) => ({
157
+ x: apexX + (u * width - v * depth) * AXIS_COS,
158
+ y: frame.y + (u * width + v * depth) * AXIS_SIN + z
159
+ });
160
+ const top = points.map((point) => project(point, 0));
161
+ const turn = signedArea(points) >= 0 ? 1 : -1;
162
+ const edges = points.map((from, i) => {
163
+ const to = points[(i + 1) % points.length];
164
+ const edgeU = (to[0] - from[0]) * width;
165
+ const edgeV = (to[1] - from[1]) * depth;
166
+ const length = Math.hypot(edgeU, edgeV);
167
+ const normalU = length === 0 ? 0 : edgeV / length * turn;
168
+ const normalV = length === 0 ? 0 : -edgeU / length * turn;
169
+ return { from, to, length, normalU, normalV, visible: length > 0 && normalU + normalV > 1e-9 };
170
+ });
171
+ const sameWay = (a, b) => {
172
+ return a.visible && b.visible && a.normalU * b.normalU + a.normalV * b.normalV > Math.cos(0.5);
173
+ };
174
+ const sides = [];
175
+ edges.forEach((edge, i) => {
176
+ if (!edge.visible) {
177
+ return;
178
+ }
179
+ const before = edges[(i - 1 + edges.length) % edges.length];
180
+ const after = edges[(i + 1) % edges.length];
181
+ const { from, to } = edge;
182
+ sides.push({
183
+ points: [project(from, 0), project(to, 0), project(to, height), project(from, height)],
184
+ light: 0.72 + 0.28 * Math.max(0, Math.min(1, edge.normalV / (Math.abs(edge.normalU) + Math.abs(edge.normalV)))),
185
+ depth: (from[0] + to[0]) / 2 + (from[1] + to[1]) / 2,
186
+ smoothStart: sameWay(before, edge),
187
+ smoothEnd: sameWay(edge, after)
188
+ });
189
+ });
190
+ sides.sort((a, b) => a.depth - b.depth);
191
+ return { top, sides };
192
+ }
193
+
85
194
  // src/model/isometricObject/shading.ts
86
195
  function clamp255(value) {
87
196
  return Math.max(0, Math.min(255, Math.round(value)));
@@ -105,6 +214,9 @@ function multiply(hex, factor) {
105
214
  const [r, g, b] = rgb;
106
215
  return rgbToHex(r * factor, g * factor, b * factor);
107
216
  }
217
+ function shadeFill(fill, factor) {
218
+ return multiply(fill, factor);
219
+ }
108
220
  function deriveFaceFills(fill) {
109
221
  return {
110
222
  topFill: fill,
@@ -113,6 +225,114 @@ function deriveFaceFills(fill) {
113
225
  };
114
226
  }
115
227
 
228
+ // src/model/path/curve.ts
229
+ var SAMPLES_PER_SEGMENT = 8;
230
+ function pointTension(curve, point) {
231
+ return Math.max(0, point.tension ?? curve.tension);
232
+ }
233
+ function isStraight(curve) {
234
+ return curve.points.length < 3 || curve.points.every((point) => pointTension(curve, point) <= 0);
235
+ }
236
+ function pointAt(curve, index) {
237
+ const { points } = curve;
238
+ if (curve.closed) {
239
+ return points[(index + points.length) % points.length];
240
+ }
241
+ return points[Math.max(0, Math.min(points.length - 1, index))];
242
+ }
243
+ function pathSegments(curve) {
244
+ const count = curve.closed ? curve.points.length : curve.points.length - 1;
245
+ return Array.from({ length: Math.max(0, count) }, (_, index) => {
246
+ const previous = pointAt(curve, index - 1);
247
+ const from = pointAt(curve, index);
248
+ const to = pointAt(curve, index + 1);
249
+ const next = pointAt(curve, index + 2);
250
+ const fromFactor = pointTension(curve, from) / 6;
251
+ const toFactor = pointTension(curve, to) / 6;
252
+ if (fromFactor === 0 && toFactor === 0) {
253
+ return { from, to, controls: null };
254
+ }
255
+ const first = { x: from.x + (to.x - previous.x) * fromFactor, y: from.y + (to.y - previous.y) * fromFactor };
256
+ const second = { x: to.x - (next.x - from.x) * toFactor, y: to.y - (next.y - from.y) * toFactor };
257
+ return { from, to, controls: [first, second] };
258
+ });
259
+ }
260
+ function bezierAt(segment, t) {
261
+ const { from, to, controls } = segment;
262
+ const u = 1 - t;
263
+ const weights = [u * u * u, 3 * u * u * t, 3 * u * t * t, t * t * t];
264
+ const anchors = [from, controls[0], controls[1], to];
265
+ return {
266
+ x: anchors.reduce((sum, anchor, i) => sum + anchor.x * weights[i], 0),
267
+ y: anchors.reduce((sum, anchor, i) => sum + anchor.y * weights[i], 0)
268
+ };
269
+ }
270
+ function flattenPath(curve, samples = SAMPLES_PER_SEGMENT) {
271
+ if (isStraight(curve)) {
272
+ return curve.points.map((point) => ({ x: point.x, y: point.y }));
273
+ }
274
+ const flat = [];
275
+ const segments = pathSegments(curve);
276
+ segments.forEach((segment) => {
277
+ flat.push({ x: segment.from.x, y: segment.from.y });
278
+ if (segment.controls) {
279
+ const curved = { ...segment, controls: segment.controls };
280
+ for (let step = 1; step < samples; step++) {
281
+ flat.push(bezierAt(curved, step / samples));
282
+ }
283
+ }
284
+ });
285
+ const last = segments[segments.length - 1];
286
+ if (!curve.closed && last) {
287
+ flat.push({ x: last.to.x, y: last.to.y });
288
+ }
289
+ return flat;
290
+ }
291
+
292
+ // src/model/path/symbol.ts
293
+ function pathBounds(points) {
294
+ const xs = points.map((point) => point.x);
295
+ const ys = points.map((point) => point.y);
296
+ const x = Math.min(...xs);
297
+ const y = Math.min(...ys);
298
+ return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y };
299
+ }
300
+ var round = (value) => Math.round(value * 1e4) / 1e4;
301
+ function pathToSymbol(points) {
302
+ if (points.length === 0) {
303
+ return { points: [], width: 0, height: 0 };
304
+ }
305
+ const frame = pathBounds(points);
306
+ const unit = (value, size) => size === 0 ? 0 : round(value / size);
307
+ return {
308
+ width: frame.width,
309
+ height: frame.height,
310
+ points: points.map((point) => {
311
+ const x = unit(point.x - frame.x, frame.width);
312
+ const y = unit(point.y - frame.y, frame.height);
313
+ return point.tension === void 0 ? [x, y] : [x, y, point.tension];
314
+ })
315
+ };
316
+ }
317
+ function symbolToPath(points, frame) {
318
+ return points.map((point) => {
319
+ const placed = { x: frame.x + point[0] * frame.width, y: frame.y + point[1] * frame.height };
320
+ return point[2] === void 0 ? placed : { ...placed, tension: point[2] };
321
+ });
322
+ }
323
+
324
+ // src/model/component/categories.ts
325
+ var COMPONENT_CATEGORIES = [
326
+ { id: "action", label: "Actions" },
327
+ { id: "selection", label: "Selection" },
328
+ { id: "value", label: "Value input" },
329
+ { id: "text", label: "Text input" },
330
+ { id: "indicator", label: "Indicators" },
331
+ { id: "instrument", label: "Instruments" },
332
+ { id: "navigation", label: "Navigation" },
333
+ { id: "container", label: "Containers" }
334
+ ];
335
+
116
336
  // src/model/component/supportedTypes.ts
117
337
  var BUILT_IN_COMPONENT_TYPES = ["rollingNumber", "tickScale", "ruler"];
118
338
  function isBuiltInComponentType(value) {
@@ -129,6 +349,7 @@ var BUILT_IN_DESCRIPTORS = [
129
349
  {
130
350
  type: "rollingNumber",
131
351
  group: "readout",
352
+ category: "indicator",
132
353
  value: { type: "number", writable: false, default: 0 },
133
354
  properties: {},
134
355
  interaction: "none",
@@ -138,6 +359,7 @@ var BUILT_IN_DESCRIPTORS = [
138
359
  {
139
360
  type: "tickScale",
140
361
  group: "readout",
362
+ category: "instrument",
141
363
  value: { type: "number", writable: false, default: 0 },
142
364
  properties: {},
143
365
  interaction: "none",
@@ -147,6 +369,7 @@ var BUILT_IN_DESCRIPTORS = [
147
369
  {
148
370
  type: "ruler",
149
371
  group: "input",
372
+ category: "instrument",
150
373
  value: { type: "number", writable: false, default: 0 },
151
374
  properties: {},
152
375
  interaction: "scale",
@@ -156,11 +379,13 @@ var BUILT_IN_DESCRIPTORS = [
156
379
  {
157
380
  type: "switch",
158
381
  group: "input",
382
+ category: "selection",
159
383
  value: { type: "boolean", writable: true, default: false },
160
384
  properties: {
161
385
  accent: { type: "color", default: "#5a6bff" },
162
386
  track: { type: "color", default: "#cbd5e1" },
163
- thumb: { type: "color", default: "#ffffff" }
387
+ thumb: { type: "color", default: "#ffffff" },
388
+ animate: { type: "number", default: 160, min: 0, max: 2e3, step: 10 }
164
389
  },
165
390
  interaction: "toggle",
166
391
  pointerScale: false,
@@ -170,13 +395,15 @@ var BUILT_IN_DESCRIPTORS = [
170
395
  {
171
396
  type: "checkbox",
172
397
  group: "input",
398
+ category: "selection",
173
399
  value: { type: "boolean", writable: true, default: false },
174
400
  properties: {
175
401
  accent: { type: "color", default: "#5a6bff" },
176
402
  stroke: { type: "color", default: "#94a3b8" },
177
403
  check: { type: "color", default: "#ffffff" },
178
404
  textColor: { type: "color", default: "#0f172a" },
179
- fontSize: { type: "number", default: 14, min: 6, max: 200 }
405
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
406
+ animate: { type: "number", default: 160, min: 0, max: 2e3, step: 10 }
180
407
  },
181
408
  interaction: "toggle",
182
409
  pointerScale: false,
@@ -186,13 +413,15 @@ var BUILT_IN_DESCRIPTORS = [
186
413
  {
187
414
  type: "toggleButton",
188
415
  group: "input",
416
+ category: "action",
189
417
  value: { type: "boolean", writable: true, default: false },
190
418
  properties: {
191
419
  accent: { type: "color", default: "#5a6bff" },
192
420
  stroke: { type: "color", default: "#94a3b8" },
193
421
  textColor: { type: "color", default: "#0f172a" },
194
422
  onTextColor: { type: "color", default: "#ffffff" },
195
- fontSize: { type: "number", default: 14, min: 6, max: 200 }
423
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
424
+ animate: { type: "number", default: 160, min: 0, max: 2e3, step: 10 }
196
425
  },
197
426
  interaction: "toggle",
198
427
  pointerScale: false,
@@ -202,16 +431,153 @@ var BUILT_IN_DESCRIPTORS = [
202
431
  {
203
432
  type: "button",
204
433
  group: "action",
434
+ category: "action",
205
435
  properties: {
206
436
  accent: { type: "color", default: "#5a6bff" },
207
437
  textColor: { type: "color", default: "#ffffff" },
208
438
  radius: { type: "number", default: 8, min: 0, max: 200 },
209
- fontSize: { type: "number", default: 14, min: 6, max: 200 }
439
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
440
+ animate: { type: "number", default: 160, min: 0, max: 2e3, step: 10 }
210
441
  },
211
442
  interaction: "press",
212
443
  pointerScale: false,
213
444
  size: { width: 120, height: 40, minWidth: 40, minHeight: 24 },
214
445
  role: "button"
446
+ },
447
+ {
448
+ type: "slider",
449
+ group: "input",
450
+ category: "value",
451
+ value: { type: "number", writable: true, default: 40 },
452
+ properties: {
453
+ variant: { type: "enum", default: "line", options: ["line", "field"] },
454
+ direction: { type: "enum", default: "horizontal", options: ["horizontal", "vertical"] },
455
+ ticks: { type: "number", default: 0, min: 0, max: 200 },
456
+ tickColor: { type: "color", default: "#94a3b8" },
457
+ min: { type: "number", default: 0 },
458
+ max: { type: "number", default: 100 },
459
+ step: { type: "number", default: 0, min: 0 },
460
+ surface: { type: "color", default: "#eef1f6" },
461
+ fill: { type: "color", default: "#cbd5e1" },
462
+ textColor: { type: "color", default: "#0f172a" },
463
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
464
+ display: { type: "enum", default: "value", options: ["none", "value", "percent"] },
465
+ radius: { type: "number", default: 10, min: 0, max: 200 },
466
+ accent: { type: "color", default: "#5a6bff" },
467
+ track: { type: "color", default: "#cbd5e1" },
468
+ thumb: { type: "color", default: "#ffffff" },
469
+ trackHeight: { type: "number", default: 6, min: 1, max: 80 },
470
+ thumbSize: { type: "number", default: 56, min: 20, max: 100, step: 5 },
471
+ animate: { type: "number", default: 0, min: 0, max: 2e3, step: 10 }
472
+ },
473
+ interaction: "slide",
474
+ pointerScale: false,
475
+ size: { width: 220, height: 28, minWidth: 60, minHeight: 12 },
476
+ role: "slider"
477
+ },
478
+ {
479
+ type: "range",
480
+ group: "input",
481
+ category: "value",
482
+ value: { type: "number", writable: true, default: 25 },
483
+ properties: {
484
+ variant: { type: "enum", default: "line", options: ["line", "field"] },
485
+ direction: { type: "enum", default: "horizontal", options: ["horizontal", "vertical"] },
486
+ ticks: { type: "number", default: 0, min: 0, max: 200 },
487
+ tickColor: { type: "color", default: "#94a3b8" },
488
+ valueEnd: { type: "number", default: 75 },
489
+ min: { type: "number", default: 0 },
490
+ max: { type: "number", default: 100 },
491
+ step: { type: "number", default: 0, min: 0 },
492
+ surface: { type: "color", default: "#eef1f6" },
493
+ fill: { type: "color", default: "#cbd5e1" },
494
+ textColor: { type: "color", default: "#0f172a" },
495
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
496
+ display: { type: "enum", default: "value", options: ["none", "value", "percent"] },
497
+ radius: { type: "number", default: 10, min: 0, max: 200 },
498
+ accent: { type: "color", default: "#5a6bff" },
499
+ track: { type: "color", default: "#cbd5e1" },
500
+ thumb: { type: "color", default: "#ffffff" },
501
+ trackHeight: { type: "number", default: 6, min: 1, max: 80 },
502
+ thumbSize: { type: "number", default: 56, min: 20, max: 100, step: 5 },
503
+ animate: { type: "number", default: 0, min: 0, max: 2e3, step: 10 }
504
+ },
505
+ interaction: "range",
506
+ pointerScale: false,
507
+ size: { width: 220, height: 28, minWidth: 60, minHeight: 12 },
508
+ role: "slider"
509
+ },
510
+ {
511
+ type: "progress",
512
+ group: "readout",
513
+ category: "indicator",
514
+ value: { type: "number", writable: false, default: 60 },
515
+ properties: {
516
+ min: { type: "number", default: 0 },
517
+ max: { type: "number", default: 100 },
518
+ variant: { type: "enum", default: "bar", options: ["bar", "ring"] },
519
+ direction: { type: "enum", default: "horizontal", options: ["horizontal", "vertical"] },
520
+ accent: { type: "color", default: "#5a6bff" },
521
+ track: { type: "color", default: "#e2e8f0" },
522
+ thickness: { type: "number", default: 10, min: 1, max: 80 },
523
+ rounded: { type: "boolean", default: true },
524
+ display: { type: "enum", default: "none", options: ["none", "percent", "value"] },
525
+ textColor: { type: "color", default: "#0f172a" },
526
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
527
+ animate: { type: "number", default: 300, min: 0, max: 2e3, step: 10 }
528
+ },
529
+ interaction: "none",
530
+ pointerScale: false,
531
+ size: { width: 220, height: 12, minWidth: 20, minHeight: 4 },
532
+ role: "progressbar"
533
+ },
534
+ {
535
+ type: "segmented",
536
+ group: "input",
537
+ category: "selection",
538
+ value: { type: "number", writable: true, default: 0 },
539
+ properties: {
540
+ options: { type: "string", default: "Day,Week,Month" },
541
+ accent: { type: "color", default: "#5a6bff" },
542
+ track: { type: "color", default: "#e2e8f0" },
543
+ textColor: { type: "color", default: "#475569" },
544
+ activeTextColor: { type: "color", default: "#ffffff" },
545
+ radius: { type: "number", default: 200, min: 0, max: 200 },
546
+ inset: { type: "number", default: 3, min: 0, max: 20 },
547
+ fontSize: { type: "number", default: 14, min: 6, max: 200 },
548
+ animate: { type: "number", default: 200, min: 0, max: 2e3, step: 10 }
549
+ },
550
+ interaction: "pick",
551
+ pointerScale: false,
552
+ size: { width: 300, height: 40, minWidth: 80, minHeight: 20 },
553
+ role: "radiogroup"
554
+ },
555
+ {
556
+ type: "knob",
557
+ group: "input",
558
+ category: "value",
559
+ value: { type: "number", writable: true, default: 40 },
560
+ properties: {
561
+ min: { type: "number", default: 0 },
562
+ max: { type: "number", default: 100 },
563
+ step: { type: "number", default: 0, min: 0 },
564
+ start: { type: "number", default: 225, min: 0, max: 360 },
565
+ sweep: { type: "number", default: 270, min: 30, max: 360 },
566
+ accent: { type: "color", default: "#5a6bff" },
567
+ track: { type: "color", default: "#cbd5e1" },
568
+ face: { type: "color", default: "#f1f5f9" },
569
+ dot: { type: "color", default: "#0f172a" },
570
+ thickness: { type: "number", default: 8, min: 1, max: 80 },
571
+ rounded: { type: "boolean", default: true },
572
+ display: { type: "enum", default: "value", options: ["none", "value", "percent"] },
573
+ textColor: { type: "color", default: "#0f172a" },
574
+ fontSize: { type: "number", default: 16, min: 6, max: 200 },
575
+ animate: { type: "number", default: 0, min: 0, max: 2e3, step: 10 }
576
+ },
577
+ interaction: "turn",
578
+ pointerScale: false,
579
+ size: { width: 96, height: 96, minWidth: 40, minHeight: 40, aspect: 1 },
580
+ role: "slider"
215
581
  }
216
582
  ];
217
583
 
@@ -691,6 +1057,7 @@ var NAMED_BLOCK_KINDS = [
691
1057
  "Shape",
692
1058
  "Text",
693
1059
  "Isometric",
1060
+ "Dimension",
694
1061
  "Link",
695
1062
  "Connection",
696
1063
  "Layout",
@@ -1464,6 +1831,11 @@ function isChartObject(canvasObject) {
1464
1831
  return canvasObject.objectType === "chart" && canvasObject.chart !== void 0;
1465
1832
  }
1466
1833
 
1834
+ // src/sflSemantic/canvasObjects/artifacts/dimension/types.ts
1835
+ function isDimensionObject(canvasObject) {
1836
+ return canvasObject.objectType === "dimension" && canvasObject.dimension !== void 0;
1837
+ }
1838
+
1467
1839
  // src/sflSemantic/canvasObjects/artifacts/isometric/types.ts
1468
1840
  function isIsometricObject(canvasObject) {
1469
1841
  return canvasObject.objectType === "isometric" && canvasObject.isometric !== void 0;
@@ -1601,7 +1973,8 @@ var CANVAS_OBJECT_BLOCK_KINDS = [
1601
1973
  "Chart",
1602
1974
  "Widget",
1603
1975
  "Component",
1604
- "Isometric"
1976
+ "Isometric",
1977
+ "Dimension"
1605
1978
  ];
1606
1979
  var canvasObjectBlockKinds = new Set(CANVAS_OBJECT_BLOCK_KINDS);
1607
1980
  function isCanvasObjectBlockKind(kind) {
@@ -2007,21 +2380,77 @@ function resolveChartObject(base, block2, properties, symbolDefinitions, mergedP
2007
2380
  };
2008
2381
  }
2009
2382
 
2383
+ // src/sflSemantic/canvasObjects/artifacts/dimension/reader.ts
2384
+ function readPoint(value, origin) {
2385
+ const [x, y] = tupleValues(value) ?? [];
2386
+ return { x: origin.x + (x ?? 0), y: origin.y + (y ?? 0) };
2387
+ }
2388
+ function readDimension(properties, origin) {
2389
+ return {
2390
+ start: readPoint(properties.get("start"), origin),
2391
+ end: readPoint(properties.get("end"), origin),
2392
+ offset: asNumber(properties.get("offset")) ?? 0,
2393
+ unit: asString(properties.get("unit"))
2394
+ };
2395
+ }
2396
+
2397
+ // src/sflSemantic/canvasObjects/artifacts/dimension/resolver.ts
2398
+ function resolveDimensionObject(base, properties, origin) {
2399
+ return {
2400
+ ...base,
2401
+ objectType: "dimension",
2402
+ dimension: readDimension(properties, origin)
2403
+ };
2404
+ }
2405
+
2010
2406
  // src/sflSemantic/canvasObjects/artifacts/isometric/reader.ts
2011
- function readIsometric(properties, depth) {
2407
+ function readFootprintPoint(value) {
2408
+ if (value.type !== "list" || value.values.length < 2) {
2409
+ return [];
2410
+ }
2411
+ const x = asNumber(value.values[0]);
2412
+ const y = asNumber(value.values[1]);
2413
+ const tension = value.values[2] === void 0 ? void 0 : asNumber(value.values[2]);
2414
+ if (x === void 0 || y === void 0) {
2415
+ return [];
2416
+ }
2417
+ return [tension === void 0 ? { x, y } : { x, y, tension }];
2418
+ }
2419
+ function asPolygon(points, tension) {
2420
+ const flat = flattenPath({ points, tension, closed: true });
2421
+ return flat.length >= 3 ? flat.map((point) => [point.x, point.y]) : void 0;
2422
+ }
2423
+ function readFootprint(value, symbolDefs) {
2424
+ if (value?.type === "list") {
2425
+ return asPolygon(value.values.flatMap(readFootprintPoint), 0);
2426
+ }
2427
+ const name = asString(value);
2428
+ const definition = name ? symbolDefs.get(name) : void 0;
2429
+ if (!definition) {
2430
+ return void 0;
2431
+ }
2432
+ const points = definition.points.map(([x, y], index) => {
2433
+ const tension = definition.pointTensions?.[index];
2434
+ return tension === void 0 ? { x, y } : { x, y, tension };
2435
+ });
2436
+ return asPolygon(points, definition.tension ?? 0);
2437
+ }
2438
+ function readIsometric(properties, depth, symbolDefs) {
2012
2439
  return {
2013
2440
  depth,
2014
- icon: asString(properties.get("icon"))
2441
+ icon: asString(properties.get("icon")),
2442
+ footprint: readFootprint(properties.get("symbol"), symbolDefs),
2443
+ form: asString(properties.get("shape")) === "sphere" ? "sphere" : "box"
2015
2444
  };
2016
2445
  }
2017
2446
 
2018
2447
  // src/sflSemantic/canvasObjects/artifacts/isometric/resolver.ts
2019
- function resolveIsometricObject(base, block2, properties, layoutProperty) {
2448
+ function resolveIsometricObject(base, block2, properties, layoutProperty, symbolDefinitions) {
2020
2449
  const size = tupleValues(layoutProperty(block2, "size"));
2021
2450
  return {
2022
2451
  ...base,
2023
2452
  objectType: "isometric",
2024
- isometric: readIsometric(properties, size?.[2] ?? 24)
2453
+ isometric: readIsometric(properties, size?.[2] ?? 24, symbolDefinitions)
2025
2454
  };
2026
2455
  }
2027
2456
 
@@ -2034,7 +2463,12 @@ function readPath(p, origin) {
2034
2463
  }
2035
2464
  const x = asNumber(value.values[0]);
2036
2465
  const y = asNumber(value.values[1]);
2037
- return x !== void 0 && y !== void 0 ? [{ x: origin.x + x, y: origin.y + y }] : [];
2466
+ const tension = value.values[2] === void 0 ? void 0 : asNumber(value.values[2]);
2467
+ if (x === void 0 || y === void 0) {
2468
+ return [];
2469
+ }
2470
+ const point = { x: origin.x + x, y: origin.y + y };
2471
+ return [tension === void 0 ? point : { ...point, tension }];
2038
2472
  }) : [];
2039
2473
  return {
2040
2474
  points,
@@ -2101,6 +2535,9 @@ function declaredCanvasObjectKind(block2, properties) {
2101
2535
  if (block2.kind === "Isometric") {
2102
2536
  return "isometric";
2103
2537
  }
2538
+ if (block2.kind === "Dimension") {
2539
+ return "dimension";
2540
+ }
2104
2541
  return asString(properties.get("kind")) ?? "";
2105
2542
  }
2106
2543
  function canvasObjectTypeForKind(kind) {
@@ -2122,6 +2559,9 @@ function canvasObjectTypeForKind(kind) {
2122
2559
  if (kind === "isometric") {
2123
2560
  return "isometric";
2124
2561
  }
2562
+ if (kind === "dimension") {
2563
+ return "dimension";
2564
+ }
2125
2565
  return "shape";
2126
2566
  }
2127
2567
  function classifyCanvasObject(block2, properties, symbolDefinitions) {
@@ -2184,9 +2624,11 @@ function resolveCanvasObject(block2, origin, context, frameId, positionOverride)
2184
2624
  case "chart":
2185
2625
  return resolveChartObject(base, block2, properties, symbolDefs, mergedProps);
2186
2626
  case "isometric":
2187
- return resolveIsometricObject(base, block2, properties, layoutProp);
2627
+ return resolveIsometricObject(base, block2, properties, layoutProp, symbolDefs);
2188
2628
  case "path":
2189
2629
  return resolvePathObject(base, properties, origin);
2630
+ case "dimension":
2631
+ return resolveDimensionObject(base, properties, origin);
2190
2632
  case "swimlane":
2191
2633
  return resolveSwimlaneObject(base, properties);
2192
2634
  case "frame":
@@ -2320,12 +2762,13 @@ function resolveCanvasTree(model, resolution) {
2320
2762
  function readShaderDefinition(block2) {
2321
2763
  const properties = directProperties(block2);
2322
2764
  const program = asString(properties.get("program"));
2765
+ const surfacePadding = asNumber(properties.get("surfacePadding"));
2323
2766
  if (!program) {
2324
2767
  return void 0;
2325
2768
  }
2326
2769
  const parameters = {};
2327
2770
  for (const [key, value] of properties) {
2328
- if (key === "program") {
2771
+ if (key === "program" || key === "surfacePadding") {
2329
2772
  continue;
2330
2773
  }
2331
2774
  const number = asNumber(value);
@@ -2336,23 +2779,35 @@ function readShaderDefinition(block2) {
2336
2779
  parameters[key] = text === "true" ? true : text === "false" ? false : text;
2337
2780
  }
2338
2781
  }
2339
- return { name: block2.name, program, parameters };
2782
+ return {
2783
+ name: block2.name,
2784
+ program,
2785
+ ...surfacePadding === void 0 ? {} : { surfacePadding: Math.max(0, surfacePadding) },
2786
+ parameters
2787
+ };
2340
2788
  }
2341
2789
 
2342
2790
  // src/sflSemantic/definitions/symbols.ts
2343
2791
  function readSymbolPoints(block2) {
2344
2792
  const value = directProperties(block2).get("points");
2793
+ const points = [];
2794
+ const tensions = [];
2345
2795
  if (value?.type !== "list") {
2346
- return [];
2796
+ return { points, tensions };
2347
2797
  }
2348
- return value.values.flatMap((item) => {
2798
+ for (const item of value.values) {
2349
2799
  if (item.type !== "list" || item.values.length < 2) {
2350
- return [];
2800
+ continue;
2351
2801
  }
2352
2802
  const x = asNumber(item.values[0]);
2353
2803
  const y = asNumber(item.values[1]);
2354
- return x === void 0 || y === void 0 ? [] : [[x, y]];
2355
- });
2804
+ if (x === void 0 || y === void 0) {
2805
+ continue;
2806
+ }
2807
+ points.push([x, y]);
2808
+ tensions.push(item.values[2] === void 0 ? void 0 : asNumber(item.values[2]));
2809
+ }
2810
+ return { points, tensions };
2356
2811
  }
2357
2812
  function readSymbolPorts(block2) {
2358
2813
  const ports = childBlocks(block2).filter((child) => child.kind === "Port").flatMap((port) => {
@@ -2365,13 +2820,14 @@ function readSymbolPorts(block2) {
2365
2820
  return ports.length > 0 ? ports : void 0;
2366
2821
  }
2367
2822
  function readSymbolDefinition(block2) {
2368
- const points = readSymbolPoints(block2);
2823
+ const { points, tensions } = readSymbolPoints(block2);
2369
2824
  if (points.length < 2) {
2370
2825
  return void 0;
2371
2826
  }
2372
2827
  return {
2373
2828
  name: block2.name,
2374
2829
  points,
2830
+ pointTensions: tensions.some((tension) => tension !== void 0) ? tensions : void 0,
2375
2831
  tension: asNumber(directProperties(block2).get("tension")),
2376
2832
  ports: readSymbolPorts(block2)
2377
2833
  };
@@ -2912,43 +3368,25 @@ function freeformPathData(geometry) {
2912
3368
  if (geometry.points.length === 0) {
2913
3369
  return "";
2914
3370
  }
2915
- if (geometry.points.length < 3 || geometry.tension <= 0) {
3371
+ if (isStraight(geometry)) {
2916
3372
  return linearPathData(geometry);
2917
3373
  }
2918
- return smoothPathData(geometry);
2919
- }
2920
- function linearPathData(geometry) {
2921
- const [first, ...remaining] = geometry.points;
2922
- const segments = remaining.map((point) => `L ${point.x} ${point.y}`).join(" ");
2923
- return `M ${first.x} ${first.y} ${segments}${geometry.closed ? " Z" : ""}`;
2924
- }
2925
- function smoothPathData(geometry) {
2926
3374
  const first = geometry.points[0];
2927
- const segmentCount = geometry.closed ? geometry.points.length : geometry.points.length - 1;
2928
3375
  const commands = [`M ${first.x} ${first.y}`];
2929
- for (let index = 0; index < segmentCount; index++) {
2930
- commands.push(curveSegmentCommand(geometry, index));
3376
+ for (const { to, controls } of pathSegments(geometry)) {
3377
+ commands.push(
3378
+ controls ? `C ${controls[0].x} ${controls[0].y} ${controls[1].x} ${controls[1].y} ${to.x} ${to.y}` : `L ${to.x} ${to.y}`
3379
+ );
2931
3380
  }
2932
3381
  if (geometry.closed) {
2933
3382
  commands.push("Z");
2934
3383
  }
2935
3384
  return commands.join(" ");
2936
3385
  }
2937
- function curveSegmentCommand(geometry, index) {
2938
- const previous = freeformPointAt(geometry, index - 1);
2939
- const start = freeformPointAt(geometry, index);
2940
- const end = freeformPointAt(geometry, index + 1);
2941
- const next = freeformPointAt(geometry, index + 2);
2942
- const factor = geometry.tension / 6;
2943
- const firstControl = { x: start.x + (end.x - previous.x) * factor, y: start.y + (end.y - previous.y) * factor };
2944
- const secondControl = { x: end.x - (next.x - start.x) * factor, y: end.y - (next.y - start.y) * factor };
2945
- return `C ${firstControl.x} ${firstControl.y} ${secondControl.x} ${secondControl.y} ${end.x} ${end.y}`;
2946
- }
2947
- function freeformPointAt(geometry, index) {
2948
- if (geometry.closed) {
2949
- return geometry.points[(index + geometry.points.length) % geometry.points.length];
2950
- }
2951
- return geometry.points[Math.max(0, Math.min(geometry.points.length - 1, index))];
3386
+ function linearPathData(geometry) {
3387
+ const [first, ...remaining] = geometry.points;
3388
+ const segments = remaining.map((point) => `L ${point.x} ${point.y}`).join(" ");
3389
+ return `M ${first.x} ${first.y} ${segments}${geometry.closed ? " Z" : ""}`;
2952
3390
  }
2953
3391
 
2954
3392
  // src/renderScene/charts/primitives/radarShape.ts
@@ -3447,8 +3885,8 @@ function createRoundedCorner(previous, corner, next, maximumRadius) {
3447
3885
  const outgoing = { x: next.x - corner.x, y: next.y - corner.y };
3448
3886
  const incomingIsAxisAligned = incoming.x === 0 || incoming.y === 0;
3449
3887
  const outgoingIsAxisAligned = outgoing.x === 0 || outgoing.y === 0;
3450
- const isStraight = incoming.x === 0 && outgoing.x === 0 || incoming.y === 0 && outgoing.y === 0;
3451
- if (!incomingIsAxisAligned || !outgoingIsAxisAligned || isStraight) {
3888
+ const isStraight2 = incoming.x === 0 && outgoing.x === 0 || incoming.y === 0 && outgoing.y === 0;
3889
+ if (!incomingIsAxisAligned || !outgoingIsAxisAligned || isStraight2) {
3452
3890
  return null;
3453
3891
  }
3454
3892
  const radius = Math.min(maximumRadius, axisLength(incoming) * 0.4, axisLength(outgoing) * 0.4);
@@ -4877,6 +5315,7 @@ exports.CATEGORY_LABEL_ROW = CATEGORY_LABEL_ROW;
4877
5315
  exports.CHART_COLORS = CHART_COLORS;
4878
5316
  exports.CHART_TITLE_PROP = CHART_TITLE_PROP;
4879
5317
  exports.CHART_TYPES = CHART_TYPES;
5318
+ exports.COMPONENT_CATEGORIES = COMPONENT_CATEGORIES;
4880
5319
  exports.CORNER_RADIUS_ATTR = CORNER_RADIUS_ATTR;
4881
5320
  exports.DEFAULT_FONT = DEFAULT_FONT;
4882
5321
  exports.DEFAULT_HEATMAP_ZONES = DEFAULT_HEATMAP_ZONES;
@@ -4912,9 +5351,11 @@ exports.canonicalizeSource = canonicalizeSource;
4912
5351
  exports.categoryProp = categoryProp;
4913
5352
  exports.chartText = chartText;
4914
5353
  exports.chartTicks = chartTicks;
5354
+ exports.cleanFootprint = cleanFootprint;
4915
5355
  exports.clipSegmentToRect = clipSegmentToRect;
4916
5356
  exports.colorWithAlpha = colorWithAlpha;
4917
5357
  exports.componentRegistryVersion = componentRegistryVersion;
5358
+ exports.componentTypes = componentTypes;
4918
5359
  exports.computeBoxplotStats = computeBoxplotStats;
4919
5360
  exports.contrastTextColor = contrastTextColor;
4920
5361
  exports.cornersRoundedRectPath = cornersRoundedRectPath;
@@ -4927,7 +5368,9 @@ exports.elementCenter = elementCenter;
4927
5368
  exports.ellipsizeToWidth = ellipsizeToWidth;
4928
5369
  exports.errorBarRange = errorBarRange;
4929
5370
  exports.estimateTextWidth = estimateTextWidth;
5371
+ exports.extrudeFootprint = extrudeFootprint;
4930
5372
  exports.finite = finite;
5373
+ exports.flattenPath = flattenPath;
4931
5374
  exports.formatBarLabel = formatBarLabel;
4932
5375
  exports.formatFieldValue = formatFieldValue;
4933
5376
  exports.formatRollingNumber = formatRollingNumber;
@@ -4940,6 +5383,7 @@ exports.horizontalRows = horizontalRows;
4940
5383
  exports.interpolateHexColorStops = interpolateHexColorStops;
4941
5384
  exports.isBuiltInComponentType = isBuiltInComponentType;
4942
5385
  exports.isChartObject = isChartObject;
5386
+ exports.isDimensionObject = isDimensionObject;
4943
5387
  exports.isGenericComponent = isGenericComponent;
4944
5388
  exports.isHorizontalBar = isHorizontalBar;
4945
5389
  exports.isIsometricObject = isIsometricObject;
@@ -4959,6 +5403,8 @@ exports.maxApexCornerRadius = maxApexCornerRadius;
4959
5403
  exports.maxPieCornerRadius = maxPieCornerRadius;
4960
5404
  exports.paint = paint;
4961
5405
  exports.parseSource = parseSource;
5406
+ exports.pathBounds = pathBounds;
5407
+ exports.pathToSymbol = pathToSymbol;
4962
5408
  exports.personLabelArea = personLabelArea;
4963
5409
  exports.pieApexRadius = pieApexRadius;
4964
5410
  exports.pieArcPoint = pieArcPoint;
@@ -4999,13 +5445,15 @@ exports.seriesLabelProp = seriesLabelProp;
4999
5445
  exports.seriesValueColorProp = seriesValueColorProp;
5000
5446
  exports.seriesValueProp = seriesValueProp;
5001
5447
  exports.sflToCanvasState = sflToCanvasState;
5448
+ exports.shadeFill = shadeFill;
5002
5449
  exports.stackRank = stackRank;
5003
5450
  exports.stackSequence = stackSequence;
5004
5451
  exports.stackedSegment = stackedSegment;
5452
+ exports.symbolToPath = symbolToPath;
5005
5453
  exports.tag = tag;
5006
5454
  exports.tokenizeSource = tokenizeSource;
5007
5455
  exports.topRoundedRectPath = topRoundedRectPath;
5008
5456
  exports.wrapText = wrapText;
5009
5457
  exports.zoneColorAtValue = zoneColorAtValue;
5010
- //# sourceMappingURL=chunk-XY2GZUHC.cjs.map
5011
- //# sourceMappingURL=chunk-XY2GZUHC.cjs.map
5458
+ //# sourceMappingURL=chunk-KXYSO6GC.cjs.map
5459
+ //# sourceMappingURL=chunk-KXYSO6GC.cjs.map