@jetta/blocks-allocator 0.0.0-stage → 0.1.0

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 (282) hide show
  1. package/README.md +103 -2
  2. package/package.json +67 -5
  3. package/src/Allocation_Attempt.js +135 -0
  4. package/src/Allocation_Error_Handler.js +69 -0
  5. package/src/Allocation_Flow.js +162 -0
  6. package/src/Allocation_Optimization/Allocation_LP.js +150 -0
  7. package/src/Allocation_Optimization/Block_Allocator.js +129 -0
  8. package/src/Allocation_Optimization/Block_Layer_Order.js +50 -0
  9. package/src/Allocation_Optimization/Block_Potential_Weight.js +54 -0
  10. package/src/Allocation_Optimization/Chosen_Blocks_Stock_Cap.js +82 -0
  11. package/src/Allocation_Optimization/block_builder/Allocation_Item_Creator.js +37 -0
  12. package/src/Allocation_Optimization/block_builder/Block_Item_List_Validator.js +18 -0
  13. package/src/Allocation_Optimization/block_builder/Block_Wall_Builder.js +303 -0
  14. package/src/Allocation_Optimization/block_builder/Blocks_Builder.js +40 -0
  15. package/src/Allocation_Optimization/block_builder/Next_Block_Position.js +33 -0
  16. package/src/Allocation_Optimization/block_builder/Slot_Item_Assigner.js +45 -0
  17. package/src/Allocation_Optimization/block_builder/Stacking_Validation.js +30 -0
  18. package/src/Allocation_Optimization/block_builder/assert_tie_ratio_block_matches_orientation_below.js +44 -0
  19. package/src/Allocation_Optimization/block_builder/block_shape_stock.js +129 -0
  20. package/src/Allocation_Optimization/block_builder/exceptions/Empty_Block_Item_List_Exception.js +21 -0
  21. package/src/Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception.js +14 -0
  22. package/src/Allocation_Optimization/block_builder/exceptions/No_Suitable_Item_Exception.js +16 -0
  23. package/src/Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception.js +21 -0
  24. package/src/Allocation_Optimization/block_builder/should_omit_block_group_id.js +29 -0
  25. package/src/Allocation_Optimization/block_builder/snap_elevated_block_wall_items.js +34 -0
  26. package/src/Allocation_Optimization/block_builder/stacking_rules_input.js +52 -0
  27. package/src/Allocation_Optimization/cap_chosen_blocks_by_shape_stock.js +110 -0
  28. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Preparer.js +21 -0
  29. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Selector.js +55 -0
  30. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Threshold_Resolver.js +28 -0
  31. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Thresholds.js +23 -0
  32. package/src/Allocation_Optimization/density_groups/Container_Utilization.js +67 -0
  33. package/src/Allocation_Optimization/density_groups/Density_Group_Partitioner.js +74 -0
  34. package/src/Allocation_Optimization/density_groups/Density_Group_Scheduler.js +168 -0
  35. package/src/Allocation_Optimization/density_groups/Density_Group_Stock.js +49 -0
  36. package/src/Allocation_Optimization/density_groups/Density_Groups_Strategy.js +26 -0
  37. package/src/Allocation_Optimization/density_groups/Item_Density_Calculator.js +20 -0
  38. package/src/Allocation_Optimization/density_groups/Lock_Weight_Ahead_Release.js +75 -0
  39. package/src/Allocation_Optimization/exceptions/Invalid_Item_Amount_Exception.js +17 -0
  40. package/src/Allocation_Optimization/exceptions/No_Valid_Allocation_Exception.js +14 -0
  41. package/src/Allocation_Optimization/exceptions/Optimization_Infeasible_Exception.js +14 -0
  42. package/src/Allocation_Optimization/functions/Measure_Reader.js +20 -0
  43. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Mode.js +25 -0
  44. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Strategies.js +8 -0
  45. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js +70 -0
  46. package/src/Allocation_Optimization/functions/Weight_Getter/Translation.js +22 -0
  47. package/src/Allocation_Optimization/functions/Weight_Getter/Variable_Weight_Getter.js +85 -0
  48. package/src/Allocation_Optimization/functions/Weight_Getter/constants.js +16 -0
  49. package/src/Allocation_Optimization/functions/measure_to_optimize.js +6 -0
  50. package/src/Allocation_Optimization/item_consumption_heuristic/Capacity_Bias_Item_Order.js +76 -0
  51. package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js +63 -0
  52. package/src/Allocation_Optimization/item_consumption_heuristic/Item_Chooser.js +159 -0
  53. package/src/Allocation_Optimization/item_consumption_heuristic/Item_For_Slot_Chooser.js +49 -0
  54. package/src/Allocation_Optimization/item_consumption_heuristic/Slot_Compatible_Items_Finder.js +88 -0
  55. package/src/Allocation_Optimization/item_consumption_heuristic/Slots_Items_Assigner.js +182 -0
  56. package/src/Allocation_Optimization/item_consumption_heuristic/Stack_Slot_Calculator.js +87 -0
  57. package/src/Allocation_Optimization/item_consumption_heuristic/Weight_Slot_Distribution.js +72 -0
  58. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Empty_Slot_Exception.js +17 -0
  59. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Item_Taller_Than_Limit_Exception.js +21 -0
  60. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Available_Items_Exception.js +14 -0
  61. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Slots_For_Items_Exception.js +14 -0
  62. package/src/Allocation_Optimization/lp_model/Block_Weight_Calculator.js +31 -0
  63. package/src/Allocation_Optimization/lp_model/LP_Data_Processor.js +42 -0
  64. package/src/Allocation_Optimization/lp_model/LP_Item_Slot_Assignment.js +93 -0
  65. package/src/Allocation_Optimization/lp_model/LP_Result_Mapper.js +47 -0
  66. package/src/Allocation_Optimization/lp_model/model_builder/Dimension_Range_Helper.js +49 -0
  67. package/src/Allocation_Optimization/lp_model/model_builder/Item_Assignment_Variables.js +133 -0
  68. package/src/Allocation_Optimization/lp_model/model_builder/LP_Model_Builder.js +132 -0
  69. package/src/Allocation_Optimization/lp_model/model_builder/exceptions/Missing_Item_Stock_Exception.js +18 -0
  70. package/src/Allocation_Optimization/lp_model/model_builder/goal_function/Goal_Function_Creator.js +83 -0
  71. package/src/Allocation_Optimization/lp_model/model_builder/item_dimension_hashes.js +31 -0
  72. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Block_Item_Amount_Restriction.js +53 -0
  73. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Coherence_Restriction.js +65 -0
  74. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Container_Supported_Weight_Restriction.js +42 -0
  75. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Exact_Pass_Amount_Restriction.js +62 -0
  76. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Group_Restriction.js +97 -0
  77. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Single_Item_Type_Restriction.js +79 -0
  78. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Space_Restriction.js +47 -0
  79. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Unavailable_Block_Restriction.js +27 -0
  80. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Uniform_Block_Measure_Restriction.js +92 -0
  81. package/src/Allocation_Optimization/next_group_id_after_preloaded.js +30 -0
  82. package/src/Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier.js +74 -0
  83. package/src/Allocation_Optimization/preferential_blocks/key_item/Key_Item_Mapper.js +49 -0
  84. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Almost_Unique_Item.js +31 -0
  85. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Cant_Stack_It_Self.js +68 -0
  86. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Rule_Interface.js +26 -0
  87. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Intercalation_State.js +49 -0
  88. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter.js +33 -0
  89. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter.js +20 -0
  90. package/src/Allocation_Optimization/tie_ratio/collect_tie_ratio_orientations_below_footprint.js +64 -0
  91. package/src/Allocation_Optimization/tie_ratio/filter_blocks_by_orientation.js +17 -0
  92. package/src/Allocation_Optimization/tie_ratio/find_orientation_below_space.js +77 -0
  93. package/src/Allocation_Optimization/tie_ratio/loose_on_block/allocated_item_penetrates_any.js +31 -0
  94. package/src/Allocation_Optimization/tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item.js +94 -0
  95. package/src/Allocation_Optimization/tie_ratio/loose_on_block/axis_overlap_length.js +16 -0
  96. package/src/Allocation_Optimization/tie_ratio/loose_on_block/block_local_origin.js +18 -0
  97. package/src/Allocation_Optimization/tie_ratio/loose_on_block/box_fits_inside_container.js +39 -0
  98. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_allocated_item_at_placement.js +18 -0
  99. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_placement_on_generic_supporter.js +64 -0
  100. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_slot_grid_from_cluster.js +66 -0
  101. package/src/Allocation_Optimization/tie_ratio/loose_on_block/compare_group_ids.js +20 -0
  102. package/src/Allocation_Optimization/tie_ratio/loose_on_block/container_with_pending_wall_items.js +26 -0
  103. package/src/Allocation_Optimization/tie_ratio/loose_on_block/empty_space_is_on_floor.js +16 -0
  104. package/src/Allocation_Optimization/tie_ratio/loose_on_block/finalize_loose_item_placement.js +58 -0
  105. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_best_generic_supporter_placement.js +58 -0
  106. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_next_free_slot_index.js +119 -0
  107. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_supporter_directly_below.js +51 -0
  108. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_tie_ratio_supporter_cluster.js +57 -0
  109. package/src/Allocation_Optimization/tie_ratio/loose_on_block/footprint_xz_overlap_area.js +26 -0
  110. package/src/Allocation_Optimization/tie_ratio/loose_on_block/item_fits_supporter_slot.js +22 -0
  111. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_footprint_region_from_options.js +24 -0
  112. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_fits_inside_container.js +21 -0
  113. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_has_geometric_support.js +21 -0
  114. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_on_block_slot_state.js +88 -0
  115. package/src/Allocation_Optimization/tie_ratio/loose_on_block/placement_coords_fit_inside_container.js +34 -0
  116. package/src/Allocation_Optimization/tie_ratio/loose_on_block/read_empilhar_area_igual_from_allocation_item.js +12 -0
  117. package/src/Allocation_Optimization/tie_ratio/loose_on_block/realigned_loose_geometry_gates.js +25 -0
  118. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_on_generic_supporter.js +65 -0
  119. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_placement_position.js +68 -0
  120. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_placement_y_at_slot.js +45 -0
  121. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_without_tie_ratio_cluster.js +79 -0
  122. package/src/Allocation_Optimization/tie_ratio/loose_on_block/select_tie_ratio_slot_placement.js +84 -0
  123. package/src/Allocation_Optimization/tie_ratio/loose_on_block/slot_footprint_collision.js +105 -0
  124. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_cluster_selection.js +119 -0
  125. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_footprint_overlap.js +56 -0
  126. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_placement_plane.js +109 -0
  127. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_supporter_predicate.js +23 -0
  128. package/src/Allocation_Optimization/tie_ratio/loose_on_block/try_tie_ratio_slot_placement.js +62 -0
  129. package/src/Allocation_Optimization/tie_ratio/snap_stacked_items_to_floor_footprints.js +138 -0
  130. package/src/Allocation_Optimization/tie_ratio/supporters_by_top_y_index.js +78 -0
  131. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space.js +89 -0
  132. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_from_group.js +48 -0
  133. package/src/Block_Management.js +34 -0
  134. package/src/Blocks_Preparation/Cube_Map_Function.js +27 -0
  135. package/src/Blocks_Wall_Allocation.js +3 -0
  136. package/src/IO/Answer_Status.js +4 -0
  137. package/src/IO/Output_Builder.js +35 -0
  138. package/src/IO/count_allocated_items.js +31 -0
  139. package/src/IO/create_error_response.js +62 -0
  140. package/src/IO/format_allocation_error_message.js +25 -0
  141. package/src/Item_Continuation_Lock.js +129 -0
  142. package/src/Item_Picking_Continuity.js +41 -0
  143. package/src/allocation_flow/chooser_session_state.js +21 -0
  144. package/src/allocation_flow/compound_probe_fallback.js +17 -0
  145. package/src/allocation_flow/container_remaining_capacity.js +23 -0
  146. package/src/allocation_flow/density_group_item_filter.js +31 -0
  147. package/src/allocation_flow/effective_item_fingerprint.js +14 -0
  148. package/src/allocation_flow/item_continuation_lock_gate.js +38 -0
  149. package/src/allocation_flow/no_space_left_recovery.js +48 -0
  150. package/src/allocation_flow/run_allocation_iteration.js +155 -0
  151. package/src/allocation_flow/space_skip_state.js +91 -0
  152. package/src/allocation_flow/try_no_space_left_recovery.js +50 -0
  153. package/src/exceptions/Invalid_Parameter_Exception.js +17 -0
  154. package/src/exceptions/Relational_Allocation_Incomplete_Exception.js +24 -0
  155. package/src/exceptions/Relational_Colocation_Violation_Exception.js +23 -0
  156. package/src/exceptions/Relational_Config_Mismatch_Exception.js +17 -0
  157. package/src/exceptions/There_Is_No_Block_Options_To_Allocate_Exception.js +14 -0
  158. package/src/index.js +6 -0
  159. package/src/input_preparation/Block_Formatter.js +179 -0
  160. package/src/input_preparation/Input_Creator.js +76 -0
  161. package/src/input_preparation/Input_State_Preparation.js +47 -0
  162. package/src/input_preparation/State_Builder.js +27 -0
  163. package/src/input_preparation/block_formatter/align_flush_axis_config.js +36 -0
  164. package/src/input_preparation/block_formatter/align_flush_axis_single_round.js +112 -0
  165. package/src/input_preparation/block_formatter/align_flush_stacked_slots.js +67 -0
  166. package/src/input_preparation/block_formatter/overlapped_slots.js +24 -0
  167. package/src/input_preparation/block_formatter/parallelepiped_shell.js +38 -0
  168. package/src/input_preparation/block_formatter/rectangle_coverage.js +112 -0
  169. package/src/input_preparation/block_formatter/shell_face_coverage.js +64 -0
  170. package/src/input_preparation/block_formatter/shell_snap_convergence.js +104 -0
  171. package/src/input_preparation/block_preparation/Block_Data_To_Object_Transformer.js +57 -0
  172. package/src/input_preparation/block_preparation/Block_Module_Name.js +17 -0
  173. package/src/input_preparation/block_preparation/Blocks_Creator.js +101 -0
  174. package/src/input_preparation/block_preparation/Blocksmith.js +19 -0
  175. package/src/input_preparation/block_preparation/block_modules/create_block_candidates.js +41 -0
  176. package/src/input_preparation/block_preparation/block_modules/manual_blocks.js +10 -0
  177. package/src/input_preparation/block_preparation/block_modules/module_registry.js +20 -0
  178. package/src/input_preparation/block_preparation/block_modules/run_creator.js +34 -0
  179. package/src/input_preparation/block_preparation/block_modules/single_item_blocks.js +12 -0
  180. package/src/input_preparation/block_preparation/block_modules/spiral_blocks.js +12 -0
  181. package/src/input_preparation/block_preparation/block_modules/tie_ratio_blocks.js +12 -0
  182. package/src/input_preparation/block_preparation/block_modules/tower_blocks.js +12 -0
  183. package/src/input_preparation/block_preparation/exceptions/Failed_To_Create_Block_Exception.js +14 -0
  184. package/src/input_preparation/block_preparation/exceptions/Failed_To_Retrieve_Block_Exception.js +17 -0
  185. package/src/input_preparation/block_preparation/exceptions/Missing_Object_Store_Exception.js +10 -0
  186. package/src/input_preparation/block_preparation/exceptions/No_Blocks_Were_Created_Exception.js +14 -0
  187. package/src/input_preparation/block_preparation/input/Input_Creator.js +96 -0
  188. package/src/input_preparation/block_preparation/manual_blocks/Manual_Blocks.js +95 -0
  189. package/src/input_preparation/build_empty_space_finder_options.js +43 -0
  190. package/src/input_preparation/item_preparation/Items_Reader.js +27 -0
  191. package/src/input_preparation/min_extents_from_items.js +29 -0
  192. package/src/input_preparation/stackability_index/Blocks_Stackability_Index_Calculator.js +58 -0
  193. package/src/input_preparation/stackability_index/Slots_Stackability_index_Calculator.js +28 -0
  194. package/src/input_preparation/stackability_index/Stackability_Input_Creator.js +27 -0
  195. package/src/input_preparation/stackability_index/stackability_index_pop_stack.js +81 -0
  196. package/src/input_preparation/stacking_constraints/Weight_Stacking_Validation.js +15 -0
  197. package/src/lp_optimizer_result_status.js +20 -0
  198. package/src/messages/Allocator_Message.js +42 -0
  199. package/src/messages/resolve_error_message_entry.js +57 -0
  200. package/src/models/Allocated_Item.js +136 -0
  201. package/src/models/Allocation_Item.js +219 -0
  202. package/src/models/Block.js +198 -0
  203. package/src/models/Cargo_Profile.js +418 -0
  204. package/src/models/Preloaded_Allocated_Item.js +132 -0
  205. package/src/models/Slot.js +67 -0
  206. package/src/models/Stacking_Rules.js +58 -0
  207. package/src/models/auxiliaryFunctions/Available_Block_Module_List_Creator.js +9 -0
  208. package/src/models/auxiliaryFunctions/Measure_Translator.js +24 -0
  209. package/src/models/auxiliaryFunctions/item_json_reader.js +44 -0
  210. package/src/models/item_json_reader.js +71 -0
  211. package/src/models/placed_item_record.js +70 -0
  212. package/src/models/preloaded_rotation_helpers.js +38 -0
  213. package/src/models/slots_have_same_measure.js +45 -0
  214. package/src/models/transport/Container.js +162 -0
  215. package/src/models/transport/Transport.js +62 -0
  216. package/src/models/transport/build_stacking_feasibility_checker.js +64 -0
  217. package/src/models/transport/container_stacking_checkpoint.js +42 -0
  218. package/src/models/transport/factory/Container_Factory.js +46 -0
  219. package/src/models/transport/factory/Corner_Casting_Factory.js +62 -0
  220. package/src/models/transport/factory/Previously_Allocated_Item_Factory.js +28 -0
  221. package/src/models/transport/factory/Transport_Factory.js +13 -0
  222. package/src/models/transport/items_for_empty_space_finder.js +91 -0
  223. package/src/models/transport/resolve_container_stacking_inputs.js +23 -0
  224. package/src/models/transport/stacking_input_from_wire.js +58 -0
  225. package/src/optimizer_connection_errors.js +50 -0
  226. package/src/relational/Relational_Error_Codes.js +7 -0
  227. package/src/relational/finalize_relational_allocation.js +20 -0
  228. package/src/relational/has_relational_items.js +11 -0
  229. package/src/relational/is_relational_error_code.js +15 -0
  230. package/src/relational/resolve_relational_container_sequences.js +29 -0
  231. package/src/run_core_allocation.js +118 -0
  232. package/src/space_and_block_chooser/Space_And_Blocks_Chooser.js +115 -0
  233. package/src/space_and_block_chooser/blocks_filters/Block_Filter_Interface.js +19 -0
  234. package/src/space_and_block_chooser/blocks_filters/Filter_Runner.js +46 -0
  235. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Block_With_Overlapped_Slots_Filter.js +14 -0
  236. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Initial_Blocks_Filter_List.js +19 -0
  237. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Blocks_Bigger_Than_Space_Filter.js +17 -0
  238. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Post_Selection_Filter_List.js +9 -0
  239. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Insuficient_Items_Filter.js +81 -0
  240. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Pre_Selection_Filter_List.js +8 -0
  241. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Blocks_Lower_Than_Max_Tower_Height.js +23 -0
  242. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Max_Tower_Height.js +82 -0
  243. package/src/space_and_block_chooser/build_allocated_item_snapshots.js +19 -0
  244. package/src/space_and_block_chooser/compound_first_empty_space_branch.js +61 -0
  245. package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +142 -0
  246. package/src/space_and_block_chooser/compound_first_without_leftover_fill.js +56 -0
  247. package/src/space_and_block_chooser/empty_spaces_where_post_selection_keeps_blocks.js +83 -0
  248. package/src/space_and_block_chooser/exceptions/Invalid_Space_To_Allocate_Exception.js +14 -0
  249. package/src/space_and_block_chooser/leftover_space_memory.js +113 -0
  250. package/src/space_and_block_chooser/leftover_unitary_blocks.js +153 -0
  251. package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +135 -0
  252. package/src/space_and_block_chooser/probe_set_pool.js +35 -0
  253. package/src/space_and_block_chooser/run_space_and_block_selection_attempt.js +88 -0
  254. package/src/tools/Array_Validator.js +6 -0
  255. package/src/tools/Clone.js +27 -0
  256. package/src/tools/Hash.js +8 -0
  257. package/src/tools/Rounder.js +5 -0
  258. package/src/tools/String_To_Boolean.js +12 -0
  259. package/src/tools/cargo_profile/Cargo_Profile_Field_Value_Resolver.js +44 -0
  260. package/src/tools/compact_items_with_stock.js +9 -0
  261. package/src/tools/mm_to_allocation_domain.js +14 -0
  262. package/src/tracing/Allocation_Tracer.js +52 -0
  263. package/src/tracing/Trace_Context.js +18 -0
  264. package/src/tracing/trace_outcome.js +18 -0
  265. package/src/tracing/traced_step.js +57 -0
  266. package/src/validation/Item_Continuation_Lock_Flag.js +52 -0
  267. package/src/validation/Item_Validation.js +29 -0
  268. package/src/validation/Relational_Colocation_Validator.js +60 -0
  269. package/src/validation/Relational_Completeness_Validator.js +146 -0
  270. package/src/validation/Relational_Continuation_Lock_Validation.js +37 -0
  271. package/src/validation/Relational_Proportional_Normalizer.js +194 -0
  272. package/src/validation/Validation.js +9 -0
  273. package/src/validation/Validation_Runner.js +20 -0
  274. package/src/validation/exceptions/Invalid_Block_Module_Config_Exception.js +14 -0
  275. package/src/validation/exceptions/Invalid_Input_Exception.js +14 -0
  276. package/src/validation/exceptions/Invalid_Input_Type_Exception.js +14 -0
  277. package/src/validation/schemas/allocated_item_schema.js +18 -0
  278. package/src/validation/schemas/allocation_request_schema.js +178 -0
  279. package/src/validation/schemas/container_row_schema.js +16 -0
  280. package/src/validation/schemas/item_schema.js +60 -0
  281. package/src/validation/schemas/transport_env_schema.js +19 -0
  282. package/src/validation/validate_block_module_config.js +147 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * If the optimizer call failed due to a peer-closed HTTP socket or a temporary
