@lv-x-software-house/x_view 1.2.4-dev.1 → 1.2.4-dev.4

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 +671 -335
  2. package/dist/index.mjs +597 -261
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -43,9 +43,9 @@ __export(index_exports, {
43
43
  module.exports = __toCommonJS(index_exports);
44
44
 
45
45
  // src/XViewScene.jsx
46
- var import_react24 = __toESM(require("react"));
46
+ var import_react25 = __toESM(require("react"));
47
47
  var import_navigation = require("next/navigation");
48
- var import_react25 = require("next-auth/react");
48
+ var import_react26 = require("next-auth/react");
49
49
  var import_crypto_js = __toESM(require("crypto-js"));
50
50
  var THREE3 = __toESM(require("three"));
51
51
  var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
@@ -7848,9 +7848,181 @@ function InSceneVersionForm({
7848
7848
  ));
7849
7849
  }
7850
7850
 
7851
- // src/components/NodeDetailsPanel.jsx
7851
+ // src/components/InSceneQuestForm.jsx
7852
7852
  var import_react16 = __toESM(require("react"));
7853
7853
  var import_fi14 = require("react-icons/fi");
7854
+ var QUEST_STATUS_COLORS = {
7855
+ "Backlog": "#64748b",
7856
+ // Slate (Cinza azulado)
7857
+ "In Progress": "#eab308",
7858
+ // Yellow (Amarelo)
7859
+ "Review": "#a855f7",
7860
+ // Purple (Roxo)
7861
+ "Done": "#22c55e"
7862
+ // Green (Verde)
7863
+ };
7864
+ function InSceneQuestForm({
7865
+ onSave,
7866
+ onCancel,
7867
+ style,
7868
+ refEl,
7869
+ onOpenImageViewer,
7870
+ availableNodes = [],
7871
+ availableAncestries = [],
7872
+ onMentionClick,
7873
+ onUploadFile
7874
+ }) {
7875
+ const [name, setName] = (0, import_react16.useState)("");
7876
+ const [types, setTypes] = (0, import_react16.useState)(["quest"]);
7877
+ const [typeInput, setTypeInput] = (0, import_react16.useState)("");
7878
+ const [status, setStatus] = (0, import_react16.useState)("Backlog");
7879
+ const [size, setSize] = (0, import_react16.useState)("medium");
7880
+ const [intensity, setIntensity] = (0, import_react16.useState)(0);
7881
+ const [description, setDescription] = (0, import_react16.useState)("");
7882
+ const [customProps, setCustomProps] = (0, import_react16.useState)([]);
7883
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
7884
+ const propsEndRef = (0, import_react16.useRef)(null);
7885
+ const handleAddProp = () => {
7886
+ const newProp = createNewCustomProperty(customProps);
7887
+ setCustomProps([...customProps, newProp]);
7888
+ setTimeout(() => {
7889
+ var _a;
7890
+ (_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
7891
+ }, 100);
7892
+ };
7893
+ const handleRemoveProp = (index) => setCustomProps(customProps.filter((_, i) => i !== index));
7894
+ const handleUpdateProp = (index, updatedProp) => {
7895
+ const newProps = [...customProps];
7896
+ newProps[index] = updatedProp;
7897
+ setCustomProps(newProps);
7898
+ };
7899
+ const handleAddType = (newType) => {
7900
+ const trimmed = newType.trim().toLowerCase();
7901
+ if (trimmed && !types.includes(trimmed)) {
7902
+ setTypes([...types, trimmed]);
7903
+ setTypeInput("");
7904
+ }
7905
+ };
7906
+ const handleRemoveType = (indexToRemove) => {
7907
+ if (types[indexToRemove] === "quest") return;
7908
+ setTypes(types.filter((_, index) => index !== indexToRemove));
7909
+ };
7910
+ const handleTypeInputKeyDown = (e) => {
7911
+ if (e.key === "Enter") {
7912
+ e.preventDefault();
7913
+ handleAddType(typeInput);
7914
+ } else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
7915
+ handleRemoveType(types.length - 1);
7916
+ }
7917
+ };
7918
+ const handleSubmit = (e) => {
7919
+ e.preventDefault();
7920
+ if (!name.trim()) {
7921
+ alert("O campo 'Nome' \xE9 obrigat\xF3rio.");
7922
+ return;
7923
+ }
7924
+ const additionalData = toObjectFromCustomProps(
7925
+ customProps.filter((prop) => prop.key.trim() && !prop.isEditing)
7926
+ );
7927
+ const processedSections = processDescriptionForSave(description, []);
7928
+ onSave({
7929
+ name: name.trim(),
7930
+ type: types,
7931
+ color: QUEST_STATUS_COLORS[status],
7932
+ // Cor atrelada ao status
7933
+ status,
7934
+ size,
7935
+ intensity,
7936
+ description: description.trim(),
7937
+ description_sections: processedSections,
7938
+ useImageAsTexture: false,
7939
+ textureImageUrl: null,
7940
+ ...additionalData
7941
+ });
7942
+ };
7943
+ const swallow = (e) => e.stopPropagation();
7944
+ const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
7945
+ const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
7946
+ return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(
7947
+ "div",
7948
+ {
7949
+ ref: refEl,
7950
+ 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",
7951
+ style,
7952
+ onPointerDown: swallow,
7953
+ onClick: swallow,
7954
+ onWheel: swallow,
7955
+ onContextMenu: swallow,
7956
+ onDoubleClick: swallow
7957
+ },
7958
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS[status]}, transparent)` } }),
7959
+ /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Nova Tarefa / Objetivo")), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, "Criar Quest")),
7960
+ /* @__PURE__ */ import_react16.default.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col max-h-[68vh]" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react16.default.createElement(
7961
+ "select",
7962
+ {
7963
+ value: status,
7964
+ onChange: (e) => setStatus(e.target.value),
7965
+ 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",
7966
+ style: { borderLeft: `4px solid ${QUEST_STATUS_COLORS[status]}` }
7967
+ },
7968
+ /* @__PURE__ */ import_react16.default.createElement("option", { value: "Backlog" }, "Backlog"),
7969
+ /* @__PURE__ */ import_react16.default.createElement("option", { value: "In Progress" }, "In Progress"),
7970
+ /* @__PURE__ */ import_react16.default.createElement("option", { value: "Review" }, "Review"),
7971
+ /* @__PURE__ */ import_react16.default.createElement("option", { value: "Done" }, "Done")
7972
+ )), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Quest"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.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__ */ import_react16.default.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(FiX, { size: 12 })))), /* @__PURE__ */ import_react16.default.createElement(
7973
+ "input",
7974
+ {
7975
+ type: "text",
7976
+ value: typeInput,
7977
+ onChange: (e) => setTypeInput(e.target.value),
7978
+ onKeyDown: handleTypeInputKeyDown,
7979
+ onBlur: () => {
7980
+ if (typeInput.trim()) handleAddType(typeInput);
7981
+ },
7982
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
7983
+ placeholder: "Ex.: Bugfix",
7984
+ autoComplete: "off"
7985
+ }
7986
+ ))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
7987
+ DescriptionDisplay,
7988
+ {
7989
+ description,
7990
+ savedSections: [],
7991
+ availableNodes,
7992
+ availableAncestries,
7993
+ onMentionClick,
7994
+ onSaveDescription: (newDesc) => setDescription(newDesc)
7995
+ }
7996
+ ), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 }))), !description && /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Cen\xE1rio (Size)"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => /* @__PURE__ */ import_react16.default.createElement("button", { key: s, type: "button", onClick: () => setSize(s), className: "flex items-center gap-2 group cursor-pointer focus:outline-none" }, /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${size === s ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, index) => /* @__PURE__ */ import_react16.default.createElement(
7997
+ CustomPropertyDisplay,
7998
+ {
7999
+ key: prop.id,
8000
+ prop,
8001
+ onUpdate: (updatedProp) => handleUpdateProp(index, updatedProp),
8002
+ onRemove: () => handleRemoveProp(index),
8003
+ onOpenImageViewer,
8004
+ unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type),
8005
+ onUploadFile
8006
+ }
8007
+ )), /* @__PURE__ */ import_react16.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.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__ */ import_react16.default.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")))
8008
+ ), isDescriptionModalOpen && /* @__PURE__ */ import_react16.default.createElement(
8009
+ DescriptionEditModal,
8010
+ {
8011
+ isOpen: isDescriptionModalOpen,
8012
+ title: "Editar Descri\xE7\xE3o da Quest",
8013
+ initialValue: description,
8014
+ onSave: (newDescription) => setDescription(newDescription),
8015
+ onClose: () => setIsDescriptionModalOpen(false),
8016
+ availableNodes,
8017
+ availableAncestries,
8018
+ availableImages
8019
+ }
8020
+ ));
8021
+ }
8022
+
8023
+ // src/components/NodeDetailsPanel.jsx
8024
+ var import_react17 = __toESM(require("react"));
8025
+ var import_fi15 = require("react-icons/fi");
7854
8026
  function NodeDetailsPanel({
7855
8027
  node,
7856
8028
  onClose,
@@ -7871,38 +8043,38 @@ function NodeDetailsPanel({
7871
8043
  userRole,
7872
8044
  currentDatasetName
7873
8045
  }) {
7874
- const [name, setName] = (0, import_react16.useState)((node == null ? void 0 : node.name) ?? "");
7875
- const [types, setTypes] = (0, import_react16.useState)([]);
7876
- const [typeInput, setTypeInput] = (0, import_react16.useState)("");
7877
- const [color, setColor] = (0, import_react16.useState)((node == null ? void 0 : node.color) ?? "#8b5cf6");
7878
- const [size, setSize] = (0, import_react16.useState)((node == null ? void 0 : node.size) ?? "medium");
7879
- const [description, setDescription] = (0, import_react16.useState)((node == null ? void 0 : node.description) ?? "");
7880
- const [intensity, setIntensity] = (0, import_react16.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
7881
- const [customProps, setCustomProps] = (0, import_react16.useState)(() => extractCustomPropsFromNode(node || {}));
7882
- const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react16.useState)(false);
7883
- const [filteredTypes, setFilteredTypes] = (0, import_react16.useState)([]);
7884
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react16.useState)(false);
7885
- const [isReadMode, setIsReadMode] = (0, import_react16.useState)(false);
7886
- const [existingSections, setExistingSections] = (0, import_react16.useState)((node == null ? void 0 : node.description_sections) || []);
7887
- const [isSaving, setIsSaving] = (0, import_react16.useState)(false);
7888
- const [isLinkCopied, setIsLinkCopied] = (0, import_react16.useState)(false);
7889
- const [useImageAsTexture, setUseImageAsTexture] = (0, import_react16.useState)(() => {
8046
+ const [name, setName] = (0, import_react17.useState)((node == null ? void 0 : node.name) ?? "");
8047
+ const [types, setTypes] = (0, import_react17.useState)([]);
8048
+ const [typeInput, setTypeInput] = (0, import_react17.useState)("");
8049
+ const [color, setColor] = (0, import_react17.useState)((node == null ? void 0 : node.color) ?? "#8b5cf6");
8050
+ const [size, setSize] = (0, import_react17.useState)((node == null ? void 0 : node.size) ?? "medium");
8051
+ const [description, setDescription] = (0, import_react17.useState)((node == null ? void 0 : node.description) ?? "");
8052
+ const [intensity, setIntensity] = (0, import_react17.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
8053
+ const [customProps, setCustomProps] = (0, import_react17.useState)(() => extractCustomPropsFromNode(node || {}));
8054
+ const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react17.useState)(false);
8055
+ const [filteredTypes, setFilteredTypes] = (0, import_react17.useState)([]);
8056
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react17.useState)(false);
8057
+ const [isReadMode, setIsReadMode] = (0, import_react17.useState)(false);
8058
+ const [existingSections, setExistingSections] = (0, import_react17.useState)((node == null ? void 0 : node.description_sections) || []);
8059
+ const [isSaving, setIsSaving] = (0, import_react17.useState)(false);
8060
+ const [isLinkCopied, setIsLinkCopied] = (0, import_react17.useState)(false);
8061
+ const [useImageAsTexture, setUseImageAsTexture] = (0, import_react17.useState)(() => {
7890
8062
  if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
7891
8063
  if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
7892
8064
  return !!(node == null ? void 0 : node.useImageAsTexture);
7893
8065
  });
7894
- const [selectedImageUrl, setSelectedImageUrl] = (0, import_react16.useState)((node == null ? void 0 : node.textureImageUrl) ?? null);
8066
+ const [selectedImageUrl, setSelectedImageUrl] = (0, import_react17.useState)((node == null ? void 0 : node.textureImageUrl) ?? null);
7895
8067
  const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
7896
8068
  const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
7897
8069
  initialWidth: isReadMode ? 700 : 440,
7898
8070
  minWidth: 320,
7899
8071
  maxWidth: maxPanelW
7900
8072
  });
7901
- (0, import_react16.useEffect)(() => {
8073
+ (0, import_react17.useEffect)(() => {
7902
8074
  setWidth(isReadMode ? 700 : 440);
7903
8075
  }, [isReadMode, setWidth]);
7904
- const prevNodeIdRef = (0, import_react16.useRef)(null);
7905
- const propsEndRef = (0, import_react16.useRef)(null);
8076
+ const prevNodeIdRef = (0, import_react17.useRef)(null);
8077
+ const propsEndRef = (0, import_react17.useRef)(null);
7906
8078
  const canEdit = userRole !== "viewer";
7907
8079
  const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
7908
8080
  const handleImageClickFromText = (url, name2) => {
@@ -7910,7 +8082,7 @@ function NodeDetailsPanel({
7910
8082
  onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
7911
8083
  }
7912
8084
  };
7913
- (0, import_react16.useEffect)(() => {
8085
+ (0, import_react17.useEffect)(() => {
7914
8086
  if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
7915
8087
  prevNodeIdRef.current = node == null ? void 0 : node.id;
7916
8088
  setName((node == null ? void 0 : node.name) ?? "");
@@ -7932,13 +8104,13 @@ function NodeDetailsPanel({
7932
8104
  }
7933
8105
  }, [node]);
7934
8106
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
7935
- (0, import_react16.useEffect)(() => {
8107
+ (0, import_react17.useEffect)(() => {
7936
8108
  if (!hasImages && useImageAsTexture) {
7937
8109
  setUseImageAsTexture(false);
7938
8110
  setSelectedImageUrl(null);
7939
8111
  }
7940
8112
  }, [hasImages, useImageAsTexture]);
7941
- (0, import_react16.useEffect)(() => {
8113
+ (0, import_react17.useEffect)(() => {
7942
8114
  if (typeInput.trim() === "") {
7943
8115
  setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
7944
8116
  } else {
@@ -8110,7 +8282,7 @@ function NodeDetailsPanel({
8110
8282
  onClose();
8111
8283
  };
8112
8284
  const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
8113
- return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(
8285
+ return /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement(
8114
8286
  "div",
8115
8287
  {
8116
8288
  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"}`,
@@ -8123,7 +8295,7 @@ function NodeDetailsPanel({
8123
8295
  onContextMenu: swallow,
8124
8296
  onDoubleClick: swallow
8125
8297
  },
8126
- /* @__PURE__ */ import_react16.default.createElement(
8298
+ /* @__PURE__ */ import_react17.default.createElement(
8127
8299
  "div",
8128
8300
  {
8129
8301
  onPointerDown: (e) => {
@@ -8134,7 +8306,7 @@ function NodeDetailsPanel({
8134
8306
  title: "Arraste para redimensionar"
8135
8307
  }
8136
8308
  ),
8137
- isReadMode ? /* @__PURE__ */ import_react16.default.createElement(
8309
+ isReadMode ? /* @__PURE__ */ import_react17.default.createElement(
8138
8310
  DescriptionReadModePanel,
8139
8311
  {
8140
8312
  title: name || (node == null ? void 0 : node.name),
@@ -8155,23 +8327,23 @@ function NodeDetailsPanel({
8155
8327
  onImageClick: handleImageClickFromText,
8156
8328
  onSaveDescription: handleSaveDescriptionInline
8157
8329
  }
8158
- ) : /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react16.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react16.default.createElement("div", null, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react16.default.createElement(
8330
+ ) : /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }), /* @__PURE__ */ import_react17.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react17.default.createElement("div", null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes do Node"), /* @__PURE__ */ import_react17.default.createElement(
8159
8331
  "button",
8160
8332
  {
8161
8333
  onClick: handleCopyLink,
8162
8334
  className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
8163
8335
  title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
8164
8336
  },
8165
- isLinkCopied ? /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiLink, { size: 12 })
8166
- )), /* @__PURE__ */ import_react16.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.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__ */ import_react16.default.createElement(
8337
+ isLinkCopied ? /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLink, { size: 12 })
8338
+ )), /* @__PURE__ */ import_react17.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.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__ */ import_react17.default.createElement(
8167
8339
  "button",
8168
8340
  {
8169
8341
  type: "button",
8170
8342
  onClick: () => handleRemoveType(index),
8171
8343
  className: "hover:text-white transition-colors"
8172
8344
  },
8173
- /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiX, { size: 12 })
8174
- ))), canEdit && /* @__PURE__ */ import_react16.default.createElement(
8345
+ /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiX, { size: 12 })
8346
+ ))), canEdit && /* @__PURE__ */ import_react17.default.createElement(
8175
8347
  "input",
8176
8348
  {
8177
8349
  type: "text",
@@ -8192,7 +8364,7 @@ function NodeDetailsPanel({
8192
8364
  placeholder: types.length === 0 ? "Ex.: Cliente" : "",
8193
8365
  autoComplete: "off"
8194
8366
  }
8195
- ), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
8367
+ ), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(
8196
8368
  "li",
8197
8369
  {
8198
8370
  key: index,
@@ -8203,7 +8375,7 @@ function NodeDetailsPanel({
8203
8375
  }
8204
8376
  },
8205
8377
  suggestedType
8206
- ))))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react16.default.createElement(
8378
+ ))))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react17.default.createElement(
8207
8379
  "input",
8208
8380
  {
8209
8381
  type: "text",
@@ -8212,7 +8384,7 @@ function NodeDetailsPanel({
8212
8384
  readOnly: !canEdit,
8213
8385
  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"}`
8214
8386
  }
8215
- )), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
8387
+ )), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(
8216
8388
  DescriptionDisplay,
8217
8389
  {
8218
8390
  description,
@@ -8224,7 +8396,7 @@ function NodeDetailsPanel({
8224
8396
  onImageClick: handleImageClickFromText,
8225
8397
  onSaveDescription: handleSaveDescriptionInline
8226
8398
  }
8227
- ), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(
8399
+ ), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(
8228
8400
  "button",
8229
8401
  {
8230
8402
  type: "button",
@@ -8232,8 +8404,8 @@ function NodeDetailsPanel({
8232
8404
  className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`,
8233
8405
  title: "Modo de Leitura"
8234
8406
  },
8235
- /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiBookOpen, { size: 14 })
8236
- ), canEdit && /* @__PURE__ */ import_react16.default.createElement(
8407
+ /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiBookOpen, { size: 14 })
8408
+ ), canEdit && /* @__PURE__ */ import_react17.default.createElement(
8237
8409
  "button",
8238
8410
  {
8239
8411
  type: "button",
@@ -8241,17 +8413,17 @@ function NodeDetailsPanel({
8241
8413
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8242
8414
  title: "Editar descri\xE7\xE3o (Modo de Escrita)"
8243
8415
  },
8244
- /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiEdit2, { size: 14 })
8245
- )), canEdit && !description && /* @__PURE__ */ import_react16.default.createElement(
8416
+ /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiEdit2, { size: 14 })
8417
+ )), canEdit && !description && /* @__PURE__ */ import_react17.default.createElement(
8246
8418
  "div",
8247
8419
  {
8248
8420
  onClick: () => setIsDescriptionModalOpen(true),
8249
8421
  className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
8250
8422
  },
8251
8423
  "Adicionar descri\xE7\xE3o..."
8252
- ))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
8424
+ ))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Size"), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
8253
8425
  const isSelected = size === s;
8254
- return /* @__PURE__ */ import_react16.default.createElement(
8426
+ return /* @__PURE__ */ import_react17.default.createElement(
8255
8427
  "button",
8256
8428
  {
8257
8429
  key: s,
@@ -8259,10 +8431,10 @@ function NodeDetailsPanel({
8259
8431
  onClick: () => canEdit && handleSizeChange(s),
8260
8432
  className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
8261
8433
  },
8262
- /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })),
8263
- /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
8434
+ /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })),
8435
+ /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
8264
8436
  );
8265
- }))), /* @__PURE__ */ import_react16.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react16.default.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ import_react16.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(import_fi14.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react16.default.createElement(
8437
+ }))), /* @__PURE__ */ import_react17.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react17.default.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ import_react17.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(import_fi15.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react17.default.createElement(
8266
8438
  "input",
8267
8439
  {
8268
8440
  type: "checkbox",
@@ -8270,14 +8442,14 @@ function NodeDetailsPanel({
8270
8442
  onChange: handleToggleImageMode,
8271
8443
  className: "hidden"
8272
8444
  }
8273
- ), /* @__PURE__ */ import_react16.default.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ import_react16.default.createElement(
8445
+ ), /* @__PURE__ */ import_react17.default.createElement("span", { className: `text-xs ${useImageAsTexture ? "text-indigo-300" : "text-slate-400 group-hover:text-slate-300"}` }, "Usar imagem para representar o node"))), /* @__PURE__ */ import_react17.default.createElement(
8274
8446
  ColorPicker,
8275
8447
  {
8276
8448
  color,
8277
8449
  onChange: handleColorChange,
8278
8450
  disabled: !canEdit || useImageAsTexture
8279
8451
  }
8280
- ), /* @__PURE__ */ import_react16.default.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiSun, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react16.default.createElement(
8452
+ ), /* @__PURE__ */ import_react17.default.createElement("div", { className: "mt-3 flex items-center gap-3" }, /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiSun, { className: "text-slate-400", size: 14 }), /* @__PURE__ */ import_react17.default.createElement(
8281
8453
  "input",
8282
8454
  {
8283
8455
  type: "range",
@@ -8290,7 +8462,7 @@ function NodeDetailsPanel({
8290
8462
  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"}`,
8291
8463
  title: `Intensidade do brilho: ${intensity}`
8292
8464
  }
8293
- ), /* @__PURE__ */ import_react16.default.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react16.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement(import_fi14.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react16.default.createElement(
8465
+ ), /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-xs text-slate-400 w-6 text-right" }, intensity)), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react17.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement(import_fi15.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react17.default.createElement(
8294
8466
  CustomPropertyDisplay,
8295
8467
  {
8296
8468
  key: prop.id,
@@ -8305,7 +8477,7 @@ function NodeDetailsPanel({
8305
8477
  onUploadFile: canEdit ? onUploadFile : void 0,
8306
8478
  readOnly: !canEdit
8307
8479
  }
8308
- )), /* @__PURE__ */ import_react16.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react16.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react16.default.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__ */ import_react16.default.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__ */ import_react16.default.createElement(
8480
+ )), /* @__PURE__ */ import_react17.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react17.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.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__ */ import_react17.default.createElement(
8309
8481
  "button",
8310
8482
  {
8311
8483
  onClick: () => handleSave(false),
@@ -8314,10 +8486,10 @@ function NodeDetailsPanel({
8314
8486
  ${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"}
8315
8487
  `
8316
8488
  },
8317
- isSaving && /* @__PURE__ */ import_react16.default.createElement(import_fi14.FiLoader, { className: "animate-spin" }),
8489
+ isSaving && /* @__PURE__ */ import_react17.default.createElement(import_fi15.FiLoader, { className: "animate-spin" }),
8318
8490
  isSaving ? "Salvando..." : "Salvar"
8319
8491
  )))
8320
- ), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react16.default.createElement(
8492
+ ), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react17.default.createElement(
8321
8493
  DescriptionEditModal,
8322
8494
  {
8323
8495
  isOpen: isDescriptionModalOpen,
@@ -8337,7 +8509,7 @@ function NodeDetailsPanel({
8337
8509
  }
8338
8510
 
8339
8511
  // src/components/MultiNodeContextMenu.jsx
8340
- var import_react17 = __toESM(require("react"));
8512
+ var import_react18 = __toESM(require("react"));
8341
8513
  function MultiNodeContextMenu({
8342
8514
  data,
8343
8515
  userRole,
@@ -8346,12 +8518,12 @@ function MultiNodeContextMenu({
8346
8518
  onDismissOtherNodes,
8347
8519
  onDeleteNodes
8348
8520
  }) {
8349
- const menuRef = (0, import_react17.useRef)(null);
8350
- const [menuPos, setMenuPos] = (0, import_react17.useState)({ left: 0, top: 0 });
8351
- const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react17.useState)(false);
8521
+ const menuRef = (0, import_react18.useRef)(null);
8522
+ const [menuPos, setMenuPos] = (0, import_react18.useState)({ left: 0, top: 0 });
8523
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react18.useState)(false);
8352
8524
  const ability = defineAbilityFor(userRole);
8353
8525
  const canDelete = ability.can("delete", "Node");
8354
- (0, import_react17.useLayoutEffect)(() => {
8526
+ (0, import_react18.useLayoutEffect)(() => {
8355
8527
  if (!data.visible || !menuRef.current) return;
8356
8528
  const el = menuRef.current;
8357
8529
  const w = el.clientWidth;
@@ -8364,7 +8536,7 @@ function MultiNodeContextMenu({
8364
8536
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
8365
8537
  setMenuPos({ left, top });
8366
8538
  }, [data]);
8367
- (0, import_react17.useEffect)(() => {
8539
+ (0, import_react18.useEffect)(() => {
8368
8540
  if (data.visible) {
8369
8541
  setIsConfirmingDelete(false);
8370
8542
  }
@@ -8379,7 +8551,7 @@ function MultiNodeContextMenu({
8379
8551
  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";
8380
8552
  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";
8381
8553
  const nodeCount = data.nodeIds.size;
8382
- return /* @__PURE__ */ import_react17.default.createElement(
8554
+ return /* @__PURE__ */ import_react18.default.createElement(
8383
8555
  "div",
8384
8556
  {
8385
8557
  ref: menuRef,
@@ -8393,28 +8565,28 @@ function MultiNodeContextMenu({
8393
8565
  onContextMenu: swallow,
8394
8566
  onDoubleClick: swallow
8395
8567
  },
8396
- /* @__PURE__ */ import_react17.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8397
- /* @__PURE__ */ import_react17.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react17.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react17.default.createElement(
8568
+ /* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8569
+ /* @__PURE__ */ import_react18.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react18.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react18.default.createElement(
8398
8570
  "button",
8399
8571
  {
8400
8572
  onClick: () => setIsConfirmingDelete(false),
8401
8573
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8402
8574
  },
8403
8575
  "Cancelar"
8404
- ), /* @__PURE__ */ import_react17.default.createElement(
8576
+ ), /* @__PURE__ */ import_react18.default.createElement(
8405
8577
  "button",
8406
8578
  {
8407
8579
  onClick: () => onDeleteNodes(data.nodeIds),
8408
8580
  className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
8409
8581
  },
8410
8582
  "Excluir"
8411
- ))) : /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react17.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.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__ */ import_react17.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react17.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, null, /* @__PURE__ */ import_react17.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react17.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react17.default.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__ */ import_react17.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react17.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react17.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8583
+ ))) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.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__ */ import_react18.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react18.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8412
8584
  );
8413
8585
  }
8414
8586
 
8415
8587
  // src/components/RelationshipDetailsPanel.jsx
8416
- var import_react18 = __toESM(require("react"));
8417
- var import_fi15 = require("react-icons/fi");
8588
+ var import_react19 = __toESM(require("react"));
8589
+ var import_fi16 = require("react-icons/fi");
8418
8590
  function RelationshipDetailsPanel({
8419
8591
  link,
8420
8592
  onClose,
@@ -8428,19 +8600,19 @@ function RelationshipDetailsPanel({
8428
8600
  onUploadFile,
8429
8601
  userRole
8430
8602
  }) {
8431
- const [name, setName] = (0, import_react18.useState)((link == null ? void 0 : link.name) ?? "");
8432
- const [description, setDescription] = (0, import_react18.useState)((link == null ? void 0 : link.description) ?? "");
8433
- const [customProps, setCustomProps] = (0, import_react18.useState)(() => extractCustomPropsFromNode(link || {}));
8434
- const [existingSections, setExistingSections] = (0, import_react18.useState)((link == null ? void 0 : link.description_sections) || []);
8435
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react18.useState)(false);
8436
- const [isSaving, setIsSaving] = (0, import_react18.useState)(false);
8437
- const [isReadMode, setIsReadMode] = (0, import_react18.useState)(false);
8438
- const propsEndRef = (0, import_react18.useRef)(null);
8439
- const canEdit = (0, import_react18.useMemo)(() => {
8603
+ const [name, setName] = (0, import_react19.useState)((link == null ? void 0 : link.name) ?? "");
8604
+ const [description, setDescription] = (0, import_react19.useState)((link == null ? void 0 : link.description) ?? "");
8605
+ const [customProps, setCustomProps] = (0, import_react19.useState)(() => extractCustomPropsFromNode(link || {}));
8606
+ const [existingSections, setExistingSections] = (0, import_react19.useState)((link == null ? void 0 : link.description_sections) || []);
8607
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react19.useState)(false);
8608
+ const [isSaving, setIsSaving] = (0, import_react19.useState)(false);
8609
+ const [isReadMode, setIsReadMode] = (0, import_react19.useState)(false);
8610
+ const propsEndRef = (0, import_react19.useRef)(null);
8611
+ const canEdit = (0, import_react19.useMemo)(() => {
8440
8612
  const ability = defineAbilityFor(userRole);
8441
8613
  return ability.can("update", "Connection");
8442
8614
  }, [userRole]);
8443
- (0, import_react18.useEffect)(() => {
8615
+ (0, import_react19.useEffect)(() => {
8444
8616
  setName((link == null ? void 0 : link.name) ?? "");
8445
8617
  setDescription((link == null ? void 0 : link.description) ?? "");
8446
8618
  setExistingSections((link == null ? void 0 : link.description_sections) || []);
@@ -8515,7 +8687,7 @@ function RelationshipDetailsPanel({
8515
8687
  onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
8516
8688
  }
8517
8689
  };
8518
- return /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement(
8690
+ return /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
8519
8691
  "div",
8520
8692
  {
8521
8693
  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
@@ -8530,7 +8702,7 @@ function RelationshipDetailsPanel({
8530
8702
  onContextMenu: swallow,
8531
8703
  onDoubleClick: swallow
8532
8704
  },
8533
- isReadMode ? /* @__PURE__ */ import_react18.default.createElement(
8705
+ isReadMode ? /* @__PURE__ */ import_react19.default.createElement(
8534
8706
  DescriptionReadModePanel,
8535
8707
  {
8536
8708
  title: name || "Rela\xE7\xE3o",
@@ -8551,7 +8723,7 @@ function RelationshipDetailsPanel({
8551
8723
  onImageClick: handleImageClickFromText,
8552
8724
  onSaveDescription: handleSaveDescriptionInline
8553
8725
  }
8554
- ) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react18.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react18.default.createElement("div", null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react18.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react18.default.createElement(
8726
+ ) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react19.default.createElement("div", null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react19.default.createElement(
8555
8727
  "input",
8556
8728
  {
8557
8729
  type: "text",
@@ -8563,7 +8735,7 @@ function RelationshipDetailsPanel({
8563
8735
  ${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
8564
8736
  `
8565
8737
  }
8566
- )), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(
8738
+ )), /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement(
8567
8739
  DescriptionDisplay,
8568
8740
  {
8569
8741
  description,
@@ -8575,7 +8747,7 @@ function RelationshipDetailsPanel({
8575
8747
  onImageClick: handleImageClickFromText,
8576
8748
  onSaveDescription: handleSaveDescriptionInline
8577
8749
  }
8578
- ), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(
8750
+ ), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement(
8579
8751
  "button",
8580
8752
  {
8581
8753
  type: "button",
@@ -8583,8 +8755,8 @@ function RelationshipDetailsPanel({
8583
8755
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
8584
8756
  title: "Modo de Leitura"
8585
8757
  },
8586
- /* @__PURE__ */ import_react18.default.createElement(import_fi15.FiBookOpen, { size: 14 })
8587
- ), canEdit && /* @__PURE__ */ import_react18.default.createElement(
8758
+ /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiBookOpen, { size: 14 })
8759
+ ), canEdit && /* @__PURE__ */ import_react19.default.createElement(
8588
8760
  "button",
8589
8761
  {
8590
8762
  type: "button",
@@ -8592,15 +8764,15 @@ function RelationshipDetailsPanel({
8592
8764
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8593
8765
  title: "Editar descri\xE7\xE3o"
8594
8766
  },
8595
- /* @__PURE__ */ import_react18.default.createElement(import_fi15.FiEdit2, { size: 14 })
8596
- )), !description && canEdit && /* @__PURE__ */ import_react18.default.createElement(
8767
+ /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiEdit2, { size: 14 })
8768
+ )), !description && canEdit && /* @__PURE__ */ import_react19.default.createElement(
8597
8769
  "div",
8598
8770
  {
8599
8771
  onClick: () => setIsDescriptionModalOpen(true),
8600
8772
  className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
8601
8773
  },
8602
8774
  "Adicionar descri\xE7\xE3o..."
8603
- ))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react18.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi15.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react18.default.createElement(
8775
+ ))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react19.default.createElement(
8604
8776
  CustomPropertyDisplay,
8605
8777
  {
8606
8778
  key: prop.id,
@@ -8612,7 +8784,7 @@ function RelationshipDetailsPanel({
8612
8784
  onUploadFile,
8613
8785
  disabled: !canEdit
8614
8786
  }
8615
- )), /* @__PURE__ */ import_react18.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.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__ */ import_react18.default.createElement(
8787
+ )), /* @__PURE__ */ import_react19.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.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__ */ import_react19.default.createElement(
8616
8788
  "button",
8617
8789
  {
8618
8790
  onClick: () => handleSave(false),
@@ -8621,10 +8793,10 @@ function RelationshipDetailsPanel({
8621
8793
  ${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"}
8622
8794
  `
8623
8795
  },
8624
- isSaving && /* @__PURE__ */ import_react18.default.createElement(import_fi15.FiLoader, { className: "animate-spin" }),
8796
+ isSaving && /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }),
8625
8797
  isSaving ? "Salvando..." : "Salvar"
8626
8798
  )))
8627
- ), isDescriptionModalOpen && /* @__PURE__ */ import_react18.default.createElement(
8799
+ ), isDescriptionModalOpen && /* @__PURE__ */ import_react19.default.createElement(
8628
8800
  DescriptionEditModal,
8629
8801
  {
8630
8802
  isOpen: isDescriptionModalOpen,
@@ -8645,7 +8817,7 @@ function RelationshipDetailsPanel({
8645
8817
  }
8646
8818
 
8647
8819
  // src/components/RelationshipContextMenu.jsx
8648
- var import_react19 = __toESM(require("react"));
8820
+ var import_react20 = __toESM(require("react"));
8649
8821
  function RelationshipContextMenu({
8650
8822
  data,
8651
8823
  userRole,
@@ -8655,25 +8827,25 @@ function RelationshipContextMenu({
8655
8827
  onDelete,
8656
8828
  onClose
8657
8829
  }) {
8658
- const menuRef = (0, import_react19.useRef)(null);
8659
- const [menuPos, setMenuPos] = (0, import_react19.useState)({ left: 0, top: 0 });
8660
- const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react19.useState)(false);
8661
- const ability = (0, import_react19.useMemo)(() => defineAbilityFor(userRole), [userRole]);
8662
- const sourceName = (0, import_react19.useMemo)(
8830
+ const menuRef = (0, import_react20.useRef)(null);
8831
+ const [menuPos, setMenuPos] = (0, import_react20.useState)({ left: 0, top: 0 });
8832
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react20.useState)(false);
8833
+ const ability = (0, import_react20.useMemo)(() => defineAbilityFor(userRole), [userRole]);
8834
+ const sourceName = (0, import_react20.useMemo)(
8663
8835
  () => {
8664
8836
  var _a, _b, _c, _d;
8665
8837
  return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.sourceNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
8666
8838
  },
8667
8839
  [data == null ? void 0 : data.linkObject]
8668
8840
  );
8669
- const targetName = (0, import_react19.useMemo)(
8841
+ const targetName = (0, import_react20.useMemo)(
8670
8842
  () => {
8671
8843
  var _a, _b, _c, _d;
8672
8844
  return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
8673
8845
  },
8674
8846
  [data == null ? void 0 : data.linkObject]
8675
8847
  );
8676
- (0, import_react19.useLayoutEffect)(() => {
8848
+ (0, import_react20.useLayoutEffect)(() => {
8677
8849
  if (!data.visible || !menuRef.current) return;
8678
8850
  const el = menuRef.current;
8679
8851
  const w = el.clientWidth;
@@ -8686,7 +8858,7 @@ function RelationshipContextMenu({
8686
8858
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
8687
8859
  setMenuPos({ left, top });
8688
8860
  }, [data]);
8689
- (0, import_react19.useEffect)(() => {
8861
+ (0, import_react20.useEffect)(() => {
8690
8862
  if (data.visible) {
8691
8863
  setIsConfirmingDelete(false);
8692
8864
  }
@@ -8702,7 +8874,7 @@ function RelationshipContextMenu({
8702
8874
  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";
8703
8875
  const canUpdate = ability.can("update", "Connection");
8704
8876
  const canDelete = ability.can("delete", "Connection");
8705
- return /* @__PURE__ */ import_react19.default.createElement(
8877
+ return /* @__PURE__ */ import_react20.default.createElement(
8706
8878
  "div",
8707
8879
  {
8708
8880
  ref: menuRef,
@@ -8716,29 +8888,29 @@ function RelationshipContextMenu({
8716
8888
  onContextMenu: swallow,
8717
8889
  onDoubleClick: swallow
8718
8890
  },
8719
- /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8720
- /* @__PURE__ */ import_react19.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react19.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react19.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react19.default.createElement(
8891
+ /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
8892
+ /* @__PURE__ */ import_react20.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react20.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react20.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react20.default.createElement(
8721
8893
  "button",
8722
8894
  {
8723
8895
  onClick: () => setIsConfirmingDelete(false),
8724
8896
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8725
8897
  },
8726
8898
  "Cancelar"
8727
- ), /* @__PURE__ */ import_react19.default.createElement(
8899
+ ), /* @__PURE__ */ import_react20.default.createElement(
8728
8900
  "button",
8729
8901
  {
8730
8902
  onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
8731
8903
  className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
8732
8904
  },
8733
8905
  "Excluir"
8734
- ))) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react19.default.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__ */ import_react19.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
8906
+ ))) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react20.default.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__ */ import_react20.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
8735
8907
  "button",
8736
8908
  {
8737
8909
  onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
8738
8910
  className: baseButtonClass,
8739
8911
  title: "Desconectar ponta ligada ao Source"
8740
8912
  },
8741
- /* @__PURE__ */ import_react19.default.createElement(
8913
+ /* @__PURE__ */ import_react20.default.createElement(
8742
8914
  "svg",
8743
8915
  {
8744
8916
  xmlns: "http://www.w3.org/2000/svg",
@@ -8751,18 +8923,18 @@ function RelationshipContextMenu({
8751
8923
  strokeLinecap: "round",
8752
8924
  strokeLinejoin: "round"
8753
8925
  },
8754
- /* @__PURE__ */ import_react19.default.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" }),
8755
- /* @__PURE__ */ import_react19.default.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" })
8926
+ /* @__PURE__ */ import_react20.default.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" }),
8927
+ /* @__PURE__ */ import_react20.default.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" })
8756
8928
  ),
8757
- /* @__PURE__ */ import_react19.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
8758
- ), /* @__PURE__ */ import_react19.default.createElement(
8929
+ /* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
8930
+ ), /* @__PURE__ */ import_react20.default.createElement(
8759
8931
  "button",
8760
8932
  {
8761
8933
  onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
8762
8934
  className: baseButtonClass,
8763
8935
  title: "Desconectar ponta ligada ao Target"
8764
8936
  },
8765
- /* @__PURE__ */ import_react19.default.createElement(
8937
+ /* @__PURE__ */ import_react20.default.createElement(
8766
8938
  "svg",
8767
8939
  {
8768
8940
  xmlns: "http://www.w3.org/2000/svg",
@@ -8775,21 +8947,21 @@ function RelationshipContextMenu({
8775
8947
  strokeLinecap: "round",
8776
8948
  strokeLinejoin: "round"
8777
8949
  },
8778
- /* @__PURE__ */ import_react19.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
8779
- /* @__PURE__ */ import_react19.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
8780
- /* @__PURE__ */ import_react19.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
8781
- /* @__PURE__ */ import_react19.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
8782
- /* @__PURE__ */ import_react19.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
8950
+ /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
8951
+ /* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
8952
+ /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
8953
+ /* @__PURE__ */ import_react20.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
8954
+ /* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
8783
8955
  ),
8784
- /* @__PURE__ */ import_react19.default.createElement("span", null, "Desconectar Target (", targetName, ")")
8785
- ), /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react19.default.createElement(
8956
+ /* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Target (", targetName, ")")
8957
+ ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react20.default.createElement(
8786
8958
  "button",
8787
8959
  {
8788
8960
  onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
8789
8961
  className: baseButtonClass,
8790
8962
  title: "Abrir detalhes da rela\xE7\xE3o"
8791
8963
  },
8792
- /* @__PURE__ */ import_react19.default.createElement(
8964
+ /* @__PURE__ */ import_react20.default.createElement(
8793
8965
  "svg",
8794
8966
  {
8795
8967
  xmlns: "http://www.w3.org/2000/svg",
@@ -8802,19 +8974,19 @@ function RelationshipContextMenu({
8802
8974
  strokeLinecap: "round",
8803
8975
  strokeLinejoin: "round"
8804
8976
  },
8805
- /* @__PURE__ */ import_react19.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
8806
- /* @__PURE__ */ import_react19.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
8807
- /* @__PURE__ */ import_react19.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
8977
+ /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
8978
+ /* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
8979
+ /* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
8808
8980
  ),
8809
- /* @__PURE__ */ import_react19.default.createElement("span", null, "Abrir Detalhes")
8810
- ), canDelete && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react19.default.createElement(
8981
+ /* @__PURE__ */ import_react20.default.createElement("span", null, "Abrir Detalhes")
8982
+ ), canDelete && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react20.default.createElement(
8811
8983
  "button",
8812
8984
  {
8813
8985
  onClick: () => setIsConfirmingDelete(true),
8814
8986
  className: dangerButtonClass,
8815
8987
  title: "Excluir esta conex\xE3o"
8816
8988
  },
8817
- /* @__PURE__ */ import_react19.default.createElement(
8989
+ /* @__PURE__ */ import_react20.default.createElement(
8818
8990
  "svg",
8819
8991
  {
8820
8992
  xmlns: "http://www.w3.org/2000/svg",
@@ -8827,19 +8999,19 @@ function RelationshipContextMenu({
8827
8999
  strokeLinecap: "round",
8828
9000
  strokeLinejoin: "round"
8829
9001
  },
8830
- /* @__PURE__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
8831
- /* @__PURE__ */ import_react19.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
8832
- /* @__PURE__ */ import_react19.default.createElement("path", { d: "M10 11v6" }),
8833
- /* @__PURE__ */ import_react19.default.createElement("path", { d: "M14 11v6" }),
8834
- /* @__PURE__ */ import_react19.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
9002
+ /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
9003
+ /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
9004
+ /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }),
9005
+ /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }),
9006
+ /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
8835
9007
  ),
8836
- /* @__PURE__ */ import_react19.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
9008
+ /* @__PURE__ */ import_react20.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
8837
9009
  )))))
8838
9010
  );
8839
9011
  }
8840
9012
 
8841
9013
  // src/components/LoadingScreen.jsx
8842
- var import_react20 = __toESM(require("react"));
9014
+ var import_react21 = __toESM(require("react"));
8843
9015
  var styles = {
8844
9016
  loadingOverlay: {
8845
9017
  position: "fixed",
@@ -8871,11 +9043,11 @@ var styles = {
8871
9043
  `
8872
9044
  };
8873
9045
  function LoadingScreen() {
8874
- return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react20.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react20.default.createElement("div", { style: styles.spinner })));
9046
+ return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.spinner })));
8875
9047
  }
8876
9048
 
8877
9049
  // src/components/ImportParentFileModal.jsx
8878
- var import_react21 = __toESM(require("react"));
9050
+ var import_react22 = __toESM(require("react"));
8879
9051
  function ImportParentFileModal({
8880
9052
  isOpen,
8881
9053
  onClose,
@@ -8886,12 +9058,12 @@ function ImportParentFileModal({
8886
9058
  onFetchAvailableFiles,
8887
9059
  currentViewName
8888
9060
  }) {
8889
- const [activeTab, setActiveTab] = (0, import_react21.useState)("databases");
8890
- const [availableDbs, setAvailableDbs] = (0, import_react21.useState)([]);
8891
- const [availableViews, setAvailableViews] = (0, import_react21.useState)([]);
8892
- const [selectedItem, setSelectedItem] = (0, import_react21.useState)(null);
8893
- const [isLoading, setIsLoading] = (0, import_react21.useState)(false);
8894
- (0, import_react21.useEffect)(() => {
9061
+ const [activeTab, setActiveTab] = (0, import_react22.useState)("databases");
9062
+ const [availableDbs, setAvailableDbs] = (0, import_react22.useState)([]);
9063
+ const [availableViews, setAvailableViews] = (0, import_react22.useState)([]);
9064
+ const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
9065
+ const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
9066
+ (0, import_react22.useEffect)(() => {
8895
9067
  if (isOpen && session && onFetchAvailableFiles) {
8896
9068
  const fetchData = async () => {
8897
9069
  setIsLoading(true);
@@ -8927,7 +9099,7 @@ function ImportParentFileModal({
8927
9099
  fetchData();
8928
9100
  }
8929
9101
  }, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
8930
- (0, import_react21.useEffect)(() => {
9102
+ (0, import_react22.useEffect)(() => {
8931
9103
  setSelectedItem(null);
8932
9104
  }, [activeTab]);
8933
9105
  if (!isOpen) {
@@ -8956,13 +9128,13 @@ function ImportParentFileModal({
8956
9128
  const swallow = (e) => e.stopPropagation();
8957
9129
  const currentList = activeTab === "databases" ? availableDbs : availableViews;
8958
9130
  const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
8959
- return /* @__PURE__ */ import_react21.default.createElement(
9131
+ return /* @__PURE__ */ import_react22.default.createElement(
8960
9132
  "div",
8961
9133
  {
8962
9134
  className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
8963
9135
  onClick: onClose
8964
9136
  },
8965
- /* @__PURE__ */ import_react21.default.createElement(
9137
+ /* @__PURE__ */ import_react22.default.createElement(
8966
9138
  "div",
8967
9139
  {
8968
9140
  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]",
@@ -8974,14 +9146,14 @@ function ImportParentFileModal({
8974
9146
  onContextMenu: swallow,
8975
9147
  onDoubleClick: swallow
8976
9148
  },
8977
- /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react21.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react21.default.createElement(
9149
+ /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react22.default.createElement(
8978
9150
  "button",
8979
9151
  {
8980
9152
  onClick: onClose,
8981
9153
  className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8982
9154
  title: "Fechar"
8983
9155
  },
8984
- /* @__PURE__ */ import_react21.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react21.default.createElement(
9156
+ /* @__PURE__ */ import_react22.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react22.default.createElement(
8985
9157
  "path",
8986
9158
  {
8987
9159
  fillRule: "evenodd",
@@ -8990,14 +9162,14 @@ function ImportParentFileModal({
8990
9162
  }
8991
9163
  ))
8992
9164
  )),
8993
- /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react21.default.createElement(
9165
+ /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement(
8994
9166
  "button",
8995
9167
  {
8996
9168
  onClick: () => setActiveTab("databases"),
8997
9169
  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"}`
8998
9170
  },
8999
9171
  "Arquivos Parent"
9000
- ), /* @__PURE__ */ import_react21.default.createElement(
9172
+ ), /* @__PURE__ */ import_react22.default.createElement(
9001
9173
  "button",
9002
9174
  {
9003
9175
  onClick: () => setActiveTab("views"),
@@ -9005,24 +9177,24 @@ function ImportParentFileModal({
9005
9177
  },
9006
9178
  "Views (Ancestralidades)"
9007
9179
  )),
9008
- /* @__PURE__ */ import_react21.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react21.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react21.default.createElement(
9180
+ /* @__PURE__ */ import_react22.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react22.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react22.default.createElement(
9009
9181
  "div",
9010
9182
  {
9011
9183
  key: item.id,
9012
9184
  onClick: () => setSelectedItem(item),
9013
9185
  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"}`
9014
9186
  },
9015
- /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react21.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react21.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9016
- item.description && /* @__PURE__ */ import_react21.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9017
- )) : /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9018
- /* @__PURE__ */ import_react21.default.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__ */ import_react21.default.createElement(
9187
+ /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react22.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9188
+ item.description && /* @__PURE__ */ import_react22.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9189
+ )) : /* @__PURE__ */ import_react22.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9190
+ /* @__PURE__ */ import_react22.default.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__ */ import_react22.default.createElement(
9019
9191
  "button",
9020
9192
  {
9021
9193
  onClick: onClose,
9022
9194
  className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
9023
9195
  },
9024
9196
  "Cancelar"
9025
- ), /* @__PURE__ */ import_react21.default.createElement(
9197
+ ), /* @__PURE__ */ import_react22.default.createElement(
9026
9198
  "button",
9027
9199
  {
9028
9200
  onClick: handleConfirm,
@@ -9036,8 +9208,8 @@ function ImportParentFileModal({
9036
9208
  }
9037
9209
 
9038
9210
  // src/components/AncestryLinkDetailsPanel.jsx
9039
- var import_react22 = __toESM(require("react"));
9040
- var import_fi16 = require("react-icons/fi");
9211
+ var import_react23 = __toESM(require("react"));
9212
+ var import_fi17 = require("react-icons/fi");
9041
9213
  function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
9042
9214
  var _a, _b, _c, _d;
9043
9215
  const relationshipData = data.relationship || {};
@@ -9046,21 +9218,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9046
9218
  const customProps = extractCustomPropsFromNode(relationshipData);
9047
9219
  const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
9048
9220
  const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
9049
- const [isReadMode, setIsReadMode] = (0, import_react22.useState)(false);
9221
+ const [isReadMode, setIsReadMode] = (0, import_react23.useState)(false);
9050
9222
  const swallow = (e) => e.stopPropagation();
9051
9223
  const handleImageClickFromText = (url, name) => {
9052
9224
  if (onOpenImageViewer) {
9053
9225
  onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
9054
9226
  }
9055
9227
  };
9056
- return /* @__PURE__ */ import_react22.default.createElement(
9228
+ return /* @__PURE__ */ import_react23.default.createElement(
9057
9229
  "div",
9058
9230
  {
9059
9231
  className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
9060
9232
  onClick: onClose,
9061
9233
  onPointerDown: swallow
9062
9234
  },
9063
- /* @__PURE__ */ import_react22.default.createElement(
9235
+ /* @__PURE__ */ import_react23.default.createElement(
9064
9236
  "div",
9065
9237
  {
9066
9238
  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
@@ -9068,7 +9240,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9068
9240
  `,
9069
9241
  onClick: swallow
9070
9242
  },
9071
- isReadMode ? /* @__PURE__ */ import_react22.default.createElement(
9243
+ isReadMode ? /* @__PURE__ */ import_react23.default.createElement(
9072
9244
  DescriptionReadModePanel,
9073
9245
  {
9074
9246
  title: `${sourceName} \u2794 ${targetName}`,
@@ -9080,15 +9252,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9080
9252
  onMentionClick,
9081
9253
  onImageClick: handleImageClickFromText
9082
9254
  }
9083
- ) : /* @__PURE__ */ import_react22.default.createElement(import_react22.default.Fragment, null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react22.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react22.default.createElement("div", null, /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react22.default.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__ */ import_react22.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react22.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react22.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react22.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react22.default.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__ */ import_react22.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react22.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react22.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react22.default.createElement(
9255
+ ) : /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react23.default.createElement("div", null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react23.default.createElement(
9084
9256
  "button",
9085
9257
  {
9086
9258
  onClick: () => setIsReadMode(true),
9087
9259
  className: "p-1 text-slate-400 hover:text-white transition-colors",
9088
9260
  title: "Modo de Leitura"
9089
9261
  },
9090
- /* @__PURE__ */ import_react22.default.createElement(import_fi16.FiBookOpen, { size: 14 })
9091
- )), /* @__PURE__ */ import_react22.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react22.default.createElement(
9262
+ /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiBookOpen, { size: 14 })
9263
+ )), /* @__PURE__ */ import_react23.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react23.default.createElement(
9092
9264
  DescriptionDisplay,
9093
9265
  {
9094
9266
  description,
@@ -9097,7 +9269,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9097
9269
  onMentionClick,
9098
9270
  onImageClick: handleImageClickFromText
9099
9271
  }
9100
- ))), customProps.length > 0 && /* @__PURE__ */ import_react22.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react22.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react22.default.createElement(
9272
+ ))), customProps.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react23.default.createElement(
9101
9273
  CustomPropertyDisplay,
9102
9274
  {
9103
9275
  key: prop.id,
@@ -9106,14 +9278,14 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9106
9278
  onOpenImageViewer,
9107
9279
  onUploadFile
9108
9280
  }
9109
- )))), !description && customProps.length === 0 && /* @__PURE__ */ import_react22.default.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__ */ import_react22.default.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".')))
9281
+ )))), !description && customProps.length === 0 && /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.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".')))
9110
9282
  )
9111
9283
  );
9112
9284
  }
9113
9285
 
9114
9286
  // src/components/AncestryBoard.jsx
9115
- var import_react23 = __toESM(require("react"));
9116
- var import_fi17 = require("react-icons/fi");
9287
+ var import_react24 = __toESM(require("react"));
9288
+ var import_fi18 = require("react-icons/fi");
9117
9289
  var GroupItem = ({
9118
9290
  group,
9119
9291
  index,
@@ -9133,7 +9305,7 @@ var GroupItem = ({
9133
9305
  }) => {
9134
9306
  const canIndent = index > 0;
9135
9307
  const isPickingForThisGroup = pickingGroupId === group.id;
9136
- const textareaRef = (0, import_react23.useRef)(null);
9308
+ const textareaRef = (0, import_react24.useRef)(null);
9137
9309
  const adjustHeight = () => {
9138
9310
  const textarea = textareaRef.current;
9139
9311
  if (textarea) {
@@ -9141,13 +9313,13 @@ var GroupItem = ({
9141
9313
  textarea.style.height = `${textarea.scrollHeight}px`;
9142
9314
  }
9143
9315
  };
9144
- (0, import_react23.useEffect)(() => {
9316
+ (0, import_react24.useEffect)(() => {
9145
9317
  adjustHeight();
9146
9318
  }, [group.text]);
9147
- return /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react23.default.createElement("div", { className: `
9319
+ return /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: `
9148
9320
  flex flex-col gap-2 py-2 px-3 transition-all duration-200
9149
9321
  ${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__ */ import_react23.default.createElement(
9322
+ ` }, /* @__PURE__ */ import_react24.default.createElement(
9151
9323
  "textarea",
9152
9324
  {
9153
9325
  ref: textareaRef,
@@ -9164,9 +9336,9 @@ var GroupItem = ({
9164
9336
  if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
9165
9337
  }
9166
9338
  }
9167
- ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9339
+ ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9168
9340
  const isValid = availableIds.has(String(anc.ancestry_id));
9169
- return /* @__PURE__ */ import_react23.default.createElement(
9341
+ return /* @__PURE__ */ import_react24.default.createElement(
9170
9342
  "div",
9171
9343
  {
9172
9344
  key: anc.ancestry_id,
@@ -9178,28 +9350,28 @@ var GroupItem = ({
9178
9350
  },
9179
9351
  isValid ? (
9180
9352
  // [MANTIDO] Botão Play visível para todos
9181
- /* @__PURE__ */ import_react23.default.createElement(
9353
+ /* @__PURE__ */ import_react24.default.createElement(
9182
9354
  "button",
9183
9355
  {
9184
9356
  onClick: () => onPlayAncestry(anc.ancestry_id),
9185
9357
  className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
9186
9358
  title: "Renderizar no cen\xE1rio"
9187
9359
  },
9188
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9360
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9189
9361
  )
9190
- ) : /* @__PURE__ */ import_react23.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiAlertTriangle, { size: 10 })),
9191
- /* @__PURE__ */ import_react23.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9192
- canEdit && /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react23.default.createElement(
9362
+ ) : /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiAlertTriangle, { size: 10 })),
9363
+ /* @__PURE__ */ import_react24.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9364
+ canEdit && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react24.default.createElement(
9193
9365
  "button",
9194
9366
  {
9195
9367
  onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
9196
9368
  className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
9197
9369
  title: "Remover men\xE7\xE3o"
9198
9370
  },
9199
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiX, { size: 12 })
9371
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiX, { size: 12 })
9200
9372
  ))
9201
9373
  );
9202
- })), canEdit && /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react23.default.createElement(
9374
+ })), canEdit && /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
9203
9375
  "button",
9204
9376
  {
9205
9377
  onClick: () => onRequestPickAncestry(group.id),
@@ -9209,17 +9381,17 @@ var GroupItem = ({
9209
9381
  `,
9210
9382
  title: "Adicionar Ancestralidade a este grupo"
9211
9383
  },
9212
- isPickingForThisGroup ? /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiSearch, { size: 12 }),
9384
+ isPickingForThisGroup ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { size: 12 }),
9213
9385
  isPickingForThisGroup ? "Selecionando..." : "Adicionar"
9214
- ), /* @__PURE__ */ import_react23.default.createElement(
9386
+ ), /* @__PURE__ */ import_react24.default.createElement(
9215
9387
  "button",
9216
9388
  {
9217
9389
  onClick: () => onAddSubgroup(group.id),
9218
9390
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9219
9391
  title: "Criar Subgrupo"
9220
9392
  },
9221
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiPlus, { size: 14 })
9222
- )), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react23.default.createElement(
9393
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14 })
9394
+ )), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
9223
9395
  "button",
9224
9396
  {
9225
9397
  onClick: () => onIndent(group.id),
@@ -9227,24 +9399,24 @@ var GroupItem = ({
9227
9399
  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
9400
  title: "Aninhar no grupo acima"
9229
9401
  },
9230
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiArrowRight, { size: 14 })
9231
- ), /* @__PURE__ */ import_react23.default.createElement(
9402
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowRight, { size: 14 })
9403
+ ), /* @__PURE__ */ import_react24.default.createElement(
9232
9404
  "button",
9233
9405
  {
9234
9406
  onClick: () => onOutdent(group.id),
9235
9407
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9236
9408
  title: "Desaninhar"
9237
9409
  },
9238
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiArrowLeft, { size: 14 })
9239
- ), /* @__PURE__ */ import_react23.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react23.default.createElement(
9410
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowLeft, { size: 14 })
9411
+ ), /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement(
9240
9412
  "button",
9241
9413
  {
9242
9414
  onClick: () => onDelete(group.id),
9243
9415
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
9244
9416
  title: "Remover Grupo"
9245
9417
  },
9246
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiTrash2, { size: 14 })
9247
- )))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react23.default.createElement(
9418
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiTrash2, { size: 14 })
9419
+ )))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react24.default.createElement(
9248
9420
  GroupItem,
9249
9421
  {
9250
9422
  key: childGroup.id,
@@ -9276,21 +9448,21 @@ function AncestryBoard({
9276
9448
  userRole
9277
9449
  // [NOVO] Recebe a role do usuário
9278
9450
  }) {
9279
- const [searchTerm, setSearchTerm] = (0, import_react23.useState)("");
9280
- const [groups, setGroups] = (0, import_react23.useState)([]);
9281
- const [isLoaded, setIsLoaded] = (0, import_react23.useState)(false);
9282
- const [pickingGroupId, setPickingGroupId] = (0, import_react23.useState)(null);
9283
- const [saveStatus, setSaveStatus] = (0, import_react23.useState)("idle");
9284
- const canEdit = (0, import_react23.useMemo)(() => {
9451
+ const [searchTerm, setSearchTerm] = (0, import_react24.useState)("");
9452
+ const [groups, setGroups] = (0, import_react24.useState)([]);
9453
+ const [isLoaded, setIsLoaded] = (0, import_react24.useState)(false);
9454
+ const [pickingGroupId, setPickingGroupId] = (0, import_react24.useState)(null);
9455
+ const [saveStatus, setSaveStatus] = (0, import_react24.useState)("idle");
9456
+ const canEdit = (0, import_react24.useMemo)(() => {
9285
9457
  return userRole !== "viewer";
9286
9458
  }, [userRole]);
9287
- (0, import_react23.useEffect)(() => {
9459
+ (0, import_react24.useEffect)(() => {
9288
9460
  if (initialGroups && !isLoaded) {
9289
9461
  setGroups(initialGroups);
9290
9462
  setIsLoaded(true);
9291
9463
  }
9292
9464
  }, [initialGroups, isLoaded]);
9293
- const nodeNamesMap = (0, import_react23.useMemo)(() => {
9465
+ const nodeNamesMap = (0, import_react24.useMemo)(() => {
9294
9466
  const map = /* @__PURE__ */ new Map();
9295
9467
  if (availableNodes && Array.isArray(availableNodes)) {
9296
9468
  availableNodes.forEach((node) => {
@@ -9301,7 +9473,7 @@ function AncestryBoard({
9301
9473
  }
9302
9474
  return map;
9303
9475
  }, [availableNodes]);
9304
- const availableIds = (0, import_react23.useMemo)(() => {
9476
+ const availableIds = (0, import_react24.useMemo)(() => {
9305
9477
  return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
9306
9478
  }, [availableAncestries]);
9307
9479
  const sanitizeGroups = (groupList) => {
@@ -9315,7 +9487,7 @@ function AncestryBoard({
9315
9487
  children: sanitizeGroups(g.children || [])
9316
9488
  }));
9317
9489
  };
9318
- (0, import_react23.useEffect)(() => {
9490
+ (0, import_react24.useEffect)(() => {
9319
9491
  if (!isLoaded || !onSave) return;
9320
9492
  const timeoutId = setTimeout(async () => {
9321
9493
  setSaveStatus("saving");
@@ -9333,7 +9505,7 @@ function AncestryBoard({
9333
9505
  }, 3e3);
9334
9506
  return () => clearTimeout(timeoutId);
9335
9507
  }, [groups, isLoaded, onSave]);
9336
- (0, import_react23.useEffect)(() => {
9508
+ (0, import_react24.useEffect)(() => {
9337
9509
  if (!isOpen) return;
9338
9510
  const handleKeyDown = (e) => {
9339
9511
  if (e.key === "Escape") {
@@ -9349,7 +9521,7 @@ function AncestryBoard({
9349
9521
  window.addEventListener("keydown", handleKeyDown);
9350
9522
  return () => window.removeEventListener("keydown", handleKeyDown);
9351
9523
  }, [isOpen, onClose, pickingGroupId]);
9352
- const filtered = (0, import_react23.useMemo)(() => {
9524
+ const filtered = (0, import_react24.useMemo)(() => {
9353
9525
  const term = searchTerm.toLowerCase().trim();
9354
9526
  return availableAncestries.filter((a) => {
9355
9527
  if (!term) return true;
@@ -9488,27 +9660,27 @@ function AncestryBoard({
9488
9660
  });
9489
9661
  };
9490
9662
  if (!isOpen) return null;
9491
- return /* @__PURE__ */ import_react23.default.createElement(
9663
+ return /* @__PURE__ */ import_react24.default.createElement(
9492
9664
  "div",
9493
9665
  {
9494
9666
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
9495
9667
  onClick: onClose
9496
9668
  },
9497
- /* @__PURE__ */ import_react23.default.createElement(
9669
+ /* @__PURE__ */ import_react24.default.createElement(
9498
9670
  "div",
9499
9671
  {
9500
9672
  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
9673
  onClick: (e) => e.stopPropagation()
9502
9674
  },
9503
- /* @__PURE__ */ import_react23.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react23.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react23.default.createElement(
9675
+ /* @__PURE__ */ import_react24.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react24.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react24.default.createElement(
9504
9676
  "button",
9505
9677
  {
9506
9678
  onClick: handleAddRootGroup,
9507
9679
  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
9680
  },
9509
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiPlus, { size: 14, className: "text-indigo-400" }),
9510
- /* @__PURE__ */ import_react23.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
9511
- ), /* @__PURE__ */ import_react23.default.createElement(
9681
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14, className: "text-indigo-400" }),
9682
+ /* @__PURE__ */ import_react24.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
9683
+ ), /* @__PURE__ */ import_react24.default.createElement(
9512
9684
  "button",
9513
9685
  {
9514
9686
  onClick: onClose,
@@ -9516,11 +9688,11 @@ function AncestryBoard({
9516
9688
  },
9517
9689
  "\xD7"
9518
9690
  ))),
9519
- /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: `
9691
+ /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: `
9520
9692
  flex flex-col border-r border-white/10 transition-all duration-300 flex-none
9521
9693
  ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
9522
9694
  min-w-[280px] max-w-[500px] bg-slate-900
9523
- ` }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiSearch, { 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__ */ import_react23.default.createElement(
9695
+ ` }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { 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__ */ import_react24.default.createElement(
9524
9696
  "input",
9525
9697
  {
9526
9698
  type: "text",
@@ -9533,10 +9705,10 @@ function AncestryBoard({
9533
9705
  onChange: (e) => setSearchTerm(e.target.value),
9534
9706
  autoFocus: !pickingGroupId
9535
9707
  }
9536
- ))), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
9708
+ ))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
9537
9709
  const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
9538
9710
  const isPicking = !!pickingGroupId;
9539
- return /* @__PURE__ */ import_react23.default.createElement(
9711
+ return /* @__PURE__ */ import_react24.default.createElement(
9540
9712
  "div",
9541
9713
  {
9542
9714
  key: anc.ancestry_id,
@@ -9548,12 +9720,12 @@ function AncestryBoard({
9548
9720
  ${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
9721
  `
9550
9722
  },
9551
- /* @__PURE__ */ import_react23.default.createElement("div", { className: `
9723
+ /* @__PURE__ */ import_react24.default.createElement("div", { className: `
9552
9724
  mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
9553
9725
  ${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__ */ import_react23.default.createElement(import_fi17.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiLayers, { size: 14 })),
9555
- /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.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__ */ import_react23.default.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__ */ import_react23.default.createElement(import_fi17.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react23.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
9556
- !isPicking && /* @__PURE__ */ import_react23.default.createElement(
9726
+ ` }, isPicking ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 14 })),
9727
+ /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.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__ */ import_react24.default.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__ */ import_react24.default.createElement(import_fi18.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react24.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
9728
+ !isPicking && /* @__PURE__ */ import_react24.default.createElement(
9557
9729
  "button",
9558
9730
  {
9559
9731
  onClick: (e) => {
@@ -9563,10 +9735,10 @@ function AncestryBoard({
9563
9735
  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
9736
  title: "Renderizar Ancestralidade"
9565
9737
  },
9566
- /* @__PURE__ */ import_react23.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiPlay, { size: 14, className: "ml-0.5" }))
9738
+ /* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 14, className: "ml-0.5" }))
9567
9739
  )
9568
9740
  );
9569
- }))), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement(import_fi17.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react23.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react23.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react23.default.createElement(
9741
+ }))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react24.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react24.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react24.default.createElement(
9570
9742
  GroupItem,
9571
9743
  {
9572
9744
  key: group.id,
@@ -9586,7 +9758,7 @@ function AncestryBoard({
9586
9758
  canEdit
9587
9759
  }
9588
9760
  ))))),
9589
- /* @__PURE__ */ import_react23.default.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__ */ import_react23.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react23.default.createElement("span", null, groups.length, " grupos raiz"))
9761
+ /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react24.default.createElement("span", null, groups.length, " grupos raiz"))
9590
9762
  )
9591
9763
  );
9592
9764
  }
@@ -9666,12 +9838,12 @@ function XViewScene({
9666
9838
  check_user_permission
9667
9839
  }) {
9668
9840
  var _a, _b, _c, _d, _e, _f, _g;
9669
- const { data: session, status } = (0, import_react25.useSession)();
9841
+ const { data: session, status } = (0, import_react26.useSession)();
9670
9842
  const router = (0, import_navigation.useRouter)();
9671
9843
  const searchParams = (0, import_navigation.useSearchParams)();
9672
9844
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
9673
9845
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
9674
- const viewParams = (0, import_react24.useMemo)(() => {
9846
+ const viewParams = (0, import_react25.useMemo)(() => {
9675
9847
  if (encryptedConfig) {
9676
9848
  const data = decryptData(encryptedConfig);
9677
9849
  if (data) {
@@ -9680,7 +9852,7 @@ function XViewScene({
9680
9852
  }
9681
9853
  return null;
9682
9854
  }, [encryptedConfig, session]);
9683
- (0, import_react24.useEffect)(() => {
9855
+ (0, import_react25.useEffect)(() => {
9684
9856
  async function verifyPermission() {
9685
9857
  if (!viewParams || !session || !check_user_permission) return;
9686
9858
  const { id, type, owner_id } = viewParams;
@@ -9710,64 +9882,65 @@ function XViewScene({
9710
9882
  setIsLoading(false);
9711
9883
  }
9712
9884
  }, [viewParams, session, status, check_user_permission]);
9713
- const sceneConfigId = (0, import_react24.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
9714
- const ownerId = (0, import_react24.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
9715
- const dbSaveUrl = (0, import_react24.useMemo)(() => {
9885
+ const sceneConfigId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
9886
+ const ownerId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
9887
+ const dbSaveUrl = (0, import_react25.useMemo)(() => {
9716
9888
  if (ownerId && sceneConfigId) {
9717
9889
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
9718
9890
  }
9719
9891
  return null;
9720
9892
  }, [ownerId, sceneConfigId]);
9721
- const sceneSaveUrl = (0, import_react24.useMemo)(() => {
9893
+ const sceneSaveUrl = (0, import_react25.useMemo)(() => {
9722
9894
  if (ownerId && sceneConfigId) {
9723
9895
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
9724
9896
  }
9725
9897
  return null;
9726
9898
  }, [ownerId, sceneConfigId]);
9727
- const ancestry_save_url = (0, import_react24.useMemo)(() => {
9899
+ const ancestry_save_url = (0, import_react25.useMemo)(() => {
9728
9900
  if (ownerId && sceneConfigId) {
9729
9901
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
9730
9902
  }
9731
9903
  return null;
9732
9904
  }, [ownerId, sceneConfigId]);
9733
- const sceneDataRef = (0, import_react24.useRef)(null);
9734
- const parentDataRef = (0, import_react24.useRef)(null);
9735
- const ancestryDataRef = (0, import_react24.useRef)(null);
9736
- const [isLoading, setIsLoading] = (0, import_react24.useState)(true);
9737
- const [permissionStatus, setPermissionStatus] = (0, import_react24.useState)("loading");
9738
- const [userPermissionRole, setUserPermissionRole] = (0, import_react24.useState)(null);
9739
- const [isInitialized, setIsInitialized] = (0, import_react24.useState)(false);
9740
- const [sceneVersion, setSceneVersion] = (0, import_react24.useState)(0);
9741
- const [contextMenu, setContextMenu] = (0, import_react24.useState)({ visible: false, x: 0, y: 0, nodeData: null });
9742
- const [multiContextMenu, setMultiContextMenu] = (0, import_react24.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
9743
- const [relationshipMenu, setRelationshipMenu] = (0, import_react24.useState)({ visible: false, x: 0, y: 0, linkObject: null });
9744
- const [creationMode, setCreationMode] = (0, import_react24.useState)({ isActive: false, sourceNodeData: null });
9745
- const [versionMode, setVersionMode] = (0, import_react24.useState)({ isActive: false, sourceNodeData: null });
9746
- const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react24.useState)(false);
9747
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react24.useState)(false);
9748
- const [ancestryMode, setAncestryMode] = (0, import_react24.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9749
- const [readingMode, setReadingMode] = (0, import_react24.useState)({
9905
+ const sceneDataRef = (0, import_react25.useRef)(null);
9906
+ const parentDataRef = (0, import_react25.useRef)(null);
9907
+ const ancestryDataRef = (0, import_react25.useRef)(null);
9908
+ const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
9909
+ const [permissionStatus, setPermissionStatus] = (0, import_react25.useState)("loading");
9910
+ const [userPermissionRole, setUserPermissionRole] = (0, import_react25.useState)(null);
9911
+ const [isInitialized, setIsInitialized] = (0, import_react25.useState)(false);
9912
+ const [sceneVersion, setSceneVersion] = (0, import_react25.useState)(0);
9913
+ const [contextMenu, setContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeData: null });
9914
+ const [multiContextMenu, setMultiContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
9915
+ const [relationshipMenu, setRelationshipMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, linkObject: null });
9916
+ const [creationMode, setCreationMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
9917
+ const [versionMode, setVersionMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
9918
+ const [questMode, setQuestMode] = (0, import_react25.useState)({ isActive: false });
9919
+ const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react25.useState)(false);
9920
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react25.useState)(false);
9921
+ const [ancestryMode, setAncestryMode] = (0, import_react25.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9922
+ const [readingMode, setReadingMode] = (0, import_react25.useState)({
9750
9923
  isActive: false,
9751
9924
  ancestry: null,
9752
9925
  branchStack: [],
9753
9926
  autoAbstraction: false
9754
9927
  });
9755
- const [formPosition, setFormPosition] = (0, import_react24.useState)({ left: 16, top: 16, opacity: 0 });
9756
- const [detailsNode, setDetailsNode] = (0, import_react24.useState)(null);
9757
- const [detailsLink, setDetailsLink] = (0, import_react24.useState)(null);
9758
- const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react24.useState)(null);
9759
- const [imageViewer, setImageViewer] = (0, import_react24.useState)({ visible: false, images: [], startIndex: 0 });
9760
- const [editingAncestryRel, setEditingAncestryRel] = (0, import_react24.useState)({ visible: false, data: null, path: null });
9761
- const [isImportModalOpen, setIsImportModalOpen] = (0, import_react24.useState)(false);
9762
- const [importSuccessMessage, setImportSuccessMessage] = (0, import_react24.useState)("");
9763
- const [highlightedNodeId, setHighlightedNodeId] = (0, import_react24.useState)(null);
9764
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react24.useState)(false);
9765
- const [ancestryBoardData, setAncestryBoardData] = (0, import_react24.useState)([]);
9766
- const [isSidebarOpen, setIsSidebarOpen] = (0, import_react24.useState)(false);
9767
- const mountRef = (0, import_react24.useRef)(null);
9768
- const tooltipRef = (0, import_react24.useRef)(null);
9769
- const formRef = (0, import_react24.useRef)(null);
9770
- const stateRef = (0, import_react24.useRef)({
9928
+ const [formPosition, setFormPosition] = (0, import_react25.useState)({ left: 16, top: 16, opacity: 0 });
9929
+ const [detailsNode, setDetailsNode] = (0, import_react25.useState)(null);
9930
+ const [detailsLink, setDetailsLink] = (0, import_react25.useState)(null);
9931
+ const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react25.useState)(null);
9932
+ const [imageViewer, setImageViewer] = (0, import_react25.useState)({ visible: false, images: [], startIndex: 0 });
9933
+ const [editingAncestryRel, setEditingAncestryRel] = (0, import_react25.useState)({ visible: false, data: null, path: null });
9934
+ const [isImportModalOpen, setIsImportModalOpen] = (0, import_react25.useState)(false);
9935
+ const [importSuccessMessage, setImportSuccessMessage] = (0, import_react25.useState)("");
9936
+ const [highlightedNodeId, setHighlightedNodeId] = (0, import_react25.useState)(null);
9937
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react25.useState)(false);
9938
+ const [ancestryBoardData, setAncestryBoardData] = (0, import_react25.useState)([]);
9939
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react25.useState)(false);
9940
+ const mountRef = (0, import_react25.useRef)(null);
9941
+ const tooltipRef = (0, import_react25.useRef)(null);
9942
+ const formRef = (0, import_react25.useRef)(null);
9943
+ const stateRef = (0, import_react25.useRef)({
9771
9944
  readMode: {
9772
9945
  currentMaxIndex: 0,
9773
9946
  progressMap: {}
@@ -9812,10 +9985,10 @@ function XViewScene({
9812
9985
  minWidth: 320,
9813
9986
  maxWidth: maxReadPanelW
9814
9987
  });
9815
- (0, import_react24.useEffect)(() => {
9988
+ (0, import_react25.useEffect)(() => {
9816
9989
  stateRef.current.ancestry = ancestryMode;
9817
9990
  }, [ancestryMode]);
9818
- (0, import_react24.useEffect)(() => {
9991
+ (0, import_react25.useEffect)(() => {
9819
9992
  var _a2;
9820
9993
  if (!isInitialized) return;
9821
9994
  const map = /* @__PURE__ */ new Map();
@@ -9836,10 +10009,10 @@ function XViewScene({
9836
10009
  }
9837
10010
  stateRef.current.nodeIdToParentFileMap = map;
9838
10011
  }, [isInitialized, sceneVersion]);
9839
- const handleNavigateBack = (0, import_react24.useCallback)(() => {
10012
+ const handleNavigateBack = (0, import_react25.useCallback)(() => {
9840
10013
  router.push("/dashboard/scenes");
9841
10014
  }, [router]);
9842
- const handleConfirmImport = (0, import_react24.useCallback)(
10015
+ const handleConfirmImport = (0, import_react25.useCallback)(
9843
10016
  async (importPayload) => {
9844
10017
  var _a2, _b2;
9845
10018
  let files = [];
@@ -9937,7 +10110,7 @@ function XViewScene({
9937
10110
  const handleOpenImageViewer = (images, startIndex) => {
9938
10111
  setImageViewer({ visible: true, images, startIndex });
9939
10112
  };
9940
- const tweenToTarget = (0, import_react24.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
10113
+ const tweenToTarget = (0, import_react25.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
9941
10114
  const { camera, controls, tweenGroup } = stateRef.current;
9942
10115
  if (!camera || !controls || !tweenGroup) return;
9943
10116
  const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
@@ -9960,7 +10133,7 @@ function XViewScene({
9960
10133
  if (!t || typeof t.closest !== "function") return false;
9961
10134
  return !!t.closest(".ui-overlay");
9962
10135
  };
9963
- const buildFullAncestryTree = (0, import_react24.useCallback)((idTree, nodes, ancestries = []) => {
10136
+ const buildFullAncestryTree = (0, import_react25.useCallback)((idTree, nodes, ancestries = []) => {
9964
10137
  if (!idTree) return null;
9965
10138
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
9966
10139
  const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
@@ -10036,7 +10209,7 @@ function XViewScene({
10036
10209
  }
10037
10210
  return recursiveBuild(idTree);
10038
10211
  }, []);
10039
- const handleActivateTimeline = (0, import_react24.useCallback)(() => {
10212
+ const handleActivateTimeline = (0, import_react25.useCallback)(() => {
10040
10213
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
10041
10214
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
10042
10215
  while (timelineIntervalsGroup.children.length > 0) {
@@ -10189,7 +10362,7 @@ function XViewScene({
10189
10362
  }
10190
10363
  });
10191
10364
  }, []);
10192
- const handleVersionTimeline = (0, import_react24.useCallback)((sourceMesh, versionMeshes) => {
10365
+ const handleVersionTimeline = (0, import_react25.useCallback)((sourceMesh, versionMeshes) => {
10193
10366
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
10194
10367
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
10195
10368
  versionMeshes.forEach((mesh) => {
@@ -10312,7 +10485,7 @@ function XViewScene({
10312
10485
  }
10313
10486
  });
10314
10487
  }, []);
10315
- (0, import_react24.useEffect)(() => {
10488
+ (0, import_react25.useEffect)(() => {
10316
10489
  async function fetchAllData(configPath, ownerId2) {
10317
10490
  var _a2, _b2;
10318
10491
  if (!get_scene_view_data) {
@@ -10384,12 +10557,12 @@ function XViewScene({
10384
10557
  focusNodeId,
10385
10558
  focusAncestryId
10386
10559
  ]);
10387
- const isNodeInView = (0, import_react24.useCallback)((id) => {
10560
+ const isNodeInView = (0, import_react25.useCallback)((id) => {
10388
10561
  const key = String(id);
10389
10562
  const objs = stateRef.current.nodeObjects || {};
10390
10563
  return !!objs[key];
10391
10564
  }, []);
10392
- const addOrUpdateNodeMesh = (0, import_react24.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
10565
+ const addOrUpdateNodeMesh = (0, import_react25.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
10393
10566
  const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
10394
10567
  const nodeId = String(nodeData.id);
10395
10568
  if (nodeObjects[nodeId]) {
@@ -10416,7 +10589,7 @@ function XViewScene({
10416
10589
  }
10417
10590
  return mesh;
10418
10591
  }, []);
10419
- (0, import_react24.useEffect)(() => {
10592
+ (0, import_react25.useEffect)(() => {
10420
10593
  if (!isInitialized || !sceneDataRef.current) return;
10421
10594
  const currentMount = mountRef.current;
10422
10595
  if (!currentMount) return;
@@ -10809,12 +10982,15 @@ function XViewScene({
10809
10982
  if (mountRef.current) mountRef.current.style.cursor = "grab";
10810
10983
  }
10811
10984
  function handleKeyDown(event) {
10985
+ var _a2, _b2, _c2, _d2;
10812
10986
  const context = actionHandlerContext;
10813
10987
  if (event.key === "Escape") {
10814
10988
  if (stateRef.current.connection.isActive) userActionHandlers.handleCancelConnection(context);
10815
10989
  if (stateRef.current.relink.isActive) userActionHandlers.handleCancelRelink(context);
10816
10990
  if (stateRef.current.creation.isActive) userActionHandlers.handleCancelCreation(context);
10991
+ if ((_a2 = stateRef.current.versionMode) == null ? void 0 : _a2.isActive) userActionHandlers.handleCancelVersioning(context);
10817
10992
  if (stateRef.current.ancestry.isActive) handleCancelAncestryCreation();
10993
+ if ((_b2 = context.questMode) == null ? void 0 : _b2.isActive) context.setters.setQuestMode({ isActive: false });
10818
10994
  if (stateRef.current.selectedNodes.size > 0) {
10819
10995
  stateRef.current.selectedNodes.clear();
10820
10996
  }
@@ -10822,6 +10998,17 @@ function XViewScene({
10822
10998
  setMultiContextMenu((prev) => ({ ...prev, visible: false }));
10823
10999
  setRelationshipMenu((prev) => ({ ...prev, visible: false }));
10824
11000
  }
11001
+ if (event.key.toLowerCase() === "q") {
11002
+ 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;
11003
+ if (isUiClear) {
11004
+ const isView = ((_d2 = viewParams == null ? void 0 : viewParams.type) == null ? void 0 : _d2.toLowerCase()) === "view";
11005
+ if (!isView) {
11006
+ alert("Nodes de Quest s\xF3 podem ser criados dentro de uma View.");
11007
+ return;
11008
+ }
11009
+ setQuestMode({ isActive: true });
11010
+ }
11011
+ }
10825
11012
  }
10826
11013
  function handleDoubleClick(event) {
10827
11014
  if (stateRef.current.camera) stateRef.current.camera.layers.enableAll();
@@ -10980,9 +11167,7 @@ function XViewScene({
10980
11167
  mountEl: currentMount,
10981
11168
  isSceneBusy: stateRef.current.isDragging || creation.isActive || connection.isActive || relink.isActive || ancestryMode.isActive,
10982
11169
  parentData: parentDataRef.current,
10983
- // <--- ADICIONADO AQUI
10984
11170
  ancestryData: ancestryDataRef.current
10985
- // <--- ADICIONADO AQUI
10986
11171
  });
10987
11172
  (_b2 = stateRef.current.tweenGroup) == null ? void 0 : _b2.update(time);
10988
11173
  stateRef.current.controls.update();
@@ -11049,7 +11234,7 @@ function XViewScene({
11049
11234
  }
11050
11235
  };
11051
11236
  }, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
11052
- const handleGhostNodeImageChange = (0, import_react24.useCallback)((useImage, imageUrl) => {
11237
+ const handleGhostNodeImageChange = (0, import_react25.useCallback)((useImage, imageUrl) => {
11053
11238
  const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
11054
11239
  const { graphGroup, glowTexture } = stateRef.current;
11055
11240
  if (!ghostNode || !graphGroup) return;
@@ -11091,7 +11276,7 @@ function XViewScene({
11091
11276
  aura: newGhostNode.getObjectByName("aura")
11092
11277
  };
11093
11278
  }, []);
11094
- const handleGhostNodeIntensityChange = (0, import_react24.useCallback)((newIntensity) => {
11279
+ const handleGhostNodeIntensityChange = (0, import_react25.useCallback)((newIntensity) => {
11095
11280
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
11096
11281
  if (!ghostNode) return;
11097
11282
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -11112,7 +11297,7 @@ function XViewScene({
11112
11297
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
11113
11298
  }
11114
11299
  }, []);
11115
- const handleDetailNodeIntensityChange = (0, import_react24.useCallback)((nodeId, newIntensity) => {
11300
+ const handleDetailNodeIntensityChange = (0, import_react25.useCallback)((nodeId, newIntensity) => {
11116
11301
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
11117
11302
  if (!mesh) return;
11118
11303
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -11258,7 +11443,7 @@ function XViewScene({
11258
11443
  mountRef.current.style.cursor = "default";
11259
11444
  }
11260
11445
  };
11261
- const handleAncestryTreeUpdate = (0, import_react24.useCallback)((newTree, extraData = null) => {
11446
+ const handleAncestryTreeUpdate = (0, import_react25.useCallback)((newTree, extraData = null) => {
11262
11447
  setAncestryMode((prev) => {
11263
11448
  const prevTreeStr = JSON.stringify(prev.tree);
11264
11449
  const newTreeStr = JSON.stringify(newTree);
@@ -11278,7 +11463,7 @@ function XViewScene({
11278
11463
  };
11279
11464
  });
11280
11465
  }, []);
11281
- const actionHandlerContext = (0, import_react24.useMemo)(
11466
+ const actionHandlerContext = (0, import_react25.useMemo)(
11282
11467
  () => {
11283
11468
  var _a2;
11284
11469
  return {
@@ -11288,6 +11473,16 @@ function XViewScene({
11288
11473
  mountRef,
11289
11474
  creationMode,
11290
11475
  versionMode,
11476
+ questMode,
11477
+ // <-- Adicionado
11478
+ sceneSaveUrl,
11479
+ // <-- Adicionado
11480
+ sceneConfigId,
11481
+ // <-- Adicionado
11482
+ ownerId,
11483
+ // <-- Adicionado
11484
+ viewType: viewParams == null ? void 0 : viewParams.type,
11485
+ // <-- Adicionado
11291
11486
  userId: (_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.id,
11292
11487
  setters: {
11293
11488
  setContextMenu,
@@ -11299,7 +11494,9 @@ function XViewScene({
11299
11494
  setDetailsNode,
11300
11495
  setDetailsLink,
11301
11496
  setSceneVersion,
11302
- setAncestryMode
11497
+ setAncestryMode,
11498
+ setQuestMode
11499
+ // <-- Adicionado
11303
11500
  },
11304
11501
  tweenToTarget,
11305
11502
  handleVersionTimeline,
@@ -11315,8 +11512,13 @@ function XViewScene({
11315
11512
  [
11316
11513
  creationMode,
11317
11514
  versionMode,
11318
- tweenToTarget,
11515
+ questMode,
11516
+ sceneSaveUrl,
11517
+ sceneConfigId,
11518
+ ownerId,
11519
+ viewParams == null ? void 0 : viewParams.type,
11319
11520
  (_a = session == null ? void 0 : session.user) == null ? void 0 : _a.id,
11521
+ tweenToTarget,
11320
11522
  handleVersionTimeline,
11321
11523
  save_view_data,
11322
11524
  get_single_parent_file,
@@ -11328,7 +11530,112 @@ function XViewScene({
11328
11530
  const handleStartVersioning = (nodeData) => {
11329
11531
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
11330
11532
  };
11331
- const handleClearAncestryVisuals = (0, import_react24.useCallback)((ancestryId) => {
11533
+ const handleSaveQuestNode = async (context, newQuestData) => {
11534
+ const { graphDataRef, sceneDataRef: sceneDataRef2, stateRef: stateRef2, setters, actions, sceneSaveUrl: sceneSaveUrl2, viewType, sceneConfigId: sceneConfigId2, ownerId: ownerId2 } = context;
11535
+ if (!graphDataRef.current || (viewType == null ? void 0 : viewType.toLowerCase()) !== "view") return;
11536
+ const newNode = {
11537
+ id: import_short_uuid2.default.generate(),
11538
+ ...newQuestData,
11539
+ type: ["quest", ...newQuestData.type.filter((t) => t !== "quest")]
11540
+ };
11541
+ if (!graphDataRef.current[sceneConfigId2]) {
11542
+ graphDataRef.current[sceneConfigId2] = { nodes: [], links: [] };
11543
+ }
11544
+ graphDataRef.current[sceneConfigId2].nodes.push(newNode);
11545
+ sceneDataRef2.current.nodes.push(newNode);
11546
+ const currentVisualNodes = Object.values(stateRef2.current.nodeObjects).map((mesh) => {
11547
+ const { _baseEmissiveIntensity, labelObject, labelOffset, timelineIntervalBar, timelineEndLabel, ...rest } = mesh.userData;
11548
+ return rest;
11549
+ });
11550
+ currentVisualNodes.push(newNode);
11551
+ const currentVisualLinks = stateRef2.current.allLinks.map((line) => {
11552
+ const { sourceNode, targetNode, ...rest } = line.userData;
11553
+ return rest;
11554
+ });
11555
+ const sceneFileData = {
11556
+ parent_dbs: sceneDataRef2.current.parent_dbs,
11557
+ nodes: currentVisualNodes,
11558
+ links: currentVisualLinks,
11559
+ quest_nodes: graphDataRef.current[sceneConfigId2].nodes,
11560
+ quest_links: graphDataRef.current[sceneConfigId2].links
11561
+ };
11562
+ try {
11563
+ await actions.save_view_data(sceneSaveUrl2, sceneFileData);
11564
+ stateRef2.current.nodeIdToParentFileMap.set(String(newNode.id), {
11565
+ parentFileId: sceneConfigId2,
11566
+ ownerId: ownerId2,
11567
+ datasetName: "Quests Internas (View)"
11568
+ });
11569
+ const basePosition = stateRef2.current.controls.target.clone();
11570
+ const offset = new THREE3.Vector3((Math.random() - 0.5) * 15, (Math.random() - 0.5) * 5, 0);
11571
+ const finalPosition = basePosition.add(offset);
11572
+ addStandaloneNodeToScene(stateRef2.current, newNode, finalPosition);
11573
+ context.tweenToTarget(finalPosition, 1.2);
11574
+ setters.setQuestMode({ isActive: false });
11575
+ setters.setSceneVersion((v) => v + 1);
11576
+ } catch (error) {
11577
+ console.error("Falha ao salvar Quest na View:", error);
11578
+ alert("Ocorreu um erro ao criar a Quest.");
11579
+ }
11580
+ };
11581
+ userActionHandlers.handleCompleteConnection = async (context, targetNodeData) => {
11582
+ const { stateRef: stateRef2, graphDataRef, sceneDataRef: sceneDataRef2, sceneConfigId: sceneConfigId2, sceneSaveUrl: sceneSaveUrl2 } = context;
11583
+ const { sourceNodeData } = stateRef2.current.connection;
11584
+ if (!graphDataRef.current || !sceneDataRef2.current || !sourceNodeData || !targetNodeData) {
11585
+ userActionHandlers.handleCancelConnection(context);
11586
+ return;
11587
+ }
11588
+ const sourceParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, sourceNodeData.id);
11589
+ const targetParentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef2.current, targetNodeData.id);
11590
+ let parentInfoToSave = sourceParentInfo;
11591
+ if (sourceParentInfo.parentFileId === sceneConfigId2 && targetParentInfo.parentFileId !== sceneConfigId2) {
11592
+ parentInfoToSave = targetParentInfo;
11593
+ } else if (targetParentInfo.parentFileId === sceneConfigId2 && sourceParentInfo.parentFileId !== sceneConfigId2) {
11594
+ parentInfoToSave = sourceParentInfo;
11595
+ }
11596
+ const { parentFileId: parentFileIdToSave, ownerId: ownerIdToSave } = parentInfoToSave;
11597
+ const newLink = {
11598
+ id: `link_${import_short_uuid2.default.generate()}`,
11599
+ source: sourceNodeData.id,
11600
+ target: targetNodeData.id
11601
+ };
11602
+ try {
11603
+ if (parentFileIdToSave === sceneConfigId2) {
11604
+ const specificParentData = graphDataRef.current[sceneConfigId2];
11605
+ specificParentData.links.push(newLink);
11606
+ const currentVisualNodes = Object.values(stateRef2.current.nodeObjects).map((m) => {
11607
+ const { _baseEmissiveIntensity, labelObject, labelOffset, timelineIntervalBar, timelineEndLabel, ...rest } = m.userData;
11608
+ return rest;
11609
+ });
11610
+ const currentVisualLinks = stateRef2.current.allLinks.map((l) => {
11611
+ const { sourceNode, targetNode, ...rest } = l.userData;
11612
+ return rest;
11613
+ });
11614
+ currentVisualLinks.push(newLink);
11615
+ const viewFilePayload = {
11616
+ parent_dbs: sceneDataRef2.current.parent_dbs,
11617
+ nodes: currentVisualNodes,
11618
+ links: currentVisualLinks,
11619
+ quest_nodes: specificParentData.nodes,
11620
+ quest_links: specificParentData.links
11621
+ // Salva a conexão aqui!
11622
+ };
11623
+ await context.actions.save_view_data(sceneSaveUrl2, viewFilePayload);
11624
+ } else {
11625
+ const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileIdToSave]));
11626
+ specificParentData.links.push(newLink);
11627
+ const filenameForSpecificParent = `x_view_dbs/${ownerIdToSave}/${parentFileIdToSave}`;
11628
+ await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
11629
+ graphDataRef.current[parentFileIdToSave] = specificParentData;
11630
+ }
11631
+ addNewLinkToScene(stateRef2.current, newLink);
11632
+ } catch (error) {
11633
+ console.error("Falha ao salvar a nova conex\xE3o:", error);
11634
+ alert("Ocorreu um erro ao salvar a nova conex\xE3o.");
11635
+ }
11636
+ userActionHandlers.handleCancelConnection(context);
11637
+ };
11638
+ const handleClearAncestryVisuals = (0, import_react25.useCallback)((ancestryId) => {
11332
11639
  const { renderedAncestries, ancestryGroup } = stateRef.current;
11333
11640
  const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
11334
11641
  if (renderIndex !== -1) {
@@ -11342,7 +11649,7 @@ function XViewScene({
11342
11649
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
11343
11650
  }
11344
11651
  }, []);
11345
- const handleRenderAncestry = (0, import_react24.useCallback)(
11652
+ const handleRenderAncestry = (0, import_react25.useCallback)(
11346
11653
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
11347
11654
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11348
11655
  if (!ancestryObject || !ancestryObject.tree) {
@@ -11758,7 +12065,7 @@ function XViewScene({
11758
12065
  },
11759
12066
  [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
11760
12067
  );
11761
- const handleRenderAbstractionTree = (0, import_react24.useCallback)((ancestryObject, targetNodeId = null) => {
12068
+ const handleRenderAbstractionTree = (0, import_react25.useCallback)((ancestryObject, targetNodeId = null) => {
11762
12069
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11763
12070
  if (!ancestryObject || !ancestryObject.abstraction_tree) return;
11764
12071
  const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
@@ -11819,7 +12126,7 @@ function XViewScene({
11819
12126
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
11820
12127
  tweenToTarget(rootTargetPos, 0.7);
11821
12128
  }, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
11822
- const handleReadModeBranchNav = (0, import_react24.useCallback)((nodeId, action, direction = "right") => {
12129
+ const handleReadModeBranchNav = (0, import_react25.useCallback)((nodeId, action, direction = "right") => {
11823
12130
  const { ancestry, branchStack } = readingMode;
11824
12131
  if (!ancestry || !ancestry.tree) return;
11825
12132
  const allAncestries = ancestryDataRef.current || [];
@@ -11960,13 +12267,13 @@ function XViewScene({
11960
12267
  }));
11961
12268
  }
11962
12269
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
11963
- const handleReadModeHighlight = (0, import_react24.useCallback)((nodeId) => {
12270
+ const handleReadModeHighlight = (0, import_react25.useCallback)((nodeId) => {
11964
12271
  if (stateRef.current.highlightedNodeId !== nodeId) {
11965
12272
  stateRef.current.highlightedNodeId = nodeId;
11966
12273
  }
11967
12274
  setHighlightedNodeId(nodeId);
11968
12275
  }, []);
11969
- const activeNodeBranches = (0, import_react24.useMemo)(() => {
12276
+ const activeNodeBranches = (0, import_react25.useMemo)(() => {
11970
12277
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree) return null;
11971
12278
  const fullTree = buildFullAncestryTree(
11972
12279
  readingMode.ancestry.tree,
@@ -12003,7 +12310,7 @@ function XViewScene({
12003
12310
  }
12004
12311
  return null;
12005
12312
  }, [highlightedNodeId, readingMode.ancestry, buildFullAncestryTree, readingMode.branchStack, ancestryDataRef.current]);
12006
- const backNavigationInfo = (0, import_react24.useMemo)(() => {
12313
+ const backNavigationInfo = (0, import_react25.useMemo)(() => {
12007
12314
  const { branchStack } = readingMode;
12008
12315
  if (!branchStack || branchStack.length === 0) return null;
12009
12316
  const lastStep = branchStack[branchStack.length - 1];
@@ -12014,7 +12321,7 @@ function XViewScene({
12014
12321
  name: "Voltar para anterior"
12015
12322
  };
12016
12323
  }, [readingMode.branchStack]);
12017
- const getReadModeDisplayContext = (0, import_react24.useMemo)(() => {
12324
+ const getReadModeDisplayContext = (0, import_react25.useMemo)(() => {
12018
12325
  const { ancestry, branchStack } = readingMode;
12019
12326
  if (!ancestry) return null;
12020
12327
  if (branchStack.length === 0) {
@@ -12055,7 +12362,7 @@ function XViewScene({
12055
12362
  customProperties: branchProps
12056
12363
  };
12057
12364
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
12058
- const readModeAbstractionTree = (0, import_react24.useMemo)(() => {
12365
+ const readModeAbstractionTree = (0, import_react25.useMemo)(() => {
12059
12366
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
12060
12367
  return null;
12061
12368
  }
@@ -12067,7 +12374,7 @@ function XViewScene({
12067
12374
  allAncestries
12068
12375
  );
12069
12376
  }, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
12070
- const handleStartReadingAncestry = (0, import_react24.useCallback)(
12377
+ const handleStartReadingAncestry = (0, import_react25.useCallback)(
12071
12378
  async (ancestryObject) => {
12072
12379
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
12073
12380
  if (!ancestryObject || !ancestryObject.tree) {
@@ -12102,7 +12409,7 @@ function XViewScene({
12102
12409
  },
12103
12410
  [handleRenderAncestry, handleRenderAbstractionTree]
12104
12411
  );
12105
- const handleReadModeSectionChange = (0, import_react24.useCallback)((activeSectionId) => {
12412
+ const handleReadModeSectionChange = (0, import_react25.useCallback)((activeSectionId) => {
12106
12413
  const { ancestry, branchStack } = readingMode;
12107
12414
  if (!ancestry || !readingMode.isActive) return;
12108
12415
  let targetObj = ancestry;
@@ -12171,10 +12478,10 @@ function XViewScene({
12171
12478
  }, 0);
12172
12479
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
12173
12480
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
12174
- const handleCloseReadMode = (0, import_react24.useCallback)(() => {
12481
+ const handleCloseReadMode = (0, import_react25.useCallback)(() => {
12175
12482
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
12176
12483
  }, []);
12177
- const handleAncestrySectionChange = (0, import_react24.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
12484
+ const handleAncestrySectionChange = (0, import_react25.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
12178
12485
  var _a2, _b2;
12179
12486
  const currentMode = stateRef.current.ancestry;
12180
12487
  let targetObj = ancestryOverride;
@@ -12226,7 +12533,7 @@ function XViewScene({
12226
12533
  const renderPayload = { ...targetObj, tree: treeToRender };
12227
12534
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
12228
12535
  }, [handleRenderAncestry]);
12229
- const handleEditAncestry = (0, import_react24.useCallback)(
12536
+ const handleEditAncestry = (0, import_react25.useCallback)(
12230
12537
  async (ancestryObject) => {
12231
12538
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
12232
12539
  if (!ancestryObject || !ancestryObject.tree) {
@@ -12265,7 +12572,7 @@ function XViewScene({
12265
12572
  const handleSelectAncestryParent = (nodeId) => {
12266
12573
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
12267
12574
  };
12268
- const handleRemoveFromAncestry = (0, import_react24.useCallback)((pathToRemove) => {
12575
+ const handleRemoveFromAncestry = (0, import_react25.useCallback)((pathToRemove) => {
12269
12576
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
12270
12577
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
12271
12578
  return;
@@ -12290,7 +12597,7 @@ function XViewScene({
12290
12597
  return { ...prev, tree: newTree };
12291
12598
  });
12292
12599
  }, []);
12293
- const handleSaveAncestry = (0, import_react24.useCallback)(
12600
+ const handleSaveAncestry = (0, import_react25.useCallback)(
12294
12601
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
12295
12602
  const treeToUse = treeOverride || ancestryMode.tree;
12296
12603
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -12494,7 +12801,7 @@ function XViewScene({
12494
12801
  });
12495
12802
  setEditingAncestryRel({ visible: false, data: null, path: null });
12496
12803
  };
12497
- const handleDeleteAncestry = (0, import_react24.useCallback)(
12804
+ const handleDeleteAncestry = (0, import_react25.useCallback)(
12498
12805
  async (ancestryIdToDelete) => {
12499
12806
  if (!ancestryIdToDelete) {
12500
12807
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -12556,20 +12863,20 @@ function XViewScene({
12556
12863
  },
12557
12864
  [save_view_data, delete_file_action]
12558
12865
  );
12559
- const handleOpenAncestryBoard = (0, import_react24.useCallback)(() => {
12866
+ const handleOpenAncestryBoard = (0, import_react25.useCallback)(() => {
12560
12867
  setIsAncestryBoardOpen(true);
12561
12868
  }, []);
12562
- const handleSelectAncestryFromBoard = (0, import_react24.useCallback)((ancestry) => {
12869
+ const handleSelectAncestryFromBoard = (0, import_react25.useCallback)((ancestry) => {
12563
12870
  setIsAncestryBoardOpen(false);
12564
12871
  setIsSidebarOpen(false);
12565
12872
  handleStartReadingAncestry(ancestry);
12566
12873
  }, [handleStartReadingAncestry]);
12567
- const handleSaveAncestryBoard = (0, import_react24.useCallback)(async (groups) => {
12874
+ const handleSaveAncestryBoard = (0, import_react25.useCallback)(async (groups) => {
12568
12875
  if (!sceneConfigId || !viewParams || !session) return;
12569
12876
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
12570
12877
  await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
12571
12878
  }, [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]);
12572
- const existingNodeTypes = (0, import_react24.useMemo)(() => {
12879
+ const existingNodeTypes = (0, import_react25.useMemo)(() => {
12573
12880
  if (!parentDataRef.current) {
12574
12881
  return [];
12575
12882
  }
@@ -12579,7 +12886,7 @@ function XViewScene({
12579
12886
  })).filter(Boolean);
12580
12887
  return [...new Set(allTypes)];
12581
12888
  }, [parentDataRef.current, sceneVersion]);
12582
- const searchableDbNodes = (0, import_react24.useMemo)(() => {
12889
+ const searchableDbNodes = (0, import_react25.useMemo)(() => {
12583
12890
  if (!parentDataRef.current) {
12584
12891
  return [];
12585
12892
  }
@@ -12588,13 +12895,14 @@ function XViewScene({
12588
12895
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
12589
12896
  });
12590
12897
  }, [parentDataRef.current, sceneVersion]);
12591
- const handleAddExistingNode = (0, import_react24.useCallback)(
12898
+ const handleAddExistingNode = (0, import_react25.useCallback)(
12592
12899
  (nodeId) => {
12593
12900
  return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
12594
12901
  },
12595
12902
  [actionHandlerContext]
12596
12903
  );
12597
- const handleSaveCurrentView = (0, import_react24.useCallback)(async () => {
12904
+ const handleSaveCurrentView = (0, import_react25.useCallback)(async () => {
12905
+ var _a2, _b2;
12598
12906
  const { nodeObjects, allLinks } = stateRef.current;
12599
12907
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
12600
12908
  console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
@@ -12619,22 +12927,25 @@ function XViewScene({
12619
12927
  const sceneFileData = {
12620
12928
  parent_dbs: sceneDataRef.current.parent_dbs,
12621
12929
  nodes: currentNodes,
12622
- links: currentLinks
12930
+ links: currentLinks,
12931
+ // --- ADICIONE ESTAS DUAS LINHAS PARA PRESERVAR A FONTE DA VERDADE ---
12932
+ quest_nodes: ((_a2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _a2.nodes) || [],
12933
+ quest_links: ((_b2 = parentDataRef.current[sceneConfigId]) == null ? void 0 : _b2.links) || []
12623
12934
  };
12624
12935
  try {
12625
12936
  await save_view_data(sceneSaveUrl, sceneFileData);
12626
12937
  } catch (error) {
12627
12938
  console.error("Erro na chamada de save_view_data:", error);
12628
12939
  }
12629
- }, [sceneSaveUrl, save_view_data]);
12630
- const allAvailableNodes = (0, import_react24.useMemo)(() => {
12940
+ }, [sceneSaveUrl, save_view_data, sceneConfigId]);
12941
+ const allAvailableNodes = (0, import_react25.useMemo)(() => {
12631
12942
  if (!parentDataRef.current) return [];
12632
12943
  return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
12633
12944
  }, [sceneVersion, isInitialized]);
12634
- const allAvailableAncestries = (0, import_react24.useMemo)(() => {
12945
+ const allAvailableAncestries = (0, import_react25.useMemo)(() => {
12635
12946
  return ancestryDataRef.current || [];
12636
12947
  }, [sceneVersion, isInitialized]);
12637
- const handleOpenReference = (0, import_react24.useCallback)((referenceData) => {
12948
+ const handleOpenReference = (0, import_react25.useCallback)((referenceData) => {
12638
12949
  const { type, id } = referenceData;
12639
12950
  if (type === "node") {
12640
12951
  const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
@@ -12661,17 +12972,17 @@ function XViewScene({
12661
12972
  }
12662
12973
  }
12663
12974
  }, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
12664
- const handleToggleAncestryAddMode = (0, import_react24.useCallback)(() => {
12975
+ const handleToggleAncestryAddMode = (0, import_react25.useCallback)(() => {
12665
12976
  setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
12666
12977
  }, []);
12667
- const handleFocusNode = (0, import_react24.useCallback)((nodeData) => {
12978
+ const handleFocusNode = (0, import_react25.useCallback)((nodeData) => {
12668
12979
  if (!nodeData) return;
12669
12980
  const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
12670
12981
  if (nodeMesh) {
12671
12982
  tweenToTarget(nodeMesh, 1.2);
12672
12983
  }
12673
12984
  }, [tweenToTarget]);
12674
- const availableDatasets = (0, import_react24.useMemo)(() => {
12985
+ const availableDatasets = (0, import_react25.useMemo)(() => {
12675
12986
  if (!sceneDataRef.current || !parentDataRef.current) return [];
12676
12987
  return sceneDataRef.current.parent_dbs.map((db) => {
12677
12988
  var _a2;
@@ -12683,7 +12994,7 @@ function XViewScene({
12683
12994
  }, [sceneVersion, isInitialized]);
12684
12995
  const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
12685
12996
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
12686
- (0, import_react24.useEffect)(() => {
12997
+ (0, import_react25.useEffect)(() => {
12687
12998
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
12688
12999
  const nodeObjects = stateRef.current.nodeObjects || {};
12689
13000
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -12697,7 +13008,7 @@ function XViewScene({
12697
13008
  }
12698
13009
  }
12699
13010
  }, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
12700
- (0, import_react24.useEffect)(() => {
13011
+ (0, import_react25.useEffect)(() => {
12701
13012
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
12702
13013
  const ancestries = ancestryDataRef.current || [];
12703
13014
  const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
@@ -12712,20 +13023,20 @@ function XViewScene({
12712
13023
  }
12713
13024
  }, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
12714
13025
  if (isLoading || status === "loading" || permissionStatus === "loading") {
12715
- return /* @__PURE__ */ import_react24.default.createElement(LoadingScreen, null);
13026
+ return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
12716
13027
  }
12717
13028
  if (permissionStatus === "denied") {
12718
- return /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.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__ */ import_react24.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement(
13029
+ return /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.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__ */ import_react25.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement(
12719
13030
  "button",
12720
13031
  {
12721
13032
  onClick: () => router.push("/dashboard/scenes"),
12722
13033
  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
13034
  },
12724
- /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
13035
+ /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
12725
13036
  "Voltar para Scenes"
12726
13037
  )));
12727
13038
  }
12728
- return /* @__PURE__ */ import_react24.default.createElement(
13039
+ return /* @__PURE__ */ import_react25.default.createElement(
12729
13040
  "div",
12730
13041
  {
12731
13042
  ref: mountRef,
@@ -12737,7 +13048,7 @@ function XViewScene({
12737
13048
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
12738
13049
  }
12739
13050
  },
12740
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react24.default.createElement(
13051
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react25.default.createElement(
12741
13052
  XViewSidebar,
12742
13053
  {
12743
13054
  dbNodes: searchableDbNodes,
@@ -12757,7 +13068,7 @@ function XViewScene({
12757
13068
  userRole: userPermissionRole
12758
13069
  }
12759
13070
  ),
12760
- creationMode.isActive && /* @__PURE__ */ import_react24.default.createElement(
13071
+ creationMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
12761
13072
  InSceneCreationForm,
12762
13073
  {
12763
13074
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -12782,7 +13093,7 @@ function XViewScene({
12782
13093
  availableAncestries: allAvailableAncestries
12783
13094
  }
12784
13095
  ),
12785
- versionMode.isActive && /* @__PURE__ */ import_react24.default.createElement(
13096
+ versionMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
12786
13097
  InSceneVersionForm,
12787
13098
  {
12788
13099
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -12801,13 +13112,27 @@ function XViewScene({
12801
13112
  availableAncestries: allAvailableAncestries
12802
13113
  }
12803
13114
  ),
12804
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react24.default.createElement(
13115
+ questMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
13116
+ InSceneQuestForm,
13117
+ {
13118
+ onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
13119
+ onCancel: () => setQuestMode({ isActive: false }),
13120
+ style: { position: "absolute", left: `16px`, top: `16px`, zIndex: 20, transition: "opacity 200ms ease-out" },
13121
+ refEl: formRef,
13122
+ onOpenImageViewer: handleOpenImageViewer,
13123
+ onMentionClick: handleAddExistingNode,
13124
+ onUploadFile: upload_file_action,
13125
+ availableNodes: allAvailableNodes,
13126
+ availableAncestries: allAvailableAncestries
13127
+ }
13128
+ ),
13129
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react25.default.createElement(
12805
13130
  "div",
12806
13131
  {
12807
13132
  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
13133
  style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
12809
13134
  },
12810
- /* @__PURE__ */ import_react24.default.createElement(
13135
+ /* @__PURE__ */ import_react25.default.createElement(
12811
13136
  "div",
12812
13137
  {
12813
13138
  onPointerDown: (e) => {
@@ -12818,7 +13143,7 @@ function XViewScene({
12818
13143
  title: "Arraste para redimensionar"
12819
13144
  }
12820
13145
  ),
12821
- /* @__PURE__ */ import_react24.default.createElement(
13146
+ /* @__PURE__ */ import_react25.default.createElement(
12822
13147
  DescriptionReadModePanel,
12823
13148
  {
12824
13149
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -12853,7 +13178,7 @@ function XViewScene({
12853
13178
  }
12854
13179
  )
12855
13180
  ),
12856
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react24.default.createElement(
13181
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react25.default.createElement(
12857
13182
  CreateAncestryPanel,
12858
13183
  {
12859
13184
  ancestryMode,
@@ -12880,7 +13205,7 @@ function XViewScene({
12880
13205
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
12881
13206
  }
12882
13207
  ),
12883
- editingAncestryRel.visible && /* @__PURE__ */ import_react24.default.createElement(
13208
+ editingAncestryRel.visible && /* @__PURE__ */ import_react25.default.createElement(
12884
13209
  AncestryRelationshipPanel,
12885
13210
  {
12886
13211
  data: editingAncestryRel.data,
@@ -12894,7 +13219,7 @@ function XViewScene({
12894
13219
  onUploadFile: upload_file_action
12895
13220
  }
12896
13221
  ),
12897
- detailsNode && /* @__PURE__ */ import_react24.default.createElement(
13222
+ detailsNode && /* @__PURE__ */ import_react25.default.createElement(
12898
13223
  NodeDetailsPanel,
12899
13224
  {
12900
13225
  node: detailsNode,
@@ -12921,7 +13246,7 @@ function XViewScene({
12921
13246
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12922
13247
  }
12923
13248
  ),
12924
- detailsLink && /* @__PURE__ */ import_react24.default.createElement(
13249
+ detailsLink && /* @__PURE__ */ import_react25.default.createElement(
12925
13250
  RelationshipDetailsPanel,
12926
13251
  {
12927
13252
  link: detailsLink,
@@ -12935,7 +13260,7 @@ function XViewScene({
12935
13260
  userRole: userPermissionRole
12936
13261
  }
12937
13262
  ),
12938
- ancestryLinkDetails && /* @__PURE__ */ import_react24.default.createElement(
13263
+ ancestryLinkDetails && /* @__PURE__ */ import_react25.default.createElement(
12939
13264
  AncestryLinkDetailsPanel,
12940
13265
  {
12941
13266
  data: ancestryLinkDetails,
@@ -12946,7 +13271,7 @@ function XViewScene({
12946
13271
  onUploadFile: upload_file_action
12947
13272
  }
12948
13273
  ),
12949
- /* @__PURE__ */ import_react24.default.createElement(
13274
+ /* @__PURE__ */ import_react25.default.createElement(
12950
13275
  "div",
12951
13276
  {
12952
13277
  ref: tooltipRef,
@@ -12973,7 +13298,7 @@ function XViewScene({
12973
13298
  }
12974
13299
  }
12975
13300
  ),
12976
- /* @__PURE__ */ import_react24.default.createElement(
13301
+ /* @__PURE__ */ import_react25.default.createElement(
12977
13302
  ContextMenu,
12978
13303
  {
12979
13304
  data: contextMenu,
@@ -12996,7 +13321,7 @@ function XViewScene({
12996
13321
  onFocusNode: handleFocusNode
12997
13322
  }
12998
13323
  ),
12999
- /* @__PURE__ */ import_react24.default.createElement(
13324
+ /* @__PURE__ */ import_react25.default.createElement(
13000
13325
  MultiNodeContextMenu,
13001
13326
  {
13002
13327
  data: multiContextMenu,
@@ -13007,7 +13332,7 @@ function XViewScene({
13007
13332
  onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
13008
13333
  }
13009
13334
  ),
13010
- /* @__PURE__ */ import_react24.default.createElement(
13335
+ /* @__PURE__ */ import_react25.default.createElement(
13011
13336
  RelationshipContextMenu,
13012
13337
  {
13013
13338
  data: relationshipMenu,
@@ -13025,8 +13350,8 @@ function XViewScene({
13025
13350
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
13026
13351
  }
13027
13352
  ),
13028
- /* @__PURE__ */ import_react24.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13029
- /* @__PURE__ */ import_react24.default.createElement(
13353
+ /* @__PURE__ */ import_react25.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13354
+ /* @__PURE__ */ import_react25.default.createElement(
13030
13355
  AncestryBoard,
13031
13356
  {
13032
13357
  isOpen: isAncestryBoardOpen,
@@ -13039,7 +13364,7 @@ function XViewScene({
13039
13364
  userRole: userPermissionRole
13040
13365
  }
13041
13366
  ),
13042
- /* @__PURE__ */ import_react24.default.createElement(
13367
+ /* @__PURE__ */ import_react25.default.createElement(
13043
13368
  ImportParentFileModal,
13044
13369
  {
13045
13370
  isOpen: isImportModalOpen,
@@ -13100,11 +13425,22 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id, ty
13100
13425
  );
13101
13426
  }
13102
13427
  }
13428
+ parentData[scene_config] = {
13429
+ dataset_name: "Quests Internas (View)",
13430
+ nodes: sceneData.quest_nodes || [],
13431
+ links: sceneData.quest_links || []
13432
+ };
13103
13433
  const allNodes = Object.values(parentData).flatMap((db) => db.nodes || []);
13104
13434
  const allLinks = Object.values(parentData).flatMap((db) => db.links || []);
13105
13435
  const parentNodeMap = new Map(allNodes.map((node) => [String(node.id), node]));
13106
13436
  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);
13437
+ const validatedNodes = (sceneData.nodes || []).map((sceneNode) => {
13438
+ const nodeTypes = Array.isArray(sceneNode.type) ? sceneNode.type : [sceneNode.type];
13439
+ if (nodeTypes.includes("quest")) {
13440
+ return sceneNode;
13441
+ }
13442
+ return parentNodeMap.get(String(sceneNode.id));
13443
+ }).filter(Boolean);
13108
13444
  const validNodeIdsInScene = new Set(validatedNodes.map((node) => String(node.id)));
13109
13445
  const validatedLinks = (sceneData.links || []).filter((sceneLink) => {
13110
13446
  const linkExistsInParent = parentLinkMap.has(`${sceneLink.source}-${sceneLink.target}`);