@mylasertools/kerfscript 0.2.1 → 0.4.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/CHANGELOG.md +99 -2
- package/LANGUAGE.md +102 -66
- package/README.md +21 -10
- package/THIRD-PARTY-NOTICES.md +13 -4
- package/dist/assembly.d.cts +20 -0
- package/dist/assembly.d.ts +20 -0
- package/dist/cli.js +923 -288
- package/dist/evaluator.d.cts +6 -0
- package/dist/evaluator.d.ts +6 -0
- package/dist/export/dxf.d.cts +1 -1
- package/dist/export/dxf.d.ts +1 -1
- package/dist/font.d.cts +3 -0
- package/dist/font.d.ts +3 -0
- package/dist/functions.d.cts +21 -2
- package/dist/functions.d.ts +21 -2
- package/dist/geometry.d.cts +2 -0
- package/dist/geometry.d.ts +2 -0
- package/dist/index.cjs +24 -19
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +24 -19
- package/dist/lexer.d.cts +4 -1
- package/dist/lexer.d.ts +4 -1
- package/dist/parser.d.cts +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/render.d.cts +3 -1
- package/dist/render.d.ts +3 -1
- package/dist/values.d.cts +10 -2
- package/dist/values.d.ts +10 -2
- package/dist/wasm.d.cts +1 -0
- package/dist/wasm.d.ts +1 -0
- package/docs/cli.md +46 -20
- package/docs/compatibility.md +3 -3
- package/docs/customizer.md +9 -9
- package/docs/desktop.md +96 -0
- package/docs/javascript.md +30 -27
- package/docs/layers.md +6 -6
- package/docs/openscad.md +9 -9
- package/docs/parts-and-sheets.md +32 -0
- package/docs/versions.md +2 -2
- package/docs/webassembly.md +133 -0
- package/fonts/OFL.txt +92 -0
- package/package.json +6 -3
package/dist/cli.js
CHANGED
|
@@ -31,10 +31,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
32
32
|
mod
|
|
33
33
|
));
|
|
34
|
+
var __toBinaryNode = (base64) => new Uint8Array(Buffer.from(base64, "base64"));
|
|
34
35
|
|
|
35
|
-
//
|
|
36
|
+
// node_modules/opentype.js/dist/opentype.js
|
|
36
37
|
var require_opentype = __commonJS({
|
|
37
|
-
"
|
|
38
|
+
"node_modules/opentype.js/dist/opentype.js"(exports, module) {
|
|
38
39
|
(function(global, factory) {
|
|
39
40
|
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = global || self, factory(global.opentype = {}));
|
|
40
41
|
})(exports, (function(exports2) {
|
|
@@ -922,14 +923,14 @@ var require_opentype = __commonJS({
|
|
|
922
923
|
}
|
|
923
924
|
return encodingTable;
|
|
924
925
|
};
|
|
925
|
-
encode.MACSTRING = function(
|
|
926
|
+
encode.MACSTRING = function(str, encoding) {
|
|
926
927
|
var table2 = getMacEncodingTable(encoding);
|
|
927
928
|
if (table2 === void 0) {
|
|
928
929
|
return void 0;
|
|
929
930
|
}
|
|
930
931
|
var result = [];
|
|
931
|
-
for (var i = 0; i <
|
|
932
|
-
var c =
|
|
932
|
+
for (var i = 0; i < str.length; i++) {
|
|
933
|
+
var c = str.charCodeAt(i);
|
|
933
934
|
if (c >= 128) {
|
|
934
935
|
c = table2[c];
|
|
935
936
|
if (c === void 0) {
|
|
@@ -940,8 +941,8 @@ var require_opentype = __commonJS({
|
|
|
940
941
|
}
|
|
941
942
|
return result;
|
|
942
943
|
};
|
|
943
|
-
sizeOf.MACSTRING = function(
|
|
944
|
-
var b = encode.MACSTRING(
|
|
944
|
+
sizeOf.MACSTRING = function(str, encoding) {
|
|
945
|
+
var b = encode.MACSTRING(str, encoding);
|
|
945
946
|
if (b !== void 0) {
|
|
946
947
|
return b.length;
|
|
947
948
|
} else {
|
|
@@ -5687,18 +5688,18 @@ var require_opentype = __commonJS({
|
|
|
5687
5688
|
var language = getLanguageCode(platformID, languageID, ltag2);
|
|
5688
5689
|
var encoding = getEncoding(platformID, encodingID, languageID);
|
|
5689
5690
|
if (encoding !== void 0 && language !== void 0) {
|
|
5690
|
-
var
|
|
5691
|
+
var text2 = void 0;
|
|
5691
5692
|
if (encoding === utf16) {
|
|
5692
|
-
|
|
5693
|
+
text2 = decode.UTF16(data, stringOffset + offset2, byteLength);
|
|
5693
5694
|
} else {
|
|
5694
|
-
|
|
5695
|
+
text2 = decode.MACSTRING(data, stringOffset + offset2, byteLength, encoding);
|
|
5695
5696
|
}
|
|
5696
|
-
if (
|
|
5697
|
+
if (text2) {
|
|
5697
5698
|
var translations = name[property];
|
|
5698
5699
|
if (translations === void 0) {
|
|
5699
5700
|
translations = name[property] = {};
|
|
5700
5701
|
}
|
|
5701
|
-
translations[language] =
|
|
5702
|
+
translations[language] = text2;
|
|
5702
5703
|
}
|
|
5703
5704
|
}
|
|
5704
5705
|
}
|
|
@@ -5778,12 +5779,12 @@ var require_opentype = __commonJS({
|
|
|
5778
5779
|
nameID = nameIDs[i];
|
|
5779
5780
|
var translations = namesWithNumericKeys[nameID];
|
|
5780
5781
|
for (var lang in translations) {
|
|
5781
|
-
var
|
|
5782
|
+
var text2 = translations[lang];
|
|
5782
5783
|
var macPlatform = 1;
|
|
5783
5784
|
var macLanguage = macLanguageIds[lang];
|
|
5784
5785
|
var macScript = macLanguageToScript[macLanguage];
|
|
5785
5786
|
var macEncoding = getEncoding(macPlatform, macScript, macLanguage);
|
|
5786
|
-
var macName = encode.MACSTRING(
|
|
5787
|
+
var macName = encode.MACSTRING(text2, macEncoding);
|
|
5787
5788
|
if (macName === void 0) {
|
|
5788
5789
|
macPlatform = 0;
|
|
5789
5790
|
macLanguage = ltag2.indexOf(lang);
|
|
@@ -5792,7 +5793,7 @@ var require_opentype = __commonJS({
|
|
|
5792
5793
|
ltag2.push(lang);
|
|
5793
5794
|
}
|
|
5794
5795
|
macScript = 4;
|
|
5795
|
-
macName = encode.UTF16(
|
|
5796
|
+
macName = encode.UTF16(text2);
|
|
5796
5797
|
}
|
|
5797
5798
|
var macNameOffset = addStringToPool(macName, stringPool);
|
|
5798
5799
|
nameRecords.push(makeNameRecord(
|
|
@@ -5805,7 +5806,7 @@ var require_opentype = __commonJS({
|
|
|
5805
5806
|
));
|
|
5806
5807
|
var winLanguage = windowsLanguageIds[lang];
|
|
5807
5808
|
if (winLanguage !== void 0) {
|
|
5808
|
-
var winName = encode.UTF16(
|
|
5809
|
+
var winName = encode.UTF16(text2);
|
|
5809
5810
|
var winNameOffset = addStringToPool(winName, stringPool);
|
|
5810
5811
|
nameRecords.push(makeNameRecord(
|
|
5811
5812
|
3,
|
|
@@ -6537,8 +6538,8 @@ var require_opentype = __commonJS({
|
|
|
6537
6538
|
var tag = p.parseTag();
|
|
6538
6539
|
var dataOffset = p.parseULong();
|
|
6539
6540
|
var dataLength = p.parseULong();
|
|
6540
|
-
var
|
|
6541
|
-
tags[tag] =
|
|
6541
|
+
var text2 = decode.UTF8(data, start + dataOffset, dataLength);
|
|
6542
|
+
tags[tag] = text2;
|
|
6542
6543
|
}
|
|
6543
6544
|
return tags;
|
|
6544
6545
|
}
|
|
@@ -10474,10 +10475,10 @@ var require_opentype = __commonJS({
|
|
|
10474
10475
|
}
|
|
10475
10476
|
});
|
|
10476
10477
|
};
|
|
10477
|
-
Tokenizer.prototype.tokenize = function(
|
|
10478
|
+
Tokenizer.prototype.tokenize = function(text2) {
|
|
10478
10479
|
this.tokens = [];
|
|
10479
10480
|
this.resetContextsRanges();
|
|
10480
|
-
var chars = Array.from(
|
|
10481
|
+
var chars = Array.from(text2);
|
|
10481
10482
|
this.dispatch("start");
|
|
10482
10483
|
for (var i = 0; i < chars.length; i++) {
|
|
10483
10484
|
var char = chars[i];
|
|
@@ -11166,8 +11167,8 @@ var require_opentype = __commonJS({
|
|
|
11166
11167
|
this.tokenizer = new Tokenizer();
|
|
11167
11168
|
this.featuresTags = {};
|
|
11168
11169
|
}
|
|
11169
|
-
Bidi.prototype.setText = function(
|
|
11170
|
-
this.text =
|
|
11170
|
+
Bidi.prototype.setText = function(text2) {
|
|
11171
|
+
this.text = text2;
|
|
11171
11172
|
};
|
|
11172
11173
|
Bidi.prototype.contextChecks = {
|
|
11173
11174
|
latinWordCheck,
|
|
@@ -11299,19 +11300,19 @@ var require_opentype = __commonJS({
|
|
|
11299
11300
|
reverseArabicSentences.call(this);
|
|
11300
11301
|
}
|
|
11301
11302
|
};
|
|
11302
|
-
Bidi.prototype.processText = function(
|
|
11303
|
-
if (!this.text || this.text !==
|
|
11304
|
-
this.setText(
|
|
11303
|
+
Bidi.prototype.processText = function(text2) {
|
|
11304
|
+
if (!this.text || this.text !== text2) {
|
|
11305
|
+
this.setText(text2);
|
|
11305
11306
|
tokenizeText.call(this);
|
|
11306
11307
|
this.applyFeaturesToContexts();
|
|
11307
11308
|
}
|
|
11308
11309
|
};
|
|
11309
|
-
Bidi.prototype.getBidiText = function(
|
|
11310
|
-
this.processText(
|
|
11310
|
+
Bidi.prototype.getBidiText = function(text2) {
|
|
11311
|
+
this.processText(text2);
|
|
11311
11312
|
return this.tokenizer.getText();
|
|
11312
11313
|
};
|
|
11313
|
-
Bidi.prototype.getTextGlyphs = function(
|
|
11314
|
-
this.processText(
|
|
11314
|
+
Bidi.prototype.getTextGlyphs = function(text2) {
|
|
11315
|
+
this.processText(text2);
|
|
11315
11316
|
var indexes = [];
|
|
11316
11317
|
for (var i = 0; i < this.tokenizer.tokens.length; i++) {
|
|
11317
11318
|
var token = this.tokenizer.tokens[i];
|
|
@@ -11463,13 +11464,13 @@ var require_opentype = __commonJS({
|
|
|
11463
11464
|
{ script: "latn", tags: ["liga", "rlig"] }
|
|
11464
11465
|
]
|
|
11465
11466
|
};
|
|
11466
|
-
Font.prototype.forEachGlyph = function(
|
|
11467
|
+
Font.prototype.forEachGlyph = function(text2, x, y, fontSize, options, callback) {
|
|
11467
11468
|
x = x !== void 0 ? x : 0;
|
|
11468
11469
|
y = y !== void 0 ? y : 0;
|
|
11469
11470
|
fontSize = fontSize !== void 0 ? fontSize : 72;
|
|
11470
11471
|
options = Object.assign({}, this.defaultRenderOptions, options);
|
|
11471
11472
|
var fontScale = 1 / this.unitsPerEm * fontSize;
|
|
11472
|
-
var glyphs = this.stringToGlyphs(
|
|
11473
|
+
var glyphs = this.stringToGlyphs(text2, options);
|
|
11473
11474
|
var kerningLookups;
|
|
11474
11475
|
if (options.kerning) {
|
|
11475
11476
|
var script = options.script || this.position.getDefaultScriptName();
|
|
@@ -11493,36 +11494,36 @@ var require_opentype = __commonJS({
|
|
|
11493
11494
|
}
|
|
11494
11495
|
return x;
|
|
11495
11496
|
};
|
|
11496
|
-
Font.prototype.getPath = function(
|
|
11497
|
+
Font.prototype.getPath = function(text2, x, y, fontSize, options) {
|
|
11497
11498
|
var fullPath = new Path();
|
|
11498
|
-
this.forEachGlyph(
|
|
11499
|
+
this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
|
|
11499
11500
|
var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
|
|
11500
11501
|
fullPath.extend(glyphPath);
|
|
11501
11502
|
});
|
|
11502
11503
|
return fullPath;
|
|
11503
11504
|
};
|
|
11504
|
-
Font.prototype.getPaths = function(
|
|
11505
|
+
Font.prototype.getPaths = function(text2, x, y, fontSize, options) {
|
|
11505
11506
|
var glyphPaths = [];
|
|
11506
|
-
this.forEachGlyph(
|
|
11507
|
+
this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
|
|
11507
11508
|
var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
|
|
11508
11509
|
glyphPaths.push(glyphPath);
|
|
11509
11510
|
});
|
|
11510
11511
|
return glyphPaths;
|
|
11511
11512
|
};
|
|
11512
|
-
Font.prototype.getAdvanceWidth = function(
|
|
11513
|
-
return this.forEachGlyph(
|
|
11513
|
+
Font.prototype.getAdvanceWidth = function(text2, fontSize, options) {
|
|
11514
|
+
return this.forEachGlyph(text2, 0, 0, fontSize, options, function() {
|
|
11514
11515
|
});
|
|
11515
11516
|
};
|
|
11516
|
-
Font.prototype.draw = function(ctx,
|
|
11517
|
-
this.getPath(
|
|
11517
|
+
Font.prototype.draw = function(ctx, text2, x, y, fontSize, options) {
|
|
11518
|
+
this.getPath(text2, x, y, fontSize, options).draw(ctx);
|
|
11518
11519
|
};
|
|
11519
|
-
Font.prototype.drawPoints = function(ctx,
|
|
11520
|
-
this.forEachGlyph(
|
|
11520
|
+
Font.prototype.drawPoints = function(ctx, text2, x, y, fontSize, options) {
|
|
11521
|
+
this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
|
|
11521
11522
|
glyph.drawPoints(ctx, gX, gY, gFontSize);
|
|
11522
11523
|
});
|
|
11523
11524
|
};
|
|
11524
|
-
Font.prototype.drawMetrics = function(ctx,
|
|
11525
|
-
this.forEachGlyph(
|
|
11525
|
+
Font.prototype.drawMetrics = function(ctx, text2, x, y, fontSize, options) {
|
|
11526
|
+
this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
|
|
11526
11527
|
glyph.drawMetrics(ctx, gX, gY, gFontSize);
|
|
11527
11528
|
});
|
|
11528
11529
|
};
|
|
@@ -12301,16 +12302,292 @@ var require_opentype = __commonJS({
|
|
|
12301
12302
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
12302
12303
|
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
12303
12304
|
|
|
12305
|
+
// src/assembly.ts
|
|
12306
|
+
var RAD = Math.PI / 180;
|
|
12307
|
+
function multiply(a, b) {
|
|
12308
|
+
const out = new Array(16).fill(0);
|
|
12309
|
+
for (let r = 0; r < 4; r++)
|
|
12310
|
+
for (let c = 0; c < 4; c++)
|
|
12311
|
+
for (let k = 0; k < 4; k++) out[r * 4 + c] += a[r * 4 + k] * b[k * 4 + c];
|
|
12312
|
+
return out;
|
|
12313
|
+
}
|
|
12314
|
+
function rotation(axis, degrees) {
|
|
12315
|
+
const c = Math.cos(degrees * RAD);
|
|
12316
|
+
const s = Math.sin(degrees * RAD);
|
|
12317
|
+
if (axis === 0) return [1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1];
|
|
12318
|
+
if (axis === 1) return [c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1];
|
|
12319
|
+
return [c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
12320
|
+
}
|
|
12321
|
+
var clean = (n2) => Math.abs(n2) < 1e-12 ? 0 : n2;
|
|
12322
|
+
function placementMatrix(p) {
|
|
12323
|
+
const [ax, ay, az] = p.rotate;
|
|
12324
|
+
const r = multiply(rotation(2, az), multiply(rotation(1, ay), rotation(0, ax)));
|
|
12325
|
+
r[3] = p.at[0];
|
|
12326
|
+
r[7] = p.at[1];
|
|
12327
|
+
r[11] = p.at[2];
|
|
12328
|
+
return r.map(clean);
|
|
12329
|
+
}
|
|
12330
|
+
function apply(m, x, y, z) {
|
|
12331
|
+
return [
|
|
12332
|
+
m[0] * x + m[1] * y + m[2] * z + m[3],
|
|
12333
|
+
m[4] * x + m[5] * y + m[6] * z + m[7],
|
|
12334
|
+
m[8] * x + m[9] * y + m[10] * z + m[11]
|
|
12335
|
+
];
|
|
12336
|
+
}
|
|
12337
|
+
function invertRigid(m) {
|
|
12338
|
+
const [tx, ty, tz] = [m[3], m[7], m[11]];
|
|
12339
|
+
const r = [m[0], m[4], m[8], m[1], m[5], m[9], m[2], m[6], m[10]];
|
|
12340
|
+
return [
|
|
12341
|
+
r[0],
|
|
12342
|
+
r[1],
|
|
12343
|
+
r[2],
|
|
12344
|
+
-(r[0] * tx + r[1] * ty + r[2] * tz),
|
|
12345
|
+
r[3],
|
|
12346
|
+
r[4],
|
|
12347
|
+
r[5],
|
|
12348
|
+
-(r[3] * tx + r[4] * ty + r[5] * tz),
|
|
12349
|
+
r[6],
|
|
12350
|
+
r[7],
|
|
12351
|
+
r[8],
|
|
12352
|
+
-(r[6] * tx + r[7] * ty + r[8] * tz),
|
|
12353
|
+
0,
|
|
12354
|
+
0,
|
|
12355
|
+
0,
|
|
12356
|
+
1
|
|
12357
|
+
];
|
|
12358
|
+
}
|
|
12359
|
+
function bounds2(regions) {
|
|
12360
|
+
let [x0, y0, x1, y1] = [Infinity, Infinity, -Infinity, -Infinity];
|
|
12361
|
+
for (const ring of regions)
|
|
12362
|
+
for (const [x, y] of ring) {
|
|
12363
|
+
x0 = Math.min(x0, x);
|
|
12364
|
+
y0 = Math.min(y0, y);
|
|
12365
|
+
x1 = Math.max(x1, x);
|
|
12366
|
+
y1 = Math.max(y1, y);
|
|
12367
|
+
}
|
|
12368
|
+
return [x0, y0, x1, y1];
|
|
12369
|
+
}
|
|
12370
|
+
function worldBox(p) {
|
|
12371
|
+
const [x0, y0, x1, y1] = bounds2(p.outline);
|
|
12372
|
+
const lo = [Infinity, Infinity, Infinity];
|
|
12373
|
+
const hi = [-Infinity, -Infinity, -Infinity];
|
|
12374
|
+
for (const x of [x0, x1])
|
|
12375
|
+
for (const y of [y0, y1])
|
|
12376
|
+
for (const z of [0, p.thickness]) {
|
|
12377
|
+
const w = apply(p.matrix, x, y, z);
|
|
12378
|
+
for (let k = 0; k < 3; k++) {
|
|
12379
|
+
lo[k] = Math.min(lo[k], w[k]);
|
|
12380
|
+
hi[k] = Math.max(hi[k], w[k]);
|
|
12381
|
+
}
|
|
12382
|
+
}
|
|
12383
|
+
return [lo, hi];
|
|
12384
|
+
}
|
|
12385
|
+
function besideAssembly(placed, loose, gap = 10) {
|
|
12386
|
+
const lo = [Infinity, Infinity, Infinity];
|
|
12387
|
+
const hi = [-Infinity, -Infinity, -Infinity];
|
|
12388
|
+
for (const [a, b] of placed.map(worldBox))
|
|
12389
|
+
for (let k = 0; k < 3; k++) {
|
|
12390
|
+
lo[k] = Math.min(lo[k], a[k]);
|
|
12391
|
+
hi[k] = Math.max(hi[k], b[k]);
|
|
12392
|
+
}
|
|
12393
|
+
const sizes = loose.map((p) => bounds2(p.outline));
|
|
12394
|
+
const limit = sizes.reduce((w, [x0, , x1]) => Math.max(w, x1 - x0), hi[0] - lo[0]);
|
|
12395
|
+
let x = 0;
|
|
12396
|
+
let y = 0;
|
|
12397
|
+
let row = 0;
|
|
12398
|
+
return loose.map((p, i) => {
|
|
12399
|
+
const [x0, y0, x1, y1] = sizes[i];
|
|
12400
|
+
if (x > 0 && x + x1 - x0 > limit) {
|
|
12401
|
+
x = 0;
|
|
12402
|
+
y += row + gap;
|
|
12403
|
+
row = 0;
|
|
12404
|
+
}
|
|
12405
|
+
const matrix = [
|
|
12406
|
+
1,
|
|
12407
|
+
0,
|
|
12408
|
+
0,
|
|
12409
|
+
hi[0] + gap + x - x0,
|
|
12410
|
+
0,
|
|
12411
|
+
1,
|
|
12412
|
+
0,
|
|
12413
|
+
lo[1] + y - y0,
|
|
12414
|
+
0,
|
|
12415
|
+
0,
|
|
12416
|
+
1,
|
|
12417
|
+
lo[2],
|
|
12418
|
+
0,
|
|
12419
|
+
0,
|
|
12420
|
+
0,
|
|
12421
|
+
1
|
|
12422
|
+
];
|
|
12423
|
+
x += x1 - x0 + gap;
|
|
12424
|
+
row = Math.max(row, y1 - y0);
|
|
12425
|
+
return { ...p, matrix: matrix.map(clean) };
|
|
12426
|
+
});
|
|
12427
|
+
}
|
|
12428
|
+
var overlaps = (a, b, eps) => [0, 1, 2].every((k) => a[0][k] < b[1][k] - eps && b[0][k] < a[1][k] - eps);
|
|
12429
|
+
var dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
12430
|
+
var cross = (a, b) => [
|
|
12431
|
+
a[1] * b[2] - a[2] * b[1],
|
|
12432
|
+
a[2] * b[0] - a[0] * b[2],
|
|
12433
|
+
a[0] * b[1] - a[1] * b[0]
|
|
12434
|
+
];
|
|
12435
|
+
var add = (a, b, k = 1) => [a[0] + b[0] * k, a[1] + b[1] * k, a[2] + b[2] * k];
|
|
12436
|
+
var normal = (m) => [m[2], m[6], m[10]];
|
|
12437
|
+
var origin = (m) => [m[3], m[7], m[11]];
|
|
12438
|
+
var turn = (m, v) => [
|
|
12439
|
+
m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
|
|
12440
|
+
m[4] * v[0] + m[5] * v[1] + m[6] * v[2],
|
|
12441
|
+
m[8] * v[0] + m[9] * v[1] + m[10] * v[2]
|
|
12442
|
+
];
|
|
12443
|
+
function spans(regions, from, dir) {
|
|
12444
|
+
const len = dir[0] * dir[0] + dir[1] * dir[1];
|
|
12445
|
+
const hits = [];
|
|
12446
|
+
for (const ring of regions)
|
|
12447
|
+
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
12448
|
+
const a = ring[j];
|
|
12449
|
+
const b = ring[i];
|
|
12450
|
+
const da = dir[0] * (a[1] - from[1]) - dir[1] * (a[0] - from[0]);
|
|
12451
|
+
const db = dir[0] * (b[1] - from[1]) - dir[1] * (b[0] - from[0]);
|
|
12452
|
+
if (da > 0 === db > 0) continue;
|
|
12453
|
+
const f = da / (da - db);
|
|
12454
|
+
const x = a[0] + (b[0] - a[0]) * f - from[0];
|
|
12455
|
+
const y = a[1] + (b[1] - a[1]) * f - from[1];
|
|
12456
|
+
hits.push((x * dir[0] + y * dir[1]) / len);
|
|
12457
|
+
}
|
|
12458
|
+
return hits.sort((p, q) => p - q);
|
|
12459
|
+
}
|
|
12460
|
+
function shared(a, b, eps) {
|
|
12461
|
+
let total = 0;
|
|
12462
|
+
let i = 0;
|
|
12463
|
+
let j = 0;
|
|
12464
|
+
while (i + 1 < a.length && j + 1 < b.length) {
|
|
12465
|
+
const length = Math.min(a[i + 1], b[j + 1]) - Math.max(a[i], b[j]);
|
|
12466
|
+
if (length > eps) total += length;
|
|
12467
|
+
if (a[i + 1] < b[j + 1]) i += 2;
|
|
12468
|
+
else j += 2;
|
|
12469
|
+
}
|
|
12470
|
+
return total;
|
|
12471
|
+
}
|
|
12472
|
+
function steps(lo, hi, eps, pitch) {
|
|
12473
|
+
const from = lo + eps;
|
|
12474
|
+
const to = hi - eps;
|
|
12475
|
+
if (to <= from) return { at: [], size: 0 };
|
|
12476
|
+
const n2 = Math.max(4, Math.ceil((to - from) / pitch));
|
|
12477
|
+
return {
|
|
12478
|
+
at: Array.from({ length: n2 }, (_, i) => from + (to - from) * (i + 0.5) / n2),
|
|
12479
|
+
size: (to - from) / n2
|
|
12480
|
+
};
|
|
12481
|
+
}
|
|
12482
|
+
function localLine(inverse, at, dir) {
|
|
12483
|
+
const p = apply(inverse, at[0], at[1], at[2]);
|
|
12484
|
+
const d2 = turn(inverse, dir);
|
|
12485
|
+
return [
|
|
12486
|
+
[p[0], p[1]],
|
|
12487
|
+
[d2[0], d2[1]]
|
|
12488
|
+
];
|
|
12489
|
+
}
|
|
12490
|
+
function crossing(A, B, invA, invB, eps, pitch, volume) {
|
|
12491
|
+
const nA = normal(A.matrix);
|
|
12492
|
+
const nB = normal(B.matrix);
|
|
12493
|
+
const raw = cross(nA, nB);
|
|
12494
|
+
const size = Math.hypot(...raw);
|
|
12495
|
+
const line = [raw[0] / size, raw[1] / size, raw[2] / size];
|
|
12496
|
+
const side = cross(line, nA);
|
|
12497
|
+
const tilt = dot(nB, side);
|
|
12498
|
+
const oA = origin(A.matrix);
|
|
12499
|
+
const bLevel = dot(nB, origin(B.matrix));
|
|
12500
|
+
const depths = steps(0, A.thickness, eps, pitch);
|
|
12501
|
+
let total = 0;
|
|
12502
|
+
for (const depth of depths.at) {
|
|
12503
|
+
const base = add(oA, nA, depth);
|
|
12504
|
+
const b0 = (bLevel - dot(nB, base)) / tilt;
|
|
12505
|
+
const b1 = (bLevel + B.thickness - dot(nB, base)) / tilt;
|
|
12506
|
+
const alongs = steps(Math.min(b0, b1), Math.max(b0, b1), eps, pitch);
|
|
12507
|
+
for (const along of alongs.at) {
|
|
12508
|
+
const at = add(base, side, along);
|
|
12509
|
+
const [fromA, dirA] = localLine(invA, at, line);
|
|
12510
|
+
const [fromB, dirB] = localLine(invB, at, line);
|
|
12511
|
+
total += shared(spans(A.outline, fromA, dirA), spans(B.outline, fromB, dirB), eps) * depths.size * alongs.size;
|
|
12512
|
+
if (total > volume) return true;
|
|
12513
|
+
}
|
|
12514
|
+
}
|
|
12515
|
+
return false;
|
|
12516
|
+
}
|
|
12517
|
+
function stacked(A, B, invA, eps, pitch, volume) {
|
|
12518
|
+
const rel = [0, 1, 2, 3].flatMap(
|
|
12519
|
+
(r) => [0, 1, 2, 3].map((c) => {
|
|
12520
|
+
let v = 0;
|
|
12521
|
+
for (let k = 0; k < 4; k++) v += invA[r * 4 + k] * B.matrix[k * 4 + c];
|
|
12522
|
+
return v;
|
|
12523
|
+
})
|
|
12524
|
+
);
|
|
12525
|
+
const z0 = rel[11];
|
|
12526
|
+
const z1 = rel[11] + rel[10] * B.thickness;
|
|
12527
|
+
const depth = Math.min(A.thickness, Math.max(z0, z1)) - Math.max(0, Math.min(z0, z1));
|
|
12528
|
+
if (depth <= eps) return false;
|
|
12529
|
+
const moved = B.outline.map(
|
|
12530
|
+
(ring) => ring.map(
|
|
12531
|
+
([x, y]) => [rel[0] * x + rel[1] * y + rel[3], rel[4] * x + rel[5] * y + rel[7]]
|
|
12532
|
+
)
|
|
12533
|
+
);
|
|
12534
|
+
const [ax0, ay0, ax1, ay1] = bounds2(A.outline);
|
|
12535
|
+
const [bx0, by0, bx1, by1] = bounds2(moved);
|
|
12536
|
+
const rows = steps(Math.max(ay0, by0), Math.min(ay1, by1), eps, pitch);
|
|
12537
|
+
let across = 0;
|
|
12538
|
+
for (const y of rows.at) {
|
|
12539
|
+
across += shared(spans(A.outline, [0, y], [1, 0]), spans(moved, [0, y], [1, 0]), eps) * rows.size * depth;
|
|
12540
|
+
if (across > volume) return true;
|
|
12541
|
+
}
|
|
12542
|
+
const columns = steps(Math.max(ax0, bx0), Math.min(ax1, bx1), eps, pitch);
|
|
12543
|
+
let down = 0;
|
|
12544
|
+
for (const x of columns.at) {
|
|
12545
|
+
down += shared(spans(A.outline, [x, 0], [0, 1]), spans(moved, [x, 0], [0, 1]), eps) * columns.size * depth;
|
|
12546
|
+
if (down > volume) return true;
|
|
12547
|
+
}
|
|
12548
|
+
return false;
|
|
12549
|
+
}
|
|
12550
|
+
function collisions(parts, maxPairs = Infinity, eps = 0.05, pitch = 0.25, volume = 1) {
|
|
12551
|
+
const boxes = parts.map(worldBox);
|
|
12552
|
+
const inverses = parts.map((p) => invertRigid(p.matrix));
|
|
12553
|
+
const order = parts.map((_, i) => i).sort((i, j) => boxes[i][0][0] - boxes[j][0][0]);
|
|
12554
|
+
const found = [];
|
|
12555
|
+
let checked = 0;
|
|
12556
|
+
for (let i = 0; i < order.length; i++)
|
|
12557
|
+
for (let j = i + 1; j < order.length; j++) {
|
|
12558
|
+
const a = order[i];
|
|
12559
|
+
const b = order[j];
|
|
12560
|
+
if (boxes[b][0][0] >= boxes[a][1][0] - eps) break;
|
|
12561
|
+
if (!overlaps(boxes[a], boxes[b], eps)) continue;
|
|
12562
|
+
if (++checked > maxPairs) return { found, complete: false };
|
|
12563
|
+
const [A, B] = a < b ? [parts[a], parts[b]] : [parts[b], parts[a]];
|
|
12564
|
+
const [invA, invB] = a < b ? [inverses[a], inverses[b]] : [inverses[b], inverses[a]];
|
|
12565
|
+
const parallel = Math.hypot(...cross(normal(A.matrix), normal(B.matrix))) < 1e-9;
|
|
12566
|
+
const hit = parallel ? stacked(A, B, invA, eps, pitch, volume) : crossing(A, B, invA, invB, eps, pitch, volume);
|
|
12567
|
+
if (hit) found.push([A, B]);
|
|
12568
|
+
}
|
|
12569
|
+
return { found, complete: true };
|
|
12570
|
+
}
|
|
12571
|
+
|
|
12304
12572
|
// src/values.ts
|
|
12305
12573
|
var isRange = (v) => typeof v === "object" && v !== null && !Array.isArray(v) && v.type === "range";
|
|
12306
12574
|
var isFn = (v) => typeof v === "object" && v !== null && !Array.isArray(v) && v.type === "function";
|
|
12307
12575
|
var isNum = (v) => typeof v === "number";
|
|
12576
|
+
var own = (o, key) => o && Object.prototype.hasOwnProperty.call(o, key) ? o[key] : void 0;
|
|
12577
|
+
function checkSetting(name, v, depth = 0) {
|
|
12578
|
+
if (v === null || v === void 0 || ["number", "string", "boolean"].includes(typeof v)) return;
|
|
12579
|
+
if (Array.isArray(v) && depth < 32) {
|
|
12580
|
+
for (const x of v) checkSetting(name, x, depth + 1);
|
|
12581
|
+
return;
|
|
12582
|
+
}
|
|
12583
|
+
throw new Error(`Setting "${name}" must be a number, string, boolean or list`);
|
|
12584
|
+
}
|
|
12308
12585
|
function rangeValues(r, limit) {
|
|
12309
12586
|
const out = [];
|
|
12310
12587
|
if (r.step === 0) return out;
|
|
12311
12588
|
if (r.step > 0 ? r.start > r.end : r.start < r.end) return out;
|
|
12312
12589
|
const n2 = Math.floor((r.end - r.start) / r.step + 1e-9) + 1;
|
|
12313
|
-
if (n2 > limit) throw new Error(`
|
|
12590
|
+
if (n2 > limit) throw new Error(`a range of ${n2} items is more than the limit of ${limit}`);
|
|
12314
12591
|
for (let k = 0; k < n2; k++) out.push(r.start + k * r.step);
|
|
12315
12592
|
return out;
|
|
12316
12593
|
}
|
|
@@ -12320,11 +12597,34 @@ function truthy(v) {
|
|
|
12320
12597
|
if (typeof v === "number") return !Number.isNaN(v);
|
|
12321
12598
|
return true;
|
|
12322
12599
|
}
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
if (
|
|
12327
|
-
|
|
12600
|
+
var same = (a, b) => isRange(a) && isRange(b) ? a.start === b.start && a.step === b.step && a.end === b.end : a === b;
|
|
12601
|
+
function equals(a, b, step) {
|
|
12602
|
+
step?.();
|
|
12603
|
+
if (!Array.isArray(a) || !Array.isArray(b)) return same(a, b);
|
|
12604
|
+
const seen = /* @__PURE__ */ new Map();
|
|
12605
|
+
const open = [];
|
|
12606
|
+
const enter = (x, y) => {
|
|
12607
|
+
let ys = seen.get(x);
|
|
12608
|
+
if (ys?.has(y)) return true;
|
|
12609
|
+
if (x.length !== y.length) return false;
|
|
12610
|
+
if (!ys) seen.set(x, ys = /* @__PURE__ */ new Set());
|
|
12611
|
+
ys.add(y);
|
|
12612
|
+
open.push([x, y, 0]);
|
|
12613
|
+
return true;
|
|
12614
|
+
};
|
|
12615
|
+
if (!enter(a, b)) return false;
|
|
12616
|
+
while (open.length) {
|
|
12617
|
+
const top = open[open.length - 1];
|
|
12618
|
+
if (top[2] === top[0].length) {
|
|
12619
|
+
open.pop();
|
|
12620
|
+
continue;
|
|
12621
|
+
}
|
|
12622
|
+
const x = top[0][top[2]];
|
|
12623
|
+
const y = top[1][top[2]++];
|
|
12624
|
+
step?.();
|
|
12625
|
+
if (Array.isArray(x) && Array.isArray(y) ? !enter(x, y) : !same(x, y)) return false;
|
|
12626
|
+
}
|
|
12627
|
+
return true;
|
|
12328
12628
|
}
|
|
12329
12629
|
function typeName(v) {
|
|
12330
12630
|
if (v === void 0) return "undef";
|
|
@@ -12333,17 +12633,73 @@ function typeName(v) {
|
|
|
12333
12633
|
if (isFn(v)) return "function";
|
|
12334
12634
|
return typeof v;
|
|
12335
12635
|
}
|
|
12336
|
-
function
|
|
12636
|
+
function scalar(v) {
|
|
12337
12637
|
if (v === void 0) return "undef";
|
|
12338
12638
|
if (typeof v === "string") return JSON.stringify(v);
|
|
12339
12639
|
if (typeof v === "number") return fmt(v);
|
|
12340
|
-
if (Array.isArray(v)) return `[${v.map(show).join(", ")}]`;
|
|
12341
12640
|
if (isRange(v)) return `[${fmt(v.start)}:${fmt(v.step)}:${fmt(v.end)}]`;
|
|
12342
12641
|
if (isFn(v)) return `function(${v.params.map((p) => p.name).join(", ")})`;
|
|
12343
12642
|
return String(v);
|
|
12344
12643
|
}
|
|
12345
|
-
function
|
|
12346
|
-
|
|
12644
|
+
function write(v, max, quote = false) {
|
|
12645
|
+
if (typeof v === "string" && !quote)
|
|
12646
|
+
return { text: v.length > max ? v.slice(0, Math.max(max, 0)) : v, whole: v.length <= max };
|
|
12647
|
+
const out = [];
|
|
12648
|
+
let n2 = 0;
|
|
12649
|
+
const put = (s) => {
|
|
12650
|
+
out.push(s);
|
|
12651
|
+
n2 += s.length;
|
|
12652
|
+
};
|
|
12653
|
+
const open = [];
|
|
12654
|
+
let next = v;
|
|
12655
|
+
for (; ; ) {
|
|
12656
|
+
if (Array.isArray(next)) {
|
|
12657
|
+
put("[");
|
|
12658
|
+
open.push([next, 0]);
|
|
12659
|
+
} else put(scalar(next));
|
|
12660
|
+
let more = false;
|
|
12661
|
+
while (open.length && !more) {
|
|
12662
|
+
const top = open[open.length - 1];
|
|
12663
|
+
if (top[1] < top[0].length) {
|
|
12664
|
+
if (top[1]) put(", ");
|
|
12665
|
+
next = top[0][top[1]++];
|
|
12666
|
+
more = true;
|
|
12667
|
+
} else {
|
|
12668
|
+
open.pop();
|
|
12669
|
+
put("]");
|
|
12670
|
+
}
|
|
12671
|
+
}
|
|
12672
|
+
if (!more || n2 > max) break;
|
|
12673
|
+
}
|
|
12674
|
+
const text2 = out.join("");
|
|
12675
|
+
return n2 > max ? { text: text2.slice(0, Math.max(max, 0)), whole: false } : { text: text2, whole: true };
|
|
12676
|
+
}
|
|
12677
|
+
function joinText(vs, sep, max) {
|
|
12678
|
+
const out = [];
|
|
12679
|
+
let n2 = 0;
|
|
12680
|
+
for (const v of vs) {
|
|
12681
|
+
if (out.length) n2 += sep.length;
|
|
12682
|
+
const r = write(v, max - n2);
|
|
12683
|
+
if (!r.whole) return void 0;
|
|
12684
|
+
n2 += r.text.length;
|
|
12685
|
+
out.push(r.text);
|
|
12686
|
+
}
|
|
12687
|
+
return out.join(sep);
|
|
12688
|
+
}
|
|
12689
|
+
function show(v) {
|
|
12690
|
+
const r = write(v, 200, true);
|
|
12691
|
+
return r.whole ? r.text : r.text + "...";
|
|
12692
|
+
}
|
|
12693
|
+
var toText = (v) => typeof v === "string" ? v : show(v);
|
|
12694
|
+
function toNumber(v) {
|
|
12695
|
+
let inList = false;
|
|
12696
|
+
while (Array.isArray(v) && v.length === 1) {
|
|
12697
|
+
v = v[0];
|
|
12698
|
+
inList = true;
|
|
12699
|
+
}
|
|
12700
|
+
if (Array.isArray(v)) return v.length ? NaN : 0;
|
|
12701
|
+
if (inList && (v === void 0 || typeof v === "boolean")) return v === void 0 ? 0 : NaN;
|
|
12702
|
+
return typeof v === "object" ? NaN : Number(v);
|
|
12347
12703
|
}
|
|
12348
12704
|
function fmt(n2) {
|
|
12349
12705
|
if (Number.isInteger(n2)) return String(n2);
|
|
@@ -12351,19 +12707,74 @@ function fmt(n2) {
|
|
|
12351
12707
|
}
|
|
12352
12708
|
|
|
12353
12709
|
// src/functions.ts
|
|
12354
|
-
var
|
|
12710
|
+
var RAD2 = Math.PI / 180;
|
|
12711
|
+
var def = (sig, run, order) => ({
|
|
12712
|
+
params: sig.replace("...", "").split(",").map((p) => p.trim()).filter(Boolean),
|
|
12713
|
+
rest: sig.endsWith("..."),
|
|
12714
|
+
order,
|
|
12715
|
+
run
|
|
12716
|
+
});
|
|
12717
|
+
function givenTwice(f, pos, named) {
|
|
12718
|
+
if (f.order) return [];
|
|
12719
|
+
return f.params.filter((p, i) => i < pos.length && named.has(p));
|
|
12720
|
+
}
|
|
12721
|
+
function bindArgs(f, pos, named) {
|
|
12722
|
+
if (f.rest) {
|
|
12723
|
+
const out = [...pos];
|
|
12724
|
+
f.params.forEach((p, i) => {
|
|
12725
|
+
if (named.has(p)) out[i] = named.get(p);
|
|
12726
|
+
});
|
|
12727
|
+
return out;
|
|
12728
|
+
}
|
|
12729
|
+
if (!f.order) return f.params.map((p, i) => named.has(p) ? named.get(p) : pos[i]);
|
|
12730
|
+
const given = pos.length + f.params.filter((p) => named.has(p)).length;
|
|
12731
|
+
const free = f.order(given).filter((p) => !named.has(p));
|
|
12732
|
+
return f.params.map((p) => named.has(p) ? named.get(p) : pos[free.indexOf(p)]);
|
|
12733
|
+
}
|
|
12734
|
+
function text(vs, sep, c, fn) {
|
|
12735
|
+
const out = joinText(vs, sep, c.maxLength);
|
|
12736
|
+
if (out === void 0)
|
|
12737
|
+
throw new Error(
|
|
12738
|
+
`${fn}(): the text would be longer than the limit of ${c.maxLength} characters`
|
|
12739
|
+
);
|
|
12740
|
+
c.step(Math.ceil(out.length / 8));
|
|
12741
|
+
return out;
|
|
12742
|
+
}
|
|
12355
12743
|
function num(v, fn) {
|
|
12356
12744
|
if (typeof v !== "number") throw new Error(`${fn}() needs a number, got ${typeName(v)}`);
|
|
12357
12745
|
return v;
|
|
12358
12746
|
}
|
|
12359
|
-
function list(v, fn) {
|
|
12747
|
+
function list(v, fn, c) {
|
|
12360
12748
|
if (Array.isArray(v)) return v;
|
|
12361
|
-
if (isRange(v)) return rangeValues(v,
|
|
12749
|
+
if (isRange(v)) return rangeValues(v, c.maxLength);
|
|
12362
12750
|
if (typeof v === "string") return [...v];
|
|
12363
12751
|
throw new Error(`${fn}() needs a list, got ${typeName(v)}`);
|
|
12364
12752
|
}
|
|
12365
|
-
var
|
|
12366
|
-
|
|
12753
|
+
var CONSTANT_TIME = /* @__PURE__ */ new Set([
|
|
12754
|
+
"is_num",
|
|
12755
|
+
"is_string",
|
|
12756
|
+
"is_bool",
|
|
12757
|
+
"is_list",
|
|
12758
|
+
"is_undef",
|
|
12759
|
+
"is_function",
|
|
12760
|
+
"type_of",
|
|
12761
|
+
"ord"
|
|
12762
|
+
]);
|
|
12763
|
+
function argumentWork(name, args, max) {
|
|
12764
|
+
if (CONSTANT_TIME.has(name)) return 0;
|
|
12765
|
+
let n2 = 0;
|
|
12766
|
+
for (const v of args) {
|
|
12767
|
+
if (typeof v === "string") n2 += v.length;
|
|
12768
|
+
else if (Array.isArray(v)) n2 += name === "len" ? 0 : v.length;
|
|
12769
|
+
else if (isRange(v) && v.step !== 0) {
|
|
12770
|
+
const items = Math.floor((v.end - v.start) / v.step) + 1;
|
|
12771
|
+
if (items > 0) n2 += Math.min(items, max + 1);
|
|
12772
|
+
}
|
|
12773
|
+
}
|
|
12774
|
+
return n2;
|
|
12775
|
+
}
|
|
12776
|
+
var math1 = (f) => def("x", (a) => typeof a[0] === "number" ? clean2(f(a[0])) : void 0);
|
|
12777
|
+
function clean2(x) {
|
|
12367
12778
|
const r = Math.round(x);
|
|
12368
12779
|
return Math.abs(x - r) < 1e-12 ? r : x;
|
|
12369
12780
|
}
|
|
@@ -12383,69 +12794,112 @@ function minmax(a, pick, name) {
|
|
|
12383
12794
|
return pick(xs.map((x) => num(x, name)));
|
|
12384
12795
|
}
|
|
12385
12796
|
var FUNCTIONS = {
|
|
12386
|
-
abs: math1(
|
|
12387
|
-
sign: math1(
|
|
12388
|
-
floor: math1(
|
|
12389
|
-
ceil: math1(
|
|
12390
|
-
round: math1(
|
|
12391
|
-
sqrt: math1(
|
|
12392
|
-
exp: math1(
|
|
12393
|
-
ln: math1(
|
|
12394
|
-
log
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12797
|
+
abs: math1(Math.abs),
|
|
12798
|
+
sign: math1(Math.sign),
|
|
12799
|
+
floor: math1(Math.floor),
|
|
12800
|
+
ceil: math1(Math.ceil),
|
|
12801
|
+
round: math1((x) => x < 0 ? -Math.round(-x) : Math.round(x)),
|
|
12802
|
+
sqrt: math1(Math.sqrt),
|
|
12803
|
+
exp: math1(Math.exp),
|
|
12804
|
+
ln: math1(Math.log),
|
|
12805
|
+
// log(x) is base 10; log(base, x) takes the base first
|
|
12806
|
+
log: def(
|
|
12807
|
+
"x, base",
|
|
12808
|
+
(a, c) => c.given < 2 ? clean2(Math.log10(num(a[0], "log"))) : Math.log(num(a[0], "log")) / Math.log(num(a[1], "log")),
|
|
12809
|
+
(n2) => n2 >= 2 ? ["base", "x"] : ["x", "base"]
|
|
12810
|
+
),
|
|
12811
|
+
sin: math1((x) => Math.sin(x * RAD2)),
|
|
12812
|
+
cos: math1((x) => Math.cos(x * RAD2)),
|
|
12813
|
+
tan: math1((x) => Math.tan(x * RAD2)),
|
|
12814
|
+
asin: math1((x) => Math.asin(x) / RAD2),
|
|
12815
|
+
acos: math1((x) => Math.acos(x) / RAD2),
|
|
12816
|
+
atan: math1((x) => Math.atan(x) / RAD2),
|
|
12817
|
+
atan2: def("y, x", (a) => clean2(Math.atan2(num(a[0], "atan2"), num(a[1], "atan2")) / RAD2)),
|
|
12818
|
+
pow: def("x, y", (a) => Math.pow(num(a[0], "pow"), num(a[1], "pow"))),
|
|
12819
|
+
min: def(
|
|
12820
|
+
"values...",
|
|
12821
|
+
(a) => minmax(a, (xs) => xs.reduce((m, x) => x < m ? x : m, Infinity), "min")
|
|
12822
|
+
),
|
|
12823
|
+
max: def(
|
|
12824
|
+
"values...",
|
|
12825
|
+
(a) => minmax(a, (xs) => xs.reduce((m, x) => x > m ? x : m, -Infinity), "max")
|
|
12826
|
+
),
|
|
12827
|
+
clamp: def(
|
|
12828
|
+
"x, low, high",
|
|
12829
|
+
(a) => Math.min(Math.max(num(a[0], "clamp"), num(a[1], "clamp")), num(a[2], "clamp"))
|
|
12830
|
+
),
|
|
12831
|
+
lerp: def("a, b, t", (a) => {
|
|
12407
12832
|
const t = num(a[2], "lerp");
|
|
12408
12833
|
if (Array.isArray(a[0]) && Array.isArray(a[1])) {
|
|
12409
12834
|
const b = a[1];
|
|
12410
12835
|
return a[0].map((x, i) => num(x, "lerp") + (num(b[i], "lerp") - num(x, "lerp")) * t);
|
|
12411
12836
|
}
|
|
12412
12837
|
return num(a[0], "lerp") + (num(a[1], "lerp") - num(a[0], "lerp")) * t;
|
|
12413
|
-
},
|
|
12414
|
-
norm: (
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12838
|
+
}),
|
|
12839
|
+
norm: def(
|
|
12840
|
+
"v",
|
|
12841
|
+
(a, c) => Math.sqrt(list(a[0], "norm", c).reduce((s, x) => s + num(x, "norm") ** 2, 0))
|
|
12842
|
+
),
|
|
12843
|
+
cross: def("a, b", (a, c) => {
|
|
12844
|
+
const u = list(a[0], "cross", c).map((x) => num(x, "cross"));
|
|
12845
|
+
const v = list(a[1], "cross", c).map((x) => num(x, "cross"));
|
|
12418
12846
|
if (u.length === 2) return u[0] * v[1] - u[1] * v[0];
|
|
12419
12847
|
return [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];
|
|
12420
|
-
},
|
|
12421
|
-
len: (
|
|
12422
|
-
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
|
|
12426
|
-
const
|
|
12848
|
+
}),
|
|
12849
|
+
len: def(
|
|
12850
|
+
"value",
|
|
12851
|
+
(a) => typeof a[0] === "string" ? [...a[0]].length : Array.isArray(a[0]) ? a[0].length : void 0
|
|
12852
|
+
),
|
|
12853
|
+
concat: def("...", (a, c) => {
|
|
12854
|
+
const n2 = a.reduce((s, x) => s + (Array.isArray(x) ? x.length : 1), 0);
|
|
12855
|
+
if (n2 > c.maxLength)
|
|
12856
|
+
throw new Error(`concat(): a list of ${n2} items is more than the limit of ${c.maxLength}`);
|
|
12857
|
+
return a.flatMap((x) => Array.isArray(x) ? x : [x]);
|
|
12858
|
+
}),
|
|
12859
|
+
reverse: def(
|
|
12860
|
+
"value",
|
|
12861
|
+
(a, c) => typeof a[0] === "string" ? [...a[0]].reverse().join("") : [...list(a[0], "reverse", c)].reverse()
|
|
12862
|
+
),
|
|
12863
|
+
sum: def("values", (a, c) => list(a[0], "sum", c).reduce((s, x) => s + num(x, "sum"), 0)),
|
|
12864
|
+
slice: def("value, start, end", (a, c) => {
|
|
12865
|
+
const xs = typeof a[0] === "string" ? [...a[0]] : list(a[0], "slice", c);
|
|
12427
12866
|
const out = xs.slice(
|
|
12428
12867
|
num(a[1] ?? 0, "slice"),
|
|
12429
12868
|
a[2] === void 0 ? void 0 : num(a[2], "slice")
|
|
12430
12869
|
);
|
|
12431
12870
|
return typeof a[0] === "string" ? out.join("") : out;
|
|
12432
|
-
},
|
|
12433
|
-
str: (a) => a
|
|
12434
|
-
chr: (
|
|
12435
|
-
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12871
|
+
}),
|
|
12872
|
+
str: def("...", (a, c) => text(a, "", c, "str")),
|
|
12873
|
+
chr: def(
|
|
12874
|
+
"...",
|
|
12875
|
+
(a) => a.flatMap((x) => Array.isArray(x) ? x : [x]).map((x) => String.fromCodePoint(num(x, "chr"))).join("")
|
|
12876
|
+
),
|
|
12877
|
+
ord: def(
|
|
12878
|
+
"text",
|
|
12879
|
+
(a) => typeof a[0] === "string" && a[0].length ? a[0].codePointAt(0) : void 0
|
|
12880
|
+
),
|
|
12881
|
+
upper: def("text", (a) => typeof a[0] === "string" ? a[0].toUpperCase() : void 0),
|
|
12882
|
+
lower: def("text", (a) => typeof a[0] === "string" ? a[0].toLowerCase() : void 0),
|
|
12883
|
+
split: def(
|
|
12884
|
+
"text, separator",
|
|
12885
|
+
(a) => typeof a[0] === "string" ? a[0].split(typeof a[1] === "string" ? a[1] : " ") : void 0
|
|
12886
|
+
),
|
|
12887
|
+
join: def(
|
|
12888
|
+
"values, separator",
|
|
12889
|
+
(a, c) => text(list(a[0], "join", c), typeof a[1] === "string" ? a[1] : "", c, "join")
|
|
12890
|
+
),
|
|
12891
|
+
search: def("value, list", (a, c) => {
|
|
12892
|
+
const xs = typeof a[1] === "string" ? [...a[1]] : list(a[1], "search", c);
|
|
12893
|
+
const i = xs.findIndex((x) => equals(x, a[0], c.step));
|
|
12443
12894
|
return i < 0 ? void 0 : i;
|
|
12444
|
-
},
|
|
12445
|
-
contains: (
|
|
12446
|
-
|
|
12895
|
+
}),
|
|
12896
|
+
contains: def(
|
|
12897
|
+
"value, item",
|
|
12898
|
+
(a, c) => typeof a[0] === "string" ? a[0].includes(text([a[1]], "", c, "contains")) : list(a[0], "contains", c).some((x) => equals(x, a[1], c.step))
|
|
12899
|
+
),
|
|
12900
|
+
lookup: def("x, table", (a, c) => {
|
|
12447
12901
|
const key = num(a[0], "lookup");
|
|
12448
|
-
const table = list(a[1], "lookup");
|
|
12902
|
+
const table = list(a[1], "lookup", c);
|
|
12449
12903
|
if (!table.length) return void 0;
|
|
12450
12904
|
const rows = table.map((r) => [num(r[0], "lookup"), num(r[1], "lookup")]).sort((p, q) => p[0] - q[0]);
|
|
12451
12905
|
if (key <= rows[0][0]) return rows[0][1];
|
|
@@ -12456,25 +12910,25 @@ var FUNCTIONS = {
|
|
|
12456
12910
|
return y0 + (key - x0) / (x1 - x0) * (y1 - y0);
|
|
12457
12911
|
}
|
|
12458
12912
|
return rows[rows.length - 1][1];
|
|
12459
|
-
},
|
|
12460
|
-
rands: (a) => {
|
|
12913
|
+
}),
|
|
12914
|
+
rands: def("min, max, count, seed", (a) => {
|
|
12461
12915
|
const lo = num(a[0], "rands"), hi = num(a[1], "rands"), n2 = num(a[2], "rands");
|
|
12462
12916
|
const rnd = seeded(a[3] === void 0 ? 1 : num(a[3], "rands"));
|
|
12463
12917
|
return Array.from(
|
|
12464
12918
|
{ length: Math.min(Math.max(0, Math.floor(n2)), 1e6) },
|
|
12465
12919
|
() => lo + (hi - lo) * rnd()
|
|
12466
12920
|
);
|
|
12467
|
-
},
|
|
12468
|
-
is_num: (a) => isNum(a[0]) && !Number.isNaN(a[0]),
|
|
12469
|
-
is_string: (a) => typeof a[0] === "string",
|
|
12470
|
-
is_bool: (a) => typeof a[0] === "boolean",
|
|
12471
|
-
is_list: (a) => Array.isArray(a[0]),
|
|
12472
|
-
is_undef: (a) => a[0] === void 0,
|
|
12473
|
-
is_function: (a) => isFn(a[0]),
|
|
12474
|
-
type_of: (a) => typeName(a[0])
|
|
12921
|
+
}),
|
|
12922
|
+
is_num: def("value", (a) => isNum(a[0]) && !Number.isNaN(a[0])),
|
|
12923
|
+
is_string: def("value", (a) => typeof a[0] === "string"),
|
|
12924
|
+
is_bool: def("value", (a) => typeof a[0] === "boolean"),
|
|
12925
|
+
is_list: def("value", (a) => Array.isArray(a[0])),
|
|
12926
|
+
is_undef: def("value", (a) => a[0] === void 0),
|
|
12927
|
+
is_function: def("value", (a) => isFn(a[0])),
|
|
12928
|
+
type_of: def("value", (a) => typeName(a[0]))
|
|
12475
12929
|
};
|
|
12476
12930
|
|
|
12477
|
-
//
|
|
12931
|
+
// node_modules/clipper2-ts/dist/Core.js
|
|
12478
12932
|
var ClipType;
|
|
12479
12933
|
(function(ClipType2) {
|
|
12480
12934
|
ClipType2[ClipType2["NoClip"] = 0] = "NoClip";
|
|
@@ -13133,7 +13587,7 @@ var RectDUtils = {
|
|
|
13133
13587
|
var InvalidRect64 = Object.freeze(Rect64Utils.createInvalid());
|
|
13134
13588
|
var InvalidRectD = Object.freeze(RectDUtils.createInvalid());
|
|
13135
13589
|
|
|
13136
|
-
//
|
|
13590
|
+
// node_modules/clipper2-ts/dist/Engine.js
|
|
13137
13591
|
var B02 = BigInt(0);
|
|
13138
13592
|
var B22 = BigInt(2);
|
|
13139
13593
|
var B42 = BigInt(4);
|
|
@@ -13825,7 +14279,7 @@ var ClipperBase = class _ClipperBase {
|
|
|
13825
14279
|
next.prevInAEL = prev;
|
|
13826
14280
|
}
|
|
13827
14281
|
getBounds() {
|
|
13828
|
-
const
|
|
14282
|
+
const bounds3 = {
|
|
13829
14283
|
left: Number.MAX_SAFE_INTEGER,
|
|
13830
14284
|
top: Number.MAX_SAFE_INTEGER,
|
|
13831
14285
|
right: Number.MIN_SAFE_INTEGER,
|
|
@@ -13834,18 +14288,18 @@ var ClipperBase = class _ClipperBase {
|
|
|
13834
14288
|
for (const t of this.vertexList) {
|
|
13835
14289
|
let v = t;
|
|
13836
14290
|
do {
|
|
13837
|
-
if (v.pt.x <
|
|
13838
|
-
|
|
13839
|
-
if (v.pt.x >
|
|
13840
|
-
|
|
13841
|
-
if (v.pt.y <
|
|
13842
|
-
|
|
13843
|
-
if (v.pt.y >
|
|
13844
|
-
|
|
14291
|
+
if (v.pt.x < bounds3.left)
|
|
14292
|
+
bounds3.left = v.pt.x;
|
|
14293
|
+
if (v.pt.x > bounds3.right)
|
|
14294
|
+
bounds3.right = v.pt.x;
|
|
14295
|
+
if (v.pt.y < bounds3.top)
|
|
14296
|
+
bounds3.top = v.pt.y;
|
|
14297
|
+
if (v.pt.y > bounds3.bottom)
|
|
14298
|
+
bounds3.bottom = v.pt.y;
|
|
13845
14299
|
v = v.next;
|
|
13846
14300
|
} while (v !== t);
|
|
13847
14301
|
}
|
|
13848
|
-
return Rect64Utils.isEmpty(
|
|
14302
|
+
return Rect64Utils.isEmpty(bounds3) ? { left: 0, top: 0, right: 0, bottom: 0 } : bounds3;
|
|
13849
14303
|
}
|
|
13850
14304
|
executeInternal(ct, fillRule) {
|
|
13851
14305
|
if (ct === ClipType.NoClip)
|
|
@@ -15060,17 +15514,17 @@ var ClipperBase = class _ClipperBase {
|
|
|
15060
15514
|
return false;
|
|
15061
15515
|
const maxCoord = InternalClipper.maxCoordForSafeCrossSq;
|
|
15062
15516
|
if (Math.abs(a) < maxCoord && Math.abs(b) < maxCoord && Math.abs(c) < maxCoord && Math.abs(d2) < maxCoord) {
|
|
15063
|
-
const
|
|
15064
|
-
return
|
|
15517
|
+
const cross3 = a * d2 - c * b;
|
|
15518
|
+
return cross3 * cross3 / (c * c + d2 * d2) > 0.25;
|
|
15065
15519
|
}
|
|
15066
15520
|
if (Number.isSafeInteger(a) && Number.isSafeInteger(b) && Number.isSafeInteger(c) && Number.isSafeInteger(d2)) {
|
|
15067
|
-
const
|
|
15068
|
-
const crossSq =
|
|
15521
|
+
const cross3 = BigInt(a) * BigInt(d2) - BigInt(c) * BigInt(b);
|
|
15522
|
+
const crossSq = cross3 * cross3;
|
|
15069
15523
|
const denom = BigInt(c) * BigInt(c) + BigInt(d2) * BigInt(d2);
|
|
15070
15524
|
return B42 * crossSq > denom;
|
|
15071
15525
|
}
|
|
15072
|
-
const
|
|
15073
|
-
return
|
|
15526
|
+
const cross2 = a * d2 - c * b;
|
|
15527
|
+
return cross2 * cross2 / (c * c + d2 * d2) > 0.25;
|
|
15074
15528
|
}
|
|
15075
15529
|
intersectEdges(ae1, ae2, pt) {
|
|
15076
15530
|
let resultOp;
|
|
@@ -15898,7 +16352,7 @@ var Clipper = {
|
|
|
15898
16352
|
}
|
|
15899
16353
|
};
|
|
15900
16354
|
|
|
15901
|
-
//
|
|
16355
|
+
// node_modules/clipper2-ts/dist/Offset.js
|
|
15902
16356
|
var JoinType;
|
|
15903
16357
|
(function(JoinType2) {
|
|
15904
16358
|
JoinType2[JoinType2["Miter"] = 0] = "Miter";
|
|
@@ -16255,8 +16709,8 @@ var ClipperOffset = class _ClipperOffset {
|
|
|
16255
16709
|
y: Math.round(pt.y + offsetVec.y),
|
|
16256
16710
|
z: ptz
|
|
16257
16711
|
});
|
|
16258
|
-
const
|
|
16259
|
-
for (let i = 1; i <
|
|
16712
|
+
const steps2 = Math.ceil(this.stepsPerRad * Math.abs(angle));
|
|
16713
|
+
for (let i = 1; i < steps2; i++) {
|
|
16260
16714
|
offsetVec = {
|
|
16261
16715
|
x: offsetVec.x * this.stepCos - this.stepSin * offsetVec.y,
|
|
16262
16716
|
y: offsetVec.x * this.stepSin + offsetVec.y * this.stepCos
|
|
@@ -16426,8 +16880,8 @@ var ClipperOffset = class _ClipperOffset {
|
|
|
16426
16880
|
}
|
|
16427
16881
|
const ptz = pt.z || 0;
|
|
16428
16882
|
if (group.endType === EndType.Round) {
|
|
16429
|
-
const
|
|
16430
|
-
this.pathOut = _ClipperOffset.ellipse(pt, Math.abs(this.groupDelta), Math.abs(this.groupDelta),
|
|
16883
|
+
const steps2 = Math.ceil(this.stepsPerRad * 2 * Math.PI);
|
|
16884
|
+
this.pathOut = _ClipperOffset.ellipse(pt, Math.abs(this.groupDelta), Math.abs(this.groupDelta), steps2);
|
|
16431
16885
|
if (ptz !== 0)
|
|
16432
16886
|
for (let i = 0; i < this.pathOut.length; i++)
|
|
16433
16887
|
this.pathOut[i].z = ptz;
|
|
@@ -16485,20 +16939,20 @@ var ClipperOffset = class _ClipperOffset {
|
|
|
16485
16939
|
static sqr(val) {
|
|
16486
16940
|
return val * val;
|
|
16487
16941
|
}
|
|
16488
|
-
static ellipse(center, radiusX, radiusY = 0,
|
|
16942
|
+
static ellipse(center, radiusX, radiusY = 0, steps2 = 0) {
|
|
16489
16943
|
if (radiusX <= 0)
|
|
16490
16944
|
return [];
|
|
16491
16945
|
if (radiusY <= 0)
|
|
16492
16946
|
radiusY = radiusX;
|
|
16493
|
-
if (
|
|
16494
|
-
|
|
16947
|
+
if (steps2 <= 2) {
|
|
16948
|
+
steps2 = Math.ceil(Math.PI * Math.sqrt((radiusX + radiusY) / 2));
|
|
16495
16949
|
}
|
|
16496
|
-
const si = Math.sin(2 * Math.PI /
|
|
16497
|
-
const co = Math.cos(2 * Math.PI /
|
|
16950
|
+
const si = Math.sin(2 * Math.PI / steps2);
|
|
16951
|
+
const co = Math.cos(2 * Math.PI / steps2);
|
|
16498
16952
|
let dx = co;
|
|
16499
16953
|
let dy = si;
|
|
16500
16954
|
const result = [{ x: Math.round(center.x + radiusX), y: center.y }];
|
|
16501
|
-
for (let i = 1; i <
|
|
16955
|
+
for (let i = 1; i < steps2; ++i) {
|
|
16502
16956
|
result.push({
|
|
16503
16957
|
x: Math.round(center.x + radiusX * dx),
|
|
16504
16958
|
y: Math.round(center.y + radiusY * dy)
|
|
@@ -16511,7 +16965,7 @@ var ClipperOffset = class _ClipperOffset {
|
|
|
16511
16965
|
}
|
|
16512
16966
|
};
|
|
16513
16967
|
|
|
16514
|
-
//
|
|
16968
|
+
// node_modules/clipper2-ts/dist/Clipper.js
|
|
16515
16969
|
var B23 = BigInt(2);
|
|
16516
16970
|
function union(subject, clipOrFillRule, fillRule) {
|
|
16517
16971
|
if (typeof clipOrFillRule === "number") {
|
|
@@ -16644,7 +17098,7 @@ function area2(p) {
|
|
|
16644
17098
|
a += (p[j][0] + p[i][0]) * (p[j][1] - p[i][1]);
|
|
16645
17099
|
return -a / 2;
|
|
16646
17100
|
}
|
|
16647
|
-
function
|
|
17101
|
+
function apply2(m, [x, y]) {
|
|
16648
17102
|
return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
|
|
16649
17103
|
}
|
|
16650
17104
|
function transformLayers(layers, m) {
|
|
@@ -16653,10 +17107,10 @@ function transformLayers(layers, m) {
|
|
|
16653
17107
|
for (const [k, l] of layers) {
|
|
16654
17108
|
out.set(k, {
|
|
16655
17109
|
regions: l.regions.map((p) => {
|
|
16656
|
-
const q = p.map((pt) =>
|
|
17110
|
+
const q = p.map((pt) => apply2(m, pt));
|
|
16657
17111
|
return flip ? q.reverse() : q;
|
|
16658
17112
|
}),
|
|
16659
|
-
lines: l.lines.map((p) => p.map((pt) =>
|
|
17113
|
+
lines: l.lines.map((p) => p.map((pt) => apply2(m, pt)))
|
|
16660
17114
|
});
|
|
16661
17115
|
}
|
|
16662
17116
|
return out;
|
|
@@ -16720,17 +17174,17 @@ function layerBounds(layers, skip) {
|
|
|
16720
17174
|
function hull(points) {
|
|
16721
17175
|
const pts = [...points].sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
16722
17176
|
if (pts.length < 3) return pts;
|
|
16723
|
-
const
|
|
17177
|
+
const cross2 = (o, a, b) => (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
|
|
16724
17178
|
const lower = [];
|
|
16725
17179
|
for (const p of pts) {
|
|
16726
|
-
while (lower.length >= 2 &&
|
|
17180
|
+
while (lower.length >= 2 && cross2(lower[lower.length - 2], lower[lower.length - 1], p) <= 0)
|
|
16727
17181
|
lower.pop();
|
|
16728
17182
|
lower.push(p);
|
|
16729
17183
|
}
|
|
16730
17184
|
const upper = [];
|
|
16731
17185
|
for (let i = pts.length - 1; i >= 0; i--) {
|
|
16732
17186
|
const p = pts[i];
|
|
16733
|
-
while (upper.length >= 2 &&
|
|
17187
|
+
while (upper.length >= 2 && cross2(upper[upper.length - 2], upper[upper.length - 1], p) <= 0)
|
|
16734
17188
|
upper.pop();
|
|
16735
17189
|
upper.push(p);
|
|
16736
17190
|
}
|
|
@@ -16850,14 +17304,16 @@ function livingHinge(w, h, spacing, bridge, cut) {
|
|
|
16850
17304
|
}
|
|
16851
17305
|
|
|
16852
17306
|
// src/lexer.ts
|
|
17307
|
+
var where = (pos, col = true) => `line ${pos.line}${col ? `, column ${pos.col}` : ""}${pos.file ? ` in <${pos.file}>` : ""}`;
|
|
16853
17308
|
var KerfError = class extends Error {
|
|
16854
17309
|
constructor(message, pos) {
|
|
16855
|
-
super(pos ? `${message} (
|
|
17310
|
+
super(pos ? `${message} (${where(pos)})` : message);
|
|
16856
17311
|
this.echoes = [];
|
|
16857
17312
|
this.name = "KerfError";
|
|
16858
17313
|
if (pos) {
|
|
16859
17314
|
this.line = pos.line;
|
|
16860
17315
|
this.col = pos.col;
|
|
17316
|
+
this.file = pos.file;
|
|
16861
17317
|
}
|
|
16862
17318
|
}
|
|
16863
17319
|
};
|
|
@@ -16891,13 +17347,13 @@ var PUNCT = [
|
|
|
16891
17347
|
"}",
|
|
16892
17348
|
"#"
|
|
16893
17349
|
];
|
|
16894
|
-
function tokenize(src) {
|
|
17350
|
+
function tokenize(src, file) {
|
|
16895
17351
|
const tokens = [];
|
|
16896
17352
|
const comments = [];
|
|
16897
17353
|
let i = 0;
|
|
16898
17354
|
let line = 1;
|
|
16899
17355
|
let lineStart = 0;
|
|
16900
|
-
const pos = () => ({ line, col: i - lineStart + 1, offset: i });
|
|
17356
|
+
const pos = () => ({ line, col: i - lineStart + 1, offset: i, ...file && { file } });
|
|
16901
17357
|
const advance = (n2) => {
|
|
16902
17358
|
for (let k = 0; k < n2; k++) {
|
|
16903
17359
|
if (src[i] === "\n") {
|
|
@@ -16916,8 +17372,8 @@ function tokenize(src) {
|
|
|
16916
17372
|
if (c === "/" && src[i + 1] === "/") {
|
|
16917
17373
|
const end = src.indexOf("\n", i);
|
|
16918
17374
|
const stop = end < 0 ? src.length : end;
|
|
16919
|
-
const
|
|
16920
|
-
comments.push({ text: src.slice(i + 2, stop).trim(), line, block: false, own });
|
|
17375
|
+
const own2 = /^[ \t]*$/.test(src.slice(src.lastIndexOf("\n", i - 1) + 1, i));
|
|
17376
|
+
comments.push({ text: src.slice(i + 2, stop).trim(), line, block: false, own: own2 });
|
|
16921
17377
|
i = stop;
|
|
16922
17378
|
continue;
|
|
16923
17379
|
}
|
|
@@ -17006,8 +17462,8 @@ var KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
17006
17462
|
"false",
|
|
17007
17463
|
"undef"
|
|
17008
17464
|
]);
|
|
17009
|
-
function parse(src) {
|
|
17010
|
-
const { tokens, comments } = tokenize(src);
|
|
17465
|
+
function parse(src, file) {
|
|
17466
|
+
const { tokens, comments } = tokenize(src, file);
|
|
17011
17467
|
const p = new Parser(tokens);
|
|
17012
17468
|
const body = [];
|
|
17013
17469
|
while (!p.at("eof")) body.push(...p.statement());
|
|
@@ -17149,12 +17605,12 @@ var Parser = class _Parser {
|
|
|
17149
17605
|
const out = [];
|
|
17150
17606
|
while (!this.isP(")")) {
|
|
17151
17607
|
const name = this.ident().value;
|
|
17152
|
-
let
|
|
17608
|
+
let def2 = null;
|
|
17153
17609
|
if (this.isP("=")) {
|
|
17154
17610
|
this.next();
|
|
17155
|
-
|
|
17611
|
+
def2 = this.expr();
|
|
17156
17612
|
}
|
|
17157
|
-
out.push({ name, default:
|
|
17613
|
+
out.push({ name, default: def2 });
|
|
17158
17614
|
if (!this.isP(")")) this.expectP(",");
|
|
17159
17615
|
}
|
|
17160
17616
|
this.next();
|
|
@@ -17373,7 +17829,7 @@ var Parser = class _Parser {
|
|
|
17373
17829
|
|
|
17374
17830
|
// src/stdlib.ts
|
|
17375
17831
|
var LIBRARIES = {
|
|
17376
|
-
"kerf/box": '// kerf/box: finger-jointed boxes.\n// Copyright (c) 2026 MyLaserTools. AGPL-3.0-only or MyLaserTools commercial licence.\n\n// Box from its outer size [width, depth, height] in the current material.\n// Edges pair "out" with "in", and the bottom owns every bottom corner,\n// so the six panels interlock without gaps.\nmodule box(size, lid = false, finger = undef) {\n w = size[0];\n d = size[1];\n h = size[2];\n top = lid ? "in" : "flat";\n part("bottom") finger_rect([w, d], "out", finger = finger);\n if (lid) part("lid") finger_rect([w, d], "out", finger = finger);\n part("front")
|
|
17832
|
+
"kerf/box": '// kerf/box: finger-jointed boxes.\n// Copyright (c) 2026 MyLaserTools. AGPL-3.0-only or MyLaserTools commercial licence.\n\n// Box from its outer size [width, depth, height] in the current material.\n// Edges pair "out" with "in", and the bottom owns every bottom corner,\n// so the six panels interlock without gaps.\nmodule box(size, lid = false, finger = undef) {\n w = size[0];\n d = size[1];\n h = size[2];\n t = $thickness;\n top = lid ? "in" : "flat";\n part("bottom", at = [0, 0, 0]) finger_rect([w, d], "out", finger = finger);\n if (lid) part("lid", at = [0, 0, h - t]) finger_rect([w, d], "out", finger = finger);\n part("front", at = [0, t, 0], rotate = [90, 0, 0])\n finger_rect([w, h], ["in", "out", top, "out"], finger = finger);\n part("back", at = [0, d, 0], rotate = [90, 0, 0])\n finger_rect([w, h], ["in", "out", top, "out"], finger = finger);\n part("left", rotate = [90, 0, 90])\n finger_rect([d, h], ["in", "in", top, "in"], finger = finger);\n part("right", at = [w - t, 0, 0], rotate = [90, 0, 90])\n finger_rect([d, h], ["in", "in", top, "in"], finger = finger);\n}\n\n// Divider that slides between two walls: tabs on both sides drop into\n// finger_holes() cut in the walls.\nmodule divider(size, finger = undef) {\n finger_rect(size, ["flat", "out", "flat", "out"], finger = finger);\n}\n'
|
|
17377
17833
|
};
|
|
17378
17834
|
|
|
17379
17835
|
// src/paths.ts
|
|
@@ -17387,7 +17843,7 @@ function flatten(cmds, tolerance = 0.02) {
|
|
|
17387
17843
|
if (cur.length >= 2) (close ? closed : open).push(cur);
|
|
17388
17844
|
cur = [];
|
|
17389
17845
|
};
|
|
17390
|
-
const
|
|
17846
|
+
const steps2 = (len) => Math.max(2, Math.min(256, Math.ceil(Math.sqrt(len / tolerance))));
|
|
17391
17847
|
for (const c of cmds) {
|
|
17392
17848
|
if (c.type === "M") {
|
|
17393
17849
|
finish(false);
|
|
@@ -17398,7 +17854,7 @@ function flatten(cmds, tolerance = 0.02) {
|
|
|
17398
17854
|
cur.push(last);
|
|
17399
17855
|
} else if (c.type === "Q") {
|
|
17400
17856
|
const [x0, y0] = last;
|
|
17401
|
-
const n2 =
|
|
17857
|
+
const n2 = steps2(Math.hypot(c.x1 - x0, c.y1 - y0) + Math.hypot(c.x - c.x1, c.y - c.y1));
|
|
17402
17858
|
for (let i = 1; i <= n2; i++) {
|
|
17403
17859
|
const t = i / n2, u = 1 - t;
|
|
17404
17860
|
cur.push([
|
|
@@ -17409,7 +17865,7 @@ function flatten(cmds, tolerance = 0.02) {
|
|
|
17409
17865
|
last = [c.x, c.y];
|
|
17410
17866
|
} else if (c.type === "C") {
|
|
17411
17867
|
const [x0, y0] = last;
|
|
17412
|
-
const n2 =
|
|
17868
|
+
const n2 = steps2(
|
|
17413
17869
|
Math.hypot(c.x1 - x0, c.y1 - y0) + Math.hypot(c.x2 - c.x1, c.y2 - c.y1) + Math.hypot(c.x - c.x2, c.y - c.y2)
|
|
17414
17870
|
);
|
|
17415
17871
|
for (let i = 1; i <= n2; i++) {
|
|
@@ -17600,7 +18056,7 @@ var FontBook = class {
|
|
|
17600
18056
|
}
|
|
17601
18057
|
const hit = this.parsed.get(key);
|
|
17602
18058
|
if (hit) return hit;
|
|
17603
|
-
const src = this.sources
|
|
18059
|
+
const src = own(this.sources, key);
|
|
17604
18060
|
if (!src) {
|
|
17605
18061
|
this.missing.add(key);
|
|
17606
18062
|
throw new Error(
|
|
@@ -17613,25 +18069,23 @@ var FontBook = class {
|
|
|
17613
18069
|
return font;
|
|
17614
18070
|
}
|
|
17615
18071
|
};
|
|
17616
|
-
function layoutCommands(font,
|
|
18072
|
+
function layoutCommands(font, text2, o) {
|
|
17617
18073
|
const opts = { kerning: true };
|
|
17618
18074
|
if (o.spacing === 1) {
|
|
17619
|
-
const path = font.getPath(
|
|
17620
|
-
return { cmds: path.commands, advance: font.getAdvanceWidth(
|
|
18075
|
+
const path = font.getPath(text2, 0, 0, o.size, opts);
|
|
18076
|
+
return { cmds: path.commands, advance: font.getAdvanceWidth(text2, o.size, opts) };
|
|
17621
18077
|
}
|
|
17622
18078
|
const cmds = [];
|
|
17623
18079
|
let x = 0;
|
|
17624
|
-
const chars = [...
|
|
18080
|
+
const chars = [...text2];
|
|
17625
18081
|
chars.forEach((ch, i) => {
|
|
17626
18082
|
cmds.push(...font.getPath(ch, x, 0, o.size, opts).commands);
|
|
17627
18083
|
x += font.getAdvanceWidth(ch, o.size, opts) * (i < chars.length - 1 ? o.spacing : 1);
|
|
17628
18084
|
});
|
|
17629
18085
|
return { cmds, advance: x };
|
|
17630
18086
|
}
|
|
17631
|
-
function
|
|
17632
|
-
|
|
17633
|
-
const font = book.get(o.font);
|
|
17634
|
-
const { cmds, advance } = layoutCommands(font, text, o);
|
|
18087
|
+
function outlines(font, text2, o) {
|
|
18088
|
+
const { cmds, advance } = layoutCommands(font, text2, o);
|
|
17635
18089
|
const flipped = cmds.map((c) => {
|
|
17636
18090
|
if (c.type === "Z") return c;
|
|
17637
18091
|
if (c.type === "C") return { ...c, y1: -c.y1, y2: -c.y2, y: -c.y };
|
|
@@ -17639,17 +18093,22 @@ function textRegions(book, text, o) {
|
|
|
17639
18093
|
return { ...c, y: -c.y };
|
|
17640
18094
|
});
|
|
17641
18095
|
const flat = flatten(flipped, Math.max(5e-3, o.size / 2e3));
|
|
17642
|
-
|
|
18096
|
+
return { polys: [...flat.closed, ...flat.open.filter((p) => p.length >= 3)], advance };
|
|
18097
|
+
}
|
|
18098
|
+
function textRegions(book, text2, o) {
|
|
18099
|
+
if (!text2) return [];
|
|
18100
|
+
const font = book.get(o.font);
|
|
18101
|
+
const { polys: raw, advance } = outlines(font, text2, o);
|
|
18102
|
+
const polys = union2(raw);
|
|
17643
18103
|
const b = bounds(polys);
|
|
17644
18104
|
if (!b) return [];
|
|
17645
18105
|
const dx = o.halign === "center" ? -advance / 2 : o.halign === "right" ? -advance : 0;
|
|
17646
18106
|
const dy = o.valign === "top" ? -b[3] : o.valign === "center" ? -(b[1] + b[3]) / 2 : o.valign === "bottom" ? -b[1] : 0;
|
|
17647
18107
|
return polys.map((p) => p.map(([x, y]) => [x + dx, y + dy]));
|
|
17648
18108
|
}
|
|
17649
|
-
function textMetrics(book,
|
|
18109
|
+
function textMetrics(book, text2, o) {
|
|
17650
18110
|
const font = book.get(o.font);
|
|
17651
|
-
const { advance } =
|
|
17652
|
-
const polys = textRegions(book, text, { ...o, halign: "left", valign: "baseline" });
|
|
18111
|
+
const { polys, advance } = outlines(font, text2, o);
|
|
17653
18112
|
const b = bounds(polys) ?? [0, 0, 0, 0];
|
|
17654
18113
|
return {
|
|
17655
18114
|
advance,
|
|
@@ -17677,21 +18136,22 @@ var DEFAULT_LIMITS = {
|
|
|
17677
18136
|
maxTextLength: 2e3,
|
|
17678
18137
|
maxPoints: 2e6,
|
|
17679
18138
|
maxOutputPoints: 1e6,
|
|
17680
|
-
maxSheets: 200
|
|
18139
|
+
maxSheets: 200,
|
|
18140
|
+
maxCollisionPairs: 2e4
|
|
17681
18141
|
};
|
|
17682
18142
|
var SHAPE_COST = 100;
|
|
17683
18143
|
var LIST_COST = 4;
|
|
17684
18144
|
var CHARS_PER_ITEM = 8;
|
|
17685
18145
|
var shapePoints = (s) => {
|
|
17686
18146
|
let n2 = SHAPE_COST;
|
|
17687
|
-
const
|
|
18147
|
+
const add2 = (layers) => {
|
|
17688
18148
|
for (const l of layers.values()) {
|
|
17689
18149
|
for (const p of l.regions) n2 += p.length;
|
|
17690
18150
|
for (const p of l.lines) n2 += p.length;
|
|
17691
18151
|
}
|
|
17692
18152
|
};
|
|
17693
|
-
|
|
17694
|
-
for (const p of s.parts)
|
|
18153
|
+
add2(s.layers);
|
|
18154
|
+
for (const p of s.parts) add2(p.layers);
|
|
17695
18155
|
return n2;
|
|
17696
18156
|
};
|
|
17697
18157
|
var Env = class {
|
|
@@ -17769,17 +18229,17 @@ var Evaluator = class {
|
|
|
17769
18229
|
warnings: this.warnings
|
|
17770
18230
|
};
|
|
17771
18231
|
}
|
|
17772
|
-
tick(pos) {
|
|
17773
|
-
if (
|
|
18232
|
+
tick(pos, n2 = 1) {
|
|
18233
|
+
if (!((this.steps += n2) <= this.maxSteps))
|
|
17774
18234
|
throw new KerfError(`Stopped after ${this.maxSteps} steps. Is there an endless loop?`, pos);
|
|
17775
18235
|
}
|
|
17776
18236
|
load(path, at) {
|
|
17777
18237
|
const hit = this.loaded.get(path);
|
|
17778
18238
|
if (hit) return hit;
|
|
17779
|
-
const src = STDLIB
|
|
17780
|
-
if (src
|
|
18239
|
+
const src = own(STDLIB, path) ?? this.opts.resolve?.(path);
|
|
18240
|
+
if (typeof src !== "string") throw new KerfError(`Library <${path}> not found`, at);
|
|
17781
18241
|
this.loaded.set(path, { body: [] });
|
|
17782
|
-
const { program } = parse(src);
|
|
18242
|
+
const { program } = parse(src, path);
|
|
17783
18243
|
this.loaded.set(path, program);
|
|
17784
18244
|
return program;
|
|
17785
18245
|
}
|
|
@@ -17867,7 +18327,7 @@ var Evaluator = class {
|
|
|
17867
18327
|
iterable(v, at) {
|
|
17868
18328
|
if (isRange(v)) {
|
|
17869
18329
|
try {
|
|
17870
|
-
return rangeValues(v,
|
|
18330
|
+
return rangeValues(v, this.limits.maxListLength);
|
|
17871
18331
|
} catch (e) {
|
|
17872
18332
|
throw new KerfError(e.message, at);
|
|
17873
18333
|
}
|
|
@@ -17908,13 +18368,17 @@ var Evaluator = class {
|
|
|
17908
18368
|
});
|
|
17909
18369
|
for (const k of args.named.keys()) {
|
|
17910
18370
|
if (k.startsWith("$")) env.vars.set(k, args.named.get(k));
|
|
17911
|
-
else if (!names.has(k))
|
|
17912
|
-
const warning = `${what}: unknown argument "${k}" (line ${args.at.line})`;
|
|
17913
|
-
if (!this.warnings.includes(warning)) this.warnings.push(warning);
|
|
17914
|
-
}
|
|
18371
|
+
else if (!names.has(k)) this.unknownArg(what, k, args.at);
|
|
17915
18372
|
}
|
|
17916
18373
|
void defEnv;
|
|
17917
18374
|
}
|
|
18375
|
+
unknownArg(what, name, at) {
|
|
18376
|
+
this.warn(`${what}: unknown argument "${name}" (${where(at, false)})`);
|
|
18377
|
+
}
|
|
18378
|
+
// A warning, once however often it comes up
|
|
18379
|
+
warn(warning) {
|
|
18380
|
+
if (!this.warnings.includes(warning)) this.warnings.push(warning);
|
|
18381
|
+
}
|
|
17918
18382
|
callModule(s, env) {
|
|
17919
18383
|
const args = this.evalArgs(s.args, env, s.pos);
|
|
17920
18384
|
const user = env.mod(s.name);
|
|
@@ -17931,7 +18395,7 @@ var Evaluator = class {
|
|
|
17931
18395
|
this.depth--;
|
|
17932
18396
|
}
|
|
17933
18397
|
}
|
|
17934
|
-
const b = this.builtins
|
|
18398
|
+
const b = own(this.builtins, s.name);
|
|
17935
18399
|
if (!b) {
|
|
17936
18400
|
const hint = s.name === "color" ? " Use layer(), cut(), score() or engrave() instead." : s.name === "square" ? " Use rect()." : "";
|
|
17937
18401
|
throw new KerfError(`Unknown module ${s.name}().${hint}`, s.pos);
|
|
@@ -18029,8 +18493,8 @@ var Evaluator = class {
|
|
|
18029
18493
|
if (x.op === "||") return truthy(this.expr(x.left, env)) || truthy(this.expr(x.right, env));
|
|
18030
18494
|
const a = this.expr(x.left, env);
|
|
18031
18495
|
const b = this.expr(x.right, env);
|
|
18032
|
-
if (x.op === "=="
|
|
18033
|
-
|
|
18496
|
+
if (x.op === "==" || x.op === "!=")
|
|
18497
|
+
return equals(a, b, () => this.tick(x.pos)) === (x.op === "==");
|
|
18034
18498
|
if (x.op === "<" || x.op === "<=" || x.op === ">" || x.op === ">=") {
|
|
18035
18499
|
if (!(typeof a === "number" && typeof b === "number" || typeof a === "string" && typeof b === "string"))
|
|
18036
18500
|
throw new KerfError(`Can't compare ${typeName(a)} ${x.op} ${typeName(b)}`, x.pos);
|
|
@@ -18122,13 +18586,27 @@ var Evaluator = class {
|
|
|
18122
18586
|
if (f2) return this.callFunction(f2, this.evalArgs(x.args, env, x.pos), env, name);
|
|
18123
18587
|
const special = this.specialFunction(name, x, env);
|
|
18124
18588
|
if (special.handled) return special.value;
|
|
18125
|
-
const b = FUNCTIONS
|
|
18589
|
+
const b = own(FUNCTIONS, name);
|
|
18126
18590
|
if (b) {
|
|
18127
18591
|
const args = this.evalArgs(x.args, env, x.pos);
|
|
18592
|
+
for (const k of args.named.keys())
|
|
18593
|
+
if (!k.startsWith("$") && !b.params.includes(k)) this.unknownArg(`${name}()`, k, x.pos);
|
|
18594
|
+
for (const k of givenTwice(b, args.pos, args.named))
|
|
18595
|
+
this.warn(
|
|
18596
|
+
`${name}(): "${k}" is given by position and by name; the named value is used (${where(x.pos, false)})`
|
|
18597
|
+
);
|
|
18598
|
+
const ctx = {
|
|
18599
|
+
maxLength: this.limits.maxListLength,
|
|
18600
|
+
step: (n2) => this.tick(x.pos, n2),
|
|
18601
|
+
given: args.pos.length + b.params.filter((p) => args.named.has(p)).length
|
|
18602
|
+
};
|
|
18603
|
+
const bound = bindArgs(b, args.pos, args.named);
|
|
18604
|
+
this.tick(x.pos, argumentWork(name, bound, this.limits.maxListLength));
|
|
18128
18605
|
let out;
|
|
18129
18606
|
try {
|
|
18130
|
-
out = b(
|
|
18607
|
+
out = b.run(bound, ctx);
|
|
18131
18608
|
} catch (e) {
|
|
18609
|
+
if (e instanceof KerfError) throw e;
|
|
18132
18610
|
throw new KerfError(
|
|
18133
18611
|
e instanceof RangeError ? `${name}(): the result is too large` : e.message,
|
|
18134
18612
|
x.pos
|
|
@@ -18154,12 +18632,7 @@ var Evaluator = class {
|
|
|
18154
18632
|
return { handled: true, value: void 0 };
|
|
18155
18633
|
}
|
|
18156
18634
|
if (name === "assert") {
|
|
18157
|
-
|
|
18158
|
-
if (!truthy(a.pos[0]))
|
|
18159
|
-
throw new KerfError(
|
|
18160
|
-
`Assertion failed${a.pos[1] !== void 0 ? ": " + (typeof a.pos[1] === "string" ? a.pos[1] : show(a.pos[1])) : ""}`,
|
|
18161
|
-
x.pos
|
|
18162
|
-
);
|
|
18635
|
+
this.assert(this.evalArgs(x.args, env, x.pos));
|
|
18163
18636
|
return { handled: true, value: true };
|
|
18164
18637
|
}
|
|
18165
18638
|
if (name === "text_width" || name === "text_metrics") {
|
|
@@ -18178,13 +18651,33 @@ var Evaluator = class {
|
|
|
18178
18651
|
}
|
|
18179
18652
|
return { handled: false };
|
|
18180
18653
|
}
|
|
18181
|
-
|
|
18182
|
-
this.
|
|
18183
|
-
this.
|
|
18654
|
+
assert(a) {
|
|
18655
|
+
if (truthy(this.arg(a, "condition", 0))) return;
|
|
18656
|
+
const m = this.arg(a, "message", 1);
|
|
18657
|
+
throw new KerfError(`Assertion failed${m === void 0 ? "" : ": " + toText(m)}`, a.at);
|
|
18658
|
+
}
|
|
18659
|
+
echo(text2, at) {
|
|
18660
|
+
this.charge(Math.ceil(text2.length / CHARS_PER_ITEM), at);
|
|
18661
|
+
this.echoes.push(text2);
|
|
18184
18662
|
}
|
|
18663
|
+
// Echo text stops at maxListLength characters, before it is all written out
|
|
18185
18664
|
echoText(a) {
|
|
18186
|
-
const
|
|
18187
|
-
|
|
18665
|
+
const max = this.limits.maxListLength;
|
|
18666
|
+
const parts = [];
|
|
18667
|
+
let n2 = 0;
|
|
18668
|
+
const add2 = (label, v, quote) => {
|
|
18669
|
+
if (parts.length) n2 += 2;
|
|
18670
|
+
const r = write(v, max - n2 - label.length, quote);
|
|
18671
|
+
n2 += label.length + r.text.length;
|
|
18672
|
+
if (!r.whole)
|
|
18673
|
+
throw new KerfError(
|
|
18674
|
+
`echo(): the text would be longer than the limit of ${max} characters`,
|
|
18675
|
+
a.at
|
|
18676
|
+
);
|
|
18677
|
+
parts.push(label + r.text);
|
|
18678
|
+
};
|
|
18679
|
+
for (const v of a.pos) add2("", v, false);
|
|
18680
|
+
for (const [k, v] of a.named) add2(`${k} = `, v, true);
|
|
18188
18681
|
return parts.join(", ");
|
|
18189
18682
|
}
|
|
18190
18683
|
arith(op, a, b, at) {
|
|
@@ -18219,21 +18712,37 @@ var Evaluator = class {
|
|
|
18219
18712
|
return a.map((x, i) => this.arith(op, x, b[i], at));
|
|
18220
18713
|
}
|
|
18221
18714
|
if (op === "*") {
|
|
18222
|
-
if (Array.isArray(a[0]))
|
|
18715
|
+
if (Array.isArray(a[0])) {
|
|
18716
|
+
this.charge(a.length + LIST_COST, at);
|
|
18717
|
+
return a.map((row) => this.arith("*", row, b, at));
|
|
18718
|
+
}
|
|
18719
|
+
const term = (x, y) => {
|
|
18720
|
+
const t = this.arith("*", x, y, at);
|
|
18721
|
+
if (typeof t !== "number")
|
|
18722
|
+
throw new KerfError(
|
|
18723
|
+
"Can't multiply these lists: an item times an item is not a number",
|
|
18724
|
+
at
|
|
18725
|
+
);
|
|
18726
|
+
return t;
|
|
18727
|
+
};
|
|
18223
18728
|
if (Array.isArray(b[0])) {
|
|
18224
18729
|
const cols = b[0].length;
|
|
18730
|
+
if (a.length !== b.length || b.some((r) => !Array.isArray(r) || r.length !== cols))
|
|
18731
|
+
throw new KerfError(
|
|
18732
|
+
`Can't multiply a list of length ${a.length} by a matrix: it needs ${a.length} rows of the same length`,
|
|
18733
|
+
at
|
|
18734
|
+
);
|
|
18225
18735
|
this.checkSize(cols, false, at);
|
|
18736
|
+
this.tick(at, cols * a.length);
|
|
18226
18737
|
return Array.from(
|
|
18227
18738
|
{ length: cols },
|
|
18228
|
-
(_, j) => a.reduce(
|
|
18229
|
-
(s, x, i) => s + this.arith("*", x, b[i][j], at),
|
|
18230
|
-
0
|
|
18231
|
-
)
|
|
18739
|
+
(_, j) => a.reduce((s, x, i) => s + term(x, b[i][j]), 0)
|
|
18232
18740
|
);
|
|
18233
18741
|
}
|
|
18234
18742
|
if (a.length !== b.length)
|
|
18235
18743
|
throw new KerfError(`Can't multiply lists of length ${a.length} and ${b.length}`, at);
|
|
18236
|
-
|
|
18744
|
+
this.tick(at, a.length);
|
|
18745
|
+
return a.reduce((s, x, i) => s + term(x, b[i]), 0);
|
|
18237
18746
|
}
|
|
18238
18747
|
}
|
|
18239
18748
|
if (Array.isArray(a) && typeof b === "number" && (op === "*" || op === "/")) {
|
|
@@ -18254,10 +18763,10 @@ var Evaluator = class {
|
|
|
18254
18763
|
};
|
|
18255
18764
|
throw new KerfError(`Can't ${verb[op] ?? op} ${typeName(a)} and ${typeName(b)}`, at);
|
|
18256
18765
|
}
|
|
18257
|
-
arg(a, name, index,
|
|
18766
|
+
arg(a, name, index, def2) {
|
|
18258
18767
|
if (a.named.has(name)) return a.named.get(name);
|
|
18259
18768
|
if (index >= 0 && index < a.pos.length) return a.pos[index];
|
|
18260
|
-
return
|
|
18769
|
+
return def2;
|
|
18261
18770
|
}
|
|
18262
18771
|
num(v, fn, name) {
|
|
18263
18772
|
if (typeof v !== "number" || !Number.isFinite(v))
|
|
@@ -18271,6 +18780,34 @@ var Evaluator = class {
|
|
|
18271
18780
|
return [v[0], v[1] ?? 0];
|
|
18272
18781
|
throw new Error(`${name} must be a number or [x, y], got ${show(v)}`);
|
|
18273
18782
|
}
|
|
18783
|
+
vec3(v, name) {
|
|
18784
|
+
const ok = (x) => typeof x === "number" && Number.isFinite(x);
|
|
18785
|
+
if (Array.isArray(v) && (v.length === 2 || v.length === 3) && v.every(ok))
|
|
18786
|
+
return [v[0], v[1], v[2] ?? 0];
|
|
18787
|
+
throw new Error(`${name} must be [x, y, z], got ${show(v)}`);
|
|
18788
|
+
}
|
|
18789
|
+
placements(at, turn2, qty) {
|
|
18790
|
+
const list2 = (v, name) => {
|
|
18791
|
+
if (v === void 0) return [[0, 0, 0]];
|
|
18792
|
+
if (Array.isArray(v) && v.length > 0 && Array.isArray(v[0]))
|
|
18793
|
+
return v.map((item, i) => this.vec3(item, `${name}[${i}]`));
|
|
18794
|
+
return [this.vec3(v, name)];
|
|
18795
|
+
};
|
|
18796
|
+
const ats = list2(at, "at");
|
|
18797
|
+
const turns = list2(turn2, "rotate");
|
|
18798
|
+
for (const [items, name] of [
|
|
18799
|
+
[ats, "at"],
|
|
18800
|
+
[turns, "rotate"]
|
|
18801
|
+
])
|
|
18802
|
+
if (items.length !== 1 && items.length !== qty)
|
|
18803
|
+
throw new Error(
|
|
18804
|
+
`${name} needs one placement per copy: qty is ${qty} but ${name} has ${items.length}`
|
|
18805
|
+
);
|
|
18806
|
+
return Array.from({ length: qty }, (_, i) => ({
|
|
18807
|
+
at: ats[ats.length === 1 ? 0 : i],
|
|
18808
|
+
rotate: turns[turns.length === 1 ? 0 : i]
|
|
18809
|
+
}));
|
|
18810
|
+
}
|
|
18274
18811
|
points(v, name) {
|
|
18275
18812
|
if (!Array.isArray(v)) throw new Error(`${name} must be a list of [x, y] points`);
|
|
18276
18813
|
return v.map((p, i) => {
|
|
@@ -18302,9 +18839,9 @@ var Evaluator = class {
|
|
|
18302
18839
|
this.charge(isString ? Math.ceil(n2 / CHARS_PER_ITEM) : n2 + LIST_COST, pos);
|
|
18303
18840
|
}
|
|
18304
18841
|
segs(env) {
|
|
18305
|
-
const fn =
|
|
18306
|
-
const fa =
|
|
18307
|
-
const fs =
|
|
18842
|
+
const fn = toNumber(this.dyn(env, "$fn")) || 0;
|
|
18843
|
+
const fa = toNumber(this.dyn(env, "$fa")) || 2;
|
|
18844
|
+
const fs = toNumber(this.dyn(env, "$fs")) || 0.2;
|
|
18308
18845
|
const max = this.limits.maxSegments;
|
|
18309
18846
|
return (r) => {
|
|
18310
18847
|
const n2 = fragments(r, fn, fa, fs);
|
|
@@ -18331,9 +18868,15 @@ var Evaluator = class {
|
|
|
18331
18868
|
"text needs a font. Pass fonts to render(), or --font on the command line.",
|
|
18332
18869
|
a.at
|
|
18333
18870
|
);
|
|
18334
|
-
const
|
|
18871
|
+
const shown = write(this.arg(a, "text", 0, ""), this.limits.maxTextLength);
|
|
18872
|
+
if (!shown.whole)
|
|
18873
|
+
throw new KerfError(
|
|
18874
|
+
`the text is more than ${this.limits.maxTextLength} characters, the limit for one text()`,
|
|
18875
|
+
a.at
|
|
18876
|
+
);
|
|
18877
|
+
this.tick(a.at, shown.text.length);
|
|
18335
18878
|
try {
|
|
18336
|
-
return textMetrics(this.opts.fonts, text, this.textOpts(a, env));
|
|
18879
|
+
return textMetrics(this.opts.fonts, shown.text, this.textOpts(a, env));
|
|
18337
18880
|
} catch (e) {
|
|
18338
18881
|
if (e instanceof KerfError) throw e;
|
|
18339
18882
|
throw new KerfError(e.message, a.at);
|
|
@@ -18342,10 +18885,10 @@ var Evaluator = class {
|
|
|
18342
18885
|
textOpts(a, env) {
|
|
18343
18886
|
return {
|
|
18344
18887
|
size: this.num(this.arg(a, "size", 1, 10), "text", "size"),
|
|
18345
|
-
font:
|
|
18346
|
-
halign:
|
|
18347
|
-
valign:
|
|
18348
|
-
spacing:
|
|
18888
|
+
font: toText(this.arg(a, "font", 2, this.dyn(env, "$font") ?? "")),
|
|
18889
|
+
halign: toText(this.arg(a, "halign", -1, "left")),
|
|
18890
|
+
valign: toText(this.arg(a, "valign", -1, "baseline")),
|
|
18891
|
+
spacing: toNumber(this.arg(a, "spacing", -1, 1))
|
|
18349
18892
|
};
|
|
18350
18893
|
}
|
|
18351
18894
|
edges(v) {
|
|
@@ -18363,7 +18906,7 @@ var Evaluator = class {
|
|
|
18363
18906
|
return {
|
|
18364
18907
|
rect: (c) => {
|
|
18365
18908
|
const [w, h] = this.vec2(this.arg(c.args, "size", 0, 1), "size");
|
|
18366
|
-
const r =
|
|
18909
|
+
const r = toNumber(this.arg(c.args, "r", -1, 0)) || 0;
|
|
18367
18910
|
const center = truthy(this.arg(c.args, "center", 1, false));
|
|
18368
18911
|
const p = roundedRect(w, h, r, this.segs(c.env));
|
|
18369
18912
|
return regionShape(union2([center ? p.map(([x, y]) => [x - w / 2, y - h / 2]) : p]));
|
|
@@ -18406,7 +18949,7 @@ var Evaluator = class {
|
|
|
18406
18949
|
const pts = this.points(this.arg(c.args, "points", 0), "points");
|
|
18407
18950
|
const paths = this.arg(c.args, "paths", 1);
|
|
18408
18951
|
const polys = Array.isArray(paths) ? paths.map(
|
|
18409
|
-
(ix) => (Array.isArray(ix) ? ix : []).map((i) => pts[
|
|
18952
|
+
(ix) => (Array.isArray(ix) ? ix : []).map((i) => pts[toNumber(i)]).filter(Boolean)
|
|
18410
18953
|
) : [pts];
|
|
18411
18954
|
return regionShape(union2(polys, "evenodd"));
|
|
18412
18955
|
},
|
|
@@ -18415,7 +18958,7 @@ var Evaluator = class {
|
|
|
18415
18958
|
if (typeof d2 !== "string")
|
|
18416
18959
|
throw new Error('path() needs SVG path data, like path("M0 0 L10 0 L5 8 Z")');
|
|
18417
18960
|
const flat2 = flatten(parseSvgPath(d2), 0.01);
|
|
18418
|
-
const fill =
|
|
18961
|
+
const fill = this.arg(c.args, "fill", -1, "evenodd") === "nonzero" ? "nonzero" : "evenodd";
|
|
18419
18962
|
return merge([regionShape(union2(flat2.closed, fill)), lineShape(flat2.open)]);
|
|
18420
18963
|
},
|
|
18421
18964
|
line: (c) => {
|
|
@@ -18449,13 +18992,14 @@ var Evaluator = class {
|
|
|
18449
18992
|
throw new Error(
|
|
18450
18993
|
"text() needs a font. Pass fonts to render(), or --font on the command line."
|
|
18451
18994
|
);
|
|
18452
|
-
const
|
|
18453
|
-
const shown =
|
|
18454
|
-
if (shown.
|
|
18995
|
+
const text2 = this.arg(c.args, "text", 0, "");
|
|
18996
|
+
const shown = write(text2, this.limits.maxTextLength);
|
|
18997
|
+
if (!shown.whole)
|
|
18455
18998
|
throw new Error(
|
|
18456
|
-
|
|
18999
|
+
`the text is more than ${this.limits.maxTextLength} characters, the limit for one text()`
|
|
18457
19000
|
);
|
|
18458
|
-
|
|
19001
|
+
this.tick(c.args.at, shown.text.length);
|
|
19002
|
+
return regionShape(textRegions(this.opts.fonts, shown.text, this.textOpts(c.args, c.env)));
|
|
18459
19003
|
},
|
|
18460
19004
|
translate: (c) => {
|
|
18461
19005
|
const [x, y] = this.vec2(this.arg(c.args, "v", 0, [0, 0]), "v", false);
|
|
@@ -18463,7 +19007,7 @@ var Evaluator = class {
|
|
|
18463
19007
|
},
|
|
18464
19008
|
rotate: (c) => {
|
|
18465
19009
|
const a = this.arg(c.args, "a", 0, 0);
|
|
18466
|
-
const deg = Array.isArray(a) ?
|
|
19010
|
+
const deg = Array.isArray(a) ? toNumber(a[2] ?? 0) : this.num(a, "rotate", "a");
|
|
18467
19011
|
const r = deg * Math.PI / 180;
|
|
18468
19012
|
const cs = Math.cos(r), sn = Math.sin(r);
|
|
18469
19013
|
const ctr = this.arg(c.args, "center", -1);
|
|
@@ -18514,22 +19058,26 @@ var Evaluator = class {
|
|
|
18514
19058
|
}
|
|
18515
19059
|
return out;
|
|
18516
19060
|
},
|
|
19061
|
+
// One hull for the shapes outside parts, and one inside each part
|
|
18517
19062
|
hull: (c) => {
|
|
18518
19063
|
const s = c.children();
|
|
18519
|
-
const
|
|
18520
|
-
|
|
18521
|
-
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
|
|
19064
|
+
const each = (layers) => {
|
|
19065
|
+
const pts = [];
|
|
19066
|
+
let key = "cut";
|
|
19067
|
+
let first = true;
|
|
19068
|
+
for (const [k, l] of layers) {
|
|
19069
|
+
if (first && (l.regions.length || l.lines.length)) {
|
|
19070
|
+
key = k;
|
|
19071
|
+
first = false;
|
|
19072
|
+
}
|
|
19073
|
+
for (const p of [...l.regions, ...l.lines]) for (const q of p) pts.push(q);
|
|
18526
19074
|
}
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
19075
|
+
const h = hull(pts);
|
|
19076
|
+
return /* @__PURE__ */ new Map([[key, { regions: h.length >= 3 ? [h] : [], lines: [] }]]);
|
|
19077
|
+
};
|
|
18530
19078
|
return {
|
|
18531
|
-
layers:
|
|
18532
|
-
parts: s.parts
|
|
19079
|
+
layers: each(s.layers),
|
|
19080
|
+
parts: s.parts.map((p) => ({ ...p, layers: each(p.layers) }))
|
|
18533
19081
|
};
|
|
18534
19082
|
},
|
|
18535
19083
|
offset: (c) => {
|
|
@@ -18568,18 +19116,21 @@ var Evaluator = class {
|
|
|
18568
19116
|
const m = mode ?? known?.mode ?? "line";
|
|
18569
19117
|
if (!["cut", "line", "fill", "guide"].includes(m))
|
|
18570
19118
|
throw new Error('mode must be "cut", "line", "fill" or "guide"');
|
|
18571
|
-
const col =
|
|
19119
|
+
const col = toText(color ?? known?.color ?? "#00aa00");
|
|
18572
19120
|
if (!/^#[0-9a-fA-F]{6}$/.test(col)) throw new Error('color must look like "#00aa00"');
|
|
18573
19121
|
this.layers.set(name, { name, mode: m, color: col });
|
|
18574
19122
|
}
|
|
18575
19123
|
return retag(c.children(), name);
|
|
18576
19124
|
},
|
|
18577
19125
|
part: (c) => {
|
|
18578
|
-
const name =
|
|
18579
|
-
const qty = Math.max(1, Math.floor(
|
|
19126
|
+
const name = toText(this.arg(c.args, "name", 0, "part"));
|
|
19127
|
+
const qty = Math.max(1, Math.floor(toNumber(this.arg(c.args, "qty", 1, 1)) || 1));
|
|
18580
19128
|
this.copies += qty;
|
|
18581
19129
|
if (!(this.copies <= this.limits.maxParts))
|
|
18582
19130
|
throw new Error(`more than ${this.limits.maxParts} part copies in total, the limit`);
|
|
19131
|
+
const at = this.arg(c.args, "at", -1);
|
|
19132
|
+
const turn2 = this.arg(c.args, "rotate", -1);
|
|
19133
|
+
const placements = at === void 0 && turn2 === void 0 ? void 0 : this.placements(at, turn2, qty);
|
|
18583
19134
|
const s = c.children();
|
|
18584
19135
|
return {
|
|
18585
19136
|
layers: /* @__PURE__ */ new Map(),
|
|
@@ -18590,8 +19141,9 @@ var Evaluator = class {
|
|
|
18590
19141
|
qty,
|
|
18591
19142
|
layers: s.layers,
|
|
18592
19143
|
thickness: this.thickness(c.env),
|
|
18593
|
-
kerf:
|
|
18594
|
-
material:
|
|
19144
|
+
kerf: toNumber(this.dyn(c.env, "$kerf")) || 0,
|
|
19145
|
+
material: toText(this.dyn(c.env, "$material") ?? "material"),
|
|
19146
|
+
...placements ? { placements } : {}
|
|
18595
19147
|
}
|
|
18596
19148
|
]
|
|
18597
19149
|
};
|
|
@@ -18602,7 +19154,7 @@ var Evaluator = class {
|
|
|
18602
19154
|
const n2 = this.arg(c.args, "name", 2);
|
|
18603
19155
|
if (t !== void 0) c.env.vars.set("$thickness", this.num(t, "material", "thickness"));
|
|
18604
19156
|
if (k !== void 0) c.env.vars.set("$kerf", this.num(k, "material", "kerf"));
|
|
18605
|
-
if (n2 !== void 0) c.env.vars.set("$material",
|
|
19157
|
+
if (n2 !== void 0) c.env.vars.set("$material", toText(n2));
|
|
18606
19158
|
return c.children();
|
|
18607
19159
|
},
|
|
18608
19160
|
children: (c) => {
|
|
@@ -18616,7 +19168,7 @@ var Evaluator = class {
|
|
|
18616
19168
|
if (idx === void 0) kids.forEach((k) => want.add(k));
|
|
18617
19169
|
else
|
|
18618
19170
|
for (const i of this.iterable(idx, c.args.at))
|
|
18619
|
-
if (kids[
|
|
19171
|
+
if (kids[toNumber(i)]) want.add(kids[toNumber(i)]);
|
|
18620
19172
|
const out = [];
|
|
18621
19173
|
for (const st of ctx.stmts) {
|
|
18622
19174
|
if (st.kind === "assign") this.stmt(st, e);
|
|
@@ -18632,12 +19184,7 @@ var Evaluator = class {
|
|
|
18632
19184
|
return c.children();
|
|
18633
19185
|
},
|
|
18634
19186
|
assert: (c) => {
|
|
18635
|
-
|
|
18636
|
-
if (!truthy(a.pos[0] ?? a.named.get("condition")))
|
|
18637
|
-
throw new KerfError(
|
|
18638
|
-
`Assertion failed${a.pos[1] !== void 0 ? ": " + (typeof a.pos[1] === "string" ? a.pos[1] : show(a.pos[1])) : ""}`,
|
|
18639
|
-
a.at
|
|
18640
|
-
);
|
|
19187
|
+
this.assert(c.args);
|
|
18641
19188
|
return c.children();
|
|
18642
19189
|
},
|
|
18643
19190
|
finger_rect: (c) => {
|
|
@@ -18720,21 +19267,21 @@ function tidy(p, closed) {
|
|
|
18720
19267
|
var d = (p, closed) => `M${tidy(p, closed).map(([x, y]) => `${x} ${y}`).join("L")}${closed ? "Z" : ""}`;
|
|
18721
19268
|
function layerPaths(items, layers) {
|
|
18722
19269
|
const out = [];
|
|
18723
|
-
for (const
|
|
19270
|
+
for (const def2 of layers) {
|
|
18724
19271
|
const lines = [];
|
|
18725
19272
|
const holes = [];
|
|
18726
19273
|
const shapes = [];
|
|
18727
19274
|
for (const it of items) {
|
|
18728
|
-
const l = it.layers.get(
|
|
19275
|
+
const l = it.layers.get(def2.name);
|
|
18729
19276
|
if (!l) continue;
|
|
18730
19277
|
for (const p of l.lines) lines.push(d(p, false));
|
|
18731
19278
|
for (const p of l.regions) (area2(p) < 0 ? holes : shapes).push(d(p, true));
|
|
18732
19279
|
}
|
|
18733
19280
|
if (lines.length || holes.length || shapes.length)
|
|
18734
19281
|
out.push({
|
|
18735
|
-
name:
|
|
18736
|
-
mode:
|
|
18737
|
-
color:
|
|
19282
|
+
name: def2.name,
|
|
19283
|
+
mode: def2.mode,
|
|
19284
|
+
color: def2.color,
|
|
18738
19285
|
d: [...lines, ...holes, ...shapes].join(""),
|
|
18739
19286
|
regions: [...holes, ...shapes].join(""),
|
|
18740
19287
|
lines: lines.join("")
|
|
@@ -18747,19 +19294,19 @@ function toSvg(items, width, height, layers) {
|
|
|
18747
19294
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
18748
19295
|
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="${n(width)}mm" height="${n(height)}mm" viewBox="0 0 ${n(width)} ${n(height)}">`
|
|
18749
19296
|
];
|
|
18750
|
-
for (const
|
|
19297
|
+
for (const def2 of layers) {
|
|
18751
19298
|
const inner = [];
|
|
18752
19299
|
const outer = [];
|
|
18753
19300
|
for (const it of items) {
|
|
18754
|
-
const l = it.layers.get(
|
|
19301
|
+
const l = it.layers.get(def2.name);
|
|
18755
19302
|
if (!l) continue;
|
|
18756
19303
|
const tag = ` data-part="${esc(it.part)}"`;
|
|
18757
|
-
if (
|
|
19304
|
+
if (def2.mode === "fill") {
|
|
18758
19305
|
if (l.regions.length)
|
|
18759
19306
|
outer.push(`<path${tag} d="${l.regions.map((p) => d(p, true)).join("")}"/>`);
|
|
18760
19307
|
for (const p of l.lines)
|
|
18761
19308
|
outer.push(
|
|
18762
|
-
`<path${tag} fill="none" stroke="${
|
|
19309
|
+
`<path${tag} fill="none" stroke="${def2.color}" stroke-width="0.1" d="${d(p, false)}"/>`
|
|
18763
19310
|
);
|
|
18764
19311
|
continue;
|
|
18765
19312
|
}
|
|
@@ -18768,9 +19315,9 @@ function toSvg(items, width, height, layers) {
|
|
|
18768
19315
|
(area2(p) < 0 ? inner : outer).push(`<path${tag} d="${d(p, true)}"/>`);
|
|
18769
19316
|
}
|
|
18770
19317
|
if (!inner.length && !outer.length) continue;
|
|
18771
|
-
const paint =
|
|
19318
|
+
const paint = def2.mode === "fill" ? `fill="${def2.color}" fill-rule="evenodd" stroke="none"` : `fill="none" stroke="${def2.color}" stroke-width="0.1"${def2.mode === "guide" ? ' stroke-dasharray="1 1"' : ""}`;
|
|
18772
19319
|
out.push(
|
|
18773
|
-
`<g id="${esc(
|
|
19320
|
+
`<g id="${esc(def2.name)}" inkscape:groupmode="layer" inkscape:label="${esc(def2.name)}" data-mode="${def2.mode}" ${paint}>`,
|
|
18774
19321
|
...inner,
|
|
18775
19322
|
...outer,
|
|
18776
19323
|
"</g>"
|
|
@@ -18799,10 +19346,32 @@ var aci = (color) => {
|
|
|
18799
19346
|
if (b > r && b > g) return 5;
|
|
18800
19347
|
return 7;
|
|
18801
19348
|
};
|
|
19349
|
+
function dxfNames(layers) {
|
|
19350
|
+
const base = (s) => s.toUpperCase().replace(/[^A-Z0-9_-]/g, "_");
|
|
19351
|
+
const builtIn = new Set(DEFAULT_LAYERS.map((l) => l.name));
|
|
19352
|
+
const taken = new Set(layers.map((l) => base(l.name)));
|
|
19353
|
+
const used = /* @__PURE__ */ new Set();
|
|
19354
|
+
const out = /* @__PURE__ */ new Map();
|
|
19355
|
+
const ordered = [
|
|
19356
|
+
...layers.filter((l) => builtIn.has(l.name)),
|
|
19357
|
+
...layers.filter((l) => !builtIn.has(l.name))
|
|
19358
|
+
];
|
|
19359
|
+
for (const l of ordered) {
|
|
19360
|
+
let n2 = base(l.name);
|
|
19361
|
+
if (used.has(n2)) {
|
|
19362
|
+
let i = 2;
|
|
19363
|
+
while (taken.has(`${n2}_${i}`) || used.has(`${n2}_${i}`)) i++;
|
|
19364
|
+
n2 = `${n2}_${i}`;
|
|
19365
|
+
}
|
|
19366
|
+
used.add(n2);
|
|
19367
|
+
out.set(l.name, n2);
|
|
19368
|
+
}
|
|
19369
|
+
return out;
|
|
19370
|
+
}
|
|
18802
19371
|
function toDxf(items, _width, height, layers) {
|
|
18803
19372
|
const out = [];
|
|
18804
19373
|
const g = (code, value) => out.push(String(code), String(value));
|
|
18805
|
-
const
|
|
19374
|
+
const names = dxfNames(layers);
|
|
18806
19375
|
g(0, "SECTION");
|
|
18807
19376
|
g(2, "HEADER");
|
|
18808
19377
|
g(9, "$ACADVER");
|
|
@@ -18817,7 +19386,7 @@ function toDxf(items, _width, height, layers) {
|
|
|
18817
19386
|
g(70, layers.length);
|
|
18818
19387
|
for (const l of layers) {
|
|
18819
19388
|
g(0, "LAYER");
|
|
18820
|
-
g(2,
|
|
19389
|
+
g(2, names.get(l.name));
|
|
18821
19390
|
g(70, 0);
|
|
18822
19391
|
g(62, aci(l.color));
|
|
18823
19392
|
g(6, "CONTINUOUS");
|
|
@@ -18847,11 +19416,11 @@ function toDxf(items, _width, height, layers) {
|
|
|
18847
19416
|
g(0, "SEQEND");
|
|
18848
19417
|
g(8, layer);
|
|
18849
19418
|
};
|
|
18850
|
-
for (const
|
|
18851
|
-
const ln =
|
|
19419
|
+
for (const def2 of layers) {
|
|
19420
|
+
const ln = names.get(def2.name);
|
|
18852
19421
|
const outer = [];
|
|
18853
19422
|
for (const it of items) {
|
|
18854
|
-
const l = it.layers.get(
|
|
19423
|
+
const l = it.layers.get(def2.name);
|
|
18855
19424
|
if (!l) continue;
|
|
18856
19425
|
for (const p of l.lines) poly(ln, p, false);
|
|
18857
19426
|
for (const p of l.regions) area2(p) < 0 ? poly(ln, p, true) : outer.push(p);
|
|
@@ -18873,6 +19442,13 @@ var perimeter = (p, closed) => {
|
|
|
18873
19442
|
};
|
|
18874
19443
|
var round2 = (n2) => Math.round(n2 * 100) / 100;
|
|
18875
19444
|
function render(source, options = {}) {
|
|
19445
|
+
for (const [name, v] of Object.entries(options.params ?? {})) {
|
|
19446
|
+
try {
|
|
19447
|
+
checkSetting(name, v);
|
|
19448
|
+
} catch (e) {
|
|
19449
|
+
throw new KerfError(e.message);
|
|
19450
|
+
}
|
|
19451
|
+
}
|
|
18876
19452
|
const { program } = parse(source);
|
|
18877
19453
|
const fonts = options.fonts ? new FontBook(options.fonts, options.defaultFont) : void 0;
|
|
18878
19454
|
const ev = new Evaluator({
|
|
@@ -18907,12 +19483,15 @@ function render(source, options = {}) {
|
|
|
18907
19483
|
name: "part",
|
|
18908
19484
|
qty: 1,
|
|
18909
19485
|
layers: res.shape.layers,
|
|
18910
|
-
thickness:
|
|
18911
|
-
kerf:
|
|
18912
|
-
material:
|
|
19486
|
+
thickness: toNumber(g("$thickness")) || 3,
|
|
19487
|
+
kerf: toNumber(g("$kerf")) || 0,
|
|
19488
|
+
material: toText(g("$material") ?? "material")
|
|
18913
19489
|
});
|
|
18914
19490
|
if (!parts.length) warnings.push("Nothing to cut: the program made no shapes.");
|
|
18915
19491
|
const infos = [];
|
|
19492
|
+
const assembly = [];
|
|
19493
|
+
const loose = [];
|
|
19494
|
+
const stackedCopies = /* @__PURE__ */ new Set();
|
|
18916
19495
|
const ready = [];
|
|
18917
19496
|
for (const p of parts) {
|
|
18918
19497
|
const material = union2(
|
|
@@ -18933,6 +19512,30 @@ function render(source, options = {}) {
|
|
|
18933
19512
|
}
|
|
18934
19513
|
if (regions.length || lines.length) layers.set(k, { regions, lines });
|
|
18935
19514
|
}
|
|
19515
|
+
if (material.length) {
|
|
19516
|
+
const flat = { name: p.name, thickness: p.thickness, outline: material };
|
|
19517
|
+
if (p.placements) {
|
|
19518
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19519
|
+
p.placements.forEach((placement, i) => {
|
|
19520
|
+
const part = { ...flat, copy: i + 1, matrix: placementMatrix(placement), placed: true };
|
|
19521
|
+
assembly.push(part);
|
|
19522
|
+
const key = part.matrix.map((v) => v.toFixed(6)).join(",");
|
|
19523
|
+
if (seen.has(key)) stackedCopies.add(part);
|
|
19524
|
+
seen.add(key);
|
|
19525
|
+
});
|
|
19526
|
+
if (seen.size < p.placements.length)
|
|
19527
|
+
warnings.push(
|
|
19528
|
+
`Copies of part "${p.name}" are in the same place in the assembly. Give at a list with one placement per copy to spread them out.`
|
|
19529
|
+
);
|
|
19530
|
+
} else
|
|
19531
|
+
for (let i = 0; i < p.qty; i++)
|
|
19532
|
+
loose.push({
|
|
19533
|
+
...flat,
|
|
19534
|
+
copy: i + 1,
|
|
19535
|
+
matrix: placementMatrix({ at: [0, 0, 0], rotate: [0, 0, 0] }),
|
|
19536
|
+
placed: false
|
|
19537
|
+
});
|
|
19538
|
+
}
|
|
18936
19539
|
const n2 = pieces(material).length;
|
|
18937
19540
|
if (n2 > 1)
|
|
18938
19541
|
warnings.push(
|
|
@@ -18974,6 +19577,27 @@ function render(source, options = {}) {
|
|
|
18974
19577
|
infos.push(info);
|
|
18975
19578
|
ready.push({ info, layers });
|
|
18976
19579
|
}
|
|
19580
|
+
const { found: clashes, complete } = collisions(
|
|
19581
|
+
assembly.filter((part) => !stackedCopies.has(part)),
|
|
19582
|
+
limits.maxCollisionPairs
|
|
19583
|
+
);
|
|
19584
|
+
if (!complete)
|
|
19585
|
+
warnings.push(
|
|
19586
|
+
`The assembly has more than ${limits.maxCollisionPairs} pairs of touching parts, the limit, so only those were checked for collisions.`
|
|
19587
|
+
);
|
|
19588
|
+
for (const [a, b] of clashes.slice(0, 5))
|
|
19589
|
+
warnings.push(
|
|
19590
|
+
`Parts "${a.name}"${a.copy > 1 ? ` (copy ${a.copy})` : ""} and "${b.name}"${b.copy > 1 ? ` (copy ${b.copy})` : ""} collide in the assembly. Check their edges and where they are placed.`
|
|
19591
|
+
);
|
|
19592
|
+
if (clashes.length > 5)
|
|
19593
|
+
warnings.push(`${clashes.length - 5} more pairs of parts collide in the assembly.`);
|
|
19594
|
+
if (assembly.length && loose.length) {
|
|
19595
|
+
const names = [...new Set(loose.map((p) => `"${p.name}"`))];
|
|
19596
|
+
warnings.push(
|
|
19597
|
+
`${names.length === 1 ? "Part" : "Parts"} ${names.slice(0, 5).join(", ")}${names.length > 5 ? ` and ${names.length - 5} more` : ""} ${names.length === 1 ? "has" : "have"} no at or rotate, so ${names.length === 1 ? "it lies" : "they lie"} flat beside the assembly.`
|
|
19598
|
+
);
|
|
19599
|
+
assembly.push(...besideAssembly(assembly, loose));
|
|
19600
|
+
}
|
|
18977
19601
|
let outputPoints = 0;
|
|
18978
19602
|
for (const r of ready) {
|
|
18979
19603
|
let n2 = 0;
|
|
@@ -18990,7 +19614,7 @@ function render(source, options = {}) {
|
|
|
18990
19614
|
const sheetSize = options.sheet ?? g("$sheet");
|
|
18991
19615
|
if (!Array.isArray(sheetSize) || !(Number.isFinite(sheetSize[0]) && sheetSize[0] > 0) || !(Number.isFinite(sheetSize[1]) && sheetSize[1] > 0))
|
|
18992
19616
|
throw new KerfError("$sheet must be [width, height], both more than 0");
|
|
18993
|
-
const gap = options.gap ??
|
|
19617
|
+
const gap = options.gap ?? toNumber(g("$gap") ?? 3);
|
|
18994
19618
|
const margin = options.margin ?? gap;
|
|
18995
19619
|
if (!(Number.isFinite(gap) && gap >= 0)) throw new KerfError("$gap must be a number, 0 or more");
|
|
18996
19620
|
if (!(Number.isFinite(margin) && margin >= 0))
|
|
@@ -19120,7 +19744,7 @@ function render(source, options = {}) {
|
|
|
19120
19744
|
};
|
|
19121
19745
|
}
|
|
19122
19746
|
const single = sheets.length === 1 ? sheets[0] : void 0;
|
|
19123
|
-
const
|
|
19747
|
+
const stacked2 = single ? [] : sheets.flatMap((s, i) => {
|
|
19124
19748
|
const dy = sheets.slice(0, i).reduce((acc, p) => acc + p.height + 10, 0);
|
|
19125
19749
|
return s.items.map((it) => ({ ...it, layers: moved(it.layers, [1, 0, 0, 1, 0, dy]) }));
|
|
19126
19750
|
});
|
|
@@ -19128,8 +19752,8 @@ function render(source, options = {}) {
|
|
|
19128
19752
|
const height = round2(
|
|
19129
19753
|
Math.max(1, sheets.reduce((acc, s) => acc + s.height, 0) + 10 * Math.max(0, sheets.length - 1))
|
|
19130
19754
|
);
|
|
19131
|
-
const svg = single ? single.svg : toSvg(
|
|
19132
|
-
const paths = single ? single.paths : layerPaths(
|
|
19755
|
+
const svg = single ? single.svg : toSvg(stacked2, width, height, layerList);
|
|
19756
|
+
const paths = single ? single.paths : layerPaths(stacked2, layerList);
|
|
19133
19757
|
return {
|
|
19134
19758
|
sheets,
|
|
19135
19759
|
width: single?.width ?? width,
|
|
@@ -19137,6 +19761,7 @@ function render(source, options = {}) {
|
|
|
19137
19761
|
paths,
|
|
19138
19762
|
svg,
|
|
19139
19763
|
parts: infos,
|
|
19764
|
+
assembly,
|
|
19140
19765
|
layers: layerList,
|
|
19141
19766
|
warnings,
|
|
19142
19767
|
echoes: res.echoes
|
|
@@ -19227,9 +19852,18 @@ function parameters(source) {
|
|
|
19227
19852
|
}
|
|
19228
19853
|
|
|
19229
19854
|
// src/index.ts
|
|
19230
|
-
var VERSION = "0.
|
|
19855
|
+
var VERSION = "0.4.0";
|
|
19231
19856
|
var LANGUAGE_VERSION = "0.1";
|
|
19232
19857
|
|
|
19858
|
+
// fonts/AtkinsonHyperlegible-Regular.ttf
|
|
19859
|
+
var AtkinsonHyperlegible_Regular_default = __toBinaryNode("AAEAAAASAQAABAAgRFNJRwAAAAEAANREAAAACEdERUYmIiVoAACtoAAAAPhHUE9TBhS8lAAArpgAACDKR1NVQs2+72cAAM9kAAAE3k9TLzKBnCDAAAABqAAAAGBjbWFwMF4gUgAAB8wAAAOOY3Z0IBXBCrQAABooAAAAbGZwZ21iLv99AAALXAAADgxnYXNwAAAAEAAArZgAAAAIZ2x5ZhpHbHEAAB14AACEOGhlYWQdEfmxAAABLAAAADZoaGVhCIkENgAAAWQAAAAkaG10eMbdPbEAAAIIAAAFwmxvY2GjLsNGAAAalAAAAuRtYXhwAssPEgAAAYgAAAAgbmFtZXEwlLkAAKGwAAAEpnBvc3S6e2pLAACmWAAAB0BwcmVwWrHfOwAAGWgAAAC9AAEAAAABAYk7pItRXw889QAPA+gAAAAA3G3PNQAAAADcsOWS/8b/BgUKA3gAAAAGAAIAAAAAAAAAAQAAA7b+3gAABTD/xv63BQoAAQAAAAAAAAAAAAAAAAAAAXAAAQAAAXEAWAAHAFQABAACACoAVwCNAAAAlQ4MAAIAAQAEAhYBkAAFAAACigK7AAAAjAKKArsAAAHfADEBAgAAAAAAAAAAAAAAAIAAAO8AACBLAAAAAAAAAABOT05FAMAADSXKA7b+3gAAA7YBIiAAAAMAAAAAAfACnAAAACAAAwIPADICWAAAAAAAAAEYAAABGAAAAogAPAGSACoCJQAiAj4AKgJmACYCRwA2AlYAPAH+AA8CZwA8AlYAPAJyAAoCawBMApAAMgKhAEwCNwBMAiQATALGADICsgBMAZ4AQgH+AA8CcwBMAhsATAM0AEwCsQBMAtcAMgJZAEwC8QAyAmoATAJUACgCLgAKArIATAJNAAoDSAAKAm8ACgJTAAoCXwAsAg4AJgI2AEYB9AAmAjQAJgIbACYBNwAPAjAAJgIiAEYBFgAtAP7/xgHqAEYA7wBGA0kARgIiAEYCKAAmAjYARgJAACYBVABGAdcAHwFEABQCGABEAbkAAAKOAAABzQAAAa0AAAHMACgBrQA1Aa0ANQGPADUA1gA1AP0ADwEHADUA6wA1AOsANQDrADUBjgA1AY4ANQGOADUCHQAoAh0AKAG2ADUCuAA1BTAAJgFhADUBYQA1AkoADwFzADUCMgA1AloANQMeADUBfgA1AWAAKAJDADUBfgA1AX8ANQEMADUCGgBGAfwAJgDrADUBIwBJAQAANQF9ADkCMgA1AzoANQMsADUDZAA1AikAKAJaADUCKQAoAggAKAMMADIAzQAmAM0AJgE7AEwBeQAPATsAIQIoADUBjAAKAQwANQEZAEwBLQAoAo8AJgJSACgDnwAmAsEAJgCgACgBLAAyASwAIwGxAEQCWgA1AM0AJgFwACYAzQAmAXkADwE/ACYA6QBMAT8AIgIrACgBGQBMAfQAJgJKAEYCRAA1AlMACgDpAEwCEgAfAakANQMeADUCCAAxAlUATAPmAAoBQQAZAcoANQJFADUCWgA1AkMANQJDADUCMQA1AksANQJaADUCVgAPAOsANQJGADUDBQA1Aq8AMgJuADUCRgA1AvcANQJJADUCTwAUAZ4ANQGzADUB4AApAyAAKQNQADUBwgA1Aj0AFADtAA8CKAAmAtcAMgJAAEwDagAmAjcAJgI2AEYCEAA1AloANQQcADIDnwAmAnIACgJyAAoCcgAKAnIACgJyAAoCcgAKAnIACgIOACYCDgAmAg4AJgIOACYCDgAmAg4AJgIOACYCkAAyAfQAJgI3AEwCNwBMAjcATAI3AEwCGwAmAhsAJgIbACYCGwAmAZ4AQgGeAEIBngAtAZ4ALwEWABoBFgAtARb/5AEW/+YCsQBMAtcAMgLXADIC1wAyAtcAMgLXADICsgBMArIATAKyAEwCsgBMAlMACgIiAEYCKAAmAigAJgIoACYCKAAmAigAJgIYAEQCGABEAhgARAIYAEQBrQAAAa0AAAJUACgB1wAfAlMACgJfACwBzAAoAsgAFAJ/ADgCfwBtAn8ATwJ/AFQCfwAzAn8AVgJ/AFECfwBZAn8ASAJ/AFECcgAKAg4AJgJyAAoCDgAmAjcATAIbACYCNwBMAhsAJgI3AEwCGwAmAjcATAIbACYC1wAyAigAJgGeAEIBFv/8AZ4AQgEWACICkAAyAfQAJgKQADIB9AAmAlQAKAHXAB8CsgBMAhgARAKyAEwCGABEArIATAIYAEQCsgBMAhgARAKxAEwCIgBGArEATAIiAEYCXwAsAcwAKAJfACwBzAAoAsYACgJFABQCxgAyAjAAJgLGADICMAAmAjAAJgIbAEwA7wA3Ai4ACgDvAEYCGwBMAUQAFAKxAEwCIgBGAmoATAFUAEYCagBMAVQAJQLIABQCWwAm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JUawF0NYUBtSWVggPFkusTABFCstsEQssDsriiAgPLAGI0KKOCMgLkawAiVGsBdDWFAbUllYIDxZLrEwARQrsAZDLrAwKy2wRSywABawBCWwBCYgICBGI0dhsAwjQi5HI0cjYbALQysjIDwgLiM4sTABFCstsEYssQoEJUKwABawBCWwBCUgLkcjRyNhILAGI0KxDABCsAtDKyCwYFBYILBAUVizBCAFIBuzBCYFGllCQiMgR7AGQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsARDYGQjsAVDYWRQWLAEQ2EbsAVDYFmwAyWwAmIgsABQWLBAYFlmsAFjYbACJUZhOCMgPCM4GyEgIEYjR7ABKyNhOCFZsTABFCstsEcssQA6Ky6xMAEUKy2wSCyxADsrISMgIDywBiNCIzixMAEUK7AGQy6wMCstsEkssAAVIEewACNCsgABARUUEy6wNiotsEossAAVIEewACNCsgABARUUEy6wNiotsEsssQABFBOwNyotsEwssDkqLbBNLLAAFkUjIC4gRoojYTixMAEUKy2wTiywCiNCsE0rLbBPLLIAAEYrLbBQLLIAAUYrLbBRLLIBAEYrLbBSLLIBAUYrLbBTLLIAAEcrLbBULLIAAUcrLbBVLLIBAEcrLbBWLLIBAUcrLbBXLLMAAABDKy2wWCyzAAEAQystsFksswEAAEMrLbBaLLMBAQBDKy2wWyyzAAABQystsFwsswABAUMrLbBdLLMBAAFDKy2wXiyzAQEBQystsF8ssgAARSstsGAssgABRSstsGEssgEARSstsGIssgEBRSstsGMssgAASCstsGQssgABSCstsGUssgEASCstsGYssgEBSCstsGcsswAAAEQrLbBoLLMAAQBEKy2waSyzAQAARCstsGosswEBAEQrLbBrLLMAAAFEKy2wbCyzAAEBRCstsG0sswEAAUQrLbBuLLMBAQFEKy2wbyyxADwrLrEwARQrLbBwLLEAPCuwQCstsHEssQA8K7BBKy2wciywABaxADwrsEIrLbBzLLEBPCuwQCstsHQssQE8K7BBKy2wdSywABaxATwrsEIrLbB2LLEAPSsusTABFCstsHcssQA9K7BAKy2weCyxAD0rsEErLbB5LLEAPSuwQistsHossQE9K7BAKy2weyyxAT0rsEErLbB8LLEBPSuwQist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AF8ArAAIsQIBsKywNSsAAP//AAoAAAJoA08CJgAPAAABBwCSAGQAlgAIsQICsJawNSsAAP//AAoAAAJoA0YCJgAPAAABBwBHAL0APQAIsQICsD2wNSsAAP//AAoAAAJoA2ACJgAPAAAABwFfAL8AAP//AAoAAAJoA2ACJgAPAAAABwFNAP8AAP//AAoAAAJoAz0CJgAPAAABBwBbAHoAoQAIsQIBsKGwNSsAAP//ACb/9AHbApwCJgApAAAABgFjfQAAAP//ACb/9AHbAsMCJgApAAAABwFeAJsAAP//ACb/9AHbArcCJgApAAAABgFVZQAAAP//ACb/9AHbAqkCJgApAAAABgFvYgAAAP//ACb/9AHbArkCJgApAAAABgFYZwAAAP//ACb/9AHbAwkCJgApAAAABwFoAJoAAP//ACb/9AHbAsMCJgApAAAABwFMANgAAP//ADL/SwJqAqgCJgARAAAABwFUAQMAAP//ACb/SwHTAfgCJgArAAAABwFUALUAAP//AEwAAAIRA2ACJgATAAAABwFfALYAAP//AEwAAAIRA2ACJgATAAAABwFNAPYAAP//AEwAAAIRA2MCJgATAAAABwFWAI4AAP//AEwAAAIRA08CJgATAAABBwCSAFsAlgAIsQECsJawNSsAAP//ACb/9AICAsMCJgAtAAAABwFeAK0AAP//ACb/9AICAsMCJgAtAAAABwFMAOoAAP//ACb/9AICArcCJgAtAAAABgFVdwAAAP//ACb/9AICArkCJgAtAAAABgFYeQAAAP//AEIAAAFcA2ACJgAXAAAABgFfVQAAAP//AEIAAAFcA2ACJgAXAAAABwFNAJUAAP//AC0AAAFwA2MCJgAXAAAABgFWLQAAAP//AC8AAAFuA08CJgAXAAABBwCS//oAlgAIsQECsJawNSsAAP//ABoAAADGAsMCJgFiAAAABgFeGgAAAP//AC0AAAD5AsMCJgFiAAAABgFMVwAAAP///+QAAAEnArcCJgFiAAAABgFV5AAAAP///+YAAAElArkCJgFiAAAABgFY5gAAAP//AEwAAAJlA1UCJgAcAAABBwCrAJAArAAIsQEBsKywNSsAAP//ADL/9AKlA2ACJgAdAAAABwFfAPIAAP//ADL/9AKlA2ACJgAdAAAABwFNATIAAP//ADL/9AKlA2MCJgAdAAAABwFW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AAEECQAAAGIAAAADAAEECQABACoAYgADAAEECQACAA4AjAADAAEECQADAE4AmgADAAEECQAEADoA6AADAAEECQAFAEYBIgADAAEECQAGADgBaAADAAEECQAIACIBoAADAAEECQAJAHoBwgADAAEECQALAEICPAADAAEECQAMAC4CfgADAAEECQANASICrAADAAEECQAOADYDzgBDAG8AcAB5AHIAaQBnAGgAdAAgADIAMAAyADAAIABCAHIAYQBpAGwAbABlACAASQBuAHMAdABpAHQAdQB0AGUAIABvAGYAIABBAG0AZQByAGkAYwBhACwAIABJAG4AYwAuAEEAdABrAGkAbgBzAG8AbgAgAEgAeQBwAGUAcgBsAGUAZwBpAGIAbABlAFIAZQBnAHUAbABhAHIAMQAuADAAMAA2ADsATgBPAE4ARQA7AEEAdABrAGkAbgBzAG8AbgBIAHkAcABlAHIAbABlAGcAaQBiAGwAZQAtAFIAZQBnAHUAbABhAHIAQQB0AGsAaQBuAHMAbwBuACAASAB5AHAAZQByAGwAZQBnAGkAYgBsAGUAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADYAOwAgAHQAdABmAGEAdQB0AG8AaABpAG4AdAAgACgAdgAxAC4AOAAuADMAKQBBAHQAawBpAG4AcwBvAG4ASAB5AHAAZQByAGwAZQBnAGkAYgBsAGUALQBSAGUAZwB1AGwAYQByAEIAcgBhAGkAbABsAGUAIABJAG4AcwB0AGkAdAB1AHQAZQBFAGwAbABpAG8AdAB0ACAAUwBjAG8AdAB0ACwAIABNAGUAZwBhAG4AIABFAGkAcwB3AGUAcgB0AGgALAAgAEwAaQBuAHUAcwAgAEIAbwBtAGEAbgAsACAAVABoAGUAbwBkAG8AcgBlACAAUABlAHQAcgBvAHMAawB5AGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAEIAcgBhAGkAbABsAGUASQBuAHMAdABpAHQAdQB0AGUALgBvAHIAZwAvAGgAdAB0AHAAOgAvAC8AaABlAGwAbABvAGEAcABwAGwAaQBlAGQALgBjAG8AbQBUAGgAaQBzACAARgBvAG4AdAAgAFMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAGwAaQBjAGUAbgBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAAUwBJAEwAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUALAAgAFYAZQByAHMAaQBvAG4AIAAxAC4AMQAuACAAVABoAGkAcwAgAGwAaQBjAGUAbgBzAGUAIABpAHMAIABhAHYAYQBpAGwAYQBiAGwAZQAgAHcAaQB0AGgAIABhACAARgBBAFEAIABhAHQAOgAgAGgAdAB0AHAAcwA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAGgAdAB0AHAAcwA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAAAAAgAAAAAAAP+yADkAAAAAAAAAAAAAAAAAAAAAAAAAAAFxAAABAgEDAAMBBAATABQAFQAWABcAGAAZABoAGwAcACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0A2ADhANsA3ADdAOAAtgC3AMQAtAC1AMUAggDCAIcAqwDGAL4AvwC8AJ0AqQCkAIoA2gCDAJMBBQEGAI0BBwCIAMMA3gEIAJ4AqgD1APQA9gAfACAAIQAiACMAHQAeAD4APwBAAEEAQgBDAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASAF4AXwBgAGEAowCEAIUAvQCWAOgAhgCOAIsAogCJAJAApgCcAKcAjwCUAJUAuQCZAO8BCQEKAKUAkgELAQwAmAENAJoAmwDfANkAsgCzAIwBDgDiAOMAoQCRAO0AoADqAO4A8AC4ALAAsQDHAK4AYgBjAK0AyQEPARAAagBrAG0AbABuAGkAZABvAMsAZQDIAMoAcQBwAHIAcwDPAMwAzQDOAHUAdAB2AHcAZgDTANAA0QCvAGcA1gDUANUAaADrAHgAegB5AHsAfQB8AH8AfgCAAIEA7AC6AOQA5QC7AOYA5wDpAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwA/QD+AS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIA+AD5AUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBAQFTAVQBVQFWAVcA/wEAAPsA/AFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwANcBcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+BE5VTEwCQ1IHdW5pMDBBMAd1bmkwMEIyB3VuaTAwQjMHdW5pMDNCQwd1bmkwMEI5B3VuaTIyMTUHdW5pMjIxOQd1bmkwM0E5CWVzdGltYXRlZAd1bmkwMzk0B3VuaTIxMTMHQW1hY3JvbgdhbWFjcm9uB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYGQWJyZXZlBmFicmV2ZQdBb2dvbmVrB2FvZ29uZWsHRW1hY3JvbgdlbWFjcm9uCkVkb3RhY2NlbnQKZWRvdGFjY2VudAdFb2dvbmVrB2VvZ29uZWsGRWNhcm9uBmVjYXJvbg1PaHVuZ2FydW1sYXV0DW9odW5nYXJ1bWxhdXQHSW1hY3JvbgdpbWFjcm9uB0lvZ29uZWsHaW9nb25lawpDZG90YWNjZW50CmNkb3RhY2NlbnQGU2FjdXRlBnNhY3V0ZQdVbWFjcm9uB3VtYWNyb24FVXJpbmcFdXJpbmcNVWh1bmdhcnVtbGF1dA11aHVuZ2FydW1sYXV0B1VvZ29uZWsHdW9nb25lawZOYWN1dGUGbmFjdXRlBk5jYXJvbgZuY2Fyb24GWmFjdXRlBnphY3V0ZQpaZG90YWNjZW50Cnpkb3RhY2NlbnQESGJhcgRoYmFyCkdkb3RhY2NlbnQKZ2RvdGFjY2VudAd1bmkwMTIzB3VuaTAxM0IHdW5pMDEzQwZUY2Fyb24GbGNhcm9uBkxjYXJvbgZ0Y2Fyb24HdW5pMDE0NQd1bmkwMTQ2BlJhY3V0ZQZyYWN1dGUGUmNhcm9uBnJjYXJvbgZEY3JvYXQGRGNhcm9uBmRjYXJvbgd1bmkwMTM2B3VuaTAxMzcHdW5pMDEyMgd1bmkwMjE4B3VuaTAxNjIHdW5pMDIxQQlhY3V0ZWNvbWIOYWN1dGVjb21iLmNh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/64Aw//kAMT/5ADF/+QAxv/kAMf/5ADI/+QAyf/kAOb/7QD0/+0A9f/tAPb/7QED/64BBP/kAQX/rgEG/+QBGv/tAUj/7QFq/+0AEgAPABwAJgATACf/2gBCABMAvAAcAL0AHAC+ABwAvwAcAMAAHADBABwAwgAcAOb/2gD1/9oA9wATAQMAHAEFABwBKAATASoAEwBbAA//vQAR/+QAFf/kABj/2gAd/+QAH//kACIAJgAkABMAJQATACcAEwAp/9oAK//RACz/0QAt/9EAL//RADX/7QA2/+0AN//RADn/0QA7/+0Alv+iALL/0QC1/9oAtv/RALr/5AC7/9EAvP+9AL3/vQC+/70Av/+9AMD/vQDB/70Awv+9AMP/2gDE/9oAxf/aAMb/2gDH/9oAyP/aAMn/2gDK/+QAy//RAND/0QDR/9EA0v/RANP/0QDd/+QA3v/kAN//5ADg/+QA4f/kAOYAEwDn/+0A6P/RAOn/0QDq/9EA6//RAOz/0QD0/+0A9QATAQP/vQEE/9oBBf+9AQb/2gEI/9EBCv/RAQz/0QEO/9EBFf/kARb/0QEX/+QBGP/RARr/7QEk/+0BJv/tAS3/5AEu/9EBL//kATD/0QEx/9EBNAAmATn/7QE//9EBQf/RAUT/5AFF/+QBRv/RAUj/7QFKACYBSwAmAWr/7QBLAA//0QAR/+0AFf/tABj/5AAd/+0AH//tACIAHAAkABMAKf/kACv/6QAs/+kALf/pAC//5AA3/+kAOf/pALL/6QC1/+QAtv/pALr/7QC7/+kAvP/RAL3/0QC+/9EAv//RAMD/0QDB/9EAwv/RAMP/5ADE/+QAxf/kAMb/5ADH/+QAyP/kAMn/5ADK/+0Ay//pAND/6QDR/+kA0v/pANP/6QDd/+0A3v/tAN//7QDg/+0A4f/tAOj/6QDp/+kA6v/pAOv/6QDs/+kBA//RAQT/5AEF/9EBBv/kAQj/6QEK/+kBDP/pAQ7/6QEV/+0BFv/pARf/7QEY/+kBLf/tAS7/5AEv/+0BMP/kATH/5AE0ABwBP//pAUH/6QFE/+0BRf/tAUb/6QFKABwBSwAcAC0AEf/kABX/5AAd/+QAH//kACn/7QAv/+0APf/kAD7/7QBB/+0Atf/tALr/5ADD/+0AxP/tAMX/7QDG/+0Ax//tAMj/7QDJ/+0Ayv/kAN3/5ADe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AQYBBwEIAQkBCgELAQwBDQEOAREBEwEVARYBFwEYARoBHgEgASIBJAEmAScBKAEpASoBNAE1ATcBOQE6ATwBPgE/AUABQQFFAUYBSAFKAUsBagFsAW4AAgBbAA8ADwAEABEAEQALABIAEgADABMAEwACABcAFwAGABoAGgAWAB0AHQADACAAIAASACIAIgAQACMAIwAKACcAJwARACgAKAAPACsAKwAJAC0ALQABAC4ALgAVADkAOQAXADsAOwAHADwAPAAOAD0APQAFAD4APgANAEEAQQANAEIAQgAMAEoASgATAEsASwAIAE0ATQATAE4ATgAIAFIAUgAIAIMAgwAIAIUAhQAIAJYAlgACALAAsAAWALUAtQABALYAtgADALoAugACALsAuwABALwAwgAEAMoAygALAMsAywAJAMwAzwACANAA0wABANQA1wAGAN0A4QADAOIA5QAKAOYA5gARAO0A8AAFAPEA8gANAPQA9AAHAPUA9QARAPYA9gAPAPcA9wAMAPgA+AADAQMBAwAEAQUBBQAEAQcBBwACAQgBCAABAQkBCQACAQoBCgABAQsBCwACAQwBDAABAQ0BDQACAQ4BDgABAREBEQAGARMBEwAGARUBFQALARYBFgAJARcBFwALARgBGAAJARoBGgAHAR4BHgAFASABIAAFASIBIgAFAScBJwAPASgBKAAMASkBKQAPASoBKgAMATQBNAAQATUBNQAUATcBNwAOAToBOgASATwBPAASAT4BPgADAT8BPwAVAUABQAADAUEBQQAUAUUBRQALAUYBRgAJAUgBSAAHAUoBSwAQAWoBagAHAWwBbAAOAW4BbgAOAAIAUgAPAA8ABAARABEAAgAVABUAAgAdAB0AAgAfAB8AAgAiACIADQAnACcADgAoACgADwApACkAAwArAC0AAQAvAC8ADAAxADEABgA2ADYACAA3ADcAAQA5ADkAAQA7ADsABwA8ADwACwA9AD0ABQA+AD4ACgBBAEEACgBCAEIACQCyALIAAQC1ALUAAwC2ALYAAQC6ALoAAgC7ALsAAQC8AMIABADDAMkAAwDKAMoAAgDLAMsAAQDQANMAAQDYANsABgDdAOEAAgDmAOYADgDnAOcACADoAOwAAQDtAPAABQDxAPIACgD0APQABwD1APUADgD2APYADwD3APcACQEDAQMABAEEAQQAAwEFAQUABAEGAQYAAwEIAQgAAQEKAQoAAQEMAQwAAQEOAQ4AAQESARIABgEUARQABgEVARUAAgEWARYAAQEXARcAAgEYARgAAQEaARoABwEcARwABQEeAR4ABQEgASAABQEiASIABQEkASQACAEmASYACAEoASgACQEqASoACQEtAS0AAgEuAS4ADAEvAS8AAgEwATEADAE0ATQADQE3ATcACwE5ATkACAE/AT8AAQFBAUEAAQFEAUUAAgFGAUYAAQFIAUgABwFKAUsADQFiAWIABgFqAWoABwFsAWwACwFuAW4ACwAEAAAAAQAIAAEADAA0AAQAtgEwAAIABgFMAU8AAAFRAVsABAFeAWEADwFjAWQAEwFmAWkAFQFvAXAAGQACABUADwAPAAAAEQATAAEAFQAXAAQAGQAaAAcAHAAdAAkAIAAjAAsAJwApAA8AKwAtABIALwAwABUAMwA3ABcAOgA9ABwAQQBCACAAvAD4ACIBAwETAF8BFQEhAHABIwErAH0BLQE+AIYBQAFLAJgBYgFiAKQBagFqAKUBbAFuAKYAGwAAC0IAAAtIAAALTgAAC1QAAAtaAAEAbgAAC2AAAgqEAAALWgAAC2AAAgqKAAALZgAAC2wAAAtyAAALeAAAC34AAAuEAAALigAAC5AAAAuWAAAMPAADAHQAAwB0AAALnAAAC6IAAAuoAAALrgABAAACmwABAJ0AAACpBwYAAAcMBxIF7AAACXwAAAVKAAAJOgAABzwAAAdOB1QJagAACIwAAAgUAAAIIAAAB6IAAAeoB64JUgAABVAAAAjUCNoI4AAACOwAAAg+AAAFVgdsB3IHeAVcAAAJFgAACZoAAAfSAAAJpgAACLwAAAgUCBoIIAgmCZoAAAfSAAAHPAAACGIAAAcYAAAHHgckBfgAAAmIAAAJQAlGCUwAAAdCAAAJiAdgCJ4AAAiYAAAFYgAAB64AAAleAAAFaAAACMIIyAjOAAAFbgAABXQAAAj4AAAISgAABXoHhAeKB5AFgAAACSIAAAnEAAAIbgAACuAJ1gjmAAAFhggCCAgIDgWMAAAG3AAABZIAAAhuAAAFmAAABwwHEgWeAAAHDAcSBaQAAAcMBxIFqgAABwwHEgWwAAAHDAcSBbYAAAcMBxIFvAAABwwHEgXCAAAHHgckBcgAAAceByQFzgAABx4HJAXUAAAHHgckBdoAAAceByQF4AAABx4HJAXmAAAHHgckBewAAAXyAAAF+AAABf4AAAYEAAAHTgdUCFAAAAdOB1QGCgAAB04HVAYQAAAHTgdUBtAAAAmIB2AGFgAACYgHYAYcAAAJiAdgBiIAAAmIB2AGKAAAB6gHrgYuAAAHqAeuBjQAAAeoB64GOgAAB6gHrgZAAAAJuAm+BkYAAAm4Cb4GTAAACbgJvgZSAAAJuAm+BlgAAAg+AAAGXgdsB3IHeAZkB2wHcgd4BmoHbAdyB3gGcAdsB3IHeAZ2B2wHcgd4BnwIGgggCCYGgggaCCAIJgaICBoIIAgmBo4IGgggCCYHzAAAB9IAAAaUAAAISgAABpoHhAeKB5AGoAeEB4oHkAamB4QHigeQBqwHhAeKB5AGsgeEB4oHkAa4CAIICAgOBr4IAggICA4GxAgCCAgIDgbKCAIICAgOBtAAAAbcAAAG1gAABtwAAAbiAAAH0gAABugAAAhuAAAG7gAAB9IAAAdIAAAIYgAABvQAAAhuAAAJKAAACS4AAAb6AAAHDAcSBwAAAAceByQHBgAABwwHEgcYAAAHHgckByoAAAdOB1QHMAAACYgHYAhcAAAHTgdUBzYAAAmIB2AHPAAAB04HVAdCAAAJiAdgB0gAAAdOB1QHWgAACYgHYAdmB2wHcgd4B34HhAeKB5AHlgAAB6gHrgecAAAJuAm+B6IAAAeoB64HtAAACXwAAAe6AAAJiAAAB8AAAAl8AAAHxgAACYgAAAfMAAAH0gAAB9gAAAhuAAAH3ggaCCAIJgfkCAIICAgOB+oIGgggCCYH8AgCCAgIDgf2CBoIIAgmB/wIAggICA4IFAgaCCAIJggsAAAIPgAACDIAAAhKAAAIOAAACD4AAAhEAAAISgAACFAAAAhiAAAIVgAACG4AAAhcAAAIYgAACGgAAAhuAAAIdAAACIwAAAh6AAAIjAAACIAAAAiYAAAIhgAACIwAAAiSAAAImAAACJ4AAAikAAAI1AjaCKoAAAjCCMgIsAAACLYAAAi8AAAIwgjICM4AAAjUCNoI4AAACuAJ1gjmAAAI7AAACPIAAAj4AAAI/gAACQQAAAkWAAAJCgAACSIAAAkQAAAJFgAACRwAAAkiAAAJKAAACS4AAAk0AAAJOgAACUAJRglMAAAJUgAACVgAAAleAAAJZAAACWoAAAlwAAAJdgAACXwAAAmCAAAJiAAACZoAAAmOAAAJxAAACZQAAAmaAAAJoAAACaYAAAmsAAAJpgAACawAAAmyAAAJuAm+CcQAAAnKAAAK4AnWCdAAAArgCdYJ3AAACuAJ1gncAAAAAQFHApwAAQE6AAAAAQFsApwAAQEvApwAAQERAxwAAQD7AAAAAQGlAfAAAQGlAAAAAQEUAfAAAQDHAfAAAQELAfAAAQDcAfAAAQDtAfAAAQE5A2MAAQE5A1UAAQE5A08AAQE5AxQAAQEWA2AAAQFVA2AAAQE5Az0AAQEHApwAAQDsAsMAAQEHArcAAQEHAqkAAQEHArkAAQEHAwkAAQEpAsMAAQFhApwAAQFg/0sAAQETAfAAAQES/0sAAQENA2AAAQEwA2MAAQEwA08AAQE7AsMAAQEZArcAAQEZArkAAQCsA2AAAQDrA2AAAQDPA2MAAQDPA08AAQBrAsMAAQCoAsMAAQCGArcAAQCGArkAAQFqA1UAAQFJA2AAAQGIA2AAAQFsA2MAAQFsA1UAAQFsA08AAQE2A2AAAQF1A2AAAQFZA2MAAQFZA08AAQEgAqkAAQD5AsMAAQE2AsMAAQEUArcAAQEUAqkAAQEUArkAAQDwAsMAAQEtAsMAAQELArcAAQELArkAAQD+AsMAAQDcArkAAQDXAAAAAQEqA10AAQDwArEAAQEqA08AAQDtArEAAQE5A10AAQEHArEAAQE5ApwAAQE5AAAAAQJnAAAAAQEHAfAAAQEHAAAAAQHbAAAAAQEwAz0AAQEZApwAAQEZAroAAQEwApwAAQEZAfAAAQEwA10AAQEcAAAAAQH6AAAAAQEZArEAAQFtAAAAAQGUA3AAAQLDApwAAQFsAAAAAQKOAAoAAQE8AsQAAQIUAfAAAQEUAAAAAQHxAAoAAQDPAz0AAQCGApwAAQDPApwAAQDPAAAAAQERAAAAAQF9A2AAAQE1AsMAAQFhA2YAAQETAroAAQFGA2AAAQEqAAAAAQESAsMAAQFZAz0AAQELApwAAQFZA0YAAQELAwkAAQGBA3AAAQEzAsQAAQIEAfAAAQEMAAAAAQHVAAAAAQFZApwAAQKeApwAAQFZAAAAAQGrAAAAAQGGA2AAAQFCAsMAAQFqA10AAQE3AAAAAQEgArEAAQEBAAAAAQFMA2AAAQEPAsMAAQEwA2YAAQEwAAAAAQDtAroAAQDmAAAAAQFjApwAAQFnA10AAQEMArEAAQFnA2YAAQFjAAAAAQEMAroAAQEY/wUAAQEMAfAAAQFFAwUAAQEn/wYAAQCH/wYAAQEXA10AAQEXAAAAAQB1AqgAAQCxApoAAQCRAAAAAQEOApwAAQEhApwAAQExAAAAAQC3AAAAAQFqApwAAQEt/wYAAQEgAfAAAQD3/wYAAQFLA2AAAQDpAsMAAQEvA10AAQE1AAAAAQDHArEAAQBxAAAAAQFuApwAAQF4AAAAAQFHA10AAQFRAAAAAQEaAxwAAQIJApoAAQEaAAAAAQE6ApwAAQEw/wYAAQD1AxwAAQDx/wYAAQFnApwAAQFZ/wYAAQFhA10AAQFcAAAAAQETArEAAQEOAAAAAQEu/0sAAQDq/0sAAQEqApwAAQEg/wYAAQEXApwAAQEN/wYAAQCGAfAAAQCLAAAAAQD6AAoAAQDwAfAAAQDc/wYAAQC7/0sAAQDcAtEAAQCt/wYABgAQAAEACgAAAAEADAAMAAEAFAAqAAEAAgFUAVcAAgAAAAoAAAAQAAEAWQAAAAEAWgAAAAIABgAMAAEAXf9LAAEAUP8GAAYAEAABAAoAAQABAAwADAABADwBCAABABYBTAFNAU4BTwFRAVMBVQFWAVgBWQFaAVsBXgFfAWABYQFjAWQBaAFpAW8BcAAWAAAAWgAAAGAAAABmAAAAbAAAAHIAAAB4AAAAcgAAAHgAAAB+AAAAhAAAAIoAAACQAAAAlgAAAJwAAACiAAAAqAAAAK4AAAFUAAAAtAAAALoAAADAAAAAxgABAC8B8AABADoCnAABAJMB8AABAJMCnAABAKIB8AABAKICnAABAKAB8AABAKACnAABADYB8AABADYCnAABAGwB8AABAHoCnAABAHIB8AABAHICnAABAIoB8AABAG0B8AABAG0CnAABAKUB8AABAKUCnAAWAHAALgA0ADoAQABGAEwAUgBYAF4AZABqAHAAdgB8AIIAiACOAJQAmgCgAKYAAQBWA2AAAQCTArEAAQCTA10AAQCiArEAAQCiA10AAQCiArcAAQCiA2MAAQCgArkAAQCgA08AAQA2AroAAQA2A2YAAQBRAsMAAQBXA2AAAQCaAsQAAQCaA3AAAQCKApwAAQCKAz0AAQBtAwkAAQBtA0YAAQClAqkAAQClA1UAAAABAAAACgBKALwAA0RGTFQAFGdyZWsAFGxhdG4AGAAOAAAACgABTU9MIAAgAAD//wAIAAAAAQACAAMABQAGAAcACAAA//8AAQAEAAlhYWx0ADhjYXNlAEBjY21wAEZmcmFjAE5sb2NsAFRvcmRuAFpwbnVtAGBzdXBzAGZ0bnVtAGwAAAACAAAAAQAAAAEADwAAAAIAAgAFAAAAAQAKAAAAAQAIAAAAAQALAAAAAQANAAAAAQAJAAAAAQAOABAAIgDEAPICQgJCAogD4APgAtIC9AMUA1ADjgOwA8gD4AABAAAAAQAIAAIATgAkAPkA/gD/AQABAQECAFcAZgBXAGYABQAGAAcACAAJAAoACwAMAA0ADgFJAWoBSwFNAU8BUwFWAVkBWwFfAWEBZAFnAWkBbgFwAAEAJAAFAAoACwAMAA0ADgAPAB0AKQA3APkA+gD7APwA/QD+AP8BAAEBAQIBRwFIAUoBTAFOAVEBVQFYAVoBXgFgAWMBZgFoAW0BbwADAAAAAQAIAAECPgAEAA4AFAAaACAAAgBlAPoAAgBeAPsAAgBfAPwAAgD9AV0ABgAAAAQADgAgAFwAbgADAAAAAQAmAAEANAABAAAAAwADAAAAAQAUAAIAGgAiAAEAAAAEAAEAAQAxAAEAAgFUAWYAAQALAUwBTgFRAVUBWAFaAV4BYAFjAWgBbwADAAECuAABArgAAAABAAAAAwADAAEAEgABAqYAAAABAAAABAABAGYADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoAJYApACnALAAswC0ALoAvAC9AL4AvwDAAMEAwgDKAMwAzQDOAM8A1ADVANYA1wDcAN0A3gDfAOAA4QDiAOMA5ADlAOYA8wD1APYA+AEDAQUBBwEJAQsBDQEPAREBEwEVARcBGQEbAR0BHwEhASMBJQEnASkBKwEtAS8BMgE0ATYBOAE6ATwBPgFAAUIBRAFFAUcBSQFKAUsAAQAAAAEACAACACAADQFiAU0BTwFTAVYBWQFbAV8BYQFkAWcBaQFwAAEADQAxAUwBTgFRAVUBWAFaAV4BYAFjAWYBaAFvAAYAAAACAAoAHAADAAAAAQF0AAEAJAABAAAABgADAAEAEgABAWIAAAABAAAABwABAAwBTQFPAVMBVgFZAVsBXwFhAWQBZwFpAXAAAQAAAAEACAACAA4ABAFJAWoBSwFuAAEABAFHAUgBSgFtAAEAAAABAAgAAgAOAAQAZQBeAF8BXQACAAEABgAJAAAABAAAAAEACAABACwAAgAKACAAAgAGAA4AaAADAIYACQBpAAMAhgAHAAEABABqAAMAhgAJAAEAAgAGAAgABgAAAAIACgAkAAMAAQB8AAEAEgAAAAEAAAAMAAEAAgAPACkAAwABAGIAAQASAAAAAQAAAAwAAQACAB0ANwABAAAAAQAIAAIADgAEAFcAZgBXAGYAAQAEAA8AHQApADcAAQAAAAEACAABAAb/DAACAAEA+QECAAAAAQAAAAEACAABAAYA9AACAAEABQAOAAAAAQAAAAEACAACAB4ADAFNAU8BUwFWAVkBWwFfAWEBZAFnAWkBcAABAAwBTAFOAVEBVQFYAVoBXgFgAWMBZgFoAW8AAAAAAAEAAAAA");
|
|
19860
|
+
|
|
19861
|
+
// src/font.ts
|
|
19862
|
+
var BUILTIN_FONT = "Atkinson";
|
|
19863
|
+
function withBuiltinFont(fonts) {
|
|
19864
|
+
return BUILTIN_FONT in fonts ? fonts : { ...fonts, [BUILTIN_FONT]: AtkinsonHyperlegible_Regular_default };
|
|
19865
|
+
}
|
|
19866
|
+
|
|
19233
19867
|
// src/cli.ts
|
|
19234
19868
|
var HELP = `kerf ${VERSION}: the KerfScript laser cutting language
|
|
19235
19869
|
|
|
@@ -19242,7 +19876,8 @@ Options:
|
|
|
19242
19876
|
-o, --out <file> output file (.svg, .dxf or .json); default <file>.svg
|
|
19243
19877
|
-D name=value set a parameter (value is KerfScript: 40, "Oak", true, [1,2])
|
|
19244
19878
|
-p, --params <file> JSON file of parameter values
|
|
19245
|
-
--font <file.ttf> font for text(); repeat for more fonts (name = file name)
|
|
19879
|
+
--font <file.ttf> font for text(); repeat for more fonts (name = file name).
|
|
19880
|
+
Built in: ${BUILTIN_FONT}
|
|
19246
19881
|
--kerf <mm> override kerf compensation for all parts
|
|
19247
19882
|
--sheet <W>x<H> sheet size for packing, in mm
|
|
19248
19883
|
--gap <mm> space between packed parts
|
|
@@ -19257,8 +19892,8 @@ function fail(msg) {
|
|
|
19257
19892
|
process.stderr.write(msg + "\n");
|
|
19258
19893
|
process.exit(1);
|
|
19259
19894
|
}
|
|
19260
|
-
function parseValue(
|
|
19261
|
-
const { program } = parse(`__v = ${
|
|
19895
|
+
function parseValue(text2) {
|
|
19896
|
+
const { program } = parse(`__v = ${text2};`);
|
|
19262
19897
|
const ev = new Evaluator();
|
|
19263
19898
|
const res = ev.run(program);
|
|
19264
19899
|
return res.globals.get("__v").value;
|
|
@@ -19332,7 +19967,7 @@ function main(argv) {
|
|
|
19332
19967
|
const result = render(source, {
|
|
19333
19968
|
...opts,
|
|
19334
19969
|
params,
|
|
19335
|
-
fonts:
|
|
19970
|
+
fonts: withBuiltinFont(fonts),
|
|
19336
19971
|
resolve: resolveLib
|
|
19337
19972
|
});
|
|
19338
19973
|
for (const e of result.echoes) process.stderr.write(`ECHO: ${e}
|