3
+ * NATS failure, returns a clearer Error; otherwise returns the original error.
4
+ * @param {Error} error - Error from `@jetta/lp-framework`.
5
+ * @param {number} elapsed_ms - Time spent in optimize() until failure.
6
+ * @param {number} block_count - Blocks in the LP model.
7
+ * @param {number} restriction_count - Restrictions registered on the optimizer instance.
8
+ * @returns {Error} Original or wrapped error.
9
+ */
10
+ function enrich_optimizer_http_error(error, elapsed_ms, block_count, restriction_count)
11
+ {
12
+ const message = String(error?.message ?? '')
13
+ const is_socket_peer = error?.code === 'UND_ERR_SOCKET'
14
+ || message.includes('other side closed')
15
+ const is_nats_temporary = error?.name === 'OptimizerNatsTemporaryError'
16
+ || message.toLowerCase().includes('nats request failed')
17
+ || message.toLowerCase().includes('no responders')
18
+ if (!is_socket_peer && !is_nats_temporary)
19
+ {
20
+ return error
21
+ }
22
+
23
+ const model_context = `while solving an LP with ${block_count} blocks and ${restriction_count} restrictions`
24
+ const immediate_close_threshold_ms = 1000
25
+ let guidance
26
+ if (is_nats_temporary)
27
+ {
28
+ guidance = 'NATS request-reply timed out or had no responders '
29
+ + '(worker scaled to zero, stream lag, or cold start). '
30
+ + 'Wait for KEDA to scale python-optimizer-nats and/or raise OPTIMIZER_NATS_TIMEOUT_MS.'
31
+ }
32
+ else if (elapsed_ms < immediate_close_threshold_ms)
33
+ {
34
+ guidance = 'This usually means the optimizer connection was reset (pod restart, failed liveness/readiness probe, or dying endpoint), not a slow CPLEX solve.'
35
+ }
36
+ else
37
+ {
38
+ guidance = 'This is usually a server or proxy read/worker timeout on a large model. '
39
+ + 'Raise the optimizer timeout, or reduce candidate blocks in the allocation input.'
40
+ }
41
+
42
+ const prefix = is_nats_temporary
43
+ ? `Optimizer NATS request failed after ${elapsed_ms} ms`
44
+ : `Optimizer closed the HTTP connection after ${elapsed_ms} ms`
45
+ const wrapped = new Error(`${prefix} ${model_context}. ${guidance}`)
46
+ wrapped.cause = error
47
+ return wrapped
48
+ }
49
+
50
+ module.exports = { enrich_optimizer_http_error }
@@ -0,0 +1,7 @@
1
+ const RELATION_ERROR_CODES = Object.freeze({
2
+ COLOCATION_VIOLATION: 'RELATION_COLOCATION_VIOLATION',
3
+ ALLOCATION_INCOMPLETE: 'RELATION_ALLOCATION_INCOMPLETE',
4
+ CONFIG_MISMATCH: 'RELATION_CONFIG_MISMATCH'
5
+ })
6
+
7
+ module.exports = RELATION_ERROR_CODES
@@ -0,0 +1,20 @@
1
+ const { validate_transport_colocation } = require('../validation/Relational_Colocation_Validator')
2
+ const { validate_relational_completeness } = require('../validation/Relational_Completeness_Validator')
3
+ const {
4
+ normalize_relational_proportional_allocation
5
+ } = require('../validation/Relational_Proportional_Normalizer')
6
+
7
+ /**
8
+ * Normalizes proportional relational amounts and validates completeness and co-location.
9
+ * @param {object} transport - Allocated transport to finalize.
10
+ * @param {object[]} item_list - Remaining items after allocation (may be empty).
11
+ * @returns {void}
12
+ */
13
+ function finalize_relational_allocation(transport, item_list)
14
+ {
15
+ normalize_relational_proportional_allocation(transport, item_list)
16
+ validate_relational_completeness(transport, item_list)
17
+ validate_transport_colocation(transport)
18
+ }
19
+
20
+ module.exports = finalize_relational_allocation
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns whether any item in the list belongs to a relational group.
3
+ * @param {object[]} item_list
4
+ * @returns {boolean}
5
+ */
6
+ function has_relational_items(item_list)
7
+ {
8
+ return item_list.some(item => item.get_relational_group_id && item.get_relational_group_id())
9
+ }
10
+
11
+ module.exports = has_relational_items
@@ -0,0 +1,15 @@
1
+ const RELATION_ERROR_CODES = require('./Relational_Error_Codes')
2
+
3
+ const RELATIONAL_ERROR_CODE_SET = new Set(Object.values(RELATION_ERROR_CODES))
4
+
5
+ /**
6
+ * Whether a value is a known relational allocation error code.
7
+ * @param {unknown} code
8
+ * @returns {boolean}
9
+ */
10
+ function is_relational_error_code(code)
11
+ {
12
+ return RELATIONAL_ERROR_CODE_SET.has(code)
13
+ }
14
+
15
+ module.exports = is_relational_error_code
@@ -0,0 +1,29 @@
1
+ const Cargo_Profile = require('../models/Cargo_Profile')
2
+ const has_relational_items = require('./has_relational_items')
3
+
4
+ /**
5
+ * Returns container sequences to allocate. When relational co-location is enforced
6
+ * and relational items remain, only the first container sequence is used.
7
+ * @param {object} transport - Allocation transport with container sequences.
8
+ * @param {object[]} item_list - Items still to allocate.
9
+ * @returns {Array<number|string>} Container sequence list for this allocate pass.
10
+ */
11
+ function resolve_relational_container_sequences(transport, item_list)
12
+ {
13
+ const all_sequences = transport.get_container_sequence_list()
14
+
15
+ if (!Cargo_Profile.enforce_relational_group_co_location())
16
+ {
17
+ return all_sequences
18
+ }
19
+
20
+ const has_relational_items_present = has_relational_items(item_list)
21
+ if (!has_relational_items_present || all_sequences.length === 0)
22
+ {
23
+ return all_sequences
24
+ }
25
+
26
+ return [all_sequences[0]]
27
+ }
28
+
29
+ module.exports = resolve_relational_container_sequences
@@ -0,0 +1,118 @@
1
+ const { performance } = require('perf_hooks')
2
+ const Allocation_Flow = require('./Allocation_Flow')
3
+ const build_input_state = require('./input_preparation/State_Builder')
4
+ const { SUCCESS, ERROR } = require('./IO/Answer_Status')
5
+ const build_output_answer = require('./IO/Output_Builder')
6
+ const run_validations = require('./validation/Validation_Runner')
7
+ const Config = require('./models/Cargo_Profile')
8
+ const { Logger } = require('@jetta/logger')
9
+ const {
10
+ count_allocated_items_in_transport,
11
+ count_preloaded_items_in_input,
12
+ } = require('./IO/count_allocated_items')
13
+ const { parse_allocation_request } = require('./validation/schemas/allocation_request_schema')
14
+ const create_error_response = require('./IO/create_error_response')
15
+ const { run_with_existing_tracer, get_tracer } = require('./tracing/Allocation_Tracer')
16
+ const { TRACE_CONTEXT } = require('./tracing/Trace_Context')
17
+
18
+ const logger = new Logger('Blocks Wall Allocation')
19
+
20
+ /**
21
+ * Runs one allocation request.
22
+ * @param {object} input_data
23
+ * @param {{ object_store?: { get_object: Function }, tracer?: object }} [dependencies]
24
+ * @returns {Promise<string>}
25
+ */
26
+ async function run_core_allocation(input_data, dependencies = {})
27
+ {
28
+ const execute = () => run_blocks_wall_allocation(input_data, dependencies)
29
+ if (dependencies.tracer)
30
+ {
31
+ return run_with_existing_tracer(dependencies.tracer, execute)
32
+ }
33
+ return execute()
34
+ }
35
+
36
+ /**
37
+ * @param {object} input_data
38
+ * @param {{ object_store?: { get_object: Function } }} dependencies
39
+ * @returns {Promise<string>}
40
+ */
41
+ async function run_blocks_wall_allocation(input_data, dependencies)
42
+ {
43
+ const start_time = performance.now()
44
+ const tracer = get_tracer()
45
+ const tx_id = tracer?.start_transaction(TRACE_CONTEXT.MAIN_FLOW)
46
+ try
47
+ {
48
+ const output = await allocate_request(input_data, dependencies)
49
+ return finish_success(start_time, tracer, tx_id, output)
50
+ }
51
+ catch (error)
52
+ {
53
+ return finish_failure(start_time, tracer, tx_id, error)
54
+ }
55
+ }
56
+
57
+ /**
58
+ * @param {object} input_data
59
+ * @param {{ object_store?: { get_object: Function } }} dependencies
60
+ * @returns {Promise<string>}
61
+ */
62
+ async function allocate_request(input_data, dependencies)
63
+ {
64
+ logger.log('request received.')
65
+ const safe_input = parse_allocation_request(input_data)
66
+ const items_to_allocate = safe_input.items.reduce((accumulator, item) => accumulator + item.qtd, 0)
67
+ logger.debug(`starting Blocks Wall Allocation request with ${items_to_allocate} items.`)
68
+ run_validations(safe_input)
69
+ const input_state = await build_input_state(safe_input, dependencies)
70
+ const flow = new Allocation_Flow(input_state)
71
+ const output_data = await flow.allocate()
72
+ const total_allocated = count_allocated_items_in_transport(output_data)
73
+ const preloaded_count = count_preloaded_items_in_input(safe_input)
74
+ logger.debug(`allocated a total of ${total_allocated - preloaded_count} items.`)
75
+ return build_output_answer(SUCCESS, output_data)
76
+ }
77
+
78
+ /**
79
+ * @param {number} start_time
80
+ * @param {object|null} tracer
81
+ * @param {string|undefined} tx_id
82
+ * @param {string} output
83
+ * @returns {string}
84
+ */
85
+ function finish_success(start_time, tracer, tx_id, output)
86
+ {
87
+ print_elapsed_time(start_time)
88
+ Config.reset()
89
+ logger.log('request finished successfully.')
90
+ tracer?.end_transaction_succesfully(tx_id)
91
+ return output
92
+ }
93
+
94
+ /**
95
+ * @param {number} start_time
96
+ * @param {object|null} tracer
97
+ * @param {string|undefined} tx_id
98
+ * @param {Error} error
99
+ * @returns {string}
100
+ */
101
+ function finish_failure(start_time, tracer, tx_id, error)
102
+ {
103
+ logger.error(error.message)
104
+ logger.error(error.stack)
105
+ print_elapsed_time(start_time)
106
+ Config.reset()
107
+ tracer?.end_transaction_with_failure(tx_id)
108
+ return build_output_answer(ERROR, create_error_response(error))
109
+ }
110
+
111
+ function print_elapsed_time(start_time)
112
+ {
113
+ const end_time = performance.now()
114
+ const elapsed_time = ((end_time - start_time) / 1000).toFixed(5)
115
+ logger.debug(`finished request in ${elapsed_time} seconds`)
116
+ }
117
+
118
+ module.exports = run_core_allocation
@@ -0,0 +1,115 @@
1
+ const run_filters = require('./blocks_filters/Filter_Runner')
2
+ const run_space_and_block_selection_attempt = require('./run_space_and_block_selection_attempt')
3
+ const {NoSpaceLeftException} = require('@jetta/empty-spaces-manager')
4
+ const Invalid_Space_To_Allocate_Exception = require('./exceptions/Invalid_Space_To_Allocate_Exception')
5
+ const {Logger} = require('@jetta/logger')
6
+ const logger = new Logger('Space and Blocks Creator')
7
+ const { traced_step } = require('../tracing/traced_step')
8
+ const { TRACE_CONTEXT } = require('../tracing/Trace_Context')
9
+
10
+ function get_unattempted_space_list(empty_space_list, spaces_to_avoid)
11
+ {
12
+ const pending_spaces = []
13
+ for (const space of empty_space_list)
14
+ {
15
+ if (!spaces_to_avoid.has(space))
16
+ {
17
+ pending_spaces.push(space)
18
+ }
19
+ }
20
+ return pending_spaces
21
+ }
22
+
23
+ function handle_invalid_space_exception(error, chosen_empty_space)
24
+ {
25
+ if (!(error instanceof Invalid_Space_To_Allocate_Exception))
26
+ {
27
+ throw error
28
+ }
29
+ if (chosen_empty_space === undefined)
30
+ {
31
+ throw new NoSpaceLeftException()
32
+ }
33
+ }
34
+
35
+ function remove_empty_space_from_pending_list(pending_list, chosen_empty_space)
36
+ {
37
+ const index = pending_list.indexOf(chosen_empty_space)
38
+ if (index > -1)
39
+ {
40
+ pending_list.splice(index, 1)
41
+ }
42
+ }
43
+
44
+ async function process_space_and_blocks(filter_data, empty_space_list)
45
+ {
46
+ let chosen_empty_space
47
+ try
48
+ {
49
+ const outcome = await run_space_and_block_selection_attempt(run_filters, filter_data, empty_space_list)
50
+ chosen_empty_space = outcome.chosen_empty_space
51
+ if (outcome.pos_selection_block_list !== null)
52
+ {
53
+ return {
54
+ empty_space: chosen_empty_space,
55
+ block_list: outcome.pos_selection_block_list,
56
+ no_fillable_space_set: filter_data.no_fillable_space_set
57
+ }
58
+ }
59
+ }
60
+ catch (error)
61
+ {
62
+ handle_invalid_space_exception(error, chosen_empty_space)
63
+ }
64
+
65
+ remove_empty_space_from_pending_list(empty_space_list, chosen_empty_space)
66
+ return null
67
+ }
68
+
69
+ /**
70
+ * Chooses an empty space and matching blocks for allocation.
71
+ * @param {object} container - Current transport container.
72
+ * @param {object[]} block_list - Candidate blocks.
73
+ * @param {object[]} item_list - Items to allocate in this iteration.
74
+ * @param {Set<object>} spaces_to_avoid - Spaces skipped for the current iteration view.
75
+ * @param {object} [chooser_session] - Optional persistent session from the allocation flow.
76
+ * @returns {Promise<{ empty_space: object, block_list: object[], no_fillable_space_set: Set<object> }>}
77
+ */
78
+ module.exports = async function choose_space_and_blocks(
79
+ container,
80
+ block_list,
81
+ item_list,
82
+ spaces_to_avoid,
83
+ chooser_session
84
+ )
85
+ {
86
+ return traced_step(TRACE_CONTEXT.SPACE_AND_BLOCK_CHOICE, async () =>
87
+ {
88
+ logger.debug('choosing space and blocks')
89
+ const empty_space_list = get_unattempted_space_list(container.empty_spaces(), spaces_to_avoid)
90
+ const obligate_compound_session = chooser_session?.obligate_compound_session
91
+ ?? { skip_compound_probe: false }
92
+ const filter_data = {
93
+ container,
94
+ block_list,
95
+ item_list,
96
+ spaces_to_avoid,
97
+ no_fillable_space_set: new Set(),
98
+ obligate_compound_session,
99
+ tie_ratio_intercalation_state: chooser_session?.tie_ratio_intercalation_state ?? null,
100
+ empty_space: undefined
101
+ }
102
+
103
+ while (empty_space_list.length > 0)
104
+ {
105
+ filter_data.empty_space = undefined
106
+ const result = await process_space_and_blocks(filter_data, empty_space_list)
107
+ if (result)
108
+ {
109
+ return result
110
+ }
111
+ }
112
+
113
+ throw new NoSpaceLeftException()
114
+ })
115
+ }
@@ -0,0 +1,19 @@
1
+ class Block_Filter_Interface
2
+ {
3
+ /**
4
+ * @description a virtual method to be implemented by all block filters"
5
+ * @param {Object} filter_data
6
+ * {
7
+ * container: Container,
8
+ * empty_space: Empty_Space,
9
+ * block_list: Array<Block>,
10
+ * item_list: Array<Item>
11
+ * }
12
+ * @return {Array<Block>} filtered block list
13
+ **/
14
+ static run(filter_data)
15
+ {
16
+ throw new Error('do not overrided pure virtual method, please implement on your extended class')
17
+ }
18
+ }
19
+ module.exports = Block_Filter_Interface
@@ -0,0 +1,46 @@
1
+ const Invalid_Space_To_Allocate_Exception = require('../exceptions/Invalid_Space_To_Allocate_Exception')
2
+ const {Logger} = require('@jetta/logger')
3
+ const logger = new Logger('Filter Runner')
4
+
5
+ /**
6
+ * Runs a series of filters on a list of blocks, progressively reducing the list.
7
+ *
8
+ * This function iterates through a list of provided filters, passing a data object to each.
9
+ * Each filter returns a new, potentially smaller, list of blocks. If the final list of blocks
10
+ * is empty, it means no block could pass the filters for the given empty space. In this case,
11
+ * the space is marked as invalid and an exception is thrown to signal that this allocation path failed.
12
+ *
13
+ * @param {Array<{ run: function(Object): Array<Object> }>} filter_list Filters with a sync `run()` method.
14
+ * @param {Object} filter_data The data object required by the filters.
15
+ * @property {Array<Object>} filter_data.block_list The initial list of blocks to filter.
16
+ * @property {Object} [filter_data.empty_space] The candidate empty space being evaluated.
17
+ * @property {Set<Object>} filter_data.spaces_to_avoid A set to record spaces that become invalid.
18
+ * @property {Set<Object>} filter_data.no_fillable_space_set A set to record spaces that could not be filled.
19
+ *
20
+ * @returns {Array<Object>} The final, filtered list of blocks.
21
+ * @throws {Invalid_Space_To_Allocate_Exception} Thrown if no blocks remain after applying all filters.
22
+ */
23
+ module.exports = function run_filters(filter_list, filter_data)
24
+ {
25
+ let block_list = filter_data.block_list
26
+
27
+ for (const filter of filter_list)
28
+ {
29
+ filter_data.block_list = block_list
30
+ block_list = filter.run(filter_data)
31
+ }
32
+
33
+ if (block_list.length === 0)
34
+ {
35
+ if (filter_data.empty_space)
36
+ {
37
+ filter_data.spaces_to_avoid.add(filter_data.empty_space)
38
+ filter_data.no_fillable_space_set.add(filter_data.empty_space)
39
+ }
40
+
41
+ logger.warn('no blocks left after filtering for the chosen space.')
42
+ throw new Invalid_Space_To_Allocate_Exception()
43
+ }
44
+
45
+ return block_list
46
+ }
@@ -0,0 +1,14 @@
1
+ const { slot_list_has_overlapped_slots } = require('../../../input_preparation/block_formatter/overlapped_slots')
2
+
3
+ module.exports = class Block_With_Overlapped_Slots_Filter
4
+ {
5
+ static run(filter_data)
6
+ {
7
+ return filter_data.block_list.filter(block => !this.#does_block_have_overlapped_slots(block))
8
+ }
9
+
10
+ static #does_block_have_overlapped_slots(block)
11
+ {
12
+ return slot_list_has_overlapped_slots(block.get_slot_list())
13
+ }
14
+ }
@@ -0,0 +1,19 @@
1
+ const Insuficient_Items_Filter = require('../pre_selection_filter/Insuficient_Items_Filter')
2
+ const Block_With_Overlapped_Slots_Filter = require('./Block_With_Overlapped_Slots_Filter')
3
+ const Cargo_Profile = require('../../../models/Cargo_Profile')
4
+
5
+ /**
6
+ * Initial block filters. Overlapped-slot rejection is opt-in (prod default off).
7
+ * @returns {Array<{ run: Function }>}
8
+ */
9
+ function build_initial_blocks_filter_list()
10
+ {
11
+ const filter_list = [Insuficient_Items_Filter]
12
+ if (Cargo_Profile.reject_blocks_with_overlapped_slots())
13
+ {
14
+ filter_list.push(Block_With_Overlapped_Slots_Filter)
15
+ }
16
+ return filter_list
17
+ }
18
+
19
+ module.exports = build_initial_blocks_filter_list
@@ -0,0 +1,17 @@
1
+ const math = require('@jetta/number-compare')
2
+
3
+ module.exports = class Blocks_Bigger_Than_Space_Filter extends require('../Block_Filter_Interface')
4
+ {
5
+ static run(filter_data)
6
+ {
7
+ return filter_data.block_list.filter(block => this.#is_block_smaller_than_empty_space(block, filter_data.empty_space))
8
+ }
9
+
10
+ static #is_block_smaller_than_empty_space(block, empty_space)
11
+ {
12
+ const height_fit = math.le(block.get_height(), empty_space.get_height())
13
+ const length_fit = math.le(block.get_length(), empty_space.get_length())
14
+ const width_fit = math.le(block.get_width(), empty_space.get_width())
15
+ return height_fit && length_fit && width_fit
16
+ }
17
+ }
@@ -0,0 +1,9 @@
1
+ const Blocks_Bigger_Than_Space_Filter = require('./Blocks_Bigger_Than_Space_Filter')
2
+ const Tie_Ratio_Orientation_Filter = require('../../../Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter')
3
+ const Tie_Ratio_Vertical_Stack_Filter = require('../../../Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter')
4
+
5
+ module.exports = [
6
+ Blocks_Bigger_Than_Space_Filter,
7
+ Tie_Ratio_Orientation_Filter,
8
+ Tie_Ratio_Vertical_Stack_Filter
9
+ ]
@@ -0,0 +1,81 @@
1
+ const { cube_map_function } = require('../../../Blocks_Preparation/Cube_Map_Function')
2
+
3
+ module.exports = class Insuficient_Items_Filter
4
+ {
5
+ static #scratch_available_shapes = new Map()
6
+
7
+ static run(filter_data)
8
+ {
9
+ const available_shapes_map = this.#get_available_shapes_map(filter_data.item_list)
10
+ return filter_data.block_list.filter(
11
+ block => this.#has_sufficient_items(block, available_shapes_map)
12
+ )
13
+ }
14
+
15
+ static #has_sufficient_items(block, available_shapes_map)
16
+ {
17
+ const required_shapes_map = this.#get_required_shapes_map(block)
18
+ if (required_shapes_map.size === 0)
19
+ {
20
+ return false
21
+ }
22
+
23
+ const scratch_map = this.#scratch_available_shapes
24
+ this.#copy_map_into_scratch(available_shapes_map, scratch_map)
25
+
26
+ for (const [shape_hash, required_amount] of required_shapes_map.entries())
27
+ {
28
+ const available_amount = scratch_map.get(shape_hash) || 0
29
+ if (available_amount < required_amount)
30
+ {
31
+ return false
32
+ }
33
+ scratch_map.set(shape_hash, available_amount - required_amount)
34
+ }
35
+
36
+ return true
37
+ }
38
+
39
+ static #copy_map_into_scratch(source_map, target_map)
40
+ {
41
+ target_map.clear()
42
+ for (const [shape_hash, amount] of source_map.entries())
43
+ {
44
+ target_map.set(shape_hash, amount)
45
+ }
46
+ }
47
+
48
+ static #get_required_shapes_map(block)
49
+ {
50
+ const required_shapes = new Map()
51
+ const slot_list = block.get_slot_list()
52
+
53
+ for (const slot of slot_list)
54
+ {
55
+ const shape_hash = cube_map_function(slot)
56
+ required_shapes.set(shape_hash, (required_shapes.get(shape_hash) || 0) + 1)
57
+ }
58
+
59
+ return required_shapes
60
+ }
61
+
62
+ static #get_available_shapes_map(item_list)
63
+ {
64
+ const available_shapes = new Map()
65
+
66
+ for (const item of item_list)
67
+ {
68
+ const unique_shape_hashes = new Set()
69
+ for (const rotated_item of item.get_all_rotated_options())
70
+ {
71
+ unique_shape_hashes.add(cube_map_function(rotated_item))
72
+ }
73
+ const item_amount = item.get_amount()
74
+ for (const shape_hash of unique_shape_hashes)
75
+ {
76
+ available_shapes.set(shape_hash, (available_shapes.get(shape_hash) || 0) + item_amount)
77
+ }
78
+ }
79
+ return available_shapes
80
+ }
81
+ }
@@ -0,0 +1,8 @@
1
+ const Insuficient_Items_Filter = require('./Insuficient_Items_Filter')
2
+ const Blocks_Lower_Than_Max_Tower_Height = require('./max_tower_height/Blocks_Lower_Than_Max_Tower_Height')
3
+
4
+
5
+ module.exports = [
6
+ Insuficient_Items_Filter,
7
+ Blocks_Lower_Than_Max_Tower_Height
8
+ ]
@@ -0,0 +1,23 @@
1
+ const calculate_max_tower_height = require('./Max_Tower_Height')
2
+ const Config = require('../../../../models/Cargo_Profile')
3
+ const number_compare = require('@jetta/number-compare')
4
+ const Block_Filter_Interface = require('../../Block_Filter_Interface')
5
+
6
+ module.exports = class Blocks_Lower_Than_Max_Tower_Height extends Block_Filter_Interface
7
+ {
8
+ static run(filter_data)
9
+ {
10
+ if (!Config.enable_max_tower_cut())
11
+ {
12
+ return filter_data.block_list
13
+ }
14
+
15
+ const max_height = calculate_max_tower_height(filter_data.container, filter_data.item_list)
16
+ return filter_data.block_list.filter(block => this.#is_block_smaller_than_max_height(block, max_height))
17
+ }
18
+
19
+ static #is_block_smaller_than_max_height(block, max_height)
20
+ {
21
+ return number_compare.le(block.get_height(), max_height)
22
+ }
23
+ }