@2112-lab/central-plant 0.1.19 → 0.1.21

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.
@@ -21447,7 +21447,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
21447
21447
  case 0:
21448
21448
  component = this.sceneViewer;
21449
21449
  _context6.p = 1;
21450
- defaultCentralPlantUrl = './mock-data/cp-01-01.json';
21450
+ defaultCentralPlantUrl = process.env.DEFAULT_CENTRAL_PLANT_URL;
21451
21451
  _context6.n = 2;
21452
21452
  return fetch(defaultCentralPlantUrl);
21453
21453
  case 2:
@@ -21600,6 +21600,115 @@ var SceneOperationsManager = /*#__PURE__*/function () {
21600
21600
  });
21601
21601
  }
21602
21602
 
21603
+ /**
21604
+ * Add a new component to the scene data
21605
+ * @param {Object} componentModel - The Three.js component model that was added to the scene
21606
+ * @param {Object} currentSceneData - The current scene data structure
21607
+ * @returns {boolean} True if the component was successfully added to scene data
21608
+ */
21609
+ }, {
21610
+ key: "addComponentToSceneData",
21611
+ value: function addComponentToSceneData(componentModel, currentSceneData) {
21612
+ if (!componentModel || !currentSceneData) {
21613
+ console.error('❌ addComponentToSceneData: Missing componentModel or currentSceneData');
21614
+ return false;
21615
+ }
21616
+ if (!currentSceneData.scene || !currentSceneData.scene.object) {
21617
+ console.error('❌ addComponentToSceneData: Invalid scene data structure');
21618
+ return false;
21619
+ }
21620
+ try {
21621
+ var _componentModel$userD;
21622
+ // Calculate world bounding box for the component
21623
+ var boundingBox = new THREE__namespace.Box3().setFromObject(componentModel);
21624
+
21625
+ // Create scene data entry for the new component
21626
+ var componentSceneData = {
21627
+ uuid: componentModel.uuid,
21628
+ name: componentModel.name,
21629
+ type: 'Group',
21630
+ matrix: componentModel.matrix.elements,
21631
+ position: {
21632
+ x: componentModel.position.x,
21633
+ y: componentModel.position.y,
21634
+ z: componentModel.position.z
21635
+ },
21636
+ rotation: {
21637
+ x: componentModel.rotation.x,
21638
+ y: componentModel.rotation.y,
21639
+ z: componentModel.rotation.z
21640
+ },
21641
+ scale: {
21642
+ x: componentModel.scale.x,
21643
+ y: componentModel.scale.y,
21644
+ z: componentModel.scale.z
21645
+ },
21646
+ userData: _objectSpread2(_objectSpread2({}, componentModel.userData), {}, {
21647
+ worldBoundingBox: {
21648
+ min: boundingBox.min.toArray(),
21649
+ max: boundingBox.max.toArray()
21650
+ }
21651
+ }),
21652
+ children: []
21653
+ };
21654
+
21655
+ // Process children (connectors, etc.) if they exist
21656
+ if (componentModel.children && componentModel.children.length > 0) {
21657
+ componentModel.children.forEach(function (child) {
21658
+ var _child$userData17;
21659
+ if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.componentType) === 'connector') {
21660
+ var _child$geometry5;
21661
+ var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
21662
+ var childSceneData = {
21663
+ uuid: child.uuid,
21664
+ name: child.name,
21665
+ type: child.type,
21666
+ position: {
21667
+ x: child.position.x,
21668
+ y: child.position.y,
21669
+ z: child.position.z
21670
+ },
21671
+ rotation: {
21672
+ x: child.rotation.x,
21673
+ y: child.rotation.y,
21674
+ z: child.rotation.z
21675
+ },
21676
+ scale: {
21677
+ x: child.scale.x,
21678
+ y: child.scale.y,
21679
+ z: child.scale.z
21680
+ },
21681
+ userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
21682
+ worldBoundingBox: {
21683
+ min: childBoundingBox.min.toArray(),
21684
+ max: childBoundingBox.max.toArray()
21685
+ }
21686
+ }),
21687
+ geometry: ((_child$geometry5 = child.geometry) === null || _child$geometry5 === void 0 ? void 0 : _child$geometry5.uuid) || 'CONNECTOR-GEO'
21688
+ };
21689
+ componentSceneData.children.push(childSceneData);
21690
+ }
21691
+ });
21692
+ }
21693
+
21694
+ // Add the component to the scene data
21695
+ if (!currentSceneData.scene.object.children) {
21696
+ currentSceneData.scene.object.children = [];
21697
+ }
21698
+ currentSceneData.scene.object.children.push(componentSceneData);
21699
+ console.log('✅ addComponentToSceneData: Component added to scene data successfully', {
21700
+ componentId: componentModel.uuid,
21701
+ libraryId: (_componentModel$userD = componentModel.userData) === null || _componentModel$userD === void 0 ? void 0 : _componentModel$userD.libraryId,
21702
+ childrenCount: componentSceneData.children.length,
21703
+ totalSceneChildren: currentSceneData.scene.object.children.length
21704
+ });
21705
+ return true;
21706
+ } catch (error) {
21707
+ console.error('❌ addComponentToSceneData: Error adding component to scene data:', error);
21708
+ return false;
21709
+ }
21710
+ }
21711
+
21603
21712
  /**
21604
21713
  * Update scene data after object transform
21605
21714
  */
