@2112-lab/central-plant 0.1.92 → 0.1.93

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.
@@ -11518,10 +11518,23 @@ var SceneExportManager = /*#__PURE__*/function () {
11518
11518
  // Helper function to extract behaviors from current scene data
11519
11519
  var extractBehaviors = function extractBehaviors() {
11520
11520
  var _this$sceneViewer, _this$sceneViewer2;
11521
+ // Only export behaviors that are NOT re-derivable from a component's
11522
+ // defaultBehaviors[]. All component/device default behaviors are
11523
+ // reconstructed at load time by Step B of _processBehaviors() using the
11524
+ // component dictionary, so writing compact behaviorRef entries for them
11525
+ // would be redundant. The scene JSON behaviors[] array is reserved for
11526
+ // any future scene-level overrides that cannot be derived from the asset.
11521
11527
  if ((_this$sceneViewer = _this.sceneViewer) !== null && _this$sceneViewer !== void 0 && (_this$sceneViewer = _this$sceneViewer.managers) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.behaviorManager) {
11522
- return _this.sceneViewer.managers.behaviorManager.getBehaviors();
11528
+ return _this.sceneViewer.managers.behaviorManager.getBehaviors().filter(function (b) {
11529
+ return !b._isDefaultBehavior;
11530
+ });
11523
11531
  }
11524
- return ((_this$sceneViewer2 = _this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.currentSceneData) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.behaviors) || [];
11532
+ // Fallback when BehaviorManager is not available: exclude any entry that
11533
+ // was already a behaviorRef (it was derivable from the component asset)
11534
+ // and exclude the legacy _isDefaultBehavior marker if present.
11535
+ return (((_this$sceneViewer2 = _this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.currentSceneData) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.behaviors) || []).filter(function (b) {
11536
+ return !b.behaviorRef && !b._isDefaultBehavior;
11537
+ });
11525
11538
  };
11526
11539
 
11527
11540
  // Build the complete export data structure (matching central-plant-input.json format)
@@ -19510,62 +19523,43 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
19510
19523
  key: "_loadComponentDictionary",
19511
19524
  value: (function () {
19512
19525
  var _loadComponentDictionary2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
19513
- var _yield$import, getCachedLocalJson, response, _t4, _t5;
19526
+ var response, _t4;
19514
19527
  return _regenerator().w(function (_context6) {
19515
19528
  while (1) switch (_context6.n) {
19516
19529
  case 0:
19517
19530
  _context6.p = 0;
19518
- if (!(typeof window !== 'undefined' && 'caches' in window)) {
19519
- _context6.n = 5;
19520
- break;
19521
- }
19522
- _context6.p = 1;
19523
- _context6.n = 2;
19524
- return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('~/utils/s3Cache')); });
19525
- case 2:
19526
- _yield$import = _context6.v;
19527
- getCachedLocalJson = _yield$import.getCachedLocalJson;
19528
- _context6.n = 3;
19529
- return getCachedLocalJson('/library/component-dictionary.json');
19530
- case 3:
19531
- this.componentDictionary = _context6.v;
19532
- console.log('📚 ComponentDataManager: Component dictionary loaded from cache');
19533
- return _context6.a(2);
19534
- case 4:
19535
- _context6.p = 4;
19536
- _t4 = _context6.v;
19537
- console.warn('⚠️ ComponentDataManager: Cache load failed, falling back to direct fetch:', _t4);
19538
- case 5:
19539
- _context6.n = 6;
19540
- return fetch('/library/component-dictionary.json');
19541
- case 6:
19531
+ _context6.n = 1;
19532
+ return fetch('/library/component-dictionary.json', {
19533
+ cache: 'no-cache'
19534
+ });
19535
+ case 1:
19542
19536
  response = _context6.v;
19543
19537
  if (!response.ok) {
19544
- _context6.n = 8;
19538
+ _context6.n = 3;
19545
19539
  break;
19546
19540
  }
19547
- _context6.n = 7;
19541
+ _context6.n = 2;
19548
19542
  return response.json();
19549
- case 7:
19543
+ case 2:
19550
19544
  this.componentDictionary = _context6.v;
19551
19545
  console.log('📚 ComponentDataManager: Component dictionary loaded successfully');
19552
- _context6.n = 9;
19546
+ _context6.n = 4;
19553
19547
  break;
19554
- case 8:
19548
+ case 3:
19555
19549
  console.warn('⚠️ ComponentDataManager: Could not load component dictionary');
19556
19550
  this.componentDictionary = null;
19557
- case 9:
19558
- _context6.n = 11;
19551
+ case 4:
19552
+ _context6.n = 6;
19559
19553
  break;
19560
- case 10:
19561
- _context6.p = 10;
19562
- _t5 = _context6.v;
19563
- console.warn('⚠️ ComponentDataManager: Error loading component dictionary:', _t5);
19554
+ case 5:
19555
+ _context6.p = 5;
19556
+ _t4 = _context6.v;
19557
+ console.warn('⚠️ ComponentDataManager: Error loading component dictionary:', _t4);
19564
19558
  this.componentDictionary = null;
19565
- case 11:
19559
+ case 6:
19566
19560
  return _context6.a(2);
19567
19561
  }
19568
- }, _callee6, this, [[1, 4], [0, 10]]);
19562
+ }, _callee6, this, [[0, 5]]);
19569
19563
  }));
