@retikz/core 0.1.0-alpha.0 → 0.1.0-alpha.2

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 (121) hide show
  1. package/dist/es/compile/index.d.ts +1 -0
  2. package/dist/es/compile/index.d.ts.map +1 -1
  3. package/dist/es/compile/node.d.ts +73 -22
  4. package/dist/es/compile/node.d.ts.map +1 -1
  5. package/dist/es/compile/node.js +276 -52
  6. package/dist/es/compile/parseTarget.d.ts +25 -0
  7. package/dist/es/compile/parseTarget.d.ts.map +1 -0
  8. package/dist/es/compile/parseTarget.js +48 -0
  9. package/dist/es/compile/path.d.ts +17 -7
  10. package/dist/es/compile/path.d.ts.map +1 -1
  11. package/dist/es/compile/path.js +276 -33
  12. package/dist/es/compile/text-metrics.d.ts +2 -2
  13. package/dist/es/compile/text-metrics.d.ts.map +1 -1
  14. package/dist/es/geometry/circle.d.ts +32 -0
  15. package/dist/es/geometry/circle.d.ts.map +1 -0
  16. package/dist/es/geometry/circle.js +79 -0
  17. package/dist/es/geometry/diamond.d.ts +44 -0
  18. package/dist/es/geometry/diamond.d.ts.map +1 -0
  19. package/dist/es/geometry/diamond.js +87 -0
  20. package/dist/es/geometry/ellipse.d.ts +38 -0
  21. package/dist/es/geometry/ellipse.d.ts.map +1 -0
  22. package/dist/es/geometry/ellipse.js +86 -0
  23. package/dist/es/geometry/index.d.ts +3 -0
  24. package/dist/es/geometry/index.d.ts.map +1 -1
  25. package/dist/es/index.d.ts +9 -7
  26. package/dist/es/index.d.ts.map +1 -1
  27. package/dist/es/index.js +8 -4
  28. package/dist/es/ir/node.d.ts +319 -7
  29. package/dist/es/ir/node.d.ts.map +1 -1
  30. package/dist/es/ir/node.js +96 -8
  31. package/dist/es/ir/path/arrow.d.ts +26 -0
  32. package/dist/es/ir/path/arrow.d.ts.map +1 -0
  33. package/dist/es/ir/path/arrow.js +25 -0
  34. package/dist/es/ir/path/index.d.ts +1 -0
  35. package/dist/es/ir/path/index.d.ts.map +1 -1
  36. package/dist/es/ir/path/path.d.ts +60 -0
  37. package/dist/es/ir/path/path.d.ts.map +1 -1
  38. package/dist/es/ir/path/path.js +10 -0
  39. package/dist/es/ir/path/step.d.ts +56 -2
  40. package/dist/es/ir/path/step.d.ts.map +1 -1
  41. package/dist/es/ir/path/step.js +17 -2
  42. package/dist/es/ir/scene.d.ts +538 -16
  43. package/dist/es/ir/scene.d.ts.map +1 -1
  44. package/dist/es/parsers/parseWay.d.ts +56 -10
  45. package/dist/es/parsers/parseWay.d.ts.map +1 -1
  46. package/dist/es/parsers/parseWay.js +68 -6
  47. package/dist/es/primitive/ellipse.d.ts +34 -0
  48. package/dist/es/primitive/ellipse.d.ts.map +1 -0
  49. package/dist/es/primitive/index.d.ts +1 -0
  50. package/dist/es/primitive/index.d.ts.map +1 -1
  51. package/dist/es/primitive/path.d.ts +11 -0
  52. package/dist/es/primitive/path.d.ts.map +1 -1
  53. package/dist/es/primitive/rect.d.ts +2 -0
  54. package/dist/es/primitive/rect.d.ts.map +1 -1
  55. package/dist/es/primitive/scene.d.ts +2 -1
  56. package/dist/es/primitive/scene.d.ts.map +1 -1
  57. package/dist/es/primitive/text.d.ts +43 -13
  58. package/dist/es/primitive/text.d.ts.map +1 -1
  59. package/dist/es/types.d.ts +3 -0
  60. package/dist/es/types.d.ts.map +1 -0
  61. package/dist/lib/compile/index.d.ts +1 -0
  62. package/dist/lib/compile/index.d.ts.map +1 -1
  63. package/dist/lib/compile/node.cjs +278 -52
  64. package/dist/lib/compile/node.d.ts +73 -22
  65. package/dist/lib/compile/node.d.ts.map +1 -1
  66. package/dist/lib/compile/parseTarget.cjs +48 -0
  67. package/dist/lib/compile/parseTarget.d.ts +25 -0
  68. package/dist/lib/compile/parseTarget.d.ts.map +1 -0
  69. package/dist/lib/compile/path.cjs +275 -32
  70. package/dist/lib/compile/path.d.ts +17 -7
  71. package/dist/lib/compile/path.d.ts.map +1 -1
  72. package/dist/lib/compile/text-metrics.d.ts +2 -2
  73. package/dist/lib/compile/text-metrics.d.ts.map +1 -1
  74. package/dist/lib/geometry/circle.cjs +79 -0
  75. package/dist/lib/geometry/circle.d.ts +32 -0
  76. package/dist/lib/geometry/circle.d.ts.map +1 -0
  77. package/dist/lib/geometry/diamond.cjs +87 -0
  78. package/dist/lib/geometry/diamond.d.ts +44 -0
  79. package/dist/lib/geometry/diamond.d.ts.map +1 -0
  80. package/dist/lib/geometry/ellipse.cjs +86 -0
  81. package/dist/lib/geometry/ellipse.d.ts +38 -0
  82. package/dist/lib/geometry/ellipse.d.ts.map +1 -0
  83. package/dist/lib/geometry/index.d.ts +3 -0
  84. package/dist/lib/geometry/index.d.ts.map +1 -1
  85. package/dist/lib/index.cjs +16 -0
  86. package/dist/lib/index.d.ts +9 -7
  87. package/dist/lib/index.d.ts.map +1 -1
  88. package/dist/lib/ir/node.cjs +100 -7
  89. package/dist/lib/ir/node.d.ts +319 -7
  90. package/dist/lib/ir/node.d.ts.map +1 -1
  91. package/dist/lib/ir/path/arrow.cjs +25 -0
  92. package/dist/lib/ir/path/arrow.d.ts +26 -0
  93. package/dist/lib/ir/path/arrow.d.ts.map +1 -0
  94. package/dist/lib/ir/path/index.d.ts +1 -0
  95. package/dist/lib/ir/path/index.d.ts.map +1 -1
  96. package/dist/lib/ir/path/path.cjs +10 -0
  97. package/dist/lib/ir/path/path.d.ts +60 -0
  98. package/dist/lib/ir/path/path.d.ts.map +1 -1
  99. package/dist/lib/ir/path/step.cjs +18 -1
  100. package/dist/lib/ir/path/step.d.ts +56 -2
  101. package/dist/lib/ir/path/step.d.ts.map +1 -1
  102. package/dist/lib/ir/scene.d.ts +538 -16
  103. package/dist/lib/ir/scene.d.ts.map +1 -1
  104. package/dist/lib/parsers/parseWay.cjs +68 -5
  105. package/dist/lib/parsers/parseWay.d.ts +56 -10
  106. package/dist/lib/parsers/parseWay.d.ts.map +1 -1
  107. package/dist/lib/primitive/ellipse.d.ts +34 -0
  108. package/dist/lib/primitive/ellipse.d.ts.map +1 -0
  109. package/dist/lib/primitive/index.d.ts +1 -0
  110. package/dist/lib/primitive/index.d.ts.map +1 -1
  111. package/dist/lib/primitive/path.d.ts +11 -0
  112. package/dist/lib/primitive/path.d.ts.map +1 -1
  113. package/dist/lib/primitive/rect.d.ts +2 -0
  114. package/dist/lib/primitive/rect.d.ts.map +1 -1
  115. package/dist/lib/primitive/scene.d.ts +2 -1
  116. package/dist/lib/primitive/scene.d.ts.map +1 -1
  117. package/dist/lib/primitive/text.d.ts +43 -13
  118. package/dist/lib/primitive/text.d.ts.map +1 -1
  119. package/dist/lib/types.d.ts +3 -0
  120. package/dist/lib/types.d.ts.map +1 -0
  121. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ //#region src/geometry/ellipse.ts