@@ -21621,9 +21730,9 @@ var SceneOperationsManager = /*#__PURE__*/function () {
21621
21730
 
21622
21731
  // Also update the corresponding scene data object
21623
21732
  for (var i = 0; i < currentSceneData.scene.object.children.length; i++) {
21624
- var _object$userData4, _child$userData17;
21733
+ var _object$userData4, _child$userData18;
21625
21734
  var child = currentSceneData.scene.object.children[i];
21626
- if (child.uuid === object.uuid || child.uuid === ((_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.originalUuid) || object.uuid === ((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.originalUuid)) {
21735
+ if (child.uuid === object.uuid || child.uuid === ((_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.originalUuid) || object.uuid === ((_child$userData18 = child.userData) === null || _child$userData18 === void 0 ? void 0 : _child$userData18.originalUuid)) {
21627
21736
  if (!child.userData) child.userData = {};
21628
21737
  child.userData.origin = 'declared';
21629
21738
  break;
@@ -21672,20 +21781,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
21672
21781
 
21673
21782
  // Update the corresponding child in currentSceneData with the transformed object
21674
21783
  var _loop = function _loop() {
21675
- var _object$userData6, _child$userData18, _object$userData7, _child$userData19;
21784
+ var _object$userData6, _child$userData19, _object$userData7, _child$userData20;
21676
21785
  var child = currentSceneData.scene.object.children[_i2];
21677
21786
  console.log("onTransformEnd child.uuid:", child.uuid);
21678
21787
  // Enhanced matching logic with hardcoded UUID priority
21679
21788
  var isMatch = false;
21680
21789
 
21681
21790
  // Strategy 1: Direct hardcoded UUID match (HIGHEST PRIORITY)
21682
- if (child.uuid === object.uuid || child.uuid === ((_object$userData6 = object.userData) === null || _object$userData6 === void 0 ? void 0 : _object$userData6.originalUuid) || object.uuid === ((_child$userData18 = child.userData) === null || _child$userData18 === void 0 ? void 0 : _child$userData18.originalUuid)) {
21791
+ if (child.uuid === object.uuid || child.uuid === ((_object$userData6 = object.userData) === null || _object$userData6 === void 0 ? void 0 : _object$userData6.originalUuid) || object.uuid === ((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.originalUuid)) {
21683
21792
  isMatch = true;
21684
21793
  console.log('🎯 Matched by hardcoded UUID');
21685
21794
  }
21686
21795
 
21687
21796
  // Strategy 4: Component type and library ID match
21688
- if (!isMatch && (_object$userData7 = object.userData) !== null && _object$userData7 !== void 0 && _object$userData7.libraryId && (_child$userData19 = child.userData) !== null && _child$userData19 !== void 0 && _child$userData19.libraryId && object.userData.libraryId === child.userData.libraryId) {
21797
+ if (!isMatch && (_object$userData7 = object.userData) !== null && _object$userData7 !== void 0 && _object$userData7.libraryId && (_child$userData20 = child.userData) !== null && _child$userData20 !== void 0 && _child$userData20.libraryId && object.userData.libraryId === child.userData.libraryId) {
21689
21798
  // For library components, also check position similarity
21690
21799
  var positionTolerance = 1.0; // Larger tolerance for main components
21691
21800
  if (child.position && object.position) {
@@ -26482,6 +26591,615 @@ var CentralPlant = /*#__PURE__*/function () {
26482
26591
  value: function getUtility(utilityName) {
26483
26592
  return this.utilities[utilityName] || null;
26484
26593
  }
26594
+
26595
+ /**
26596
+ * Translate a component by a specified value along a given axis
26597
+ * @param {string} componentId - The UUID or identifier of the component to translate
26598
+ * @param {string} axis - The axis to translate along ('x', 'y', or 'z')
26599
+ * @param {number} value - The value to translate by (can be positive or negative)
26600
+ * @returns {Object|false} The component object if translation was successful, false otherwise
26601
+ */
26602
+ }, {
26603
+ key: "translate",
26604
+ value: function translate(componentId, axis, value) {
26605
+ // Validate input parameters
26606
+ if (!componentId || typeof componentId !== 'string') {
26607
+ console.error('❌ translate(): Invalid componentId provided:', componentId);
26608
+ return false;
26609
+ }
26610
+ if (!['x', 'y', 'z'].includes(axis.toLowerCase())) {
26611
+ console.error('❌ translate(): Invalid axis provided. Must be "x", "y", or "z":', axis);
26612
+ return false;
26613
+ }
26614
+ if (typeof value !== 'number' || isNaN(value)) {
26615
+ console.error('❌ translate(): Invalid value provided. Must be a number:', value);
26616
+ return false;
26617
+ }
26618
+
26619
+ // Check if scene viewer is available
26620
+ if (!this.sceneViewer || !this.sceneViewer.scene) {
26621
+ console.error('❌ translate(): Scene viewer or scene not available');
26622
+ return false;
26623
+ }
26624
+
26625
+ // Find the component in the scene
26626
+ var component = this.utilities.findObjectByHardcodedUuid(this.sceneViewer.scene, componentId);
26627
+ if (!component) {
26628
+ console.error("\u274C translate(): Component not found with ID: ".concat(componentId));
26629
+ return false;
26630
+ }
26631
+
26632
+ // Verify this is a valid component that can be translated
26633
+ if (!component.userData || !component.userData.componentType) {
26634
+ console.warn("\u26A0\uFE0F translate(): Object found but may not be a valid component: ".concat(componentId));
26635
+ }
26636
+
26637
+ // Store previous transform values for undo functionality
26638
+ var previousValues = {
26639
+ position: component.position.clone(),
26640
+ rotation: component.rotation.clone(),
26641
+ scale: component.scale.clone()
26642
+ };
26643
+
26644
+ // Perform the translation
26645
+ var normalizedAxis = axis.toLowerCase();
26646
+ var previousPosition = component.position[normalizedAxis];
26647
+ try {
26648
+ // Apply the translation
26649
+ component.position[normalizedAxis] += value;
26650
+
26651
+ // Force update the component's matrices
26652
+ component.updateMatrix();
26653
+ component.updateMatrixWorld(true);
26654
+
26655
+ // Update world bounding box if the component has an associated JSON object
26656
+ if (component.userData.associatedJsonObject) {
26657
+ var worldBoundingBox = new THREE__namespace.Box3().setFromObject(component);
26658
+ component.userData.associatedJsonObject.userData.worldBoundingBox = {
26659
+ min: worldBoundingBox.min.toArray(),
26660
+ max: worldBoundingBox.max.toArray()
26661
+ };
26662
+ }
26663
+
26664
+ // Record this transform operation in history
26665
+ this.recordTransform({
26666
+ type: 'translate',
26667
+ object: component,
26668
+ values: {
26669
+ position: component.position.clone(),
26670
+ rotation: component.rotation.clone(),
26671
+ scale: component.scale.clone()
26672
+ },
26673
+ previousValues: previousValues,
26674
+ axis: normalizedAxis,
26675
+ translationValue: value
26676
+ });
26677
+
26678
+ // Emit transform event if the scene viewer supports it
26679
+ if (this.sceneViewer.emit && typeof this.sceneViewer.emit === 'function') {
26680
+ this.sceneViewer.emit('transform-update', {
26681
+ componentId: componentId,
26682
+ component: component,
26683
+ type: 'translate',
26684
+ axis: normalizedAxis,
26685
+ value: value,
26686
+ newPosition: {
26687
+ x: component.position.x,
26688
+ y: component.position.y,
26689
+ z: component.position.z
26690
+ }
26691
+ });
26692
+ this.sceneViewer.emit('scene-changed', {
26693
+ action: 'translate',
26694
+ componentId: componentId,
26695
+ axis: normalizedAxis,
26696
+ value: value
26697
+ });
26698
+ }
26699
+
26700
+ // If there's a scene operations manager, update scene data
26701
+ if (this.sceneViewer.sceneOperationsManager && this.sceneViewer.currentSceneData) {
26702
+ this.sceneViewer.sceneOperationsManager.updateSceneDataAfterTransform(component, this.sceneViewer.currentSceneData);
26703
+ }
26704
+
26705
+ // if (this.sceneViewer.shouldUpdatePaths && this.sceneViewer.updatePaths) {
26706
+ // this.sceneViewer.updatePaths()
26707
+ // }
26708
+
26709
+ // // Update scene data and paths after successful translation
26710
+ // this.updatePaths(component)
26711
+
26712
+ // Log successful translation
26713
+ console.log("\u2705 translate(): Component ".concat(componentId, " translated ").concat(value, " units along ").concat(normalizedAxis.toUpperCase(), "-axis"), {
26714
+ componentId: componentId,
26715
+ axis: normalizedAxis,
26716
+ value: value,
26717
+ previousPosition: previousPosition,
26718
+ newPosition: component.position[normalizedAxis],
26719
+ totalPosition: {
26720
+ x: component.position.x.toFixed(3),
26721
+ y: component.position.y.toFixed(3),
26722
+ z: component.position.z.toFixed(3)
26723
+ }
26724
+ });
26725
+ return component;
26726
+ } catch (error) {
26727
+ console.error("\u274C translate(): Error translating component ".concat(componentId, ":"), error);
26728
+
26729
+ // Attempt to restore previous position on error
26730
+ try {
26731
+ component.position.copy(previousValues.position);
26732
+ component.updateMatrix();
26733
+ component.updateMatrixWorld(true);
26734
+ console.log('🔄 translate(): Restored previous position after error');
26735
+ } catch (restoreError) {
26736
+ console.error('❌ translate(): Failed to restore previous position:', restoreError);
26737
+ }
26738
+ return false;
26739
+ }
26740
+ }
26741
+
26742
+ /**
26743
+ * Add a new component to the scene using its library ID
26744
+ * @param {string} libraryId - The library identifier for the component type (e.g., 'PUMP', 'CHILLER', 'COOLING-TOWER')
26745
+ * @param {Object} options - Optional configuration for the new component
26746
+ * @param {Object} options.position - Initial position for the component (default: random position within scene bounds)
26747
+ * @param {Object} options.rotation - Initial rotation for the component (default: no rotation)
26748
+ * @param {Object} options.scale - Initial scale for the component (default: 1.0 on all axes)
26749
+ * @param {string} options.customId - Custom identifier for the component (default: auto-generated UUID)
26750
+ * @returns {Object|false} The added component object if successful, false otherwise
26751
+ */
26752
+ }, {
26753
+ key: "addComponent",
26754
+ value: function addComponent(libraryId) {
26755
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
26756
+ // Validate input parameters
26757
+ if (!libraryId || typeof libraryId !== 'string') {
26758
+ console.error('❌ addComponent(): Invalid library ID provided. Must be a non-empty string.');
26759
+ return false;
26760
+ }
26761
+
26762
+ // Check if scene viewer is available
26763
+ if (!this.sceneViewer || !this.sceneViewer.scene) {
26764
+ console.error('❌ addComponent(): Scene viewer or scene not available');
26765
+ return false;
26766
+ }
26767
+
26768
+ // Check if component manager is available
26769
+ var componentManager = this.sceneViewer.componentManager;
26770
+ if (!componentManager) {
26771
+ console.error('❌ addComponent(): Component manager not available');
26772
+ return false;
26773
+ }
26774
+
26775
+ // Check if model preloader is available
26776
+ var modelPreloader = this.utilities.modelPreloader;
26777
+ if (!modelPreloader) {
26778
+ console.error('❌ addComponent(): Model preloader not available');
26779
+ return false;
26780
+ }
26781
+ try {
26782
+ // Generate a unique component ID if not provided
26783
+ var componentId = options.customId || this.utilities.generateUuidFromName(libraryId + '_' + Date.now());
26784
+
26785
+ // Set default position within scene boundaries if not provided
26786
+ var position = options.position || {
26787
+ x: 0,
26788
+ y: 0,
26789
+ z: 0
26790
+ };
26791
+
26792
+ // Set default rotation if not provided
26793
+ var rotation = options.rotation || {
26794
+ x: 0,
26795
+ y: 0,
26796
+ z: 0
26797
+ };
26798
+ console.log("\uD83D\uDD04 addComponent(): Adding component ".concat(libraryId, " at position:"), position);
26799
+
26800
+ // Get the component data from the preloader's component dictionary
26801
+ if (!modelPreloader.componentDictionary) {
26802
+ console.error("\u274C addComponent(): Component dictionary not available in model preloader");
26803
+ return false;
26804
+ }
26805
+ var componentData = modelPreloader.componentDictionary[libraryId];
26806
+ if (!componentData || !componentData.modelKey) {
26807
+ console.error("\u274C addComponent(): Component data not found for library ID '".concat(libraryId, "'. Available components:"), Object.keys(modelPreloader.componentDictionary));
26808
+ return false;
26809
+ }
26810
+
26811
+ // Get the cached model using the modelKey
26812
+ var cachedModel = modelPreloader.getCachedModelWithDimensions(componentData.modelKey, libraryId);
26813
+ if (!cachedModel) {
26814
+ var status = modelPreloader.getStatus();
26815
+ console.error("\u274C addComponent(): Model for library ID '".concat(libraryId, "' (modelKey: '").concat(componentData.modelKey, "') not found in cache. Cache status:"), {
26816
+ cachedModels: status.cachedModels,
26817
+ totalCached: status.totalCached,
26818
+ isPreloading: status.isPreloading,
26819
+ currentlyLoading: status.currentlyLoading
26820
+ });
26821
+ return false;
26822
+ }
26823
+
26824
+ // Clone the cached model to create a new instance
26825
+ var componentModel = cachedModel;
26826
+
26827
+ // Set the component properties
26828
+ componentModel.uuid = componentId;
26829
+ componentModel.name = libraryId + '_' + componentId.substring(0, 8);
26830
+
26831
+ // Set position and rotation
26832
+ componentModel.position.set(position.x, position.y, position.z);
26833
+ componentModel.rotation.set(rotation.x, rotation.y, rotation.z);
26834
+
26835
+ // Set up component metadata
26836
+ componentModel.userData = {
26837
+ componentType: 'component',
26838
+ libraryId: libraryId,
26839
+ originalUuid: componentId,
26840
+ hardcodedUuid: componentId,
26841
+ addedTimestamp: new Date().toISOString(),
26842
+ addedBy: 'centralPlant.addComponent()',
26843
+ isUserAdded: true,
26844
+ initialPosition: _objectSpread2({}, position),
26845
+ initialRotation: _objectSpread2({}, rotation)
26846
+ };
26847
+
26848
+ // Add the component to the scene
26849
+ this.sceneViewer.scene.add(componentModel);
26850
+
26851
+ // Update matrices to ensure proper positioning
26852
+ componentModel.updateMatrix();
26853
+ componentModel.updateMatrixWorld(true);
26854
+
26855
+ // Add children connectors from component dictionary
26856
+ if (componentData.children && Array.isArray(componentData.children)) {
26857
+ console.log("\uD83D\uDD0C addComponent(): Adding ".concat(componentData.children.length, " connectors for ").concat(libraryId));
26858
+ componentData.children.forEach(function (childData, index) {
26859
+ try {
26860
+ var _childData$userData, _childData$userData2, _childData$userData3;
26861
+ // Create connector geometry (simple sphere for now)
26862
+ var connectorGeometry = new THREE__namespace.SphereGeometry(0.1, 8, 6);
26863
+ var connectorMaterial = new THREE__namespace.MeshPhysicalMaterial({
26864
+ color: 0xC0C0C0,
26865
+ roughness: 0.15,
26866
+ metalness: 0.9,
26867
+ emissive: 0x000000,
26868
+ envMapIntensity: 1.5,
26869
+ transparent: true,
26870
+ opacity: 0.8
26871
+ });
26872
+
26873
+ // Create connector mesh
26874
+ var connectorMesh = new THREE__namespace.Mesh(connectorGeometry, connectorMaterial);
26875
+
26876
+ // Set connector properties from child data
26877
+ if (childData.uuid) {
26878
+ connectorMesh.uuid = "".concat(componentId, "_").concat(childData.uuid);
26879
+ }
26880
+ connectorMesh.name = "".concat(libraryId, "_connector_").concat(index);
26881
+
26882
+ // Set connector position relative to component
26883
+ if (childData.position) {
26884
+ connectorMesh.position.set(childData.position.x || 0, childData.position.y || 0, childData.position.z || 0);
26885
+ }
26886
+
26887
+ // Set connector user data
26888
+ connectorMesh.userData = {
26889
+ componentType: 'connector',
26890
+ parentComponentId: componentId,
26891
+ connectorIndex: index,
26892
+ direction: ((_childData$userData = childData.userData) === null || _childData$userData === void 0 ? void 0 : _childData$userData.direction) || [0, 1, 0],
26893
+ group: ((_childData$userData2 = childData.userData) === null || _childData$userData2 === void 0 ? void 0 : _childData$userData2.group) || null,
26894
+ forExport: ((_childData$userData3 = childData.userData) === null || _childData$userData3 === void 0 ? void 0 : _childData$userData3.forExport) || false,
26895
+ originalChildData: childData
26896
+ };
26897
+
26898
+ // Add connector as child of the component
26899
+ componentModel.add(connectorMesh);
26900
+ console.log("\u2705 Added connector ".concat(index, " to component ").concat(libraryId, ":"), {
26901
+ uuid: connectorMesh.uuid,
26902
+ position: connectorMesh.position,
26903
+ direction: connectorMesh.userData.direction,
26904
+ group: connectorMesh.userData.group
26905
+ });
26906
+ } catch (connectorError) {
26907
+ console.error("\u274C Error creating connector ".concat(index, " for ").concat(libraryId, ":"), connectorError);
26908
+ }
26909
+ });
26910
+ }
26911
+
26912
+ // Notify the component manager about the new component
26913
+ if (componentManager.registerComponent) {
26914
+ componentManager.registerComponent(componentModel);
26915
+ }
26916
+
26917
+ // Update scene data if available
26918
+ if (this.sceneViewer.sceneOperationsManager && this.sceneViewer.currentSceneData) {
26919
+ var success = this.sceneViewer.sceneOperationsManager.addComponentToSceneData(componentModel, this.sceneViewer.currentSceneData);
26920
+ if (success) {
26921
+ console.log('✅ Component successfully added to scene data');
26922
+ } else {
26923
+ console.warn('⚠️ Failed to add component to scene data');
26924
+ }
26925
+ }
26926
+
26927
+ // Record the add operation in metadata
26928
+ this.recordComponentAddition(componentModel, libraryId, options);
26929
+
26930
+ // Log successful addition
26931
+ console.log("\u2705 addComponent(): Component ".concat(libraryId, " added successfully"), componentModel);
26932
+ return componentModel;
26933
+ } catch (error) {
26934
+ console.error("\u274C addComponent(): Error adding component ".concat(libraryId, ":"), error);
26935
+ return false;
26936
+ }
26937
+ }
26938
+
26939
+ /**
26940
+ * Record component addition in metadata for tracking and potential undo
26941
+ * @param {Object} component - The added component
26942
+ * @param {string} libraryId - The library ID used
26943
+ * @param {Object} options - The options used for addition
26944
+ */
26945
+ }, {
26946
+ key: "recordComponentAddition",
26947
+ value: function recordComponentAddition(component, libraryId, options) {
26948
+ // Get existing addition history or create new array
26949
+ var additionHistory = this.getMetadata('componentAdditionHistory') || [];
26950
+ var additionRecord = {
26951
+ componentId: component.uuid,
26952
+ libraryId: libraryId,
26953
+ position: {
26954
+ x: component.position.x,
26955
+ y: component.position.y,
26956
+ z: component.position.z
26957
+ },
26958
+ rotation: {
26959
+ x: component.rotation.x,
26960
+ y: component.rotation.y,
26961
+ z: component.rotation.z
26962
+ },
26963
+ scale: {
26964
+ x: component.scale.x,
26965
+ y: component.scale.y,
26966
+ z: component.scale.z
26967
+ },
26968
+ options: options,
26969
+ timestamp: new Date().toISOString(),
26970
+ sessionId: this.getMetadata('sessionId') || 'unknown'
26971
+ };
26972
+
26973
+ // Add to history (keep only last 50 additions to prevent memory issues)
26974
+ additionHistory.push(additionRecord);
26975
+ if (additionHistory.length > 50) {
26976
+ additionHistory.shift(); // Remove oldest entry
26977
+ }
26978
+
26979
+ // Update metadata
26980
+ this.setMetadata('componentAdditionHistory', additionHistory);
26981
+ this.setMetadata('lastComponentAddition', additionRecord);
26982
+ console.log('📝 Component addition recorded in metadata:', {
26983
+ componentId: component.uuid,
26984
+ libraryId: libraryId,
26985
+ totalAdditions: additionHistory.length
26986
+ });
26987
+ }
26988
+
26989
+ /**
26990
+ * Add a connection between two connector IDs to the connections list
26991
+ * This method adds a new connection to the currentSceneData.connections array
26992
+ * @param {string} fromConnectorId - The ID of the source connector
26993
+ * @param {string} toConnectorId - The ID of the destination connector
26994
+ * @returns {Object|false} The added connection object if successful, false otherwise
26995
+ */
26996
+ }, {
26997
+ key: "addConnection",
26998
+ value: function addConnection(fromConnectorId, toConnectorId) {
26999
+ // Validate input parameters
27000
+ if (!fromConnectorId || typeof fromConnectorId !== 'string') {
27001
+ console.error('❌ addConnection(): Invalid fromConnectorId provided. Must be a non-empty string:', fromConnectorId);
27002
+ return false;
27003
+ }
27004
+ if (!toConnectorId || typeof toConnectorId !== 'string') {
27005
+ console.error('❌ addConnection(): Invalid toConnectorId provided. Must be a non-empty string:', toConnectorId);
27006
+ return false;
27007
+ }
27008
+
27009
+ // Check if the same connector IDs (avoid self-connection)
27010
+ if (fromConnectorId === toConnectorId) {
27011
+ console.error('❌ addConnection(): Cannot connect a connector to itself:', fromConnectorId);
27012
+ return false;
27013
+ }
27014
+
27015
+ // Check if scene viewer and currentSceneData are available
27016
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
27017
+ console.error('❌ addConnection(): Scene viewer or current scene data not available');
27018
+ return false;
27019
+ }
27020
+ try {
27021
+ // Initialize connections array if it doesn't exist
27022
+ if (!this.sceneViewer.currentSceneData.connections) {
27023
+ this.sceneViewer.currentSceneData.connections = [];
27024
+ console.log('🔄 addConnection(): Initialized connections array in currentSceneData');
27025
+ }
27026
+
27027
+ // Check if connection already exists
27028
+ var existingConnection = this.sceneViewer.currentSceneData.connections.find(function (connection) {
27029
+ return connection.from === fromConnectorId && connection.to === toConnectorId || connection.from === toConnectorId && connection.to === fromConnectorId;
27030
+ });
27031
+ if (existingConnection) {
27032
+ console.warn("\u26A0\uFE0F addConnection(): Connection already exists between ".concat(fromConnectorId, " and ").concat(toConnectorId));
27033
+ return existingConnection;
27034
+ }
27035
+
27036
+ // Create the new connection object
27037
+ var newConnection = {
27038
+ from: fromConnectorId,
27039
+ to: toConnectorId
27040
+ };
27041
+
27042
+ // Add the connection to the connections array
27043
+ this.sceneViewer.currentSceneData.connections.push(newConnection);
27044
+
27045
+ // Log successful addition
27046
+ console.log("\u2705 addConnection(): Connection added successfully", {
27047
+ from: fromConnectorId,
27048
+ to: toConnectorId,
27049
+ totalConnections: this.sceneViewer.currentSceneData.connections.length
27050
+ });
27051
+
27052
+ // Record the connection addition in metadata for tracking
27053
+ this.recordConnectionAddition(newConnection);
27054
+ return newConnection;
27055
+ } catch (error) {
27056
+ console.error("\u274C addConnection(): Error adding connection from ".concat(fromConnectorId, " to ").concat(toConnectorId, ":"), error);
27057
+ return false;
27058
+ }
27059
+ }
27060
+
27061
+ /**
27062
+ * Record connection addition in metadata for tracking and potential undo
27063
+ * @param {Object} connection - The added connection object
27064
+ */
27065
+ }, {
27066
+ key: "recordConnectionAddition",
27067
+ value: function recordConnectionAddition(connection) {
27068
+ try {
27069
+ // Get existing connection history or create new array
27070
+ var connectionHistory = this.getMetadata('connectionAdditionHistory') || [];
27071
+ var connectionRecord = {
27072
+ from: connection.from,
27073
+ to: connection.to,
27074
+ timestamp: new Date().toISOString(),
27075
+ addedBy: 'centralPlant.addConnection()'
27076
+ };
27077
+
27078
+ // Add to history
27079
+ connectionHistory.push(connectionRecord);
27080
+
27081
+ // Store updated history (keep last 100 entries to prevent memory issues)
27082
+ this.setMetadata('connectionAdditionHistory', connectionHistory.slice(-100));
27083
+
27084
+ // Update connection statistics
27085
+ var stats = this.getMetadata('connectionStats') || {
27086
+ totalAdded: 0
27087
+ };
27088
+ stats.totalAdded = (stats.totalAdded || 0) + 1;
27089
+ stats.lastAddedTimestamp = new Date().toISOString();
27090
+ this.setMetadata('connectionStats', stats);
27091
+ } catch (error) {
27092
+ console.warn('⚠️ Failed to record connection addition in metadata:', error);
27093
+ }
27094
+ }
27095
+
27096
+ /**
27097
+ * Get all current connections from the scene data
27098
+ * @returns {Array} Array of connection objects or empty array if none exist
27099
+ */
27100
+ }, {
27101
+ key: "getConnections",
27102
+ value: function getConnections() {
27103
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
27104
+ console.warn('⚠️ getConnections(): Scene viewer or current scene data not available');
27105
+ return [];
27106
+ }
27107
+ return this.sceneViewer.currentSceneData.connections || [];
27108
+ }
27109
+
27110
+ /**
27111
+ * Remove a connection between two connector IDs from the connections list
27112
+ * @param {string} fromConnectorId - The ID of the source connector
27113
+ * @param {string} toConnectorId - The ID of the destination connector
27114
+ * @returns {boolean} True if connection was removed, false otherwise
27115
+ */
27116
+ }, {
27117
+ key: "removeConnection",
27118
+ value: function removeConnection(fromConnectorId, toConnectorId) {
27119
+ // Validate input parameters
27120
+ if (!fromConnectorId || typeof fromConnectorId !== 'string') {
27121
+ console.error('❌ removeConnection(): Invalid fromConnectorId provided. Must be a non-empty string:', fromConnectorId);
27122
+ return false;
27123
+ }
27124
+ if (!toConnectorId || typeof toConnectorId !== 'string') {
27125
+ console.error('❌ removeConnection(): Invalid toConnectorId provided. Must be a non-empty string:', toConnectorId);
27126
+ return false;
27127
+ }
27128
+
27129
+ // Check if scene viewer and currentSceneData are available
27130
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData || !this.sceneViewer.currentSceneData.connections) {
27131
+ console.error('❌ removeConnection(): Scene viewer, current scene data, or connections array not available');
27132
+ return false;
27133
+ }
27134
+ try {
27135
+ // Find the connection to remove (check both directions)
27136
+ var connectionIndex = this.sceneViewer.currentSceneData.connections.findIndex(function (connection) {
27137
+ return connection.from === fromConnectorId && connection.to === toConnectorId || connection.from === toConnectorId && connection.to === fromConnectorId;
27138
+ });
27139
+ if (connectionIndex === -1) {
27140
+ console.warn("\u26A0\uFE0F removeConnection(): Connection not found between ".concat(fromConnectorId, " and ").concat(toConnectorId));
27141
+ return false;
27142
+ }
27143
+
27144
+ // Remove the connection
27145
+ var removedConnection = this.sceneViewer.currentSceneData.connections.splice(connectionIndex, 1)[0];
27146
+
27147
+ // Log successful removal
27148
+ console.log("\u2705 removeConnection(): Connection removed successfully", {
27149
+ from: removedConnection.from,
27150
+ to: removedConnection.to,
27151
+ remainingConnections: this.sceneViewer.currentSceneData.connections.length
27152
+ });
27153
+
27154
+ // Record the connection removal in metadata
27155
+ this.recordConnectionRemoval(removedConnection);
27156
+ return true;
27157
+ } catch (error) {
27158
+ console.error("\u274C removeConnection(): Error removing connection from ".concat(fromConnectorId, " to ").concat(toConnectorId, ":"), error);
27159
+ return false;
27160
+ }
27161
+ }
27162
+
27163
+ /**
27164
+ * Record connection removal in metadata for tracking
27165
+ * @param {Object} connection - The removed connection object
27166
+ */
27167
+ }, {
27168
+ key: "recordConnectionRemoval",
27169
+ value: function recordConnectionRemoval(connection) {
27170
+ try {
27171
+ // Get existing removal history or create new array
27172
+ var removalHistory = this.getMetadata('connectionRemovalHistory') || [];
27173
+ var removalRecord = {
27174
+ from: connection.from,
27175
+ to: connection.to,
27176
+ timestamp: new Date().toISOString(),
27177
+ removedBy: 'centralPlant.removeConnection()'
27178
+ };
27179
+
27180
+ // Add to history
27181
+ removalHistory.push(removalRecord);
27182
+
27183
+ // Store updated history (keep last 100 entries to prevent memory issues)
27184
+ this.setMetadata('connectionRemovalHistory', removalHistory.slice(-100));
27185
+
27186
+ // Update connection statistics
27187
+ var stats = this.getMetadata('connectionStats') || {
27188
+ totalAdded: 0,
27189
+ totalRemoved: 0
27190
+ };
27191
+ stats.totalRemoved = (stats.totalRemoved || 0) + 1;
27192
+ stats.lastRemovedTimestamp = new Date().toISOString();
27193
+ this.setMetadata('connectionStats', stats);
27194
+ } catch (error) {
27195
+ console.warn('⚠️ Failed to record connection removal in metadata:', error);
27196
+ }
27197
+ }
27198
+ }, {
27199
+ key: "updatePaths",
27200
+ value: function updatePaths() {
27201
+ this.sceneViewer.updatePaths();
27202
+ }
26485
27203
  }]);
26486
27204
  }();
26487
27205