19570
19564
  function _loadComponentDictionary() {
19571
19565
  return _loadComponentDictionary2.apply(this, arguments);
@@ -19814,6 +19808,8 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
19814
19808
  boundingBox: component.boundingBox || null,
19815
19809
  adaptedBoundingBox: component.adaptedBoundingBox || null,
19816
19810
  children: component.children || [],
19811
+ meshChildren: component.meshChildren || [],
19812
+ defaultBehaviors: component.defaultBehaviors || [],
19817
19813
  specifications: ((_component$metadata2 = component.metadata) === null || _component$metadata2 === void 0 ? void 0 : _component$metadata2.specifications) || {},
19818
19814
  description: ((_component$metadata3 = component.metadata) === null || _component$metadata3 === void 0 ? void 0 : _component$metadata3.description) || ''
19819
19815
  });
@@ -31062,20 +31058,252 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31062
31058
  }
31063
31059
 
31064
31060
  /**
31065
- * Process behaviors from the scene data and pass them to the BehaviorManager.
31061
+ * Process behaviors from the scene data, expand any defaultBehaviors defined
31062
+ * on component dictionary entries, resolve behaviorRef entries against device
31063
+ * assets, inject per-instance component UUIDs, and hand the flat resolved
31064
+ * array to BehaviorManager.
31065
+ *
31066
+ * Resolution cascade:
31067
+ * 1. Explicit behaviors in data.behaviors — passed through as-is (behaviorRef
31068
+ * entries are resolved against the component/device dictionaries).
31069
+ * 2. defaultBehaviors[] on each placed smart component's dictionary entry —
31070
+ * expanded per instance with the instance UUID injected. Compact
31071
+ * behaviorRef-derived entries are tagged _isDefaultBehavior:true (the
31072
+ * exporter can re-derive them); full L2 behavior objects are tagged false
31073
+ * so they are exported verbatim and survive round-trips.
31074
+ *
31066
31075
  * @param {Object} data - Scene JSON data
31067
31076
  */