2
+ var SQRT_HALF = Math.SQRT1_2;
3
+ var localToWorld = (e, local) => {
4
+ const angle = e.rotate ?? 0;
5
+ if (angle === 0) return [e.x + local[0], e.y + local[1]];
6
+ const cos = Math.cos(angle);
7
+ const sin = Math.sin(angle);
8
+ return [e.x + local[0] * cos - local[1] * sin, e.y + local[0] * sin + local[1] * cos];
9
+ };
10
+ var worldToLocal = (e, world) => {
11
+ const tx = world[0] - e.x;
12
+ const ty = world[1] - e.y;
13
+ const angle = e.rotate ?? 0;
14
+ if (angle === 0) return [tx, ty];
15
+ const cos = Math.cos(angle);
16
+ const sin = Math.sin(angle);
17
+ return [tx * cos + ty * sin, -tx * sin + ty * cos];
18
+ };
19
+ /** 椭圆相关基础工具 */
20
+ var ellipse = {
21
+ /** 中心 */
22
+ center: (e) => [e.x, e.y],
23
+ /** 判断点是否在椭圆内(含边界,考虑旋转) */
24
+ contains: (e, p) => {
25
+ const [lx, ly] = worldToLocal(e, p);
26
+ return lx * lx / (e.rx * e.rx) + ly * ly / (e.ry * e.ry) <= 1;
27
+ },
28
+ /**
29
+ * 9 个标准 anchor 的世界坐标。
30
+ * 对角 anchor(NE/NW/SE/SW)取参数曲线 t=π/4 处的点:
31
+ * (rx·cos(π/4), ry·sin(π/4)) = (rx/√2, ry/√2)。
32
+ * 这与 TikZ 椭圆对角 anchor 的"参数等分"约定一致。
33
+ */
34
+ anchor: (e, name) => {
35
+ let lx = 0;
36
+ let ly = 0;
37
+ switch (name) {
38
+ case "center": break;
39
+ case "north":
40
+ ly = -e.ry;
41
+ break;
42
+ case "south":
43
+ ly = e.ry;
44
+ break;
45
+ case "east":
46
+ lx = e.rx;
47
+ break;
48
+ case "west":
49
+ lx = -e.rx;
50
+ break;
51
+ case "north-east":
52
+ lx = e.rx * SQRT_HALF;
53
+ ly = -e.ry * SQRT_HALF;
54
+ break;
55
+ case "north-west":
56
+ lx = -e.rx * SQRT_HALF;
57
+ ly = -e.ry * SQRT_HALF;
58
+ break;
59
+ case "south-east":
60
+ lx = e.rx * SQRT_HALF;
61
+ ly = e.ry * SQRT_HALF;
62
+ break;
63
+ case "south-west":
64
+ lx = -e.rx * SQRT_HALF;
65
+ ly = e.ry * SQRT_HALF;
66
+ break;
67
+ }
68
+ return localToWorld(e, [lx, ly]);
69
+ },
70
+ /**
71
+ * 从中心向 toward 方向画射线,求与椭圆的交点。
72
+ * 椭圆方程:(x/rx)² + (y/ry)² = 1。
73
+ * 沿方向 (lx, ly) 缩放 t 倍命中:t² × ((lx/rx)² + (ly/ry)²) = 1
74
+ * → t = 1 / √((lx/rx)² + (ly/ry)²)。
75
+ */
76
+ boundaryPoint: (e, toward) => {
77
+ const [lx, ly] = worldToLocal(e, toward);
78
+ if (lx === 0 && ly === 0) return [e.x, e.y];
79
+ const a = lx / e.rx;
80
+ const b = ly / e.ry;
81
+ const t = 1 / Math.sqrt(a * a + b * b);
82
+ return localToWorld(e, [lx * t, ly * t]);
83
+ }
84
+ };
85
+ //#endregion
86
+ export { ellipse };
@@ -1,4 +1,7 @@
1
1
  export * from './point';
