@2112-lab/central-plant 0.3.41 → 0.3.42

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.
@@ -1164,6 +1164,122 @@ var DisposalUtilities = /*#__PURE__*/function () {
1164
1164
  }]);
1165
1165
  }();
1166
1166
 
1167
+ /**
1168
+ * Shared I/O device state dispatch helpers used by centralPlant and componentTooltipManager.
1169
+ */
1170
+
1171
+ /**
1172
+ * @param {string} attachmentId
1173
+ * @param {string|null|undefined} parentUuid
1174
+ * @returns {string}
1175
+ */
1176
+ function getScopedAttachmentKey(attachmentId, parentUuid) {
1177
+ if (!parentUuid) return attachmentId;
1178
+ return "".concat(parentUuid, "::").concat(attachmentId);
1179
+ }
1180
+
1181
+ /**
1182
+ * @param {Object} sceneViewer
1183
+ * @returns {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager|null}
1184
+ */
1185
+ function getIoBehaviorManager(sceneViewer) {
1186
+ var _sceneViewer$managers, _sceneViewer$centralP;
1187
+ if (!sceneViewer) return null;
1188
+ return ((_sceneViewer$managers = sceneViewer.managers) === null || _sceneViewer$managers === void 0 ? void 0 : _sceneViewer$managers.ioBehaviorManager) || sceneViewer.ioBehaviorManager || ((_sceneViewer$centralP = sceneViewer.centralPlant) === null || _sceneViewer$centralP === void 0 || (_sceneViewer$centralP = _sceneViewer$centralP.managers) === null || _sceneViewer$centralP === void 0 ? void 0 : _sceneViewer$centralP.ioBehaviorManager) || null;
1189
+ }
1190
+
1191
+ /**
1192
+ * Resolve tooltip/drag data points for an I/O device attachment.
1193
+ * Prefers behaviorConfig-driven animation data points; merges legacy ioConfig snapshot.
1194
+ *
1195
+ * @param {string} parentUuid
1196
+ * @param {string} attachmentId
1197
+ * @param {Object} userData - io-device userData (may include dataPoints snapshot)
1198
+ * @param {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager|null} ioBehaviorManager
1199
+ * @param {THREE.Object3D|null} [hitMesh]
1200
+ * @returns {Object[]}
1201
+ */
1202
+ function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager) {
1203
+ var hitMesh = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
1204
+ var fromAnimations = (ioBehaviorManager === null || ioBehaviorManager === void 0 ? void 0 : ioBehaviorManager.getAnimationDataPoints(parentUuid, attachmentId, hitMesh)) || [];
1205
+ if (fromAnimations.length) return fromAnimations;
1206
+ var legacy = (userData === null || userData === void 0 ? void 0 : userData.dataPoints) || [];
1207
+ return legacy.map(function (dp) {
1208
+ var _dp$defaultValue;
1209
+ return {
1210
+ id: dp.id || dp.name,
1211
+ name: dp.name || dp.id,
1212
+ stateType: dp.stateType || 'binary',
1213
+ stateConfig: dp.stateConfig || {},
1214
+ defaultValue: (_dp$defaultValue = dp.defaultValue) !== null && _dp$defaultValue !== void 0 ? _dp$defaultValue : null,
1215
+ direction: dp.direction || (userData === null || userData === void 0 ? void 0 : userData.ioDirection) || 'output'
1216
+ };
1217
+ }).filter(function (dp) {
1218
+ return dp.id;
1219
+ });
1220
+ }
1221
+
1222
+ /**
1223
+ * Apply persisted default values for I/O device animation states in the live scene.
1224
+ * Updates the state adapter (e.g. Vuex) and drives mesh animations via IoBehaviorManager.
1225
+ *
1226
+ * @param {Object} centralPlant
1227
+ * @param {{ parentUuid?: string, attachmentId?: string }} [options]
1228
+ */
1229
+ function applyDefaultIoDeviceStates(centralPlant) {
1230
+ var _centralPlant$sceneVi;
1231
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1232
+ var parentUuid = options.parentUuid,
1233
+ attachmentId = options.attachmentId;
1234
+ var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
1235
+ var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
1236
+ if (!ioBehavMgr || !scene || typeof (centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.setIoDeviceState) !== 'function') return;
1237
+ var seen = new Set();
1238
+ scene.traverse(function (obj) {
1239
+ var _obj$userData, _obj$parent;
1240
+ if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) !== 'io-device') return;
1241
+ var objParentUuid = obj.userData.parentComponentId || ((_obj$parent = obj.parent) === null || _obj$parent === void 0 ? void 0 : _obj$parent.uuid);
1242
+ var objAttachmentId = obj.userData.attachmentId;
1243
+ if (!objParentUuid || !objAttachmentId) return;
1244
+ if (parentUuid && objParentUuid !== parentUuid) return;
1245
+ if (attachmentId && objAttachmentId !== attachmentId) return;
1246
+ var scopedKey = getScopedAttachmentKey(objAttachmentId, objParentUuid);
1247
+ if (seen.has(scopedKey)) return;
1248
+ seen.add(scopedKey);
1249
+ var dps = ioBehavMgr.getAnimationDataPoints(objParentUuid, objAttachmentId) || [];
1250
+ if (dps.length) {
1251
+ var _iterator = _createForOfIteratorHelper(dps),
1252
+ _step;
1253
+ try {
1254
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1255
+ var dp = _step.value;
1256
+ if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
1257
+ centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
1258
+ }
1259
+ } catch (err) {
1260
+ _iterator.e(err);
1261
+ } finally {
1262
+ _iterator.f();
1263
+ }
1264
+ return;
1265
+ }
1266
+ var _iterator2 = _createForOfIteratorHelper(obj.userData.dataPoints || []),
1267
+ _step2;
1268
+ try {
1269
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
1270
+ var _dp = _step2.value;
1271
+ var dpId = _dp.id || _dp.name;
1272
+ if (!dpId || _dp.defaultValue === undefined || _dp.defaultValue === null) continue;
1273
+ centralPlant.setIoDeviceState(objAttachmentId, dpId, _dp.defaultValue, objParentUuid);
1274
+ }
1275
+ } catch (err) {
1276
+ _iterator2.e(err);
1277
+ } finally {
1278
+ _iterator2.f();
1279
+ }
1280
+ });
1281
+ }
1282
+
1167
1283
  /**
1168
1284
  * Register mesh animations and intra-component state links when a smart
1169
1285
  * component is placed or imported into the scene.
@@ -1173,8 +1289,9 @@ var DisposalUtilities = /*#__PURE__*/function () {
1173
1289
  * @param {Object} componentData - Smart component dictionary entry
1174
1290
  * @param {Object} componentModel - Root THREE.Object3D of the placed component
1175
1291
  * @param {Object} componentDictionary - modelPreloader.componentDictionary
1292
+ * @param {Object} [centralPlant] - When provided, default animation states are applied after registration
1176
1293
  */
1177
- function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary) {
1294
+ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary, centralPlant) {
1178
1295
  var _componentData$behavi;
1179
1296
  if (!ioBehavMgr || !componentData || !componentModel) {
1180
1297
  return;
@@ -1204,6 +1321,11 @@ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData,
1204
1321
  } else if (componentData.isSmart) {
1205
1322
  ioBehavMgr.registerComponentBehaviors(componentUuid, []);
1206
1323
  }
1324
+ if (centralPlant) {
1325
+ applyDefaultIoDeviceStates(centralPlant, {
1326
+ parentUuid: componentUuid
1327
+ });
1328
+ }
1207
1329
  }
