@lv-x-software-house/x_view 1.2.6-dev.77 → 1.2.6-dev.79

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 (3) hide show
  1. package/dist/index.js +148 -107
  2. package/dist/index.mjs +148 -107
  3. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -706,20 +706,20 @@ var updateSceneHighlights = (state) => {
706
706
  var addNewNodeToScene = (state, newNodeData, newLinkData, position) => {
707
707
  const {
708
708
  graphGroup,
709
- nodeObjects: nodeObjects2,
709
+ nodeObjects,
710
710
  clickableNodes,
711
711
  allLinks,
712
712
  glowTexture,
713
713
  renderer
714
714
  } = state;
715
- const sourceNodeMesh = nodeObjects2[String(newLinkData.source)];
715
+ const sourceNodeMesh = nodeObjects[String(newLinkData.source)];
716
716
  if (!sourceNodeMesh || !graphGroup) return;
717
717
  const mesh = createNodeMesh(newNodeData, position, glowTexture);
718
718
  graphGroup.add(mesh);
719
719
  if (mesh.userData.labelObject) {
720
720
  graphGroup.add(mesh.userData.labelObject);
721
721
  }
722
- nodeObjects2[String(newNodeData.id)] = mesh;
722
+ nodeObjects[String(newNodeData.id)] = mesh;
723
723
  clickableNodes.push(mesh);
724
724
  const resolution = new THREE.Vector2(
725
725
  renderer.domElement.clientWidth,
@@ -737,9 +737,9 @@ var addNewNodeToScene = (state, newNodeData, newLinkData, position) => {
737
737
  });
738
738
  };
739
739
  var addNewLinkToScene = (state, newLinkData) => {
740
- const { graphGroup, nodeObjects: nodeObjects2, allLinks, renderer } = state;
741
- const sourceNodeMesh = nodeObjects2[String(newLinkData.source)];
742
- const targetNodeMesh = nodeObjects2[String(newLinkData.target)];
740
+ const { graphGroup, nodeObjects, allLinks, renderer } = state;
741
+ const sourceNodeMesh = nodeObjects[String(newLinkData.source)];
742
+ const targetNodeMesh = nodeObjects[String(newLinkData.target)];
743
743
  if (!sourceNodeMesh || !targetNodeMesh || !graphGroup) return;
744
744
  const resolution = new THREE.Vector2(
745
745
  renderer.domElement.clientWidth,
@@ -784,12 +784,12 @@ var removeLinkFromScene = (state, linkObject) => {
784
784
  var removeNodeFromScene = (state, nodeId) => {
785
785
  const {
786
786
  graphGroup,
787
- nodeObjects: nodeObjects2,
787
+ nodeObjects,
788
788
  clickableNodes,
789
789
  allLinks,
790
790
  timelineIntervalsGroup
791
791
  } = state;
792
- const nodeToRemove = nodeObjects2[String(nodeId)];
792
+ const nodeToRemove = nodeObjects[String(nodeId)];
793
793
  if (!nodeToRemove) return;
794
794
  const strNodeId = String(nodeId);
795
795
  const linksToRemove = [...allLinks].filter(
@@ -798,7 +798,7 @@ var removeNodeFromScene = (state, nodeId) => {
798
798
  linksToRemove.forEach((link) => removeLinkFromScene(state, link));
799
799
  const nodeIdx = clickableNodes.indexOf(nodeToRemove);
800
800
  if (nodeIdx > -1) clickableNodes.splice(nodeIdx, 1);
801
- delete nodeObjects2[strNodeId];
801
+ delete nodeObjects[strNodeId];
802
802
  if (graphGroup && nodeToRemove.userData.labelObject) {
803
803
  const label = nodeToRemove.userData.labelObject;
804
804
  graphGroup.remove(label);
@@ -833,7 +833,7 @@ var removeNodeFromScene = (state, nodeId) => {
833
833
  }
834
834
  };
835
835
  var addStandaloneNodeToScene = (state, nodeData, position, forceShowQuestDate = false) => {
836
- const { graphGroup, nodeObjects: nodeObjects2, clickableNodes, glowTexture } = state;
836
+ const { graphGroup, nodeObjects, clickableNodes, glowTexture } = state;
837
837
  if (!graphGroup) return;
838
838
  const mesh = createNodeMesh(nodeData, position, glowTexture, forceShowQuestDate);
839
839
  mesh.scale.set(0.01, 0.01, 0.01);
@@ -841,7 +841,7 @@ var addStandaloneNodeToScene = (state, nodeData, position, forceShowQuestDate =
841
841
  if (mesh.userData.labelObject) {
842
842
  graphGroup.add(mesh.userData.labelObject);
843
843
  }
844
- nodeObjects2[String(nodeData.id)] = mesh;
844
+ nodeObjects[String(nodeData.id)] = mesh;
845
845
  clickableNodes.push(mesh);
846
846
  if (state.tweenGroup) {
847
847
  const targetScale = NODE_SCALE_FACTORS[nodeData.size || "medium"] || 1;
@@ -879,7 +879,7 @@ var userActionHandlers = {
879
879
  const { stateRef, setters, tweenToTarget } = context;
880
880
  setters.setContextMenu({ visible: false });
881
881
  setters.setRelationshipMenu({ visible: false });
882
- const { graphGroup, nodeObjects: nodeObjects2, renderer, ghostElements, glowTexture } = stateRef.current;
882
+ const { graphGroup, nodeObjects, renderer, ghostElements, glowTexture } = stateRef.current;
883
883
  if (ghostElements.node && graphGroup) {
884
884
  graphGroup.remove(ghostElements.node);
885
885
  ghostElements.node.traverse((child) => {
@@ -895,7 +895,7 @@ var userActionHandlers = {
895
895
  ghostElements.line.geometry.dispose();
896
896
  ghostElements.line.material.dispose();
897
897
  }
898
- const sourceNodeMesh = nodeObjects2[String(sourceNodeData.id)];
898
+ const sourceNodeMesh = nodeObjects[String(sourceNodeData.id)];
899
899
  if (!sourceNodeMesh || !graphGroup || !renderer) return;
900
900
  stateRef.current.creation = { isActive: true, sourceNodeData };
901
901
  const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
@@ -1073,7 +1073,7 @@ var userActionHandlers = {
1073
1073
  const { stateRef, setters, tweenToTarget } = context;
1074
1074
  setters.setContextMenu({ visible: false });
1075
1075
  setters.setRelationshipMenu({ visible: false });
1076
- const { graphGroup, nodeObjects: nodeObjects2, renderer, ghostElements, glowTexture } = stateRef.current;
1076
+ const { graphGroup, nodeObjects, renderer, ghostElements, glowTexture } = stateRef.current;
1077
1077
  if (ghostElements.node && graphGroup) {
1078
1078
  if (ghostElements.node.userData.labelObject) {
1079
1079
  graphGroup.remove(ghostElements.node.userData.labelObject);
@@ -1095,7 +1095,7 @@ var userActionHandlers = {
1095
1095
  ghostElements.line.geometry.dispose();
1096
1096
  ghostElements.line.material.dispose();
1097
1097
  }
1098
- const sourceNodeMesh = nodeObjects2[String(sourceNodeData.id)];
1098
+ const sourceNodeMesh = nodeObjects[String(sourceNodeData.id)];
1099
1099
  if (!sourceNodeMesh || !graphGroup || !renderer) return;
1100
1100
  stateRef.current.creation = { isActive: true, sourceNodeData };
1101
1101
  const ghostGeometry = new THREE.SphereGeometry(1.5, 32, 32);
@@ -1276,7 +1276,7 @@ var userActionHandlers = {
1276
1276
  } = context;
1277
1277
  const {
1278
1278
  graphGroup,
1279
- nodeObjects: nodeObjects2,
1279
+ nodeObjects,
1280
1280
  clickableNodes,
1281
1281
  allLinks,
1282
1282
  glowTexture,
@@ -1285,7 +1285,7 @@ var userActionHandlers = {
1285
1285
  } = stateRef.current;
1286
1286
  if (!graphGroup || !sceneDataRef.current || !graphDataRef.current || !linksToExpand || linksToExpand.length === 0)
1287
1287
  return;
1288
- const sourceNodeMesh = nodeObjects2[String(sourceNode.id)];
1288
+ const sourceNodeMesh = nodeObjects[String(sourceNode.id)];
1289
1289
  if (!sourceNodeMesh) return;
1290
1290
  const resolution = new THREE.Vector2(
1291
1291
  mountRef.current.clientWidth,
@@ -1297,7 +1297,7 @@ var userActionHandlers = {
1297
1297
  var _a;
1298
1298
  const isSource = String(link.source) === String(sourceNode.id);
1299
1299
  const targetNodeId = isSource ? link.target : link.source;
1300
- if (!nodeObjects2[String(targetNodeId)]) {
1300
+ if (!nodeObjects[String(targetNodeId)]) {
1301
1301
  const allParentNodes = Object.values(graphDataRef.current).flatMap(
1302
1302
  (fileData) => fileData.nodes
1303
1303
  );
@@ -1325,7 +1325,7 @@ var userActionHandlers = {
1325
1325
  if (targetMesh.userData.labelObject) {
1326
1326
  graphGroup.add(targetMesh.userData.labelObject);
1327
1327
  }
1328
- nodeObjects2[String(targetNodeId)] = targetMesh;
1328
+ nodeObjects[String(targetNodeId)] = targetMesh;
1329
1329
  clickableNodes.push(targetMesh);
1330
1330
  const posTween = new Tween(targetMesh.position).to(endPosition, 1200).easing(Easing.Quadratic.Out);
1331
1331
  tweenGroup.add(posTween);
@@ -1344,8 +1344,8 @@ var userActionHandlers = {
1344
1344
  (l) => String(l.userData.id) === String(link.id)
1345
1345
  );
1346
1346
  if (linkAlreadyInSceneObjects) return;
1347
- const sourceMesh = nodeObjects2[String(link.source)];
1348
- const targetMesh = nodeObjects2[String(link.target)];
1347
+ const sourceMesh = nodeObjects[String(link.source)];
1348
+ const targetMesh = nodeObjects[String(link.target)];
1349
1349
  if (sourceMesh && targetMesh) {
1350
1350
  const currentLinksBetweenNodesData = allLinks.filter(
1351
1351
  (l) => String(l.userData.source) === String(link.source) && String(l.userData.target) === String(link.target) || String(l.userData.source) === String(link.target) && String(l.userData.target) === String(link.source)
@@ -1407,8 +1407,8 @@ var userActionHandlers = {
1407
1407
  const { stateRef, mountRef, setters } = context;
1408
1408
  setters.setContextMenu({ visible: false });
1409
1409
  setters.setRelationshipMenu({ visible: false });
1410
- const { graphGroup, nodeObjects: nodeObjects2, renderer, controls } = stateRef.current;
1411
- const sourceNodeMesh = nodeObjects2[String(sourceNodeData.id)];
1410
+ const { graphGroup, nodeObjects, renderer, controls } = stateRef.current;
1411
+ const sourceNodeMesh = nodeObjects[String(sourceNodeData.id)];
1412
1412
  if (!sourceNodeMesh || !graphGroup || !renderer) return;
1413
1413
  controls.enabled = false;
1414
1414
  if (mountRef.current) mountRef.current.style.cursor = "crosshair";
@@ -1581,7 +1581,7 @@ var userActionHandlers = {
1581
1581
  },
1582
1582
  handleCompleteRelink: async (context, newEndNodeData) => {
1583
1583
  const { stateRef, graphDataRef, sceneDataRef } = context;
1584
- const { relink, nodeObjects: nodeObjects2 } = stateRef.current;
1584
+ const { relink, nodeObjects } = stateRef.current;
1585
1585
  const originalLinkData = relink.originalLine.userData;
1586
1586
  const oldSourceId = originalLinkData.source;
1587
1587
  const oldTargetId = originalLinkData.target;
@@ -8890,10 +8890,6 @@ function CreateQuestTreePanel({
8890
8890
  }
8891
8891
  };
8892
8892
  const handleLocalSave = async () => {
8893
- if (!hasUnsavedChanges) {
8894
- onClose();
8895
- return;
8896
- }
8897
8893
  try {
8898
8894
  setIsSaving(true);
8899
8895
  await onSave(questTreeMode.tree, questTreeMode.abstraction_tree);
@@ -8936,13 +8932,20 @@ function CreateQuestTreePanel({
8936
8932
  }
8937
8933
  ),
8938
8934
  /* @__PURE__ */ React11.createElement("div", { className: "flex-shrink-0 p-4 border-b border-slate-700 bg-slate-800/80 backdrop-blur-xl flex flex-col gap-1 z-20" }, /* @__PURE__ */ React11.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React11.createElement("h2", { className: "text-xl font-bold text-white flex items-center gap-2" }, /* @__PURE__ */ React11.createElement(FiGitBranch3, { className: "text-emerald-400" }), "Quest Trees"), /* @__PURE__ */ React11.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React11.createElement(
8935
+ "button",
8936
+ {
8937
+ onClick: onClose,
8938
+ className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
8939
+ },
8940
+ "Fechar"
8941
+ ), /* @__PURE__ */ React11.createElement(
8939
8942
  "button",
8940
8943
  {
8941
8944
  onClick: handleLocalSave,
8942
8945
  disabled: isSaving,
8943
- className: `flex items-center gap-2 px-4 py-2 ${hasUnsavedChanges ? "bg-emerald-600 hover:bg-emerald-500" : "bg-slate-700 hover:bg-slate-600"} text-white rounded-md transition-colors text-sm font-semibold`
8946
+ className: `px-4 py-2 rounded-lg transition-all font-semibold text-sm flex items-center gap-2 ${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 text-white shadow-[0_8px_24px_rgba(99,102,241,0.35)]"}`
8944
8947
  },
8945
- isSaving ? "Salvando..." : hasUnsavedChanges ? "Salvar Altera\xE7\xF5es" : "Fechar"
8948
+ isSaving ? "Salvando..." : "Salvar Mudan\xE7as"
8946
8949
  )))),
8947
8950
  /* @__PURE__ */ React11.createElement("div", { className: "flex border-b border-slate-800 bg-slate-900/50 p-2 gap-2 flex-shrink-0" }, /* @__PURE__ */ React11.createElement(
8948
8951
  "button",
@@ -8977,16 +8980,7 @@ function CreateQuestTreePanel({
8977
8980
  selectedParentId
8978
8981
  }
8979
8982
  )) : /* @__PURE__ */ React11.createElement("div", { className: "text-center py-8 text-slate-500 text-sm italic" }, "\xC1rvore vazia. Ofertada inicializa\xE7\xE3o autom\xE1tica em breve..."))),
8980
- /* @__PURE__ */ React11.createElement("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 flex items-center gap-3 z-30" }, /* @__PURE__ */ React11.createElement(
8981
- "button",
8982
- {
8983
- onClick: handleLocalSave,
8984
- disabled: isSaving,
8985
- className: "flex items-center gap-2 px-8 py-3 rounded-full font-bold shadow-2xl transition-all scale-110 bg-emerald-600 hover:bg-emerald-500 text-white shadow-emerald-500/20 active:scale-100"
8986
- },
8987
- isSaving ? "Salvando..." : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React11.createElement("path", { d: "M20 6L9 17l-5-5" })), " Salvar Mudan\xE7as")
8988
- )),
8989
- isAddingModeActive && selectedParentId && /* @__PURE__ */ React11.createElement("div", { className: "absolute bottom-20 left-1/2 -translate-x-1/2 bg-slate-800 px-4 py-2 rounded-full border border-slate-600 text-xs text-slate-300 shadow-lg whitespace-nowrap" }, "Destino: ", /* @__PURE__ */ React11.createElement("span", { className: "text-emerald-400 font-bold" }, ((_c = (_b = (_a = findNodePath3(currentTree, selectedParentId)) == null ? void 0 : _a.node) == null ? void 0 : _b.node) == null ? void 0 : _c.name) || "Root"))
8983
+ isAddingModeActive && selectedParentId && /* @__PURE__ */ React11.createElement("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-slate-800 px-4 py-2 rounded-full border border-slate-600 text-xs text-slate-300 shadow-lg whitespace-nowrap z-30" }, "Destino: ", /* @__PURE__ */ React11.createElement("span", { className: "text-emerald-400 font-bold" }, ((_c = (_b = (_a = findNodePath3(currentTree, selectedParentId)) == null ? void 0 : _a.node) == null ? void 0 : _b.node) == null ? void 0 : _c.name) || "Root"))
8990
8984
  );
8991
8985
  }
8992
8986
 
@@ -13081,11 +13075,30 @@ ${noteText}` : noteText : entry.notes,
13081
13075
  type: "button",
13082
13076
  onClick: () => {
13083
13077
  if (setQuestTreeMode2) {
13078
+ const convertPersistedTree = (storedTree) => {
13079
+ if (!storedTree) return null;
13080
+ if (storedTree.node || storedTree.is_section) return storedTree;
13081
+ const nodeId = storedTree.node_id;
13082
+ if (!nodeId) return null;
13083
+ const foundNode = availableNodes.find((n) => String(n.id) === String(nodeId)) || (String(nodeId) === String(node == null ? void 0 : node.id) ? node : null);
13084
+ return {
13085
+ node: foundNode ? { id: foundNode.id, name: foundNode.raw_title || foundNode.name } : { id: nodeId, name: `Node ${nodeId}` },
13086
+ relationship: storedTree.relationship || {},
13087
+ children: (storedTree.children || []).map(convertPersistedTree).filter(Boolean)
13088
+ };
13089
+ };
13090
+ const rootNode = { id: node == null ? void 0 : node.id, name: (node == null ? void 0 : node.raw_title) || (node == null ? void 0 : node.name) || "Quest Principal" };
13091
+ const existingTree = (node == null ? void 0 : node.quest_tree) ? convertPersistedTree(node.quest_tree) : { node: rootNode, children: [] };
13092
+ const existingAbstractionTree = (node == null ? void 0 : node.quest_abstraction_tree) ? convertPersistedTree(node.quest_abstraction_tree) : { node: rootNode, children: [] };
13084
13093
  setQuestTreeMode2((prev) => ({
13085
13094
  ...prev,
13086
13095
  isActive: true,
13087
13096
  isAddingNodes: true,
13088
- questNodeId: node == null ? void 0 : node.id
13097
+ questNodeId: node == null ? void 0 : node.id,
13098
+ questNodeName: (node == null ? void 0 : node.raw_title) || (node == null ? void 0 : node.name),
13099
+ tree: existingTree,
13100
+ abstraction_tree: existingAbstractionTree,
13101
+ selectedParentId: rootNode.id
13089
13102
  }));
13090
13103
  }
13091
13104
  },
@@ -15543,6 +15556,7 @@ function XViewScene({
15543
15556
  }, [ownerId, sceneConfigId]);
15544
15557
  const sceneDataRef = useRef21(null);
15545
15558
  const parentDataRef = useRef21(null);
15559
+ const graphDataRef = parentDataRef;
15546
15560
  const ancestryDataRef = useRef21(null);
15547
15561
  const [isLoading, setIsLoading] = useState30(true);
15548
15562
  const [permissionStatus, setPermissionStatus] = useState30("loading");
@@ -16008,8 +16022,8 @@ function XViewScene({
16008
16022
  []
16009
16023
  );
16010
16024
  const handleActivateTimeline = useCallback7(() => {
16011
- const { nodeObjects: nodeObjects2, tweenGroup, timelineIntervalsGroup } = stateRef.current;
16012
- if (!nodeObjects2 || !tweenGroup || !timelineIntervalsGroup) return;
16025
+ const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
16026
+ if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
16013
16027
  while (timelineIntervalsGroup.children.length > 0) {
16014
16028
  const obj = timelineIntervalsGroup.children[0];
16015
16029
  timelineIntervalsGroup.remove(obj);
@@ -16019,7 +16033,7 @@ function XViewScene({
16019
16033
  obj.material.dispose();
16020
16034
  }
16021
16035
  }
16022
- Object.values(nodeObjects2).forEach((mesh) => {
16036
+ Object.values(nodeObjects).forEach((mesh) => {
16023
16037
  const oldLabel = mesh.getObjectByName("timelineLabel");
16024
16038
  if (oldLabel) {
16025
16039
  mesh.remove(oldLabel);
@@ -16043,7 +16057,7 @@ function XViewScene({
16043
16057
  }
16044
16058
  return null;
16045
16059
  };
16046
- Object.values(nodeObjects2).forEach((mesh) => {
16060
+ Object.values(nodeObjects).forEach((mesh) => {
16047
16061
  const dateProp = mesh.userData.Date;
16048
16062
  let nodeInfo = { mesh, type: "point", label: "", isUndated: true };
16049
16063
  if (dateProp) {
@@ -16418,14 +16432,14 @@ function XViewScene({
16418
16432
  (nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
16419
16433
  const {
16420
16434
  graphGroup,
16421
- nodeObjects: nodeObjects2,
16435
+ nodeObjects,
16422
16436
  clickableNodes,
16423
16437
  glowTexture,
16424
16438
  tweenGroup
16425
16439
  } = stateRef.current;
16426
16440
  const nodeId = String(nodeData.id);
16427
- if (nodeObjects2[nodeId]) {
16428
- const existingMesh = nodeObjects2[nodeId];
16441
+ if (nodeObjects[nodeId]) {
16442
+ const existingMesh = nodeObjects[nodeId];
16429
16443
  if (position) {
16430
16444
  const updateTween = new Tween2(existingMesh.position).to(position, 800).easing(Easing2.Cubic.Out);
16431
16445
  tweenGroup.add(updateTween);
@@ -16446,7 +16460,7 @@ function XViewScene({
16446
16460
  }
16447
16461
  graphGroup.add(mesh.userData.labelObject);
16448
16462
  }
16449
- nodeObjects2[nodeId] = mesh;
16463
+ nodeObjects[nodeId] = mesh;
16450
16464
  clickableNodes.push(mesh);
16451
16465
  if (!suppressVersionUpdate) {
16452
16466
  setSceneVersion((v) => v + 1);
@@ -16456,15 +16470,15 @@ function XViewScene({
16456
16470
  []
16457
16471
  );
16458
16472
  const handleActivateReshapeLens = useCallback7(({ type, columns, centerNodeId }) => {
16459
- const { nodeObjects: nodeObjects2, tweenGroup, camera, controls } = stateRef.current;
16460
- if (!nodeObjects2 || !tweenGroup || !camera || !controls) return;
16461
- const activeNodeIds = Object.keys(nodeObjects2);
16473
+ const { nodeObjects, tweenGroup, camera, controls } = stateRef.current;
16474
+ if (!nodeObjects || !tweenGroup || !camera || !controls) return;
16475
+ const activeNodeIds = Object.keys(nodeObjects);
16462
16476
  if (activeNodeIds.length === 0) return;
16463
16477
  let sumX = 0;
16464
16478
  let sumY = 0;
16465
16479
  let nodeCount = 0;
16466
16480
  activeNodeIds.forEach((id) => {
16467
- const mesh = nodeObjects2[id];
16481
+ const mesh = nodeObjects[id];
16468
16482
  if (mesh && mesh.material) {
16469
16483
  const opacityTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
16470
16484
  tweenGroup.add(opacityTween);
@@ -16479,7 +16493,7 @@ function XViewScene({
16479
16493
  const rowSpacing = 80;
16480
16494
  const numCols = columns || 4;
16481
16495
  activeNodeIds.forEach((id, index) => {
16482
- const mesh = nodeObjects2[id];
16496
+ const mesh = nodeObjects[id];
16483
16497
  const col = index % numCols;
16484
16498
  const row = Math.floor(index / numCols);
16485
16499
  const targetX = (col - (numCols - 1) / 2) * colSpacing;
@@ -16501,7 +16515,7 @@ function XViewScene({
16501
16515
  const total = activeNodeIds.length;
16502
16516
  const radius = Math.max(80, total * 8);
16503
16517
  activeNodeIds.forEach((id, index) => {
16504
- const mesh = nodeObjects2[id];
16518
+ const mesh = nodeObjects[id];
16505
16519
  const angle = index / total * Math.PI * 2;
16506
16520
  const targetX = Math.cos(angle) * radius;
16507
16521
  const targetY = Math.sin(angle) * radius;
@@ -16519,7 +16533,7 @@ function XViewScene({
16519
16533
  nodeCount++;
16520
16534
  });
16521
16535
  } else if (type === "Star") {
16522
- const centerMesh = centerNodeId ? nodeObjects2[String(centerNodeId)] : null;
16536
+ const centerMesh = centerNodeId ? nodeObjects[String(centerNodeId)] : null;
16523
16537
  const orbitingNodeIds = activeNodeIds.filter((id) => id !== String(centerNodeId));
16524
16538
  const totalOrbiting = orbitingNodeIds.length;
16525
16539
  const radius = Math.max(80, totalOrbiting * 10);
@@ -16538,7 +16552,7 @@ function XViewScene({
16538
16552
  nodeCount++;
16539
16553
  }
16540
16554
  orbitingNodeIds.forEach((id, index) => {
16541
- const mesh = nodeObjects2[id];
16555
+ const mesh = nodeObjects[id];
16542
16556
  const angle = totalOrbiting > 0 ? index / totalOrbiting * Math.PI * 2 : 0;
16543
16557
  const targetX = Math.cos(angle) * radius;
16544
16558
  const targetY = Math.sin(angle) * radius;
@@ -16578,8 +16592,8 @@ function XViewScene({
16578
16592
  }, []);
16579
16593
  const handleActivateQuestLens = useCallback7(({ assigneeId, status: status2, milestoneId }) => {
16580
16594
  var _a2;
16581
- const { nodeObjects: nodeObjects2, tweenGroup, graphGroup } = stateRef.current;
16582
- if (!nodeObjects2 || !tweenGroup || !graphGroup) return;
16595
+ const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
16596
+ if (!nodeObjects || !tweenGroup || !graphGroup) return;
16583
16597
  const allQuests = ((_a2 = sceneDataRef.current) == null ? void 0 : _a2.quest_nodes) || [];
16584
16598
  const filteredQuests = allQuests.filter((q) => {
16585
16599
  const matchAssignee = !assigneeId || String(q.assignee_id) === String(assigneeId);
@@ -16641,7 +16655,7 @@ function XViewScene({
16641
16655
  positionGroups.get(posKey).push(String(q.id));
16642
16656
  });
16643
16657
  });
16644
- Object.values(nodeObjects2).forEach((mesh) => {
16658
+ Object.values(nodeObjects).forEach((mesh) => {
16645
16659
  const oldLabel = mesh.getObjectByName("questDateLabel") || mesh.getObjectByName("timelineLabel");
16646
16660
  if (oldLabel) {
16647
16661
  mesh.remove(oldLabel);
@@ -16656,13 +16670,13 @@ function XViewScene({
16656
16670
  mesh.userData.timelineEndLabel = null;
16657
16671
  }
16658
16672
  });
16659
- const nonFilteredNodeIds = Object.keys(nodeObjects2).filter((id) => !filteredQuests.some((q) => String(q.id) === String(id)));
16673
+ const nonFilteredNodeIds = Object.keys(nodeObjects).filter((id) => !filteredQuests.some((q) => String(q.id) === String(id)));
16660
16674
  const COMMON_START_X = startX - 100;
16661
16675
  const COMMON_COL_SPACING = 30;
16662
16676
  const COMMON_ROW_SPACING = 35;
16663
16677
  const MAX_COMMON_ROWS = 15;
16664
16678
  nonFilteredNodeIds.forEach((id, idx) => {
16665
- const mesh = nodeObjects2[id];
16679
+ const mesh = nodeObjects[id];
16666
16680
  if (!mesh) return;
16667
16681
  const col = Math.floor(idx / MAX_COMMON_ROWS);
16668
16682
  const row = idx % MAX_COMMON_ROWS;
@@ -16688,7 +16702,7 @@ function XViewScene({
16688
16702
  sideTween.start();
16689
16703
  });
16690
16704
  filteredQuests.forEach((q) => {
16691
- const mesh = nodeObjects2[String(q.id)];
16705
+ const mesh = nodeObjects[String(q.id)];
16692
16706
  if (mesh) {
16693
16707
  if (mesh.material) {
16694
16708
  const fadeInTween = new Tween2(mesh.material).to({ opacity: 1 }, 1200).easing(Easing2.Cubic.Out);
@@ -16706,7 +16720,7 @@ function XViewScene({
16706
16720
  const colX = startX + colIndex * QUEST_LENS_COLUMN_SPACING;
16707
16721
  questsInCol.forEach((q, rowIndex) => {
16708
16722
  const nodeId = String(q.id);
16709
- let mesh = nodeObjects2[nodeId];
16723
+ let mesh = nodeObjects[nodeId];
16710
16724
  const timeInfo = questTimeInfos.get(nodeId) || { isUndated: true };
16711
16725
  let targetY;
16712
16726
  if (!timeInfo.isUndated) {
@@ -16852,8 +16866,8 @@ function XViewScene({
16852
16866
  stateRef.current.timelineIntervalsGroup = timelineIntervalsGroup;
16853
16867
  const graphData = sceneDataRef.current;
16854
16868
  const nodePositions = calculateNodePositions(graphData.nodes);
16855
- const nodeObjects2 = {};
16856
- stateRef.current.nodeObjects = nodeObjects2;
16869
+ const nodeObjects = {};
16870
+ stateRef.current.nodeObjects = nodeObjects;
16857
16871
  stateRef.current.glowTexture = makeGlowTexture();
16858
16872
  graphData.nodes.forEach((node) => {
16859
16873
  const position = nodePositions[node.id] || new THREE3.Vector3();
@@ -16863,7 +16877,7 @@ function XViewScene({
16863
16877
  mesh.userData.labelObject.position.copy(mesh.position).add(mesh.userData.labelOffset);
16864
16878
  graphGroup.add(mesh.userData.labelObject);
16865
16879
  }
16866
- nodeObjects2[String(node.id)] = mesh;
16880
+ nodeObjects[String(node.id)] = mesh;
16867
16881
  stateRef.current.clickableNodes.push(mesh);
16868
16882
  });
16869
16883
  const linksGroupedByNodes = /* @__PURE__ */ new Map();
@@ -16875,8 +16889,8 @@ function XViewScene({
16875
16889
  linksGroupedByNodes.get(pairKey).push(link);
16876
16890
  });
16877
16891
  linksGroupedByNodes.forEach((linksArray) => {
16878
- const sourceNode = nodeObjects2[String(linksArray[0].source)];
16879
- const targetNode = nodeObjects2[String(linksArray[0].target)];
16892
+ const sourceNode = nodeObjects[String(linksArray[0].source)];
16893
+ const targetNode = nodeObjects[String(linksArray[0].target)];
16880
16894
  if (sourceNode && targetNode) {
16881
16895
  const resolution = new THREE3.Vector2(
16882
16896
  currentMount.clientWidth,
@@ -18104,17 +18118,44 @@ function XViewScene({
18104
18118
  const formattedTree = convertTreeToIds(newTree);
18105
18119
  const formattedAbstractionTree = convertTreeToIds(newAbstractionTree);
18106
18120
  if (questNodeId && sceneConfigId) {
18107
- const sceneData = (_a2 = sceneDataRef.current) == null ? void 0 : _a2[sceneConfigId];
18121
+ const sceneData = sceneDataRef.current;
18108
18122
  if (sceneData && sceneData.quest_nodes) {
18109
18123
  const questIndex = sceneData.quest_nodes.findIndex((q) => String(q.id) === String(questNodeId));
18110
18124
  if (questIndex !== -1) {
18111
18125
  sceneData.quest_nodes[questIndex].quest_tree = formattedTree;
18112
18126
  sceneData.quest_nodes[questIndex].quest_abstraction_tree = formattedAbstractionTree;
18113
- if (save_view_data) {
18114
- await save_view_data(sceneConfigId, sceneData, "scene");
18127
+ if (parentDataRef.current[sceneConfigId]) {
18128
+ const parentIndex = parentDataRef.current[sceneConfigId].nodes.findIndex(
18129
+ (q) => String(q.id) === String(questNodeId)
18130
+ );
18131
+ if (parentIndex !== -1) {
18132
+ parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_tree = formattedTree;
18133
+ parentDataRef.current[sceneConfigId].nodes[parentIndex].quest_abstraction_tree = formattedAbstractionTree;
18134
+ }
18135
+ }
18136
+ if (save_view_data && sceneSaveUrl) {
18137
+ const { nodeObjects: nObj, allLinks: aLinks } = stateRef.current;
18138
+ const currentNodes = nObj ? Object.values(nObj).map((mesh) => {
18139
+ const { _baseEmissiveIntensity, labelObject, labelOffset, timelineIntervalBar, timelineEndLabel, ...serializableNodeData } = mesh.userData;
18140
+ return serializableNodeData;
18141
+ }) : sceneData.nodes || [];
18142
+ const currentLinks = aLinks ? aLinks.map((line) => {
18143
+ const { sourceNode, targetNode, ...serializableLinkData } = line.userData;
18144
+ return serializableLinkData;
18145
+ }) : sceneData.links || [];
18146
+ const sceneFileData = {
18147
+ ...sceneData,
18148
+ nodes: currentNodes,
18149
+ links: currentLinks,
18150
+ quest_nodes: sceneData.quest_nodes,
18151
+ quest_links: sceneData.quest_links || [],
18152
+ quest_counter: sceneData.quest_counter || 1,
18153
+ milestones: sceneData.milestones || []
18154
+ };
18155
+ await save_view_data(sceneSaveUrl, sceneFileData);
18115
18156
  }
18116
18157
  const updatedNodeData = sceneData.quest_nodes[questIndex];
18117
- const nodeMesh = nodeObjects[String(questNodeId)];
18158
+ const nodeMesh = (_a2 = stateRef.current.nodeObjects) == null ? void 0 : _a2[String(questNodeId)];
18118
18159
  if (nodeMesh) {
18119
18160
  nodeMesh.userData.questData = updatedNodeData;
18120
18161
  }
@@ -18156,7 +18197,7 @@ function XViewScene({
18156
18197
  };
18157
18198
  const handleSaveQuestNode = async (context, newQuestData) => {
18158
18199
  const {
18159
- graphDataRef,
18200
+ graphDataRef: graphDataRef2,
18160
18201
  sceneDataRef: sceneDataRef2,
18161
18202
  stateRef: stateRef2,
18162
18203
  setters,
@@ -18166,7 +18207,7 @@ function XViewScene({
18166
18207
  sceneConfigId: sceneConfigId2,
18167
18208
  ownerId: ownerId2
18168
18209
  } = context;
18169
- if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
18210
+ if (!graphDataRef2.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
18170
18211
  const currentCounter = sceneDataRef2.current.quest_counter || 1;
18171
18212
  const newNode = {
18172
18213
  id: short2.generate(),
@@ -18174,14 +18215,14 @@ function XViewScene({
18174
18215
  is_quest: true,
18175
18216
  type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
18176
18217
  };
18177
- if (!graphDataRef.current[sceneConfigId2]) {
18178
- graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
18218
+ if (!graphDataRef2.current[sceneConfigId2]) {
18219
+ graphDataRef2.current[sceneConfigId2] = { nodes: [], links: [] };
18179
18220
  }
18180
- graphDataRef.current[sceneConfigId2].nodes.push(newNode);
18221
+ graphDataRef2.current[sceneConfigId2].nodes.push(newNode);
18181
18222
  const sceneFileData = {
18182
18223
  ...sceneDataRef2.current,
18183
- quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
18184
- quest_links: graphDataRef.current[sceneConfigId2].links,
18224
+ quest_nodes: graphDataRef2.current[sceneConfigId2].nodes,
18225
+ quest_links: graphDataRef2.current[sceneConfigId2].links,
18185
18226
  quest_counter: currentCounter + 1
18186
18227
  };
18187
18228
  try {
@@ -18192,9 +18233,9 @@ function XViewScene({
18192
18233
  ownerId: ownerId2,
18193
18234
  datasetName: "Quests Internas (View)"
18194
18235
  });
18195
- sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
18236
+ sceneDataRef2.current.quest_nodes = [...graphDataRef2.current[sceneConfigId2].nodes];
18196
18237
  if (parentDataRef.current[sceneConfigId2]) {
18197
- parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
18238
+ parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef2.current[sceneConfigId2].nodes];
18198
18239
  }
18199
18240
  const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
18200
18241
  const { graphGroup, ghostElements } = stateRef2.current;
@@ -18216,26 +18257,26 @@ function XViewScene({
18216
18257
  userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
18217
18258
  const {
18218
18259
  stateRef: stateRef2,
18219
- graphDataRef,
18260
+ graphDataRef: graphDataRef2,
18220
18261
  sceneDataRef: sceneDataRef2,
18221
18262
  sceneConfigId: sceneConfigId2,
18222
18263
  sceneSaveUrl: sceneSaveUrl2,
18223
18264
  ownerId: ownerId2
18224
18265
  } = context;
18225
18266
  const { sourceNodeData } = stateRef2.current.connection;
18226
- if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
18267
+ if (!graphDataRef2.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
18227
18268
  userActionHandlers.handleCancelConnection(context);
18228
18269
  return;
18229
18270
  }
18230
18271
  const sourceParentInfo = getParentFileInfoForNode(
18231
- graphDataRef.current,
18272
+ graphDataRef2.current,
18232
18273
  sceneDataRef2.current,
18233
18274
  sourceNodeData.id,
18234
18275
  sceneConfigId2,
18235
18276
  ownerId2
18236
18277
  );
18237
18278
  const targetParentInfo = getParentFileInfoForNode(
18238
- graphDataRef.current,
18279
+ graphDataRef2.current,
18239
18280
  sceneDataRef2.current,
18240
18281
  targetNodeData.id,
18241
18282
  sceneConfigId2,
@@ -18255,7 +18296,7 @@ function XViewScene({
18255
18296
  };
18256
18297
  try {
18257
18298
  if (parentFileIdToSave === sceneConfigId2) {
18258
- const specificParentData = graphDataRef.current[sceneConfigId2];
18299
+ const specificParentData = graphDataRef2.current[sceneConfigId2];
18259
18300
  specificParentData.links.push(newLink);
18260
18301
  const viewFilePayload = {
18261
18302
  ...sceneDataRef2.current,
@@ -18266,7 +18307,7 @@ function XViewScene({
18266
18307
  await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
18267
18308
  } else {
18268
18309
  const specificParentData = JSON.parse(
18269
- JSON.stringify(graphDataRef.current[parentFileIdToSave])
18310
+ JSON.stringify(graphDataRef2.current[parentFileIdToSave])
18270
18311
  );
18271
18312
  specificParentData.links.push(newLink);
18272
18313
  const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
@@ -18274,7 +18315,7 @@ function XViewScene({
18274
18315
  filenameForSpecificParent,
18275
18316
  specificParentData
18276
18317
  );
18277
- graphDataRef.current[parentFileIdToSave] = specificParentData;
18318
+ graphDataRef2.current[parentFileIdToSave] = specificParentData;
18278
18319
  }
18279
18320
  addNewLinkToScene(stateRef2.current, newLink);
18280
18321
  } catch (error) {
@@ -18321,7 +18362,7 @@ function XViewScene({
18321
18362
  }
18322
18363
  });
18323
18364
  }
18324
- const { ancestryGroup, nodeObjects: nodeObjects2, renderer, renderedAncestries } = stateRef.current;
18365
+ const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
18325
18366
  const currentRenderLimit = stateRef.current.maxAncestryRenderIndex || 0;
18326
18367
  const isFullRenderRequest = !normalizedAllowedIds;
18327
18368
  const checkShouldRender = (section) => {
@@ -18425,10 +18466,10 @@ function XViewScene({
18425
18466
  );
18426
18467
  if (!fullTree) return;
18427
18468
  const rootNodeId = String(ancestryObject.ancestral_node);
18428
- let rootNodeMesh = nodeObjects2[rootNodeId];
18469
+ let rootNodeMesh = nodeObjects[rootNodeId];
18429
18470
  let originMesh = null;
18430
18471
  if (ancestryObject._originNodeId) {
18431
- originMesh = nodeObjects2[String(ancestryObject._originNodeId)];
18472
+ originMesh = nodeObjects[String(ancestryObject._originNodeId)];
18432
18473
  }
18433
18474
  let rootTargetPos = null;
18434
18475
  if (originMesh) {
@@ -18642,7 +18683,7 @@ function XViewScene({
18642
18683
  } else {
18643
18684
  const traverseAndCollect = (item) => {
18644
18685
  if (item.node) {
18645
- const mesh = nodeObjects2[String(item.node.id)];
18686
+ const mesh = nodeObjects[String(item.node.id)];
18646
18687
  if (mesh) allRenderedNodePositions.push(mesh.position.clone());
18647
18688
  }
18648
18689
  if (item.children) item.children.forEach(traverseAndCollect);
@@ -18690,7 +18731,7 @@ function XViewScene({
18690
18731
  const nodeIds = collectNodeIdsInSection(targetSectionForZone);
18691
18732
  const vectors = [];
18692
18733
  nodeIds.forEach((id) => {
18693
- const mesh = nodeObjects2[String(id)];
18734
+ const mesh = nodeObjects[String(id)];
18694
18735
  if (mesh) {
18695
18736
  const targetPos = targetPositionsCache.get(String(id));
18696
18737
  vectors.push(targetPos ? targetPos.clone() : mesh.position.clone());
@@ -18749,8 +18790,8 @@ function XViewScene({
18749
18790
  focusTargetPosition = targetPositionsCache.get(anchorId) || currentAnchorMesh.position.clone();
18750
18791
  focusTargetRotation = baseRotation;
18751
18792
  }
18752
- } else if (activeSectionIdForFocus && nodeObjects2[String(activeSectionIdForFocus)]) {
18753
- const directNode = nodeObjects2[String(activeSectionIdForFocus)];
18793
+ } else if (activeSectionIdForFocus && nodeObjects[String(activeSectionIdForFocus)]) {
18794
+ const directNode = nodeObjects[String(activeSectionIdForFocus)];
18754
18795
  const tPos = targetPositionsCache.get(String(activeSectionIdForFocus));
18755
18796
  focusTargetPosition = tPos ? tPos.clone() : directNode.position.clone();
18756
18797
  focusTargetRotation = baseRotation;
@@ -18801,7 +18842,7 @@ function XViewScene({
18801
18842
  (prev) => prev.visible ? { ...prev, visible: false } : prev
18802
18843
  );
18803
18844
  if (!ancestryObject || !ancestryObject.abstraction_tree) return;
18804
- const { ancestryGroup, nodeObjects: nodeObjects2, renderer, renderedAncestries } = stateRef.current;
18845
+ const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
18805
18846
  const allParentNodes = Object.values(parentDataRef.current).flatMap(
18806
18847
  (f) => f.nodes
18807
18848
  );
@@ -18842,7 +18883,7 @@ function XViewScene({
18842
18883
  const ancestryEntry = { id: absId, lines: [], isFullRender: true };
18843
18884
  renderedAncestries.push(ancestryEntry);
18844
18885
  const rootNodeId = String(fullTree.node.id);
18845
- let rootNodeMesh = nodeObjects2[rootNodeId];
18886
+ let rootNodeMesh = nodeObjects[rootNodeId];
18846
18887
  let rootTargetPos = rootNodeMesh ? rootNodeMesh.position.clone() : new THREE3.Vector3(0, 0, 0);
18847
18888
  if (!rootNodeMesh) {
18848
18889
  rootNodeMesh = addOrUpdateNodeMesh(fullTree.node, rootTargetPos, true);
@@ -19954,8 +19995,8 @@ function XViewScene({
19954
19995
  setSceneVersion((v) => v + 1);
19955
19996
  const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
19956
19997
  if (!isView || !save_view_data || !sceneSaveUrl) return;
19957
- const { nodeObjects: nodeObjects2, allLinks } = stateRef.current;
19958
- const currentNodes = Object.values(nodeObjects2 || {}).map((mesh) => {
19998
+ const { nodeObjects, allLinks } = stateRef.current;
19999
+ const currentNodes = Object.values(nodeObjects || {}).map((mesh) => {
19959
20000
  const {
19960
20001
  _baseEmissiveIntensity,
19961
20002
  labelObject,
@@ -19994,15 +20035,15 @@ function XViewScene({
19994
20035
  );
19995
20036
  const handleSaveCurrentView = useCallback7(async () => {
19996
20037
  var _a2, _b2, _c2;
19997
- const { nodeObjects: nodeObjects2, allLinks } = stateRef.current;
19998
- if (!nodeObjects2 || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
20038
+ const { nodeObjects, allLinks } = stateRef.current;
20039
+ if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
19999
20040
  console.warn(
20000
20041
  "N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente."
20001
20042
  );
20002
20043
  return;
20003
20044
  }
20004
20045
  if (!save_view_data) return;
20005
- const currentNodes = Object.values(nodeObjects2).map((mesh) => {
20046
+ const currentNodes = Object.values(nodeObjects).map((mesh) => {
20006
20047
  const {
20007
20048
  _baseEmissiveIntensity,
20008
20049
  labelObject,
@@ -20057,8 +20098,8 @@ function XViewScene({
20057
20098
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
20058
20099
  useEffect25(() => {
20059
20100
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
20060
- const nodeObjects2 = stateRef.current.nodeObjects || {};
20061
- const targetMesh = nodeObjects2[String(focusNodeId)];
20101
+ const nodeObjects = stateRef.current.nodeObjects || {};
20102
+ const targetMesh = nodeObjects[String(focusNodeId)];
20062
20103
  if (targetMesh) {
20063
20104
  setTimeout(() => {
20064
20105
  tweenToTarget(targetMesh, 1.2);
@@ -20147,10 +20188,10 @@ function XViewScene({
20147
20188
  if (isUiClear) {
20148
20189
  const isView = ((_c2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _c2.toLowerCase()) === "view";
20149
20190
  if (!isView) return;
20150
- const { graphGroup, glowTexture, controls: sceneControls, nodeObjects: nodeObjects2 } = stateRef.current;
20191
+ const { graphGroup, glowTexture, controls: sceneControls, nodeObjects } = stateRef.current;
20151
20192
  if (graphGroup) {
20152
20193
  let ghostPosition = sceneControls.target.clone();
20153
- const existingNodes = Object.values(nodeObjects2);
20194
+ const existingNodes = Object.values(nodeObjects);
20154
20195
  let isOccupied = true;
20155
20196
  let radius = 18;
20156
20197
  let angle = 0;