@lv-x-software-house/x_view 1.2.3 → 1.2.4-dev.10

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 +723 -351
  2. package/dist/index.mjs +643 -271
  3. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/XViewScene.jsx
2
- import React23, { useCallback as useCallback4, useEffect as useEffect21, useRef as useRef17, useState as useState23, useMemo as useMemo12 } from "react";
2
+ import React24, { useCallback as useCallback4, useEffect as useEffect21, useRef as useRef18, useState as useState24, useMemo as useMemo12 } from "react";
3
3
  import { useRouter, useSearchParams } from "next/navigation";
4
4
  import { useSession } from "next-auth/react";
5
5
  import CryptoJS from "crypto-js";
@@ -1515,7 +1515,7 @@ var addStandaloneNodeToScene = (state, nodeData, position) => {
1515
1515
  scaleTween.start();
1516
1516
  }
1517
1517
  };
1518
- var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
1518
+ var getParentFileInfoForNode = (allParentData, sceneData, nodeId, sceneConfigId = null, sceneOwnerId = null) => {
1519
1519
  const parentDbsArray = (sceneData == null ? void 0 : sceneData.parent_dbs) || [];
1520
1520
  for (const parentFileId in allParentData) {
1521
1521
  if (allParentData.hasOwnProperty(parentFileId)) {
@@ -1524,6 +1524,8 @@ var getParentFileInfoForNode = (allParentData, sceneData, nodeId) => {
1524
1524
  const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
1525
1525
  if (parentDbInfo) {
1526
1526
  return { parentFileId, ownerId: parentDbInfo.owner_id };
1527
+ } else if (sceneConfigId && String(parentFileId) === String(sceneConfigId)) {
1528
+ return { parentFileId, ownerId: sceneOwnerId };
1527
1529
  } else {
1528
1530
  console.warn(`Owner ID n\xE3o encontrado em sceneData.parent_dbs para o parentFileId: ${parentFileId}`);
1529
1531
  return { parentFileId, ownerId: null };
@@ -1802,7 +1804,7 @@ var userActionHandlers = {
1802
1804
  version_node: { is_version: true, parent_node: sourceNodeData.id }
1803
1805
  };
1804
1806
  const newLink = { id: `link_${short.generate()}`, source: sourceNodeData.id, target: newNode.id };
1805
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
1807
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
1806
1808
  if (!parentInfo || !parentInfo.ownerId) {
1807
1809
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
1808
1810
  alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
@@ -1978,7 +1980,7 @@ var userActionHandlers = {
1978
1980
  userActionHandlers.handleCancelConnection(context);
1979
1981
  return;
1980
1982
  }
1981
- const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
1983
+ const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id, context.sceneConfigId, context.ownerId);
1982
1984
  if (!sourceParentInfo || !sourceParentInfo.ownerId) {
1983
1985
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
1984
1986
  alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
@@ -2067,8 +2069,8 @@ var userActionHandlers = {
2067
2069
  } else {
2068
2070
  newTargetId = newEndNodeData.id;
2069
2071
  }
2070
- const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId);
2071
- const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId);
2072
+ const originalParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, oldSourceId, context.sceneConfigId, context.ownerId);
2073
+ const newParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, newSourceId, context.sceneConfigId, context.ownerId);
2072
2074
  if (!originalParentInfo || !newParentInfo || !originalParentInfo.ownerId || !newParentInfo.ownerId) {
2073
2075
  console.error("N\xE3o foi poss\xEDvel encontrar informa\xE7\xF5es dos arquivos pai para o relink.");
2074
2076
  alert("Ocorreu um erro ao identificar os arquivos pai para salvar a altera\xE7\xE3o.");
@@ -2136,7 +2138,7 @@ var userActionHandlers = {
2136
2138
  console.error("Tentativa de deletar um link sem ID.", linkObject.userData);
2137
2139
  return;
2138
2140
  }
2139
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source);
2141
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkObject.userData.source, context.sceneConfigId, context.ownerId);
2140
2142
  if (!parentInfo || !parentInfo.ownerId) {
2141
2143
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link:", linkIdToDelete);
2142
2144
  alert("Ocorreu um erro ao identificar o arquivo pai da rela\xE7\xE3o para exclus\xE3o.");
@@ -2148,9 +2150,24 @@ var userActionHandlers = {
2148
2150
  const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
2149
2151
  const newLinks = (specificParentData.links || []).filter((l) => String(l.id) !== String(linkIdToDelete));
2150
2152
  specificParentData.links = newLinks;
2151
- const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
2153
+ let filenameToSave;
2154
+ let payloadToSave;
2155
+ if (parentFileId === context.sceneConfigId) {
2156
+ filenameToSave = context.sceneSaveUrl;
2157
+ sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => String(l.id) !== String(linkIdToDelete));
2158
+ payloadToSave = {
2159
+ parent_dbs: sceneDataRef.current.parent_dbs,
2160
+ nodes: sceneDataRef.current.nodes,
2161
+ links: sceneDataRef.current.links,
2162
+ quest_nodes: specificParentData.nodes,
2163
+ quest_links: specificParentData.links
2164
+ };
2165
+ } else {
2166
+ filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
2167
+ payloadToSave = specificParentData;
2168
+ }
2152
2169
  try {
2153
- await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
2170
+ await context.actions.save_view_data(filenameToSave, payloadToSave);
2154
2171
  graphDataRef.current[parentFileId] = specificParentData;
2155
2172
  setters.setDetailsLink((prev) => String(prev == null ? void 0 : prev.id) === String(linkIdToDelete) ? null : prev);
2156
2173
  if (stateRef.current.hoveredLink === linkObject) {
@@ -2313,7 +2330,7 @@ var userActionHandlers = {
2313
2330
  }
2314
2331
  const changesByParentFile = {};
2315
2332
  for (const nodeId of strNodeIdsToDelete) {
2316
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId);
2333
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeId, context.sceneConfigId, context.ownerId);
2317
2334
  if (!parentInfo || !parentInfo.ownerId) {
2318
2335
  console.warn(`Node com ID ${nodeId} n\xE3o encontrado ou sem ownerId. Ignorando.`);
2319
2336
  continue;
@@ -2347,8 +2364,26 @@ var userActionHandlers = {
2347
2364
  originalData.links = (originalData.links || []).filter(
2348
2365
  (l) => !linksToDelete.has(String(l.id))
2349
2366
  );
2350
- const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
2351
- savePromises.push(context.actions.save_view_data(filenameForSpecificParent, originalData));
2367
+ let filenameToSave;
2368
+ let payloadToSave;
2369
+ if (parentFileId === context.sceneConfigId) {
2370
+ filenameToSave = context.sceneSaveUrl;
2371
+ const strNodesToDelete = Array.from(nodesToDelete).map(String);
2372
+ const strLinksToDelete = Array.from(linksToDelete).map(String);
2373
+ sceneDataRef.current.nodes = sceneDataRef.current.nodes.filter((n) => !strNodesToDelete.includes(String(n.id)));
2374
+ sceneDataRef.current.links = sceneDataRef.current.links.filter((l) => !strLinksToDelete.includes(String(l.id)));
2375
+ payloadToSave = {
2376
+ parent_dbs: sceneDataRef.current.parent_dbs,
2377
+ nodes: sceneDataRef.current.nodes,
2378
+ links: sceneDataRef.current.links,
2379
+ quest_nodes: originalData.nodes,
2380
+ quest_links: originalData.links
2381
+ };
2382
+ } else {
2383
+ filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
2384
+ payloadToSave = originalData;
2385
+ }
2386
+ savePromises.push(context.actions.save_view_data(filenameToSave, payloadToSave));
2352
2387
  updatedParentDataCache[parentFileId] = originalData;
2353
2388
  }
2354
2389
  }
@@ -2380,7 +2415,7 @@ var userActionHandlers = {
2380
2415
  if (!nodeData || !graphDataRef.current || !sceneDataRef.current) return;
2381
2416
  const nodeIdToDelete = nodeData.id;
2382
2417
  const strNodeId = String(nodeIdToDelete);
2383
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete);
2418
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeIdToDelete, context.sceneConfigId, context.ownerId);
2384
2419
  if (!parentInfo || !parentInfo.ownerId) {
2385
2420
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser exclu\xEDdo:", nodeIdToDelete);
2386
2421
  alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para exclus\xE3o.");
@@ -2392,9 +2427,27 @@ var userActionHandlers = {
2392
2427
  const newLinks = (specificParentData.links || []).filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
2393
2428
  specificParentData.nodes = newNodes;
2394
2429
  specificParentData.links = newLinks;
2395
- const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
2430
+ let filenameToSave;
2431
+ let payloadToSave;
2432
+ if (parentFileId === context.sceneConfigId) {
2433
+ filenameToSave = context.sceneSaveUrl;
2434
+ const newVisualNodes = sceneDataRef.current.nodes.filter((n) => String(n.id) !== strNodeId);
2435
+ const newVisualLinks = sceneDataRef.current.links.filter((l) => String(l.source) !== strNodeId && String(l.target) !== strNodeId);
2436
+ sceneDataRef.current.nodes = newVisualNodes;
2437
+ sceneDataRef.current.links = newVisualLinks;
2438
+ payloadToSave = {
2439
+ parent_dbs: sceneDataRef.current.parent_dbs,
2440
+ nodes: newVisualNodes,
2441
+ links: newVisualLinks,
2442
+ quest_nodes: specificParentData.nodes,
2443
+ quest_links: specificParentData.links
2444
+ };
2445
+ } else {
2446
+ filenameToSave = `x_view_dbs/${ownerId}/${parentFileId}`;
2447
+ payloadToSave = specificParentData;
2448
+ }
2396
2449
  try {
2397
- await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
2450
+ await context.actions.save_view_data(filenameToSave, payloadToSave);
2398
2451
  graphDataRef.current[parentFileId] = specificParentData;
2399
2452
  setters.setDetailsNode((prev) => String(prev == null ? void 0 : prev.id) === String(nodeIdToDelete) ? null : prev);
2400
2453
  removeNodeFromScene(stateRef.current, nodeIdToDelete);
@@ -2408,7 +2461,7 @@ var userActionHandlers = {
2408
2461
  const { graphDataRef, sceneDataRef, stateRef, setters } = context;
2409
2462
  if (!graphDataRef.current || !sceneDataRef.current) return;
2410
2463
  const { _baseEmissiveIntensity: ignored, ...nodeToSave } = updatedNode;
2411
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id);
2464
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, nodeToSave.id, context.sceneConfigId, context.ownerId);
2412
2465
  if (!parentInfo || !parentInfo.ownerId) {
2413
2466
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node a ser atualizado:", nodeToSave.id);
2414
2467
  alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
@@ -2442,7 +2495,7 @@ var userActionHandlers = {
2442
2495
  const { graphDataRef, sceneDataRef, stateRef, setters } = context;
2443
2496
  if (!graphDataRef.current || !sceneDataRef.current) return;
2444
2497
  const { sourceNode, targetNode, ...linkToSave } = updatedLink;
2445
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source);
2498
+ const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, linkToSave.source, context.sceneConfigId, context.ownerId);
2446
2499
  if (!parentInfo || !parentInfo.ownerId) {
2447
2500
  console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o link a ser atualizado:", linkToSave.id);
2448
2501
  alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio para atualiza\xE7\xE3o.");
@@ -7835,9 +7888,180 @@ function InSceneVersionForm({
7835
7888
  ));
7836
7889
  }
7837
7890
 
7891
+ // src/components/InSceneQuestForm.jsx
7892
+ import React15, { useState as useState16, useRef as useRef12 } from "react";
7893
+ import { FiPlus as FiPlus5, FiCheck as FiCheck9, FiEdit2 as FiEdit26, FiTarget, FiX as FiX4 } from "react-icons/fi";
7894
+ var QUEST_STATUS_COLORS = {
7895
+ "Backlog": "#64748b",
7896
+ // Slate (Cinza azulado)
7897
+ "In Progress": "#eab308",
7898
+ // Yellow (Amarelo)
7899
+ "Review": "#a855f7",
7900
+ // Purple (Roxo)
7901
+ "Done": "#22c55e"
7902
+ // Green (Verde)
7903
+ };
7904
+ function InSceneQuestForm({
7905
+ onSave,
7906
+ onCancel,
7907
+ style,
7908
+ refEl,
7909
+ onOpenImageViewer,
7910
+ availableNodes = [],
7911
+ availableAncestries = [],
7912
+ onMentionClick,
7913
+ onUploadFile
7914
+ }) {
7915
+ const [name, setName] = useState16("");
7916
+ const [types, setTypes] = useState16(["quest"]);
7917
+ const [typeInput, setTypeInput] = useState16("");
7918
+ const [status, setStatus] = useState16("Backlog");
7919
+ const [size, setSize] = useState16("medium");
7920
+ const [intensity, setIntensity] = useState16(0);
7921
+ const [description, setDescription] = useState16("");
7922
+ const [customProps, setCustomProps] = useState16([]);
7923
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
7924
+ const propsEndRef = useRef12(null);
7925
+ const handleAddProp = () => {
7926
+ const newProp = createNewCustomProperty(customProps);
7927
+ setCustomProps([...customProps, newProp]);
7928
+ setTimeout(() => {
7929
+ var _a;
7930
+ (_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
7931
+ }, 100);
7932
+ };
7933
+ const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
7934
+ const handleUpdateProp = (index, updatedProp) => {
7935
+ const newProps = [...customProps];
7936
+ newProps[index] = updatedProp;
7937
+ setCustomProps(newProps);
7938
+ };
7939
+ const handleAddType = (newType) => {
7940
+ const trimmed = newType.trim();
7941
+ if (trimmed && !types.includes(trimmed)) {
7942
+ setTypes([...types, trimmed]);
7943
+ setTypeInput("");
7944
+ }
7945
+ };
7946
+ const handleRemoveType = (indexToRemove) => {
7947
+ if (types[indexToRemove] === "quest") return;
7948
+ setTypes(types.filter((_, index) => index !== indexToRemove));
7949
+ };
7950
+ const handleTypeInputKeyDown = (e) => {
7951
+ if (e.key === "Enter") {
7952
+ e.preventDefault();
7953
+ handleAddType(typeInput);
7954
+ } else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
7955
+ handleRemoveType(types.length - 1);
7956
+ }
7957
+ };
7958
+ const handleSubmit = (e) => {
7959
+ e.preventDefault();
7960
+ if (!name.trim()) {
7961
+ alert("O campo 'Nome' \xE9 obrigat\xF3rio.");
7962
+ return;
7963
+ }
7964
+ const additionalData = toObjectFromCustomProps(
7965
+ customProps.filter((prop) => prop.key.trim() && !prop.isEditing)
7966
+ );
7967
+ const processedSections = processDescriptionForSave(description, []);
7968
+ onSave({
7969
+ name: name.trim(),
7970
+ type: types,
7971
+ color: QUEST_STATUS_COLORS[status],
7972
+ // Cor atrelada ao status
7973
+ status,
7974
+ size,
7975
+ intensity,
7976
+ description: description.trim(),
7977
+ description_sections: processedSections,
7978
+ useImageAsTexture: false,
7979
+ textureImageUrl: null,
7980
+ ...additionalData
7981
+ });
7982
+ };
7983
+ const swallow = (e) => e.stopPropagation();
7984
+ const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
7985
+ const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
7986
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
7987
+ "div",
7988
+ {
7989
+ ref: refEl,
7990
+ className: "ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white w-[min(92vw,440px)] overflow-hidden",
7991
+ style,
7992
+ onPointerDown: swallow,
7993
+ onClick: swallow,
7994
+ onWheel: swallow,
7995
+ onContextMenu: swallow,
7996
+ onDoubleClick: swallow
7997
+ },
7998
+ /* @__PURE__ */ React15.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
7999
+ /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement(FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")),
8000
+ /* @__PURE__ */ React15.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ React15.createElement(
8001
+ "select",
8002
+ {
8003
+ value: status,
8004
+ onChange: (e) => setStatus(e.target.value),
8005
+ className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 appearance-none cursor-pointer",
8006
+ style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
8007
+ },
8008
+ /* @__PURE__ */ React15.createElement("option", { value: "Backlog" }, "Backlog"),
8009
+ /* @__PURE__ */ React15.createElement("option", { value: "In Progress" }, "In Progress"),
8010
+ /* @__PURE__ */ React15.createElement("option", { value: "Review" }, "Review"),
8011
+ /* @__PURE__ */ React15.createElement("option", { value: "Done" }, "Done")
8012
+ )), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ React15.createElement("input", { required: true, type: "text", placeholder: "Ex.: Refatorar M\xF3dulo X", value: name, onChange: (e) => setName(e.target.value), className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ React15.createElement("div", { className: "relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 focus-within:ring-2 focus-within:ring-indigo-400/60 transition-all" }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, t !== "quest" && /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ React15.createElement(FiX4, { size: 12 })))), /* @__PURE__ */ React15.createElement(
8013
+ "input",
8014
+ {
8015
+ type: "text",
8016
+ value: typeInput,
8017
+ onChange: (e) => setTypeInput(e.target.value),
8018
+ onKeyDown: handleTypeInputKeyDown,
8019
+ onBlur: () => {
8020
+ if (typeInput.trim()) handleAddType(typeInput);
8021
+ },
8022
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
8023
+ autoComplete: "off"
8024
+ }
8025
+ ))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React15.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React15.createElement(
8026
+ DescriptionDisplay,
8027
+ {
8028
+ description,
8029
+ savedSections: [],
8030
+ availableNodes,
8031
+ availableAncestries,
8032
+ onMentionClick,
8033
+ onSaveDescription: (newDesc) => setDescription(newDesc)
8034
+ }
8035
+ ), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 }))), !description && /* @__PURE__ */ React15.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ React15.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${size === s ? "bg-indigo-500 border-indigo-500" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, size === s && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ React15.createElement(
8036
+ CustomPropertyDisplay,
8037
+ {
8038
+ key: prop.id,
8039
+ prop,
8040
+ onUpdate: (updatedProp) => handleUpdateProp(index, updatedProp),
8041
+ onRemove: () => handleRemoveProp(index),
8042
+ onOpenImageViewer,
8043
+ unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
8044
+ onUploadFile
8045
+ }
8046
+ )), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React15.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm" }, "Cancelar"), /* @__PURE__ */ React15.createElement("button", { type: "submit", className: "px-4 py-2 rounded-lg bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 transition-colors font-semibold text-sm shadow-[0_8px_24px_rgba(99,102,241,0.35)]" }, "Salvar Quest")))
8047
+ ), isDescriptionModalOpen && /* @__PURE__ */ React15.createElement(
8048
+ DescriptionEditModal,
8049
+ {
8050
+ isOpen: isDescriptionModalOpen,
8051
+ title: "Editar Descri\xE7\xE3o da Quest",
8052
+ initialValue: description,
8053
+ onSave: (newDescription) => setDescription(newDescription),
8054
+ onClose: () => setIsDescriptionModalOpen(false),
8055
+ availableNodes,
8056
+ availableAncestries,
8057
+ availableImages
8058
+ }
8059
+ ));
8060
+ }
8061
+
7838
8062
  // src/components/NodeDetailsPanel.jsx
