@tomaszjarosz/react-visualizers 0.2.4 → 0.2.7

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/index.cjs CHANGED
@@ -5601,6 +5601,7 @@ const LinkedHashMapVisualizerComponent = ({
5601
5601
  });
5602
5602
  const stepData = currentStepData || {
5603
5603
  operation: "init",
5604
+ key: "",
5604
5605
  buckets: [],
5605
5606
  linkedOrder: [],
5606
5607
  description: ""
@@ -5681,9 +5682,30 @@ const LinkedHashMapVisualizerComponent = ({
5681
5682
  ] }) }),
5682
5683
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
5683
5684
  /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 400, className: showCode ? "flex-1" : "w-full", children: [
5684
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 p-2 bg-amber-50 rounded text-xs text-amber-700", children: [
5685
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Dual structure:" }),
5686
- " Hash table (O(1) lookup) + Doubly-linked list (ordered iteration)"
5685
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-orange-50 to-amber-50 rounded-xl border-2 border-orange-200", children: [
5686
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-bold text-orange-800 mb-3 flex items-center gap-2", children: [
5687
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg", children: "🔗" }),
5688
+ " LinkedHashMap = HashMap + LinkedList"
5689
+ ] }),
5690
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: [
5691
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 rounded-lg border border-orange-200", children: [
5692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-gray-700 mb-1", children: "🗂️ Hash Table" }),
5693
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-gray-500", children: "O(1) get/put • Same as HashMap" })
5694
+ ] }),
5695
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white p-3 rounded-lg border border-orange-200", children: [
5696
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-gray-700 mb-1", children: "🔗 Doubly Linked List" }),
5697
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] text-gray-500", children: [
5698
+ accessOrder ? "Access order (LRU cache)" : "Insertion order",
5699
+ " • O(1) reorder"
5700
+ ] })
5701
+ ] })
5702
+ ] }),
5703
+ stepData.operation === "access" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-orange-100 rounded-lg border border-orange-300", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-center text-orange-800", children: [
5704
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold", children: "LRU Update:" }),
5705
+ ' Entry "',
5706
+ stepData.key,
5707
+ '" moved to end of list (most recently used)'
5708
+ ] }) })
5687
5709
  ] }),
5688
5710
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
5689
5711
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-medium text-gray-700 mb-2", children: [
@@ -5715,22 +5737,31 @@ const LinkedHashMapVisualizerComponent = ({
5715
5737
  ] }, eIdx)) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-gray-400 mt-1", children: "∅" }) })
5716
5738
  ] }, idx)) })
5717
5739
  ] }),
5718
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
5719
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: accessOrder ? "Access Order (LRU: oldest → newest)" : "Insertion Order" }),
5720
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-1", children: linkedOrder.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5721
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-gray-500", children: "HEAD →" }),
5722
- linkedOrder.map((key, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
5723
- idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-orange-400", children: "→" }),
5724
- /* @__PURE__ */ jsxRuntime.jsx(
5725
- "div",
5726
- {
5727
- className: `px-2 py-0.5 text-xs font-medium rounded transition-all ${getLinkedNodeStyle(key)}`,
5728
- children: key
5729
- }
5730
- )
5731
- ] }, key)),
5732
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-gray-500", children: "→ TAIL" })
5733
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 italic", children: "Empty list" }) })
5740
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 p-3 bg-gradient-to-r from-orange-100 to-amber-100 rounded-xl border-2 border-orange-300", children: [
5741
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-semibold text-orange-800 mb-2 flex items-center gap-2", children: [
5742
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "🔗" }),
5743
+ " ",
5744
+ accessOrder ? "Access Order (LRU: oldest newest)" : "Insertion Order"
5745
+ ] }),
5746
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-lg p-3 border border-orange-200", children: [
5747
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-1", children: linkedOrder.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5748
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1 bg-gray-100 text-[10px] text-gray-600 rounded font-semibold", children: "HEAD" }),
5749
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-orange-400 font-bold", children: "→" }),
5750
+ linkedOrder.map((key, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
5751
+ idx > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-orange-400 font-bold", children: "⇄" }),
5752
+ /* @__PURE__ */ jsxRuntime.jsx(
5753
+ "div",
5754
+ {
5755
+ className: `px-3 py-1 text-xs font-bold rounded-full transition-colors ${getLinkedNodeStyle(key)}`,
5756
+ children: key
5757
+ }
5758
+ )
5759
+ ] }, key)),
5760
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-orange-400 font-bold", children: "→" }),
5761
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1 bg-gray-100 text-[10px] text-gray-600 rounded font-semibold", children: "TAIL" })
5762
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 italic", children: "HEAD → TAIL (empty)" }) }),
5763
+ linkedOrder.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 pt-2 border-t border-orange-200 text-[10px] text-gray-500 text-center", children: "Doubly linked: each entry has prev/next pointers" })
5764
+ ] })
5734
5765
  ] }),