1208
1330
 
1209
1331
  /**
@@ -1229,6 +1351,10 @@ function reloadBehaviorsForDeviceAsset(ioBehavMgr, deviceAssetId, componentDicti
1229
1351
  if (!parentUuid || !attachmentId) return;
1230
1352
  ioBehavMgr.unloadForAttachment(parentUuid, attachmentId);
1231
1353
  ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, obj, parentUuid);
1354
+ applyDefaultIoDeviceStates(centralPlant, {
1355
+ parentUuid: parentUuid,
1356
+ attachmentId: attachmentId
1357
+ });
1232
1358
  });
1233
1359
  }
1234
1360
 
@@ -31438,7 +31564,7 @@ var ModelManager = /*#__PURE__*/function () {
31438
31564
  key: "loadLibraryModel",
31439
31565
  value: function () {
31440
31566
  var _loadLibraryModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
31441
- var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, warmFn, _jsonEntry$userData4, _t;
31567
+ var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, _this$sceneViewer2, warmFn, _jsonEntry$userData4, _t;
31442
31568
  return _regenerator().w(function (_context) {
31443
31569
  while (1) switch (_context.n) {
31444
31570
  case 0:
@@ -31483,7 +31609,7 @@ var ModelManager = /*#__PURE__*/function () {
31483
31609
  case 4:
31484
31610
  ioBehavMgr = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.ioBehaviorManager;
31485
31611
  if (ioBehavMgr) {
31486
- registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary);
31612
+ registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary, (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.centralPlant);
31487
31613
  }
31488
31614
  case 5:
31489
31615
  // Replace mesh in scene
@@ -36612,61 +36738,6 @@ var SceneTooltipsManager = /*#__PURE__*/function (_BaseDisposable) {
36612
36738
  }]);
36613
36739
  }(BaseDisposable);
36614
36740
 
36615
- /**
36616
- * Shared I/O device state dispatch helpers used by centralPlant and componentTooltipManager.
36617
- */
36618
-
36619
- /**
36620
- * @param {string} attachmentId
36621
- * @param {string|null|undefined} parentUuid
36622
- * @returns {string}
36623
- */
36624
- function getScopedAttachmentKey(attachmentId, parentUuid) {
36625
- if (!parentUuid) return attachmentId;
36626
- return "".concat(parentUuid, "::").concat(attachmentId);
36627
- }
36628
-
36629
- /**
36630
- * @param {Object} sceneViewer
36631
- * @returns {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager|null}
36632
- */
36633
- function getIoBehaviorManager(sceneViewer) {
36634
- var _sceneViewer$managers, _sceneViewer$centralP;
36635
- if (!sceneViewer) return null;
36636
- return ((_sceneViewer$managers = sceneViewer.managers) === null || _sceneViewer$managers === void 0 ? void 0 : _sceneViewer$managers.ioBehaviorManager) || sceneViewer.ioBehaviorManager || ((_sceneViewer$centralP = sceneViewer.centralPlant) === null || _sceneViewer$centralP === void 0 || (_sceneViewer$centralP = _sceneViewer$centralP.managers) === null || _sceneViewer$centralP === void 0 ? void 0 : _sceneViewer$centralP.ioBehaviorManager) || null;
36637
- }
36638
-
36639
- /**
36640
- * Resolve tooltip/drag data points for an I/O device attachment.
36641
- * Prefers behaviorConfig-driven animation data points; merges legacy ioConfig snapshot.
36642
- *
36643
- * @param {string} parentUuid
36644
- * @param {string} attachmentId
36645
- * @param {Object} userData - io-device userData (may include dataPoints snapshot)
36646
- * @param {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager|null} ioBehaviorManager
36647
- * @param {THREE.Object3D|null} [hitMesh]
36648
- * @returns {Object[]}
36649
- */
36650
- function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager) {
36651
- var hitMesh = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
36652
- var fromAnimations = (ioBehaviorManager === null || ioBehaviorManager === void 0 ? void 0 : ioBehaviorManager.getAnimationDataPoints(parentUuid, attachmentId, hitMesh)) || [];
36653
- if (fromAnimations.length) return fromAnimations;
36654
- var legacy = (userData === null || userData === void 0 ? void 0 : userData.dataPoints) || [];
36655
- return legacy.map(function (dp) {
36656
- var _dp$defaultValue;
36657
- return {
36658
- id: dp.id || dp.name,
36659
- name: dp.name || dp.id,
36660
- stateType: dp.stateType || 'binary',
36661
- stateConfig: dp.stateConfig || {},
36662
- defaultValue: (_dp$defaultValue = dp.defaultValue) !== null && _dp$defaultValue !== void 0 ? _dp$defaultValue : null,
36663
- direction: dp.direction || (userData === null || userData === void 0 ? void 0 : userData.ioDirection) || 'output'
36664
- };
36665
- }).filter(function (dp) {
36666
- return dp.id;
36667
- });
36668
- }
36669
-
36670
36741
  // ---------------------------------------------------------------------------
36671
36742
  // Inline styles (injected once into the document head)
36672
36743
  // ---------------------------------------------------------------------------
@@ -37734,6 +37805,53 @@ function parseCrossBehavior(behavior) {
37734
37805
  };
37735
37806
  }
