@lv-x-software-house/x_view 1.2.2-dev.13 → 1.2.2-dev.14

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 +871 -791
  2. package/dist/index.mjs +306 -226
  3. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/XViewScene.jsx
2
- import React23, { useCallback as useCallback3, useEffect as useEffect21, useRef as useRef17, useState as useState22, useMemo as useMemo12 } from "react";
2
+ import React23, { useCallback as useCallback4, useEffect as useEffect21, useRef as useRef17, useState as useState23, useMemo as useMemo12 } from "react";
3
3
  import { useRouter, useSearchParams } from "next/navigation";
4
4
  import { useSession } from "next-auth/react";
5
5
  import CryptoJS from "crypto-js";
@@ -735,7 +735,7 @@ function XViewSidebar({
735
735
  }
736
736
 
737
737
  // src/components/AncestryRelationshipPanel.jsx
738
- import React8, { useState as useState8, useEffect as useEffect8, useRef as useRef7 } from "react";
738
+ import React8, { useState as useState9, useEffect as useEffect8, useRef as useRef7 } from "react";
739
739
 
740
740
  // node_modules/uuid/dist/esm-node/rng.js
741
741
  import crypto from "crypto";
@@ -785,6 +785,7 @@ function v4(options, buf, offset) {
785
785
  var v4_default = v4;
786
786
 
787
787
  // src/logic/x_view_utils.js
788
+ import { useState as useState3, useCallback } from "react";
788
789
  import * as THREE2 from "three";
789
790
 
790
791
  // src/logic/x_view_config.js
@@ -2999,9 +3000,36 @@ var extractFileUrlsFromProperties = (dataObject) => {
2999
3000
  });
3000
3001
  return urlsToDelete;
3001
3002
  };
3003
+ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
3004
+ const [width, setWidth] = useState3(initialWidth);
3005
+ const [isResizing, setIsResizing] = useState3(false);
3006
+ const handlePointerDown = useCallback((e) => {
3007
+ e.preventDefault();
3008
+ e.stopPropagation();
3009
+ setIsResizing(true);
3010
+ const startX = e.clientX;
3011
+ const startWidth = width;
3012
+ const originalUserSelect = document.body.style.userSelect;
3013
+ document.body.style.userSelect = "none";
3014
+ const handlePointerMove = (moveEvent) => {
3015
+ const deltaX = startX - moveEvent.clientX;
3016
+ const newWidth = Math.min(Math.max(startWidth + deltaX, minWidth), maxWidth);
3017
+ setWidth(newWidth);
3018
+ };
3019
+ const handlePointerUp = () => {
3020
+ setIsResizing(false);
3021
+ document.body.style.userSelect = originalUserSelect;
3022
+ document.removeEventListener("pointermove", handlePointerMove);
3023
+ document.removeEventListener("pointerup", handlePointerUp);
3024
+ };
3025
+ document.addEventListener("pointermove", handlePointerMove);
3026
+ document.addEventListener("pointerup", handlePointerUp);
3027
+ }, [width, minWidth, maxWidth]);
3028
+ return { width, isResizing, handlePointerDown, setWidth };
3029
+ }
3002
3030
 
3003
3031
  // src/components/CustomPropertyDisplay.jsx
3004
- import React3, { useState as useState3, useRef as useRef3, useEffect as useEffect3 } from "react";
3032
+ import React3, { useState as useState4, useRef as useRef3, useEffect as useEffect3 } from "react";
3005
3033
  import { FiCheck, FiX, FiEdit3, FiTrash2, FiExternalLink, FiFileText, FiChevronDown, FiUpload, FiLoader } from "react-icons/fi";