7839
- import React15, { useState as useState16, useEffect as useEffect15, useRef as useRef12 } from "react";
7840
- import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
8063
+ import React16, { useState as useState17, useEffect as useEffect15, useRef as useRef13 } from "react";
8064
+ import { FiPlus as FiPlus6, FiMaximize2 as FiMaximize23, FiX as FiX5, FiCheck as FiCheck10, FiImage as FiImage3, FiEdit2 as FiEdit27, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
7841
8065
  function NodeDetailsPanel({
7842
8066
  node,
7843
8067
  onClose,
@@ -7858,27 +8082,27 @@ function NodeDetailsPanel({
7858
8082
  userRole,
7859
8083
  currentDatasetName
7860
8084
  }) {
7861
- const [name, setName] = useState16((node == null ? void 0 : node.name) ?? "");
7862
- const [types, setTypes] = useState16([]);
7863
- const [typeInput, setTypeInput] = useState16("");
7864
- const [color, setColor] = useState16((node == null ? void 0 : node.color) ?? "#8b5cf6");
7865
- const [size, setSize] = useState16((node == null ? void 0 : node.size) ?? "medium");
7866
- const [description, setDescription] = useState16((node == null ? void 0 : node.description) ?? "");
7867
- const [intensity, setIntensity] = useState16((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
7868
- const [customProps, setCustomProps] = useState16(() => extractCustomPropsFromNode(node || {}));
7869
- const [showTypeSuggestions, setShowTypeSuggestions] = useState16(false);
7870
- const [filteredTypes, setFilteredTypes] = useState16([]);
7871
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
7872
- const [isReadMode, setIsReadMode] = useState16(false);
7873
- const [existingSections, setExistingSections] = useState16((node == null ? void 0 : node.description_sections) || []);
7874
- const [isSaving, setIsSaving] = useState16(false);
7875
- const [isLinkCopied, setIsLinkCopied] = useState16(false);
7876
- const [useImageAsTexture, setUseImageAsTexture] = useState16(() => {
8085
+ const [name, setName] = useState17((node == null ? void 0 : node.name) ?? "");
8086
+ const [types, setTypes] = useState17([]);
8087
+ const [typeInput, setTypeInput] = useState17("");
8088
+ const [color, setColor] = useState17((node == null ? void 0 : node.color) ?? "#8b5cf6");
8089
+ const [size, setSize] = useState17((node == null ? void 0 : node.size) ?? "medium");
8090
+ const [description, setDescription] = useState17((node == null ? void 0 : node.description) ?? "");
8091
+ const [intensity, setIntensity] = useState17((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
8092
+ const [customProps, setCustomProps] = useState17(() => extractCustomPropsFromNode(node || {}));
8093
+ const [showTypeSuggestions, setShowTypeSuggestions] = useState17(false);
8094
+ const [filteredTypes, setFilteredTypes] = useState17([]);
8095
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState17(false);
8096
+ const [isReadMode, setIsReadMode] = useState17(false);
8097
+ const [existingSections, setExistingSections] = useState17((node == null ? void 0 : node.description_sections) || []);
8098
+ const [isSaving, setIsSaving] = useState17(false);
8099
+ const [isLinkCopied, setIsLinkCopied] = useState17(false);
8100
+ const [useImageAsTexture, setUseImageAsTexture] = useState17(() => {
7877
8101
  if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
7878
8102
  if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
7879
8103
  return !!(node == null ? void 0 : node.useImageAsTexture);
7880
8104
  });
7881
- const [selectedImageUrl, setSelectedImageUrl] = useState16((node == null ? void 0 : node.textureImageUrl) ?? null);
8105
+ const [selectedImageUrl, setSelectedImageUrl] = useState17((node == null ? void 0 : node.textureImageUrl) ?? null);
7882
8106
  const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
7883
8107
  const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
7884
8108
  initialWidth: isReadMode ? 700 : 440,
@@ -7888,8 +8112,8 @@ function NodeDetailsPanel({
7888
8112
  useEffect15(() => {
7889
8113
  setWidth(isReadMode ? 700 : 440);
7890
8114
  }, [isReadMode, setWidth]);
7891
- const prevNodeIdRef = useRef12(null);
7892
- const propsEndRef = useRef12(null);
8115
+ const prevNodeIdRef = useRef13(null);
8116
+ const propsEndRef = useRef13(null);
7893
8117
  const canEdit = userRole !== "viewer";
7894
8118
  const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
7895
8119
  const handleImageClickFromText = (url, name2) => {
@@ -8097,7 +8321,7 @@ function NodeDetailsPanel({
8097
8321
  onClose();
8098
8322
  };
8099
8323
  const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
8100
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
8324
+ return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
8101
8325
  "div",
8102
8326
  {
8103
8327
  className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
@@ -8110,7 +8334,7 @@ function NodeDetailsPanel({
8110
8334
  onContextMenu: swallow,
8111
8335
  onDoubleClick: swallow
8112
8336
  },
8113
- /* @__PURE__ */ React15.createElement(
8337
+ /* @__PURE__ */ React16.createElement(
8114
8338
  "div",
8115
8339
  {
8116
8340
  onPointerDown: (e) => {
@@ -8121,7 +8345,7 @@ function NodeDetailsPanel({
8121
8345
  title: "Arraste para redimensionar"
8122
8346
  }
8123
8347
  ),
8124
- isReadMode ? /* @__PURE__ */ React15.createElement(
8348
+ isReadMode ? /* @__PURE__ */ React16.createElement(
8125
8349
  DescriptionReadModePanel,
8126
8350
  {
8127
8351
  title: name || (node == null ? void 0 : node.name),
@@ -8142,23 +8366,23 @@ function NodeDetailsPanel({
8142
8366
  onImageClick: handleImageClickFromText,
8143
8367
  onSaveDescription: handleSaveDescriptionInline
8144
8368
  }
8145
- ) : /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React15.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React15.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React15.createElement(
8369
+ ) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ React16.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React16.createElement("div", null, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React16.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React16.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ React16.createElement(
8146
8370
  "button",
8147
8371
  {
8148
8372
  onClick: handleCopyLink,
8149
8373
  className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
8150
8374
  title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
8151
8375
  },
8152
- isLinkCopied ? /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12 }) : /* @__PURE__ */ React15.createElement(FiLink5, { size: 12 })
8153
- )), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ React15.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ React15.createElement(
8376
+ isLinkCopied ? /* @__PURE__ */ React16.createElement(FiCheck10, { size: 12 }) : /* @__PURE__ */ React16.createElement(FiLink5, { size: 12 })
8377
+ )), /* @__PURE__ */ React16.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React16.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ React16.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ React16.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ React16.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ React16.createElement(
8154
8378
  "button",
8155
8379
  {
8156
8380
  type: "button",
8157
8381
  onClick: () => handleRemoveType(index),
8158
8382
  className: "hover:text-white transition-colors"
8159
8383
  },
8160
- /* @__PURE__ */ React15.createElement(FiX4, { size: 12 })
8161
- ))), canEdit && /* @__PURE__ */ React15.createElement(
8384
+ /* @__PURE__ */ React16.createElement(FiX5, { size: 12 })
8385
+ ))), canEdit && /* @__PURE__ */ React16.createElement(
8162
8386
  "input",
8163
8387
  {
8164
8388
  type: "text",
@@ -8179,7 +8403,7 @@ function NodeDetailsPanel({
8179
8403
  placeholder: types.length === 0 ? "Ex.: Cliente" : "",
8180
8404
  autoComplete: "off"
8181
8405
  }
8182
- ), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ React15.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-10 w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredTypes.map((suggestedType, index) => /* @__PURE__ */ React15.createElement(
8406
+ ), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ React16.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-10 w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredTypes.map((suggestedType, index) => /* @__PURE__ */ React16.createElement(
8183
8407
  "li",
8184
8408
  {
8185
8409
  key: index,
@@ -8190,7 +8414,7 @@ function NodeDetailsPanel({
8190
8414
  }
8191
8415
  },
8192
8416
  suggestedType
8193
- ))))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ React15.createElement(
8417
+ ))))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ React16.createElement(
8194
8418
  "input",
8195
8419
  {
8196
8420
  type: "text",
@@ -8199,7 +8423,7 @@ function NodeDetailsPanel({
8199
8423
  readOnly: !canEdit,
8200
8424
  className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none ${canEdit ? "focus:ring-2 focus:ring-indigo-400/60" : "cursor-default text-slate-400"}`
8201
8425
  }
8202
- )), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React15.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React15.createElement(
8426
+ )), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React16.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React16.createElement(
8203
8427
  DescriptionDisplay,
8204
8428
  {
8205
8429
  description,
@@ -8211,7 +8435,7 @@ function NodeDetailsPanel({
8211
8435
  onImageClick: handleImageClickFromText,
8212
8436
  onSaveDescription: handleSaveDescriptionInline
8213
8437
  }
8214
- ), /* @__PURE__ */ React15.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React15.createElement(
8438
+ ), /* @__PURE__ */ React16.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React16.createElement(
8215
8439
  "button",
8216
8440
  {
8217
8441
  type: "button",
@@ -8219,8 +8443,8 @@ function NodeDetailsPanel({
8219
8443
  className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`,
8220
8444
  title: "Modo de Leitura"
8221
8445
  },
8222
- /* @__PURE__ */ React15.createElement(FiBookOpen3, { size: 14 })
8223
- ), canEdit && /* @__PURE__ */ React15.createElement(
8446
+ /* @__PURE__ */ React16.createElement(FiBookOpen3, { size: 14 })
8447
+ ), canEdit && /* @__PURE__ */ React16.createElement(
8224
8448
  "button",
8225
8449
  {
8226
8450
  type: "button",
@@ -8228,17 +8452,17 @@ function NodeDetailsPanel({
8228
8452
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8229
8453
  title: "Editar descri\xE7\xE3o (Modo de Escrita)"
8230
8454
  },
8231
- /* @__PURE__ */ React15.createElement(FiEdit26, { size: 14 })
8232
- )), canEdit && !description && /* @__PURE__ */ React15.createElement(
8455
+ /* @__PURE__ */ React16.createElement(FiEdit27, { size: 14 })
8456
+ )), canEdit && !description && /* @__PURE__ */ React16.createElement(
8233
8457
  "div",
8234
8458
  {
8235
8459
  onClick: () => setIsDescriptionModalOpen(true),
8236
8460
  className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
8237
8461
  },
8238
8462
  "Adicionar descri\xE7\xE3o..."
8239
- ))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
8463
+ ))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
8240
8464
  const isSelected = size === s;
8241
- return /* @__PURE__ */ React15.createElement(
8465
+ return /* @__PURE__ */ React16.createElement(
8242
8466
  "button",
8243
8467
  {
8244
8468
  key: s,
@@ -8246,10 +8470,10 @@ function NodeDetailsPanel({
8246
8470
  onClick: () => canEdit && handleSizeChange(s),
8247
8471
  className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
8248
8472
  },
8249
- /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })),
8250
- /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
8473
+ /* @__PURE__ */ React16.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ React16.createElement(FiCheck10, { size: 12, className: "text-white" })),
8474
+ /* @__PURE__ */ React16.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
8251
8475
  );
8252
- }))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ React15.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement(
8476
+ }))), /* @__PURE__ */ React16.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React16.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ React16.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React16.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React16.createElement(FiCheck10, { size: 12, className: "text-white" })), /* @__PURE__ */ React16.createElement(
8253
8477
  "input",
8254
8478
  {
8255
8479
  type: "checkbox",
@@ -8257,14 +8481,14 @@ function NodeDetailsPanel({
8257
8481
  onChange: handleToggleImageMode,
8258
8482
  className: "hidden"
8259
8483
  }
8260
- ), /* @__PURE__ */ React15.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ React15.createElement(
8484
+ ), /* @__PURE__ */ React16.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ React16.createElement(
8261
8485
  ColorPicker,
8262
8486
  {
8263
8487
  color,
8264
8488
  onChange: handleColorChange,
8265
8489
  disabled: !canEdit || useImageAsTexture
8266
8490
  }
8267
- ), /* @__PURE__ */ React15.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ React15.createElement(FiSun2, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React15.createElement(
8491
+ ), /* @__PURE__ */ React16.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ React16.createElement(FiSun2, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ React16.createElement(
8268
8492
  "input",
8269
8493
  {
8270
8494
  type: "range",
@@ -8277,7 +8501,7 @@ function NodeDetailsPanel({
8277
8501
  className: `w-full h-1.5 bg-slate-700 rounded-lg appearance-none ${canEdit ? "cursor-pointer accent-indigo-500 hover:accent-indigo-400" : "cursor-default accent-slate-500"}`,
8278
8502
  title: `Intensidade do brilho: ${intensity}`
8279
8503
  }
8280
- ), /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ React15.createElement("span", { className: `text-xs block mt-1 transition-opacity ${useImageAsTexture ? "opacity-40" : "text-slate-400"}` }, useImageAsTexture ? "Cor da borda (definida pela imagem)" : "Ajuste a cor e a intensidade do brilho.")), /* @__PURE__ */ React15.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React15.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React15.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React15.createElement(FiPlus5, { size: 14 }), " Adicionar")), /* @__PURE__ */ React15.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React15.createElement(
8504
+ ), /* @__PURE__ */ React16.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ React16.createElement("span", { className: `text-xs block mt-1 transition-opacity ${useImageAsTexture ? "opacity-40" : "text-slate-400"}` }, useImageAsTexture ? "Cor da borda (definida pela imagem)" : "Ajuste a cor e a intensidade do brilho.")), /* @__PURE__ */ React16.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React16.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React16.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React16.createElement(FiPlus6, { size: 14 }), " Adicionar")), /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React16.createElement(
8281
8505
  CustomPropertyDisplay,
8282
8506
  {
8283
8507
  key: prop.id,
@@ -8292,7 +8516,7 @@ function NodeDetailsPanel({
8292
8516
  onUploadFile: canEdit ? onUploadFile : void 0,
8293
8517
  readOnly: !canEdit
8294
8518
  }
8295
- )), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React15.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ React15.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ React15.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React15.createElement(
8519
+ )), /* @__PURE__ */ React16.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React16.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ React16.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ React16.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ React16.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React16.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React16.createElement(
8296
8520
  "button",
8297
8521
  {
8298
8522
  onClick: () => handleSave(false),
@@ -8301,10 +8525,10 @@ function NodeDetailsPanel({
8301
8525
  ${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"}
8302
8526
  `
8303
8527
  },
8304
- isSaving && /* @__PURE__ */ React15.createElement(FiLoader2, { className: "animate-spin" }),
8528
+ isSaving && /* @__PURE__ */ React16.createElement(FiLoader2, { className: "animate-spin" }),
8305
8529
  isSaving ? "Salvando..." : "Salvar"
8306
8530
  )))
8307
- ), isDescriptionModalOpen && canEdit && /* @__PURE__ */ React15.createElement(
8531
+ ), isDescriptionModalOpen && canEdit && /* @__PURE__ */ React16.createElement(
8308
8532
  DescriptionEditModal,
8309
8533
  {
8310
8534
  isOpen: isDescriptionModalOpen,
@@ -8324,7 +8548,7 @@ function NodeDetailsPanel({
8324
8548
  }
8325
8549
 
8326
8550
  // src/components/MultiNodeContextMenu.jsx
8327
- import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState17, useEffect as useEffect16 } from "react";
8551
+ import React17, { useLayoutEffect as useLayoutEffect3, useRef as useRef14, useState as useState18, useEffect as useEffect16 } from "react";
8328
8552
  function MultiNodeContextMenu({
8329
8553
  data,
8330
8554
  userRole,
@@ -8333,9 +8557,9 @@ function MultiNodeContextMenu({
8333
8557
  onDismissOtherNodes,
8334
8558
  onDeleteNodes
8335
8559
  }) {
8336
- const menuRef = useRef13(null);
8337
- const [menuPos, setMenuPos] = useState17({ left: 0, top: 0 });
8338
- const [isConfirmingDelete, setIsConfirmingDelete] = useState17(false);
8560
+ const menuRef = useRef14(null);
8561
+ const [menuPos, setMenuPos] = useState18({ left: 0, top: 0 });
8562
+ const [isConfirmingDelete, setIsConfirmingDelete] = useState18(false);
8339
8563
  const ability = defineAbilityFor(userRole);
8340
8564
  const canDelete = ability.can("delete", "Node");
8341
8565
  useLayoutEffect3(() => {
@@ -8366,7 +8590,7 @@ function MultiNodeContextMenu({
8366
8590
  const baseButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-indigo-500/20 text-slate-200 hover:text-white transition-colors duration-150 truncate";
8367
8591
  const deleteButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-red-500/25 text-red-400 hover:text-red-300 transition-colors duration-150 truncate";
8368
8592
  const nodeCount = data.nodeIds.size;
8369
- return /* @__PURE__ */ React16.createElement(
8593
+ return /* @__PURE__ */ React17.createElement(
8370
8594
  "div",
8371
8595
  {
8372
8596
  ref: menuRef,
@@ -8380,28 +8604,28 @@ function MultiNodeContextMenu({
8380
8604
  onContextMenu: swallow,
8381
8605
  onDoubleClick: swallow
8382
8606
  },
8383
- /* @__PURE__ */ React16.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8384
- /* @__PURE__ */ React16.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React16.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React16.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React16.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React16.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React16.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React16.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ React16.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ React16.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React16.createElement(
8607
+ /* @__PURE__ */ React17.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8608
+ /* @__PURE__ */ React17.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React17.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ React17.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React17.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React17.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React17.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ React17.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ React17.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ React17.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React17.createElement(
8385
8609
  "button",
8386
8610
  {
8387
8611
  onClick: () => setIsConfirmingDelete(false),
8388
8612
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8389
8613
  },
8390
8614
  "Cancelar"
8391
- ), /* @__PURE__ */ React16.createElement(
8615
+ ), /* @__PURE__ */ React17.createElement(
8392
8616
  "button",
8393
8617
  {
8394
8618
  onClick: () => onDeleteNodes(data.nodeIds),
8395
8619
  className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
8396
8620
  },
8397
8621
  "Excluir"
8398
- ))) : /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React16.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React16.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React16.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React16.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React16.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React16.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React16.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React16.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React16.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React16.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React16.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React16.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React16.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React16.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React16.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React16.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React16.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React16.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React16.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React16.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React16.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8622
+ ))) : /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React17.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React17.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React17.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React17.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React17.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React17.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React17.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React17.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React17.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ React17.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React17.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React17.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React17.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React17.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React17.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React17.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React17.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React17.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ React17.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React17.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React17.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React17.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React17.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React17.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8399
8623
  );
8400
8624
  }
8401
8625
 
8402
8626
  // src/components/RelationshipDetailsPanel.jsx
8403
- import React17, { useState as useState18, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
8404
- import { FiPlus as FiPlus6, FiEdit2 as FiEdit27, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
8627
+ import React18, { useState as useState19, useEffect as useEffect17, useRef as useRef15, useMemo as useMemo9 } from "react";
8628
+ import { FiPlus as FiPlus7, FiEdit2 as FiEdit28, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
8405
8629
  function RelationshipDetailsPanel({
8406
8630
  link,
8407
8631
  onClose,
@@ -8415,14 +8639,14 @@ function RelationshipDetailsPanel({
8415
8639
  onUploadFile,
8416
8640
  userRole
8417
8641
  }) {
8418
- const [name, setName] = useState18((link == null ? void 0 : link.name) ?? "");
8419
- const [description, setDescription] = useState18((link == null ? void 0 : link.description) ?? "");
8420
- const [customProps, setCustomProps] = useState18(() => extractCustomPropsFromNode(link || {}));
8421
- const [existingSections, setExistingSections] = useState18((link == null ? void 0 : link.description_sections) || []);
8422
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState18(false);
8423
- const [isSaving, setIsSaving] = useState18(false);
8424
- const [isReadMode, setIsReadMode] = useState18(false);
8425
- const propsEndRef = useRef14(null);
8642
+ const [name, setName] = useState19((link == null ? void 0 : link.name) ?? "");
8643
+ const [description, setDescription] = useState19((link == null ? void 0 : link.description) ?? "");
8644
+ const [customProps, setCustomProps] = useState19(() => extractCustomPropsFromNode(link || {}));
8645
+ const [existingSections, setExistingSections] = useState19((link == null ? void 0 : link.description_sections) || []);
8646
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState19(false);
8647
+ const [isSaving, setIsSaving] = useState19(false);
8648
+ const [isReadMode, setIsReadMode] = useState19(false);
8649
+ const propsEndRef = useRef15(null);
8426
8650
  const canEdit = useMemo9(() => {
8427
8651
  const ability = defineAbilityFor(userRole);
8428
8652
  return ability.can("update", "Connection");
@@ -8502,7 +8726,7 @@ function RelationshipDetailsPanel({
8502
8726
  onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
8503
8727
  }
8504
8728
  };
8505
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
8729
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
8506
8730
  "div",
8507
8731
  {
8508
8732
  className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden transition-all duration-300 ease-out
@@ -8517,7 +8741,7 @@ function RelationshipDetailsPanel({
8517
8741
  onContextMenu: swallow,
8518
8742
  onDoubleClick: swallow
8519
8743
  },
8520
- isReadMode ? /* @__PURE__ */ React17.createElement(
8744
+ isReadMode ? /* @__PURE__ */ React18.createElement(
8521
8745
  DescriptionReadModePanel,
8522
8746
  {
8523
8747
  title: name || "Rela\xE7\xE3o",
@@ -8538,7 +8762,7 @@ function RelationshipDetailsPanel({
8538
8762
  onImageClick: handleImageClickFromText,
8539
8763
  onSaveDescription: handleSaveDescriptionInline
8540
8764
  }
8541
- ) : /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ React17.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React17.createElement("div", null, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React17.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ React17.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ React17.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ React17.createElement("button", { onClick: onClose, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React17.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ React17.createElement(
8765
+ ) : /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ React18.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React18.createElement("div", null, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React18.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ React18.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("button", { onClick: onClose, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React18.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React18.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React18.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ React18.createElement(
8542
8766
  "input",
8543
8767
  {
8544
8768
  type: "text",
@@ -8550,7 +8774,7 @@ function RelationshipDetailsPanel({
8550
8774
  ${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
8551
8775
  `
8552
8776
  }
8553
- )), /* @__PURE__ */ React17.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React17.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React17.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React17.createElement(
8777
+ )), /* @__PURE__ */ React18.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React18.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React18.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React18.createElement(
8554
8778
  DescriptionDisplay,
8555
8779
  {
8556
8780
  description,
@@ -8562,7 +8786,7 @@ function RelationshipDetailsPanel({
8562
8786
  onImageClick: handleImageClickFromText,
8563
8787
  onSaveDescription: handleSaveDescriptionInline
8564
8788
  }
8565
- ), /* @__PURE__ */ React17.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React17.createElement(
8789
+ ), /* @__PURE__ */ React18.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ React18.createElement(
8566
8790
  "button",
8567
8791
  {
8568
8792
  type: "button",
@@ -8570,8 +8794,8 @@ function RelationshipDetailsPanel({
8570
8794
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
8571
8795
  title: "Modo de Leitura"
8572
8796
  },
8573
- /* @__PURE__ */ React17.createElement(FiBookOpen4, { size: 14 })
8574
- ), canEdit && /* @__PURE__ */ React17.createElement(
8797
+ /* @__PURE__ */ React18.createElement(FiBookOpen4, { size: 14 })
8798
+ ), canEdit && /* @__PURE__ */ React18.createElement(
8575
8799
  "button",
8576
8800
  {
8577
8801
  type: "button",
@@ -8579,15 +8803,15 @@ function RelationshipDetailsPanel({
8579
8803
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8580
8804
  title: "Editar descri\xE7\xE3o"
8581
8805
  },
8582
- /* @__PURE__ */ React17.createElement(FiEdit27, { size: 14 })
8583
- )), !description && canEdit && /* @__PURE__ */ React17.createElement(
8806
+ /* @__PURE__ */ React18.createElement(FiEdit28, { size: 14 })
8807
+ )), !description && canEdit && /* @__PURE__ */ React18.createElement(
8584
8808
  "div",
8585
8809
  {
8586
8810
  onClick: () => setIsDescriptionModalOpen(true),
8587
8811
  className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
8588
8812
  },
8589
8813
  "Adicionar descri\xE7\xE3o..."
8590
- ))), /* @__PURE__ */ React17.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React17.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React17.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React17.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React17.createElement(FiPlus6, { size: 14 }), " Adicionar")), /* @__PURE__ */ React17.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React17.createElement(
8814
+ ))), /* @__PURE__ */ React18.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ React18.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ React18.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ React18.createElement(FiPlus7, { size: 14 }), " Adicionar")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ React18.createElement(
8591
8815
  CustomPropertyDisplay,
8592
8816
  {
8593
8817
  key: prop.id,
@@ -8599,7 +8823,7 @@ function RelationshipDetailsPanel({
8599
8823
  onUploadFile,
8600
8824
  disabled: !canEdit
8601
8825
  }
8602
- )), /* @__PURE__ */ React17.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React17.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React17.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React17.createElement(
8826
+ )), /* @__PURE__ */ React18.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React18.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React18.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React18.createElement(
8603
8827
  "button",
8604
8828
  {
8605
8829
  onClick: () => handleSave(false),
@@ -8608,10 +8832,10 @@ function RelationshipDetailsPanel({
8608
8832
  ${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-teal-600 to-teal-400 hover:from-teal-500 hover:to-teal-300 text-white"}
8609
8833
  `
8610
8834
  },
8611
- isSaving && /* @__PURE__ */ React17.createElement(FiLoader3, { className: "animate-spin" }),
8835
+ isSaving && /* @__PURE__ */ React18.createElement(FiLoader3, { className: "animate-spin" }),
8612
8836
  isSaving ? "Salvando..." : "Salvar"
8613
8837
  )))
8614
- ), isDescriptionModalOpen && /* @__PURE__ */ React17.createElement(
8838
+ ), isDescriptionModalOpen && /* @__PURE__ */ React18.createElement(
8615
8839
  DescriptionEditModal,
8616
8840
  {
8617
8841
  isOpen: isDescriptionModalOpen,
@@ -8632,7 +8856,7 @@ function RelationshipDetailsPanel({
8632
8856
  }
8633
8857
 
8634
8858
  // src/components/RelationshipContextMenu.jsx
8635
- import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState19, useEffect as useEffect18, useMemo as useMemo10 } from "react";
8859
+ import React19, { useLayoutEffect as useLayoutEffect4, useRef as useRef16, useState as useState20, useEffect as useEffect18, useMemo as useMemo10 } from "react";
8636
8860
  function RelationshipContextMenu({
8637
8861
  data,
8638
8862
  userRole,
@@ -8642,9 +8866,9 @@ function RelationshipContextMenu({
8642
8866
  onDelete,
8643
8867
  onClose
8644
8868
  }) {
8645
- const menuRef = useRef15(null);
8646
- const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
8647
- const [isConfirmingDelete, setIsConfirmingDelete] = useState19(false);
8869
+ const menuRef = useRef16(null);
8870
+ const [menuPos, setMenuPos] = useState20({ left: 0, top: 0 });
8871
+ const [isConfirmingDelete, setIsConfirmingDelete] = useState20(false);
8648
8872
  const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
8649
8873
  const sourceName = useMemo10(
8650
8874
  () => {
@@ -8689,7 +8913,7 @@ function RelationshipContextMenu({
8689
8913
  const dangerButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-rose-500/20 text-rose-300 hover:text-rose-100 transition-colors duration-150 truncate";
8690
8914
  const canUpdate = ability.can("update", "Connection");
8691
8915
  const canDelete = ability.can("delete", "Connection");
8692
- return /* @__PURE__ */ React18.createElement(
8916
+ return /* @__PURE__ */ React19.createElement(
8693
8917
  "div",
8694
8918
  {
8695
8919
  ref: menuRef,
@@ -8703,29 +8927,29 @@ function RelationshipContextMenu({
8703
8927
  onContextMenu: swallow,
8704
8928
  onDoubleClick: swallow
8705
8929
  },
8706
- /* @__PURE__ */ React18.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8707
- /* @__PURE__ */ React18.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React18.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ React18.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React18.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ React18.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ React18.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ React18.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React18.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ React18.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ React18.createElement("strong", null, targetName), ".")), /* @__PURE__ */ React18.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React18.createElement(
8930
+ /* @__PURE__ */ React19.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8931
+ /* @__PURE__ */ React19.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ React19.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ React19.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React19.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React19.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ React19.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ React19.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ React19.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ React19.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ React19.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ React19.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ React19.createElement("strong", null, targetName), ".")), /* @__PURE__ */ React19.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ React19.createElement(
8708
8932
  "button",
8709
8933
  {
8710
8934
  onClick: () => setIsConfirmingDelete(false),
8711
8935
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8712
8936
  },
8713
8937
  "Cancelar"
8714
- ), /* @__PURE__ */ React18.createElement(
8938
+ ), /* @__PURE__ */ React19.createElement(
8715
8939
  "button",
8716
8940
  {
8717
8941
  onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8718
8942
  className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
8719
8943
  },
8720
8944
  "Excluir"
8721
- ))) : /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React18.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ React18.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React18.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(
8945
+ ))) : /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React19.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ React19.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
8722
8946
  "button",
8723
8947
  {
8724
8948
  onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
8725
8949
  className: baseButtonClass,
8726
8950
  title: "Desconectar ponta ligada ao Source"
8727
8951
  },
8728
- /* @__PURE__ */ React18.createElement(
8952
+ /* @__PURE__ */ React19.createElement(
8729
8953
  "svg",
8730
8954
  {
8731
8955
  xmlns: "http://www.w3.org/2000/svg",
@@ -8738,18 +8962,18 @@ function RelationshipContextMenu({
8738
8962
  strokeLinecap: "round",
8739
8963
  strokeLinejoin: "round"
8740
8964
  },
8741
- /* @__PURE__ */ React18.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }),
8742
- /* @__PURE__ */ React18.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })
8965
+ /* @__PURE__ */ React19.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }),
8966
+ /* @__PURE__ */ React19.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })
8743
8967
  ),
8744
- /* @__PURE__ */ React18.createElement("span", null, "Desconectar Source (", sourceName, ")")
8745
- ), /* @__PURE__ */ React18.createElement(
8968
+ /* @__PURE__ */ React19.createElement("span", null, "Desconectar Source (", sourceName, ")")
8969
+ ), /* @__PURE__ */ React19.createElement(
8746
8970
  "button",
8747
8971
  {
8748
8972
  onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
8749
8973
  className: baseButtonClass,
8750
8974
  title: "Desconectar ponta ligada ao Target"
8751
8975
  },
8752
- /* @__PURE__ */ React18.createElement(
8976
+ /* @__PURE__ */ React19.createElement(
8753
8977
  "svg",
8754
8978
  {
8755
8979
  xmlns: "http://www.w3.org/2000/svg",
@@ -8762,21 +8986,21 @@ function RelationshipContextMenu({
8762
8986
  strokeLinecap: "round",
8763
8987
  strokeLinejoin: "round"
8764
8988
  },
8765
- /* @__PURE__ */ React18.createElement("polyline", { points: "16 3 21 3 21 8" }),
8766
- /* @__PURE__ */ React18.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
8767
- /* @__PURE__ */ React18.createElement("polyline", { points: "21 16 21 21 16 21" }),
8768
- /* @__PURE__ */ React18.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
8769
- /* @__PURE__ */ React18.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
8989
+ /* @__PURE__ */ React19.createElement("polyline", { points: "16 3 21 3 21 8" }),
8990
+ /* @__PURE__ */ React19.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
8991
+ /* @__PURE__ */ React19.createElement("polyline", { points: "21 16 21 21 16 21" }),
8992
+ /* @__PURE__ */ React19.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
8993
+ /* @__PURE__ */ React19.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
8770
8994
  ),
8771
- /* @__PURE__ */ React18.createElement("span", null, "Desconectar Target (", targetName, ")")
8772
- ), /* @__PURE__ */ React18.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ React18.createElement(
8995
+ /* @__PURE__ */ React19.createElement("span", null, "Desconectar Target (", targetName, ")")
8996
+ ), /* @__PURE__ */ React19.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ React19.createElement(
8773
8997
  "button",
8774
8998
  {
8775
8999
  onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
8776
9000
  className: baseButtonClass,
8777
9001
  title: "Abrir detalhes da rela\xE7\xE3o"
8778
9002
  },
8779
- /* @__PURE__ */ React18.createElement(
9003
+ /* @__PURE__ */ React19.createElement(
8780
9004
  "svg",
8781
9005
  {
8782
9006
  xmlns: "http://www.w3.org/2000/svg",
@@ -8789,19 +9013,19 @@ function RelationshipContextMenu({
8789
9013
  strokeLinecap: "round",
8790
9014
  strokeLinejoin: "round"
8791
9015
  },
8792
- /* @__PURE__ */ React18.createElement("circle", { cx: "12", cy: "12", r: "10" }),
8793
- /* @__PURE__ */ React18.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
8794
- /* @__PURE__ */ React18.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
9016
+ /* @__PURE__ */ React19.createElement("circle", { cx: "12", cy: "12", r: "10" }),
9017
+ /* @__PURE__ */ React19.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
9018
+ /* @__PURE__ */ React19.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
8795
9019
  ),
8796
- /* @__PURE__ */ React18.createElement("span", null, "Abrir Detalhes")
8797
- ), canDelete && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ React18.createElement(
9020
+ /* @__PURE__ */ React19.createElement("span", null, "Abrir Detalhes")
9021
+ ), canDelete && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ React19.createElement(
8798
9022
  "button",
8799
9023
  {
8800
9024
  onClick: () => setIsConfirmingDelete(true),
8801
9025
  className: dangerButtonClass,
8802
9026
  title: "Excluir esta conex\xE3o"
8803
9027
  },
8804
- /* @__PURE__ */ React18.createElement(
9028
+ /* @__PURE__ */ React19.createElement(
8805
9029
  "svg",
8806
9030
  {
8807
9031
  xmlns: "http://www.w3.org/2000/svg",
@@ -8814,19 +9038,19 @@ function RelationshipContextMenu({
8814
9038
  strokeLinecap: "round",
8815
9039
  strokeLinejoin: "round"
8816
9040
  },
8817
- /* @__PURE__ */ React18.createElement("polyline", { points: "3 6 5 6 21 6" }),
8818
- /* @__PURE__ */ React18.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
8819
- /* @__PURE__ */ React18.createElement("path", { d: "M10 11v6" }),
8820
- /* @__PURE__ */ React18.createElement("path", { d: "M14 11v6" }),
8821
- /* @__PURE__ */ React18.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
9041
+ /* @__PURE__ */ React19.createElement("polyline", { points: "3 6 5 6 21 6" }),
9042
+ /* @__PURE__ */ React19.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
9043
+ /* @__PURE__ */ React19.createElement("path", { d: "M10 11v6" }),
9044
+ /* @__PURE__ */ React19.createElement("path", { d: "M14 11v6" }),
9045
+ /* @__PURE__ */ React19.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
8822
9046
  ),
8823
- /* @__PURE__ */ React18.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
9047
+ /* @__PURE__ */ React19.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
8824
9048
  )))))
8825
9049
  );
8826
9050
  }
8827
9051
 
8828
9052
  // src/components/LoadingScreen.jsx
8829
- import React19 from "react";
9053
+ import React20 from "react";
8830
9054
  var styles = {
8831
9055
  loadingOverlay: {
8832
9056
  position: "fixed",
@@ -8858,11 +9082,11 @@ var styles = {
8858
9082
  `
8859
9083
  };
8860
9084
  function LoadingScreen() {
8861
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("style", null, styles.keyframes), /* @__PURE__ */ React19.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ React19.createElement("div", { style: styles.spinner })));
9085
+ return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("style", null, styles.keyframes), /* @__PURE__ */ React20.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ React20.createElement("div", { style: styles.spinner })));
8862
9086
  }
8863
9087
 
8864
9088
  // src/components/ImportParentFileModal.jsx
8865
- import React20, { useEffect as useEffect19, useState as useState20 } from "react";
9089
+ import React21, { useEffect as useEffect19, useState as useState21 } from "react";
8866
9090
  function ImportParentFileModal({
8867
9091
  isOpen,
8868
9092
  onClose,
@@ -8873,11 +9097,11 @@ function ImportParentFileModal({
8873
9097
  onFetchAvailableFiles,
8874
9098
  currentViewName
8875
9099
  }) {
8876
- const [activeTab, setActiveTab] = useState20("databases");
8877
- const [availableDbs, setAvailableDbs] = useState20([]);
8878
- const [availableViews, setAvailableViews] = useState20([]);
8879
- const [selectedItem, setSelectedItem] = useState20(null);
8880
- const [isLoading, setIsLoading] = useState20(false);
9100
+ const [activeTab, setActiveTab] = useState21("databases");
9101
+ const [availableDbs, setAvailableDbs] = useState21([]);
9102
+ const [availableViews, setAvailableViews] = useState21([]);
9103
+ const [selectedItem, setSelectedItem] = useState21(null);
9104
+ const [isLoading, setIsLoading] = useState21(false);
8881
9105
  useEffect19(() => {
8882
9106
  if (isOpen && session && onFetchAvailableFiles) {
8883
9107
  const fetchData = async () => {
@@ -8943,13 +9167,13 @@ function ImportParentFileModal({
8943
9167
  const swallow = (e) => e.stopPropagation();
8944
9168
  const currentList = activeTab === "databases" ? availableDbs : availableViews;
8945
9169
  const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
8946
- return /* @__PURE__ */ React20.createElement(
9170
+ return /* @__PURE__ */ React21.createElement(
8947
9171
  "div",
8948
9172
  {
8949
9173
  className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
8950
9174
  onClick: onClose
8951
9175
  },
8952
- /* @__PURE__ */ React20.createElement(
9176
+ /* @__PURE__ */ React21.createElement(
8953
9177
  "div",
8954
9178
  {
8955
9179
  className: "ui-overlay relative rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] text-white w-[min(92vw,500px)] flex flex-col max-h-[85vh]",
@@ -8961,14 +9185,14 @@ function ImportParentFileModal({
8961
9185
  onContextMenu: swallow,
8962
9186
  onDoubleClick: swallow
8963
9187
  },
8964
- /* @__PURE__ */ React20.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ React20.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ React20.createElement(
9188
+ /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ React21.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ React21.createElement(
8965
9189
  "button",
8966
9190
  {
8967
9191
  onClick: onClose,
8968
9192
  className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8969
9193
  title: "Fechar"
8970
9194
  },
8971
- /* @__PURE__ */ React20.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React20.createElement(
9195
+ /* @__PURE__ */ React21.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React21.createElement(
8972
9196
  "path",
8973
9197
  {
8974
9198
  fillRule: "evenodd",
@@ -8977,14 +9201,14 @@ function ImportParentFileModal({
8977
9201
  }
8978
9202
  ))
8979
9203
  )),
8980
- /* @__PURE__ */ React20.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ React20.createElement(
9204
+ /* @__PURE__ */ React21.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ React21.createElement(
8981
9205
  "button",
8982
9206
  {
8983
9207
  onClick: () => setActiveTab("databases"),
8984
9208
  className: `flex-1 py-3 text-sm font-medium border-b-2 transition-colors ${activeTab === "databases" ? "border-indigo-500 text-white" : "border-transparent text-slate-400 hover:text-slate-200"}`
8985
9209
  },
8986
9210
  "Arquivos Parent"
8987
- ), /* @__PURE__ */ React20.createElement(
9211
+ ), /* @__PURE__ */ React21.createElement(
8988
9212
  "button",
8989
9213
  {
8990
9214
  onClick: () => setActiveTab("views"),
@@ -8992,24 +9216,24 @@ function ImportParentFileModal({
8992
9216
  },
8993
9217
  "Views (Ancestralidades)"
8994
9218
  )),
8995
- /* @__PURE__ */ React20.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ React20.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ React20.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ React20.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ React20.createElement(
9219
+ /* @__PURE__ */ React21.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ React21.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ React21.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ React21.createElement(
8996
9220
  "div",
8997
9221
  {
8998
9222
  key: item.id,
8999
9223
  onClick: () => setSelectedItem(item),
9000
9224
  className: `px-4 py-3 rounded-lg border cursor-pointer transition-all duration-150 flex flex-col gap-1 ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "bg-indigo-600 border-indigo-500 shadow-lg" : "bg-slate-800/60 border-white/10 hover:border-white/20 hover:bg-slate-800"}`
9001
9225
  },
9002
- /* @__PURE__ */ React20.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React20.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ React20.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9003
- item.description && /* @__PURE__ */ React20.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9004
- )) : /* @__PURE__ */ React20.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9005
- /* @__PURE__ */ React20.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ React20.createElement(
9226
+ /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ React21.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9227
+ item.description && /* @__PURE__ */ React21.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9228
+ )) : /* @__PURE__ */ React21.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9229
+ /* @__PURE__ */ React21.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ React21.createElement(
9006
9230
  "button",
9007
9231
  {
9008
9232
  onClick: onClose,
9009
9233
  className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
9010
9234
  },
9011
9235
  "Cancelar"
9012
- ), /* @__PURE__ */ React20.createElement(
9236
+ ), /* @__PURE__ */ React21.createElement(
9013
9237
  "button",
9014
9238
  {
9015
9239
  onClick: handleConfirm,
@@ -9023,7 +9247,7 @@ function ImportParentFileModal({
9023
9247
  }
9024
9248
 
9025
9249
  // src/components/AncestryLinkDetailsPanel.jsx
9026
- import React21, { useState as useState21 } from "react";
9250
+ import React22, { useState as useState22 } from "react";
9027
9251
  import { FiBookOpen as FiBookOpen5 } from "react-icons/fi";
9028
9252
  function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
9029
9253
  var _a, _b, _c, _d;
@@ -9033,21 +9257,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9033
9257
  const customProps = extractCustomPropsFromNode(relationshipData);
9034
9258
  const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
9035
9259
  const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
9036
- const [isReadMode, setIsReadMode] = useState21(false);
9260
+ const [isReadMode, setIsReadMode] = useState22(false);
9037
9261
  const swallow = (e) => e.stopPropagation();
9038
9262
  const handleImageClickFromText = (url, name) => {
9039
9263
  if (onOpenImageViewer) {
9040
9264
  onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
9041
9265
  }
9042
9266
  };
9043
- return /* @__PURE__ */ React21.createElement(
9267
+ return /* @__PURE__ */ React22.createElement(
9044
9268
  "div",
9045
9269
  {
9046
9270
  className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
9047
9271
  onClick: onClose,
9048
9272
  onPointerDown: swallow
9049
9273
  },
9050
- /* @__PURE__ */ React21.createElement(
9274
+ /* @__PURE__ */ React22.createElement(
9051
9275
  "div",
9052
9276
  {
9053
9277
  className: `relative group rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col max-h-[calc(100vh-4rem)] transition-all duration-300 ease-out
@@ -9055,7 +9279,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9055
9279
  `,
9056
9280
  onClick: swallow
9057
9281
  },
9058
- isReadMode ? /* @__PURE__ */ React21.createElement(
9282
+ isReadMode ? /* @__PURE__ */ React22.createElement(
9059
9283
  DescriptionReadModePanel,
9060
9284
  {
9061
9285
  title: `${sourceName} \u2794 ${targetName}`,
@@ -9067,15 +9291,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9067
9291
  onMentionClick,
9068
9292
  onImageClick: handleImageClickFromText
9069
9293
  }
9070
- ) : /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ React21.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React21.createElement("div", null, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React21.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ React21.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ React21.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ React21.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ React21.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ React21.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ React21.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React21.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ React21.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React21.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React21.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React21.createElement(
9294
+ ) : /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ React22.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ React22.createElement("div", null, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React22.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ React22.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ React22.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ React22.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ React22.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ React22.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ React22.createElement("button", { onClick: onClose, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl", title: "Fechar" }, "\xD7")), /* @__PURE__ */ React22.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ React22.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React22.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ React22.createElement(
9071
9295
  "button",
9072
9296
  {
9073
9297
  onClick: () => setIsReadMode(true),
9074
9298
  className: "p-1 text-slate-400 hover:text-white transition-colors",
9075
9299
  title: "Modo de Leitura"
9076
9300
  },
9077
- /* @__PURE__ */ React21.createElement(FiBookOpen5, { size: 14 })
9078
- )), /* @__PURE__ */ React21.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ React21.createElement(
9301
+ /* @__PURE__ */ React22.createElement(FiBookOpen5, { size: 14 })
9302
+ )), /* @__PURE__ */ React22.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ React22.createElement(
9079
9303
  DescriptionDisplay,
9080
9304
  {
9081
9305
  description,
@@ -9084,7 +9308,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9084
9308
  onMentionClick,
9085
9309
  onImageClick: handleImageClickFromText
9086
9310
  }
9087
- ))), customProps.length > 0 && /* @__PURE__ */ React21.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React21.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ React21.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ React21.createElement(
9311
+ ))), customProps.length > 0 && /* @__PURE__ */ React22.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React22.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ React22.createElement(
9088
9312
  CustomPropertyDisplay,
9089
9313
  {
9090
9314
  key: prop.id,
@@ -9093,25 +9317,25 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9093
9317
  onOpenImageViewer,
9094
9318
  onUploadFile
9095
9319
  }
9096
- )))), !description && customProps.length === 0 && /* @__PURE__ */ React21.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ React21.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
9320
+ )))), !description && customProps.length === 0 && /* @__PURE__ */ React22.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ React22.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
9097
9321
  )
9098
9322
  );
9099
9323
  }
9100
9324
 
9101
9325
  // src/components/AncestryBoard.jsx
9102
- import React22, { useState as useState22, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
9326
+ import React23, { useState as useState23, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef17 } from "react";
9103
9327
  import {
9104
9328
  FiSearch as FiSearch4,
9105
9329
  FiLayers as FiLayers6,
9106
9330
  FiCornerUpRight as FiCornerUpRight4,
9107
9331
  FiPlay,
9108
- FiPlus as FiPlus7,
9332
+ FiPlus as FiPlus8,
9109
9333
  FiTrash2 as FiTrash23,
9110
9334
  FiArrowLeft as FiArrowLeft3,
9111
9335
  FiArrowRight,
9112
9336
  FiCheckCircle,
9113
9337
  FiLoader as FiLoader4,
9114
- FiX as FiX5,
9338
+ FiX as FiX6,
9115
9339
  FiAlertTriangle
9116
9340
  } from "react-icons/fi";
9117
9341
  var GroupItem = ({
@@ -9133,7 +9357,7 @@ var GroupItem = ({
9133
9357
  }) => {
9134
9358
  const canIndent = index > 0;
9135
9359
  const isPickingForThisGroup = pickingGroupId === group.id;
9136
- const textareaRef = useRef16(null);
9360
+ const textareaRef = useRef17(null);
9137
9361
  const adjustHeight = () => {
9138
9362
  const textarea = textareaRef.current;
9139
9363
  if (textarea) {
@@ -9144,10 +9368,10 @@ var GroupItem = ({
9144
9368
  useEffect20(() => {
9145
9369
  adjustHeight();
9146
9370
  }, [group.text]);
9147
- return /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React22.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React22.createElement("div", { className: `
9371
+ return /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React23.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React23.createElement("div", { className: `
9148
9372
  flex flex-col gap-2 py-2 px-3 transition-all duration-200
9149
9373
  ${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
9150
- ` }, /* @__PURE__ */ React22.createElement(
9374
+ ` }, /* @__PURE__ */ React23.createElement(
9151
9375
  "textarea",
9152
9376
  {
9153
9377
  ref: textareaRef,
@@ -9164,9 +9388,9 @@ var GroupItem = ({
9164
9388
  if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
9165
9389
  }
9166
9390
  }
9167
- ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ React22.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9391
+ ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ React23.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9168
9392
  const isValid = availableIds.has(String(anc.ancestry_id));
9169
- return /* @__PURE__ */ React22.createElement(
9393
+ return /* @__PURE__ */ React23.createElement(
9170
9394
  "div",
9171
9395
  {
9172
9396
  key: anc.ancestry_id,
@@ -9178,28 +9402,28 @@ var GroupItem = ({
9178
9402
  },
9179
9403
  isValid ? (
9180
9404
  // [MANTIDO] Botão Play visível para todos
9181
- /* @__PURE__ */ React22.createElement(
9405
+ /* @__PURE__ */ React23.createElement(
9182
9406
  "button",
9183
9407
  {
9184
9408
  onClick: () => onPlayAncestry(anc.ancestry_id),
9185
9409
  className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
9186
9410
  title: "Renderizar no cen\xE1rio"
9187
9411
  },
9188
- /* @__PURE__ */ React22.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9412
+ /* @__PURE__ */ React23.createElement(FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9189
9413
  )
9190
- ) : /* @__PURE__ */ React22.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React22.createElement(FiAlertTriangle, { size: 10 })),
9191
- /* @__PURE__ */ React22.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9192
- canEdit && /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ React22.createElement(
9414
+ ) : /* @__PURE__ */ React23.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ React23.createElement(FiAlertTriangle, { size: 10 })),
9415
+ /* @__PURE__ */ React23.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9416
+ canEdit && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ React23.createElement(
9193
9417
  "button",
9194
9418
  {
9195
9419
  onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
9196
9420
  className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
9197
9421
  title: "Remover men\xE7\xE3o"
9198
9422
  },
9199
- /* @__PURE__ */ React22.createElement(FiX5, { size: 12 })
9423
+ /* @__PURE__ */ React23.createElement(FiX6, { size: 12 })
9200
9424
  ))
9201
9425
  );
9202
- })), canEdit && /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React22.createElement(
9426
+ })), canEdit && /* @__PURE__ */ React23.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React23.createElement(
9203
9427
  "button",
9204
9428
  {
9205
9429
  onClick: () => onRequestPickAncestry(group.id),
@@ -9209,17 +9433,17 @@ var GroupItem = ({
9209
9433
  `,
9210
9434
  title: "Adicionar Ancestralidade a este grupo"
9211
9435
  },
9212
- isPickingForThisGroup ? /* @__PURE__ */ React22.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React22.createElement(FiSearch4, { size: 12 }),
9436
+ isPickingForThisGroup ? /* @__PURE__ */ React23.createElement(FiCheckCircle, { size: 12 }) : /* @__PURE__ */ React23.createElement(FiSearch4, { size: 12 }),
9213
9437
  isPickingForThisGroup ? "Selecionando..." : "Adicionar"
9214
- ), /* @__PURE__ */ React22.createElement(
9438
+ ), /* @__PURE__ */ React23.createElement(
9215
9439
  "button",
9216
9440
  {
9217
9441
  onClick: () => onAddSubgroup(group.id),
9218
9442
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9219
9443
  title: "Criar Subgrupo"
9220
9444
  },
9221
- /* @__PURE__ */ React22.createElement(FiPlus7, { size: 14 })
9222
- )), /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React22.createElement(
9445
+ /* @__PURE__ */ React23.createElement(FiPlus8, { size: 14 })
9446
+ )), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ React23.createElement(
9223
9447
  "button",
9224
9448
  {
9225
9449
  onClick: () => onIndent(group.id),
@@ -9227,24 +9451,24 @@ var GroupItem = ({
9227
9451
  className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
9228
9452
  title: "Aninhar no grupo acima"
9229
9453
  },
9230
- /* @__PURE__ */ React22.createElement(FiArrowRight, { size: 14 })
9231
- ), /* @__PURE__ */ React22.createElement(
9454
+ /* @__PURE__ */ React23.createElement(FiArrowRight, { size: 14 })
9455
+ ), /* @__PURE__ */ React23.createElement(
9232
9456
  "button",
9233
9457
  {
9234
9458
  onClick: () => onOutdent(group.id),
9235
9459
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9236
9460
  title: "Desaninhar"
9237
9461
  },
9238
- /* @__PURE__ */ React22.createElement(FiArrowLeft3, { size: 14 })
9239
- ), /* @__PURE__ */ React22.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React22.createElement(
9462
+ /* @__PURE__ */ React23.createElement(FiArrowLeft3, { size: 14 })
9463
+ ), /* @__PURE__ */ React23.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ React23.createElement(
9240
9464
  "button",
9241
9465
  {
9242
9466
  onClick: () => onDelete(group.id),
9243
9467
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
9244
9468
  title: "Remover Grupo"
9245
9469
  },
9246
- /* @__PURE__ */ React22.createElement(FiTrash23, { size: 14 })
9247
- )))), group.children && group.children.length > 0 && /* @__PURE__ */ React22.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React22.createElement(
9470
+ /* @__PURE__ */ React23.createElement(FiTrash23, { size: 14 })
9471
+ )))), group.children && group.children.length > 0 && /* @__PURE__ */ React23.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ React23.createElement(
9248
9472
  GroupItem,
9249
9473
  {
9250
9474
  key: childGroup.id,
@@ -9276,11 +9500,11 @@ function AncestryBoard({
9276
9500
  userRole
9277
9501
  // [NOVO] Recebe a role do usuário
9278
9502
  }) {
9279
- const [searchTerm, setSearchTerm] = useState22("");
9280
- const [groups, setGroups] = useState22([]);
9281
- const [isLoaded, setIsLoaded] = useState22(false);
9282
- const [pickingGroupId, setPickingGroupId] = useState22(null);
9283
- const [saveStatus, setSaveStatus] = useState22("idle");
9503
+ const [searchTerm, setSearchTerm] = useState23("");
9504
+ const [groups, setGroups] = useState23([]);
9505
+ const [isLoaded, setIsLoaded] = useState23(false);
9506
+ const [pickingGroupId, setPickingGroupId] = useState23(null);
9507
+ const [saveStatus, setSaveStatus] = useState23("idle");
9284
9508
  const canEdit = useMemo11(() => {
9285
9509
  return userRole !== "viewer";
9286
9510
  }, [userRole]);
@@ -9488,27 +9712,27 @@ function AncestryBoard({
9488
9712
  });
9489
9713
  };
9490
9714
  if (!isOpen) return null;
9491
- return /* @__PURE__ */ React22.createElement(
9715
+ return /* @__PURE__ */ React23.createElement(
9492
9716
  "div",
9493
9717
  {
9494
9718
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
9495
9719
  onClick: onClose
9496
9720
  },
9497
- /* @__PURE__ */ React22.createElement(
9721
+ /* @__PURE__ */ React23.createElement(
9498
9722
  "div",
9499
9723
  {
9500
9724
  className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
9501
9725
  onClick: (e) => e.stopPropagation()
9502
9726
  },
9503
- /* @__PURE__ */ React22.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React22.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React22.createElement(FiLayers6, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React22.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(FiLoader4, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React22.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React22.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React22.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React22.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React22.createElement(
9727
+ /* @__PURE__ */ React23.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ React23.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ React23.createElement(FiLayers6, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React23.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(FiLoader4, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ React23.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ React23.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ React23.createElement(
9504
9728
  "button",
9505
9729
  {
9506
9730
  onClick: handleAddRootGroup,
9507
9731
  className: "\n flex items-center gap-2 px-3 py-1.5 \n bg-white/5 hover:bg-white/10 \n border border-white/10 hover:border-white/20\n backdrop-blur-sm\n text-slate-200 hover:text-white\n rounded-md transition-all duration-200\n text-xs font-medium shadow-sm\n "
9508
9732
  },
9509
- /* @__PURE__ */ React22.createElement(FiPlus7, { size: 14, className: "text-indigo-400" }),
9510
- /* @__PURE__ */ React22.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
9511
- ), /* @__PURE__ */ React22.createElement(
9733
+ /* @__PURE__ */ React23.createElement(FiPlus8, { size: 14, className: "text-indigo-400" }),
9734
+ /* @__PURE__ */ React23.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
9735
+ ), /* @__PURE__ */ React23.createElement(
9512
9736
  "button",
9513
9737
  {
9514
9738
  onClick: onClose,
@@ -9516,11 +9740,11 @@ function AncestryBoard({
9516
9740
  },
9517
9741
  "\xD7"
9518
9742
  ))),
9519
- /* @__PURE__ */ React22.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React22.createElement("div", { className: `
9743
+ /* @__PURE__ */ React23.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ React23.createElement("div", { className: `
9520
9744
  flex flex-col border-r border-white/10 transition-all duration-300 flex-none
9521
9745
  ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
9522
9746
  min-w-[280px] max-w-[500px] bg-slate-900
9523
- ` }, /* @__PURE__ */ React22.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React22.createElement("div", { className: "relative group" }, /* @__PURE__ */ React22.createElement(FiSearch4, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ React22.createElement(
9747
+ ` }, /* @__PURE__ */ React23.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ React23.createElement("div", { className: "relative group" }, /* @__PURE__ */ React23.createElement(FiSearch4, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ React23.createElement(
9524
9748
  "input",
9525
9749
  {
9526
9750
  type: "text",
@@ -9533,10 +9757,10 @@ function AncestryBoard({
9533
9757
  onChange: (e) => setSearchTerm(e.target.value),
9534
9758
  autoFocus: !pickingGroupId
9535
9759
  }
9536
- ))), /* @__PURE__ */ React22.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
9760
+ ))), /* @__PURE__ */ React23.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
9537
9761
  const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
9538
9762
  const isPicking = !!pickingGroupId;
9539
- return /* @__PURE__ */ React22.createElement(
9763
+ return /* @__PURE__ */ React23.createElement(
9540
9764
  "div",
9541
9765
  {
9542
9766
  key: anc.ancestry_id,
@@ -9548,12 +9772,12 @@ function AncestryBoard({
9548
9772
  ${isPicking ? "border-indigo-500/30 bg-indigo-500/5 hover:bg-indigo-500/20 hover:border-indigo-400 cursor-pointer" : "border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default"}
9549
9773
  `
9550
9774
  },
9551
- /* @__PURE__ */ React22.createElement("div", { className: `
9775
+ /* @__PURE__ */ React23.createElement("div", { className: `
9552
9776
  mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
9553
9777
  ${isPicking ? "bg-indigo-500 text-white border-indigo-400" : "bg-slate-800 text-indigo-400 border-white/5 group-hover:bg-indigo-500 group-hover:text-white"}
9554
- ` }, isPicking ? /* @__PURE__ */ React22.createElement(FiPlus7, { size: 16 }) : /* @__PURE__ */ React22.createElement(FiLayers6, { size: 14 })),
9555
- /* @__PURE__ */ React22.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React22.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ React22.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ React22.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React22.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React22.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ React22.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
9556
- !isPicking && /* @__PURE__ */ React22.createElement(
9778
+ ` }, isPicking ? /* @__PURE__ */ React23.createElement(FiPlus8, { size: 16 }) : /* @__PURE__ */ React23.createElement(FiLayers6, { size: 14 })),
9779
+ /* @__PURE__ */ React23.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ React23.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React23.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ React23.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ React23.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ React23.createElement(FiCornerUpRight4, { size: 10 }), /* @__PURE__ */ React23.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ React23.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
9780
+ !isPicking && /* @__PURE__ */ React23.createElement(
9557
9781
  "button",
9558
9782
  {
9559
9783
  onClick: (e) => {
@@ -9563,10 +9787,10 @@ function AncestryBoard({
9563
9787
  className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
9564
9788
  title: "Renderizar Ancestralidade"
9565
9789
  },
9566
- /* @__PURE__ */ React22.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React22.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
9790
+ /* @__PURE__ */ React23.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ React23.createElement(FiPlay, { size: 14, className: "ml-0.5" }))
9567
9791
  )
9568
9792
  );
9569
- }))), /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React22.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React22.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React22.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React22.createElement(React22.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React22.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React22.createElement(React22.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React22.createElement(
9793
+ }))), /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ React23.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ React23.createElement(FiLayers6, { size: 24, className: "opacity-20" }), /* @__PURE__ */ React23.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ React23.createElement(React23.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ React23.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ React23.createElement(React23.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ React23.createElement(
9570
9794
  GroupItem,
9571
9795
  {
9572
9796
  key: group.id,
@@ -9586,7 +9810,7 @@ function AncestryBoard({
9586
9810
  canEdit
9587
9811
  }
9588
9812
  ))))),
9589
- /* @__PURE__ */ React22.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ React22.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React22.createElement("span", null, groups.length, " grupos raiz"))
9813
+ /* @__PURE__ */ React23.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ React23.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ React23.createElement("span", null, groups.length, " grupos raiz"))
9590
9814
  )
9591
9815
  );
9592
9816
  }
@@ -9730,44 +9954,45 @@ function XViewScene({
9730
9954
  }
9731
9955
  return null;
9732
9956
  }, [ownerId, sceneConfigId]);
9733
- const sceneDataRef = useRef17(null);
9734
- const parentDataRef = useRef17(null);
9735
- const ancestryDataRef = useRef17(null);
9736
- const [isLoading, setIsLoading] = useState23(true);
9737
- const [permissionStatus, setPermissionStatus] = useState23("loading");
9738
- const [userPermissionRole, setUserPermissionRole] = useState23(null);
9739
- const [isInitialized, setIsInitialized] = useState23(false);
9740
- const [sceneVersion, setSceneVersion] = useState23(0);
9741
- const [contextMenu, setContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeData: null });
9742
- const [multiContextMenu, setMultiContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeIds: null });
9743
- const [relationshipMenu, setRelationshipMenu] = useState23({ visible: false, x: 0, y: 0, linkObject: null });
9744
- const [creationMode, setCreationMode] = useState23({ isActive: false, sourceNodeData: null });
9745
- const [versionMode, setVersionMode] = useState23({ isActive: false, sourceNodeData: null });
9746
- const [hasFocusedInitial, setHasFocusedInitial] = useState23(false);
9747
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState23(false);
9748
- const [ancestryMode, setAncestryMode] = useState23({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9749
- const [readingMode, setReadingMode] = useState23({
9957
+ const sceneDataRef = useRef18(null);
9958
+ const parentDataRef = useRef18(null);
9959
+ const ancestryDataRef = useRef18(null);
9960
+ const [isLoading, setIsLoading] = useState24(true);
9961
+ const [permissionStatus, setPermissionStatus] = useState24("loading");
9962
+ const [userPermissionRole, setUserPermissionRole] = useState24(null);
9963
+ const [isInitialized, setIsInitialized] = useState24(false);
9964
+ const [sceneVersion, setSceneVersion] = useState24(0);
9965
+ const [contextMenu, setContextMenu] = useState24({ visible: false, x: 0, y: 0, nodeData: null });
9966
+ const [multiContextMenu, setMultiContextMenu] = useState24({ visible: false, x: 0, y: 0, nodeIds: null });
9967
+ const [relationshipMenu, setRelationshipMenu] = useState24({ visible: false, x: 0, y: 0, linkObject: null });
9968
+ const [creationMode, setCreationMode] = useState24({ isActive: false, sourceNodeData: null });
9969
+ const [versionMode, setVersionMode] = useState24({ isActive: false, sourceNodeData: null });
9970
+ const [questMode, setQuestMode] = useState24({ isActive: false });
9971
+ const [hasFocusedInitial, setHasFocusedInitial] = useState24(false);
9972
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState24(false);
9973
+ const [ancestryMode, setAncestryMode] = useState24({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9974
+ const [readingMode, setReadingMode] = useState24({
9750
9975
  isActive: false,
9751
9976
  ancestry: null,
9752
9977
  branchStack: [],
9753
9978
  autoAbstraction: false
9754
9979
  });
9755
- const [formPosition, setFormPosition] = useState23({ left: 16, top: 16, opacity: 0 });
9756
- const [detailsNode, setDetailsNode] = useState23(null);
9757
- const [detailsLink, setDetailsLink] = useState23(null);
9758
- const [ancestryLinkDetails, setAncestryLinkDetails] = useState23(null);
9759
- const [imageViewer, setImageViewer] = useState23({ visible: false, images: [], startIndex: 0 });
9760
- const [editingAncestryRel, setEditingAncestryRel] = useState23({ visible: false, data: null, path: null });
9761
- const [isImportModalOpen, setIsImportModalOpen] = useState23(false);
9762
- const [importSuccessMessage, setImportSuccessMessage] = useState23("");
9763
- const [highlightedNodeId, setHighlightedNodeId] = useState23(null);
9764
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState23(false);
9765
- const [ancestryBoardData, setAncestryBoardData] = useState23([]);
9766
- const [isSidebarOpen, setIsSidebarOpen] = useState23(false);
9767
- const mountRef = useRef17(null);
9768
- const tooltipRef = useRef17(null);
9769
- const formRef = useRef17(null);
9770
- const stateRef = useRef17({
9980
+ const [formPosition, setFormPosition] = useState24({ left: 16, top: 16, opacity: 0 });
9981
+ const [detailsNode, setDetailsNode] = useState24(null);
9982
+ const [detailsLink, setDetailsLink] = useState24(null);
9983
+ const [ancestryLinkDetails, setAncestryLinkDetails] = useState24(null);
9984
+ const [imageViewer, setImageViewer] = useState24({ visible: false, images: [], startIndex: 0 });
9985
+ const [editingAncestryRel, setEditingAncestryRel] = useState24({ visible: false, data: null, path: null });
9986
+ const [isImportModalOpen, setIsImportModalOpen] = useState24(false);
9987
+ const [importSuccessMessage, setImportSuccessMessage] = useState24("");
9988
+ const [highlightedNodeId, setHighlightedNodeId] = useState24(null);
9989
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState24(false);
9990
+ const [ancestryBoardData, setAncestryBoardData] = useState24([]);
9991
+ const [isSidebarOpen, setIsSidebarOpen] = useState24(false);
9992
+ const mountRef = useRef18(null);
9993
+ const tooltipRef = useRef18(null);
9994
+ const formRef = useRef18(null);
9995
+ const stateRef = useRef18({
9771
9996
  readMode: {
9772
9997
  currentMaxIndex: 0,
9773
9998
  progressMap: {}
@@ -10809,12 +11034,15 @@ function XViewScene({
10809
11034
  if (mountRef.current) mountRef.current.style.cursor = "grab";
10810
11035
  }
10811
11036
  function handleKeyDown(event) {
11037
+ var _a2, _b2, _c2, _d2;
10812
11038
  const context = actionHandlerContext;
10813
11039
  if (event.key === "Escape") {
10814
11040
  if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
10815
11041
  if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
10816
11042
  if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
11043
+ if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
10817
11044
  if (stateRef.current.ancestry.isActive) handleCancelAncestryCreation();
11045
+ if ((_b2 = context.questMode) == null ? void 0 : _b2.isActive) context.setters.setQuestMode({ isActive: false });
10818
11046
  if (stateRef.current.selectedNodes.size > 0) {
10819
11047
  stateRef.current.selectedNodes.clear();
10820
11048
  }
@@ -10822,6 +11050,17 @@ function XViewScene({
10822
11050
  setMultiContextMenu((prev) => ({ ...prev, visible: false }));
10823
11051
  setRelationshipMenu((prev) => ({ ...prev, visible: false }));
10824
11052
  }
11053
+ if (event.key.toLowerCase() === "q") {
11054
+ const isUiClear = !stateRef.current.creation.isActive && !stateRef.current.connection.isActive && !stateRef.current.relink.isActive && !stateRef.current.ancestry.isActive && !((_c2 = context.versionMode) == null ? void 0 : _c2.isActive) && !contextMenu.visible && !multiContextMenu.visible && !relationshipMenu.visible && !readingMode.isActive && !isImportModalOpen && !isAncestryBoardOpen;
11055
+ if (isUiClear) {
11056
+ const isView = ((_d2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _d2.toLowerCase()) === "view";
11057
+ if (!isView) {
11058
+ alert("Nodes de Quest s\xF3 podem ser criados dentro de uma View.");
11059
+ return;
11060
+ }
11061
+ setQuestMode({ isActive: true });
11062
+ }
11063
+ }
10825
11064
  }
10826
11065
  function handleDoubleClick(event) {
10827
11066
  if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
@@ -10980,9 +11219,7 @@ function XViewScene({
10980
11219
  mountEl: currentMount,
10981
11220
  isSceneBusy: stateRef.current.isDragging || creation.isActive || connection.isActive || relink.isActive || ancestryMode.isActive,
10982
11221
  parentData: parentDataRef.current,
10983
- // <--- ADICIONADO AQUI
10984
11222
  ancestryData: ancestryDataRef.current
10985
- // <--- ADICIONADO AQUI
10986
11223
  });
10987
11224
  (_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
10988
11225
  stateRef.current.controls.update();
@@ -11288,6 +11525,11 @@ function XViewScene({
11288
11525
  mountRef,
11289
11526
  creationMode,
11290
11527
  versionMode,
11528
+ questMode,
11529
+ sceneSaveUrl,
11530
+ sceneConfigId,
11531
+ ownerId,
11532
+ viewType: viewParams == null ? void 0 : viewParams.type,
11291
11533
  userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
11292
11534
  setters: {
11293
11535
  setContextMenu,
@@ -11299,7 +11541,8 @@ function XViewScene({
11299
11541
  setDetailsNode,
11300
11542
  setDetailsLink,
11301
11543
  setSceneVersion,
11302
- setAncestryMode
11544
+ setAncestryMode,
11545
+ setQuestMode
11303
11546
  },
11304
11547
  tweenToTarget,
11305
11548
  handleVersionTimeline,
@@ -11315,8 +11558,13 @@ function XViewScene({
11315
11558
  [
11316
11559
  creationMode,
11317
11560
  versionMode,
11318
- tweenToTarget,
11561
+ questMode,
11562
+ sceneSaveUrl,
11563
+ sceneConfigId,
11564
+ ownerId,
11565
+ viewParams == null ? void 0 : viewParams.type,
11319
11566
  (_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
11567
+ tweenToTarget,
11320
11568
  handleVersionTimeline,
11321
11569
  save_view_data,
11322
11570
  get_single_parent_file,
@@ -11328,6 +11576,97 @@ function XViewScene({
11328
11576
  const handleStartVersioning = (nodeData) => {
11329
11577
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
11330
11578
  };
11579
+ const handleSaveQuestNode = async (context, newQuestData) => {
11580
+ const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
11581
+ if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
11582
+ const newNode = {
11583
+ id: short2.generate(),
11584
+ ...newQuestData,
11585
+ is_quest: true,
11586
+ type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
11587
+ };
11588
+ if (!graphDataRef.current[sceneConfigId2]) {
11589
+ graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
11590
+ }
11591
+ graphDataRef.current[sceneConfigId2].nodes.push(newNode);
11592
+ const sceneFileData = {
11593
+ parent_dbs: sceneDataRef2.current.parent_dbs,
11594
+ nodes: sceneDataRef2.current.nodes,
11595
+ // <-- Mantém o cenário inicial inalterado
11596
+ links: sceneDataRef2.current.links,
11597
+ // <-- Mantém o cenário inicial inalterado
11598
+ quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
11599
+ quest_links: graphDataRef.current[sceneConfigId2].links
11600
+ };
11601
+ try {
11602
+ await actions.save_view_data(sceneSaveUrl2, sceneFileData);
11603
+ stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
11604
+ parentFileId: sceneConfigId2,
11605
+ ownerId: ownerId2,
11606
+ datasetName: "Quests Internas (View)"
11607
+ });
11608
+ const basePosition = stateRef2.current.controls.target.clone();
11609
+ const offset = new THREE3.Vector3((Math.random() - 0.5) * 15, (Math.random() - 0.5) * 5, 0);
11610
+ const finalPosition = basePosition.add(offset);
11611
+ addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
11612
+ context.tweenToTarget(finalPosition, 1.2);
11613
+ setters.setQuestMode({ isActive: false });
11614
+ setters.setSceneVersion((v) => v + 1);
11615
+ } catch (error) {
11616
+ console.error("Falha ao salvar Quest na View:", error);
11617
+ alert("Ocorreu um erro ao criar a Quest.");
11618
+ }
11619
+ };
11620
+ userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
11621
+ const { stateRef: stateRef2, graphDataRef, sceneDataRef: sceneDataRef2, sceneConfigId: sceneConfigId2, sceneSaveUrl: sceneSaveUrl2, ownerId: ownerId2 } = context;
11622
+ const { sourceNodeData } = stateRef2.current.connection;
11623
+ if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
11624
+ userActionHandlers.handleCancelConnection(context);
11625
+ return;
11626
+ }
11627
+ const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id, sceneConfigId2, ownerId2);
11628
+ const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id, sceneConfigId2, ownerId2);
11629
+ let parentInfoToSave = sourceParentInfo;
11630
+ if (sourceParentInfo.parentFileId === sceneConfigId2 && targetParentInfo.parentFileId !== sceneConfigId2) {
11631
+ parentInfoToSave = targetParentInfo;
11632
+ } else if (targetParentInfo.parentFileId === sceneConfigId2 && sourceParentInfo.parentFileId !== sceneConfigId2) {
11633
+ parentInfoToSave = sourceParentInfo;
11634
+ }
11635
+ const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
11636
+ const newLink = {
11637
+ id: `link_${short2.generate()}`,
11638
+ source: sourceNodeData.id,
11639
+ target: targetNodeData.id
11640
+ };
11641
+ try {
11642
+ if (parentFileIdToSave === sceneConfigId2) {
11643
+ const specificParentData = graphDataRef.current[sceneConfigId2];
11644
+ specificParentData.links.push(newLink);
11645
+ const viewFilePayload = {
11646
+ parent_dbs: sceneDataRef2.current.parent_dbs,
11647
+ nodes: sceneDataRef2.current.nodes,
11648
+ // <-- Usa o estado original intocado
11649
+ links: sceneDataRef2.current.links,
11650
+ // <-- Usa o estado original intocado
11651
+ quest_nodes: specificParentData.nodes,
11652
+ quest_links: specificParentData.links
11653
+ // Salva a conexão aqui!
11654
+ };
11655
+ await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
11656
+ } else {
11657
+ const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
11658
+ specificParentData.links.push(newLink);
11659
+ const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
11660
+ await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
11661
+ graphDataRef.current[parentFileIdToSave] = specificParentData;
11662
+ }
11663
+ addNewLinkToScene(stateRef2.current, newLink);
11664
+ } catch (error) {
11665
+ console.error("Falha ao salvar a nova conex\xE3o:", error);
11666
+ alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
11667
+ }
11668
+ userActionHandlers.handleCancelConnection(context);
11669
+ };
11331
11670
  const handleClearAncestryVisuals = useCallback4((ancestryId) => {
11332
11671
  const { renderedAncestries, ancestryGroup } = stateRef.current;
11333
11672
  const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
@@ -12595,6 +12934,7 @@ function XViewScene({
12595
12934
  [actionHandlerContext]
12596
12935
  );
12597
12936
  const handleSaveCurrentView = useCallback4(async () => {
12937
+ var _a2, _b2, _c2;
12598
12938
  const { nodeObjects, allLinks } = stateRef.current;
12599
12939
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
12600
12940
  console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
@@ -12616,17 +12956,22 @@ function XViewScene({
12616
12956
  const { sourceNode, targetNode, ...serializableLinkData } = line.userData;
12617
12957
  return serializableLinkData;
12618
12958
  });
12959
+ sceneDataRef.current.nodes = currentNodes;
12960
+ sceneDataRef.current.links = currentLinks;
12961
+ const isView = ((_a2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _a2.toLowerCase()) === "view";
12619
12962
  const sceneFileData = {
12620
12963
  parent_dbs: sceneDataRef.current.parent_dbs,
12621
12964
  nodes: currentNodes,
12622
- links: currentLinks
12965
+ links: currentLinks,
12966
+ quest_nodes: isView ? ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.nodes) || [] : sceneDataRef.current.quest_nodes || [],
12967
+ quest_links: isView ? ((_c2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _c2.links) || [] : sceneDataRef.current.quest_links || []
12623
12968
  };
12624
12969
  try {
12625
12970
  await save_view_data(sceneSaveUrl, sceneFileData);
12626
12971
  } catch (error) {
12627
12972
  console.error("Erro na chamada de save_view_data:", error);
12628
12973
  }
12629
- }, [sceneSaveUrl, save_view_data]);
12974
+ }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
12630
12975
  const allAvailableNodes = useMemo12(() => {
12631
12976
  if (!parentDataRef.current) return [];
12632
12977
  return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
@@ -12712,20 +13057,20 @@ function XViewScene({
12712
13057
  }
12713
13058
  }, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
12714
13059
  if (isLoading || status === "loading" || permissionStatus === "loading") {
12715
- return /* @__PURE__ */ React23.createElement(LoadingScreen, null);
13060
+ return /* @__PURE__ */ React24.createElement(LoadingScreen, null);
12716
13061
  }
12717
13062
  if (permissionStatus === "denied") {
12718
- return /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React23.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React23.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React23.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ React23.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ React23.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React23.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ React23.createElement(
13063
+ return /* @__PURE__ */ React24.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ React24.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ React24.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ React24.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ React24.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ React24.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ React24.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ React24.createElement(
12719
13064
  "button",
12720
13065
  {
12721
13066
  onClick: () => router.push("/dashboard/scenes"),
12722
13067
  className: "flex items-center justify-center gap-2 w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
12723
13068
  },
12724
- /* @__PURE__ */ React23.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ React23.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
13069
+ /* @__PURE__ */ React24.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ React24.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
12725
13070
  "Voltar para Scenes"
12726
13071
  )));
12727
13072
  }
12728
- return /* @__PURE__ */ React23.createElement(
13073
+ return /* @__PURE__ */ React24.createElement(
12729
13074
  "div",
12730
13075
  {
12731
13076
  ref: mountRef,
@@ -12737,7 +13082,7 @@ function XViewScene({
12737
13082
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
12738
13083
  }
12739
13084
  },
12740
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ React23.createElement(
13085
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ React24.createElement(
12741
13086
  XViewSidebar,
12742
13087
  {
12743
13088
  dbNodes: searchableDbNodes,
@@ -12757,7 +13102,7 @@ function XViewScene({
12757
13102
  userRole: userPermissionRole
12758
13103
  }
12759
13104
  ),
12760
- creationMode.isActive && /* @__PURE__ */ React23.createElement(
13105
+ creationMode.isActive && /* @__PURE__ */ React24.createElement(
12761
13106
  InSceneCreationForm,
12762
13107
  {
12763
13108
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -12782,7 +13127,7 @@ function XViewScene({
12782
13127
  availableAncestries: allAvailableAncestries
12783
13128
  }
12784
13129
  ),
12785
- versionMode.isActive && /* @__PURE__ */ React23.createElement(
13130
+ versionMode.isActive && /* @__PURE__ */ React24.createElement(
12786
13131
  InSceneVersionForm,
12787
13132
  {
12788
13133
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -12801,13 +13146,27 @@ function XViewScene({
12801
13146
  availableAncestries: allAvailableAncestries
12802
13147
  }
12803
13148
  ),
12804
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React23.createElement(
13149
+ questMode.isActive && /* @__PURE__ */ React24.createElement(
13150
+ InSceneQuestForm,
13151
+ {
13152
+ onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
13153
+ onCancel: () => setQuestMode({ isActive: false }),
13154
+ style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
13155
+ refEl: formRef,
13156
+ onOpenImageViewer: handleOpenImageViewer,
13157
+ onMentionClick: handleAddExistingNode,
13158
+ onUploadFile: upload_file_action,
13159
+ availableNodes: allAvailableNodes,
13160
+ availableAncestries: allAvailableAncestries
13161
+ }
13162
+ ),
13163
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React24.createElement(
12805
13164
  "div",
12806
13165
  {
12807
13166
  className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isReadModeResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
12808
13167
  style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
12809
13168
  },
12810
- /* @__PURE__ */ React23.createElement(
13169
+ /* @__PURE__ */ React24.createElement(
12811
13170
  "div",
12812
13171
  {
12813
13172
  onPointerDown: (e) => {
@@ -12818,7 +13177,7 @@ function XViewScene({
12818
13177
  title: "Arraste para redimensionar"
12819
13178
  }
12820
13179
  ),
12821
- /* @__PURE__ */ React23.createElement(
13180
+ /* @__PURE__ */ React24.createElement(
12822
13181
  DescriptionReadModePanel,
12823
13182
  {
12824
13183
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -12853,7 +13212,7 @@ function XViewScene({
12853
13212
  }
12854
13213
  )
12855
13214
  ),
12856
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React23.createElement(
13215
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ React24.createElement(
12857
13216
  CreateAncestryPanel,
12858
13217
  {
12859
13218
  ancestryMode,
@@ -12880,7 +13239,7 @@ function XViewScene({
12880
13239
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
12881
13240
  }
12882
13241
  ),
12883
- editingAncestryRel.visible && /* @__PURE__ */ React23.createElement(
13242
+ editingAncestryRel.visible && /* @__PURE__ */ React24.createElement(
12884
13243
  AncestryRelationshipPanel,
12885
13244
  {
12886
13245
  data: editingAncestryRel.data,
@@ -12894,7 +13253,7 @@ function XViewScene({
12894
13253
  onUploadFile: upload_file_action
12895
13254
  }
12896
13255
  ),
12897
- detailsNode && /* @__PURE__ */ React23.createElement(
13256
+ detailsNode && /* @__PURE__ */ React24.createElement(
12898
13257
  NodeDetailsPanel,
12899
13258
  {
12900
13259
  node: detailsNode,
@@ -12921,7 +13280,7 @@ function XViewScene({
12921
13280
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12922
13281
  }
12923
13282
  ),
12924
- detailsLink && /* @__PURE__ */ React23.createElement(
13283
+ detailsLink && /* @__PURE__ */ React24.createElement(
12925
13284
  RelationshipDetailsPanel,
12926
13285
  {
12927
13286
  link: detailsLink,
@@ -12935,7 +13294,7 @@ function XViewScene({
12935
13294
  userRole: userPermissionRole
12936
13295
  }
12937
13296
  ),
12938
- ancestryLinkDetails && /* @__PURE__ */ React23.createElement(
13297
+ ancestryLinkDetails && /* @__PURE__ */ React24.createElement(
12939
13298
  AncestryLinkDetailsPanel,
12940
13299
  {
12941
13300
  data: ancestryLinkDetails,
@@ -12946,7 +13305,7 @@ function XViewScene({
12946
13305
  onUploadFile: upload_file_action
12947
13306
  }
12948
13307
  ),
12949
- /* @__PURE__ */ React23.createElement(
13308
+ /* @__PURE__ */ React24.createElement(
12950
13309
  "div",
12951
13310
  {
12952
13311
  ref: tooltipRef,
@@ -12973,7 +13332,7 @@ function XViewScene({
12973
13332
  }
12974
13333
  }
12975
13334
  ),
12976
- /* @__PURE__ */ React23.createElement(
13335
+ /* @__PURE__ */ React24.createElement(
12977
13336
  ContextMenu,
12978
13337
  {
12979
13338
  data: contextMenu,
@@ -12996,7 +13355,7 @@ function XViewScene({
12996
13355
  onFocusNode: handleFocusNode
12997
13356
  }
12998
13357
  ),
12999
- /* @__PURE__ */ React23.createElement(
13358
+ /* @__PURE__ */ React24.createElement(
13000
13359
  MultiNodeContextMenu,
13001
13360
  {
13002
13361
  data: multiContextMenu,
@@ -13007,7 +13366,7 @@ function XViewScene({
13007
13366
  onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
13008
13367
  }
13009
13368
  ),
13010
- /* @__PURE__ */ React23.createElement(
13369
+ /* @__PURE__ */ React24.createElement(
13011
13370
  RelationshipContextMenu,
13012
13371
  {
13013
13372
  data: relationshipMenu,
@@ -13025,8 +13384,8 @@ function XViewScene({
13025
13384
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
13026
13385
  }
13027
13386
  ),
13028
- /* @__PURE__ */ React23.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13029
- /* @__PURE__ */ React23.createElement(
13387
+ /* @__PURE__ */ React24.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13388
+ /* @__PURE__ */ React24.createElement(
13030
13389
  AncestryBoard,
13031
13390
  {
13032
13391
  isOpen: isAncestryBoardOpen,
@@ -13039,7 +13398,7 @@ function XViewScene({
13039
13398
  userRole: userPermissionRole
13040
13399
  }
13041
13400
  ),
13042
- /* @__PURE__ */ React23.createElement(
13401
+ /* @__PURE__ */ React24.createElement(
13043
13402
  ImportParentFileModal,
13044
13403
  {
13045
13404
  isOpen: isImportModalOpen,
@@ -13100,11 +13459,24 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
13100
13459
  );
13101
13460
  }
13102
13461
  }
13462
+ if (type && type.toLowerCase() === "view") {
13463
+ parentData[scene_config] = {
13464
+ dataset_name: "Quests Internas (View)",
13465
+ nodes: sceneData.quest_nodes || [],
13466
+ links: sceneData.quest_links || []
13467
+ };
13468
+ }
13103
13469
  const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
13104
13470
  const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
13105
13471
  const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
13106
13472
  const parentLinkMap = new Map(allLinks.map((link) => [`${link.source}-${link.target}`, link]));
13107
- const validatedNodes = (sceneData.nodes || []).map((sceneNode) => parentNodeMap.get(String(sceneNode.id))).filter(Boolean);
13473
+ const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
13474
+ const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
13475
+ if (nodeTypes.includes("quest")) {
13476
+ return sceneNode;
13477
+ }
13478
+ return parentNodeMap.get(String(sceneNode.id));
13479
+ }).filter(Boolean);
13108
13480
  const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
13109
13481
  const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
13110
13482
  const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);