5735
5766
  accessOrder && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 p-3 bg-blue-50 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-blue-700", children: [
5736
5767
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "LRU Cache Usage:" }),
@@ -6977,6 +7008,59 @@ const TreeSetVisualizerComponent = ({
6977
7008
  ] }) }),
6978
7009
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
6979
7010
  /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 400, className: showCode ? "flex-1" : "w-full", children: [
7011
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-emerald-50 to-teal-50 rounded-xl border-2 border-emerald-200", children: [
7012
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-bold text-emerald-800 mb-3 flex items-center gap-2", children: [
7013
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg", children: "🌳" }),
7014
+ " Binary Search Tree Property"
7015
+ ] }),
7016
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-emerald-200", children: [
7017
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center text-emerald-700 font-bold text-base mb-2", children: [
7018
+ "left < ",
7019
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-800", children: "node" }),
7020
+ " < right"
7021
+ ] }),
7022
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-gray-500 text-center", children: "All values in left subtree are smaller • All values in right subtree are larger" })
7023
+ ] }),
7024
+ currentStepData.operation === "add" && currentStepData.value !== void 0 && currentNode !== void 0 && currentNode !== currentStepData.value && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-emerald-200", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-center", children: [
7025
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-emerald-700", children: "Comparing:" }),
7026
+ " ",
7027
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
7028
+ currentStepData.value,
7029
+ " ",
7030
+ currentStepData.value < currentNode ? "<" : ">",
7031
+ " ",
7032
+ currentNode
7033
+ ] }),
7034
+ " → ",
7035
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `font-bold ${currentStepData.value < currentNode ? "text-blue-600" : "text-orange-600"}`, children: [
7036
+ "Go ",
7037
+ currentStepData.value < currentNode ? "LEFT" : "RIGHT"
7038
+ ] })
7039
+ ] }) }),
7040
+ currentStepData.operation === "contains" && currentStepData.value !== void 0 && currentNode !== void 0 && !found && path.length > 0 && path[path.length - 1] !== currentStepData.value && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-emerald-200", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-center", children: [
7041
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-emerald-700", children: "Comparing:" }),
7042
+ " ",
7043
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
7044
+ currentStepData.value,
7045
+ " ",
7046
+ currentStepData.value < currentNode ? "<" : ">",
7047
+ " ",
7048
+ currentNode
7049
+ ] }),
7050
+ " → ",
7051
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `font-bold ${currentStepData.value < currentNode ? "text-blue-600" : "text-orange-600"}`, children: [
7052
+ "Go ",
7053
+ currentStepData.value < currentNode ? "LEFT" : "RIGHT"
7054
+ ] })
7055
+ ] }) }),
7056
+ found === true && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-green-100 rounded-lg border border-green-300", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-center text-green-800 font-bold", children: [
7057
+ "✓ Found! ",
7058
+ currentStepData.value,
7059
+ " == ",
7060
+ currentNode
7061
+ ] }) }),
7062
+ found === false && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-red-100 rounded-lg border border-red-300", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-center text-red-800 font-bold", children: "✗ Not found! Reached null (no more children to check)" }) })
7063
+ ] }),
6980
7064
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
6981
7065
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Binary Search Tree" }),
6982
7066
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-gray-50 rounded-lg p-2 overflow-x-auto", children: tree ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "300", height: "250", className: "mx-auto", children: renderTree(tree) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-32 flex items-center justify-center text-gray-400 text-sm", children: "Empty tree" }) })
@@ -7440,6 +7524,7 @@ const HEAP_CODE = [
7440
7524
  const LEGEND_ITEMS$6 = [
7441
7525
  { color: "bg-purple-100", label: "Root (min)", border: "#c4b5fd" },
7442
7526
  { color: "bg-purple-500", label: "Active" },
7527
+ { color: "bg-purple-200", label: "Sift Path", border: "#a78bfa" },
7443
7528
  { color: "bg-yellow-300", label: "Comparing" },
7444
7529
  { color: "bg-green-400", label: "Swapped" }
7445
7530
  ];
@@ -7456,6 +7541,15 @@ function generateHeapSteps() {
7456
7541
  if (op === "offer" && value !== void 0) {
7457
7542
  heap.push(value);
7458
7543
  let idx = heap.length - 1;
7544
+ const getPathToRoot = (index) => {
7545
+ const path = [index];
7546
+ let i = index;
7547
+ while (i > 0) {
7548
+ i = Math.floor((i - 1) / 2);
7549
+ path.push(i);
7550
+ }
7551
+ return path;
7552
+ };
7459
7553
  steps.push({
7460
7554
  operation: "offer",
7461
7555
  value,
@@ -7463,7 +7557,9 @@ function generateHeapSteps() {
7463
7557
  description: `offer(${value}): Add to end of heap at index ${idx}`,
7464
7558
  codeLine: 1,
7465
7559
  variables: { value, index: idx },
7466
- highlightIndex: idx
7560
+ highlightIndex: idx,
7561
+ siftPath: getPathToRoot(idx),
7562
+ currentIndex: idx
7467
7563
  });
7468
7564
  while (idx > 0) {
7469
7565
  const parentIdx = Math.floor((idx - 1) / 2);
@@ -7478,7 +7574,9 @@ function generateHeapSteps() {
7478
7574
  child: heap[idx],
7479
7575
  parentVal: heap[parentIdx]
7480
7576
  },
7481
- compareIndices: [idx, parentIdx]
7577
+ compareIndices: [idx, parentIdx],
7578
+ siftPath: getPathToRoot(idx),
7579
+ currentIndex: idx
7482
7580
  });
7483
7581
  if (heap[idx] < heap[parentIdx]) {
7484
7582
  [heap[idx], heap[parentIdx]] = [heap[parentIdx], heap[idx]];
@@ -7489,7 +7587,9 @@ function generateHeapSteps() {
7489
7587
  codeLine: 8,
7490
7588
  variables: { swapped: heap[parentIdx], index: parentIdx },
7491
7589
  swapIndices: [idx, parentIdx],
7492
- highlightIndex: parentIdx
7590
+ highlightIndex: parentIdx,
7591
+ siftPath: getPathToRoot(parentIdx),
7592
+ currentIndex: parentIdx
7493
7593
  });
7494
7594
  idx = parentIdx;
7495
7595
  } else {
@@ -7499,7 +7599,9 @@ function generateHeapSteps() {
7499
7599
  description: `siftUp: ${heap[idx]} >= ${heap[parentIdx]}, heap property satisfied!`,
7500
7600
  codeLine: 7,
7501
7601
  variables: { index: idx },
7502
- highlightIndex: idx
7602
+ highlightIndex: idx,
7603
+ siftPath: getPathToRoot(idx),
7604
+ currentIndex: idx
7503
7605
  });
7504
7606
  break;
7505
7607
  }
@@ -7509,6 +7611,21 @@ function generateHeapSteps() {
7509
7611
  const removed = heap[0];
7510
7612
  const last = heap.pop();
7511
7613
  if (last === void 0) continue;
7614
+ const getPathToLeaf = (heapSize, startIdx) => {
7615
+ const path = [startIdx];
7616
+ let i = startIdx;
7617
+ while (2 * i + 1 < heapSize) {
7618
+ const left = 2 * i + 1;
7619
+ const right = 2 * i + 2;
7620
+ if (right < heapSize) {
7621
+ path.push(left, right);
7622
+ } else {
7623
+ path.push(left);
7624
+ }
7625
+ i = left;
7626
+ }
7627
+ return path;
7628
+ };
7512
7629
  if (heap.length === 0) {
7513
7630
  steps.push({
7514
7631
  operation: "poll",
@@ -7528,7 +7645,9 @@ function generateHeapSteps() {
7528
7645
  description: `poll(): Remove min ${removed}, move last element ${last} to root`,
7529
7646
  codeLine: 13,
7530
7647
  variables: { removed, moved: last },
7531
- highlightIndex: 0
7648
+ highlightIndex: 0,
7649
+ siftPath: getPathToLeaf(heap.length, 0),
7650
+ currentIndex: 0
7532
7651
  });
7533
7652
  let idx = 0;
7534
7653
  while (true) {
@@ -7548,7 +7667,8 @@ function generateHeapSteps() {
7548
7667
  description: `siftDown: ${heap[idx]} is smaller than children, heap property satisfied!`,
7549
7668
  codeLine: 14,
7550
7669
  variables: { index: idx, value: heap[idx] },
7551
- highlightIndex: idx
7670
+ highlightIndex: idx,
7671
+ currentIndex: idx
7552
7672
  });
7553
7673
  break;
7554
7674
  }
@@ -7562,7 +7682,9 @@ function generateHeapSteps() {
7562
7682
  child: heap[smallestIdx],
7563
7683
  childIdx: smallestIdx
7564
7684
  },
7565
- compareIndices: [idx, smallestIdx]
7685
+ compareIndices: [idx, smallestIdx],
7686
+ siftPath: [idx, leftIdx < heap.length ? leftIdx : -1, rightIdx < heap.length ? rightIdx : -1].filter((i) => i >= 0),
7687
+ currentIndex: idx
7566
7688
  });
7567
7689
  [heap[idx], heap[smallestIdx]] = [heap[smallestIdx], heap[idx]];
7568
7690
  steps.push({
@@ -7572,7 +7694,8 @@ function generateHeapSteps() {
7572
7694
  codeLine: 14,
7573
7695
  variables: { index: smallestIdx },
7574
7696
  swapIndices: [idx, smallestIdx],
7575
- highlightIndex: smallestIdx
7697
+ highlightIndex: smallestIdx,
7698
+ currentIndex: smallestIdx
7576
7699
  });
7577
7700
  idx = smallestIdx;
7578
7701
  }
@@ -7698,7 +7821,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7698
7821
  heap: [],
7699
7822
  description: ""
7700
7823
  };