2
2
  export * from './rect';
3
+ export * from './circle';
4
+ export * from './ellipse';
5
+ export * from './diamond';
3
6
  export * from './polar';
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/geometry/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/geometry/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
@@ -6,13 +6,15 @@
6
6
  *
7
7
  * 本包零 React、零 DOM 依赖。
8
8
  */
9
- export { PositionSchema, PolarPositionSchema, TargetSchema, MoveStepSchema, LineStepSchema, StepSchema, NodeSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
10
- export type { IRPosition, IRTarget, IRMoveStep, IRLineStep, IRStep, IRNode, IRPath, IRChild, IR, } from './ir';
11
- export type { ScenePrimitive, RectPrim, TextPrim, PathPrim, GroupPrim, ViewBox, Scene, } from './primitive';
9
+ export { PositionSchema, PolarPositionSchema, TargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, StepSchema, NodeSchema, FontSchema, NodeTextSchema, LineSpecSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
10
+ export type { IRPosition, IRTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRStep, IRNode, IRFont, IRLineSpec, IRPath, IRChild, IR, ArrowShape, NodeShape, NodeTextAlign, } from './ir';
11
+ export { ARROW_SHAPES, NODE_SHAPES, NODE_TEXT_ALIGNS } from './ir';
12
+ export type { ScenePrimitive, RectPrim, EllipsePrim, TextPrim, TextLine, PathPrim, GroupPrim, ViewBox, Scene, } from './primitive';
12
13
  export type { FontSpec, TextMetrics, TextMeasurer, CompileOptions, } from './compile';
13
14
  export { fallbackMeasurer, compileToScene } from './compile';
14
- export type { WayItem, WayDSL } from './parsers';
15
- export { parseWay } from './parsers';
16
- export type { Position, Rect, RectAnchor, PolarPosition } from './geometry';
17
- export { point, rect, RECT_ANCHORS, polar } from './geometry';
15
+ export type { WayItem, WayDSL, WayCycle, WayVia } from './parsers';
16
+ export { parseWay, DrawWay } from './parsers';
17
+ export type { Position, Rect, RectAnchor, Circle, CircleAnchor, Ellipse, EllipseAnchor, Diamond, DiamondAnchor, PolarPosition, } from './geometry';
18
+ export { point, rect, circle, ellipse, diamond, RECT_ANCHORS, polar } from './geometry';
19
+ export type { ValueOf } from './types';
18
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,EAAE,GACH,MAAM,MAAM,CAAC;AAGd,YAAY,EACV,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,OAAO,EACP,KAAK,GACN,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG7D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIrC,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,MAAM,EACN,MAAM,EACN,MAAM,EACN,UAAU,EACV,MAAM,EACN,OAAO,EACP,EAAE,EACF,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AAGnE,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,OAAO,EACP,KAAK,GACN,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG7D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAI9C,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,MAAM,EACN,YAAY,EACZ,OAAO,EACP,aAAa,EACb,OAAO,EACP,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxF,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
package/dist/es/index.js CHANGED
@@ -1,14 +1,18 @@
1
1
  import { PositionSchema } from "./ir/position/position.js";
2
2
  import { PolarPositionSchema } from "./ir/position/polar-position.js";
3
+ import { ARROW_SHAPES } from "./ir/path/arrow.js";
3
4
  import { TargetSchema } from "./ir/path/target.js";
4
- import { LineStepSchema, MoveStepSchema, StepSchema } from "./ir/path/step.js";
5
+ import { CycleStepSchema, FoldStepSchema, LineStepSchema, MoveStepSchema, StepSchema } from "./ir/path/step.js";
5
6
  import { PathSchema } from "./ir/path/path.js";
6
- import { NodeSchema } from "./ir/node.js";
7
+ import { FontSchema, LineSpecSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeSchema, NodeTextSchema } from "./ir/node.js";
7
8
  import { CURRENT_IR_VERSION, ChildSchema, SceneSchema } from "./ir/scene.js";
8
9
  import { RECT_ANCHORS, rect } from "./geometry/rect.js";
10
+ import { circle } from "./geometry/circle.js";
11
+ import { diamond } from "./geometry/diamond.js";
12
+ import { ellipse } from "./geometry/ellipse.js";
9
13
  import { fallbackMeasurer } from "./compile/text-metrics.js";
10
14
  import { compileToScene } from "./compile/compile.js";
11
- import { parseWay } from "./parsers/parseWay.js";
15
+ import { DrawWay, parseWay } from "./parsers/parseWay.js";
12
16
  import { polar } from "./geometry/polar.js";
13
17
  import { point } from "./geometry/point.js";
14
- export { CURRENT_IR_VERSION, ChildSchema, LineStepSchema, MoveStepSchema, NodeSchema, PathSchema, PolarPositionSchema, PositionSchema, RECT_ANCHORS, SceneSchema, StepSchema, TargetSchema, compileToScene, fallbackMeasurer, parseWay, point, polar, rect };
18
+ export { ARROW_SHAPES, CURRENT_IR_VERSION, ChildSchema, CycleStepSchema, DrawWay, FoldStepSchema, FontSchema, LineSpecSchema, LineStepSchema, MoveStepSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeSchema, NodeTextSchema, PathSchema, PolarPositionSchema, PositionSchema, RECT_ANCHORS, SceneSchema, StepSchema, TargetSchema, circle, compileToScene, diamond, ellipse, fallbackMeasurer, parseWay, point, polar, rect };
@@ -1,41 +1,353 @@
1
1
  import { z } from 'zod';
2
+ import { ValueOf } from '../types';
3
+ /**
4
+ * 节点形状常量。值是 IR 中 `shape` 字段的字面字符串;
5
+ * 用 const + ValueOf 派生(不用 TS enum)。
6
+ *
7
+ * - `rectangle`:矩形(默认;UML 类、流程图常规节点)
8
+ * - `circle`:圆形(流程图起止、状态机)
9
+ * - `ellipse`:椭圆(状态机、集合图)
10
+ * - `diamond`:菱形(流程图判定)
11
+ *
12
+ * 每个 shape 的几何语义:node 的视觉边界包住"text 矩形 + padding"——
13
+ * - rectangle: 视觉 rect = text rect
14
+ * - circle: 外接圆,r = √(innerHalfW² + innerHalfH²)
15
+ * - ellipse: 外接椭圆,rx = innerHalfW×√2、ry = innerHalfH×√2
16
+ * - diamond: 外接菱形,halfA = 2×innerHalfW、halfB = 2×innerHalfH
17
+ */
18
+ export declare const NODE_SHAPES: {
19
+ readonly rectangle: "rectangle";
20
+ readonly circle: "circle";
21
+ readonly ellipse: "ellipse";
22
+ readonly diamond: "diamond";
23
+ };
24
+ /** 节点形状字面量类型,由 `NODE_SHAPES` 派生 */
25
+ export type NodeShape = ValueOf<typeof NODE_SHAPES>;
26
+ /**
27
+ * 节点字体规格——family / size / weight / style 全部可选;
28
+ * 单字段透传到 SVG `<text>` 的 `font-*` 属性 / `font-size`。
29
+ *
30
+ * 取代 alpha.1 的标量 `fontSize` 字段(已删)。
31
+ */
32
+ export declare const FontSchema: z.ZodObject<{
33
+ family: z.ZodOptional<z.ZodString>;
34
+ size: z.ZodOptional<z.ZodNumber>;
35
+ weight: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["normal", "bold"]>, z.ZodNumber]>>;
36
+ style: z.ZodOptional<z.ZodEnum<["normal", "italic", "oblique"]>>;
37
+ }, "strip", z.ZodTypeAny, {
38
+ family?: string | undefined;
39
+ size?: number | undefined;
40
+ weight?: number | "normal" | "bold" | undefined;
41
+ style?: "normal" | "italic" | "oblique" | undefined;
42
+ }, {
43
+ family?: string | undefined;
44
+ size?: number | undefined;
45
+ weight?: number | "normal" | "bold" | undefined;
46
+ style?: "normal" | "italic" | "oblique" | undefined;
47
+ }>;
48
+ /** 节点字体规格(IR 层)——所有字段可选,编译期解析默认值 */
49
+ export type IRFont = z.infer<typeof FontSchema>;
50
+ /**
51
+ * 单行文本规格——纯字符串走块级默认样式;对象形式可对该行覆盖 fill / opacity / font。
52
+ *
53
+ * 行级覆盖只生效于本行的 `<tspan>`:
54
+ * - `fill`:仅这一行颜色
55
+ * - `opacity`:仅这一行 0~1 透明度
56
+ * - `font`:family / size / weight / style 任意子集;未填字段继承块级 font
57
+ *
58
+ * 块级 `align` / `lineHeight` 不可被行覆盖(多行块整体属性)。
59
+ */
60
+ export declare const LineSpecSchema: z.ZodUnion<[z.ZodString, z.ZodObject<{
61
+ text: z.ZodString;
62
+ fill: z.ZodOptional<z.ZodString>;
63
+ opacity: z.ZodOptional<z.ZodNumber>;
64
+ font: z.ZodOptional<z.ZodObject<{
65
+ family: z.ZodOptional<z.ZodString>;
66
+ size: z.ZodOptional<z.ZodNumber>;
67
+ weight: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["normal", "bold"]>, z.ZodNumber]>>;
68
+ style: z.ZodOptional<z.ZodEnum<["normal", "italic", "oblique"]>>;
69
+ }, "strip", z.ZodTypeAny, {
70
+ family?: string | undefined;
71
+ size?: number | undefined;
72
+ weight?: number | "normal" | "bold" | undefined;
73
+ style?: "normal" | "italic" | "oblique" | undefined;
74
+ }, {
75
+ family?: string | undefined;
76
+ size?: number | undefined;
77
+ weight?: number | "normal" | "bold" | undefined;
78
+ style?: "normal" | "italic" | "oblique" | undefined;
79
+ }>>;
80
+ }, "strip", z.ZodTypeAny, {
81
+ text: string;
82
+ fill?: string | undefined;
83
+ opacity?: number | undefined;
84
+ font?: {
85
+ family?: string | undefined;
86
+ size?: number | undefined;
87
+ weight?: number | "normal" | "bold" | undefined;
88
+ style?: "normal" | "italic" | "oblique" | undefined;
89
+ } | undefined;
90
+ }, {
91
+ text: string;
92
+ fill?: string | undefined;
93
+ opacity?: number | undefined;
94
+ font?: {
95
+ family?: string | undefined;
96
+ size?: number | undefined;
97
+ weight?: number | "normal" | "bold" | undefined;
98
+ style?: "normal" | "italic" | "oblique" | undefined;
99
+ } | undefined;
100
+ }>]>;
101
+ /** 行规格 IR 类型(string 或对象) */
102
+ export type IRLineSpec = z.infer<typeof LineSpecSchema>;
103
+ /**
104
+ * 节点文本——单行字符串或非空多行数组(每元素一个 LineSpec):
105
+ * - `'Hello'` 等价于 `[{ text: 'Hello' }]`,按一行渲染
106
+ * - `['Line 1', 'Line 2']` 两行无样式覆盖
107
+ * - `[{ text: 'Heading', fill: 'red', font: { weight: 'bold' } }, 'body']` 混排
108
+ *
109
+ * 选 `Array<LineSpec>` 而非 `'\n'` 字符串:JSON 友好(无 escape);行级覆盖天然落字段。
110
+ */
111
+ export declare const NodeTextSchema: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
112
+ text: z.ZodString;
113
+ fill: z.ZodOptional<z.ZodString>;
114
+ opacity: z.ZodOptional<z.ZodNumber>;
115
+ font: z.ZodOptional<z.ZodObject<{
116
+ family: z.ZodOptional<z.ZodString>;
117
+ size: z.ZodOptional<z.ZodNumber>;
118
+ weight: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["normal", "bold"]>, z.ZodNumber]>>;
119
+ style: z.ZodOptional<z.ZodEnum<["normal", "italic", "oblique"]>>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ family?: string | undefined;
122
+ size?: number | undefined;
123
+ weight?: number | "normal" | "bold" | undefined;
124
+ style?: "normal" | "italic" | "oblique" | undefined;
125
+ }, {
126
+ family?: string | undefined;
127
+ size?: number | undefined;
128
+ weight?: number | "normal" | "bold" | undefined;
129
+ style?: "normal" | "italic" | "oblique" | undefined;
130
+ }>>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ text: string;
133
+ fill?: string | undefined;
134
+ opacity?: number | undefined;
135
+ font?: {
136
+ family?: string | undefined;
137
+ size?: number | undefined;
138
+ weight?: number | "normal" | "bold" | undefined;
139
+ style?: "normal" | "italic" | "oblique" | undefined;
140
+ } | undefined;
141
+ }, {
142
+ text: string;
143
+ fill?: string | undefined;
144
+ opacity?: number | undefined;
145
+ font?: {
146
+ family?: string | undefined;
147
+ size?: number | undefined;
148
+ weight?: number | "normal" | "bold" | undefined;
149
+ style?: "normal" | "italic" | "oblique" | undefined;
150
+ } | undefined;
151
+ }>]>, "many">]>;
152
+ /** 节点文本对齐(多行内文本对齐)——TikZ `align=` 同义词 */
153
+ export declare const NODE_TEXT_ALIGNS: {
154
+ readonly left: "left";
155
+ readonly center: "center";
156
+ readonly right: "right";
157
+ };
158
+ /** 多行文本对齐字面量类型 */
159
+ export type NodeTextAlign = ValueOf<typeof NODE_TEXT_ALIGNS>;
2
160
  export declare const NodeSchema: z.ZodObject<{
3
161
  type: z.ZodLiteral<"node">;
4
162
  id: z.ZodOptional<z.ZodString>;
163
+ shape: z.ZodOptional<z.ZodNativeEnum<{
164
+ readonly rectangle: "rectangle";
165
+ readonly circle: "circle";
166
+ readonly ellipse: "ellipse";
167
+ readonly diamond: "diamond";
168
+ }>>;
5
169
  position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, z.ZodType<import('./position').PolarPosition, z.ZodTypeDef, import('./position').PolarPosition>]>;