37736
37807
 
37808
+ /**
37809
+ * Resolve the runtime default value for an animation behavior entry.
37810
+ * Uses explicit `defaultValue` when present; otherwise infers from stateType and mappings.
37811
+ *
37812
+ * @param {Object} anim - Behavior entry from behaviorConfig
37813
+ * @returns {boolean|string|number}
37814
+ */
37815
+ function resolveAnimationDefaultValue(anim) {
37816
+ var _anim$stateConfig2, _anim$stateConfig3;
37817
+ if (!anim) return null;
37818
+ var rawType = (anim.stateType || '').toLowerCase();
37819
+ var isBinary = rawType === 'binary' || rawType === 'boolean';
37820
+ var isEnum = rawType === 'enum';
37821
+ if (anim.defaultValue !== undefined && anim.defaultValue !== null) {
37822
+ if (isBinary) return !!anim.defaultValue;
37823
+ if (isEnum) return String(anim.defaultValue);
37824
+ var n = Number(anim.defaultValue);
37825
+ return Number.isNaN(n) ? 0 : n;
37826
+ }
37827
+ if (isBinary) return false;
37828
+ if (isEnum) {
37829
+ var _anim$stateConfig, _resolved$;
37830
+ var _mappingValues = (anim.mappings || []).map(function (m) {
37831
+ return m.stateValue;
37832
+ }).filter(function (v) {
37833
+ return v !== '' && v != null;
37834
+ });
37835
+ var options = (((_anim$stateConfig = anim.stateConfig) === null || _anim$stateConfig === void 0 ? void 0 : _anim$stateConfig.options) || []).filter(function (o) {
37836
+ return o !== '';
37837
+ });
37838
+ var resolved = options.length ? options : _toConsumableArray(new Set(_mappingValues.map(String)));
37839
+ return (_resolved$ = resolved[0]) !== null && _resolved$ !== void 0 ? _resolved$ : '';
37840
+ }
37841
+ var mappingValues = (anim.mappings || []).map(function (m) {
37842
+ return m.stateValue;
37843
+ });
37844
+ var nums = mappingValues.map(Number).filter(function (n) {
37845
+ return !Number.isNaN(n);
37846
+ });
37847
+ if (nums.length) return Math.min.apply(Math, _toConsumableArray(nums));
37848
+ if (((_anim$stateConfig2 = anim.stateConfig) === null || _anim$stateConfig2 === void 0 ? void 0 : _anim$stateConfig2.min) !== undefined && ((_anim$stateConfig3 = anim.stateConfig) === null || _anim$stateConfig3 === void 0 ? void 0 : _anim$stateConfig3.min) !== null) {
37849
+ var min = Number(anim.stateConfig.min);
37850
+ return Number.isNaN(min) ? 0 : min;
37851
+ }
37852
+ return 0;
37853
+ }
37854
+
37737
37855
  /**
37738
37856
  * Translation helpers for I/O device animations.
37739
37857
  * Offsets are expressed in the device/model root's local space so every child
@@ -38377,18 +38495,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
38377
38495
  stateConfig.max = Math.max.apply(Math, _toConsumableArray(nums));
38378
38496
  }
38379
38497
  }
38380
-
38381
- // Sensible default values
38382
- var defaultValue = void 0;
38383
- if (stateType === 'binary') {
38384
- defaultValue = 0;
38385
- } else if (stateType === 'enum') {
38386
- var _stateConfig$options$, _stateConfig$options;
38387
- defaultValue = (_stateConfig$options$ = (_stateConfig$options = stateConfig.options) === null || _stateConfig$options === void 0 ? void 0 : _stateConfig$options[0]) !== null && _stateConfig$options$ !== void 0 ? _stateConfig$options$ : '';
38388
- } else {
38389
- var _stateConfig$min;
38390
- defaultValue = (_stateConfig$min = stateConfig.min) !== null && _stateConfig$min !== void 0 ? _stateConfig$min : 0;
38391
- }
38498
+ var defaultValue = resolveAnimationDefaultValue(_anim);
38392
38499
  dps.push({
38393
38500
  id: stateVar,
38394
38501
  name: _anim.name || stateVar,
@@ -39976,7 +40083,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
39976
40083
  }, {
39977
40084
  key: "addComponent",
39978
40085
  value: function addComponent(libraryId) {
39979
- var _this$centralPlant$sc6;
40086
+ var _this$centralPlant$sc6,
40087
+ _this2 = this;
39980
40088
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
39981
40089
  // Use centralized validation for component addition parameters
39982
40090
  var existingIds = this.getComponentIds();
@@ -40213,7 +40321,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
40213
40321
  var ioBehavMgr = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 || (_this$centralPlant$sc8 = _this$centralPlant$sc8.managers) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.ioBehaviorManager;
40214
40322
  attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId).then(function () {
40215
40323
  if (ioBehavMgr) {
40216
- registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary);
40324
+ registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary, _this2.centralPlant);
40217
40325
  }
40218
40326
  }).catch(function (err) {
40219
40327
  console.error("\u274C Error attaching IO devices for ".concat(libraryId, ":"), err);
@@ -40636,7 +40744,7 @@ function reregisterSceneBehaviors(centralPlant) {
40636
40744
  if (!libraryId) return;
40637
40745
  var componentData = dict[libraryId];
40638
40746
  if (!componentData) return;
40639
- registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict);
40747
+ registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict, centralPlant);
40640
40748
  });
40641
40749
  }
40642
40750
 
@@ -40666,7 +40774,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
40666
40774
  * Initialize the CentralPlant manager
40667
40775
  *
40668
40776
  * @constructor
40669
- * @version 0.3.41
40777
+ * @version 0.3.42
40670
40778
  * @updated 2025-10-22
40671
40779
  *
40672
40780
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -49344,6 +49452,7 @@ exports.SceneTooltipsManager = SceneTooltipsManager;
49344
49452
  exports.SnapshotManager = SnapshotManager;
49345
49453
  exports.ThreeJSResourceManager = ThreeJSResourceManager;
49346
49454
  exports.applyCrossComponentBehaviors = applyCrossComponentBehaviors;
49455
+ exports.applyDefaultIoDeviceStates = applyDefaultIoDeviceStates;
49347
49456
  exports.applyModelRootTranslation = applyModelRootTranslation;
49348
49457
  exports.applyModelRootTranslationFromWorldBase = applyModelRootTranslationFromWorldBase;
49349
49458
  exports.buildCrossBehavior = buildCrossBehavior;
@@ -49407,6 +49516,7 @@ exports.removeCachedJsonData = removeCachedJsonData;
49407
49516
  exports.reregisterSceneBehaviors = reregisterSceneBehaviors;
49408
49517
  exports.resetCacheIdentity = resetCacheIdentity;
49409
49518
  exports.resetGlobalCacheStats = resetGlobalCacheStats;
49519
+ exports.resolveAnimationDefaultValue = resolveAnimationDefaultValue;
49410
49520
  exports.resolveDataPoints = resolveDataPoints;
49411
49521
  exports.s3MetadataCache = s3MetadataCache;
49412
49522
  exports.scanSceneIoEndpoints = scanSceneIoEndpoints;
@@ -37,7 +37,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
37
37
  * Initialize the CentralPlant manager
38
38
  *
39
39
  * @constructor
40
- * @version 0.3.41
40
+ * @version 0.3.42
41
41
  * @updated 2025-10-22
42
42
  *
43
43
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -916,7 +916,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
916
916
  }, {
917
917
  key: "addComponent",
918
918
  value: function addComponent(libraryId) {
919
- var _this$centralPlant$sc6;
919
+ var _this$centralPlant$sc6,
920
+ _this2 = this;
920
921
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
921
922
  // Use centralized validation for component addition parameters
922
923
  var existingIds = this.getComponentIds();
@@ -1153,7 +1154,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1153
1154
  var ioBehavMgr = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 || (_this$centralPlant$sc8 = _this$centralPlant$sc8.managers) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.ioBehaviorManager;
1154
1155
  ioDeviceUtils.attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId).then(function () {
1155
1156
  if (ioBehavMgr) {
1156
- behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary);
1157
+ behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary, _this2.centralPlant);
1157
1158
  }
1158
1159
  }).catch(function (err) {
1159
1160
  console.error("\u274C Error attaching IO devices for ".concat(libraryId, ":"), err);
@@ -78,8 +78,10 @@ exports.buildIntraBehavior = behaviorSchema.buildIntraBehavior;
78
78
  exports.normalizeBehavior = behaviorSchema.normalizeBehavior;
79
79
  exports.parseCrossBehavior = behaviorSchema.parseCrossBehavior;
80
80
  exports.parseIntraBehavior = behaviorSchema.parseIntraBehavior;
81
+ exports.resolveAnimationDefaultValue = behaviorSchema.resolveAnimationDefaultValue;
81
82
  exports.registerBehaviorsForComponent = behaviorRegistration.registerBehaviorsForComponent;
82
83
  exports.reloadBehaviorsForDeviceAsset = behaviorRegistration.reloadBehaviorsForDeviceAsset;
84
+ exports.applyDefaultIoDeviceStates = behaviorDispatch.applyDefaultIoDeviceStates;
83
85
  exports.getIoBehaviorManager = behaviorDispatch.getIoBehaviorManager;
84
86
  exports.getScopedAttachmentKey = behaviorDispatch.getScopedAttachmentKey;
85
87
  exports.resolveDataPoints = behaviorDispatch.resolveDataPoints;
@@ -619,18 +619,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
619
619
  stateConfig.max = Math.max.apply(Math, _rollupPluginBabelHelpers.toConsumableArray(nums));
620
620
  }
621
621
  }
622
-
623
- // Sensible default values
624
- var defaultValue = void 0;
625
- if (stateType === 'binary') {
626
- defaultValue = 0;
627
- } else if (stateType === 'enum') {
628
- var _stateConfig$options$, _stateConfig$options;
629
- defaultValue = (_stateConfig$options$ = (_stateConfig$options = stateConfig.options) === null || _stateConfig$options === void 0 ? void 0 : _stateConfig$options[0]) !== null && _stateConfig$options$ !== void 0 ? _stateConfig$options$ : '';
630
- } else {
631
- var _stateConfig$min;
632
- defaultValue = (_stateConfig$min = stateConfig.min) !== null && _stateConfig$min !== void 0 ? _stateConfig$min : 0;
633
- }
622
+ var defaultValue = behaviorSchema.resolveAnimationDefaultValue(_anim);
634
623
  dps.push({
635
624
  id: stateVar,
636
625
  name: _anim.name || stateVar,
@@ -78,7 +78,7 @@ var ModelManager = /*#__PURE__*/function () {
78
78
  key: "loadLibraryModel",
79
79
  value: function () {
80
80
  var _loadLibraryModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
81
- var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, warmFn, _jsonEntry$userData4, _t;
81
+ var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, _this$sceneViewer2, warmFn, _jsonEntry$userData4, _t;
82
82
  return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
83
83
  while (1) switch (_context.n) {
84
84
  case 0:
@@ -123,7 +123,7 @@ var ModelManager = /*#__PURE__*/function () {
123
123
  case 4:
124
124
  ioBehavMgr = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.ioBehaviorManager;
125
125
  if (ioBehavMgr) {
126
- behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader["default"].componentDictionary);
126
+ behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader["default"].componentDictionary, (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.centralPlant);
127
127
  }
128
128
  case 5:
129
129
  // Replace mesh in scene
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
+
5
7
  /**
6
8
  * Shared I/O device state dispatch helpers used by centralPlant and componentTooltipManager.
7
9
  */
@@ -57,6 +59,68 @@ function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager
57
59
  });
58
60
  }
