@sarmal/core 0.30.0 → 0.33.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/dist/auto-init.cjs +115 -31
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +115 -31
- package/dist/auto-init.js.map +1 -1
- package/dist/cli.js +8 -7
- package/dist/cli.js.map +1 -1
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/index.d.cts +1 -1
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/index.cjs +122 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +122 -34
- package/dist/index.js.map +1 -1
- package/dist/{renderer-shared-OR--cv-t.d.ts → renderer-shared-Bdca4O4G.d.ts} +8 -4
- package/dist/{renderer-shared-jqw_Q1WO.d.cts → renderer-shared-Ke9BeK1P.d.cts} +8 -4
- package/dist/terminal.cjs +8 -7
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +2 -2
- package/dist/terminal.d.ts +2 -2
- package/dist/terminal.js +8 -7
- package/dist/terminal.js.map +1 -1
- package/dist/{types-zbxUgcmZ.d.cts → types-BBuUk6nn.d.cts} +9 -0
- package/dist/{types-zbxUgcmZ.d.ts → types-BBuUk6nn.d.ts} +9 -0
- package/package.json +1 -1
package/dist/auto-init.cjs
CHANGED
|
@@ -406,6 +406,49 @@ function parseColorToRgb(s) {
|
|
|
406
406
|
}
|
|
407
407
|
return null;
|
|
408
408
|
}
|
|
409
|
+
var OKLCH_RE = /^oklch\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*[\d.]+)?\s*\)$/i;
|
|
410
|
+
function parseOklchToOklab(s) {
|
|
411
|
+
const m = OKLCH_RE.exec(s.trim());
|
|
412
|
+
if (!m) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
const L = parseFloat(m[1]);
|
|
416
|
+
const C = parseFloat(m[2]);
|
|
417
|
+
const H = parseFloat(m[3]);
|
|
418
|
+
if (Number.isNaN(L) || Number.isNaN(C) || Number.isNaN(H)) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const clampedL = Math.max(0, Math.min(1, L));
|
|
422
|
+
const clampedC = Math.max(0, Math.min(0.4, C));
|
|
423
|
+
const H_rad = H * (Math.PI / 180);
|
|
424
|
+
return {
|
|
425
|
+
L: clampedL,
|
|
426
|
+
a: clampedC * Math.cos(H_rad),
|
|
427
|
+
b: clampedC * Math.sin(H_rad)
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function parseColorToOklab(s) {
|
|
431
|
+
const oklab = parseOklchToOklab(s);
|
|
432
|
+
if (oklab !== null) {
|
|
433
|
+
return oklab;
|
|
434
|
+
}
|
|
435
|
+
const rgb = parseColorToRgb(s);
|
|
436
|
+
if (rgb === null) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
return rgbToOklab(rgb);
|
|
440
|
+
}
|
|
441
|
+
function colorToRgb(color) {
|
|
442
|
+
const rgb = parseColorToRgb(color);
|
|
443
|
+
if (rgb !== null) {
|
|
444
|
+
return rgb;
|
|
445
|
+
}
|
|
446
|
+
const lab = parseOklchToOklab(color);
|
|
447
|
+
if (lab !== null) {
|
|
448
|
+
return oklabToRgb(lab);
|
|
449
|
+
}
|
|
450
|
+
throw new Error(`[sarmal] unrecognized color "${color}"`);
|
|
451
|
+
}
|
|
409
452
|
function srgbByteToLinear(c) {
|
|
410
453
|
const n = c / 255;
|
|
411
454
|
return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
|
|
@@ -443,26 +486,25 @@ var lerpOklab = (a, b, t) => {
|
|
|
443
486
|
if (t >= 1) {
|
|
444
487
|
return b;
|
|
445
488
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
});
|
|
489
|
+
return {
|
|
490
|
+
L: a.L + (b.L - a.L) * t,
|
|
491
|
+
a: a.a + (b.a - a.a) * t,
|
|
492
|
+
b: a.b + (b.b - a.b) * t
|
|
493
|
+
};
|
|
452
494
|
};
|
|
453
495
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
454
496
|
if (palette.length === 0) {
|
|
455
|
-
return {
|
|
497
|
+
return { L: 1, a: 0, b: 0 };
|
|
456
498
|
}
|
|
457
499
|
if (palette.length === 1) {
|
|
458
|
-
return
|
|
500
|
+
return palette[0];
|
|
459
501
|
}
|
|
460
502
|
const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
|
|
461
503
|
const scaled = cyclePos * palette.length;
|
|
462
504
|
const idx = Math.floor(scaled);
|
|
463
505
|
const t = scaled - idx;
|
|
464
|
-
const c1 =
|
|
465
|
-
const c2 =
|
|
506
|
+
const c1 = palette[idx % palette.length];
|
|
507
|
+
const c2 = palette[(idx + 1) % palette.length];
|
|
466
508
|
return lerpOklab(c1, c2, t);
|
|
467
509
|
}
|
|
468
510
|
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
@@ -471,7 +513,8 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
471
513
|
"headColor",
|
|
472
514
|
"skeletonColor",
|
|
473
515
|
"trailStyle",
|
|
474
|
-
"headRadius"
|
|
516
|
+
"headRadius",
|
|
517
|
+
"trailWidth"
|
|
475
518
|
]);
|
|
476
519
|
function validateRenderOptions(partial) {
|
|
477
520
|
for (const key of Object.keys(partial)) {
|
|
@@ -494,12 +537,15 @@ function validateRenderOptions(partial) {
|
|
|
494
537
|
if (partial.headRadius !== void 0) {
|
|
495
538
|
assertHeadRadius(partial.headRadius);
|
|
496
539
|
}
|
|
540
|
+
if (partial.trailWidth !== void 0) {
|
|
541
|
+
assertTrailWidth(partial.trailWidth);
|
|
542
|
+
}
|
|
497
543
|
}
|
|
498
544
|
function assertTrailColor(value) {
|
|
499
545
|
if (typeof value === "string") {
|
|
500
|
-
if (
|
|
546
|
+
if (parseColorToOklab(value) === null) {
|
|
501
547
|
throw new TypeError(
|
|
502
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got "${value}"`
|
|
548
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got "${value}"`
|
|
503
549
|
);
|
|
504
550
|
}
|
|
505
551
|
return;
|
|
@@ -512,25 +558,25 @@ function assertTrailColor(value) {
|
|
|
512
558
|
}
|
|
513
559
|
for (let i = 0; i < value.length; i++) {
|
|
514
560
|
const entry = value[i];
|
|
515
|
-
if (typeof entry !== "string" ||
|
|
561
|
+
if (typeof entry !== "string" || parseColorToOklab(entry) === null) {
|
|
516
562
|
throw new TypeError(
|
|
517
|
-
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got ${JSON.stringify(entry)}`
|
|
563
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got ${JSON.stringify(entry)}`
|
|
518
564
|
);
|
|
519
565
|
}
|
|
520
566
|
}
|
|
521
567
|
return;
|
|
522
568
|
}
|
|
523
569
|
throw new TypeError(
|
|
524
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
570
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
525
571
|
);
|
|
526
572
|
}
|
|
527
573
|
function assertHeadColor(value) {
|
|
528
574
|
if (value === null) {
|
|
529
575
|
return;
|
|
530
576
|
}
|
|
531
|
-
if (typeof value !== "string" ||
|
|
577
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
532
578
|
throw new TypeError(
|
|
533
|
-
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or null, got ${JSON.stringify(value)}`
|
|
579
|
+
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or null, got ${JSON.stringify(value)}`
|
|
534
580
|
);
|
|
535
581
|
}
|
|
536
582
|
}
|
|
@@ -538,9 +584,9 @@ function assertSkeletonColor(value) {
|
|
|
538
584
|
if (value === "transparent") {
|
|
539
585
|
return;
|
|
540
586
|
}
|
|
541
|
-
if (typeof value !== "string" ||
|
|
587
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
542
588
|
throw new TypeError(
|
|
543
|
-
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or "transparent", got ${JSON.stringify(value)}`
|
|
589
|
+
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or "transparent", got ${JSON.stringify(value)}`
|
|
544
590
|
);
|
|
545
591
|
}
|
|
546
592
|
}
|
|
@@ -563,6 +609,18 @@ function assertHeadRadius(value) {
|
|
|
563
609
|
);
|
|
564
610
|
}
|
|
565
611
|
}
|
|
612
|
+
function assertTrailWidth(value) {
|
|
613
|
+
if (typeof value !== "number") {
|
|
614
|
+
throw new TypeError(
|
|
615
|
+
`[sarmal] setRenderOptions: trailWidth must be a number, got ${JSON.stringify(value)}`
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
619
|
+
throw new TypeError(
|
|
620
|
+
`[sarmal] setRenderOptions: trailWidth must be a finite positive number, got ${value}`
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
566
624
|
function resolveTrailMainColor(trailColor) {
|
|
567
625
|
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
568
626
|
}
|
|
@@ -575,7 +633,7 @@ function resolveHeadColor(trailColor, trailStyle) {
|
|
|
575
633
|
}
|
|
576
634
|
const palette = resolveTrailPalette(trailColor);
|
|
577
635
|
const last = palette[palette.length - 1];
|
|
578
|
-
const { r, g, b } =
|
|
636
|
+
const { r, g, b } = colorToRgb(last);
|
|
579
637
|
return `rgb(${r},${g},${b})`;
|
|
580
638
|
}
|
|
581
639
|
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
@@ -596,8 +654,8 @@ function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
|
596
654
|
var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));
|
|
597
655
|
var WHITE_HEX = "#ffffff";
|
|
598
656
|
function colorToRgbComponents(color) {
|
|
599
|
-
const
|
|
600
|
-
return `${
|
|
657
|
+
const { r, g, b } = colorToRgb(color);
|
|
658
|
+
return `${r},${g},${b}`;
|
|
601
659
|
}
|
|
602
660
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
603
661
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -619,6 +677,7 @@ function createRenderer(options) {
|
|
|
619
677
|
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
620
678
|
let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
621
679
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
680
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
622
681
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
623
682
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
624
683
|
function setupCanvas() {
|
|
@@ -630,7 +689,14 @@ function createRenderer(options) {
|
|
|
630
689
|
setupCanvas();
|
|
631
690
|
let logicalWidth = canvas.width / dpr;
|
|
632
691
|
let logicalHeight = canvas.height / dpr;
|
|
692
|
+
if (options.headRadius !== void 0) {
|
|
693
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
694
|
+
}
|
|
695
|
+
if (options.trailWidth !== void 0) {
|
|
696
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
697
|
+
}
|
|
633
698
|
let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);
|
|
699
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
634
700
|
let skeleton = [];
|
|
635
701
|
let skeletonCanvas = null;
|
|
636
702
|
let trail = [];
|
|
@@ -724,14 +790,16 @@ function createRenderer(options) {
|
|
|
724
790
|
i,
|
|
725
791
|
trailCount,
|
|
726
792
|
toX,
|
|
727
|
-
toY
|
|
793
|
+
toY,
|
|
794
|
+
TRAIL_MIN_WIDTH * trailWidth,
|
|
795
|
+
TRAIL_MAX_WIDTH * trailWidth
|
|
728
796
|
);
|
|
729
797
|
if (trailStyle === "default") {
|
|
730
798
|
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
731
799
|
} else {
|
|
732
800
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
733
|
-
const
|
|
734
|
-
ctx.fillStyle = `rgba(${
|
|
801
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
802
|
+
ctx.fillStyle = `rgba(${r},${g},${b},${opacity})`;
|
|
735
803
|
}
|
|
736
804
|
ctx.beginPath();
|
|
737
805
|
ctx.moveTo(l0x, l0y);
|
|
@@ -865,6 +933,7 @@ function createRenderer(options) {
|
|
|
865
933
|
trailColor = partial.trailColor;
|
|
866
934
|
trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
867
935
|
trailPalette = resolveTrailPalette(trailColor);
|
|
936
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
868
937
|
}
|
|
869
938
|
if (partial.skeletonColor !== void 0) {
|
|
870
939
|
skeletonColor = partial.skeletonColor;
|
|
@@ -881,6 +950,9 @@ function createRenderer(options) {
|
|
|
881
950
|
if (partial.headRadius !== void 0) {
|
|
882
951
|
headRadius = partial.headRadius;
|
|
883
952
|
}
|
|
953
|
+
if (partial.trailWidth !== void 0) {
|
|
954
|
+
trailWidth = partial.trailWidth;
|
|
955
|
+
}
|
|
884
956
|
if (userHeadColor === null) {
|
|
885
957
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
886
958
|
} else {
|
|
@@ -948,8 +1020,8 @@ function el(tag) {
|
|
|
948
1020
|
return document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
949
1021
|
}
|
|
950
1022
|
function colorToRgbAttr(color) {
|
|
951
|
-
const
|
|
952
|
-
return `rgb(${
|
|
1023
|
+
const { r, g, b } = colorToRgb(color);
|
|
1024
|
+
return `rgb(${r},${g},${b})`;
|
|
953
1025
|
}
|
|
954
1026
|
function createSVGRenderer(options) {
|
|
955
1027
|
const { container, engine } = options;
|
|
@@ -967,6 +1039,7 @@ function createSVGRenderer(options) {
|
|
|
967
1039
|
let headRadius;
|
|
968
1040
|
let trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
969
1041
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
1042
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
970
1043
|
const ariaLabel = options.ariaLabel ?? "Loading";
|
|
971
1044
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
972
1045
|
const viewSize = 100;
|
|
@@ -978,7 +1051,14 @@ function createSVGRenderer(options) {
|
|
|
978
1051
|
const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
|
|
979
1052
|
const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
|
|
980
1053
|
const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
|
|
1054
|
+
if (options.headRadius !== void 0) {
|
|
1055
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
1056
|
+
}
|
|
1057
|
+
if (options.trailWidth !== void 0) {
|
|
1058
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
1059
|
+
}
|
|
981
1060
|
headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
|
|
1061
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
982
1062
|
container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
|
|
983
1063
|
container.setAttribute("role", "img");
|
|
984
1064
|
container.setAttribute("aria-label", ariaLabel);
|
|
@@ -1073,15 +1153,15 @@ function createSVGRenderer(options) {
|
|
|
1073
1153
|
trailCount,
|
|
1074
1154
|
px,
|
|
1075
1155
|
py,
|
|
1076
|
-
svgTrailMinWidth,
|
|
1077
|
-
svgTrailMaxWidth
|
|
1156
|
+
svgTrailMinWidth * trailWidth,
|
|
1157
|
+
svgTrailMaxWidth * trailWidth
|
|
1078
1158
|
);
|
|
1079
1159
|
const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;
|
|
1080
1160
|
trailPaths[i].setAttribute("d", d);
|
|
1081
1161
|
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
1082
1162
|
if (trailStyle !== "default") {
|
|
1083
1163
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
1084
|
-
const { r, g, b } = getPaletteColor(
|
|
1164
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
1085
1165
|
trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
|
|
1086
1166
|
}
|
|
1087
1167
|
}
|
|
@@ -1233,6 +1313,7 @@ function createSVGRenderer(options) {
|
|
|
1233
1313
|
trailColor = partial.trailColor;
|
|
1234
1314
|
trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
1235
1315
|
trailPalette = resolveTrailPalette(trailColor);
|
|
1316
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
1236
1317
|
if (trailStyle === "default") {
|
|
1237
1318
|
for (const p of trailPaths) {
|
|
1238
1319
|
p.setAttribute("fill", trailSolid);
|
|
@@ -1265,6 +1346,9 @@ function createSVGRenderer(options) {
|
|
|
1265
1346
|
headRadius = partial.headRadius;
|
|
1266
1347
|
headCircle.setAttribute("r", String(headRadius));
|
|
1267
1348
|
}
|
|
1349
|
+
if (partial.trailWidth !== void 0) {
|
|
1350
|
+
trailWidth = partial.trailWidth;
|
|
1351
|
+
}
|
|
1268
1352
|
if (userHeadColor === null) {
|
|
1269
1353
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
1270
1354
|
} else {
|