6
170
  rotate: z.ZodOptional<z.ZodNumber>;
7
- text: z.ZodOptional<z.ZodString>;
171
+ text: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
172
+ text: z.ZodString;
173
+ fill: z.ZodOptional<z.ZodString>;
174
+ opacity: z.ZodOptional<z.ZodNumber>;
175
+ font: z.ZodOptional<z.ZodObject<{
176
+ family: z.ZodOptional<z.ZodString>;
177
+ size: z.ZodOptional<z.ZodNumber>;
178
+ weight: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["normal", "bold"]>, z.ZodNumber]>>;
179
+ style: z.ZodOptional<z.ZodEnum<["normal", "italic", "oblique"]>>;
180
+ }, "strip", z.ZodTypeAny, {
181
+ family?: string | undefined;
182
+ size?: number | undefined;
183
+ weight?: number | "normal" | "bold" | undefined;
184
+ style?: "normal" | "italic" | "oblique" | undefined;
185
+ }, {
186
+ family?: string | undefined;
187
+ size?: number | undefined;
188
+ weight?: number | "normal" | "bold" | undefined;
189
+ style?: "normal" | "italic" | "oblique" | undefined;
190
+ }>>;
191
+ }, "strip", z.ZodTypeAny, {
192
+ text: string;
193
+ fill?: string | undefined;
194
+ opacity?: number | undefined;
195
+ font?: {
196
+ family?: string | undefined;
197
+ size?: number | undefined;
198
+ weight?: number | "normal" | "bold" | undefined;
199
+ style?: "normal" | "italic" | "oblique" | undefined;
200
+ } | undefined;
201
+ }, {
202
+ text: string;
203
+ fill?: string | undefined;
204
+ opacity?: number | undefined;
205
+ font?: {
206
+ family?: string | undefined;
207
+ size?: number | undefined;
208
+ weight?: number | "normal" | "bold" | undefined;
209
+ style?: "normal" | "italic" | "oblique" | undefined;
210
+ } | undefined;
211
+ }>]>, "many">]>>;
212
+ align: z.ZodOptional<z.ZodNativeEnum<{
213
+ readonly left: "left";
214
+ readonly center: "center";
215
+ readonly right: "right";
216
+ }>>;
217
+ lineHeight: z.ZodOptional<z.ZodNumber>;
8
218
  fill: z.ZodOptional<z.ZodString>;