59
61
 
62
+ /**
63
+ * Apply persisted default values for I/O device animation states in the live scene.
64
+ * Updates the state adapter (e.g. Vuex) and drives mesh animations via IoBehaviorManager.
65
+ *
66
+ * @param {Object} centralPlant
67
+ * @param {{ parentUuid?: string, attachmentId?: string }} [options]
68
+ */
69
+ function applyDefaultIoDeviceStates(centralPlant) {
70
+ var _centralPlant$sceneVi;
71
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
72
+ var parentUuid = options.parentUuid,
73
+ attachmentId = options.attachmentId;
74
+ var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
75
+ var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
76
+ if (!ioBehavMgr || !scene || typeof (centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.setIoDeviceState) !== 'function') return;
77
+ var seen = new Set();
78
+ scene.traverse(function (obj) {
79
+ var _obj$userData, _obj$parent;
80
+ if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) !== 'io-device') return;
81
+ var objParentUuid = obj.userData.parentComponentId || ((_obj$parent = obj.parent) === null || _obj$parent === void 0 ? void 0 : _obj$parent.uuid);
82
+ var objAttachmentId = obj.userData.attachmentId;
83
+ if (!objParentUuid || !objAttachmentId) return;
84
+ if (parentUuid && objParentUuid !== parentUuid) return;
85
+ if (attachmentId && objAttachmentId !== attachmentId) return;
86
+ var scopedKey = getScopedAttachmentKey(objAttachmentId, objParentUuid);
87
+ if (seen.has(scopedKey)) return;
88
+ seen.add(scopedKey);
89
+ var dps = ioBehavMgr.getAnimationDataPoints(objParentUuid, objAttachmentId) || [];
90
+ if (dps.length) {
91
+ var _iterator = _rollupPluginBabelHelpers.createForOfIteratorHelper(dps),
92
+ _step;
93
+ try {
94
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
95
+ var dp = _step.value;
96
+ if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
97
+ centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
98
+ }
99
+ } catch (err) {
100
+ _iterator.e(err);
101
+ } finally {
102
+ _iterator.f();
103
+ }
104
+ return;
105
+ }
106
+ var _iterator2 = _rollupPluginBabelHelpers.createForOfIteratorHelper(obj.userData.dataPoints || []),
107
+ _step2;
108
+ try {
109
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
110
+ var _dp = _step2.value;
111
+ var dpId = _dp.id || _dp.name;
112
+ if (!dpId || _dp.defaultValue === undefined || _dp.defaultValue === null) continue;
113
+ centralPlant.setIoDeviceState(objAttachmentId, dpId, _dp.defaultValue, objParentUuid);
114
+ }
115
+ } catch (err) {
116
+ _iterator2.e(err);
117
+ } finally {
118
+ _iterator2.f();
119
+ }
120
+ });
121
+ }
122
+
123
+ exports.applyDefaultIoDeviceStates = applyDefaultIoDeviceStates;
60
124
  exports.getIoBehaviorManager = getIoBehaviorManager;
