@goplasmatic/datalogic-ui 4.0.21 → 5.0.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 (38) hide show
  1. package/README.md +35 -15
  2. package/dist/components/logic-editor/DataLogicEditor.d.ts +1 -1
  3. package/dist/components/logic-editor/DataLogicEditor.d.ts.map +1 -1
  4. package/dist/components/logic-editor/EditorToolbar.d.ts +3 -3
  5. package/dist/components/logic-editor/EditorToolbar.d.ts.map +1 -1
  6. package/dist/components/logic-editor/UndoRedoToolbar.d.ts.map +1 -1
  7. package/dist/components/logic-editor/config/operators/utility.d.ts.map +1 -1
  8. package/dist/components/logic-editor/context/editor/useClipboardState.d.ts.map +1 -1
  9. package/dist/components/logic-editor/context/editor/useHistoryState.d.ts.map +1 -1
  10. package/dist/components/logic-editor/debugger-controls/DebuggerControls.d.ts.map +1 -1
  11. package/dist/components/logic-editor/hooks/index.d.ts +1 -1
  12. package/dist/components/logic-editor/hooks/index.d.ts.map +1 -1
  13. package/dist/components/logic-editor/hooks/useLogicEditor.d.ts +3 -3
  14. package/dist/components/logic-editor/hooks/useLogicEditor.d.ts.map +1 -1
  15. package/dist/components/logic-editor/hooks/useWasmEvaluator.d.ts +8 -3
  16. package/dist/components/logic-editor/hooks/useWasmEvaluator.d.ts.map +1 -1
  17. package/dist/components/logic-editor/types/editor.d.ts +18 -6
  18. package/dist/components/logic-editor/types/editor.d.ts.map +1 -1
  19. package/dist/components/logic-editor/types/index.d.ts +1 -1
  20. package/dist/components/logic-editor/types/index.d.ts.map +1 -1
  21. package/dist/components/logic-editor/types/trace.d.ts +22 -0
  22. package/dist/components/logic-editor/types/trace.d.ts.map +1 -1
  23. package/dist/components/logic-editor/utils/converters/types.d.ts +2 -2
  24. package/dist/components/logic-editor/utils/converters/types.d.ts.map +1 -1
  25. package/dist/components/logic-editor/utils/jsonlogic-to-nodes.d.ts +2 -2
  26. package/dist/components/logic-editor/utils/jsonlogic-to-nodes.d.ts.map +1 -1
  27. package/dist/components/logic-editor/utils/trace/node-type.d.ts +1 -1
  28. package/dist/components/logic-editor/utils/trace/node-type.d.ts.map +1 -1
  29. package/dist/components/logic-editor/utils/trace/types.d.ts +3 -3
  30. package/dist/components/logic-editor/utils/trace/types.d.ts.map +1 -1
  31. package/dist/datalogic_wasm-CF1jcNAu.js +634 -0
  32. package/dist/datalogic_wasm-Dj9TEPTG.cjs +637 -0
  33. package/dist/index.cjs +868 -388
  34. package/dist/index.js +869 -389
  35. package/dist/styles.css +302 -136
  36. package/package.json +32 -29
  37. package/dist/datalogic_wasm-Ckkdrc0z.cjs +0 -383
  38. package/dist/datalogic_wasm-daWVf40b.js +0 -380
package/dist/index.cjs CHANGED
@@ -26,9 +26,9 @@ react = __toESM(react, 1);
26
26
  let _xyflow_react = require("@xyflow/react");
27
27
  let react_jsx_runtime = require("react/jsx-runtime");
28
28
  let react_dom = require("react-dom");
29
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
29
+ //#region node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs
30
30
  /**
31
- * @license lucide-react v1.8.0 - ISC
31
+ * @license lucide-react v1.14.0 - ISC
32
32
  *
33
33
  * This source code is licensed under the ISC license.
34
34
  * See the LICENSE file in the root directory of this source tree.
@@ -37,27 +37,27 @@ var mergeClasses = (...classes) => classes.filter((className, index, array) => {
37
37
  return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
38
38
  }).join(" ").trim();
39
39
  //#endregion
40
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.js
40
+ //#region node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs
41
41
  /**
42
- * @license lucide-react v1.8.0 - ISC
42
+ * @license lucide-react v1.14.0 - ISC
43
43
  *
44
44
  * This source code is licensed under the ISC license.
45
45
  * See the LICENSE file in the root directory of this source tree.
46
46
  */
47
47
  var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
48
48
  //#endregion
49
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.js
49
+ //#region node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs
50
50
  /**
51
- * @license lucide-react v1.8.0 - ISC
51
+ * @license lucide-react v1.14.0 - ISC
52
52
  *
53
53
  * This source code is licensed under the ISC license.
54
54
  * See the LICENSE file in the root directory of this source tree.
55
55
  */
56
56
  var toCamelCase = (string) => string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase());
57
57
  //#endregion