219
+ fillOpacity: z.ZodOptional<z.ZodNumber>;
9
220
  stroke: z.ZodOptional<z.ZodString>;
221
+ drawOpacity: z.ZodOptional<z.ZodNumber>;
10
222
  strokeWidth: z.ZodOptional<z.ZodNumber>;
223
+ dashed: z.ZodOptional<z.ZodBoolean>;
224
+ dotted: z.ZodOptional<z.ZodBoolean>;
225
+ dashArray: z.ZodOptional<z.ZodString>;
226
+ roundedCorners: z.ZodOptional<z.ZodNumber>;
227
+ minimumWidth: z.ZodOptional<z.ZodNumber>;
228
+ minimumHeight: z.ZodOptional<z.ZodNumber>;
229
+ minimumSize: z.ZodOptional<z.ZodNumber>;
230
+ scale: z.ZodOptional<z.ZodNumber>;
231
+ xScale: z.ZodOptional<z.ZodNumber>;
232
+ yScale: z.ZodOptional<z.ZodNumber>;
233
+ textColor: z.ZodOptional<z.ZodString>;
234
+ opacity: z.ZodOptional<z.ZodNumber>;
235
+ innerXSep: z.ZodOptional<z.ZodNumber>;
236
+ innerYSep: z.ZodOptional<z.ZodNumber>;
237
+ outerSep: z.ZodOptional<z.ZodNumber>;
11
238
  padding: z.ZodOptional<z.ZodNumber>;