61
125
  exports.getScopedAttachmentKey = getScopedAttachmentKey;
62
126
  exports.resolveDataPoints = resolveDataPoints;
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
+ var behaviorDispatch = require('./behaviorDispatch.js');
6
7
 
7
8
  /**
8
9
  * Register mesh animations and intra-component state links when a smart
@@ -13,8 +14,9 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
14
  * @param {Object} componentData - Smart component dictionary entry
14
15
  * @param {Object} componentModel - Root THREE.Object3D of the placed component
15
16
  * @param {Object} componentDictionary - modelPreloader.componentDictionary
17
+ * @param {Object} [centralPlant] - When provided, default animation states are applied after registration
16
18
  */
17
- function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary) {
19
+ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary, centralPlant) {
18
20
  var _componentData$behavi;
19
21
  if (!ioBehavMgr || !componentData || !componentModel) {
20
22
  return;
@@ -44,6 +46,11 @@ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData,
44
46
  } else if (componentData.isSmart) {
45
47
  ioBehavMgr.registerComponentBehaviors(componentUuid, []);
46
48
  }
49
+ if (centralPlant) {
50
+ behaviorDispatch.applyDefaultIoDeviceStates(centralPlant, {
51
+ parentUuid: componentUuid
52
+ });
53
+ }
47
54
  }
48
55
 
49
56
  /**
@@ -69,6 +76,10 @@ function reloadBehaviorsForDeviceAsset(ioBehavMgr, deviceAssetId, componentDicti
69
76
  if (!parentUuid || !attachmentId) return;
70
77
  ioBehavMgr.unloadForAttachment(parentUuid, attachmentId);
71
78
  ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, obj, parentUuid);
79
+ behaviorDispatch.applyDefaultIoDeviceStates(centralPlant, {
80
+ parentUuid: parentUuid,
81
+ attachmentId: attachmentId
82
+ });
72
83
  });
73
84
  }
74
85
 
@@ -144,7 +144,7 @@ function reregisterSceneBehaviors(centralPlant) {
144
144
  if (!libraryId) return;
145
145
  var componentData = dict[libraryId];
146
146
  if (!componentData) return;
147
- behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict);
147
+ behaviorRegistration.registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict, centralPlant);
148
148
  });
149
149
  }
150
150
 
@@ -202,8 +202,56 @@ function parseCrossBehavior(behavior) {
202
202
  };
203
203
  }
204
204
 
205
+ /**
206
+ * Resolve the runtime default value for an animation behavior entry.
207
+ * Uses explicit `defaultValue` when present; otherwise infers from stateType and mappings.
208
+ *
209
+ * @param {Object} anim - Behavior entry from behaviorConfig
210
+ * @returns {boolean|string|number}
211
+ */
212
+ function resolveAnimationDefaultValue(anim) {
213
+ var _anim$stateConfig2, _anim$stateConfig3;
214
+ if (!anim) return null;
215
+ var rawType = (anim.stateType || '').toLowerCase();
216
+ var isBinary = rawType === 'binary' || rawType === 'boolean';
217
+ var isEnum = rawType === 'enum';
218
+ if (anim.defaultValue !== undefined && anim.defaultValue !== null) {
219
+ if (isBinary) return !!anim.defaultValue;
220
+ if (isEnum) return String(anim.defaultValue);
221
+ var n = Number(anim.defaultValue);
222
+ return Number.isNaN(n) ? 0 : n;
223
+ }
224
+ if (isBinary) return false;
225
+ if (isEnum) {
226
+ var _anim$stateConfig, _resolved$;
227
+ var _mappingValues = (anim.mappings || []).map(function (m) {
228
+ return m.stateValue;
229
+ }).filter(function (v) {
230
+ return v !== '' && v != null;
231
+ });
232
+ var options = (((_anim$stateConfig = anim.stateConfig) === null || _anim$stateConfig === void 0 ? void 0 : _anim$stateConfig.options) || []).filter(function (o) {
233
+ return o !== '';
234
+ });
235
+ var resolved = options.length ? options : _rollupPluginBabelHelpers.toConsumableArray(new Set(_mappingValues.map(String)));
236
+ return (_resolved$ = resolved[0]) !== null && _resolved$ !== void 0 ? _resolved$ : '';
237
+ }
238
+ var mappingValues = (anim.mappings || []).map(function (m) {
239
+ return m.stateValue;
240
+ });
241
+ var nums = mappingValues.map(Number).filter(function (n) {
242
+ return !Number.isNaN(n);
243
+ });
244
+ if (nums.length) return Math.min.apply(Math, _rollupPluginBabelHelpers.toConsumableArray(nums));
245
+ if (((_anim$stateConfig2 = anim.stateConfig) === null || _anim$stateConfig2 === void 0 ? void 0 : _anim$stateConfig2.min) !== undefined && ((_anim$stateConfig3 = anim.stateConfig) === null || _anim$stateConfig3 === void 0 ? void 0 : _anim$stateConfig3.min) !== null) {
246
+ var min = Number(anim.stateConfig.min);
247
+ return Number.isNaN(min) ? 0 : min;
248
+ }
249
+ return 0;
250
+ }
251
+
205
252
  exports.buildCrossBehavior = buildCrossBehavior;
