lineadraw 0.7.0 → 0.9.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.
- package/README.md +276 -203
- package/bin/lineadraw.mjs +35 -115
- package/dist/bridge.d.ts +102 -0
- package/dist/bridge.js +16 -0
- package/dist/{chunk-NCNZ7A6M.js → chunk-BQCSFVAF.js} +3061 -678
- package/dist/chunk-BQCSFVAF.js.map +1 -0
- package/dist/chunk-L2CWZAKW.js +141 -0
- package/dist/chunk-L2CWZAKW.js.map +1 -0
- package/dist/exportDxf-T2RTSTH5.js +10 -0
- package/dist/exportDxf-T2RTSTH5.js.map +1 -0
- package/dist/{node-2RH2EKXG.js → node-PLO3I6OZ.js} +39 -1
- package/dist/node-PLO3I6OZ.js.map +1 -0
- package/dist/pkg/linea_dwg_bg.wasm +0 -0
- package/dist/sdk.d.ts +1338 -592
- package/dist/sdk.js +3499 -1622
- package/dist/sdk.js.map +1 -1
- package/lineadraw.d.ts +481 -1424
- package/package.json +2 -2
- package/templates/sample.block.ts +2 -2
- package/dist/chunk-NCNZ7A6M.js.map +0 -1
- package/dist/exportDxf-2HC6UIBS.js +0 -8
- package/dist/node-2RH2EKXG.js.map +0 -1
- /package/dist/{exportDxf-2HC6UIBS.js.map → bridge.js.map} +0 -0
|
@@ -2,21 +2,7 @@ import {
|
|
|
2
2
|
__export
|
|
3
3
|
} from "./chunk-PZ5AY32C.js";
|
|
4
4
|
|
|
5
|
-
// ../core/src/
|
|
6
|
-
import {
|
|
7
|
-
DxfWriter,
|
|
8
|
-
Units,
|
|
9
|
-
LayerFlags,
|
|
10
|
-
LWPolylineFlags,
|
|
11
|
-
TextHorizontalAlignment,
|
|
12
|
-
TextVerticalAlignment,
|
|
13
|
-
HatchBoundaryPaths,
|
|
14
|
-
HatchPolylineBoundary,
|
|
15
|
-
HatchPredefinedPatterns,
|
|
16
|
-
pattern
|
|
17
|
-
} from "@tarikjabiri/dxf";
|
|
18
|
-
|
|
19
|
-
// ../core/src/model/objects.ts
|
|
5
|
+
// ../core/src/model/hatchPatterns.ts
|
|
20
6
|
import { z as z2 } from "zod";
|
|
21
7
|
|
|
22
8
|
// ../core/src/model/common.ts
|
|
@@ -40,6 +26,716 @@ var ObjectBaseSchema = z.object({
|
|
|
40
26
|
opacity: z.number().min(0).max(1).optional()
|
|
41
27
|
});
|
|
42
28
|
|
|
29
|
+
// ../core/src/paint/sink.ts
|
|
30
|
+
var matIdentity = [1, 0, 0, 1, 0, 0];
|
|
31
|
+
var matMultiply = (m, n) => [
|
|
32
|
+
m[0] * n[0] + m[2] * n[1],
|
|
33
|
+
m[1] * n[0] + m[3] * n[1],
|
|
34
|
+
m[0] * n[2] + m[2] * n[3],
|
|
35
|
+
m[1] * n[2] + m[3] * n[3],
|
|
36
|
+
m[0] * n[4] + m[2] * n[5] + m[4],
|
|
37
|
+
m[1] * n[4] + m[3] * n[5] + m[5]
|
|
38
|
+
];
|
|
39
|
+
var matApply = (m, p) => ({
|
|
40
|
+
x: m[0] * p.x + m[2] * p.y + m[4],
|
|
41
|
+
y: m[1] * p.x + m[3] * p.y + m[5]
|
|
42
|
+
});
|
|
43
|
+
var signedArcSweep = (startAngle, endAngle, ccw) => {
|
|
44
|
+
const TAU = Math.PI * 2;
|
|
45
|
+
let sweep = ccw ? ((endAngle - startAngle) % TAU + TAU) % TAU : -(((startAngle - endAngle) % TAU + TAU) % TAU);
|
|
46
|
+
if (sweep === 0) sweep = ccw ? TAU : -TAU;
|
|
47
|
+
return sweep;
|
|
48
|
+
};
|
|
49
|
+
var arcToBeziers = (center, r, startAngle, sweep) => {
|
|
50
|
+
const n = Math.max(1, Math.ceil(Math.abs(sweep) / (Math.PI / 2)));
|
|
51
|
+
const step = sweep / n;
|
|
52
|
+
const k = 4 / 3 * Math.tan(step / 4);
|
|
53
|
+
const result = [];
|
|
54
|
+
for (let i = 0; i < n; i++) {
|
|
55
|
+
const a0 = startAngle + step * i;
|
|
56
|
+
const a1 = a0 + step;
|
|
57
|
+
const p0 = {
|
|
58
|
+
x: center.x + r * Math.cos(a0),
|
|
59
|
+
y: center.y + r * Math.sin(a0)
|
|
60
|
+
};
|
|
61
|
+
const p1 = {
|
|
62
|
+
x: center.x + r * Math.cos(a1),
|
|
63
|
+
y: center.y + r * Math.sin(a1)
|
|
64
|
+
};
|
|
65
|
+
result.push({
|
|
66
|
+
start: p0,
|
|
67
|
+
c1: { x: p0.x - r * k * Math.sin(a0), y: p0.y + r * k * Math.cos(a0) },
|
|
68
|
+
c2: { x: p1.x + r * k * Math.sin(a1), y: p1.y - r * k * Math.cos(a1) },
|
|
69
|
+
end: p1
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
};
|
|
74
|
+
var vExtent = (rings, v) => {
|
|
75
|
+
let min = Infinity;
|
|
76
|
+
let max = -Infinity;
|
|
77
|
+
for (const ring of rings) {
|
|
78
|
+
for (const p of ring) {
|
|
79
|
+
const dv = p.x * v.x + p.y * v.y;
|
|
80
|
+
if (dv < min) min = dv;
|
|
81
|
+
if (dv > max) max = dv;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Number.isFinite(min) ? { min, max } : null;
|
|
85
|
+
};
|
|
86
|
+
var scanlineCrossings = (rings, u, v, off) => {
|
|
87
|
+
const crossings = [];
|
|
88
|
+
for (const ring of rings) {
|
|
89
|
+
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
90
|
+
const a = ring[j];
|
|
91
|
+
const b = ring[i];
|
|
92
|
+
const va = a.x * v.x + a.y * v.y;
|
|
93
|
+
const vb = b.x * v.x + b.y * v.y;
|
|
94
|
+
if (va < off === vb < off) continue;
|
|
95
|
+
const t = (off - va) / (vb - va);
|
|
96
|
+
const px = a.x + (b.x - a.x) * t;
|
|
97
|
+
const py = a.y + (b.y - a.y) * t;
|
|
98
|
+
crossings.push(px * u.x + py * u.y);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
crossings.sort((x, y) => x - y);
|
|
102
|
+
return crossings;
|
|
103
|
+
};
|
|
104
|
+
var computeHatchLines = (rings, angle2, spacing) => spacing <= 0 ? [] : computeHatchFamily(rings, {
|
|
105
|
+
angle: angle2,
|
|
106
|
+
origin: { x: 0, y: 0 },
|
|
107
|
+
deltaAlong: 0,
|
|
108
|
+
deltaPerp: spacing
|
|
109
|
+
});
|
|
110
|
+
var DOT_LENGTH_MM = 0.35;
|
|
111
|
+
var splitByDashes = (a, b, u, dashes, along0, out) => {
|
|
112
|
+
const len3 = (b.x - a.x) * u.x + (b.y - a.y) * u.y;
|
|
113
|
+
if (len3 <= 1e-9) return;
|
|
114
|
+
const cycle = dashes.reduce((s, d) => s + Math.abs(d), 0);
|
|
115
|
+
if (cycle <= 1e-9) {
|
|
116
|
+
out.push({ a, b });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const pt = (d) => ({ x: a.x + u.x * d, y: a.y + u.y * d });
|
|
120
|
+
const base = a.x * u.x + a.y * u.y - along0;
|
|
121
|
+
let phase = (base % cycle + cycle) % cycle;
|
|
122
|
+
let idx = 0;
|
|
123
|
+
for (; idx < dashes.length; idx++) {
|
|
124
|
+
const w = Math.abs(dashes[idx]);
|
|
125
|
+
if (phase < w || w <= 1e-9) break;
|
|
126
|
+
phase -= w;
|
|
127
|
+
}
|
|
128
|
+
if (idx >= dashes.length) {
|
|
129
|
+
idx = 0;
|
|
130
|
+
phase = 0;
|
|
131
|
+
}
|
|
132
|
+
let remaining = Math.max(0, Math.abs(dashes[idx]) - phase);
|
|
133
|
+
let pos = 0;
|
|
134
|
+
let guard = 0;
|
|
135
|
+
while (pos < len3 - 1e-9 && guard++ < 1e5) {
|
|
136
|
+
const w = Math.abs(dashes[idx]);
|
|
137
|
+
const draw = dashes[idx] >= 0;
|
|
138
|
+
if (w <= 1e-9) {
|
|
139
|
+
if (draw) {
|
|
140
|
+
const s0 = Math.max(0, pos - DOT_LENGTH_MM / 2);
|
|
141
|
+
const s1 = Math.min(len3, pos + DOT_LENGTH_MM / 2);
|
|
142
|
+
if (s1 > s0) out.push({ a: pt(s0), b: pt(s1) });
|
|
143
|
+
}
|
|
144
|
+
idx = (idx + 1) % dashes.length;
|
|
145
|
+
remaining = Math.abs(dashes[idx]);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const step = Math.min(remaining, len3 - pos);
|
|
149
|
+
if (draw) out.push({ a: pt(pos), b: pt(pos + step) });
|
|
150
|
+
pos += step;
|
|
151
|
+
remaining -= step;
|
|
152
|
+
if (remaining <= 1e-9) {
|
|
153
|
+
idx = (idx + 1) % dashes.length;
|
|
154
|
+
remaining = Math.abs(dashes[idx]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var computeHatchFamily = (rings, family) => {
|
|
159
|
+
const { deltaPerp } = family;
|
|
160
|
+
if (rings.length === 0 || Math.abs(deltaPerp) <= 1e-9) return [];
|
|
161
|
+
const u = { x: Math.cos(family.angle), y: Math.sin(family.angle) };
|
|
162
|
+
const v = { x: -u.y, y: u.x };
|
|
163
|
+
const ext = vExtent(rings, v);
|
|
164
|
+
if (!ext) return [];
|
|
165
|
+
const oV = family.origin.x * v.x + family.origin.y * v.y;
|
|
166
|
+
const oU = family.origin.x * u.x + family.origin.y * u.y;
|
|
167
|
+
const iA = (ext.min - oV) / deltaPerp;
|
|
168
|
+
const iB = (ext.max - oV) / deltaPerp;
|
|
169
|
+
const iLo = Math.ceil(Math.min(iA, iB));
|
|
170
|
+
const iHi = Math.floor(Math.max(iA, iB));
|
|
171
|
+
const dashes = family.dashesMm && family.dashesMm.length ? family.dashesMm : null;
|
|
172
|
+
const out = [];
|
|
173
|
+
for (let i = iLo; i <= iHi; i++) {
|
|
174
|
+
const off = oV + i * deltaPerp;
|
|
175
|
+
const along0 = oU + i * family.deltaAlong;
|
|
176
|
+
const crossings = scanlineCrossings(rings, u, v, off);
|
|
177
|
+
for (let k = 0; k + 1 < crossings.length; k += 2) {
|
|
178
|
+
const c0 = crossings[k];
|
|
179
|
+
const c1 = crossings[k + 1];
|
|
180
|
+
if (c1 - c0 < 1e-9) continue;
|
|
181
|
+
const a = { x: u.x * c0 + v.x * off, y: u.y * c0 + v.y * off };
|
|
182
|
+
const b = { x: u.x * c1 + v.x * off, y: u.y * c1 + v.y * off };
|
|
183
|
+
if (dashes) splitByDashes(a, b, u, dashes, along0, out);
|
|
184
|
+
else out.push({ a, b });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
};
|
|
189
|
+
var ellipseArcToBeziers = (center, rx, ry, rotation, startAngle, sweep) => {
|
|
190
|
+
const cosR = Math.cos(rotation);
|
|
191
|
+
const sinR = Math.sin(rotation);
|
|
192
|
+
const map = (p) => ({
|
|
193
|
+
x: center.x + p.x * cosR - p.y * sinR,
|
|
194
|
+
y: center.y + p.x * sinR + p.y * cosR
|
|
195
|
+
});
|
|
196
|
+
return arcToBeziers({ x: 0, y: 0 }, 1, startAngle, sweep).map((b) => ({
|
|
197
|
+
start: map({ x: b.start.x * rx, y: b.start.y * ry }),
|
|
198
|
+
c1: map({ x: b.c1.x * rx, y: b.c1.y * ry }),
|
|
199
|
+
c2: map({ x: b.c2.x * rx, y: b.c2.y * ry }),
|
|
200
|
+
end: map({ x: b.end.x * rx, y: b.end.y * ry })
|
|
201
|
+
}));
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// ../core/src/model/builtinPat.ts
|
|
205
|
+
var BUILTIN_PAT = `;; Linea built-in hatch pattern library.
|
|
206
|
+
;;
|
|
207
|
+
;; Format: .pat syntax - a \`*NAME,description\` header followed by one line
|
|
208
|
+
;; family per row: \`angle, x-origin, y-origin, delta-x, delta-y [, dash...]\`
|
|
209
|
+
;; (angle in degrees CCW; delta-x shifts successive lines along their own
|
|
210
|
+
;; direction - dash phase - and delta-y is the perpendicular spacing;
|
|
211
|
+
;; dashes: >0 pen-down, <0 gap, 0 dot). All lengths are millimeters (ISO
|
|
212
|
+
;; scaling).
|
|
213
|
+
;;
|
|
214
|
+
;; The pattern geometry is functional interchange data, kept name- and
|
|
215
|
+
;; value-compatible with the predefined DXF HATCH patterns other CAD
|
|
216
|
+
;; applications resolve - ANSI/ISO/JIS/GOST section conventions plus common
|
|
217
|
+
;; architectural textures. Descriptions and organization are Linea's
|
|
218
|
+
;; own. There is no SOLID entry: solid fill is its own fill kind, not a
|
|
219
|
+
;; line-family pattern.
|
|
220
|
+
;;
|
|
221
|
+
;; After editing, regenerate the embedded TS mirror:
|
|
222
|
+
;; npm run gen:patterns -w @lineadraw/core
|
|
223
|
+
;;
|
|
224
|
+
|
|
225
|
+
;; Material and texture patterns.
|
|
226
|
+
|
|
227
|
+
*ANGLE,Steel angle framing
|
|
228
|
+
0, 0, 0, 0, 6.985, 5.08, -1.905
|
|
229
|
+
90, 0, 0, 0, 6.985, 5.08, -1.905
|
|
230
|
+
*ANSI31,Cast iron; general section (ANSI)
|
|
231
|
+
45, 0, 0, 0, 3.175
|
|
232
|
+
*ANSI32,Steel (ANSI)
|
|
233
|
+
45, 0, 0, 0, 9.525
|
|
234
|
+
45, 4.49013, 0, 0, 9.525
|
|
235
|
+
*ANSI33,Bronze, brass, copper (ANSI)
|
|
236
|
+
45, 0, 0, 0, 6.35
|
|
237
|
+
45, 4.49013, 0, 0, 6.35, 3.175, -1.5875
|
|
238
|
+
*ANSI34,Plastic, rubber (ANSI)
|
|
239
|
+
45, 0, 0, 0, 19.05
|
|
240
|
+
45, 4.49013, 0, 0, 19.05
|
|
241
|
+
45, 8.98026, 0, 0, 19.05
|
|
242
|
+
45, 13.4704, 0, 0, 19.05
|
|
243
|
+
*ANSI35,Fire brick, refractory (ANSI)
|
|
244
|
+
45, 0, 0, 0, 6.35
|
|
245
|
+
45, 4.49013, 0, 0, 6.35, 7.9375, -1.5875, 0, -1.5875
|
|
246
|
+
*ANSI36,Marble, slate, glass (ANSI)
|
|
247
|
+
45, 0, 0, 5.55625, 3.175, 7.9375, -1.5875, 0, -1.5875
|
|
248
|
+
*ANSI37,Lead, zinc, insulation (ANSI)
|
|
249
|
+
45, 0, 0, 0, 3.175
|
|
250
|
+
135, 0, 0, 0, 3.175
|
|
251
|
+
*ANSI38,Aluminum (ANSI)
|
|
252
|
+
45, 0, 0, 0, 3.175
|
|
253
|
+
135, 0, 0, 6.35, 3.175, 7.9375, -4.7625
|
|
254
|
+
*AR-B816,Block wall 8x16, running bond
|
|
255
|
+
0, 0, 0, 0, 203.2
|
|
256
|
+
90, 0, 0, 203.2, 203.2, 203.2, -203.2
|
|
257
|
+
*AR-B816C,Block wall 8x16 with mortar joints
|
|
258
|
+
0, 0, 0, 203.2, 203.2, 396.875, -9.525
|
|
259
|
+
0, -203.2, 9.525, 203.2, 203.2, 396.875, -9.525
|
|
260
|
+
90, 0, 0, 203.2, 203.2, -212.725, 193.675
|
|
261
|
+
90, -9.525, 0, 203.2, 203.2, -212.725, 193.675
|
|
262
|
+
*AR-B88,Block wall 8x8, running bond
|
|
263
|
+
0, 0, 0, 0, 203.2
|
|
264
|
+
90, 0, 0, 203.2, 101.6, 203.2, -203.2
|
|
265
|
+
*AR-BRELM,Brick wall, English bond, mortar joints
|
|
266
|
+
0, 0, 0, 0, 135.484, 193.675, -9.525
|
|
267
|
+
0, 0, 57.15, 0, 135.484, 193.675, -9.525
|
|
268
|
+
0, 50.8, 67.7418, 0, 135.484, 92.075, -9.525
|
|
269
|
+
0, 50.8, 124.892, 0, 135.484, 92.075, -9.525
|
|
270
|
+
90, 0, 0, 0, 203.2, 57.15, -78.334
|
|
271
|
+
90, -9.525, 0, 0, 203.2, 57.15, -78.334
|
|
272
|
+
90, 50.8, 67.7418, 0, 101.6, 57.15, -78.334
|
|
273
|
+
90, 41.275, 67.7418, 0, 101.6, 57.15, -78.334
|
|
274
|
+
*AR-BRSTD,Brick wall, running bond
|
|
275
|
+
0, 0, 0, 0, 67.7418
|
|
276
|
+
90, 0, 0, 67.7418, 101.6, 67.7418, -67.7418
|
|
277
|
+
*AR-CONC,Concrete, random aggregate
|
|
278
|
+
50, 0, 0, 104.896, -149.807, 19.05, -209.55
|
|
279
|
+
355, 0, 0, -51.76101082,187.25814969, 15.24, -167.64058417
|
|
280
|
+
100.4514447,15.182007,-1.3282535,145.5569059,-176.270089,16.1900088,-178.0902446
|
|
281
|
+
46.1842, 0, 50.8, 157.343, -224.71, 28.575, -314.325
|
|
282
|
+
96.63555761,22.5899,47.2965,218.33577212,-264.40480444,24.28502314,-267.13560816
|
|
283
|
+
351.18415117,0,50.8,196.67912063,280.88740361,22.85996707,-251.45973192
|
|
284
|
+
21, 25.4, 38.1, 104.89565868, -149.80652586, 19.05, -209.55
|
|
285
|
+
326, 25.4, 38.1, -51.7604, 187.258, 15.24, -167.64
|
|
286
|
+
71.451445,38.0345326,29.5779001,145.5567546,-176.2700748,16.1900088,-178.0899376
|
|
287
|
+
37.5, 0, 0, 53.9242, 65.2018, 0, -165.608, 0, -170.18, 0, -168.275
|
|
288
|
+
7.5, 0, 0, 79.3242, 90.6018, 0, -97.028, 0, -161.798, 0, -64.135
|
|
289
|
+
-32.5, -56.642, 0, 117.434, 68.0212, 0, -63.5, 0, -198.12, 0, -262.89
|
|
290
|
+
-42.5, -82.042, 0, 92.0344, 118.821, 0, -82.55, 0, -131.572, 0, -186.69
|
|
291
|
+
*AR-HBONE,Brick paving, herringbone at 45 deg
|
|
292
|
+
45, 0, 0, 101.6, 101.6, 304.8, -101.6
|
|
293
|
+
135, 71.842, 71.842, 101.6, -101.6, 304.8, -101.6
|
|
294
|
+
*AR-PARQ1,Parquet flooring, basket weave
|
|
295
|
+
90, 0, 0, 304.8, 304.8, 304.8, -304.8
|
|
296
|
+
90, 50.8, 0, 304.8, 304.8, 304.8, -304.8
|
|
297
|
+
90, 101.6, 0, 304.8, 304.8, 304.8, -304.8
|
|
298
|
+
90, 152.4, 0, 304.8, 304.8, 304.8, -304.8
|
|
299
|
+
90, 203.2, 0, 304.8, 304.8, 304.8, -304.8
|
|
300
|
+
90, 254, 0, 304.8, 304.8, 304.8, -304.8
|
|
301
|
+
90, 304.8, 0, 304.8, 304.8, 304.8, -304.8
|
|
302
|
+
0, 0, 304.8, 304.8, -304.8, 304.8, -304.8
|
|
303
|
+
0, 0, 355.6, 304.8, -304.8, 304.8, -304.8
|
|
304
|
+
0, 0, 406.4, 304.8, -304.8, 304.8, -304.8
|
|
305
|
+
0, 0, 457.2, 304.8, -304.8, 304.8, -304.8
|
|
306
|
+
0, 0, 508, 304.8, -304.8, 304.8, -304.8
|
|
307
|
+
0, 0, 558.8, 304.8, -304.8, 304.8, -304.8
|
|
308
|
+
0, 0, 609.6, 304.8, -304.8, 304.8, -304.8
|
|
309
|
+
*AR-RROOF,Roof shingles
|
|
310
|
+
0, 0, 0, 55.88, 25.4, 381, -50.8, 127, -25.4
|
|
311
|
+
0, 33.782, 12.7, -25.4, 33.782, 76.2, -8.382, 152.4, -19.05
|
|
312
|
+
0, 12.7, 21.59, 132.08, 17.018, 203.2, -35.56, 101.6, -25.4
|
|
313
|
+
*AR-RSHKE,Roof wood shakes
|
|
314
|
+
0, 0, 0, 647.7, 304.8, 152.4, -127, 177.8, -76.2, 228.6, -101.6
|
|
315
|
+
0, 152.4, 12.7, 647.7, 304.8, 127, -482.6, 101.6, -152.4
|
|
316
|
+
0, 457.2, -19.05, 647.7, 304.8, 76.2, -787.4
|
|
317
|
+
90, 0, 0, 304.8, 215.9, 292.1, -927.1
|
|
318
|
+
90, 152.4, 0, 304.8, 215.9, 285.75, -933.45
|
|
319
|
+
90, 279.4, 0, 304.8, 215.9, 266.7, -952.5
|
|
320
|
+
90, 457.2, -19.05, 304.8, 215.9, 292.1, -927.1
|
|
321
|
+
90, 533.4, -19.05, 304.8, 215.9, 292.1, -927.1
|
|
322
|
+
90, 762, 0, 304.8, 215.9, 279.4, -939.8
|
|
323
|
+
*AR-SAND,Sand stipple
|
|
324
|
+
37.5, 0, 0, 28.5242, 39.8018, 0, -38.608, 0, -43.18, 0, -41.275
|
|
325
|
+
7.5, 0, 0, 53.9242, 65.2018, 0, -20.828, 0, -34.798, 0, -13.335
|
|
326
|
+
-32.5, -31.242, 0, 66.6344, 42.6212, 0, -12.7, 0, -45.72, 0, -59.69
|
|
327
|
+
-42.5, -31.242, 0, 41.2344, 68.0212, 0, -6.35, 0, -29.972, 0, -34.29
|
|
328
|
+
*BOX,Interlocking box weave
|
|
329
|
+
90, 0, 0, 0, 25.4
|
|
330
|
+
90, 6.35, 0, 0, 25.4
|
|
331
|
+
0, 0, 0, 0, 25.4, -6.35, 6.35
|
|
332
|
+
0, 0, 6.35, 0, 25.4, -6.35, 6.35
|
|
333
|
+
0, 0, 12.7, 0, 25.4, 6.35, -6.35
|
|
334
|
+
0, 0, 19.05, 0, 25.4, 6.35, -6.35
|
|
335
|
+
90, 12.7, 0, 0, 25.4, 6.35, -6.35
|
|
336
|
+
90, 19.05, 0, 0, 25.4, 6.35, -6.35
|
|
337
|
+
*BRASS,Brass
|
|
338
|
+
0, 0, 0, 0, 6.35
|
|
339
|
+
0, 0, 3.175, 0, 6.35, 3.175, -1.5875
|
|
340
|
+
*BRICK,Brick coursing
|
|
341
|
+
0, 0, 0, 0, 6.35
|
|
342
|
+
90, 0, 0, 0, 12.7, 6.35, -6.35
|
|
343
|
+
90, 6.35, 0, 0, 12.7, -6.35, 6.35
|
|
344
|
+
*BRSTONE,Brick and stone mix
|
|
345
|
+
0, 0, 0, 0, 8.382
|
|
346
|
+
90, 22.86, 0, 8.382, 12.7, 8.382, -8.382
|
|
347
|
+
90, 20.32, 0, 8.382, 12.7, 8.382, -8.382
|
|
348
|
+
0, 22.86, 1.397, 12.7, 8.382, -22.86, 2.54
|
|
349
|
+
0, 22.86, 2.794, 12.7, 8.382, -22.86, 2.54
|
|
350
|
+
0, 22.86, 4.191, 12.7, 8.382, -22.86, 2.54
|
|
351
|
+
0, 22.86, 5.588, 12.7, 8.382, -22.86, 2.54
|
|
352
|
+
0, 22.86, 6.985, 12.7, 8.382, -22.86, 2.54
|
|
353
|
+
*CLAY,Clay
|
|
354
|
+
0, 0, 0, 0, 4.7625
|
|
355
|
+
0, 0, 0.79375, 0, 4.7625
|
|
356
|
+
0, 0, 1.5875, 0, 4.7625
|
|
357
|
+
0, 0, 3.175, 0, 4.7625, 4.7625, -3.175
|
|
358
|
+
*CORK,Cork
|
|
359
|
+
0, 0, 0, 0, 3.175
|
|
360
|
+
135, 1.5875, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
361
|
+
135, 2.38125, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
362
|
+
135, 3.175, -1.5875, 0, 8.98026, 4.49013, -4.49013
|
|
363
|
+
*CROSS,Cross tiling
|
|
364
|
+
0, 0, 0, 6.35, 6.35, 3.175, -9.525
|
|
365
|
+
90, 1.5875, -1.5875, 6.35, 6.35, 3.175, -9.525
|
|
366
|
+
*DASH,Staggered dashes
|
|
367
|
+
0, 0, 0, 3.175, 3.175, 3.175, -3.175
|
|
368
|
+
*DOLMIT,Layered rock (dolomite)
|
|
369
|
+
0, 0, 0, 0, 6.35
|
|
370
|
+
45, 0, 0, 0, 17.9605,8.98025612106915355989072339,-17.9605122421383071197814467
|
|
371
|
+
*DOTS,Dot screen
|
|
372
|
+
0, 0, 0, 0.79375, 1.5875, 0, -1.5875
|
|
373
|
+
*EARTH,Earth (section)
|
|
374
|
+
0, 0, 0, 6.35, 6.35, 6.35, -6.35
|
|
375
|
+
0, 0, 2.38125, 6.35, 6.35, 6.35, -6.35
|
|
376
|
+
0, 0, 4.7625, 6.35, 6.35, 6.35, -6.35
|
|
377
|
+
90, 0.79375, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
378
|
+
90, 3.175, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
379
|
+
90, 5.55625, 5.55625, 6.35, 6.35, 6.35, -6.35
|
|
380
|
+
*ESCHER,Isometric cube tiling
|
|
381
|
+
60, 0, 0, -15.24, 26.3964542936, 27.94, -2.54
|
|
382
|
+
180, 0, 0, -15.24, 26.3964542936, 27.94, -2.54
|
|
383
|
+
300, 0, 0, 15.24, 26.3964542936, 27.94, -2.54
|
|
384
|
+
60, 2.54, 0, -15.24, 26.3964542936, 5.08, -25.4
|
|
385
|
+
300, 2.54, 0, 15.24, 26.3964542936, 5.08, -25.4
|
|
386
|
+
60, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
387
|
+
180, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
388
|
+
300, -1.27, -2.199704516, 15.24, 26.3964542936, 5.08, -25.4
|
|
389
|
+
180, -1.27, -2.199704516, -15.24, 26.3964542936, 5.08, -25.4
|
|
390
|
+
60, -10.16, 0, -15.24, 26.3964542936, 5.08, -25.4
|
|
391
|
+
300, -10.16, 0, 15.24, 26.3964542936, 5.08, -25.4
|
|
392
|
+
60, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
393
|
+
180, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
394
|
+
300, 5.08, 8.7988180894, 15.24, 26.3964542936, 5.08, -25.4
|
|
395
|
+
180, 5.08, 8.7988180894, -15.24, 26.3964542936, 5.08, -25.4
|
|
396
|
+
0, 5.08, 4.3994090574, -15.24, 26.3964542936, 17.78, -12.7
|
|
397
|
+
0, 5.08, -4.3994090574, -15.24, 26.3964542936, 17.78, -12.7
|
|
398
|
+
120, 1.27, 6.5991135734, 15.24, 26.3964542936, 17.78, -12.7
|
|
399
|
+
120, -6.35, 2.199704516, 15.24, 26.3964542936, 17.78, -12.7
|
|
400
|
+
240, -6.35, -2.199704516, 15.24, 26.3964542936, 17.78, -12.7
|
|
401
|
+
240, 1.27, -6.5991135734, 15.24, 26.3964542936, 17.78, -12.7
|
|
402
|
+
*FLEX,Flexible material
|
|
403
|
+
0, 0, 0, 0, 6.35, 6.35, -6.35
|
|
404
|
+
45,6.35,0,4.490128053,4.490128053,1.5875,-5.8052561314,1.5875,-8.9802561314
|
|
405
|
+
*GOST_GLASS,Glass (GOST)
|
|
406
|
+
45, 0, 0, 6, -6, 5, -7
|
|
407
|
+
45, 2.121320, 0, 6, -6, 2, -10
|
|
408
|
+
45, 0, 2.121320, 6, -6, 2, -10
|
|
409
|
+
*GOST_GROUND,Ground (GOST)
|
|
410
|
+
45, 0, 0, 10, -10, 20
|
|
411
|
+
45, 3, 0, 10, -10, 20
|
|
412
|
+
45, 6, 0, 10, -10, 20
|
|
413
|
+
*GOST_WOOD,Wood (GOST)
|
|
414
|
+
90, 0, 0, 0, -6, 10, -2
|
|
415
|
+
90, 2, -2, 0, -6, 6, -1.5, 3, -1.5
|
|
416
|
+
90, 4, -5, 0, -6, 10, -2
|
|
417
|
+
*GRASS,Grass
|
|
418
|
+
90, 0, 0, 17.96051224, 17.96051224, 4.7625, -31.15852448
|
|
419
|
+
45, 0, 0, 0, 25.4, 4.7625, -20.6375
|
|
420
|
+
135, 0, 0, 0, 25.4, 4.7625, -20.6375
|
|
421
|
+
*GRATE,Grating
|
|
422
|
+
0, 0, 0, 0, 0.79375
|
|
423
|
+
90, 0, 0, 0, 3.175
|
|
424
|
+
*GRAVEL,Gravel, random cobbles
|
|
425
|
+
228.0127875,18.288,25.4,305.85067529778,1.88796713245,3.4172144,-338.30483639565
|
|
426
|
+
184.969741,16.002,22.86,-305.8545235377,1.10019612724,5.8640472,-580.54048893524
|
|
427
|
+
132.5104471,10.16,22.352,-377.59492241548,1.56030959675,4.1348152,-409.347227941
|
|
428
|
+
267.273689,.254,16.002,-508.63316875916,1.20815479432,5.3400452,-528.66437425738
|
|
429
|
+
292.83365418,0.0,10.668,-330.19770134945,1.23208097566,5.236337,-518.39807745344
|
|
430
|
+
357.273689,2.032,5.842,-508.63316875916,1.20815479432,5.3400452,-528.66437425738
|
|
431
|
+
37.69424047,7.366,5.588,-416.58997273292,.91357450169,7.0619366,-699.13115314247
|
|
432
|
+
72.25532837,12.954,9.906,586.40373773403,.96766293399,6.6671952,-660.05256601905
|
|
433
|
+
121.42956562,14.986,16.256,387.71230339293,1.2040754753,5.35813,-530.45545698712
|
|
434
|
+
175.2363583,12.192,20.828,-280.5442400419,2.10935518695,6.1171328,-299.7393695
|
|
435
|
+
222.3974378,6.096,21.336,413.48123885686,.81554484621,7.9107792,-783.16772512177
|
|
436
|
+
138.81407483,25.4,15.748,234.164238558,2.38943100688,2.7000454,-267.30565824344
|
|
437
|
+
171.4692344,23.368,17.526,-334.082478726,1.25594916784,5.1368198,-508.5463899704
|
|
438
|
+
225.00000,18.288,18.288,17.96051224214,17.96051224214,3.5920934,-32.32893108428
|
|
439
|
+
203.19859051,16.51,21.336,-136.74251918,3.33518339548,1.9344132,-191.50622368894
|
|
440
|
+
291.80140949,14.732,20.574,-80.18324702488,4.71666158921,2.7356562,-134.0475299
|
|
441
|
+
30.96375653,15.748,18.034,91.47734531502,4.35606406258,4.4431966,-143.6629815291
|
|
442
|
+
161.56505118,19.558,20.32,-56.2252967978,8.03218525675,3.2128714,-77.10898116828
|
|
443
|
+
16.389540334,0.0,20.574,265.17991128726,1.43340492604,4.50088,-445.58826672539
|
|
444
|
+
70.34617594,4.318,21.844,-297.29446803469,1.70858889651,3.7759894,-373.822156782
|
|
445
|
+
293.19859051,19.558,25.4,-136.7425191801,3.33518339548,3.868801,-189.57183588894
|
|
446
|
+
343.61045967,21.082,21.844,-265.17991128725,1.433404926,4.50088,-445.5882667254
|
|
447
|
+
339.44395478,0.0,4.826,-136.75087638398,2.97284513779,4.340352,-212.67734313106
|
|
448
|
+
294.7751406,4.064,3.302,-306.90424056705,1.77401295215,3.6367212,-360.0359338072
|
|
449
|
+
66.80140949,19.812,0.0,136.74251918012,3.33518339452,3.868801,-189.57183588894
|
|
450
|
+
17.35402464,21.336,3.556,-345.47402804977,1.51523696536,4.2578274,-421.523759802
|
|
451
|
+
69.44395478,7.366,0.0,-136.75087638396,2.97284513874,2.170176,-214.84751913106
|
|
452
|
+
101.309932474,18.288,0.0,104.60834648271,4.98134983255,1.295146,-128.21994964526
|
|
453
|
+
165.963756532,18.034,1.27,-80.085263387,6.16040487582,5.236337,-99.49054589069
|
|
454
|
+
186.00900596,12.954,2.54,-255.26337856879,1.32949676118,4.85267,-480.41364863337
|
|
455
|
+
303.69006753,15.748,15.748,-56.35753993648,7.0446924921,3.6632388,-87.9177635968
|
|
456
|
+
353.15722659,17.78,12.7,434.77679606606,1.0087628707,6.3955676,-633.16009065031
|
|
457
|
+
60.9453959,24.13,11.938,-204.76648550216,2.46706609031,2.6150824,-258.8939231811
|
|
458
|
+
90.0000000,25.4,14.224,25.4,25.4,1.524,-23.876
|
|
459
|
+
120.25643716,12.446,3.302,-204.77318477297,1.8283320086,3.5286696,-349.339407732
|
|
460
|
+
48.01278750,10.668,6.35,305.85067529778,1.88796713138,6.8344288,-334.88762199565
|
|
461
|
+
0.000000000,15.24,11.43,25.4,25.4,6.604,-18.796
|
|
462
|
+
325.3048465,21.844,11.43,310.04235091354,-1.6064370526,4.0160956,-397.5931672414
|
|
463
|
+
254.0546041,25.146,9.144,104.6687497289,3.48895832444,3.6982908,-181.21650038772
|
|
464
|
+
207.64597536,24.13,5.588,545.36007557253,1.07143433066,6.021451,-596.12464422938
|
|
465
|
+
175.42607874,18.796,2.794,331.1739336186,1.01276432357,6.3702946,-630.6584645624
|
|
466
|
+
*HEX,Hexagonal mesh
|
|
467
|
+
0, 0, 0, 0, 5.4992613154, 3.175, -6.35
|
|
468
|
+
120, 0, 0, 0, 5.4992613154, 3.175, -6.35
|
|
469
|
+
60, 3.175, 0, 0, 5.4992613154, 3.175, -6.35
|
|
470
|
+
*HONEY,Honeycomb
|
|
471
|
+
0, 0, 0, 4.7625, 2.749630645, 3.175, -6.35
|
|
472
|
+
120, 0, 0, 4.7625, 2.749630645, 3.175, -6.35
|
|
473
|
+
60, 0, 0, 4.7625, 2.749630645, -6.35, 3.175
|
|
474
|
+
*HOUND,Houndstooth
|
|
475
|
+
0, 0, 0, 6.35, 1.5875, 25.4, -12.7
|
|
476
|
+
90, 0, 0, -6.35, 1.5875, 25.4, -12.7
|
|
477
|
+
*INSUL,Insulation batt
|
|
478
|
+
0, 0, 0, 0, 9.525
|
|
479
|
+
0, 0, 3.175, 0, 9.525, 3.175, -3.175
|
|
480
|
+
0, 0, 6.35, 0, 9.525, 3.175, -3.175
|
|
481
|
+
*LINE,Horizontal lines
|
|
482
|
+
0, 0, 0, 0, 3.175
|
|
483
|
+
*MUDST,Mud / sand (geological)
|
|
484
|
+
0, 0, 0, 12.7, 6.35, 6.35, -6.35, 0, -6.35, 0, -6.35
|
|
485
|
+
*NET,Square grid
|
|
486
|
+
0, 0, 0, 0, 3.175
|
|
487
|
+
90, 0, 0, 0, 3.175
|
|
488
|
+
*NET3,Triangular grid
|
|
489
|
+
0, 0, 0, 0, 3.175
|
|
490
|
+
60, 0, 0, 0, 3.175
|
|
491
|
+
120, 0, 0, 0, 3.175
|
|
492
|
+
*PLAST,Plastic
|
|
493
|
+
0, 0, 0, 0, 6.35
|
|
494
|
+
0, 0, 0.79375, 0, 6.35
|
|
495
|
+
0, 0, 1.5875, 0, 6.35
|
|
496
|
+
*PLASTI,Plastic, dense
|
|
497
|
+
0, 0, 0, 0, 6.35
|
|
498
|
+
0, 0, 0.79375, 0, 6.35
|
|
499
|
+
0, 0, 1.5875, 0, 6.35
|
|
500
|
+
0, 0, 3.96875, 0, 6.35
|
|
501
|
+
*SACNCR,Concrete, dotted diagonal
|
|
502
|
+
45, 0, 0, 0, 2.38125
|
|
503
|
+
45, 1.6838, 0, 0, 2.38125, 0, -2.38125
|
|
504
|
+
*SQUARE,Dashed square lattice
|
|
505
|
+
0, 0, 0, 0, 3.175, 3.175, -3.175
|
|
506
|
+
90, 0, 0, 0, 3.175, 3.175, -3.175
|
|
507
|
+
*STARS,Six-pointed star lattice
|
|
508
|
+
0, 0, 0, 0, 5.4992613154, 3.175, -3.175
|
|
509
|
+
60, 0, 0, 0, 5.4992613154, 3.175, -3.175
|
|
510
|
+
120, 1.5875, 2.7496306704, 0, 5.4992613154, 3.175, -3.175
|
|
511
|
+
*STEEL,Steel, paired lines
|
|
512
|
+
45, 0, 0, 0, 3.175
|
|
513
|
+
45, 0, 1.5875, 0, 3.175
|
|
514
|
+
*SWAMP,Swamp / marsh
|
|
515
|
+
0, 0, 0, 12.7, 21.9970452362, 3.175, -22.225
|
|
516
|
+
90, 1.5875, 0, 21.9970452362, 12.7, 1.5875, -42.4065904724
|
|
517
|
+
90, 1.984375, 0, 21.9970452362, 12.7, 1.27, -42.7240904724
|
|
518
|
+
90, 1.190625, 0, 21.9970452362, 12.7, 1.27, -42.7240904724
|
|
519
|
+
60, 2.38125, 0, 12.7, 21.9970452362, 1.016, -24.384
|
|
520
|
+
120, 0.79375, 0, 12.7, 21.9970452362, 1.016, -24.384
|
|
521
|
+
*TRANS,Heat-transfer surface
|
|
522
|
+
0, 0, 0, 0, 6.35
|
|
523
|
+
0, 0, 3.175, 0, 6.35, 3.175, -3.175
|
|
524
|
+
*TRIANG,Triangle tiling
|
|
525
|
+
60, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
526
|
+
120, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
527
|
+
0, -2.38125, 4.1244459802, 4.7625, 8.2488919604, 4.7625, -4.7625
|
|
528
|
+
*ZIGZAG,Stair-step zigzag
|
|
529
|
+
0, 0, 0, 3.175, 3.175, 3.175, -3.175
|
|
530
|
+
90, 3.175, 0, 3.175, 3.175, 3.175, -3.175
|
|
531
|
+
|
|
532
|
+
;; Hatch companions to the ISO 128 line types (1 mm pen base).
|
|
533
|
+
|
|
534
|
+
*ACAD_ISO02W100,ISO dashed
|
|
535
|
+
0, 0,0, 0,5, 12,-3
|
|
536
|
+
*ACAD_ISO03W100,ISO dashed, wide gaps
|
|
537
|
+
0, 0,0, 0,5, 12,-18
|
|
538
|
+
*ACAD_ISO04W100,ISO long-dash dot
|
|
539
|
+
0, 0,0, 0,5, 24,-3,.5,-3
|
|
540
|
+
*ACAD_ISO05W100,ISO long-dash double-dot
|
|
541
|
+
0, 0,0, 0,5, 24,-3,.5,-3,.5,-3
|
|
542
|
+
*ACAD_ISO06W100,ISO long-dash triple-dot
|
|
543
|
+
0, 0,0, 0,5, 24,-3,.5,-3,.5,-6.5
|
|
544
|
+
0, 0,0, 0,5, -34,.5,-3
|
|
545
|
+
*ACAD_ISO07W100,ISO dotted
|
|
546
|
+
0, 0,0, 0,5, .5,-3
|
|
547
|
+
*ACAD_ISO08W100,ISO long-dash short-dash
|
|
548
|
+
0, 0,0, 0,5, 24,-3,6,-3
|
|
549
|
+
*ACAD_ISO09W100,ISO long-dash double short-dash
|
|
550
|
+
0, 0,0, 0,5, 24,-3,6,-3,6,-3
|
|
551
|
+
*ACAD_ISO10W100,ISO dash dot
|
|
552
|
+
0, 0,0, 0,5, 12,-3,.5,-3
|
|
553
|
+
*ACAD_ISO11W100,ISO double-dash dot
|
|
554
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-3
|
|
555
|
+
*ACAD_ISO12W100,ISO dash double-dot
|
|
556
|
+
0, 0,0, 0,5, 12,-3,.5,-3,.5,-3
|
|
557
|
+
*ACAD_ISO13W100,ISO double-dash double-dot
|
|
558
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-6.5
|
|
559
|
+
0, 0,0, 0,5, -33.5,.5,-3
|
|
560
|
+
*ACAD_ISO14W100,ISO dash triple-dot
|
|
561
|
+
0, 0,0, 0,5, 12,-3,.5,-3,.5,-6.5
|
|
562
|
+
0, 0,0, 0,5, -22,.5,-3
|
|
563
|
+
*ACAD_ISO15W100,ISO double-dash triple-dot
|
|
564
|
+
0, 0,0, 0,5, 12,-3,12,-3,.5,-10
|
|
565
|
+
0, 0,0, 0,5, -33.5,.5,-3,.5,-3
|
|
566
|
+
|
|
567
|
+
;; JIS A 0150 section patterns.
|
|
568
|
+
|
|
569
|
+
*JIS_LC_20,Lightweight concrete, 20 mm (JIS)
|
|
570
|
+
45,0,0,0,20
|
|
571
|
+
45,.4,0,0,20
|
|
572
|
+
*JIS_LC_20A,Lightweight concrete, 20 mm wide (JIS)
|
|
573
|
+
45,0,0,0,20
|
|
574
|
+
45,1,0,0,20
|
|
575
|
+
*JIS_LC_8,Lightweight concrete, 8 mm (JIS)
|
|
576
|
+
45,0,0,0,7.8
|
|
577
|
+
45,.4,0,0,7.8
|
|
578
|
+
*JIS_LC_8A,Lightweight concrete, 8 mm wide (JIS)
|
|
579
|
+
45,0,0,0,7.8
|
|
580
|
+
45,1,0,0,7.8
|
|
581
|
+
*JIS_RC_10,Reinforced concrete, 10 mm (JIS)
|
|
582
|
+
45,0,0,0,10
|
|
583
|
+
45,.725,0,0,10
|
|
584
|
+
45,1.45,0,0,10
|
|
585
|
+
*JIS_RC_15,Reinforced concrete, 15 mm (JIS)
|
|
586
|
+
45,0,0,0,15
|
|
587
|
+
45,.725,0,0,15
|
|
588
|
+
45,1.45,0,0,15
|
|
589
|
+
*JIS_RC_18,Reinforced concrete, 18 mm (JIS)
|
|
590
|
+
45,0,0,0,18
|
|
591
|
+
45,1,0,0,18
|
|
592
|
+
45,2,0,0,18
|
|
593
|
+
*JIS_RC_30,Reinforced concrete, 30 mm (JIS)
|
|
594
|
+
45,0,0,0,30
|
|
595
|
+
45,1,0,0,30
|
|
596
|
+
45,2,0,0,30
|
|
597
|
+
*JIS_STN_1E,Stone, 1 mm (JIS)
|
|
598
|
+
45, 0, 0, 0, 1
|
|
599
|
+
45, .705, 0, 0,1, 1, -.5
|
|
600
|
+
*JIS_STN_2.5,Stone, 2.5 mm (JIS)
|
|
601
|
+
45, 0, 0, 0, 2.5
|
|
602
|
+
45, 1.765, 0, 0,2.5, 1.2, -.5
|
|
603
|
+
*JIS_WOOD,Wood (JIS)
|
|
604
|
+
45,0,0,0,.70710678
|
|
605
|
+
`;
|
|
606
|
+
|
|
607
|
+
// ../core/src/model/hatchPatterns.ts
|
|
608
|
+
var parsePatternDefinitions = (text, unitScale = 25.4) => {
|
|
609
|
+
const DEG2RAD = Math.PI / 180;
|
|
610
|
+
const patterns = [];
|
|
611
|
+
let current = null;
|
|
612
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
613
|
+
const line = raw.trim();
|
|
614
|
+
if (!line || line.startsWith(";")) continue;
|
|
615
|
+
if (line.startsWith("*")) {
|
|
616
|
+
const [name, ...desc] = line.slice(1).split(",");
|
|
617
|
+
current = { name: name.trim(), lines: [] };
|
|
618
|
+
const d = desc.join(",").trim();
|
|
619
|
+
if (d) current.description = d;
|
|
620
|
+
patterns.push(current);
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
if (!current) continue;
|
|
624
|
+
const n = line.split(",").map((s) => Number(s.trim()));
|
|
625
|
+
if (n.length < 5 || n.some((v) => Number.isNaN(v))) continue;
|
|
626
|
+
const [angle2, x, y, dx, dy, ...dashes] = n;
|
|
627
|
+
current.lines.push({
|
|
628
|
+
angle: angle2 * DEG2RAD,
|
|
629
|
+
origin: { x: x * unitScale, y: y * unitScale },
|
|
630
|
+
deltaX: dx * unitScale,
|
|
631
|
+
deltaY: dy * unitScale,
|
|
632
|
+
dashesMm: dashes.length ? dashes.map((v) => v * unitScale) : void 0
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
return patterns.filter((p) => p.lines.length > 0);
|
|
636
|
+
};
|
|
637
|
+
var BUILT_IN_PATTERNS = parsePatternDefinitions(
|
|
638
|
+
BUILTIN_PAT,
|
|
639
|
+
1
|
|
640
|
+
).filter((p) => p.name.toUpperCase() !== "SOLID");
|
|
641
|
+
var normalizeName = (name) => name.trim().toUpperCase().replace(/[\s.-]+/g, "_");
|
|
642
|
+
var BUILT_IN_BY_NAME = new Map(
|
|
643
|
+
BUILT_IN_PATTERNS.map((p) => [normalizeName(p.name), p])
|
|
644
|
+
);
|
|
645
|
+
var HATCH_PATTERN_NAMES = BUILT_IN_PATTERNS.map(
|
|
646
|
+
(p) => p.name
|
|
647
|
+
);
|
|
648
|
+
var getHatchPattern = (name) => BUILT_IN_BY_NAME.get(normalizeName(name));
|
|
649
|
+
var MAX_HATCH_SEGMENTS = 1e5;
|
|
650
|
+
var estimatePatternSegments = (rings, pattern2, scale3) => {
|
|
651
|
+
if (scale3 <= 0) return 0;
|
|
652
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
653
|
+
for (const ring of rings)
|
|
654
|
+
for (const p of ring) {
|
|
655
|
+
if (p.x < minX) minX = p.x;
|
|
656
|
+
if (p.x > maxX) maxX = p.x;
|
|
657
|
+
if (p.y < minY) minY = p.y;
|
|
658
|
+
if (p.y > maxY) maxY = p.y;
|
|
659
|
+
}
|
|
660
|
+
if (minX > maxX) return 0;
|
|
661
|
+
const diag = Math.hypot(maxX - minX, maxY - minY);
|
|
662
|
+
let count = 0;
|
|
663
|
+
for (const fam of pattern2.lines) {
|
|
664
|
+
const perp2 = Math.abs(fam.deltaY) * scale3;
|
|
665
|
+
if (perp2 <= 1e-9) continue;
|
|
666
|
+
const lines = diag / perp2 + 1;
|
|
667
|
+
const period = (fam.dashesMm?.reduce((a, b) => a + Math.abs(b), 0) ?? 0) * scale3;
|
|
668
|
+
const perLine = period > 1e-9 ? diag / period + 1 : 1;
|
|
669
|
+
count += lines * perLine;
|
|
670
|
+
}
|
|
671
|
+
return count;
|
|
672
|
+
};
|
|
673
|
+
var computePatternGeometry = (rings, pattern2, angle2, scale3, origin = { x: 0, y: 0 }) => {
|
|
674
|
+
const out = [];
|
|
675
|
+
if (scale3 <= 0) return out;
|
|
676
|
+
const c = Math.cos(angle2);
|
|
677
|
+
const s = Math.sin(angle2);
|
|
678
|
+
for (const fam of pattern2.lines) {
|
|
679
|
+
if (Math.abs(fam.deltaY) * scale3 <= 1e-9) continue;
|
|
680
|
+
const ox = fam.origin.x * scale3;
|
|
681
|
+
const oy = fam.origin.y * scale3;
|
|
682
|
+
const segs = computeHatchFamily(rings, {
|
|
683
|
+
angle: angle2 + fam.angle,
|
|
684
|
+
origin: { x: ox * c - oy * s + origin.x, y: ox * s + oy * c + origin.y },
|
|
685
|
+
deltaAlong: fam.deltaX * scale3,
|
|
686
|
+
deltaPerp: fam.deltaY * scale3,
|
|
687
|
+
dashesMm: fam.dashesMm?.map((d) => d * scale3)
|
|
688
|
+
});
|
|
689
|
+
for (const seg of segs) out.push(seg);
|
|
690
|
+
}
|
|
691
|
+
return out;
|
|
692
|
+
};
|
|
693
|
+
var PatternLineSchema = z2.object({
|
|
694
|
+
/** Radians CCW, in the pattern's own frame. */
|
|
695
|
+
angle: z2.number(),
|
|
696
|
+
/** Base point, mm. */
|
|
697
|
+
origin: Vec2Schema,
|
|
698
|
+
/** Shift ALONG the line between successive lines (dash phase), mm. */
|
|
699
|
+
deltaX: z2.number(),
|
|
700
|
+
/** Perpendicular spacing between successive lines, mm. */
|
|
701
|
+
deltaY: z2.number().positive(),
|
|
702
|
+
/** Dash cycle along the line: >0 dash, <0 gap, 0 dot; absent = solid. */
|
|
703
|
+
dashesMm: z2.array(z2.number()).optional()
|
|
704
|
+
});
|
|
705
|
+
var HatchPatternSchema = z2.object({
|
|
706
|
+
/** Stored on fills as `fill.name`; case-insensitive, unique per document. */
|
|
707
|
+
name: z2.string().min(1),
|
|
708
|
+
description: z2.string().optional(),
|
|
709
|
+
lines: z2.array(PatternLineSchema).min(1)
|
|
710
|
+
});
|
|
711
|
+
var hatchPatternKey = (name) => normalizeName(name);
|
|
712
|
+
var resolveHatchPattern = (name, hatchPatterns) => {
|
|
713
|
+
if (!name) return void 0;
|
|
714
|
+
if (hatchPatterns && hatchPatterns.length > 0) {
|
|
715
|
+
const key = normalizeName(name);
|
|
716
|
+
const own = hatchPatterns.find((p) => normalizeName(p.name) === key);
|
|
717
|
+
if (own) return own;
|
|
718
|
+
}
|
|
719
|
+
return getHatchPattern(name);
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
// ../core/src/export/dxf/exportDxf.ts
|
|
723
|
+
import {
|
|
724
|
+
DxfWriter,
|
|
725
|
+
Units,
|
|
726
|
+
LayerFlags,
|
|
727
|
+
LWPolylineFlags,
|
|
728
|
+
TextHorizontalAlignment,
|
|
729
|
+
TextVerticalAlignment,
|
|
730
|
+
HatchBoundaryPaths,
|
|
731
|
+
HatchPolylineBoundary,
|
|
732
|
+
HatchPredefinedPatterns,
|
|
733
|
+
pattern
|
|
734
|
+
} from "@tarikjabiri/dxf";
|
|
735
|
+
|
|
736
|
+
// ../core/src/model/objects.ts
|
|
737
|
+
import { z as z3 } from "zod";
|
|
738
|
+
|
|
43
739
|
// ../core/src/model/fonts.ts
|
|
44
740
|
var DEFAULT_FONT = "arial";
|
|
45
741
|
var FONTS = {
|
|
@@ -172,102 +868,185 @@ var fontTypeface = (def) => def.cssStack.split(",")[0].replace(/["']/g, "").trim
|
|
|
172
868
|
var FONT_OPTIONS = Object.values(
|
|
173
869
|
FONTS
|
|
174
870
|
).filter((f) => f.id !== "osifont-italic").map((f) => ({ value: f.id, label: f.label }));
|
|
871
|
+
var SHX_STEMS = /* @__PURE__ */ new Set([
|
|
872
|
+
"txt",
|
|
873
|
+
"monotxt",
|
|
874
|
+
"simplex",
|
|
875
|
+
"complex",
|
|
876
|
+
"romans",
|
|
877
|
+
"romand",
|
|
878
|
+
"romanc",
|
|
879
|
+
"romant",
|
|
880
|
+
"italic",
|
|
881
|
+
"italicc",
|
|
882
|
+
"italict",
|
|
883
|
+
"scripts",
|
|
884
|
+
"scriptc",
|
|
885
|
+
"gothice",
|
|
886
|
+
"gothicg",
|
|
887
|
+
"gothici",
|
|
888
|
+
"greeks",
|
|
889
|
+
"greekc",
|
|
890
|
+
"isocp",
|
|
891
|
+
"isocp2",
|
|
892
|
+
"isocp3",
|
|
893
|
+
"isoct",
|
|
894
|
+
"isoct2",
|
|
895
|
+
"isoct3",
|
|
896
|
+
"iso",
|
|
897
|
+
"amgdt",
|
|
898
|
+
"gdt",
|
|
899
|
+
"symap",
|
|
900
|
+
"syastro",
|
|
901
|
+
"symath",
|
|
902
|
+
"symeteo",
|
|
903
|
+
"symusic",
|
|
904
|
+
"bigfont",
|
|
905
|
+
"ltypeshp",
|
|
906
|
+
"swiss",
|
|
907
|
+
"swissb",
|
|
908
|
+
"swissi",
|
|
909
|
+
"swissbi",
|
|
910
|
+
"sansserif",
|
|
911
|
+
"sanss",
|
|
912
|
+
"sansserifb",
|
|
913
|
+
"sanssb",
|
|
914
|
+
"arc",
|
|
915
|
+
"ic-romans",
|
|
916
|
+
"ic-simplex",
|
|
917
|
+
"txtalt"
|
|
918
|
+
]);
|
|
919
|
+
var fontFromDxfStyle = (fontFile, typeface) => {
|
|
920
|
+
const file = (fontFile ?? "").trim();
|
|
921
|
+
const stem = file.replace(/\.[a-z0-9]+$/i, "").toLowerCase();
|
|
922
|
+
const family = (typeface ?? "").trim();
|
|
923
|
+
const familyLower = family.toLowerCase();
|
|
924
|
+
for (const def of Object.values(FONTS)) {
|
|
925
|
+
if (file && def.dxfFontFile.toLowerCase() === file.toLowerCase() || familyLower && fontTypeface(def).toLowerCase() === familyLower)
|
|
926
|
+
return def.id === "osifont-italic" ? { font: "osifont", italic: true } : { font: def.id };
|
|
927
|
+
}
|
|
928
|
+
const arialFace = /^arial(bd|bi|i)$/.exec(stem);
|
|
929
|
+
if (arialFace)
|
|
930
|
+
return {
|
|
931
|
+
font: "arial",
|
|
932
|
+
...arialFace[1].includes("b") ? { bold: true } : {},
|
|
933
|
+
...arialFace[1].includes("i") ? { italic: true } : {}
|
|
934
|
+
};
|
|
935
|
+
const key = `${familyLower} ${stem}`;
|
|
936
|
+
if (/narrow|condensed|arialn/.test(key)) return { font: "roboto-condensed" };
|
|
937
|
+
if (/mono|courier|\bcour\b|consola|lucon|menlo/.test(key))
|
|
938
|
+
return { font: "jetbrains-mono" };
|
|
939
|
+
if (/times|georgia|cambria|garamond|serif|\bbook/.test(key))
|
|
940
|
+
return { font: "source-serif" };
|
|
941
|
+
if (/comic/.test(key)) return { font: "comic-neue" };
|
|
942
|
+
if (/\.shx$/i.test(file) || !file && !family || SHX_STEMS.has(stem))
|
|
943
|
+
return {
|
|
944
|
+
font: "osifont",
|
|
945
|
+
.../italic/.test(stem) ? { italic: true } : {}
|
|
946
|
+
};
|
|
947
|
+
return { font: family || stem };
|
|
948
|
+
};
|
|
175
949
|
|
|
176
950
|
// ../core/src/model/objects.ts
|
|
177
951
|
var PointSchema = ObjectBaseSchema.extend({
|
|
178
|
-
type:
|
|
952
|
+
type: z3.literal("point"),
|
|
179
953
|
p: Vec2Schema
|
|
180
954
|
});
|
|
181
955
|
var LineSchema = ObjectBaseSchema.extend({
|
|
182
|
-
type:
|
|
956
|
+
type: z3.literal("line"),
|
|
183
957
|
a: Vec2Schema,
|
|
184
958
|
b: Vec2Schema
|
|
185
959
|
});
|
|
186
|
-
var PolylineVertexSchema =
|
|
960
|
+
var PolylineVertexSchema = z3.preprocess(
|
|
187
961
|
(v) => Array.isArray(v) && v.length >= 2 ? { x: v[0], y: v[1], bulge: v[2] ?? 0 } : v,
|
|
188
|
-
|
|
962
|
+
z3.object({ x: z3.number(), y: z3.number(), bulge: z3.number().default(0) })
|
|
189
963
|
);
|
|
190
964
|
var PolylineSchema = ObjectBaseSchema.extend({
|
|
191
|
-
type:
|
|
192
|
-
points:
|
|
193
|
-
closed:
|
|
965
|
+
type: z3.literal("polyline"),
|
|
966
|
+
points: z3.array(PolylineVertexSchema).min(2),
|
|
967
|
+
closed: z3.boolean().default(false)
|
|
194
968
|
});
|
|
195
969
|
var CircleSchema = ObjectBaseSchema.extend({
|
|
196
|
-
type:
|
|
970
|
+
type: z3.literal("circle"),
|
|
197
971
|
center: Vec2Schema,
|
|
198
|
-
radius:
|
|
972
|
+
radius: z3.number().positive()
|
|
199
973
|
});
|
|
200
974
|
var ArcSchema = ObjectBaseSchema.extend({
|
|
201
|
-
type:
|
|
975
|
+
type: z3.literal("arc"),
|
|
202
976
|
center: Vec2Schema,
|
|
203
|
-
radius:
|
|
204
|
-
startAngle:
|
|
205
|
-
endAngle:
|
|
977
|
+
radius: z3.number().positive(),
|
|
978
|
+
startAngle: z3.number(),
|
|
979
|
+
endAngle: z3.number()
|
|
206
980
|
});
|
|
207
981
|
var EllipseSchema = ObjectBaseSchema.extend({
|
|
208
|
-
type:
|
|
982
|
+
type: z3.literal("ellipse"),
|
|
209
983
|
center: Vec2Schema,
|
|
210
984
|
majorAxis: Vec2Schema,
|
|
211
|
-
ratio:
|
|
212
|
-
startAngle:
|
|
213
|
-
endAngle:
|
|
985
|
+
ratio: z3.number().gt(0).max(1),
|
|
986
|
+
startAngle: z3.number().default(0),
|
|
987
|
+
endAngle: z3.number().default(Math.PI * 2)
|
|
214
988
|
});
|
|
215
|
-
var HatchLoopSchema =
|
|
216
|
-
points:
|
|
989
|
+
var HatchLoopSchema = z3.object({
|
|
990
|
+
points: z3.array(PolylineVertexSchema).min(3)
|
|
217
991
|
});
|
|
218
|
-
var HatchFillSchema =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
kind:
|
|
222
|
-
name:
|
|
223
|
-
angle:
|
|
224
|
-
scale:
|
|
992
|
+
var HatchFillSchema = z3.discriminatedUnion("kind", [
|
|
993
|
+
z3.object({ kind: z3.literal("solid") }),
|
|
994
|
+
z3.object({
|
|
995
|
+
kind: z3.literal("pattern"),
|
|
996
|
+
name: z3.string(),
|
|
997
|
+
angle: z3.number(),
|
|
998
|
+
scale: z3.number().positive(),
|
|
999
|
+
/** Where the pattern frame is anchored, world mm (absent = the drawing
|
|
1000
|
+
* origin, like a hatch drawn here). Set by import for hatches that came
|
|
1001
|
+
* out of blocks — AutoCAD anchors a block's hatch to the block, so the
|
|
1002
|
+
* pattern phase follows the insertion — and carried by the transforms. */
|
|
1003
|
+
origin: Vec2Schema.optional()
|
|
225
1004
|
}),
|
|
226
|
-
|
|
227
|
-
kind:
|
|
228
|
-
angle:
|
|
229
|
-
spacing:
|
|
1005
|
+
z3.object({
|
|
1006
|
+
kind: z3.literal("lines"),
|
|
1007
|
+
angle: z3.number(),
|
|
1008
|
+
spacing: z3.number().positive()
|
|
230
1009
|
}),
|
|
231
|
-
|
|
232
|
-
kind:
|
|
1010
|
+
z3.object({
|
|
1011
|
+
kind: z3.literal("gradient"),
|
|
233
1012
|
/** linear = color1→color2 along `angle`; radial = color1 at the
|
|
234
1013
|
* boundary's center fading to color2 at its edge. */
|
|
235
|
-
shape:
|
|
236
|
-
color1:
|
|
237
|
-
color2:
|
|
1014
|
+
shape: z3.enum(["linear", "radial"]).default("linear"),
|
|
1015
|
+
color1: z3.string().default("#808080"),
|
|
1016
|
+
color2: z3.string().default("#2d2d2d"),
|
|
238
1017
|
/** Direction, radians CCW: 0 = color1 on the left (linear only). */
|
|
239
|
-
angle:
|
|
1018
|
+
angle: z3.number().default(0)
|
|
240
1019
|
})
|
|
241
1020
|
]);
|
|
242
1021
|
var HatchSchema = ObjectBaseSchema.extend({
|
|
243
|
-
type:
|
|
244
|
-
loops:
|
|
1022
|
+
type: z3.literal("hatch"),
|
|
1023
|
+
loops: z3.array(HatchLoopSchema).min(1),
|
|
245
1024
|
fill: HatchFillSchema.default({
|
|
246
1025
|
kind: "lines",
|
|
247
1026
|
angle: Math.PI / 4,
|
|
248
1027
|
spacing: 5
|
|
249
1028
|
}),
|
|
250
1029
|
/** Pattern spacing multiplier (same idea as DimStyle.scale). */
|
|
251
|
-
scale:
|
|
1030
|
+
scale: z3.number().positive().default(1)
|
|
252
1031
|
});
|
|
253
|
-
var ArrowTypeSchema =
|
|
254
|
-
var TextStyleSchema =
|
|
255
|
-
id:
|
|
256
|
-
name:
|
|
1032
|
+
var ArrowTypeSchema = z3.enum(["filled", "open", "tick", "dot", "none"]);
|
|
1033
|
+
var TextStyleSchema = z3.object({
|
|
1034
|
+
id: z3.string().default(() => crypto.randomUUID()),
|
|
1035
|
+
name: z3.string().default("Standard"),
|
|
257
1036
|
/** Font id (model/fonts.ts). */
|
|
258
|
-
font:
|
|
1037
|
+
font: z3.string().default("arial"),
|
|
259
1038
|
/** AutoCAD-style width factor: horizontal glyph scale. */
|
|
260
|
-
widthFactor:
|
|
1039
|
+
widthFactor: z3.number().positive().default(1),
|
|
261
1040
|
/** Bold / italic face (bundled outlines where the font has them, else
|
|
262
1041
|
* synthesized — model/fonts.ts `fontFace`). Absent = regular. */
|
|
263
|
-
bold:
|
|
264
|
-
italic:
|
|
1042
|
+
bold: z3.boolean().optional(),
|
|
1043
|
+
italic: z3.boolean().optional(),
|
|
265
1044
|
/** Cap height in mm (world), before the object's `scale`. */
|
|
266
|
-
textHeight:
|
|
1045
|
+
textHeight: z3.number().positive().default(2.5),
|
|
267
1046
|
/** Leader arrowhead style. */
|
|
268
1047
|
arrowType: ArrowTypeSchema.default("filled"),
|
|
269
1048
|
/** Leader arrowhead size (mm), before the object's `scale`. */
|
|
270
|
-
arrowSize:
|
|
1049
|
+
arrowSize: z3.number().positive().default(2.5)
|
|
271
1050
|
});
|
|
272
1051
|
var DEFAULT_TEXT_STYLE = {
|
|
273
1052
|
id: "standard",
|
|
@@ -278,14 +1057,14 @@ var DEFAULT_TEXT_STYLE = {
|
|
|
278
1057
|
arrowType: "filled",
|
|
279
1058
|
arrowSize: 2.5
|
|
280
1059
|
};
|
|
281
|
-
var TextStyleOverrideSchema =
|
|
282
|
-
font:
|
|
283
|
-
widthFactor:
|
|
284
|
-
bold:
|
|
285
|
-
italic:
|
|
286
|
-
textHeight:
|
|
1060
|
+
var TextStyleOverrideSchema = z3.object({
|
|
1061
|
+
font: z3.string().optional(),
|
|
1062
|
+
widthFactor: z3.number().positive().optional(),
|
|
1063
|
+
bold: z3.boolean().optional(),
|
|
1064
|
+
italic: z3.boolean().optional(),
|
|
1065
|
+
textHeight: z3.number().positive().optional(),
|
|
287
1066
|
arrowType: ArrowTypeSchema.optional(),
|
|
288
|
-
arrowSize:
|
|
1067
|
+
arrowSize: z3.number().positive().optional()
|
|
289
1068
|
});
|
|
290
1069
|
var textStyleFor = (obj, styles) => styles.find((s) => s.id === obj.styleId) ?? styles[0] ?? DEFAULT_TEXT_STYLE;
|
|
291
1070
|
var resolveTextStyle = (obj, styles) => ({ ...textStyleFor(obj, styles), ...obj.styleOverride });
|
|
@@ -301,62 +1080,79 @@ var effectiveTextFont = (obj, styles) => {
|
|
|
301
1080
|
widthFactor: o?.widthFactor ?? base.widthFactor
|
|
302
1081
|
};
|
|
303
1082
|
};
|
|
1083
|
+
var TextSpanSchema = z3.object({
|
|
1084
|
+
start: z3.number().int().min(0),
|
|
1085
|
+
end: z3.number().int().min(0),
|
|
1086
|
+
/** Font id (model/fonts.ts). */
|
|
1087
|
+
font: z3.string().optional(),
|
|
1088
|
+
bold: z3.boolean().optional(),
|
|
1089
|
+
italic: z3.boolean().optional(),
|
|
1090
|
+
underline: z3.boolean().optional(),
|
|
1091
|
+
/** Literal colour; absent = the text's own (possibly ByLayer) colour. */
|
|
1092
|
+
color: ColorSchema.optional(),
|
|
1093
|
+
/** × the text's cap height. */
|
|
1094
|
+
height: z3.number().positive().optional(),
|
|
1095
|
+
script: z3.enum(["sub", "super"]).optional()
|
|
1096
|
+
});
|
|
304
1097
|
var TextSchema = ObjectBaseSchema.extend({
|
|
305
|
-
type:
|
|
1098
|
+
type: z3.literal("text"),
|
|
306
1099
|
position: Vec2Schema,
|
|
307
|
-
content:
|
|
1100
|
+
content: z3.string(),
|
|
1101
|
+
/** Character formatting over `content`; absent = all plain. Replacing
|
|
1102
|
+
* `content` without new spans drops them (offsets would be stale). */
|
|
1103
|
+
spans: z3.array(TextSpanSchema).optional(),
|
|
308
1104
|
/** Arrow polylines pointing at this text (arrowhead at [0]). */
|
|
309
|
-
leaderLines:
|
|
1105
|
+
leaderLines: z3.array(z3.array(Vec2Schema).min(2)).default([]),
|
|
310
1106
|
/**
|
|
311
1107
|
* Max text box width in mm (before `scale`) — the word-wrap boundary and the
|
|
312
1108
|
* frame width. Undefined = no wrapping (lines break only on explicit
|
|
313
1109
|
* newlines). Maps to the DXF MTEXT reference rectangle width.
|
|
314
1110
|
*/
|
|
315
|
-
width:
|
|
316
|
-
hAlign:
|
|
317
|
-
vAlign:
|
|
1111
|
+
width: z3.number().positive().optional(),
|
|
1112
|
+
hAlign: z3.enum(["left", "center", "right"]).default("center"),
|
|
1113
|
+
vAlign: z3.enum(["bottom", "center", "top"]).default("center"),
|
|
318
1114
|
/** Border drawn around the text: a rectangle, a circle, a slot (rounded
|
|
319
1115
|
* ends), a line under the text or under its first line. */
|
|
320
|
-
frame:
|
|
1116
|
+
frame: z3.enum(["none", "rectangle", "circle", "slot", "bottom", "firstLine"]).optional(),
|
|
321
1117
|
/** The document text style this text follows (absent/dangling = the
|
|
322
1118
|
* document's first style). */
|
|
323
|
-
styleId:
|
|
1119
|
+
styleId: z3.string().optional(),
|
|
324
1120
|
/** Style keys the user set on THIS text (font, height, arrows, …);
|
|
325
1121
|
* absent = inherit the referenced style. */
|
|
326
1122
|
styleOverride: TextStyleOverrideSchema.optional(),
|
|
327
|
-
rotation:
|
|
1123
|
+
rotation: z3.number().default(0),
|
|
328
1124
|
/** Size multiplier for height + arrow size (same idea as
|
|
329
1125
|
* Dimension.scale). */
|
|
330
|
-
scale:
|
|
1126
|
+
scale: z3.number().positive().default(1)
|
|
331
1127
|
});
|
|
332
|
-
var DimensionKindSchema =
|
|
1128
|
+
var DimensionKindSchema = z3.enum([
|
|
333
1129
|
"linear",
|
|
334
1130
|
"angular",
|
|
335
1131
|
"radial",
|
|
336
1132
|
"diameter"
|
|
337
1133
|
]);
|
|
338
|
-
var DimStyleSchema =
|
|
339
|
-
id:
|
|
340
|
-
name:
|
|
1134
|
+
var DimStyleSchema = z3.object({
|
|
1135
|
+
id: z3.string().default(() => crypto.randomUUID()),
|
|
1136
|
+
name: z3.string().default("Standard"),
|
|
341
1137
|
/** Font id for dimension text (model/fonts.ts). */
|
|
342
|
-
font:
|
|
1138
|
+
font: z3.string().default("arial"),
|
|
343
1139
|
/** Horizontal glyph scale for dimension text. */
|
|
344
|
-
widthFactor:
|
|
1140
|
+
widthFactor: z3.number().positive().default(1),
|
|
345
1141
|
/** Bold / italic dimension text (same faces as TextStyle). */
|
|
346
|
-
bold:
|
|
347
|
-
italic:
|
|
348
|
-
textHeight:
|
|
1142
|
+
bold: z3.boolean().optional(),
|
|
1143
|
+
italic: z3.boolean().optional(),
|
|
1144
|
+
textHeight: z3.number().positive().default(2.5),
|
|
349
1145
|
/** Dimension line → text center distance (mm, × scale; DXF DIMGAP-ish). */
|
|
350
|
-
textOffset:
|
|
1146
|
+
textOffset: z3.number().default(1.8),
|
|
351
1147
|
arrowType: ArrowTypeSchema.default("tick"),
|
|
352
|
-
arrowSize:
|
|
1148
|
+
arrowSize: z3.number().positive().default(2.5),
|
|
353
1149
|
/** "long" runs each extension line from the measured point to the
|
|
354
1150
|
* dimension line; "short" draws only a 2×overshoot tick across it. */
|
|
355
|
-
extensionType:
|
|
356
|
-
extensionOffset:
|
|
357
|
-
extensionOvershoot:
|
|
1151
|
+
extensionType: z3.enum(["long", "short"]).default("long"),
|
|
1152
|
+
extensionOffset: z3.number().default(1),
|
|
1153
|
+
extensionOvershoot: z3.number().default(1.25),
|
|
358
1154
|
/** Decimal places for the measurement text. */
|
|
359
|
-
precision:
|
|
1155
|
+
precision: z3.number().int().min(0).max(6).default(1)
|
|
360
1156
|
});
|
|
361
1157
|
var DEFAULT_DIM_STYLE = {
|
|
362
1158
|
id: "standard",
|
|
@@ -372,19 +1168,19 @@ var DEFAULT_DIM_STYLE = {
|
|
|
372
1168
|
extensionOvershoot: 1,
|
|
373
1169
|
precision: 1
|
|
374
1170
|
};
|
|
375
|
-
var DimStyleOverrideSchema =
|
|
376
|
-
font:
|
|
377
|
-
widthFactor:
|
|
378
|
-
bold:
|
|
379
|
-
italic:
|
|
380
|
-
textHeight:
|
|
381
|
-
textOffset:
|
|
1171
|
+
var DimStyleOverrideSchema = z3.object({
|
|
1172
|
+
font: z3.string().optional(),
|
|
1173
|
+
widthFactor: z3.number().positive().optional(),
|
|
1174
|
+
bold: z3.boolean().optional(),
|
|
1175
|
+
italic: z3.boolean().optional(),
|
|
1176
|
+
textHeight: z3.number().positive().optional(),
|
|
1177
|
+
textOffset: z3.number().optional(),
|
|
382
1178
|
arrowType: ArrowTypeSchema.optional(),
|
|
383
|
-
arrowSize:
|
|
384
|
-
extensionType:
|
|
385
|
-
extensionOffset:
|
|
386
|
-
extensionOvershoot:
|
|
387
|
-
precision:
|
|
1179
|
+
arrowSize: z3.number().positive().optional(),
|
|
1180
|
+
extensionType: z3.enum(["long", "short"]).optional(),
|
|
1181
|
+
extensionOffset: z3.number().optional(),
|
|
1182
|
+
extensionOvershoot: z3.number().optional(),
|
|
1183
|
+
precision: z3.number().int().min(0).max(6).optional()
|
|
388
1184
|
});
|
|
389
1185
|
var unknownStyleOverrideKeys = (input) => {
|
|
390
1186
|
const so = input.styleOverride;
|
|
@@ -403,48 +1199,114 @@ var assertKnownStyleOverrideKeys = (input, where) => {
|
|
|
403
1199
|
};
|
|
404
1200
|
var dimStyleFor = (obj, styles) => styles.find((s) => s.id === obj.styleId) ?? styles[0] ?? DEFAULT_DIM_STYLE;
|
|
405
1201
|
var dimFontFace = (style) => fontFace(style.font, style.bold, style.italic);
|
|
406
|
-
var
|
|
407
|
-
|
|
1202
|
+
var DIM_VALUE_TOKEN = "{value}";
|
|
1203
|
+
var DimLabelSchema = z3.object({
|
|
1204
|
+
/** mm along the dimension line from the segment's origin (linear: the
|
|
1205
|
+
* foot of the segment's first point; angular: where ray a meets the arc,
|
|
1206
|
+
* as arc length; radial/diameter: the center). Undefined = automatic
|
|
1207
|
+
* placement: centered when the text fits, else outside. */
|
|
1208
|
+
along: z3.number().optional(),
|
|
1209
|
+
/** mm perpendicular to the dimension line, positive on the side the
|
|
1210
|
+
* dimension line is on (linear/angular) or to the left of `along`
|
|
1211
|
+
* (radial/diameter). Undefined or 0 = on the line; otherwise the text
|
|
1212
|
+
* floats, with a leader when it no longer overlaps its segment. */
|
|
1213
|
+
across: z3.number().optional(),
|
|
1214
|
+
/** Text; `{value}` is replaced by the formatted measurement. Undefined =
|
|
1215
|
+
* the kind's default template ("{value}", "{value}°", "R{value}",
|
|
1216
|
+
* "Ø{value}"). */
|
|
1217
|
+
content: z3.string().optional(),
|
|
1218
|
+
/** Character formatting over `content` (the TEMPLATE: a span covering
|
|
1219
|
+
* `{value}` formats the measurement). Needs `content` set. */
|
|
1220
|
+
spans: z3.array(TextSpanSchema).optional()
|
|
1221
|
+
});
|
|
1222
|
+
var DimensionShapeSchema = ObjectBaseSchema.extend({
|
|
1223
|
+
type: z3.literal("dimension"),
|
|
408
1224
|
kind: DimensionKindSchema.default("linear"),
|
|
409
1225
|
/**
|
|
410
|
-
* Measured points.
|
|
411
|
-
*
|
|
412
|
-
*
|
|
1226
|
+
* Measured points. linear: 2+ (more than two render as a CHAIN — one
|
|
1227
|
+
* measurement per consecutive pair sharing the dimension line);
|
|
1228
|
+
* angular: [vertex, a, b]; radial: [center, curve point]; diameter:
|
|
1229
|
+
* [p1, p2] opposite on the curve.
|
|
1230
|
+
*/
|
|
1231
|
+
points: z3.array(Vec2Schema).min(2),
|
|
1232
|
+
/**
|
|
1233
|
+
* linear only: the measuring direction, radians CCW from +X (DXF's
|
|
1234
|
+
* "rotated" dimension, code 50). Undefined = aligned to
|
|
1235
|
+
* points[0] → points[last] (DXF "aligned"), so dragging a point turns the
|
|
1236
|
+
* dimension; set, the direction is locked and a point drag only changes
|
|
1237
|
+
* the measurement.
|
|
413
1238
|
*/
|
|
414
|
-
|
|
1239
|
+
rotation: z3.number().optional(),
|
|
415
1240
|
/**
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
1241
|
+
* linear: signed distance of the dimension line from points[0] along the
|
|
1242
|
+
* LEFT perpendicular of the measuring direction. angular: the arc radius,
|
|
1243
|
+
* positive for the arc running CCW from a to b, negative for the
|
|
1244
|
+
* complementary arc. radial/diameter: absent — the line's direction comes
|
|
1245
|
+
* from the points and the text position is labels[0].along.
|
|
421
1246
|
*/
|
|
422
|
-
offset:
|
|
423
|
-
|
|
1247
|
+
offset: z3.number().optional(),
|
|
1248
|
+
/** One label per measured segment (linear chain: points.length − 1,
|
|
1249
|
+
* every other kind: 1). Missing or short = automatic. */
|
|
1250
|
+
labels: z3.array(DimLabelSchema).default([]),
|
|
424
1251
|
/** The document dimension style this dimension follows (absent/dangling =
|
|
425
1252
|
* the document's first style). */
|
|
426
|
-
styleId:
|
|
1253
|
+
styleId: z3.string().optional(),
|
|
427
1254
|
styleOverride: DimStyleOverrideSchema.optional(),
|
|
428
1255
|
/** Annotation size multiplier (text/arrows/offsets — same idea as
|
|
429
1256
|
* Text.scale; rides as DIMSCALE in DXF). */
|
|
430
|
-
scale:
|
|
1257
|
+
scale: z3.number().positive().default(1)
|
|
431
1258
|
});
|
|
1259
|
+
var dimensionRefinement = (d, ctx) => {
|
|
1260
|
+
const need = d.kind === "angular" ? 3 : 2;
|
|
1261
|
+
if (d.points.length < need)
|
|
1262
|
+
ctx.addIssue({
|
|
1263
|
+
code: "custom",
|
|
1264
|
+
path: ["points"],
|
|
1265
|
+
message: `a ${d.kind} dimension needs at least ${need} points`
|
|
1266
|
+
});
|
|
1267
|
+
if (d.kind !== "linear" && d.kind !== "angular") {
|
|
1268
|
+
if (d.offset !== void 0)
|
|
1269
|
+
ctx.addIssue({
|
|
1270
|
+
code: "custom",
|
|
1271
|
+
path: ["offset"],
|
|
1272
|
+
message: `offset does not apply to a ${d.kind} dimension (the text position is labels[0].along)`
|
|
1273
|
+
});
|
|
1274
|
+
} else if (d.offset === void 0)
|
|
1275
|
+
ctx.addIssue({
|
|
1276
|
+
code: "custom",
|
|
1277
|
+
path: ["offset"],
|
|
1278
|
+
message: `a ${d.kind} dimension needs offset`
|
|
1279
|
+
});
|
|
1280
|
+
if (d.kind !== "linear" && d.rotation !== void 0)
|
|
1281
|
+
ctx.addIssue({
|
|
1282
|
+
code: "custom",
|
|
1283
|
+
path: ["rotation"],
|
|
1284
|
+
message: "rotation applies to linear dimensions only"
|
|
1285
|
+
});
|
|
1286
|
+
};
|
|
1287
|
+
var DimensionSchema = DimensionShapeSchema.superRefine(dimensionRefinement);
|
|
1288
|
+
var DIM_DEFAULT_CONTENT = {
|
|
1289
|
+
linear: DIM_VALUE_TOKEN,
|
|
1290
|
+
angular: `${DIM_VALUE_TOKEN}\xB0`,
|
|
1291
|
+
radial: `R${DIM_VALUE_TOKEN}`,
|
|
1292
|
+
diameter: `\xD8${DIM_VALUE_TOKEN}`
|
|
1293
|
+
};
|
|
432
1294
|
var BlockSchema = ObjectBaseSchema.extend({
|
|
433
|
-
type:
|
|
434
|
-
definitionId:
|
|
1295
|
+
type: z3.literal("block"),
|
|
1296
|
+
definitionId: z3.string(),
|
|
435
1297
|
/** Applied LAST, about the pivot (the first point input). */
|
|
436
|
-
rotation:
|
|
437
|
-
scale:
|
|
1298
|
+
rotation: z3.number().default(0),
|
|
1299
|
+
scale: z3.number().positive().default(1),
|
|
438
1300
|
/** Per-instance parameter values (merged over the definition defaults). */
|
|
439
|
-
params:
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
1301
|
+
params: z3.record(
|
|
1302
|
+
z3.string(),
|
|
1303
|
+
z3.union([
|
|
1304
|
+
z3.number(),
|
|
1305
|
+
z3.string(),
|
|
1306
|
+
z3.boolean(),
|
|
445
1307
|
// numberList / stringList parameters.
|
|
446
|
-
|
|
447
|
-
|
|
1308
|
+
z3.array(z3.number()),
|
|
1309
|
+
z3.array(z3.string())
|
|
448
1310
|
])
|
|
449
1311
|
).default({}),
|
|
450
1312
|
/**
|
|
@@ -456,63 +1318,73 @@ var BlockSchema = ObjectBaseSchema.extend({
|
|
|
456
1318
|
* Transforms map the points and the script recomputes, which is what
|
|
457
1319
|
* makes mirror correct for script-derived geometry.
|
|
458
1320
|
*/
|
|
459
|
-
inputs:
|
|
1321
|
+
inputs: z3.array(z3.union([Vec2Schema, z3.string()])).default([])
|
|
460
1322
|
});
|
|
461
1323
|
var CommentSchema = ObjectBaseSchema.extend({
|
|
462
|
-
type:
|
|
1324
|
+
type: z3.literal("comment"),
|
|
463
1325
|
/** Tail tip of the bubble (world/sheet mm). */
|
|
464
1326
|
position: Vec2Schema,
|
|
465
|
-
text:
|
|
466
|
-
tags:
|
|
1327
|
+
text: z3.string().default(""),
|
|
1328
|
+
tags: z3.array(z3.string()).default([])
|
|
467
1329
|
});
|
|
468
|
-
var
|
|
469
|
-
|
|
470
|
-
text
|
|
1330
|
+
var cellInput = (v) => {
|
|
1331
|
+
if (typeof v === "string") return { content: v };
|
|
1332
|
+
if (v && typeof v === "object" && "text" in v && !("content" in v)) {
|
|
1333
|
+
const { text, ...rest } = v;
|
|
1334
|
+
return { ...rest, content: text };
|
|
1335
|
+
}
|
|
1336
|
+
return v;
|
|
1337
|
+
};
|
|
1338
|
+
var TableCellSchema = z3.object({
|
|
1339
|
+
/** Plain text; "\n" = line break. Long lines wrap at the cell width.
|
|
1340
|
+
* (Named `text` before document v22 — still read, see `cellInput`.) */
|
|
1341
|
+
content: z3.string().default(""),
|
|
1342
|
+
/** Character formatting over `content` (core/table.ts `cellWithContent`
|
|
1343
|
+
* keeps it consistent when the content changes). */
|
|
1344
|
+
spans: z3.array(TextSpanSchema).optional(),
|
|
471
1345
|
/** Merge, set on the ANCHOR (top-left) cell. Covered cells stay in the
|
|
472
1346
|
* grid with their content ignored — AutoCAD's model. */
|
|
473
|
-
span:
|
|
474
|
-
cols:
|
|
475
|
-
rows:
|
|
1347
|
+
span: z3.object({
|
|
1348
|
+
cols: z3.number().int().min(1),
|
|
1349
|
+
rows: z3.number().int().min(1)
|
|
476
1350
|
}).optional(),
|
|
477
1351
|
/** Where the text sits in the cell; absent = left / center. */
|
|
478
|
-
hAlign:
|
|
479
|
-
vAlign:
|
|
480
|
-
styleId:
|
|
1352
|
+
hAlign: z3.enum(["left", "center", "right"]).optional(),
|
|
1353
|
+
vAlign: z3.enum(["top", "center", "bottom"]).optional(),
|
|
1354
|
+
styleId: z3.string().optional(),
|
|
481
1355
|
styleOverride: TextStyleOverrideSchema.optional(),
|
|
482
1356
|
/** Text color; absent = the table's. */
|
|
483
1357
|
color: ColorSchema.optional()
|
|
484
1358
|
});
|
|
485
|
-
var
|
|
486
|
-
type:
|
|
1359
|
+
var TableShapeSchema = ObjectBaseSchema.extend({
|
|
1360
|
+
type: z3.literal("table"),
|
|
487
1361
|
position: Vec2Schema,
|
|
488
|
-
rotation:
|
|
489
|
-
scale:
|
|
1362
|
+
rotation: z3.number().default(0),
|
|
1363
|
+
scale: z3.number().positive().default(1),
|
|
490
1364
|
/** Column widths (mm). */
|
|
491
|
-
columns:
|
|
1365
|
+
columns: z3.array(z3.number().positive()).min(1),
|
|
492
1366
|
/** Per-row settings. Input may give a row COUNT (all auto-height). */
|
|
493
|
-
rows:
|
|
1367
|
+
rows: z3.preprocess(
|
|
494
1368
|
(v) => typeof v === "number" ? Array.from({ length: v }, () => ({})) : v,
|
|
495
|
-
|
|
1369
|
+
z3.array(z3.object({ minHeight: z3.number().positive().optional() })).min(1)
|
|
496
1370
|
),
|
|
497
1371
|
/** Row-major: `cells[row][column]`, exactly rows × columns. Input may
|
|
498
1372
|
* give a cell as a plain string (= `{ text }`). */
|
|
499
|
-
cells:
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
(v) => typeof v === "string" ? { text: v } : v,
|
|
503
|
-
TableCellSchema
|
|
504
|
-
)
|
|
1373
|
+
cells: z3.array(
|
|
1374
|
+
z3.array(
|
|
1375
|
+
z3.preprocess(cellInput, TableCellSchema)
|
|
505
1376
|
)
|
|
506
1377
|
),
|
|
507
1378
|
/** Rows above the heavier header rule. */
|
|
508
|
-
headerRows:
|
|
1379
|
+
headerRows: z3.number().int().min(0).default(0),
|
|
509
1380
|
/** Text inset from the cell edges (mm). */
|
|
510
|
-
cellMargin:
|
|
511
|
-
borders:
|
|
1381
|
+
cellMargin: z3.number().min(0).default(1),
|
|
1382
|
+
borders: z3.enum(["all", "outer", "rows", "none"]).default("all"),
|
|
512
1383
|
/** Document text style for every cell (cells may override). */
|
|
513
|
-
styleId:
|
|
1384
|
+
styleId: z3.string().optional(),
|
|
514
1385
|
styleOverride: TextStyleOverrideSchema.optional()
|
|
515
|
-
})
|
|
1386
|
+
});
|
|
1387
|
+
var tableRefinement = (t, ctx) => {
|
|
516
1388
|
const issue = (message) => ctx.addIssue({ code: "custom", message });
|
|
517
1389
|
const nr = t.rows.length;
|
|
518
1390
|
const nc = t.columns.length;
|
|
@@ -536,40 +1408,28 @@ var TableSchema = ObjectBaseSchema.extend({
|
|
|
536
1408
|
}
|
|
537
1409
|
})
|
|
538
1410
|
);
|
|
539
|
-
}
|
|
1411
|
+
};
|
|
1412
|
+
var TableSchema = TableShapeSchema.superRefine(tableRefinement);
|
|
540
1413
|
var blockPivot = (b) => {
|
|
541
1414
|
for (const v of b.inputs) if (typeof v !== "string") return v;
|
|
542
1415
|
return { x: 0, y: 0 };
|
|
543
1416
|
};
|
|
544
1417
|
var ViewportSchema = ObjectBaseSchema.extend({
|
|
545
|
-
type:
|
|
1418
|
+
type: z3.literal("viewport"),
|
|
546
1419
|
/** Placement on the sheet, mm, origin bottom-left of sheet. */
|
|
547
|
-
rect:
|
|
548
|
-
x:
|
|
549
|
-
y:
|
|
550
|
-
w:
|
|
551
|
-
h:
|
|
1420
|
+
rect: z3.object({
|
|
1421
|
+
x: z3.number(),
|
|
1422
|
+
y: z3.number(),
|
|
1423
|
+
w: z3.number().positive(),
|
|
1424
|
+
h: z3.number().positive()
|
|
552
1425
|
}),
|
|
553
1426
|
/** World point shown at the center of the rect. */
|
|
554
1427
|
modelCenter: Vec2Schema.default({ x: 0, y: 0 }),
|
|
555
1428
|
/** Drawing-scale denominator (model mm per paper mm); 1:50 => 50. */
|
|
556
|
-
scale:
|
|
1429
|
+
scale: z3.number().positive().default(1),
|
|
557
1430
|
/** Pinned: no pan/zoom-through, no move/resize grips. */
|
|
558
|
-
locked:
|
|
559
|
-
hiddenLayerIds:
|
|
560
|
-
});
|
|
561
|
-
var ImageSchema = ObjectBaseSchema.extend({
|
|
562
|
-
type: z2.literal("image"),
|
|
563
|
-
/** Key into `document.assets`. */
|
|
564
|
-
assetId: z2.string(),
|
|
565
|
-
/** Bottom-left corner (world/sheet mm) — rotation pivots here. */
|
|
566
|
-
origin: Vec2Schema,
|
|
567
|
-
width: z2.number().positive(),
|
|
568
|
-
height: z2.number().positive(),
|
|
569
|
-
/** Radians CCW about `origin`. */
|
|
570
|
-
rotation: z2.number().default(0)
|
|
571
|
-
// (opacity moved to ObjectBaseSchema — every object paints with it now;
|
|
572
|
-
// documents that stored it per-image parse unchanged.)
|
|
1431
|
+
locked: z3.boolean().default(false),
|
|
1432
|
+
hiddenLayerIds: z3.array(z3.string()).default([])
|
|
573
1433
|
});
|
|
574
1434
|
var REFERENCE_FORMATS = [
|
|
575
1435
|
"linea",
|
|
@@ -579,54 +1439,55 @@ var REFERENCE_FORMATS = [
|
|
|
579
1439
|
"png",
|
|
580
1440
|
"jpg"
|
|
581
1441
|
];
|
|
582
|
-
var ReferenceSourceSchema =
|
|
583
|
-
|
|
584
|
-
kind:
|
|
585
|
-
path:
|
|
586
|
-
cacheKey:
|
|
1442
|
+
var ReferenceSourceSchema = z3.discriminatedUnion("kind", [
|
|
1443
|
+
z3.object({
|
|
1444
|
+
kind: z3.literal("path"),
|
|
1445
|
+
path: z3.string().min(1),
|
|
1446
|
+
cacheKey: z3.string().min(1).optional()
|
|
587
1447
|
}),
|
|
588
|
-
|
|
1448
|
+
z3.object({ kind: z3.literal("url"), url: z3.string().url() }),
|
|
1449
|
+
z3.object({ kind: z3.literal("asset"), assetId: z3.string().min(1) })
|
|
589
1450
|
]);
|
|
590
1451
|
var ReferenceSchema = ObjectBaseSchema.extend({
|
|
591
|
-
type:
|
|
592
|
-
format:
|
|
593
|
-
name:
|
|
1452
|
+
type: z3.literal("reference"),
|
|
1453
|
+
format: z3.enum(REFERENCE_FORMATS),
|
|
1454
|
+
name: z3.string().min(1),
|
|
594
1455
|
source: ReferenceSourceSchema,
|
|
595
1456
|
position: Vec2Schema,
|
|
596
1457
|
/** Radians CCW about `position`. */
|
|
597
|
-
rotation:
|
|
598
|
-
scale:
|
|
599
|
-
mirrored:
|
|
1458
|
+
rotation: z3.number().default(0),
|
|
1459
|
+
scale: z3.number().positive().default(1),
|
|
1460
|
+
mirrored: z3.boolean().optional(),
|
|
600
1461
|
/** PDF: the 1-based page drawn, and how (vector lines + text / raster). */
|
|
601
|
-
pdfPage:
|
|
602
|
-
pdfMode:
|
|
1462
|
+
pdfPage: z3.number().int().positive().optional(),
|
|
1463
|
+
pdfMode: z3.enum(["vector", "raster"]).optional(),
|
|
603
1464
|
/** The FILE's layers not drawn, by name (stable across reloads). */
|
|
604
|
-
hiddenLayers:
|
|
1465
|
+
hiddenLayers: z3.array(z3.string()).default([]),
|
|
605
1466
|
/** Switched off in the References panel: not drawn, picked or snapped. */
|
|
606
|
-
hidden:
|
|
1467
|
+
hidden: z3.boolean().optional(),
|
|
607
1468
|
/** Locked in the References panel: drawn and snapped, but never hovered
|
|
608
1469
|
* or picked on the canvas — select it from the panel instead. */
|
|
609
|
-
locked:
|
|
1470
|
+
locked: z3.boolean().optional(),
|
|
610
1471
|
/** Crop rectangle in FILE coordinates: only content inside is drawn and
|
|
611
1472
|
* snapped (AutoCAD's XCLIP, rectangular). */
|
|
612
|
-
clip:
|
|
613
|
-
minX:
|
|
614
|
-
minY:
|
|
615
|
-
maxX:
|
|
616
|
-
maxY:
|
|
1473
|
+
clip: z3.object({
|
|
1474
|
+
minX: z3.number(),
|
|
1475
|
+
minY: z3.number(),
|
|
1476
|
+
maxX: z3.number(),
|
|
1477
|
+
maxY: z3.number()
|
|
617
1478
|
}).optional(),
|
|
618
1479
|
/**
|
|
619
1480
|
* The content's bounds in file coordinates, recorded on each successful
|
|
620
1481
|
* load: a missing file still has a frame to draw, pick and snap to.
|
|
621
1482
|
*/
|
|
622
|
-
extent:
|
|
623
|
-
minX:
|
|
624
|
-
minY:
|
|
625
|
-
maxX:
|
|
626
|
-
maxY:
|
|
1483
|
+
extent: z3.object({
|
|
1484
|
+
minX: z3.number(),
|
|
1485
|
+
minY: z3.number(),
|
|
1486
|
+
maxX: z3.number(),
|
|
1487
|
+
maxY: z3.number()
|
|
627
1488
|
}).optional()
|
|
628
1489
|
});
|
|
629
|
-
var ModelObjectSchema =
|
|
1490
|
+
var ModelObjectSchema = z3.discriminatedUnion("type", [
|
|
630
1491
|
PointSchema,
|
|
631
1492
|
LineSchema,
|
|
632
1493
|
PolylineSchema,
|
|
@@ -637,13 +1498,15 @@ var ModelObjectSchema = z2.discriminatedUnion("type", [
|
|
|
637
1498
|
TextSchema,
|
|
638
1499
|
DimensionSchema,
|
|
639
1500
|
BlockSchema,
|
|
640
|
-
ImageSchema,
|
|
641
1501
|
ViewportSchema,
|
|
642
1502
|
CommentSchema,
|
|
643
1503
|
TableSchema,
|
|
644
1504
|
ReferenceSchema
|
|
645
1505
|
]);
|
|
646
1506
|
|
|
1507
|
+
// ../core/src/model/lineTypes.ts
|
|
1508
|
+
import { z as z4 } from "zod";
|
|
1509
|
+
|
|
647
1510
|
// ../core/src/model/builtinLin.ts
|
|
648
1511
|
var BUILTIN_LIN = `;; Linea built-in line type library.
|
|
649
1512
|
;;
|
|
@@ -799,7 +1662,7 @@ var CURATED = [
|
|
|
799
1662
|
dxfName: "DIVIDE"
|
|
800
1663
|
}
|
|
801
1664
|
];
|
|
802
|
-
var
|
|
1665
|
+
var normalizeName2 = (name) => name.trim().toUpperCase().replace(/[\s.-]+/g, "_");
|
|
803
1666
|
var asciiPreview = (dashesMm) => {
|
|
804
1667
|
const WIDTH = 15;
|
|
805
1668
|
if (!dashesMm.length) return "_".repeat(WIDTH * 0.8);
|
|
@@ -820,9 +1683,9 @@ var withPreview = (p) => {
|
|
|
820
1683
|
return { ...p, label: `${p.label} ${asciiPreview(p.dashesMm)}` };
|
|
821
1684
|
};
|
|
822
1685
|
var BUILT_IN = CURATED.map(withPreview);
|
|
823
|
-
var BY_NAME = new Map(BUILT_IN.map((p) => [
|
|
1686
|
+
var BY_NAME = new Map(BUILT_IN.map((p) => [normalizeName2(p.name), p]));
|
|
824
1687
|
for (const p of parseLinDefinitions(BUILTIN_LIN)) {
|
|
825
|
-
const key =
|
|
1688
|
+
const key = normalizeName2(p.name);
|
|
826
1689
|
if (BY_NAME.has(key)) continue;
|
|
827
1690
|
const pattern2 = withPreview({
|
|
828
1691
|
name: p.name,
|
|
@@ -840,15 +1703,40 @@ var scaleVariantBase = (name) => {
|
|
|
840
1703
|
};
|
|
841
1704
|
for (const p of BUILT_IN) {
|
|
842
1705
|
const base = scaleVariantBase(p.name);
|
|
843
|
-
const target = base ? BY_NAME.get(
|
|
1706
|
+
const target = base ? BY_NAME.get(normalizeName2(base)) : void 0;
|
|
844
1707
|
if (target && target !== p) p.hidden = true;
|
|
845
1708
|
}
|
|
846
1709
|
var LINE_TYPE_NAMES = BUILT_IN.filter((p) => !p.hidden).map(
|
|
847
1710
|
(p) => p.name
|
|
848
1711
|
);
|
|
849
1712
|
var LINE_TYPE_DEFS = BUILT_IN;
|
|
850
|
-
var getLineType = (name) => BY_NAME.get(
|
|
1713
|
+
var getLineType = (name) => BY_NAME.get(normalizeName2(name));
|
|
851
1714
|
var renderDashes = (pattern2) => pattern2.dashesMm.length ? pattern2.dashesMm.map((v) => v === 0 ? 0.1 : Math.abs(v)) : void 0;
|
|
1715
|
+
var LineTypeSchema = z4.object({
|
|
1716
|
+
/** Stored on objects/layers as `lineType`; case-insensitive, unique per
|
|
1717
|
+
* document. */
|
|
1718
|
+
name: z4.string().min(1),
|
|
1719
|
+
description: z4.string().optional(),
|
|
1720
|
+
/** Signed dash cycle, mm per 1 mm of line width: >0 dash, <0 gap, 0 dot.
|
|
1721
|
+
* Empty = continuous. */
|
|
1722
|
+
dashesMm: z4.array(z4.number())
|
|
1723
|
+
});
|
|
1724
|
+
var lineTypeKey = (name) => normalizeName2(name);
|
|
1725
|
+
var lineTypeAsPattern = (t) => ({
|
|
1726
|
+
name: t.name,
|
|
1727
|
+
label: t.description ?? t.name,
|
|
1728
|
+
dashesMm: t.dashesMm,
|
|
1729
|
+
dxfName: t.name.toUpperCase()
|
|
1730
|
+
});
|
|
1731
|
+
var resolveLineType = (name, lineTypes) => {
|
|
1732
|
+
if (!name) return void 0;
|
|
1733
|
+
if (lineTypes && lineTypes.length > 0) {
|
|
1734
|
+
const key = normalizeName2(name);
|
|
1735
|
+
const own = lineTypes.find((t) => normalizeName2(t.name) === key);
|
|
1736
|
+
if (own) return lineTypeAsPattern(own);
|
|
1737
|
+
}
|
|
1738
|
+
return getLineType(name);
|
|
1739
|
+
};
|
|
852
1740
|
|
|
853
1741
|
// ../core/src/geometry/vec2.ts
|
|
854
1742
|
var add = (a, b) => ({ x: a.x + b.x, y: a.y + b.y });
|
|
@@ -939,105 +1827,105 @@ var readListParam = (type, value) => {
|
|
|
939
1827
|
};
|
|
940
1828
|
|
|
941
1829
|
// ../core/src/model/blockDefinition.ts
|
|
942
|
-
import { z as
|
|
1830
|
+
import { z as z5 } from "zod";
|
|
943
1831
|
var paramBase = {
|
|
944
|
-
name:
|
|
945
|
-
label:
|
|
1832
|
+
name: z5.string().regex(/^[a-zA-Z_]\w*$/),
|
|
1833
|
+
label: z5.string().optional(),
|
|
946
1834
|
/** What the parameter means: the label's tooltip in the panel. */
|
|
947
|
-
hint:
|
|
1835
|
+
hint: z5.string().optional()
|
|
948
1836
|
};
|
|
949
1837
|
var HEX_COLOR = /^#[0-9a-f]{6}$/i;
|
|
950
|
-
var EnumOptionSchema =
|
|
1838
|
+
var EnumOptionSchema = z5.preprocess(
|
|
951
1839
|
(raw) => typeof raw === "string" ? { value: raw } : raw,
|
|
952
|
-
|
|
953
|
-
value:
|
|
954
|
-
label:
|
|
1840
|
+
z5.object({
|
|
1841
|
+
value: z5.string(),
|
|
1842
|
+
label: z5.string().optional(),
|
|
955
1843
|
/** A `#rrggbb` color square before the option's label. */
|
|
956
|
-
swatch:
|
|
1844
|
+
swatch: z5.string().regex(HEX_COLOR).optional()
|
|
957
1845
|
})
|
|
958
1846
|
);
|
|
959
|
-
var NumberParam =
|
|
1847
|
+
var NumberParam = z5.object({
|
|
960
1848
|
...paramBase,
|
|
961
|
-
type:
|
|
962
|
-
default:
|
|
963
|
-
min:
|
|
964
|
-
max:
|
|
1849
|
+
type: z5.literal("number"),
|
|
1850
|
+
default: z5.number(),
|
|
1851
|
+
min: z5.number().optional(),
|
|
1852
|
+
max: z5.number().optional(),
|
|
965
1853
|
/** Whole numbers only. */
|
|
966
|
-
integer:
|
|
1854
|
+
integer: z5.boolean().optional(),
|
|
967
1855
|
/** ArrowUp / ArrowDown increment in the panel (default 1). */
|
|
968
|
-
step:
|
|
1856
|
+
step: z5.number().positive().optional(),
|
|
969
1857
|
/** Shown inside the field before / after the value ("1:", "mm"). */
|
|
970
|
-
prefix:
|
|
971
|
-
suffix:
|
|
1858
|
+
prefix: z5.string().optional(),
|
|
1859
|
+
suffix: z5.string().optional(),
|
|
972
1860
|
/** Standard values offered in the field's dropdown; typing stays free. */
|
|
973
|
-
presets:
|
|
1861
|
+
presets: z5.array(z5.number()).optional()
|
|
974
1862
|
});
|
|
975
|
-
var StringParam =
|
|
1863
|
+
var StringParam = z5.object({
|
|
976
1864
|
...paramBase,
|
|
977
|
-
type:
|
|
978
|
-
default:
|
|
979
|
-
placeholder:
|
|
1865
|
+
type: z5.literal("string"),
|
|
1866
|
+
default: z5.string(),
|
|
1867
|
+
placeholder: z5.string().optional(),
|
|
980
1868
|
/** A textarea; Shift+Enter starts a new line. */
|
|
981
|
-
multiline:
|
|
982
|
-
presets:
|
|
1869
|
+
multiline: z5.boolean().optional(),
|
|
1870
|
+
presets: z5.array(z5.string()).optional()
|
|
983
1871
|
});
|
|
984
|
-
var BooleanParam =
|
|
1872
|
+
var BooleanParam = z5.object({
|
|
985
1873
|
...paramBase,
|
|
986
|
-
type:
|
|
987
|
-
default:
|
|
1874
|
+
type: z5.literal("boolean"),
|
|
1875
|
+
default: z5.boolean(),
|
|
988
1876
|
/** "toggle": a toggle button showing the label (compact, e.g. in a row
|
|
989
1877
|
* beside a picker) instead of a switch. */
|
|
990
|
-
display:
|
|
1878
|
+
display: z5.enum(["switch", "toggle"]).optional()
|
|
991
1879
|
});
|
|
992
|
-
var NumberListParam =
|
|
1880
|
+
var NumberListParam = z5.object({
|
|
993
1881
|
...paramBase,
|
|
994
|
-
type:
|
|
995
|
-
default:
|
|
1882
|
+
type: z5.literal("numberList"),
|
|
1883
|
+
default: z5.array(z5.number()),
|
|
996
1884
|
/** Shown while the list is empty. */
|
|
997
|
-
placeholder:
|
|
998
|
-
min:
|
|
999
|
-
max:
|
|
1000
|
-
presets:
|
|
1885
|
+
placeholder: z5.string().optional(),
|
|
1886
|
+
min: z5.number().optional(),
|
|
1887
|
+
max: z5.number().optional(),
|
|
1888
|
+
presets: z5.array(z5.array(z5.number())).optional()
|
|
1001
1889
|
});
|
|
1002
|
-
var StringListParam =
|
|
1890
|
+
var StringListParam = z5.object({
|
|
1003
1891
|
...paramBase,
|
|
1004
|
-
type:
|
|
1005
|
-
default:
|
|
1892
|
+
type: z5.literal("stringList"),
|
|
1893
|
+
default: z5.array(z5.string()),
|
|
1006
1894
|
/** Shown while the list is empty. */
|
|
1007
|
-
placeholder:
|
|
1008
|
-
presets:
|
|
1895
|
+
placeholder: z5.string().optional(),
|
|
1896
|
+
presets: z5.array(z5.array(z5.string())).optional()
|
|
1009
1897
|
});
|
|
1010
|
-
var ColorParam =
|
|
1898
|
+
var ColorParam = z5.object({
|
|
1011
1899
|
...paramBase,
|
|
1012
|
-
type:
|
|
1013
|
-
default:
|
|
1014
|
-
presets:
|
|
1900
|
+
type: z5.literal("color"),
|
|
1901
|
+
default: z5.string().regex(HEX_COLOR),
|
|
1902
|
+
presets: z5.array(z5.string().regex(HEX_COLOR)).optional()
|
|
1015
1903
|
});
|
|
1016
|
-
var EnumParam =
|
|
1904
|
+
var EnumParam = z5.object({
|
|
1017
1905
|
...paramBase,
|
|
1018
|
-
type:
|
|
1019
|
-
default:
|
|
1020
|
-
options:
|
|
1906
|
+
type: z5.literal("enum"),
|
|
1907
|
+
default: z5.string(),
|
|
1908
|
+
options: z5.array(EnumOptionSchema).min(1),
|
|
1021
1909
|
/** "buttons": a segmented toggle group of the options (short choices);
|
|
1022
1910
|
* the panel falls back to the dropdown when they don't fit. */
|
|
1023
|
-
display:
|
|
1911
|
+
display: z5.enum(["dropdown", "buttons"]).optional()
|
|
1024
1912
|
});
|
|
1025
|
-
var resourceParam = (type, fallback) =>
|
|
1913
|
+
var resourceParam = (type, fallback) => z5.object({
|
|
1026
1914
|
...paramBase,
|
|
1027
|
-
type:
|
|
1028
|
-
default:
|
|
1915
|
+
type: z5.literal(type),
|
|
1916
|
+
default: z5.string().default(fallback)
|
|
1029
1917
|
});
|
|
1030
1918
|
var TextStyleParam = resourceParam("textStyle", "");
|
|
1031
1919
|
var DimStyleParam = resourceParam("dimStyle", "");
|
|
1032
1920
|
var FontParam = resourceParam("font", "arial");
|
|
1033
1921
|
var LineTypeParam = resourceParam("lineType", "continuous");
|
|
1034
1922
|
var HatchPatternParam = resourceParam("hatchPattern", "ANSI31");
|
|
1035
|
-
var LabelParam =
|
|
1923
|
+
var LabelParam = z5.object({ ...paramBase, type: z5.literal("label") });
|
|
1036
1924
|
var enumDefaultIsAnOption = (p) => p.type !== "enum" || p.options.some(
|
|
1037
1925
|
(o) => o.value === p.default
|
|
1038
1926
|
);
|
|
1039
1927
|
var ENUM_DEFAULT = { message: "enum default must be one of its options" };
|
|
1040
|
-
var RowItemSchema =
|
|
1928
|
+
var RowItemSchema = z5.discriminatedUnion("type", [
|
|
1041
1929
|
NumberParam,
|
|
1042
1930
|
StringParam,
|
|
1043
1931
|
BooleanParam,
|
|
@@ -1049,12 +1937,12 @@ var RowItemSchema = z3.discriminatedUnion("type", [
|
|
|
1049
1937
|
LineTypeParam,
|
|
1050
1938
|
HatchPatternParam
|
|
1051
1939
|
]).refine(enumDefaultIsAnOption, ENUM_DEFAULT);
|
|
1052
|
-
var RowParam =
|
|
1940
|
+
var RowParam = z5.object({
|
|
1053
1941
|
...paramBase,
|
|
1054
|
-
type:
|
|
1055
|
-
items:
|
|
1942
|
+
type: z5.literal("row"),
|
|
1943
|
+
items: z5.array(RowItemSchema).min(2).max(3)
|
|
1056
1944
|
});
|
|
1057
|
-
var
|
|
1945
|
+
var ParamDefSchema = z5.discriminatedUnion("type", [
|
|
1058
1946
|
NumberParam,
|
|
1059
1947
|
StringParam,
|
|
1060
1948
|
BooleanParam,
|
|
@@ -1075,7 +1963,7 @@ var valueParams = (defs) => defs.flatMap(
|
|
|
1075
1963
|
);
|
|
1076
1964
|
|
|
1077
1965
|
// ../core/src/extensions/evalBlock.ts
|
|
1078
|
-
import { z as
|
|
1966
|
+
import { z as z7 } from "zod";
|
|
1079
1967
|
|
|
1080
1968
|
// ../core/src/geometry/line.ts
|
|
1081
1969
|
var projectParam = (p, a, b) => {
|
|
@@ -1108,16 +1996,6 @@ var remapBlockInputRefs = (obj, idMap) => {
|
|
|
1108
1996
|
};
|
|
1109
1997
|
var mapInputPoints = (obj, fn) => obj.inputs.map((value) => typeof value === "string" ? value : fn(value));
|
|
1110
1998
|
var pointsCarryPose = (obj) => obj.inputs.some((v) => typeof v === "string") || obj.inputs.filter((v) => typeof v !== "string").length >= 2;
|
|
1111
|
-
var imageCenter = (obj) => add(obj.origin, rot({ x: obj.width / 2, y: obj.height / 2 }, obj.rotation));
|
|
1112
|
-
var imageCorners = (obj) => {
|
|
1113
|
-
const c = (x, y) => add(obj.origin, rot({ x, y }, obj.rotation));
|
|
1114
|
-
return [
|
|
1115
|
-
obj.origin,
|
|
1116
|
-
c(obj.width, 0),
|
|
1117
|
-
c(obj.width, obj.height),
|
|
1118
|
-
c(0, obj.height)
|
|
1119
|
-
];
|
|
1120
|
-
};
|
|
1121
1999
|
var mapObjectPoints = (obj, fn) => {
|
|
1122
2000
|
switch (obj.type) {
|
|
1123
2001
|
case "line":
|
|
@@ -1133,6 +2011,10 @@ var mapObjectPoints = (obj, fn) => {
|
|
|
1133
2011
|
case "hatch":
|
|
1134
2012
|
return {
|
|
1135
2013
|
...obj,
|
|
2014
|
+
// The pattern frame moves with its region, as in AutoCAD — an
|
|
2015
|
+
// unanchored fill's frame is the drawing origin, which moves along
|
|
2016
|
+
// too (else the pattern would swim inside a moved hatch).
|
|
2017
|
+
fill: obj.fill.kind === "pattern" ? { ...obj.fill, origin: fn(obj.fill.origin ?? { x: 0, y: 0 }) } : obj.fill,
|
|
1136
2018
|
loops: obj.loops.map((loop) => ({
|
|
1137
2019
|
points: loop.points.map((v) => ({ ...v, ...fn(v) }))
|
|
1138
2020
|
}))
|
|
@@ -1149,8 +2031,6 @@ var mapObjectPoints = (obj, fn) => {
|
|
|
1149
2031
|
return { ...obj, inputs: mapInputPoints(obj, fn) };
|
|
1150
2032
|
case "viewport":
|
|
1151
2033
|
return obj;
|
|
1152
|
-
case "image":
|
|
1153
|
-
return { ...obj, origin: fn(obj.origin) };
|
|
1154
2034
|
case "comment":
|
|
1155
2035
|
return { ...obj, position: fn(obj.position) };
|
|
1156
2036
|
case "table":
|
|
@@ -1178,6 +2058,7 @@ var moveViewportCenter = (obj, map) => {
|
|
|
1178
2058
|
const nc = map(c);
|
|
1179
2059
|
return translateObject(obj, sub(nc, c));
|
|
1180
2060
|
};
|
|
2061
|
+
var turnFill = (fill, f) => fill.kind === "pattern" || fill.kind === "lines" ? { ...fill, angle: f(fill.angle) } : fill;
|
|
1181
2062
|
var rotateObject = (obj, center, ang) => {
|
|
1182
2063
|
const r = (p) => rotAround(p, center, ang);
|
|
1183
2064
|
const mapped = mapObjectPoints(obj, r);
|
|
@@ -1194,19 +2075,19 @@ var rotateObject = (obj, center, ang) => {
|
|
|
1194
2075
|
case "table":
|
|
1195
2076
|
return { ...mapped, rotation: mapped.rotation + ang };
|
|
1196
2077
|
case "dimension":
|
|
1197
|
-
return { ...mapped,
|
|
2078
|
+
return mapped.rotation === void 0 ? mapped : { ...mapped, rotation: mapped.rotation + ang };
|
|
1198
2079
|
case "block":
|
|
1199
2080
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, rotation: mapped.rotation + ang };
|
|
1200
2081
|
case "viewport":
|
|
1201
2082
|
return moveViewportCenter(mapped, r);
|
|
1202
|
-
case "image":
|
|
1203
2083
|
case "reference":
|
|
1204
2084
|
return { ...mapped, rotation: normAngle(mapped.rotation + ang) };
|
|
2085
|
+
case "hatch":
|
|
2086
|
+
return { ...mapped, fill: turnFill(mapped.fill, (a) => a + ang) };
|
|
1205
2087
|
case "line":
|
|
1206
2088
|
case "point":
|
|
1207
2089
|
case "polyline":
|
|
1208
2090
|
case "circle":
|
|
1209
|
-
case "hatch":
|
|
1210
2091
|
case "comment":
|
|
1211
2092
|
return mapped;
|
|
1212
2093
|
default:
|
|
@@ -1231,7 +2112,16 @@ var scaleObjectUniform = (obj, s) => {
|
|
|
1231
2112
|
case "table":
|
|
1232
2113
|
return { ...mapped, scale: mapped.scale * s };
|
|
1233
2114
|
case "dimension":
|
|
1234
|
-
return {
|
|
2115
|
+
return {
|
|
2116
|
+
...mapped,
|
|
2117
|
+
...mapped.offset === void 0 ? {} : { offset: mapped.offset * s },
|
|
2118
|
+
labels: mapped.labels.map((l) => ({
|
|
2119
|
+
...l,
|
|
2120
|
+
...l.along === void 0 ? {} : { along: l.along * s },
|
|
2121
|
+
...l.across === void 0 ? {} : { across: l.across * s }
|
|
2122
|
+
})),
|
|
2123
|
+
scale: mapped.scale * s
|
|
2124
|
+
};
|
|
1235
2125
|
case "block":
|
|
1236
2126
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, scale: mapped.scale * s };
|
|
1237
2127
|
case "viewport":
|
|
@@ -1247,8 +2137,6 @@ var scaleObjectUniform = (obj, s) => {
|
|
|
1247
2137
|
// mm per paper mm) shrinks as the frame grows.
|
|
1248
2138
|
scale: mapped.scale / s
|
|
1249
2139
|
};
|
|
1250
|
-
case "image":
|
|
1251
|
-
return { ...mapped, width: mapped.width * s, height: mapped.height * s };
|
|
1252
2140
|
case "reference":
|
|
1253
2141
|
return { ...mapped, scale: mapped.scale * s };
|
|
1254
2142
|
case "point":
|
|
@@ -1284,12 +2172,6 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1284
2172
|
mirrored: !obj.mirrored
|
|
1285
2173
|
};
|
|
1286
2174
|
}
|
|
1287
|
-
if (obj.type === "image") {
|
|
1288
|
-
const c = imageCenter(obj);
|
|
1289
|
-
const rotation = mirrorAngle(obj.rotation);
|
|
1290
|
-
const moved = { ...obj, rotation };
|
|
1291
|
-
return translateObject(moved, sub(m(c), imageCenter(moved)));
|
|
1292
|
-
}
|
|
1293
2175
|
if (obj.type === "table") {
|
|
1294
2176
|
const width = obj.columns.reduce((a2, w) => a2 + w, 0) * obj.scale;
|
|
1295
2177
|
const topRight = add(obj.position, scale(fromAngle(obj.rotation), width));
|
|
@@ -1317,6 +2199,7 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1317
2199
|
case "hatch":
|
|
1318
2200
|
return {
|
|
1319
2201
|
...mapped,
|
|
2202
|
+
fill: turnFill(mapped.fill, mirrorAngle),
|
|
1320
2203
|
loops: mapped.loops.map((loop) => ({
|
|
1321
2204
|
points: loop.points.map((v) => ({ ...v, bulge: -v.bulge }))
|
|
1322
2205
|
}))
|
|
@@ -1331,8 +2214,17 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1331
2214
|
hAlign: readable ? mapped.hAlign : swap[mapped.hAlign]
|
|
1332
2215
|
};
|
|
1333
2216
|
}
|
|
1334
|
-
case "dimension":
|
|
1335
|
-
|
|
2217
|
+
case "dimension": {
|
|
2218
|
+
const handed = mapped.kind === "radial" || mapped.kind === "diameter";
|
|
2219
|
+
return {
|
|
2220
|
+
...mapped,
|
|
2221
|
+
...mapped.rotation === void 0 ? {} : { rotation: mirrorAngle(mapped.rotation) },
|
|
2222
|
+
...mapped.offset === void 0 ? {} : { offset: -mapped.offset },
|
|
2223
|
+
labels: handed ? mapped.labels.map(
|
|
2224
|
+
(l) => l.across === void 0 ? l : { ...l, across: -l.across }
|
|
2225
|
+
) : mapped.labels
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
1336
2228
|
case "block":
|
|
1337
2229
|
return pointsCarryPose(mapped) ? mapped : { ...mapped, rotation: mirrorAngle(mapped.rotation) };
|
|
1338
2230
|
case "viewport":
|
|
@@ -1345,7 +2237,6 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1345
2237
|
// Mirrored above, before the point map.
|
|
1346
2238
|
case "ellipse":
|
|
1347
2239
|
case "reference":
|
|
1348
|
-
case "image":
|
|
1349
2240
|
case "table":
|
|
1350
2241
|
return mapped;
|
|
1351
2242
|
default:
|
|
@@ -1354,7 +2245,7 @@ var mirrorObject = (obj, a, b) => {
|
|
|
1354
2245
|
};
|
|
1355
2246
|
|
|
1356
2247
|
// ../core/src/extensions/blockDtos.ts
|
|
1357
|
-
import { z as
|
|
2248
|
+
import { z as z6 } from "zod";
|
|
1358
2249
|
|
|
1359
2250
|
// ../core/src/extensions/jsLiteral.ts
|
|
1360
2251
|
var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
@@ -1385,8 +2276,51 @@ ${indent}}`;
|
|
|
1385
2276
|
return "undefined";
|
|
1386
2277
|
};
|
|
1387
2278
|
|
|
2279
|
+
// ../core/src/model/assets.ts
|
|
2280
|
+
var hashAsset = (data) => {
|
|
2281
|
+
let h = 5381;
|
|
2282
|
+
for (let i = 0; i < data.length; i++)
|
|
2283
|
+
h = (h << 5) + h + data.charCodeAt(i) | 0;
|
|
2284
|
+
return `${(h >>> 0).toString(16)}-${data.length.toString(16)}`;
|
|
2285
|
+
};
|
|
2286
|
+
var dataUrlMime = (dataUrl) => /^data:([^;,]*)/.exec(dataUrl)?.[1] ?? "";
|
|
2287
|
+
var dataUrlBytes = (dataUrl) => {
|
|
2288
|
+
const comma = dataUrl.indexOf(",");
|
|
2289
|
+
const payload = dataUrl.slice(comma + 1);
|
|
2290
|
+
if (!/;base64$/.test(dataUrl.slice(0, comma)))
|
|
2291
|
+
return new TextEncoder().encode(decodeURIComponent(payload));
|
|
2292
|
+
const bin = atob(payload);
|
|
2293
|
+
const out = new Uint8Array(bin.length);
|
|
2294
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
2295
|
+
return out;
|
|
2296
|
+
};
|
|
2297
|
+
var bytesToDataUrl = (bytes, mime) => {
|
|
2298
|
+
let bin = "";
|
|
2299
|
+
for (let i = 0; i < bytes.length; i += 32768)
|
|
2300
|
+
bin += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
2301
|
+
return `data:${mime};base64,${btoa(bin)}`;
|
|
2302
|
+
};
|
|
2303
|
+
var imagePixelSize = (b) => {
|
|
2304
|
+
const u32 = (i) => (b[i] << 24 | b[i + 1] << 16 | b[i + 2] << 8 | b[i + 3]) >>> 0;
|
|
2305
|
+
const u16 = (i) => b[i] << 8 | b[i + 1];
|
|
2306
|
+
if (b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71)
|
|
2307
|
+
return { width: u32(16), height: u32(20) };
|
|
2308
|
+
if (b[0] !== 255 || b[1] !== 216) return null;
|
|
2309
|
+
for (let i = 2; i + 9 < b.length; ) {
|
|
2310
|
+
if (b[i] !== 255) return null;
|
|
2311
|
+
const marker = b[i + 1];
|
|
2312
|
+
const len3 = u16(i + 2);
|
|
2313
|
+
if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204)
|
|
2314
|
+
return { width: u16(i + 7), height: u16(i + 5) };
|
|
2315
|
+
i += 2 + len3;
|
|
2316
|
+
}
|
|
2317
|
+
return null;
|
|
2318
|
+
};
|
|
2319
|
+
var PX_TO_MM = 25.4 / 96;
|
|
2320
|
+
var embeddedAssetId = (o) => o.type === "reference" && o.source?.kind === "asset" ? o.source.assetId : void 0;
|
|
2321
|
+
|
|
1388
2322
|
// ../core/src/model/migrations.ts
|
|
1389
|
-
var CURRENT_DOCUMENT_VERSION =
|
|
2323
|
+
var CURRENT_DOCUMENT_VERSION = 23;
|
|
1390
2324
|
var leaderRawToText = (raw) => {
|
|
1391
2325
|
const points = Array.isArray(raw.points) ? raw.points : [];
|
|
1392
2326
|
const extraLines = Array.isArray(raw.extraLines) ? raw.extraLines : [];
|
|
@@ -1888,6 +2822,134 @@ var migrateV18toV19 = (doc) => {
|
|
|
1888
2822
|
};
|
|
1889
2823
|
};
|
|
1890
2824
|
var migrateV19toV20 = (doc) => ({ ...swapTextAlignments(doc), version: 20 });
|
|
2825
|
+
var dimensionPointCount = (kind) => kind === "angular" ? 3 : 2;
|
|
2826
|
+
var wrapAngle = (a) => {
|
|
2827
|
+
const twoPi = 2 * Math.PI;
|
|
2828
|
+
const r = a % twoPi;
|
|
2829
|
+
return r < 0 ? r + twoPi : r;
|
|
2830
|
+
};
|
|
2831
|
+
var dimensionRawToLabels = (raw) => {
|
|
2832
|
+
if (raw.type !== "dimension") return raw;
|
|
2833
|
+
const legacyOffset = Array.isArray(raw.offset) ? { x: Number(raw.offset[0]), y: Number(raw.offset[1]) } : raw.offset !== null && typeof raw.offset === "object" ? raw.offset : null;
|
|
2834
|
+
if (legacyOffset === null && !("textOverride" in raw)) return raw;
|
|
2835
|
+
const kind = typeof raw.kind === "string" ? raw.kind : "linear";
|
|
2836
|
+
const points = Array.isArray(raw.points) ? raw.points : [];
|
|
2837
|
+
const tooFew = points.length < dimensionPointCount(kind);
|
|
2838
|
+
const out = { ...raw };
|
|
2839
|
+
delete out.textOverride;
|
|
2840
|
+
const labels = Array.isArray(raw.labels) ? raw.labels.map((l) => ({ ...l })) : [];
|
|
2841
|
+
const label = (i) => labels[i] ??= {};
|
|
2842
|
+
if (legacyOffset) {
|
|
2843
|
+
const v = legacyOffset;
|
|
2844
|
+
const vLen = Math.hypot(v.x, v.y);
|
|
2845
|
+
if (kind === "linear") {
|
|
2846
|
+
delete out.rotation;
|
|
2847
|
+
if (vLen < 1e-9 || tooFew) out.offset = 0;
|
|
2848
|
+
else {
|
|
2849
|
+
let ux = -v.y / vLen;
|
|
2850
|
+
let uy = v.x / vLen;
|
|
2851
|
+
if (ux < 0 || ux === 0 && uy < 0) {
|
|
2852
|
+
ux = -ux;
|
|
2853
|
+
uy = -uy;
|
|
2854
|
+
}
|
|
2855
|
+
out.rotation = Math.atan2(uy, ux);
|
|
2856
|
+
out.offset = v.x * -uy + v.y * ux;
|
|
2857
|
+
}
|
|
2858
|
+
} else if (kind === "angular") {
|
|
2859
|
+
if (tooFew) out.offset = vLen;
|
|
2860
|
+
else {
|
|
2861
|
+
const [vertex, a, b] = points;
|
|
2862
|
+
const angA = Math.atan2(a.y - vertex.y, a.x - vertex.x);
|
|
2863
|
+
const angB = Math.atan2(b.y - vertex.y, b.x - vertex.x);
|
|
2864
|
+
const angL = Math.atan2(v.y, v.x);
|
|
2865
|
+
const inAB = wrapAngle(angL - angA) <= wrapAngle(angB - angA);
|
|
2866
|
+
out.offset = inAB ? vLen : -vLen;
|
|
2867
|
+
}
|
|
2868
|
+
} else {
|
|
2869
|
+
delete out.offset;
|
|
2870
|
+
const [p0, p1] = points;
|
|
2871
|
+
const d = tooFew ? 0 : Math.hypot(p1.x - p0.x, p1.y - p0.y);
|
|
2872
|
+
if (d > 1e-9) {
|
|
2873
|
+
const ux = (p1.x - p0.x) / d;
|
|
2874
|
+
const uy = (p1.y - p0.y) / d;
|
|
2875
|
+
label(0).along = v.x * ux + v.y * uy;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
if (typeof raw.textOverride === "string") {
|
|
2880
|
+
const template = {
|
|
2881
|
+
linear: "{value}",
|
|
2882
|
+
angular: "{value}\xB0",
|
|
2883
|
+
radial: "R{value}",
|
|
2884
|
+
diameter: "\xD8{value}"
|
|
2885
|
+
};
|
|
2886
|
+
const content = raw.textOverride.replaceAll(
|
|
2887
|
+
"<>",
|
|
2888
|
+
template[kind] ?? "{value}"
|
|
2889
|
+
);
|
|
2890
|
+
const segments = kind === "linear" ? Math.max(1, points.length - 1) : 1;
|
|
2891
|
+
for (let i = 0; i < segments; i++) label(i).content = content;
|
|
2892
|
+
}
|
|
2893
|
+
if (labels.length > 0) out.labels = labels;
|
|
2894
|
+
return out;
|
|
2895
|
+
};
|
|
2896
|
+
var migrateV20toV21 = (doc) => {
|
|
2897
|
+
const degenerate = (raw) => raw.type === "dimension" && (Array.isArray(raw.points) ? raw.points.length : 0) < dimensionPointCount(typeof raw.kind === "string" ? raw.kind : "linear");
|
|
2898
|
+
const mapObjects = (list) => Array.isArray(list) ? list.filter(
|
|
2899
|
+
(raw) => raw === null || typeof raw !== "object" || !degenerate(raw)
|
|
2900
|
+
).map(
|
|
2901
|
+
(raw) => raw !== null && typeof raw === "object" ? dimensionRawToLabels(raw) : raw
|
|
2902
|
+
) : list;
|
|
2903
|
+
const layouts = Array.isArray(doc.layouts) ? doc.layouts.map((raw) => {
|
|
2904
|
+
if (raw === null || typeof raw !== "object") return raw;
|
|
2905
|
+
const layout = raw;
|
|
2906
|
+
return { ...layout, objects: mapObjects(layout.objects) };
|
|
2907
|
+
}) : doc.layouts;
|
|
2908
|
+
return { ...doc, objects: mapObjects(doc.objects), layouts, version: 21 };
|
|
2909
|
+
};
|
|
2910
|
+
var migrateV21toV22 = (doc) => ({ ...doc, version: 22 });
|
|
2911
|
+
var imageRawToReference = (raw, assets) => {
|
|
2912
|
+
const rest = { ...raw };
|
|
2913
|
+
delete rest.assetId;
|
|
2914
|
+
delete rest.origin;
|
|
2915
|
+
delete rest.width;
|
|
2916
|
+
delete rest.height;
|
|
2917
|
+
const assetId = typeof raw.assetId === "string" ? raw.assetId : "";
|
|
2918
|
+
const data = assets[assetId];
|
|
2919
|
+
const width = typeof raw.width === "number" && raw.width > 0 ? raw.width : 1;
|
|
2920
|
+
const height = typeof raw.height === "number" && raw.height > 0 ? raw.height : 1;
|
|
2921
|
+
let px;
|
|
2922
|
+
try {
|
|
2923
|
+
px = typeof data === "string" ? imagePixelSize(dataUrlBytes(data)) : null;
|
|
2924
|
+
} catch {
|
|
2925
|
+
px = null;
|
|
2926
|
+
}
|
|
2927
|
+
const w = px ? px.width * PX_TO_MM : width;
|
|
2928
|
+
const h = px ? px.height * PX_TO_MM : height;
|
|
2929
|
+
return {
|
|
2930
|
+
...rest,
|
|
2931
|
+
type: "reference",
|
|
2932
|
+
format: typeof data === "string" && dataUrlMime(data) === "image/jpeg" ? "jpg" : "png",
|
|
2933
|
+
name: "Image",
|
|
2934
|
+
source: { kind: "asset", assetId: assetId || "missing" },
|
|
2935
|
+
position: raw.origin ?? { x: 0, y: 0 },
|
|
2936
|
+
rotation: typeof raw.rotation === "number" ? raw.rotation : 0,
|
|
2937
|
+
scale: width / w,
|
|
2938
|
+
extent: { minX: 0, minY: 0, maxX: w, maxY: h }
|
|
2939
|
+
};
|
|
2940
|
+
};
|
|
2941
|
+
var migrateV22toV23 = (doc) => {
|
|
2942
|
+
const assets = doc.assets !== null && typeof doc.assets === "object" ? doc.assets : {};
|
|
2943
|
+
const mapObjects = (list) => Array.isArray(list) ? list.map(
|
|
2944
|
+
(raw) => raw !== null && typeof raw === "object" && raw.type === "image" ? imageRawToReference(raw, assets) : raw
|
|
2945
|
+
) : list;
|
|
2946
|
+
const layouts = Array.isArray(doc.layouts) ? doc.layouts.map((raw) => {
|
|
2947
|
+
if (raw === null || typeof raw !== "object") return raw;
|
|
2948
|
+
const layout = raw;
|
|
2949
|
+
return { ...layout, objects: mapObjects(layout.objects) };
|
|
2950
|
+
}) : doc.layouts;
|
|
2951
|
+
return { ...doc, objects: mapObjects(doc.objects), layouts, version: 23 };
|
|
2952
|
+
};
|
|
1891
2953
|
var MIGRATION_STEPS = [
|
|
1892
2954
|
migrateV1toV2,
|
|
1893
2955
|
migrateV2toV3,
|
|
@@ -1907,7 +2969,10 @@ var MIGRATION_STEPS = [
|
|
|
1907
2969
|
migrateV16toV17,
|
|
1908
2970
|
migrateV17toV18,
|
|
1909
2971
|
migrateV18toV19,
|
|
1910
|
-
migrateV19toV20
|
|
2972
|
+
migrateV19toV20,
|
|
2973
|
+
migrateV20toV21,
|
|
2974
|
+
migrateV21toV22,
|
|
2975
|
+
migrateV22toV23
|
|
1911
2976
|
];
|
|
1912
2977
|
function migrateDocument(raw) {
|
|
1913
2978
|
if (raw === null || typeof raw !== "object") return raw;
|
|
@@ -1926,7 +2991,11 @@ function migrateDocument(raw) {
|
|
|
1926
2991
|
|
|
1927
2992
|
// ../core/src/extensions/blockDtos.ts
|
|
1928
2993
|
var CHILD_OMIT = { id: true, layerId: true };
|
|
1929
|
-
var
|
|
2994
|
+
var CHILD_LAYER = {
|
|
2995
|
+
layerId: z6.string().optional(),
|
|
2996
|
+
layer: z6.string().optional()
|
|
2997
|
+
};
|
|
2998
|
+
var BlockChildSchema = z6.preprocess(
|
|
1930
2999
|
// Back-compat: scripts written before document v6 may still emit "leader"
|
|
1931
3000
|
// children (→ text with leaderLines), pre-v9 scripts may emit dimensions
|
|
1932
3001
|
// in the linePoint/rotation shape (→ offset), pre-v17 scripts may put
|
|
@@ -1939,27 +3008,30 @@ var BlockChildSchema = z4.preprocess(
|
|
|
1939
3008
|
let obj = raw;
|
|
1940
3009
|
if (obj.type === "leader") obj = leaderRawToText(obj);
|
|
1941
3010
|
if (obj.type === "dimension")
|
|
1942
|
-
return
|
|
3011
|
+
return dimensionRawToLabels(
|
|
3012
|
+
dimRawScaleToField(dimensionRawToOffset(obj))
|
|
3013
|
+
);
|
|
1943
3014
|
if (obj.type === "text") return textRawStyleToOverride(obj);
|
|
1944
3015
|
return obj;
|
|
1945
3016
|
},
|
|
1946
|
-
|
|
1947
|
-
LineSchema.omit(CHILD_OMIT),
|
|
1948
|
-
PointSchema.omit(CHILD_OMIT),
|
|
1949
|
-
PolylineSchema.omit(CHILD_OMIT),
|
|
1950
|
-
CircleSchema.omit(CHILD_OMIT),
|
|
1951
|
-
ArcSchema.omit(CHILD_OMIT),
|
|
1952
|
-
EllipseSchema.omit(CHILD_OMIT),
|
|
1953
|
-
HatchSchema.omit(CHILD_OMIT),
|
|
1954
|
-
TextSchema.omit(CHILD_OMIT),
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
3017
|
+
z6.discriminatedUnion("type", [
|
|
3018
|
+
LineSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3019
|
+
PointSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3020
|
+
PolylineSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3021
|
+
CircleSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3022
|
+
ArcSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3023
|
+
EllipseSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3024
|
+
HatchSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3025
|
+
TextSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3026
|
+
TableShapeSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).superRefine(tableRefinement),
|
|
3027
|
+
DimensionShapeSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).superRefine(dimensionRefinement),
|
|
3028
|
+
ReferenceSchema.omit(CHILD_OMIT).extend(CHILD_LAYER),
|
|
3029
|
+
BlockSchema.omit(CHILD_OMIT).extend(CHILD_LAYER).refine((b) => b.inputs.every((v) => typeof v !== "string"), {
|
|
3030
|
+
message: "nested block instances may not carry object references"
|
|
3031
|
+
})
|
|
1960
3032
|
])
|
|
1961
3033
|
);
|
|
1962
|
-
var BlockScriptResultSchema =
|
|
3034
|
+
var BlockScriptResultSchema = z6.array(BlockChildSchema);
|
|
1963
3035
|
|
|
1964
3036
|
// ../core/src/extensions/scriptHelpers.ts
|
|
1965
3037
|
var scriptHelpers_exports = {};
|
|
@@ -1967,7 +3039,6 @@ __export(scriptHelpers_exports, {
|
|
|
1967
3039
|
add: () => add2,
|
|
1968
3040
|
dist: () => dist2,
|
|
1969
3041
|
dot: () => dot2,
|
|
1970
|
-
helpers: () => helpers,
|
|
1971
3042
|
len: () => len2,
|
|
1972
3043
|
norm: () => norm2,
|
|
1973
3044
|
polar: () => polar,
|
|
@@ -2011,22 +3082,9 @@ var rotate = (p, angle2) => {
|
|
|
2011
3082
|
const sin = Math.sin(angle2);
|
|
2012
3083
|
return { x: p.x * cos - p.y * sin, y: p.x * sin + p.y * cos };
|
|
2013
3084
|
};
|
|
2014
|
-
var helpers = Object.freeze({
|
|
2015
|
-
range,
|
|
2016
|
-
polar,
|
|
2017
|
-
toDeg,
|
|
2018
|
-
toRad,
|
|
2019
|
-
len: len2,
|
|
2020
|
-
dist: dist2,
|
|
2021
|
-
add: add2,
|
|
2022
|
-
sub: sub2,
|
|
2023
|
-
scale: scale2,
|
|
2024
|
-
norm: norm2,
|
|
2025
|
-
dot: dot2,
|
|
2026
|
-
rotate
|
|
2027
|
-
});
|
|
2028
3085
|
|
|
2029
3086
|
// ../core/src/extensions/scriptRuntime.ts
|
|
3087
|
+
var helpers = Object.freeze({ ...scriptHelpers_exports });
|
|
2030
3088
|
var onTranspilerReady = null;
|
|
2031
3089
|
var transpiler = null;
|
|
2032
3090
|
var transpilerLoading = null;
|
|
@@ -2146,13 +3204,13 @@ var toBlockModule = (mod) => {
|
|
|
2146
3204
|
);
|
|
2147
3205
|
return { ...mod, draw, place };
|
|
2148
3206
|
};
|
|
2149
|
-
var ParamsExportSchema =
|
|
2150
|
-
var OptionalBlockMetaSchema =
|
|
2151
|
-
description:
|
|
2152
|
-
version:
|
|
2153
|
-
authors:
|
|
2154
|
-
tags:
|
|
2155
|
-
dependencies:
|
|
3207
|
+
var ParamsExportSchema = z7.array(ParamDefSchema);
|
|
3208
|
+
var OptionalBlockMetaSchema = z7.object({
|
|
3209
|
+
description: z7.string().optional(),
|
|
3210
|
+
version: z7.string().optional(),
|
|
3211
|
+
authors: z7.array(z7.string()).optional(),
|
|
3212
|
+
tags: z7.array(z7.string()).optional(),
|
|
3213
|
+
dependencies: z7.array(z7.string()).optional()
|
|
2156
3214
|
});
|
|
2157
3215
|
var parseParamsExport = (paramsExport) => {
|
|
2158
3216
|
if (typeof paramsExport === "function") {
|
|
@@ -2288,7 +3346,7 @@ var stylesSig = (s) => {
|
|
|
2288
3346
|
};
|
|
2289
3347
|
return `${sig(s.textStyles)}.${sig(s.dimStyles)}`;
|
|
2290
3348
|
};
|
|
2291
|
-
var ParamVisibilityResultSchema =
|
|
3349
|
+
var ParamVisibilityResultSchema = z7.record(z7.string(), z7.boolean());
|
|
2292
3350
|
var paramsKey = (params) => JSON.stringify(Object.entries(params).sort(([a], [b]) => a.localeCompare(b)));
|
|
2293
3351
|
var r6 = (v) => Math.round(v * 1e6) / 1e6;
|
|
2294
3352
|
var sigOf = (v) => typeof v === "string" ? `#${v}` : `${r6(v.x)},${r6(v.y)}`;
|
|
@@ -2314,7 +3372,7 @@ var resolveInputs = (inputs, pivot, resolve) => {
|
|
|
2314
3372
|
return obj ? translateObject(obj, neg) : null;
|
|
2315
3373
|
});
|
|
2316
3374
|
};
|
|
2317
|
-
var BlockInputsSchema =
|
|
3375
|
+
var BlockInputsSchema = z7.array(z7.union([Vec2Schema, z7.string()]));
|
|
2318
3376
|
var acquireBlockInputs = async (script, pickers) => {
|
|
2319
3377
|
const { mod, meta } = compileBlock(script);
|
|
2320
3378
|
if (!mod.place) return [await pickers.pickPoint("Insertion point")];
|
|
@@ -2410,15 +3468,17 @@ var testBlockDefinition = async (script) => {
|
|
|
2410
3468
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
2411
3469
|
}
|
|
2412
3470
|
};
|
|
2413
|
-
var childToObject = (child, instance, index) => {
|
|
3471
|
+
var childToObject = (child, instance, index, layers) => {
|
|
3472
|
+
const { layer, ...rest } = child;
|
|
3473
|
+
const named = layer === void 0 ? void 0 : (layers?.find((l) => l.id === layer) ?? layers?.find((l) => l.name === layer))?.id;
|
|
2414
3474
|
return {
|
|
2415
3475
|
color: instance.color,
|
|
2416
3476
|
lineType: instance.lineType,
|
|
2417
3477
|
lineTypeScale: instance.lineTypeScale,
|
|
2418
3478
|
lineWidth: instance.lineWidth,
|
|
2419
|
-
...
|
|
3479
|
+
...rest,
|
|
2420
3480
|
id: `${instance.id}:${index}`,
|
|
2421
|
-
layerId: instance.layerId
|
|
3481
|
+
layerId: named ?? child.layerId ?? instance.layerId
|
|
2422
3482
|
};
|
|
2423
3483
|
};
|
|
2424
3484
|
var evaluating = /* @__PURE__ */ new Set();
|
|
@@ -2486,7 +3546,7 @@ var getEvaluatedWorldChildren = (instance, scripts, resolveObject, styles = DEFA
|
|
|
2486
3546
|
evalErrors.delete(instance.id);
|
|
2487
3547
|
const pivot = blockPivot(instance);
|
|
2488
3548
|
return children.map((child, i) => {
|
|
2489
|
-
let obj = childToObject(child, instance, i);
|
|
3549
|
+
let obj = childToObject(child, instance, i, styles.layers);
|
|
2490
3550
|
if (instance.scale !== 1) obj = scaleObjectUniform(obj, instance.scale);
|
|
2491
3551
|
if (instance.rotation !== 0)
|
|
2492
3552
|
obj = rotateObject(obj, { x: 0, y: 0 }, instance.rotation);
|
|
@@ -2516,246 +3576,29 @@ var indexOf = (doc) => {
|
|
|
2516
3576
|
var resolveDocumentObject = (doc, id) => indexOf(doc).get(id);
|
|
2517
3577
|
var documentObjectResolver = (doc) => (id) => resolveDocumentObject(doc, id);
|
|
2518
3578
|
|
|
2519
|
-
// ../core/src/paint/
|
|
2520
|
-
var
|
|
2521
|
-
var
|
|
2522
|
-
|
|
2523
|
-
|
|
3579
|
+
// ../core/src/paint/textMetrics.ts
|
|
3580
|
+
var LINE_HEIGHT_FACTOR = 1.66;
|
|
3581
|
+
var TAB_SIZE_FACTOR = 4;
|
|
3582
|
+
var boundMeasurer = (measure, font, widthFactor) => font === void 0 && widthFactor === void 0 ? measure : {
|
|
3583
|
+
measureTextWidth: (text, heightMm) => measure.measureTextWidth(text, heightMm, font, widthFactor)
|
|
2524
3584
|
};
|
|
2525
|
-
var
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
3585
|
+
var lineSegments = (line, heightMm, measure) => {
|
|
3586
|
+
if (!line.includes(" ")) return [{ text: line, x: 0 }];
|
|
3587
|
+
const tab = heightMm * TAB_SIZE_FACTOR;
|
|
3588
|
+
const out = [];
|
|
3589
|
+
let x = 0;
|
|
3590
|
+
const parts = line.split(" ");
|
|
3591
|
+
for (let i = 0; i < parts.length; i++) {
|
|
3592
|
+
if (i > 0) x = (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
3593
|
+
out.push({ text: parts[i], x });
|
|
3594
|
+
x += measure.measureTextWidth(parts[i], heightMm);
|
|
3595
|
+
}
|
|
3596
|
+
return out;
|
|
2534
3597
|
};
|
|
2535
|
-
var
|
|
2536
|
-
const
|
|
2537
|
-
const
|
|
2538
|
-
return
|
|
2539
|
-
content,
|
|
2540
|
-
anchor: add(at, scale(textUp, style.textOffset * style.scale)),
|
|
2541
|
-
rotation,
|
|
2542
|
-
height: style.textHeight * style.scale,
|
|
2543
|
-
font: dimFontFace(style),
|
|
2544
|
-
widthFactor: style.widthFactor
|
|
2545
|
-
};
|
|
2546
|
-
};
|
|
2547
|
-
var linearGeometry = (obj, style) => {
|
|
2548
|
-
if (obj.points.length < 2) return null;
|
|
2549
|
-
const s = style.scale;
|
|
2550
|
-
const points = obj.points;
|
|
2551
|
-
const first = points[0];
|
|
2552
|
-
const last = points[points.length - 1];
|
|
2553
|
-
const upLen = len(obj.offset);
|
|
2554
|
-
const u = upLen > 1e-9 ? perp(scale(obj.offset, 1 / upLen)) : dist(first, last) > 1e-9 ? norm(sub(last, first)) : { x: 1, y: 0 };
|
|
2555
|
-
const v = perp(u);
|
|
2556
|
-
const h = dot(obj.offset, v);
|
|
2557
|
-
const feet = points.map((p) => add(p, scale(v, h - dot(sub(p, first), v))));
|
|
2558
|
-
const extensionLines = [];
|
|
2559
|
-
points.forEach((p, i) => {
|
|
2560
|
-
const f = feet[i];
|
|
2561
|
-
const gap = dist(p, f);
|
|
2562
|
-
if (gap < 1e-9) return;
|
|
2563
|
-
const w = norm(sub(f, p));
|
|
2564
|
-
extensionLines.push({
|
|
2565
|
-
a: style.extensionType === "short" ? sub(f, scale(w, style.extensionOvershoot * s)) : add(p, scale(w, Math.min(style.extensionOffset * s, gap))),
|
|
2566
|
-
b: add(f, scale(w, style.extensionOvershoot * s))
|
|
2567
|
-
});
|
|
2568
|
-
});
|
|
2569
|
-
const dimLines = [];
|
|
2570
|
-
const arrows = [];
|
|
2571
|
-
const texts = [];
|
|
2572
|
-
for (let i = 0; i + 1 < feet.length; i++) {
|
|
2573
|
-
const a = feet[i];
|
|
2574
|
-
const b = feet[i + 1];
|
|
2575
|
-
const value = dist(a, b);
|
|
2576
|
-
if (value < 1e-9) continue;
|
|
2577
|
-
dimLines.push({ a, b });
|
|
2578
|
-
arrows.push(
|
|
2579
|
-
{ tip: a, toward: b, size: style.arrowSize * s },
|
|
2580
|
-
{ tip: b, toward: a, size: style.arrowSize * s }
|
|
2581
|
-
);
|
|
2582
|
-
texts.push(
|
|
2583
|
-
textFor(
|
|
2584
|
-
obj.textOverride ?? formatDimValue(value, style.precision),
|
|
2585
|
-
mid(a, b),
|
|
2586
|
-
u,
|
|
2587
|
-
style
|
|
2588
|
-
)
|
|
2589
|
-
);
|
|
2590
|
-
}
|
|
2591
|
-
if (dimLines.length === 0) return null;
|
|
2592
|
-
return {
|
|
2593
|
-
extensionLines,
|
|
2594
|
-
dimLines,
|
|
2595
|
-
dimArc: null,
|
|
2596
|
-
arrows,
|
|
2597
|
-
arrowType: style.arrowType,
|
|
2598
|
-
texts,
|
|
2599
|
-
value: dist(feet[0], feet[feet.length - 1])
|
|
2600
|
-
};
|
|
2601
|
-
};
|
|
2602
|
-
var angularGeometry = (obj, style) => {
|
|
2603
|
-
if (obj.points.length < 3) return null;
|
|
2604
|
-
const s = style.scale;
|
|
2605
|
-
const [vertex, a, b] = obj.points;
|
|
2606
|
-
const radius = len(obj.offset);
|
|
2607
|
-
const da = dist(vertex, a);
|
|
2608
|
-
const db = dist(vertex, b);
|
|
2609
|
-
if (radius < 1e-9 || da < 1e-9 || db < 1e-9) return null;
|
|
2610
|
-
const angA = angle(sub(a, vertex));
|
|
2611
|
-
const angB = angle(sub(b, vertex));
|
|
2612
|
-
const angL = angle(obj.offset);
|
|
2613
|
-
const sweepAB = normAngle(angB - angA);
|
|
2614
|
-
const inAB = normAngle(angL - angA) <= sweepAB;
|
|
2615
|
-
const start = inAB ? angA : angB;
|
|
2616
|
-
const sweep = inAB ? sweepAB : normAngle(angA - angB);
|
|
2617
|
-
if (sweep < 1e-9) return null;
|
|
2618
|
-
const at = (t) => add(vertex, scale(fromAngle(start + t), radius));
|
|
2619
|
-
const extensionLines = [];
|
|
2620
|
-
for (const [p, d] of [
|
|
2621
|
-
[a, da],
|
|
2622
|
-
[b, db]
|
|
2623
|
-
]) {
|
|
2624
|
-
const w = norm(sub(p, vertex));
|
|
2625
|
-
const inner = style.extensionType === "short" ? radius - style.extensionOvershoot * s : Math.min(d + style.extensionOffset * s, radius);
|
|
2626
|
-
const outer = radius + style.extensionOvershoot * s;
|
|
2627
|
-
if (outer - inner > 1e-9)
|
|
2628
|
-
extensionLines.push({
|
|
2629
|
-
a: add(vertex, scale(w, inner)),
|
|
2630
|
-
b: add(vertex, scale(w, outer))
|
|
2631
|
-
});
|
|
2632
|
-
}
|
|
2633
|
-
const tangentStep = Math.min(sweep / 3, style.arrowSize * s * 2 / radius);
|
|
2634
|
-
const valueDeg = sweep * RAD2DEG;
|
|
2635
|
-
const midPoint = at(sweep / 2);
|
|
2636
|
-
const midTangent = perp(norm(sub(midPoint, vertex)));
|
|
2637
|
-
return {
|
|
2638
|
-
extensionLines,
|
|
2639
|
-
dimLines: [],
|
|
2640
|
-
dimArc: {
|
|
2641
|
-
center: vertex,
|
|
2642
|
-
radius,
|
|
2643
|
-
startAngle: start,
|
|
2644
|
-
endAngle: start + sweep
|
|
2645
|
-
},
|
|
2646
|
-
arrows: [
|
|
2647
|
-
{ tip: at(0), toward: at(tangentStep), size: style.arrowSize * s },
|
|
2648
|
-
{
|
|
2649
|
-
tip: at(sweep),
|
|
2650
|
-
toward: at(sweep - tangentStep),
|
|
2651
|
-
size: style.arrowSize * s
|
|
2652
|
-
}
|
|
2653
|
-
],
|
|
2654
|
-
arrowType: style.arrowType,
|
|
2655
|
-
texts: [
|
|
2656
|
-
textFor(
|
|
2657
|
-
obj.textOverride ?? `${formatDimValue(valueDeg, style.precision)}\xB0`,
|
|
2658
|
-
midPoint,
|
|
2659
|
-
midTangent,
|
|
2660
|
-
style
|
|
2661
|
-
)
|
|
2662
|
-
],
|
|
2663
|
-
value: sweep
|
|
2664
|
-
};
|
|
2665
|
-
};
|
|
2666
|
-
var radialGeometry = (obj, style) => {
|
|
2667
|
-
if (obj.points.length < 2) return null;
|
|
2668
|
-
const s = style.scale;
|
|
2669
|
-
const [center, p] = obj.points;
|
|
2670
|
-
const r = dist(center, p);
|
|
2671
|
-
if (r < 1e-9) return null;
|
|
2672
|
-
const u = norm(sub(p, center));
|
|
2673
|
-
const t = Math.max(dot(obj.offset, u), r * 0.2);
|
|
2674
|
-
const textAt = add(center, scale(u, t));
|
|
2675
|
-
return {
|
|
2676
|
-
extensionLines: [],
|
|
2677
|
-
// The line runs center → text position (through the curve point).
|
|
2678
|
-
dimLines: [{ a: center, b: t > r ? textAt : p }],
|
|
2679
|
-
dimArc: null,
|
|
2680
|
-
arrows: [{ tip: p, toward: center, size: style.arrowSize * s }],
|
|
2681
|
-
arrowType: style.arrowType,
|
|
2682
|
-
texts: [
|
|
2683
|
-
textFor(
|
|
2684
|
-
obj.textOverride ?? `R${formatDimValue(r, style.precision)}`,
|
|
2685
|
-
textAt,
|
|
2686
|
-
u,
|
|
2687
|
-
style
|
|
2688
|
-
)
|
|
2689
|
-
],
|
|
2690
|
-
value: r
|
|
2691
|
-
};
|
|
2692
|
-
};
|
|
2693
|
-
var diameterGeometry = (obj, style) => {
|
|
2694
|
-
if (obj.points.length < 2) return null;
|
|
2695
|
-
const s = style.scale;
|
|
2696
|
-
const [p1, p2] = obj.points;
|
|
2697
|
-
const d = dist(p1, p2);
|
|
2698
|
-
if (d < 1e-9) return null;
|
|
2699
|
-
const u = norm(sub(p2, p1));
|
|
2700
|
-
const t = dot(sub(add(mid(p1, p2), obj.offset), p1), u);
|
|
2701
|
-
const textAt = add(p1, scale(u, Math.min(Math.max(t, d * 0.15), d * 0.85)));
|
|
2702
|
-
return {
|
|
2703
|
-
extensionLines: [],
|
|
2704
|
-
dimLines: [{ a: p1, b: p2 }],
|
|
2705
|
-
dimArc: null,
|
|
2706
|
-
arrows: [
|
|
2707
|
-
{ tip: p1, toward: p2, size: style.arrowSize * s },
|
|
2708
|
-
{ tip: p2, toward: p1, size: style.arrowSize * s }
|
|
2709
|
-
],
|
|
2710
|
-
arrowType: style.arrowType,
|
|
2711
|
-
texts: [
|
|
2712
|
-
textFor(
|
|
2713
|
-
obj.textOverride ?? `\xD8${formatDimValue(d, style.precision)}`,
|
|
2714
|
-
textAt,
|
|
2715
|
-
u,
|
|
2716
|
-
style
|
|
2717
|
-
)
|
|
2718
|
-
],
|
|
2719
|
-
value: d
|
|
2720
|
-
};
|
|
2721
|
-
};
|
|
2722
|
-
var dimensionGeometry = (obj, styles) => {
|
|
2723
|
-
const style = resolveDimStyle(obj, styles);
|
|
2724
|
-
switch (obj.kind) {
|
|
2725
|
-
case "angular":
|
|
2726
|
-
return angularGeometry(obj, style);
|
|
2727
|
-
case "radial":
|
|
2728
|
-
return radialGeometry(obj, style);
|
|
2729
|
-
case "diameter":
|
|
2730
|
-
return diameterGeometry(obj, style);
|
|
2731
|
-
case "linear":
|
|
2732
|
-
return linearGeometry(obj, style);
|
|
2733
|
-
}
|
|
2734
|
-
};
|
|
2735
|
-
|
|
2736
|
-
// ../core/src/paint/textMetrics.ts
|
|
2737
|
-
var LINE_HEIGHT_FACTOR = 1.66;
|
|
2738
|
-
var TAB_SIZE_FACTOR = 4;
|
|
2739
|
-
var boundMeasurer = (measure, font, widthFactor) => font === void 0 && widthFactor === void 0 ? measure : {
|
|
2740
|
-
measureTextWidth: (text, heightMm) => measure.measureTextWidth(text, heightMm, font, widthFactor)
|
|
2741
|
-
};
|
|
2742
|
-
var lineSegments = (line, heightMm, measure) => {
|
|
2743
|
-
if (!line.includes(" ")) return [{ text: line, x: 0 }];
|
|
2744
|
-
const tab = heightMm * TAB_SIZE_FACTOR;
|
|
2745
|
-
const out = [];
|
|
2746
|
-
let x = 0;
|
|
2747
|
-
const parts = line.split(" ");
|
|
2748
|
-
for (let i = 0; i < parts.length; i++) {
|
|
2749
|
-
if (i > 0) x = (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
2750
|
-
out.push({ text: parts[i], x });
|
|
2751
|
-
x += measure.measureTextWidth(parts[i], heightMm);
|
|
2752
|
-
}
|
|
2753
|
-
return out;
|
|
2754
|
-
};
|
|
2755
|
-
var lineWidthWithTabs = (line, heightMm, measure) => {
|
|
2756
|
-
const segs = lineSegments(line, heightMm, measure);
|
|
2757
|
-
const last = segs[segs.length - 1];
|
|
2758
|
-
return last.x + measure.measureTextWidth(last.text, heightMm);
|
|
3598
|
+
var lineWidthWithTabs = (line, heightMm, measure) => {
|
|
3599
|
+
const segs = lineSegments(line, heightMm, measure);
|
|
3600
|
+
const last = segs[segs.length - 1];
|
|
3601
|
+
return last.x + measure.measureTextWidth(last.text, heightMm);
|
|
2759
3602
|
};
|
|
2760
3603
|
var wrapWords = (line, heightMm, measure, maxWidthMm) => {
|
|
2761
3604
|
const words = line.split(" ");
|
|
@@ -2802,6 +3645,203 @@ var textBlock = (content, heightMm, measure, maxWidthMm) => {
|
|
|
2802
3645
|
};
|
|
2803
3646
|
};
|
|
2804
3647
|
|
|
3648
|
+
// ../core/src/paint/richText.ts
|
|
3649
|
+
var ATTR_KEYS = [
|
|
3650
|
+
"font",
|
|
3651
|
+
"bold",
|
|
3652
|
+
"italic",
|
|
3653
|
+
"underline",
|
|
3654
|
+
"color",
|
|
3655
|
+
"height",
|
|
3656
|
+
"script"
|
|
3657
|
+
];
|
|
3658
|
+
var SCRIPT_SCALE = 0.6;
|
|
3659
|
+
var SUPER_RISE = 0.45;
|
|
3660
|
+
var SUB_DROP = 0.2;
|
|
3661
|
+
var attrsOf = (s) => {
|
|
3662
|
+
const out = {};
|
|
3663
|
+
for (const k of ATTR_KEYS) if (s[k] !== void 0) out[k] = s[k];
|
|
3664
|
+
return out;
|
|
3665
|
+
};
|
|
3666
|
+
var sameAttrs = (a, b) => ATTR_KEYS.every((k) => a[k] === b[k]);
|
|
3667
|
+
var isEmpty = (a) => ATTR_KEYS.every((k) => a[k] === void 0);
|
|
3668
|
+
var snap = (i, content) => {
|
|
3669
|
+
const c = Math.max(0, Math.min(content.length, Math.round(i)));
|
|
3670
|
+
const code = content.charCodeAt(c);
|
|
3671
|
+
return c > 0 && code >= 56320 && code <= 57343 ? c - 1 : c;
|
|
3672
|
+
};
|
|
3673
|
+
var toIntervals = (spans, content, extra = []) => {
|
|
3674
|
+
const cuts = /* @__PURE__ */ new Set([0, content.length]);
|
|
3675
|
+
for (const s of spans ?? []) {
|
|
3676
|
+
cuts.add(snap(s.start, content));
|
|
3677
|
+
cuts.add(snap(s.end, content));
|
|
3678
|
+
}
|
|
3679
|
+
for (const c of extra) cuts.add(snap(c, content));
|
|
3680
|
+
const sorted = [...cuts].sort((a, b) => a - b);
|
|
3681
|
+
const out = [];
|
|
3682
|
+
for (let i = 0; i + 1 < sorted.length; i++) {
|
|
3683
|
+
const start = sorted[i];
|
|
3684
|
+
const end = sorted[i + 1];
|
|
3685
|
+
let attrs = {};
|
|
3686
|
+
for (const s of spans ?? [])
|
|
3687
|
+
if (snap(s.start, content) <= start && snap(s.end, content) >= end)
|
|
3688
|
+
attrs = { ...attrs, ...attrsOf(s) };
|
|
3689
|
+
out.push({ start, end, attrs });
|
|
3690
|
+
}
|
|
3691
|
+
return out;
|
|
3692
|
+
};
|
|
3693
|
+
var fromIntervals = (intervals) => {
|
|
3694
|
+
const out = [];
|
|
3695
|
+
for (const iv of intervals) {
|
|
3696
|
+
if (iv.end <= iv.start || isEmpty(iv.attrs)) continue;
|
|
3697
|
+
const last = out[out.length - 1];
|
|
3698
|
+
if (last && last.end === iv.start && sameAttrs(attrsOf(last), iv.attrs))
|
|
3699
|
+
last.end = iv.end;
|
|
3700
|
+
else out.push({ start: iv.start, end: iv.end, ...iv.attrs });
|
|
3701
|
+
}
|
|
3702
|
+
return out;
|
|
3703
|
+
};
|
|
3704
|
+
var normalizeSpans = (spans, content) => fromIntervals(toIntervals(spans, content));
|
|
3705
|
+
var sliceSpans = (spans, start, end, to = 0) => (spans ?? []).filter((s) => s.end > start && s.start < end).map((s) => ({
|
|
3706
|
+
...s,
|
|
3707
|
+
start: Math.max(s.start, start) - start + to,
|
|
3708
|
+
end: Math.min(s.end, end) - start + to
|
|
3709
|
+
}));
|
|
3710
|
+
var richTextBlock = (content, spans, base, measure, tabMeasure, maxWidthMm) => {
|
|
3711
|
+
const h = base.heightMm;
|
|
3712
|
+
const baseFace = parseFontFace(base.face);
|
|
3713
|
+
const runs = toIntervals(spans, content).map((iv) => {
|
|
3714
|
+
const a = iv.attrs;
|
|
3715
|
+
const cap = h * (a.height ?? 1);
|
|
3716
|
+
return {
|
|
3717
|
+
...iv,
|
|
3718
|
+
face: fontFace(
|
|
3719
|
+
a.font ?? baseFace.font,
|
|
3720
|
+
a.bold ?? baseFace.bold,
|
|
3721
|
+
a.italic ?? baseFace.italic
|
|
3722
|
+
),
|
|
3723
|
+
cap,
|
|
3724
|
+
glyph: a.script ? cap * SCRIPT_SCALE : cap,
|
|
3725
|
+
dy: a.script === "super" ? cap * SUPER_RISE : a.script === "sub" ? -cap * SUB_DROP : 0
|
|
3726
|
+
};
|
|
3727
|
+
});
|
|
3728
|
+
const runsIn = (a, b) => runs.filter((r) => r.end > a && r.start < b);
|
|
3729
|
+
const widthOf = (a, b, m) => runsIn(a, b).reduce(
|
|
3730
|
+
(w, r) => w + m.measureTextWidth(
|
|
3731
|
+
content.slice(Math.max(a, r.start), Math.min(b, r.end)),
|
|
3732
|
+
r.glyph,
|
|
3733
|
+
r.face,
|
|
3734
|
+
base.widthFactor
|
|
3735
|
+
),
|
|
3736
|
+
0
|
|
3737
|
+
);
|
|
3738
|
+
const tab = h * TAB_SIZE_FACTOR;
|
|
3739
|
+
const nextStop = (x) => (Math.floor(x / tab + 1e-9) + 1) * tab;
|
|
3740
|
+
const segments = (a, b) => {
|
|
3741
|
+
const out = [];
|
|
3742
|
+
let x = 0;
|
|
3743
|
+
let s = a;
|
|
3744
|
+
for (let i = a; i <= b; i++) {
|
|
3745
|
+
if (i < b && content[i] !== " ") continue;
|
|
3746
|
+
out.push({ start: s, end: i, x });
|
|
3747
|
+
x = nextStop(x + widthOf(s, i, tabMeasure));
|
|
3748
|
+
s = i + 1;
|
|
3749
|
+
}
|
|
3750
|
+
return out;
|
|
3751
|
+
};
|
|
3752
|
+
const wrapWords2 = (a, b, max) => {
|
|
3753
|
+
const out = [];
|
|
3754
|
+
let lineStart = a;
|
|
3755
|
+
let cur = -1;
|
|
3756
|
+
for (let i = a; i <= b; i++) {
|
|
3757
|
+
if (i < b && content[i] !== " ") continue;
|
|
3758
|
+
if (cur >= 0 && widthOf(lineStart, i, measure) > max) {
|
|
3759
|
+
out.push([lineStart, cur]);
|
|
3760
|
+
lineStart = cur + 1;
|
|
3761
|
+
}
|
|
3762
|
+
cur = i;
|
|
3763
|
+
}
|
|
3764
|
+
out.push([lineStart, b]);
|
|
3765
|
+
return out;
|
|
3766
|
+
};
|
|
3767
|
+
const raw = [];
|
|
3768
|
+
let p0 = 0;
|
|
3769
|
+
for (const para of content.split("\n")) {
|
|
3770
|
+
const p1 = p0 + para.length;
|
|
3771
|
+
const tabbed = para.includes(" ");
|
|
3772
|
+
const wrap = maxWidthMm !== void 0 && maxWidthMm > 0;
|
|
3773
|
+
if (!wrap) raw.push({ start: p0, end: p1, tabbed });
|
|
3774
|
+
else if (!tabbed)
|
|
3775
|
+
for (const [s, e] of wrapWords2(p0, p1, maxWidthMm))
|
|
3776
|
+
raw.push({ start: s, end: e, tabbed });
|
|
3777
|
+
else {
|
|
3778
|
+
const segs = segments(p0, p1);
|
|
3779
|
+
const last = segs[segs.length - 1];
|
|
3780
|
+
const width = last.x + widthOf(last.start, last.end, measure);
|
|
3781
|
+
if (width <= maxWidthMm || maxWidthMm - last.x <= h)
|
|
3782
|
+
raw.push({ start: p0, end: p1, tabbed });
|
|
3783
|
+
else
|
|
3784
|
+
wrapWords2(last.start, p1, maxWidthMm - last.x).forEach(
|
|
3785
|
+
([s, e], i) => raw.push(
|
|
3786
|
+
i === 0 ? { start: p0, end: e, tabbed } : { start: s, end: e, hang: last.x, tabbed }
|
|
3787
|
+
)
|
|
3788
|
+
);
|
|
3789
|
+
}
|
|
3790
|
+
p0 = p1 + 1;
|
|
3791
|
+
}
|
|
3792
|
+
const lines = [];
|
|
3793
|
+
let baseline = 0;
|
|
3794
|
+
let prevCap = 0;
|
|
3795
|
+
for (const r of raw) {
|
|
3796
|
+
const segs = r.hang !== void 0 ? [{ start: r.start, end: r.end, x: r.hang }] : segments(r.start, r.end);
|
|
3797
|
+
const pieces = [];
|
|
3798
|
+
for (const seg of segs) {
|
|
3799
|
+
let x = seg.x;
|
|
3800
|
+
for (const run of runsIn(seg.start, seg.end)) {
|
|
3801
|
+
const text = content.slice(
|
|
3802
|
+
Math.max(seg.start, run.start),
|
|
3803
|
+
Math.min(seg.end, run.end)
|
|
3804
|
+
);
|
|
3805
|
+
const width = measure.measureTextWidth(
|
|
3806
|
+
text,
|
|
3807
|
+
run.glyph,
|
|
3808
|
+
run.face,
|
|
3809
|
+
base.widthFactor
|
|
3810
|
+
);
|
|
3811
|
+
pieces.push({
|
|
3812
|
+
text,
|
|
3813
|
+
x,
|
|
3814
|
+
width,
|
|
3815
|
+
dy: run.dy,
|
|
3816
|
+
heightMm: run.glyph,
|
|
3817
|
+
face: run.face,
|
|
3818
|
+
...run.attrs.color ? { color: run.attrs.color } : {},
|
|
3819
|
+
...run.attrs.underline ? { underline: true } : {}
|
|
3820
|
+
});
|
|
3821
|
+
x += width;
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3824
|
+
const at = runsIn(r.start, Math.max(r.end, r.start + 1));
|
|
3825
|
+
const cap = Math.max(...at.map((run) => run.cap), at.length ? 0 : h);
|
|
3826
|
+
baseline += lines.length === 0 ? cap : LINE_HEIGHT_FACTOR * (prevCap + cap) / 2;
|
|
3827
|
+
prevCap = cap;
|
|
3828
|
+
const last = pieces[pieces.length - 1];
|
|
3829
|
+
lines.push({
|
|
3830
|
+
start: r.start,
|
|
3831
|
+
end: r.end,
|
|
3832
|
+
pieces,
|
|
3833
|
+
width: last ? last.x + last.width : 0,
|
|
3834
|
+
fromBlockEdge: r.tabbed,
|
|
3835
|
+
baseline
|
|
3836
|
+
});
|
|
3837
|
+
}
|
|
3838
|
+
return {
|
|
3839
|
+
lines,
|
|
3840
|
+
width: maxWidthMm !== void 0 && maxWidthMm > 0 ? maxWidthMm : Math.max(...lines.map((l) => l.width), 0),
|
|
3841
|
+
height: baseline
|
|
3842
|
+
};
|
|
3843
|
+
};
|
|
3844
|
+
|
|
2805
3845
|
// ../core/src/paint/advanceTables.ts
|
|
2806
3846
|
var EXTRACTED_RANGES = [
|
|
2807
3847
|
[32, 126],
|
|
@@ -6284,6 +7324,473 @@ var approximateTextMeasurer = {
|
|
|
6284
7324
|
}
|
|
6285
7325
|
};
|
|
6286
7326
|
|
|
7327
|
+
// ../core/src/paint/dimensionGeometry.ts
|
|
7328
|
+
var RAD2DEG = 180 / Math.PI;
|
|
7329
|
+
var formatDimValue = (value, precision) => {
|
|
7330
|
+
const fixed = value.toFixed(precision);
|
|
7331
|
+
return fixed.includes(".") ? fixed.replace(/\.?0+$/, "") : fixed;
|
|
7332
|
+
};
|
|
7333
|
+
var dimLabelContent = (kind, label, formatted) => {
|
|
7334
|
+
const parts = (label?.content ?? DIM_DEFAULT_CONTENT[kind]).split(
|
|
7335
|
+
DIM_VALUE_TOKEN
|
|
7336
|
+
);
|
|
7337
|
+
const content = parts.join(formatted);
|
|
7338
|
+
if (!label?.spans?.length || label.content === void 0) return { content };
|
|
7339
|
+
const T = DIM_VALUE_TOKEN.length;
|
|
7340
|
+
const map = (p, end) => {
|
|
7341
|
+
let t = 0;
|
|
7342
|
+
let c = 0;
|
|
7343
|
+
for (let i = 0; i < parts.length; i++) {
|
|
7344
|
+
if (p <= t + parts[i].length) return c + (p - t);
|
|
7345
|
+
t += parts[i].length;
|
|
7346
|
+
c += parts[i].length;
|
|
7347
|
+
if (i === parts.length - 1) break;
|
|
7348
|
+
if (p < t + T) return end ? c + formatted.length : c;
|
|
7349
|
+
t += T;
|
|
7350
|
+
c += formatted.length;
|
|
7351
|
+
}
|
|
7352
|
+
return content.length;
|
|
7353
|
+
};
|
|
7354
|
+
const spans = normalizeSpans(
|
|
7355
|
+
label.spans.map((s) => ({
|
|
7356
|
+
...s,
|
|
7357
|
+
start: map(s.start, false),
|
|
7358
|
+
end: map(s.end, true)
|
|
7359
|
+
})),
|
|
7360
|
+
content
|
|
7361
|
+
);
|
|
7362
|
+
return spans.length ? { content, spans } : { content };
|
|
7363
|
+
};
|
|
7364
|
+
var labelWidth = (label, h, font, widthFactor) => label.spans?.length ? richTextBlock(
|
|
7365
|
+
label.content,
|
|
7366
|
+
label.spans,
|
|
7367
|
+
{ face: font, heightMm: h, widthFactor },
|
|
7368
|
+
approximateTextMeasurer,
|
|
7369
|
+
approximateTextMeasurer
|
|
7370
|
+
).width : approximateTextMeasurer.measureTextWidth(
|
|
7371
|
+
label.content,
|
|
7372
|
+
h,
|
|
7373
|
+
font,
|
|
7374
|
+
widthFactor
|
|
7375
|
+
);
|
|
7376
|
+
var resolveDimStyle = (obj, styles) => ({
|
|
7377
|
+
...dimStyleFor(obj, styles),
|
|
7378
|
+
...obj.styleOverride,
|
|
7379
|
+
scale: obj.scale
|
|
7380
|
+
});
|
|
7381
|
+
var readableRotation = (u) => {
|
|
7382
|
+
const raw = normAngle(angle(u));
|
|
7383
|
+
const flipped = raw > Math.PI / 2 + 1e-9 && raw <= 3 * Math.PI / 2 + 1e-9;
|
|
7384
|
+
return flipped ? raw - Math.PI : raw;
|
|
7385
|
+
};
|
|
7386
|
+
var straightFrame = (origin, u, n, s0, s1) => ({
|
|
7387
|
+
s0,
|
|
7388
|
+
s1,
|
|
7389
|
+
toWorld: (along, across) => add(origin, add(scale(u, along), scale(n, across))),
|
|
7390
|
+
fromWorld: (p) => {
|
|
7391
|
+
const d = sub(p, origin);
|
|
7392
|
+
return { along: dot(d, u), across: dot(d, n) };
|
|
7393
|
+
},
|
|
7394
|
+
tangent: () => u
|
|
7395
|
+
});
|
|
7396
|
+
var linearAxis = (obj) => {
|
|
7397
|
+
const first = obj.points[0];
|
|
7398
|
+
const last = obj.points[obj.points.length - 1];
|
|
7399
|
+
const u = obj.rotation !== void 0 ? fromAngle(obj.rotation) : dist(first, last) > 1e-9 ? norm(sub(last, first)) : { x: 1, y: 0 };
|
|
7400
|
+
return { u, n: perp(u) };
|
|
7401
|
+
};
|
|
7402
|
+
var linearFeet = (obj) => {
|
|
7403
|
+
const { u, n } = linearAxis(obj);
|
|
7404
|
+
const first = obj.points[0];
|
|
7405
|
+
const h = obj.offset ?? 0;
|
|
7406
|
+
const feet = obj.points.map(
|
|
7407
|
+
(p) => add(p, scale(n, h - dot(sub(p, first), n)))
|
|
7408
|
+
);
|
|
7409
|
+
return { feet, u, n };
|
|
7410
|
+
};
|
|
7411
|
+
var dimensionLabelFrames = (obj) => {
|
|
7412
|
+
switch (obj.kind) {
|
|
7413
|
+
case "linear": {
|
|
7414
|
+
if (obj.points.length < 2) return [];
|
|
7415
|
+
const { feet, u, n } = linearFeet(obj);
|
|
7416
|
+
const across = (obj.offset ?? 0) >= 0 ? n : scale(n, -1);
|
|
7417
|
+
const frames = [];
|
|
7418
|
+
for (let i = 0; i + 1 < feet.length; i++) {
|
|
7419
|
+
const L = dot(sub(feet[i + 1], feet[i]), u);
|
|
7420
|
+
if (Math.abs(L) < 1e-9) continue;
|
|
7421
|
+
const dir = L > 0 ? u : scale(u, -1);
|
|
7422
|
+
frames.push(straightFrame(feet[i], dir, across, 0, Math.abs(L)));
|
|
7423
|
+
}
|
|
7424
|
+
return frames;
|
|
7425
|
+
}
|
|
7426
|
+
case "angular": {
|
|
7427
|
+
const polar2 = angularFrame(obj);
|
|
7428
|
+
return polar2 ? [polar2.frame] : [];
|
|
7429
|
+
}
|
|
7430
|
+
case "radial": {
|
|
7431
|
+
if (obj.points.length < 2) return [];
|
|
7432
|
+
const [center, p] = obj.points;
|
|
7433
|
+
const r = dist(center, p);
|
|
7434
|
+
if (r < 1e-9) return [];
|
|
7435
|
+
const u = norm(sub(p, center));
|
|
7436
|
+
return [straightFrame(center, u, perp(u), 0, r)];
|
|
7437
|
+
}
|
|
7438
|
+
case "diameter": {
|
|
7439
|
+
if (obj.points.length < 2) return [];
|
|
7440
|
+
const [p1, p2] = obj.points;
|
|
7441
|
+
const d = dist(p1, p2);
|
|
7442
|
+
if (d < 1e-9) return [];
|
|
7443
|
+
const u = norm(sub(p2, p1));
|
|
7444
|
+
const center = add(p1, scale(u, d / 2));
|
|
7445
|
+
return [straightFrame(center, u, perp(u), -d / 2, d / 2)];
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
};
|
|
7449
|
+
var angularFrame = (obj) => {
|
|
7450
|
+
if (obj.points.length < 3) return null;
|
|
7451
|
+
const [vertex, a, b] = obj.points;
|
|
7452
|
+
const signed = obj.offset ?? 0;
|
|
7453
|
+
const radius = Math.abs(signed);
|
|
7454
|
+
if (radius < 1e-9 || dist(vertex, a) < 1e-9 || dist(vertex, b) < 1e-9)
|
|
7455
|
+
return null;
|
|
7456
|
+
const angA = angle(sub(a, vertex));
|
|
7457
|
+
const angB = angle(sub(b, vertex));
|
|
7458
|
+
const start = signed >= 0 ? angA : angB;
|
|
7459
|
+
const sweep = signed >= 0 ? normAngle(angB - angA) : normAngle(angA - angB);
|
|
7460
|
+
if (sweep < 1e-9) return null;
|
|
7461
|
+
const frame = {
|
|
7462
|
+
s0: 0,
|
|
7463
|
+
s1: radius * sweep,
|
|
7464
|
+
toWorld: (along, across) => add(vertex, scale(fromAngle(start + along / radius), radius + across)),
|
|
7465
|
+
fromWorld: (p) => {
|
|
7466
|
+
const d = sub(p, vertex);
|
|
7467
|
+
let w = normAngle(angle(d) - start);
|
|
7468
|
+
if (w > Math.PI) w -= 2 * Math.PI;
|
|
7469
|
+
return { along: w * radius, across: len(d) - radius };
|
|
7470
|
+
},
|
|
7471
|
+
tangent: (along) => perp(fromAngle(start + along / radius))
|
|
7472
|
+
};
|
|
7473
|
+
return { vertex, radius, start, sweep, frame };
|
|
7474
|
+
};
|
|
7475
|
+
var overlaps = (a, b) => a[0] < b[1] - 1e-9 && b[0] < a[1] - 1e-9;
|
|
7476
|
+
var placeLabel = (frame, spec, index, label, style, arrowCount, mode, stack) => {
|
|
7477
|
+
const s = style.scale;
|
|
7478
|
+
const h = style.textHeight * s;
|
|
7479
|
+
const gap = style.textOffset * s;
|
|
7480
|
+
const A = style.arrowSize * s;
|
|
7481
|
+
const font = dimFontFace(style);
|
|
7482
|
+
const width = labelWidth(label, h, font, style.widthFactor);
|
|
7483
|
+
const L = frame.s1 - frame.s0;
|
|
7484
|
+
const arrowsInside = L >= arrowCount * A - 1e-9;
|
|
7485
|
+
let along = spec?.along;
|
|
7486
|
+
let across = spec?.across ?? 0;
|
|
7487
|
+
let row = 0;
|
|
7488
|
+
if (along === void 0) {
|
|
7489
|
+
const fits = L >= width + 2 * gap + arrowCount * A - 1e-9;
|
|
7490
|
+
const push = (arrowsInside ? 0 : A) + gap + width / 2;
|
|
7491
|
+
if (fits) along = (frame.s0 + frame.s1) / 2;
|
|
7492
|
+
else if (mode === "end") along = frame.s1 + push;
|
|
7493
|
+
else if (mode === "start") along = frame.s0 - push;
|
|
7494
|
+
else {
|
|
7495
|
+
along = (frame.s0 + frame.s1) / 2;
|
|
7496
|
+
row = 1;
|
|
7497
|
+
const interval2 = [along - width / 2, along + width / 2];
|
|
7498
|
+
if (stack && stack.row >= 1 && overlaps(interval2, stack.interval))
|
|
7499
|
+
row = stack.row + 1;
|
|
7500
|
+
across = row * (h + gap);
|
|
7501
|
+
}
|
|
7502
|
+
}
|
|
7503
|
+
const interval = [along - width / 2, along + width / 2];
|
|
7504
|
+
let cover = null;
|
|
7505
|
+
if (across === 0 && (interval[1] > frame.s1 || interval[0] < frame.s0))
|
|
7506
|
+
cover = [
|
|
7507
|
+
Math.min(frame.s0, interval[0] - gap),
|
|
7508
|
+
Math.max(frame.s1, interval[1] + gap)
|
|
7509
|
+
];
|
|
7510
|
+
const leaders = [];
|
|
7511
|
+
if (spec?.across !== void 0 && spec.across !== 0) {
|
|
7512
|
+
const landingA = frame.toWorld(interval[0], across);
|
|
7513
|
+
const landingB = frame.toWorld(interval[1], across);
|
|
7514
|
+
const from = frame.toWorld((frame.s0 + frame.s1) / 2, 0);
|
|
7515
|
+
const to = dist(from, landingA) <= dist(from, landingB) ? landingA : landingB;
|
|
7516
|
+
leaders.push({ a: from, b: to }, { a: landingA, b: landingB });
|
|
7517
|
+
}
|
|
7518
|
+
const tangent = frame.tangent(along);
|
|
7519
|
+
const rotation = readableRotation(tangent);
|
|
7520
|
+
const textUp = perp(fromAngle(rotation));
|
|
7521
|
+
const text = {
|
|
7522
|
+
content: label.content,
|
|
7523
|
+
...label.spans ? { spans: label.spans } : {},
|
|
7524
|
+
anchor: add(frame.toWorld(along, across), scale(textUp, gap)),
|
|
7525
|
+
rotation,
|
|
7526
|
+
height: h,
|
|
7527
|
+
width,
|
|
7528
|
+
font,
|
|
7529
|
+
widthFactor: style.widthFactor,
|
|
7530
|
+
segment: index,
|
|
7531
|
+
along,
|
|
7532
|
+
across
|
|
7533
|
+
};
|
|
7534
|
+
return { text, cover, leaders, row };
|
|
7535
|
+
};
|
|
7536
|
+
var linearGeometry = (obj, style) => {
|
|
7537
|
+
if (obj.points.length < 2) return null;
|
|
7538
|
+
const s = style.scale;
|
|
7539
|
+
const A = style.arrowSize * s;
|
|
7540
|
+
const { feet, u } = linearFeet(obj);
|
|
7541
|
+
const frames = dimensionLabelFrames(obj);
|
|
7542
|
+
if (frames.length === 0) return null;
|
|
7543
|
+
const extensionLines = [];
|
|
7544
|
+
obj.points.forEach((p, i) => {
|
|
7545
|
+
const f = feet[i];
|
|
7546
|
+
const gap = dist(p, f);
|
|
7547
|
+
if (gap < 1e-9) return;
|
|
7548
|
+
const w = norm(sub(f, p));
|
|
7549
|
+
extensionLines.push({
|
|
7550
|
+
a: style.extensionType === "short" ? sub(f, scale(w, style.extensionOvershoot * s)) : add(p, scale(w, Math.min(style.extensionOffset * s, gap))),
|
|
7551
|
+
b: add(f, scale(w, style.extensionOvershoot * s))
|
|
7552
|
+
});
|
|
7553
|
+
});
|
|
7554
|
+
const dimLines = [];
|
|
7555
|
+
const arrows = [];
|
|
7556
|
+
const labels = [];
|
|
7557
|
+
const leaders = [];
|
|
7558
|
+
let stack = null;
|
|
7559
|
+
frames.forEach((frame, i) => {
|
|
7560
|
+
const L = frame.s1 - frame.s0;
|
|
7561
|
+
const value = L;
|
|
7562
|
+
const mode = frames.length === 1 || i === frames.length - 1 ? "end" : i === 0 ? "start" : "raise";
|
|
7563
|
+
const placed = placeLabel(
|
|
7564
|
+
frame,
|
|
7565
|
+
obj.labels[i],
|
|
7566
|
+
i,
|
|
7567
|
+
dimLabelContent(
|
|
7568
|
+
obj.kind,
|
|
7569
|
+
obj.labels[i],
|
|
7570
|
+
formatDimValue(value, style.precision)
|
|
7571
|
+
),
|
|
7572
|
+
style,
|
|
7573
|
+
2,
|
|
7574
|
+
mode,
|
|
7575
|
+
stack
|
|
7576
|
+
);
|
|
7577
|
+
stack = placed.row > 0 ? {
|
|
7578
|
+
row: placed.row,
|
|
7579
|
+
interval: [
|
|
7580
|
+
placed.text.along - placed.text.width / 2,
|
|
7581
|
+
placed.text.along + placed.text.width / 2
|
|
7582
|
+
]
|
|
7583
|
+
} : null;
|
|
7584
|
+
labels.push(placed.text);
|
|
7585
|
+
leaders.push(...placed.leaders);
|
|
7586
|
+
const a = frame.toWorld(frame.s0, 0);
|
|
7587
|
+
const b = frame.toWorld(frame.s1, 0);
|
|
7588
|
+
const arrowsInside = L >= 2 * A - 1e-9;
|
|
7589
|
+
let from = frame.s0;
|
|
7590
|
+
let to = frame.s1;
|
|
7591
|
+
if (!arrowsInside) {
|
|
7592
|
+
from -= 2 * A;
|
|
7593
|
+
to += 2 * A;
|
|
7594
|
+
}
|
|
7595
|
+
if (placed.cover) {
|
|
7596
|
+
from = Math.min(from, placed.cover[0]);
|
|
7597
|
+
to = Math.max(to, placed.cover[1]);
|
|
7598
|
+
}
|
|
7599
|
+
dimLines.push({ a: frame.toWorld(from, 0), b: frame.toWorld(to, 0) });
|
|
7600
|
+
arrows.push(
|
|
7601
|
+
arrowsInside ? { tip: a, toward: b, size: A } : { tip: a, toward: frame.toWorld(from, 0), size: A },
|
|
7602
|
+
arrowsInside ? { tip: b, toward: a, size: A } : { tip: b, toward: frame.toWorld(to, 0), size: A }
|
|
7603
|
+
);
|
|
7604
|
+
});
|
|
7605
|
+
return {
|
|
7606
|
+
extensionLines,
|
|
7607
|
+
dimLines,
|
|
7608
|
+
dimArc: null,
|
|
7609
|
+
leaders,
|
|
7610
|
+
arrows,
|
|
7611
|
+
arrowType: style.arrowType,
|
|
7612
|
+
labels,
|
|
7613
|
+
value: Math.abs(dot(sub(feet[feet.length - 1], feet[0]), u))
|
|
7614
|
+
};
|
|
7615
|
+
};
|
|
7616
|
+
var angularGeometry = (obj, style) => {
|
|
7617
|
+
const polar2 = angularFrame(obj);
|
|
7618
|
+
if (!polar2) return null;
|
|
7619
|
+
const { vertex, radius, start, sweep, frame } = polar2;
|
|
7620
|
+
const s = style.scale;
|
|
7621
|
+
const A = style.arrowSize * s;
|
|
7622
|
+
const [, a, b] = obj.points;
|
|
7623
|
+
const extensionLines = [];
|
|
7624
|
+
for (const p of [a, b]) {
|
|
7625
|
+
const d = dist(vertex, p);
|
|
7626
|
+
const w = norm(sub(p, vertex));
|
|
7627
|
+
const inner = style.extensionType === "short" ? radius - style.extensionOvershoot * s : Math.min(d + style.extensionOffset * s, radius);
|
|
7628
|
+
const outer = radius + style.extensionOvershoot * s;
|
|
7629
|
+
if (outer - inner > 1e-9)
|
|
7630
|
+
extensionLines.push({
|
|
7631
|
+
a: add(vertex, scale(w, inner)),
|
|
7632
|
+
b: add(vertex, scale(w, outer))
|
|
7633
|
+
});
|
|
7634
|
+
}
|
|
7635
|
+
const placed = placeLabel(
|
|
7636
|
+
frame,
|
|
7637
|
+
obj.labels[0],
|
|
7638
|
+
0,
|
|
7639
|
+
dimLabelContent(
|
|
7640
|
+
obj.kind,
|
|
7641
|
+
obj.labels[0],
|
|
7642
|
+
formatDimValue(sweep * RAD2DEG, style.precision)
|
|
7643
|
+
),
|
|
7644
|
+
style,
|
|
7645
|
+
2,
|
|
7646
|
+
"end",
|
|
7647
|
+
null
|
|
7648
|
+
);
|
|
7649
|
+
const L = frame.s1;
|
|
7650
|
+
const arrowsInside = L >= 2 * A - 1e-9;
|
|
7651
|
+
let from = 0;
|
|
7652
|
+
let to = L;
|
|
7653
|
+
if (!arrowsInside) {
|
|
7654
|
+
from -= 2 * A;
|
|
7655
|
+
to += 2 * A;
|
|
7656
|
+
}
|
|
7657
|
+
if (placed.cover) {
|
|
7658
|
+
from = Math.min(from, placed.cover[0]);
|
|
7659
|
+
to = Math.max(to, placed.cover[1]);
|
|
7660
|
+
}
|
|
7661
|
+
const step = Math.min(sweep / 3, A * 2 / radius) * radius;
|
|
7662
|
+
const at = (along) => frame.toWorld(along, 0);
|
|
7663
|
+
return {
|
|
7664
|
+
extensionLines,
|
|
7665
|
+
dimLines: [],
|
|
7666
|
+
dimArc: {
|
|
7667
|
+
center: vertex,
|
|
7668
|
+
radius,
|
|
7669
|
+
startAngle: start + from / radius,
|
|
7670
|
+
endAngle: start + to / radius
|
|
7671
|
+
},
|
|
7672
|
+
leaders: placed.leaders,
|
|
7673
|
+
arrows: [
|
|
7674
|
+
{ tip: at(0), toward: at(arrowsInside ? step : -step), size: A },
|
|
7675
|
+
{ tip: at(L), toward: at(arrowsInside ? L - step : L + step), size: A }
|
|
7676
|
+
],
|
|
7677
|
+
arrowType: style.arrowType,
|
|
7678
|
+
labels: [placed.text],
|
|
7679
|
+
value: sweep
|
|
7680
|
+
};
|
|
7681
|
+
};
|
|
7682
|
+
var radialGeometry = (obj, style) => {
|
|
7683
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7684
|
+
if (!frame) return null;
|
|
7685
|
+
const s = style.scale;
|
|
7686
|
+
const A = style.arrowSize * s;
|
|
7687
|
+
const [center, p] = obj.points;
|
|
7688
|
+
const r = frame.s1;
|
|
7689
|
+
const spec = obj.labels[0];
|
|
7690
|
+
const content = dimLabelContent(
|
|
7691
|
+
obj.kind,
|
|
7692
|
+
spec,
|
|
7693
|
+
formatDimValue(r, style.precision)
|
|
7694
|
+
);
|
|
7695
|
+
const width = labelWidth(
|
|
7696
|
+
content,
|
|
7697
|
+
style.textHeight * s,
|
|
7698
|
+
dimFontFace(style),
|
|
7699
|
+
style.widthFactor
|
|
7700
|
+
);
|
|
7701
|
+
const gap = style.textOffset * s;
|
|
7702
|
+
const autoInside = spec?.along === void 0 && r >= width + 2 * gap + A - 1e-9 ? { ...spec, along: r - A - gap - width / 2 } : spec;
|
|
7703
|
+
const placed = placeLabel(
|
|
7704
|
+
frame,
|
|
7705
|
+
autoInside,
|
|
7706
|
+
0,
|
|
7707
|
+
content,
|
|
7708
|
+
style,
|
|
7709
|
+
1,
|
|
7710
|
+
"end",
|
|
7711
|
+
null
|
|
7712
|
+
);
|
|
7713
|
+
const outside = placed.text.along > r + 1e-9;
|
|
7714
|
+
let to = r;
|
|
7715
|
+
if (placed.cover) to = Math.max(to, placed.cover[1]);
|
|
7716
|
+
return {
|
|
7717
|
+
extensionLines: [],
|
|
7718
|
+
dimLines: [{ a: center, b: frame.toWorld(to, 0) }],
|
|
7719
|
+
dimArc: null,
|
|
7720
|
+
leaders: placed.leaders,
|
|
7721
|
+
// Head at the curve: pointing outward with the text inside, inward
|
|
7722
|
+
// (body on the outside) with the text outside.
|
|
7723
|
+
arrows: [
|
|
7724
|
+
{ tip: p, toward: outside ? frame.toWorld(r + A, 0) : center, size: A }
|
|
7725
|
+
],
|
|
7726
|
+
arrowType: style.arrowType,
|
|
7727
|
+
labels: [placed.text],
|
|
7728
|
+
value: r
|
|
7729
|
+
};
|
|
7730
|
+
};
|
|
7731
|
+
var diameterGeometry = (obj, style) => {
|
|
7732
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7733
|
+
if (!frame) return null;
|
|
7734
|
+
const s = style.scale;
|
|
7735
|
+
const A = style.arrowSize * s;
|
|
7736
|
+
const [p1, p2] = obj.points;
|
|
7737
|
+
const d = frame.s1 - frame.s0;
|
|
7738
|
+
const placed = placeLabel(
|
|
7739
|
+
frame,
|
|
7740
|
+
obj.labels[0],
|
|
7741
|
+
0,
|
|
7742
|
+
dimLabelContent(
|
|
7743
|
+
obj.kind,
|
|
7744
|
+
obj.labels[0],
|
|
7745
|
+
formatDimValue(d, style.precision)
|
|
7746
|
+
),
|
|
7747
|
+
style,
|
|
7748
|
+
2,
|
|
7749
|
+
"end",
|
|
7750
|
+
null
|
|
7751
|
+
);
|
|
7752
|
+
const arrowsInside = d >= 2 * A - 1e-9;
|
|
7753
|
+
let from = frame.s0;
|
|
7754
|
+
let to = frame.s1;
|
|
7755
|
+
if (!arrowsInside) {
|
|
7756
|
+
from -= 2 * A;
|
|
7757
|
+
to += 2 * A;
|
|
7758
|
+
}
|
|
7759
|
+
if (placed.cover) {
|
|
7760
|
+
from = Math.min(from, placed.cover[0]);
|
|
7761
|
+
to = Math.max(to, placed.cover[1]);
|
|
7762
|
+
}
|
|
7763
|
+
return {
|
|
7764
|
+
extensionLines: [],
|
|
7765
|
+
dimLines: [{ a: frame.toWorld(from, 0), b: frame.toWorld(to, 0) }],
|
|
7766
|
+
dimArc: null,
|
|
7767
|
+
leaders: placed.leaders,
|
|
7768
|
+
arrows: arrowsInside ? [
|
|
7769
|
+
{ tip: p1, toward: p2, size: A },
|
|
7770
|
+
{ tip: p2, toward: p1, size: A }
|
|
7771
|
+
] : [
|
|
7772
|
+
{ tip: p1, toward: frame.toWorld(from, 0), size: A },
|
|
7773
|
+
{ tip: p2, toward: frame.toWorld(to, 0), size: A }
|
|
7774
|
+
],
|
|
7775
|
+
arrowType: style.arrowType,
|
|
7776
|
+
labels: [placed.text],
|
|
7777
|
+
value: d
|
|
7778
|
+
};
|
|
7779
|
+
};
|
|
7780
|
+
var dimensionGeometry = (obj, styles) => {
|
|
7781
|
+
const style = resolveDimStyle(obj, styles);
|
|
7782
|
+
switch (obj.kind) {
|
|
7783
|
+
case "linear":
|
|
7784
|
+
return linearGeometry(obj, style);
|
|
7785
|
+
case "angular":
|
|
7786
|
+
return angularGeometry(obj, style);
|
|
7787
|
+
case "radial":
|
|
7788
|
+
return radialGeometry(obj, style);
|
|
7789
|
+
case "diameter":
|
|
7790
|
+
return diameterGeometry(obj, style);
|
|
7791
|
+
}
|
|
7792
|
+
};
|
|
7793
|
+
|
|
6287
7794
|
// ../core/src/paint/textGeometry.ts
|
|
6288
7795
|
var textHeight = (obj, textStyles) => (obj.styleOverride?.textHeight ?? textStyleFor(obj, textStyles).textHeight) * obj.scale;
|
|
6289
7796
|
var textArrowSize = (obj, textStyles) => (obj.styleOverride?.arrowSize ?? textStyleFor(obj, textStyles).arrowSize) * obj.scale;
|
|
@@ -6292,11 +7799,24 @@ var textWidth = (obj) => obj.width === void 0 ? void 0 : obj.width * obj.scale;
|
|
|
6292
7799
|
var FRAME_MARGIN_FACTOR = 0.35;
|
|
6293
7800
|
var textBoxLocal = (obj, measure, textStyles) => {
|
|
6294
7801
|
const { font, widthFactor } = effectiveTextFont(obj, textStyles);
|
|
6295
|
-
const
|
|
6296
|
-
|
|
7802
|
+
const block = obj.spans?.length ? (
|
|
7803
|
+
// Formatted: per-run fonts, so the measurer stays unbound.
|
|
7804
|
+
richTextBlock(
|
|
7805
|
+
obj.content,
|
|
7806
|
+
obj.spans,
|
|
7807
|
+
{
|
|
7808
|
+
face: font,
|
|
7809
|
+
heightMm: textHeight(obj, textStyles),
|
|
7810
|
+
widthFactor
|
|
7811
|
+
},
|
|
7812
|
+
measure,
|
|
7813
|
+
approximateTextMeasurer,
|
|
7814
|
+
textWidth(obj)
|
|
7815
|
+
)
|
|
7816
|
+
) : textBlock(
|
|
6297
7817
|
obj.content,
|
|
6298
7818
|
textHeight(obj, textStyles),
|
|
6299
|
-
|
|
7819
|
+
boundMeasurer(measure, font, widthFactor),
|
|
6300
7820
|
textWidth(obj)
|
|
6301
7821
|
);
|
|
6302
7822
|
const u = fromAngle(obj.rotation);
|
|
@@ -6397,7 +7917,7 @@ var cellText = (t, row, col) => {
|
|
|
6397
7917
|
id: `${t.id}:${row}:${col}`,
|
|
6398
7918
|
layerId: t.layerId,
|
|
6399
7919
|
position: { x: 0, y: 0 },
|
|
6400
|
-
content: cell.
|
|
7920
|
+
content: cell.content,
|
|
6401
7921
|
leaderLines: [],
|
|
6402
7922
|
hAlign: "center",
|
|
6403
7923
|
vAlign: "center",
|
|
@@ -6441,6 +7961,18 @@ var cellAnchor = (t, colX, rowY, a) => {
|
|
|
6441
7961
|
vAlign: v
|
|
6442
7962
|
};
|
|
6443
7963
|
};
|
|
7964
|
+
var tableCellFrame = (t, textStyles, row, col) => {
|
|
7965
|
+
const { colX, rowY, anchors } = tableLayout(t, textStyles);
|
|
7966
|
+
const a = anchors.find(
|
|
7967
|
+
(a2) => row >= a2.row && row < a2.row + a2.rows && col >= a2.col && col < a2.col + a2.cols
|
|
7968
|
+
) ?? { row, col, rows: 1, cols: 1 };
|
|
7969
|
+
return {
|
|
7970
|
+
row: a.row,
|
|
7971
|
+
col: a.col,
|
|
7972
|
+
text: { ...cellText(t, a.row, a.col), ...cellAnchor(t, colX, rowY, a) },
|
|
7973
|
+
innerWidth: colX[a.col + a.cols] - colX[a.col] - 2 * t.cellMargin * t.scale
|
|
7974
|
+
};
|
|
7975
|
+
};
|
|
6444
7976
|
var cache = /* @__PURE__ */ new WeakMap();
|
|
6445
7977
|
var tableLayout = (t, textStyles) => {
|
|
6446
7978
|
const hit = cache.get(t);
|
|
@@ -6462,9 +7994,32 @@ var tableLayout = (t, textStyles) => {
|
|
|
6462
7994
|
const h = textHeight(text, textStyles);
|
|
6463
7995
|
const { font, widthFactor } = effectiveTextFont(text, textStyles);
|
|
6464
7996
|
const inner2 = colX[c + cols] - colX[c] - 2 * margin;
|
|
7997
|
+
if (cell.spans?.length) {
|
|
7998
|
+
const rich = richTextBlock(
|
|
7999
|
+
cell.content,
|
|
8000
|
+
cell.spans,
|
|
8001
|
+
{ face: font, heightMm: h, widthFactor },
|
|
8002
|
+
approximateTextMeasurer,
|
|
8003
|
+
approximateTextMeasurer,
|
|
8004
|
+
inner2 > 0 ? inner2 : void 0
|
|
8005
|
+
);
|
|
8006
|
+
let content = "";
|
|
8007
|
+
const spans = [];
|
|
8008
|
+
rich.lines.forEach((l, k) => {
|
|
8009
|
+
if (k > 0) content += "\n";
|
|
8010
|
+
spans.push(...sliceSpans(cell.spans, l.start, l.end, content.length));
|
|
8011
|
+
content += cell.content.slice(l.start, l.end);
|
|
8012
|
+
});
|
|
8013
|
+
wrapped.push({
|
|
8014
|
+
text: { ...text, spans },
|
|
8015
|
+
lines: [content],
|
|
8016
|
+
height: rich.height + 2 * margin
|
|
8017
|
+
});
|
|
8018
|
+
return;
|
|
8019
|
+
}
|
|
6465
8020
|
const measure = boundMeasurer(approximateTextMeasurer, font, widthFactor);
|
|
6466
8021
|
const block = textBlock(
|
|
6467
|
-
cell.
|
|
8022
|
+
cell.content,
|
|
6468
8023
|
h,
|
|
6469
8024
|
measure,
|
|
6470
8025
|
inner2 > 0 ? inner2 : void 0
|
|
@@ -6474,7 +8029,7 @@ var tableLayout = (t, textStyles) => {
|
|
|
6474
8029
|
text,
|
|
6475
8030
|
lines,
|
|
6476
8031
|
// An empty cell still reserves one line of its text height.
|
|
6477
|
-
height: (cell.
|
|
8032
|
+
height: (cell.content ? h + (lines.length - 1) * block.lineHeight : h) + 2 * margin
|
|
6478
8033
|
});
|
|
6479
8034
|
})
|
|
6480
8035
|
);
|
|
@@ -6553,7 +8108,7 @@ var tableLayout = (t, textStyles) => {
|
|
|
6553
8108
|
}));
|
|
6554
8109
|
anchors.forEach((a, i) => {
|
|
6555
8110
|
const { text, lines } = wrapped[i];
|
|
6556
|
-
if (!t.cells[a.row][a.col].
|
|
8111
|
+
if (!t.cells[a.row][a.col].content) return;
|
|
6557
8112
|
children.push({
|
|
6558
8113
|
...text,
|
|
6559
8114
|
...cellAnchor(t, colX, rowY, a),
|
|
@@ -6869,6 +8424,303 @@ var hexToTrueColor = (hex) => {
|
|
|
6869
8424
|
return rgb ? rgb[0] << 16 | rgb[1] << 8 | rgb[2] : null;
|
|
6870
8425
|
};
|
|
6871
8426
|
|
|
8427
|
+
// ../core/src/export/dxf/codecs.ts
|
|
8428
|
+
var LINE_WEIGHTS = [
|
|
8429
|
+
0,
|
|
8430
|
+
5,
|
|
8431
|
+
9,
|
|
8432
|
+
13,
|
|
8433
|
+
15,
|
|
8434
|
+
18,
|
|
8435
|
+
20,
|
|
8436
|
+
25,
|
|
8437
|
+
30,
|
|
8438
|
+
35,
|
|
8439
|
+
40,
|
|
8440
|
+
50,
|
|
8441
|
+
53,
|
|
8442
|
+
60,
|
|
8443
|
+
70,
|
|
8444
|
+
80,
|
|
8445
|
+
90,
|
|
8446
|
+
100,
|
|
8447
|
+
106,
|
|
8448
|
+
120,
|
|
8449
|
+
140,
|
|
8450
|
+
158,
|
|
8451
|
+
200,
|
|
8452
|
+
211
|
|
8453
|
+
];
|
|
8454
|
+
var lineWeightToMm = (lineWeight) => lineWeight === void 0 || lineWeight < 0 ? void 0 : Math.max(lineWeight, 5) / 100;
|
|
8455
|
+
var mmToLineWeight = (mm) => LINE_WEIGHTS.reduce(
|
|
8456
|
+
(best, w) => Math.abs(w - mm * 100) < Math.abs(best - mm * 100) ? w : best
|
|
8457
|
+
);
|
|
8458
|
+
var encodeMtext = (s) => s.replace(/\r\n/g, "\n").replace(/\r/g, "").replace(/\\/g, "\\\\").replace(/\{/g, "\\{").replace(/\}/g, "\\}").replace(/\^/g, "^ ").replace(/\n/g, "\\P").replace(/\t/g, "^I");
|
|
8459
|
+
var decodeTextEscapes = (text) => text.replace(/%%([dpcuo%])/gi, (_, ch) => {
|
|
8460
|
+
switch (ch.toLowerCase()) {
|
|
8461
|
+
case "d":
|
|
8462
|
+
return "\xB0";
|
|
8463
|
+
case "p":
|
|
8464
|
+
return "\xB1";
|
|
8465
|
+
case "c":
|
|
8466
|
+
return "\xD8";
|
|
8467
|
+
case "u":
|
|
8468
|
+
case "o":
|
|
8469
|
+
return "";
|
|
8470
|
+
default:
|
|
8471
|
+
return "%";
|
|
8472
|
+
}
|
|
8473
|
+
});
|
|
8474
|
+
var SUPERSCRIPT = {
|
|
8475
|
+
"0": "\u2070",
|
|
8476
|
+
"1": "\xB9",
|
|
8477
|
+
"2": "\xB2",
|
|
8478
|
+
"3": "\xB3",
|
|
8479
|
+
"4": "\u2074",
|
|
8480
|
+
"5": "\u2075",
|
|
8481
|
+
"6": "\u2076",
|
|
8482
|
+
"7": "\u2077",
|
|
8483
|
+
"8": "\u2078",
|
|
8484
|
+
"9": "\u2079",
|
|
8485
|
+
"+": "\u207A",
|
|
8486
|
+
"-": "\u207B",
|
|
8487
|
+
"=": "\u207C",
|
|
8488
|
+
"(": "\u207D",
|
|
8489
|
+
")": "\u207E",
|
|
8490
|
+
n: "\u207F",
|
|
8491
|
+
i: "\u2071"
|
|
8492
|
+
};
|
|
8493
|
+
var SUBSCRIPT = {
|
|
8494
|
+
"0": "\u2080",
|
|
8495
|
+
"1": "\u2081",
|
|
8496
|
+
"2": "\u2082",
|
|
8497
|
+
"3": "\u2083",
|
|
8498
|
+
"4": "\u2084",
|
|
8499
|
+
"5": "\u2085",
|
|
8500
|
+
"6": "\u2086",
|
|
8501
|
+
"7": "\u2087",
|
|
8502
|
+
"8": "\u2088",
|
|
8503
|
+
"9": "\u2089",
|
|
8504
|
+
"+": "\u208A",
|
|
8505
|
+
"-": "\u208B",
|
|
8506
|
+
"=": "\u208C",
|
|
8507
|
+
"(": "\u208D",
|
|
8508
|
+
")": "\u208E"
|
|
8509
|
+
};
|
|
8510
|
+
var toScript = (s, map) => [...s].every((c) => map[c]) ? [...s].map((c) => map[c]).join("") : s;
|
|
8511
|
+
var stackText = (body) => {
|
|
8512
|
+
const m = /^(.*?)([\^#/])(.*)$/s.exec(body);
|
|
8513
|
+
if (!m) return body;
|
|
8514
|
+
const top = m[1].trim();
|
|
8515
|
+
const bottom = m[3].trim();
|
|
8516
|
+
if (top && !bottom) return toScript(top, SUPERSCRIPT);
|
|
8517
|
+
if (!top && bottom) return toScript(bottom, SUBSCRIPT);
|
|
8518
|
+
return `${top}/${bottom}`;
|
|
8519
|
+
};
|
|
8520
|
+
var SYMBOL_FONT = {
|
|
8521
|
+
a: "\u03B1",
|
|
8522
|
+
b: "\u03B2",
|
|
8523
|
+
c: "\u03C7",
|
|
8524
|
+
d: "\u03B4",
|
|
8525
|
+
e: "\u03B5",
|
|
8526
|
+
f: "\u03C6",
|
|
8527
|
+
g: "\u03B3",
|
|
8528
|
+
h: "\u03B7",
|
|
8529
|
+
i: "\u03B9",
|
|
8530
|
+
k: "\u03BA",
|
|
8531
|
+
l: "\u03BB",
|
|
8532
|
+
m: "\u03BC",
|
|
8533
|
+
n: "\u03BD",
|
|
8534
|
+
p: "\u03C0",
|
|
8535
|
+
q: "\u03B8",
|
|
8536
|
+
r: "\u03C1",
|
|
8537
|
+
s: "\u03C3",
|
|
8538
|
+
t: "\u03C4",
|
|
8539
|
+
u: "\u03C5",
|
|
8540
|
+
w: "\u03C9",
|
|
8541
|
+
x: "\u03BE",
|
|
8542
|
+
y: "\u03C8",
|
|
8543
|
+
z: "\u03B6",
|
|
8544
|
+
D: "\u0394",
|
|
8545
|
+
F: "\u03A6",
|
|
8546
|
+
G: "\u0393",
|
|
8547
|
+
L: "\u039B",
|
|
8548
|
+
P: "\u03A0",
|
|
8549
|
+
Q: "\u0398",
|
|
8550
|
+
S: "\u03A3",
|
|
8551
|
+
W: "\u03A9",
|
|
8552
|
+
X: "\u039E",
|
|
8553
|
+
Y: "\u03A8",
|
|
8554
|
+
"\xA3": "\u2264",
|
|
8555
|
+
"\xB3": "\u2265",
|
|
8556
|
+
"\xB9": "\u2260",
|
|
8557
|
+
"\xBB": "\u2248",
|
|
8558
|
+
"\xA5": "\u221E",
|
|
8559
|
+
"\xB4": "\xD7",
|
|
8560
|
+
"\xB8": "\xF7",
|
|
8561
|
+
\u00D6: "\u221A",
|
|
8562
|
+
"\xAE": "\u2192",
|
|
8563
|
+
"\xAC": "\u2190",
|
|
8564
|
+
\u00C6: "\u2205",
|
|
8565
|
+
\u00CE: "\u2208",
|
|
8566
|
+
"\xB6": "\u2202"
|
|
8567
|
+
};
|
|
8568
|
+
var isSymbolFont = (fontCode) => /^symbol(\.ttf)?$/i.test(fontCode.split("|")[0].trim());
|
|
8569
|
+
var scanMtext = (text, opts) => {
|
|
8570
|
+
const chunks = [];
|
|
8571
|
+
let st = { symbol: false };
|
|
8572
|
+
const stack = [];
|
|
8573
|
+
const attrs = (extra) => opts ? {
|
|
8574
|
+
...st.font !== void 0 ? { font: st.font } : {},
|
|
8575
|
+
...st.bold !== void 0 ? { bold: st.bold } : {},
|
|
8576
|
+
...st.italic !== void 0 ? { italic: st.italic } : {},
|
|
8577
|
+
...st.height !== void 0 ? { height: st.height } : {},
|
|
8578
|
+
...st.color !== void 0 ? { color: st.color } : {},
|
|
8579
|
+
...st.underline ? { underline: true } : {},
|
|
8580
|
+
...extra
|
|
8581
|
+
} : {};
|
|
8582
|
+
const emit = (t, extra) => {
|
|
8583
|
+
if (!t) return;
|
|
8584
|
+
const a = attrs(extra);
|
|
8585
|
+
const last = chunks[chunks.length - 1];
|
|
8586
|
+
if (!extra && last && JSON.stringify(last.attrs) === JSON.stringify(a))
|
|
8587
|
+
last.text += t;
|
|
8588
|
+
else chunks.push({ text: t, attrs: a });
|
|
8589
|
+
};
|
|
8590
|
+
const codeBody = (i2) => {
|
|
8591
|
+
const end = text.indexOf(";", i2);
|
|
8592
|
+
return end === -1 ? ["", i2] : [text.slice(i2, end), end + 1];
|
|
8593
|
+
};
|
|
8594
|
+
let i = 0;
|
|
8595
|
+
while (i < text.length) {
|
|
8596
|
+
const ch = text[i];
|
|
8597
|
+
if (ch === "{") {
|
|
8598
|
+
stack.push(st);
|
|
8599
|
+
st = { ...st };
|
|
8600
|
+
i++;
|
|
8601
|
+
} else if (ch === "}") {
|
|
8602
|
+
st = stack.pop() ?? st;
|
|
8603
|
+
i++;
|
|
8604
|
+
} else if (ch !== "\\") {
|
|
8605
|
+
emit(st.symbol ? SYMBOL_FONT[ch] ?? ch : ch);
|
|
8606
|
+
i++;
|
|
8607
|
+
} else {
|
|
8608
|
+
const next = text[i + 1] ?? "";
|
|
8609
|
+
if (next === "\\" || next === "{" || next === "}") {
|
|
8610
|
+
emit(next);
|
|
8611
|
+
i += 2;
|
|
8612
|
+
} else if (next === "P") {
|
|
8613
|
+
emit("\n");
|
|
8614
|
+
i += 2;
|
|
8615
|
+
} else if (next === "~") {
|
|
8616
|
+
emit(" ");
|
|
8617
|
+
i += 2;
|
|
8618
|
+
} else if (next === "L" || next === "l") {
|
|
8619
|
+
st = { ...st, underline: next === "L" };
|
|
8620
|
+
i += 2;
|
|
8621
|
+
} else if ("OoKk".includes(next)) {
|
|
8622
|
+
i += 2;
|
|
8623
|
+
} else if (next === "S") {
|
|
8624
|
+
const [body, at] = codeBody(i + 2);
|
|
8625
|
+
const m = /^(.*?)([\^#/])(.*)$/s.exec(body);
|
|
8626
|
+
const top = m?.[1].trim() ?? "";
|
|
8627
|
+
const bottom = m?.[3].trim() ?? "";
|
|
8628
|
+
if (opts && m && m[2] === "^" && top && !bottom)
|
|
8629
|
+
emit(top, { script: "super" });
|
|
8630
|
+
else if (opts && m && m[2] === "^" && !top && bottom)
|
|
8631
|
+
emit(bottom, { script: "sub" });
|
|
8632
|
+
else emit(stackText(body));
|
|
8633
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8634
|
+
} else if ((next === "U" || next === "u") && /^\+[0-9a-fA-F]{4}/.test(text.slice(i + 2, i + 7))) {
|
|
8635
|
+
emit(String.fromCodePoint(parseInt(text.slice(i + 3, i + 7), 16)));
|
|
8636
|
+
i += 7;
|
|
8637
|
+
} else if (next === "f" || next === "F") {
|
|
8638
|
+
const [body, at] = codeBody(i + 2);
|
|
8639
|
+
st = { ...st, symbol: isSymbolFont(body) };
|
|
8640
|
+
if (opts && !st.symbol && body) {
|
|
8641
|
+
const [name, ...flags] = body.split("|");
|
|
8642
|
+
const file = name.includes(".");
|
|
8643
|
+
const face = fontFromDxfStyle(
|
|
8644
|
+
file ? name : void 0,
|
|
8645
|
+
file ? void 0 : name
|
|
8646
|
+
);
|
|
8647
|
+
const flag = (k) => flags.find((f) => f[0] === k)?.slice(1);
|
|
8648
|
+
st.font = face.font;
|
|
8649
|
+
st.bold = flag("b") !== void 0 ? flag("b") === "1" : face.bold;
|
|
8650
|
+
st.italic = flag("i") !== void 0 ? flag("i") === "1" : face.italic;
|
|
8651
|
+
}
|
|
8652
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8653
|
+
} else if (opts && next === "H") {
|
|
8654
|
+
const [body, at] = codeBody(i + 2);
|
|
8655
|
+
const v = Number.parseFloat(body);
|
|
8656
|
+
if (Number.isFinite(v) && v > 0)
|
|
8657
|
+
st = {
|
|
8658
|
+
...st,
|
|
8659
|
+
height: /x$/i.test(body) ? (st.height ?? 1) * v : v / (opts.heightMm > 0 ? opts.heightMm : v)
|
|
8660
|
+
};
|
|
8661
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8662
|
+
} else if (opts && next === "C") {
|
|
8663
|
+
const [body, at] = codeBody(i + 2);
|
|
8664
|
+
st = { ...st, color: aciToHex(Number.parseInt(body, 10)) };
|
|
8665
|
+
i = at === i + 2 ? i + 2 : at;
|
|
8666
|
+
} else {
|
|
8667
|
+
const end = text.indexOf(";", i + 1);
|
|
8668
|
+
i = end === -1 ? i + 2 : end + 1;
|
|
8669
|
+
}
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8672
|
+
return chunks;
|
|
8673
|
+
};
|
|
8674
|
+
var stripMtextCodes = (text) => scanMtext(text).map((c) => c.text).join("");
|
|
8675
|
+
var mtextWidthFactor = (text) => {
|
|
8676
|
+
const m = /\\W([0-9.]+);/.exec(text);
|
|
8677
|
+
const v = m ? Number(m[1]) : NaN;
|
|
8678
|
+
return Number.isFinite(v) && v > 0 && v !== 1 ? v : void 0;
|
|
8679
|
+
};
|
|
8680
|
+
var mtextFontFlags = (text) => {
|
|
8681
|
+
const m = /\\f[^|;]*((?:\|[a-z]\d+)*)/.exec(text);
|
|
8682
|
+
if (!m) return {};
|
|
8683
|
+
return {
|
|
8684
|
+
.../\|b1/.test(m[1]) ? { bold: true } : {},
|
|
8685
|
+
.../\|i1/.test(m[1]) ? { italic: true } : {}
|
|
8686
|
+
};
|
|
8687
|
+
};
|
|
8688
|
+
var decodeControlCodes = (text) => text.replace(
|
|
8689
|
+
/\^M\^J|\^[IJM ]|\r\n?/g,
|
|
8690
|
+
(m) => m === "^I" ? " " : m === "^ " ? "^" : "\n"
|
|
8691
|
+
);
|
|
8692
|
+
var cleanText = (raw, mtext) => decodeControlCodes(decodeTextEscapes(mtext ? stripMtextCodes(raw) : raw));
|
|
8693
|
+
var cleanRichText = (raw, heightMm) => {
|
|
8694
|
+
let content = "";
|
|
8695
|
+
const spans = [];
|
|
8696
|
+
for (const c of scanMtext(raw, { heightMm })) {
|
|
8697
|
+
const text = decodeControlCodes(decodeTextEscapes(c.text));
|
|
8698
|
+
spans.push({
|
|
8699
|
+
start: content.length,
|
|
8700
|
+
end: content.length + text.length,
|
|
8701
|
+
...c.attrs
|
|
8702
|
+
});
|
|
8703
|
+
content += text;
|
|
8704
|
+
}
|
|
8705
|
+
return { content, spans: normalizeSpans(spans, content) };
|
|
8706
|
+
};
|
|
8707
|
+
var encodeStack = (s) => encodeMtext(s).replace(/[#/;]/g, (c) => `\\${c}`);
|
|
8708
|
+
var encodeRichMtext = (content, spans, face) => {
|
|
8709
|
+
const base = parseFontFace(face);
|
|
8710
|
+
let out = "";
|
|
8711
|
+
let at = 0;
|
|
8712
|
+
for (const s of normalizeSpans(spans, content)) {
|
|
8713
|
+
out += encodeMtext(content.slice(at, s.start));
|
|
8714
|
+
const fontCode = s.font !== void 0 || s.bold !== void 0 || s.italic !== void 0 ? `\\f${fontTypeface(resolveFont(s.font ?? base.font))}|b${s.bold ?? base.bold ? 1 : 0}|i${s.italic ?? base.italic ? 1 : 0};` : "";
|
|
8715
|
+
const codes = fontCode + (s.height !== void 0 ? `\\H${s.height}x;` : "") + (s.color ? `\\C${nearestAci(s.color)};` : "") + (s.underline ? "\\L" : "");
|
|
8716
|
+
const body = content.slice(s.start, s.end);
|
|
8717
|
+
const text = s.script && !/[\n\t]/.test(body) ? s.script === "super" ? `\\S${encodeStack(body)}^;` : `\\S^${encodeStack(body)};` : encodeMtext(body);
|
|
8718
|
+
out += codes || s.script ? `{${codes}${text}}` : text;
|
|
8719
|
+
at = s.end;
|
|
8720
|
+
}
|
|
8721
|
+
return out + encodeMtext(content.slice(at));
|
|
8722
|
+
};
|
|
8723
|
+
|
|
6872
8724
|
// ../core/src/export/dxf/dxfExtras.ts
|
|
6873
8725
|
import { Point, DxfObject } from "@tarikjabiri/dxf";
|
|
6874
8726
|
var RAW_COLOR_BY_BLOCK = -1056964608;
|
|
@@ -7030,7 +8882,7 @@ var MultiLeaderEntity = class extends Point {
|
|
|
7030
8882
|
dx.push(45, 1);
|
|
7031
8883
|
dx.push(170, 1);
|
|
7032
8884
|
dx.push(90, RAW_COLOR_BY_BLOCK);
|
|
7033
|
-
dx.push(171,
|
|
8885
|
+
dx.push(171, a.attachment);
|
|
7034
8886
|
dx.push(172, 1);
|
|
7035
8887
|
dx.push(91, RAW_COLOR_NONE);
|
|
7036
8888
|
dx.push(141, 1.5);
|
|
@@ -7167,6 +9019,130 @@ var MLeaderStyleObject = class extends DxfObject {
|
|
|
7167
9019
|
dx.push(273, 9);
|
|
7168
9020
|
}
|
|
7169
9021
|
};
|
|
9022
|
+
var AcadTableEntity = class extends Point {
|
|
9023
|
+
args;
|
|
9024
|
+
constructor(args) {
|
|
9025
|
+
super(args.position.x, args.position.y, 0);
|
|
9026
|
+
this.args = args;
|
|
9027
|
+
this.type = "ACAD_TABLE";
|
|
9028
|
+
this.subclassMarker = "AcDbBlockReference";
|
|
9029
|
+
}
|
|
9030
|
+
dxfyChild(dx) {
|
|
9031
|
+
const a = this.args;
|
|
9032
|
+
dx.push(2, a.blockName);
|
|
9033
|
+
dx.push(10, a.position.x);
|
|
9034
|
+
dx.push(20, a.position.y);
|
|
9035
|
+
dx.push(30, 0);
|
|
9036
|
+
dx.push(100, "AcDbTable");
|
|
9037
|
+
dx.push(280, 0);
|
|
9038
|
+
dx.push(342, a.tableStyleHandle);
|
|
9039
|
+
dx.push(343, a.blockRecordHandle);
|
|
9040
|
+
dx.push(11, a.direction.x);
|
|
9041
|
+
dx.push(21, a.direction.y);
|
|
9042
|
+
dx.push(31, 0);
|
|
9043
|
+
dx.push(90, 22);
|
|
9044
|
+
dx.push(91, a.rowHeights.length);
|
|
9045
|
+
dx.push(92, a.colWidths.length);
|
|
9046
|
+
dx.push(93, 2);
|
|
9047
|
+
dx.push(94, 0);
|
|
9048
|
+
dx.push(95, 0);
|
|
9049
|
+
dx.push(96, 0);
|
|
9050
|
+
dx.push(281, 1);
|
|
9051
|
+
for (const h of a.rowHeights) dx.push(141, h);
|
|
9052
|
+
for (const w of a.colWidths) dx.push(142, w);
|
|
9053
|
+
for (const c of a.cells) {
|
|
9054
|
+
dx.push(171, 1);
|
|
9055
|
+
dx.push(172, 0);
|
|
9056
|
+
dx.push(173, c.merged ? 1 : 0);
|
|
9057
|
+
dx.push(174, 0);
|
|
9058
|
+
dx.push(175, c.cols);
|
|
9059
|
+
dx.push(176, c.rows);
|
|
9060
|
+
dx.push(91, 1);
|
|
9061
|
+
dx.push(178, 0);
|
|
9062
|
+
dx.push(145, 0);
|
|
9063
|
+
dx.push(170, c.alignment);
|
|
9064
|
+
dx.push(92, 0);
|
|
9065
|
+
dx.push(301, "CELL_VALUE");
|
|
9066
|
+
if (c.text === "") {
|
|
9067
|
+
dx.push(93, 3);
|
|
9068
|
+
dx.push(90, 0);
|
|
9069
|
+
} else {
|
|
9070
|
+
dx.push(93, 6);
|
|
9071
|
+
dx.push(90, 4);
|
|
9072
|
+
dx.push(1, c.text);
|
|
9073
|
+
}
|
|
9074
|
+
dx.push(94, 0);
|
|
9075
|
+
dx.push(300, "");
|
|
9076
|
+
dx.push(302, c.text);
|
|
9077
|
+
dx.push(304, "ACVALUE_END");
|
|
9078
|
+
}
|
|
9079
|
+
}
|
|
9080
|
+
};
|
|
9081
|
+
var TableStyleObject = class extends DxfObject {
|
|
9082
|
+
args;
|
|
9083
|
+
constructor(args) {
|
|
9084
|
+
super("TABLESTYLE");
|
|
9085
|
+
this.args = args;
|
|
9086
|
+
}
|
|
9087
|
+
dxfy(dx) {
|
|
9088
|
+
const a = this.args;
|
|
9089
|
+
dx.push(0, "TABLESTYLE");
|
|
9090
|
+
dx.push(5, this.handle);
|
|
9091
|
+
dx.push(102, "{ACAD_REACTORS");
|
|
9092
|
+
dx.push(330, a.dictionaryHandle);
|
|
9093
|
+
dx.push(102, "}");
|
|
9094
|
+
dx.push(330, a.dictionaryHandle);
|
|
9095
|
+
dx.push(100, "AcDbTableStyle");
|
|
9096
|
+
dx.push(280, 0);
|
|
9097
|
+
dx.push(3, a.name);
|
|
9098
|
+
dx.push(70, 0);
|
|
9099
|
+
dx.push(71, 0);
|
|
9100
|
+
dx.push(40, a.margin);
|
|
9101
|
+
dx.push(41, a.margin);
|
|
9102
|
+
dx.push(280, 0);
|
|
9103
|
+
dx.push(281, 0);
|
|
9104
|
+
for (const [height, alignment] of [
|
|
9105
|
+
[a.textHeight, 2],
|
|
9106
|
+
[a.textHeight, 5],
|
|
9107
|
+
[a.textHeight, 5]
|
|
9108
|
+
]) {
|
|
9109
|
+
dx.push(7, a.textStyleName);
|
|
9110
|
+
dx.push(140, height);
|
|
9111
|
+
dx.push(170, alignment);
|
|
9112
|
+
dx.push(62, 0);
|
|
9113
|
+
dx.push(63, 7);
|
|
9114
|
+
dx.push(283, 0);
|
|
9115
|
+
dx.push(90, 4);
|
|
9116
|
+
dx.push(91, 0);
|
|
9117
|
+
dx.push(1, "");
|
|
9118
|
+
for (const [lw, vis, color] of [
|
|
9119
|
+
[274, 284, 64],
|
|
9120
|
+
[275, 285, 65],
|
|
9121
|
+
[276, 286, 66],
|
|
9122
|
+
[277, 287, 67],
|
|
9123
|
+
[278, 288, 68],
|
|
9124
|
+
[279, 289, 69]
|
|
9125
|
+
]) {
|
|
9126
|
+
dx.push(lw, -2);
|
|
9127
|
+
dx.push(vis, 1);
|
|
9128
|
+
dx.push(color, 0);
|
|
9129
|
+
}
|
|
9130
|
+
}
|
|
9131
|
+
}
|
|
9132
|
+
};
|
|
9133
|
+
var DXF_CLASSES = [
|
|
9134
|
+
["ACAD_TABLE", "AcDbTable", "ObjectDBX Classes", 1025, 1],
|
|
9135
|
+
["TABLESTYLE", "AcDbTableStyle", "ObjectDBX Classes", 4095, 0],
|
|
9136
|
+
["MULTILEADER", "AcDbMLeader", "ACDB_MLEADER_CLASS", 1025, 1],
|
|
9137
|
+
["MLEADERSTYLE", "AcDbMLeaderStyle", "ACDB_MLEADERSTYLE_CLASS", 4095, 0]
|
|
9138
|
+
];
|
|
9139
|
+
var classesSection = (content) => DXF_CLASSES.filter(([name]) => content.includes(`
|
|
9140
|
+
0
|
|
9141
|
+
${name}
|
|
9142
|
+
`)).map(
|
|
9143
|
+
([name, cpp, app, proxy, isEntity]) => [0, "CLASS", 1, name, 2, cpp, 3, app, 90, proxy, 91, 0, 280, 0, 281, isEntity].map((v) => `${v}
|
|
9144
|
+
`).join("")
|
|
9145
|
+
).join("");
|
|
7170
9146
|
|
|
7171
9147
|
// ../core/src/export/dxf/hatchPattern.ts
|
|
7172
9148
|
var ANSI31_BASE_SPACING = 3.175;
|
|
@@ -7187,17 +9163,35 @@ var mtextAttachment = (hAlign, vAlign) => {
|
|
|
7187
9163
|
const col = hAlign === "left" ? 1 : hAlign === "center" ? 2 : 3;
|
|
7188
9164
|
return row + col;
|
|
7189
9165
|
};
|
|
7190
|
-
var
|
|
7191
|
-
var dxfLineTypeName = (lineType) => {
|
|
9166
|
+
var dxfLineTypeName = (lineType, lineTypes) => {
|
|
7192
9167
|
if (!lineType) return void 0;
|
|
7193
|
-
const p =
|
|
9168
|
+
const p = resolveLineType(lineType, lineTypes);
|
|
7194
9169
|
if (!p || p.dashesMm.length === 0) return void 0;
|
|
7195
9170
|
return p.dxfName ?? p.name.toUpperCase();
|
|
7196
9171
|
};
|
|
7197
|
-
var
|
|
9172
|
+
var setLineWeight = (target, weight) => {
|
|
9173
|
+
const emit = target.dxfy.bind(target);
|
|
9174
|
+
target.dxfy = (dx) => {
|
|
9175
|
+
const start = dx.lines.length;
|
|
9176
|
+
emit(dx);
|
|
9177
|
+
const lines = dx.lines;
|
|
9178
|
+
for (let i = start; i < lines.length; i += 2)
|
|
9179
|
+
if (lines[i] === 370) {
|
|
9180
|
+
lines[i + 1] = weight;
|
|
9181
|
+
return;
|
|
9182
|
+
}
|
|
9183
|
+
let markers = 0;
|
|
9184
|
+
for (let i = start; i < lines.length; i += 2)
|
|
9185
|
+
if (lines[i] === 100 && ++markers === 2) {
|
|
9186
|
+
lines.splice(i, 0, 370, weight);
|
|
9187
|
+
return;
|
|
9188
|
+
}
|
|
9189
|
+
lines.push(370, weight);
|
|
9190
|
+
};
|
|
9191
|
+
};
|
|
7198
9192
|
var optionsFor = (obj, ctx) => {
|
|
7199
9193
|
const layer = ctx.doc.layers.find((l) => l.id === obj.layerId);
|
|
7200
|
-
const dashed = (
|
|
9194
|
+
const dashed = (resolveLineType(obj.lineType ?? layer?.lineType ?? "", ctx.doc.lineTypes)?.dashesMm.length ?? 0) > 0;
|
|
7201
9195
|
const lineTypeScale = (obj.lineTypeScale ?? 1) * (obj.lineWidth ?? layer?.lineWidth ?? 0.25);
|
|
7202
9196
|
const trueColor = obj.color ? hexToTrueColor(obj.color) : null;
|
|
7203
9197
|
return {
|
|
@@ -7206,7 +9200,7 @@ var optionsFor = (obj, ctx) => {
|
|
|
7206
9200
|
// color (420) which wins wherever it is supported.
|
|
7207
9201
|
...obj.color ? { colorNumber: nearestAci(obj.color) } : {},
|
|
7208
9202
|
...trueColor !== null ? { trueColor: String(trueColor) } : {},
|
|
7209
|
-
...dxfLineTypeName(obj.lineType) ? { lineType: dxfLineTypeName(obj.lineType) } : {},
|
|
9203
|
+
...dxfLineTypeName(obj.lineType, ctx.doc.lineTypes) ? { lineType: dxfLineTypeName(obj.lineType, ctx.doc.lineTypes) } : {},
|
|
7210
9204
|
...dashed && lineTypeScale !== 1 ? { lineTypeScale } : {}
|
|
7211
9205
|
};
|
|
7212
9206
|
};
|
|
@@ -7251,28 +9245,87 @@ var addArrowhead = (space, tip, toward, size, type, opts) => {
|
|
|
7251
9245
|
break;
|
|
7252
9246
|
}
|
|
7253
9247
|
};
|
|
7254
|
-
var
|
|
9248
|
+
var uniqueTableName = (taken, base) => {
|
|
9249
|
+
let name = base;
|
|
9250
|
+
for (let i = 2; taken.has(name.toUpperCase()); i++) name = `${base}_${i}`;
|
|
9251
|
+
taken.add(name.toUpperCase());
|
|
9252
|
+
return name;
|
|
9253
|
+
};
|
|
9254
|
+
var writableFace = (font) => {
|
|
7255
9255
|
const def = resolveFont(font);
|
|
7256
|
-
const { bold, italic } = parseFontFace(font);
|
|
7257
|
-
const
|
|
7258
|
-
const
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
}
|
|
9256
|
+
const { font: bare, bold, italic } = parseFontFace(font);
|
|
9257
|
+
const foreign = bare !== void 0 && bare !== "" && bare !== def.id;
|
|
9258
|
+
const fontId = foreign ? bare : def.id;
|
|
9259
|
+
return {
|
|
9260
|
+
face: fontFace(fontId, bold, italic),
|
|
9261
|
+
fontFile: foreign ? `${fontId}.ttf` : def.dxfFontFile,
|
|
9262
|
+
fontId,
|
|
9263
|
+
foreign
|
|
9264
|
+
};
|
|
9265
|
+
};
|
|
9266
|
+
var addStyleRecord = (ctx, key, name, font, widthFactor = 1, fixedHeight = 0) => {
|
|
9267
|
+
const { face, fontFile } = writableFace(font);
|
|
9268
|
+
const table = ctx.writer.document.tables.styleTable;
|
|
9269
|
+
const predefined = name.toUpperCase() === "STANDARD" && !ctx.styleNames.has("STANDARD") ? table.records.find((r) => r.name.toUpperCase() === "STANDARD") : void 0;
|
|
9270
|
+
const style = predefined ?? table.addStyle(uniqueTableName(ctx.styleNames, name));
|
|
9271
|
+
if (predefined) ctx.styleNames.add("STANDARD");
|
|
9272
|
+
style.fontFileName = fontFile;
|
|
9273
|
+
style.widthFactor = widthFactor;
|
|
9274
|
+
style.fixedTextHeight = fixedHeight;
|
|
9275
|
+
const rec = { name: style.name, handle: style.handle, face };
|
|
9276
|
+
ctx.textStyles.set(key, rec);
|
|
7268
9277
|
return rec;
|
|
7269
9278
|
};
|
|
9279
|
+
var createDocTextStyles = (ctx) => {
|
|
9280
|
+
for (const s of ctx.doc.textStyles)
|
|
9281
|
+
addStyleRecord(
|
|
9282
|
+
ctx,
|
|
9283
|
+
`doc:${s.id}`,
|
|
9284
|
+
sanitizeLayerName(s.name),
|
|
9285
|
+
fontFace(s.font, s.bold, s.italic),
|
|
9286
|
+
s.widthFactor,
|
|
9287
|
+
s.textHeight
|
|
9288
|
+
);
|
|
9289
|
+
};
|
|
9290
|
+
var dimTextStyleFor = (ctx, face, widthFactor) => {
|
|
9291
|
+
const want = writableFace(face).face;
|
|
9292
|
+
const own = ctx.doc.textStyles.find(
|
|
9293
|
+
(s) => writableFace(fontFace(s.font, s.bold, s.italic)).face === want && Math.abs(s.widthFactor - widthFactor) < 1e-9
|
|
9294
|
+
);
|
|
9295
|
+
const ownRec = own && ctx.textStyles.get(`doc:${own.id}`);
|
|
9296
|
+
if (ownRec) return ownRec;
|
|
9297
|
+
if (Math.abs(widthFactor - 1) < 1e-9) return textStyleFor2(ctx, face);
|
|
9298
|
+
const key = `${want}|w${widthFactor}`;
|
|
9299
|
+
return ctx.textStyles.get(key) ?? addStyleRecord(
|
|
9300
|
+
ctx,
|
|
9301
|
+
key,
|
|
9302
|
+
`${textStyleFor2(ctx, face).name}_W${Math.round(widthFactor * 100)}`,
|
|
9303
|
+
face,
|
|
9304
|
+
widthFactor
|
|
9305
|
+
);
|
|
9306
|
+
};
|
|
9307
|
+
var textStyleFor2 = (ctx, font) => {
|
|
9308
|
+
const { face, fontId, foreign } = writableFace(font);
|
|
9309
|
+
const { bold, italic } = parseFontFace(face);
|
|
9310
|
+
const suffix = (bold ? "B" : "") + (italic ? "I" : "");
|
|
9311
|
+
return ctx.textStyles.get(face) ?? addStyleRecord(
|
|
9312
|
+
ctx,
|
|
9313
|
+
face,
|
|
9314
|
+
`LINEA_${(foreign ? fontId.replace(/[^A-Za-z0-9_-]/g, "_") : fontId).toUpperCase()}${suffix ? `_${suffix}` : ""}`,
|
|
9315
|
+
face
|
|
9316
|
+
);
|
|
9317
|
+
};
|
|
9318
|
+
var textRecordFor = (ctx, obj, face) => {
|
|
9319
|
+
const base = textStyleFor(obj, ctx.doc.textStyles);
|
|
9320
|
+
const own = ctx.textStyles.get(`doc:${base.id}`);
|
|
9321
|
+
return own && writableFace(fontFace(base.font, base.bold, base.italic)).face === writableFace(face).face ? own : textStyleFor2(ctx, face);
|
|
9322
|
+
};
|
|
7270
9323
|
var addTextLines = (space, content, position, height, rotation, hAlign, vAlign, opts, measure, mtextWidth, fontOpts = {}) => {
|
|
7271
|
-
const { styleName, font, widthFactor = 1 } = fontOpts;
|
|
9324
|
+
const { styleName, font, widthFactor = 1, spans } = fontOpts;
|
|
7272
9325
|
const m = boundMeasurer(measure, font, widthFactor);
|
|
7273
9326
|
const block = textBlock(content, height, m, mtextWidth);
|
|
7274
|
-
if (block.lines.length > 1 || mtextWidth !== void 0 && mtextWidth > 0 || content.includes(" ")) {
|
|
7275
|
-
const value = (widthFactor !== 1 ? `\\W${widthFactor};` : "") +
|
|
9327
|
+
if (block.lines.length > 1 || mtextWidth !== void 0 && mtextWidth > 0 || content.includes(" ") || !!spans?.length) {
|
|
9328
|
+
const value = (widthFactor !== 1 ? `\\W${widthFactor};` : "") + (spans?.length ? encodeRichMtext(content, spans, font) : encodeMtext(content));
|
|
7276
9329
|
const mtext = space.addMText(v3(position), height, value, {
|
|
7277
9330
|
rotation: rotation * RAD2DEG2,
|
|
7278
9331
|
attachmentPoint: mtextAttachment(hAlign, vAlign),
|
|
@@ -7283,7 +9336,8 @@ var addTextLines = (space, content, position, height, rotation, hAlign, vAlign,
|
|
|
7283
9336
|
return;
|
|
7284
9337
|
}
|
|
7285
9338
|
const down = scale(perp(fromAngle(rotation)), -1);
|
|
7286
|
-
block.lines.forEach((
|
|
9339
|
+
block.lines.forEach((raw, i) => {
|
|
9340
|
+
const line = raw.replace(/\r/g, "");
|
|
7287
9341
|
if (!line) return;
|
|
7288
9342
|
const anchor = add(position, scale(down, i * block.lineHeight));
|
|
7289
9343
|
const text = space.addText(v3(anchor), height, line, {
|
|
@@ -7298,11 +9352,94 @@ var addTextLines = (space, content, position, height, rotation, hAlign, vAlign,
|
|
|
7298
9352
|
if (styleName) text.textStyle = styleName;
|
|
7299
9353
|
});
|
|
7300
9354
|
};
|
|
9355
|
+
var documentPattern = (ctx, name) => ctx.doc.hatchPatterns.find(
|
|
9356
|
+
(p) => hatchPatternKey(p.name) === hatchPatternKey(name)
|
|
9357
|
+
);
|
|
9358
|
+
var injectHatchPatternLines = (content, ctx) => {
|
|
9359
|
+
if (!content.includes("\n0\nHATCH\n")) return content;
|
|
9360
|
+
const out = [];
|
|
9361
|
+
let pos = 0;
|
|
9362
|
+
for (; ; ) {
|
|
9363
|
+
const start = content.indexOf("\n0\nHATCH\n", pos);
|
|
9364
|
+
if (start === -1) break;
|
|
9365
|
+
const rest = content.slice(start + 8);
|
|
9366
|
+
const m = /\n0\n(?=[A-Z][A-Z0-9_]*\n)/.exec(rest);
|
|
9367
|
+
const end = m ? start + 8 + m.index : content.length;
|
|
9368
|
+
let record = content.slice(start, end);
|
|
9369
|
+
const handle = /\n5\n([0-9A-Fa-f]+)\n/.exec(record)?.[1];
|
|
9370
|
+
const bodyAt = record.indexOf("\nAcDbHatch\n");
|
|
9371
|
+
const body = bodyAt === -1 ? record : record.slice(bodyAt);
|
|
9372
|
+
const name = /\n2\n([^\n]*)\n/.exec(body)?.[1];
|
|
9373
|
+
const anchor = handle ? ctx.hatchOrigins.get(handle) : void 0;
|
|
9374
|
+
const own = name ? documentPattern(ctx, name) : void 0;
|
|
9375
|
+
const pat = own ?? (name ? resolveHatchPattern(name, []) : void 0);
|
|
9376
|
+
const m77 = pat ? /\n77\n[^\n]*\n/.exec(body) : null;
|
|
9377
|
+
if (pat && m77 && bodyAt !== -1) {
|
|
9378
|
+
const angle2 = Number(/\n52\n([^\n]*)\n/.exec(body)?.[1] ?? 0) * Math.PI / 180;
|
|
9379
|
+
const scale3 = Number(/\n41\n([^\n]*)\n/.exec(body)?.[1] ?? 1) || 1;
|
|
9380
|
+
const cos = Math.cos(angle2);
|
|
9381
|
+
const sin = Math.sin(angle2);
|
|
9382
|
+
const bake = (x, y) => [
|
|
9383
|
+
(cos * x - sin * y) * scale3,
|
|
9384
|
+
(sin * x + cos * y) * scale3
|
|
9385
|
+
];
|
|
9386
|
+
const lines = pat.lines.map((l) => {
|
|
9387
|
+
const [bx, by] = bake(l.origin.x, l.origin.y);
|
|
9388
|
+
const ox = bx + (anchor?.x ?? 0);
|
|
9389
|
+
const oy = by + (anchor?.y ?? 0);
|
|
9390
|
+
const bakedAngle = l.angle + angle2;
|
|
9391
|
+
const dx = (Math.cos(bakedAngle) * l.deltaX - Math.sin(bakedAngle) * l.deltaY) * scale3;
|
|
9392
|
+
const dy = (Math.sin(bakedAngle) * l.deltaX + Math.cos(bakedAngle) * l.deltaY) * scale3;
|
|
9393
|
+
const dashes = l.dashesMm ?? [];
|
|
9394
|
+
return `53
|
|
9395
|
+
${(l.angle * 180 / Math.PI + angle2 * 180 / Math.PI).toFixed(6)}
|
|
9396
|
+
43
|
|
9397
|
+
${ox.toFixed(6)}
|
|
9398
|
+
44
|
|
9399
|
+
${oy.toFixed(6)}
|
|
9400
|
+
45
|
|
9401
|
+
${dx.toFixed(6)}
|
|
9402
|
+
46
|
|
9403
|
+
${dy.toFixed(6)}
|
|
9404
|
+
79
|
|
9405
|
+
${dashes.length}
|
|
9406
|
+
` + dashes.map((d) => `49
|
|
9407
|
+
${(d * scale3).toFixed(6)}
|
|
9408
|
+
`).join("");
|
|
9409
|
+
}).join("");
|
|
9410
|
+
const at = bodyAt + m77.index + m77[0].length;
|
|
9411
|
+
const tail = record.slice(at);
|
|
9412
|
+
const writerBlock = tail.startsWith("78\n") ? (() => {
|
|
9413
|
+
const stop = /\n(?:47|98)\n/.exec(tail);
|
|
9414
|
+
return stop ? stop.index + 1 : tail.length;
|
|
9415
|
+
})() : 0;
|
|
9416
|
+
record = record.slice(0, at) + `78
|
|
9417
|
+
${pat.lines.length}
|
|
9418
|
+
` + lines + tail.slice(writerBlock);
|
|
9419
|
+
if (own) record = record.replace(/\n76\n1\n/, "\n76\n2\n");
|
|
9420
|
+
else if (name && name !== pat.name.toUpperCase()) {
|
|
9421
|
+
const nameAt = record.indexOf(`
|
|
9422
|
+
2
|
|
9423
|
+
${name}
|
|
9424
|
+
`, bodyAt);
|
|
9425
|
+
if (nameAt !== -1)
|
|
9426
|
+
record = record.slice(0, nameAt) + `
|
|
9427
|
+
2
|
|
9428
|
+
${pat.name.toUpperCase()}
|
|
9429
|
+
` + record.slice(nameAt + name.length + 4);
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9432
|
+
out.push(content.slice(pos, start), record);
|
|
9433
|
+
pos = end;
|
|
9434
|
+
}
|
|
9435
|
+
out.push(content.slice(pos));
|
|
9436
|
+
return out.join("");
|
|
9437
|
+
};
|
|
7301
9438
|
var dxfPatternName = (name) => {
|
|
7302
9439
|
const key = name.toUpperCase().replace(/-/g, "_").replace(/\./g, "_");
|
|
7303
9440
|
return HatchPredefinedPatterns[key] ?? HatchPredefinedPatterns.ANSI31;
|
|
7304
9441
|
};
|
|
7305
|
-
var writeHatch = (space, obj, opts) => {
|
|
9442
|
+
var writeHatch = (space, obj, opts, ctx) => {
|
|
7306
9443
|
if (obj.type !== "hatch") return;
|
|
7307
9444
|
if (obj.fill.kind === "gradient") {
|
|
7308
9445
|
opts = {
|
|
@@ -7326,9 +9463,11 @@ var writeHatch = (space, obj, opts) => {
|
|
|
7326
9463
|
obj.fill.kind === "solid" || obj.fill.kind === "gradient" ? pattern({ name: HatchPredefinedPatterns.SOLID }) : obj.fill.kind === "pattern" ? (
|
|
7327
9464
|
// The curated library names are the standard predefined patterns, so
|
|
7328
9465
|
// this is a direct mapping; fill.angle/scale ARE the DXF rotation
|
|
7329
|
-
// (code 52) and scale (code 41).
|
|
9466
|
+
// (code 52) and scale (code 41). A DOCUMENT pattern goes out under
|
|
9467
|
+
// its own name; its definition lines are spliced in afterwards
|
|
9468
|
+
// (injectHatchPatternLines — the writer has no custom patterns).
|
|
7330
9469
|
pattern({
|
|
7331
|
-
name: dxfPatternName(obj.fill.name),
|
|
9470
|
+
name: documentPattern(ctx, obj.fill.name) ? obj.fill.name.toUpperCase() : dxfPatternName(obj.fill.name),
|
|
7332
9471
|
angle: obj.fill.angle * RAD2DEG2,
|
|
7333
9472
|
scale: obj.fill.scale * obj.scale
|
|
7334
9473
|
})
|
|
@@ -7339,10 +9478,12 @@ var writeHatch = (space, obj, opts) => {
|
|
|
7339
9478
|
scale: obj.fill.spacing * obj.scale / ANSI31_BASE_SPACING
|
|
7340
9479
|
})
|
|
7341
9480
|
);
|
|
7342
|
-
space.addHatch(boundary, fill, opts);
|
|
9481
|
+
const written = space.addHatch(boundary, fill, opts);
|
|
9482
|
+
if (obj.fill.kind === "pattern" && obj.fill.origin)
|
|
9483
|
+
ctx.hatchOrigins.set(written.handle, obj.fill.origin);
|
|
7343
9484
|
};
|
|
7344
9485
|
var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
7345
|
-
for (const seg of [...geom.extensionLines, ...geom.dimLines])
|
|
9486
|
+
for (const seg of [...geom.extensionLines, ...geom.dimLines, ...geom.leaders])
|
|
7346
9487
|
target.addLine(v3(seg.a), v3(seg.b), opts);
|
|
7347
9488
|
if (geom.dimArc)
|
|
7348
9489
|
target.addArc(
|
|
@@ -7361,7 +9502,7 @@ var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
|
7361
9502
|
geom.arrowType,
|
|
7362
9503
|
opts
|
|
7363
9504
|
);
|
|
7364
|
-
for (const text of geom.
|
|
9505
|
+
for (const text of geom.labels)
|
|
7365
9506
|
addTextLines(
|
|
7366
9507
|
target,
|
|
7367
9508
|
text.content,
|
|
@@ -7376,13 +9517,43 @@ var writeDimensionGeometry = (target, geom, opts, ctx) => {
|
|
|
7376
9517
|
{
|
|
7377
9518
|
styleName: textStyleFor2(ctx, text.font).name,
|
|
7378
9519
|
font: text.font,
|
|
7379
|
-
widthFactor: text.widthFactor
|
|
9520
|
+
widthFactor: text.widthFactor,
|
|
9521
|
+
spans: text.spans
|
|
7380
9522
|
}
|
|
7381
9523
|
);
|
|
7382
9524
|
};
|
|
7383
|
-
var
|
|
9525
|
+
var addDimStyleRecord = (ctx, name, style) => {
|
|
9526
|
+
const table = ctx.writer.document.tables.dimStyleTable;
|
|
9527
|
+
const predefined = name.toUpperCase() === "STANDARD" && !ctx.dimStyleNames.has("STANDARD") ? table.records.find((r) => r.name.toUpperCase() === "STANDARD") : void 0;
|
|
9528
|
+
const rec = predefined ?? ctx.writer.addDimStyle(uniqueTableName(ctx.dimStyleNames, name));
|
|
9529
|
+
if (predefined) ctx.dimStyleNames.add("STANDARD");
|
|
7384
9530
|
const scale3 = style.scale ?? 1;
|
|
9531
|
+
rec.DIMASZ = style.arrowSize;
|
|
9532
|
+
rec.DIMEXO = style.extensionOffset;
|
|
9533
|
+
rec.DIMEXE = style.extensionOvershoot;
|
|
9534
|
+
rec.DIMTXT = style.textHeight;
|
|
9535
|
+
rec.DIMGAP = style.textOffset;
|
|
9536
|
+
rec.DIMDEC = style.precision;
|
|
9537
|
+
if (scale3 !== 1) rec.DIMSCALE = scale3;
|
|
9538
|
+
if (style.arrowType !== "filled") rec.DIMBLK = DIMBLK_NAMES[style.arrowType];
|
|
9539
|
+
rec.DIMTXSTY = dimTextStyleFor(
|
|
9540
|
+
ctx,
|
|
9541
|
+
dimFontFace(style),
|
|
9542
|
+
style.widthFactor
|
|
9543
|
+
).handle;
|
|
9544
|
+
return rec.name;
|
|
9545
|
+
};
|
|
9546
|
+
var createDocDimStyles = (ctx) => {
|
|
9547
|
+
for (const s of ctx.doc.dimStyles)
|
|
9548
|
+
ctx.dimStyleRecords.set(
|
|
9549
|
+
s.id,
|
|
9550
|
+
addDimStyleRecord(ctx, sanitizeLayerName(s.name), s)
|
|
9551
|
+
);
|
|
9552
|
+
};
|
|
9553
|
+
var dimOverrideStyleFor = (ctx, base, style) => {
|
|
9554
|
+
const baseName = ctx.dimStyleRecords.get(base.id) ?? ctx.dimStyleRecords.values().next().value ?? "Standard";
|
|
7385
9555
|
const key = JSON.stringify([
|
|
9556
|
+
baseName,
|
|
7386
9557
|
style.arrowSize,
|
|
7387
9558
|
style.arrowType,
|
|
7388
9559
|
style.extensionOffset,
|
|
@@ -7391,21 +9562,13 @@ var dimStyleFor2 = (ctx, style) => {
|
|
|
7391
9562
|
style.textOffset,
|
|
7392
9563
|
style.precision,
|
|
7393
9564
|
dimFontFace(style),
|
|
7394
|
-
|
|
9565
|
+
style.scale ?? 1
|
|
7395
9566
|
]);
|
|
7396
|
-
|
|
7397
|
-
if (
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
rec.DIMEXO = style.extensionOffset;
|
|
7402
|
-
rec.DIMEXE = style.extensionOvershoot;
|
|
7403
|
-
rec.DIMTXT = style.textHeight;
|
|
7404
|
-
rec.DIMGAP = style.textOffset;
|
|
7405
|
-
rec.DIMDEC = style.precision;
|
|
7406
|
-
if (scale3 !== 1) rec.DIMSCALE = scale3;
|
|
7407
|
-
if (style.arrowType !== "filled") rec.DIMBLK = DIMBLK_NAMES[style.arrowType];
|
|
7408
|
-
rec.DIMTXSTY = textStyleFor2(ctx, dimFontFace(style)).handle;
|
|
9567
|
+
const cached = ctx.dimStyles.get(key);
|
|
9568
|
+
if (cached) return cached;
|
|
9569
|
+
const n = (ctx.dimOverrideCounts.get(baseName) ?? 0) + 1;
|
|
9570
|
+
ctx.dimOverrideCounts.set(baseName, n);
|
|
9571
|
+
const name = addDimStyleRecord(ctx, `${baseName}_${n}`, style);
|
|
7409
9572
|
ctx.dimStyles.set(key, name);
|
|
7410
9573
|
return name;
|
|
7411
9574
|
};
|
|
@@ -7431,26 +9594,38 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7431
9594
|
const blockName = `LINEA_DIM_${ctx.dimBlockCount++}`;
|
|
7432
9595
|
const block = ctx.writer.addBlock(blockName);
|
|
7433
9596
|
writeDimensionGeometry(block, geom, opts, ctx);
|
|
7434
|
-
const
|
|
7435
|
-
|
|
9597
|
+
const baseStyle = dimStyleFor(obj, ctx.doc.dimStyles);
|
|
9598
|
+
const hasOverride = obj.styleOverride !== void 0 && Object.values(obj.styleOverride).some((v) => v !== void 0);
|
|
9599
|
+
const styleName = hasOverride || obj.scale !== 1 ? dimOverrideStyleFor(ctx, baseStyle, {
|
|
9600
|
+
...baseStyle,
|
|
7436
9601
|
...obj.styleOverride,
|
|
7437
9602
|
scale: obj.scale
|
|
7438
|
-
}) :
|
|
9603
|
+
}) : ctx.dimStyleRecords.get(baseStyle.id) ?? dimOverrideStyleFor(ctx, baseStyle, baseStyle);
|
|
9604
|
+
const content = obj.labels[0]?.content;
|
|
9605
|
+
const precision = {
|
|
9606
|
+
...dimStyleFor(obj, ctx.doc.dimStyles),
|
|
9607
|
+
...obj.styleOverride
|
|
9608
|
+
}.precision;
|
|
9609
|
+
const text = content === void 0 ? void 0 : content.split(DIM_DEFAULT_CONTENT[obj.kind]).join("<>").split(DIM_VALUE_TOKEN).join(
|
|
9610
|
+
obj.kind === "radial" || obj.kind === "diameter" ? formatDimValue(geom.value, precision) : "<>"
|
|
9611
|
+
);
|
|
7439
9612
|
const dimOpts = {
|
|
7440
9613
|
blockName,
|
|
7441
|
-
text:
|
|
9614
|
+
...text === void 0 ? {} : { text },
|
|
7442
9615
|
styleName,
|
|
7443
9616
|
// Text middle point (group 11) — without it a regenerating CAD places
|
|
7444
9617
|
// the value at the style default instead of where the user saw it.
|
|
7445
|
-
...geom.
|
|
9618
|
+
...geom.labels[0] ? { middlePoint: v3(geom.labels[0].anchor) } : {},
|
|
7446
9619
|
...opts
|
|
7447
9620
|
};
|
|
7448
9621
|
switch (obj.kind) {
|
|
7449
9622
|
case "angular": {
|
|
7450
9623
|
const [vertex, a, b] = obj.points;
|
|
9624
|
+
const [frame] = dimensionLabelFrames(obj);
|
|
7451
9625
|
space.addAngularPointsDim(v3(vertex), v3(a), v3(b), {
|
|
7452
9626
|
...dimOpts,
|
|
7453
|
-
|
|
9627
|
+
// A point on the arc (its middle): the radius and which arc.
|
|
9628
|
+
definitionPoint: v3(frame.toWorld((frame.s0 + frame.s1) / 2, 0))
|
|
7454
9629
|
});
|
|
7455
9630
|
break;
|
|
7456
9631
|
}
|
|
@@ -7466,8 +9641,7 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7466
9641
|
}
|
|
7467
9642
|
case "linear": {
|
|
7468
9643
|
const [p1, p2] = obj.points;
|
|
7469
|
-
const
|
|
7470
|
-
const u = upLen > 1e-9 ? perp(scale(obj.offset, 1 / upLen)) : norm(sub(p2, p1));
|
|
9644
|
+
const { u } = linearAxis(obj);
|
|
7471
9645
|
space.addLinearDim(v3(p1), v3(p2), {
|
|
7472
9646
|
...dimOpts,
|
|
7473
9647
|
definitionPoint: v3(geom.dimLines[0].b),
|
|
@@ -7478,7 +9652,90 @@ var writeDimension = (space, obj, opts, ctx) => {
|
|
|
7478
9652
|
}
|
|
7479
9653
|
return true;
|
|
7480
9654
|
};
|
|
9655
|
+
var tableCellMtext = (text, ctx) => {
|
|
9656
|
+
if (text.content.trim() === "") return "";
|
|
9657
|
+
const eff = resolveTextStyle(text, ctx.doc.textStyles);
|
|
9658
|
+
const face = fontFace(eff.font, eff.bold, eff.italic);
|
|
9659
|
+
const { font, bold, italic } = parseFontFace(face);
|
|
9660
|
+
const height = eff.textHeight * text.scale;
|
|
9661
|
+
const body = text.spans?.length ? encodeRichMtext(text.content, text.spans, face) : encodeMtext(text.content);
|
|
9662
|
+
return `{\\f${fontTypeface(resolveFont(font))}|b${bold ? 1 : 0}|i${italic ? 1 : 0}|c0|p34;\\H${+height.toFixed(6)};` + (eff.widthFactor !== 1 ? `\\W${eff.widthFactor};` : "") + `${body}}`;
|
|
9663
|
+
};
|
|
9664
|
+
var attachmentOf = (hAlign, vAlign) => (vAlign === "top" ? 0 : vAlign === "center" ? 3 : 6) + (hAlign === "left" ? 1 : hAlign === "center" ? 2 : 3);
|
|
9665
|
+
var writeNativeTable = (space, obj, ctx) => {
|
|
9666
|
+
const layout = tableLayout(obj, ctx.doc.textStyles);
|
|
9667
|
+
const name = `*T${++ctx.tableBlockCount}`;
|
|
9668
|
+
const block = ctx.writer.document.blocks.addBlock(
|
|
9669
|
+
name,
|
|
9670
|
+
ctx.writer.document.objects,
|
|
9671
|
+
false
|
|
9672
|
+
);
|
|
9673
|
+
block.flags = 1;
|
|
9674
|
+
const before = ctx.exported;
|
|
9675
|
+
const origin = { x: 0, y: 0 };
|
|
9676
|
+
for (const child of layout.children)
|
|
9677
|
+
writeObject(
|
|
9678
|
+
block,
|
|
9679
|
+
rotateObject(
|
|
9680
|
+
translateObject(child, { x: -obj.position.x, y: -obj.position.y }),
|
|
9681
|
+
origin,
|
|
9682
|
+
-obj.rotation
|
|
9683
|
+
),
|
|
9684
|
+
ctx
|
|
9685
|
+
);
|
|
9686
|
+
ctx.exported = before;
|
|
9687
|
+
const blockRecordHandle = ctx.writer.document.tables.blockRecordTable.records.find(
|
|
9688
|
+
(r) => r.name === name
|
|
9689
|
+
)?.handle ?? "0";
|
|
9690
|
+
const rows = obj.rows.length;
|
|
9691
|
+
const cols = obj.columns.length;
|
|
9692
|
+
const anchorAt = new Map(
|
|
9693
|
+
layout.anchors.map((a) => [`${a.row}:${a.col}`, a])
|
|
9694
|
+
);
|
|
9695
|
+
const cells = [];
|
|
9696
|
+
for (let r = 0; r < rows; r++)
|
|
9697
|
+
for (let c = 0; c < cols; c++) {
|
|
9698
|
+
const a = anchorAt.get(`${r}:${c}`);
|
|
9699
|
+
if (!a) {
|
|
9700
|
+
cells.push({ text: "", cols: 1, rows: 1, merged: true, alignment: 1 });
|
|
9701
|
+
continue;
|
|
9702
|
+
}
|
|
9703
|
+
const { text } = tableCellFrame(obj, ctx.doc.textStyles, r, c);
|
|
9704
|
+
cells.push({
|
|
9705
|
+
text: tableCellMtext(text, ctx),
|
|
9706
|
+
cols: a.cols,
|
|
9707
|
+
rows: a.rows,
|
|
9708
|
+
merged: false,
|
|
9709
|
+
alignment: attachmentOf(text.hAlign, text.vAlign)
|
|
9710
|
+
});
|
|
9711
|
+
}
|
|
9712
|
+
const diffs = (xs) => xs.slice(1).map((x, i) => x - xs[i]);
|
|
9713
|
+
const entity = new AcadTableEntity({
|
|
9714
|
+
blockName: name,
|
|
9715
|
+
blockRecordHandle,
|
|
9716
|
+
tableStyleHandle: ctx.tableStyleHandle,
|
|
9717
|
+
position: obj.position,
|
|
9718
|
+
direction: { x: Math.cos(obj.rotation), y: Math.sin(obj.rotation) },
|
|
9719
|
+
rowHeights: diffs(layout.rowY),
|
|
9720
|
+
colWidths: diffs(layout.colX),
|
|
9721
|
+
cells
|
|
9722
|
+
});
|
|
9723
|
+
entity.layerName = ctx.layerNames.get(obj.layerId) ?? "0";
|
|
9724
|
+
if (obj.color) {
|
|
9725
|
+
entity.colorNumber = nearestAci(obj.color);
|
|
9726
|
+
const tc = hexToTrueColor(obj.color);
|
|
9727
|
+
if (tc !== null) entity.trueColor = String(tc);
|
|
9728
|
+
}
|
|
9729
|
+
space.addEntity(entity);
|
|
9730
|
+
};
|
|
7481
9731
|
var writeObject = (space, obj, ctx) => {
|
|
9732
|
+
const before = space.entities.length;
|
|
9733
|
+
writeObjectEntities(space, obj, ctx);
|
|
9734
|
+
if (obj.lineWidth !== void 0)
|
|
9735
|
+
for (const entity of space.entities.slice(before))
|
|
9736
|
+
setLineWeight(entity, mmToLineWeight(obj.lineWidth));
|
|
9737
|
+
};
|
|
9738
|
+
var writeObjectEntities = (space, obj, ctx) => {
|
|
7482
9739
|
const opts = optionsFor(obj, ctx);
|
|
7483
9740
|
switch (obj.type) {
|
|
7484
9741
|
case "line":
|
|
@@ -7523,12 +9780,27 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7523
9780
|
);
|
|
7524
9781
|
break;
|
|
7525
9782
|
case "hatch":
|
|
7526
|
-
writeHatch(space, obj, opts);
|
|
9783
|
+
writeHatch(space, obj, opts, ctx);
|
|
7527
9784
|
break;
|
|
7528
9785
|
case "text": {
|
|
7529
9786
|
const eff = resolveTextStyle(obj, ctx.doc.textStyles);
|
|
7530
9787
|
const { arrowSize, arrowType } = eff;
|
|
7531
9788
|
const face = fontFace(eff.font, eff.bold, eff.italic);
|
|
9789
|
+
for (const part of textFrameGeometry(
|
|
9790
|
+
obj,
|
|
9791
|
+
ctx.measure,
|
|
9792
|
+
ctx.doc.textStyles
|
|
9793
|
+
))
|
|
9794
|
+
space.addLWPolyline(
|
|
9795
|
+
part.points.map((v) => ({
|
|
9796
|
+
point: { x: v.x, y: v.y },
|
|
9797
|
+
bulge: v.bulge
|
|
9798
|
+
})),
|
|
9799
|
+
{
|
|
9800
|
+
flags: part.closed ? LWPolylineFlags.Closed : LWPolylineFlags.None,
|
|
9801
|
+
...opts
|
|
9802
|
+
}
|
|
9803
|
+
);
|
|
7532
9804
|
if (obj.leaderLines.length > 0 && ctx.explodeLeaders) {
|
|
7533
9805
|
for (const line of obj.leaderLines) {
|
|
7534
9806
|
space.addLWPolyline(
|
|
@@ -7562,13 +9834,15 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7562
9834
|
junction,
|
|
7563
9835
|
doglegDirection: { x: toText.x / gap, y: toText.y / gap },
|
|
7564
9836
|
doglegLength: gap,
|
|
7565
|
-
content:
|
|
9837
|
+
content: obj.spans?.length ? encodeRichMtext(obj.content, obj.spans, face) : encodeMtext(obj.content),
|
|
7566
9838
|
textHeight: eff.textHeight,
|
|
7567
9839
|
arrowSize,
|
|
7568
9840
|
overallScale: obj.scale,
|
|
7569
9841
|
textLocation: obj.position,
|
|
9842
|
+
// Model alignment → MTEXT-style attachment point (1–9).
|
|
9843
|
+
attachment: 1 + 3 * ["top", "center", "bottom"].indexOf(obj.vAlign) + ["left", "center", "right"].indexOf(obj.hAlign),
|
|
7570
9844
|
styleHandle: ctx.mleaderStyleHandle,
|
|
7571
|
-
textStyleHandle:
|
|
9845
|
+
textStyleHandle: textRecordFor(ctx, obj, face).handle,
|
|
7572
9846
|
lineTypeHandle: ctx.lineTypeHandle
|
|
7573
9847
|
});
|
|
7574
9848
|
entity.layerName = ctx.layerNames.get(obj.layerId) ?? "0";
|
|
@@ -7592,9 +9866,10 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7592
9866
|
ctx.measure,
|
|
7593
9867
|
obj.width === void 0 ? void 0 : obj.width * obj.scale,
|
|
7594
9868
|
{
|
|
7595
|
-
styleName:
|
|
9869
|
+
styleName: textRecordFor(ctx, obj, face).name,
|
|
7596
9870
|
font: face,
|
|
7597
|
-
widthFactor: eff.widthFactor
|
|
9871
|
+
widthFactor: eff.widthFactor,
|
|
9872
|
+
spans: obj.spans
|
|
7598
9873
|
}
|
|
7599
9874
|
);
|
|
7600
9875
|
break;
|
|
@@ -7606,6 +9881,10 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7606
9881
|
}
|
|
7607
9882
|
break;
|
|
7608
9883
|
case "block": {
|
|
9884
|
+
if (ctx.blockChain.includes(obj.definitionId)) {
|
|
9885
|
+
skip(ctx, "block");
|
|
9886
|
+
return;
|
|
9887
|
+
}
|
|
7609
9888
|
const children = getEvaluatedWorldChildren(
|
|
7610
9889
|
obj,
|
|
7611
9890
|
ctx.doc.blockDefinitions,
|
|
@@ -7617,14 +9896,23 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7617
9896
|
return;
|
|
7618
9897
|
}
|
|
7619
9898
|
const before = ctx.exported;
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
9899
|
+
ctx.blockChain.push(obj.definitionId);
|
|
9900
|
+
try {
|
|
9901
|
+
for (const child of children) {
|
|
9902
|
+
if (child.type === "viewport") continue;
|
|
9903
|
+
writeObject(space, child, ctx);
|
|
9904
|
+
}
|
|
9905
|
+
} finally {
|
|
9906
|
+
ctx.blockChain.pop();
|
|
7623
9907
|
}
|
|
7624
9908
|
ctx.exported = before;
|
|
7625
9909
|
break;
|
|
7626
9910
|
}
|
|
7627
9911
|
case "table": {
|
|
9912
|
+
if (!ctx.explodeTables) {
|
|
9913
|
+
writeNativeTable(space, obj, ctx);
|
|
9914
|
+
break;
|
|
9915
|
+
}
|
|
7628
9916
|
const before = ctx.exported;
|
|
7629
9917
|
for (const child of tableLayout(obj, ctx.doc.textStyles).children)
|
|
7630
9918
|
writeObject(space, child, ctx);
|
|
@@ -7634,9 +9922,6 @@ var writeObject = (space, obj, ctx) => {
|
|
|
7634
9922
|
case "viewport":
|
|
7635
9923
|
skip(ctx, "viewport");
|
|
7636
9924
|
return;
|
|
7637
|
-
case "image":
|
|
7638
|
-
skip(ctx, "image");
|
|
7639
|
-
return;
|
|
7640
9925
|
case "reference": {
|
|
7641
9926
|
if (obj.hidden || obj.format !== "dxf" && obj.format !== "dwg" || obj.source.kind !== "path") {
|
|
7642
9927
|
skip(ctx, "reference");
|
|
@@ -7690,10 +9975,22 @@ var writeViewport = (space, vp, id, ctx) => {
|
|
|
7690
9975
|
);
|
|
7691
9976
|
ctx.exported++;
|
|
7692
9977
|
};
|
|
9978
|
+
var DWG_DXF_OPTIONS = {
|
|
9979
|
+
explodeLeaders: true,
|
|
9980
|
+
explodeTables: true
|
|
9981
|
+
};
|
|
7693
9982
|
var buildDxf = (doc, measure, options = {}) => {
|
|
7694
9983
|
const writer = new DxfWriter();
|
|
7695
9984
|
writer.setUnits(Units.Millimeters);
|
|
7696
9985
|
const emittedLtypes = /* @__PURE__ */ new Set();
|
|
9986
|
+
for (const t of doc.lineTypes) {
|
|
9987
|
+
if (t.dashesMm.length === 0) continue;
|
|
9988
|
+
const dxfName = t.name.toUpperCase();
|
|
9989
|
+
if (emittedLtypes.has(dxfName)) continue;
|
|
9990
|
+
emittedLtypes.add(dxfName);
|
|
9991
|
+
const descriptive = (t.description ?? t.name).replace(/[^\x20-\x7e]/g, "").slice(0, 47);
|
|
9992
|
+
writer.addLType(dxfName, descriptive, t.dashesMm);
|
|
9993
|
+
}
|
|
7697
9994
|
for (const p of LINE_TYPE_DEFS) {
|
|
7698
9995
|
if (p.dashesMm.length === 0) continue;
|
|
7699
9996
|
const dxfName = p.dxfName ?? p.name.toUpperCase();
|
|
@@ -7715,18 +10012,22 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7715
10012
|
layerNames.set(layer.id, name);
|
|
7716
10013
|
if (name === "0") {
|
|
7717
10014
|
const zero = writer.layer("0");
|
|
7718
|
-
if (zero)
|
|
10015
|
+
if (zero) {
|
|
10016
|
+
setLineWeight(zero, mmToLineWeight(layer.lineWidth));
|
|
10017
|
+
layerRecords.set(layer.id, zero);
|
|
10018
|
+
}
|
|
7719
10019
|
continue;
|
|
7720
10020
|
}
|
|
7721
10021
|
const flags = (layer.visible ? 0 : LayerFlags.Frozen) | (layer.locked ? LayerFlags.Locked : 0);
|
|
7722
10022
|
const record = writer.addLayer(
|
|
7723
10023
|
name,
|
|
7724
10024
|
nearestAci(layer.color),
|
|
7725
|
-
dxfLineTypeName(layer.lineType) ?? "Continuous",
|
|
10025
|
+
dxfLineTypeName(layer.lineType, doc.lineTypes) ?? "Continuous",
|
|
7726
10026
|
flags || void 0
|
|
7727
10027
|
);
|
|
7728
10028
|
const tc = hexToTrueColor(layer.color);
|
|
7729
10029
|
if (tc !== null) record.trueColor = tc;
|
|
10030
|
+
setLineWeight(record, mmToLineWeight(layer.lineWidth));
|
|
7730
10031
|
layerRecords.set(layer.id, record);
|
|
7731
10032
|
}
|
|
7732
10033
|
const textStyleHandle = writer.document.tables.styleTable.records.find((r) => r.name === "Standard")?.handle ?? "0";
|
|
@@ -7747,6 +10048,22 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7747
10048
|
);
|
|
7748
10049
|
mleaderStyle.ownerObjecthandle = mleaderDict.handle;
|
|
7749
10050
|
mleaderDict.addEntryObject("Standard", mleaderStyle.handle);
|
|
10051
|
+
const tableStyleDict = writer.document.objects.addDictionary();
|
|
10052
|
+
writer.document.objects.addEntryToRoot(
|
|
10053
|
+
"ACAD_TABLESTYLE",
|
|
10054
|
+
tableStyleDict.handle
|
|
10055
|
+
);
|
|
10056
|
+
const tableStyle = writer.document.objects.addObject(
|
|
10057
|
+
new TableStyleObject({
|
|
10058
|
+
name: "Standard",
|
|
10059
|
+
textStyleName: "Standard",
|
|
10060
|
+
textHeight: doc.textStyles[0]?.textHeight ?? 2.5,
|
|
10061
|
+
margin: 1.5,
|
|
10062
|
+
dictionaryHandle: tableStyleDict.handle
|
|
10063
|
+
})
|
|
10064
|
+
);
|
|
10065
|
+
tableStyle.ownerObjecthandle = tableStyleDict.handle;
|
|
10066
|
+
tableStyleDict.addEntryObject("Standard", tableStyle.handle);
|
|
7750
10067
|
const ctx = {
|
|
7751
10068
|
doc,
|
|
7752
10069
|
measure,
|
|
@@ -7757,14 +10074,24 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7757
10074
|
exported: 0,
|
|
7758
10075
|
dimBlockCount: 0,
|
|
7759
10076
|
xrefBlocks: /* @__PURE__ */ new Map(),
|
|
10077
|
+
blockChain: [],
|
|
7760
10078
|
explodeLeaders: options.explodeLeaders ?? false,
|
|
10079
|
+
explodeTables: options.explodeTables ?? false,
|
|
10080
|
+
tableStyleHandle: tableStyle.handle,
|
|
10081
|
+
tableBlockCount: 0,
|
|
7761
10082
|
mleaderStyleHandle: mleaderStyle.handle,
|
|
7762
10083
|
textStyleHandle,
|
|
7763
10084
|
lineTypeHandle,
|
|
7764
10085
|
textStyles: /* @__PURE__ */ new Map(),
|
|
7765
|
-
|
|
10086
|
+
styleNames: /* @__PURE__ */ new Set(),
|
|
10087
|
+
dimStyleRecords: /* @__PURE__ */ new Map(),
|
|
10088
|
+
dimStyleNames: /* @__PURE__ */ new Set(),
|
|
10089
|
+
dimStyles: /* @__PURE__ */ new Map(),
|
|
10090
|
+
dimOverrideCounts: /* @__PURE__ */ new Map(),
|
|
10091
|
+
hatchOrigins: /* @__PURE__ */ new Map()
|
|
7766
10092
|
};
|
|
7767
|
-
|
|
10093
|
+
createDocTextStyles(ctx);
|
|
10094
|
+
createDocDimStyles(ctx);
|
|
7768
10095
|
for (const obj of doc.objects)
|
|
7769
10096
|
writeObject(writer.document.blocks.modelSpace, obj, ctx);
|
|
7770
10097
|
const layoutRecords = [];
|
|
@@ -7836,16 +10163,35 @@ var buildDxf = (doc, measure, options = {}) => {
|
|
|
7836
10163
|
);
|
|
7837
10164
|
if (record) record.layoutObject = layoutObj.handle;
|
|
7838
10165
|
}
|
|
10166
|
+
const content = injectHatchPatternLines(
|
|
10167
|
+
injectStyleTypefaces(writer.stringify(), ctx.textStyles),
|
|
10168
|
+
ctx
|
|
10169
|
+
);
|
|
7839
10170
|
return {
|
|
7840
|
-
|
|
10171
|
+
// The writer's CLASSES section is always empty: declare the non-fixed
|
|
10172
|
+
// types this file uses (AutoCAD expects them declared).
|
|
10173
|
+
content: content.replace(
|
|
10174
|
+
"\n0\nSECTION\n2\nCLASSES\n0\nENDSEC\n",
|
|
10175
|
+
`
|
|
10176
|
+
0
|
|
10177
|
+
SECTION
|
|
10178
|
+
2
|
|
10179
|
+
CLASSES
|
|
10180
|
+
${classesSection(content)}0
|
|
10181
|
+
ENDSEC
|
|
10182
|
+
`
|
|
10183
|
+
),
|
|
7841
10184
|
exported: ctx.exported,
|
|
7842
10185
|
skipped: ctx.skipped
|
|
7843
10186
|
};
|
|
7844
10187
|
};
|
|
7845
10188
|
var injectStyleTypefaces = (content, textStyles) => {
|
|
7846
10189
|
let out = content;
|
|
7847
|
-
for (const
|
|
7848
|
-
const
|
|
10190
|
+
for (const rec of textStyles.values()) {
|
|
10191
|
+
const fontId = rec.face;
|
|
10192
|
+
const { font: bare } = parseFontFace(fontId);
|
|
10193
|
+
const def = resolveFont(fontId);
|
|
10194
|
+
const typeface = bare !== void 0 && bare !== def.id ? bare : fontTypeface(def);
|
|
7849
10195
|
const { bold, italic } = parseFontFace(fontId);
|
|
7850
10196
|
const flags = (italic ? 16777216 : 0) | (bold ? 33554432 : 0);
|
|
7851
10197
|
const marker = `
|
|
@@ -7875,6 +10221,7 @@ export {
|
|
|
7875
10221
|
add,
|
|
7876
10222
|
sub,
|
|
7877
10223
|
scale,
|
|
10224
|
+
dot,
|
|
7878
10225
|
len,
|
|
7879
10226
|
dist,
|
|
7880
10227
|
norm,
|
|
@@ -7885,8 +10232,6 @@ export {
|
|
|
7885
10232
|
normAngle,
|
|
7886
10233
|
closestPointOnSegment,
|
|
7887
10234
|
remapBlockInputRefs,
|
|
7888
|
-
imageCenter,
|
|
7889
|
-
imageCorners,
|
|
7890
10235
|
translateObject,
|
|
7891
10236
|
rotateObject,
|
|
7892
10237
|
scaleObjectUniform,
|
|
@@ -7894,10 +10239,12 @@ export {
|
|
|
7894
10239
|
Vec2Schema,
|
|
7895
10240
|
ColorSchema,
|
|
7896
10241
|
FONTS,
|
|
10242
|
+
fontFace,
|
|
7897
10243
|
parseFontFace,
|
|
7898
10244
|
REAL_FACES,
|
|
7899
10245
|
realFace,
|
|
7900
10246
|
resolveFont,
|
|
10247
|
+
fontFromDxfStyle,
|
|
7901
10248
|
TextStyleSchema,
|
|
7902
10249
|
DEFAULT_TEXT_STYLE,
|
|
7903
10250
|
textStyleFor,
|
|
@@ -7916,6 +10263,8 @@ export {
|
|
|
7916
10263
|
approximateTextMeasurer,
|
|
7917
10264
|
lineSegments,
|
|
7918
10265
|
textBlock,
|
|
10266
|
+
normalizeSpans,
|
|
10267
|
+
richTextBlock,
|
|
7919
10268
|
textHeight,
|
|
7920
10269
|
textArrowSize,
|
|
7921
10270
|
textArrowType,
|
|
@@ -7923,10 +10272,34 @@ export {
|
|
|
7923
10272
|
textBoxCorners,
|
|
7924
10273
|
textFrameGeometry,
|
|
7925
10274
|
tableLayout,
|
|
10275
|
+
hashAsset,
|
|
10276
|
+
dataUrlBytes,
|
|
10277
|
+
bytesToDataUrl,
|
|
10278
|
+
imagePixelSize,
|
|
10279
|
+
PX_TO_MM,
|
|
10280
|
+
embeddedAssetId,
|
|
10281
|
+
matIdentity,
|
|
10282
|
+
matMultiply,
|
|
10283
|
+
matApply,
|
|
10284
|
+
signedArcSweep,
|
|
10285
|
+
arcToBeziers,
|
|
10286
|
+
computeHatchLines,
|
|
10287
|
+
ellipseArcToBeziers,
|
|
10288
|
+
getHatchPattern,
|
|
10289
|
+
MAX_HATCH_SEGMENTS,
|
|
10290
|
+
estimatePatternSegments,
|
|
10291
|
+
computePatternGeometry,
|
|
10292
|
+
HatchPatternSchema,
|
|
10293
|
+
hatchPatternKey,
|
|
10294
|
+
resolveHatchPattern,
|
|
7926
10295
|
getLineType,
|
|
7927
10296
|
renderDashes,
|
|
10297
|
+
LineTypeSchema,
|
|
10298
|
+
lineTypeKey,
|
|
10299
|
+
resolveLineType,
|
|
7928
10300
|
CURRENT_DOCUMENT_VERSION,
|
|
7929
10301
|
dimensionRawToOffset,
|
|
10302
|
+
dimensionRawToLabels,
|
|
7930
10303
|
migrateDocument,
|
|
7931
10304
|
HEX_COLOR,
|
|
7932
10305
|
valueParams,
|
|
@@ -7935,6 +10308,7 @@ export {
|
|
|
7935
10308
|
ensureScriptTranspiler,
|
|
7936
10309
|
executeScriptModule,
|
|
7937
10310
|
scriptTranspilerReady,
|
|
10311
|
+
BlockChildSchema,
|
|
7938
10312
|
expandWithBlockDependents,
|
|
7939
10313
|
invalidateBlockCache,
|
|
7940
10314
|
getBlockError,
|
|
@@ -7949,9 +10323,18 @@ export {
|
|
|
7949
10323
|
testBlockDefinition,
|
|
7950
10324
|
getEvaluatedWorldChildren,
|
|
7951
10325
|
ANSI31_BASE_SPACING,
|
|
10326
|
+
linearAxis,
|
|
7952
10327
|
dimensionGeometry,
|
|
10328
|
+
hexToRgb,
|
|
7953
10329
|
rgbToHex,
|
|
7954
10330
|
aciToHex,
|
|
10331
|
+
lineWeightToMm,
|
|
10332
|
+
decodeTextEscapes,
|
|
10333
|
+
mtextWidthFactor,
|
|
10334
|
+
mtextFontFlags,
|
|
10335
|
+
cleanText,
|
|
10336
|
+
cleanRichText,
|
|
10337
|
+
DWG_DXF_OPTIONS,
|
|
7955
10338
|
buildDxf
|
|
7956
10339
|
};
|
|
7957
|
-
//# sourceMappingURL=chunk-
|
|
10340
|
+
//# sourceMappingURL=chunk-BQCSFVAF.js.map
|