lineadraw 0.8.0 → 0.10.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 +373 -199
- package/bin/lineadraw.mjs +15 -110
- package/dist/bridge.d.ts +102 -0
- package/dist/bridge.js +16 -0
- package/dist/chunk-L2CWZAKW.js +141 -0
- package/dist/chunk-L2CWZAKW.js.map +1 -0
- package/dist/{chunk-VWED6V6F.js → chunk-YYJAXJOY.js} +4291 -1114
- package/dist/chunk-YYJAXJOY.js.map +1 -0
- package/dist/exportDxf-C4CLQCC3.js +10 -0
- package/dist/exportDxf-C4CLQCC3.js.map +1 -0
- package/dist/sdk.d.ts +705 -253
- package/dist/sdk.js +288 -231
- package/dist/sdk.js.map +1 -1
- package/lineadraw.d.ts +804 -1649
- package/package.json +3 -3
- package/templates/README.md +6 -4
- package/templates/sample.block.ts +2 -2
- package/dist/chunk-VWED6V6F.js.map +0 -1
- package/dist/exportDxf-2VU5475O.js +0 -8
- /package/dist/{exportDxf-2VU5475O.js.map → bridge.js.map} +0 -0
package/dist/sdk.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BridgeError,
|
|
3
|
+
DEFAULT_BRIDGE_PORT,
|
|
4
|
+
bridgeFilePath,
|
|
5
|
+
connectEditors,
|
|
6
|
+
createBridge
|
|
7
|
+
} from "./chunk-L2CWZAKW.js";
|
|
1
8
|
import {
|
|
2
9
|
ADVANCE_TABLES,
|
|
3
10
|
ANSI31_BASE_SPACING,
|
|
@@ -10,16 +17,17 @@ import {
|
|
|
10
17
|
EXTRACTED_EXTRAS,
|
|
11
18
|
EXTRACTED_RANGES,
|
|
12
19
|
FONTS,
|
|
13
|
-
HEX_COLOR,
|
|
14
20
|
HatchPatternSchema,
|
|
15
21
|
LineTypeSchema,
|
|
16
22
|
MAX_HATCH_SEGMENTS,
|
|
17
23
|
ModelObjectSchema,
|
|
24
|
+
PX_TO_MM,
|
|
18
25
|
REAL_FACES,
|
|
19
26
|
REFERENCE_FORMATS,
|
|
20
27
|
TextStyleSchema,
|
|
21
28
|
Vec2Schema,
|
|
22
29
|
aciToHex,
|
|
30
|
+
acquireInputTable,
|
|
23
31
|
add,
|
|
24
32
|
angle,
|
|
25
33
|
approximateTextMeasurer,
|
|
@@ -28,11 +36,14 @@ import {
|
|
|
28
36
|
blockDefinitionExists,
|
|
29
37
|
blockPivot,
|
|
30
38
|
blockScriptId,
|
|
39
|
+
bytesToDataUrl,
|
|
40
|
+
checkNamedInputs,
|
|
31
41
|
cleanRichText,
|
|
32
42
|
cleanText,
|
|
33
43
|
closestPointOnSegment,
|
|
34
44
|
computeHatchLines,
|
|
35
45
|
computePatternGeometry,
|
|
46
|
+
dataUrlBytes,
|
|
36
47
|
decodeTextEscapes,
|
|
37
48
|
dimFontFace,
|
|
38
49
|
dimStyleFor,
|
|
@@ -40,12 +51,14 @@ import {
|
|
|
40
51
|
dimensionRawToLabels,
|
|
41
52
|
dimensionRawToOffset,
|
|
42
53
|
dist,
|
|
54
|
+
documentBlocks,
|
|
43
55
|
documentObjectResolver,
|
|
44
56
|
dot,
|
|
45
|
-
|
|
57
|
+
dryRunBlockPlacement,
|
|
46
58
|
dryRunObjectResolver,
|
|
47
59
|
effectiveTextFont,
|
|
48
60
|
ellipseArcToBeziers,
|
|
61
|
+
embeddedAssetId,
|
|
49
62
|
ensureScriptTranspiler,
|
|
50
63
|
estimatePatternSegments,
|
|
51
64
|
executeScriptModule,
|
|
@@ -59,17 +72,23 @@ import {
|
|
|
59
72
|
getEvaluatedWorldChildren,
|
|
60
73
|
getHatchPattern,
|
|
61
74
|
getLineType,
|
|
75
|
+
hashAsset,
|
|
62
76
|
hatchPatternKey,
|
|
63
77
|
hexToRgb,
|
|
64
|
-
|
|
65
|
-
|
|
78
|
+
hostedClosure,
|
|
79
|
+
imagePixelSize,
|
|
80
|
+
inputLabel,
|
|
81
|
+
inputPoints,
|
|
82
|
+
inputRefs,
|
|
66
83
|
invalidateBlockCache,
|
|
84
|
+
isRequiredInput,
|
|
67
85
|
len,
|
|
68
86
|
lineSegments,
|
|
69
87
|
lineTypeKey,
|
|
70
88
|
lineWeightToMm,
|
|
71
89
|
linearAxis,
|
|
72
90
|
listBlockMeta,
|
|
91
|
+
mapInputValues,
|
|
73
92
|
matApply,
|
|
74
93
|
matIdentity,
|
|
75
94
|
matMultiply,
|
|
@@ -81,7 +100,9 @@ import {
|
|
|
81
100
|
norm,
|
|
82
101
|
normAngle,
|
|
83
102
|
normalizeSpans,
|
|
103
|
+
paramMismatch,
|
|
84
104
|
parseFontFace,
|
|
105
|
+
parseInputTable,
|
|
85
106
|
parseParamsExport,
|
|
86
107
|
perp,
|
|
87
108
|
realFace,
|
|
@@ -96,7 +117,9 @@ import {
|
|
|
96
117
|
rotateObject,
|
|
97
118
|
scale,
|
|
98
119
|
scaleObjectUniform,
|
|
120
|
+
scanScriptId,
|
|
99
121
|
scriptTranspilerReady,
|
|
122
|
+
selectionFits,
|
|
100
123
|
signedArcSweep,
|
|
101
124
|
sub,
|
|
102
125
|
tableLayout,
|
|
@@ -110,8 +133,9 @@ import {
|
|
|
110
133
|
textStyleFor,
|
|
111
134
|
textWidth,
|
|
112
135
|
translateObject,
|
|
113
|
-
valueParams
|
|
114
|
-
|
|
136
|
+
valueParams,
|
|
137
|
+
withEmptyLists
|
|
138
|
+
} from "./chunk-YYJAXJOY.js";
|
|
115
139
|
import {
|
|
116
140
|
embeddedPdfFonts
|
|
117
141
|
} from "./chunk-L4FNH35X.js";
|
|
@@ -446,9 +470,10 @@ var LineaDocumentSchema = z2.preprocess(
|
|
|
446
470
|
/** Document-defined hatch patterns (model/hatchPatterns.ts), same model. */
|
|
447
471
|
hatchPatterns: z2.array(HatchPatternSchema).default([]),
|
|
448
472
|
/**
|
|
449
|
-
* Embedded
|
|
450
|
-
*
|
|
451
|
-
*
|
|
473
|
+
* Embedded files (the bytes of `asset`-source references — PNG, JPEG,
|
|
474
|
+
* PDF, DXF, DWG, .linea): content hash → data URL. Kept IN the document
|
|
475
|
+
* so the .linea file stays self-contained (the cost is base64 in the
|
|
476
|
+
* JSON). Entries orphaned by deleted references just
|
|
452
477
|
* ride along (no GC — deletion is undoable, so eager sweeps would break
|
|
453
478
|
* redo).
|
|
454
479
|
*/
|
|
@@ -513,14 +538,6 @@ function emptyDocument() {
|
|
|
513
538
|
});
|
|
514
539
|
}
|
|
515
540
|
|
|
516
|
-
// ../core/src/model/assets.ts
|
|
517
|
-
var hashAsset = (data) => {
|
|
518
|
-
let h = 5381;
|
|
519
|
-
for (let i = 0; i < data.length; i++)
|
|
520
|
-
h = (h << 5) + h + data.charCodeAt(i) | 0;
|
|
521
|
-
return `${(h >>> 0).toString(16)}-${data.length.toString(16)}`;
|
|
522
|
-
};
|
|
523
|
-
|
|
524
541
|
// ../core/src/serialize.ts
|
|
525
542
|
var documentToJson = (doc) => JSON.stringify(doc, null, 2);
|
|
526
543
|
var documentFromJson = (text) => LineaDocumentSchema.parse(JSON.parse(text));
|
|
@@ -1240,7 +1257,9 @@ var paintChildren = (children, sink, env, parentLayerId) => {
|
|
|
1240
1257
|
hatchPatterns: env.hatchPatterns,
|
|
1241
1258
|
blockDefinitions: env.blockDefinitions,
|
|
1242
1259
|
resolveObject: env.resolveObject,
|
|
1243
|
-
assets: env.assets
|
|
1260
|
+
assets: env.assets,
|
|
1261
|
+
// A reference child (linked / embedded file) loads like any other.
|
|
1262
|
+
resolveReference: env.resolveReference
|
|
1244
1263
|
}
|
|
1245
1264
|
);
|
|
1246
1265
|
}
|
|
@@ -1258,36 +1277,6 @@ var paintViewport = (obj, sink, env) => {
|
|
|
1258
1277
|
sink.stroke({ color: env.style.color, widthMm: env.style.widthMm });
|
|
1259
1278
|
};
|
|
1260
1279
|
|
|
1261
|
-
// ../core/src/paint/painters/image.ts
|
|
1262
|
-
var paintImage = (obj, sink, env) => {
|
|
1263
|
-
const data = env.assets?.[obj.assetId];
|
|
1264
|
-
if (data !== void 0 && !env.forceStyle) {
|
|
1265
|
-
sink.image({
|
|
1266
|
-
data,
|
|
1267
|
-
origin: obj.origin,
|
|
1268
|
-
widthMm: obj.width,
|
|
1269
|
-
heightMm: obj.height,
|
|
1270
|
-
rotation: obj.rotation,
|
|
1271
|
-
opacity: env.style.opacity ?? 1
|
|
1272
|
-
});
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
const [a, b, c, d] = imageCorners(obj);
|
|
1276
|
-
sink.beginPath();
|
|
1277
|
-
sink.moveTo(a);
|
|
1278
|
-
sink.lineTo(b);
|
|
1279
|
-
sink.lineTo(c);
|
|
1280
|
-
sink.lineTo(d);
|
|
1281
|
-
sink.closePath();
|
|
1282
|
-
if (data === void 0) {
|
|
1283
|
-
sink.moveTo(a);
|
|
1284
|
-
sink.lineTo(c);
|
|
1285
|
-
sink.moveTo(b);
|
|
1286
|
-
sink.lineTo(d);
|
|
1287
|
-
}
|
|
1288
|
-
sink.stroke(env.style);
|
|
1289
|
-
};
|
|
1290
|
-
|
|
1291
1280
|
// ../core/src/paint/painters/table.ts
|
|
1292
1281
|
var paintTable = (obj, sink, env) => paintChildren(tableLayout(obj, env.textStyles).children, sink, env);
|
|
1293
1282
|
|
|
@@ -1706,10 +1695,8 @@ var buildEntry = (obj, ctx) => {
|
|
|
1706
1695
|
};
|
|
1707
1696
|
}
|
|
1708
1697
|
case "block": {
|
|
1709
|
-
const
|
|
1710
|
-
|
|
1711
|
-
);
|
|
1712
|
-
const points = (inputPoints.length > 0 ? inputPoints : [blockPivot(obj)]).map((p) => ({ p, type: "endpoint" }));
|
|
1698
|
+
const pts = inputPoints(obj.inputs);
|
|
1699
|
+
const points = (pts.length > 0 ? pts : inputRefs(obj.inputs).length > 0 ? [] : [blockPivot(obj)]).map((p) => ({ p, type: "endpoint" }));
|
|
1713
1700
|
const segments = [];
|
|
1714
1701
|
const arcs = [];
|
|
1715
1702
|
const ellipses = [];
|
|
@@ -1757,26 +1744,6 @@ var buildEntry = (obj, ctx) => {
|
|
|
1757
1744
|
rings: [outline]
|
|
1758
1745
|
};
|
|
1759
1746
|
}
|
|
1760
|
-
case "image": {
|
|
1761
|
-
const corners = imageCorners(obj);
|
|
1762
|
-
const segments = corners.map((c, i) => ({
|
|
1763
|
-
a: c,
|
|
1764
|
-
b: corners[(i + 1) % corners.length]
|
|
1765
|
-
}));
|
|
1766
|
-
const points = corners.map((p) => ({
|
|
1767
|
-
p,
|
|
1768
|
-
type: "endpoint"
|
|
1769
|
-
}));
|
|
1770
|
-
for (const s of segments)
|
|
1771
|
-
points.push({ p: mid(s.a, s.b), type: "midpoint" });
|
|
1772
|
-
points.push({ p: imageCenter(obj), type: "center" });
|
|
1773
|
-
return {
|
|
1774
|
-
bounds: boundsOfPoints(corners),
|
|
1775
|
-
points,
|
|
1776
|
-
segments,
|
|
1777
|
-
arcs: []
|
|
1778
|
-
};
|
|
1779
|
-
}
|
|
1780
1747
|
case "comment": {
|
|
1781
1748
|
const bounds = emptyBounds();
|
|
1782
1749
|
addPointToBounds(bounds, obj.position);
|
|
@@ -4300,10 +4267,9 @@ var convertAcadTable = (e, ctx) => {
|
|
|
4300
4267
|
const cell = cells[r * cols + c];
|
|
4301
4268
|
const raw = cell.text || cell.display || "";
|
|
4302
4269
|
const a = cell.alignment;
|
|
4303
|
-
const
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
);
|
|
4270
|
+
const inlineHeight = Number(/\\H(\d+(?:\.\d+)?);/.exec(raw)?.[1]);
|
|
4271
|
+
const height = cell.height && cell.height > 0 ? cell.height : inlineHeight > 0 ? inlineHeight : void 0;
|
|
4272
|
+
const rich = cleanRichText(raw, height ?? 2.5);
|
|
4307
4273
|
const text = rich.content.replace(/\s+$/, "");
|
|
4308
4274
|
const spans = normalizeSpans(rich.spans, text).filter(
|
|
4309
4275
|
(s) => s.start > 0 || s.end < text.length
|
|
@@ -4317,7 +4283,7 @@ var convertAcadTable = (e, ctx) => {
|
|
|
4317
4283
|
vAlign: a <= 3 ? "top" : a <= 6 ? "center" : "bottom"
|
|
4318
4284
|
} : {},
|
|
4319
4285
|
styleOverride: {
|
|
4320
|
-
...
|
|
4286
|
+
...height !== void 0 ? { textHeight: height * f } : {},
|
|
4321
4287
|
...mtextFontFlags(raw)
|
|
4322
4288
|
}
|
|
4323
4289
|
};
|
|
@@ -4985,7 +4951,7 @@ var dxfToModel = (text, input) => {
|
|
|
4985
4951
|
|
|
4986
4952
|
// ../core/src/reference/reference.ts
|
|
4987
4953
|
var rebaseReferenceSource = (child, parent) => {
|
|
4988
|
-
if (child.kind
|
|
4954
|
+
if (child.kind !== "path" || parent.kind !== "path") return child;
|
|
4989
4955
|
if (/^([A-Za-z]:[\\/]|[\\/])/.test(child.path)) return child;
|
|
4990
4956
|
const folder = parent.path.replace(/\\/g, "/").replace(/\/?[^/]*$/, "");
|
|
4991
4957
|
return { ...child, path: folder ? `${folder}/${child.path}` : child.path };
|
|
@@ -5028,7 +4994,10 @@ var contentFromDocument = (doc, refId, bounds = emptyBounds()) => {
|
|
|
5028
4994
|
(o) => o.type === "block" ? {
|
|
5029
4995
|
...o,
|
|
5030
4996
|
id: prefix + o.id,
|
|
5031
|
-
inputs:
|
|
4997
|
+
inputs: mapInputValues(
|
|
4998
|
+
o.inputs,
|
|
4999
|
+
(v) => typeof v === "string" ? prefix + v : v
|
|
5000
|
+
)
|
|
5032
5001
|
} : { ...o, id: prefix + o.id }
|
|
5033
5002
|
);
|
|
5034
5003
|
const byId = new Map(objects.map((o) => [o.id, o]));
|
|
@@ -5090,39 +5059,43 @@ var documentFromDxf = (text) => documentWithObjects((doc) => {
|
|
|
5090
5059
|
]
|
|
5091
5060
|
};
|
|
5092
5061
|
});
|
|
5093
|
-
var
|
|
5094
|
-
const
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
{
|
|
5099
|
-
id: "image",
|
|
5100
|
-
type: "image",
|
|
5101
|
-
layerId: doc.layers[0].id,
|
|
5102
|
-
assetId,
|
|
5103
|
-
origin: { x: 0, y: 0 },
|
|
5104
|
-
width: widthMm,
|
|
5105
|
-
height: heightMm,
|
|
5106
|
-
rotation: 0
|
|
5107
|
-
}
|
|
5062
|
+
var rasterSnap = (w, h, layer) => {
|
|
5063
|
+
const corners = [
|
|
5064
|
+
{ x: 0, y: 0 },
|
|
5065
|
+
{ x: w, y: 0 },
|
|
5066
|
+
{ x: w, y: h },
|
|
5067
|
+
{ x: 0, y: h }
|
|
5108
5068
|
];
|
|
5109
|
-
return
|
|
5069
|
+
return {
|
|
5070
|
+
points: [
|
|
5071
|
+
...corners.map((p) => ({ p, type: "endpoint", layer })),
|
|
5072
|
+
...corners.map((p, i) => {
|
|
5073
|
+
const q = corners[(i + 1) % 4];
|
|
5074
|
+
return {
|
|
5075
|
+
p: { x: (p.x + q.x) / 2, y: (p.y + q.y) / 2 },
|
|
5076
|
+
type: "midpoint",
|
|
5077
|
+
layer
|
|
5078
|
+
};
|
|
5079
|
+
}),
|
|
5080
|
+
{ p: { x: w / 2, y: h / 2 }, type: "center", layer }
|
|
5081
|
+
],
|
|
5082
|
+
segments: corners.map((a, i) => ({ a, b: corners[(i + 1) % 4], layer })),
|
|
5083
|
+
arcs: [],
|
|
5084
|
+
ellipses: []
|
|
5085
|
+
};
|
|
5110
5086
|
};
|
|
5111
|
-
var
|
|
5112
|
-
const
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
i += 2 + len2;
|
|
5124
|
-
}
|
|
5125
|
-
return null;
|
|
5087
|
+
var contentFromRaster = (refId, data, width, height) => {
|
|
5088
|
+
const content = contentFromDocument(emptyDocument(), refId, {
|
|
5089
|
+
minX: 0,
|
|
5090
|
+
minY: 0,
|
|
5091
|
+
maxX: width,
|
|
5092
|
+
maxY: height
|
|
5093
|
+
});
|
|
5094
|
+
return {
|
|
5095
|
+
...content,
|
|
5096
|
+
raster: { data, width, height },
|
|
5097
|
+
snap: rasterSnap(width, height, content.layers[0].id)
|
|
5098
|
+
};
|
|
5126
5099
|
};
|
|
5127
5100
|
var measureContentBounds = (content, measure) => {
|
|
5128
5101
|
const ctx = {
|
|
@@ -5266,6 +5239,26 @@ var paintReference = (obj, sink, env) => {
|
|
|
5266
5239
|
w: clip.maxX - clip.minX,
|
|
5267
5240
|
h: clip.maxY - clip.minY
|
|
5268
5241
|
});
|
|
5242
|
+
const raster = content.raster;
|
|
5243
|
+
if (raster) {
|
|
5244
|
+
if (env.forceStyle) {
|
|
5245
|
+
out.beginPath();
|
|
5246
|
+
out.moveTo({ x: 0, y: 0 });
|
|
5247
|
+
out.lineTo({ x: raster.width, y: 0 });
|
|
5248
|
+
out.lineTo({ x: raster.width, y: raster.height });
|
|
5249
|
+
out.lineTo({ x: 0, y: raster.height });
|
|
5250
|
+
out.closePath();
|
|
5251
|
+
out.stroke(env.style);
|
|
5252
|
+
} else
|
|
5253
|
+
out.image({
|
|
5254
|
+
data: raster.data,
|
|
5255
|
+
origin: { x: 0, y: 0 },
|
|
5256
|
+
widthMm: raster.width,
|
|
5257
|
+
heightMm: raster.height,
|
|
5258
|
+
rotation: 0,
|
|
5259
|
+
opacity: fade
|
|
5260
|
+
});
|
|
5261
|
+
}
|
|
5269
5262
|
for (const child of content.objects) {
|
|
5270
5263
|
if (shown.get(child.layerId) === false) continue;
|
|
5271
5264
|
const own = resolveStyle(
|
|
@@ -5345,7 +5338,6 @@ var painters = {
|
|
|
5345
5338
|
dimension: paintDimension,
|
|
5346
5339
|
block: paintBlockInstance,
|
|
5347
5340
|
viewport: paintViewport,
|
|
5348
|
-
image: paintImage,
|
|
5349
5341
|
table: paintTable,
|
|
5350
5342
|
reference: paintReference,
|
|
5351
5343
|
// Screen-fixed editor chrome — painted by the editor's canvas renderer
|
|
@@ -5366,7 +5358,7 @@ var renderBlockThumbnailSvg = async (script, {
|
|
|
5366
5358
|
} = {}) => {
|
|
5367
5359
|
await ensureScriptTranspiler();
|
|
5368
5360
|
const defId = getBlockMeta(script).id;
|
|
5369
|
-
const inputs = await
|
|
5361
|
+
const { inputs, params } = await dryRunBlockPlacement(script);
|
|
5370
5362
|
const defs = [script];
|
|
5371
5363
|
const present = /* @__PURE__ */ new Set([defId]);
|
|
5372
5364
|
for (const extra of definitions) {
|
|
@@ -5382,7 +5374,7 @@ var renderBlockThumbnailSvg = async (script, {
|
|
|
5382
5374
|
definitionId: defId,
|
|
5383
5375
|
rotation: 0,
|
|
5384
5376
|
scale: 1,
|
|
5385
|
-
params
|
|
5377
|
+
params,
|
|
5386
5378
|
inputs
|
|
5387
5379
|
};
|
|
5388
5380
|
const env = {
|
|
@@ -5548,8 +5540,23 @@ var OptionalMetaSchema = z3.object({
|
|
|
5548
5540
|
version: z3.string().optional(),
|
|
5549
5541
|
authors: z3.array(z3.string()).optional(),
|
|
5550
5542
|
tags: z3.array(z3.string()).optional(),
|
|
5551
|
-
|
|
5543
|
+
requiresEditor: z3.boolean().optional()
|
|
5552
5544
|
});
|
|
5545
|
+
var isInputTable = (inputs) => inputs !== void 0 && inputs.length > 0 && typeof inputs[0] !== "string";
|
|
5546
|
+
var parseCommandInputs = (raw, params) => {
|
|
5547
|
+
if (raw === void 0) return void 0;
|
|
5548
|
+
if (Array.isArray(raw) && raw.every((l) => typeof l === "string")) {
|
|
5549
|
+
if (raw.some((l) => l === ""))
|
|
5550
|
+
throw new Error("Invalid command metadata \u2014 inputs: empty label");
|
|
5551
|
+
return raw;
|
|
5552
|
+
}
|
|
5553
|
+
const table = parseInputTable(raw, params);
|
|
5554
|
+
if (table?.some((d) => d.type === "host"))
|
|
5555
|
+
throw new Error(
|
|
5556
|
+
"Invalid command metadata \u2014 inputs: `host` is a block input (a command has no frame to live in)"
|
|
5557
|
+
);
|
|
5558
|
+
return table;
|
|
5559
|
+
};
|
|
5553
5560
|
var extractCommandMeta = (mod) => {
|
|
5554
5561
|
if (typeof mod.id !== "string" || mod.id.trim() === "")
|
|
5555
5562
|
throw new Error("Command script must export a non-empty string `id`");
|
|
@@ -5563,10 +5570,12 @@ var extractCommandMeta = (mod) => {
|
|
|
5563
5570
|
);
|
|
5564
5571
|
}
|
|
5565
5572
|
const params = parseParamsExport(mod.params);
|
|
5573
|
+
const inputs = parseCommandInputs(mod.inputs, params);
|
|
5566
5574
|
return {
|
|
5567
5575
|
id: mod.id,
|
|
5568
5576
|
name: mod.name,
|
|
5569
5577
|
...parsed.data,
|
|
5578
|
+
...inputs ? { inputs } : {},
|
|
5570
5579
|
...params.length > 0 ? { params } : {}
|
|
5571
5580
|
};
|
|
5572
5581
|
};
|
|
@@ -5605,16 +5614,11 @@ var getCommandMetaResult = (script) => {
|
|
|
5605
5614
|
};
|
|
5606
5615
|
var listCommandMeta = (scripts) => scripts.map(getCommandMetaResult);
|
|
5607
5616
|
var getCommandRun = (script) => compileCommand(script).run;
|
|
5608
|
-
var ID_EXPORT_RE = /export\s+const\s+id\s*=\s*["']([^"']+)["']/;
|
|
5609
5617
|
var commandScriptId = (script) => {
|
|
5610
5618
|
try {
|
|
5611
5619
|
return compileCommand(script).meta.id;
|
|
5612
5620
|
} catch {
|
|
5613
|
-
|
|
5614
|
-
if (named) return named[1];
|
|
5615
|
-
const call = script.search(/defineCommand\s*\(|export\s+default\s*\{/);
|
|
5616
|
-
if (call === -1) return void 0;
|
|
5617
|
-
return /\bid\s*:\s*["']([^"']+)["']/.exec(script.slice(call))?.[1];
|
|
5621
|
+
return scanScriptId(script, /defineCommand\s*\(|export\s+default\s*\{/);
|
|
5618
5622
|
}
|
|
5619
5623
|
};
|
|
5620
5624
|
var mergeCommandModules = (existing, incoming) => mergeScriptModules(existing, incoming, {
|
|
@@ -8012,7 +8016,7 @@ var applySetAsset = (doc, op) => {
|
|
|
8012
8016
|
};
|
|
8013
8017
|
};
|
|
8014
8018
|
var assetInUse = (doc, id) => {
|
|
8015
|
-
const used = (objs) => objs.some((o) => o
|
|
8019
|
+
const used = (objs) => objs.some((o) => embeddedAssetId(o) === id);
|
|
8016
8020
|
return used(doc.objects) || doc.layouts.some((l) => used(l.objects));
|
|
8017
8021
|
};
|
|
8018
8022
|
var applyRemoveAsset = (doc, op) => {
|
|
@@ -8193,7 +8197,9 @@ var invalidationIds = (op) => {
|
|
|
8193
8197
|
switch (op.type) {
|
|
8194
8198
|
case "add-objects":
|
|
8195
8199
|
case "update-objects":
|
|
8196
|
-
return op.objects.
|
|
8200
|
+
return op.objects.flatMap(
|
|
8201
|
+
(o) => o.type === "block" ? [o.id, ...inputRefs(o.inputs)] : [o.id]
|
|
8202
|
+
);
|
|
8197
8203
|
case "remove-objects":
|
|
8198
8204
|
return op.ids;
|
|
8199
8205
|
case "set-current-layer":
|
|
@@ -8688,8 +8694,9 @@ var LocalDrawing = class {
|
|
|
8688
8694
|
}
|
|
8689
8695
|
// --- document meta / assets ------------------------------------------------
|
|
8690
8696
|
/**
|
|
8691
|
-
* Embed
|
|
8692
|
-
*
|
|
8697
|
+
* Embed a file (a data URL — PNG, JPEG, PDF…) and return the assetId an
|
|
8698
|
+
* embedded reference's `source: { kind: "asset", assetId }` names.
|
|
8699
|
+
* Content-keyed: the same data reuses one entry.
|
|
8693
8700
|
*/
|
|
8694
8701
|
addAsset(dataUrl) {
|
|
8695
8702
|
const id = hashAsset(dataUrl);
|
|
@@ -8697,7 +8704,7 @@ var LocalDrawing = class {
|
|
|
8697
8704
|
this.applyForward({ type: "set-asset", id, dataUrl });
|
|
8698
8705
|
return id;
|
|
8699
8706
|
}
|
|
8700
|
-
/** Remove an asset (the kernel refuses while
|
|
8707
|
+
/** Remove an asset (the kernel refuses while a reference embeds it). */
|
|
8701
8708
|
removeAsset(id) {
|
|
8702
8709
|
this.applyForward({ type: "remove-asset", id });
|
|
8703
8710
|
}
|
|
@@ -8707,9 +8714,10 @@ var LocalDrawing = class {
|
|
|
8707
8714
|
this.state.objects,
|
|
8708
8715
|
...this.state.layouts.map((l) => l.objects)
|
|
8709
8716
|
])
|
|
8710
|
-
for (const o of objs)
|
|
8711
|
-
|
|
8712
|
-
|
|
8717
|
+
for (const o of objs) {
|
|
8718
|
+
const id = embeddedAssetId(o);
|
|
8719
|
+
if (id !== void 0) users.set(id, (users.get(id) ?? 0) + 1);
|
|
8720
|
+
}
|
|
8713
8721
|
return Object.entries(this.state.assets).map(([id, dataUrl]) => {
|
|
8714
8722
|
const comma = dataUrl.indexOf(",");
|
|
8715
8723
|
const base64 = dataUrl.slice(comma + 1);
|
|
@@ -8748,7 +8756,8 @@ var LocalDrawing = class {
|
|
|
8748
8756
|
return this.importDxfText(await dwgToDxf(data), opts);
|
|
8749
8757
|
}
|
|
8750
8758
|
/** Merge a PDF: its vector/text content onto the current layer, or
|
|
8751
|
-
* (`as: "image"`) every page
|
|
8759
|
+
* (`as: "image"`) embedded, every page a raster reference at true page
|
|
8760
|
+
* scale. */
|
|
8752
8761
|
async importPdfData(data, opts = {}) {
|
|
8753
8762
|
if (opts.as === "image") {
|
|
8754
8763
|
if (!this.rasterizePdf)
|
|
@@ -8758,15 +8767,20 @@ var LocalDrawing = class {
|
|
|
8758
8767
|
const pages = await this.rasterizePdf(data);
|
|
8759
8768
|
const at = toVec(opts.origin ?? [0, 0]);
|
|
8760
8769
|
const layerId2 = this.state.currentLayerId;
|
|
8770
|
+
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
8771
|
+
const assetId = this.addAsset(bytesToDataUrl(bytes, "application/pdf"));
|
|
8761
8772
|
let x = at.x;
|
|
8762
|
-
const placed = pages.map((p) => {
|
|
8773
|
+
const placed = pages.map((p, i) => {
|
|
8763
8774
|
const object = {
|
|
8764
|
-
type: "
|
|
8775
|
+
type: "reference",
|
|
8765
8776
|
layerId: layerId2,
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8777
|
+
format: "pdf",
|
|
8778
|
+
name: pages.length > 1 ? `PDF page ${i + 1}` : "PDF",
|
|
8779
|
+
source: { kind: "asset", assetId },
|
|
8780
|
+
pdfPage: i + 1,
|
|
8781
|
+
pdfMode: "raster",
|
|
8782
|
+
position: { x, y: at.y },
|
|
8783
|
+
extent: { minX: 0, minY: 0, maxX: p.widthMm, maxY: p.heightMm }
|
|
8770
8784
|
};
|
|
8771
8785
|
x += p.widthMm + PDF_PAGE_GAP_MM;
|
|
8772
8786
|
return object;
|
|
@@ -8952,10 +8966,6 @@ var LocalDrawing = class {
|
|
|
8952
8966
|
id: this.resolveStyle(this.state.dimStyles, nameOrId, "dim style").id
|
|
8953
8967
|
});
|
|
8954
8968
|
}
|
|
8955
|
-
/** @deprecated Use updateDimStyle (default here: the first style). */
|
|
8956
|
-
setDimStyle(patch, styleId) {
|
|
8957
|
-
this.updateDimStyle(styleId ?? this.state.dimStyles[0].id, patch);
|
|
8958
|
-
}
|
|
8959
8969
|
/** Replace the document's dimension styles (min 1; objects reference by
|
|
8960
8970
|
* id). Diffed into granular per-style ops. */
|
|
8961
8971
|
setDimStyles(styles) {
|
|
@@ -8963,10 +8973,6 @@ var LocalDrawing = class {
|
|
|
8963
8973
|
assertUniqueIds(parsed, "setDimStyles()");
|
|
8964
8974
|
this.applyForwardAll(diffDimStyleOps(this.state.dimStyles, parsed));
|
|
8965
8975
|
}
|
|
8966
|
-
/** @deprecated Use updateTextStyle (default here: the first style). */
|
|
8967
|
-
setTextStyle(patch, styleId) {
|
|
8968
|
-
this.updateTextStyle(styleId ?? this.state.textStyles[0].id, patch);
|
|
8969
|
-
}
|
|
8970
8976
|
/** Replace the document's text styles (min 1; objects reference by id).
|
|
8971
8977
|
* Diffed into granular per-style ops. */
|
|
8972
8978
|
setTextStyles(styles) {
|
|
@@ -9334,7 +9340,12 @@ var LocalDrawing = class {
|
|
|
9334
9340
|
/** Delete objects by id (unknown ids are skipped); returns how many went. */
|
|
9335
9341
|
remove(ids) {
|
|
9336
9342
|
const entries = [];
|
|
9337
|
-
|
|
9343
|
+
const all = hostedClosure(
|
|
9344
|
+
ids,
|
|
9345
|
+
this.state.blockDefinitions,
|
|
9346
|
+
documentBlocks(this.state)
|
|
9347
|
+
);
|
|
9348
|
+
for (const id of all) {
|
|
9338
9349
|
try {
|
|
9339
9350
|
entries.push({ space: this.findObject(id).space, item: id });
|
|
9340
9351
|
} catch {
|
|
@@ -9469,6 +9480,7 @@ var LocalDrawing = class {
|
|
|
9469
9480
|
return {
|
|
9470
9481
|
dimStyles: this.state.dimStyles,
|
|
9471
9482
|
textStyles: this.state.textStyles,
|
|
9483
|
+
layers: this.state.layers,
|
|
9472
9484
|
blockDefinitions: this.state.blockDefinitions,
|
|
9473
9485
|
resolveObject: this.resolveObject(),
|
|
9474
9486
|
resolveReference: this.resolveReference,
|
|
@@ -9635,19 +9647,17 @@ var LocalDrawing = class {
|
|
|
9635
9647
|
}
|
|
9636
9648
|
/** Export the document to a DXF string. */
|
|
9637
9649
|
async toDxf() {
|
|
9638
|
-
const { buildDxf } = await import("./exportDxf-
|
|
9650
|
+
const { buildDxf } = await import("./exportDxf-C4CLQCC3.js");
|
|
9639
9651
|
return buildDxf(this.state, this.measurer).content;
|
|
9640
9652
|
}
|
|
9641
9653
|
/** Export the document to DWG bytes (the DXF content, wasm-transcoded).
|
|
9642
9654
|
* Defaults to AC1027 (AutoCAD 2013) — readable by every current CAD tool.
|
|
9643
|
-
* Dimensions transcode as real DIMENSION objects; leaders
|
|
9644
|
-
* plain geometry (
|
|
9645
|
-
*
|
|
9655
|
+
* Dimensions transcode as real DIMENSION objects; leaders and tables are
|
|
9656
|
+
* exploded to plain geometry (DWG_DXF_OPTIONS — the transcoder's DWG
|
|
9657
|
+
* output for them is not accepted by AutoCAD). */
|
|
9646
9658
|
async toDwg(opts) {
|
|
9647
|
-
const { buildDxf } = await import("./exportDxf-
|
|
9648
|
-
const dxf = buildDxf(this.state, this.measurer,
|
|
9649
|
-
explodeLeaders: true
|
|
9650
|
-
}).content;
|
|
9659
|
+
const { buildDxf, DWG_DXF_OPTIONS } = await import("./exportDxf-C4CLQCC3.js");
|
|
9660
|
+
const dxf = buildDxf(this.state, this.measurer, DWG_DXF_OPTIONS).content;
|
|
9651
9661
|
return dxfToDwg(dxf, opts?.version ?? "AC1027");
|
|
9652
9662
|
}
|
|
9653
9663
|
toLinea() {
|
|
@@ -9656,66 +9666,15 @@ var LocalDrawing = class {
|
|
|
9656
9666
|
};
|
|
9657
9667
|
|
|
9658
9668
|
// ../core/src/drawing/runCommand.ts
|
|
9659
|
-
var needsEditor = (what) => () => {
|
|
9660
|
-
throw new Error(`${what} needs an editor (this command runs headlessly)`);
|
|
9661
|
-
};
|
|
9662
9669
|
var makeContext = (opts, inputs, params) => {
|
|
9663
9670
|
const { document, editor } = opts;
|
|
9664
9671
|
return {
|
|
9665
9672
|
document,
|
|
9666
9673
|
editor,
|
|
9667
9674
|
inputs,
|
|
9668
|
-
params
|
|
9669
|
-
// Deprecated shorthands (pre-`editor` wire form) — one release.
|
|
9670
|
-
pickPoint: editor ? (label) => editor.pickPoint({ label }) : needsEditor("pickPoint"),
|
|
9671
|
-
pickObject: editor ? (label) => editor.pickObject({ label }) : needsEditor("pickObject"),
|
|
9672
|
-
selection: editor ? () => editor.state().selectedIds : needsEditor("selection"),
|
|
9673
|
-
setSelection: editor ? (ids) => editor.setSelection(ids) : needsEditor("setSelection"),
|
|
9674
|
-
prompt: editor ? (message, o) => editor.prompt(message, o) : needsEditor("prompt"),
|
|
9675
|
-
showToast: editor ? (message, kind) => editor.toast(message, kind) : () => {
|
|
9676
|
-
}
|
|
9675
|
+
params
|
|
9677
9676
|
};
|
|
9678
9677
|
};
|
|
9679
|
-
var paramMismatch = (def, value) => {
|
|
9680
|
-
switch (def.type) {
|
|
9681
|
-
case "number":
|
|
9682
|
-
if (typeof value !== "number" || !Number.isFinite(value))
|
|
9683
|
-
return "expected a number";
|
|
9684
|
-
if (def.integer && !Number.isInteger(value))
|
|
9685
|
-
return "expected a whole number";
|
|
9686
|
-
if (def.min !== void 0 && value < def.min)
|
|
9687
|
-
return `below the minimum ${def.min}`;
|
|
9688
|
-
if (def.max !== void 0 && value > def.max)
|
|
9689
|
-
return `above the maximum ${def.max}`;
|
|
9690
|
-
return null;
|
|
9691
|
-
case "string":
|
|
9692
|
-
case "textStyle":
|
|
9693
|
-
case "dimStyle":
|
|
9694
|
-
case "font":
|
|
9695
|
-
case "lineType":
|
|
9696
|
-
case "hatchPattern":
|
|
9697
|
-
return typeof value === "string" ? null : "expected a string";
|
|
9698
|
-
case "boolean":
|
|
9699
|
-
return typeof value === "boolean" ? null : "expected true or false";
|
|
9700
|
-
case "numberList": {
|
|
9701
|
-
if (!Array.isArray(value) || !value.every((v) => typeof v === "number" && Number.isFinite(v)))
|
|
9702
|
-
return "expected an array of numbers";
|
|
9703
|
-
const low = value.find((v) => def.min !== void 0 && v < def.min);
|
|
9704
|
-
if (low !== void 0) return `${low} is below the minimum ${def.min}`;
|
|
9705
|
-
const high = value.find((v) => def.max !== void 0 && v > def.max);
|
|
9706
|
-
if (high !== void 0) return `${high} is above the maximum ${def.max}`;
|
|
9707
|
-
return null;
|
|
9708
|
-
}
|
|
9709
|
-
case "color":
|
|
9710
|
-
return typeof value === "string" && HEX_COLOR.test(value) ? null : 'expected a "#rrggbb" color';
|
|
9711
|
-
case "stringList":
|
|
9712
|
-
return Array.isArray(value) && value.every((v) => typeof v === "string") ? null : "expected an array of strings";
|
|
9713
|
-
case "enum":
|
|
9714
|
-
return def.options.some((o) => o.value === value) ? null : `expected one of ${def.options.map((o) => JSON.stringify(o.value)).join(", ")}`;
|
|
9715
|
-
default:
|
|
9716
|
-
return "a label carries no value";
|
|
9717
|
-
}
|
|
9718
|
-
};
|
|
9719
9678
|
var resolveCommandParams = (meta, given = {}) => {
|
|
9720
9679
|
const defs = valueParams(meta.params ?? []);
|
|
9721
9680
|
const params = /* @__PURE__ */ Object.create(null);
|
|
@@ -9733,8 +9692,57 @@ var resolveCommandParams = (meta, given = {}) => {
|
|
|
9733
9692
|
}
|
|
9734
9693
|
return params;
|
|
9735
9694
|
};
|
|
9695
|
+
var surfacePickers = (editor, document) => {
|
|
9696
|
+
let selectionUsed = false;
|
|
9697
|
+
const fromSelection = (def) => {
|
|
9698
|
+
if (selectionUsed) return null;
|
|
9699
|
+
const selected = editor.state().selectedIds.map((id) => document.getObject(id)).filter((o) => o !== void 0);
|
|
9700
|
+
if (!selectionFits(def, selected)) return null;
|
|
9701
|
+
selectionUsed = true;
|
|
9702
|
+
return selected.map((o) => o.id);
|
|
9703
|
+
};
|
|
9704
|
+
return {
|
|
9705
|
+
point: (def, ref) => editor.pickPoint({ label: inputLabel(def), referencePoint: ref }),
|
|
9706
|
+
points: (def, ref) => editor.pickPoints({ ...def, referencePoint: ref }),
|
|
9707
|
+
object: async (def) => fromSelection({ types: def.types, min: 1, max: 1 })?.[0] ?? editor.pickObject({ label: inputLabel(def), types: def.types }),
|
|
9708
|
+
objects: async (def) => fromSelection(def) ?? editor.pickObjects(def)
|
|
9709
|
+
};
|
|
9710
|
+
};
|
|
9711
|
+
var acquireNamedCommandInputs = async (meta, table, opts) => {
|
|
9712
|
+
const { inputs, missing } = checkNamedInputs(
|
|
9713
|
+
meta.name,
|
|
9714
|
+
table,
|
|
9715
|
+
opts.inputs,
|
|
9716
|
+
(id) => opts.document.getObject(id)
|
|
9717
|
+
);
|
|
9718
|
+
if (!opts.editor) {
|
|
9719
|
+
const required = missing.filter(isRequiredInput);
|
|
9720
|
+
if (required.length > 0)
|
|
9721
|
+
throw new Error(
|
|
9722
|
+
`${meta.name} needs an editor for: ${required.map((d) => d.name).join(", ")} \u2014 supply inputs`
|
|
9723
|
+
);
|
|
9724
|
+
return withEmptyLists(table, inputs);
|
|
9725
|
+
}
|
|
9726
|
+
if (missing.length === 0) return inputs;
|
|
9727
|
+
const picked = await acquireInputTable(
|
|
9728
|
+
missing,
|
|
9729
|
+
surfacePickers(opts.editor, opts.document)
|
|
9730
|
+
);
|
|
9731
|
+
const out = {};
|
|
9732
|
+
for (const def of table) {
|
|
9733
|
+
const v = inputs[def.name] ?? picked[def.name];
|
|
9734
|
+
if (v !== void 0) out[def.name] = v;
|
|
9735
|
+
}
|
|
9736
|
+
return out;
|
|
9737
|
+
};
|
|
9736
9738
|
var acquireCommandInputs = async (meta, opts) => {
|
|
9739
|
+
if (isInputTable(meta.inputs))
|
|
9740
|
+
return acquireNamedCommandInputs(meta, meta.inputs, opts);
|
|
9737
9741
|
const labels = meta.inputs ?? [];
|
|
9742
|
+
if (opts.inputs !== void 0 && !Array.isArray(opts.inputs))
|
|
9743
|
+
throw new Error(
|
|
9744
|
+
`${meta.name}: inputs are positional (${labels.join(", ") || "none declared"}) \u2014 pass an array`
|
|
9745
|
+
);
|
|
9738
9746
|
const given = (opts.inputs ?? []).map((p, i) => {
|
|
9739
9747
|
try {
|
|
9740
9748
|
return Vec2Schema.parse(p);
|
|
@@ -9766,11 +9774,29 @@ var runCommandModule = async (source, opts) => {
|
|
|
9766
9774
|
const result = getCommandMetaResult(source);
|
|
9767
9775
|
if (!result.ok) throw new Error(`Command failed to compile: ${result.error}`);
|
|
9768
9776
|
const run = getCommandRun(source);
|
|
9777
|
+
if (result.meta.requiresEditor && !opts.editor)
|
|
9778
|
+
throw new Error(
|
|
9779
|
+
`${result.meta.name} needs the editor (it asks during the run) \u2014 run it from Linea`
|
|
9780
|
+
);
|
|
9769
9781
|
const params = resolveCommandParams(result.meta, opts.params);
|
|
9770
9782
|
const inputs = await acquireCommandInputs(result.meta, opts);
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9783
|
+
try {
|
|
9784
|
+
return await opts.document.transaction(
|
|
9785
|
+
() => run(makeContext(opts, inputs, params)),
|
|
9786
|
+
result.meta.name
|
|
9787
|
+
);
|
|
9788
|
+
} catch (e) {
|
|
9789
|
+
throw opts.editor ? e : namedEditorError(result.meta.name, e);
|
|
9790
|
+
}
|
|
9791
|
+
};
|
|
9792
|
+
var namedEditorError = (name, e) => {
|
|
9793
|
+
const m = e instanceof TypeError ? /reading '(pickPoint|pickPoints|pickObject|pickObjects|prompt|ask|toast|state|setSelection|setActiveSpace|zoom|listCommands|runCommand)'/.exec(
|
|
9794
|
+
e.message
|
|
9795
|
+
) : null;
|
|
9796
|
+
if (!m) return e;
|
|
9797
|
+
return new Error(
|
|
9798
|
+
`${name} used editor.${m[1]} but runs without an editor here \u2014 check \`editor\` before using it, or declare \`requiresEditor: true\``,
|
|
9799
|
+
{ cause: e }
|
|
9774
9800
|
);
|
|
9775
9801
|
};
|
|
9776
9802
|
var runDocumentCommand = async (id, opts) => {
|
|
@@ -9824,18 +9850,30 @@ var referenceDocument = async (ref, bytes) => {
|
|
|
9824
9850
|
}));
|
|
9825
9851
|
}
|
|
9826
9852
|
case "png":
|
|
9827
|
-
case "jpg":
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9853
|
+
case "jpg":
|
|
9854
|
+
throw new Error("pictures load as raster content");
|
|
9855
|
+
}
|
|
9856
|
+
};
|
|
9857
|
+
var referenceContent = async (ref, bytes) => {
|
|
9858
|
+
if (ref.format === "png" || ref.format === "jpg") {
|
|
9859
|
+
const size = imagePixelSize(bytes);
|
|
9860
|
+
if (!size) throw new Error(`${ref.name}: not a PNG/JPEG`);
|
|
9861
|
+
const mime = ref.format === "png" ? "image/png" : "image/jpeg";
|
|
9862
|
+
return contentFromRaster(
|
|
9863
|
+
ref.id,
|
|
9864
|
+
`data:${mime};base64,${Buffer.from(bytes).toString("base64")}`,
|
|
9865
|
+
size.width * PX_TO_MM,
|
|
9866
|
+
size.height * PX_TO_MM
|
|
9867
|
+
);
|
|
9838
9868
|
}
|
|
9869
|
+
const content = contentFromDocument(
|
|
9870
|
+
await referenceDocument(ref, bytes),
|
|
9871
|
+
ref.id
|
|
9872
|
+
);
|
|
9873
|
+
return {
|
|
9874
|
+
...content,
|
|
9875
|
+
bounds: measureContentBounds(content, approximateTextMeasurer)
|
|
9876
|
+
};
|
|
9839
9877
|
};
|
|
9840
9878
|
var Drawing = class extends LocalDrawing {
|
|
9841
9879
|
path;
|
|
@@ -9873,22 +9911,31 @@ var Drawing = class extends LocalDrawing {
|
|
|
9873
9911
|
...this.layouts.flatMap((l) => l.objects)
|
|
9874
9912
|
].filter((o) => o.type === "reference");
|
|
9875
9913
|
for (const ref of refs) {
|
|
9876
|
-
const content = await this.loadReference(
|
|
9914
|
+
const content = await this.loadReference(
|
|
9915
|
+
ref,
|
|
9916
|
+
ref.source,
|
|
9917
|
+
this.state.assets,
|
|
9918
|
+
0,
|
|
9919
|
+
/* @__PURE__ */ new Set()
|
|
9920
|
+
);
|
|
9877
9921
|
if (content) this.referenceContent.set(ref.id, content);
|
|
9878
9922
|
else this.referenceContent.delete(ref.id);
|
|
9879
9923
|
}
|
|
9880
9924
|
}
|
|
9881
9925
|
/** One reference's content (null when unreadable); a .linea's own
|
|
9882
|
-
* references load relative to it —
|
|
9883
|
-
* file above in the chain (the
|
|
9884
|
-
|
|
9885
|
-
|
|
9926
|
+
* references load relative to it — and its embedded ones from ITS assets —
|
|
9927
|
+
* depth-limited, never re-entering a file above in the chain (the
|
|
9928
|
+
* editor's rules). */
|
|
9929
|
+
async loadReference(ref, source, assets, depth, seen) {
|
|
9930
|
+
let content;
|
|
9886
9931
|
try {
|
|
9887
|
-
|
|
9932
|
+
content = await referenceContent(
|
|
9933
|
+
ref,
|
|
9934
|
+
await this.readSource(source, assets)
|
|
9935
|
+
);
|
|
9888
9936
|
} catch {
|
|
9889
9937
|
return null;
|
|
9890
9938
|
}
|
|
9891
|
-
const content = contentFromDocument(doc, ref.id);
|
|
9892
9939
|
if (ref.format === "linea" && depth + 1 < 4) {
|
|
9893
9940
|
const above = new Set(seen).add(JSON.stringify(source));
|
|
9894
9941
|
const nested = /* @__PURE__ */ new Map();
|
|
@@ -9899,19 +9946,23 @@ var Drawing = class extends LocalDrawing {
|
|
|
9899
9946
|
const c = await this.loadReference(
|
|
9900
9947
|
child,
|
|
9901
9948
|
childSource,
|
|
9949
|
+
content.assets ?? {},
|
|
9902
9950
|
depth + 1,
|
|
9903
9951
|
above
|
|
9904
9952
|
);
|
|
9905
9953
|
if (c) nested.set(child.id, c);
|
|
9906
9954
|
}
|
|
9907
9955
|
content.resolveReference = (r) => nested.get(r.id) ?? null;
|
|
9956
|
+
content.bounds = measureContentBounds(content, approximateTextMeasurer);
|
|
9908
9957
|
}
|
|
9909
|
-
return
|
|
9910
|
-
...content,
|
|
9911
|
-
bounds: measureContentBounds(content, approximateTextMeasurer)
|
|
9912
|
-
};
|
|
9958
|
+
return content;
|
|
9913
9959
|
}
|
|
9914
|
-
async readSource(source) {
|
|
9960
|
+
async readSource(source, assets) {
|
|
9961
|
+
if (source.kind === "asset") {
|
|
9962
|
+
const data = assets[source.assetId];
|
|
9963
|
+
if (data === void 0) throw new Error("embedded file missing");
|
|
9964
|
+
return dataUrlBytes(data);
|
|
9965
|
+
}
|
|
9915
9966
|
if (source.kind === "url") {
|
|
9916
9967
|
const res = await fetch(source.url);
|
|
9917
9968
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
@@ -9991,7 +10042,8 @@ var Drawing = class extends LocalDrawing {
|
|
|
9991
10042
|
}
|
|
9992
10043
|
// --- scripts ---------------------------------------------------------------
|
|
9993
10044
|
/** Run a command module source (`defineCommand`) against this drawing as
|
|
9994
|
-
* ONE undo step, headlessly: declared `inputs` must be supplied
|
|
10045
|
+
* ONE undo step, headlessly: declared `inputs` must be supplied (points
|
|
10046
|
+
* in label order, or a record by name for an inputs table); declared
|
|
9995
10047
|
* `params` take their defaults unless given by name (unknown names and
|
|
9996
10048
|
* wrong types throw). Resolves with the script's return value. */
|
|
9997
10049
|
runScript(source, inputs, params) {
|
|
@@ -10032,7 +10084,12 @@ async function openDrawing(path, options = {}) {
|
|
|
10032
10084
|
return doc;
|
|
10033
10085
|
}
|
|
10034
10086
|
export {
|
|
10087
|
+
BridgeError,
|
|
10088
|
+
DEFAULT_BRIDGE_PORT,
|
|
10035
10089
|
Drawing,
|
|
10090
|
+
bridgeFilePath,
|
|
10091
|
+
connectEditors,
|
|
10092
|
+
createBridge,
|
|
10036
10093
|
drawingFromJson,
|
|
10037
10094
|
ensureScriptTranspiler,
|
|
10038
10095
|
getBlockMetaResult,
|