206
253
  exports.buildIntraBehavior = buildIntraBehavior;
207
254
  exports.normalizeBehavior = normalizeBehavior;
208
255
  exports.parseCrossBehavior = parseCrossBehavior;
209
256
  exports.parseIntraBehavior = parseIntraBehavior;
257
+ exports.resolveAnimationDefaultValue = resolveAnimationDefaultValue;
@@ -33,7 +33,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
33
33
  * Initialize the CentralPlant manager
34
34
  *
35
35
  * @constructor
36
- * @version 0.3.41
36
+ * @version 0.3.42
37
37
  * @updated 2025-10-22
38
38
  *
39
39
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -892,7 +892,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
892
892
  }, {
893
893
  key: "addComponent",
894
894
  value: function addComponent(libraryId) {
895
- var _this$centralPlant$sc6;
895
+ var _this$centralPlant$sc6,
896
+ _this2 = this;
896
897
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
897
898
  // Use centralized validation for component addition parameters
898
899
  var existingIds = this.getComponentIds();
@@ -1129,7 +1130,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1129
1130
  var ioBehavMgr = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 || (_this$centralPlant$sc8 = _this$centralPlant$sc8.managers) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.ioBehaviorManager;
1130
1131
  attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId).then(function () {
1131
1132
  if (ioBehavMgr) {
1132
- registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary);
1133
+ registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary, _this2.centralPlant);
1133
1134
  }
1134
1135
  }).catch(function (err) {
1135
1136
  console.error("\u274C Error attaching IO devices for ".concat(libraryId, ":"), err);
@@ -10,9 +10,9 @@ export { SceneTooltipsManager } from './managers/scene/sceneTooltipsManager.js';
10
10
  export { ComponentTooltipManager } from './managers/scene/componentTooltipManager.js';
11
11
  export { SceneHierarchyManager } from './managers/scene/sceneHierarchyManager.js';
12
12
  export { IoBehaviorManager } from './managers/behaviors/IoBehaviorManager.js';
13
- export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior } from './utils/behaviorSchema.js';
13
+ export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior, resolveAnimationDefaultValue } from './utils/behaviorSchema.js';
14
14
  export { registerBehaviorsForComponent, reloadBehaviorsForDeviceAsset } from './utils/behaviorRegistration.js';
15
- export { getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints } from './utils/behaviorDispatch.js';
15
+ export { applyDefaultIoDeviceStates, getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints } from './utils/behaviorDispatch.js';
16
16
  export { applyCrossComponentBehaviors, loadCrossComponentBehaviors, refreshSceneIntraBehaviors, reregisterSceneBehaviors, scanSceneIoEndpoints } from './utils/behaviorSceneUtils.js';
17
17
  export { applyModelRootTranslation, applyModelRootTranslationFromWorldBase, modelOffsetToWorldDelta } from './utils/animationTransformUtils.js';
18
18
  export { ComponentManager } from './managers/components/componentManager.js';
@@ -1,7 +1,7 @@
1
1
  import { inherits as _inherits, createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray, superPropGet as _superPropGet, classCallCheck as _classCallCheck, callSuper as _callSuper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
2
  import * as THREE from 'three';
3
3
  import { BaseDisposable } from '../../core/baseDisposable.js';
4
- import { normalizeBehavior } from '../../utils/behaviorSchema.js';
4
+ import { normalizeBehavior, resolveAnimationDefaultValue } from '../../utils/behaviorSchema.js';
5
5
  import { getScopedAttachmentKey } from '../../utils/behaviorDispatch.js';
6
6
  import { applyModelRootTranslation } from '../../utils/animationTransformUtils.js';
7
7
 
@@ -595,18 +595,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
595
595
  stateConfig.max = Math.max.apply(Math, _toConsumableArray(nums));
596
596
  }
597
597
  }