12
239
  margin: z.ZodOptional<z.ZodNumber>;
13
- fontSize: z.ZodOptional<z.ZodNumber>;
240
+ font: z.ZodOptional<z.ZodObject<{
241
+ family: z.ZodOptional<z.ZodString>;
242
+ size: z.ZodOptional<z.ZodNumber>;
243
+ weight: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["normal", "bold"]>, z.ZodNumber]>>;
244
+ style: z.ZodOptional<z.ZodEnum<["normal", "italic", "oblique"]>>;
245
+ }, "strip", z.ZodTypeAny, {
246
+ family?: string | undefined;
247
+ size?: number | undefined;
248
+ weight?: number | "normal" | "bold" | undefined;
249
+ style?: "normal" | "italic" | "oblique" | undefined;
250
+ }, {
251
+ family?: string | undefined;
252
+ size?: number | undefined;
253
+ weight?: number | "normal" | "bold" | undefined;
254
+ style?: "normal" | "italic" | "oblique" | undefined;
255
+ }>>;
14
256
  }, "strip", z.ZodTypeAny, {
15
257
  type: "node";
16
258
  position: [number, number] | import('./position').PolarPosition;
17
259
  fill?: string | undefined;
260
+ shape?: "diamond" | "circle" | "rectangle" | "ellipse" | undefined;
18
261
  stroke?: string | undefined;
19
262
  strokeWidth?: number | undefined;
263
+ text?: string | (string | {
264
+ text: string;
265
+ fill?: string | undefined;
266
+ opacity?: number | undefined;
267
+ font?: {
268
+ family?: string | undefined;
269
+ size?: number | undefined;
270
+ weight?: number | "normal" | "bold" | undefined;
271
+ style?: "normal" | "italic" | "oblique" | undefined;
272
+ } | undefined;
273
+ })[] | undefined;
274
+ opacity?: number | undefined;
275
+ font?: {
276
+ family?: string | undefined;
277
+ size?: number | undefined;
278
+ weight?: number | "normal" | "bold" | undefined;
279
+ style?: "normal" | "italic" | "oblique" | undefined;
280
+ } | undefined;
20
281
  id?: string | undefined;
21
282
  rotate?: number | undefined;
22
- text?: string | undefined;
283
+ align?: "left" | "center" | "right" | undefined;
284
+ lineHeight?: number | undefined;
285
+ fillOpacity?: number | undefined;
286
+ drawOpacity?: number | undefined;
287
+ dashed?: boolean | undefined;
288
+ dotted?: boolean | undefined;
289
+ dashArray?: string | undefined;
290
+ roundedCorners?: number | undefined;
291
+ minimumWidth?: number | undefined;
292
+ minimumHeight?: number | undefined;
293
+ minimumSize?: number | undefined;
294
+ scale?: number | undefined;
295
+ xScale?: number | undefined;
296
+ yScale?: number | undefined;
297
+ textColor?: string | undefined;
298
+ innerXSep?: number | undefined;
299
+ innerYSep?: number | undefined;
300
+ outerSep?: number | undefined;
23
301
  padding?: number | undefined;
24
302
  margin?: number | undefined;
25
- fontSize?: number | undefined;
26
303
  }, {
27
304
  type: "node";
28
305
  position: [number, number] | import('./position').PolarPosition;
29
306
  fill?: string | undefined;
307
+ shape?: "diamond" | "circle" | "rectangle" | "ellipse" | undefined;
30
308
  stroke?: string | undefined;
31
309
  strokeWidth?: number | undefined;
310
+ text?: string | (string | {
311
+ text: string;
312
+ fill?: string | undefined;
313
+ opacity?: number | undefined;
314
+ font?: {
315
+ family?: string | undefined;
316
+ size?: number | undefined;
317
+ weight?: number | "normal" | "bold" | undefined;
318
+ style?: "normal" | "italic" | "oblique" | undefined;
319
+ } | undefined;
320
+ })[] | undefined;
321
+ opacity?: number | undefined;
322
+ font?: {
323
+ family?: string | undefined;
324
+ size?: number | undefined;
325
+ weight?: number | "normal" | "bold" | undefined;
326
+ style?: "normal" | "italic" | "oblique" | undefined;
327
+ } | undefined;
32
328
  id?: string | undefined;
33
329
  rotate?: number | undefined;
34
- text?: string | undefined;
330
+ align?: "left" | "center" | "right" | undefined;
331
+ lineHeight?: number | undefined;
332
+ fillOpacity?: number | undefined;
333
+ drawOpacity?: number | undefined;
334
+ dashed?: boolean | undefined;
335
+ dotted?: boolean | undefined;
336
+ dashArray?: string | undefined;
337
+ roundedCorners?: number | undefined;
338
+ minimumWidth?: number | undefined;
339
+ minimumHeight?: number | undefined;
340
+ minimumSize?: number | undefined;
341
+ scale?: number | undefined;
342
+ xScale?: number | undefined;
343
+ yScale?: number | undefined;
344
+ textColor?: string | undefined;
345
+ innerXSep?: number | undefined;
346
+ innerYSep?: number | undefined;
347
+ outerSep?: number | undefined;
35
348
  padding?: number | undefined;
36
349
  margin?: number | undefined;
37
- fontSize?: number | undefined;
38
350
  }>;