3006
3034
  function CustomPropertyDisplay({
3007
3035
  prop,
@@ -3016,12 +3044,12 @@ function CustomPropertyDisplay({
3016
3044
  },
3017
3045
  onUploadFile
3018
3046
  }) {
3019
- const [isEditing, setIsEditing] = useState3(prop.isEditing ?? false);
3020
- const [tempProp, setTempProp] = useState3(prop);
3021
- const [isHovered, setIsHovered] = useState3(false);
3022
- const [isTypeDropdownOpen, setIsTypeDropdownOpen] = useState3(false);
3047
+ const [isEditing, setIsEditing] = useState4(prop.isEditing ?? false);
3048
+ const [tempProp, setTempProp] = useState4(prop);
3049
+ const [isHovered, setIsHovered] = useState4(false);
3050
+ const [isTypeDropdownOpen, setIsTypeDropdownOpen] = useState4(false);
3023
3051
  const dropdownRef = useRef3(null);
3024
- const [uploadingItemIndex, setUploadingItemIndex] = useState3(null);
3052
+ const [uploadingItemIndex, setUploadingItemIndex] = useState4(null);
3025
3053
  const fileInputRef = useRef3(null);
3026
3054
  const currentUploadTargetRef = useRef3(null);
3027
3055
  useEffect3(() => {
@@ -3367,15 +3395,15 @@ function CustomPropertyDisplay({
3367
3395
  import { FiPlus, FiEdit2 as FiEdit22, FiBookOpen } from "react-icons/fi";
3368
3396
 
3369
3397
  // src/components/DescriptionEditModal.jsx
3370
- import React5, { useState as useState5, useEffect as useEffect5, useRef as useRef5, useMemo as useMemo4 } from "react";
3398
+ import React5, { useState as useState6, useEffect as useEffect5, useRef as useRef5, useMemo as useMemo4 } from "react";
3371
3399
  import { FiType, FiList, FiCode, FiLink as FiLink2, FiAtSign, FiSearch as FiSearch2, FiHexagon as FiHexagon2, FiGlobe, FiImage } from "react-icons/fi";
3372
3400
 
3373
3401
  // src/components/SectionImportModal.jsx
3374
- import React4, { useState as useState4, useMemo as useMemo3, useRef as useRef4, useEffect as useEffect4 } from "react";
3402
+ import React4, { useState as useState5, useMemo as useMemo3, useRef as useRef4, useEffect as useEffect4 } from "react";
3375
3403
  import { FiSearch, FiLayers as FiLayers2, FiHexagon, FiClock, FiCheck as FiCheck2, FiCopy, FiTerminal, FiChevronDown as FiChevronDown2, FiChevronRight, FiDownload, FiLink } from "react-icons/fi";
3376
3404
  var CodeBlock = ({ content, isActive, onClick }) => {
3377
- const [isExpanded, setIsExpanded] = useState4(false);
3378
- const [copied, setCopied] = useState4(false);
3405
+ const [isExpanded, setIsExpanded] = useState5(false);
3406
+ const [copied, setCopied] = useState5(false);
3379
3407
  const cleanContent = content.replace(/^```|```$/g, "").trim();
3380
3408
  const isLongCode = cleanContent.split("\n").length > 4;
3381
3409
  const handleCopy = (e) => {
@@ -3438,14 +3466,14 @@ var formatLineContent = (line) => {
3438
3466
  return /* @__PURE__ */ React4.createElement("span", { className: "break-words" }, line);
3439
3467
  };
3440
3468
  function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], availableAncestries = [] }) {
3441
- const [searchTerm, setSearchTerm] = useState4("");
3442
- const [selectedItem, setSelectedItem] = useState4(null);
3443
- const [searchHistory, setSearchHistory] = useState4([]);
3444
- const [activeIndex, setActiveIndex] = useState4(0);
3445
- const [selectedIndices, setSelectedIndices] = useState4(/* @__PURE__ */ new Set([0]));
3446
- const [lastSelectedIndex, setLastSelectedIndex] = useState4(0);
3469
+ const [searchTerm, setSearchTerm] = useState5("");
3470
+ const [selectedItem, setSelectedItem] = useState5(null);
3471
+ const [searchHistory, setSearchHistory] = useState5([]);
3472
+ const [activeIndex, setActiveIndex] = useState5(0);
3473
+ const [selectedIndices, setSelectedIndices] = useState5(/* @__PURE__ */ new Set([0]));
3474
+ const [lastSelectedIndex, setLastSelectedIndex] = useState5(0);
3447
3475
  const sectionRefs = useRef4([]);
3448
- const [isDropdownOpen, setIsDropdownOpen] = useState4(false);
3476
+ const [isDropdownOpen, setIsDropdownOpen] = useState5(false);
3449
3477
  const inputRef = useRef4(null);
3450
3478
  useEffect4(() => {
3451
3479
  if (!selectedItem) return;
@@ -3784,16 +3812,22 @@ function DescriptionEditModal({
3784
3812
  availableAncestries = [],
3785
3813
  availableImages = []
3786
3814
  }) {
3787
- const [text, setText] = useState5(initialValue || "");
3815
+ const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.9 : 1200;
3816
+ const { width: panelWidth, isResizing, handlePointerDown: handleResize } = useResizablePanel({
3817
+ initialWidth: 700,
3818
+ minWidth: 400,
3819
+ maxWidth: maxPanelW
3820
+ });
3821
+ const [text, setText] = useState6(initialValue || "");
3788
3822
  const textareaRef = useRef5(null);
3789
- const [isImportModalOpen, setIsImportModalOpen] = useState5(false);
3790
- const [isMentionModalOpen, setIsMentionModalOpen] = useState5(false);
3791
- const [mentionSearch, setMentionSearch] = useState5("");
3792
- const [mentionTriggerIndex, setMentionTriggerIndex] = useState5(null);
3793
- const [isImageModalOpen, setIsImageModalOpen] = useState5(false);
3794
- const [manualImageUrl, setManualImageUrl] = useState5("");
3823
+ const [isImportModalOpen, setIsImportModalOpen] = useState6(false);
3824
+ const [isMentionModalOpen, setIsMentionModalOpen] = useState6(false);
3825
+ const [mentionSearch, setMentionSearch] = useState6("");
3826
+ const [mentionTriggerIndex, setMentionTriggerIndex] = useState6(null);
3827
+ const [isImageModalOpen, setIsImageModalOpen] = useState6(false);
3828
+ const [manualImageUrl, setManualImageUrl] = useState6("");
3795
3829
  const hoverTimeoutRef = useRef5(null);
3796
- const [tooltipData, setTooltipData] = useState5(null);
3830
+ const [tooltipData, setTooltipData] = useState6(null);
3797
3831
  useEffect5(() => {
3798
3832
  const handleKeyDown = (e) => {
3799
3833
  if (e.key === "Escape") {
@@ -3952,7 +3986,8 @@ function DescriptionEditModal({
3952
3986
  return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement("div", { className: "fixed inset-0 z-[2000] flex justify-end pointer-events-none bg-transparent" }, /* @__PURE__ */ React5.createElement(
3953
3987
  "div",
3954
3988
  {
3955
- className: "ui-overlay pointer-events-auto relative group h-full w-[min(90vw,700px)] border-l border-white/10 bg-slate-950/95 shadow-2xl text-white flex flex-col",
3989
+ className: `ui-overlay pointer-events-auto relative group h-full border-l border-white/10 bg-slate-950/95 shadow-2xl text-white flex flex-col ${isResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
3990
+ style: { width: `${panelWidth}px`, maxWidth: "90vw" },
3956
3991
  onClick: swallow,
3957
3992
  onPointerDown: swallow,
3958
3993
  onPointerMove: swallow,
@@ -3961,6 +3996,17 @@ function DescriptionEditModal({
3961
3996
  onContextMenu: swallow,
3962
3997
  onDoubleClick: swallow
3963
3998
  },
3999
+ /* @__PURE__ */ React5.createElement(
4000
+ "div",
4001
+ {
4002
+ onPointerDown: (e) => {
4003
+ e.stopPropagation();
4004
+ handleResize(e);
4005
+ },
4006
+ className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
4007
+ title: "Arraste para redimensionar"
4008
+ }
4009
+ ),
3964
4010
  /* @__PURE__ */ React5.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 shrink-0" }),
3965
4011
  /* @__PURE__ */ React5.createElement("div", { className: "px-6 pt-5 pb-3 flex items-center justify-between gap-4 shrink-0" }, /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React5.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80" }), /* @__PURE__ */ React5.createElement("p", { className: "text-sm font-medium text-slate-200" }, title || "Editar Descri\xE7\xE3o")), /* @__PURE__ */ React5.createElement("button", { onClick: handleClose, 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")),
3966
4012
  /* @__PURE__ */ React5.createElement("div", { className: "px-6 py-3 flex flex-col gap-3 border-b border-white/5 bg-white/5 shrink-0" }, /* @__PURE__ */ React5.createElement("div", { className: "flex items-center gap-2 overflow-x-auto custom-scrollbar" }, /* @__PURE__ */ React5.createElement(
@@ -4152,11 +4198,11 @@ function DescriptionEditModal({
4152
4198
  }
4153
4199
 
4154
4200
  // src/components/DescriptionDisplay.jsx
4155
- import React6, { useMemo as useMemo5, useState as useState6, useEffect as useEffect6, useRef as useRef6 } from "react";
4201
+ import React6, { useMemo as useMemo5, useState as useState7, useEffect as useEffect6, useRef as useRef6 } from "react";
4156
4202
  import { FiCopy as FiCopy2, FiCheck as FiCheck3, FiChevronDown as FiChevronDown3, FiChevronRight as FiChevronRight2, FiTerminal as FiTerminal2, FiCornerDownRight, FiExternalLink as FiExternalLink2, FiImage as FiImage2 } from "react-icons/fi";
4157
4203
  var CodeBlock2 = ({ content, isActive, onClick }) => {
4158
- const [isExpanded, setIsExpanded] = useState6(false);
4159
- const [copied, setCopied] = useState6(false);
4204
+ const [isExpanded, setIsExpanded] = useState7(false);
4205
+ const [copied, setCopied] = useState7(false);
4160
4206
  const cleanContent = content.replace(/^```|```$/g, "").trim();
4161
4207
  const isLongCode = cleanContent.split("\n").length > 4;
4162
4208
  const handleCopy = (e) => {
@@ -4355,7 +4401,7 @@ function DescriptionDisplay({
4355
4401
  });
4356
4402
  return navItems;
4357
4403
  }, [sections]);
4358
- const [currentStepIndex, setCurrentStepIndex] = useState6(0);
4404
+ const [currentStepIndex, setCurrentStepIndex] = useState7(0);
4359
4405
  const activeRef = useRef6(null);
4360
4406
  const lastNotifiedSectionId = useRef6(null);
4361
4407
  const isInitialMount = useRef6(true);
@@ -4536,7 +4582,7 @@ function DescriptionDisplay({
4536
4582
  }
4537
4583
 
4538
4584
  // src/components/DescriptionReadModePanel.jsx
4539
- import React7, { useState as useState7, useMemo as useMemo6, useEffect as useEffect7 } from "react";
4585
+ import React7, { useState as useState8, useMemo as useMemo6, useEffect as useEffect7 } from "react";
4540
4586
  import {
4541
4587
  FiArrowLeft,
4542
4588
  FiEdit2,
@@ -4638,10 +4684,10 @@ function DescriptionReadModePanel({
4638
4684
  onRenderAbstractionTree = null,
4639
4685
  initialShowAbstraction = false
4640
4686
  }) {
4641
- const [showProperties, setShowProperties] = useState7(false);
4642
- const [showAbstraction, setShowAbstraction] = useState7(false);
4643
- const [targetRenderNodeId, setTargetRenderNodeId] = useState7(null);
4644
- const [isLinkCopied, setIsLinkCopied] = useState7(false);
4687
+ const [showProperties, setShowProperties] = useState8(false);
4688
+ const [showAbstraction, setShowAbstraction] = useState8(false);
4689
+ const [targetRenderNodeId, setTargetRenderNodeId] = useState8(null);
4690
+ const [isLinkCopied, setIsLinkCopied] = useState8(false);
4645
4691
  const handleCopyLink = (e) => {
4646
4692
  e.stopPropagation();
4647
4693
  if (!ancestryId) return;
@@ -4896,11 +4942,11 @@ function AncestryRelationshipPanel({
4896
4942
  onMentionClick,
4897
4943
  onUploadFile
4898
4944
  }) {
4899
- const [description, setDescription] = useState8((data == null ? void 0 : data.description) ?? "");
4900
- const [customProps, setCustomProps] = useState8(() => extractCustomPropsFromNode(data || {}));
4901
- const [existingSections, setExistingSections] = useState8((data == null ? void 0 : data.description_sections) || []);
4902
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState8(false);
4903
- const [isReadMode, setIsReadMode] = useState8(false);
4945
+ const [description, setDescription] = useState9((data == null ? void 0 : data.description) ?? "");
4946
+ const [customProps, setCustomProps] = useState9(() => extractCustomPropsFromNode(data || {}));
4947
+ const [existingSections, setExistingSections] = useState9((data == null ? void 0 : data.description_sections) || []);
4948
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState9(false);
4949
+ const [isReadMode, setIsReadMode] = useState9(false);
4904
4950
  const propsEndRef = useRef7(null);
4905
4951
  useEffect8(() => {
4906
4952
  setDescription((data == null ? void 0 : data.description) ?? "");
@@ -5042,7 +5088,7 @@ function AncestryRelationshipPanel({
5042
5088
  }
5043
5089
 
5044
5090
  // src/components/CreateAncestryPanel.jsx
5045
- import React10, { useState as useState10, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef8, useCallback } from "react";
5091
+ import React10, { useState as useState11, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef8, useCallback as useCallback2 } from "react";
5046
5092
  import {
5047
5093
  FiEdit2 as FiEdit23,
5048
5094
  FiBookOpen as FiBookOpen2,
@@ -5062,7 +5108,7 @@ import {
5062
5108
  } from "react-icons/fi";
5063
5109
 
5064
5110
  // src/components/AncestryPickerModal.jsx
5065
- import React9, { useState as useState9, useMemo as useMemo7, useEffect as useEffect9 } from "react";
5111
+ import React9, { useState as useState10, useMemo as useMemo7, useEffect as useEffect9 } from "react";
5066
5112
  import { FiSearch as FiSearch3, FiLayers as FiLayers4, FiCornerUpRight as FiCornerUpRight2 } from "react-icons/fi";
5067
5113
  function AncestryPickerModal({
5068
5114
  isOpen,
@@ -5072,7 +5118,7 @@ function AncestryPickerModal({
5072
5118
  availableNodes = [],
5073
5119
  currentAncestryId
5074
5120
  }) {
5075
- const [searchTerm, setSearchTerm] = useState9("");
5121
+ const [searchTerm, setSearchTerm] = useState10("");
5076
5122
  useEffect9(() => {
5077
5123
  if (!isOpen) return;
5078
5124
  const handleKeyDown = (e) => {
@@ -5157,7 +5203,7 @@ var NodeItem = ({ nodeData, onSelectParent, onViewSelect, highlightedPathIds = [
5157
5203
  var _a, _b;
5158
5204
  const itemId = nodeData.is_section ? nodeData.id : (_a = nodeData.node) == null ? void 0 : _a.id;
5159
5205
  const itemName = nodeData.is_section ? nodeData.name : (_b = nodeData.node) == null ? void 0 : _b.name;
5160
- const [isDragOver, setIsDragOver] = useState10(false);
5206
+ const [isDragOver, setIsDragOver] = useState11(false);
5161
5207
  const isSelectedParent = String(selectedParentId) === String(itemId);
5162
5208
  const isTargetViewNode = String(targetRenderNodeId) === String(itemId);
5163
5209
  const isHighlightedPath = highlightedPathIds.includes(String(itemId));
@@ -5293,8 +5339,8 @@ function CreateAncestryPanel({
5293
5339
  isAddingNodes,
5294
5340
  currentAncestryId
5295
5341
  } = ancestryMode;
5296
- const [isSaving, setIsSaving] = useState10(false);
5297
- const [isLinkCopied, setIsLinkCopied] = useState10(false);
5342
+ const [isSaving, setIsSaving] = useState11(false);
5343
+ const [isLinkCopied, setIsLinkCopied] = useState11(false);
5298
5344
  const handleCopyLink = (e) => {
5299
5345
  e.stopPropagation();
5300
5346
  if (!currentAncestryId || currentAncestryId === "temp_root" || currentAncestryId === "temp_creating") {
@@ -5308,11 +5354,11 @@ function CreateAncestryPanel({
5308
5354
  setTimeout(() => setIsLinkCopied(false), 2e3);
5309
5355
  }).catch((err) => console.error("Erro ao copiar link:", err));
5310
5356
  };
5311
- const [isPickerOpen, setIsPickerOpen] = useState10(false);
5312
- const [customProps, setCustomProps] = useState10([]);
5357
+ const [isPickerOpen, setIsPickerOpen] = useState11(false);
5358
+ const [customProps, setCustomProps] = useState11([]);
5313
5359
  const propsEndRef = useRef8(null);
5314
- const [branchStack, setBranchStack] = useState10([]);
5315
- const [targetRenderNodeId, setTargetRenderNodeId] = useState10(null);
5360
+ const [branchStack, setBranchStack] = useState11([]);
5361
+ const [targetRenderNodeId, setTargetRenderNodeId] = useState11(null);
5316
5362
  const highlightedPathIds = useMemo8(() => {
5317
5363
  var _a, _b;
5318
5364
  if (!targetRenderNodeId || !ancestryMode.abstraction_tree) return [];
@@ -5326,17 +5372,26 @@ function CreateAncestryPanel({
5326
5372
  }
5327
5373
  return ids;
5328
5374
  }, [targetRenderNodeId, ancestryMode.abstraction_tree]);
5329
- const [targetScrollSectionId, setTargetScrollSectionId] = useState10(null);
5330
- const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState10(null);
5331
- const [ancestryName, setAncestryName] = useState10(initialName);
5332
- const [description, setDescription] = useState10(initialDescription || "");
5333
- const [existingSections, setExistingSections] = useState10(initialSections || []);
5334
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState10(false);
5335
- const [isReadMode, setIsReadMode] = useState10(false);
5375
+ const [targetScrollSectionId, setTargetScrollSectionId] = useState11(null);
5376
+ const [internalHighlightedNodeId, setInternalHighlightedNodeId] = useState11(null);
5377
+ const [ancestryName, setAncestryName] = useState11(initialName);
5378
+ const [description, setDescription] = useState11(initialDescription || "");
5379
+ const [existingSections, setExistingSections] = useState11(initialSections || []);
5380
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState11(false);
5381
+ const [isReadMode, setIsReadMode] = useState11(false);
5382
+ const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
5383
+ const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
5384
+ initialWidth: isReadMode ? 700 : 440,
5385
+ minWidth: 320,
5386
+ maxWidth: maxPanelW
5387
+ });
5388
+ useEffect10(() => {
5389
+ setWidth(isReadMode ? 700 : 440);
5390
+ }, [isReadMode, setWidth]);
5336
5391
  const currentMaxRenderIndexRef = useRef8(0);
5337
5392
  const branchProgressMapRef = useRef8({});
5338
- const [lastSavedSnapshot, setLastSavedSnapshot] = useState10(null);
5339
- const [isPrivate, setIsPrivate] = useState10(ancestryMode.is_private || false);
5393
+ const [lastSavedSnapshot, setLastSavedSnapshot] = useState11(null);
5394
+ const [isPrivate, setIsPrivate] = useState11(ancestryMode.is_private || false);
5340
5395
  const initializedContextIdRef = useRef8(null);
5341
5396
  const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
5342
5397
  const handleImageClickFromText = (url, name) => {
@@ -5355,7 +5410,7 @@ function CreateAncestryPanel({
5355
5410
  }
5356
5411
  setAncestryMode((prev) => isAbstraction ? { ...prev, isAddingAbstractionNodes: !prev.isAddingAbstractionNodes } : { ...prev, isAddingNodes: !prev.isAddingNodes });
5357
5412
  };
5358
- const handleRemoveNode = useCallback((pathToRemove, isAbstraction = false) => {
5413
+ const handleRemoveNode = useCallback2((pathToRemove, isAbstraction = false) => {
5359
5414
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) return;
5360
5415
  const treeKey = isAbstraction ? "abstraction_tree" : "tree";
5361
5416
  setAncestryMode((prev) => {
@@ -6311,10 +6366,8 @@ function CreateAncestryPanel({
6311
6366
  return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
6312
6367
  "div",
6313
6368
  {
6314
- 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 transition-all duration-300 ease-out
6315
- ${isReadMode ? "w-[min(92vw,700px)]" : "w-[min(92vw,440px)]"}
6316
- `,
6317
- style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
6369
+ 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"}`,
6370
+ style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
6318
6371
  onPointerDown: swallow,
6319
6372
  onPointerMove: swallow,
6320
6373
  onPointerUp: swallow,
@@ -6323,6 +6376,17 @@ function CreateAncestryPanel({
6323
6376
  onContextMenu: swallow,
6324
6377
  onDoubleClick: swallow
6325
6378
  },
6379
+ /* @__PURE__ */ React10.createElement(
6380
+ "div",
6381
+ {
6382
+ onPointerDown: (e) => {
6383
+ e.stopPropagation();
6384
+ handleResize(e);
6385
+ },
6386
+ className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
6387
+ title: "Arraste para redimensionar"
6388
+ }
6389
+ ),
6326
6390
  isReadMode ? /* @__PURE__ */ React10.createElement(
6327
6391
  DescriptionReadModePanel,
6328
6392
  {
@@ -6619,25 +6683,25 @@ function CreateAncestryPanel({
6619
6683
  }
6620
6684
 
6621
6685
  // src/components/ImageViewer.jsx
6622
- import React11, { useState as useState11, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback2 } from "react";
6686
+ import React11, { useState as useState12, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback3 } from "react";
6623
6687
  import { FiX as FiX2, FiChevronLeft as FiChevronLeft3, FiChevronRight as FiChevronRight5 } from "react-icons/fi";
6624
6688
  function ImageViewer({ data, onClose }) {
6625
6689
  var _a;
6626
6690
  const { images = [], startIndex = 0, visible } = data;
6627
- const [currentIndex, setCurrentIndex] = useState11(startIndex);
6628
- const [isLoading, setIsLoading] = useState11(false);
6629
- const [loadedSrc, setLoadedSrc] = useState11(null);
6691
+ const [currentIndex, setCurrentIndex] = useState12(startIndex);
6692
+ const [isLoading, setIsLoading] = useState12(false);
6693
+ const [loadedSrc, setLoadedSrc] = useState12(null);
6630
6694
  useLayoutEffect2(() => {
6631
6695
  if (visible) {
6632
6696
  setCurrentIndex(startIndex);
6633
6697
  }
6634
6698
  }, [visible, startIndex]);
6635
- const handleNext = useCallback2(() => {
6699
+ const handleNext = useCallback3(() => {
6636
6700
  if (images.length > 1) {
6637
6701
  setCurrentIndex((prev) => (prev + 1) % images.length);
6638
6702
  }
6639
6703
  }, [images.length]);
6640
- const handlePrev = useCallback2(() => {
6704
+ const handlePrev = useCallback3(() => {
6641
6705
  if (images.length > 1) {
6642
6706
  setCurrentIndex((prev) => (prev - 1 + images.length) % images.length);
6643
6707
  }
@@ -6742,10 +6806,10 @@ function ImageViewer({ data, onClose }) {
6742
6806
  }
6743
6807
 
6744
6808
  // src/components/InSceneCreationForm.jsx
6745
- import React13, { useState as useState13, useEffect as useEffect13, useRef as useRef10 } from "react";
6809
+ import React13, { useState as useState14, useEffect as useEffect13, useRef as useRef10 } from "react";
6746
6810
 
6747
6811
  // src/components/ColorPicker.jsx
6748
- import React12, { useState as useState12, useEffect as useEffect12, useRef as useRef9 } from "react";
6812
+ import React12, { useState as useState13, useEffect as useEffect12, useRef as useRef9 } from "react";
6749
6813
  import { HexColorPicker } from "react-colorful";
6750
6814
  import { FiHash, FiCheck as FiCheck6 } from "react-icons/fi";
6751
6815
  var PRESET_COLORS = [
@@ -6766,7 +6830,7 @@ var PRESET_COLORS = [
6766
6830
  "#000000"
6767
6831
  ];
6768
6832
  function ColorPicker({ color, onChange, disabled }) {
6769
- const [isOpen, setIsOpen] = useState12(false);
6833
+ const [isOpen, setIsOpen] = useState13(false);
6770
6834
  const popoverRef = useRef9(null);
6771
6835
  useEffect12(() => {
6772
6836
  const handleClickOutside = (event) => {
@@ -6865,21 +6929,21 @@ function InSceneCreationForm({
6865
6929
  viewType
6866
6930
  }) {
6867
6931
  var _a;
6868
- const [name, setName] = useState13("");
6869
- const [types, setTypes] = useState13([]);
6870
- const [typeInput, setTypeInput] = useState13("");
6871
- const [color, setColor] = useState13(initialColor || "#cccccc");
6872
- const [size, setSize] = useState13("medium");
6873
- const [intensity, setIntensity] = useState13(0);
6874
- const [description, setDescription] = useState13("");
6875
- const [customProps, setCustomProps] = useState13([]);
6876
- const [showTypeSuggestions, setShowTypeSuggestions] = useState13(false);
6877
- const [filteredTypes, setFilteredTypes] = useState13([]);
6878
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState13(false);
6879
- const [useImageAsTexture, setUseImageAsTexture] = useState13(false);
6880
- const [selectedImageUrl, setSelectedImageUrl] = useState13(null);
6881
- const [targetDatasetId, setTargetDatasetId] = useState13(sourceNodeDatasetId || "");
6882
- const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = useState13(false);
6932
+ const [name, setName] = useState14("");
6933
+ const [types, setTypes] = useState14([]);
6934
+ const [typeInput, setTypeInput] = useState14("");
6935
+ const [color, setColor] = useState14(initialColor || "#cccccc");
6936
+ const [size, setSize] = useState14("medium");
6937
+ const [intensity, setIntensity] = useState14(0);
6938
+ const [description, setDescription] = useState14("");
6939
+ const [customProps, setCustomProps] = useState14([]);
6940
+ const [showTypeSuggestions, setShowTypeSuggestions] = useState14(false);
6941
+ const [filteredTypes, setFilteredTypes] = useState14([]);
6942
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState14(false);
6943
+ const [useImageAsTexture, setUseImageAsTexture] = useState14(false);
6944
+ const [selectedImageUrl, setSelectedImageUrl] = useState14(null);
6945
+ const [targetDatasetId, setTargetDatasetId] = useState14(sourceNodeDatasetId || "");
6946
+ const [isDatasetDropdownOpen, setIsDatasetDropdownOpen] = useState14(false);
6883
6947
  const datasetDropdownRef = useRef10(null);
6884
6948
  useEffect13(() => {
6885
6949
  if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
@@ -7212,7 +7276,7 @@ function InSceneCreationForm({
7212
7276
  }
7213
7277
 
7214
7278
  // src/components/InSceneVersionForm.jsx
7215
- import React14, { useState as useState14, useEffect as useEffect14, useRef as useRef11 } from "react";
7279
+ import React14, { useState as useState15, useEffect as useEffect14, useRef as useRef11 } from "react";
7216
7280
  import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
7217
7281
  function InSceneVersionForm({
7218
7282
  onSave,
@@ -7230,14 +7294,14 @@ function InSceneVersionForm({
7230
7294
  onMentionClick,
7231
7295
  onUploadFile
7232
7296
  }) {
7233
- const [name, setName] = useState14("");
7234
- const [size, setSize] = useState14("medium");
7235
- const [description, setDescription] = useState14("");
7236
- const [customProps, setCustomProps] = useState14([{ id: v4_default(), key: "Date", type: "date", value: { type: "Data", value: "" }, isEditing: true }]);
7237
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState14(false);
7297
+ const [name, setName] = useState15("");
7298
+ const [size, setSize] = useState15("medium");
7299
+ const [description, setDescription] = useState15("");
7300
+ const [customProps, setCustomProps] = useState15([{ id: v4_default(), key: "Date", type: "date", value: { type: "Data", value: "" }, isEditing: true }]);
7301
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState15(false);
7238
7302
  const propsEndRef = useRef11(null);
7239
- const [useImageAsTexture, setUseImageAsTexture] = useState14(false);
7240
- const [selectedImageUrl, setSelectedImageUrl] = useState14(null);
7303
+ const [useImageAsTexture, setUseImageAsTexture] = useState15(false);
7304
+ const [selectedImageUrl, setSelectedImageUrl] = useState15(null);
7241
7305
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
7242
7306
  useEffect14(() => {
7243
7307
  if (!hasImages && useImageAsTexture) {
@@ -7430,7 +7494,7 @@ function InSceneVersionForm({
7430
7494
  }
7431
7495
 
7432
7496
  // src/components/NodeDetailsPanel.jsx
7433
- import React15, { useState as useState15, useEffect as useEffect15, useRef as useRef12 } from "react";
7497
+ import React15, { useState as useState16, useEffect as useEffect15, useRef as useRef12 } from "react";
7434
7498
  import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
7435
7499
  function NodeDetailsPanel({
7436
7500
  node,
@@ -7452,27 +7516,36 @@ function NodeDetailsPanel({
7452
7516
  userRole,
7453
7517
  currentDatasetName
7454
7518
  }) {
7455
- const [name, setName] = useState15((node == null ? void 0 : node.name) ?? "");
7456
- const [types, setTypes] = useState15([]);
7457
- const [typeInput, setTypeInput] = useState15("");
7458
- const [color, setColor] = useState15((node == null ? void 0 : node.color) ?? "#8b5cf6");
7459
- const [size, setSize] = useState15((node == null ? void 0 : node.size) ?? "medium");
7460
- const [description, setDescription] = useState15((node == null ? void 0 : node.description) ?? "");
7461
- const [intensity, setIntensity] = useState15((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
7462
- const [customProps, setCustomProps] = useState15(() => extractCustomPropsFromNode(node || {}));
7463
- const [showTypeSuggestions, setShowTypeSuggestions] = useState15(false);
7464
- const [filteredTypes, setFilteredTypes] = useState15([]);
7465
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState15(false);
7466
- const [isReadMode, setIsReadMode] = useState15(false);
7467
- const [existingSections, setExistingSections] = useState15((node == null ? void 0 : node.description_sections) || []);
7468
- const [isSaving, setIsSaving] = useState15(false);
7469
- const [isLinkCopied, setIsLinkCopied] = useState15(false);
7470
- const [useImageAsTexture, setUseImageAsTexture] = useState15(() => {
7519
+ const [name, setName] = useState16((node == null ? void 0 : node.name) ?? "");
7520
+ const [types, setTypes] = useState16([]);
7521
+ const [typeInput, setTypeInput] = useState16("");
7522
+ const [color, setColor] = useState16((node == null ? void 0 : node.color) ?? "#8b5cf6");
7523
+ const [size, setSize] = useState16((node == null ? void 0 : node.size) ?? "medium");
7524
+ const [description, setDescription] = useState16((node == null ? void 0 : node.description) ?? "");
7525
+ const [intensity, setIntensity] = useState16((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
7526
+ const [customProps, setCustomProps] = useState16(() => extractCustomPropsFromNode(node || {}));
7527
+ const [showTypeSuggestions, setShowTypeSuggestions] = useState16(false);
7528
+ const [filteredTypes, setFilteredTypes] = useState16([]);
7529
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState16(false);
7530
+ const [isReadMode, setIsReadMode] = useState16(false);
7531
+ const [existingSections, setExistingSections] = useState16((node == null ? void 0 : node.description_sections) || []);
7532
+ const [isSaving, setIsSaving] = useState16(false);
7533
+ const [isLinkCopied, setIsLinkCopied] = useState16(false);
7534
+ const [useImageAsTexture, setUseImageAsTexture] = useState16(() => {
7471
7535
  if ((node == null ? void 0 : node.useImageAsTexture) === "true") return true;
7472
7536
  if ((node == null ? void 0 : node.useImageAsTexture) === "false") return false;
7473
7537
  return !!(node == null ? void 0 : node.useImageAsTexture);
7474
7538
  });
7475
- const [selectedImageUrl, setSelectedImageUrl] = useState15((node == null ? void 0 : node.textureImageUrl) ?? null);
7539
+ const [selectedImageUrl, setSelectedImageUrl] = useState16((node == null ? void 0 : node.textureImageUrl) ?? null);
7540
+ const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
7541
+ const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
7542
+ initialWidth: isReadMode ? 700 : 440,
7543
+ minWidth: 320,
7544
+ maxWidth: maxPanelW
7545
+ });
7546
+ useEffect15(() => {
7547
+ setWidth(isReadMode ? 700 : 440);
7548
+ }, [isReadMode, setWidth]);
7476
7549
  const prevNodeIdRef = useRef12(null);
7477
7550
  const propsEndRef = useRef12(null);
7478
7551
  const canEdit = userRole !== "viewer";
@@ -7680,10 +7753,8 @@ function NodeDetailsPanel({
7680
7753
  return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(
7681
7754
  "div",
7682
7755
  {
7683
- 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 transition-all duration-300 ease-out
7684
- ${isReadMode ? "w-[min(92vw,700px)]" : "w-[min(92vw,440px)]"}
7685
- `,
7686
- style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" },
7756
+ 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"}`,
7757
+ style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
7687
7758
  onPointerDown: swallow,
7688
7759
  onPointerMove: swallow,
7689
7760
  onPointerUp: swallow,
@@ -7692,6 +7763,17 @@ function NodeDetailsPanel({
7692
7763
  onContextMenu: swallow,
7693
7764
  onDoubleClick: swallow
7694
7765
  },
7766
+ /* @__PURE__ */ React15.createElement(
7767
+ "div",
7768
+ {
7769
+ onPointerDown: (e) => {
7770
+ e.stopPropagation();
7771
+ handleResize(e);
7772
+ },
7773
+ className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
7774
+ title: "Arraste para redimensionar"
7775
+ }
7776
+ ),
7695
7777
  isReadMode ? /* @__PURE__ */ React15.createElement(
7696
7778
  DescriptionReadModePanel,
7697
7779
  {
@@ -7893,7 +7975,7 @@ function NodeDetailsPanel({
7893
7975
  }
7894
7976
 
7895
7977
  // src/components/MultiNodeContextMenu.jsx
7896
- import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState16, useEffect as useEffect16 } from "react";
7978
+ import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState17, useEffect as useEffect16 } from "react";
7897
7979
  function MultiNodeContextMenu({
7898
7980
  data,
7899
7981
  userRole,
@@ -7904,7 +7986,7 @@ function MultiNodeContextMenu({
7904
7986
  onDeleteNodes
7905
7987
  }) {
7906
7988
  const menuRef = useRef13(null);
7907
- const [menuPos, setMenuPos] = useState16({ left: 0, top: 0 });
7989
+ const [menuPos, setMenuPos] = useState17({ left: 0, top: 0 });
7908
7990
  const ability = defineAbilityFor(userRole);
7909
7991
  const canDelete = ability.can("delete", "Node");
7910
7992
  useLayoutEffect3(() => {
@@ -7953,7 +8035,7 @@ function MultiNodeContextMenu({
7953
8035
  }
7954
8036
 
7955
8037
  // src/components/RelationshipDetailsPanel.jsx
7956
- import React17, { useState as useState17, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
8038
+ import React17, { useState as useState18, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
7957
8039
  import { FiPlus as FiPlus6, FiEdit2 as FiEdit27, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
7958
8040
  function RelationshipDetailsPanel({
7959
8041
  link,
@@ -7969,13 +8051,13 @@ function RelationshipDetailsPanel({
7969
8051
  userRole
7970
8052
  // Recebendo userRole via props
7971
8053
  }) {
7972
- const [name, setName] = useState17((link == null ? void 0 : link.name) ?? "");
7973
- const [description, setDescription] = useState17((link == null ? void 0 : link.description) ?? "");
7974
- const [customProps, setCustomProps] = useState17(() => extractCustomPropsFromNode(link || {}));
7975
- const [existingSections, setExistingSections] = useState17((link == null ? void 0 : link.description_sections) || []);
7976
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState17(false);
7977
- const [isSaving, setIsSaving] = useState17(false);
7978
- const [isReadMode, setIsReadMode] = useState17(false);
8054
+ const [name, setName] = useState18((link == null ? void 0 : link.name) ?? "");
8055
+ const [description, setDescription] = useState18((link == null ? void 0 : link.description) ?? "");
8056
+ const [customProps, setCustomProps] = useState18(() => extractCustomPropsFromNode(link || {}));
8057
+ const [existingSections, setExistingSections] = useState18((link == null ? void 0 : link.description_sections) || []);
8058
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState18(false);
8059
+ const [isSaving, setIsSaving] = useState18(false);
8060
+ const [isReadMode, setIsReadMode] = useState18(false);
7979
8061
  const propsEndRef = useRef14(null);
7980
8062
  const canEdit = useMemo9(() => {
7981
8063
  const ability = defineAbilityFor(userRole);
@@ -8178,7 +8260,7 @@ function RelationshipDetailsPanel({
8178
8260
  }
8179
8261
 
8180
8262
  // src/components/RelationshipContextMenu.jsx
8181
- import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState18, useEffect as useEffect18, useMemo as useMemo10 } from "react";
8263
+ import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState19, useEffect as useEffect18, useMemo as useMemo10 } from "react";
8182
8264
  function RelationshipContextMenu({
8183
8265
  data,
8184
8266
  userRole,
@@ -8190,7 +8272,7 @@ function RelationshipContextMenu({
8190
8272
  onClose
8191
8273
  }) {
8192
8274
  const menuRef = useRef15(null);
8193
- const [menuPos, setMenuPos] = useState18({ left: 0, top: 0 });
8275
+ const [menuPos, setMenuPos] = useState19({ left: 0, top: 0 });
8194
8276
  const ability = useMemo10(() => defineAbilityFor(userRole), [userRole]);
8195
8277
  const sourceName = useMemo10(
8196
8278
  () => {
@@ -8392,7 +8474,7 @@ function LoadingScreen() {
8392
8474
  }
8393
8475
 
8394
8476
  // src/components/ImportParentFileModal.jsx
8395
- import React20, { useEffect as useEffect19, useState as useState19 } from "react";
8477
+ import React20, { useEffect as useEffect19, useState as useState20 } from "react";
8396
8478
  function ImportParentFileModal({
8397
8479
  isOpen,
8398
8480
  onClose,
@@ -8403,11 +8485,11 @@ function ImportParentFileModal({
8403
8485
  onFetchAvailableFiles,
8404
8486
  currentViewName
8405
8487
  }) {
8406
- const [activeTab, setActiveTab] = useState19("databases");
8407
- const [availableDbs, setAvailableDbs] = useState19([]);
8408
- const [availableViews, setAvailableViews] = useState19([]);
8409
- const [selectedItem, setSelectedItem] = useState19(null);
8410
- const [isLoading, setIsLoading] = useState19(false);
8488
+ const [activeTab, setActiveTab] = useState20("databases");
8489
+ const [availableDbs, setAvailableDbs] = useState20([]);
8490
+ const [availableViews, setAvailableViews] = useState20([]);
8491
+ const [selectedItem, setSelectedItem] = useState20(null);
8492
+ const [isLoading, setIsLoading] = useState20(false);
8411
8493
  useEffect19(() => {
8412
8494
  if (isOpen && session && onFetchAvailableFiles) {
8413
8495
  const fetchData = async () => {
@@ -8553,7 +8635,7 @@ function ImportParentFileModal({
8553
8635
  }
8554
8636
 
8555
8637
  // src/components/AncestryLinkDetailsPanel.jsx
8556
- import React21, { useState as useState20 } from "react";
8638
+ import React21, { useState as useState21 } from "react";
8557
8639
  import { FiBookOpen as FiBookOpen5 } from "react-icons/fi";
8558
8640
  function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
8559
8641
  var _a, _b, _c, _d;
@@ -8563,7 +8645,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
8563
8645
  const customProps = extractCustomPropsFromNode(relationshipData);
8564
8646
  const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
8565
8647
  const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
8566
- const [isReadMode, setIsReadMode] = useState20(false);
8648
+ const [isReadMode, setIsReadMode] = useState21(false);
8567
8649
  const swallow = (e) => e.stopPropagation();
8568
8650
  const handleImageClickFromText = (url, name) => {
8569
8651
  if (onOpenImageViewer) {
@@ -8629,7 +8711,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
8629
8711
  }
8630
8712
 
8631
8713
  // src/components/AncestryBoard.jsx
8632
- import React22, { useState as useState21, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
8714
+ import React22, { useState as useState22, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
8633
8715
  import {
8634
8716
  FiSearch as FiSearch4,
8635
8717
  FiLayers as FiLayers6,
@@ -8806,11 +8888,11 @@ function AncestryBoard({
8806
8888
  userRole
8807
8889
  // [NOVO] Recebe a role do usuário
8808
8890
  }) {
8809
- const [searchTerm, setSearchTerm] = useState21("");
8810
- const [groups, setGroups] = useState21([]);
8811
- const [isLoaded, setIsLoaded] = useState21(false);
8812
- const [pickingGroupId, setPickingGroupId] = useState21(null);
8813
- const [saveStatus, setSaveStatus] = useState21("idle");
8891
+ const [searchTerm, setSearchTerm] = useState22("");
8892
+ const [groups, setGroups] = useState22([]);
8893
+ const [isLoaded, setIsLoaded] = useState22(false);
8894
+ const [pickingGroupId, setPickingGroupId] = useState22(null);
8895
+ const [saveStatus, setSaveStatus] = useState22("idle");
8814
8896
  const canEdit = useMemo11(() => {
8815
8897
  return userRole !== "viewer";
8816
8898
  }, [userRole]);
@@ -9260,37 +9342,37 @@ function XViewScene({
9260
9342
  const sceneDataRef = useRef17(null);
9261
9343
  const parentDataRef = useRef17(null);
9262
9344
  const ancestryDataRef = useRef17(null);
9263
- const [isLoading, setIsLoading] = useState22(true);
9264
- const [permissionStatus, setPermissionStatus] = useState22("loading");
9265
- const [userPermissionRole, setUserPermissionRole] = useState22(null);
9266
- const [isInitialized, setIsInitialized] = useState22(false);
9267
- const [sceneVersion, setSceneVersion] = useState22(0);
9268
- const [contextMenu, setContextMenu] = useState22({ visible: false, x: 0, y: 0, nodeData: null });
9269
- const [multiContextMenu, setMultiContextMenu] = useState22({ visible: false, x: 0, y: 0, nodeIds: null });
9270
- const [relationshipMenu, setRelationshipMenu] = useState22({ visible: false, x: 0, y: 0, linkObject: null });
9271
- const [creationMode, setCreationMode] = useState22({ isActive: false, sourceNodeData: null });
9272
- const [versionMode, setVersionMode] = useState22({ isActive: false, sourceNodeData: null });
9273
- const [hasFocusedInitial, setHasFocusedInitial] = useState22(false);
9274
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState22(false);
9275
- const [ancestryMode, setAncestryMode] = useState22({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9276
- const [readingMode, setReadingMode] = useState22({
9345
+ const [isLoading, setIsLoading] = useState23(true);
9346
+ const [permissionStatus, setPermissionStatus] = useState23("loading");
9347
+ const [userPermissionRole, setUserPermissionRole] = useState23(null);
9348
+ const [isInitialized, setIsInitialized] = useState23(false);
9349
+ const [sceneVersion, setSceneVersion] = useState23(0);
9350
+ const [contextMenu, setContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeData: null });
9351
+ const [multiContextMenu, setMultiContextMenu] = useState23({ visible: false, x: 0, y: 0, nodeIds: null });
9352
+ const [relationshipMenu, setRelationshipMenu] = useState23({ visible: false, x: 0, y: 0, linkObject: null });
9353
+ const [creationMode, setCreationMode] = useState23({ isActive: false, sourceNodeData: null });
9354
+ const [versionMode, setVersionMode] = useState23({ isActive: false, sourceNodeData: null });
9355
+ const [hasFocusedInitial, setHasFocusedInitial] = useState23(false);
9356
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState23(false);
9357
+ const [ancestryMode, setAncestryMode] = useState23({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9358
+ const [readingMode, setReadingMode] = useState23({
9277
9359
  isActive: false,
9278
9360
  ancestry: null,
9279
9361
  branchStack: [],
9280
9362
  autoAbstraction: false
9281
9363
  });
9282
- const [formPosition, setFormPosition] = useState22({ left: 16, top: 16, opacity: 0 });
9283
- const [detailsNode, setDetailsNode] = useState22(null);
9284
- const [detailsLink, setDetailsLink] = useState22(null);
9285
- const [ancestryLinkDetails, setAncestryLinkDetails] = useState22(null);
9286
- const [imageViewer, setImageViewer] = useState22({ visible: false, images: [], startIndex: 0 });
9287
- const [editingAncestryRel, setEditingAncestryRel] = useState22({ visible: false, data: null, path: null });
9288
- const [isImportModalOpen, setIsImportModalOpen] = useState22(false);
9289
- const [importSuccessMessage, setImportSuccessMessage] = useState22("");
9290
- const [highlightedNodeId, setHighlightedNodeId] = useState22(null);
9291
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState22(false);
9292
- const [ancestryBoardData, setAncestryBoardData] = useState22([]);
9293
- const [isSidebarOpen, setIsSidebarOpen] = useState22(false);
9364
+ const [formPosition, setFormPosition] = useState23({ left: 16, top: 16, opacity: 0 });
9365
+ const [detailsNode, setDetailsNode] = useState23(null);
9366
+ const [detailsLink, setDetailsLink] = useState23(null);
9367
+ const [ancestryLinkDetails, setAncestryLinkDetails] = useState23(null);
9368
+ const [imageViewer, setImageViewer] = useState23({ visible: false, images: [], startIndex: 0 });
9369
+ const [editingAncestryRel, setEditingAncestryRel] = useState23({ visible: false, data: null, path: null });
9370
+ const [isImportModalOpen, setIsImportModalOpen] = useState23(false);
9371
+ const [importSuccessMessage, setImportSuccessMessage] = useState23("");
9372
+ const [highlightedNodeId, setHighlightedNodeId] = useState23(null);
9373
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = useState23(false);
9374
+ const [ancestryBoardData, setAncestryBoardData] = useState23([]);
9375
+ const [isSidebarOpen, setIsSidebarOpen] = useState23(false);
9294
9376
  const mountRef = useRef17(null);
9295
9377
  const tooltipRef = useRef17(null);
9296
9378
  const formRef = useRef17(null);
@@ -9333,6 +9415,12 @@ function XViewScene({
9333
9415
  lastDescriptionLength: 0,
9334
9416
  highlightedNodeId: null
9335
9417
  });
9418
+ const maxReadPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
9419
+ const { width: readModeWidth, isResizing: isReadModeResizing, handlePointerDown: handleReadModeResize } = useResizablePanel({
9420
+ initialWidth: 700,
9421
+ minWidth: 320,
9422
+ maxWidth: maxReadPanelW
9423
+ });
9336
9424
  useEffect21(() => {
9337
9425
  stateRef.current.ancestry = ancestryMode;
9338
9426
  }, [ancestryMode]);
@@ -9357,10 +9445,10 @@ function XViewScene({
9357
9445
  }
9358
9446
  stateRef.current.nodeIdToParentFileMap = map;
9359
9447
  }, [isInitialized, sceneVersion]);
9360
- const handleNavigateBack = useCallback3(() => {
9448
+ const handleNavigateBack = useCallback4(() => {
9361
9449
  router.push("/dashboard/scenes");
9362
9450
  }, [router]);
9363
- const handleConfirmImport = useCallback3(
9451
+ const handleConfirmImport = useCallback4(
9364
9452
  async (importPayload) => {
9365
9453
  var _a2, _b2;
9366
9454
  let files = [];
@@ -9408,7 +9496,6 @@ function XViewScene({
9408
9496
  if (ancestryResponse.success && Array.isArray(ancestryResponse.data)) {
9409
9497
  const viewSpecificAncestries = ancestryResponse.data.filter(
9410
9498
  (anc) => anc._source_file_id === viewToImport.id && !anc.is_private
9411
- // <--- AQUI ESTÁ A TRAVA DE SEGURANÇA
9412
9499
  );
9413
9500
  const processedAncestries = viewSpecificAncestries.map((anc) => ({
9414
9501
  ...anc,
@@ -9459,7 +9546,7 @@ function XViewScene({
9459
9546
  const handleOpenImageViewer = (images, startIndex) => {
9460
9547
  setImageViewer({ visible: true, images, startIndex });
9461
9548
  };
9462
- const tweenToTarget = useCallback3((target, zoomFactor = 1, forcedDirection = null) => {
9549
+ const tweenToTarget = useCallback4((target, zoomFactor = 1, forcedDirection = null) => {
9463
9550
  const { camera, controls, tweenGroup } = stateRef.current;
9464
9551
  if (!camera || !controls || !tweenGroup) return;
9465
9552
  const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
@@ -9482,7 +9569,7 @@ function XViewScene({
9482
9569
  if (!t || typeof t.closest !== "function") return false;
9483
9570
  return !!t.closest(".ui-overlay");
9484
9571
  };
9485
- const buildFullAncestryTree = useCallback3((idTree, nodes, ancestries = []) => {
9572
+ const buildFullAncestryTree = useCallback4((idTree, nodes, ancestries = []) => {
9486
9573
  if (!idTree) return null;
9487
9574
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
9488
9575
  const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
@@ -9508,14 +9595,10 @@ function XViewScene({
9508
9595
  return {
9509
9596
  ...branch,
9510
9597
  name: linkedAncestry.name,
9511
- // Sobrescreve nome para exibição
9512
9598
  description: linkedAncestry.description,
9513
- // Sobrescreve descrição
9514
9599
  description_sections: linkedAncestry.description_sections,
9515
9600
  tree: graftedTree,
9516
- // ENXERTA A ÁRVORE AQUI
9517
9601
  isLinked: true
9518
- // Flag útil
9519
9602
  };
9520
9603
  }
9521
9604
  }
@@ -9562,7 +9645,7 @@ function XViewScene({
9562
9645
  }
9563
9646
  return recursiveBuild(idTree);
9564
9647
  }, []);
9565
- const handleActivateTimeline = useCallback3(() => {
9648
+ const handleActivateTimeline = useCallback4(() => {
9566
9649
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
9567
9650
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
9568
9651
  while (timelineIntervalsGroup.children.length > 0) {
@@ -9715,7 +9798,7 @@ function XViewScene({
9715
9798
  }
9716
9799
  });
9717
9800
  }, []);
9718
- const handleVersionTimeline = useCallback3((sourceMesh, versionMeshes) => {
9801
+ const handleVersionTimeline = useCallback4((sourceMesh, versionMeshes) => {
9719
9802
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
9720
9803
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
9721
9804
  versionMeshes.forEach((mesh) => {
@@ -9908,16 +9991,14 @@ function XViewScene({
9908
9991
  isInitialized,
9909
9992
  permissionStatus,
9910
9993
  focusNodeId,
9911
- // <-- MANTIDO
9912
9994
  focusAncestryId
9913
- // <-- ADICIONADO O focusAncestryId NAS DEPENDÊNCIAS
9914
9995
  ]);
9915
- const isNodeInView = useCallback3((id) => {
9996
+ const isNodeInView = useCallback4((id) => {
9916
9997
  const key = String(id);
9917
9998
  const objs = stateRef.current.nodeObjects || {};
9918
9999
  return !!objs[key];
9919
10000
  }, []);
9920
- const addOrUpdateNodeMesh = useCallback3((nodeData, position, suppressVersionUpdate = false) => {
10001
+ const addOrUpdateNodeMesh = useCallback4((nodeData, position, suppressVersionUpdate = false) => {
9921
10002
  const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
9922
10003
  const nodeId = String(nodeData.id);
9923
10004
  if (nodeObjects[nodeId]) {
@@ -10566,7 +10647,7 @@ function XViewScene({
10566
10647
  }
10567
10648
  };
10568
10649
  }, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
10569
- const handleGhostNodeImageChange = useCallback3((useImage, imageUrl) => {
10650
+ const handleGhostNodeImageChange = useCallback4((useImage, imageUrl) => {
10570
10651
  const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
10571
10652
  const { graphGroup, glowTexture } = stateRef.current;
10572
10653
  if (!ghostNode || !graphGroup) return;
@@ -10608,7 +10689,7 @@ function XViewScene({
10608
10689
  aura: newGhostNode.getObjectByName("aura")
10609
10690
  };
10610
10691
  }, []);
10611
- const handleGhostNodeIntensityChange = useCallback3((newIntensity) => {
10692
+ const handleGhostNodeIntensityChange = useCallback4((newIntensity) => {
10612
10693
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
10613
10694
  if (!ghostNode) return;
10614
10695
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -10629,7 +10710,7 @@ function XViewScene({
10629
10710
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
10630
10711
  }
10631
10712
  }, []);
10632
- const handleDetailNodeIntensityChange = useCallback3((nodeId, newIntensity) => {
10713
+ const handleDetailNodeIntensityChange = useCallback4((nodeId, newIntensity) => {
10633
10714
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
10634
10715
  if (!mesh) return;
10635
10716
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -10775,7 +10856,7 @@ function XViewScene({
10775
10856
  mountRef.current.style.cursor = "default";
10776
10857
  }
10777
10858
  };
10778
- const handleAncestryTreeUpdate = useCallback3((newTree, extraData = null) => {
10859
+ const handleAncestryTreeUpdate = useCallback4((newTree, extraData = null) => {
10779
10860
  setAncestryMode((prev) => {
10780
10861
  const prevTreeStr = JSON.stringify(prev.tree);
10781
10862
  const newTreeStr = JSON.stringify(newTree);
@@ -10845,7 +10926,7 @@ function XViewScene({
10845
10926
  const handleStartVersioning = (nodeData) => {
10846
10927
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
10847
10928
  };
10848
- const handleClearAncestryVisuals = useCallback3((ancestryId) => {
10929
+ const handleClearAncestryVisuals = useCallback4((ancestryId) => {
10849
10930
  const { renderedAncestries, ancestryGroup } = stateRef.current;
10850
10931
  const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
10851
10932
  if (renderIndex !== -1) {
@@ -10859,7 +10940,7 @@ function XViewScene({
10859
10940
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
10860
10941
  }
10861
10942
  }, []);
10862
- const handleRenderAncestry = useCallback3(
10943
+ const handleRenderAncestry = useCallback4(
10863
10944
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
10864
10945
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
10865
10946
  if (!ancestryObject || !ancestryObject.tree) {
@@ -11275,7 +11356,7 @@ function XViewScene({
11275
11356
  },
11276
11357
  [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
11277
11358
  );
11278
- const handleRenderAbstractionTree = useCallback3((ancestryObject, targetNodeId = null) => {
11359
+ const handleRenderAbstractionTree = useCallback4((ancestryObject, targetNodeId = null) => {
11279
11360
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11280
11361
  if (!ancestryObject || !ancestryObject.abstraction_tree) return;
11281
11362
  const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
@@ -11336,7 +11417,7 @@ function XViewScene({
11336
11417
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
11337
11418
  tweenToTarget(rootTargetPos, 0.7);
11338
11419
  }, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
11339
- const handleReadModeBranchNav = useCallback3((nodeId, action, direction = "right") => {
11420
+ const handleReadModeBranchNav = useCallback4((nodeId, action, direction = "right") => {
11340
11421
  const { ancestry, branchStack } = readingMode;
11341
11422
  if (!ancestry || !ancestry.tree) return;
11342
11423
  const allAncestries = ancestryDataRef.current || [];
@@ -11374,9 +11455,7 @@ function XViewScene({
11374
11455
  description_sections: branchToOpen.description_sections,
11375
11456
  tree: branchToOpen.tree,
11376
11457
  _originNodeId: nodeId,
11377
- // <--- ID do node pai (link visual)
11378
11458
  _branchDirection: direction
11379
- // <--- Direção para cálculo de posição
11380
11459
  };
11381
11460
  const allowedIds = /* @__PURE__ */ new Set(["preamble", 0, "0"]);
11382
11461
  const branchSections = parseDescriptionSections(branchToOpen.description || "", branchToOpen.description_sections || []);
@@ -11432,7 +11511,6 @@ function XViewScene({
11432
11511
  const parentAncestryObj = {
11433
11512
  ...targetAncestryInfo,
11434
11513
  tree: targetTreeToRender,
11435
- // Re-injeta a origem se o pai também for uma branch aninhada
11436
11514
  _originNodeId: activeParentStackItem ? activeParentStackItem.nodeId : null,
11437
11515
  _branchDirection: activeParentStackItem ? activeParentStackItem.entryDirection : null
11438
11516
  };
@@ -11480,7 +11558,7 @@ function XViewScene({
11480
11558
  }));
11481
11559
  }
11482
11560
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
11483
- const handleReadModeHighlight = useCallback3((nodeId) => {
11561
+ const handleReadModeHighlight = useCallback4((nodeId) => {
11484
11562
  if (stateRef.current.highlightedNodeId !== nodeId) {
11485
11563
  stateRef.current.highlightedNodeId = nodeId;
11486
11564
  }
@@ -11492,7 +11570,6 @@ function XViewScene({
11492
11570
  readingMode.ancestry.tree,
11493
11571
  Object.values(parentDataRef.current).flatMap((f) => f.nodes),
11494
11572
  ancestryDataRef.current
11495
- // <--- Adicionar
11496
11573
  );
11497
11574
  const findNodeInTree = (tree, targetId) => {
11498
11575
  if (!tree) return null;
@@ -11546,7 +11623,6 @@ function XViewScene({
11546
11623
  description_sections: ancestry.description_sections,
11547
11624
  direction: null,
11548
11625
  customProperties: rootProps
11549
- // <--- ADICIONADO
11550
11626
  };
11551
11627
  }
11552
11628
  const fullTree = buildFullAncestryTree(
@@ -11575,7 +11651,6 @@ function XViewScene({
11575
11651
  description_sections: currentMeta.description_sections,
11576
11652
  direction: currentDirection,
11577
11653
  customProperties: branchProps
11578
- // <--- ADICIONADO
11579
11654
  };
11580
11655
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
11581
11656
  const readModeAbstractionTree = useMemo12(() => {
@@ -11590,7 +11665,7 @@ function XViewScene({
11590
11665
  allAncestries
11591
11666
  );
11592
11667
  }, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
11593
- const handleStartReadingAncestry = useCallback3(
11668
+ const handleStartReadingAncestry = useCallback4(
11594
11669
  async (ancestryObject) => {
11595
11670
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11596
11671
  if (!ancestryObject || !ancestryObject.tree) {
@@ -11611,7 +11686,6 @@ function XViewScene({
11611
11686
  ancestry: ancestryObject,
11612
11687
  branchStack: [],
11613
11688
  autoAbstraction: shouldAutoRenderAbstraction
11614
- // <--- FLAG ENVIADA PARA A UI
11615
11689
  });
11616
11690
  if (shouldAutoRenderAbstraction) {
11617
11691
  handleRenderAbstractionTree(ancestryObject, null);
@@ -11625,9 +11699,8 @@ function XViewScene({
11625
11699
  }
11626
11700
  },
11627
11701
  [handleRenderAncestry, handleRenderAbstractionTree]
11628
- // <--- DEPENDÊNCIA ADICIONADA
11629
11702
  );
11630
- const handleReadModeSectionChange = useCallback3((activeSectionId) => {
11703
+ const handleReadModeSectionChange = useCallback4((activeSectionId) => {
11631
11704
  const { ancestry, branchStack } = readingMode;
11632
11705
  if (!ancestry || !readingMode.isActive) return;
11633
11706
  let targetObj = ancestry;
@@ -11696,10 +11769,10 @@ function XViewScene({
11696
11769
  }, 0);
11697
11770
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
11698
11771
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
11699
- const handleCloseReadMode = useCallback3(() => {
11772
+ const handleCloseReadMode = useCallback4(() => {
11700
11773
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
11701
11774
  }, []);
11702
- const handleAncestrySectionChange = useCallback3((activeSectionId, ancestryOverride = null, rotation = 0) => {
11775
+ const handleAncestrySectionChange = useCallback4((activeSectionId, ancestryOverride = null, rotation = 0) => {
11703
11776
  var _a2, _b2;
11704
11777
  const currentMode = stateRef.current.ancestry;
11705
11778
  let targetObj = ancestryOverride;
@@ -11751,7 +11824,7 @@ function XViewScene({
11751
11824
  const renderPayload = { ...targetObj, tree: treeToRender };
11752
11825
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
11753
11826
  }, [handleRenderAncestry]);
11754
- const handleEditAncestry = useCallback3(
11827
+ const handleEditAncestry = useCallback4(
11755
11828
  async (ancestryObject) => {
11756
11829
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11757
11830
  if (!ancestryObject || !ancestryObject.tree) {
@@ -11774,10 +11847,8 @@ function XViewScene({
11774
11847
  ...ancestryObject,
11775
11848
  tree: fullTree,
11776
11849
  abstraction_tree: fullAbstractionTree,
11777
- // NOVO
11778
11850
  selectedParentId: ancestryObject.ancestral_node,
11779
11851
  selectedAbstractionParentId: ancestryObject.ancestral_node,
11780
- // NOVO
11781
11852
  isEditMode: true,
11782
11853
  currentAncestryId: ancestryObject.ancestry_id,
11783
11854
  ancestryName: ancestryObject.name || `Ancestralidade ${fullTree.node.name}`,
@@ -11785,7 +11856,6 @@ function XViewScene({
11785
11856
  ancestryDescriptionSections: ancestryObject.description_sections || [],
11786
11857
  isAddingNodes: false,
11787
11858
  isAddingAbstractionNodes: false
11788
- // NOVO
11789
11859
  });
11790
11860
  },
11791
11861
  [handleRenderAncestry, buildFullAncestryTree]
@@ -11793,7 +11863,7 @@ function XViewScene({
11793
11863
  const handleSelectAncestryParent = (nodeId) => {
11794
11864
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
11795
11865
  };
11796
- const handleRemoveFromAncestry = useCallback3((pathToRemove) => {
11866
+ const handleRemoveFromAncestry = useCallback4((pathToRemove) => {
11797
11867
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
11798
11868
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
11799
11869
  return;
@@ -11818,7 +11888,7 @@ function XViewScene({
11818
11888
  return { ...prev, tree: newTree };
11819
11889
  });
11820
11890
  }, []);
11821
- const handleSaveAncestry = useCallback3(
11891
+ const handleSaveAncestry = useCallback4(
11822
11892
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
11823
11893
  const treeToUse = treeOverride || ancestryMode.tree;
11824
11894
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -12022,7 +12092,7 @@ function XViewScene({
12022
12092
  });
12023
12093
  setEditingAncestryRel({ visible: false, data: null, path: null });
12024
12094
  };
12025
- const handleDeleteAncestry = useCallback3(
12095
+ const handleDeleteAncestry = useCallback4(
12026
12096
  async (ancestryIdToDelete) => {
12027
12097
  if (!ancestryIdToDelete) {
12028
12098
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -12084,15 +12154,15 @@ function XViewScene({
12084
12154
  },
12085
12155
  [save_view_data, delete_file_action]
12086
12156
  );
12087
- const handleOpenAncestryBoard = useCallback3(() => {
12157
+ const handleOpenAncestryBoard = useCallback4(() => {
12088
12158
  setIsAncestryBoardOpen(true);
12089
12159
  }, []);
12090
- const handleSelectAncestryFromBoard = useCallback3((ancestry) => {
12160
+ const handleSelectAncestryFromBoard = useCallback4((ancestry) => {
12091
12161
  setIsAncestryBoardOpen(false);
12092
12162
  setIsSidebarOpen(false);
12093
12163
  handleStartReadingAncestry(ancestry);
12094
12164
  }, [handleStartReadingAncestry]);
12095
- const handleSaveAncestryBoard = useCallback3(async (groups) => {
12165
+ const handleSaveAncestryBoard = useCallback4(async (groups) => {
12096
12166
  if (!sceneConfigId || !viewParams || !session) return;
12097
12167
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
12098
12168
  await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
@@ -12116,13 +12186,13 @@ function XViewScene({
12116
12186
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
12117
12187
  });
12118
12188
  }, [parentDataRef.current, sceneVersion]);
12119
- const handleAddExistingNode = useCallback3(
12189
+ const handleAddExistingNode = useCallback4(
12120
12190
  (nodeId) => {
12121
12191
  return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
12122
12192
  },
12123
12193
  [actionHandlerContext]
12124
12194
  );
12125
- const handleSaveCurrentView = useCallback3(async () => {
12195
+ const handleSaveCurrentView = useCallback4(async () => {
12126
12196
  const { nodeObjects, allLinks } = stateRef.current;
12127
12197
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
12128
12198
  console.warn("N\xE3o \xE9 poss\xEDvel salvar a cena: estado n\xE3o inicializado ou URL de salvamento ausente.");
@@ -12162,7 +12232,7 @@ function XViewScene({
12162
12232
  const allAvailableAncestries = useMemo12(() => {
12163
12233
  return ancestryDataRef.current || [];
12164
12234
  }, [sceneVersion, isInitialized]);
12165
- const handleOpenReference = useCallback3((referenceData) => {
12235
+ const handleOpenReference = useCallback4((referenceData) => {
12166
12236
  const { type, id } = referenceData;
12167
12237
  if (type === "node") {
12168
12238
  const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
@@ -12189,10 +12259,10 @@ function XViewScene({
12189
12259
  }
12190
12260
  }
12191
12261
  }, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
12192
- const handleToggleAncestryAddMode = useCallback3(() => {
12262
+ const handleToggleAncestryAddMode = useCallback4(() => {
12193
12263
  setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
12194
12264
  }, []);
12195
- const handleFocusNode = useCallback3((nodeData) => {
12265
+ const handleFocusNode = useCallback4((nodeData) => {
12196
12266
  if (!nodeData) return;
12197
12267
  const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
12198
12268
  if (nodeMesh) {
@@ -12262,7 +12332,6 @@ function XViewScene({
12262
12332
  height: "100vh",
12263
12333
  position: "relative",
12264
12334
  overflow: "hidden",
12265
- // <--- ADICIONE ESTA LINHA
12266
12335
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
12267
12336
  }
12268
12337
  },
@@ -12329,9 +12398,20 @@ function XViewScene({
12329
12398
  readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React23.createElement(
12330
12399
  "div",
12331
12400
  {
12332
- 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 transition-all duration-300 ease-out w-[min(92vw,700px)]",
12333
- style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)" }
12401
+ 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"}`,
12402
+ style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
12334
12403
  },
12404
+ /* @__PURE__ */ React23.createElement(
12405
+ "div",
12406
+ {
12407
+ onPointerDown: (e) => {
12408
+ e.stopPropagation();
12409
+ handleReadModeResize(e);
12410
+ },
12411
+ className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors",
12412
+ title: "Arraste para redimensionar"
12413
+ }
12414
+ ),
12335
12415
  /* @__PURE__ */ React23.createElement(
12336
12416
  DescriptionReadModePanel,
12337
12417
  {