31068
31077
  }, {
31069
31078
  key: "_processBehaviors",
31070
31079
  value: function _processBehaviors(data) {
31071
- var _this$sceneViewer2;
31072
- if (!(data !== null && data !== void 0 && data.behaviors) || !Array.isArray(data.behaviors)) return;
31080
+ var _this$sceneViewer2,
31081
+ _this$sceneViewer$cen2,
31082
+ _this5 = this,
31083
+ _data$scene3;
31073
31084
  var behaviorManager = (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.managers) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.behaviorManager;
31074
31085
  if (!behaviorManager) {
31075
31086
  console.warn('⚠️ _processBehaviors: BehaviorManager not available');
31076
31087
  return;
31077
31088
  }
31078
- behaviorManager.loadBehaviors(data.behaviors);
31089
+
31090
+ // Obtain the component dictionary (extended = includes S3/smart components)
31091
+ var componentDictionary = ((_this$sceneViewer$cen2 = this.sceneViewer.centralPlant) === null || _this$sceneViewer$cen2 === void 0 || (_this$sceneViewer$cen2 = _this$sceneViewer$cen2.managers) === null || _this$sceneViewer$cen2 === void 0 || (_this$sceneViewer$cen2 = _this$sceneViewer$cen2.componentDataManager) === null || _this$sceneViewer$cen2 === void 0 ? void 0 : _this$sceneViewer$cen2.componentDictionary) || {};
31092
+
31093
+ // ── Step A: Resolve any behaviorRef entries from data.behaviors ─────────
31094
+ var explicitBehaviors = [];
31095
+ if (Array.isArray(data === null || data === void 0 ? void 0 : data.behaviors)) {
31096
+ data.behaviors.forEach(function (entry) {
31097
+ if (entry.behaviorRef) {
31098
+ var resolved = _this5._resolveBehaviorRef(entry, componentDictionary);
31099
+ if (resolved) explicitBehaviors.push(resolved);
31100
+ } else {
31101
+ explicitBehaviors.push(entry);
31102
+ }
31103
+ });
31104
+ }
31105
+
31106
+ // Build a set of explicit behavior ids for deduplication
31107
+ var explicitIds = new Set(explicitBehaviors.map(function (b) {
31108
+ return b.id;
31109
+ }));
31110
+
31111
+ // Build a set of instanceUuids already covered by behaviorRef entries in
31112
+ // data.behaviors (written by the exporter for smart component defaults).
31113
+ // Step B skips these instances to avoid loading the same behaviors twice —
31114
+ // once via Step A (resolved from data.behaviors refs) and once via Step B
31115
+ // (auto-expanded from the component dictionary).
31116
+ var coveredInstances = new Set();
31117
+ if (Array.isArray(data === null || data === void 0 ? void 0 : data.behaviors)) {
31118
+ data.behaviors.forEach(function (entry) {
31119
+ if (entry.behaviorRef && entry.component) {
31120
+ coveredInstances.add(entry.component);
31121
+ }
31122
+ });
31123
+ }
31124
+
31125
+ // ── Step B: Walk placed components and expand their defaultBehaviors ─────
31126
+ var instanceBehaviors = [];
31127
+ if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
31128
+ data.scene.children.forEach(function (child) {
31129
+ var _child$userData0, _compData$defaultBeha;
31130
+ var libraryId = (_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId;
31131
+ if (!libraryId) return;
31132
+ var instanceUuid = child.uuid;
31133
+ // Skip instances whose defaults were already resolved by Step A
31134
+ // (they have explicit behaviorRef entries in data.behaviors).
31135
+ if (coveredInstances.has(instanceUuid)) return;
31136
+ var compData = componentDictionary[libraryId];
31137
+ if (!(compData !== null && compData !== void 0 && (_compData$defaultBeha = compData.defaultBehaviors) !== null && _compData$defaultBeha !== void 0 && _compData$defaultBeha.length)) return;
31138
+ compData.defaultBehaviors.forEach(function (template) {
31139
+ var expanded = _this5._expandDefaultBehavior(template, instanceUuid, componentDictionary);
31140
+ if (!expanded) return;
31141
+ // Skip if an explicit scene behavior already covers this id
31142
+ if (explicitIds.has(expanded.id)) return;
31143
+ // All component defaultBehaviors are re-derivable from the component
31144
+ // asset at export time (via compact behaviorRef), so mark them all.
31145
+ expanded._isDefaultBehavior = true;
31146
+ instanceBehaviors.push(expanded);
31147
+ });
31148
+ });
31149
+ }
31150
+ var allBehaviors = [].concat(explicitBehaviors, instanceBehaviors);
31151
+ if (allBehaviors.length === 0) return;
31152
+ behaviorManager.loadBehaviors(allBehaviors);
31153
+ console.log("\u2705 _processBehaviors: loaded ".concat(explicitBehaviors.length, " explicit + ").concat(instanceBehaviors.length, " default-expanded behavior(s)"));
31154
+ }
31155
+
31156
+ /**
31157
+ * Register the defaultBehaviors of a single newly placed component instance
31158
+ * into the BehaviorManager. Called from addComponent() (drag-drop), where
31159
+ * _processBehaviors() (scene-load path) is not invoked.
31160
+ *
31161
+ * @param {Object} componentData - Entry from the component dictionary
31162
+ * @param {string} instanceUuid - UUID of the placed component (componentModel.uuid)
31163
+ */
31164
+ }, {
31165
+ key: "registerBehaviorsForComponentInstance",
31166
+ value: function registerBehaviorsForComponentInstance(componentData, instanceUuid) {
31167
+ var _this$sceneViewer3,
31168
+ _componentData$defaul,
31169
+ _this$sceneViewer$cen3,
31170
+ _this6 = this;
31171
+ var behaviorManager = (_this$sceneViewer3 = this.sceneViewer) === null || _this$sceneViewer3 === void 0 || (_this$sceneViewer3 = _this$sceneViewer3.managers) === null || _this$sceneViewer3 === void 0 ? void 0 : _this$sceneViewer3.behaviorManager;
31172
+ if (!behaviorManager) return;
31173
+ if (!(componentData !== null && componentData !== void 0 && (_componentData$defaul = componentData.defaultBehaviors) !== null && _componentData$defaul !== void 0 && _componentData$defaul.length)) return;
31174
+ var componentDictionary = ((_this$sceneViewer$cen3 = this.sceneViewer.centralPlant) === null || _this$sceneViewer$cen3 === void 0 || (_this$sceneViewer$cen3 = _this$sceneViewer$cen3.managers) === null || _this$sceneViewer$cen3 === void 0 || (_this$sceneViewer$cen3 = _this$sceneViewer$cen3.componentDataManager) === null || _this$sceneViewer$cen3 === void 0 ? void 0 : _this$sceneViewer$cen3.componentDictionary) || {};
31175
+ var registered = 0;
31176
+ componentData.defaultBehaviors.forEach(function (template) {
31177
+ var expanded = _this6._expandDefaultBehavior(template, instanceUuid, componentDictionary);
31178
+ if (!expanded) return;
31179
+ expanded._isDefaultBehavior = true;
31180
+ behaviorManager.addBehavior(expanded);
31181
+ registered++;
31182
+ });
31183
+ if (registered > 0) {
31184
+ console.log("\u2705 registerBehaviorsForComponentInstance: registered ".concat(registered, " behavior(s) for instance ").concat(instanceUuid));
31185
+ }
31186
+ }
31187
+
31188
+ /**
31189
+ * Resolve a scene-level or component-level behaviorRef entry into a full
31190
+ * behavior definition by looking up the referenced template in the device
31191
+ * asset's defaultBehaviors[] and substituting 'self' with the real
31192
+ * attachmentId.
31193
+ *
31194
+ * Ref shape: { behaviorRef, deviceId, attachment, component? }
31195
+ *
31196
+ * @param {Object} ref
31197
+ * @param {Object} componentDictionary
31198
+ * @returns {Object|null} Resolved behavior or null if not found
31199
+ */
31200
+ }, {
31201
+ key: "_resolveBehaviorRef",
31202
+ value: function _resolveBehaviorRef(ref, componentDictionary) {
31203
+ var _resolved$input, _resolved$output;
31204
+ if (!ref.behaviorRef) {
31205
+ console.warn('⚠️ _resolveBehaviorRef: missing behaviorRef', ref);
31206
+ return null;
31207
+ }
31208
+
31209
+ // ── Component-level L2 ref: { behaviorRef, libraryId, component } ──────
31210
+ // The full behavior template lives on the smart component's defaultBehaviors[].
31211
+ // No 'self' substitution needed — attachment IDs are already real.
31212
+ if (ref.libraryId) {
31213
+ var compData = componentDictionary[ref.libraryId];
31214
+ if (!compData) {
31215
+ console.warn("\u26A0\uFE0F _resolveBehaviorRef: component \"".concat(ref.libraryId, "\" not in dictionary"));
31216
+ return null;
31217
+ }
31218
+ var _template = (compData.defaultBehaviors || []).find(function (b) {
31219
+ return b.id === ref.behaviorRef;
31220
+ });
31221
+ if (!_template) {
31222
+ console.warn("\u26A0\uFE0F _resolveBehaviorRef: behavior \"".concat(ref.behaviorRef, "\" not found on component \"").concat(ref.libraryId, "\""));
31223
+ return null;
31224
+ }
31225
+ var _resolved = JSON.parse(JSON.stringify(_template));
31226
+ _resolved.id = "".concat(_resolved.id, "::").concat(ref.component);
31227
+ if (ref.component) {
31228
+ _resolved.input = _objectSpread2(_objectSpread2({}, _resolved.input), {}, {
31229
+ component: ref.component
31230
+ });
31231
+ _resolved.output = _objectSpread2(_objectSpread2({}, _resolved.output), {}, {
31232
+ component: ref.component
31233
+ });
31234
+ }
31235
+ return _resolved;
31236
+ }
31237
+
31238
+ // ── Device-level L1 ref: { behaviorRef, deviceId, attachment, component } ─
31239
+ if (!ref.deviceId || !ref.attachment) {
31240
+ console.warn('⚠️ _resolveBehaviorRef: incomplete ref', ref);
31241
+ return null;
31242
+ }
31243
+ var deviceData = componentDictionary[ref.deviceId];
31244
+ if (!deviceData) {
31245
+ console.warn("\u26A0\uFE0F _resolveBehaviorRef: device \"".concat(ref.deviceId, "\" not in dictionary"));
31246
+ return null;
31247
+ }
31248
+ var template = (deviceData.defaultBehaviors || []).find(function (b) {
31249
+ return b.id === ref.behaviorRef;
31250
+ });
31251
+ if (!template) {
31252
+ console.warn("\u26A0\uFE0F _resolveBehaviorRef: behavior \"".concat(ref.behaviorRef, "\" not found on device \"").concat(ref.deviceId, "\""));
31253
+ return null;
31254
+ }
31255
+ // Deep clone and substitute 'self' -> real attachmentId
31256
+ var resolved = JSON.parse(JSON.stringify(template));
31257
+ resolved.id = "".concat(resolved.id, "::").concat(ref.attachment);
31258
+ if (((_resolved$input = resolved.input) === null || _resolved$input === void 0 ? void 0 : _resolved$input.attachment) === 'self') resolved.input.attachment = ref.attachment;
31259
+ if (((_resolved$output = resolved.output) === null || _resolved$output === void 0 ? void 0 : _resolved$output.attachment) === 'self') resolved.output.attachment = ref.attachment;
31260
+ // Inject component UUID guard if the ref carries one
31261
+ if (ref.component) {
31262
+ resolved.input = _objectSpread2(_objectSpread2({}, resolved.input), {}, {
31263
+ component: ref.component
31264
+ });
31265
+ resolved.output = _objectSpread2(_objectSpread2({}, resolved.output), {}, {
31266
+ component: ref.component
31267
+ });
31268
+ }
31269
+ return resolved;
31270
+ }
31271
+
31272
+ /**
31273
+ * Expand a single defaultBehaviors[] template entry for a specific component
31274
+ * instance placed in the scene.
31275
+ *
31276
+ * If the entry is a behaviorRef, it is first resolved against the device
31277
+ * library; otherwise it is treated as a full behavior definition.
31278
+ * In both cases the instanceUuid is injected as input.component and
31279
+ * output.component, and the behavior id is suffixed with ::instanceUuid.
31280
+ *
31281
+ * @param {Object} template - Entry from compData.defaultBehaviors[]
31282
+ * @param {string} instanceUuid - UUID of the placed component instance
31283
+ * @param {Object} componentDictionary
31284
+ * @returns {Object|null}
31285
+ */
31286
+ }, {
31287
+ key: "_expandDefaultBehavior",
31288
+ value: function _expandDefaultBehavior(template, instanceUuid, componentDictionary) {
31289
+ var base;
31290
+ if (template.behaviorRef) {
31291
+ // Resolve the device ref first (substitutes 'self' -> attachment)
31292
+ base = this._resolveBehaviorRef(template, componentDictionary);
31293
+ if (!base) return null;
31294
+ } else {
31295
+ base = JSON.parse(JSON.stringify(template));
31296
+ }
31297
+ // Suffix the id so each instance gets a unique behavior id
31298
+ base.id = "".concat(base.id, "::").concat(instanceUuid);
31299
+ // Inject the instance UUID as the component scope guard
31300
+ base.input = _objectSpread2(_objectSpread2({}, base.input), {}, {
31301
+ component: instanceUuid
31302
+ });
31303
+ base.output = _objectSpread2(_objectSpread2({}, base.output), {}, {
31304
+ component: instanceUuid
31305
+ });
31306
+ return base;
31079
31307
  }
31080
31308
 
31081
31309
  /**
@@ -31146,7 +31374,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31146
31374
  key: "loadSceneFromData",
31147
31375
  value: (function () {
31148
31376
  var _loadSceneFromData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9(data) {
31149
- var _data$scene3, _data$scene4, _data$scene5, _data$scene6;
31377
+ var _data$scene4, _data$scene5, _data$scene6, _data$scene7;
31150
31378
  return _regenerator().w(function (_context9) {
31151
31379
  while (1) switch (_context9.n) {
31152
31380
  case 0:
@@ -31156,10 +31384,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31156
31384
  dataType: _typeof(data),
31157
31385
  hasScene: !!(data !== null && data !== void 0 && data.scene),
31158
31386
  sceneType: _typeof(data === null || data === void 0 ? void 0 : data.scene),
31159
- hasChildren: !!(data !== null && data !== void 0 && (_data$scene3 = data.scene) !== null && _data$scene3 !== void 0 && _data$scene3.children),
31160
- childrenType: data !== null && data !== void 0 && (_data$scene4 = data.scene) !== null && _data$scene4 !== void 0 && _data$scene4.children ? _typeof(data.scene.children) : 'undefined',
31161
- isArray: Array.isArray(data === null || data === void 0 || (_data$scene5 = data.scene) === null || _data$scene5 === void 0 ? void 0 : _data$scene5.children),
31162
- childrenLength: data === null || data === void 0 || (_data$scene6 = data.scene) === null || _data$scene6 === void 0 || (_data$scene6 = _data$scene6.children) === null || _data$scene6 === void 0 ? void 0 : _data$scene6.length,
31387
+ hasChildren: !!(data !== null && data !== void 0 && (_data$scene4 = data.scene) !== null && _data$scene4 !== void 0 && _data$scene4.children),
31388
+ childrenType: data !== null && data !== void 0 && (_data$scene5 = data.scene) !== null && _data$scene5 !== void 0 && _data$scene5.children ? _typeof(data.scene.children) : 'undefined',
31389
+ isArray: Array.isArray(data === null || data === void 0 || (_data$scene6 = data.scene) === null || _data$scene6 === void 0 ? void 0 : _data$scene6.children),
31390
+ childrenLength: data === null || data === void 0 || (_data$scene7 = data.scene) === null || _data$scene7 === void 0 || (_data$scene7 = _data$scene7.children) === null || _data$scene7 === void 0 ? void 0 : _data$scene7.length,
31163
31391
  dataKeys: data ? Object.keys(data) : [],
31164
31392
  sceneKeys: data !== null && data !== void 0 && data.scene ? Object.keys(data.scene) : []
31165
31393
  });
@@ -31290,8 +31518,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31290
31518
  // Process children (connectors, etc.) if they exist
31291
31519
  if (componentModel.children && componentModel.children.length > 0) {
31292
31520
  componentModel.children.forEach(function (child) {
31293
- var _child$userData0, _child$userData1;
31294
- var childType = ((_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.objectType) || ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType);
31521
+ var _child$userData1, _child$userData10;
31522
+ var childType = ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) || ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType);
31295
31523
  if (childType === 'connector') {
31296
31524
  var _child$geometry;
31297
31525
  var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
@@ -31376,8 +31604,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31376
31604
  if (segment.children && segment.children.length > 0) {
31377
31605
  var childrenToRemove = _toConsumableArray(segment.children);
31378
31606
  childrenToRemove.forEach(function (child) {
31379
- var _child$userData10;
31380
- if ((_child$userData10 = child.userData) !== null && _child$userData10 !== void 0 && _child$userData10.isPipeElbow) {
31607
+ var _child$userData11;
31608
+ if ((_child$userData11 = child.userData) !== null && _child$userData11 !== void 0 && _child$userData11.isPipeElbow) {
31381
31609
  console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
31382
31610
  segment.remove(child);
31383
31611
  if (child.geometry) child.geometry.dispose();
@@ -31528,7 +31756,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31528
31756
  value: function _convertConnectedGatewaysToManual(connectors, currentSceneData) {
31529
31757
  var _connectors$,
31530
31758
  _segment$userData2,
31531
- _this5 = this;
31759
+ _this7 = this;
31532
31760
  console.log('🔍 Checking for connected gateways to convert to manual...');
31533
31761
  var sceneViewer = this.sceneViewer;
31534
31762
  var convertedGateways = [];
@@ -31565,7 +31793,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
31565
31793
  console.log("\uD83D\uDD27 Found computed gateway at endpoint: ".concat(endpointObject.uuid, " - converting to manual"));
31566
31794
 
31567
31795
  // Convert gateway to manual (declared) using manualizeGateway for consistency
31568
- _this5.manualizeGateway(endpointObject, currentSceneData);
31796
+ _this7.manualizeGateway(endpointObject, currentSceneData);
31569
31797
  convertedGateways.push(endpointObject);
31570
31798
  } else if (((_endpointObject$userD5 = endpointObject.userData) === null || _endpointObject$userD5 === void 0 ? void 0 : _endpointObject$userD5.objectType) === 'gateway' && ((_endpointObject$userD6 = endpointObject.userData) === null || _endpointObject$userD6 === void 0 ? void 0 : _endpointObject$userD6.isDeclared) === true) {
31571
31799
  console.log("\u2139\uFE0F Gateway ".concat(endpointObject.uuid, " is already declared (manual), skipping conversion"));
@@ -36512,7 +36740,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
36512
36740
  return false;
36513
36741
  }
36514
36742
  try {
36515
- var _componentData$childr, _componentData$childr2, _this$centralPlant$sc6, _componentData$childr3;
36743
+ var _componentData$childr, _componentData$childr2, _this$centralPlant$sc6, _componentData$childr3, _componentData$defaul;
36516
36744
  // Generate a unique component ID if not provided
36517
36745
  var componentId = options.customId || this.generateUniqueComponentId(libraryId);
36518
36746
 
@@ -36718,6 +36946,15 @@ var CentralPlantInternals = /*#__PURE__*/function () {
36718
36946
  attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId);
36719
36947
  }