39
- /** 节点:矩形 + 可选文本标签,是最基础的有定位图元 */
351
+ /** 节点:可定位的形状容器(矩形 / / 椭圆 / 菱形)+ 可选文本标签 */
40
352
  export type IRNode = z.infer<typeof NodeSchema>;
41
353
  //# sourceMappingURL=node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/ir/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEpB,CAAC;AAEJ,gCAAgC;AAChC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/ir/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW;;;;;CAKd,CAAC;AAEX,mCAAmC;AACnC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EAwBpB,CAAC;AAEJ,oCAAoC;AACpC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEhD;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsBxB,CAAC;AAEJ,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAIxB,CAAC;AAEJ,yCAAyC;AACzC,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,kBAAkB;AAClB,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyKpB,CAAC;AAEJ,4CAA4C;AAC5C,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
@@ -2,18 +2,106 @@ import { PositionSchema } from "./position/position.js";
2
2
  import { PolarPositionSchema } from "./position/polar-position.js";
3
3
  import { z } from "zod";
4
4
  //#region src/ir/node.ts
5
+ /**
6
+ * 节点形状常量。值是 IR 中 `shape` 字段的字面字符串;
7
+ * 用 const + ValueOf 派生(不用 TS enum)。
8
+ *
9
+ * - `rectangle`:矩形(默认;UML 类、流程图常规节点)
10
+ * - `circle`:圆形(流程图起止、状态机)
11
+ * - `ellipse`:椭圆(状态机、集合图)
12
+ * - `diamond`:菱形(流程图判定)
13
+ *
14
+ * 每个 shape 的几何语义:node 的视觉边界包住"text 矩形 + padding"——
15
+ * - rectangle: 视觉 rect = text rect
16
+ * - circle: 外接圆,r = √(innerHalfW² + innerHalfH²)
17
+ * - ellipse: 外接椭圆,rx = innerHalfW×√2、ry = innerHalfH×√2
18
+ * - diamond: 外接菱形,halfA = 2×innerHalfW、halfB = 2×innerHalfH
19
+ */
20
+ var NODE_SHAPES = {
21
+ rectangle: "rectangle",
22
+ circle: "circle",
23
+ ellipse: "ellipse",
24
+ diamond: "diamond"
25
+ };
26
+ /**
27
+ * 节点字体规格——family / size / weight / style 全部可选;
28
+ * 单字段透传到 SVG `<text>` 的 `font-*` 属性 / `font-size`。
29
+ *
30
+ * 取代 alpha.1 的标量 `fontSize` 字段(已删)。
31
+ */
32
+ var FontSchema = z.object({
33
+ family: z.string().optional().describe("CSS font-family string, e.g. \"serif\", \"monospace\", \"Inter, sans-serif\""),
34
+ size: z.number().positive().optional().describe("Font size in user units; falls back to the renderer default when omitted"),
35
+ weight: z.union([z.enum(["normal", "bold"]), z.number()]).optional().describe("CSS font-weight: keyword `normal` / `bold` or numeric 100..900"),
36
+ style: z.enum([
37
+ "normal",
38
+ "italic",
39
+ "oblique"
40
+ ]).optional().describe("CSS font-style")
41
+ }).describe("Font properties for the node text label; all fields optional, nested object form (replaces the alpha.1 `fontSize` scalar).");
42
+ /**
43
+ * 单行文本规格——纯字符串走块级默认样式;对象形式可对该行覆盖 fill / opacity / font。
44
+ *
45
+ * 行级覆盖只生效于本行的 `<tspan>`:
46
+ * - `fill`:仅这一行颜色
47
+ * - `opacity`:仅这一行 0~1 透明度
48
+ * - `font`:family / size / weight / style 任意子集;未填字段继承块级 font
49
+ *
50
+ * 块级 `align` / `lineHeight` 不可被行覆盖(多行块整体属性)。
51
+ */
52
+ var LineSpecSchema = z.union([z.string(), z.object({
53
+ text: z.string().describe("Line content"),
54
+ fill: z.string().optional().describe("Per-line text color; overrides block default"),
55
+ opacity: z.number().min(0).max(1).optional().describe("Per-line opacity 0..1"),
56
+ font: FontSchema.optional().describe("Per-line font overrides; missing fields inherit from block-level `font`")
57
+ })]).describe("Single line of text: bare string for default styling, or an object with per-line `fill` / `opacity` / `font` overrides.");
58
+ /**
59
+ * 节点文本——单行字符串或非空多行数组(每元素一个 LineSpec):
60
+ * - `'Hello'` 等价于 `[{ text: 'Hello' }]`,按一行渲染
61
+ * - `['Line 1', 'Line 2']` 两行无样式覆盖
62
+ * - `[{ text: 'Heading', fill: 'red', font: { weight: 'bold' } }, 'body']` 混排
63
+ *
64
+ * 选 `Array<LineSpec>` 而非 `'\n'` 字符串:JSON 友好(无 escape);行级覆盖天然落字段。
65
+ */
66
+ var NodeTextSchema = z.union([z.string(), z.array(LineSpecSchema).min(1)]).describe("Text label rendered inside the node: a single string for one line, or a non-empty array of line specs (string for default, object for per-line overrides).");
67
+ /** 节点文本对齐(多行内文本对齐)——TikZ `align=` 同义词 */
68
+ var NODE_TEXT_ALIGNS = {
69
+ left: "left",
70
+ center: "center",
71
+ right: "right"
72
+ };
5
73
  var NodeSchema = z.object({
6
74
  type: z.literal("node").describe("Discriminator marking this child as a node"),
7
75
  id: z.string().min(1).optional().describe("Optional unique id; required if any path needs to reference this node by string"),
76
+ shape: z.nativeEnum(NODE_SHAPES).optional().describe("Node visual shape; defaults to `rectangle`. The boundary fully contains text + padding (circumscribed for circle / ellipse / diamond)."),
8
77
  position: z.union([PositionSchema, PolarPositionSchema]).describe("Center point of the node content box; Cartesian [x, y] or polar (resolved at compile time)"),
9
78
  rotate: z.number().optional().describe("Rotation in degrees around the node center; positive = clockwise (matches TikZ rotate=...)"),
10
- text: z.string().optional().describe("Text label rendered inside the node; omit for an empty node"),
11
- fill: z.string().optional().describe("Background color of the node rectangle; any CSS color (e.g. \"lightblue\", \"#fafafa\", \"rgba(...)\")"),
12
- stroke: z.string().optional().describe("Border color of the node rectangle; any CSS color. Defaults to currentColor when omitted"),
79
+ text: NodeTextSchema.optional(),
80
+ align: z.nativeEnum(NODE_TEXT_ALIGNS).optional().describe("Multi-line text alignment within the text block; `left` / `center` / `right`. Defaults to `center` (matches TikZ)."),
81
+ lineHeight: z.number().positive().optional().describe("Line height in user units; falls back to `font.size × 1.2` when omitted."),
82
+ fill: z.string().optional().describe("Background color of the node shape; any CSS color (e.g. \"lightblue\", \"#fafafa\", \"rgba(...)\")"),
83
+ fillOpacity: z.number().min(0).max(1).optional().describe("Fill opacity 0..1; affects only the shape fill, leaves stroke / text alone."),
84
+ stroke: z.string().optional().describe("Border color of the node shape; any CSS color. Defaults to currentColor when omitted"),
85
+ drawOpacity: z.number().min(0).max(1).optional().describe("Stroke opacity 0..1 (TikZ `draw opacity`); affects only the border."),
13
86
  strokeWidth: z.number().optional().describe("Border width in user units; defaults to 1 when omitted"),
14
- padding: z.number().optional().describe("Inner padding in user units between the text content and the node border"),
15
- margin: z.number().nonnegative().optional().describe("Outer margin in user units: distance between the visual border and where paths attach. Lines stop this far from the border. Defaults to 0."),
16
- fontSize: z.number().optional().describe("Text font size in user units; defaults to a fixed size for now (TikZ font sizes will be supported later)")
17
- }).describe("Rectangle node with optional text label; the basic positional drawing primitive");
87
+ dashed: z.boolean().optional().describe("Border style preset: dashed line (TikZ `dashed`); compiled to a default dash pattern. `dashArray` takes precedence."),
88
+ dotted: z.boolean().optional().describe("Border style preset: dotted line (TikZ `dotted`); compiled to a default dot pattern. `dashArray` and `dashed` take precedence."),
89
+ dashArray: z.string().optional().describe("Explicit SVG stroke-dasharray value (e.g. \"4 2\"); overrides `dashed` / `dotted`."),
90
+ roundedCorners: z.number().nonnegative().optional().describe("Corner radius in user units; only effective on `rectangle` shape (rx / ry on `<rect>`)."),
91
+ minimumWidth: z.number().nonnegative().optional().describe("Minimum visual border width in user units; floors the bounding box width."),
92
+ minimumHeight: z.number().nonnegative().optional().describe("Minimum visual border height in user units; floors the bounding box height."),
93
+ minimumSize: z.number().nonnegative().optional().describe("Symmetric alias for `minimumWidth` + `minimumHeight`; axis-specific fields take precedence."),
94
+ scale: z.number().positive().optional().describe("Uniform scale factor; multiplies all node dimensions (border, padding, text, fontSize) at layout time. Affects path attachment positions."),
95
+ xScale: z.number().positive().optional().describe("Horizontal scale factor; overrides `scale` for the X axis."),
96
+ yScale: z.number().positive().optional().describe("Vertical scale factor; overrides `scale` for the Y axis."),
97
+ textColor: z.string().optional().describe("Text label color; any CSS color. Defaults to `currentColor`."),
98
+ opacity: z.number().min(0).max(1).optional().describe("Whole-node opacity 0..1; applies uniformly to shape and text."),
99
+ innerXSep: z.number().nonnegative().optional().describe("Inner horizontal padding from text to border in user units. Falls back to `padding` then default."),
100
+ innerYSep: z.number().nonnegative().optional().describe("Inner vertical padding from text to border in user units. Falls back to `padding` then default."),
101
+ outerSep: z.number().nonnegative().optional().describe("Outer margin from border to path attachment point in user units; does NOT change the visible border. Falls back to `margin`."),
102
+ padding: z.number().nonnegative().optional().describe("Symmetric inner padding (alias for `innerXSep` + `innerYSep`); axis-specific fields take precedence."),
103
+ margin: z.number().nonnegative().optional().describe("Symmetric outer margin (alias for `outerSep`); axis-specific field takes precedence."),
104
+ font: FontSchema.optional().describe("Font spec for the inner text label (family / size / weight / style); all fields optional, all fall back to renderer defaults.")
105
+ }).describe("Node primitive: a positioned, optionally textual shape (rectangle / circle / ellipse / diamond)");
18
106
  //#endregion
19
- export { NodeSchema };
107
+ export { FontSchema, LineSpecSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeSchema, NodeTextSchema };