@retikz/core 0.1.0-alpha.3 → 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/compile/compile.d.ts +6 -0
- package/dist/es/compile/compile.d.ts.map +1 -1
- package/dist/es/compile/compile.js +30 -1
- package/dist/es/compile/node.d.ts +23 -2
- package/dist/es/compile/node.d.ts.map +1 -1
- package/dist/es/compile/node.js +94 -4
- package/dist/es/compile/position.d.ts +8 -5
- package/dist/es/compile/position.d.ts.map +1 -1
- package/dist/es/compile/position.js +32 -5
- package/dist/es/index.d.ts +2 -2
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +4 -2
- package/dist/es/ir/coordinate.d.ts +57 -0
- package/dist/es/ir/coordinate.d.ts.map +1 -0
- package/dist/es/ir/coordinate.js +27 -0
- package/dist/es/ir/index.d.ts +1 -0
- package/dist/es/ir/index.d.ts.map +1 -1
- package/dist/es/ir/node.d.ts +264 -5
- package/dist/es/ir/node.d.ts.map +1 -1
- package/dist/es/ir/node.js +28 -3
- package/dist/es/ir/position/at-position.d.ts +50 -0
- package/dist/es/ir/position/at-position.d.ts.map +1 -0
- package/dist/es/ir/position/at-position.js +30 -0
- package/dist/es/ir/position/index.d.ts +1 -0
- package/dist/es/ir/position/index.d.ts.map +1 -1
- package/dist/es/ir/scene.d.ts +551 -15
- package/dist/es/ir/scene.d.ts.map +1 -1
- package/dist/es/ir/scene.js +6 -1
- package/dist/lib/compile/compile.cjs +30 -1
- package/dist/lib/compile/compile.d.ts +6 -0
- package/dist/lib/compile/compile.d.ts.map +1 -1
- package/dist/lib/compile/node.cjs +94 -4
- package/dist/lib/compile/node.d.ts +23 -2
- package/dist/lib/compile/node.d.ts.map +1 -1
- package/dist/lib/compile/position.cjs +32 -5
- package/dist/lib/compile/position.d.ts +8 -5
- package/dist/lib/compile/position.d.ts.map +1 -1
- package/dist/lib/index.cjs +6 -0
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/ir/coordinate.cjs +27 -0
- package/dist/lib/ir/coordinate.d.ts +57 -0
- package/dist/lib/ir/coordinate.d.ts.map +1 -0
- package/dist/lib/ir/index.d.ts +1 -0
- package/dist/lib/ir/index.d.ts.map +1 -1
- package/dist/lib/ir/node.cjs +28 -2
- package/dist/lib/ir/node.d.ts +264 -5
- package/dist/lib/ir/node.d.ts.map +1 -1
- package/dist/lib/ir/position/at-position.cjs +31 -0
- package/dist/lib/ir/position/at-position.d.ts +50 -0
- package/dist/lib/ir/position/at-position.d.ts.map +1 -0
- package/dist/lib/ir/position/index.d.ts +1 -0
- package/dist/lib/ir/position/index.d.ts.map +1 -1
- package/dist/lib/ir/scene.cjs +6 -1
- package/dist/lib/ir/scene.d.ts +551 -15
- package/dist/lib/ir/scene.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -13,6 +13,12 @@ export type CompileOptions = {
|
|
|
13
13
|
* 内部几何计算保持完整 double 精度,避免误差累积。
|
|
14
14
|
*/
|
|
15
15
|
precision?: number;
|
|
16
|
+
/**
|
|
17
|
+
* 相对定位(AtPosition)的默认距离,对应 TikZ `node distance`;user units。
|
|
18
|
+
* 当 `Node.position` 是 `{ direction, of }` 形态且未自带 `distance` 时取此值;
|
|
19
|
+
* 未配则回退到 1。
|
|
20
|
+
*/
|
|
21
|
+
nodeDistance?: number;
|
|
16
22
|
};
|
|
17
23
|
/**
|
|
18
24
|
* IR → Scene。纯函数。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/compile/compile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAkB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/compile/compile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAkB,MAAM,cAAc,CAAC;AAK1D,OAAO,EAAE,KAAK,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAwBrE,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GAAG;IAC3B,oCAAoC;IACpC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,IAAI,EAAE,EAAE,UAAS,cAAmB,KAAG,KAsDrE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { rect } from "../geometry/rect.js";
|
|
2
|
+
import { resolvePosition } from "./position.js";
|
|
2
3
|
import { emitNodePrimitives, layoutNode } from "./node.js";
|
|
3
4
|
import { fallbackMeasurer } from "./text-metrics.js";
|
|
4
5
|
import { emitPathPrimitive } from "./path.js";
|
|
@@ -6,6 +7,29 @@ import { makeRound } from "./precision.js";
|
|
|
6
7
|
import { computeViewBox } from "./view-box.js";
|
|
7
8
|
//#region src/compile/compile.ts
|
|
8
9
|
/**
|
|
10
|
+
* 把 coordinate 注册成最小 NodeLayout——0×0 rectangle,用于
|
|
11
|
+
* 后续 path target / `at.of` 引用时 boundaryPoint 命中(0×0 rect
|
|
12
|
+
* 的 boundaryPoint 始终返回中心,符合"占位无形状边界"语义)。
|
|
13
|
+
*/
|
|
14
|
+
var coordinateAsLayout = (id, center) => ({
|
|
15
|
+
id,
|
|
16
|
+
shape: "rectangle",
|
|
17
|
+
rect: {
|
|
18
|
+
x: center[0],
|
|
19
|
+
y: center[1],
|
|
20
|
+
width: 0,
|
|
21
|
+
height: 0,
|
|
22
|
+
rotate: 0
|
|
23
|
+
},
|
|
24
|
+
rotateDeg: 0,
|
|
25
|
+
margin: 0,
|
|
26
|
+
textWidth: 0,
|
|
27
|
+
textHeight: 0,
|
|
28
|
+
align: "middle",
|
|
29
|
+
lineHeight: 0,
|
|
30
|
+
fontSize: 0
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
9
33
|
* IR → Scene。纯函数。
|
|
10
34
|
* 这是所有 adapter 共享的最深层共享代码。
|
|
11
35
|
*
|
|
@@ -18,14 +42,19 @@ var compileToScene = (ir, options = {}) => {
|
|
|
18
42
|
const measureText = options.measureText ?? fallbackMeasurer;
|
|
19
43
|
const viewBoxPadding = options.padding ?? 10;
|
|
20
44
|
const round = makeRound(options.precision ?? 2);
|
|
45
|
+
const nodeDistance = options.nodeDistance;
|
|
21
46
|
const primitives = [];
|
|
22
47
|
const nodeIndex = /* @__PURE__ */ new Map();
|
|
23
48
|
const allPoints = [];
|
|
24
49
|
for (const child of ir.children) if (child.type === "node") {
|
|
25
|
-
const layout = layoutNode(child, measureText, nodeIndex);
|
|
50
|
+
const layout = layoutNode(child, measureText, nodeIndex, nodeDistance);
|
|
26
51
|
if (child.id) nodeIndex.set(child.id, layout);
|
|
27
52
|
for (const prim of emitNodePrimitives(layout, round)) primitives.push(prim);
|
|
28
53
|
allPoints.push(rect.anchor(layout.rect, "north-west"), rect.anchor(layout.rect, "north-east"), rect.anchor(layout.rect, "south-west"), rect.anchor(layout.rect, "south-east"));
|
|
54
|
+
} else if (child.type === "coordinate") {
|
|
55
|
+
const center = resolvePosition(child.position, nodeIndex, nodeDistance);
|
|
56
|
+
if (!center) throw new Error(`Cannot resolve position for coordinate ${child.id}; polar.origin or at.of may reference an undefined node`);
|
|
57
|
+
nodeIndex.set(child.id, coordinateAsLayout(child.id, center));
|
|
29
58
|
}
|
|
30
59
|
for (const child of ir.children) if (child.type === "path") {
|
|
31
60
|
const result = emitPathPrimitive(child, nodeIndex, round, measureText);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Position } from '../geometry/point';
|
|
2
2
|
import { Rect, RectAnchor } from '../geometry/rect';
|
|
3
|
-
import { IRNode, NodeShape } from '../ir';
|
|
3
|
+
import { AtDirection, IRNode, NodeShape } from '../ir';
|
|
4
4
|
import { ScenePrimitive, TextLine } from '../primitive';
|
|
5
5
|
import { TextMeasurer } from './text-metrics';
|
|
6
6
|
export type NodeLayout = {
|
|
@@ -62,6 +62,27 @@ export type NodeLayout = {
|
|
|
62
62
|
textColor?: string;
|
|
63
63
|
/** 整节点透明度 0~1;emit 时同时挂 shape 与 text primitive */
|
|
64
64
|
opacity?: number;
|
|
65
|
+
/**
|
|
66
|
+
* 已解析的 label 列表(IR 层 `Node.label` 标准化后)。每条 label 已合并:
|
|
67
|
+
* - position 默认 'above'
|
|
68
|
+
* - distance 默认 DEFAULT_LABEL_DISTANCE
|
|
69
|
+
* - font 字段从 Node 继承(family / size / weight / style 任一未填则取 Node 块级值)
|
|
70
|
+
*/
|
|
71
|
+
labels?: Array<NodeLabelLayout>;
|
|
72
|
+
};
|
|
73
|
+
/** 节点附属标签的 layout——layoutNode 阶段已合并好默认值与样式继承 */
|
|
74
|
+
export type NodeLabelLayout = {
|
|
75
|
+
text: string;
|
|
76
|
+
/** 8 方向枚举或数字角度(与 IR 同形态) */
|
|
77
|
+
position: AtDirection | number;
|
|
78
|
+
/** 已应用默认值的距离 */
|
|
79
|
+
distance: number;
|
|
80
|
+
textColor?: string;
|
|
81
|
+
opacity?: number;
|
|
82
|
+
fontSize: number;
|
|
83
|
+
fontFamily?: string;
|
|
84
|
+
fontWeight?: string | number;
|
|
85
|
+
fontStyle?: 'normal' | 'italic' | 'oblique';
|
|
65
86
|
};
|
|
66
87
|
/**
|
|
67
88
|
* 取节点 shape 在 toward 方向上的"附着点"——path 端点贴边用。
|
|
@@ -89,7 +110,7 @@ export declare const angleBoundaryOf: (layout: NodeLayout, angleDeg: number) =>
|
|
|
89
110
|
* - IR 的 rotate(度数)转弧度存进 Rect.rotate
|
|
90
111
|
* - 透传 margin / 样式属性
|
|
91
112
|
*/
|
|
92
|
-
export declare const layoutNode: (node: IRNode, measureText: TextMeasurer, nodeIndex: Map<string, NodeLayout
|
|
113
|
+
export declare const layoutNode: (node: IRNode, measureText: TextMeasurer, nodeIndex: Map<string, NodeLayout>, nodeDistance?: number) => NodeLayout;
|
|
93
114
|
/**
|
|
94
115
|
* 把 NodeLayout 翻译为 Scene primitives:
|
|
95
116
|
* - shape 主体:按 shape 分发(rect / ellipse / path)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/compile/node.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/compile/node.ts"],"names":[],"mappings":"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"}
|
package/dist/es/compile/node.js
CHANGED
|
@@ -8,6 +8,8 @@ var DEFAULT_FONT_SIZE = 14;
|
|
|
8
8
|
var DEFAULT_PADDING = 8;
|
|
9
9
|
var DEFAULT_LINE_HEIGHT_FACTOR = 1.2;
|
|
10
10
|
var DEG_TO_RAD = Math.PI / 180;
|
|
11
|
+
/** Node label 与 node 边界的默认距离(user units);TikZ 默认是 0pt 但视觉上太贴 */
|
|
12
|
+
var DEFAULT_LABEL_DISTANCE = 4;
|
|
11
13
|
var SQRT2 = Math.SQRT2;
|
|
12
14
|
/** dashed 预设:SVG stroke-dasharray "4 2"——4 px 实线 + 2 px 间隙循环 */
|
|
13
15
|
var DASHED_PATTERN = "4 2";
|
|
@@ -80,6 +82,59 @@ var anchorOf = (layout, name) => {
|
|
|
80
82
|
}
|
|
81
83
|
};
|
|
82
84
|
/**
|
|
85
|
+
* 8 方向 label position → (anchorName, 单位向量) 映射。
|
|
86
|
+
* 视觉语义与 `at.direction` 一致——above 是视觉上方(y 减小)。
|
|
87
|
+
*/
|
|
88
|
+
var LABEL_DIRECTION_MAP = {
|
|
89
|
+
above: {
|
|
90
|
+
anchor: "north",
|
|
91
|
+
vec: [0, -1]
|
|
92
|
+
},
|
|
93
|
+
below: {
|
|
94
|
+
anchor: "south",
|
|
95
|
+
vec: [0, 1]
|
|
96
|
+
},
|
|
97
|
+
left: {
|
|
98
|
+
anchor: "west",
|
|
99
|
+
vec: [-1, 0]
|
|
100
|
+
},
|
|
101
|
+
right: {
|
|
102
|
+
anchor: "east",
|
|
103
|
+
vec: [1, 0]
|
|
104
|
+
},
|
|
105
|
+
"above-left": {
|
|
106
|
+
anchor: "north-west",
|
|
107
|
+
vec: [-Math.SQRT1_2, -Math.SQRT1_2]
|
|
108
|
+
},
|
|
109
|
+
"above-right": {
|
|
110
|
+
anchor: "north-east",
|
|
111
|
+
vec: [Math.SQRT1_2, -Math.SQRT1_2]
|
|
112
|
+
},
|
|
113
|
+
"below-left": {
|
|
114
|
+
anchor: "south-west",
|
|
115
|
+
vec: [-Math.SQRT1_2, Math.SQRT1_2]
|
|
116
|
+
},
|
|
117
|
+
"below-right": {
|
|
118
|
+
anchor: "south-east",
|
|
119
|
+
vec: [Math.SQRT1_2, Math.SQRT1_2]
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* 算 label 中心点:
|
|
124
|
+
* - 8 方向:节点对应 anchor 出发,按单位向量 × distance 外推
|
|
125
|
+
* - 数字角度:先取 angleBoundary 边界点,再沿 (cos, sin) 单位向量 × distance 外推
|
|
126
|
+
*/
|
|
127
|
+
var labelCenter = (layout, label) => {
|
|
128
|
+
if (typeof label.position === "number") {
|
|
129
|
+
const rad = label.position * Math.PI / 180;
|
|
130
|
+
const [bx, by] = angleBoundaryOf(layout, label.position);
|
|
131
|
+
return [bx + Math.cos(rad) * label.distance, by + Math.sin(rad) * label.distance];
|
|
132
|
+
}
|
|
133
|
+
const { anchor, vec } = LABEL_DIRECTION_MAP[label.position];
|
|
134
|
+
const [bx, by] = anchorOf(layout, anchor);
|
|
135
|
+
return [bx + vec[0] * label.distance, by + vec[1] * label.distance];
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
83
138
|
* 取节点 shape 在指定角度方向上的边界点。角度约定与 PolarPosition 一致(度数):
|
|
84
139
|
* 0° = +x(east),90° = +y(screen 下方)。
|
|
85
140
|
* **不应用 margin**——同 anchorOf。用于 `'A.30'` 这种语法落点。
|
|
@@ -102,7 +157,7 @@ var angleBoundaryOf = (layout, angleDeg) => {
|
|
|
102
157
|
* - IR 的 rotate(度数)转弧度存进 Rect.rotate
|
|
103
158
|
* - 透传 margin / 样式属性
|
|
104
159
|
*/
|
|
105
|
-
var layoutNode = (node, measureText, nodeIndex) => {
|
|
160
|
+
var layoutNode = (node, measureText, nodeIndex, nodeDistance) => {
|
|
106
161
|
const sx = node.xScale ?? node.scale ?? 1;
|
|
107
162
|
const sy = node.yScale ?? node.scale ?? 1;
|
|
108
163
|
const fontScale = Math.min(sx, sy);
|
|
@@ -173,8 +228,22 @@ var layoutNode = (node, measureText, nodeIndex) => {
|
|
|
173
228
|
break;
|
|
174
229
|
}
|
|
175
230
|
const rotateDeg = node.rotate ?? 0;
|
|
176
|
-
const center = resolvePosition(node.position, nodeIndex);
|
|
177
|
-
if (!center) throw new Error(`Cannot resolve position for node ${node.id ?? "(unnamed)"}; polar.origin may reference an undefined node`);
|
|
231
|
+
const center = resolvePosition(node.position, nodeIndex, nodeDistance);
|
|
232
|
+
if (!center) throw new Error(`Cannot resolve position for node ${node.id ?? "(unnamed)"}; polar.origin or at.of may reference an undefined node`);
|
|
233
|
+
const labels = (node.label === void 0 ? void 0 : Array.isArray(node.label) ? node.label : [node.label])?.map((lab) => {
|
|
234
|
+
const labFont = lab.font;
|
|
235
|
+
return {
|
|
236
|
+
text: lab.text,
|
|
237
|
+
position: lab.position ?? "above",
|
|
238
|
+
distance: lab.distance ?? DEFAULT_LABEL_DISTANCE,
|
|
239
|
+
textColor: lab.textColor ?? node.textColor,
|
|
240
|
+
opacity: lab.opacity,
|
|
241
|
+
fontSize: (labFont?.size ?? baseFontSize) * fontScale,
|
|
242
|
+
fontFamily: labFont?.family ?? fontFamily,
|
|
243
|
+
fontWeight: labFont?.weight ?? fontWeight,
|
|
244
|
+
fontStyle: labFont?.style ?? fontStyle
|
|
245
|
+
};
|
|
246
|
+
});
|
|
178
247
|
return {
|
|
179
248
|
id: node.id,
|
|
180
249
|
shape,
|
|
@@ -204,7 +273,8 @@ var layoutNode = (node, measureText, nodeIndex) => {
|
|
|
204
273
|
strokeDasharray: resolveDashArray(node.dashArray, node.dashed, node.dotted),
|
|
205
274
|
roundedCorners: node.roundedCorners,
|
|
206
275
|
textColor: node.textColor,
|
|
207
|
-
opacity: node.opacity
|
|
276
|
+
opacity: node.opacity,
|
|
277
|
+
labels
|
|
208
278
|
};
|
|
209
279
|
};
|
|
210
280
|
/** rectangle shape 的 RectPrim */
|
|
@@ -305,6 +375,26 @@ var emitNodePrimitives = (layout, round) => {
|
|
|
305
375
|
measuredHeight: round(layout.textHeight)
|
|
306
376
|
});
|
|
307
377
|
}
|
|
378
|
+
if (layout.labels) for (const lab of layout.labels) {
|
|
379
|
+
const [lx, ly] = labelCenter(layout, lab);
|
|
380
|
+
inner.push({
|
|
381
|
+
type: "text",
|
|
382
|
+
x: round(lx),
|
|
383
|
+
y: round(ly),
|
|
384
|
+
lines: [{ text: lab.text }],
|
|
385
|
+
fontSize: lab.fontSize,
|
|
386
|
+
fontFamily: lab.fontFamily,
|
|
387
|
+
fontWeight: lab.fontWeight,
|
|
388
|
+
fontStyle: lab.fontStyle,
|
|
389
|
+
align: "middle",
|
|
390
|
+
baseline: "middle",
|
|
391
|
+
lineHeight: round(lab.fontSize * DEFAULT_LINE_HEIGHT_FACTOR),
|
|
392
|
+
fill: lab.textColor ?? "currentColor",
|
|
393
|
+
opacity: lab.opacity ?? layout.opacity,
|
|
394
|
+
measuredWidth: 0,
|
|
395
|
+
measuredHeight: round(lab.fontSize)
|
|
396
|
+
});
|
|
397
|
+
}
|
|
308
398
|
if (layout.rotateDeg === 0) return inner;
|
|
309
399
|
return [{
|
|
310
400
|
type: "group",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { IRPosition, PolarPosition } from '../ir';
|
|
1
|
+
import { IRAtPosition, IRPosition, PolarPosition } from '../ir';
|
|
2
2
|
import { NodeLayout } from './node';
|
|
3
3
|
/**
|
|
4
|
-
* 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 节点 id)解析为笛卡尔位置。
|
|
5
|
-
* 极坐标的 origin 可递归 / 可引用节点 id
|
|
6
|
-
*
|
|
4
|
+
* 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 相对定位 / 节点 id)解析为笛卡尔位置。
|
|
5
|
+
* - 极坐标的 origin 可递归 / 可引用节点 id
|
|
6
|
+
* - 相对定位的 of 必须引用已定义的节点 / coordinate(前向引用要求被引节点先出现)
|
|
7
|
+
* - 解析失败返回 null(如引用了未定义节点)
|
|
8
|
+
*
|
|
9
|
+
* `nodeDistance` 是 Tikz 容器 prop 注入的相对定位默认距离;AtPosition 自带 distance 时优先用自带值。
|
|
7
10
|
*/
|
|
8
|
-
export declare const resolvePosition: (pos: IRPosition | PolarPosition | string, nodeMap: Map<string, NodeLayout
|
|
11
|
+
export declare const resolvePosition: (pos: IRPosition | PolarPosition | IRAtPosition | string, nodeMap: Map<string, NodeLayout>, nodeDistance?: number) => IRPosition | null;
|
|
9
12
|
//# sourceMappingURL=position.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../src/compile/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../src/compile/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAqBzC;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,UAAU,GAAG,aAAa,GAAG,YAAY,GAAG,MAAM,EACvD,SAAS,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAChC,eAAc,MAA8B,KAC3C,UAAU,GAAG,IA4Bf,CAAC"}
|
|
@@ -1,19 +1,46 @@
|
|
|
1
1
|
//#region src/compile/position.ts
|
|
2
|
+
/** 默认相对定位距离(user units)——CompileOptions.nodeDistance 未提供时使用 */
|
|
3
|
+
var DEFAULT_NODE_DISTANCE = 1;
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
5
|
+
* 8 方向到屏幕坐标系(y 向下)单位向量的映射。
|
|
6
|
+
* 视觉语义:above 在视觉上方(y 减小),below 在视觉下方(y 增大)。
|
|
7
|
+
* 4 对角分量为 1/√2,保证斜向距离与水平 / 垂直距离等长(对角点位于半径 = distance 的圆周上)。
|
|
6
8
|
*/
|
|
7
|
-
var
|
|
9
|
+
var DIRECTION_VECTOR = {
|
|
10
|
+
above: [0, -1],
|
|
11
|
+
below: [0, 1],
|
|
12
|
+
left: [-1, 0],
|
|
13
|
+
right: [1, 0],
|
|
14
|
+
"above-left": [-Math.SQRT1_2, -Math.SQRT1_2],
|
|
15
|
+
"above-right": [Math.SQRT1_2, -Math.SQRT1_2],
|
|
16
|
+
"below-left": [-Math.SQRT1_2, Math.SQRT1_2],
|
|
17
|
+
"below-right": [Math.SQRT1_2, Math.SQRT1_2]
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 相对定位 / 节点 id)解析为笛卡尔位置。
|
|
21
|
+
* - 极坐标的 origin 可递归 / 可引用节点 id
|
|
22
|
+
* - 相对定位的 of 必须引用已定义的节点 / coordinate(前向引用要求被引节点先出现)
|
|
23
|
+
* - 解析失败返回 null(如引用了未定义节点)
|
|
24
|
+
*
|
|
25
|
+
* `nodeDistance` 是 Tikz 容器 prop 注入的相对定位默认距离;AtPosition 自带 distance 时优先用自带值。
|
|
26
|
+
*/
|
|
27
|
+
var resolvePosition = (pos, nodeMap, nodeDistance = DEFAULT_NODE_DISTANCE) => {
|
|
8
28
|
if (typeof pos === "string") {
|
|
9
29
|
const node = nodeMap.get(pos);
|
|
10
30
|
return node ? [node.rect.x, node.rect.y] : null;
|
|
11
31
|
}
|
|
12
32
|
if (Array.isArray(pos)) return pos;
|
|
33
|
+
if ("direction" in pos) {
|
|
34
|
+
const ref = nodeMap.get(pos.of);
|
|
35
|
+
if (!ref) return null;
|
|
36
|
+
const distance = pos.distance ?? nodeDistance;
|
|
37
|
+
const [dx, dy] = DIRECTION_VECTOR[pos.direction];
|
|
38
|
+
return [ref.rect.x + dx * distance, ref.rect.y + dy * distance];
|
|
39
|
+
}
|
|
13
40
|
let origin;
|
|
14
41
|
if (!pos.origin) origin = [0, 0];
|
|
15
42
|
else {
|
|
16
|
-
const resolved = resolvePosition(pos.origin, nodeMap);
|
|
43
|
+
const resolved = resolvePosition(pos.origin, nodeMap, nodeDistance);
|
|
17
44
|
if (!resolved) return null;
|
|
18
45
|
origin = resolved;
|
|
19
46
|
}
|
package/dist/es/index.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* 本包零 React、零 DOM 依赖。
|
|
8
8
|
*/
|
|
9
|
-
export { PositionSchema, PolarPositionSchema, TargetSchema, RelTargetSchema, RelAccumulateTargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, CurveStepSchema, CubicStepSchema, BendStepSchema, ArcStepSchema, CirclePathStepSchema, EllipsePathStepSchema, ControlPointSchema, StepLabelSchema, StepSchema, NodeSchema, FontSchema, NodeTextSchema, LineSpecSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
|
|
10
|
-
export type { IRPosition, IRTarget, IRRelTarget, IRRelAccumulateTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRCurveStep, IRCubicStep, IRBendStep, IRArcStep, IRCirclePathStep, IREllipsePathStep, IRControlPoint, IRStepLabel, IRStep, IRNode, IRFont, IRLineSpec, IRPath, IRChild, IR, ArrowShape, NodeShape, NodeTextAlign, } from './ir';
|
|
9
|
+
export { PositionSchema, PolarPositionSchema, AtPositionSchema, AT_DIRECTIONS, TargetSchema, RelTargetSchema, RelAccumulateTargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, CurveStepSchema, CubicStepSchema, BendStepSchema, ArcStepSchema, CirclePathStepSchema, EllipsePathStepSchema, ControlPointSchema, StepLabelSchema, StepSchema, NodeSchema, NodeLabelSchema, CoordinateSchema, FontSchema, NodeTextSchema, LineSpecSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
|
|
10
|
+
export type { IRPosition, IRAtPosition, AtDirection, IRTarget, IRRelTarget, IRRelAccumulateTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRCurveStep, IRCubicStep, IRBendStep, IRArcStep, IRCirclePathStep, IREllipsePathStep, IRControlPoint, IRStepLabel, IRStep, IRNode, IRNodeLabel, IRCoordinate, IRFont, IRLineSpec, IRPath, IRChild, IR, ArrowShape, NodeShape, NodeTextAlign, } from './ir';
|
|
11
11
|
export { ARROW_SHAPES, NODE_SHAPES, NODE_TEXT_ALIGNS } from './ir';
|
|
12
12
|
export type { ScenePrimitive, RectPrim, EllipsePrim, TextPrim, TextLine, PathPrim, GroupPrim, ViewBox, Scene, } from './primitive';
|
|
13
13
|
export type { FontSpec, TextMetrics, TextMeasurer, CompileOptions, } from './compile';
|
package/dist/es/index.d.ts.map
CHANGED
|
@@ -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,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,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,WAAW,EACX,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,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,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAIhE,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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,WAAW,EACX,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,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,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAIhE,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,10 +1,12 @@
|
|
|
1
1
|
import { PositionSchema } from "./ir/position/position.js";
|
|
2
2
|
import { PolarPositionSchema } from "./ir/position/polar-position.js";
|
|
3
|
+
import { AT_DIRECTIONS, AtPositionSchema } from "./ir/position/at-position.js";
|
|
3
4
|
import { ARROW_SHAPES } from "./ir/path/arrow.js";
|
|
4
5
|
import { RelAccumulateTargetSchema, RelTargetSchema, TargetSchema } from "./ir/path/target.js";
|
|
5
6
|
import { ArcStepSchema, BendStepSchema, CirclePathStepSchema, ControlPointSchema, CubicStepSchema, CurveStepSchema, CycleStepSchema, EllipsePathStepSchema, FoldStepSchema, LineStepSchema, MoveStepSchema, StepLabelSchema, StepSchema } from "./ir/path/step.js";
|
|
6
7
|
import { PathSchema } from "./ir/path/path.js";
|
|
7
|
-
import { FontSchema, LineSpecSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeSchema, NodeTextSchema } from "./ir/node.js";
|
|
8
|
+
import { FontSchema, LineSpecSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeLabelSchema, NodeSchema, NodeTextSchema } from "./ir/node.js";
|
|
9
|
+
import { CoordinateSchema } from "./ir/coordinate.js";
|
|
8
10
|
import { CURRENT_IR_VERSION, ChildSchema, SceneSchema } from "./ir/scene.js";
|
|
9
11
|
import { RECT_ANCHORS, rect } from "./geometry/rect.js";
|
|
10
12
|
import { circle } from "./geometry/circle.js";
|
|
@@ -16,4 +18,4 @@ import { parseTargetSugar } from "./parsers/parseTargetSugar.js";
|
|
|
16
18
|
import { DrawWay, parseWay } from "./parsers/parseWay.js";
|
|
17
19
|
import { polar } from "./geometry/polar.js";
|
|
18
20
|
import { point } from "./geometry/point.js";
|
|
19
|
-
export { ARROW_SHAPES, ArcStepSchema, BendStepSchema, CURRENT_IR_VERSION, ChildSchema, CirclePathStepSchema, ControlPointSchema, CubicStepSchema, CurveStepSchema, CycleStepSchema, DrawWay, EllipsePathStepSchema, FoldStepSchema, FontSchema, LineSpecSchema, LineStepSchema, MoveStepSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeSchema, NodeTextSchema, PathSchema, PolarPositionSchema, PositionSchema, RECT_ANCHORS, RelAccumulateTargetSchema, RelTargetSchema, SceneSchema, StepLabelSchema, StepSchema, TargetSchema, circle, compileToScene, diamond, ellipse, fallbackMeasurer, parseTargetSugar, parseWay, point, polar, rect };
|
|
21
|
+
export { ARROW_SHAPES, AT_DIRECTIONS, ArcStepSchema, AtPositionSchema, BendStepSchema, CURRENT_IR_VERSION, ChildSchema, CirclePathStepSchema, ControlPointSchema, CoordinateSchema, CubicStepSchema, CurveStepSchema, CycleStepSchema, DrawWay, EllipsePathStepSchema, FoldStepSchema, FontSchema, LineSpecSchema, LineStepSchema, MoveStepSchema, NODE_SHAPES, NODE_TEXT_ALIGNS, NodeLabelSchema, NodeSchema, NodeTextSchema, PathSchema, PolarPositionSchema, PositionSchema, RECT_ANCHORS, RelAccumulateTargetSchema, RelTargetSchema, SceneSchema, StepLabelSchema, StepSchema, TargetSchema, circle, compileToScene, diamond, ellipse, fallbackMeasurer, parseTargetSugar, parseWay, point, polar, rect };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Coordinate(占位节点)——TikZ `\coordinate (m) at (3,2);` 同义。
|
|
4
|
+
*
|
|
5
|
+
* 命名一个点供后续 path / at 引用,自身不绘制任何图形。
|
|
6
|
+
* 支持笛卡尔 / 极坐标 / 相对定位三种 position 形态,与 `Node.position` 完全一致。
|
|
7
|
+
*
|
|
8
|
+
* 特点:
|
|
9
|
+
* - 必须有 `id`(无 id 的占位节点没有意义)
|
|
10
|
+
* - 不参与 viewBox 扩展(无视觉边界);只在被引用时才间接影响 viewBox(通过引用它的 node / path)
|
|
11
|
+
* - 与 Node 在同一个 nodeIndex 中注册——path target 字符串、`Node.position.of` 都能命中 coordinate id
|
|
12
|
+
*/
|
|
13
|
+
export declare const CoordinateSchema: z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"coordinate">;
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, z.ZodType<import('./position').PolarPosition, z.ZodTypeDef, import('./position').PolarPosition>, z.ZodObject<{
|
|
17
|
+
direction: z.ZodNativeEnum<{
|
|
18
|
+
readonly above: "above";
|
|
19
|
+
readonly below: "below";
|
|
20
|
+
readonly left: "left";
|
|
21
|
+
readonly right: "right";
|
|
22
|
+
readonly 'above-left': "above-left";
|
|
23
|
+
readonly 'above-right': "above-right";
|
|
24
|
+
readonly 'below-left': "below-left";
|
|
25
|
+
readonly 'below-right': "below-right";
|
|
26
|
+
}>;
|
|
27
|
+
of: z.ZodString;
|
|
28
|
+
distance: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
|
|
31
|
+
of: string;
|
|
32
|
+
distance?: number | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
|
|
35
|
+
of: string;
|
|
36
|
+
distance?: number | undefined;
|
|
37
|
+
}>]>;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
type: "coordinate";
|
|
40
|
+
position: [number, number] | import('./position').PolarPosition | {
|
|
41
|
+
direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
|
|
42
|
+
of: string;
|
|
43
|
+
distance?: number | undefined;
|
|
44
|
+
};
|
|
45
|
+
id: string;
|
|
46
|
+
}, {
|
|
47
|
+
type: "coordinate";
|
|
48
|
+
position: [number, number] | import('./position').PolarPosition | {
|
|
49
|
+
direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
|
|
50
|
+
of: string;
|
|
51
|
+
distance?: number | undefined;
|
|
52
|
+
};
|
|
53
|
+
id: string;
|
|
54
|
+
}>;
|
|
55
|
+
/** Coordinate IR 类型——`{ type: 'coordinate', id, position }` */
|
|
56
|
+
export type IRCoordinate = z.infer<typeof CoordinateSchema>;
|
|
57
|
+
//# sourceMappingURL=coordinate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate.d.ts","sourceRoot":"","sources":["../../../src/ir/coordinate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB1B,CAAC;AAEJ,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PositionSchema } from "./position/position.js";
|
|
2
|
+
import { PolarPositionSchema } from "./position/polar-position.js";
|
|
3
|
+
import { AtPositionSchema } from "./position/at-position.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/ir/coordinate.ts
|
|
6
|
+
/**
|
|
7
|
+
* Coordinate(占位节点)——TikZ `\coordinate (m) at (3,2);` 同义。
|
|
8
|
+
*
|
|
9
|
+
* 命名一个点供后续 path / at 引用,自身不绘制任何图形。
|
|
10
|
+
* 支持笛卡尔 / 极坐标 / 相对定位三种 position 形态,与 `Node.position` 完全一致。
|
|
11
|
+
*
|
|
12
|
+
* 特点:
|
|
13
|
+
* - 必须有 `id`(无 id 的占位节点没有意义)
|
|
14
|
+
* - 不参与 viewBox 扩展(无视觉边界);只在被引用时才间接影响 viewBox(通过引用它的 node / path)
|
|
15
|
+
* - 与 Node 在同一个 nodeIndex 中注册——path target 字符串、`Node.position.of` 都能命中 coordinate id
|
|
16
|
+
*/
|
|
17
|
+
var CoordinateSchema = z.object({
|
|
18
|
+
type: z.literal("coordinate").describe("Discriminator marking this child as a coordinate placeholder"),
|
|
19
|
+
id: z.string().min(1).describe("Required unique id; the whole point of a coordinate is to be referenced by paths or other nodes"),
|
|
20
|
+
position: z.union([
|
|
21
|
+
PositionSchema,
|
|
22
|
+
PolarPositionSchema,
|
|
23
|
+
AtPositionSchema
|
|
24
|
+
]).describe("Coordinate position; Cartesian [x, y], polar, or relative-to-another-node (`at`-style). Resolved at compile time.")
|
|
25
|
+
}).describe("Coordinate placeholder: a named point with no visual; usable as a target for paths and as an anchor for relative positioning. Mirrors TikZ `\\coordinate (id) at (...);`");
|
|
26
|
+
//#endregion
|
|
27
|
+
export { CoordinateSchema };
|
package/dist/es/ir/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ir/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ir/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
|