36720
36948
 
36949
+ // Register default behaviors for smart components so the BehaviorManager
36950
+ // responds to tooltip-driven state changes immediately after drop.
36951
+ // (The scene-load path uses _processBehaviors instead, which runs on loadSceneData.)
36952
+ if ((_componentData$defaul = componentData.defaultBehaviors) !== null && _componentData$defaul !== void 0 && _componentData$defaul.length) {
36953
+ var _this$centralPlant$sc7, _som$registerBehavior;
36954
+ var som = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.sceneOperationsManager;
36955
+ som === null || som === void 0 || (_som$registerBehavior = som.registerBehaviorsForComponentInstance) === null || _som$registerBehavior === void 0 || _som$registerBehavior.call(som, componentData, componentId);
36956
+ }
36957
+
36721
36958
  // Notify the component manager about the new component
36722
36959
  if (componentManager.registerComponent) {
36723
36960
  componentManager.registerComponent(componentModel);
@@ -36776,9 +37013,9 @@ var CentralPlantInternals = /*#__PURE__*/function () {
36776
37013
  }, {
36777
37014
  key: "deleteComponent",
36778
37015
  value: function deleteComponent(componentId) {
36779
- var _this$centralPlant$sc7;
37016
+ var _this$centralPlant$sc8;
36780
37017
  // Check if component manager is available
36781
- var componentManager = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.componentManager;
37018
+ var componentManager = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.componentManager;
36782
37019
  if (!componentManager) {
36783
37020
  console.error('❌ deleteComponent(): Component manager not available');
36784
37021
  return false;
@@ -36873,7 +37110,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
36873
37110
  * Initialize the CentralPlant manager
36874
37111
  *
36875
37112
  * @constructor
36876
- * @version 0.1.92
37113
+ * @version 0.1.93
36877
37114
  * @updated 2025-10-22
36878
37115
  *
36879
37116
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
19
19
  * Initialize the CentralPlant manager
20
20
  *
21
21
  * @constructor
22
- * @version 0.1.92
22
+ * @version 0.1.93
23
23
  * @updated 2025-10-22
24
24
  *
25
25
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -876,7 +876,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
876
876
  return false;
877
877
  }
878
878
  try {
879
- var _componentData$childr, _componentData$childr2, _this$centralPlant$sc6, _componentData$childr3;
879
+ var _componentData$childr, _componentData$childr2, _this$centralPlant$sc6, _componentData$childr3, _componentData$defaul;
880
880
  // Generate a unique component ID if not provided
881
881
  var componentId = options.customId || this.generateUniqueComponentId(libraryId);
882
882
 
@@ -1082,6 +1082,15 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1082
1082
  ioDeviceUtils.attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId);
1083
1083
  }
1084
1084
 
1085
+ // Register default behaviors for smart components so the BehaviorManager
1086
+ // responds to tooltip-driven state changes immediately after drop.
1087
+ // (The scene-load path uses _processBehaviors instead, which runs on loadSceneData.)
1088
+ if ((_componentData$defaul = componentData.defaultBehaviors) !== null && _componentData$defaul !== void 0 && _componentData$defaul.length) {
1089
+ var _this$centralPlant$sc7, _som$registerBehavior;
1090
+ var som = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.sceneOperationsManager;
1091
+ som === null || som === void 0 || (_som$registerBehavior = som.registerBehaviorsForComponentInstance) === null || _som$registerBehavior === void 0 || _som$registerBehavior.call(som, componentData, componentId);
1092
+ }
1093
+
1085
1094
  // Notify the component manager about the new component
1086
1095
  if (componentManager.registerComponent) {
1087
1096
  componentManager.registerComponent(componentModel);
@@ -1140,9 +1149,9 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1140
1149
  }, {
1141
1150
  key: "deleteComponent",
1142
1151
  value: function deleteComponent(componentId) {
1143
- var _this$centralPlant$sc7;
1152
+ var _this$centralPlant$sc8;
1144
1153
  // Check if component manager is available
1145
- var componentManager = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.componentManager;
1154
+ var componentManager = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.componentManager;
1146
1155
  if (!componentManager) {
1147
1156
  console.error('❌ deleteComponent(): Component manager not available');
1148
1157
  return false;
@@ -559,62 +559,43 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
559
559
  key: "_loadComponentDictionary",
560
560
  value: (function () {
561
561
  var _loadComponentDictionary2 = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee6() {
562
- var _yield$import, getCachedLocalJson, response, _t4, _t5;
562
+ var response, _t4;
563
563
  return _rollupPluginBabelHelpers.regenerator().w(function (_context6) {
564
564
  while (1) switch (_context6.n) {
565
565
  case 0:
566
566
  _context6.p = 0;
567
- if (!(typeof window !== 'undefined' && 'caches' in window)) {
568
- _context6.n = 5;
569
- break;
570
- }
571
- _context6.p = 1;
572
- _context6.n = 2;
573
- return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('~/utils/s3Cache')); });
574
- case 2:
575
- _yield$import = _context6.v;
576
- getCachedLocalJson = _yield$import.getCachedLocalJson;
577
- _context6.n = 3;
578
- return getCachedLocalJson('/library/component-dictionary.json');
579
- case 3:
580
- this.componentDictionary = _context6.v;
581
- console.log('📚 ComponentDataManager: Component dictionary loaded from cache');
582
- return _context6.a(2);
583
- case 4:
584
- _context6.p = 4;
585
- _t4 = _context6.v;
586
- console.warn('⚠️ ComponentDataManager: Cache load failed, falling back to direct fetch:', _t4);
587
- case 5:
588
- _context6.n = 6;
589
- return fetch('/library/component-dictionary.json');
590
- case 6:
567
+ _context6.n = 1;
568
+ return fetch('/library/component-dictionary.json', {
569
+ cache: 'no-cache'
570
+ });
571
+ case 1:
591
572
  response = _context6.v;
592
573
  if (!response.ok) {
593
- _context6.n = 8;
574
+ _context6.n = 3;
594
575
  break;
595
576
  }
596
- _context6.n = 7;
577
+ _context6.n = 2;
597
578
  return response.json();
598
- case 7:
579
+ case 2:
599
580
  this.componentDictionary = _context6.v;
600
581
  console.log('📚 ComponentDataManager: Component dictionary loaded successfully');
601
- _context6.n = 9;
582
+ _context6.n = 4;
602
583
  break;
603
- case 8:
584
+ case 3:
604
585
  console.warn('⚠️ ComponentDataManager: Could not load component dictionary');
605
586
  this.componentDictionary = null;
606
- case 9:
607
- _context6.n = 11;
587
+ case 4:
588
+ _context6.n = 6;
608
589
  break;
609
- case 10:
610
- _context6.p = 10;
611
- _t5 = _context6.v;
612
- console.warn('⚠️ ComponentDataManager: Error loading component dictionary:', _t5);
590
+ case 5:
591
+ _context6.p = 5;
592
+ _t4 = _context6.v;
593
+ console.warn('⚠️ ComponentDataManager: Error loading component dictionary:', _t4);
613
594
  this.componentDictionary = null;
614
- case 11:
595
+ case 6:
615
596
  return _context6.a(2);
616
597
  }
617
- }, _callee6, this, [[1, 4], [0, 10]]);
598
+ }, _callee6, this, [[0, 5]]);
618
599
  }));