598
-
599
- // Sensible default values
600
- var defaultValue = void 0;
601
- if (stateType === 'binary') {
602
- defaultValue = 0;
603
- } else if (stateType === 'enum') {
604
- var _stateConfig$options$, _stateConfig$options;
605
- defaultValue = (_stateConfig$options$ = (_stateConfig$options = stateConfig.options) === null || _stateConfig$options === void 0 ? void 0 : _stateConfig$options[0]) !== null && _stateConfig$options$ !== void 0 ? _stateConfig$options$ : '';
606
- } else {
607
- var _stateConfig$min;
608
- defaultValue = (_stateConfig$min = stateConfig.min) !== null && _stateConfig$min !== void 0 ? _stateConfig$min : 0;
609
- }
598
+ var defaultValue = resolveAnimationDefaultValue(_anim);
610
599
  dps.push({
611
600
  id: stateVar,
612
601
  name: _anim.name || stateVar,
@@ -54,7 +54,7 @@ var ModelManager = /*#__PURE__*/function () {
54
54
  key: "loadLibraryModel",
55
55
  value: function () {
56
56
  var _loadLibraryModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
57
- var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, warmFn, _jsonEntry$userData4, _t;
57
+ var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, _this$sceneViewer2, warmFn, _jsonEntry$userData4, _t;
58
58
  return _regenerator().w(function (_context) {
59
59
  while (1) switch (_context.n) {
60
60
  case 0:
@@ -99,7 +99,7 @@ var ModelManager = /*#__PURE__*/function () {
99
99
  case 4:
100
100
  ioBehavMgr = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.ioBehaviorManager;
101
101
  if (ioBehavMgr) {
102
- registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary);
102
+ registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary, (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.centralPlant);
103
103
  }
104
104
  case 5:
105
105
  // Replace mesh in scene
@@ -1,3 +1,5 @@
1
+ import { createForOfIteratorHelper as _createForOfIteratorHelper } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+
1
3
  /**
2
4
  * Shared I/O device state dispatch helpers used by centralPlant and componentTooltipManager.
3
5
  */
@@ -53,4 +55,65 @@ function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager
53
55
  });
54
56
  }
55
57
 
56
- export { getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints };
58
+ /**
59
+ * Apply persisted default values for I/O device animation states in the live scene.
60
+ * Updates the state adapter (e.g. Vuex) and drives mesh animations via IoBehaviorManager.
61
+ *
62
+ * @param {Object} centralPlant
63
+ * @param {{ parentUuid?: string, attachmentId?: string }} [options]
64
+ */
65
+ function applyDefaultIoDeviceStates(centralPlant) {
66
+ var _centralPlant$sceneVi;
67
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
68
+ var parentUuid = options.parentUuid,
69
+ attachmentId = options.attachmentId;
70
+ var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
71
+ var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
72
+ if (!ioBehavMgr || !scene || typeof (centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.setIoDeviceState) !== 'function') return;
73
+ var seen = new Set();
74
+ scene.traverse(function (obj) {
75
+ var _obj$userData, _obj$parent;
76
+ if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) !== 'io-device') return;
77
+ var objParentUuid = obj.userData.parentComponentId || ((_obj$parent = obj.parent) === null || _obj$parent === void 0 ? void 0 : _obj$parent.uuid);
78
+ var objAttachmentId = obj.userData.attachmentId;
79
+ if (!objParentUuid || !objAttachmentId) return;
80
+ if (parentUuid && objParentUuid !== parentUuid) return;
81
+ if (attachmentId && objAttachmentId !== attachmentId) return;
82
+ var scopedKey = getScopedAttachmentKey(objAttachmentId, objParentUuid);
83
+ if (seen.has(scopedKey)) return;
84
+ seen.add(scopedKey);
85
+ var dps = ioBehavMgr.getAnimationDataPoints(objParentUuid, objAttachmentId) || [];
86
+ if (dps.length) {
87
+ var _iterator = _createForOfIteratorHelper(dps),
88
+ _step;
89
+ try {
90
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
91
+ var dp = _step.value;
92
+ if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
93
+ centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
94
+ }
95
+ } catch (err) {
96
+ _iterator.e(err);
97
+ } finally {
98
+ _iterator.f();
99
+ }
100
+ return;
101
+ }
102
+ var _iterator2 = _createForOfIteratorHelper(obj.userData.dataPoints || []),
103
+ _step2;
104
+ try {
105
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
106
+ var _dp = _step2.value;
107
+ var dpId = _dp.id || _dp.name;
108
+ if (!dpId || _dp.defaultValue === undefined || _dp.defaultValue === null) continue;
109
+ centralPlant.setIoDeviceState(objAttachmentId, dpId, _dp.defaultValue, objParentUuid);
110
+ }
111
+ } catch (err) {
112
+ _iterator2.e(err);
113
+ } finally {
114
+ _iterator2.f();
115
+ }
116
+ });
117
+ }
118
+
119
+ export { applyDefaultIoDeviceStates, getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints };
@@ -1,4 +1,5 @@
1
1
  import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { applyDefaultIoDeviceStates } from './behaviorDispatch.js';
2
3
 
3
4
  /**
4
5
  * Register mesh animations and intra-component state links when a smart
@@ -9,8 +10,9 @@ import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBab
9
10
  * @param {Object} componentData - Smart component dictionary entry
10
11
  * @param {Object} componentModel - Root THREE.Object3D of the placed component
11
12
  * @param {Object} componentDictionary - modelPreloader.componentDictionary
13
+ * @param {Object} [centralPlant] - When provided, default animation states are applied after registration
12
14
  */
13
- function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary) {
15
+ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary, centralPlant) {
14
16
  var _componentData$behavi;
15
17
  if (!ioBehavMgr || !componentData || !componentModel) {
16
18
  return;
@@ -40,6 +42,11 @@ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData,
40
42
  } else if (componentData.isSmart) {
41
43
  ioBehavMgr.registerComponentBehaviors(componentUuid, []);
42
44
  }
45
+ if (centralPlant) {
46
+ applyDefaultIoDeviceStates(centralPlant, {
47
+ parentUuid: componentUuid
48
+ });
49
+ }
43
50
  }
44
51
 