7701
- const { heap, highlightIndex, swapIndices, compareIndices, description } = currentStepData;
7824
+ const { heap, highlightIndex, swapIndices, compareIndices, description, siftPath, currentIndex } = currentStepData;
7702
7825
  const positions = getTreePositions(heap.length);
7703
7826
  const getNodeStyle = (idx) => {
7704
7827
  if (idx === highlightIndex) {
@@ -7710,11 +7833,25 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7710
7833
  if (compareIndices == null ? void 0 : compareIndices.includes(idx)) {
7711
7834
  return "fill-yellow-300 stroke-yellow-400";
7712
7835
  }
7836
+ if ((siftPath == null ? void 0 : siftPath.includes(idx)) && idx !== currentIndex) {
7837
+ return "fill-purple-200 stroke-purple-400";
7838
+ }
7713
7839
  if (idx === 0) {
7714
7840
  return "fill-purple-100 stroke-purple-300";
7715
7841
  }
7716
7842
  return "fill-white stroke-gray-300";
7717
7843
  };
7844
+ const isEdgeOnPath = (parentIdx, childIdx) => {
7845
+ if (!siftPath || siftPath.length < 2) return false;
7846
+ for (let i = 0; i < siftPath.length - 1; i++) {
7847
+ const a = siftPath[i];
7848
+ const b = siftPath[i + 1];
7849
+ if (a === parentIdx && b === childIdx || a === childIdx && b === parentIdx) {
7850
+ return true;
7851
+ }
7852
+ }
7853
+ return false;
7854
+ };
7718
7855
  const getTextColor = (idx) => {
7719
7856
  if (idx === highlightIndex || (swapIndices == null ? void 0 : swapIndices.includes(idx))) {
7720
7857
  return "white";
@@ -7735,6 +7872,49 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7735
7872
  ] }) }) }),
