@almadar/ui 5.156.0 → 5.157.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.
@@ -15511,6 +15511,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
15511
15511
  case "path": {
15512
15512
  if (!shape.path) break;
15513
15513
  const p = new Path2D(shape.path);
15514
+ ctx.lineJoin = "round";
15515
+ ctx.lineCap = "round";
15514
15516
  if (fill) {
15515
15517
  ctx.fillStyle = fill;
15516
15518
  ctx.fill(p);
@@ -15719,7 +15721,7 @@ var init_LearningCanvas = __esm({
15719
15721
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
15720
15722
  ctx.clearRect(0, 0, width, height);
15721
15723
  if (backgroundColor) {
15722
- ctx.fillStyle = backgroundColor;
15724
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
15723
15725
  ctx.fillRect(0, 0, width, height);
15724
15726
  }
15725
15727
  for (const shape of derivedShapes) {
@@ -32845,6 +32847,9 @@ var init_MathCanvas = __esm({
32845
32847
  showAxes = true,
32846
32848
  showGrid = true,
32847
32849
  gridStep = 1,
32850
+ backgroundColor,
32851
+ gridColor = "var(--color-border, #9ca3af)",
32852
+ axisColor = "var(--color-muted-foreground, #374151)",
32848
32853
  showTickLabels = false,
32849
32854
  showCurveLabels = false,
32850
32855
  curves = [],
@@ -32899,11 +32904,11 @@ var init_MathCanvas = __esm({
32899
32904
  if (showGrid) {
32900
32905
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
32901
32906
  const px = mapX(x);
32902
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
32907
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
32903
32908
  }
32904
32909
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
32905
32910
  const py = mapY(y);
32906
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
32911
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
32907
32912
  }
32908
32913
  }
32909
32914
  if (showTickLabels) {
@@ -32974,8 +32979,8 @@ var init_MathCanvas = __esm({
32974
32979
  });
32975
32980
  }
32976
32981
  if (showAxes) {
32977
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
32978
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
32982
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
32983
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
32979
32984
  }
32980
32985
  for (const guide of guides) {
32981
32986
  const color = guide.color ?? "#9ca3af";
@@ -32998,23 +33003,36 @@ var init_MathCanvas = __esm({
32998
33003
  }
32999
33004
  for (const curve of curves) {
33000
33005
  if (!curve.samples || curve.samples.length < 2) continue;
33006
+ let d = "";
33007
+ let penDown = false;
33001
33008
  let lastInRange;
33002
33009
  for (let i = 1; i < curve.samples.length; i++) {
33003
33010
  const a = curve.samples[i - 1];
33004
33011
  const b = curve.samples[i];
33005
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
33006
- out.push({
33007
- type: "line",
33008
- x1: mapX(a.x),
33009
- y1: mapY(a.y),
33010
- x2: mapX(b.x),
33011
- y2: mapY(b.y),
33012
- color: curve.color ?? "#2563eb",
33013
- lineWidth: 2,
33014
- dash: curve.dash
33015
- });
33016
- lastInRange = b;
33017
- }
33012
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
33013
+ penDown = false;
33014
+ continue;
33015
+ }
33016
+ const clip = (p, q, xLim) => {
33017
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
33018
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
33019
+ };
33020
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
33021
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
33022
+ const pax = mapX(ca.x);
33023
+ const pay = mapY(ca.y);
33024
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
33025
+ penDown = true;
33026
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
33027
+ }
33028
+ if (!d) continue;
33029
+ out.push({
33030
+ type: "path",
33031
+ path: d,
33032
+ color: curve.color ?? "#2563eb",
33033
+ lineWidth: 2,
33034
+ dash: curve.dash
33035
+ });
33018
33036
  if (showCurveLabels && curve.label && lastInRange) {
33019
33037
  out.push({
33020
33038
  type: "text",
@@ -33129,6 +33147,8 @@ var init_MathCanvas = __esm({
33129
33147
  showAxes,
33130
33148
  showGrid,
33131
33149
  gridStep,
33150
+ gridColor,
33151
+ axisColor,
33132
33152
  showTickLabels,
33133
33153
  showCurveLabels,
33134
33154
  curves,
@@ -33148,6 +33168,7 @@ var init_MathCanvas = __esm({
33148
33168
  {
33149
33169
  width,
33150
33170
  height,
33171
+ backgroundColor,
33151
33172
  shapes: derivedShapes,
33152
33173
  readouts,
33153
33174
  traces,
package/dist/avl/index.js CHANGED
@@ -15435,6 +15435,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
15435
15435
  case "path": {
15436
15436
  if (!shape.path) break;
15437
15437
  const p = new Path2D(shape.path);
15438
+ ctx.lineJoin = "round";
15439
+ ctx.lineCap = "round";
15438
15440
  if (fill) {
15439
15441
  ctx.fillStyle = fill;
15440
15442
  ctx.fill(p);
@@ -15643,7 +15645,7 @@ var init_LearningCanvas = __esm({
15643
15645
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
15644
15646
  ctx.clearRect(0, 0, width, height);
15645
15647
  if (backgroundColor) {
15646
- ctx.fillStyle = backgroundColor;
15648
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
15647
15649
  ctx.fillRect(0, 0, width, height);
15648
15650
  }
15649
15651
  for (const shape of derivedShapes) {
@@ -32769,6 +32771,9 @@ var init_MathCanvas = __esm({
32769
32771
  showAxes = true,
32770
32772
  showGrid = true,
32771
32773
  gridStep = 1,
32774
+ backgroundColor,
32775
+ gridColor = "var(--color-border, #9ca3af)",
32776
+ axisColor = "var(--color-muted-foreground, #374151)",
32772
32777
  showTickLabels = false,
32773
32778
  showCurveLabels = false,
32774
32779
  curves = [],
@@ -32823,11 +32828,11 @@ var init_MathCanvas = __esm({
32823
32828
  if (showGrid) {
32824
32829
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
32825
32830
  const px = mapX(x);
32826
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
32831
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
32827
32832
  }
32828
32833
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
32829
32834
  const py = mapY(y);
32830
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
32835
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
32831
32836
  }
32832
32837
  }
32833
32838
  if (showTickLabels) {
@@ -32898,8 +32903,8 @@ var init_MathCanvas = __esm({
32898
32903
  });
32899
32904
  }
32900
32905
  if (showAxes) {
32901
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
32902
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
32906
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
32907
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
32903
32908
  }
32904
32909
  for (const guide of guides) {
32905
32910
  const color = guide.color ?? "#9ca3af";
@@ -32922,23 +32927,36 @@ var init_MathCanvas = __esm({
32922
32927
  }
32923
32928
  for (const curve of curves) {
32924
32929
  if (!curve.samples || curve.samples.length < 2) continue;
32930
+ let d = "";
32931
+ let penDown = false;
32925
32932
  let lastInRange;
32926
32933
  for (let i = 1; i < curve.samples.length; i++) {
32927
32934
  const a = curve.samples[i - 1];
32928
32935
  const b = curve.samples[i];
32929
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
32930
- out.push({
32931
- type: "line",
32932
- x1: mapX(a.x),
32933
- y1: mapY(a.y),
32934
- x2: mapX(b.x),
32935
- y2: mapY(b.y),
32936
- color: curve.color ?? "#2563eb",
32937
- lineWidth: 2,
32938
- dash: curve.dash
32939
- });
32940
- lastInRange = b;
32941
- }
32936
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
32937
+ penDown = false;
32938
+ continue;
32939
+ }
32940
+ const clip = (p, q, xLim) => {
32941
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
32942
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
32943
+ };
32944
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
32945
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
32946
+ const pax = mapX(ca.x);
32947
+ const pay = mapY(ca.y);
32948
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
32949
+ penDown = true;
32950
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
32951
+ }
32952
+ if (!d) continue;
32953
+ out.push({
32954
+ type: "path",
32955
+ path: d,
32956
+ color: curve.color ?? "#2563eb",
32957
+ lineWidth: 2,
32958
+ dash: curve.dash
32959
+ });
32942
32960
  if (showCurveLabels && curve.label && lastInRange) {
32943
32961
  out.push({
32944
32962
  type: "text",
@@ -33053,6 +33071,8 @@ var init_MathCanvas = __esm({
33053
33071
  showAxes,
33054
33072
  showGrid,
33055
33073
  gridStep,
33074
+ gridColor,
33075
+ axisColor,
33056
33076
  showTickLabels,
33057
33077
  showCurveLabels,
33058
33078
  curves,
@@ -33072,6 +33092,7 @@ var init_MathCanvas = __esm({
33072
33092
  {
33073
33093
  width,
33074
33094
  height,
33095
+ backgroundColor,
33075
33096
  shapes: derivedShapes,
33076
33097
  readouts,
33077
33098
  traces,
@@ -8689,6 +8689,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
8689
8689
  case "path": {
8690
8690
  if (!shape.path) break;
8691
8691
  const p = new Path2D(shape.path);
8692
+ ctx.lineJoin = "round";
8693
+ ctx.lineCap = "round";
8692
8694
  if (fill) {
8693
8695
  ctx.fillStyle = fill;
8694
8696
  ctx.fill(p);
@@ -8897,7 +8899,7 @@ var init_LearningCanvas = __esm({
8897
8899
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
8898
8900
  ctx.clearRect(0, 0, width, height);
8899
8901
  if (backgroundColor) {
8900
- ctx.fillStyle = backgroundColor;
8902
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
8901
8903
  ctx.fillRect(0, 0, width, height);
8902
8904
  }
8903
8905
  for (const shape of derivedShapes) {
@@ -25510,6 +25512,7 @@ function currentValue(decl, override) {
25510
25512
  function TextLikeControl({
25511
25513
  field,
25512
25514
  numeric,
25515
+ secret,
25513
25516
  value,
25514
25517
  onCommit
25515
25518
  }) {
@@ -25527,7 +25530,7 @@ function TextLikeControl({
25527
25530
  return /* @__PURE__ */ jsxRuntime.jsx(
25528
25531
  exports.Input,
25529
25532
  {
25530
- inputType: numeric ? "number" : "text",
25533
+ inputType: secret ? "password" : numeric ? "number" : "text",
25531
25534
  value: draft,
25532
25535
  onChange: (e) => setDraft(e.target.value),
25533
25536
  onBlur: commit,
@@ -25588,6 +25591,8 @@ function FieldControl({
25588
25591
  );
25589
25592
  } else if (decl.type === "number") {
25590
25593
  control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
25594
+ } else if (core.isSecretConfigType(decl.type)) {
25595
+ control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, secret: true, value, onCommit: onChange });
25591
25596
  } else if (decl.type === "string") {
25592
25597
  control = /* @__PURE__ */ jsxRuntime.jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
25593
25598
  } else if (decl.type === "node") {
@@ -25627,7 +25632,7 @@ var init_PropertyInspector = __esm({
25627
25632
  init_JsonTreeEditor();
25628
25633
  init_NodeSlotEditor();
25629
25634
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
25630
- SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset"]);
25635
+ SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset", "secret"]);
25631
25636
  exports.PropertyInspector = ({
25632
25637
  config,
25633
25638
  values,
@@ -31615,6 +31620,9 @@ var init_MathCanvas = __esm({
31615
31620
  showAxes = true,
31616
31621
  showGrid = true,
31617
31622
  gridStep = 1,
31623
+ backgroundColor,
31624
+ gridColor = "var(--color-border, #9ca3af)",
31625
+ axisColor = "var(--color-muted-foreground, #374151)",
31618
31626
  showTickLabels = false,
31619
31627
  showCurveLabels = false,
31620
31628
  curves = [],
@@ -31669,11 +31677,11 @@ var init_MathCanvas = __esm({
31669
31677
  if (showGrid) {
31670
31678
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
31671
31679
  const px = mapX(x);
31672
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
31680
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
31673
31681
  }
31674
31682
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
31675
31683
  const py = mapY(y);
31676
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
31684
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
31677
31685
  }
31678
31686
  }
31679
31687
  if (showTickLabels) {
@@ -31744,8 +31752,8 @@ var init_MathCanvas = __esm({
31744
31752
  });
31745
31753
  }
31746
31754
  if (showAxes) {
31747
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
31748
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
31755
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
31756
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
31749
31757
  }
31750
31758
  for (const guide of guides) {
31751
31759
  const color = guide.color ?? "#9ca3af";
@@ -31768,23 +31776,36 @@ var init_MathCanvas = __esm({
31768
31776
  }
31769
31777
  for (const curve of curves) {
31770
31778
  if (!curve.samples || curve.samples.length < 2) continue;
31779
+ let d = "";
31780
+ let penDown = false;
31771
31781
  let lastInRange;
31772
31782
  for (let i = 1; i < curve.samples.length; i++) {
31773
31783
  const a = curve.samples[i - 1];
31774
31784
  const b = curve.samples[i];
31775
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
31776
- out.push({
31777
- type: "line",
31778
- x1: mapX(a.x),
31779
- y1: mapY(a.y),
31780
- x2: mapX(b.x),
31781
- y2: mapY(b.y),
31782
- color: curve.color ?? "#2563eb",
31783
- lineWidth: 2,
31784
- dash: curve.dash
31785
- });
31786
- lastInRange = b;
31787
- }
31785
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
31786
+ penDown = false;
31787
+ continue;
31788
+ }
31789
+ const clip = (p, q, xLim) => {
31790
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
31791
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
31792
+ };
31793
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
31794
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
31795
+ const pax = mapX(ca.x);
31796
+ const pay = mapY(ca.y);
31797
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
31798
+ penDown = true;
31799
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
31800
+ }
31801
+ if (!d) continue;
31802
+ out.push({
31803
+ type: "path",
31804
+ path: d,
31805
+ color: curve.color ?? "#2563eb",
31806
+ lineWidth: 2,
31807
+ dash: curve.dash
31808
+ });
31788
31809
  if (showCurveLabels && curve.label && lastInRange) {
31789
31810
  out.push({
31790
31811
  type: "text",
@@ -31899,6 +31920,8 @@ var init_MathCanvas = __esm({
31899
31920
  showAxes,
31900
31921
  showGrid,
31901
31922
  gridStep,
31923
+ gridColor,
31924
+ axisColor,
31902
31925
  showTickLabels,
31903
31926
  showCurveLabels,
31904
31927
  curves,
@@ -31918,6 +31941,7 @@ var init_MathCanvas = __esm({
31918
31941
  {
31919
31942
  width,
31920
31943
  height,
31944
+ backgroundColor,
31921
31945
  shapes: derivedShapes,
31922
31946
  readouts,
31923
31947
  traces,
@@ -6118,6 +6118,12 @@ interface MathCanvasProps {
6118
6118
  showAxes?: boolean;
6119
6119
  showGrid?: boolean;
6120
6120
  gridStep?: number;
6121
+ /** Canvas fill color; `var(--token, fallback)` strings resolve against the active theme. Default transparent. */
6122
+ backgroundColor?: string;
6123
+ /** Grid line color; resolves theme tokens (default `var(--color-border, #9ca3af)`). */
6124
+ gridColor?: string;
6125
+ /** Axis line color; resolves theme tokens (default `var(--color-muted-foreground, #374151)`). */
6126
+ axisColor?: string;
6121
6127
  /** Draw numeric labels on grid lines (default false). */
6122
6128
  showTickLabels?: boolean;
6123
6129
  /** Draw each curve's `label` at its last in-range sample (default false). */
@@ -6118,6 +6118,12 @@ interface MathCanvasProps {
6118
6118
  showAxes?: boolean;
6119
6119
  showGrid?: boolean;
6120
6120
  gridStep?: number;
6121
+ /** Canvas fill color; `var(--token, fallback)` strings resolve against the active theme. Default transparent. */
6122
+ backgroundColor?: string;
6123
+ /** Grid line color; resolves theme tokens (default `var(--color-border, #9ca3af)`). */
6124
+ gridColor?: string;
6125
+ /** Axis line color; resolves theme tokens (default `var(--color-muted-foreground, #374151)`). */
6126
+ axisColor?: string;
6121
6127
  /** Draw numeric labels on grid lines (default false). */
6122
6128
  showTickLabels?: boolean;
6123
6129
  /** Draw each curve's `label` at its last in-range sample (default false). */
@@ -12,7 +12,7 @@ import { useTranslate } from '@almadar/ui/hooks';
12
12
  import { useUISlots, useTheme } from '@almadar/ui/context';
13
13
  import { evaluate, createMinimalContext } from '@almadar/evaluator';
14
14
  import { createContextFromBindings, interpolateValue } from '@almadar/runtime';
15
- import { mergeEntityFrame, isFileValue, isInlineTrait, isRenderBindingMarker, ANIMATION_NAMES } from '@almadar/core';
15
+ import { mergeEntityFrame, isFileValue, isInlineTrait, isSecretConfigType, isRenderBindingMarker, ANIMATION_NAMES } from '@almadar/core';
16
16
  import { createPortal } from 'react-dom';
17
17
  import { wrapCallbackForEvent } from '@almadar/runtime/ui';
18
18
  import { Link, Outlet, useLocation } from 'react-router-dom';
@@ -8614,6 +8614,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
8614
8614
  case "path": {
8615
8615
  if (!shape.path) break;
8616
8616
  const p = new Path2D(shape.path);
8617
+ ctx.lineJoin = "round";
8618
+ ctx.lineCap = "round";
8617
8619
  if (fill) {
8618
8620
  ctx.fillStyle = fill;
8619
8621
  ctx.fill(p);
@@ -8822,7 +8824,7 @@ var init_LearningCanvas = __esm({
8822
8824
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
8823
8825
  ctx.clearRect(0, 0, width, height);
8824
8826
  if (backgroundColor) {
8825
- ctx.fillStyle = backgroundColor;
8827
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
8826
8828
  ctx.fillRect(0, 0, width, height);
8827
8829
  }
8828
8830
  for (const shape of derivedShapes) {
@@ -25435,6 +25437,7 @@ function currentValue(decl, override) {
25435
25437
  function TextLikeControl({
25436
25438
  field,
25437
25439
  numeric,
25440
+ secret,
25438
25441
  value,
25439
25442
  onCommit
25440
25443
  }) {
@@ -25452,7 +25455,7 @@ function TextLikeControl({
25452
25455
  return /* @__PURE__ */ jsx(
25453
25456
  Input,
25454
25457
  {
25455
- inputType: numeric ? "number" : "text",
25458
+ inputType: secret ? "password" : numeric ? "number" : "text",
25456
25459
  value: draft,
25457
25460
  onChange: (e) => setDraft(e.target.value),
25458
25461
  onBlur: commit,
@@ -25513,6 +25516,8 @@ function FieldControl({
25513
25516
  );
25514
25517
  } else if (decl.type === "number") {
25515
25518
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: true, value, onCommit: onChange });
25519
+ } else if (isSecretConfigType(decl.type)) {
25520
+ control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, secret: true, value, onCommit: onChange });
25516
25521
  } else if (decl.type === "string") {
25517
25522
  control = /* @__PURE__ */ jsx(TextLikeControl, { field: name, numeric: false, value, onCommit: onChange });
25518
25523
  } else if (decl.type === "node") {
@@ -25552,7 +25557,7 @@ var init_PropertyInspector = __esm({
25552
25557
  init_JsonTreeEditor();
25553
25558
  init_NodeSlotEditor();
25554
25559
  TIER_ORDER = ["presentation", "domain", "policy", "infra", "internal"];
25555
- SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset"]);
25560
+ SCALAR_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "icon", "asset", "Asset", "secret"]);
25556
25561
  PropertyInspector = ({
25557
25562
  config,
25558
25563
  values,
@@ -31540,6 +31545,9 @@ var init_MathCanvas = __esm({
31540
31545
  showAxes = true,
31541
31546
  showGrid = true,
31542
31547
  gridStep = 1,
31548
+ backgroundColor,
31549
+ gridColor = "var(--color-border, #9ca3af)",
31550
+ axisColor = "var(--color-muted-foreground, #374151)",
31543
31551
  showTickLabels = false,
31544
31552
  showCurveLabels = false,
31545
31553
  curves = [],
@@ -31594,11 +31602,11 @@ var init_MathCanvas = __esm({
31594
31602
  if (showGrid) {
31595
31603
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
31596
31604
  const px = mapX(x);
31597
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
31605
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
31598
31606
  }
31599
31607
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
31600
31608
  const py = mapY(y);
31601
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
31609
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
31602
31610
  }
31603
31611
  }
31604
31612
  if (showTickLabels) {
@@ -31669,8 +31677,8 @@ var init_MathCanvas = __esm({
31669
31677
  });
31670
31678
  }
31671
31679
  if (showAxes) {
31672
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
31673
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
31680
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
31681
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
31674
31682
  }
31675
31683
  for (const guide of guides) {
31676
31684
  const color = guide.color ?? "#9ca3af";
@@ -31693,23 +31701,36 @@ var init_MathCanvas = __esm({
31693
31701
  }
31694
31702
  for (const curve of curves) {
31695
31703
  if (!curve.samples || curve.samples.length < 2) continue;
31704
+ let d = "";
31705
+ let penDown = false;
31696
31706
  let lastInRange;
31697
31707
  for (let i = 1; i < curve.samples.length; i++) {
31698
31708
  const a = curve.samples[i - 1];
31699
31709
  const b = curve.samples[i];
31700
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
31701
- out.push({
31702
- type: "line",
31703
- x1: mapX(a.x),
31704
- y1: mapY(a.y),
31705
- x2: mapX(b.x),
31706
- y2: mapY(b.y),
31707
- color: curve.color ?? "#2563eb",
31708
- lineWidth: 2,
31709
- dash: curve.dash
31710
- });
31711
- lastInRange = b;
31712
- }
31710
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
31711
+ penDown = false;
31712
+ continue;
31713
+ }
31714
+ const clip = (p, q, xLim) => {
31715
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
31716
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
31717
+ };
31718
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
31719
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
31720
+ const pax = mapX(ca.x);
31721
+ const pay = mapY(ca.y);
31722
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
31723
+ penDown = true;
31724
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
31725
+ }
31726
+ if (!d) continue;
31727
+ out.push({
31728
+ type: "path",
31729
+ path: d,
31730
+ color: curve.color ?? "#2563eb",
31731
+ lineWidth: 2,
31732
+ dash: curve.dash
31733
+ });
31713
31734
  if (showCurveLabels && curve.label && lastInRange) {
31714
31735
  out.push({
31715
31736
  type: "text",
@@ -31824,6 +31845,8 @@ var init_MathCanvas = __esm({
31824
31845
  showAxes,
31825
31846
  showGrid,
31826
31847
  gridStep,
31848
+ gridColor,
31849
+ axisColor,
31827
31850
  showTickLabels,
31828
31851
  showCurveLabels,
31829
31852
  curves,
@@ -31843,6 +31866,7 @@ var init_MathCanvas = __esm({
31843
31866
  {
31844
31867
  width,
31845
31868
  height,
31869
+ backgroundColor,
31846
31870
  shapes: derivedShapes,
31847
31871
  readouts,
31848
31872
  traces,
@@ -12036,6 +12036,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
12036
12036
  case "path": {
12037
12037
  if (!shape.path) break;
12038
12038
  const p = new Path2D(shape.path);
12039
+ ctx.lineJoin = "round";
12040
+ ctx.lineCap = "round";
12039
12041
  if (fill) {
12040
12042
  ctx.fillStyle = fill;
12041
12043
  ctx.fill(p);
@@ -12244,7 +12246,7 @@ var init_LearningCanvas = __esm({
12244
12246
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
12245
12247
  ctx.clearRect(0, 0, width, height);
12246
12248
  if (backgroundColor) {
12247
- ctx.fillStyle = backgroundColor;
12249
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
12248
12250
  ctx.fillRect(0, 0, width, height);
12249
12251
  }
12250
12252
  for (const shape of derivedShapes) {
@@ -30580,6 +30582,9 @@ var init_MathCanvas = __esm({
30580
30582
  showAxes = true,
30581
30583
  showGrid = true,
30582
30584
  gridStep = 1,
30585
+ backgroundColor,
30586
+ gridColor = "var(--color-border, #9ca3af)",
30587
+ axisColor = "var(--color-muted-foreground, #374151)",
30583
30588
  showTickLabels = false,
30584
30589
  showCurveLabels = false,
30585
30590
  curves = [],
@@ -30634,11 +30639,11 @@ var init_MathCanvas = __esm({
30634
30639
  if (showGrid) {
30635
30640
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
30636
30641
  const px = mapX(x);
30637
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30642
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
30638
30643
  }
30639
30644
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
30640
30645
  const py = mapY(y);
30641
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30646
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
30642
30647
  }
30643
30648
  }
30644
30649
  if (showTickLabels) {
@@ -30709,8 +30714,8 @@ var init_MathCanvas = __esm({
30709
30714
  });
30710
30715
  }
30711
30716
  if (showAxes) {
30712
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
30713
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
30717
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
30718
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
30714
30719
  }
30715
30720
  for (const guide of guides) {
30716
30721
  const color = guide.color ?? "#9ca3af";
@@ -30733,23 +30738,36 @@ var init_MathCanvas = __esm({
30733
30738
  }
30734
30739
  for (const curve of curves) {
30735
30740
  if (!curve.samples || curve.samples.length < 2) continue;
30741
+ let d = "";
30742
+ let penDown = false;
30736
30743
  let lastInRange;
30737
30744
  for (let i = 1; i < curve.samples.length; i++) {
30738
30745
  const a = curve.samples[i - 1];
30739
30746
  const b = curve.samples[i];
30740
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
30741
- out.push({
30742
- type: "line",
30743
- x1: mapX(a.x),
30744
- y1: mapY(a.y),
30745
- x2: mapX(b.x),
30746
- y2: mapY(b.y),
30747
- color: curve.color ?? "#2563eb",
30748
- lineWidth: 2,
30749
- dash: curve.dash
30750
- });
30751
- lastInRange = b;
30752
- }
30747
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
30748
+ penDown = false;
30749
+ continue;
30750
+ }
30751
+ const clip = (p, q, xLim) => {
30752
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
30753
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
30754
+ };
30755
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
30756
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
30757
+ const pax = mapX(ca.x);
30758
+ const pay = mapY(ca.y);
30759
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
30760
+ penDown = true;
30761
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
30762
+ }
30763
+ if (!d) continue;
30764
+ out.push({
30765
+ type: "path",
30766
+ path: d,
30767
+ color: curve.color ?? "#2563eb",
30768
+ lineWidth: 2,
30769
+ dash: curve.dash
30770
+ });
30753
30771
  if (showCurveLabels && curve.label && lastInRange) {
30754
30772
  out.push({
30755
30773
  type: "text",
@@ -30864,6 +30882,8 @@ var init_MathCanvas = __esm({
30864
30882
  showAxes,
30865
30883
  showGrid,
30866
30884
  gridStep,
30885
+ gridColor,
30886
+ axisColor,
30867
30887
  showTickLabels,
30868
30888
  showCurveLabels,
30869
30889
  curves,
@@ -30883,6 +30903,7 @@ var init_MathCanvas = __esm({
30883
30903
  {
30884
30904
  width,
30885
30905
  height,
30906
+ backgroundColor,
30886
30907
  shapes: derivedShapes,
30887
30908
  readouts,
30888
30909
  traces,
@@ -11962,6 +11962,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
11962
11962
  case "path": {
11963
11963
  if (!shape.path) break;
11964
11964
  const p = new Path2D(shape.path);
11965
+ ctx.lineJoin = "round";
11966
+ ctx.lineCap = "round";
11965
11967
  if (fill) {
11966
11968
  ctx.fillStyle = fill;
11967
11969
  ctx.fill(p);
@@ -12170,7 +12172,7 @@ var init_LearningCanvas = __esm({
12170
12172
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
12171
12173
  ctx.clearRect(0, 0, width, height);
12172
12174
  if (backgroundColor) {
12173
- ctx.fillStyle = backgroundColor;
12175
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
12174
12176
  ctx.fillRect(0, 0, width, height);
12175
12177
  }
12176
12178
  for (const shape of derivedShapes) {
@@ -30506,6 +30508,9 @@ var init_MathCanvas = __esm({
30506
30508
  showAxes = true,
30507
30509
  showGrid = true,
30508
30510
  gridStep = 1,
30511
+ backgroundColor,
30512
+ gridColor = "var(--color-border, #9ca3af)",
30513
+ axisColor = "var(--color-muted-foreground, #374151)",
30509
30514
  showTickLabels = false,
30510
30515
  showCurveLabels = false,
30511
30516
  curves = [],
@@ -30560,11 +30565,11 @@ var init_MathCanvas = __esm({
30560
30565
  if (showGrid) {
30561
30566
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
30562
30567
  const px = mapX(x);
30563
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30568
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
30564
30569
  }
30565
30570
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
30566
30571
  const py = mapY(y);
30567
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30572
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
30568
30573
  }
30569
30574
  }
30570
30575
  if (showTickLabels) {
@@ -30635,8 +30640,8 @@ var init_MathCanvas = __esm({
30635
30640
  });
30636
30641
  }
30637
30642
  if (showAxes) {
30638
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
30639
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
30643
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
30644
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
30640
30645
  }
30641
30646
  for (const guide of guides) {
30642
30647
  const color = guide.color ?? "#9ca3af";
@@ -30659,23 +30664,36 @@ var init_MathCanvas = __esm({
30659
30664
  }
30660
30665
  for (const curve of curves) {
30661
30666
  if (!curve.samples || curve.samples.length < 2) continue;
30667
+ let d = "";
30668
+ let penDown = false;
30662
30669
  let lastInRange;
30663
30670
  for (let i = 1; i < curve.samples.length; i++) {
30664
30671
  const a = curve.samples[i - 1];
30665
30672
  const b = curve.samples[i];
30666
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
30667
- out.push({
30668
- type: "line",
30669
- x1: mapX(a.x),
30670
- y1: mapY(a.y),
30671
- x2: mapX(b.x),
30672
- y2: mapY(b.y),
30673
- color: curve.color ?? "#2563eb",
30674
- lineWidth: 2,
30675
- dash: curve.dash
30676
- });
30677
- lastInRange = b;
30678
- }
30673
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
30674
+ penDown = false;
30675
+ continue;
30676
+ }
30677
+ const clip = (p, q, xLim) => {
30678
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
30679
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
30680
+ };
30681
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
30682
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
30683
+ const pax = mapX(ca.x);
30684
+ const pay = mapY(ca.y);
30685
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
30686
+ penDown = true;
30687
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
30688
+ }
30689
+ if (!d) continue;
30690
+ out.push({
30691
+ type: "path",
30692
+ path: d,
30693
+ color: curve.color ?? "#2563eb",
30694
+ lineWidth: 2,
30695
+ dash: curve.dash
30696
+ });
30679
30697
  if (showCurveLabels && curve.label && lastInRange) {
30680
30698
  out.push({
30681
30699
  type: "text",
@@ -30790,6 +30808,8 @@ var init_MathCanvas = __esm({
30790
30808
  showAxes,
30791
30809
  showGrid,
30792
30810
  gridStep,
30811
+ gridColor,
30812
+ axisColor,
30793
30813
  showTickLabels,
30794
30814
  showCurveLabels,
30795
30815
  curves,
@@ -30809,6 +30829,7 @@ var init_MathCanvas = __esm({
30809
30829
  {
30810
30830
  width,
30811
30831
  height,
30832
+ backgroundColor,
30812
30833
  shapes: derivedShapes,
30813
30834
  readouts,
30814
30835
  traces,
@@ -12103,6 +12103,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
12103
12103
  case "path": {
12104
12104
  if (!shape.path) break;
12105
12105
  const p = new Path2D(shape.path);
12106
+ ctx.lineJoin = "round";
12107
+ ctx.lineCap = "round";
12106
12108
  if (fill) {
12107
12109
  ctx.fillStyle = fill;
12108
12110
  ctx.fill(p);
@@ -12311,7 +12313,7 @@ var init_LearningCanvas = __esm({
12311
12313
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
12312
12314
  ctx.clearRect(0, 0, width, height);
12313
12315
  if (backgroundColor) {
12314
- ctx.fillStyle = backgroundColor;
12316
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
12315
12317
  ctx.fillRect(0, 0, width, height);
12316
12318
  }
12317
12319
  for (const shape of derivedShapes) {
@@ -30069,6 +30071,9 @@ var init_MathCanvas = __esm({
30069
30071
  showAxes = true,
30070
30072
  showGrid = true,
30071
30073
  gridStep = 1,
30074
+ backgroundColor,
30075
+ gridColor = "var(--color-border, #9ca3af)",
30076
+ axisColor = "var(--color-muted-foreground, #374151)",
30072
30077
  showTickLabels = false,
30073
30078
  showCurveLabels = false,
30074
30079
  curves = [],
@@ -30123,11 +30128,11 @@ var init_MathCanvas = __esm({
30123
30128
  if (showGrid) {
30124
30129
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
30125
30130
  const px = mapX(x);
30126
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30131
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
30127
30132
  }
30128
30133
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
30129
30134
  const py = mapY(y);
30130
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30135
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
30131
30136
  }
30132
30137
  }
30133
30138
  if (showTickLabels) {
@@ -30198,8 +30203,8 @@ var init_MathCanvas = __esm({
30198
30203
  });
30199
30204
  }
30200
30205
  if (showAxes) {
30201
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
30202
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
30206
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
30207
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
30203
30208
  }
30204
30209
  for (const guide of guides) {
30205
30210
  const color = guide.color ?? "#9ca3af";
@@ -30222,23 +30227,36 @@ var init_MathCanvas = __esm({
30222
30227
  }
30223
30228
  for (const curve of curves) {
30224
30229
  if (!curve.samples || curve.samples.length < 2) continue;
30230
+ let d = "";
30231
+ let penDown = false;
30225
30232
  let lastInRange;
30226
30233
  for (let i = 1; i < curve.samples.length; i++) {
30227
30234
  const a = curve.samples[i - 1];
30228
30235
  const b = curve.samples[i];
30229
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
30230
- out.push({
30231
- type: "line",
30232
- x1: mapX(a.x),
30233
- y1: mapY(a.y),
30234
- x2: mapX(b.x),
30235
- y2: mapY(b.y),
30236
- color: curve.color ?? "#2563eb",
30237
- lineWidth: 2,
30238
- dash: curve.dash
30239
- });
30240
- lastInRange = b;
30241
- }
30236
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
30237
+ penDown = false;
30238
+ continue;
30239
+ }
30240
+ const clip = (p, q, xLim) => {
30241
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
30242
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
30243
+ };
30244
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
30245
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
30246
+ const pax = mapX(ca.x);
30247
+ const pay = mapY(ca.y);
30248
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
30249
+ penDown = true;
30250
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
30251
+ }
30252
+ if (!d) continue;
30253
+ out.push({
30254
+ type: "path",
30255
+ path: d,
30256
+ color: curve.color ?? "#2563eb",
30257
+ lineWidth: 2,
30258
+ dash: curve.dash
30259
+ });
30242
30260
  if (showCurveLabels && curve.label && lastInRange) {
30243
30261
  out.push({
30244
30262
  type: "text",
@@ -30353,6 +30371,8 @@ var init_MathCanvas = __esm({
30353
30371
  showAxes,
30354
30372
  showGrid,
30355
30373
  gridStep,
30374
+ gridColor,
30375
+ axisColor,
30356
30376
  showTickLabels,
30357
30377
  showCurveLabels,
30358
30378
  curves,
@@ -30372,6 +30392,7 @@ var init_MathCanvas = __esm({
30372
30392
  {
30373
30393
  width,
30374
30394
  height,
30395
+ backgroundColor,
30375
30396
  shapes: derivedShapes,
30376
30397
  readouts,
30377
30398
  traces,
@@ -12029,6 +12029,8 @@ function drawShape(ctx, shape, width, height, allShapes) {
12029
12029
  case "path": {
12030
12030
  if (!shape.path) break;
12031
12031
  const p = new Path2D(shape.path);
12032
+ ctx.lineJoin = "round";
12033
+ ctx.lineCap = "round";
12032
12034
  if (fill) {
12033
12035
  ctx.fillStyle = fill;
12034
12036
  ctx.fill(p);
@@ -12237,7 +12239,7 @@ var init_LearningCanvas = __esm({
12237
12239
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
12238
12240
  ctx.clearRect(0, 0, width, height);
12239
12241
  if (backgroundColor) {
12240
- ctx.fillStyle = backgroundColor;
12242
+ ctx.fillStyle = resolveColor2(backgroundColor, ctx, backgroundColor);
12241
12243
  ctx.fillRect(0, 0, width, height);
12242
12244
  }
12243
12245
  for (const shape of derivedShapes) {
@@ -29995,6 +29997,9 @@ var init_MathCanvas = __esm({
29995
29997
  showAxes = true,
29996
29998
  showGrid = true,
29997
29999
  gridStep = 1,
30000
+ backgroundColor,
30001
+ gridColor = "var(--color-border, #9ca3af)",
30002
+ axisColor = "var(--color-muted-foreground, #374151)",
29998
30003
  showTickLabels = false,
29999
30004
  showCurveLabels = false,
30000
30005
  curves = [],
@@ -30049,11 +30054,11 @@ var init_MathCanvas = __esm({
30049
30054
  if (showGrid) {
30050
30055
  for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
30051
30056
  const px = mapX(x);
30052
- out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30057
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: gridColor, opacity: 0.35, lineWidth: 1 });
30053
30058
  }
30054
30059
  for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
30055
30060
  const py = mapY(y);
30056
- out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#9ca3af", opacity: 0.35, lineWidth: 1 });
30061
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: gridColor, opacity: 0.35, lineWidth: 1 });
30057
30062
  }
30058
30063
  }
30059
30064
  if (showTickLabels) {
@@ -30124,8 +30129,8 @@ var init_MathCanvas = __esm({
30124
30129
  });
30125
30130
  }
30126
30131
  if (showAxes) {
30127
- out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
30128
- out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
30132
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: axisColor, lineWidth: 2 });
30133
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: axisColor, lineWidth: 2 });
30129
30134
  }
30130
30135
  for (const guide of guides) {
30131
30136
  const color = guide.color ?? "#9ca3af";
@@ -30148,23 +30153,36 @@ var init_MathCanvas = __esm({
30148
30153
  }
30149
30154
  for (const curve of curves) {
30150
30155
  if (!curve.samples || curve.samples.length < 2) continue;
30156
+ let d = "";
30157
+ let penDown = false;
30151
30158
  let lastInRange;
30152
30159
  for (let i = 1; i < curve.samples.length; i++) {
30153
30160
  const a = curve.samples[i - 1];
30154
30161
  const b = curve.samples[i];
30155
- if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
30156
- out.push({
30157
- type: "line",
30158
- x1: mapX(a.x),
30159
- y1: mapY(a.y),
30160
- x2: mapX(b.x),
30161
- y2: mapY(b.y),
30162
- color: curve.color ?? "#2563eb",
30163
- lineWidth: 2,
30164
- dash: curve.dash
30165
- });
30166
- lastInRange = b;
30167
- }
30162
+ if (a.x < xMin && b.x < xMin || a.x > xMax && b.x > xMax) {
30163
+ penDown = false;
30164
+ continue;
30165
+ }
30166
+ const clip = (p, q, xLim) => {
30167
+ const t = q.x === p.x ? 0 : (xLim - p.x) / (q.x - p.x);
30168
+ return { x: xLim, y: p.y + t * (q.y - p.y) };
30169
+ };
30170
+ const ca = a.x < xMin ? clip(a, b, xMin) : a.x > xMax ? clip(a, b, xMax) : a;
30171
+ const cb = b.x < xMin ? clip(a, b, xMin) : b.x > xMax ? clip(a, b, xMax) : b;
30172
+ const pax = mapX(ca.x);
30173
+ const pay = mapY(ca.y);
30174
+ d += `${penDown ? "L" : "M"} ${pax} ${pay} L ${mapX(cb.x)} ${mapY(cb.y)} `;
30175
+ penDown = true;
30176
+ if (b.x >= xMin && b.x <= xMax) lastInRange = b;
30177
+ }
30178
+ if (!d) continue;
30179
+ out.push({
30180
+ type: "path",
30181
+ path: d,
30182
+ color: curve.color ?? "#2563eb",
30183
+ lineWidth: 2,
30184
+ dash: curve.dash
30185
+ });
30168
30186
  if (showCurveLabels && curve.label && lastInRange) {
30169
30187
  out.push({
30170
30188
  type: "text",
@@ -30279,6 +30297,8 @@ var init_MathCanvas = __esm({
30279
30297
  showAxes,
30280
30298
  showGrid,
30281
30299
  gridStep,
30300
+ gridColor,
30301
+ axisColor,
30282
30302
  showTickLabels,
30283
30303
  showCurveLabels,
30284
30304
  curves,
@@ -30298,6 +30318,7 @@ var init_MathCanvas = __esm({
30298
30318
  {
30299
30319
  width,
30300
30320
  height,
30321
+ backgroundColor,
30301
30322
  shapes: derivedShapes,
30302
30323
  readouts,
30303
30324
  traces,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.156.0",
3
+ "version": "5.157.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -118,11 +118,11 @@
118
118
  "access": "public"
119
119
  },
120
120
  "dependencies": {
121
- "@almadar/core": "^10.66.0",
121
+ "@almadar/core": "^10.67.0",
122
122
  "@almadar/evaluator": "^2.41.0",
123
123
  "@almadar/logger": "^1.11.0",
124
- "@almadar/runtime": "^6.57.0",
125
- "@almadar/std": "^16.182.0",
124
+ "@almadar/runtime": "^6.58.0",
125
+ "@almadar/std": "^16.183.0",
126
126
  "@almadar/syntax": "^1.15.0",
127
127
  "@dnd-kit/core": "^6.3.1",
128
128
  "@dnd-kit/sortable": "^10.0.0",