45
52
  /**
@@ -65,6 +72,10 @@ function reloadBehaviorsForDeviceAsset(ioBehavMgr, deviceAssetId, componentDicti
65
72
  if (!parentUuid || !attachmentId) return;
66
73
  ioBehavMgr.unloadForAttachment(parentUuid, attachmentId);
67
74
  ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, obj, parentUuid);
75
+ applyDefaultIoDeviceStates(centralPlant, {
76
+ parentUuid: parentUuid,
77
+ attachmentId: attachmentId
78
+ });
68
79
  });
69
80
  }
70
81
 
@@ -140,7 +140,7 @@ function reregisterSceneBehaviors(centralPlant) {
140
140
  if (!libraryId) return;
141
141
  var componentData = dict[libraryId];
142
142
  if (!componentData) return;
143
- registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict);
143
+ registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict, centralPlant);
144
144
  });
145
145
  }
146
146
 
@@ -1,4 +1,4 @@
1
- import { objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
1
+ import { objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, typeof as _typeof, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
2
 
3
3
  /**
4
4
  * Shared behavior schema helpers for runtime normalization and UI authoring.
@@ -198,4 +198,51 @@ function parseCrossBehavior(behavior) {
198
198
  };
199
199
  }
200
200
 
201
- export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior };
201
+ /**
202
+ * Resolve the runtime default value for an animation behavior entry.
203
+ * Uses explicit `defaultValue` when present; otherwise infers from stateType and mappings.
204
+ *
205
+ * @param {Object} anim - Behavior entry from behaviorConfig
206
+ * @returns {boolean|string|number}
207
+ */
208
+ function resolveAnimationDefaultValue(anim) {
209
+ var _anim$stateConfig2, _anim$stateConfig3;
210
+ if (!anim) return null;
211
+ var rawType = (anim.stateType || '').toLowerCase();
212
+ var isBinary = rawType === 'binary' || rawType === 'boolean';
213
+ var isEnum = rawType === 'enum';
214
+ if (anim.defaultValue !== undefined && anim.defaultValue !== null) {
215
+ if (isBinary) return !!anim.defaultValue;
216
+ if (isEnum) return String(anim.defaultValue);
217
+ var n = Number(anim.defaultValue);
218
+ return Number.isNaN(n) ? 0 : n;
219
+ }
220
+ if (isBinary) return false;
221
+ if (isEnum) {
222
+ var _anim$stateConfig, _resolved$;
223
+ var _mappingValues = (anim.mappings || []).map(function (m) {
224
+ return m.stateValue;
225
+ }).filter(function (v) {
226
+ return v !== '' && v != null;
227
+ });
228
+ var options = (((_anim$stateConfig = anim.stateConfig) === null || _anim$stateConfig === void 0 ? void 0 : _anim$stateConfig.options) || []).filter(function (o) {
229
+ return o !== '';
230
+ });
231
+ var resolved = options.length ? options : _toConsumableArray(new Set(_mappingValues.map(String)));
232
+ return (_resolved$ = resolved[0]) !== null && _resolved$ !== void 0 ? _resolved$ : '';
233
+ }
234
+ var mappingValues = (anim.mappings || []).map(function (m) {
235
+ return m.stateValue;
236
+ });
237
+ var nums = mappingValues.map(Number).filter(function (n) {
238
+ return !Number.isNaN(n);
239
+ });
240
+ if (nums.length) return Math.min.apply(Math, _toConsumableArray(nums));
241
+ if (((_anim$stateConfig2 = anim.stateConfig) === null || _anim$stateConfig2 === void 0 ? void 0 : _anim$stateConfig2.min) !== undefined && ((_anim$stateConfig3 = anim.stateConfig) === null || _anim$stateConfig3 === void 0 ? void 0 : _anim$stateConfig3.min) !== null) {
242
+ var min = Number(anim.stateConfig.min);
243
+ return Number.isNaN(min) ? 0 : min;
244
+ }
245
+ return 0;
246
+ }
247
+
248
+ export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior, resolveAnimationDefaultValue };
package/dist/index.d.ts CHANGED
@@ -52,7 +52,10 @@ export interface BehaviorEntry {
52
52
  meshUuid?: string
53
53
  meshName?: string
54
54
  stateVariable: string
55
- stateType?: 'binary' | 'enum' | 'continuous' | 'number' | 'boolean'
55
+ stateType?: 'binary' | 'enum' | 'continuous' | 'number' | 'boolean' | 'range'
56
+ defaultValue?: boolean | string | number
57
+ useFormula?: boolean
58
+ stateConfig?: Record<string, unknown>
56
59
  transformTypes?: string[]
57
60
  rotAxis?: 'x' | 'y' | 'z'
58
61
  rotAxisOffset?: { x: number; y: number; z: number }
@@ -144,6 +147,7 @@ export declare function parseCrossBehavior(behavior: CrossComponentBehavior): {
144
147
  inputState: string
145
148
  outputs: Array<{ endpoint: string; state: string }>
146
149
  }
150
+ export declare function resolveAnimationDefaultValue(anim: BehaviorEntry): boolean | string | number | null
147
151
 
148
152
  export declare function getScopedAttachmentKey(attachmentId: string, parentUuid?: string | null): string
149
153
  export declare function getIoBehaviorManager(sceneViewer: any): IoBehaviorManager | null
@@ -160,7 +164,13 @@ export declare function registerBehaviorsForComponent(
160
164
  componentUuid: string,
161
165
  componentData: SmartComponentAsset,
162
166
  componentModel: any,
163
- componentDictionary: Record<string, any>
167
+ componentDictionary: Record<string, any>,
168
+ centralPlant?: any
169
+ ): void
170
+
171
+ export declare function applyDefaultIoDeviceStates(
172
+ centralPlant: any,
173
+ options?: { parentUuid?: string; attachmentId?: string }
164
174
  ): void
165
175
 
166
176
  export declare function reloadBehaviorsForDeviceAsset(
@@ -307,7 +317,8 @@ export {
307
317
  buildIntraBehavior,
308
318
  parseIntraBehavior,
309
319
  buildCrossBehavior,
310
- parseCrossBehavior
320
+ parseCrossBehavior,
321
+ resolveAnimationDefaultValue
311
322
  } from './utils/behaviorSchema.js';
312
323
  export {
313
324
  registerBehaviorsForComponent,
@@ -316,7 +327,8 @@ export {
316
327
  export {
317
328
  getScopedAttachmentKey,
318
329
  getIoBehaviorManager,
319
- resolveDataPoints
330
+ resolveDataPoints,
331
+ applyDefaultIoDeviceStates
320
332
  } from './utils/behaviorDispatch.js';
321
333
  export {
322
334
  scanSceneIoEndpoints,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.41",
3
+ "version": "0.3.42",
4
4
  "description": "Utility modules for the Central Plant Application",
5
5
  "main": "dist/bundle/index.js",
6
6
  "module": "dist/esm/src/index.js",