7736
7873
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
7737
7874
  /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 400, children: [
7875
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 p-4 bg-gradient-to-r from-purple-50 to-pink-50 rounded-xl border-2 border-purple-200", children: [
7876
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-bold text-purple-800 mb-3 flex items-center gap-2", children: [
7877
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg", children: "🏔️" }),
7878
+ " Min-Heap Property"
7879
+ ] }),
7880
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-purple-200", children: [
7881
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center text-purple-700 font-bold mb-2", children: "heap[parent] ≤ heap[children]" }),
7882
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2 text-xs text-gray-600", children: [
7883
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
7884
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: "parent(i)" }),
7885
+ " = ⌊(i-1)/2⌋"
7886
+ ] }),
7887
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
7888
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: "left(i)" }),
7889
+ " = 2i + 1"
7890
+ ] }),
7891
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-purple-50 p-2 rounded text-center", children: [
7892
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: "right(i)" }),
7893
+ " = 2i + 2"
7894
+ ] })
7895
+ ] })
7896
+ ] }),
7897
+ currentIndex !== void 0 && currentIndex >= 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 p-2 bg-white rounded-lg border border-purple-200", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-600 text-center", children: [
7898
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-purple-700", children: [
7899
+ "Current: i = ",
7900
+ currentIndex
7901
+ ] }),
7902
+ currentIndex > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mx-2", children: [
7903
+ "→ parent(",
7904
+ currentIndex,
7905
+ ") = ⌊(",
7906
+ currentIndex,
7907
+ "-1)/2⌋ = ",
7908
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-purple-600 font-bold", children: Math.floor((currentIndex - 1) / 2) })
7909
+ ] }),
7910
+ 2 * currentIndex + 1 < heap.length && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mx-2", children: [
7911
+ "→ left(",
7912
+ currentIndex,
7913
+ ") = ",
7914
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-purple-600 font-bold", children: 2 * currentIndex + 1 })
7915
+ ] })
7916
+ ] }) })
7917
+ ] }),
7738
7918
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
7739
7919
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Binary Heap Structure" }),
7740
7920
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-gray-50 rounded-lg p-2 overflow-x-auto", children: heap.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
@@ -7751,6 +7931,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7751
7931
  const childPos = positions[idx];
