@almadar/ui 5.77.0 → 5.79.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.
Files changed (71) hide show
  1. package/dist/avl/index.cjs +863 -98
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +863 -98
  4. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  5. package/dist/components/core/atoms/index.d.ts +2 -1
  6. package/dist/components/core/molecules/Card.d.ts +1 -1
  7. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  8. package/dist/components/core/molecules/DataList.d.ts +1 -1
  9. package/dist/components/core/molecules/DocPagination.d.ts +8 -1
  10. package/dist/components/core/molecules/DocSearch.d.ts +8 -1
  11. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  12. package/dist/components/core/molecules/MapView.d.ts +18 -1
  13. package/dist/components/core/molecules/PropertyInspector.d.ts +2 -0
  14. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  15. package/dist/components/core/molecules/TableView.d.ts +1 -1
  16. package/dist/components/core/molecules/index.d.ts +4 -0
  17. package/dist/components/core/organisms/DataTable.d.ts +1 -1
  18. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +10 -1
  19. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +2 -1
  20. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  21. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +6 -1
  22. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +6 -1
  23. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +12 -1
  24. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +2 -1
  25. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +2 -1
  26. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +11 -1
  27. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +8 -1
  28. package/dist/components/game/2d/atoms/ActionButton.d.ts +2 -1
  29. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +2 -1
  30. package/dist/components/game/2d/atoms/ComboCounter.d.ts +2 -1
  31. package/dist/components/game/2d/atoms/ControlButton.d.ts +2 -1
  32. package/dist/components/game/2d/atoms/DamageNumber.d.ts +2 -1
  33. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +2 -1
  34. package/dist/components/game/2d/atoms/GameIcon.d.ts +2 -1
  35. package/dist/components/game/2d/atoms/HealthBar.d.ts +2 -1
  36. package/dist/components/game/2d/atoms/ItemSlot.d.ts +2 -1
  37. package/dist/components/game/2d/atoms/MiniMap.d.ts +2 -1
  38. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +2 -1
  39. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +2 -1
  40. package/dist/components/game/2d/atoms/StatusEffect.d.ts +2 -1
  41. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +2 -1
  42. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +2 -1
  43. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +2 -1
  44. package/dist/components/game/2d/molecules/GameHud.d.ts +2 -1
  45. package/dist/components/game/2d/molecules/GameMenu.d.ts +2 -1
  46. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +2 -1
  47. package/dist/components/game/2d/molecules/ResourceBar.d.ts +2 -1
  48. package/dist/components/game/2d/molecules/StatBadge.d.ts +2 -1
  49. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  50. package/dist/components/index.cjs +2212 -1525
  51. package/dist/components/index.css +3 -3
  52. package/dist/components/index.js +1002 -315
  53. package/dist/components/learning/atoms/LearningCanvas.d.ts +80 -0
  54. package/dist/components/learning/molecules/BiologyCanvas.d.ts +47 -0
  55. package/dist/components/learning/molecules/ChemistryCanvas.d.ts +55 -0
  56. package/dist/components/learning/molecules/MathCanvas.d.ts +61 -0
  57. package/dist/components/learning/molecules/PhysicsCanvas.d.ts +54 -0
  58. package/dist/components/marketing/atoms/MarketingStatCard.d.ts +2 -2
  59. package/dist/hooks/useGitHub.d.ts +7 -7
  60. package/dist/marketing/index.cjs +2 -2
  61. package/dist/marketing/index.js +2 -2
  62. package/dist/providers/EventBusProvider.d.ts +1 -1
  63. package/dist/providers/SelectionProvider.d.ts +1 -1
  64. package/dist/providers/ServerBridge.d.ts +1 -1
  65. package/dist/providers/index.cjs +859 -94
  66. package/dist/providers/index.css +3 -3
  67. package/dist/providers/index.js +859 -94
  68. package/dist/runtime/index.cjs +859 -94
  69. package/dist/runtime/index.css +3 -3
  70. package/dist/runtime/index.js +859 -94
  71. package/package.json +1 -1
@@ -5676,6 +5676,66 @@ var init_RangeSlider = __esm({
5676
5676
  RangeSlider.displayName = "RangeSlider";
5677
5677
  }
5678
5678
  });
5679
+ function easeOut(t) {
5680
+ return t * (2 - t);
5681
+ }
5682
+ var AnimatedCounter;
5683
+ var init_AnimatedCounter = __esm({
5684
+ "components/marketing/atoms/AnimatedCounter.tsx"() {
5685
+ "use client";
5686
+ init_cn();
5687
+ init_Typography();
5688
+ AnimatedCounter = ({
5689
+ value: rawValue,
5690
+ duration = 600,
5691
+ prefix,
5692
+ suffix,
5693
+ className
5694
+ }) => {
5695
+ const numericRaw = typeof rawValue === "number" ? rawValue : Number.parseFloat(String(rawValue ?? ""));
5696
+ const value = !Number.isNaN(numericRaw) ? numericRaw : 0;
5697
+ const [displayValue, setDisplayValue] = React107.useState(value);
5698
+ const previousValueRef = React107.useRef(value);
5699
+ const animationFrameRef = React107.useRef(null);
5700
+ React107.useEffect(() => {
5701
+ const from = previousValueRef.current;
5702
+ const to = value;
5703
+ previousValueRef.current = value;
5704
+ if (from === to) {
5705
+ setDisplayValue(to);
5706
+ return;
5707
+ }
5708
+ const startTime = performance.now();
5709
+ const diff = to - from;
5710
+ function animate(currentTime) {
5711
+ const elapsed = currentTime - startTime;
5712
+ const progress = Math.min(elapsed / duration, 1);
5713
+ const easedProgress = easeOut(progress);
5714
+ setDisplayValue(from + diff * easedProgress);
5715
+ if (progress < 1) {
5716
+ animationFrameRef.current = requestAnimationFrame(animate);
5717
+ } else {
5718
+ setDisplayValue(to);
5719
+ }
5720
+ }
5721
+ animationFrameRef.current = requestAnimationFrame(animate);
5722
+ return () => {
5723
+ if (animationFrameRef.current !== null) {
5724
+ cancelAnimationFrame(animationFrameRef.current);
5725
+ }
5726
+ };
5727
+ }, [value, duration]);
5728
+ const decimalPlaces = Number.isInteger(value) ? 0 : String(value).split(".")[1]?.length ?? 0;
5729
+ const formattedValue = displayValue.toFixed(decimalPlaces);
5730
+ return /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "h3", className: cn("tabular-nums", className), children: [
5731
+ prefix,
5732
+ formattedValue,
5733
+ suffix
5734
+ ] });
5735
+ };
5736
+ AnimatedCounter.displayName = "AnimatedCounter";
5737
+ }
5738
+ });
5679
5739
  function useInfiniteScroll(onLoadMore, options = {}) {
5680
5740
  const { rootMargin = "200px", hasMore = true, isLoading = false } = options;
5681
5741
  const observerRef = React107.useRef(null);
@@ -5972,6 +6032,34 @@ var init_SectionHeader = __esm({
5972
6032
  SectionHeader.displayName = "SectionHeader";
5973
6033
  }
5974
6034
  });
6035
+ var sizeClasses6, MarketingStatCard;
6036
+ var init_MarketingStatCard = __esm({
6037
+ "components/marketing/atoms/MarketingStatCard.tsx"() {
6038
+ init_cn();
6039
+ init_Stack();
6040
+ init_Typography();
6041
+ sizeClasses6 = {
6042
+ sm: "text-2xl",
6043
+ md: "text-4xl",
6044
+ lg: "text-5xl"
6045
+ };
6046
+ MarketingStatCard = ({ value, label, size = "md", className }) => {
6047
+ return /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", align: "center", className: cn(className), children: [
6048
+ /* @__PURE__ */ jsxRuntime.jsx(
6049
+ Typography,
6050
+ {
6051
+ weight: "bold",
6052
+ color: "primary",
6053
+ className: cn(sizeClasses6[size]),
6054
+ children: value
6055
+ }
6056
+ ),
6057
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "muted", children: label })
6058
+ ] });
6059
+ };
6060
+ MarketingStatCard.displayName = "MarketingStatCard";
6061
+ }
6062
+ });
5975
6063
  var backgroundClasses, paddingClasses, ContentSection;
5976
6064
  var init_ContentSection = __esm({
5977
6065
  "components/marketing/atoms/ContentSection.tsx"() {
@@ -19804,6 +19892,315 @@ var init_molecules = __esm({
19804
19892
  init_puzzleObject();
19805
19893
  }
19806
19894
  });
19895
+ function resolveColor2(color, ctx, fallback) {
19896
+ if (!color) return fallback;
19897
+ if (color.startsWith("var(")) {
19898
+ ctx.canvas.style;
19899
+ const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color);
19900
+ if (m) {
19901
+ const computed = getComputedStyle(ctx.canvas).getPropertyValue(m[1]).trim();
19902
+ return computed || m[2]?.trim() || fallback;
19903
+ }
19904
+ }
19905
+ return color;
19906
+ }
19907
+ function shapeBounds(shape) {
19908
+ switch (shape.type) {
19909
+ case "line":
19910
+ case "arrow":
19911
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) return null;
19912
+ return {
19913
+ x: Math.min(shape.x1, shape.x2) - 6,
19914
+ y: Math.min(shape.y1, shape.y2) - 6,
19915
+ w: Math.abs(shape.x2 - shape.x1) + 12,
19916
+ h: Math.abs(shape.y2 - shape.y1) + 12
19917
+ };
19918
+ case "circle":
19919
+ if (shape.x == null || shape.y == null || shape.radius == null) return null;
19920
+ return {
19921
+ x: shape.x - shape.radius - 4,
19922
+ y: shape.y - shape.radius - 4,
19923
+ w: shape.radius * 2 + 8,
19924
+ h: shape.radius * 2 + 8
19925
+ };
19926
+ case "rect":
19927
+ if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) return null;
19928
+ return { x: shape.x - 4, y: shape.y - 4, w: shape.width + 8, h: shape.height + 8 };
19929
+ case "polygon":
19930
+ if (!shape.points || shape.points.length === 0) return null;
19931
+ {
19932
+ const xs = shape.points.map((p2) => p2.x);
19933
+ const ys = shape.points.map((p2) => p2.y);
19934
+ const minX = Math.min(...xs);
19935
+ const minY = Math.min(...ys);
19936
+ return {
19937
+ x: minX - 4,
19938
+ y: minY - 4,
19939
+ w: Math.max(...xs) - minX + 8,
19940
+ h: Math.max(...ys) - minY + 8
19941
+ };
19942
+ }
19943
+ case "text":
19944
+ if (shape.x == null || shape.y == null) return null;
19945
+ return { x: shape.x - 4, y: shape.y - (shape.fontSize ?? 14) - 4, w: 120, h: (shape.fontSize ?? 14) + 8 };
19946
+ default:
19947
+ return null;
19948
+ }
19949
+ }
19950
+ function drawArrowHead(ctx, x1, y1, x2, y2, size) {
19951
+ const angle = Math.atan2(y2 - y1, x2 - x1);
19952
+ ctx.beginPath();
19953
+ ctx.moveTo(x2, y2);
19954
+ ctx.lineTo(x2 - size * Math.cos(angle - Math.PI / 6), y2 - size * Math.sin(angle - Math.PI / 6));
19955
+ ctx.lineTo(x2 - size * Math.cos(angle + Math.PI / 6), y2 - size * Math.sin(angle + Math.PI / 6));
19956
+ ctx.closePath();
19957
+ ctx.fill();
19958
+ }
19959
+ function drawShape(ctx, shape, width, height) {
19960
+ ctx.save();
19961
+ const opacity = shape.opacity ?? 1;
19962
+ ctx.globalAlpha = opacity;
19963
+ const stroke = resolveColor2(shape.color, ctx, "#333333");
19964
+ const fill = shape.fill ? resolveColor2(shape.fill, ctx, "#cccccc") : void 0;
19965
+ ctx.lineWidth = shape.lineWidth ?? 2;
19966
+ switch (shape.type) {
19967
+ case "grid": {
19968
+ const step = shape.step ?? 40;
19969
+ ctx.strokeStyle = stroke;
19970
+ ctx.globalAlpha = opacity * 0.25;
19971
+ ctx.lineWidth = 1;
19972
+ ctx.beginPath();
19973
+ for (let x = 0; x <= width; x += step) {
19974
+ ctx.moveTo(x, 0);
19975
+ ctx.lineTo(x, height);
19976
+ }
19977
+ for (let y = 0; y <= height; y += step) {
19978
+ ctx.moveTo(0, y);
19979
+ ctx.lineTo(width, y);
19980
+ }
19981
+ ctx.stroke();
19982
+ break;
19983
+ }
19984
+ case "axis": {
19985
+ const axis = shape.axis ?? "x";
19986
+ ctx.strokeStyle = stroke;
19987
+ ctx.lineWidth = shape.lineWidth ?? 2;
19988
+ ctx.beginPath();
19989
+ if (axis === "x") {
19990
+ ctx.moveTo(0, height / 2);
19991
+ ctx.lineTo(width, height / 2);
19992
+ } else {
19993
+ ctx.moveTo(width / 2, 0);
19994
+ ctx.lineTo(width / 2, height);
19995
+ }
19996
+ ctx.stroke();
19997
+ break;
19998
+ }
19999
+ case "line": {
20000
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
20001
+ ctx.strokeStyle = stroke;
20002
+ ctx.beginPath();
20003
+ ctx.moveTo(shape.x1, shape.y1);
20004
+ ctx.lineTo(shape.x2, shape.y2);
20005
+ ctx.stroke();
20006
+ break;
20007
+ }
20008
+ case "arrow": {
20009
+ if (shape.x1 == null || shape.y1 == null || shape.x2 == null || shape.y2 == null) break;
20010
+ ctx.strokeStyle = stroke;
20011
+ ctx.fillStyle = stroke;
20012
+ ctx.beginPath();
20013
+ ctx.moveTo(shape.x1, shape.y1);
20014
+ ctx.lineTo(shape.x2, shape.y2);
20015
+ ctx.stroke();
20016
+ drawArrowHead(ctx, shape.x1, shape.y1, shape.x2, shape.y2, 10);
20017
+ break;
20018
+ }
20019
+ case "circle": {
20020
+ if (shape.x == null || shape.y == null || shape.radius == null) break;
20021
+ ctx.beginPath();
20022
+ ctx.arc(shape.x, shape.y, shape.radius, 0, Math.PI * 2);
20023
+ if (fill) {
20024
+ ctx.fillStyle = fill;
20025
+ ctx.fill();
20026
+ }
20027
+ ctx.strokeStyle = stroke;
20028
+ ctx.stroke();
20029
+ break;
20030
+ }
20031
+ case "rect": {
20032
+ if (shape.x == null || shape.y == null || shape.width == null || shape.height == null) break;
20033
+ if (fill) {
20034
+ ctx.fillStyle = fill;
20035
+ ctx.fillRect(shape.x, shape.y, shape.width, shape.height);
20036
+ }
20037
+ ctx.strokeStyle = stroke;
20038
+ ctx.strokeRect(shape.x, shape.y, shape.width, shape.height);
20039
+ break;
20040
+ }
20041
+ case "polygon": {
20042
+ if (!shape.points || shape.points.length < 2) break;
20043
+ ctx.beginPath();
20044
+ ctx.moveTo(shape.points[0].x, shape.points[0].y);
20045
+ for (let i = 1; i < shape.points.length; i++) {
20046
+ ctx.lineTo(shape.points[i].x, shape.points[i].y);
20047
+ }
20048
+ ctx.closePath();
20049
+ if (fill) {
20050
+ ctx.fillStyle = fill;
20051
+ ctx.fill();
20052
+ }
20053
+ ctx.strokeStyle = stroke;
20054
+ ctx.stroke();
20055
+ break;
20056
+ }
20057
+ case "path": {
20058
+ if (!shape.path) break;
20059
+ const p2 = new Path2D(shape.path);
20060
+ if (fill) {
20061
+ ctx.fillStyle = fill;
20062
+ ctx.fill(p2);
20063
+ }
20064
+ ctx.strokeStyle = stroke;
20065
+ ctx.stroke(p2);
20066
+ break;
20067
+ }
20068
+ case "text": {
20069
+ if (shape.x == null || shape.y == null || !shape.text) break;
20070
+ ctx.fillStyle = stroke;
20071
+ ctx.font = `${shape.fontSize ?? 14}px system-ui, sans-serif`;
20072
+ ctx.textAlign = shape.align ?? "left";
20073
+ ctx.textBaseline = "middle";
20074
+ ctx.fillText(shape.text, shape.x, shape.y);
20075
+ break;
20076
+ }
20077
+ }
20078
+ ctx.restore();
20079
+ }
20080
+ var LearningCanvas;
20081
+ var init_LearningCanvas = __esm({
20082
+ "components/learning/atoms/LearningCanvas.tsx"() {
20083
+ "use client";
20084
+ init_cn();
20085
+ init_useEventBus();
20086
+ LearningCanvas = ({
20087
+ className,
20088
+ width = 600,
20089
+ height = 400,
20090
+ backgroundColor,
20091
+ shapes = [],
20092
+ interactive = false,
20093
+ animate = false,
20094
+ onShapeClick,
20095
+ onShapeHover,
20096
+ isLoading,
20097
+ error
20098
+ }) => {
20099
+ const canvasRef = React107.useRef(null);
20100
+ const eventBus = useEventBus();
20101
+ const animRef = React107.useRef(0);
20102
+ const hoverIndexRef = React107.useRef(-1);
20103
+ const findShapeAt = React107.useCallback((clientX, clientY) => {
20104
+ const canvas = canvasRef.current;
20105
+ if (!canvas) return -1;
20106
+ const rect = canvas.getBoundingClientRect();
20107
+ const x = clientX - rect.left;
20108
+ const y = clientY - rect.top;
20109
+ for (let i = shapes.length - 1; i >= 0; i--) {
20110
+ const b = shapeBounds(shapes[i]);
20111
+ if (b && x >= b.x && x <= b.x + b.w && y >= b.y && y <= b.y + b.h) {
20112
+ return i;
20113
+ }
20114
+ }
20115
+ return -1;
20116
+ }, [shapes]);
20117
+ const draw = React107.useCallback(() => {
20118
+ const canvas = canvasRef.current;
20119
+ if (!canvas) return;
20120
+ const ctx = canvas.getContext("2d");
20121
+ if (!ctx) return;
20122
+ const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
20123
+ canvas.width = Math.max(1, Math.floor(width * dpr));
20124
+ canvas.height = Math.max(1, Math.floor(height * dpr));
20125
+ canvas.style.width = `${width}px`;
20126
+ canvas.style.height = `${height}px`;
20127
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
20128
+ ctx.clearRect(0, 0, width, height);
20129
+ if (backgroundColor) {
20130
+ ctx.fillStyle = backgroundColor;
20131
+ ctx.fillRect(0, 0, width, height);
20132
+ }
20133
+ for (const shape of shapes) {
20134
+ drawShape(ctx, shape, width, height);
20135
+ }
20136
+ }, [width, height, backgroundColor, shapes]);
20137
+ React107.useEffect(() => {
20138
+ draw();
20139
+ }, [draw]);
20140
+ React107.useEffect(() => {
20141
+ if (!animate) return;
20142
+ const loop = () => {
20143
+ draw();
20144
+ animRef.current = requestAnimationFrame(loop);
20145
+ };
20146
+ animRef.current = requestAnimationFrame(loop);
20147
+ return () => cancelAnimationFrame(animRef.current);
20148
+ }, [animate, draw]);
20149
+ const handlePointerMove = React107.useCallback(
20150
+ (e) => {
20151
+ if (!interactive) return;
20152
+ const idx = findShapeAt(e.clientX, e.clientY);
20153
+ if (idx !== hoverIndexRef.current) {
20154
+ hoverIndexRef.current = idx;
20155
+ if (idx >= 0) {
20156
+ const shape = shapes[idx];
20157
+ const payload = { id: shape.id, type: shape.type, index: idx };
20158
+ if (onShapeHover) onShapeHover(payload);
20159
+ else if (eventBus) eventBus.emit(`UI:SHAPE_HOVER`, payload);
20160
+ }
20161
+ }
20162
+ },
20163
+ [interactive, onShapeHover, eventBus, findShapeAt, shapes]
20164
+ );
20165
+ const handleClick = React107.useCallback(
20166
+ (e) => {
20167
+ if (!interactive) return;
20168
+ const idx = findShapeAt(e.clientX, e.clientY);
20169
+ if (idx >= 0) {
20170
+ const shape = shapes[idx];
20171
+ const payload = { id: shape.id, type: shape.type, index: idx };
20172
+ if (onShapeClick) onShapeClick(payload);
20173
+ else if (eventBus) eventBus.emit(`UI:SHAPE_CLICK`, payload);
20174
+ }
20175
+ },
20176
+ [interactive, onShapeClick, eventBus, findShapeAt, shapes]
20177
+ );
20178
+ if (isLoading || error) {
20179
+ return /* @__PURE__ */ jsxRuntime.jsx(
20180
+ "div",
20181
+ {
20182
+ className: cn(
20183
+ "flex items-center justify-center rounded border border-border bg-surface",
20184
+ className
20185
+ ),
20186
+ style: { width, height },
20187
+ children: error ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-destructive", children: error.message }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Loading canvas\u2026" })
20188
+ }
20189
+ );
20190
+ }
20191
+ return /* @__PURE__ */ jsxRuntime.jsx(
20192
+ "canvas",
20193
+ {
20194
+ ref: canvasRef,
20195
+ className: cn("block touch-none rounded border border-border", className),
20196
+ style: { width, height },
20197
+ onClick: handleClick,
20198
+ onPointerMove: handlePointerMove
20199
+ }
20200
+ );
20201
+ };
20202
+ }
20203
+ });
19807
20204
 
19808
20205
  // components/core/atoms/index.ts
19809
20206
  var init_atoms = __esm({
@@ -21672,91 +22069,6 @@ var init_ComponentPatterns = __esm({
21672
22069
  AlertPattern.displayName = "AlertPattern";
21673
22070
  }
21674
22071
  });
21675
- function parseValue(value) {
21676
- if (value === "" || value == null) return { num: 0, prefix: "", suffix: "", decimals: 0 };
21677
- const match = String(value).match(/^([^0-9]*)([0-9]+(?:\.[0-9]+)?)(.*)$/);
21678
- if (!match) {
21679
- return { num: 0, prefix: "", suffix: String(value), decimals: 0 };
21680
- }
21681
- const numStr = match[2];
21682
- const decimalIdx = numStr.indexOf(".");
21683
- const decimals = decimalIdx >= 0 ? numStr.length - decimalIdx - 1 : 0;
21684
- return {
21685
- prefix: match[1],
21686
- num: parseFloat(numStr),
21687
- suffix: match[3],
21688
- decimals
21689
- };
21690
- }
21691
- var AnimatedCounter;
21692
- var init_AnimatedCounter = __esm({
21693
- "components/core/molecules/AnimatedCounter.tsx"() {
21694
- "use client";
21695
- init_cn();
21696
- init_Box();
21697
- init_Typography();
21698
- AnimatedCounter = ({
21699
- value,
21700
- label,
21701
- duration = 1500,
21702
- className
21703
- }) => {
21704
- const ref = React107.useRef(null);
21705
- const [displayValue, setDisplayValue] = React107.useState("0");
21706
- const [hasAnimated, setHasAnimated] = React107.useState(false);
21707
- const animate = React107.useCallback(() => {
21708
- const { num: num2, prefix, suffix, decimals } = parseValue(value);
21709
- if (num2 === 0) {
21710
- setDisplayValue(String(value));
21711
- return;
21712
- }
21713
- const startTime = performance.now();
21714
- const tick = (now) => {
21715
- const elapsed = now - startTime;
21716
- const progress = Math.min(elapsed / duration, 1);
21717
- const eased = 1 - Math.pow(1 - progress, 3);
21718
- const current = eased * num2;
21719
- setDisplayValue(`${prefix}${current.toFixed(decimals)}${suffix}`);
21720
- if (progress < 1) {
21721
- requestAnimationFrame(tick);
21722
- } else {
21723
- setDisplayValue(String(value));
21724
- }
21725
- };
21726
- requestAnimationFrame(tick);
21727
- }, [value, duration]);
21728
- React107.useEffect(() => {
21729
- if (hasAnimated) return;
21730
- const el = ref.current;
21731
- if (!el) return;
21732
- const observer2 = new IntersectionObserver(
21733
- (entries) => {
21734
- if (entries[0].isIntersecting) {
21735
- setHasAnimated(true);
21736
- animate();
21737
- observer2.disconnect();
21738
- }
21739
- },
21740
- { threshold: 0.3 }
21741
- );
21742
- observer2.observe(el);
21743
- return () => observer2.disconnect();
21744
- }, [hasAnimated, animate]);
21745
- return /* @__PURE__ */ jsxRuntime.jsxs(Box, { ref, className: cn("flex flex-col items-center gap-1 p-4", className), children: [
21746
- /* @__PURE__ */ jsxRuntime.jsx(
21747
- Typography,
21748
- {
21749
- variant: "h2",
21750
- className: "text-primary font-bold tabular-nums",
21751
- children: hasAnimated ? displayValue : "0"
21752
- }
21753
- ),
21754
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body2", color: "muted", className: "text-center", children: label })
21755
- ] });
21756
- };
21757
- AnimatedCounter.displayName = "AnimatedCounter";
21758
- }
21759
- });
21760
22072
  var AuthLayout;
21761
22073
  var init_AuthLayout = __esm({
21762
22074
  "components/marketing/templates/AuthLayout.tsx"() {
@@ -22725,10 +23037,107 @@ var init_BehaviorView = __esm({
22725
23037
  BehaviorView.displayName = "BehaviorView";
22726
23038
  }
22727
23039
  });
23040
+ var BiologyCanvas;
23041
+ var init_BiologyCanvas = __esm({
23042
+ "components/learning/molecules/BiologyCanvas.tsx"() {
23043
+ "use client";
23044
+ init_atoms();
23045
+ init_Stack();
23046
+ init_LearningCanvas();
23047
+ BiologyCanvas = ({
23048
+ className,
23049
+ width = 600,
23050
+ height = 400,
23051
+ title,
23052
+ backgroundColor,
23053
+ nodes = [],
23054
+ edges = [],
23055
+ shapes = [],
23056
+ interactive = false,
23057
+ animate = false,
23058
+ onShapeClick,
23059
+ isLoading,
23060
+ error
23061
+ }) => {
23062
+ const derivedShapes = React107.useMemo(() => {
23063
+ const out = [];
23064
+ const nodeById = /* @__PURE__ */ new Map();
23065
+ for (const n of nodes) {
23066
+ if (n.id) nodeById.set(n.id, n);
23067
+ }
23068
+ for (const e of edges) {
23069
+ const a = nodeById.get(e.from);
23070
+ const b = nodeById.get(e.to);
23071
+ if (!a || !b) continue;
23072
+ out.push({
23073
+ type: "line",
23074
+ x1: a.x,
23075
+ y1: a.y,
23076
+ x2: b.x,
23077
+ y2: b.y,
23078
+ color: e.color ?? "#9ca3af",
23079
+ lineWidth: 2
23080
+ });
23081
+ if (e.label) {
23082
+ out.push({
23083
+ type: "text",
23084
+ x: (a.x + b.x) / 2 + 4,
23085
+ y: (a.y + b.y) / 2 - 4,
23086
+ text: e.label,
23087
+ color: "#374151",
23088
+ fontSize: 11
23089
+ });
23090
+ }
23091
+ }
23092
+ for (const n of nodes) {
23093
+ out.push({
23094
+ type: "circle",
23095
+ x: n.x,
23096
+ y: n.y,
23097
+ radius: n.radius ?? 16,
23098
+ color: n.color ?? "#16a34a",
23099
+ fill: `${n.color ?? "#16a34a"}33`,
23100
+ id: n.id
23101
+ });
23102
+ if (n.label) {
23103
+ out.push({
23104
+ type: "text",
23105
+ x: n.x,
23106
+ y: n.y + (n.radius ?? 16) + 14,
23107
+ text: n.label,
23108
+ color: "#111827",
23109
+ fontSize: 12,
23110
+ align: "center"
23111
+ });
23112
+ }
23113
+ }
23114
+ out.push(...shapes);
23115
+ return out;
23116
+ }, [nodes, edges, shapes]);
23117
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
23118
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
23119
+ /* @__PURE__ */ jsxRuntime.jsx(
23120
+ LearningCanvas,
23121
+ {
23122
+ width,
23123
+ height,
23124
+ backgroundColor,
23125
+ shapes: derivedShapes,
23126
+ interactive,
23127
+ animate,
23128
+ onShapeClick,
23129
+ isLoading,
23130
+ error
23131
+ }
23132
+ )
23133
+ ] }) });
23134
+ };
23135
+ }
23136
+ });
22728
23137
 
22729
- // node_modules/katex/dist/katex.min.css
23138
+ // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
22730
23139
  var init_katex_min = __esm({
22731
- "node_modules/katex/dist/katex.min.css"() {
23140
+ "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
22732
23141
  }
22733
23142
  });
22734
23143
  var Tabs;
@@ -29214,6 +29623,122 @@ var init_ChatBar = __esm({
29214
29623
  ChatBar.displayName = "ChatBar";
29215
29624
  }
29216
29625
  });
29626
+ var ChemistryCanvas;
29627
+ var init_ChemistryCanvas = __esm({
29628
+ "components/learning/molecules/ChemistryCanvas.tsx"() {
29629
+ "use client";
29630
+ init_atoms();
29631
+ init_Stack();
29632
+ init_LearningCanvas();
29633
+ ChemistryCanvas = ({
29634
+ className,
29635
+ width = 600,
29636
+ height = 400,
29637
+ title,
29638
+ backgroundColor,
29639
+ atoms = [],
29640
+ bonds = [],
29641
+ arrows = [],
29642
+ shapes = [],
29643
+ interactive = false,
29644
+ animate = false,
29645
+ onShapeClick,
29646
+ isLoading,
29647
+ error
29648
+ }) => {
29649
+ const derivedShapes = React107.useMemo(() => {
29650
+ const out = [];
29651
+ const atomById = /* @__PURE__ */ new Map();
29652
+ for (const a of atoms) {
29653
+ if (a.id) atomById.set(a.id, a);
29654
+ }
29655
+ for (const b of bonds) {
29656
+ const a = atomById.get(b.from);
29657
+ const c = atomById.get(b.to);
29658
+ if (!a || !c) continue;
29659
+ const color = b.color ?? "#6b7280";
29660
+ const strokeWidth = b.type === "double" ? 4 : b.type === "triple" ? 6 : 2;
29661
+ out.push({
29662
+ type: "line",
29663
+ x1: a.x,
29664
+ y1: a.y,
29665
+ x2: c.x,
29666
+ y2: c.y,
29667
+ color,
29668
+ lineWidth: strokeWidth
29669
+ });
29670
+ }
29671
+ for (const a of arrows) {
29672
+ const angle = (a.angle ?? 0) * (Math.PI / 180);
29673
+ const len = a.length ?? 60;
29674
+ const x2 = a.x + Math.cos(angle) * len;
29675
+ const y2 = a.y + Math.sin(angle) * len;
29676
+ out.push({
29677
+ type: "arrow",
29678
+ x1: a.x,
29679
+ y1: a.y,
29680
+ x2,
29681
+ y2,
29682
+ color: a.color ?? "#dc2626",
29683
+ lineWidth: 2
29684
+ });
29685
+ if (a.label) {
29686
+ out.push({
29687
+ type: "text",
29688
+ x: (a.x + x2) / 2,
29689
+ y: (a.y + y2) / 2 - 10,
29690
+ text: a.label,
29691
+ color: "#111827",
29692
+ fontSize: 12,
29693
+ align: "center"
29694
+ });
29695
+ }
29696
+ }
29697
+ for (const a of atoms) {
29698
+ out.push({
29699
+ type: "circle",
29700
+ x: a.x,
29701
+ y: a.y,
29702
+ radius: a.radius ?? 14,
29703
+ color: a.color ?? "#2563eb",
29704
+ fill: a.color ?? "#2563eb",
29705
+ id: a.id
29706
+ });
29707
+ if (a.element) {
29708
+ out.push({
29709
+ type: "text",
29710
+ x: a.x,
29711
+ y: a.y,
29712
+ text: a.element,
29713
+ color: "#ffffff",
29714
+ fontSize: 12,
29715
+ align: "center"
29716
+ });
29717
+ }
29718
+ }
29719
+ out.push(...shapes);
29720
+ return out;
29721
+ }, [atoms, bonds, arrows, shapes]);
29722
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
29723
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
29724
+ /* @__PURE__ */ jsxRuntime.jsx(
29725
+ LearningCanvas,
29726
+ {
29727
+ width,
29728
+ height,
29729
+ backgroundColor,
29730
+ shapes: derivedShapes,
29731
+ interactive,
29732
+ animate,
29733
+ onShapeClick,
29734
+ isLoading,
29735
+ error
29736
+ }
29737
+ )
29738
+ ] }) });
29739
+ };
29740
+ }
29741
+ });
29217
29742
  var CodeRunnerPanel;
29218
29743
  var init_CodeRunnerPanel = __esm({
29219
29744
  "components/core/organisms/CodeRunnerPanel.tsx"() {
@@ -34911,6 +35436,234 @@ var init_ProgressDots = __esm({
34911
35436
  ProgressDots.displayName = "ProgressDots";
34912
35437
  }
34913
35438
  });
35439
+ var MathCanvas;
35440
+ var init_MathCanvas = __esm({
35441
+ "components/learning/molecules/MathCanvas.tsx"() {
35442
+ "use client";
35443
+ init_atoms();
35444
+ init_Stack();
35445
+ init_LearningCanvas();
35446
+ MathCanvas = ({
35447
+ className,
35448
+ width = 600,
35449
+ height = 400,
35450
+ title,
35451
+ xMin = -10,
35452
+ xMax = 10,
35453
+ yMin = -10,
35454
+ yMax = 10,
35455
+ showAxes = true,
35456
+ showGrid = true,
35457
+ gridStep = 1,
35458
+ curves = [],
35459
+ points = [],
35460
+ vectors = [],
35461
+ shapes = [],
35462
+ interactive = false,
35463
+ animate = false,
35464
+ onShapeClick,
35465
+ isLoading,
35466
+ error
35467
+ }) => {
35468
+ const derivedShapes = React107.useMemo(() => {
35469
+ const out = [];
35470
+ const margin = 24;
35471
+ const plotW = width - margin * 2;
35472
+ const plotH = height - margin * 2;
35473
+ const mapX = (x) => margin + (x - xMin) / (xMax - xMin) * plotW;
35474
+ const mapY = (y) => height - (margin + (y - yMin) / (yMax - yMin) * plotH);
35475
+ if (showGrid) {
35476
+ for (let x = Math.ceil(xMin / gridStep) * gridStep; x <= xMax; x += gridStep) {
35477
+ const px = mapX(x);
35478
+ out.push({ type: "line", x1: px, y1: margin, x2: px, y2: height - margin, color: "#e5e7eb", lineWidth: 1 });
35479
+ }
35480
+ for (let y = Math.ceil(yMin / gridStep) * gridStep; y <= yMax; y += gridStep) {
35481
+ const py = mapY(y);
35482
+ out.push({ type: "line", x1: margin, y1: py, x2: width - margin, y2: py, color: "#e5e7eb", lineWidth: 1 });
35483
+ }
35484
+ }
35485
+ if (showAxes) {
35486
+ const xAxisY = Math.max(margin, Math.min(height - margin, mapY(0)));
35487
+ const yAxisX = Math.max(margin, Math.min(width - margin, mapX(0)));
35488
+ out.push({ type: "line", x1: margin, y1: xAxisY, x2: width - margin, y2: xAxisY, color: "#374151", lineWidth: 2 });
35489
+ out.push({ type: "line", x1: yAxisX, y1: margin, x2: yAxisX, y2: height - margin, color: "#374151", lineWidth: 2 });
35490
+ }
35491
+ for (const curve of curves) {
35492
+ if (!curve.samples || curve.samples.length < 2) continue;
35493
+ for (let i = 1; i < curve.samples.length; i++) {
35494
+ const a = curve.samples[i - 1];
35495
+ const b = curve.samples[i];
35496
+ if (a.x < xMin || a.x > xMax || b.x < xMin || b.x > xMax) continue;
35497
+ out.push({
35498
+ type: "line",
35499
+ x1: mapX(a.x),
35500
+ y1: mapY(a.y),
35501
+ x2: mapX(b.x),
35502
+ y2: mapY(b.y),
35503
+ color: curve.color ?? "#2563eb",
35504
+ lineWidth: 2
35505
+ });
35506
+ }
35507
+ }
35508
+ for (const p2 of points) {
35509
+ if (p2.x < xMin || p2.x > xMax || p2.y < yMin || p2.y > yMax) continue;
35510
+ out.push({
35511
+ type: "circle",
35512
+ x: mapX(p2.x),
35513
+ y: mapY(p2.y),
35514
+ radius: p2.radius ?? 4,
35515
+ color: p2.color ?? "#dc2626",
35516
+ fill: p2.color ?? "#dc2626"
35517
+ });
35518
+ if (p2.label) {
35519
+ out.push({ type: "text", x: mapX(p2.x) + 8, y: mapY(p2.y) - 8, text: p2.label, color: "#111827", fontSize: 12 });
35520
+ }
35521
+ }
35522
+ for (const v of vectors) {
35523
+ if (v.x < xMin || v.x > xMax || v.y < yMin || v.y > yMax) continue;
35524
+ const x1 = mapX(v.x);
35525
+ const y1 = mapY(v.y);
35526
+ const x2 = mapX(v.x + v.vx);
35527
+ const y2 = mapY(v.y + v.vy);
35528
+ out.push({ type: "arrow", x1, y1, x2, y2, color: v.color ?? "#7c3aed", lineWidth: 2 });
35529
+ if (v.label) {
35530
+ out.push({ type: "text", x: x2 + 6, y: y2 - 6, text: v.label, color: "#111827", fontSize: 12 });
35531
+ }
35532
+ }
35533
+ out.push(...shapes);
35534
+ return out;
35535
+ }, [width, height, xMin, xMax, yMin, yMax, showAxes, showGrid, gridStep, curves, points, vectors, shapes]);
35536
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
35537
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
35538
+ /* @__PURE__ */ jsxRuntime.jsx(
35539
+ LearningCanvas,
35540
+ {
35541
+ width,
35542
+ height,
35543
+ shapes: derivedShapes,
35544
+ interactive,
35545
+ animate,
35546
+ onShapeClick,
35547
+ isLoading,
35548
+ error
35549
+ }
35550
+ )
35551
+ ] }) });
35552
+ };
35553
+ }
35554
+ });
35555
+ var PhysicsCanvas;
35556
+ var init_PhysicsCanvas = __esm({
35557
+ "components/learning/molecules/PhysicsCanvas.tsx"() {
35558
+ "use client";
35559
+ init_atoms();
35560
+ init_Stack();
35561
+ init_LearningCanvas();
35562
+ PhysicsCanvas = ({
35563
+ className,
35564
+ width = 600,
35565
+ height = 400,
35566
+ title,
35567
+ backgroundColor,
35568
+ bodies = [],
35569
+ constraints = [],
35570
+ showVelocity = true,
35571
+ showForces = false,
35572
+ velocityScale = 20,
35573
+ forceScale = 20,
35574
+ shapes = [],
35575
+ interactive = false,
35576
+ animate = false,
35577
+ onShapeClick,
35578
+ isLoading,
35579
+ error
35580
+ }) => {
35581
+ const derivedShapes = React107.useMemo(() => {
35582
+ const out = [];
35583
+ const bodyById = /* @__PURE__ */ new Map();
35584
+ for (const b of bodies) {
35585
+ if (b.id) bodyById.set(b.id, b);
35586
+ }
35587
+ for (const c of constraints) {
35588
+ const a = bodyById.get(c.from);
35589
+ const b = bodyById.get(c.to);
35590
+ if (!a || !b) continue;
35591
+ out.push({
35592
+ type: "line",
35593
+ x1: a.x,
35594
+ y1: a.y,
35595
+ x2: b.x,
35596
+ y2: b.y,
35597
+ color: c.color ?? "#9ca3af",
35598
+ lineWidth: 2
35599
+ });
35600
+ }
35601
+ for (const b of bodies) {
35602
+ out.push({
35603
+ type: "circle",
35604
+ x: b.x,
35605
+ y: b.y,
35606
+ radius: b.radius ?? 12,
35607
+ color: b.color ?? "#2563eb",
35608
+ fill: b.color ?? "#2563eb",
35609
+ id: b.id
35610
+ });
35611
+ if (b.label) {
35612
+ out.push({
35613
+ type: "text",
35614
+ x: b.x + (b.radius ?? 12) + 6,
35615
+ y: b.y - (b.radius ?? 12) - 6,
35616
+ text: b.label,
35617
+ color: "#111827",
35618
+ fontSize: 12
35619
+ });
35620
+ }
35621
+ if (showVelocity && b.vx != null && b.vy != null && (b.vx !== 0 || b.vy !== 0)) {
35622
+ out.push({
35623
+ type: "arrow",
35624
+ x1: b.x,
35625
+ y1: b.y,
35626
+ x2: b.x + b.vx * velocityScale,
35627
+ y2: b.y + b.vy * velocityScale,
35628
+ color: "#16a34a",
35629
+ lineWidth: 2
35630
+ });
35631
+ }
35632
+ if (showForces && b.fx != null && b.fy != null && (b.fx !== 0 || b.fy !== 0)) {
35633
+ out.push({
35634
+ type: "arrow",
35635
+ x1: b.x,
35636
+ y1: b.y,
35637
+ x2: b.x + b.fx * forceScale,
35638
+ y2: b.y + b.fy * forceScale,
35639
+ color: "#dc2626",
35640
+ lineWidth: 2
35641
+ });
35642
+ }
35643
+ }
35644
+ out.push(...shapes);
35645
+ return out;
35646
+ }, [bodies, constraints, showVelocity, showForces, velocityScale, forceScale, shapes]);
35647
+ return /* @__PURE__ */ jsxRuntime.jsx(Card, { className, children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "sm", children: [
35648
+ title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h4", children: title }) : null,
35649
+ /* @__PURE__ */ jsxRuntime.jsx(
35650
+ LearningCanvas,
35651
+ {
35652
+ width,
35653
+ height,
35654
+ backgroundColor,
35655
+ shapes: derivedShapes,
35656
+ interactive,
35657
+ animate,
35658
+ onShapeClick,
35659
+ isLoading,
35660
+ error
35661
+ }
35662
+ )
35663
+ ] }) });
35664
+ };
35665
+ }
35666
+ });
34914
35667
  function resolveNodeColor(node, groups) {
34915
35668
  if (node.color) return node.color;
34916
35669
  if (node.group) {
@@ -35282,13 +36035,13 @@ var init_MapView = __esm({
35282
36035
  shadowSize: [41, 41]
35283
36036
  });
35284
36037
  L.Marker.prototype.options.icon = defaultIcon;
35285
- const { useEffect: useEffect75, useRef: useRef76, useCallback: useCallback117, useState: useState108 } = React107__namespace.default;
36038
+ const { useEffect: useEffect76, useRef: useRef77, useCallback: useCallback117, useState: useState108 } = React107__namespace.default;
35286
36039
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
35287
36040
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
35288
36041
  function MapUpdater({ centerLat, centerLng, zoom }) {
35289
36042
  const map = useMap();
35290
- const prevRef = useRef76({ centerLat, centerLng, zoom });
35291
- useEffect75(() => {
36043
+ const prevRef = useRef77({ centerLat, centerLng, zoom });
36044
+ useEffect76(() => {
35292
36045
  const prev = prevRef.current;
35293
36046
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
35294
36047
  map.setView([centerLat, centerLng], zoom);
@@ -35299,7 +36052,7 @@ var init_MapView = __esm({
35299
36052
  }
35300
36053
  function MapClickHandler({ onMapClick }) {
35301
36054
  const map = useMap();
35302
- useEffect75(() => {
36055
+ useEffect76(() => {
35303
36056
  if (!onMapClick) return;
35304
36057
  const handler = (e) => {
35305
36058
  onMapClick(e.latlng.lat, e.latlng.lng);
@@ -43740,7 +44493,7 @@ function getGroupColor(group, groups) {
43740
44493
  const idx = groups.indexOf(group);
43741
44494
  return GROUP_COLORS2[idx % GROUP_COLORS2.length];
43742
44495
  }
43743
- function resolveColor2(color, el) {
44496
+ function resolveColor3(color, el) {
43744
44497
  const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
43745
44498
  if (!m) return color;
43746
44499
  const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
@@ -44001,7 +44754,7 @@ var init_GraphCanvas = __esm({
44001
44754
  const w = logicalW;
44002
44755
  const h = height;
44003
44756
  const nodes = nodesRef.current;
44004
- const accentColor = resolveColor2("var(--color-accent)", canvas);
44757
+ const accentColor = resolveColor3("var(--color-accent)", canvas);
44005
44758
  const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
44006
44759
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
44007
44760
  ctx.clearRect(0, 0, w, h);
@@ -44040,7 +44793,7 @@ var init_GraphCanvas = __esm({
44040
44793
  ctx.globalAlpha = 1;
44041
44794
  for (const node of nodes) {
44042
44795
  const size = node.size || 8;
44043
- const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
44796
+ const color = resolveColor3(node.color || getGroupColor(node.group, groups), canvas);
44044
44797
  const isHovered = hoveredNode === node.id;
44045
44798
  const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
44046
44799
  ctx.globalAlpha = hoveredNode && !neighbors.has(node.id) ? 0.2 : 1;
@@ -50919,6 +51672,7 @@ var init_component_registry_generated = __esm({
50919
51672
  init_BattleBoard();
50920
51673
  init_BattleTemplate();
50921
51674
  init_BehaviorView();
51675
+ init_BiologyCanvas();
50922
51676
  init_BloomQuizBlock();
50923
51677
  init_BoardgameBoard();
50924
51678
  init_BookChapterView();
@@ -50948,6 +51702,7 @@ var init_component_registry_generated = __esm({
50948
51702
  init_ChartLegend();
50949
51703
  init_ChatBar();
50950
51704
  init_Checkbox();
51705
+ init_ChemistryCanvas();
50951
51706
  init_ChoiceButton();
50952
51707
  init_CityBuilderBoard();
50953
51708
  init_CityBuilderTemplate();
@@ -51039,6 +51794,7 @@ var init_component_registry_generated = __esm({
51039
51794
  init_JazariStateMachine();
51040
51795
  init_LandingPageTemplate();
51041
51796
  init_LawReferenceTooltip();
51797
+ init_LearningCanvas();
51042
51798
  init_Lightbox();
51043
51799
  init_LikertScale();
51044
51800
  init_LineChart();
@@ -51047,9 +51803,11 @@ var init_component_registry_generated = __esm({
51047
51803
  init_MapView();
51048
51804
  init_MarkdownContent();
51049
51805
  init_MarketingFooter();
51806
+ init_MarketingStatCard();
51050
51807
  init_MasterDetail();
51051
51808
  init_MasterDetailLayout();
51052
51809
  init_MatchPuzzleBoard();
51810
+ init_MathCanvas();
51053
51811
  init_MatrixQuestion();
51054
51812
  init_MediaGallery();
51055
51813
  init_Menu();
@@ -51068,6 +51826,7 @@ var init_component_registry_generated = __esm({
51068
51826
  init_PageHeader();
51069
51827
  init_Pagination();
51070
51828
  init_PatternTile();
51829
+ init_PhysicsCanvas();
51071
51830
  init_PinballBoard();
51072
51831
  init_PirateBoard();
51073
51832
  init_PlatformerBoard();
@@ -51244,6 +52003,7 @@ var init_component_registry_generated = __esm({
51244
52003
  "BattleBoard": BattleBoard,
51245
52004
  "BattleTemplate": BattleTemplate,
51246
52005
  "BehaviorView": BehaviorView,
52006
+ "BiologyCanvas": BiologyCanvas,
51247
52007
  "BloomQuizBlock": BloomQuizBlock,
51248
52008
  "BoardgameBoard": BoardgameBoard,
51249
52009
  "BookChapterView": BookChapterView,
@@ -51276,6 +52036,7 @@ var init_component_registry_generated = __esm({
51276
52036
  "ChartLegend": ChartLegend,
51277
52037
  "ChatBar": ChatBar,
51278
52038
  "Checkbox": Checkbox,
52039
+ "ChemistryCanvas": ChemistryCanvas,
51279
52040
  "ChoiceButton": ChoiceButton,
51280
52041
  "CityBuilderBoard": CityBuilderBoard,
51281
52042
  "CityBuilderTemplate": CityBuilderTemplate,
@@ -51377,6 +52138,7 @@ var init_component_registry_generated = __esm({
51377
52138
  "LabelPattern": LabelPattern,
51378
52139
  "LandingPageTemplate": LandingPageTemplate,
51379
52140
  "LawReferenceTooltip": LawReferenceTooltip,
52141
+ "LearningCanvas": LearningCanvas,
51380
52142
  "Lightbox": Lightbox,
51381
52143
  "LikertScale": LikertScale,
51382
52144
  "LineChart": LineChart2,
@@ -51385,9 +52147,11 @@ var init_component_registry_generated = __esm({
51385
52147
  "MapView": MapView,
51386
52148
  "MarkdownContent": MarkdownContent,
51387
52149
  "MarketingFooter": MarketingFooter,
52150
+ "MarketingStatCard": MarketingStatCard,
51388
52151
  "MasterDetail": MasterDetail,
51389
52152
  "MasterDetailLayout": MasterDetailLayout,
51390
52153
  "MatchPuzzleBoard": MatchPuzzleBoard,
52154
+ "MathCanvas": MathCanvas,
51391
52155
  "MatrixQuestion": MatrixQuestion,
51392
52156
  "MediaGallery": MediaGallery,
51393
52157
  "Menu": Menu,
@@ -51406,6 +52170,7 @@ var init_component_registry_generated = __esm({
51406
52170
  "PageHeader": PageHeader,
51407
52171
  "Pagination": Pagination,
51408
52172
  "PatternTile": PatternTile,
52173
+ "PhysicsCanvas": PhysicsCanvas,
51409
52174
  "PinballBoard": PinballBoard,
51410
52175
  "PirateBoard": PirateBoard,
51411
52176
  "PlatformerBoard": PlatformerBoard,