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