7752
7932
  if (!parentPos || !childPos) return null;
7753
7933
  const isHighlighted = (compareIndices == null ? void 0 : compareIndices.includes(idx)) && (compareIndices == null ? void 0 : compareIndices.includes(parentIdx)) || (swapIndices == null ? void 0 : swapIndices.includes(idx)) && (swapIndices == null ? void 0 : swapIndices.includes(parentIdx));
7934
+ const isOnPath = isEdgeOnPath(parentIdx, idx);
7754
7935
  return /* @__PURE__ */ jsxRuntime.jsx(
7755
7936
  "line",
7756
7937
  {
@@ -7758,8 +7939,9 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7758
7939
  y1: parentPos.y,
7759
7940
  x2: childPos.x,
7760
7941
  y2: childPos.y,
7761
- stroke: isHighlighted ? "#a855f7" : "#d1d5db",
7762
- strokeWidth: isHighlighted ? 2 : 1
7942
+ stroke: isHighlighted ? "#a855f7" : isOnPath ? "#c4b5fd" : "#d1d5db",
7943
+ strokeWidth: isHighlighted ? 3 : isOnPath ? 2 : 1,
7944
+ strokeDasharray: isOnPath && !isHighlighted ? "4,2" : void 0
7763
7945
  },
7764
7946
  `edge-${idx}`
7765
7947
  );
@@ -7776,7 +7958,7 @@ const PriorityQueueVisualizerComponent = ({ showControls = true, showCode = true
7776
7958
  "circle",
7777
7959
  {
7778
7960
  r: "18",
7779
- className: `${getNodeStyle(idx)} stroke-2 transition-all`
7961
+ className: `${getNodeStyle(idx)} stroke-2 transition-colors`
7780
7962
  }
7781
7963
  ),
7782
7964
  /* @__PURE__ */ jsxRuntime.jsx(