58
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.js
58
+ //#region node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs
59
59
  /**
60
- * @license lucide-react v1.8.0 - ISC
60
+ * @license lucide-react v1.14.0 - ISC
61
61
  *
62
62
  * This source code is licensed under the ISC license.
63
63
  * See the LICENSE file in the root directory of this source tree.
@@ -67,9 +67,9 @@ var toPascalCase = (string) => {
67
67
  return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
68
68
  };
69
69
  //#endregion
70
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/defaultAttributes.js
70
+ //#region node_modules/lucide-react/dist/esm/defaultAttributes.mjs
71
71
  /**
72
- * @license lucide-react v1.8.0 - ISC
72
+ * @license lucide-react v1.14.0 - ISC
73
73
  *
74
74
  * This source code is licensed under the ISC license.
75
75
  * See the LICENSE file in the root directory of this source tree.
@@ -86,9 +86,9 @@ var defaultAttributes = {
86
86
  strokeLinejoin: "round"
87
87
  };
88
88
  //#endregion
89
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.js
89
+ //#region node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs
90
90
  /**
91
- * @license lucide-react v1.8.0 - ISC
91
+ * @license lucide-react v1.14.0 - ISC
92
92
  *
93
93
  * This source code is licensed under the ISC license.
94
94
  * See the LICENSE file in the root directory of this source tree.
@@ -98,9 +98,9 @@ var hasA11yProp = (props) => {
98
98
  return false;
99
99
  };
100
100
  //#endregion
101
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/context.js
101
+ //#region node_modules/lucide-react/dist/esm/context.mjs
102
102
  /**
103
- * @license lucide-react v1.8.0 - ISC
103
+ * @license lucide-react v1.14.0 - ISC
104
104
  *
105
105
  * This source code is licensed under the ISC license.
106
106
  * See the LICENSE file in the root directory of this source tree.
@@ -108,9 +108,9 @@ var hasA11yProp = (props) => {
108
108
  var LucideContext = (0, react.createContext)({});
109
109
  var useLucideContext = () => (0, react.useContext)(LucideContext);
110
110
  //#endregion
111
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/Icon.js
111
+ //#region node_modules/lucide-react/dist/esm/Icon.mjs
112
112
  /**
113
- * @license lucide-react v1.8.0 - ISC
113
+ * @license lucide-react v1.14.0 - ISC
114
114
  *
115
115
  * This source code is licensed under the ISC license.
116
116
  * See the LICENSE file in the root directory of this source tree.
@@ -131,9 +131,9 @@ var Icon$1 = (0, react.forwardRef)(({ color, size, strokeWidth, absoluteStrokeWi
131
131
  }, [...iconNode.map(([tag, attrs]) => (0, react.createElement)(tag, attrs)), ...Array.isArray(children) ? children : [children]]);
132
132
  });
133
133
  //#endregion
134
- //#region ../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/createLucideIcon.js
134
+ //#region node_modules/lucide-react/dist/esm/createLucideIcon.mjs
135
135
  /**
136
- * @license lucide-react v1.8.0 - ISC
136
+ * @license lucide-react v1.14.0 - ISC
137
137
  *
138
138
  * This source code is licensed under the ISC license.
139
139
  * See the LICENSE file in the root directory of this source tree.
@@ -148,6 +148,12 @@ var createLucideIcon = (iconName, iconNode) => {
148
148
  Component.displayName = toPascalCase(iconName);
149
149
  return Component;
150
150
  };
151
+ /**
152
+ * @license lucide-react v1.14.0 - ISC
153
+ *
154
+ * This source code is licensed under the ISC license.
155
+ * See the LICENSE file in the root directory of this source tree.
156
+ */
151
157
  var ArrowUp = createLucideIcon("arrow-up", [["path", {
152
158
  d: "m5 12 7-7 7 7",
153
159
  key: "hav0vg"
@@ -155,6 +161,12 @@ var ArrowUp = createLucideIcon("arrow-up", [["path", {
155
161
  d: "M12 19V5",
156
162
  key: "x0mq9r"
157
163
  }]]);
164
+ /**
165
+ * @license lucide-react v1.14.0 - ISC
166
+ *
167
+ * This source code is licensed under the ISC license.
168
+ * See the LICENSE file in the root directory of this source tree.
169
+ */
158
170
  var Ban = createLucideIcon("ban", [["circle", {
159
171
  cx: "12",
160
172
  cy: "12",
@@ -164,6 +176,12 @@ var Ban = createLucideIcon("ban", [["circle", {
164
176
  d: "M4.929 4.929 19.07 19.071",
165
177
  key: "196cmz"
166
178
  }]]);
179
+ /**
180
+ * @license lucide-react v1.14.0 - ISC
181
+ *
182
+ * This source code is licensed under the ISC license.
183
+ * See the LICENSE file in the root directory of this source tree.
184
+ */
167
185
  var Binary = createLucideIcon("binary", [
168
186
  ["rect", {
169
187
  x: "14",
@@ -198,6 +216,12 @@ var Binary = createLucideIcon("binary", [
198
216
  key: "1idq9u"
199
217
  }]
200
218
  ]);
219
+ /**
220
+ * @license lucide-react v1.14.0 - ISC
221
+ *
222
+ * This source code is licensed under the ISC license.
223
+ * See the LICENSE file in the root directory of this source tree.
224
+ */
201
225
  var Box = createLucideIcon("box", [
202
226
  ["path", {
203
227
  d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z",
@@ -212,6 +236,12 @@ var Box = createLucideIcon("box", [
212
236
  key: "d0xqtd"
213
237
  }]
214
238
  ]);
239
+ /**
240
+ * @license lucide-react v1.14.0 - ISC
241
+ *
242
+ * This source code is licensed under the ISC license.
243
+ * See the LICENSE file in the root directory of this source tree.
244
+ */
215
245
  var Boxes = createLucideIcon("boxes", [
216
246
  ["path", {
217
247
  d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",
@@ -262,6 +292,12 @@ var Boxes = createLucideIcon("boxes", [
262
292
  key: "1io7kd"
263
293
  }]
264
294
  ]);
295
+ /**
296
+ * @license lucide-react v1.14.0 - ISC
297
+ *
298
+ * This source code is licensed under the ISC license.
299
+ * See the LICENSE file in the root directory of this source tree.
300
+ */
265
301
  var Braces = createLucideIcon("braces", [["path", {
266
302
  d: "M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1",
267
303
  key: "ezmyqa"
@@ -269,6 +305,12 @@ var Braces = createLucideIcon("braces", [["path", {
269
305
  d: "M16 21h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1",
270
306
  key: "e1hn23"
271
307
  }]]);
308
+ /**
309
+ * @license lucide-react v1.14.0 - ISC
310
+ *
311
+ * This source code is licensed under the ISC license.
312
+ * See the LICENSE file in the root directory of this source tree.
313
+ */
272
314
  var Bug = createLucideIcon("bug", [
273
315
  ["path", {
274
316
  d: "M12 20v-9",
@@ -315,6 +357,12 @@ var Bug = createLucideIcon("bug", [
315
357
  key: "1vgav8"
316
358
  }]
317
359
  ]);
360
+ /**
361
+ * @license lucide-react v1.14.0 - ISC
362
+ *
363
+ * This source code is licensed under the ISC license.
364
+ * See the LICENSE file in the root directory of this source tree.
365
+ */
318
366
  var Calculator = createLucideIcon("calculator", [
319
367
  ["rect", {
320
368
  width: "16",
@@ -367,6 +415,12 @@ var Calculator = createLucideIcon("calculator", [
367
415
  key: "lrp35t"
368
416
  }]
369
417
  ]);
418
+ /**
419
+ * @license lucide-react v1.14.0 - ISC
420
+ *
421
+ * This source code is licensed under the ISC license.
422
+ * See the LICENSE file in the root directory of this source tree.
423
+ */
370
424
  var Calendar = createLucideIcon("calendar", [
371
425
  ["path", {
372
426
  d: "M8 2v4",
@@ -389,22 +443,52 @@ var Calendar = createLucideIcon("calendar", [
389
443
  key: "8toen8"
390
444
  }]
391
445
  ]);
446
+ /**
447
+ * @license lucide-react v1.14.0 - ISC
448
+ *
449
+ * This source code is licensed under the ISC license.
450
+ * See the LICENSE file in the root directory of this source tree.
451
+ */
392
452
  var Check = createLucideIcon("check", [["path", {
393
453
  d: "M20 6 9 17l-5-5",
394
454
  key: "1gmf2c"
395
455
  }]]);
456
+ /**
457
+ * @license lucide-react v1.14.0 - ISC
458
+ *
459
+ * This source code is licensed under the ISC license.
460
+ * See the LICENSE file in the root directory of this source tree.
461
+ */
396
462
  var ChevronDown = createLucideIcon("chevron-down", [["path", {
397
463
  d: "m6 9 6 6 6-6",
398
464
  key: "qrunsl"
399
465
  }]]);
466
+ /**
467
+ * @license lucide-react v1.14.0 - ISC
468
+ *
469
+ * This source code is licensed under the ISC license.
470
+ * See the LICENSE file in the root directory of this source tree.
471
+ */
400
472
  var ChevronLeft = createLucideIcon("chevron-left", [["path", {
401
473
  d: "m15 18-6-6 6-6",
402
474
  key: "1wnfg3"
403
475
  }]]);
476
+ /**
477
+ * @license lucide-react v1.14.0 - ISC
478
+ *
479
+ * This source code is licensed under the ISC license.
480
+ * See the LICENSE file in the root directory of this source tree.
481
+ */
404
482
  var ChevronRight = createLucideIcon("chevron-right", [["path", {
405
483
  d: "m9 18 6-6-6-6",
406
484
  key: "mthhwq"
407
485
  }]]);
486
+ /**
487
+ * @license lucide-react v1.14.0 - ISC
488
+ *
489
+ * This source code is licensed under the ISC license.
490
+ * See the LICENSE file in the root directory of this source tree.
491
+ */
408
492
  var CircleAlert = createLucideIcon("circle-alert", [
409
493
  ["circle", {
410
494
  cx: "12",
@@ -427,6 +511,12 @@ var CircleAlert = createLucideIcon("circle-alert", [
427
511
  key: "4dfq90"
428
512
  }]
429
513
  ]);
514
+ /**
515
+ * @license lucide-react v1.14.0 - ISC
516
+ *
517
+ * This source code is licensed under the ISC license.
518
+ * See the LICENSE file in the root directory of this source tree.
519
+ */
430
520
  var CircleQuestionMark = createLucideIcon("circle-question-mark", [
431
521
  ["circle", {
432
522
  cx: "12",
@@ -443,6 +533,12 @@ var CircleQuestionMark = createLucideIcon("circle-question-mark", [
443
533
  key: "p32p05"
444
534
  }]
445
535
  ]);
536
+ /**
537
+ * @license lucide-react v1.14.0 - ISC
538
+ *
539
+ * This source code is licensed under the ISC license.
540
+ * See the LICENSE file in the root directory of this source tree.
541
+ */
446
542
  var CircleX = createLucideIcon("circle-x", [
447
543
  ["circle", {
448
544
  cx: "12",
@@ -459,6 +555,12 @@ var CircleX = createLucideIcon("circle-x", [
459
555
  key: "z0biqf"
460
556
  }]
461
557
  ]);
558
+ /**
559
+ * @license lucide-react v1.14.0 - ISC
560
+ *
561
+ * This source code is licensed under the ISC license.
562
+ * See the LICENSE file in the root directory of this source tree.
563
+ */
462
564
  var Clipboard = createLucideIcon("clipboard", [["rect", {
463
565
  width: "8",
464
566
  height: "4",
@@ -471,6 +573,12 @@ var Clipboard = createLucideIcon("clipboard", [["rect", {
471
573
  d: "M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",
472
574
  key: "116196"
473
575
  }]]);
576
+ /**
577
+ * @license lucide-react v1.14.0 - ISC
578
+ *
579
+ * This source code is licensed under the ISC license.
580
+ * See the LICENSE file in the root directory of this source tree.
581
+ */
474
582
  var Clock = createLucideIcon("clock", [["circle", {
475
583
  cx: "12",
476
584
  cy: "12",
@@ -480,6 +588,12 @@ var Clock = createLucideIcon("clock", [["circle", {
480
588
  d: "M12 6v6l4 2",
481
589
  key: "mmk7yg"
482
590
  }]]);
591
+ /**
592
+ * @license lucide-react v1.14.0 - ISC
593
+ *
594
+ * This source code is licensed under the ISC license.
595
+ * See the LICENSE file in the root directory of this source tree.
596
+ */
483
597
  var Cog = createLucideIcon("cog", [
484
598
  ["path", {
485
599
  d: "M11 10.27 7 3.34",
@@ -542,6 +656,12 @@ var Cog = createLucideIcon("cog", [
542
656
  key: "46899m"
543
657
  }]
544
658
  ]);
659
+ /**
660
+ * @license lucide-react v1.14.0 - ISC
661
+ *
662
+ * This source code is licensed under the ISC license.
663
+ * See the LICENSE file in the root directory of this source tree.
664
+ */
545
665
  var Copy = createLucideIcon("copy", [["rect", {
546
666
  width: "14",
547
667
  height: "14",
@@ -554,6 +674,12 @@ var Copy = createLucideIcon("copy", [["rect", {
554
674
  d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",
555
675
  key: "zix9uf"
556
676
  }]]);
677
+ /**
678
+ * @license lucide-react v1.14.0 - ISC
679
+ *
680
+ * This source code is licensed under the ISC license.
681
+ * See the LICENSE file in the root directory of this source tree.
682
+ */
557
683
  var Database = createLucideIcon("database", [
558
684
  ["ellipse", {
559
685
  cx: "12",
@@ -571,10 +697,22 @@ var Database = createLucideIcon("database", [
571
697
  key: "mv7ke4"
572
698
  }]
573
699
  ]);
700
+ /**
701
+ * @license lucide-react v1.14.0 - ISC
702
+ *
703
+ * This source code is licensed under the ISC license.
704
+ * See the LICENSE file in the root directory of this source tree.
705
+ */
574
706
  var Diamond = createLucideIcon("diamond", [["path", {
575
707
  d: "M2.7 10.3a2.41 2.41 0 0 0 0 3.41l7.59 7.59a2.41 2.41 0 0 0 3.41 0l7.59-7.59a2.41 2.41 0 0 0 0-3.41l-7.59-7.59a2.41 2.41 0 0 0-3.41 0Z",
576
708
  key: "1f1r0c"
577
709
  }]]);
710
+ /**
711
+ * @license lucide-react v1.14.0 - ISC
712
+ *
713
+ * This source code is licensed under the ISC license.
714
+ * See the LICENSE file in the root directory of this source tree.
715
+ */
578
716
  var Divide = createLucideIcon("divide", [
579
717
  ["circle", {
580
718
  cx: "12",
@@ -596,6 +734,12 @@ var Divide = createLucideIcon("divide", [
596
734
  key: "lqb9t5"
597
735
  }]
598
736
  ]);
737
+ /**
738
+ * @license lucide-react v1.14.0 - ISC
739
+ *
740
+ * This source code is licensed under the ISC license.
741
+ * See the LICENSE file in the root directory of this source tree.
742
+ */
599
743
  var ExternalLink = createLucideIcon("external-link", [
600
744
  ["path", {
601
745
  d: "M15 3h6v6",
@@ -610,6 +754,36 @@ var ExternalLink = createLucideIcon("external-link", [
610
754
  key: "a6xqqp"
611
755
  }]
612
756
  ]);
757
+ /**
758
+ * @license lucide-react v1.14.0 - ISC
759
+ *
760
+ * This source code is licensed under the ISC license.
761
+ * See the LICENSE file in the root directory of this source tree.
762
+ */
763
+ var GitBranch = createLucideIcon("git-branch", [
764
+ ["path", {
765
+ d: "M15 6a9 9 0 0 0-9 9V3",
766
+ key: "1cii5b"
767
+ }],
768
+ ["circle", {
769
+ cx: "18",
770
+ cy: "6",
771
+ r: "3",
772
+ key: "1h7g24"
773
+ }],
774
+ ["circle", {
775
+ cx: "6",
776
+ cy: "18",
777
+ r: "3",
778
+ key: "fqmcym"
779
+ }]
780
+ ]);
781
+ /**
782
+ * @license lucide-react v1.14.0 - ISC
783
+ *
784
+ * This source code is licensed under the ISC license.
785
+ * See the LICENSE file in the root directory of this source tree.
786
+ */
613
787
  var GitCommitHorizontal = createLucideIcon("git-commit-horizontal", [
614
788
  ["circle", {
615
789
  cx: "12",
@@ -632,24 +806,12 @@ var GitCommitHorizontal = createLucideIcon("git-commit-horizontal", [
632
806
  key: "oup4p8"
633
807
  }]
634
808
  ]);
635
- var GitBranch = createLucideIcon("git-branch", [
636
- ["path", {
637
- d: "M15 6a9 9 0 0 0-9 9V3",
638
- key: "1cii5b"
639
- }],
640
- ["circle", {
641
- cx: "18",
642
- cy: "6",
643
- r: "3",
644
- key: "1h7g24"
645
- }],
646
- ["circle", {
647
- cx: "6",
648
- cy: "18",
649
- r: "3",
650
- key: "fqmcym"
651
- }]
652
- ]);
809
+ /**
810
+ * @license lucide-react v1.14.0 - ISC
811
+ *
812
+ * This source code is licensed under the ISC license.
813
+ * See the LICENSE file in the root directory of this source tree.
814
+ */
653
815
  var GitMerge = createLucideIcon("git-merge", [
654
816
  ["circle", {
655
817
  cx: "18",
@@ -668,6 +830,12 @@ var GitMerge = createLucideIcon("git-merge", [
668
830
  key: "7kw0sc"
669
831
  }]
670
832
  ]);
833
+ /**
834
+ * @license lucide-react v1.14.0 - ISC
835
+ *
836
+ * This source code is licensed under the ISC license.
837
+ * See the LICENSE file in the root directory of this source tree.
838
+ */
671
839
  var Hash = createLucideIcon("hash", [
672
840
  ["line", {
673
841
  x1: "4",
@@ -698,6 +866,12 @@ var Hash = createLucideIcon("hash", [
698
866
  key: "weycgp"
699
867
  }]
700
868
  ]);
869
+ /**
870
+ * @license lucide-react v1.14.0 - ISC
871
+ *
872
+ * This source code is licensed under the ISC license.
873
+ * See the LICENSE file in the root directory of this source tree.
874
+ */
701
875
  var Layers = createLucideIcon("layers", [
702
876
  ["path", {
703
877
  d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",
@@ -712,6 +886,12 @@ var Layers = createLucideIcon("layers", [
712
886
  key: "kqbvx6"
713
887
  }]
714
888
  ]);
889
+ /**
890
+ * @license lucide-react v1.14.0 - ISC
891
+ *
892
+ * This source code is licensed under the ISC license.
893
+ * See the LICENSE file in the root directory of this source tree.
894
+ */
715
895
  var Link2Off = createLucideIcon("link-2-off", [
716
896
  ["path", {
717
897
  d: "M9 17H7A5 5 0 0 1 7 7",
@@ -736,6 +916,12 @@ var Link2Off = createLucideIcon("link-2-off", [
736
916
  key: "a6p6uj"
737
917
  }]
738
918
  ]);
919
+ /**
920
+ * @license lucide-react v1.14.0 - ISC
921
+ *
922
+ * This source code is licensed under the ISC license.
923
+ * See the LICENSE file in the root directory of this source tree.
924
+ */
739
925
  var List = createLucideIcon("list", [
740
926
  ["path", {
741
927
  d: "M3 5h.01",
@@ -762,6 +948,12 @@ var List = createLucideIcon("list", [
762
948
  key: "m83p4d"
763
949
  }]
764
950
  ]);
951
+ /**
952
+ * @license lucide-react v1.14.0 - ISC
953
+ *
954
+ * This source code is licensed under the ISC license.
955
+ * See the LICENSE file in the root directory of this source tree.
956
+ */
765
957
  var Maximize = createLucideIcon("maximize", [
766
958
  ["path", {
767
959
  d: "M8 3H5a2 2 0 0 0-2 2v3",
@@ -780,10 +972,22 @@ var Maximize = createLucideIcon("maximize", [
780
972
  key: "18trek"
781
973
  }]
782
974
  ]);
975
+ /**
976
+ * @license lucide-react v1.14.0 - ISC
977
+ *
978
+ * This source code is licensed under the ISC license.
979
+ * See the LICENSE file in the root directory of this source tree.
980
+ */
783
981
  var MousePointer2 = createLucideIcon("mouse-pointer-2", [["path", {
784
982
  d: "M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z",
785
983
  key: "edeuup"
786
984
  }]]);
985
+ /**
986
+ * @license lucide-react v1.14.0 - ISC
987
+ *
988
+ * This source code is licensed under the ISC license.
989
+ * See the LICENSE file in the root directory of this source tree.
990
+ */
787
991
  var Pause = createLucideIcon("pause", [["rect", {
788
992
  x: "14",
789
993
  y: "3",
@@ -799,6 +1003,12 @@ var Pause = createLucideIcon("pause", [["rect", {
799
1003
  rx: "1",
800
1004
  key: "1wsw3u"
801
1005
  }]]);
1006
+ /**
1007
+ * @license lucide-react v1.14.0 - ISC
1008
+ *
1009
+ * This source code is licensed under the ISC license.
1010
+ * See the LICENSE file in the root directory of this source tree.
1011
+ */
802
1012
  var PenLine = createLucideIcon("pen-line", [["path", {
803
1013
  d: "M13 21h8",
804
1014
  key: "1jsn5i"
@@ -806,10 +1016,22 @@ var PenLine = createLucideIcon("pen-line", [["path", {
806
1016
  d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
807
1017
  key: "1a8usu"
808
1018
  }]]);
1019
+ /**
1020
+ * @license lucide-react v1.14.0 - ISC
1021
+ *
1022
+ * This source code is licensed under the ISC license.
1023
+ * See the LICENSE file in the root directory of this source tree.
1024
+ */
809
1025
  var Play = createLucideIcon("play", [["path", {
810
1026
  d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
811
1027
  key: "10ikf1"
812
1028
  }]]);
1029
+ /**
1030
+ * @license lucide-react v1.14.0 - ISC
1031
+ *
1032
+ * This source code is licensed under the ISC license.
1033
+ * See the LICENSE file in the root directory of this source tree.
1034
+ */
813
1035
  var Plus = createLucideIcon("plus", [["path", {
814
1036
  d: "M5 12h14",
815
1037
  key: "1ays0h"
@@ -817,6 +1039,12 @@ var Plus = createLucideIcon("plus", [["path", {
817
1039
  d: "M12 5v14",
818
1040
  key: "s699le"
819
1041
  }]]);
1042
+ /**
1043
+ * @license lucide-react v1.14.0 - ISC
1044
+ *
1045
+ * This source code is licensed under the ISC license.
1046
+ * See the LICENSE file in the root directory of this source tree.
1047
+ */
820
1048
  var Quote = createLucideIcon("quote", [["path", {
821
1049
  d: "M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",
822
1050
  key: "rib7q0"
@@ -824,6 +1052,12 @@ var Quote = createLucideIcon("quote", [["path", {
824
1052
  d: "M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",
825
1053
  key: "1ymkrd"
826
1054
  }]]);
1055
+ /**
1056
+ * @license lucide-react v1.14.0 - ISC
1057
+ *
1058
+ * This source code is licensed under the ISC license.
1059
+ * See the LICENSE file in the root directory of this source tree.
1060
+ */
827
1061
  var Redo2 = createLucideIcon("redo-2", [["path", {
828
1062
  d: "m15 14 5-5-5-5",
829
1063
  key: "12vg1m"
@@ -831,6 +1065,12 @@ var Redo2 = createLucideIcon("redo-2", [["path", {
831
1065
  d: "M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13",
832
1066
  key: "6uklza"
833
1067
  }]]);
1068
+ /**
1069
+ * @license lucide-react v1.14.0 - ISC
1070
+ *
1071
+ * This source code is licensed under the ISC license.
1072
+ * See the LICENSE file in the root directory of this source tree.
1073
+ */
834
1074
  var Repeat = createLucideIcon("repeat", [
835
1075
  ["path", {
836
1076
  d: "m17 2 4 4-4 4",
@@ -849,6 +1089,12 @@ var Repeat = createLucideIcon("repeat", [
849
1089
  key: "1rx37r"
850
1090
  }]
851
1091
  ]);
1092
+ /**
1093
+ * @license lucide-react v1.14.0 - ISC
1094
+ *
1095
+ * This source code is licensed under the ISC license.
1096
+ * See the LICENSE file in the root directory of this source tree.
1097
+ */
852
1098
  var Scale = createLucideIcon("scale", [
853
1099
  ["path", {
854
1100
  d: "M12 3v18",
@@ -871,6 +1117,12 @@ var Scale = createLucideIcon("scale", [
871
1117
  key: "1b0cd5"
872
1118
  }]
873
1119
  ]);
1120
+ /**
1121
+ * @license lucide-react v1.14.0 - ISC
1122
+ *
1123
+ * This source code is licensed under the ISC license.
1124
+ * See the LICENSE file in the root directory of this source tree.
1125
+ */
874
1126
  var Search = createLucideIcon("search", [["path", {
875
1127
  d: "m21 21-4.34-4.34",
876
1128
  key: "14j7rj"
@@ -880,6 +1132,12 @@ var Search = createLucideIcon("search", [["path", {
880
1132
  r: "8",
881
1133
  key: "4ej97u"
882
1134
  }]]);
1135
+ /**
1136
+ * @license lucide-react v1.14.0 - ISC
1137
+ *
1138
+ * This source code is licensed under the ISC license.
1139
+ * See the LICENSE file in the root directory of this source tree.
1140
+ */
883
1141
  var SkipBack = createLucideIcon("skip-back", [["path", {
884
1142
  d: "M17.971 4.285A2 2 0 0 1 21 6v12a2 2 0 0 1-3.029 1.715l-9.997-5.998a2 2 0 0 1-.003-3.432z",
885
1143
  key: "15892j"
@@ -887,6 +1145,12 @@ var SkipBack = createLucideIcon("skip-back", [["path", {
887
1145
  d: "M3 20V4",
888
1146
  key: "1ptbpl"
889
1147
  }]]);
1148
+ /**
1149
+ * @license lucide-react v1.14.0 - ISC
1150
+ *
1151
+ * This source code is licensed under the ISC license.
1152
+ * See the LICENSE file in the root directory of this source tree.
1153
+ */
890
1154
  var SkipForward = createLucideIcon("skip-forward", [["path", {
891
1155
  d: "M21 4v16",
892
1156
  key: "7j8fe9"
@@ -894,6 +1158,12 @@ var SkipForward = createLucideIcon("skip-forward", [["path", {
894
1158
  d: "M6.029 4.285A2 2 0 0 0 3 6v12a2 2 0 0 0 3.029 1.715l9.997-5.998a2 2 0 0 0 .003-3.432z",
895
1159
  key: "zs4d6"
896
1160
  }]]);
1161
+ /**
1162
+ * @license lucide-react v1.14.0 - ISC
1163
+ *
1164
+ * This source code is licensed under the ISC license.
1165
+ * See the LICENSE file in the root directory of this source tree.
1166
+ */
897
1167
  var Tag = createLucideIcon("tag", [["path", {
898
1168
  d: "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",
899
1169
  key: "vktsd0"
@@ -904,6 +1174,12 @@ var Tag = createLucideIcon("tag", [["path", {
904
1174
  fill: "currentColor",
905
1175
  key: "kqv944"
906
1176
  }]]);
1177
+ /**
1178
+ * @license lucide-react v1.14.0 - ISC
1179
+ *
1180
+ * This source code is licensed under the ISC license.
1181
+ * See the LICENSE file in the root directory of this source tree.
1182
+ */
907
1183
  var TextAlignStart = createLucideIcon("text-align-start", [
908
1184
  ["path", {
909
1185
  d: "M21 5H3",
@@ -918,6 +1194,12 @@ var TextAlignStart = createLucideIcon("text-align-start", [
918
1194
  key: "z6ezky"
919
1195
  }]
920
1196
  ]);
1197
+ /**
1198
+ * @license lucide-react v1.14.0 - ISC
1199
+ *
1200
+ * This source code is licensed under the ISC license.
1201
+ * See the LICENSE file in the root directory of this source tree.
1202
+ */
921
1203
  var ToggleLeft = createLucideIcon("toggle-left", [["circle", {
922
1204
  cx: "9",
923
1205
  cy: "12",
@@ -931,6 +1213,12 @@ var ToggleLeft = createLucideIcon("toggle-left", [["circle", {
931
1213
  rx: "7",
932
1214
  key: "g7kal2"
933
1215
  }]]);
1216
+ /**
1217
+ * @license lucide-react v1.14.0 - ISC
1218
+ *
1219
+ * This source code is licensed under the ISC license.
1220
+ * See the LICENSE file in the root directory of this source tree.
1221
+ */
934
1222
  var ToggleRight = createLucideIcon("toggle-right", [["circle", {
935
1223
  cx: "15",
936
1224
  cy: "12",
@@ -944,6 +1232,12 @@ var ToggleRight = createLucideIcon("toggle-right", [["circle", {
944
1232
  rx: "7",
945
1233
  key: "g7kal2"
946
1234
  }]]);
1235
+ /**
1236
+ * @license lucide-react v1.14.0 - ISC
1237
+ *
1238
+ * This source code is licensed under the ISC license.
1239
+ * See the LICENSE file in the root directory of this source tree.
1240
+ */
947
1241
  var Trash2 = createLucideIcon("trash-2", [
948
1242
  ["path", {
949
1243
  d: "M10 11v6",
@@ -966,6 +1260,12 @@ var Trash2 = createLucideIcon("trash-2", [
966
1260
  key: "e791ji"
967
1261
  }]
968
1262
  ]);
1263
+ /**
1264
+ * @license lucide-react v1.14.0 - ISC
1265
+ *
1266
+ * This source code is licensed under the ISC license.
1267
+ * See the LICENSE file in the root directory of this source tree.
1268
+ */
969
1269
  var Type = createLucideIcon("type", [
970
1270
  ["path", {
971
1271
  d: "M12 4v16",
@@ -980,6 +1280,12 @@ var Type = createLucideIcon("type", [
980
1280
  key: "s66wpe"
981
1281
  }]
982
1282
  ]);
1283
+ /**
1284
+ * @license lucide-react v1.14.0 - ISC
1285
+ *
1286
+ * This source code is licensed under the ISC license.
1287
+ * See the LICENSE file in the root directory of this source tree.
1288
+ */
983
1289
  var Undo2 = createLucideIcon("undo-2", [["path", {
984
1290
  d: "M9 14 4 9l5-5",
985
1291
  key: "102s5s"
@@ -987,6 +1293,12 @@ var Undo2 = createLucideIcon("undo-2", [["path", {
987
1293
  d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",
988
1294
  key: "f3b9sd"
989
1295
  }]]);
1296
+ /**
1297
+ * @license lucide-react v1.14.0 - ISC
1298
+ *
1299
+ * This source code is licensed under the ISC license.
1300
+ * See the LICENSE file in the root directory of this source tree.
1301
+ */
990
1302
  var Variable = createLucideIcon("variable", [
991
1303
  ["path", {
992
1304
  d: "M8 21s-4-3-4-9 4-9 4-9",
@@ -1011,6 +1323,40 @@ var Variable = createLucideIcon("variable", [
1011
1323
  key: "1shsy8"
1012
1324
  }]
1013
1325
  ]);
1326
+ /**
1327
+ * @license lucide-react v1.14.0 - ISC
1328
+ *
1329
+ * This source code is licensed under the ISC license.
1330
+ * See the LICENSE file in the root directory of this source tree.
1331
+ */
1332
+ var Workflow = createLucideIcon("workflow", [
1333
+ ["rect", {
1334
+ width: "8",
1335
+ height: "8",
1336
+ x: "3",
1337
+ y: "3",
1338
+ rx: "2",
1339
+ key: "by2w9f"
1340
+ }],
1341
+ ["path", {
1342
+ d: "M7 11v4a2 2 0 0 0 2 2h4",
1343
+ key: "xkn7yn"
1344
+ }],
1345
+ ["rect", {
1346
+ width: "8",
1347
+ height: "8",
1348
+ x: "13",
1349
+ y: "13",
1350
+ rx: "2",
1351
+ key: "1cgmvn"
1352
+ }]
1353
+ ]);
1354
+ /**
1355
+ * @license lucide-react v1.14.0 - ISC
1356
+ *
1357
+ * This source code is licensed under the ISC license.
1358
+ * See the LICENSE file in the root directory of this source tree.
1359
+ */
1014
1360
  var X$1 = createLucideIcon("x", [["path", {
1015
1361
  d: "M18 6 6 18",
1016
1362
  key: "1bl5f8"
@@ -1018,6 +1364,12 @@ var X$1 = createLucideIcon("x", [["path", {
1018
1364
  d: "m6 6 12 12",
1019
1365
  key: "d8bk6v"
1020
1366
  }]]);
1367
+ /**
1368
+ * @license lucide-react v1.14.0 - ISC
1369
+ *
1370
+ * This source code is licensed under the ISC license.
1371
+ * See the LICENSE file in the root directory of this source tree.
1372
+ */
1021
1373
  var ZoomIn = createLucideIcon("zoom-in", [
1022
1374
  ["circle", {
1023
1375
  cx: "11",
@@ -1054,18 +1406,18 @@ var BRANCH_COLORS = {
1054
1406
  no: "#EF4444"
1055
1407
  };
1056
1408
  var CATEGORY_COLORS = {
1057
- variable: "#5C7CFA",
1058
- comparison: "#20C997",
1059
- logical: "#845EF7",
1060
- arithmetic: "#40C057",
1061
- string: "#15AABF",
1062
- array: "#5F3DC4",
1063
- control: "#F59F00",
1064
- datetime: "#748FFC",
1065
- validation: "#ADB5BD",
1066
- utility: "#6B7280",
1067
- error: "#FA5252",
1068
- literal: "#6B7280"
1409
+ variable: "#6366f1",
1410
+ comparison: "#14b8a6",
1411
+ logical: "#8b5cf6",
1412
+ arithmetic: "#22c55e",
1413
+ string: "#06b6d4",
1414
+ array: "#7c3aed",
1415
+ control: "#f59e0b",
1416
+ datetime: "#0ea5e9",
1417
+ validation: "#94a3b8",
1418
+ utility: "#64748b",
1419
+ error: "#ef4444",
1420
+ literal: "#64748b"
1069
1421
  };
1070
1422
  //#endregion
1071
1423
  //#region src/components/logic-editor/config/operators/variable.ts
@@ -6027,179 +6379,99 @@ var errorOperators = {
6027
6379
  };
6028
6380
  //#endregion
6029
6381
  //#region src/components/logic-editor/config/operators/utility.ts
6030
- var utilityOperators = {
6031
- type: {
6032
- name: "type",
6033
- label: "Type",
6034
- category: "utility",
6035
- description: "Get the type of a value",
6036
- arity: {
6037
- type: "unary",
6038
- min: 1,
6039
- max: 1,
6040
- args: [{
6041
- name: "value",
6042
- label: "Value",
6043
- type: "any",
6044
- required: true,
6045
- description: "Value to check type of"
6046
- }]
6047
- },
6048
- help: {
6049
- summary: "Returns a string indicating the type of a value",
6050
- details: "Inspects a value and returns its type as a string. Useful for conditional logic based on data types. Includes special detection for datetime and duration strings.",
6051
- returnType: "string",
6052
- examples: [
6053
- {
6054
- title: "Number type",
6055
- rule: { type: 42 },
6056
- result: "number"
6057
- },
6058
- {
6059
- title: "String type",
6060
- rule: { type: "hello" },
6061
- result: "string"
6062
- },
6063
- {
6064
- title: "Boolean type",
6065
- rule: { type: true },
6066
- result: "boolean"
6067
- },
6068
- {
6069
- title: "Null type",
6070
- rule: { type: null },
6071
- result: "null"
6072
- },
6073
- {
6074
- title: "Array type",
6075
- rule: { type: [
6076
- 1,
6077
- 2,
6078
- 3
6079
- ] },
6080
- result: "array"
6081
- },
6082
- {
6083
- title: "Object type",
6084
- rule: { type: { key: "value" } },
6085
- result: "object"
6086
- },
6087
- {
6088
- title: "Datetime detection",
6089
- rule: { type: "2024-01-15T10:30:00Z" },
6090
- result: "datetime",
6091
- note: "ISO 8601 strings detected as datetime"
6092
- },
6093
- {
6094
- title: "Duration detection",
6095
- rule: { type: "2h30m" },
6096
- result: "duration",
6097
- note: "Duration strings detected automatically"
6098
- },
6099
- {
6100
- title: "With variable",
6101
- rule: { type: { var: "value" } },
6102
- data: { value: [
6103
- 1,
6104
- 2,
6105
- 3
6106
- ] },
6107
- result: "array"
6108
- }
6109
- ],
6110
- notes: [
6111
- "Returns: \"null\", \"boolean\", \"number\", \"string\", \"array\", \"object\", \"datetime\", \"duration\"",
6112
- "Datetime: detected by ISO 8601 format (contains T, :, and Z or +)",
6113
- "Duration: detected by time units (d, h, m, s) with digits",
6114
- "Empty arrays and objects are still \"array\" and \"object\""
6115
- ],
6116
- seeAlso: ["!!"]
6117
- },
6118
- ui: {
6119
- icon: "info",
6120
- shortLabel: "type",
6121
- nodeType: "operator"
6122
- }
6382
+ var utilityOperators = { type: {
6383
+ name: "type",
6384
+ label: "Type",
6385
+ category: "utility",
6386
+ description: "Get the type of a value",
6387
+ arity: {
6388
+ type: "unary",
6389
+ min: 1,
6390
+ max: 1,
6391
+ args: [{
6392
+ name: "value",
6393
+ label: "Value",
6394
+ type: "any",
6395
+ required: true,
6396
+ description: "Value to check type of"
6397
+ }]
6123
6398
  },
6124
- preserve: {
6125
- name: "preserve",
6126
- label: "Preserve",
6127
- category: "utility",
6128
- description: "Pass values through unchanged (templating mode)",
6129
- arity: {
6130
- type: "special",
6131
- min: 0,
6132
- args: [{
6133
- name: "value",
6134
- label: "Value",
6135
- type: "any",
6136
- required: false,
6137
- repeatable: true,
6138
- description: "Value(s) to preserve"
6139
- }]
6140
- },
6141
- help: {
6142
- summary: "Evaluate and return values unchanged",
6143
- details: "Used in structure preservation (templating) mode to pass values through without interpretation as operators. With one argument, returns that value. With multiple arguments, returns an array.",
6144
- returnType: "any",
6145
- examples: [
6146
- {
6147
- title: "Preserve single value",
6148
- rule: { preserve: 42 },
6149
- result: 42
6150
- },
6151
- {
6152
- title: "Preserve expression result",
6153
- rule: { preserve: { "+": [1, 2] } },
6154
- result: 3
6155
- },
6156
- {
6157
- title: "Preserve multiple values",
6158
- rule: { preserve: [
6159
- 1,
6160
- 2,
6161
- 3
6162
- ] },
6163
- result: [
6164
- 1,
6165
- 2,
6166
- 3
6167
- ]
6168
- },
6169
- {
6170
- title: "No arguments",
6171
- rule: { preserve: [] },
6172
- result: []
6173
- },
6174
- {
6175
- title: "In template context",
6176
- rule: {
6177
- name: { var: "user.name" },
6178
- status: { preserve: "active" }
6179
- },
6180
- data: { user: { name: "Alice" } },
6181
- result: {
6182
- name: "Alice",
6183
- status: "active"
6184
- },
6185
- note: "With preserve_structure enabled"
6186
- }
6187
- ],
6188
- notes: [
6189
- "Used with preserve_structure mode for JSON templating",
6190
- "No arguments: returns empty array",
6191
- "One argument: returns that argument evaluated",
6192
- "Multiple arguments: returns array of evaluated arguments"
6193
- ],
6194
- seeAlso: ["var", "val"]
6195
- },
6196
- ui: {
6197
- icon: "lock",
6198
- shortLabel: "keep",
6199
- nodeType: "operator"
6200
- }
6399
+ help: {
6400
+ summary: "Returns a string indicating the type of a value",
6401
+ details: "Inspects a value and returns its type as a string. Useful for conditional logic based on data types. Includes special detection for datetime and duration strings.",
6402
+ returnType: "string",
6403
+ examples: [
6404
+ {
6405
+ title: "Number type",
6406
+ rule: { type: 42 },
6407
+ result: "number"
6408
+ },
6409
+ {
6410
+ title: "String type",
6411
+ rule: { type: "hello" },
6412
+ result: "string"
6413
+ },
6414
+ {
6415
+ title: "Boolean type",
6416
+ rule: { type: true },
6417
+ result: "boolean"
6418
+ },
6419
+ {
6420
+ title: "Null type",
6421
+ rule: { type: null },
6422
+ result: "null"
6423
+ },
6424
+ {
6425
+ title: "Array type",
6426
+ rule: { type: [
6427
+ 1,
6428
+ 2,
6429
+ 3
6430
+ ] },
6431
+ result: "array"
6432
+ },
6433
+ {
6434
+ title: "Object type",
6435
+ rule: { type: { key: "value" } },
6436
+ result: "object"
6437
+ },
6438
+ {
6439
+ title: "Datetime detection",
6440
+ rule: { type: "2024-01-15T10:30:00Z" },
6441
+ result: "datetime",
6442
+ note: "ISO 8601 strings detected as datetime"
6443
+ },
6444
+ {
6445
+ title: "Duration detection",
6446
+ rule: { type: "2h30m" },
6447
+ result: "duration",
6448
+ note: "Duration strings detected automatically"
6449
+ },
6450
+ {
6451
+ title: "With variable",
6452
+ rule: { type: { var: "value" } },
6453
+ data: { value: [
6454
+ 1,
6455
+ 2,
6456
+ 3
6457
+ ] },
6458
+ result: "array"
6459
+ }
6460
+ ],
6461
+ notes: [
6462
+ "Returns: \"null\", \"boolean\", \"number\", \"string\", \"array\", \"object\", \"datetime\", \"duration\"",
6463
+ "Datetime: detected by ISO 8601 format (contains T, :, and Z or +)",
6464
+ "Duration: detected by time units (d, h, m, s) with digits",
6465
+ "Empty arrays and objects are still \"array\" and \"object\""
6466
+ ],
6467
+ seeAlso: ["!!"]
6468
+ },
6469
+ ui: {
6470
+ icon: "info",
6471
+ shortLabel: "type",
6472
+ nodeType: "operator"
6201
6473
  }
6202
- };
6474
+ } };
6203
6475
  //#endregion
6204
6476
  //#region src/components/logic-editor/config/operators/index.ts
6205
6477
  /**
@@ -6304,26 +6576,24 @@ function getParentInfo(context) {
6304
6576
  };
6305
6577
  }
6306
6578
  //#endregion
6307
- //#region ../node_modules/.pnpm/uuid@13.0.0/node_modules/uuid/dist/stringify.js
6579
+ //#region node_modules/uuid/dist/stringify.js
6308
6580
  var byteToHex = [];
6309
6581
  for (let i = 0; i < 256; ++i) byteToHex.push((i + 256).toString(16).slice(1));
6310
6582
  function unsafeStringify(arr, offset = 0) {
6311
6583
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
6312
6584
  }
6313
6585
  //#endregion
6314
- //#region ../node_modules/.pnpm/uuid@13.0.0/node_modules/uuid/dist/rng.js
6315
- var getRandomValues;
6586
+ //#region node_modules/uuid/dist/rng.js
6316
6587
  var rnds8 = new Uint8Array(16);
6317
6588
  function rng() {
6318
- if (!getRandomValues) {
6319
- if (typeof crypto === "undefined" || !crypto.getRandomValues) throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
6320
- getRandomValues = crypto.getRandomValues.bind(crypto);
6321
- }
6322
- return getRandomValues(rnds8);
6589
+ return crypto.getRandomValues(rnds8);
6323
6590
  }
6324
- var native_default = { randomUUID: typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto) };
6325
6591
  //#endregion
6326
- //#region ../node_modules/.pnpm/uuid@13.0.0/node_modules/uuid/dist/v4.js
6592
+ //#region node_modules/uuid/dist/v4.js
6593
+ function v4(options, buf, offset) {
6594
+ if (!buf && !options && crypto.randomUUID) return crypto.randomUUID();
6595
+ return _v4(options, buf, offset);
6596
+ }
6327
6597
  function _v4(options, buf, offset) {
6328
6598
  options = options || {};
6329
6599
  const rnds = options.random ?? options.rng?.() ?? rng();
@@ -6338,10 +6608,6 @@ function _v4(options, buf, offset) {
6338
6608
  }
6339
6609
  return unsafeStringify(rnds);
6340
6610
  }
6341
- function v4(options, buf, offset) {
6342
- if (native_default.randomUUID && !buf && !options) return native_default.randomUUID();
6343
- return _v4(options, buf, offset);
6344
- }
6345
6611
  //#endregion
6346
6612
  //#region src/components/logic-editor/utils/formatting/expression-text.ts
6347
6613
  var COMPARISON_OPERATORS$1 = [
@@ -6908,70 +7174,70 @@ var categories = {
6908
7174
  name: "variable",
6909
7175
  label: "Variables",
6910
7176
  description: "Access data from the context",
6911
- color: "#5C7CFA",
7177
+ color: "#6366f1",
6912
7178
  icon: "database"
6913
7179
  },
6914
7180
  comparison: {
6915
7181
  name: "comparison",
6916
7182
  label: "Comparison",
6917
7183
  description: "Compare values",
6918
- color: "#20C997",
7184
+ color: "#14b8a6",
6919
7185
  icon: "scale"
6920
7186
  },
6921
7187
  logical: {
6922
7188
  name: "logical",
6923
7189
  label: "Logical",
6924
7190
  description: "Boolean logic operations",
6925
- color: "#845EF7",
7191
+ color: "#8b5cf6",
6926
7192
  icon: "binary"
6927
7193
  },
6928
7194
  arithmetic: {
6929
7195
  name: "arithmetic",
6930
7196
  label: "Arithmetic",
6931
7197
  description: "Mathematical operations",
6932
- color: "#40C057",
7198
+ color: "#22c55e",
6933
7199
  icon: "calculator"
6934
7200
  },
6935
7201
  control: {
6936
7202
  name: "control",
6937
7203
  label: "Control Flow",
6938
7204
  description: "Conditional branching",
6939
- color: "#F59F00",
7205
+ color: "#f59e0b",
6940
7206
  icon: "git-branch"
6941
7207
  },
6942
7208
  string: {
6943
7209
  name: "string",
6944
7210
  label: "String",
6945
7211
  description: "Text manipulation",
6946
- color: "#15AABF",
7212
+ color: "#06b6d4",
6947
7213
  icon: "type"
6948
7214
  },
6949
7215
  array: {
6950
7216
  name: "array",
6951
7217
  label: "Array",
6952
7218
  description: "Array operations and iteration",
6953
- color: "#5F3DC4",
7219
+ color: "#7c3aed",
6954
7220
  icon: "layers"
6955
7221
  },
6956
7222
  datetime: {
6957
7223
  name: "datetime",
6958
7224
  label: "Date & Time",
6959
7225
  description: "Date and time operations",
6960
- color: "#748FFC",
7226
+ color: "#0ea5e9",
6961
7227
  icon: "clock"
6962
7228
  },
6963
7229
  validation: {
6964
7230
  name: "validation",
6965
7231
  label: "Validation",
6966
7232
  description: "Check for missing values",
6967
- color: "#ADB5BD",
7233
+ color: "#94a3b8",
6968
7234
  icon: "alert-circle"
6969
7235
  },
6970
7236
  error: {
6971
7237
  name: "error",
6972
7238
  label: "Error Handling",
6973
7239
  description: "Handle errors gracefully",
6974
- color: "#FA5252",
7240
+ color: "#ef4444",
6975
7241
  icon: "circle-x"
6976
7242
  },
6977
7243
  utility: {
@@ -7039,7 +7305,7 @@ function convertVariable(operator, operands, context, convertValue) {
7039
7305
  edges: context.edges,
7040
7306
  parentId: nodeId,
7041
7307
  argIndex: 1,
7042
- preserveStructure: context.preserveStructure
7308
+ templating: context.templating
7043
7309
  });
7044
7310
  const summary = generateArgSummary(defaultValue);
7045
7311
  summary.label = generateExpressionText(defaultValue, TRUNCATION_LIMITS.expressionText);
@@ -7096,7 +7362,7 @@ function convertIfElse(ifArgs, context, convertValue) {
7096
7362
  parentId: parentInfo.parentId,
7097
7363
  argIndex: parentInfo.argIndex,
7098
7364
  branchType: parentInfo.branchType,
7099
- preserveStructure: context.preserveStructure
7365
+ templating: context.templating
7100
7366
  });
7101
7367
  const cells = [];
7102
7368
  let cellIndex = 0;
@@ -7111,7 +7377,7 @@ function convertIfElse(ifArgs, context, convertValue) {
7111
7377
  parentId: nodeId,
7112
7378
  argIndex: idx,
7113
7379
  branchType: "condition",
7114
- preserveStructure: context.preserveStructure
7380
+ templating: context.templating
7115
7381
  });
7116
7382
  context.edges.push({
7117
7383
  id: `${nodeId}-cond-${conditionBranchId}`,
@@ -7136,7 +7402,7 @@ function convertIfElse(ifArgs, context, convertValue) {
7136
7402
  parentId: nodeId,
7137
7403
  argIndex: idx + 1,
7138
7404
  branchType: "yes",
7139
- preserveStructure: context.preserveStructure
7405
+ templating: context.templating
7140
7406
  });
7141
7407
  context.edges.push({
7142
7408
  id: `${nodeId}-then-${thenBranchId}`,
@@ -7165,7 +7431,7 @@ function convertIfElse(ifArgs, context, convertValue) {
7165
7431
  parentId: nodeId,
7166
7432
  argIndex: ifArgs.length - 1,
7167
7433
  branchType: "no",
7168
- preserveStructure: context.preserveStructure
7434
+ templating: context.templating
7169
7435
  });
7170
7436
  context.edges.push({
7171
7437
  id: `${nodeId}-else-${elseBranchId}`,
@@ -7248,7 +7514,7 @@ function convertSwitch(operator, switchArgs, context, convertValue) {
7248
7514
  parentId: nodeId,
7249
7515
  argIndex: 0,
7250
7516
  branchType: "branch",
7251
- preserveStructure: context.preserveStructure
7517
+ templating: context.templating
7252
7518
  });
7253
7519
  context.edges.push(createBranchEdge(nodeId, discBranchId, cellIndex));
7254
7520
  cells.push({
@@ -7284,7 +7550,7 @@ function convertSwitch(operator, switchArgs, context, convertValue) {
7284
7550
  parentId: nodeId,
7285
7551
  argIndex: cellIndex,
7286
7552
  branchType: "branch",
7287
- preserveStructure: context.preserveStructure
7553
+ templating: context.templating
7288
7554
  });
7289
7555
  context.edges.push(createBranchEdge(nodeId, caseBranchId, cellIndex));
7290
7556
  cells.push({
@@ -7311,7 +7577,7 @@ function convertSwitch(operator, switchArgs, context, convertValue) {
7311
7577
  parentId: nodeId,
7312
7578
  argIndex: cellIndex,
7313
7579
  branchType: "yes",
7314
- preserveStructure: context.preserveStructure
7580
+ templating: context.templating
7315
7581
  });
7316
7582
  context.edges.push(createBranchEdge(nodeId, resultBranchId, cellIndex));
7317
7583
  cells.push({
@@ -7342,7 +7608,7 @@ function convertSwitch(operator, switchArgs, context, convertValue) {
7342
7608
  parentId: nodeId,
7343
7609
  argIndex: cellIndex,
7344
7610
  branchType: "no",
7345
- preserveStructure: context.preserveStructure
7611
+ templating: context.templating
7346
7612
  });
7347
7613
  context.edges.push(createBranchEdge(nodeId, defaultBranchId, cellIndex));
7348
7614
  cells.push({
@@ -7409,7 +7675,7 @@ function convertOperator$1(operator, operandArray, context, convertValue) {
7409
7675
  parentId: nodeId,
7410
7676
  argIndex: idx,
7411
7677
  branchType: "branch",
7412
- preserveStructure: context.preserveStructure
7678
+ templating: context.templating
7413
7679
  });
7414
7680
  const summary = generateArgSummary(operand);
7415
7681
  summary.label = generateExpressionText(operand, TRUNCATION_LIMITS.expressionText);
@@ -7473,7 +7739,7 @@ function convertStructure$1(value, context, convertValue) {
7473
7739
  edges: context.edges,
7474
7740
  parentId: nodeId,
7475
7741
  argIndex: expressionIndex,
7476
- preserveStructure: context.preserveStructure
7742
+ templating: context.templating
7477
7743
  });
7478
7744
  elements.push({
7479
7745
  type: "expression",
@@ -7557,7 +7823,7 @@ function walkAndCollect(value, path, onValue) {
7557
7823
  //#endregion
7558
7824
  //#region src/components/logic-editor/utils/converters/index.ts
7559
7825
  function convertValue(value, context) {
7560
- if (context.preserveStructure && isDataStructure(value)) return convertStructure$1(value, context, convertValue);
7826
+ if (context.templating && isDataStructure(value)) return convertStructure$1(value, context, convertValue);
7561
7827
  if (!isPlainObject(value)) return convertPrimitive(value, context);
7562
7828
  const keys = Object.keys(value);
7563
7829
  if (keys.length !== 1) return convertInvalidObject(value, context);
@@ -7584,7 +7850,7 @@ function jsonLogicToNodes(expr, options = {}) {
7584
7850
  rootId: convertValue(expr, {
7585
7851
  nodes,
7586
7852
  edges,
7587
- preserveStructure: options.preserveStructure
7853
+ templating: options.templating
7588
7854
  })
7589
7855
  };
7590
7856
  }
@@ -7626,8 +7892,8 @@ function buildEvaluationResultsFromTrace(trace) {
7626
7892
  /**
7627
7893
  * Determine what kind of node to create based on expression
7628
7894
  */
7629
- function determineNodeType(expr, preserveStructure) {
7630
- if (preserveStructure && isDataStructure(expr)) return "structure";
7895
+ function determineNodeType(expr, templating) {
7896
+ if (templating && isDataStructure(expr)) return "structure";
7631
7897
  if (expr === null || typeof expr !== "object" || Array.isArray(expr)) return "literal";
7632
7898
  if (Object.keys(expr).length !== 1) return "literal";
7633
7899
  return "operator";
@@ -8022,7 +8288,7 @@ function createIfElseNodeFromTrace(nodeId, expression, children, context, parent
8022
8288
  branchType: "condition"
8023
8289
  });
8024
8290
  } else {
8025
- const nextUnused = determineNodeType(condition, context.preserveStructure) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8291
+ const nextUnused = determineNodeType(condition, context.templating) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8026
8292
  if (nextUnused) {
8027
8293
  usedChildIndices.add(nextUnused.index);
8028
8294
  conditionBranchId = processExpressionNode(nextUnused.child, context, {
@@ -8060,7 +8326,7 @@ function createIfElseNodeFromTrace(nodeId, expression, children, context, parent
8060
8326
  branchType: "yes"
8061
8327
  });
8062
8328
  } else {
8063
- const nextUnused = determineNodeType(thenValue, context.preserveStructure) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8329
+ const nextUnused = determineNodeType(thenValue, context.templating) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8064
8330
  if (nextUnused) {
8065
8331
  usedChildIndices.add(nextUnused.index);
8066
8332
  thenBranchId = processExpressionNode(nextUnused.child, context, {
@@ -8102,7 +8368,7 @@ function createIfElseNodeFromTrace(nodeId, expression, children, context, parent
8102
8368
  branchType: "no"
8103
8369
  });
8104
8370
  } else {
8105
- const nextUnused = determineNodeType(elseValue, context.preserveStructure) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8371
+ const nextUnused = determineNodeType(elseValue, context.templating) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8106
8372
  if (nextUnused) {
8107
8373
  usedChildIndices.add(nextUnused.index);
8108
8374
  elseBranchId = processExpressionNode(nextUnused.child, context, {
@@ -8187,7 +8453,7 @@ function createSwitchNodeFromTrace(nodeId, expression, children, context, parent
8187
8453
  branchType
8188
8454
  });
8189
8455
  } else {
8190
- const nextUnused = determineNodeType(value, context.preserveStructure) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8456
+ const nextUnused = determineNodeType(value, context.templating) !== "literal" ? getNextUnusedChild(children, usedChildIndices) : null;
8191
8457
  if (nextUnused) {
8192
8458
  usedChildIndices.add(nextUnused.index);
8193
8459
  branchId = processExpressionNode(nextUnused.child, context, {
@@ -8333,11 +8599,11 @@ var EXPR_PLACEHOLDER = "{{EXPR}}";
8333
8599
  var EXPR_PLACEHOLDER_QUOTED = `"${EXPR_PLACEHOLDER}"`;
8334
8600
  /**
8335
8601
  * Check if a value should be treated as an expression branch in trace conversion
8336
- * This includes JSONLogic expressions and nested structures (when preserveStructure is enabled)
8602
+ * This includes JSONLogic expressions and nested structures (when templating is enabled)
8337
8603
  */
8338
- function isExpressionBranch(item, preserveStructure) {
8604
+ function isExpressionBranch(item, templating) {
8339
8605
  if (isJsonLogicExpression(item)) return true;
8340
- if (preserveStructure && isDataStructure(item)) return true;
8606
+ if (templating && isDataStructure(item)) return true;
8341
8607
  return false;
8342
8608
  }
8343
8609
  /**
@@ -8346,7 +8612,7 @@ function isExpressionBranch(item, preserveStructure) {
8346
8612
  function walkAndCollectFromTrace(value, path, onValue, context) {
8347
8613
  if (Array.isArray(value)) return value.map((item, index) => {
8348
8614
  const itemPath = [...path, String(index)];
8349
- if (isExpressionBranch(item, context.preserveStructure)) return onValue(itemPath, item);
8615
+ if (isExpressionBranch(item, context.templating)) return onValue(itemPath, item);
8350
8616
  else if (typeof item === "object" && item !== null) return walkAndCollectFromTrace(item, itemPath, onValue, context);
8351
8617
  return item;
8352
8618
  });
@@ -8354,7 +8620,7 @@ function walkAndCollectFromTrace(value, path, onValue, context) {
8354
8620
  const result = {};
8355
8621
  for (const [key, item] of Object.entries(value)) {
8356
8622
  const itemPath = [...path, key];
8357
- if (isExpressionBranch(item, context.preserveStructure)) result[key] = onValue(itemPath, item, key);
8623
+ if (isExpressionBranch(item, context.templating)) result[key] = onValue(itemPath, item, key);
8358
8624
  else if (typeof item === "object" && item !== null) result[key] = walkAndCollectFromTrace(item, itemPath, onValue, context);
8359
8625
  else result[key] = item;
8360
8626
  }
@@ -8459,7 +8725,7 @@ function traceToNodes(trace, options = {}) {
8459
8725
  nodes,
8460
8726
  edges,
8461
8727
  traceNodeMap,
8462
- preserveStructure: options.preserveStructure ?? false
8728
+ templating: options.templating ?? false
8463
8729
  }, {}, rootExpression);
8464
8730
  return {
8465
8731
  nodes,
@@ -8476,7 +8742,7 @@ function processExpressionNode(exprNode, context, parentInfo = {}, originalExpre
8476
8742
  const nodeId = traceIdToNodeId(exprNode.id);
8477
8743
  const expression = originalExpression ?? JSON.parse(exprNode.expression);
8478
8744
  context.traceNodeMap.set(nodeId, nodeId);
8479
- switch (determineNodeType(expression, context.preserveStructure)) {
8745
+ switch (determineNodeType(expression, context.templating)) {
8480
8746
  case "literal":
8481
8747
  createLiteralNodeFromTrace(nodeId, expression, exprNode.children, context, parentInfo);
8482
8748
  break;
@@ -8511,7 +8777,7 @@ function processExpressionNode(exprNode, context, parentInfo = {}, originalExpre
8511
8777
  * This properly handles all node types (operators, variables, structures, etc.)
8512
8778
  */
8513
8779
  function createFallbackNode(nodeId, value, context, parentInfo) {
8514
- switch (determineNodeType(value, context.preserveStructure)) {
8780
+ switch (determineNodeType(value, context.templating)) {
8515
8781
  case "literal":
8516
8782
  createLiteralNodeFromTrace(nodeId, value, [], context, parentInfo);
8517
8783
  break;
@@ -8541,7 +8807,7 @@ function createFallbackNode(nodeId, value, context, parentInfo) {
8541
8807
  }
8542
8808
  }
8543
8809
  //#endregion
8544
- //#region ../node_modules/.pnpm/@dagrejs+dagre@3.0.0/node_modules/@dagrejs/dagre/dist/dagre.esm.js
8810
+ //#region node_modules/@dagrejs/dagre/dist/dagre.esm.js
8545
8811
  var ge = Object.defineProperty;
8546
8812
  var hn = (e, n, t) => n in e ? ge(e, n, {
8547
8813
  enumerable: !0,
@@ -10729,7 +10995,7 @@ var MAX_RECURSION_DEPTH = 100;
10729
10995
  var emptyResults$1 = /* @__PURE__ */ new Map();
10730
10996
  var emptySteps = [];
10731
10997
  var emptyTraceNodeMap = /* @__PURE__ */ new Map();
10732
- function useLogicEditor({ value, evaluateWithTrace, data, preserveStructure = false }) {
10998
+ function useLogicEditor({ value, evaluateWithTrace, data, templating = false }) {
10733
10999
  const [nodes, setNodes] = (0, react.useState)([]);
10734
11000
  const [edges, setEdges] = (0, react.useState)([]);
10735
11001
  const [error, setError] = (0, react.useState)(null);
@@ -10740,12 +11006,12 @@ function useLogicEditor({ value, evaluateWithTrace, data, preserveStructure = fa
10740
11006
  const lastExternalValueRef = (0, react.useRef)("");
10741
11007
  const lastDataRef = (0, react.useRef)("");
10742
11008
  const lastHadTraceRef = (0, react.useRef)(false);
10743
- const lastPreserveStructureRef = (0, react.useRef)(false);
11009
+ const lastTemplatingRef = (0, react.useRef)(false);
10744
11010
  (0, react.useEffect)(() => {
10745
11011
  const valueStr = JSON.stringify(value);
10746
11012
  const dataStr = JSON.stringify(data);
10747
11013
  const hasTrace = !!evaluateWithTrace;
10748
- if (valueStr === lastExternalValueRef.current && dataStr === lastDataRef.current && hasTrace === lastHadTraceRef.current && preserveStructure === lastPreserveStructureRef.current) return;
11014
+ if (valueStr === lastExternalValueRef.current && dataStr === lastDataRef.current && hasTrace === lastHadTraceRef.current && templating === lastTemplatingRef.current) return;
10749
11015
  try {
10750
11016
  if (!checkDepth(value, MAX_RECURSION_DEPTH)) {
10751
11017
  setError(`Expression exceeds maximum nesting depth of ${MAX_RECURSION_DEPTH}`);
@@ -10758,13 +11024,13 @@ function useLogicEditor({ value, evaluateWithTrace, data, preserveStructure = fa
10758
11024
  lastExternalValueRef.current = valueStr;
10759
11025
  lastDataRef.current = dataStr;
10760
11026
  lastHadTraceRef.current = hasTrace;
10761
- lastPreserveStructureRef.current = preserveStructure;
11027
+ lastTemplatingRef.current = templating;
10762
11028
  return;
10763
11029
  }
10764
11030
  if (evaluateWithTrace && value) try {
10765
11031
  const trace = evaluateWithTrace(value, data ?? {});
10766
11032
  const { nodes: newNodes, edges: newEdges, traceNodeMap: newTraceNodeMap } = traceToNodes(trace, {
10767
- preserveStructure,
11033
+ templating,
10768
11034
  originalValue: value
10769
11035
  });
10770
11036
  const layoutedNodes = applyTreeLayout(newNodes, newEdges);
@@ -10779,12 +11045,12 @@ function useLogicEditor({ value, evaluateWithTrace, data, preserveStructure = fa
10779
11045
  lastExternalValueRef.current = valueStr;
10780
11046
  lastDataRef.current = dataStr;
10781
11047
  lastHadTraceRef.current = hasTrace;
10782
- lastPreserveStructureRef.current = preserveStructure;
11048
+ lastTemplatingRef.current = templating;
10783
11049
  return;
10784
11050
  } catch (traceErr) {
10785
11051
  console.warn("Trace conversion failed, falling back to JS:", traceErr);
10786
11052
  }
10787
- const { nodes: newNodes, edges: newEdges } = jsonLogicToNodes(value, { preserveStructure });
11053
+ const { nodes: newNodes, edges: newEdges } = jsonLogicToNodes(value, { templating });
10788
11054
  setNodes(applyTreeLayout(newNodes, newEdges));
10789
11055
  setEdges(newEdges);
10790
11056
  setEvaluationResults(emptyResults$1);
@@ -10804,12 +11070,12 @@ function useLogicEditor({ value, evaluateWithTrace, data, preserveStructure = fa
10804
11070
  lastExternalValueRef.current = valueStr;
10805
11071
  lastDataRef.current = dataStr;
10806
11072
  lastHadTraceRef.current = hasTrace;
10807
- lastPreserveStructureRef.current = preserveStructure;
11073
+ lastTemplatingRef.current = templating;
10808
11074
  }, [
10809
11075
  value,
10810
11076
  data,
10811
11077
  evaluateWithTrace,
10812
- preserveStructure
11078
+ templating
10813
11079
  ]);
10814
11080
  return (0, react.useMemo)(() => ({
10815
11081
  nodes,
@@ -11464,18 +11730,21 @@ var MAX_HISTORY_SIZE = 50;
11464
11730
  function useHistoryState(nodesRef, setInternalNodes, onNodesChange, clearSelection) {
11465
11731
  const undoStackRef = (0, react.useRef)([]);
11466
11732
  const redoStackRef = (0, react.useRef)([]);
11467
- const [historyVersion, setHistoryVersion] = (0, react.useState)(0);
11733
+ const [canUndo, setCanUndo] = (0, react.useState)(false);
11734
+ const [canRedo, setCanRedo] = (0, react.useState)(false);
11468
11735
  return {
11469
11736
  pushToUndoStack: (0, react.useCallback)((nodes) => {
11470
11737
  undoStackRef.current = [...undoStackRef.current.slice(-MAX_HISTORY_SIZE + 1), JSON.parse(JSON.stringify(nodes))];
11471
11738
  redoStackRef.current = [];
11472
- setHistoryVersion((v) => v + 1);
11739
+ setCanUndo(true);
11740
+ setCanRedo(false);
11473
11741
  }, []),
11474
11742
  undo: (0, react.useCallback)(() => {
11475
11743
  if (undoStackRef.current.length === 0) return;
11476
11744
  const previousState = undoStackRef.current.pop();
11477
11745
  redoStackRef.current.push(JSON.parse(JSON.stringify(nodesRef.current)));
11478
- setHistoryVersion((v) => v + 1);
11746
+ setCanUndo(undoStackRef.current.length > 0);
11747
+ setCanRedo(true);
11479
11748
  setInternalNodes(previousState);
11480
11749
  onNodesChange?.(previousState);
11481
11750
  clearSelection();
@@ -11489,7 +11758,8 @@ function useHistoryState(nodesRef, setInternalNodes, onNodesChange, clearSelecti
11489
11758
  if (redoStackRef.current.length === 0) return;
11490
11759
  const nextState = redoStackRef.current.pop();
11491
11760
  undoStackRef.current.push(JSON.parse(JSON.stringify(nodesRef.current)));
11492
- setHistoryVersion((v) => v + 1);
11761
+ setCanUndo(true);
11762
+ setCanRedo(redoStackRef.current.length > 0);
11493
11763
  setInternalNodes(nextState);
11494
11764
  onNodesChange?.(nextState);
11495
11765
  clearSelection();
@@ -11499,8 +11769,8 @@ function useHistoryState(nodesRef, setInternalNodes, onNodesChange, clearSelecti
11499
11769
  onNodesChange,
11500
11770
  clearSelection
11501
11771
  ]),
11502
- canUndo: (0, react.useMemo)(() => undoStackRef.current.length > 0, [historyVersion]),
11503
- canRedo: (0, react.useMemo)(() => redoStackRef.current.length > 0, [historyVersion])
11772
+ canUndo,
11773
+ canRedo
11504
11774
  };
11505
11775
  }
11506
11776
  //#endregion
@@ -11513,15 +11783,16 @@ function useHistoryState(nodesRef, setInternalNodes, onNodesChange, clearSelecti
11513
11783
  function useClipboardState(deps) {
11514
11784
  const { selectedNode, internalNodes, pushToUndoStack, setInternalNodes, onNodesChange, setSelectedNodeId, setPanelValues, hasEditedRef } = deps;
11515
11785
  const clipboardRef = (0, react.useRef)(null);
11516
- const [clipboardVersion, setClipboardVersion] = (0, react.useState)(0);
11786
+ const [canPaste, setCanPaste] = (0, react.useState)(false);
11517
11787
  return {
11518
11788
  copyNode: (0, react.useCallback)(() => {
11519
11789
  if (!selectedNode) return;
11790
+ const copiedNodes = [selectedNode, ...getDescendants(selectedNode.id, internalNodes)].map((n) => JSON.parse(JSON.stringify(n)));
11520
11791
  clipboardRef.current = {
11521
- nodes: [selectedNode, ...getDescendants(selectedNode.id, internalNodes)].map((n) => JSON.parse(JSON.stringify(n))),
11792
+ nodes: copiedNodes,
11522
11793
  rootId: selectedNode.id
11523
11794
  };
11524
- setClipboardVersion((v) => v + 1);
11795
+ setCanPaste(copiedNodes.length > 0);
11525
11796
  }, [selectedNode, internalNodes]),
11526
11797
  pasteNode: (0, react.useCallback)(() => {
11527
11798
  const clipboard = clipboardRef.current;
@@ -11575,7 +11846,7 @@ function useClipboardState(deps) {
11575
11846
  setPanelValues,
11576
11847
  hasEditedRef
11577
11848
  ]),
11578
- canPaste: (0, react.useMemo)(() => clipboardRef.current !== null && clipboardRef.current.nodes.length > 0, [clipboardVersion])
11849
+ canPaste
11579
11850
  };
11580
11851
  }
11581
11852
  //#endregion
@@ -13182,14 +13453,33 @@ function useNodeCollapse(nodeId) {
13182
13453
  }
13183
13454
  //#endregion
13184
13455
  //#region src/components/logic-editor/hooks/useWasmEvaluator.ts
13185
- /** Extract error message from unknown error types (Error objects, strings from WASM, etc.) */
13186
- function extractErrorMessage(err, fallback) {
13187
- if (err instanceof Error) return err.message;
13188
- if (typeof err === "string") return err;
13189
- return fallback;
13456
+ /** Error thrown from the WASM boundary that carries the parsed StructuredError. */
13457
+ var DataLogicEvaluationError = class extends Error {
13458
+ structured;
13459
+ constructor(structured) {
13460
+ super(structured.message || structured.type);
13461
+ this.name = "DataLogicEvaluationError";
13462
+ this.structured = structured;
13463
+ }
13464
+ };
13465
+ /**
13466
+ * Attempt to parse a WASM error message as a StructuredError JSON document.
13467
+ * The WASM boundary always produces JSON; non-JSON errors fall back to a
13468
+ * synthetic `Unknown` StructuredError so downstream code has a uniform shape.
13469
+ */
13470
+ function parseStructuredError(err, fallbackMessage) {
13471
+ const raw = err instanceof Error ? err.message : typeof err === "string" ? err : fallbackMessage;
13472
+ try {
13473
+ const parsed = JSON.parse(raw);
13474
+ if (parsed && typeof parsed === "object" && "type" in parsed && "message" in parsed) return parsed;
13475
+ } catch {}
13476
+ return {
13477
+ type: "Unknown",
13478
+ message: raw
13479
+ };
13190
13480
  }
13191
13481
  function useWasmEvaluator(options = {}) {
13192
- const { preserveStructure = false } = options;
13482
+ const { templating = false } = options;
13193
13483
  const [ready, setReady] = (0, react.useState)(false);
13194
13484
  const [loading, setLoading] = (0, react.useState)(true);
13195
13485
  const [error, setError] = (0, react.useState)(null);
@@ -13200,12 +13490,12 @@ function useWasmEvaluator(options = {}) {
13200
13490
  try {
13201
13491
  setLoading(true);
13202
13492
  setError(null);
13203
- const wasm = await Promise.resolve().then(() => require("./datalogic_wasm-Ckkdrc0z.cjs"));
13493
+ const wasm = await Promise.resolve().then(() => require("./datalogic_wasm-Dj9TEPTG.cjs"));
13204
13494
  await wasm.default();
13205
13495
  if (!cancelled) {
13206
13496
  moduleRef.current = {
13207
13497
  evaluate: wasm.evaluate,
13208
- evaluate_with_trace: wasm.evaluate_with_trace,
13498
+ evaluateWithTrace: wasm.evaluateWithTrace,
13209
13499
  CompiledRule: wasm.CompiledRule
13210
13500
  };
13211
13501
  setReady(true);
@@ -13229,27 +13519,27 @@ function useWasmEvaluator(options = {}) {
13229
13519
  error,
13230
13520
  evaluate: (0, react.useCallback)((logic, data) => {
13231
13521
  if (!moduleRef.current) throw new Error("WASM module not initialized");
13522
+ const logicStr = JSON.stringify(logic);
13523
+ const dataStr = JSON.stringify(data);
13232
13524
  try {
13233
- const logicStr = JSON.stringify(logic);
13234
- const dataStr = JSON.stringify(data);
13235
- const resultStr = moduleRef.current.evaluate(logicStr, dataStr, preserveStructure);
13525
+ const resultStr = moduleRef.current.evaluate(logicStr, dataStr, templating);
13236
13526
  return JSON.parse(resultStr);
13237
13527
  } catch (err) {
13238
- throw new Error(extractErrorMessage(err, "Evaluation failed"), { cause: err });
13528
+ throw new DataLogicEvaluationError(parseStructuredError(err, "Evaluation failed"));
13239
13529
  }
13240
- }, [preserveStructure]),
13530
+ }, [templating]),
13241
13531
  evaluateWithTrace: (0, react.useCallback)((logic, data) => {
13242
13532
  if (!moduleRef.current) throw new Error("WASM module not initialized");
13243
- if (!moduleRef.current.evaluate_with_trace) throw new Error("evaluate_with_trace not available in WASM module");
13533
+ if (!moduleRef.current.evaluateWithTrace) throw new Error("evaluateWithTrace not available in WASM module");
13534
+ const logicStr = JSON.stringify(logic);
13535
+ const dataStr = JSON.stringify(data);
13244
13536
  try {
13245
- const logicStr = JSON.stringify(logic);
13246
- const dataStr = JSON.stringify(data);
13247
- const resultStr = moduleRef.current.evaluate_with_trace(logicStr, dataStr, preserveStructure);
13537
+ const resultStr = moduleRef.current.evaluateWithTrace(logicStr, dataStr, templating);
13248
13538
  return JSON.parse(resultStr);
13249
13539
  } catch (err) {
13250
- throw new Error(extractErrorMessage(err, "Trace evaluation failed"), { cause: err });
13540
+ throw new DataLogicEvaluationError(parseStructuredError(err, "Trace evaluation failed"));
13251
13541
  }
13252
- }, [preserveStructure])
13542
+ }, [templating])
13253
13543
  };
13254
13544
  }
13255
13545
  //#endregion
@@ -15398,6 +15688,136 @@ function convertStructure(data, nodeMap) {
15398
15688
  return obj;
15399
15689
  }
15400
15690
  //#endregion
15691
+ //#region src/components/Tooltip.tsx
15692
+ var OFFSET = 8;
15693
+ /**
15694
+ * Lightweight tooltip primitive.
15695
+ *
15696
+ * Wraps its children in a layout-neutral `<span>` that catches hover/focus
15697
+ * events, then renders the tooltip itself into a portal at `document.body`
15698
+ * with `position: fixed` — so it's immune to `overflow: hidden` or stacking-
15699
+ * context clipping from any ancestor (e.g. `.logic-editor`'s rounded clip).
15700
+ *
15701
+ * Hides on coarse-pointer / no-hover devices via CSS.
15702
+ */
15703
+ function Tooltip({ label, shortcut, side = "bottom", delay = 300, children }) {
15704
+ const [visible, setVisible] = (0, react.useState)(false);
15705
+ const [position, setPosition] = (0, react.useState)(null);
15706
+ const triggerRef = (0, react.useRef)(null);
15707
+ const tooltipRef = (0, react.useRef)(null);
15708
+ const showTimerRef = (0, react.useRef)(null);
15709
+ const computePosition = (0, react.useCallback)(() => {
15710
+ const trigger = triggerRef.current;
15711
+ const tooltip = tooltipRef.current;
15712
+ if (!trigger) return null;
15713
+ const triggerRect = trigger.getBoundingClientRect();
15714
+ const tooltipRect = tooltip?.getBoundingClientRect();
15715
+ const w = tooltipRect?.width ?? 0;
15716
+ const h = tooltipRect?.height ?? 0;
15717
+ const compute = (s) => {
15718
+ switch (s) {
15719
+ case "top": return {
15720
+ top: triggerRect.top - h - OFFSET,
15721
+ left: triggerRect.left + triggerRect.width / 2 - w / 2
15722
+ };
15723
+ case "bottom": return {
15724
+ top: triggerRect.bottom + OFFSET,
15725
+ left: triggerRect.left + triggerRect.width / 2 - w / 2
15726
+ };
15727
+ case "left": return {
15728
+ top: triggerRect.top + triggerRect.height / 2 - h / 2,
15729
+ left: triggerRect.left - w - OFFSET
15730
+ };
15731
+ case "right": return {
15732
+ top: triggerRect.top + triggerRect.height / 2 - h / 2,
15733
+ left: triggerRect.right + OFFSET
15734
+ };
15735
+ }
15736
+ };
15737
+ let chosen = side;
15738
+ let { top, left } = compute(side);
15739
+ const margin = 4;
15740
+ if (side === "bottom" && top + h > window.innerHeight - margin) {
15741
+ chosen = "top";
15742
+ ({top, left} = compute("top"));
15743
+ } else if (side === "top" && top < margin) {
15744
+ chosen = "bottom";
15745
+ ({top, left} = compute("bottom"));
15746
+ } else if (side === "right" && left + w > window.innerWidth - margin) {
15747
+ chosen = "left";
15748
+ ({top, left} = compute("left"));
15749
+ } else if (side === "left" && left < margin) {
15750
+ chosen = "right";
15751
+ ({top, left} = compute("right"));
15752
+ }
15753
+ left = Math.max(margin, Math.min(left, window.innerWidth - w - margin));
15754
+ top = Math.max(margin, Math.min(top, window.innerHeight - h - margin));
15755
+ return {
15756
+ top,
15757
+ left,
15758
+ side: chosen
15759
+ };
15760
+ }, [side]);
15761
+ const show = (0, react.useCallback)(() => {
15762
+ if (showTimerRef.current) clearTimeout(showTimerRef.current);
15763
+ showTimerRef.current = setTimeout(() => {
15764
+ setVisible(true);
15765
+ }, delay);
15766
+ }, [delay]);
15767
+ const hide = (0, react.useCallback)(() => {
15768
+ if (showTimerRef.current) {
15769
+ clearTimeout(showTimerRef.current);
15770
+ showTimerRef.current = null;
15771
+ }
15772
+ setVisible(false);
15773
+ setPosition(null);
15774
+ }, []);
15775
+ (0, react.useEffect)(() => {
15776
+ return () => {
15777
+ if (showTimerRef.current) clearTimeout(showTimerRef.current);
15778
+ };
15779
+ }, []);
15780
+ (0, react.useLayoutEffect)(() => {
15781
+ if (!visible) return;
15782
+ setPosition(computePosition());
15783
+ const handleReposition = () => setPosition(computePosition());
15784
+ window.addEventListener("scroll", handleReposition, true);
15785
+ window.addEventListener("resize", handleReposition);
15786
+ return () => {
15787
+ window.removeEventListener("scroll", handleReposition, true);
15788
+ window.removeEventListener("resize", handleReposition);
15789
+ };
15790
+ }, [visible, computePosition]);
15791
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
15792
+ ref: triggerRef,
15793
+ className: "dl-tooltip-wrap",
15794
+ onMouseEnter: show,
15795
+ onMouseLeave: hide,
15796
+ onFocus: show,
15797
+ onBlur: hide,
15798
+ "aria-label": label,
15799
+ children
15800
+ }), visible && typeof document !== "undefined" && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
15801
+ ref: tooltipRef,
15802
+ role: "tooltip",
15803
+ className: "dl-tooltip",
15804
+ "data-side": position?.side ?? side,
15805
+ style: {
15806
+ position: "fixed",
15807
+ top: position?.top ?? -9999,
15808
+ left: position?.left ?? -9999,
15809
+ opacity: position ? 1 : 0
15810
+ },
15811
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
15812
+ className: "dl-tooltip-label",
15813
+ children: label
15814
+ }), shortcut ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
15815
+ className: "dl-tooltip-shortcut",
15816
+ children: shortcut
15817
+ }) : null]
15818
+ }), document.body)] });
15819
+ }
15820
+ //#endregion
15401
15821
  //#region src/components/logic-editor/debugger-controls/DebuggerControls.tsx
15402
15822
  function DebuggerControlsInline() {
15403
15823
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DebuggerControlsBase, { variant: "inline" });
@@ -15467,39 +15887,59 @@ function DebuggerControlsBase({ variant = "floating" }) {
15467
15887
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
15468
15888
  className: "dl-debugger-buttons",
15469
15889
  children: [
15470
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15471
- className: "dl-debugger-btn",
15472
- onClick: reset,
15473
- disabled: isAtStart,
15474
- title: "Reset to start (Home)",
15475
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkipBack, { size: 16 })
15890
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
15891
+ label: "Reset",
15892
+ shortcut: "Home",
15893
+ side: "top",
15894
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15895
+ className: "dl-debugger-btn",
15896
+ onClick: reset,
15897
+ disabled: isAtStart,
15898
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkipBack, { size: 16 })
15899
+ })
15476
15900
  }),
15477
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15478
- className: "dl-debugger-btn",
15479
- onClick: stepBackward,
15480
- disabled: isAtStart,
15481
- title: "Step backward (Left Arrow)",
15482
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronLeft, { size: 18 })
15901
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
15902
+ label: "Step back",
15903
+ shortcut: "←",
15904
+ side: "top",
15905
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15906
+ className: "dl-debugger-btn",
15907
+ onClick: stepBackward,
15908
+ disabled: isAtStart,
15909
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronLeft, { size: 18 })
15910
+ })
15483
15911
  }),
15484
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15485
- className: "dl-debugger-btn dl-debugger-btn-primary",
15486
- onClick: isPlaying ? pause : play,
15487
- title: isPlaying ? "Pause (Space)" : "Play (Space)",
15488
- children: isPlaying ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pause, { size: 18 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Play, { size: 18 })
15912
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
15913
+ label: isPlaying ? "Pause" : "Play",
15914
+ shortcut: "Space",
15915
+ side: "top",
15916
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15917
+ className: "dl-debugger-btn dl-debugger-btn-primary",
15918
+ onClick: isPlaying ? pause : play,
15919
+ children: isPlaying ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pause, { size: 18 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Play, { size: 18 })
15920
+ })
15489
15921
  }),
15490
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15491
- className: "dl-debugger-btn",
15492
- onClick: stepForward,
15493
- disabled: isAtEnd,
15494
- title: "Step forward (Right Arrow)",
15495
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { size: 18 })
15922
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
15923
+ label: "Step forward",
15924
+ shortcut: "→",
15925
+ side: "top",
15926
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15927
+ className: "dl-debugger-btn",
15928
+ onClick: stepForward,
15929
+ disabled: isAtEnd,
15930
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronRight, { size: 18 })
15931
+ })
15496
15932
  }),
15497
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15498
- className: "dl-debugger-btn",
15499
- onClick: () => goToStep(totalSteps - 1),
15500
- disabled: isAtEnd,
15501
- title: "Jump to end (End)",
15502
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkipForward, { size: 16 })
15933
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
15934
+ label: "Jump to end",
15935
+ shortcut: "End",
15936
+ side: "top",
15937
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
15938
+ className: "dl-debugger-btn",
15939
+ onClick: () => goToStep(totalSteps - 1),
15940
+ disabled: isAtEnd,
15941
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkipForward, { size: 16 })
15942
+ })
15503
15943
  })
15504
15944
  ]
15505
15945
  }),
@@ -17076,7 +17516,7 @@ var PropertiesPanel = (0, react.memo)(function PropertiesPanel({ width = 280 })
17076
17516
  if (selectedNode && Object.keys(panelValues).length > 0) applyTimerRef.current = setTimeout(() => {
17077
17517
  applyPanelChanges();
17078
17518
  applyTimerRef.current = null;
17079
- }, 500);
17519
+ }, 200);
17080
17520
  return () => {
17081
17521
  if (applyTimerRef.current) clearTimeout(applyTimerRef.current);
17082
17522
  };
@@ -17317,25 +17757,31 @@ function AutoFitView({ nodeCount }) {
17317
17757
  var UndoRedoToolbar = (0, react.memo)(function UndoRedoToolbar() {
17318
17758
  const { undo, redo, canUndo, canRedo } = useEditorContext();
17319
17759
  if (!canUndo && !canRedo) return null;
17320
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17321
- type: "button",
17322
- className: "dl-toolbar-btn",
17323
- onClick: undo,
17324
- disabled: !canUndo,
17325
- title: "Undo (Cmd/Ctrl+Z)",
17326
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Undo2, { size: 15 })
17327
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17328
- type: "button",
17329
- className: "dl-toolbar-btn",
17330
- onClick: redo,
17331
- disabled: !canRedo,
17332
- title: "Redo (Cmd/Ctrl+Shift+Z)",
17333
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Redo2, { size: 15 })
17760
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
17761
+ label: "Undo",
17762
+ shortcut: "⌘Z",
17763
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17764
+ type: "button",
17765
+ className: "dl-toolbar-btn",
17766
+ onClick: undo,
17767
+ disabled: !canUndo,
17768
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Undo2, { size: 15 })
17769
+ })
17770
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
17771
+ label: "Redo",
17772
+ shortcut: "⌘⇧Z",
17773
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17774
+ type: "button",
17775
+ className: "dl-toolbar-btn",
17776
+ onClick: redo,
17777
+ disabled: !canRedo,
17778
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Redo2, { size: 15 })
17779
+ })
17334
17780
  })] });
17335
17781
  });
17336
17782
  //#endregion
17337
17783
  //#region src/components/logic-editor/EditorToolbar.tsx
17338
- var EditorToolbar = (0, react.memo)(function EditorToolbar({ isEditMode, hasDebugger, preserveStructure, onPreserveStructureChange }) {
17784
+ var EditorToolbar = (0, react.memo)(function EditorToolbar({ isEditMode, hasDebugger, templating, onTemplatingChange }) {
17339
17785
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17340
17786
  className: "logic-editor-toolbar",
17341
17787
  children: [
@@ -17343,13 +17789,17 @@ var EditorToolbar = (0, react.memo)(function EditorToolbar({ isEditMode, hasDebu
17343
17789
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "logic-editor-toolbar-spacer" }),
17344
17790
  hasDebugger && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DebuggerControlsInline, {}),
17345
17791
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "logic-editor-toolbar-spacer" }),
17346
- onPreserveStructureChange && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
17347
- className: "dl-preserve-structure-toggle",
17348
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17349
- type: "checkbox",
17350
- checked: preserveStructure,
17351
- onChange: (e) => onPreserveStructureChange(e.target.checked)
17352
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Preserve Structure" })]
17792
+ onTemplatingChange && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
17793
+ label: "Compile multi-key objects as output templates with embedded JSONLogic",
17794
+ side: "bottom",
17795
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
17796
+ className: "dl-templating-toggle",
17797
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17798
+ type: "checkbox",
17799
+ checked: templating,
17800
+ onChange: (e) => onTemplatingChange(e.target.checked)
17801
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Templating" })]
17802
+ })
17353
17803
  })
17354
17804
  ]
17355
17805
  });
@@ -17357,11 +17807,43 @@ var EditorToolbar = (0, react.memo)(function EditorToolbar({ isEditMode, hasDebu
17357
17807
  //#endregion
17358
17808
  //#region src/components/logic-editor/DataLogicEditor.tsx
17359
17809
  var emptyResults = /* @__PURE__ */ new Map();
17810
+ function EmptyState({ exampleSuggestions, onSelectExample }) {
17811
+ const chips = exampleSuggestions && onSelectExample ? exampleSuggestions : [];
17812
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17813
+ className: "logic-editor-empty",
17814
+ children: [
17815
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17816
+ className: "logic-editor-empty-icon",
17817
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Workflow, {
17818
+ size: 28,
17819
+ strokeWidth: 1.5
17820
+ })
17821
+ }),
17822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "No expression" }),
17823
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17824
+ className: "logic-editor-empty-hint",
17825
+ children: "Enter valid JSONLogic in the input panel to visualize it."
17826
+ }),
17827
+ chips.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17828
+ className: "logic-editor-empty-chips",
17829
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
17830
+ className: "logic-editor-empty-chips-label",
17831
+ children: "Try"
17832
+ }), chips.map((name) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17833
+ type: "button",
17834
+ className: "logic-editor-empty-chip",
17835
+ onClick: () => onSelectExample?.(name),
17836
+ children: name
17837
+ }, name))]
17838
+ })
17839
+ ]
17840
+ });
17841
+ }
17360
17842
  /**
17361
17843
  * Read-only inner component - minimal, no EditorContext dependency.
17362
17844
  * Used when editable=false to avoid EditorProvider's state sync effects.
17363
17845
  */
17364
- function ReadOnlyEditorInner({ initialNodes, initialEdges, theme, showDebugger }) {
17846
+ function ReadOnlyEditorInner({ initialNodes, initialEdges, theme, showDebugger, exampleSuggestions, onSelectExample }) {
17365
17847
  const bgColor = theme === "dark" ? "#404040" : "#cccccc";
17366
17848
  const [nodes, , onNodesChange] = (0, _xyflow_react.useNodesState)(initialNodes);
17367
17849
  const [, , onEdgesChange] = (0, _xyflow_react.useEdgesState)(initialEdges);
@@ -17406,12 +17888,9 @@ function ReadOnlyEditorInner({ initialNodes, initialEdges, theme, showDebugger }
17406
17888
  showDebugger && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DebuggerControls, {}),
17407
17889
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoFitView, { nodeCount: initialNodes.length })
17408
17890
  ]
17409
- }) }), visibleNodes.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17410
- className: "logic-editor-empty",
17411
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "No expression" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17412
- className: "logic-editor-empty-hint",
17413
- children: "Enter valid JSONLogic in the input panel to visualize it"
17414
- })]
17891
+ }) }), visibleNodes.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
17892
+ exampleSuggestions,
17893
+ onSelectExample
17415
17894
  })]
17416
17895
  })
17417
17896
  });
@@ -17420,7 +17899,7 @@ function ReadOnlyEditorInner({ initialNodes, initialEdges, theme, showDebugger }
17420
17899
  * Editable inner component - full EditorContext support with syncing.
17421
17900
  * Used when editable=true.
17422
17901
  */
17423
- function EditableEditorInner({ initialNodes, initialEdges, evaluationResults, theme, showDebugger }) {
17902
+ function EditableEditorInner({ initialNodes, initialEdges, evaluationResults, theme, showDebugger, exampleSuggestions, onSelectExample }) {
17424
17903
  const bgColor = theme === "dark" ? "#404040" : "#cccccc";
17425
17904
  const { contextMenu, handleNodeContextMenu, handlePaneContextMenu, handleNodeDoubleClick, handleCloseContextMenu, handleEditProperties, contextMenuNode } = useContextMenu(true);
17426
17905
  const { nodes: editorNodes } = useEditorContext();
@@ -17498,28 +17977,25 @@ function EditableEditorInner({ initialNodes, initialEdges, evaluationResults, th
17498
17977
  onClose: handleCloseContextMenu
17499
17978
  })
17500
17979
  ]
17501
- }) }), visibleNodes.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17502
- className: "logic-editor-empty",
17503
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "No expression" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17504
- className: "logic-editor-empty-hint",
17505
- children: "Enter valid JSONLogic in the input panel to visualize it"
17506
- })]
17980
+ }) }), visibleNodes.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmptyState, {
17981
+ exampleSuggestions,
17982
+ onSelectExample
17507
17983
  })]
17508
17984
  })
17509
17985
  });
17510
17986
  }
17511
- function DataLogicEditor({ value, onChange, data, theme: themeProp, className = "", preserveStructure = false, onPreserveStructureChange, editable = false }) {
17987
+ function DataLogicEditor({ value, onChange, data, theme: themeProp, className = "", templating = false, onTemplatingChange, editable = false, exampleSuggestions, onSelectExample }) {
17512
17988
  const onChangeTimerRef = (0, react.useRef)(null);
17513
17989
  const isEditMode = editable;
17514
17990
  const systemTheme = useSystemTheme();
17515
17991
  const resolvedTheme = themeProp ?? systemTheme;
17516
- const { ready: wasmReady, evaluateWithTrace } = useWasmEvaluator({ preserveStructure });
17992
+ const { ready: wasmReady, evaluateWithTrace } = useWasmEvaluator({ templating });
17517
17993
  const evalEnabled = data !== void 0;
17518
17994
  const editor = useLogicEditor({
17519
17995
  value,
17520
17996
  evaluateWithTrace: evalEnabled && wasmReady ? evaluateWithTrace : void 0,
17521
17997
  data: evalEnabled ? data : void 0,
17522
- preserveStructure
17998
+ templating
17523
17999
  });
17524
18000
  const expressionKey = `${editor.nodes.length}-${editor.edges.length}-${editor.nodes[0]?.id ?? "empty"}`;
17525
18001
  const hasDebugger = evalEnabled && editor.usingTraceMode && editor.steps.length > 0;
@@ -17556,7 +18032,9 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17556
18032
  initialNodes: editor.nodes,
17557
18033
  initialEdges: editor.edges,
17558
18034
  theme: resolvedTheme,
17559
- showDebugger: false
18035
+ showDebugger: false,
18036
+ exampleSuggestions,
18037
+ onSelectExample
17560
18038
  }, expressionKey);
17561
18039
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17562
18040
  className: editorClassName,
@@ -17568,8 +18046,8 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17568
18046
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditorToolbar, {
17569
18047
  isEditMode: false,
17570
18048
  hasDebugger,
17571
- preserveStructure,
17572
- onPreserveStructureChange
18049
+ templating,
18050
+ onTemplatingChange
17573
18051
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17574
18052
  className: "logic-editor-body",
17575
18053
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -17580,8 +18058,8 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17580
18058
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditorToolbar, {
17581
18059
  isEditMode: false,
17582
18060
  hasDebugger,
17583
- preserveStructure,
17584
- onPreserveStructureChange
18061
+ templating,
18062
+ onTemplatingChange
17585
18063
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17586
18064
  className: "logic-editor-body",
17587
18065
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -17596,7 +18074,9 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17596
18074
  initialEdges: editor.edges,
17597
18075
  evaluationResults: emptyResults,
17598
18076
  theme: resolvedTheme,
17599
- showDebugger: false
18077
+ showDebugger: false,
18078
+ exampleSuggestions,
18079
+ onSelectExample
17600
18080
  }, expressionKey);
17601
18081
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(EditorProvider, {
17602
18082
  nodes: editor.nodes,
@@ -17612,8 +18092,8 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17612
18092
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditorToolbar, {
17613
18093
  isEditMode,
17614
18094
  hasDebugger,
17615
- preserveStructure,
17616
- onPreserveStructureChange
18095
+ templating,
18096
+ onTemplatingChange
17617
18097
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17618
18098
  className: "logic-editor-body",
17619
18099
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -17624,8 +18104,8 @@ function DataLogicEditor({ value, onChange, data, theme: themeProp, className =
17624
18104
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditorToolbar, {
17625
18105
  isEditMode,
17626
18106
  hasDebugger,
17627
- preserveStructure,
17628
- onPreserveStructureChange
18107
+ templating,
18108
+ onTemplatingChange
17629
18109
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17630
18110
  className: "logic-editor-body",
17631
18111
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {