@crystaldesign/web-planner-logic 26.13.0-beta.9 → 26.14.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/build/cjs/{DivaBoxPlanner-006ec070.js → DivaBoxPlanner-7f6bd584.js} +5 -4
  2. package/build/cjs/{DivaStandardPlanner-a428fcb7.js → DivaStandardPlanner-77c603dc.js} +1921 -203
  3. package/build/cjs/{DoorPlanner-40b303c4.js → DoorPlanner-5de2bbf0.js} +4 -3
  4. package/build/cjs/{Host3DSignalR-55f69ca3.js → Host3DSignalR-26b95303.js} +64 -20
  5. package/build/cjs/{LiviqueWWSHandler-4c6f6071.js → LiviqueWWSHandler-1e419862.js} +4 -3
  6. package/build/cjs/{PfisterWWSHandler-55bdb575.js → PfisterWWSHandler-b2f7a5ec.js} +3 -2
  7. package/build/cjs/{PlannerHandler2D-314ce41d.js → PlannerHandler2D-ff734c3e.js} +10 -10
  8. package/build/cjs/{SeriousBasketHandler-1b365a2b.js → SeriousBasketHandler-e54bd31b.js} +4 -3
  9. package/build/cjs/{ShelfPlanner-8e91f830.js → ShelfPlanner-08e15d16.js} +600 -203
  10. package/build/cjs/{StandardWWSHandler-4a2442aa.js → StandardWWSHandler-0e7b20dc.js} +4 -3
  11. package/build/cjs/{index-e08a4789.js → index-5dd5fb4b.js} +9343 -3810
  12. package/build/cjs/index.js +11 -9
  13. package/build/esm/{DivaBoxPlanner-edb41fff.js → DivaBoxPlanner-6ac448b4.js} +5 -4
  14. package/build/esm/{DivaStandardPlanner-20fe9ebf.js → DivaStandardPlanner-abd9609d.js} +1911 -194
  15. package/build/esm/{DoorPlanner-0bf17f1f.js → DoorPlanner-fde32e61.js} +4 -3
  16. package/build/esm/{Host3DSignalR-263f6d3f.js → Host3DSignalR-0f97c7f3.js} +64 -20
  17. package/build/esm/{LiviqueWWSHandler-e80b574f.js → LiviqueWWSHandler-9ee5b7cb.js} +4 -3
  18. package/build/esm/{PfisterWWSHandler-508bb12f.js → PfisterWWSHandler-b9699549.js} +3 -2
  19. package/build/esm/{PlannerHandler2D-e4d80c41.js → PlannerHandler2D-8d963e77.js} +2 -2
  20. package/build/esm/{SeriousBasketHandler-e9ebb195.js → SeriousBasketHandler-40e7e46c.js} +4 -3
  21. package/build/esm/{ShelfPlanner-fbb7d7dd.js → ShelfPlanner-69cbb2c1.js} +600 -203
  22. package/build/esm/{StandardWWSHandler-88f4eb7d.js → StandardWWSHandler-dbf02663.js} +4 -3
  23. package/build/esm/{index-86463de2.js → index-88148ccc.js} +9297 -3798
  24. package/build/esm/index.js +4 -3
  25. package/build/types/web-planner-logic/src/index.d.ts +7 -8
  26. package/build/types/web-planner-logic/src/index.d.ts.map +1 -1
  27. package/build/types/web-planner-logic/src/interface/AdditionalModelInfos.d.ts +4 -2
  28. package/build/types/web-planner-logic/src/interface/AdditionalModelInfos.d.ts.map +1 -1
  29. package/build/types/web-planner-logic/src/interface/Articles/AccessoireItemType.d.ts +6 -2
  30. package/build/types/web-planner-logic/src/interface/Articles/AccessoireItemType.d.ts.map +1 -1
  31. package/build/types/web-planner-logic/src/interface/Articles/CatalogArticleDataType.d.ts +14 -0
  32. package/build/types/web-planner-logic/src/interface/Articles/CatalogArticleDataType.d.ts.map +1 -1
  33. package/build/types/web-planner-logic/src/interface/Articles/PartListArticleToLoadType.d.ts +1 -0
  34. package/build/types/web-planner-logic/src/interface/Articles/PartListArticleToLoadType.d.ts.map +1 -1
  35. package/build/types/web-planner-logic/src/interface/DivaCatalogDataType.d.ts +7 -0
  36. package/build/types/web-planner-logic/src/interface/DivaCatalogDataType.d.ts.map +1 -1
  37. package/build/types/web-planner-logic/src/interface/FunctionTypes/index.d.ts +16 -1
  38. package/build/types/web-planner-logic/src/interface/FunctionTypes/index.d.ts.map +1 -1
  39. package/build/types/web-planner-logic/src/interface/IDM/ArticleApi.d.ts +2 -3
  40. package/build/types/web-planner-logic/src/interface/IDM/ArticleApi.d.ts.map +1 -1
  41. package/build/types/web-planner-logic/src/interface/OptionTypes/CatalogOptionDataTypes.d.ts +10 -0
  42. package/build/types/web-planner-logic/src/interface/OptionTypes/CatalogOptionDataTypes.d.ts.map +1 -1
  43. package/build/types/web-planner-logic/src/interface/Planner/IDM3DTranslation.d.ts +20 -0
  44. package/build/types/web-planner-logic/src/interface/Planner/IDM3DTranslation.d.ts.map +1 -0
  45. package/build/types/web-planner-logic/src/interface/Planner/ISaveSetPlanner.d.ts +10 -0
  46. package/build/types/web-planner-logic/src/interface/Planner/ISaveSetPlanner.d.ts.map +1 -1
  47. package/build/types/web-planner-logic/src/interface/Planner/RoomSceneTypes.d.ts +76 -0
  48. package/build/types/web-planner-logic/src/interface/Planner/RoomSceneTypes.d.ts.map +1 -0
  49. package/build/types/web-planner-logic/src/interface/Rendering/AlternativeRendering.d.ts +4 -0
  50. package/build/types/web-planner-logic/src/interface/Rendering/AlternativeRendering.d.ts.map +1 -1
  51. package/build/types/web-planner-logic/src/interface/ShelfPlanner/ShelfAccessoiresView.d.ts +5 -0
  52. package/build/types/web-planner-logic/src/interface/ShelfPlanner/ShelfAccessoiresView.d.ts.map +1 -1
  53. package/build/types/web-planner-logic/src/interface/ShelfPlanner/plannerData.d.ts +3 -0
  54. package/build/types/web-planner-logic/src/interface/ShelfPlanner/plannerData.d.ts.map +1 -1
  55. package/build/types/web-planner-logic/src/interface/webPlannerParams/WebPlannerParamsType.d.ts +1 -1
  56. package/build/types/web-planner-logic/src/interface/webPlannerParams/WebPlannerParamsType.d.ts.map +1 -1
  57. package/build/types/web-planner-logic/src/logic/Article/ArticleOptionState.d.ts.map +1 -1
  58. package/build/types/web-planner-logic/src/logic/Article/DivaArticle.d.ts +30 -0
  59. package/build/types/web-planner-logic/src/logic/Article/DivaArticle.d.ts.map +1 -1
  60. package/build/types/web-planner-logic/src/logic/Article/DivaArticleHandler.d.ts +5 -0
  61. package/build/types/web-planner-logic/src/logic/Article/DivaArticleHandler.d.ts.map +1 -1
  62. package/build/types/web-planner-logic/src/logic/Article/Engine/IDMArticleEngine.d.ts +8 -0
  63. package/build/types/web-planner-logic/src/logic/Article/Engine/IDMArticleEngine.d.ts.map +1 -1
  64. package/build/types/web-planner-logic/src/logic/Article/mandatoryAccessories.d.ts +3 -1
  65. package/build/types/web-planner-logic/src/logic/Article/mandatoryAccessories.d.ts.map +1 -1
  66. package/build/types/web-planner-logic/src/logic/Article/measureUnit.d.ts +2 -0
  67. package/build/types/web-planner-logic/src/logic/Article/measureUnit.d.ts.map +1 -1
  68. package/build/types/web-planner-logic/src/logic/Basket/DivaBasketHandler.d.ts.map +1 -1
  69. package/build/types/web-planner-logic/src/logic/ConfigTree/DivaConfigTree.d.ts.map +1 -1
  70. package/build/types/web-planner-logic/src/logic/ConfigTree/DivaConfigTreeHandler.d.ts +7 -0
  71. package/build/types/web-planner-logic/src/logic/ConfigTree/DivaConfigTreeHandler.d.ts.map +1 -1
  72. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlanner.d.ts +77 -7
  73. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlanner.d.ts.map +1 -1
  74. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlannerGrid.d.ts +14 -2
  75. package/build/types/web-planner-logic/src/logic/ConfigTree/Shelfplanner/ShelfPlannerGrid.d.ts.map +1 -1
  76. package/build/types/web-planner-logic/src/logic/ConfigTree/viewerStateToggles.d.ts +19 -0
  77. package/build/types/web-planner-logic/src/logic/ConfigTree/viewerStateToggles.d.ts.map +1 -0
  78. package/build/types/web-planner-logic/src/logic/ConfigTree/viewerStateToggles.test.d.ts +2 -0
  79. package/build/types/web-planner-logic/src/logic/ConfigTree/viewerStateToggles.test.d.ts.map +1 -0
  80. package/build/types/web-planner-logic/src/logic/DivaWebPlanner.d.ts +112 -24
  81. package/build/types/web-planner-logic/src/logic/DivaWebPlanner.d.ts.map +1 -1
  82. package/build/types/web-planner-logic/src/logic/Planner/DivaPlannerHandler.d.ts +74 -9
  83. package/build/types/web-planner-logic/src/logic/Planner/DivaPlannerHandler.d.ts.map +1 -1
  84. package/build/types/web-planner-logic/src/logic/Planner/DivaStandardPlanner.d.ts +175 -4
  85. package/build/types/web-planner-logic/src/logic/Planner/DivaStandardPlanner.d.ts.map +1 -1
  86. package/build/types/web-planner-logic/src/logic/Planner/IDM3D/idm3dTranslation.d.ts +32 -0
  87. package/build/types/web-planner-logic/src/logic/Planner/IDM3D/idm3dTranslation.d.ts.map +1 -0
  88. package/build/types/web-planner-logic/src/logic/Planner/IDM3D/idm3dTranslation.test.d.ts +2 -0
  89. package/build/types/web-planner-logic/src/logic/Planner/IDM3D/idm3dTranslation.test.d.ts.map +1 -0
  90. package/build/types/web-planner-logic/src/logic/Planner/Placement/carrierGuests.d.ts +75 -0
  91. package/build/types/web-planner-logic/src/logic/Planner/Placement/carrierGuests.d.ts.map +1 -0
  92. package/build/types/web-planner-logic/src/logic/Planner/Placement/guestPlacement.d.ts +47 -0
  93. package/build/types/web-planner-logic/src/logic/Planner/Placement/guestPlacement.d.ts.map +1 -0
  94. package/build/types/web-planner-logic/src/logic/Planner/Placement/guestPlacement.test.d.ts +2 -0
  95. package/build/types/web-planner-logic/src/logic/Planner/Placement/guestPlacement.test.d.ts.map +1 -0
  96. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementDefaults.d.ts +9 -0
  97. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementDefaults.d.ts.map +1 -0
  98. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementRules.d.ts +78 -0
  99. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementRules.d.ts.map +1 -0
  100. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementRules.test.d.ts +2 -0
  101. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementRules.test.d.ts.map +1 -0
  102. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementSlots.d.ts +81 -0
  103. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementSlots.d.ts.map +1 -0
  104. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementTypes.d.ts +13 -0
  105. package/build/types/web-planner-logic/src/logic/Planner/Placement/placementTypes.d.ts.map +1 -0
  106. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/DockingPointHandler.d.ts +1 -1
  107. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/DockingPointHandler.d.ts.map +1 -1
  108. package/build/types/web-planner-logic/src/logic/Planner/PlannerUtils/SVGUtils.d.ts +1 -1
  109. package/build/types/web-planner-logic/src/logic/Planner/Rendering/Host3DSignalR.d.ts +1 -0
  110. package/build/types/web-planner-logic/src/logic/Planner/Rendering/Host3DSignalR.d.ts.map +1 -1
  111. package/build/types/web-planner-logic/src/logic/Planner/Rendering/PlannerHandler3D.d.ts +13 -1
  112. package/build/types/web-planner-logic/src/logic/Planner/Rendering/PlannerHandler3D.d.ts.map +1 -1
  113. package/build/types/web-planner-logic/src/logic/Planner/Room/elementShapes.d.ts +56 -0
  114. package/build/types/web-planner-logic/src/logic/Planner/Room/elementShapes.d.ts.map +1 -0
  115. package/build/types/web-planner-logic/src/logic/Planner/Room/elementShapes.test.d.ts +2 -0
  116. package/build/types/web-planner-logic/src/logic/Planner/Room/elementShapes.test.d.ts.map +1 -0
  117. package/build/types/web-planner-logic/src/logic/Planner/Room/roomCollisions.d.ts +90 -0
  118. package/build/types/web-planner-logic/src/logic/Planner/Room/roomCollisions.d.ts.map +1 -0
  119. package/build/types/web-planner-logic/src/logic/Planner/Room/roomCollisions.test.d.ts +2 -0
  120. package/build/types/web-planner-logic/src/logic/Planner/Room/roomCollisions.test.d.ts.map +1 -0
  121. package/build/types/web-planner-logic/src/logic/Planner/Room/roomGroups.d.ts +32 -0
  122. package/build/types/web-planner-logic/src/logic/Planner/Room/roomGroups.d.ts.map +1 -0
  123. package/build/types/web-planner-logic/src/logic/Planner/Room/roomGroups.test.d.ts +2 -0
  124. package/build/types/web-planner-logic/src/logic/Planner/Room/roomGroups.test.d.ts.map +1 -0
  125. package/build/types/web-planner-logic/src/logic/Planner/Room/roomProperties.test.d.ts +2 -0
  126. package/build/types/web-planner-logic/src/logic/Planner/Room/roomProperties.test.d.ts.map +1 -0
  127. package/build/types/web-planner-logic/src/logic/Planner/Room/roomScenes.d.ts +21 -0
  128. package/build/types/web-planner-logic/src/logic/Planner/Room/roomScenes.d.ts.map +1 -0
  129. package/build/types/web-planner-logic/src/logic/Planner/Room/roomScenes.test.d.ts +2 -0
  130. package/build/types/web-planner-logic/src/logic/Planner/Room/roomScenes.test.d.ts.map +1 -0
  131. package/build/types/web-planner-logic/src/logic/Planner/Room/roomValidation.d.ts +13 -0
  132. package/build/types/web-planner-logic/src/logic/Planner/Room/roomValidation.d.ts.map +1 -0
  133. package/build/types/web-planner-logic/src/logic/Planner/Room/roomValidation.test.d.ts +2 -0
  134. package/build/types/web-planner-logic/src/logic/Planner/Room/roomValidation.test.d.ts.map +1 -0
  135. package/build/types/web-planner-logic/src/logic/Planner/Room/rtvFeatures.d.ts +17 -0
  136. package/build/types/web-planner-logic/src/logic/Planner/Room/rtvFeatures.d.ts.map +1 -0
  137. package/build/types/web-planner-logic/src/logic/Planner/Room/rtvFeatures.test.d.ts +2 -0
  138. package/build/types/web-planner-logic/src/logic/Planner/Room/rtvFeatures.test.d.ts.map +1 -0
  139. package/build/types/web-planner-logic/src/logic/Planner/Room/wallBinding.d.ts +72 -0
  140. package/build/types/web-planner-logic/src/logic/Planner/Room/wallBinding.d.ts.map +1 -0
  141. package/build/types/web-planner-logic/src/logic/Planner/Room/wallBinding.test.d.ts +2 -0
  142. package/build/types/web-planner-logic/src/logic/Planner/Room/wallBinding.test.d.ts.map +1 -0
  143. package/build/types/web-planner-logic/src/logic/Planner/Room/wallMode.d.ts +7 -0
  144. package/build/types/web-planner-logic/src/logic/Planner/Room/wallMode.d.ts.map +1 -0
  145. package/build/types/web-planner-logic/src/logic/Planner/plannerSwitch.d.ts +32 -0
  146. package/build/types/web-planner-logic/src/logic/Planner/plannerSwitch.d.ts.map +1 -0
  147. package/build/types/web-planner-logic/src/logic/Planner/plannerSwitch.test.d.ts +2 -0
  148. package/build/types/web-planner-logic/src/logic/Planner/plannerSwitch.test.d.ts.map +1 -0
  149. package/build/types/web-planner-logic/src/logic/Set/DivaSet.d.ts +12 -6
  150. package/build/types/web-planner-logic/src/logic/Set/DivaSet.d.ts.map +1 -1
  151. package/build/types/web-planner-logic/src/logic/Set/DivaSetHandler.d.ts +30 -6
  152. package/build/types/web-planner-logic/src/logic/Set/DivaSetHandler.d.ts.map +1 -1
  153. package/build/types/web-planner-logic/src/model/Articles/Article/CatalogArticleData.d.ts +5 -0
  154. package/build/types/web-planner-logic/src/model/Articles/Article/CatalogArticleData.d.ts.map +1 -1
  155. package/build/types/web-planner-logic/src/model/Articles/Article/DivaCatalogArticle.d.ts.map +1 -1
  156. package/build/types/web-planner-logic/src/model/Articles/Article/IDMCatalogArticle.d.ts.map +1 -1
  157. package/build/types/web-planner-logic/src/model/Catalog/CatalogData.d.ts +28 -0
  158. package/build/types/web-planner-logic/src/model/Catalog/CatalogData.d.ts.map +1 -1
  159. package/build/types/web-planner-logic/src/model/Catalog/DivaCatalogData.d.ts +3 -0
  160. package/build/types/web-planner-logic/src/model/Catalog/DivaCatalogData.d.ts.map +1 -1
  161. package/build/types/web-planner-logic/src/model/Catalog/IDMCatalogData.d.ts +4 -2
  162. package/build/types/web-planner-logic/src/model/Catalog/IDMCatalogData.d.ts.map +1 -1
  163. package/build/types/web-planner-logic/src/model/Options/ArticleOptionData.d.ts +10 -0
  164. package/build/types/web-planner-logic/src/model/Options/ArticleOptionData.d.ts.map +1 -1
  165. package/build/types/web-planner-logic/src/model/Options/CatalogOptionData.d.ts +6 -4
  166. package/build/types/web-planner-logic/src/model/Options/CatalogOptionData.d.ts.map +1 -1
  167. package/build/types/web-planner-logic/src/model/Options/CatalogOptionValueData.d.ts.map +1 -1
  168. package/build/types/web-planner-logic/src/model/Planner/DockingPoint.d.ts +1 -1
  169. package/build/types/web-planner-logic/src/model/Planner/DockingPoint.d.ts.map +1 -1
  170. package/build/types/web-planner-logic/src/model/Planner/PlannerElementData.d.ts +41 -0
  171. package/build/types/web-planner-logic/src/model/Planner/PlannerElementData.d.ts.map +1 -1
  172. package/build/types/web-planner-logic/src/model/Properties/propertySchemaRegistry.d.ts +23 -11
  173. package/build/types/web-planner-logic/src/model/Properties/propertySchemaRegistry.d.ts.map +1 -1
  174. package/build/types/web-planner-logic/src/model/Properties/propertyValueCodec.d.ts +1 -34
  175. package/build/types/web-planner-logic/src/model/Properties/propertyValueCodec.d.ts.map +1 -1
  176. package/build/types/web-planner-logic/src/model/Properties/propertyValues.d.ts +42 -0
  177. package/build/types/web-planner-logic/src/model/Properties/propertyValues.d.ts.map +1 -0
  178. package/build/types/web-planner-logic/src/test/alternateRenderingToggle.test.d.ts +2 -0
  179. package/build/types/web-planner-logic/src/test/alternateRenderingToggle.test.d.ts.map +1 -0
  180. package/build/types/web-planner-logic/src/test/bundleRulesOwnPartlist.test.d.ts +2 -0
  181. package/build/types/web-planner-logic/src/test/bundleRulesOwnPartlist.test.d.ts.map +1 -0
  182. package/build/types/web-planner-logic/src/test/capturedSetImages.test.d.ts +1 -0
  183. package/build/types/web-planner-logic/src/test/capturedSetImages.test.d.ts.map +1 -1
  184. package/build/types/web-planner-logic/src/test/carrierGuests.test.d.ts +2 -0
  185. package/build/types/web-planner-logic/src/test/carrierGuests.test.d.ts.map +1 -0
  186. package/build/types/web-planner-logic/src/test/classificationRepairFreeText.test.d.ts +2 -0
  187. package/build/types/web-planner-logic/src/test/classificationRepairFreeText.test.d.ts.map +1 -0
  188. package/build/types/web-planner-logic/src/test/copyRestoreConnectors.test.d.ts +2 -0
  189. package/build/types/web-planner-logic/src/test/copyRestoreConnectors.test.d.ts.map +1 -0
  190. package/build/types/web-planner-logic/src/test/decisionFeatureRefOp.test.d.ts +2 -0
  191. package/build/types/web-planner-logic/src/test/decisionFeatureRefOp.test.d.ts.map +1 -0
  192. package/build/types/web-planner-logic/src/test/dragZones.test.d.ts +2 -0
  193. package/build/types/web-planner-logic/src/test/dragZones.test.d.ts.map +1 -0
  194. package/build/types/web-planner-logic/src/test/familySwapInPlace.test.d.ts +2 -0
  195. package/build/types/web-planner-logic/src/test/familySwapInPlace.test.d.ts.map +1 -0
  196. package/build/types/web-planner-logic/src/test/getConfigStepKeyOfAccessoire.test.d.ts +2 -0
  197. package/build/types/web-planner-logic/src/test/getConfigStepKeyOfAccessoire.test.d.ts.map +1 -0
  198. package/build/types/web-planner-logic/src/test/headlessRoomScenes.test.d.ts +2 -0
  199. package/build/types/web-planner-logic/src/test/headlessRoomScenes.test.d.ts.map +1 -0
  200. package/build/types/web-planner-logic/src/test/host3DSignalRReconnect.test.d.ts +2 -0
  201. package/build/types/web-planner-logic/src/test/host3DSignalRReconnect.test.d.ts.map +1 -0
  202. package/build/types/web-planner-logic/src/test/liveArUpdate.test.d.ts +2 -0
  203. package/build/types/web-planner-logic/src/test/liveArUpdate.test.d.ts.map +1 -0
  204. package/build/types/web-planner-logic/src/test/oltRectBody.test.d.ts +2 -0
  205. package/build/types/web-planner-logic/src/test/oltRectBody.test.d.ts.map +1 -0
  206. package/build/types/web-planner-logic/src/test/orderNumberTemplates.test.d.ts +2 -0
  207. package/build/types/web-planner-logic/src/test/orderNumberTemplates.test.d.ts.map +1 -0
  208. package/build/types/web-planner-logic/src/test/partlistChangeReevaluatesOptionTree.test.d.ts +2 -0
  209. package/build/types/web-planner-logic/src/test/partlistChangeReevaluatesOptionTree.test.d.ts.map +1 -0
  210. package/build/types/web-planner-logic/src/test/plannerElementHeightChange.test.d.ts +2 -0
  211. package/build/types/web-planner-logic/src/test/plannerElementHeightChange.test.d.ts.map +1 -0
  212. package/build/types/web-planner-logic/src/test/plannerHandler3DRoomListQueue.test.d.ts +2 -0
  213. package/build/types/web-planner-logic/src/test/plannerHandler3DRoomListQueue.test.d.ts.map +1 -0
  214. package/build/types/web-planner-logic/src/test/plannerRoomScenesSwitch.test.d.ts +2 -0
  215. package/build/types/web-planner-logic/src/test/plannerRoomScenesSwitch.test.d.ts.map +1 -0
  216. package/build/types/web-planner-logic/src/test/planning2DCapture.test.d.ts +2 -0
  217. package/build/types/web-planner-logic/src/test/planning2DCapture.test.d.ts.map +1 -0
  218. package/build/types/web-planner-logic/src/test/planningRoundTrip.test.d.ts +2 -0
  219. package/build/types/web-planner-logic/src/test/planningRoundTrip.test.d.ts.map +1 -0
  220. package/build/types/web-planner-logic/src/test/propertyParsers.test.d.ts +2 -0
  221. package/build/types/web-planner-logic/src/test/propertyParsers.test.d.ts.map +1 -0
  222. package/build/types/web-planner-logic/src/test/propertyValues.test.d.ts +2 -0
  223. package/build/types/web-planner-logic/src/test/propertyValues.test.d.ts.map +1 -0
  224. package/build/types/web-planner-logic/src/test/roomDragContact.test.d.ts +2 -0
  225. package/build/types/web-planner-logic/src/test/roomDragContact.test.d.ts.map +1 -0
  226. package/build/types/web-planner-logic/src/test/roomPlacement.test.d.ts +2 -0
  227. package/build/types/web-planner-logic/src/test/roomPlacement.test.d.ts.map +1 -0
  228. package/build/types/web-planner-logic/src/test/roomScenePlanning.test.d.ts +2 -0
  229. package/build/types/web-planner-logic/src/test/roomScenePlanning.test.d.ts.map +1 -0
  230. package/build/types/web-planner-logic/src/test/rotationSnap.test.d.ts +2 -0
  231. package/build/types/web-planner-logic/src/test/rotationSnap.test.d.ts.map +1 -0
  232. package/build/types/web-planner-logic/src/test/shelfEditNoting.test.d.ts +3 -0
  233. package/build/types/web-planner-logic/src/test/shelfEditNoting.test.d.ts.map +1 -0
  234. package/build/types/web-planner-logic/src/test/shelfGridCarryOver.test.d.ts +2 -0
  235. package/build/types/web-planner-logic/src/test/shelfGridCarryOver.test.d.ts.map +1 -0
  236. package/build/types/web-planner-logic/src/test/shelfMoveLocks.test.d.ts +2 -0
  237. package/build/types/web-planner-logic/src/test/shelfMoveLocks.test.d.ts.map +1 -0
  238. package/build/types/web-planner-logic/src/test/shelfOfferedCells.test.d.ts +2 -0
  239. package/build/types/web-planner-logic/src/test/shelfOfferedCells.test.d.ts.map +1 -0
  240. package/build/types/web-planner-logic/src/test/shelfStashInheritedOptions.test.d.ts +2 -0
  241. package/build/types/web-planner-logic/src/test/shelfStashInheritedOptions.test.d.ts.map +1 -0
  242. package/build/types/web-planner-logic/src/test/sideCopySubstitute.test.d.ts +3 -0
  243. package/build/types/web-planner-logic/src/test/sideCopySubstitute.test.d.ts.map +1 -0
  244. package/package.json +3 -3
@@ -1,18 +1,19 @@
1
- import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
2
1
  import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
2
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
3
3
  import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
4
4
  import _createClass from '@babel/runtime/helpers/createClass';
5
5
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
6
+ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
6
7
  import _regeneratorRuntime from '@babel/runtime/regenerator';
7
- import { V as Vector3, P as PlannerElementData, B as BoundingBox } from './index-86463de2.js';
8
+ import { V as Vector3, p as poseOf, g as getSnapPlace, c as getDockingGroups, d as getElementShape, e as getCarrierSlots, h as getSlotPlaces, m as moveGroupRigidly, i as isSamePose, j as getGroupBlock, k as fitsInsideRoom, l as keepInsideRoom, n as bindToWalls, o as sameGeoExtent, q as getCornerEnd, r as getDoorClearanceRects, t as rectCorners, u as Vector2, M as MAX_GUEST_DEPTH, v as slotExempt, w as bodiesOverlap, x as getNearestMember, y as toPlacementOffset, z as getTurnDeg, A as moveSlotMember, B as moveShape, C as layersCollide, D as shapesCollide, P as PlannerElementData, E as parseGuestPlacement, F as saveElementArticleCodex, H as parseSetPlanData, I as isSavePlannerV2, J as BoundingBox, K as movePoints } from './index-88148ccc.js';
8
9
  import DivaUtils, { DivaError, md5 } from '@crystaldesign/diva-utils';
9
- import { computeDockedTransform } from '@crystaldesign/planner-2d-core';
10
- import { d as dockingPointHandlerInst, h as handler2D } from './PlannerHandler2D-e4d80c41.js';
11
- import '@babel/runtime/helpers/slicedToArray';
10
+ import { computeDockedTransform } from '@crystaldesign/planner-core';
11
+ import { d as dockingPointHandlerInst, h as handler2D } from './PlannerHandler2D-8d963e77.js';
12
12
  import '@babel/runtime/helpers/objectWithoutProperties';
13
13
  import 'axios';
14
- import '@crystaldesign/basket-model';
15
14
  import '@babel/runtime/helpers/typeof';
15
+ import '@babel/runtime/helpers/toArray';
16
+ import '@crystaldesign/basket-model';
16
17
  import 'fast-xml-parser';
17
18
  import '@babel/runtime/helpers/possibleConstructorReturn';
18
19
  import '@babel/runtime/helpers/getPrototypeOf';
@@ -22,28 +23,76 @@ import '@crystaldesign/basket-handler';
22
23
  import 'socket.io-client';
23
24
  import '@babel/runtime/helpers/get';
24
25
 
25
- /** Configurator 2.0 set planner payload (`SetPlanData` after base64 decode). */
26
-
27
- /** Legacy planner 1.x payload (no `v: 2` wrapper). */
28
-
29
- function parseSetPlanData(setPlanData) {
30
- var planDataString = DivaUtils.decodeBase64(setPlanData);
31
- return JSON.parse(planDataString);
32
- }
33
- function isSavePlannerV2(planData) {
34
- return planData.v === 2;
35
- }
36
-
37
- /** Article codex from a V2 or legacy element record. */
38
- function saveElementArticleCodex(element) {
39
- return element.articleCodex || element.Codex;
40
- }
41
-
42
26
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
43
27
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
44
28
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
29
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
30
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
45
31
  var LOG = DivaUtils.initLog('Planner', 'WEB-PLANNER-LOGIC');
46
32
  var ACC_DOCK_TYPES = ['AVO', 'AVU', 'AVC', 'AVS', 'AVN'];
33
+
34
+ /** An element of the set as a drag checks it: its shape, and its layer for the catalog's layer rule. */
35
+
36
+ /**
37
+ * Something a dragged group may not run into: an element of another docking group of this set or of another set (its id,
38
+ * its layer where the catalog's layer rule applies; of another set its set and that set's rules), or a door's clearance,
39
+ * its swing or doorway (none).
40
+ */
41
+
42
+ /** A pose on the floor moved rigidly from `from` to `to`, as the points it carries (see `movePoints`). */
43
+ function movePose(pose, from, to) {
44
+ var _movePoints = movePoints([new Vector2(pose.center.x, pose.center.z)], from, to),
45
+ _movePoints2 = _slicedToArray(_movePoints, 1),
46
+ center = _movePoints2[0];
47
+ return {
48
+ center: {
49
+ x: center.x,
50
+ z: center.y
51
+ },
52
+ rotDeg: pose.rotDeg + to.rotDeg - from.rotDeg
53
+ };
54
+ }
55
+
56
+ /** How close (cm) a 'snap' group's wall pose has to be to the dragged position for it to dock to the wall. */
57
+ var WALL_SNAP_DISTANCE = 30;
58
+ /** The free-pose search around a group that landed on another: ring spacing (cm) and directions per ring. */
59
+ var CLEAR_SEARCH_STEP = 10;
60
+ var CLEAR_SEARCH_DIRECTIONS = 16;
61
+ /** cm a blocked turn's release looks around for a free place at least (farther where the group's longer side is longer). */
62
+ var TURN_PLACE_REACH = 100;
63
+ /** cm the room rule may move a suggested place before it no longer counts as that place. */
64
+ var PLACE_TOLERANCE = 1;
65
+ /** cm the room rule may move a pose a guest snaps to off its place (the float noise of moved outlines). */
66
+ var ROOM_RULE_NOISE = 0.01;
67
+ /** cm between the poses a drag checks on its way: less than the thinnest part (a table leg), so nothing is jumped. */
68
+ var PATH_STEP = 2;
69
+ /** cm a pair that overlapped at the start may vary in depth while it moves along (the float noise of moved outlines). */
70
+ var DEPTH_NOISE = 1e-6;
71
+ /** cm within which a dragged guest snaps into a free place of a slot that takes it. */
72
+ var SLOT_SNAP_DISTANCE = 20;
73
+ /** cm within which a drag counts as back at its start (the float noise of the summed moves). */
74
+ var START_NOISE = 1e-6;
75
+ var toFloorRect = function toFloorRect(block, pose) {
76
+ return {
77
+ center: pose.center,
78
+ halfWidth: block.halfWidth,
79
+ halfDepth: block.halfDepth,
80
+ rotDeg: pose.rotDeg
81
+ };
82
+ };
83
+
84
+ /** The article codex the room rules read: a main element's; none for an accessory. */
85
+ var mainCodex = function mainCodex(member) {
86
+ return member.IsAccessoire ? '' : member.ArticleCodex;
87
+ };
88
+
89
+ /** `pose` moved back inside the room, its rotation kept. */
90
+ var insidePose = function insidePose(block, pose, room) {
91
+ return {
92
+ center: keepInsideRoom(toFloorRect(block, pose), room),
93
+ rotDeg: pose.rotDeg
94
+ };
95
+ };
47
96
  var DivaStandardPlanner = /*#__PURE__*/function () {
48
97
  /*
49
98
  This function updates te planner data of all Elements if they changed.
@@ -55,7 +104,13 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
55
104
 
56
105
  function DivaStandardPlanner(set, updatePlannerMsgContainer, plannerId, globalBoundingBox, doDisablePlanner2D, plannerHasStaticBackground) {
57
106
  var _this = this;
107
+ var getOtherCollisionSets = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : function () {
108
+ return [];
109
+ };
110
+ var findCarrier = arguments.length > 7 ? arguments[7] : undefined;
58
111
  _classCallCheck(this, DivaStandardPlanner);
112
+ this.getOtherCollisionSets = getOtherCollisionSets;
113
+ this.findCarrier = findCarrier;
59
114
  _defineProperty(this, "plannerID", void 0);
60
115
  _defineProperty(this, "set", void 0);
61
116
  _defineProperty(this, "plannerBoundingBox", void 0);
@@ -69,6 +124,16 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
69
124
  _defineProperty(this, "IDM3DCatCodex", '');
70
125
  _defineProperty(this, "IDM3DEnvironment", 'diva.ro');
71
126
  _defineProperty(this, "nextElementId", 1);
127
+ _defineProperty(this, "room", void 0);
128
+ _defineProperty(this, "roomDrag", void 0);
129
+ /** Elements whose group a room rule placed (insert, resize, drag, scene switch, …): a measurement re-binds them. */
130
+ _defineProperty(this, "roomPlaced", new WeakSet());
131
+ /** The elements the current drag moves (ids): the grabbed one, those the viewer moves with it, a room drag's group, their guests. */
132
+ _defineProperty(this, "dragUnit", void 0);
133
+ /** Of the current drag's elements, the guests it carries along (ids, see `getFollowers`). */
134
+ _defineProperty(this, "dragFollowers", new Set());
135
+ /** The free slot places the grabbed element may snap into (see `findSlotSnap`), found when the drag starts where it stood. */
136
+ _defineProperty(this, "dragSlots", void 0);
72
137
  _defineProperty(this, "collisionHandler", void 0);
73
138
  _defineProperty(this, "dockToAVUorAVOororAVNorAVSorAVC", function (plannerElement, targetElements) {
74
139
  // Capability comes from the SVG-parsed docking points, not the catalog metadata counts
@@ -166,6 +231,18 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
166
231
  if (!this.getCatalogData().dontSetPosNrFromPlanner) startChainElements = startChainElements.sort(function (a, b) {
167
232
  return a.WorldPosCenter.x - b.WorldPosCenter.x;
168
233
  });
234
+ // Elements put into a carrier's slot come after the chains, by the numbers they have; a new one last.
235
+ var keptPosNr = function keptPosNr(element) {
236
+ return element.PosNr > 0 ? element.PosNr : Infinity;
237
+ };
238
+ var atEnd = startChainElements.filter(function (element) {
239
+ return element.PosNrAtEnd;
240
+ }).sort(function (a, b) {
241
+ return keptPosNr(a) - keptPosNr(b);
242
+ });
243
+ startChainElements = [].concat(_toConsumableArray(startChainElements.filter(function (element) {
244
+ return !element.PosNrAtEnd;
245
+ })), _toConsumableArray(atEnd));
169
246
  var posNrAcc;
170
247
  var _updateAccessoiresOfElement = function updateAccessoiresOfElement(curElement, posNrParent) {
171
248
  //Nun habe ich ein Element und muss überprüfen, ob es Accessoires hat. Das sind Elemente, die über AVO, AVU oder AVC gedockt sind.
@@ -277,16 +354,217 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
277
354
  * {@link applyDockTransform} (apply → read → restore, no docking relations touched). Returns the
278
355
  * delta from the element's current transform (cm / deg), or null if nothing is in snapping range.
279
356
  * `excludeElementIds` skips the element's own move-group so it doesn't "snap" to siblings that
280
- * are translating with it.
357
+ * are translating with it. In a room drag it is the room pose instead, with what blocks it at contact.
281
358
  */
282
359
  }, {
283
360
  key: "getDockSnapPreview",
284
361
  value: function getDockSnapPreview(elementId, autoDockingDistance) {
362
+ var _this$roomDrag, _this$findDockSnap;
285
363
  var excludeElementIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
286
364
  var element = this.plannerElements.get(elementId);
287
365
  if (!element) return null;
366
+ // A room drag that turned into a rotation moves the normal way: its preview only names what the turned group runs into.
367
+ if (this.room && ((_this$roomDrag = this.roomDrag) === null || _this$roomDrag === void 0 ? void 0 : _this$roomDrag.elementId) === elementId) {
368
+ return this.roomDrag.rotating ? this.getRoomTurnPreview(element, this.roomDrag) : this.getRoomDragPreview(element, this.roomDrag);
369
+ }
370
+ return (_this$findDockSnap = this.findDockSnap(element, autoDockingDistance, [].concat(_toConsumableArray(excludeElementIds), _toConsumableArray(this.dragFollowers)))) !== null && _this$findDockSnap !== void 0 ? _this$findDockSnap : this.findSlotSnap(element);
371
+ }
372
+
373
+ /**
374
+ * The move (cm / deg, about the element's centre) into the nearest free slot place found when its drag started (see
375
+ * `findDragSlotPlaces`), within SLOT_SNAP_DISTANCE: lined up and turned as the place says, at its own distance to the
376
+ * carrier as far as the slot's band allows. Null when no place is that near, the element is not the one dragged or it
377
+ * is back where the drag started (a cancel ends there exactly).
378
+ */
379
+ }, {
380
+ key: "findSlotSnap",
381
+ value: function findSlotSnap(element) {
382
+ var _this$dragSlots;
383
+ var slots = ((_this$dragSlots = this.dragSlots) === null || _this$dragSlots === void 0 ? void 0 : _this$dragSlots.elementId) === element.ElementId ? this.dragSlots : undefined;
384
+ var _poseOf = poseOf(element),
385
+ center = _poseOf.center;
386
+ var places = slots && Math.hypot(center.x - slots.start.x, center.z - slots.start.z) > START_NOISE ? slots.places : [];
387
+ var nearest = getSnapPlace(places, center, SLOT_SNAP_DISTANCE);
388
+ if (!nearest) return null;
389
+ return {
390
+ dx: nearest.center.x - center.x,
391
+ dz: nearest.center.z - center.z,
392
+ dRotDeg: getTurnDeg(element.RotDeg, places[nearest.index].rotDeg)
393
+ };
394
+ }
395
+
396
+ // The group's pose where the grabbed element snaps into a free slot place (see findSlotSnap) from where the pointer has
397
+ // it in a room drag; undefined when no place is near.
398
+ }, {
399
+ key: "getSlotSnapPose",
400
+ value: function getSlotSnapPose(drag) {
401
+ var _this$dragSlots2;
402
+ var places = ((_this$dragSlots2 = this.dragSlots) === null || _this$dragSlots2 === void 0 ? void 0 : _this$dragSlots2.elementId) === drag.elementId ? this.dragSlots.places : [];
403
+ if (places.length === 0) return undefined;
404
+ var raw = {
405
+ center: {
406
+ x: drag.grabbedStart.x + drag.dx,
407
+ z: drag.grabbedStart.z + drag.dz
408
+ },
409
+ rotDeg: drag.grabbedStartRotDeg
410
+ };
411
+ var nearest = getSnapPlace(places, raw.center, SLOT_SNAP_DISTANCE);
412
+ if (!nearest) return undefined;
413
+ var block = {
414
+ center: {
415
+ x: drag.start.center.x + drag.dx,
416
+ z: drag.start.center.z + drag.dz
417
+ },
418
+ rotDeg: drag.start.rotDeg
419
+ };
420
+ return movePose(block, raw, {
421
+ center: nearest.center,
422
+ rotDeg: places[nearest.index].rotDeg
423
+ });
424
+ }
425
+
426
+ /**
427
+ * The free places of the slots that take the grabbed element, at carriers outside the dragged unit in this and the
428
+ * other sets, for a unit of one main element; free where the element stands clear of every body and zone there (its
429
+ * carrier's zone and a slot's reach under its carrier allowed). Found once when the drag starts.
430
+ */
431
+ }, {
432
+ key: "findDragSlotPlaces",
433
+ value: function findDragSlotPlaces(element, unit) {
434
+ var _this3 = this;
435
+ var _ref = element.IsAccessoire ? [] : this.getPlacementTypes(element),
436
+ _ref2 = _slicedToArray(_ref, 1),
437
+ type = _ref2[0];
438
+ var group = this.getDockingGroupOf(element);
439
+ if (!type || group.filter(function (member) {
440
+ return !member.IsAccessoire;
441
+ }).length !== 1) return [];
442
+ var otherSets = this.getOtherCollisionSets(group.map(function (member) {
443
+ return member.ElementId;
444
+ }));
445
+ var own = getDockingGroups(this.getAllPlannerElements().filter(function (other) {
446
+ return !unit.includes(other);
447
+ })).filter(function (carrier) {
448
+ return carrier.some(function (member) {
449
+ return !member.IsAccessoire;
450
+ });
451
+ }).map(function (carrier) {
452
+ return {
453
+ rules: _this3.getCatalogData().placementOptions.rules,
454
+ members: _this3.getSlotMembers(carrier)
455
+ };
456
+ });
457
+ var others = otherSets.flatMap(function (set) {
458
+ return _toConsumableArray(new Set(set.parts.map(function (part) {
459
+ return part.group;
460
+ }))).map(function (members) {
461
+ return {
462
+ rules: set.rules,
463
+ members: members
464
+ };
465
+ });
466
+ });
467
+ var body = getElementShape(element, false).body[0];
468
+ var pose = poseOf(element);
469
+ var outline = function outline(rotDeg) {
470
+ return movePoints(body, pose, {
471
+ center: {
472
+ x: 0,
473
+ z: 0
474
+ },
475
+ rotDeg: rotDeg
476
+ });
477
+ };
478
+ var drag = this.room ? this.createRoomDrag(element.ElementId, false, otherSets) : undefined;
479
+ return [].concat(_toConsumableArray(own), _toConsumableArray(others)).flatMap(function (_ref3) {
480
+ var rules = _ref3.rules,
481
+ members = _ref3.members;
482
+ return getCarrierSlots(rules, members, type);
483
+ }).flatMap(function (slot) {
484
+ return getSlotPlaces(slot, outline);
485
+ }).filter(function (place) {
486
+ return _this3.placeIsFree(element, group, place, otherSets);
487
+ }).map(function (place) {
488
+ return drag ? _this3.cutBandToRoom(drag, place) : place;
489
+ });
490
+ }
491
+
492
+ // The free place with its band cut to the offsets at which the room rule leaves the dragged group where it is: a guest
493
+ // never snaps where the rule would move it.
494
+ }, {
495
+ key: "cutBandToRoom",
496
+ value: function cutBandToRoom(drag, place) {
497
+ var _this4 = this;
498
+ var grabbed = {
499
+ center: drag.grabbedStart,
500
+ rotDeg: drag.grabbedStartRotDeg
501
+ };
502
+ var kept = function kept(offset) {
503
+ var center = {
504
+ x: place.center.x + place.normal.x * offset,
505
+ z: place.center.z + place.normal.z * offset
506
+ };
507
+ return !!_this4.getKeptPose(drag, movePose(drag.start, grabbed, {
508
+ center: center,
509
+ rotDeg: place.rotDeg
510
+ }), ROOM_RULE_NOISE);
511
+ };
512
+ var cut = function cut(end) {
513
+ if (kept(end)) return end;
514
+ var free = 0;
515
+ var blocked = end;
516
+ for (var i = 0; i < 12; i++) {
517
+ var mid = (free + blocked) / 2;
518
+ if (kept(mid)) free = mid;else blocked = mid;
519
+ }
520
+ return free;
521
+ };
522
+ return _objectSpread(_objectSpread({}, place), {}, {
523
+ band: [cut(place.band[0]), cut(place.band[1])]
524
+ });
525
+ }
526
+
527
+ // Whether the element's group, moved so the element stands at `place`, stands there by the room rule and collides with
528
+ // nothing (see fitsAt); it is put back where it stood.
529
+ }, {
530
+ key: "placeIsFree",
531
+ value: function placeIsFree(element, group, place, otherSets) {
532
+ var saved = group.map(function (member) {
533
+ return {
534
+ member: member,
535
+ center: member.WorldPosCenter,
536
+ rotDeg: member.RotDeg
537
+ };
538
+ });
539
+ moveGroupRigidly(group, poseOf(element), place);
540
+ var drag = this.createRoomDrag(element.ElementId, false, otherSets);
541
+ var free = !!drag && !!this.getKeptPose(drag) && !this.isBlocked(drag, drag.start);
542
+ var _iterator = _createForOfIteratorHelper(saved),
543
+ _step;
544
+ try {
545
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
546
+ var _step$value = _step.value,
547
+ member = _step$value.member,
548
+ center = _step$value.center,
549
+ rotDeg = _step$value.rotDeg;
550
+ member.WorldPosCenter = center;
551
+ member.RotDeg = rotDeg;
552
+ }
553
+ } catch (err) {
554
+ _iterator.e(err);
555
+ } finally {
556
+ _iterator.f();
557
+ }
558
+ return free;
559
+ }
560
+
561
+ // The move (cm / deg, about the element's centre) onto the element's nearest dock within `autoDockingDistance`, to an
562
+ // element not in `excludeElementIds`; null when none is in range. Nothing changes.
563
+ }, {
564
+ key: "findDockSnap",
565
+ value: function findDockSnap(element, autoDockingDistance, excludeElementIds) {
288
566
  var targets = this.getAllPlannerElements().filter(function (e) {
289
- return e.getElementId() !== elementId && !excludeElementIds.includes(e.getElementId());
567
+ return e !== element && !excludeElementIds.includes(e.getElementId());
290
568
  });
291
569
  var pairs = dockingPointHandlerInst.searchDockableElementsInArea(element, targets, autoDockingDistance);
292
570
  if (!pairs || pairs.size === 0) return null;
@@ -315,6 +593,1273 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
315
593
  return result;
316
594
  }
317
595
 
596
+ /**
597
+ * The rigid move from where the planner holds a dragged element's group to where a viewer shows it with `preview` (see
598
+ * {@link getDockSnapPreview}): none in a room drag, which holds the group where it shows; else the dock snap, turning
599
+ * about the element's centre.
600
+ */
601
+ }, {
602
+ key: "getPreviewMove",
603
+ value: function getPreviewMove(elementId, preview) {
604
+ var _this$roomDrag2;
605
+ var element = this.plannerElements.get(elementId);
606
+ if (!element || !preview || this.room && ((_this$roomDrag2 = this.roomDrag) === null || _this$roomDrag2 === void 0 ? void 0 : _this$roomDrag2.elementId) === elementId) return undefined;
607
+ return this.snapMove(element, preview);
608
+ }
609
+
610
+ // The rigid move of a dock snap (see findDockSnap): shifted and turned about the element's centre.
611
+ }, {
612
+ key: "snapMove",
613
+ value: function snapMove(element, snap) {
614
+ var center = {
615
+ x: element.WorldPosCenter.x,
616
+ z: element.WorldPosCenter.z
617
+ };
618
+ return {
619
+ from: {
620
+ center: center,
621
+ rotDeg: 0
622
+ },
623
+ to: {
624
+ center: {
625
+ x: center.x + snap.dx,
626
+ z: center.z + snap.dz
627
+ },
628
+ rotDeg: snap.dRotDeg
629
+ }
630
+ };
631
+ }
632
+
633
+ /**
634
+ * Activates (or clears) the room the elements are bound to. With `bindGroups` every docking group of main elements
635
+ * gets the room rule once: a forced group goes to its nearest wall pose, any other is pushed inside the room. A group
636
+ * the rules leave on other furniture or in a door's clearance (swing or doorway), where it did not stand so before, then
637
+ * goes to the nearest free pose (see {@link moveClearOfObstacles}). Returns false when a forced group fits on no wall
638
+ * (it stays where it is).
639
+ */
640
+ }, {
641
+ key: "setRoom",
642
+ value: function setRoom(room, bindGroups) {
643
+ // Measured in the room the elements stood in so far.
644
+ var blockedBefore = room && bindGroups ? this.getBlockedGroupKeys() : new Set();
645
+ this.room = room;
646
+ this.roomDrag = undefined;
647
+ if (!room || !bindGroups) return true;
648
+ var allGroupsFit = this.placeGroupsInRoom();
649
+ this.clearNewlyBlockedGroups(room, blockedBefore);
650
+ this.updatePlannerPosNr();
651
+ this.checkCollision(false);
652
+ this.updatePlannerBoundingBox();
653
+ return allGroupsFit;
654
+ }
655
+
656
+ // Applies the room rules to every docking group of main elements, or only to the groups holding one of `elements`;
657
+ // false when a forced group fits on no wall. A group of guests goes with its carrier instead.
658
+ }, {
659
+ key: "placeGroupsInRoom",
660
+ value: function placeGroupsInRoom(elements) {
661
+ var allGroupsFit = true;
662
+ var _iterator2 = _createForOfIteratorHelper(getDockingGroups(this.getAllPlannerElements())),
663
+ _step2;
664
+ try {
665
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
666
+ var group = _step2.value;
667
+ if (elements && !group.some(function (member) {
668
+ return elements.includes(member);
669
+ })) continue;
670
+ if (this.followsCarrier(group)) continue;
671
+ if (!this.placeGroupInRoom(group)) allGroupsFit = false;
672
+ }
673
+ } catch (err) {
674
+ _iterator2.e(err);
675
+ } finally {
676
+ _iterator2.f();
677
+ }
678
+ return allGroupsFit;
679
+ }
680
+
681
+ // The first main element of each docking group (not a guest at its carrier) that stands on another group, of this set
682
+ // or of another set in the room, or in a door's clearance in the active room.
683
+ }, {
684
+ key: "getBlockedGroupKeys",
685
+ value: function getBlockedGroupKeys() {
686
+ var blocked = new Set();
687
+ var _iterator3 = _createForOfIteratorHelper(getDockingGroups(this.getAllPlannerElements())),
688
+ _step3;
689
+ try {
690
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
691
+ var group = _step3.value;
692
+ var main = group.find(function (member) {
693
+ return !member.IsAccessoire;
694
+ });
695
+ if (!main || this.followsCarrier(group)) continue;
696
+ var drag = this.createRoomDrag(main.ElementId);
697
+ if (drag && this.isBlocked(drag, drag.start)) blocked.add(main.ElementId);
698
+ }
699
+ } catch (err) {
700
+ _iterator3.e(err);
701
+ } finally {
702
+ _iterator3.f();
703
+ }
704
+ return blocked;
705
+ }
706
+
707
+ // Every group (but a guest at its carrier) whose first main element is not in `blockedBefore` and that stands on
708
+ // another group or in a door's clearance goes to the nearest free pose (moveClearOfObstacles).
709
+ }, {
710
+ key: "clearNewlyBlockedGroups",
711
+ value: function clearNewlyBlockedGroups(room, blockedBefore) {
712
+ var _iterator4 = _createForOfIteratorHelper(getDockingGroups(this.getAllPlannerElements())),
713
+ _step4;
714
+ try {
715
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
716
+ var group = _step4.value;
717
+ var main = group.find(function (member) {
718
+ return !member.IsAccessoire;
719
+ });
720
+ if (main && !blockedBefore.has(main.ElementId) && !this.followsCarrier(group)) this.moveClearOfObstacles(main.ElementId, room);
721
+ }
722
+ } catch (err) {
723
+ _iterator4.e(err);
724
+ } finally {
725
+ _iterator4.f();
726
+ }
727
+ }
728
+
729
+ // Elements added in a room: their groups get the room rules, and with `clearOfObstacles` a group standing on another or
730
+ // in a door's clearance moves to the nearest free pose.
731
+ }, {
732
+ key: "placeAddedInRoom",
733
+ value: function placeAddedInRoom(added, clearOfObstacles) {
734
+ var room = this.room;
735
+ if (!room) return;
736
+ if (!this.placeGroupsInRoom(added)) {
737
+ this.updateRoomNoFitMsg(true);
738
+ return;
739
+ }
740
+ if (!clearOfObstacles) return;
741
+ var _iterator5 = _createForOfIteratorHelper(getDockingGroups(this.getAllPlannerElements())),
742
+ _step5;
743
+ try {
744
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
745
+ var group = _step5.value;
746
+ var main = group.find(function (member) {
747
+ return !member.IsAccessoire && added.includes(member);
748
+ });
749
+ if (main && !this.followsCarrier(group)) this.moveClearOfObstacles(main.ElementId, room);
750
+ }
751
+ } catch (err) {
752
+ _iterator5.e(err);
753
+ } finally {
754
+ _iterator5.f();
755
+ }
756
+ }
757
+
758
+ // Placing some groups can only show ROOM_NO_FIT_MSG: whether every set fits is DivaPlannerHandler's to say.
759
+ }, {
760
+ key: "updateRoomNoFitMsg",
761
+ value: function updateRoomNoFitMsg(show) {
762
+ var _this$collisionHandle, _this$collisionHandle2;
763
+ (_this$collisionHandle = (_this$collisionHandle2 = this.collisionHandler).updatePlannerMsgContainer) === null || _this$collisionHandle === void 0 || _this$collisionHandle.call(_this$collisionHandle2, 'ROOM_NO_FIT_MSG', show, 'WARNING', 'ROOM_NO_FIT_MSG', false);
764
+ }
765
+
766
+ /**
767
+ * Whether every docking group of the set has its place in the active room: a forced group stands on its wall pose, any other
768
+ * (but guests at their carrier) room within the footprint as it stands turned, with its followers (no room: true). Until the
769
+ * viewer measured its main elements a group that has a wall pose counts as standing on it: an opened one was saved
770
+ * with their measured extents, which reach at least as far as the outline, a placed one goes there once measured (see
771
+ * setElementFootprints).
772
+ */
773
+ }, {
774
+ key: "groupsFitInRoom",
775
+ value: function groupsFitInRoom() {
776
+ var _this5 = this;
777
+ var room = this.room;
778
+ if (!room) return true;
779
+ return getDockingGroups(this.getAllPlannerElements()).every(function (group) {
780
+ if (group.every(function (member) {
781
+ return member.IsAccessoire;
782
+ })) return true;
783
+ if (!_this5.isWallBound(group)) return _this5.followsCarrier(group) || _this5.fitsInside(group, room);
784
+ var _this5$getWallBinding = _this5.getWallBinding(group, room),
785
+ groupBlock = _this5$getWallBinding.groupBlock,
786
+ pose = _this5$getWallBinding.pose;
787
+ if (!pose) return false;
788
+ return isSamePose(pose, groupBlock) || group.some(function (member) {
789
+ return !member.IsAccessoire && !member.GeoExtent;
790
+ });
791
+ });
792
+ }
793
+
794
+ // Whether the group with its followers, pushed inside the room (see insidePose), lies within it.
795
+ }, {
796
+ key: "fitsInside",
797
+ value: function fitsInside(group, room) {
798
+ var groupBlock = getGroupBlock([].concat(_toConsumableArray(group), _toConsumableArray(this.getFollowers(group))), this.getRoomFrame(group).RotDeg);
799
+ return fitsInsideRoom(toFloorRect(groupBlock.block, insidePose(groupBlock.block, groupBlock, room)), room);
800
+ }
801
+
802
+ // A forced group goes to its nearest wall pose (false when it fits on none), any other group is pushed inside the room
803
+ // with its followers (their bodies too; false when it is wider or deeper than the room). The followers go along
804
+ // either way.
805
+ }, {
806
+ key: "placeGroupInRoom",
807
+ value: function placeGroupInRoom(group, frameElement) {
808
+ var _this6 = this;
809
+ var followers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getFollowers(group);
810
+ if (!this.room || group.every(function (member) {
811
+ return member.IsAccessoire;
812
+ })) return true;
813
+ group.forEach(function (member) {
814
+ return _this6.roomPlaced.add(member);
815
+ });
816
+ if (this.isWallBound(group)) return this.bindGroupToWalls(group, frameElement, followers);
817
+ var frame = this.getRoomFrame(group, frameElement);
818
+ var unit = [].concat(_toConsumableArray(group), _toConsumableArray(followers));
819
+ var groupBlock = getGroupBlock(unit, frame.RotDeg);
820
+ var pose = insidePose(groupBlock.block, groupBlock, this.room);
821
+ moveGroupRigidly(unit, groupBlock, pose);
822
+ return fitsInsideRoom(toFloorRect(groupBlock.block, pose), this.room);
823
+ }
824
+
825
+ // The element whose rotation frames the group: `preferred` unless it is an accessory, else the oldest main element.
826
+ }, {
827
+ key: "getRoomFrame",
828
+ value: function getRoomFrame(members, preferred) {
829
+ var _members$find;
830
+ if (preferred && !preferred.IsAccessoire) return preferred;
831
+ return (_members$find = members.find(function (member) {
832
+ return !member.IsAccessoire;
833
+ })) !== null && _members$find !== void 0 ? _members$find : members[0];
834
+ }
835
+ }, {
836
+ key: "bindGroupToWalls",
837
+ value: function bindGroupToWalls(members, frameElement) {
838
+ var followers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
839
+ if (!this.room || !members.length) return false;
840
+ var _this$getWallBinding = this.getWallBinding(members, this.room, frameElement),
841
+ groupBlock = _this$getWallBinding.groupBlock,
842
+ pose = _this$getWallBinding.pose;
843
+ if (!pose) return false;
844
+ moveGroupRigidly([].concat(_toConsumableArray(members), _toConsumableArray(followers)), groupBlock, pose);
845
+ return true;
846
+ }
847
+
848
+ /**
849
+ * The group as one block, and its wall pose (null: it fits on no wall), in the frame it is bound in: `preferred`'s,
850
+ * else the rotation of a main element in which it already stands on its wall pose (a group released by a turned
851
+ * element keeps that frame), else the oldest main element's (see getRoomFrame).
852
+ */
853
+ }, {
854
+ key: "getWallBinding",
855
+ value: function getWallBinding(members, room, preferred) {
856
+ var _this7 = this;
857
+ var bindingIn = function bindingIn(frame) {
858
+ var groupBlock = _this7.getRoomBlock(members, frame);
859
+ return {
860
+ groupBlock: groupBlock,
861
+ pose: bindToWalls(groupBlock.center, groupBlock.block, room)
862
+ };
863
+ };
864
+ var first = bindingIn(this.getRoomFrame(members, preferred));
865
+ if (preferred && !preferred.IsAccessoire) return first;
866
+ var standsOn = function standsOn(_ref4) {
867
+ var groupBlock = _ref4.groupBlock,
868
+ pose = _ref4.pose;
869
+ return !!pose && isSamePose(pose, groupBlock);
870
+ };
871
+ if (standsOn(first)) return first;
872
+ var _iterator6 = _createForOfIteratorHelper(members),
873
+ _step6;
874
+ try {
875
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
876
+ var member = _step6.value;
877
+ if (member.IsAccessoire || member.RotDeg === first.groupBlock.rotDeg) continue;
878
+ var binding = bindingIn(member);
879
+ if (standsOn(binding)) return binding;
880
+ }
881
+ } catch (err) {
882
+ _iterator6.e(err);
883
+ } finally {
884
+ _iterator6.f();
885
+ }
886
+ return first;
887
+ }
888
+
889
+ /**
890
+ * Takes the 3D extents the viewer measured for this set's main elements, so a part reaching beyond the 2D outline
891
+ * stays out of the walls. A forced group a room rule placed goes to its wall pose with them (it was placed before its
892
+ * model was measured); a group as the planning was opened moves only with the next user action. Returns whether an
893
+ * element moved.
894
+ */
895
+ }, {
896
+ key: "setElementFootprints",
897
+ value: function setElementFootprints(footprints) {
898
+ var _this8 = this;
899
+ var changed = [];
900
+ var _iterator7 = _createForOfIteratorHelper(footprints),
901
+ _step7;
902
+ try {
903
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
904
+ var _step7$value = _step7.value,
905
+ elementId = _step7$value.elementId,
906
+ minX = _step7$value.minX,
907
+ maxX = _step7$value.maxX,
908
+ minZ = _step7$value.minZ,
909
+ maxZ = _step7$value.maxZ,
910
+ top = _step7$value.top;
911
+ var element = this.plannerElements.get(elementId);
912
+ var extent = {
913
+ minX: minX,
914
+ maxX: maxX,
915
+ minZ: minZ,
916
+ maxZ: maxZ,
917
+ top: top
918
+ };
919
+ if (!element || element.IsAccessoire || sameGeoExtent(element.GeoExtent, extent)) continue;
920
+ element.GeoExtent = extent;
921
+ if (this.roomPlaced.has(element)) changed.push(element);
922
+ }
923
+ } catch (err) {
924
+ _iterator7.e(err);
925
+ } finally {
926
+ _iterator7.f();
927
+ }
928
+ if (!this.room || changed.length === 0) return false;
929
+ var groups = getDockingGroups(this.getAllPlannerElements()).filter(function (group) {
930
+ return group.some(function (member) {
931
+ return changed.includes(member);
932
+ }) && _this8.isWallBound(group) && !_this8.followsCarrier(group);
933
+ });
934
+ var members = groups.flat();
935
+ var before = members.map(function (member) {
936
+ return [member.WorldPosCenter.x, member.WorldPosCenter.z, member.RotDeg];
937
+ });
938
+ groups.forEach(function (group) {
939
+ return _this8.placeGroupInRoom(group);
940
+ });
941
+ var moved = members.some(function (member, i) {
942
+ var _before$i = _slicedToArray(before[i], 3),
943
+ x = _before$i[0],
944
+ z = _before$i[1],
945
+ rotDeg = _before$i[2];
946
+ return member.WorldPosCenter.x !== x || member.WorldPosCenter.z !== z || member.RotDeg !== rotDeg;
947
+ });
948
+ if (!moved) return false;
949
+ this.updatePlannerPosNr();
950
+ this.checkCollision(false);
951
+ this.updatePlannerBoundingBox();
952
+ return true;
953
+ }
954
+
955
+ /** Whether the element's docking group is bound to the walls of the active room. */
956
+ }, {
957
+ key: "isElementWallBound",
958
+ value: function isElementWallBound(elementId) {
959
+ var element = this.plannerElements.get(elementId);
960
+ return !!this.room && !!element && this.isWallBound(this.getDockingGroupOf(element));
961
+ }
962
+
963
+ /**
964
+ * A group's wall mode: forced when a main element is forced or a corner element, else snap when one snaps, else free. A
965
+ * guest's own wall rule rests while it stands at its carrier.
966
+ */
967
+ }, {
968
+ key: "getGroupWallMode",
969
+ value: function getGroupWallMode(members) {
970
+ var _this9 = this;
971
+ var catalogData = this.getCatalogData();
972
+ var modes = members.flatMap(function (member) {
973
+ var codex = _this9.getCarrierOf(member) ? '' : mainCodex(member);
974
+ if (!codex) return [];
975
+ return [catalogData.getCornerSide(codex) ? 'forced' : catalogData.getWallMode(codex)];
976
+ });
977
+ return modes.includes('forced') ? 'forced' : modes.includes('snap') ? 'snap' : 'free';
978
+ }
979
+ }, {
980
+ key: "isWallBound",
981
+ value: function isWallBound(members) {
982
+ return this.getGroupWallMode(members) === 'forced';
983
+ }
984
+
985
+ // The group as one block in `frame`'s rotation; a corner element at one of its ends pins that end into a corner.
986
+ }, {
987
+ key: "getRoomBlock",
988
+ value: function getRoomBlock(members, frame) {
989
+ var groupBlock = getGroupBlock(members, frame.RotDeg);
990
+ var catalogData = this.getCatalogData();
991
+ var _iterator8 = _createForOfIteratorHelper(members),
992
+ _step8;
993
+ try {
994
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
995
+ var member = _step8.value;
996
+ var codex = mainCodex(member);
997
+ var side = codex ? catalogData.getCornerSide(codex) : undefined;
998
+ if (!side) continue;
999
+ var cornerEnd = getCornerEnd(members, frame.RotDeg, member, side);
1000
+ if (cornerEnd) return _objectSpread(_objectSpread({}, groupBlock), {}, {
1001
+ block: _objectSpread(_objectSpread({}, groupBlock.block), {}, {
1002
+ cornerEnd: cornerEnd
1003
+ })
1004
+ });
1005
+ }
1006
+ } catch (err) {
1007
+ _iterator8.e(err);
1008
+ } finally {
1009
+ _iterator8.f();
1010
+ }
1011
+ return groupBlock;
1012
+ }
1013
+
1014
+ /** A group collides unless all its main elements are NO_COLLISION (e.g. rugs). */
1015
+ }, {
1016
+ key: "collides",
1017
+ value: function collides(members) {
1018
+ var _this10 = this;
1019
+ return members.some(function (member) {
1020
+ var codex = mainCodex(member);
1021
+ return !!codex && !_this10.hasNoCollision(codex);
1022
+ });
1023
+ }
1024
+ }, {
1025
+ key: "hasNoCollision",
1026
+ value: function hasNoCollision(codex) {
1027
+ return !!codex && this.getCatalogData().hasNoCollision(codex);
1028
+ }
1029
+
1030
+ /** The article's placement types, primary first (PLACEMENT_TYPE, else palette group); empty without one. */
1031
+ }, {
1032
+ key: "getPlacementTypes",
1033
+ value: function getPlacementTypes(element) {
1034
+ var codex = element.ArticleCodex;
1035
+ return codex && this.getCatalogData().getPlacementType(codex) || [];
1036
+ }
1037
+
1038
+ // The main elements of a group as carriers of placement slots, by their outlines (never the viewer's measures).
1039
+ }, {
1040
+ key: "getSlotMembers",
1041
+ value: function getSlotMembers(group) {
1042
+ var _this11 = this;
1043
+ return group.filter(function (member) {
1044
+ return !member.IsAccessoire;
1045
+ }).map(function (member) {
1046
+ return {
1047
+ types: _this11.getPlacementTypes(member),
1048
+ rotDeg: member.RotDeg,
1049
+ body: getElementShape(member, false).body[0],
1050
+ basketId: member.getBasketId()
1051
+ };
1052
+ });
1053
+ }
1054
+
1055
+ // The member with its shape where it stands (with the viewer's measures when `measured`) and its group as slot carrier.
1056
+ }, {
1057
+ key: "toCollisionShape",
1058
+ value: function toCollisionShape(member, slotMembers, measured) {
1059
+ return {
1060
+ elementId: member.ElementId,
1061
+ shape: getElementShape(member, measured),
1062
+ types: this.getPlacementTypes(member),
1063
+ group: slotMembers,
1064
+ layer: Number(member.Layer)
1065
+ };
1066
+ }
1067
+
1068
+ // The members of `group` that take part in collisions (see toCollisionShape).
1069
+ }, {
1070
+ key: "getCollidingShapes",
1071
+ value: function getCollidingShapes(group, measured) {
1072
+ var _this12 = this;
1073
+ var slotMembers = this.getSlotMembers(group);
1074
+ return group.filter(function (member) {
1075
+ return !_this12.hasNoCollision(member.ArticleCodex);
1076
+ }).map(function (member) {
1077
+ return _this12.toCollisionShape(member, slotMembers, measured);
1078
+ });
1079
+ }
1080
+
1081
+ // Every element of the other colliding groups (not those of `unit`, the group with its followers), the elements of the
1082
+ // other sets (`otherSets`, else those without the guests going with `members`), and in a room the door clearances: the
1083
+ // swings and doorways (getDoorClearanceRects).
1084
+ }, {
1085
+ key: "getObstacles",
1086
+ value: function getObstacles(members, measured) {
1087
+ var _this13 = this;
1088
+ var unit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : members;
1089
+ var otherSets = arguments.length > 3 ? arguments[3] : undefined;
1090
+ if (!this.collides(members)) return [];
1091
+ var others = getDockingGroups(this.getAllPlannerElements()).filter(function (group) {
1092
+ return !group.some(function (member) {
1093
+ return unit.includes(member);
1094
+ }) && _this13.collides(group);
1095
+ });
1096
+ var _this$getCatalogData = this.getCatalogData(),
1097
+ catalogCodex = _this$getCatalogData.catalogCodex;
1098
+ // Two catalogs always collide; one catalog in two sets by its layer rule.
1099
+ var foreign = (otherSets !== null && otherSets !== void 0 ? otherSets : this.getOtherCollisionSets(members.map(function (member) {
1100
+ return member.ElementId;
1101
+ }))).flatMap(function (set) {
1102
+ return set.parts.map(function (_ref5) {
1103
+ var shape = _ref5.shape,
1104
+ types = _ref5.types,
1105
+ group = _ref5.group,
1106
+ elementId = _ref5.elementId,
1107
+ layer = _ref5.layer;
1108
+ var ownLayerRule = set.catalogCodex === catalogCodex;
1109
+ return {
1110
+ shape: shape,
1111
+ types: types,
1112
+ group: group,
1113
+ elementId: elementId,
1114
+ layer: ownLayerRule ? layer : undefined,
1115
+ setId: set.setId,
1116
+ rules: set.rules
1117
+ };
1118
+ });
1119
+ });
1120
+ var doors = (this.room ? getDoorClearanceRects(this.room) : []).map(function (swing) {
1121
+ var polygon = rectCorners(swing).map(function (corner) {
1122
+ return new Vector2(corner.x, corner.z);
1123
+ });
1124
+ return {
1125
+ shape: {
1126
+ body: [polygon],
1127
+ free: [polygon]
1128
+ },
1129
+ types: [],
1130
+ group: []
1131
+ };
1132
+ });
1133
+ return [].concat(_toConsumableArray(others.flatMap(function (group) {
1134
+ return _this13.getCollidingShapes(group, measured);
1135
+ })), _toConsumableArray(foreign), _toConsumableArray(doors));
1136
+ }
1137
+ }, {
1138
+ key: "getDockingGroupOf",
1139
+ value: function getDockingGroupOf(element) {
1140
+ var _getDockingGroups$fin;
1141
+ return (_getDockingGroups$fin = getDockingGroups(this.getAllPlannerElements()).find(function (group) {
1142
+ return group.includes(element);
1143
+ })) !== null && _getDockingGroups$fin !== void 0 ? _getDockingGroups$fin : [element];
1144
+ }
1145
+
1146
+ /** The element whose article has the basket id; undefined when the set has none. */
1147
+ }, {
1148
+ key: "getElementByBasketId",
1149
+ value: function getElementByBasketId(basketId) {
1150
+ return this.getAllPlannerElements().find(function (element) {
1151
+ return element.getBasketId() === basketId;
1152
+ });
1153
+ }
1154
+
1155
+ // The carrier a guest stands at while its set is loaded; without a resolver only one of this set.
1156
+ }, {
1157
+ key: "getCarrierOf",
1158
+ value: function getCarrierOf(element) {
1159
+ var placement = element.Placement;
1160
+ if (!placement) return undefined;
1161
+ if (this.findCarrier) return this.findCarrier(placement);
1162
+ return this.getElementByBasketId(placement.carrierBasketId);
1163
+ }
1164
+
1165
+ // Whether every main element of the group is a guest at a carrier outside it: the group goes with its carrier.
1166
+ }, {
1167
+ key: "followsCarrier",
1168
+ value: function followsCarrier(group) {
1169
+ var _this14 = this;
1170
+ var mains = group.filter(function (member) {
1171
+ return !member.IsAccessoire;
1172
+ });
1173
+ return mains.length > 0 && mains.every(function (member) {
1174
+ var carrier = _this14.getCarrierOf(member);
1175
+ return !!carrier && !group.includes(carrier);
1176
+ });
1177
+ }
1178
+
1179
+ /**
1180
+ * The guests of this set that go with `members`: those standing at one of them, and the guests of those (at most
1181
+ * MAX_GUEST_DEPTH carriers deep), each with its docking group; never one of `members`.
1182
+ */
1183
+ }, {
1184
+ key: "getFollowers",
1185
+ value: function getFollowers(members) {
1186
+ var _this15 = this;
1187
+ var unit = new Set(members);
1188
+ var followers = [];
1189
+ var carriers = members;
1190
+ for (var depth = 0; depth < MAX_GUEST_DEPTH && carriers.length > 0; depth++) {
1191
+ var guests = this.getAllPlannerElements().filter(function (element) {
1192
+ var carrier = !unit.has(element) && _this15.getCarrierOf(element);
1193
+ return !!carrier && carriers.includes(carrier);
1194
+ });
1195
+ var next = _toConsumableArray(new Set(guests.flatMap(function (guest) {
1196
+ return _this15.getDockingGroupOf(guest);
1197
+ }))).filter(function (element) {
1198
+ return !unit.has(element);
1199
+ });
1200
+ next.forEach(function (element) {
1201
+ return unit.add(element);
1202
+ });
1203
+ followers.push.apply(followers, _toConsumableArray(next));
1204
+ carriers = next;
1205
+ }
1206
+ return followers;
1207
+ }
1208
+
1209
+ /** The ids of the element's docking group, the element included. */
1210
+ }, {
1211
+ key: "getDockingGroupIds",
1212
+ value: function getDockingGroupIds(elementId) {
1213
+ var element = this.plannerElements.get(elementId);
1214
+ return element ? this.getDockingGroupOf(element).map(function (member) {
1215
+ return member.ElementId;
1216
+ }) : [];
1217
+ }
1218
+
1219
+ /** The element's first placement type; undefined for an accessory or an article without one. */
1220
+ }, {
1221
+ key: "getGuestType",
1222
+ value: function getGuestType(elementId) {
1223
+ var element = this.plannerElements.get(elementId);
1224
+ return element && !element.IsAccessoire ? this.getPlacementTypes(element)[0] : undefined;
1225
+ }
1226
+
1227
+ /** The main elements of every docking group as slot carriers (see `getSlotMembers`), but groups holding one of `excludeIds`. */
1228
+ }, {
1229
+ key: "getSlotCarriers",
1230
+ value: function getSlotCarriers(excludeIds) {
1231
+ var _this16 = this;
1232
+ return getDockingGroups(this.getAllPlannerElements()).filter(function (group) {
1233
+ return !group.some(function (member) {
1234
+ return excludeIds.includes(member.ElementId);
1235
+ });
1236
+ }).map(function (group) {
1237
+ return _this16.getSlotMembers(group);
1238
+ }).filter(function (members) {
1239
+ return members.length > 0;
1240
+ });
1241
+ }
1242
+
1243
+ /** Moves the element's docking group rigidly so the element stands at `pose` (a guest following its carrier). */
1244
+ }, {
1245
+ key: "moveGuest",
1246
+ value: function moveGuest(elementId, pose) {
1247
+ var element = this.plannerElements.get(elementId);
1248
+ if (element) moveGroupRigidly(this.getDockingGroupOf(element), poseOf(element), pose);
1249
+ }
1250
+
1251
+ /** After guests moved: position numbers, the collision warning and the bounding box follow. */
1252
+ }, {
1253
+ key: "refreshAfterGuestMoves",
1254
+ value: function refreshAfterGuestMoves() {
1255
+ this.updatePlannerPosNr();
1256
+ this.checkCollision(false);
1257
+ this.updatePlannerBoundingBox();
1258
+ }
1259
+
1260
+ /**
1261
+ * Whether the element's docking group, moved so the element stands at `pose`, runs a body into another body of this set
1262
+ * or of `otherSets` (a zone does not count, a slot guest at its carrier as everywhere); the group stays where it is.
1263
+ */
1264
+ }, {
1265
+ key: "isBodyBlockedAt",
1266
+ value: function isBodyBlockedAt(elementId, pose, otherSets) {
1267
+ var element = this.plannerElements.get(elementId);
1268
+ if (!element) return true;
1269
+ var group = this.getDockingGroupOf(element);
1270
+ var saved = group.map(function (member) {
1271
+ return {
1272
+ member: member,
1273
+ center: member.WorldPosCenter,
1274
+ rotDeg: member.RotDeg
1275
+ };
1276
+ });
1277
+ moveGroupRigidly(group, poseOf(element), pose);
1278
+ var drag = this.createRoomDrag(elementId, false, otherSets);
1279
+ if (drag) drag.zonesBlock = false;
1280
+ var blocked = !!drag && this.isBlocked(drag, drag.start);
1281
+ var _iterator9 = _createForOfIteratorHelper(saved),
1282
+ _step9;
1283
+ try {
1284
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
1285
+ var _step9$value = _step9.value,
1286
+ member = _step9$value.member,
1287
+ center = _step9$value.center,
1288
+ rotDeg = _step9$value.rotDeg;
1289
+ member.WorldPosCenter = center;
1290
+ member.RotDeg = rotDeg;
1291
+ }
1292
+ } catch (err) {
1293
+ _iterator9.e(err);
1294
+ } finally {
1295
+ _iterator9.f();
1296
+ }
1297
+ return blocked;
1298
+ }
1299
+ }, {
1300
+ key: "startRoomDrag",
1301
+ value: function startRoomDrag(elementId) {
1302
+ this.roomDrag = undefined;
1303
+ var drag = this.createRoomDrag(elementId);
1304
+ if (!drag) return;
1305
+ drag.zonesBlock = false;
1306
+ var moved = this.movedShapes(drag, drag.start);
1307
+ var _iterator10 = _createForOfIteratorHelper(drag.obstacles),
1308
+ _step10;
1309
+ try {
1310
+ var _loop = function _loop() {
1311
+ var obstacle = _step10.value;
1312
+ // A guest standing in its slot as far under its carrier as the slot lets it (a chair at the table) overlaps by right.
1313
+ var depths = moved.map(function (member) {
1314
+ var _obstacle$rules;
1315
+ return slotExempt(drag.rules, member, (_obstacle$rules = obstacle.rules) !== null && _obstacle$rules !== void 0 ? _obstacle$rules : drag.rules, obstacle) ? 0 : bodiesOverlap(member.shape, obstacle.shape);
1316
+ });
1317
+ if (depths.some(function (depth) {
1318
+ return depth > 0;
1319
+ })) drag.startOverlaps.set(obstacle, depths);
1320
+ };
1321
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
1322
+ _loop();
1323
+ }
1324
+ } catch (err) {
1325
+ _iterator10.e(err);
1326
+ } finally {
1327
+ _iterator10.f();
1328
+ }
1329
+ this.roomDrag = drag;
1330
+ }
1331
+
1332
+ /**
1333
+ * The element's group as one block where it stands, with its followers (see `getFollowers`): the members' and the
1334
+ * followers' shapes and every obstacle but them; not started. A forced group's block is its own, any other group's
1335
+ * takes in the followers, so the room rule keeps them inside too.
1336
+ */
1337
+ }, {
1338
+ key: "createRoomDrag",
1339
+ value: function createRoomDrag(elementId) {
1340
+ var _this17 = this;
1341
+ var measured = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1342
+ var otherSets = arguments.length > 2 ? arguments[2] : undefined;
1343
+ var element = this.plannerElements.get(elementId);
1344
+ if (!element) return undefined;
1345
+ var members = this.getDockingGroupOf(element);
1346
+ if (members.every(function (member) {
1347
+ return member.IsAccessoire;
1348
+ })) return undefined;
1349
+ var followers = this.getFollowers(members);
1350
+ var wallMode = this.getGroupWallMode(members);
1351
+ var frame = this.getRoomFrame(members, element);
1352
+ var start = wallMode === 'forced' ? this.getRoomBlock(members, frame) : getGroupBlock([].concat(_toConsumableArray(members), _toConsumableArray(followers)), frame.RotDeg);
1353
+ var position = element.WorldPosCenter;
1354
+ var followerShapes = getDockingGroups(followers).filter(function (group) {
1355
+ return _this17.collides(group);
1356
+ }).flatMap(function (group) {
1357
+ return _this17.getCollidingShapes(group, measured);
1358
+ });
1359
+ var memberShapes = this.collides(members) ? this.getCollidingShapes(members, measured) : [];
1360
+ var drag = {
1361
+ elementId: elementId,
1362
+ members: members,
1363
+ followers: followers,
1364
+ start: start,
1365
+ current: start,
1366
+ grabbedStart: {
1367
+ x: position.x,
1368
+ z: position.z
1369
+ },
1370
+ grabbedStartRotDeg: element.RotDeg,
1371
+ dx: 0,
1372
+ dz: 0,
1373
+ wallMode: wallMode,
1374
+ shapes: this.collides(members) ? [].concat(_toConsumableArray(memberShapes), _toConsumableArray(followerShapes)) : [],
1375
+ memberShapes: memberShapes.length,
1376
+ obstacles: this.getObstacles(members, measured, [].concat(_toConsumableArray(members), _toConsumableArray(followers)), otherSets),
1377
+ blockedBy: [],
1378
+ startOverlaps: new Map(),
1379
+ rules: this.getCatalogData().placementOptions.rules,
1380
+ zonesBlock: true,
1381
+ rotating: false,
1382
+ slotSnapped: false
1383
+ };
1384
+ return drag;
1385
+ }
1386
+
1387
+ /**
1388
+ * A group placed beside the planning, or by the room rules, that stands on another group (of this set or another set in
1389
+ * the room) or in a door's clearance goes to the nearest free pose, by the room rule of its wall mode, and slides back
1390
+ * until it touches what it was cleared of. It stays where it is when the room has no free pose for it.
1391
+ */
1392
+ }, {
1393
+ key: "moveClearOfObstacles",
1394
+ value: function moveClearOfObstacles(elementId, room) {
1395
+ var drag = this.createRoomDrag(elementId);
1396
+ if (!drag || !this.isBlocked(drag, drag.start)) return;
1397
+ var _drag$start = drag.start,
1398
+ block = _drag$start.block,
1399
+ rotDeg = _drag$start.rotDeg;
1400
+ _drag$start.center;
1401
+ var poseAt = function poseAt(raw) {
1402
+ return drag.wallMode === 'forced' ? bindToWalls(raw, block, room) : insidePose(block, {
1403
+ center: raw,
1404
+ rotDeg: rotDeg
1405
+ }, room);
1406
+ };
1407
+ var xs = room.footprint.map(function (_ref6) {
1408
+ var _ref7 = _slicedToArray(_ref6, 1),
1409
+ x = _ref7[0];
1410
+ return x;
1411
+ });
1412
+ var zs = room.footprint.map(function (_ref8) {
1413
+ var _ref9 = _slicedToArray(_ref8, 2),
1414
+ z = _ref9[1];
1415
+ return z;
1416
+ });
1417
+ var reach = Math.hypot(Math.max.apply(Math, _toConsumableArray(xs)) - Math.min.apply(Math, _toConsumableArray(xs)), Math.max.apply(Math, _toConsumableArray(zs)) - Math.min.apply(Math, _toConsumableArray(zs)));
1418
+ var target = this.nearestFreePose(drag, drag.start, poseAt, reach);
1419
+ if (target) moveGroupRigidly([].concat(_toConsumableArray(drag.members), _toConsumableArray(drag.followers)), drag.start, target);
1420
+ }
1421
+
1422
+ // Of the free poses on the first ring around `origin` that has one, slid back until they touch, the nearest one.
1423
+ }, {
1424
+ key: "nearestFreePose",
1425
+ value: function nearestFreePose(drag, origin, poseAt, reach) {
1426
+ var center = origin.center;
1427
+ for (var radius = CLEAR_SEARCH_STEP; radius <= reach; radius += CLEAR_SEARCH_STEP) {
1428
+ var nearest = void 0;
1429
+ for (var i = 0; i < CLEAR_SEARCH_DIRECTIONS; i++) {
1430
+ var _this$slideToContact;
1431
+ var angle = i / CLEAR_SEARCH_DIRECTIONS * 2 * Math.PI;
1432
+ var pose = poseAt({
1433
+ x: center.x + radius * Math.cos(angle),
1434
+ z: center.z + radius * Math.sin(angle)
1435
+ });
1436
+ if (!pose || this.isBlocked(drag, pose)) continue;
1437
+ drag.current = pose;
1438
+ var slid = (_this$slideToContact = this.slideToContact(drag, origin)) === null || _this$slideToContact === void 0 ? void 0 : _this$slideToContact.pose;
1439
+ // The way back may cross a notch of the room: the slid pose counts only where the room rule keeps it.
1440
+ var kept = slid && poseAt(slid.center);
1441
+ var target = slid && kept && Math.hypot(kept.center.x - slid.center.x, kept.center.z - slid.center.z) < 0.5 ? slid : pose;
1442
+ var distance = Math.hypot(target.center.x - center.x, target.center.z - center.z);
1443
+ if (!nearest || distance < nearest.distance - START_NOISE) nearest = {
1444
+ pose: target,
1445
+ distance: distance
1446
+ };
1447
+ }
1448
+ if (nearest) return nearest.pose;
1449
+ }
1450
+ return undefined;
1451
+ }
1452
+
1453
+ /**
1454
+ * Puts a new element at the first free place a slot of the `isCarrier` groups suggests (lowest PosNr first, planner
1455
+ * data only), numbers it last (PosNrAtEnd) and makes it a guest of the carrier (see `attachToSlot`); false, the element
1456
+ * unmoved, when no place is free.
1457
+ */
1458
+ }, {
1459
+ key: "placeAtSuggestedPlace",
1460
+ value: function placeAtSuggestedPlace(element, isCarrier) {
1461
+ var _this18 = this;
1462
+ var _ref10 = element.IsAccessoire ? [] : this.getPlacementTypes(element),
1463
+ _ref11 = _slicedToArray(_ref10, 1),
1464
+ type = _ref11[0];
1465
+ if (!type) return false;
1466
+ var rules = this.getCatalogData().placementOptions.rules;
1467
+ var before = {
1468
+ center: {
1469
+ x: element.WorldPosCenter.x,
1470
+ z: element.WorldPosCenter.z
1471
+ },
1472
+ rotDeg: element.RotDeg
1473
+ };
1474
+ var body = getElementShape(element, false).body[0];
1475
+ var outline = function outline(rotDeg) {
1476
+ return movePoints(body, before, {
1477
+ center: {
1478
+ x: 0,
1479
+ z: 0
1480
+ },
1481
+ rotDeg: rotDeg
1482
+ });
1483
+ };
1484
+ var lowestPosNr = function lowestPosNr(group) {
1485
+ return Math.min.apply(Math, _toConsumableArray(group.map(function (member) {
1486
+ return member.PosNr;
1487
+ })));
1488
+ };
1489
+ var carriers = getDockingGroups(this.getAllPlannerElements().filter(function (other) {
1490
+ return other !== element;
1491
+ })).filter(function (group) {
1492
+ return isCarrier(group) && group.some(function (member) {
1493
+ return !member.IsAccessoire;
1494
+ });
1495
+ }).sort(function (a, b) {
1496
+ return lowestPosNr(a) - lowestPosNr(b);
1497
+ });
1498
+ var otherSets = carriers.length > 0 ? this.getOtherCollisionSets() : [];
1499
+ var _iterator11 = _createForOfIteratorHelper(carriers),
1500
+ _step11;
1501
+ try {
1502
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
1503
+ var group = _step11.value;
1504
+ var _iterator12 = _createForOfIteratorHelper(getCarrierSlots(rules, this.getSlotMembers(group), type)),
1505
+ _step12;
1506
+ try {
1507
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
1508
+ var slot = _step12.value;
1509
+ if (!getSlotPlaces(slot, outline).some(function (place) {
1510
+ return _this18.fitsAt(element, place, otherSets);
1511
+ })) continue;
1512
+ element.PosNrAtEnd = true;
1513
+ this.attachToSlot(element, slot);
1514
+ return true;
1515
+ }
1516
+ } catch (err) {
1517
+ _iterator12.e(err);
1518
+ } finally {
1519
+ _iterator12.f();
1520
+ }
1521
+ }
1522
+ } catch (err) {
1523
+ _iterator11.e(err);
1524
+ } finally {
1525
+ _iterator11.f();
1526
+ }
1527
+ element.WorldPosCenter = new Vector3(before.center.x, element.WorldPosCenter.y, before.center.z);
1528
+ element.RotDeg = before.rotDeg;
1529
+ return false;
1530
+ }
1531
+
1532
+ // Makes the element a guest of the member of `slot` nearest to it: it goes with that carrier from now on. Not when the
1533
+ // carrier is a guest MAX_GUEST_DEPTH deep itself.
1534
+ }, {
1535
+ key: "attachToSlot",
1536
+ value: function attachToSlot(element, slot) {
1537
+ var _getNearestMember;
1538
+ var basketId = (_getNearestMember = getNearestMember(slot, poseOf(element).center)) === null || _getNearestMember === void 0 ? void 0 : _getNearestMember.basketId;
1539
+ var carrier = basketId ? this.getElementByBasketId(basketId) : undefined;
1540
+ if (!basketId || !carrier || this.getGuestDepth(carrier) >= MAX_GUEST_DEPTH) return;
1541
+ var offset = toPlacementOffset(poseOf(carrier), poseOf(element));
1542
+ element.Placement = {
1543
+ carrierBasketId: basketId,
1544
+ slotId: slot.id,
1545
+ offset: offset
1546
+ };
1547
+ }
1548
+
1549
+ // How many carriers stand above the element: 0 on its own, 1 at a carrier on its own, …
1550
+ }, {
1551
+ key: "getGuestDepth",
1552
+ value: function getGuestDepth(element) {
1553
+ var depth = 0;
1554
+ for (var carrier = this.getCarrierOf(element); carrier && depth <= MAX_GUEST_DEPTH; carrier = this.getCarrierOf(carrier)) depth++;
1555
+ return depth;
1556
+ }
1557
+
1558
+ // Moves the element to `pose` as the room rule keeps it; whether it fits there: the rule moves it no further than the
1559
+ // tolerance and it collides with nothing of this set or of `otherSets`.
1560
+ }, {
1561
+ key: "fitsAt",
1562
+ value: function fitsAt(element, pose, otherSets) {
1563
+ element.WorldPosCenter = new Vector3(pose.center.x, this.plannerBoundingBox.WorldPos.y, pose.center.z);
1564
+ element.RotDeg = pose.rotDeg;
1565
+ var drag = this.createRoomDrag(element.ElementId, false, otherSets);
1566
+ var kept = drag && this.getKeptPose(drag);
1567
+ if (!drag || !kept) return false;
1568
+ moveGroupRigidly(drag.members, drag.start, kept);
1569
+ return !this.isBlocked(drag, kept);
1570
+ }
1571
+
1572
+ // Where the room rule of its wall mode keeps the drag's group standing at `pose` (no room: the pose); undefined when it
1573
+ // would move the group further than `tolerance`, turn it, or fit it on no wall.
1574
+ }, {
1575
+ key: "getKeptPose",
1576
+ value: function getKeptPose(drag) {
1577
+ var pose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : drag.start;
1578
+ var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : PLACE_TOLERANCE;
1579
+ var room = this.room;
1580
+ if (!room) return pose;
1581
+ var block = drag.start.block;
1582
+ var center = pose.center,
1583
+ rotDeg = pose.rotDeg;
1584
+ var kept = drag.wallMode === 'forced' ? bindToWalls(center, block, room) : insidePose(block, pose, room);
1585
+ if (!kept || Math.hypot(kept.center.x - center.x, kept.center.z - center.z) > tolerance) return undefined;
1586
+ return Math.abs(getTurnDeg(rotDeg, kept.rotDeg)) > 0.01 ? undefined : kept;
1587
+ }
1588
+
1589
+ // The colliding members and followers of the dragged group, moved with it to `pose`, each group's carrier outlines too.
1590
+ }, {
1591
+ key: "movedShapes",
1592
+ value: function movedShapes(drag, pose) {
1593
+ var movedGroups = new Map();
1594
+ return drag.shapes.map(function (member) {
1595
+ var _movedGroups$get;
1596
+ var group = (_movedGroups$get = movedGroups.get(member.group)) !== null && _movedGroups$get !== void 0 ? _movedGroups$get : member.group.map(function (slotMember) {
1597
+ return moveSlotMember(slotMember, drag.start, pose);
1598
+ });
1599
+ movedGroups.set(member.group, group);
1600
+ return _objectSpread(_objectSpread({}, member), {}, {
1601
+ shape: moveShape(member.shape, drag.start, pose),
1602
+ group: group
1603
+ });
1604
+ });
1605
+ }
1606
+
1607
+ // Whether a member collides with an obstacle: body against body (a pair that overlapped at the start once it gets
1608
+ // deeper), and where zones block, a body in the other's free area. A guest standing in a slot of its carrier's group may
1609
+ // stand in the carrier's free area (a hocker in front of the sofa), and reach under its body as far as the slot lets it
1610
+ // (a chair's seat under the table top). Two layers only as the catalog lets them collide, as in the collision warning.
1611
+ }, {
1612
+ key: "overlapsAny",
1613
+ value: function overlapsAny(moved, obstacle, drag) {
1614
+ var startDepths = drag.startOverlaps.get(obstacle);
1615
+ var collidingLayers = this.getCatalogData().checkCollisionForDifferentLayers;
1616
+ return moved.some(function (member, i) {
1617
+ var _obstacle$rules2;
1618
+ if (obstacle.layer !== undefined && !layersCollide(collidingLayers, member.layer, obstacle.layer)) return false;
1619
+ if (startDepths) return bodiesOverlap(member.shape, obstacle.shape) > startDepths[i] + DEPTH_NOISE;
1620
+ return shapesCollide(member.shape, obstacle.shape, !drag.zonesBlock) && !slotExempt(drag.rules, member, (_obstacle$rules2 = obstacle.rules) !== null && _obstacle$rules2 !== void 0 ? _obstacle$rules2 : drag.rules, obstacle);
1621
+ });
1622
+ }
1623
+ }, {
1624
+ key: "isBlocked",
1625
+ value: function isBlocked(drag, pose) {
1626
+ var _this19 = this;
1627
+ var moved = this.movedShapes(drag, pose);
1628
+ return drag.obstacles.some(function (obstacle) {
1629
+ return _this19.overlapsAny(moved, obstacle, drag);
1630
+ });
1631
+ }
1632
+
1633
+ // The obstacles the group runs into at `pose`.
1634
+ }, {
1635
+ key: "blockersAt",
1636
+ value: function blockersAt(drag, pose) {
1637
+ var _this20 = this;
1638
+ var moved = this.movedShapes(drag, pose);
1639
+ return drag.obstacles.filter(function (obstacle) {
1640
+ return _this20.overlapsAny(moved, obstacle, drag);
1641
+ });
1642
+ }
1643
+
1644
+ // The straight way from the current pose to `target`, checked every PATH_STEP and cut at the first contact: the
1645
+ // furthest free pose before it (none when the group cannot move at all), so a blocked group ends up touching, and the
1646
+ // obstacles it runs into just beyond; `target` and none when the whole way is free. Undefined when the way turns the group.
1647
+ }, {
1648
+ key: "slideToContact",
1649
+ value: function slideToContact(drag, target) {
1650
+ if (Math.abs(getTurnDeg(drag.current.rotDeg, target.rotDeg)) > 0.01) return undefined;
1651
+ var from = drag.current.center;
1652
+ var at = function at(s) {
1653
+ return {
1654
+ center: {
1655
+ x: from.x + (target.center.x - from.x) * s,
1656
+ z: from.z + (target.center.z - from.z) * s
1657
+ },
1658
+ rotDeg: target.rotDeg
1659
+ };
1660
+ };
1661
+ var steps = Math.max(1, Math.ceil(Math.hypot(target.center.x - from.x, target.center.z - from.z) / PATH_STEP));
1662
+ var free = 0;
1663
+ for (var step = 1; step <= steps; step++) {
1664
+ var blocked = step / steps;
1665
+ if (!this.isBlocked(drag, at(blocked))) {
1666
+ free = blocked;
1667
+ continue;
1668
+ }
1669
+ for (var i = 0; i < 12; i++) {
1670
+ var mid = (free + blocked) / 2;
1671
+ if (this.isBlocked(drag, at(mid))) blocked = mid;else free = mid;
1672
+ }
1673
+ return {
1674
+ pose: free > 0 ? at(free) : undefined,
1675
+ blockers: this.blockersAt(drag, at(blocked))
1676
+ };
1677
+ }
1678
+ return {
1679
+ pose: target,
1680
+ blockers: []
1681
+ };
1682
+ }
1683
+
1684
+ // The group follows the grabbed element rigidly to the wall or inside-room pose of the raw centre, also where it runs
1685
+ // into an obstacle: what it runs into there is kept as `blockedBy` (the viewer shows the drag blocked, a release there
1686
+ // goes back to the start). A forced group that fits on no wall is kept inside the room like a free one. Back at the
1687
+ // start (a cancel, a blocked release) it stands exactly where it started, nothing snaps.
1688
+ }, {
1689
+ key: "updateRoomDrag",
1690
+ value: function updateRoomDrag(room, drag, deltaMove) {
1691
+ drag.dx += deltaMove.x;
1692
+ drag.dz += deltaMove.z;
1693
+ var _drag$start2 = drag.start,
1694
+ block = _drag$start2.block,
1695
+ rotDeg = _drag$start2.rotDeg;
1696
+ var rawCenter = {
1697
+ x: drag.start.center.x + drag.dx,
1698
+ z: drag.start.center.z + drag.dz
1699
+ };
1700
+ var atStart = Math.hypot(drag.dx, drag.dz) <= START_NOISE;
1701
+ // A free slot place near the pointer comes before the wall.
1702
+ var slotPose = atStart ? undefined : this.getSlotSnapPose(drag);
1703
+ var wallPose = atStart || slotPose || drag.wallMode === 'free' ? null : bindToWalls(rawCenter, block, room);
1704
+ var snapsToWall = !!wallPose && Math.hypot(wallPose.center.x - rawCenter.x, wallPose.center.z - rawCenter.z) <= WALL_SNAP_DISTANCE;
1705
+ var startPose = {
1706
+ center: drag.start.center,
1707
+ rotDeg: rotDeg
1708
+ };
1709
+ var wanted = atStart ? startPose : slotPose !== null && slotPose !== void 0 ? slotPose : wallPose && (drag.wallMode === 'forced' || snapsToWall) ? wallPose : insidePose(block, {
1710
+ center: rawCenter,
1711
+ rotDeg: rotDeg
1712
+ }, room);
1713
+ drag.blockedBy = this.blockersAt(drag, wanted);
1714
+ moveGroupRigidly([].concat(_toConsumableArray(drag.members), _toConsumableArray(drag.followers)), drag.current, wanted);
1715
+ drag.current = wanted;
1716
+ drag.slotSnapped = !!slotPose;
1717
+ // A pair that overlapped at the start may only come apart, never go back in.
1718
+ if (drag.startOverlaps.size === 0) return;
1719
+ var moved = this.movedShapes(drag, wanted);
1720
+ drag.startOverlaps.forEach(function (depths, obstacle) {
1721
+ return drag.startOverlaps.set(obstacle, depths.map(function (depth, i) {
1722
+ return Math.min(depth, bodiesOverlap(moved[i].shape, obstacle.shape));
1723
+ }));
1724
+ });
1725
+ }
1726
+
1727
+ // The unit moved rigidly onto the nearest dock of `element` outside it (see findDockSnap), else with `slots` into the
1728
+ // nearest free slot place (see findSlotSnap).
1729
+ }, {
1730
+ key: "snapToDock",
1731
+ value: function snapToDock(element, unit, autoDockingDistance, slots) {
1732
+ var _this$findDockSnap2;
1733
+ var unitIds = unit.map(function (member) {
1734
+ return member.ElementId;
1735
+ });
1736
+ var snap = (_this$findDockSnap2 = this.findDockSnap(element, autoDockingDistance, unitIds)) !== null && _this$findDockSnap2 !== void 0 ? _this$findDockSnap2 : slots ? this.findSlotSnap(element) : null;
1737
+ if (!snap) return;
1738
+ var move = this.snapMove(element, snap);
1739
+ moveGroupRigidly(unit, move.from, move.to);
1740
+ }
1741
+
1742
+ // The unit of a drag starting at the element: in a room the drag's group, else the element (the viewer's UPDATEs add the
1743
+ // rest of its group), with the guests that go along; and the free slot places it may snap into.
1744
+ }, {
1745
+ key: "startDragUnit",
1746
+ value: function startDragUnit(elementId, roomDrag) {
1747
+ var _roomDrag$followers, _roomDrag$members$map;
1748
+ var element = this.plannerElements.get(elementId);
1749
+ var followers = (_roomDrag$followers = roomDrag === null || roomDrag === void 0 ? void 0 : roomDrag.followers) !== null && _roomDrag$followers !== void 0 ? _roomDrag$followers : element ? this.getFollowers(this.getDockingGroupOf(element)) : [];
1750
+ this.dragFollowers = new Set(followers.map(function (follower) {
1751
+ return follower.ElementId;
1752
+ }));
1753
+ this.dragUnit = new Set([elementId].concat(_toConsumableArray((_roomDrag$members$map = roomDrag === null || roomDrag === void 0 ? void 0 : roomDrag.members.map(function (member) {
1754
+ return member.ElementId;
1755
+ })) !== null && _roomDrag$members$map !== void 0 ? _roomDrag$members$map : []), _toConsumableArray(this.dragFollowers)));
1756
+ var unit = element ? [].concat(_toConsumableArray(this.getDockingGroupOf(element)), _toConsumableArray(followers)) : [];
1757
+ this.dragSlots = element ? {
1758
+ elementId: elementId,
1759
+ start: poseOf(element).center,
1760
+ places: this.findDragSlotPlaces(element, unit)
1761
+ } : undefined;
1762
+ }
1763
+
1764
+ // Where the group shows against where the pointer put the grabbed element, and what it runs into there.
1765
+ }, {
1766
+ key: "getRoomDragPreview",
1767
+ value: function getRoomDragPreview(element, drag) {
1768
+ var position = element.WorldPosCenter;
1769
+ var preview = {
1770
+ dx: position.x - (drag.grabbedStart.x + drag.dx),
1771
+ dz: position.z - (drag.grabbedStart.z + drag.dz),
1772
+ dRotDeg: getTurnDeg(drag.start.rotDeg, element.RotDeg)
1773
+ };
1774
+ return this.withDragBlock(preview, drag);
1775
+ }
1776
+
1777
+ // What a free group being turned runs into where it is turned now (it moves no further than the turn: no offset). Only
1778
+ // its members count: a guest swung into a body leaves its carrier on release instead (see DivaPlannerHandler).
1779
+ }, {
1780
+ key: "getRoomTurnPreview",
1781
+ value: function getRoomTurnPreview(element, drag) {
1782
+ var members = _objectSpread(_objectSpread({}, drag), {}, {
1783
+ shapes: drag.shapes.slice(0, drag.memberShapes)
1784
+ });
1785
+ drag.blockedBy = this.blockersAt(members, this.getTurnedPose(element, drag));
1786
+ return this.withDragBlock({
1787
+ dx: 0,
1788
+ dz: 0,
1789
+ dRotDeg: 0
1790
+ }, drag);
1791
+ }
1792
+
1793
+ // A blocked turn's release: at its angle, the nearest free place inside the room within reach; undefined when none.
1794
+ }, {
1795
+ key: "findTurnPlace",
1796
+ value: function findTurnPlace(element, drag, room) {
1797
+ var turned = this.getTurnedPose(element, drag);
1798
+ var block = drag.start.block;
1799
+ var members = _objectSpread(_objectSpread({}, drag), {}, {
1800
+ shapes: drag.shapes.slice(0, drag.memberShapes),
1801
+ current: turned
1802
+ });
1803
+ if (!this.isBlocked(members, turned)) return turned;
1804
+ var poseAt = function poseAt(raw) {
1805
+ return insidePose(block, {
1806
+ center: raw,
1807
+ rotDeg: turned.rotDeg
1808
+ }, room);
1809
+ };
1810
+ return this.nearestFreePose(members, turned, poseAt, Math.max(TURN_PLACE_REACH, 2 * Math.max(block.halfWidth, block.halfDepth)));
1811
+ }
1812
+
1813
+ // The pose of the group's block where the grabbed element stands now, moved with it rigidly from the start.
1814
+ }, {
1815
+ key: "getTurnedPose",
1816
+ value: function getTurnedPose(element, drag) {
1817
+ return movePose(drag.start, {
1818
+ center: drag.grabbedStart,
1819
+ rotDeg: drag.grabbedStartRotDeg
1820
+ }, poseOf(element));
1821
+ }
1822
+
1823
+ // `preview` with what the group runs into (`blockedBy`): the elements, and whether a door's clearance; as it is while free.
1824
+ }, {
1825
+ key: "withDragBlock",
1826
+ value: function withDragBlock(preview, drag) {
1827
+ if (drag.blockedBy.length === 0) return preview;
1828
+ var ownSetId = this.set.getSetId();
1829
+ var elements = [];
1830
+ var _iterator13 = _createForOfIteratorHelper(drag.blockedBy),
1831
+ _step13;
1832
+ try {
1833
+ var _loop2 = function _loop2() {
1834
+ var _step13$value = _step13.value,
1835
+ _step13$value$setId = _step13$value.setId,
1836
+ setId = _step13$value$setId === void 0 ? ownSetId : _step13$value$setId,
1837
+ elementId = _step13$value.elementId;
1838
+ if (elementId !== undefined && !elements.some(function (element) {
1839
+ return element.setId === setId && element.elementId === elementId;
1840
+ })) elements.push({
1841
+ setId: setId,
1842
+ elementId: elementId
1843
+ });
1844
+ };
1845
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
1846
+ _loop2();
1847
+ }
1848
+ } catch (err) {
1849
+ _iterator13.e(err);
1850
+ } finally {
1851
+ _iterator13.f();
1852
+ }
1853
+ return _objectSpread(_objectSpread({}, preview), {}, {
1854
+ blockedBy: {
1855
+ elements: elements,
1856
+ door: drag.blockedBy.some(function (obstacle) {
1857
+ return obstacle.elementId === undefined;
1858
+ })
1859
+ }
1860
+ });
1861
+ }
1862
+
318
1863
  /**
319
1864
  * This function updates the position information of all elements. It is called after updating the SVG of 1 element.
320
1865
  * The position is updated based on the posNr.
@@ -372,11 +1917,11 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
372
1917
  var progressed = true;
373
1918
  while (progressed) {
374
1919
  progressed = false;
375
- var _iterator = _createForOfIteratorHelper(sortedPlannerElementsbyPosNr),
376
- _step;
1920
+ var _iterator14 = _createForOfIteratorHelper(sortedPlannerElementsbyPosNr),
1921
+ _step14;
377
1922
  try {
378
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
379
- var _element = _step.value;
1923
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
1924
+ var _element = _step14.value;
380
1925
  if (!_element || moved.has(_element.ElementId)) continue;
381
1926
  var dpToMovedPartner = getDockedDPsInPriorityOrder(_element).find(function (dp) {
382
1927
  return moved.has(dp.OnElementId);
@@ -388,9 +1933,9 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
388
1933
  }
389
1934
  }
390
1935
  } catch (err) {
391
- _iterator.e(err);
1936
+ _iterator14.e(err);
392
1937
  } finally {
393
- _iterator.f();
1938
+ _iterator14.f();
394
1939
  }
395
1940
  }
396
1941
  }
@@ -411,8 +1956,14 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
411
1956
  key: "addElementToWorld",
412
1957
  value: (function () {
413
1958
  var _addElementToWorld = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(plannerElement, dockingPointInfos, suppressDock, globalBoundingBox) {
1959
+ var _this21 = this;
414
1960
  var xOffset,
415
1961
  setToTransform,
1962
+ placedBeside,
1963
+ _setToTransform$trans,
1964
+ worldPosCenter,
1965
+ height,
1966
+ stoodOnFloor,
416
1967
  dockingFound,
417
1968
  i,
418
1969
  targetElemIdToDock,
@@ -421,78 +1972,89 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
421
1972
  targetDP,
422
1973
  successDP,
423
1974
  success,
424
- allPlannerElements,
1975
+ selectedId,
1976
+ atSelected,
1977
+ mayPlace,
1978
+ placed,
425
1979
  _success,
1980
+ allPlannerElements,
426
1981
  _args = arguments;
427
1982
  return _regeneratorRuntime.wrap(function _callee$(_context) {
428
1983
  while (1) switch (_context.prev = _context.next) {
429
1984
  case 0:
430
1985
  xOffset = _args.length > 4 && _args[4] !== undefined ? _args[4] : 100;
431
1986
  setToTransform = _args.length > 5 ? _args[5] : undefined;
1987
+ // Docked to nothing: put beside the planning, where it may land on another group in the room.
1988
+ placedBeside = false;
432
1989
  if (!(setToTransform && setToTransform.forceSetToTrans)) {
433
- _context.next = 8;
1990
+ _context.next = 13;
434
1991
  break;
435
1992
  }
436
- plannerElement.WorldPosCenter = setToTransform.transform.worldPosCenter;
1993
+ // A switched element keeps the place of the old one; if that stood on the floor, the new one stands there too.
1994
+ _setToTransform$trans = setToTransform.transform, worldPosCenter = _setToTransform$trans.worldPosCenter, height = _setToTransform$trans.height;
1995
+ stoodOnFloor = PlannerElementData.standsOnFloor(worldPosCenter.y, height);
1996
+ plannerElement.WorldPosCenter = stoodOnFloor && Number.isFinite(plannerElement.Height) ? new Vector3(worldPosCenter.x, plannerElement.Height / 2, worldPosCenter.z) : worldPosCenter;
437
1997
  plannerElement.RotDeg = setToTransform.transform.rotDeg;
1998
+ plannerElement.PosNrAtEnd = !!setToTransform.transform.posNrAtEnd;
1999
+ plannerElement.Placement = setToTransform.transform.placement;
438
2000
  this.set.onDockingChanged(plannerElement.ElementId, -1, 'NOT_DOCKED');
439
- _context.next = 48;
2001
+ _context.next = 52;
440
2002
  break;
441
- case 8:
2003
+ case 13:
442
2004
  //Nun unterscheidet man, ob man das Element zu einem bestimmten vorselektierten Element Docken will , zu einem vorselektierten DockingPoint oder an eine Freie Planung.
443
2005
  dockingFound = false;
444
2006
  if (!dockingPointInfos) {
445
- _context.next = 47;
2007
+ _context.next = 51;
446
2008
  break;
447
2009
  }
448
2010
  i = 0;
449
- case 11:
2011
+ case 16:
450
2012
  if (!(i < dockingPointInfos.length)) {
451
- _context.next = 47;
2013
+ _context.next = 51;
452
2014
  break;
453
2015
  }
454
2016
  targetElemIdToDock = dockingPointInfos[i].targetElemIdToDock;
455
2017
  targetDockingPointId = dockingPointInfos[i].targetDockingPointId;
456
2018
  if (!(targetElemIdToDock && targetElemIdToDock > -1 && this.plannerElements.has(targetElemIdToDock))) {
457
- _context.next = 44;
2019
+ _context.next = 48;
458
2020
  break;
459
2021
  }
460
2022
  if (!(targetDockingPointId && targetDockingPointId != '')) {
461
- _context.next = 32;
2023
+ _context.next = 37;
462
2024
  break;
463
2025
  }
464
2026
  targetElem = this.plannerElements.get(targetElemIdToDock);
465
2027
  if (!targetElem) {
466
- _context.next = 30;
2028
+ _context.next = 35;
467
2029
  break;
468
2030
  }
469
2031
  targetDP = targetElem.getDockingPointById(targetDockingPointId);
470
2032
  if (!targetDP) {
471
- _context.next = 30;
2033
+ _context.next = 35;
472
2034
  break;
473
2035
  }
474
2036
  successDP = dockingPointHandlerInst.tryDockElementToDP(plannerElement, targetElem, targetDP);
475
2037
  if (!successDP) {
476
- _context.next = 26;
2038
+ _context.next = 31;
477
2039
  break;
478
2040
  }
479
2041
  this.updateWorldPos(plannerElement, successDP);
480
2042
  dockingFound = true;
481
- _context.next = 30;
2043
+ _context.next = 35;
482
2044
  break;
483
- case 26:
484
- _context.next = 28;
2045
+ case 31:
2046
+ _context.next = 33;
485
2047
  return this.tryToDockWithDifferentSVGWithFormula(plannerElement, targetElemIdToDock);
486
- case 28:
2048
+ case 33:
487
2049
  if (!_context.sent) {
488
- _context.next = 30;
2050
+ _context.next = 35;
489
2051
  break;
490
2052
  }
491
2053
  dockingFound = true;
492
- case 30:
493
- _context.next = 44;
2054
+ case 35:
2055
+ _context.next = 48;
494
2056
  break;
495
- case 32:
2057
+ case 37:
496
2058
  success = false;
497
2059
  if (plannerElement.HasAVL || plannerElement.HasAVR) {
498
2060
  success = this.dockToAVLorAVR(plannerElement, [this.plannerElements.get(targetElemIdToDock)]);
@@ -501,55 +2063,72 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
501
2063
  success = this.dockToAVUorAVOororAVNorAVSorAVC(plannerElement, [this.plannerElements.get(targetElemIdToDock)]);
502
2064
  }
503
2065
  if (success) {
504
- _context.next = 43;
2066
+ _context.next = 47;
505
2067
  break;
506
2068
  }
507
- _context.next = 38;
2069
+ _context.next = 43;
508
2070
  return this.tryToDockWithDifferentSVGWithFormula(plannerElement, targetElemIdToDock);
509
- case 38:
2071
+ case 43:
510
2072
  success = _context.sent;
511
2073
  if (success) {
512
- _context.next = 43;
2074
+ _context.next = 47;
513
2075
  break;
514
2076
  }
515
- _context.next = 42;
516
- return this.addElementToWorld(plannerElement, undefined, undefined, undefined, 50);
517
- case 42:
518
- return _context.abrupt("return");
519
- case 43:
2077
+ xOffset = 50;
2078
+ return _context.abrupt("break", 51);
2079
+ case 47:
520
2080
  if (success) dockingFound = true;
521
- case 44:
2081
+ case 48:
522
2082
  i++;
523
- _context.next = 11;
2083
+ _context.next = 16;
524
2084
  break;
525
- case 47:
2085
+ case 51:
526
2086
  if (!dockingFound) {
527
- allPlannerElements = this.getAllPlannerElements();
528
- _success = this.dockToAVLorAVR(plannerElement, allPlannerElements);
529
- if (suppressDock) _success = false;
530
- if (!_success) {
531
- //No free AVR or AVL Docking Point
532
- _success = this.dockToAVUorAVOororAVNorAVSorAVC(plannerElement, allPlannerElements);
2087
+ selectedId = dockingPointInfos === null || dockingPointInfos === void 0 ? void 0 : dockingPointInfos.map(function (info) {
2088
+ return info.targetElemIdToDock;
2089
+ }).find(function (id) {
2090
+ return id != null && _this21.plannerElements.has(id);
2091
+ });
2092
+ atSelected = function atSelected(group) {
2093
+ return selectedId === undefined || group.some(function (member) {
2094
+ return member.ElementId === selectedId;
2095
+ });
2096
+ };
2097
+ mayPlace = globalBoundingBox == undefined; // The places the rules suggest at the selected group (without a selection: at any group) come before docking anywhere.
2098
+ placed = mayPlace && this.placeAtSuggestedPlace(plannerElement, atSelected);
2099
+ _success = false;
2100
+ if (!placed) {
2101
+ allPlannerElements = this.getAllPlannerElements();
2102
+ _success = this.dockToAVLorAVR(plannerElement, allPlannerElements);
533
2103
  if (suppressDock) _success = false;
534
2104
  if (!_success) {
535
- //This is the center position of the element - This is needed in order to set the static room layout correctly
536
-
537
- if (globalBoundingBox == undefined) {
538
- plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + this.plannerBoundingBox.Size.x + (this.plannerBoundingBox.Size.x == 0 ? 0 : plannerElement.Width / 2 + xOffset), this.plannerBoundingBox.WorldPos.y, this.plannerBoundingBox.WorldPos.z + plannerElement.Depth / 2);
539
- }
540
-
541
- //Tell the set this the element was not docked
542
- this.set.onDockingChanged(plannerElement.ElementId, -1, 'NOT_DOCKED');
2105
+ //No free AVR or AVL Docking Point
2106
+ _success = this.dockToAVUorAVOororAVNorAVSorAVC(plannerElement, allPlannerElements);
2107
+ if (suppressDock) _success = false;
2108
+ }
2109
+ if (!_success && mayPlace && selectedId !== undefined) placed = this.placeAtSuggestedPlace(plannerElement, function (group) {
2110
+ return !atSelected(group);
2111
+ });
2112
+ }
2113
+ if (!_success) {
2114
+ //This is the center position of the element - This is needed in order to set the static room layout correctly
2115
+ if (mayPlace && !placed) {
2116
+ placedBeside = true;
2117
+ plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + this.plannerBoundingBox.Size.x + (this.plannerBoundingBox.Size.x == 0 ? 0 : plannerElement.Width / 2 + xOffset), this.plannerBoundingBox.WorldPos.y, this.plannerBoundingBox.WorldPos.z + plannerElement.Depth / 2);
543
2118
  }
2119
+
2120
+ //Tell the set this the element was not docked
2121
+ this.set.onDockingChanged(plannerElement.ElementId, -1, 'NOT_DOCKED');
544
2122
  }
545
2123
  }
546
- case 48:
2124
+ case 52:
547
2125
  this.updatePlannerPosNr();
548
2126
  this.updateAllElementsWorldPos();
549
2127
  this.updatePlannerPosNr();
2128
+ if (!plannerElement.IsAccessoire) this.placeAddedInRoom([plannerElement], placedBeside);
550
2129
  this.checkCollision(false, plannerElement.getElementId());
551
2130
  this.updatePlannerBoundingBox();
552
- case 53:
2131
+ case 58:
553
2132
  case "end":
554
2133
  return _context.stop();
555
2134
  }
@@ -737,16 +2316,16 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
737
2316
  var candidates = [];
738
2317
  var seen = new Set();
739
2318
  var collect = function collect(connectorFeature, targetFilters) {
740
- var _iterator2 = _createForOfIteratorHelper(targetFilters),
741
- _step2;
2319
+ var _iterator15 = _createForOfIteratorHelper(targetFilters),
2320
+ _step15;
742
2321
  try {
743
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
744
- var filter = _step2.value;
745
- var _iterator3 = _createForOfIteratorHelper(article.getVariantValuesInfluencingOptions([optPrefix + connectorFeature], opvPrefix + filter)),
746
- _step3;
2322
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
2323
+ var filter = _step15.value;
2324
+ var _iterator16 = _createForOfIteratorHelper(article.getVariantValuesInfluencingOptions([optPrefix + connectorFeature], opvPrefix + filter)),
2325
+ _step16;
747
2326
  try {
748
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
749
- var vv = _step3.value;
2327
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
2328
+ var vv = _step16.value;
750
2329
  var key = JSON.stringify(vv);
751
2330
  if (!seen.has(key)) {
752
2331
  seen.add(key);
@@ -754,15 +2333,15 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
754
2333
  }
755
2334
  }
756
2335
  } catch (err) {
757
- _iterator3.e(err);
2336
+ _iterator16.e(err);
758
2337
  } finally {
759
- _iterator3.f();
2338
+ _iterator16.f();
760
2339
  }
761
2340
  }
762
2341
  } catch (err) {
763
- _iterator2.e(err);
2342
+ _iterator15.e(err);
764
2343
  } finally {
765
- _iterator2.f();
2344
+ _iterator15.f();
766
2345
  }
767
2346
  };
768
2347
  //this article's AVL side (feature 89) docks against the target's AVR side and vice versa
@@ -961,23 +2540,24 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
961
2540
  i = 0;
962
2541
  case 3:
963
2542
  if (!(i < allPlannerElements.length)) {
964
- _context4.next = 13;
2543
+ _context4.next = 14;
965
2544
  break;
966
2545
  }
967
2546
  elem = allPlannerElements[i];
968
2547
  doReload = elem.updatePlannerData(this.set.getPlannerData(elem.getElementId()));
969
2548
  if (!doReload) {
970
- _context4.next = 10;
2549
+ _context4.next = 11;
971
2550
  break;
972
2551
  }
973
2552
  elemtsWhereSomethingChanged.push(elem.ElementId);
974
- _context4.next = 10;
2553
+ elem.keepOnFloorOnHeightChange();
2554
+ _context4.next = 11;
975
2555
  return handler2D.loadSVG(elem, this.set);
976
- case 10:
2556
+ case 11:
977
2557
  i++;
978
2558
  _context4.next = 3;
979
2559
  break;
980
- case 13:
2560
+ case 14:
981
2561
  elementsToDelete = [];
982
2562
  if (elemtsWhereSomethingChanged.length) {
983
2563
  LOG.debug('Configuration changed one plannerElement. UpdateDockingRelations', 'DivaStandardPlanner - updatePlanner');
@@ -989,6 +2569,11 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
989
2569
  }
990
2570
  }
991
2571
  this.updateAllElementsWorldPos(undefined, elemtsWhereSomethingChanged);
2572
+ // A resized group must not reach through a wall; where the room moved it, its collisions are checked again.
2573
+ if (this.room) {
2574
+ this.placeGroupsInRoom();
2575
+ this.checkCollision(false);
2576
+ }
992
2577
  this.updatePlannerPosNr();
993
2578
  this.updatePlannerBoundingBox();
994
2579
  }
@@ -998,7 +2583,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
998
2583
  elementIdsToUpdateSelection: elemtsWhereSomethingChanged,
999
2584
  failed: false
1000
2585
  });
1001
- case 16:
2586
+ case 17:
1002
2587
  case "end":
1003
2588
  return _context4.stop();
1004
2589
  }
@@ -1024,7 +2609,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1024
2609
  case 0:
1025
2610
  planData = parseSetPlanData(setPlanData);
1026
2611
  if (!isSavePlannerV2(planData)) {
1027
- _context5.next = 39;
2612
+ _context5.next = 42;
1028
2613
  break;
1029
2614
  }
1030
2615
  jsonElements = planData.set.elements;
@@ -1034,7 +2619,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1034
2619
  i = 0;
1035
2620
  case 7:
1036
2621
  if (!(i < jsonElements.length)) {
1037
- _context5.next = 35;
2622
+ _context5.next = 37;
1038
2623
  break;
1039
2624
  }
1040
2625
  _context5.prev = 8;
@@ -1047,7 +2632,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1047
2632
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
1048
2633
  code: 'WC_0012'
1049
2634
  }));
1050
- return _context5.abrupt("continue", 32);
2635
+ return _context5.abrupt("continue", 34);
1051
2636
  case 14:
1052
2637
  plannerElement = new PlannerElementData(this.set.getSetId(), jsonElement.basketID, this.nextElementId, DivaStandardPlanner.plannerType);
1053
2638
  oldElementidMapping.set(jsonElement.elementID, plannerElement);
@@ -1065,6 +2650,8 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1065
2650
  case 24:
1066
2651
  plannerElement.WorldPosCenter = new Vector3(globalBoundingBox.WorldPos.x + globalBoundingBox.Size.x + jsonElement.x + 100, globalBoundingBox.WorldPos.y + jsonElement.y, globalBoundingBox.WorldPos.z + jsonElement.z);
1067
2652
  plannerElement.RotDeg = jsonElement.rot;
2653
+ plannerElement.PosNrAtEnd = !!jsonElement.posNrAtEnd;
2654
+ plannerElement.Placement = parseGuestPlacement(jsonElement.placement);
1068
2655
  if (plannerElement.IsDockedAccessoire) {
1069
2656
  accElements.push(jsonElement);
1070
2657
  plannerElement.PosNr = jsonElement.posNr;
@@ -1073,20 +2660,20 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1073
2660
  elementsSortedbyPosNr[jsonElement.posNr - 1] = jsonElement;
1074
2661
  plannerElement.PosNr = jsonElement.posNr;
1075
2662
  }
1076
- _context5.next = 32;
2663
+ _context5.next = 34;
1077
2664
  break;
1078
- case 29:
1079
- _context5.prev = 29;
2665
+ case 31:
2666
+ _context5.prev = 31;
1080
2667
  _context5.t0 = _context5["catch"](8);
1081
2668
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
1082
2669
  cause: _context5.t0,
1083
2670
  code: 'WC_0012'
1084
2671
  }));
1085
- case 32:
2672
+ case 34:
1086
2673
  i++;
1087
2674
  _context5.next = 7;
1088
2675
  break;
1089
- case 35:
2676
+ case 37:
1090
2677
  elementsForDockingExtend = [].concat(_toConsumableArray(elementsSortedbyPosNr.filter(function (e) {
1091
2678
  return e != null;
1092
2679
  })), accElements);
@@ -1108,17 +2695,19 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1108
2695
  }
1109
2696
  }
1110
2697
  }
1111
- _context5.next = 40;
2698
+ // Added beside the planning, the new elements can stand outside the room: they get the room rules like an insert.
2699
+ this.placeAddedInRoom(_toConsumableArray(oldElementidMapping.values()), true);
2700
+ _context5.next = 43;
1112
2701
  break;
1113
- case 39:
2702
+ case 42:
1114
2703
  LOG.error(new DivaError('The function extend Planner works only with products that are saved in the configurator 2.0', {
1115
2704
  code: 'WC_0012'
1116
2705
  }));
1117
- case 40:
2706
+ case 43:
1118
2707
  case "end":
1119
2708
  return _context5.stop();
1120
2709
  }
1121
- }, _callee5, this, [[8, 29]]);
2710
+ }, _callee5, this, [[8, 31]]);
1122
2711
  }));
1123
2712
  function extendPlanner(_x10, _x11) {
1124
2713
  return _extendPlanner.apply(this, arguments);
@@ -1135,7 +2724,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1135
2724
  case 0:
1136
2725
  planData = parseSetPlanData(setPlanData);
1137
2726
  if (!isSavePlannerV2(planData)) {
1138
- _context6.next = 63;
2727
+ _context6.next = 65;
1139
2728
  break;
1140
2729
  }
1141
2730
  LOG.debug('Initialize set Plan Data - V2\n' + planData, 'DivaStandardPlanner initPlanner');
@@ -1151,7 +2740,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1151
2740
  i = 0;
1152
2741
  case 9:
1153
2742
  if (!(i < jsonElements.length)) {
1154
- _context6.next = 37;
2743
+ _context6.next = 39;
1155
2744
  break;
1156
2745
  }
1157
2746
  _context6.prev = 10;
@@ -1164,7 +2753,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1164
2753
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
1165
2754
  code: 'WC_0012'
1166
2755
  }));
1167
- return _context6.abrupt("continue", 34);
2756
+ return _context6.abrupt("continue", 36);
1168
2757
  case 16:
1169
2758
  elementID = jsonElement.elementID;
1170
2759
  plannerElement = new PlannerElementData(this.set.getSetId(), jsonElement.basketID, elementID, DivaStandardPlanner.plannerType);
@@ -1184,6 +2773,8 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1184
2773
  //plannerElement.WorldPosCenter = new Vector3(jsonElement.x, jsonElement.y, jsonElement.z);
1185
2774
  plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + jsonElement.x, this.plannerBoundingBox.WorldPos.y + jsonElement.y, this.plannerBoundingBox.WorldPos.z + jsonElement.z);
1186
2775
  plannerElement.RotDeg = jsonElement.rot;
2776
+ plannerElement.PosNrAtEnd = !!jsonElement.posNrAtEnd;
2777
+ plannerElement.Placement = parseGuestPlacement(jsonElement.placement);
1187
2778
  if (plannerElement.IsDockedAccessoire) {
1188
2779
  accElements.push(jsonElement);
1189
2780
  plannerElement.PosNr = jsonElement.posNr;
@@ -1192,34 +2783,34 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1192
2783
  elementsSortedbyPosNr[jsonElement.posNr - 1] = jsonElement;
1193
2784
  plannerElement.PosNr = jsonElement.posNr;
1194
2785
  }
1195
- _context6.next = 34;
2786
+ _context6.next = 36;
1196
2787
  break;
1197
- case 31:
1198
- _context6.prev = 31;
2788
+ case 33:
2789
+ _context6.prev = 33;
1199
2790
  _context6.t0 = _context6["catch"](10);
1200
2791
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V2', {
1201
2792
  cause: _context6.t0,
1202
2793
  code: 'WC_0012'
1203
2794
  }));
1204
- case 34:
2795
+ case 36:
1205
2796
  i++;
1206
2797
  _context6.next = 9;
1207
2798
  break;
1208
- case 37:
2799
+ case 39:
1209
2800
  onlyOneBaseElement = elementsSortedbyPosNr.filter(Boolean).length == 1; //Saves if only one base element is in the planning. All the others are only accessoires
1210
2801
  elementsForDocking = [].concat(_toConsumableArray(elementsSortedbyPosNr.filter(function (e) {
1211
2802
  return e != null;
1212
2803
  })), accElements);
1213
2804
  i = 0;
1214
- case 40:
2805
+ case 42:
1215
2806
  if (!(i < elementsForDocking.length)) {
1216
- _context6.next = 61;
2807
+ _context6.next = 63;
1217
2808
  break;
1218
2809
  }
1219
- _context6.prev = 41;
2810
+ _context6.prev = 43;
1220
2811
  row = elementsForDocking[i];
1221
2812
  if (!(i == 0 && onlyOneBaseElement && this.plannerHasStaticBackground)) {
1222
- _context6.next = 48;
2813
+ _context6.next = 50;
1223
2814
  break;
1224
2815
  }
1225
2816
  //if the planner has a static background room and there is only one base element (ignore docked ACCs) then it should be forced positioned in the center of the room.
@@ -1231,14 +2822,14 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1231
2822
  element = this.plannerElements.get(row.elementID);
1232
2823
  if (element) element.WorldPosCenter = new Vector3(0, element.Height / 2, element.Depth / 2);
1233
2824
  }
1234
- return _context6.abrupt("continue", 58);
1235
- case 48:
2825
+ return _context6.abrupt("continue", 60);
2826
+ case 50:
1236
2827
  if (!(row.DP == null || row.DP.length == 0)) {
1237
- _context6.next = 50;
2828
+ _context6.next = 52;
1238
2829
  break;
1239
2830
  }
1240
- return _context6.abrupt("continue", 58);
1241
- case 50:
2831
+ return _context6.abrupt("continue", 60);
2832
+ case 52:
1242
2833
  DPsInfo = row.DP;
1243
2834
  for (j = 0; j < DPsInfo.length; j++) {
1244
2835
  dpInfo = DPsInfo[j];
@@ -1259,79 +2850,79 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1259
2850
  }
1260
2851
  }
1261
2852
  }
1262
- _context6.next = 58;
2853
+ _context6.next = 60;
1263
2854
  break;
1264
- case 54:
1265
- _context6.prev = 54;
1266
- _context6.t1 = _context6["catch"](41);
2855
+ case 56:
2856
+ _context6.prev = 56;
2857
+ _context6.t1 = _context6["catch"](43);
1267
2858
  elementId = (_elementsForDocking$i = elementsForDocking[i]) === null || _elementsForDocking$i === void 0 ? void 0 : _elementsForDocking$i.elementID;
1268
2859
  LOG.error(new DivaError('Error initializing dockingPoints of element with elementID ' + elementId, {
1269
2860
  cause: _context6.t1,
1270
2861
  code: 'WC_0012'
1271
2862
  }));
1272
- case 58:
2863
+ case 60:
1273
2864
  i++;
1274
- _context6.next = 40;
1275
- break;
1276
- case 61:
1277
- _context6.next = 116;
2865
+ _context6.next = 42;
1278
2866
  break;
1279
2867
  case 63:
2868
+ _context6.next = 118;
2869
+ break;
2870
+ case 65:
1280
2871
  LOG.debug('Initialize set Plan Data - old V1\n' + planData, 'DivaStandardPlanner initPlanner');
1281
2872
  legacySet = (_planData$Sets = planData.Sets) === null || _planData$Sets === void 0 ? void 0 : _planData$Sets[0];
1282
2873
  if (legacySet !== null && legacySet !== void 0 && (_legacySet$Elements = legacySet.Elements) !== null && _legacySet$Elements !== void 0 && _legacySet$Elements.length) {
1283
- _context6.next = 67;
2874
+ _context6.next = 69;
1284
2875
  break;
1285
2876
  }
1286
2877
  return _context6.abrupt("return");
1287
- case 67:
2878
+ case 69:
1288
2879
  _jsonElements = legacySet.Elements;
1289
2880
  _elementsSortedbyPosNr = [];
1290
2881
  _accElements = []; //Zuerst initialisiere alle Elemente
1291
2882
  //Dann positioniere sie richtig
1292
2883
  i = 0;
1293
- case 71:
2884
+ case 73:
1294
2885
  if (!(i < _jsonElements.length)) {
1295
- _context6.next = 105;
2886
+ _context6.next = 107;
1296
2887
  break;
1297
2888
  }
1298
- _context6.prev = 72;
2889
+ _context6.prev = 74;
1299
2890
  _jsonElement2 = _jsonElements[i];
1300
2891
  _catalogArticle = this.set.CatalogData.getCatalogArticleByArticleCodex((_saveElementArticleCo3 = saveElementArticleCodex(_jsonElement2)) !== null && _saveElementArticleCo3 !== void 0 ? _saveElementArticleCo3 : '');
1301
2892
  if (!(!_catalogArticle && (_jsonElement2$Accesso = _jsonElement2.AccessoireInitParams) !== null && _jsonElement2$Accesso !== void 0 && _jsonElement2$Accesso.RelatedToBasketID && !this.set.getSetState.onlyRunLogic)) {
1302
- _context6.next = 78;
2893
+ _context6.next = 80;
1303
2894
  break;
1304
2895
  }
1305
2896
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner. PlanData V1', {
1306
2897
  code: 'WC_0012'
1307
2898
  }));
1308
- return _context6.abrupt("continue", 102);
1309
- case 78:
2899
+ return _context6.abrupt("continue", 104);
2900
+ case 80:
1310
2901
  basketID = _jsonElement2.BasketID;
1311
2902
  if (this.set.getElementId(basketID) == -1) this.set.setElementId(basketID, Number(_jsonElement2.ID));
1312
2903
  _elementId = this.set.getElementId(basketID);
1313
2904
  _jsonElement2.elementId = _elementId;
1314
2905
  if (!(_elementId == -1)) {
1315
- _context6.next = 85;
2906
+ _context6.next = 87;
1316
2907
  break;
1317
2908
  }
1318
2909
  LOG.error(new DivaError('Error when initializing planner. The elementID Was not saved in the article. ', {
1319
2910
  code: 'WC_0012'
1320
2911
  }));
1321
- return _context6.abrupt("continue", 102);
1322
- case 85:
2912
+ return _context6.abrupt("continue", 104);
2913
+ case 87:
1323
2914
  _plannerElement = new PlannerElementData(this.set.getSetId(), basketID, _elementId, DivaStandardPlanner.plannerType);
1324
2915
  this.nextElementId = _elementId + 1;
1325
2916
  this.plannerElements.set(_plannerElement.ElementId, _plannerElement);
1326
2917
  _data = this.set.getPlannerData(_plannerElement.ElementId);
1327
2918
  _plannerElement.updatePlannerData(_data);
1328
2919
  if (this.doDisablePlanner2D) {
1329
- _context6.next = 93;
2920
+ _context6.next = 95;
1330
2921
  break;
1331
2922
  }
1332
- _context6.next = 93;
2923
+ _context6.next = 95;
1333
2924
  return handler2D.loadSVG(_plannerElement, this.set);
1334
- case 93:
2925
+ case 95:
1335
2926
  //Achtung die Pos Infos im alten Planer waren Zentrumskoordinaten!!! Nicht hinten oben.
1336
2927
  centerWorldPos = new Vector3(_jsonElement2.PosX, _jsonElement2.PosZ, _jsonElement2.PosY);
1337
2928
  _plannerElement.WorldPosCenter = new Vector3(this.plannerBoundingBox.WorldPos.x + centerWorldPos.x, this.plannerBoundingBox.WorldPos.y + centerWorldPos.y, this.plannerBoundingBox.WorldPos.z + centerWorldPos.z);
@@ -1348,36 +2939,36 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1348
2939
  _elementsSortedbyPosNr[_jsonElement2.PosNum - 1] = _jsonElement2;
1349
2940
  _plannerElement.PosNr = _jsonElement2.PosNum;
1350
2941
  }
1351
- _context6.next = 102;
2942
+ _context6.next = 104;
1352
2943
  break;
1353
- case 99:
1354
- _context6.prev = 99;
1355
- _context6.t2 = _context6["catch"](72);
2944
+ case 101:
2945
+ _context6.prev = 101;
2946
+ _context6.t2 = _context6["catch"](74);
1356
2947
  LOG.error(new DivaError('Error initializing element nr ' + i + ' in the Standard Web Planner - Plan Data old Planner', {
1357
2948
  cause: _context6.t2,
1358
2949
  code: 'WC_0012'
1359
2950
  }));
1360
- case 102:
2951
+ case 104:
1361
2952
  i++;
1362
- _context6.next = 71;
2953
+ _context6.next = 73;
1363
2954
  break;
1364
- case 105:
2955
+ case 107:
1365
2956
  elementsForDockingV1 = [].concat(_toConsumableArray(_elementsSortedbyPosNr.filter(function (e) {
1366
2957
  return e != null;
1367
2958
  })), _accElements);
1368
2959
  i = 0;
1369
- case 107:
2960
+ case 109:
1370
2961
  if (!(i < elementsForDockingV1.length)) {
1371
- _context6.next = 116;
2962
+ _context6.next = 118;
1372
2963
  break;
1373
2964
  }
1374
2965
  _row = elementsForDockingV1[i];
1375
2966
  if (!(_row.DP == null || _row.DP.length == 0)) {
1376
- _context6.next = 111;
2967
+ _context6.next = 113;
1377
2968
  break;
1378
2969
  }
1379
- return _context6.abrupt("continue", 113);
1380
- case 111:
2970
+ return _context6.abrupt("continue", 115);
2971
+ case 113:
1381
2972
  _DPsInfo = _row.DP;
1382
2973
  for (j = 0; j < _DPsInfo.length; j++) {
1383
2974
  _dpInfo = _DPsInfo[j];
@@ -1395,21 +2986,21 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1395
2986
  }
1396
2987
  }
1397
2988
  }
1398
- case 113:
2989
+ case 115:
1399
2990
  i++;
1400
- _context6.next = 107;
2991
+ _context6.next = 109;
1401
2992
  break;
1402
- case 116:
2993
+ case 118:
1403
2994
  this.plannerElements.forEach(function (el) {
1404
2995
  if (!el.IsDockedAccessoire && (anchorElement == undefined || el.PosNr < anchorElement.PosNr)) anchorElement = el;
1405
2996
  });
1406
2997
  this.updateAllElementsWorldPos(undefined, anchorElement ? [anchorElement.ElementId] : undefined);
1407
2998
  this.updatePlannerPosNr();
1408
- case 119:
2999
+ case 121:
1409
3000
  case "end":
1410
3001
  return _context6.stop();
1411
3002
  }
1412
- }, _callee6, this, [[10, 31], [41, 54], [72, 99]]);
3003
+ }, _callee6, this, [[10, 33], [43, 56], [74, 101]]);
1413
3004
  }));
1414
3005
  function initPlanner(_x12) {
1415
3006
  return _initPlanner.apply(this, arguments);
@@ -1668,7 +3259,10 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1668
3259
  }
1669
3260
  transform = {
1670
3261
  rotDeg: plannerElement.getRotDeg(),
1671
- worldPosCenter: plannerElement.WorldPosCenter
3262
+ worldPosCenter: plannerElement.WorldPosCenter,
3263
+ height: plannerElement.Height,
3264
+ posNrAtEnd: plannerElement.PosNrAtEnd,
3265
+ placement: plannerElement.Placement
1672
3266
  };
1673
3267
  if (!removeDockingRelation) {
1674
3268
  dockingPointHandlerInst.removeDockingPointRelations(plannerElement);
@@ -1677,6 +3271,8 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1677
3271
  this.tryToDockForNotDockedAccessoire(parent);
1678
3272
  this.updatePlannerPosNr();
1679
3273
  this.updateAllElementsWorldPos();
3274
+ // A group the deletion lets fit, or splits, takes its place in the room.
3275
+ if (this.room) this.placeGroupsInRoom();
1680
3276
  this.updatePlannerPosNr();
1681
3277
  this.checkCollision(false, plannerElement.getElementId());
1682
3278
  this.updatePlannerBoundingBox();
@@ -1684,7 +3280,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1684
3280
  newElementToSelect: newSelElemIdPrev >= 0 ? newSelElemIdPrev : newSelElemIdNext >= 0 ? newSelElemIdNext : undefined,
1685
3281
  transform: transform
1686
3282
  });
1687
- case 24:
3283
+ case 25:
1688
3284
  case "end":
1689
3285
  return _context9.stop();
1690
3286
  }
@@ -1727,8 +3323,33 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1727
3323
  }, {
1728
3324
  key: "checkCollision",
1729
3325
  value: function checkCollision(calcCollisionPairs, checkSingleElementId) {
3326
+ var _this22 = this;
1730
3327
  if (this.doDisablePlanner2D) return;
1731
3328
  var allElements = this.getAllPlannerElements();
3329
+ // A NO_COLLISION article (e.g. a rug) neither collides with anything nor is collided with.
3330
+ var noCollisionIds = new Set(allElements.filter(function (element) {
3331
+ return _this22.hasNoCollision(element.ArticleCodex);
3332
+ }).map(function (element) {
3333
+ return element.ElementId;
3334
+ }));
3335
+ // Each colliding element with its outline and its group as slot carrier, built when a pair collides.
3336
+ var slotted;
3337
+ var slottedOf = function slottedOf(element) {
3338
+ var _slotted;
3339
+ (_slotted = slotted) !== null && _slotted !== void 0 ? _slotted : slotted = new Map(getDockingGroups(allElements).flatMap(function (group) {
3340
+ return _this22.getCollidingShapes(group, false);
3341
+ }).map(function (shape) {
3342
+ return [shape.elementId, shape];
3343
+ }));
3344
+ return slotted.get(element.ElementId);
3345
+ };
3346
+ // A guest in its carrier's slot only warns when the bodies overlap.
3347
+ var inSlotClear = function inSlotClear(a, b) {
3348
+ var shapeA = slottedOf(a);
3349
+ var shapeB = slottedOf(b);
3350
+ var rules = _this22.getCatalogData().placementOptions.rules;
3351
+ return !!shapeA && !!shapeB && slotExempt(rules, shapeA, rules, shapeB);
3352
+ };
1732
3353
  var collisionDetected = false;
1733
3354
  var collisionPairs = [];
1734
3355
  for (var i = 0; i < allElements.length; i++) {
@@ -1739,10 +3360,12 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1739
3360
  var _this$set$CatalogData, _this$set$CatalogData2;
1740
3361
  var element2 = allElements[j];
1741
3362
  if (element1.getElementId() == element2.getElementId()) continue;
3363
+ if (noCollisionIds.has(element1.ElementId) || noCollisionIds.has(element2.ElementId)) continue;
1742
3364
  if (dockingPointHandlerInst.checkElementsAreDocking(element1, element2)) continue;
1743
3365
  var collision = false;
1744
3366
  if (this.set.CatalogData.doCheckConstructionWarnings || (_this$set$CatalogData = this.set.CatalogData.forceConstructionWarningForArticles) !== null && _this$set$CatalogData !== void 0 && _this$set$CatalogData.includes(element1.ArticleCodex) || (_this$set$CatalogData2 = this.set.CatalogData.forceConstructionWarningForArticles) !== null && _this$set$CatalogData2 !== void 0 && _this$set$CatalogData2.includes(element2.ArticleCodex)) {
1745
3367
  collision = handler2D.checkCollision(element1, element2, this.set.CatalogData.checkCollisionForDifferentLayers);
3368
+ if (collision && inSlotClear(element1, element2)) collision = false;
1746
3369
  }
1747
3370
  if (collision) {
1748
3371
  collisionDetected = true;
@@ -1757,17 +3380,56 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1757
3380
  }
1758
3381
  }
1759
3382
  if (this.collisionHandler.collisionDetected && !collisionDetected) {
1760
- var _this$collisionHandle, _this$collisionHandle2;
3383
+ var _this$collisionHandle3, _this$collisionHandle4;
1761
3384
  //Collision has changed
1762
- (_this$collisionHandle = (_this$collisionHandle2 = this.collisionHandler).updatePlannerMsgContainer) === null || _this$collisionHandle === void 0 || _this$collisionHandle.call(_this$collisionHandle2, 'COLLISION_MSG', false, 'WARNING', 'COLLISION_MSG', false);
3385
+ (_this$collisionHandle3 = (_this$collisionHandle4 = this.collisionHandler).updatePlannerMsgContainer) === null || _this$collisionHandle3 === void 0 || _this$collisionHandle3.call(_this$collisionHandle4, 'COLLISION_MSG', false, 'WARNING', 'COLLISION_MSG', false);
1763
3386
  } else if (!this.collisionHandler.collisionDetected && collisionDetected) {
1764
- var _this$collisionHandle3, _this$collisionHandle4;
1765
- (_this$collisionHandle3 = (_this$collisionHandle4 = this.collisionHandler).updatePlannerMsgContainer) === null || _this$collisionHandle3 === void 0 || _this$collisionHandle3.call(_this$collisionHandle4, 'COLLISION_MSG', true, 'WARNING', 'COLLISION_MSG', false /*this.collisionHandler.collisionPairs*/);
3387
+ var _this$collisionHandle5, _this$collisionHandle6;
3388
+ (_this$collisionHandle5 = (_this$collisionHandle6 = this.collisionHandler).updatePlannerMsgContainer) === null || _this$collisionHandle5 === void 0 || _this$collisionHandle5.call(_this$collisionHandle6, 'COLLISION_MSG', true, 'WARNING', 'COLLISION_MSG', false /*this.collisionHandler.collisionPairs*/);
1766
3389
  }
1767
3390
  this.collisionHandler.collisionPairs = collisionPairs;
1768
3391
  this.collisionHandler.collisionDetected = collisionDetected;
1769
3392
  }
1770
3393
 
3394
+ /**
3395
+ * The set's elements for the planning's collision warning (`ROOM_COLLISION_MSG`): every element of a colliding docking
3396
+ * group but the NO_COLLISION ones, with its outline (never the viewer's measures). None while the 2D planner is off.
3397
+ */
3398
+ }, {
3399
+ key: "getCollisionSet",
3400
+ value: function getCollisionSet() {
3401
+ return this.toCollisionSet(this.doDisablePlanner2D ? [] : getDockingGroups(this.getAllPlannerElements()));
3402
+ }
3403
+
3404
+ // The colliding ones of the docking groups `groups` as the planning's collision warning checks them.
3405
+ }, {
3406
+ key: "toCollisionSet",
3407
+ value: function toCollisionSet(groups) {
3408
+ var _this23 = this;
3409
+ var catalogData = this.getCatalogData();
3410
+ var parts = groups.filter(function (group) {
3411
+ return _this23.collides(group);
3412
+ }).flatMap(function (group, groupIndex) {
3413
+ var slotMembers = _this23.getSlotMembers(group);
3414
+ return group.filter(function (member) {
3415
+ return !_this23.hasNoCollision(member.ArticleCodex);
3416
+ }).map(function (member) {
3417
+ var _catalogData$forceCon;
3418
+ return _objectSpread(_objectSpread({}, _this23.toCollisionShape(member, slotMembers, false)), {}, {
3419
+ groupIndex: groupIndex,
3420
+ constructionChecked: catalogData.doCheckConstructionWarnings || !!((_catalogData$forceCon = catalogData.forceConstructionWarningForArticles) !== null && _catalogData$forceCon !== void 0 && _catalogData$forceCon.includes(member.ArticleCodex))
3421
+ });
3422
+ });
3423
+ });
3424
+ return {
3425
+ setId: this.set.getSetId(),
3426
+ catalogCodex: catalogData.catalogCodex,
3427
+ rules: catalogData.placementOptions.rules,
3428
+ collidingLayers: catalogData.checkCollisionForDifferentLayers,
3429
+ parts: parts
3430
+ };
3431
+ }
3432
+
1771
3433
  /**
1772
3434
  * Updates the overall set posNr
1773
3435
  * @param startSetPosNr Indicates the start PosNr for the planner
@@ -1801,8 +3463,24 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1801
3463
  }, {
1802
3464
  key: "updatePlannerTrans",
1803
3465
  value: function updatePlannerTrans(elementId, deltaMove, deltaAngleDeg, rotCorrection, transState, autoDockingDistance, turningPoint) {
1804
- var _this3 = this;
3466
+ var _this$dragUnit,
3467
+ _this24 = this;
1805
3468
  var updateConfig = false;
3469
+ var room = this.room;
3470
+ if (room && transState == 'START') this.startRoomDrag(elementId);
3471
+ var roomDrag = room ? this.roomDrag : undefined;
3472
+ if (transState == 'START') this.startDragUnit(elementId, roomDrag);else if (transState == 'UPDATE') (_this$dragUnit = this.dragUnit) === null || _this$dragUnit === void 0 || _this$dragUnit.add(elementId);
3473
+ // A turn keeps its direction: only a move snaps into a slot place.
3474
+ if (transState == 'UPDATE' && deltaAngleDeg !== 0) this.dragSlots = undefined;
3475
+ // Group members follow the grabbed element rigidly, so their own UPDATE deltas are dropped.
3476
+ // A free group's rotation goes the normal way; only wall-bound groups take their rotation from the wall.
3477
+ if (roomDrag && roomDrag.wallMode !== 'forced' && transState == 'UPDATE' && deltaAngleDeg !== 0) roomDrag.rotating = true;
3478
+ if (room && roomDrag && !roomDrag.rotating && transState == 'UPDATE' && roomDrag.members.some(function (member) {
3479
+ return member.ElementId == elementId;
3480
+ })) {
3481
+ if (elementId == roomDrag.elementId) this.updateRoomDrag(room, roomDrag, deltaMove);
3482
+ return false;
3483
+ }
1806
3484
  if (this.plannerElements.has(elementId)) {
1807
3485
  var plannerElement = this.plannerElements.get(elementId);
1808
3486
  plannerElement === null || plannerElement === void 0 || plannerElement.updateDeltaTrans(deltaMove, deltaAngleDeg, rotCorrection, transState == 'END', turningPoint);
@@ -1815,17 +3493,51 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1815
3493
  updateConfig = this.set.onDockingChanged(plannerElement.ElementId, undockedElements[i], 'UNDOCK');
1816
3494
  }
1817
3495
  }
1818
- } else if (transState == 'END') {
3496
+ } else if (transState == 'END' && plannerElement) {
3497
+ // A drag released where its group runs into something goes back to where it started, a turn only where findTurnPlace finds none.
3498
+ if ((roomDrag === null || roomDrag === void 0 ? void 0 : roomDrag.elementId) == elementId && roomDrag.blockedBy.length > 0) {
3499
+ var current = roomDrag.rotating ? this.getTurnedPose(plannerElement, roomDrag) : roomDrag.current;
3500
+ var target = roomDrag.rotating && room && this.findTurnPlace(plannerElement, roomDrag, room) || roomDrag.start;
3501
+ moveGroupRigidly([].concat(_toConsumableArray(roomDrag.members), _toConsumableArray(roomDrag.followers)), current, target);
3502
+ roomDrag.current = target;
3503
+ roomDrag.blockedBy = [];
3504
+ roomDrag.slotSnapped = false;
3505
+ }
3506
+ // Only the dragged unit moves: it is put back into the room and goes onto what it docks to (else into the free slot
3507
+ // place it snapped to), as the drag preview shows it, so docking it re-anchors nothing else. Its guests go with it.
3508
+ var unit = this.getAllPlannerElements().filter(function (element) {
3509
+ var _this24$dragUnit;
3510
+ return element === plannerElement || ((_this24$dragUnit = _this24.dragUnit) === null || _this24$dragUnit === void 0 ? void 0 : _this24$dragUnit.has(element.ElementId));
3511
+ });
3512
+ var followers = unit.filter(function (element) {
3513
+ return _this24.dragFollowers.has(element.ElementId);
3514
+ });
3515
+ var group = unit.filter(function (element) {
3516
+ return !_this24.dragFollowers.has(element.ElementId);
3517
+ });
3518
+ this.dragUnit = undefined;
3519
+ this.dragFollowers = new Set();
3520
+ var roomRule = (roomDrag === null || roomDrag === void 0 ? void 0 : roomDrag.elementId) == elementId && !roomDrag.slotSnapped && (roomDrag.wallMode === 'forced' || roomDrag.rotating);
3521
+ if (roomRule) this.placeGroupInRoom(group, plannerElement, followers);
3522
+ this.snapToDock(plannerElement, unit, autoDockingDistance, !roomDrag);
3523
+ this.dragSlots = undefined;
1819
3524
  var dockablePairs = dockingPointHandlerInst.searchDockableElementsInArea(plannerElement, this.getAllPlannerElements(), autoDockingDistance); //hier kann jetzt ein DP drinnen stehen - docke alle
1820
3525
  if (dockablePairs != null && dockablePairs.size > 0) {
1821
3526
  dockablePairs.forEach(function (dockPair, type) {
1822
- var targetPlannerElement = _this3.plannerElements.get(dockPair.targetDP.ElementId);
3527
+ var targetPlannerElement = _this24.plannerElements.get(dockPair.targetDP.ElementId);
1823
3528
  if (targetPlannerElement) {
1824
3529
  dockingPointHandlerInst.tryDockElementDPToDP(plannerElement, targetPlannerElement, dockPair.sourceDP, dockPair.targetDP);
1825
3530
  }
1826
3531
  });
1827
3532
  }
1828
3533
  updateConfig = this.updateAllElementsWorldPos(elementId);
3534
+ if ((roomDrag === null || roomDrag === void 0 ? void 0 : roomDrag.elementId) == elementId) {
3535
+ // The group as released, docked or turned: a wall-bound one goes to its wall, any other inside the room; where a
3536
+ // slot snap put it, it stays.
3537
+ if (!roomDrag.slotSnapped) this.placeGroupInRoom(this.getDockingGroupOf(plannerElement), plannerElement);
3538
+ this.checkCollision(false, elementId);
3539
+ this.roomDrag = undefined;
3540
+ }
1829
3541
  this.updatePlannerPosNr();
1830
3542
  this.updatePlannerBoundingBox();
1831
3543
  }
@@ -1851,7 +3563,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1851
3563
  }, {
1852
3564
  key: "saveSetPlanner",
1853
3565
  value: function saveSetPlanner() {
1854
- var _this4 = this;
3566
+ var _this25 = this;
1855
3567
  if (this.plannerElements.size == 0) return null;
1856
3568
  var plannerElements = [];
1857
3569
  this.plannerElements.forEach(function (elem, elemId) {
@@ -1866,13 +3578,18 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1866
3578
  };
1867
3579
  dpArr.push(saveDP);
1868
3580
  }
1869
- var plannerElement = {
3581
+ var plannerElement = _objectSpread(_objectSpread(_objectSpread({
1870
3582
  elementID: elem.getElementId(),
1871
- basketID: _this4.set.getBasketId(elem.getElementId()),
1872
- CatalogCodex: _this4.set.getCatalogCodex(),
1873
- Codex: _this4.set.getArticleCodex(elem.getElementId()),
3583
+ basketID: _this25.set.getBasketId(elem.getElementId()),
3584
+ CatalogCodex: _this25.set.getCatalogCodex(),
3585
+ Codex: _this25.set.getArticleCodex(elem.getElementId()),
1874
3586
  posNr: elem.PosNr,
1875
- accNr: elem.IsDockedAccessoire ? elem.AccessoirePosNr : undefined,
3587
+ accNr: elem.IsDockedAccessoire ? elem.AccessoirePosNr : undefined
3588
+ }, elem.PosNrAtEnd ? {
3589
+ posNrAtEnd: true
3590
+ } : {}), elem.Placement ? {
3591
+ placement: elem.Placement
3592
+ } : {}), {}, {
1876
3593
  x: elem.WorldPosCenter.x,
1877
3594
  y: elem.WorldPosCenter.y,
1878
3595
  z: elem.WorldPosCenter.z,
@@ -1881,9 +3598,9 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1881
3598
  height: elem.Height ? elem.Height : -1,
1882
3599
  depth: elem.Depth ? elem.Depth : -1,
1883
3600
  DP: dpArr
1884
- };
3601
+ });
1885
3602
  if (elem.IsAccessoire) {
1886
- var parentBasketId = _this4.set.getParentBasketIdOfElementId(elem.getElementId());
3603
+ var parentBasketId = _this25.set.getParentBasketIdOfElementId(elem.getElementId());
1887
3604
  if (parentBasketId != undefined) {
1888
3605
  plannerElement.AccessoireInitParams = {
1889
3606
  RelatedToBasketID: parentBasketId
@@ -1917,7 +3634,7 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1917
3634
  }, {
1918
3635
  key: "getSetData",
1919
3636
  value: function getSetData(only3DCompatible, useSetPlanner, doShow3DDimensionLines, alternateRenderInfo) {
1920
- var _this5 = this;
3637
+ var _this26 = this;
1921
3638
  var setId = useSetPlanner ? this.set.getSetId() : 'S1';
1922
3639
  var setData = {
1923
3640
  //ID: "S" + this.plannerID,
@@ -1944,19 +3661,19 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1944
3661
  setData.IDM3DEnvironment = this.IDM3DEnvironment;
1945
3662
  }
1946
3663
  this.plannerElements.forEach(function (elem, elemId) {
1947
- var config = _this5.set.getPlannerConfigData(elemId, alternateRenderInfo);
3664
+ var config = _this26.set.getPlannerConfigData(elemId, alternateRenderInfo);
1948
3665
  var elemCfg = config.config;
1949
3666
  var accElements = [];
1950
3667
  if (config.accs && config.accs.length > 0) {
1951
3668
  for (var i = 0; i < config.accs.length; i++) {
1952
- if (_this5.plannerElements.has(config.accs[i])) {
3669
+ if (_this26.plannerElements.has(config.accs[i])) {
1953
3670
  accElements.push('E' + config.accs[i]);
1954
3671
  }
1955
3672
  }
1956
3673
  }
1957
3674
  if (!only3DCompatible || elemCfg.Model != undefined) {
1958
3675
  var _elemCfg$MOVE;
1959
- var article = _this5.set.getArticleByElementId(elemId);
3676
+ var article = _this26.set.getArticleByElementId(elemId);
1960
3677
  var elemJson = {
1961
3678
  ID: 'E' + elemId,
1962
3679
  // N: elemCfg.N,
@@ -1986,15 +3703,15 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
1986
3703
  elemJson.H = hash;
1987
3704
  setData.ELE.push(elemJson);
1988
3705
  }
1989
- var shelfPlannerElements = _this5.set.getShelfPlannerData(elemId);
3706
+ var shelfPlannerElements = _this26.set.getShelfPlannerData(elemId);
1990
3707
  if (shelfPlannerElements) {
1991
3708
  for (var _i5 = 0; _i5 < shelfPlannerElements.length; _i5++) {
1992
3709
  var accessorire = shelfPlannerElements[_i5];
1993
- var shelfConfig = _this5.set.getShelfPlannerConfigData(accessorire.basketId).config;
3710
+ var shelfConfig = _this26.set.getShelfPlannerConfigData(accessorire.basketId).config;
1994
3711
  var _accElements2 = [];
1995
3712
  if (shelfConfig.accs && shelfConfig.accs.length > 0) {
1996
3713
  for (var j = 0; j < shelfConfig.accs.length; j++) {
1997
- if (_this5.plannerElements.has(shelfConfig.accs[j])) {
3714
+ if (_this26.plannerElements.has(shelfConfig.accs[j])) {
1998
3715
  _accElements2.push('E' + shelfConfig.accs[j]);
1999
3716
  }
2000
3717
  }
@@ -2057,12 +3774,12 @@ var DivaStandardPlanner = /*#__PURE__*/function () {
2057
3774
  }, {
2058
3775
  key: "getPlanningIsComplete",
2059
3776
  value: function getPlanningIsComplete(forceCheck) {
2060
- var _this6 = this;
3777
+ var _this27 = this;
2061
3778
  var dontCheck = !forceCheck && (this.set.CatalogData.doHideCompletenessWarning || !this.set.CatalogData.doCheckConstructionWarnings);
2062
3779
  var elemNotComplete = false;
2063
3780
  this.plannerElements.forEach(function (plannerElement, key) {
2064
- var _this6$set$CatalogDat;
2065
- if (dontCheck && !((_this6$set$CatalogDat = _this6.set.CatalogData.forceConstructionWarningForArticles) !== null && _this6$set$CatalogDat !== void 0 && _this6$set$CatalogDat.includes(plannerElement.ArticleCodex))) return;
3781
+ var _this27$set$CatalogDa;
3782
+ if (dontCheck && !((_this27$set$CatalogDa = _this27.set.CatalogData.forceConstructionWarningForArticles) !== null && _this27$set$CatalogDa !== void 0 && _this27$set$CatalogDa.includes(plannerElement.ArticleCodex))) return;
2066
3783
  if (!elemNotComplete && (plannerElement.getFreeDockingPointsByType('AVL').length > 0 || plannerElement.getFreeDockingPointsByType('AVR').length > 0)) {
2067
3784
  elemNotComplete = true;
2068
3785
  }