619
600
  function _loadComponentDictionary() {
620
601
  return _loadComponentDictionary2.apply(this, arguments);
@@ -863,6 +844,8 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
863
844
  boundingBox: component.boundingBox || null,
864
845
  adaptedBoundingBox: component.adaptedBoundingBox || null,
865
846
  children: component.children || [],
847
+ meshChildren: component.meshChildren || [],
848
+ defaultBehaviors: component.defaultBehaviors || [],
866
849
  specifications: ((_component$metadata2 = component.metadata) === null || _component$metadata2 === void 0 ? void 0 : _component$metadata2.specifications) || {},
867
850
  description: ((_component$metadata3 = component.metadata) === null || _component$metadata3 === void 0 ? void 0 : _component$metadata3.description) || ''
868
851
  });
@@ -303,10 +303,23 @@ var SceneExportManager = /*#__PURE__*/function () {
303
303
  // Helper function to extract behaviors from current scene data
304
304
  var extractBehaviors = function extractBehaviors() {
305
305
  var _this$sceneViewer, _this$sceneViewer2;
306
+ // Only export behaviors that are NOT re-derivable from a component's
307
+ // defaultBehaviors[]. All component/device default behaviors are
308
+ // reconstructed at load time by Step B of _processBehaviors() using the
309
+ // component dictionary, so writing compact behaviorRef entries for them
310
+ // would be redundant. The scene JSON behaviors[] array is reserved for
311
+ // any future scene-level overrides that cannot be derived from the asset.
306
312
  if ((_this$sceneViewer = _this.sceneViewer) !== null && _this$sceneViewer !== void 0 && (_this$sceneViewer = _this$sceneViewer.managers) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.behaviorManager) {
307
- return _this.sceneViewer.managers.behaviorManager.getBehaviors();
313
+ return _this.sceneViewer.managers.behaviorManager.getBehaviors().filter(function (b) {
314
+ return !b._isDefaultBehavior;
315
+ });
308
316
  }
309
- return ((_this$sceneViewer2 = _this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.currentSceneData) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.behaviors) || [];
317
+ // Fallback when BehaviorManager is not available: exclude any entry that
318
+ // was already a behaviorRef (it was derivable from the component asset)
319
+ // and exclude the legacy _isDefaultBehavior marker if present.
320
+ return (((_this$sceneViewer2 = _this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.currentSceneData) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.behaviors) || []).filter(function (b) {
321
+ return !b.behaviorRef && !b._isDefaultBehavior;
322
+ });
310
323
  };
311
324
 
312
325
  // Build the complete export data structure (matching central-plant-input.json format)