@cratefit/pack 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.
@@ -0,0 +1,1280 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * CrateFit Core Types
5
+ */
6
+ export interface Point3D {
7
+ x: number;
8
+ y: number;
9
+ z: number;
10
+ }
11
+ export interface Dimensions3D {
12
+ width: number;
13
+ height: number;
14
+ depth: number;
15
+ }
16
+ export interface AABB {
17
+ minX: number;
18
+ maxX: number;
19
+ minY: number;
20
+ maxY: number;
21
+ minZ: number;
22
+ maxZ: number;
23
+ }
24
+ /**
25
+ * 6 rotation types for 3D items
26
+ * RT_WHD: W×H×D (original)
27
+ * RT_HWD: H×W×D
28
+ * RT_HDW: H×D×W
29
+ * RT_DHW: D×H×W
30
+ * RT_DWH: D×W×H
31
+ * RT_WDH: W×D×H
32
+ */
33
+ export declare const RotationType: {
34
+ readonly RT_WHD: 0;
35
+ readonly RT_HWD: 1;
36
+ readonly RT_HDW: 2;
37
+ readonly RT_DHW: 3;
38
+ readonly RT_DWH: 4;
39
+ readonly RT_WDH: 5;
40
+ };
41
+ export type RotationTypeValue = (typeof RotationType)[keyof typeof RotationType];
42
+ export type RotationMode = "all" | "horizontal" | "fixed";
43
+ export interface ItemSpec {
44
+ id: string;
45
+ width: number;
46
+ height: number;
47
+ depth: number;
48
+ weight?: number;
49
+ rotationType?: RotationMode;
50
+ allowedRotations?: RotationTypeValue[];
51
+ maxStackWeight?: number;
52
+ requiresFloor?: boolean;
53
+ requiresSupport?: number;
54
+ groupId?: string;
55
+ incompatibleWith?: string[];
56
+ deliveryOrder?: number;
57
+ metadata?: Record<string, unknown>;
58
+ }
59
+ export interface PlacedItem {
60
+ item: ItemSpec;
61
+ position: Point3D;
62
+ rotation: RotationTypeValue;
63
+ dimensions: Dimensions3D;
64
+ }
65
+ export type ContainerType = "box" | "pallet" | "container" | "truck" | "shelf" | "custom";
66
+ export interface ScenarioConstraints {
67
+ maxStackHeight?: number;
68
+ overhangAllowed?: boolean;
69
+ palletPattern?: "column" | "interlock";
70
+ axleWeights?: {
71
+ front: number;
72
+ rear: number;
73
+ };
74
+ loadingDirection?: "rear" | "side";
75
+ shelfLevels?: number[];
76
+ accessibility?: "fifo" | "lifo" | "random";
77
+ maxGirth?: number;
78
+ maxLinearDim?: number;
79
+ volumetricDivisor?: number;
80
+ }
81
+ export interface BinSpec {
82
+ id: string;
83
+ type: ContainerType;
84
+ width: number;
85
+ height: number;
86
+ depth: number;
87
+ maxWeight?: number;
88
+ cost?: number;
89
+ existingItems?: PlacedItem[];
90
+ excludeZones?: AABB[];
91
+ constraints?: ScenarioConstraints;
92
+ }
93
+ export type AlgorithmType = "extreme-point" | "layer-building" | "wall-building" | "eb-afit";
94
+ export type PreprocessorType = "block-building" | "none";
95
+ export type EnhancerType = "genetic" | "simulated-annealing" | "tabu-search" | "none";
96
+ export type OptimizeTarget = "space" | "cost" | "balanced";
97
+ export type BinSelectionStrategy = "first-fit" | "best-fit" | "spread";
98
+ export type SpatialIndexType = "naive" | "octree";
99
+ export interface PackOptions {
100
+ preprocessor?: PreprocessorType;
101
+ algorithm?: AlgorithmType;
102
+ enhancer?: EnhancerType;
103
+ timeBudgetMs?: number;
104
+ features?: {
105
+ supportCheck?: boolean;
106
+ weightBalance?: boolean;
107
+ stackingLimit?: boolean;
108
+ };
109
+ constraints?: {
110
+ respectDeliveryOrder?: boolean;
111
+ keepGroupsTogether?: boolean;
112
+ enforceIncompatibility?: boolean;
113
+ };
114
+ optimize?: {
115
+ target?: OptimizeTarget;
116
+ };
117
+ binSelection?: BinSelectionStrategy;
118
+ spatialIndex?: SpatialIndexType;
119
+ }
120
+ export interface PackConfig {
121
+ bins: BinSpec[];
122
+ items: ItemSpec[];
123
+ options?: PackOptions;
124
+ }
125
+ export interface PackedBin {
126
+ bin: BinSpec;
127
+ items: PlacedItem[];
128
+ utilization: number;
129
+ weight: number;
130
+ centerOfGravity: Point3D;
131
+ }
132
+ export interface PackStats {
133
+ totalBins: number;
134
+ totalItems: number;
135
+ packedItems: number;
136
+ unpackedItems: number;
137
+ avgUtilization: number;
138
+ totalVolume: number;
139
+ usedVolume: number;
140
+ totalWeight: number;
141
+ totalCost?: number;
142
+ actualWeight: number;
143
+ volumetricWeight?: number;
144
+ chargeableWeight?: number;
145
+ }
146
+ export interface PackResult {
147
+ packed: PackedBin[];
148
+ unpacked: ItemSpec[];
149
+ stats: PackStats;
150
+ }
151
+ export interface SpatialIndex {
152
+ insert(item: PlacedItem): void;
153
+ remove(item: PlacedItem): void;
154
+ query(bounds: AABB): PlacedItem[];
155
+ clear(): void;
156
+ }
157
+ /**
158
+ * Core pack function
159
+ */
160
+ /**
161
+ * Main pack function
162
+ */
163
+ export declare function pack(config: PackConfig): PackResult;
164
+ /**
165
+ * Packer class - chainable API wrapper
166
+ */
167
+ /**
168
+ * Chainable Packer class
169
+ */
170
+ export declare class Packer {
171
+ private bins;
172
+ private items;
173
+ private options;
174
+ /**
175
+ * Add a bin/container
176
+ */
177
+ addBin(bin: BinSpec): this;
178
+ /**
179
+ * Add multiple bins
180
+ */
181
+ addBins(bins: BinSpec[]): this;
182
+ /**
183
+ * Add an item
184
+ */
185
+ addItem(item: ItemSpec): this;
186
+ /**
187
+ * Add multiple items
188
+ */
189
+ addItems(items: ItemSpec[]): this;
190
+ /**
191
+ * Set pack options
192
+ */
193
+ setOptions(options: Partial<PackOptions>): this;
194
+ /**
195
+ * Execute packing
196
+ */
197
+ pack(options?: Partial<PackOptions>): PackResult;
198
+ /**
199
+ * Reset packer state
200
+ */
201
+ reset(): this;
202
+ /**
203
+ * Get current bins
204
+ */
205
+ getBins(): BinSpec[];
206
+ /**
207
+ * Get current items
208
+ */
209
+ getItems(): ItemSpec[];
210
+ /**
211
+ * Get current options
212
+ */
213
+ getOptions(): PackOptions;
214
+ }
215
+ /**
216
+ * Create a new Packer instance
217
+ */
218
+ export declare function createPacker(): Packer;
219
+ /**
220
+ * Extreme Point Algorithm (Optimized)
221
+ *
222
+ * An advanced heuristic algorithm that tracks "extreme points" (candidate positions)
223
+ * where items can be placed. This implementation includes:
224
+ * - Projection of extreme points to support surfaces
225
+ * - Multiple point generation strategies
226
+ * - Best-fit selection option
227
+ * - Efficient point management
228
+ *
229
+ * Based on research and improvements over basic First-Fit approaches like py3dbp.
230
+ */
231
+ /**
232
+ * Pack items into a single bin using Extreme Point algorithm
233
+ */
234
+ export declare function packWithExtremePoint(bin: BinSpec, items: ItemSpec[], options?: PackOptions): {
235
+ packed: PlacedItem[];
236
+ unpacked: ItemSpec[];
237
+ };
238
+ /**
239
+ * Layer Building Algorithm
240
+ *
241
+ * A height-based packing algorithm that builds horizontal layers.
242
+ * Well-suited for pallet packing where items need stable stacking.
243
+ *
244
+ * Key concepts:
245
+ * - Groups items by similar heights into layers
246
+ * - Uses 2D bottom-left placement within each layer
247
+ * - Builds layers from bottom to top
248
+ * - Ensures proper support between layers
249
+ */
250
+ /**
251
+ * Pack items into a single bin using Layer Building algorithm
252
+ */
253
+ export declare function packWithLayerBuilding(bin: BinSpec, items: ItemSpec[], options?: PackOptions): {
254
+ packed: PlacedItem[];
255
+ unpacked: ItemSpec[];
256
+ };
257
+ /**
258
+ * Layer information for analysis
259
+ */
260
+ export interface Layer {
261
+ yLevel: number;
262
+ height: number;
263
+ items: PlacedItem[];
264
+ coverage: number;
265
+ }
266
+ /**
267
+ * Extract layer information from packed result
268
+ */
269
+ export declare function extractLayers(packed: PlacedItem[], binWidth?: number, binDepth?: number): Layer[];
270
+ /**
271
+ * Wall Building Algorithm
272
+ *
273
+ * A depth-based packing algorithm that builds vertical "walls" from back to front.
274
+ * Well-suited for container loading with LIFO (Last In First Out) requirements.
275
+ *
276
+ * Key concepts:
277
+ * - Builds walls perpendicular to the Z-axis (depth direction)
278
+ * - Each wall is a 2D packing problem in the X-Y plane
279
+ * - Items are packed from the back of the container forward
280
+ * - Supports unloading order requirements
281
+ */
282
+ /**
283
+ * Pack items into a single bin using Wall Building algorithm
284
+ */
285
+ export declare function packWithWallBuilding(bin: BinSpec, items: ItemSpec[], options?: PackOptions): {
286
+ packed: PlacedItem[];
287
+ unpacked: ItemSpec[];
288
+ };
289
+ /**
290
+ * Wall information for analysis
291
+ */
292
+ export interface Wall {
293
+ zStart: number;
294
+ zEnd: number;
295
+ items: PlacedItem[];
296
+ utilization: number;
297
+ }
298
+ /**
299
+ * Extract wall information from packed result
300
+ */
301
+ export declare function extractWalls(packed: PlacedItem[], bin: BinSpec): Wall[];
302
+ /**
303
+ * EB-AFIT Algorithm
304
+ *
305
+ * Based on Erhan Baltacıoğlu's thesis at Air Force Institute of Technology (2001).
306
+ * A human intelligence-based heuristic approach for 3D bin packing.
307
+ *
308
+ * Key concepts:
309
+ * - Evaluates all possible layer heights based on item dimensions
310
+ * - Selects optimal layer height by analyzing potential space utilization
311
+ * - Uses sophisticated gap management for better packing
312
+ * - Considers both horizontal and vertical space optimization
313
+ */
314
+ /**
315
+ * Pack items using EB-AFIT algorithm
316
+ */
317
+ export declare function packWithEBAFIT(bin: BinSpec, items: ItemSpec[], options?: PackOptions): {
318
+ packed: PlacedItem[];
319
+ unpacked: ItemSpec[];
320
+ };
321
+ /**
322
+ * Block Building Preprocessor
323
+ *
324
+ * Groups identical or similar items into larger blocks to reduce problem complexity.
325
+ * This is a preprocessing step that can improve packing efficiency for homogeneous items.
326
+ *
327
+ * Key concepts:
328
+ * - Groups items with identical dimensions
329
+ * - Creates composite blocks from multiple items
330
+ * - Reduces the number of items to place
331
+ * - Expands blocks back to original items after placement
332
+ */
333
+ export interface Block {
334
+ id: string;
335
+ originalItems: ItemSpec[];
336
+ width: number;
337
+ height: number;
338
+ depth: number;
339
+ weight: number;
340
+ count: number;
341
+ /** How items are arranged in the block */
342
+ arrangement: BlockArrangement;
343
+ }
344
+ export interface BlockArrangement {
345
+ countX: number;
346
+ countY: number;
347
+ countZ: number;
348
+ itemWidth: number;
349
+ itemHeight: number;
350
+ itemDepth: number;
351
+ }
352
+ export interface BlockBuildingOptions {
353
+ /** Minimum items to form a block */
354
+ minBlockSize?: number;
355
+ /** Maximum items in a block */
356
+ maxBlockSize?: number;
357
+ /** Tolerance for matching dimensions (as percentage, 0-1) */
358
+ tolerancePct?: number;
359
+ /** Prefer blocks that fit container dimensions well */
360
+ optimizeForContainer?: {
361
+ width: number;
362
+ height: number;
363
+ depth: number;
364
+ };
365
+ }
366
+ /**
367
+ * Build blocks from items by grouping identical items
368
+ */
369
+ export declare function buildBlocks(items: ItemSpec[], options?: BlockBuildingOptions): {
370
+ blocks: Block[];
371
+ remaining: ItemSpec[];
372
+ };
373
+ /**
374
+ * Expand blocks back to original items (for unpacked items)
375
+ */
376
+ export declare function expandBlocks(blocks: Block[]): ItemSpec[];
377
+ /**
378
+ * Genetic Algorithm Enhancer
379
+ *
380
+ * Post-processing optimizer using genetic algorithm to improve packing results.
381
+ * Uses evolutionary strategies to find better item orderings and configurations.
382
+ *
383
+ * Key concepts:
384
+ * - Chromosome: An ordering of items (permutation)
385
+ * - Fitness: Packing utilization and quality metrics
386
+ * - Crossover: Combine good orderings from parents
387
+ * - Mutation: Random swaps and rotations
388
+ * - Selection: Keep best solutions
389
+ */
390
+ export interface GeneticOptions {
391
+ /** Number of solutions in population */
392
+ populationSize?: number;
393
+ /** Number of generations to evolve */
394
+ generations?: number;
395
+ /** Probability of crossover (0-1) */
396
+ crossoverRate?: number;
397
+ /** Probability of mutation (0-1) */
398
+ mutationRate?: number;
399
+ /** Number of best solutions to preserve */
400
+ elitismCount?: number;
401
+ /** Maximum time budget in milliseconds */
402
+ timeBudgetMs?: number;
403
+ /** Base packing options to use */
404
+ packOptions?: PackOptions;
405
+ }
406
+ /**
407
+ * Enhance packing result using genetic algorithm
408
+ */
409
+ export declare function enhanceWithGenetic(result: PackResult, options?: GeneticOptions): PackResult;
410
+ /**
411
+ * Collision detection constraints
412
+ */
413
+ /**
414
+ * Check if placing an item at a position would collide with existing items
415
+ */
416
+ export declare function hasCollision(position: Point3D, dimensions: Dimensions3D, spatialIndex: SpatialIndex): boolean;
417
+ /**
418
+ * Check if item fits within bin boundaries
419
+ */
420
+ export declare function fitsInBin(position: Point3D, dimensions: Dimensions3D, bin: BinSpec): boolean;
421
+ /**
422
+ * Check if position is within any exclude zone
423
+ */
424
+ export declare function isInExcludeZone(position: Point3D, dimensions: Dimensions3D, bin: BinSpec): boolean;
425
+ /**
426
+ * Weight-related constraints
427
+ */
428
+ /**
429
+ * Check if adding an item would exceed bin's max weight
430
+ */
431
+ export declare function canAddWeight(existingItems: PlacedItem[], newItem: ItemSpec, bin: BinSpec): boolean;
432
+ /**
433
+ * Calculate total weight of placed items
434
+ */
435
+ export declare function calcTotalWeight(items: PlacedItem[]): number;
436
+ /**
437
+ * Calculate center of gravity
438
+ */
439
+ export declare function calcCenterOfGravity(items: PlacedItem[], bin: BinSpec): Point3D;
440
+ /**
441
+ * Check if weight distribution is balanced
442
+ */
443
+ export declare function isWeightBalanced(items: PlacedItem[], bin: BinSpec, tolerance?: number): boolean;
444
+ /**
445
+ * Support/stability constraints
446
+ */
447
+ /**
448
+ * Calculate supported area for an item
449
+ */
450
+ export declare function calcSupportedArea(position: Point3D, dimensions: Dimensions3D, existingItems: PlacedItem[]): number;
451
+ /**
452
+ * Check if an item has sufficient support
453
+ */
454
+ export declare function hasSufficientSupport(position: Point3D, dimensions: Dimensions3D, existingItems: PlacedItem[], minSupportRatio?: number): boolean;
455
+ /**
456
+ * Check stacking weight limit
457
+ */
458
+ export declare function canStackOn(bottomItem: PlacedItem, topItemWeight: number, existingItems: PlacedItem[]): boolean;
459
+ /**
460
+ * Grouping and compatibility constraints
461
+ */
462
+ /**
463
+ * Check if an item can be mixed with existing items in a bin
464
+ */
465
+ export declare function canMixInBin(existingItems: PlacedItem[], newItem: ItemSpec): boolean;
466
+ /**
467
+ * Group items by groupId
468
+ */
469
+ export declare function groupItems(items: ItemSpec[]): Map<string, ItemSpec[]>;
470
+ /**
471
+ * Sort items by delivery order (higher order = process first = pack at back)
472
+ */
473
+ export declare function sortByDeliveryOrder(items: ItemSpec[]): ItemSpec[];
474
+ /**
475
+ * Sort items by volume (larger first by default)
476
+ */
477
+ export declare function sortByVolume(items: ItemSpec[], ascending?: boolean): ItemSpec[];
478
+ /**
479
+ * Sort items by weight (heavier first by default)
480
+ */
481
+ export declare function sortByWeight(items: ItemSpec[], ascending?: boolean): ItemSpec[];
482
+ /**
483
+ * Naive spatial index (linear search)
484
+ * Simple implementation for small item counts
485
+ */
486
+ export declare class NaiveSpatialIndex implements SpatialIndex {
487
+ private items;
488
+ insert(item: PlacedItem): void;
489
+ remove(item: PlacedItem): void;
490
+ query(bounds: AABB): PlacedItem[];
491
+ clear(): void;
492
+ /**
493
+ * Get all items (for iteration)
494
+ */
495
+ getAll(): PlacedItem[];
496
+ /**
497
+ * Get item count
498
+ */
499
+ get size(): number;
500
+ }
501
+ /**
502
+ * Create a naive spatial index
503
+ */
504
+ export declare function createNaiveIndex(): NaiveSpatialIndex;
505
+ /**
506
+ * Octree spatial index for efficient 3D collision queries
507
+ *
508
+ * Provides O(log n) query performance for large item counts,
509
+ * compared to O(n) for naive linear search.
510
+ */
511
+ /**
512
+ * Configuration for Octree
513
+ */
514
+ export interface OctreeConfig {
515
+ /** Maximum items per node before splitting (default: 8) */
516
+ maxItemsPerNode?: number;
517
+ /** Maximum tree depth (default: 8) */
518
+ maxDepth?: number;
519
+ /** Minimum node size - won't split below this (default: 1) */
520
+ minNodeSize?: number;
521
+ }
522
+ /**
523
+ * Octree spatial index implementation
524
+ *
525
+ * Efficiently organizes 3D items for fast spatial queries.
526
+ * Best for scenarios with 100+ items.
527
+ */
528
+ export declare class OctreeIndex implements SpatialIndex {
529
+ private root;
530
+ private config;
531
+ private itemCount;
532
+ private itemMap;
533
+ constructor(bounds: AABB, config?: OctreeConfig);
534
+ /**
535
+ * Insert an item into the octree
536
+ */
537
+ insert(item: PlacedItem): void;
538
+ /**
539
+ * Recursively insert item into appropriate node(s)
540
+ */
541
+ private insertIntoNode;
542
+ /**
543
+ * Check if a node should be subdivided
544
+ */
545
+ private shouldSubdivide;
546
+ /**
547
+ * Subdivide a node and redistribute its items
548
+ */
549
+ private subdivideNode;
550
+ /**
551
+ * Remove an item from the octree
552
+ */
553
+ remove(item: PlacedItem): void;
554
+ /**
555
+ * Recursively remove item from node and children
556
+ */
557
+ private removeFromNode;
558
+ /**
559
+ * Query all items that intersect with the given bounds
560
+ */
561
+ query(bounds: AABB): PlacedItem[];
562
+ /**
563
+ * Recursively query node and children
564
+ */
565
+ private queryNode;
566
+ /**
567
+ * Clear all items from the octree
568
+ */
569
+ clear(): void;
570
+ /**
571
+ * Get all items in the octree
572
+ */
573
+ getAll(): PlacedItem[];
574
+ /**
575
+ * Get the number of items in the octree
576
+ */
577
+ get size(): number;
578
+ /**
579
+ * Get statistics about the octree structure
580
+ */
581
+ getStats(): OctreeStats;
582
+ private collectStats;
583
+ }
584
+ /**
585
+ * Statistics about octree structure
586
+ */
587
+ export interface OctreeStats {
588
+ totalNodes: number;
589
+ leafNodes: number;
590
+ maxDepth: number;
591
+ itemCount: number;
592
+ avgItemsPerLeaf: number;
593
+ }
594
+ /**
595
+ * Create an octree spatial index
596
+ */
597
+ export declare function createOctreeIndex(bounds: AABB, config?: OctreeConfig): OctreeIndex;
598
+ /**
599
+ * Integer conversion utilities for precision handling
600
+ */
601
+ /**
602
+ * Set the scale factor for integer conversion
603
+ */
604
+ export declare function setScale(scale: number): void;
605
+ /**
606
+ * Get the current scale factor
607
+ */
608
+ export declare function getScale(): number;
609
+ /**
610
+ * Convert external value to internal integer
611
+ */
612
+ export declare function toInternal(value: number): number;
613
+ /**
614
+ * Convert internal integer to external value
615
+ */
616
+ export declare function toExternal(value: number): number;
617
+ /**
618
+ * Rotation utilities
619
+ */
620
+ /**
621
+ * Get rotated dimensions based on rotation type
622
+ */
623
+ export declare function getRotatedDimensions(width: number, height: number, depth: number, rotation: RotationTypeValue): Dimensions3D;
624
+ /**
625
+ * Get allowed rotations based on rotation mode
626
+ */
627
+ export declare function getAllowedRotations(mode: RotationMode): RotationTypeValue[];
628
+ /**
629
+ * Get all rotation variants for an item
630
+ */
631
+ export declare function getRotationVariants(width: number, height: number, depth: number, allowedRotations: RotationTypeValue[]): Array<{
632
+ rotation: RotationTypeValue;
633
+ dimensions: Dimensions3D;
634
+ }>;
635
+ /**
636
+ * Geometry utilities
637
+ */
638
+ /**
639
+ * Create AABB from position and dimensions
640
+ */
641
+ export declare function createAABB(position: Point3D, dimensions: Dimensions3D): AABB;
642
+ /**
643
+ * Check if two AABBs intersect
644
+ */
645
+ export declare function intersectsAABB(a: AABB, b: AABB): boolean;
646
+ /**
647
+ * Check if AABB a contains AABB b
648
+ */
649
+ export declare function containsAABB(a: AABB, b: AABB): boolean;
650
+ /**
651
+ * Calculate volume of AABB
652
+ */
653
+ export declare function volumeAABB(aabb: AABB): number;
654
+ /**
655
+ * Calculate volume from dimensions
656
+ */
657
+ export declare function volume(dims: Dimensions3D): number;
658
+ /**
659
+ * Get AABB of a placed item
660
+ */
661
+ export declare function getItemAABB(item: PlacedItem): AABB;
662
+ /**
663
+ * Calculate overlap area on XZ plane (for support calculation)
664
+ */
665
+ export declare function calcOverlapAreaXZ(a: AABB, b: AABB): number;
666
+ /**
667
+ * Check if item is directly above another (for stacking)
668
+ */
669
+ export declare function isDirectlyAbove(top: PlacedItem, bottom: PlacedItem): boolean;
670
+ /**
671
+ * Validation utilities for packing results
672
+ *
673
+ * Verifies that packing results are correct:
674
+ * - No collisions between items
675
+ * - All items within bin boundaries
676
+ * - Volume calculations are accurate
677
+ * - All constraints are satisfied
678
+ */
679
+ export interface ValidationResult {
680
+ valid: boolean;
681
+ errors: ValidationError[];
682
+ warnings: ValidationWarning[];
683
+ }
684
+ export interface ValidationOptions {
685
+ /** Check support constraint (items should not float) */
686
+ checkSupport?: boolean;
687
+ }
688
+ export interface ValidationError {
689
+ type: "collision" | "boundary" | "volume" | "count" | "support";
690
+ message: string;
691
+ items?: string[];
692
+ }
693
+ export interface ValidationWarning {
694
+ type: "utilization" | "balance" | "gap";
695
+ message: string;
696
+ }
697
+ /**
698
+ * Validate a packing result
699
+ */
700
+ export declare function validatePackingResult(bin: BinSpec, packed: PlacedItem[], unpacked: ItemSpec[], originalItems: ItemSpec[], options?: ValidationOptions): ValidationResult;
701
+ /**
702
+ * Quick validation check (returns true/false only)
703
+ */
704
+ export declare function isValidPacking(bin: BinSpec, packed: PlacedItem[], unpacked: ItemSpec[], originalItems: ItemSpec[], options?: ValidationOptions): boolean;
705
+ /**
706
+ * Packing Instructions Types
707
+ *
708
+ * Types for generating human-readable packing instructions
709
+ */
710
+ /**
711
+ * Action type for packing instruction
712
+ */
713
+ export type InstructionAction = "place" | "rotate" | "stack";
714
+ /**
715
+ * Orientation description
716
+ */
717
+ export type OrientationDescription = "upright" | "flat" | "sideways" | "rotated-90" | "rotated-180" | "custom";
718
+ /**
719
+ * Position description relative to bin or other items
720
+ */
721
+ export interface PositionDescription {
722
+ /** Human-readable position description */
723
+ description: string;
724
+ /** Exact coordinates */
725
+ coordinates: Point3D;
726
+ /** Reference item ID (if stacking or adjacent) */
727
+ referenceItemId?: string;
728
+ /** Relationship to reference item */
729
+ relationship?: "above" | "beside" | "behind" | "in-front";
730
+ }
731
+ /**
732
+ * Single packing instruction step
733
+ */
734
+ export interface PackingInstruction {
735
+ /** Step number (1-indexed) */
736
+ step: number;
737
+ /** Action type */
738
+ action: InstructionAction;
739
+ /** Item ID */
740
+ itemId: string;
741
+ /** Human-readable item name (from metadata or ID) */
742
+ itemName: string;
743
+ /** Position information */
744
+ position: PositionDescription;
745
+ /** Item dimensions after rotation */
746
+ dimensions: Dimensions3D;
747
+ /** Orientation description */
748
+ orientation: OrientationDescription;
749
+ /** Layer number (1-indexed, from bottom) */
750
+ layer: number;
751
+ /** Additional notes/warnings */
752
+ notes: string[];
753
+ /** Original placed item reference */
754
+ placedItem: PlacedItem;
755
+ }
756
+ /**
757
+ * Bin instruction summary
758
+ */
759
+ export interface BinInstructionSummary {
760
+ /** Bin ID */
761
+ binId: string;
762
+ /** Bin type */
763
+ binType: string;
764
+ /** Bin dimensions (W x H x D) */
765
+ binDimensions: string;
766
+ /** Total item count */
767
+ itemCount: number;
768
+ /** Total weight */
769
+ totalWeight: number;
770
+ /** Layer count */
771
+ layerCount: number;
772
+ /** Space utilization percentage */
773
+ utilization: number;
774
+ }
775
+ /**
776
+ * Instructions for a single bin
777
+ */
778
+ export interface BinInstructions {
779
+ /** Bin summary info */
780
+ summary: BinInstructionSummary;
781
+ /** Ordered list of packing steps */
782
+ steps: PackingInstruction[];
783
+ /** General notes for this bin */
784
+ notes: string[];
785
+ }
786
+ /**
787
+ * Complete packing instructions for all bins
788
+ */
789
+ export interface PackingInstructions {
790
+ /** Generated timestamp */
791
+ generatedAt: string;
792
+ /** Total bins */
793
+ totalBins: number;
794
+ /** Total items */
795
+ totalItems: number;
796
+ /** Instructions per bin */
797
+ bins: BinInstructions[];
798
+ /** Global notes/warnings */
799
+ globalNotes: string[];
800
+ }
801
+ /**
802
+ * Output format for instructions
803
+ */
804
+ export type InstructionFormat = "json" | "markdown" | "html";
805
+ /**
806
+ * Language for instructions
807
+ */
808
+ export type InstructionLanguage = "en" | "zh-TW";
809
+ /**
810
+ * Detail level for instructions
811
+ */
812
+ export type InstructionDetailLevel = "simple" | "detailed";
813
+ /**
814
+ * Options for generating instructions
815
+ */
816
+ export interface GenerateInstructionsOptions {
817
+ /** Output format */
818
+ format?: InstructionFormat;
819
+ /** Language */
820
+ language?: InstructionLanguage;
821
+ /** Detail level */
822
+ detailLevel?: InstructionDetailLevel;
823
+ /** Include coordinate details */
824
+ includeCoordinates?: boolean;
825
+ /** Include weight information */
826
+ includeWeight?: boolean;
827
+ /** Layer height threshold for grouping (in same units as dimensions) */
828
+ layerHeightThreshold?: number;
829
+ }
830
+ /**
831
+ * Result of instruction generation
832
+ */
833
+ export interface GenerateInstructionsResult {
834
+ /** Structured instructions */
835
+ instructions: PackingInstructions;
836
+ /** Formatted output string */
837
+ formatted: string;
838
+ /** Format used */
839
+ format: InstructionFormat;
840
+ /** Language used */
841
+ language: InstructionLanguage;
842
+ }
843
+ /**
844
+ * Packing Instructions Generator
845
+ *
846
+ * Converts PackResult to human-readable packing instructions
847
+ */
848
+ /**
849
+ * Generate complete packing instructions from pack result
850
+ */
851
+ export declare function generateInstructions(result: PackResult, options?: GenerateInstructionsOptions): GenerateInstructionsResult;
852
+ /**
853
+ * JSON Formatter for Packing Instructions
854
+ */
855
+ /**
856
+ * Format instructions as JSON string
857
+ */
858
+ export declare function formatAsJson(instructions: PackingInstructions, options: Required<GenerateInstructionsOptions>): string;
859
+ /**
860
+ * Markdown Formatter for Packing Instructions
861
+ */
862
+ /**
863
+ * Format instructions as Markdown
864
+ */
865
+ export declare function formatAsMarkdown(instructions: PackingInstructions, options: Required<GenerateInstructionsOptions>): string;
866
+ /**
867
+ * HTML Formatter for Packing Instructions
868
+ *
869
+ * Generates a print-friendly HTML document with embedded styles
870
+ */
871
+ /**
872
+ * Format instructions as HTML document
873
+ */
874
+ export declare function formatAsHtml(instructions: PackingInstructions, options: Required<GenerateInstructionsOptions>): string;
875
+ /**
876
+ * Online Packing Types
877
+ *
878
+ * Types for real-time/online bin packing where items arrive one at a time
879
+ * and placement decisions must be made immediately without knowing future items.
880
+ */
881
+ /**
882
+ * Placement result for a single item
883
+ */
884
+ export interface PlacementResult {
885
+ /** Whether the item was successfully placed */
886
+ success: boolean;
887
+ /** ID of the bin where item was placed (if successful) */
888
+ binId?: string;
889
+ /** Position where item was placed */
890
+ position?: Point3D;
891
+ /** Placed item details */
892
+ placedItem?: PlacedItem;
893
+ /** Reason for failure (if unsuccessful) */
894
+ reason?: "no-fit" | "weight-exceeded" | "no-bins";
895
+ }
896
+ /**
897
+ * Current state of an online packer bin
898
+ */
899
+ export interface OnlineBinState {
900
+ /** The bin specification */
901
+ bin: BinSpec;
902
+ /** Items currently placed in this bin */
903
+ items: PlacedItem[];
904
+ /** Current utilization (0-1) */
905
+ utilization: number;
906
+ /** Current total weight */
907
+ weight: number;
908
+ /** Remaining capacity (volume) */
909
+ remainingVolume: number;
910
+ }
911
+ /**
912
+ * Options for online packing
913
+ */
914
+ export interface OnlinePackerOptions extends Pick<PackOptions, "features" | "constraints"> {
915
+ /** Algorithm to use for placement decisions */
916
+ algorithm?: "online-extreme-point" | "online-first-fit";
917
+ /** Strategy for selecting which bin to use */
918
+ binSelection?: "first-fit" | "best-fit" | "worst-fit";
919
+ /** Whether to automatically add new bins when needed */
920
+ autoAddBins?: boolean;
921
+ /** Template for auto-added bins (required if autoAddBins is true) */
922
+ binTemplate?: BinSpec;
923
+ /** Maximum number of bins to auto-create */
924
+ maxBins?: number;
925
+ }
926
+ /**
927
+ * Statistics for online packing session
928
+ */
929
+ export interface OnlinePackerStats {
930
+ /** Total items processed */
931
+ totalItems: number;
932
+ /** Items successfully placed */
933
+ placedItems: number;
934
+ /** Items that could not be placed */
935
+ rejectedItems: number;
936
+ /** Number of bins in use */
937
+ binsInUse: number;
938
+ /** Average utilization across all bins */
939
+ avgUtilization: number;
940
+ /** Total weight packed */
941
+ totalWeight: number;
942
+ }
943
+ /**
944
+ * Event types for online packer
945
+ */
946
+ export type OnlinePackerEventType = "item-placed" | "item-rejected" | "bin-added" | "bin-full";
947
+ /**
948
+ * Event data for online packer events
949
+ */
950
+ export interface OnlinePackerEvent {
951
+ type: OnlinePackerEventType;
952
+ item?: ItemSpec;
953
+ bin?: BinSpec;
954
+ placement?: PlacementResult;
955
+ timestamp: number;
956
+ }
957
+ /**
958
+ * Event listener type
959
+ */
960
+ export type OnlinePackerEventListener = (event: OnlinePackerEvent) => void;
961
+ /**
962
+ * Online Packer
963
+ *
964
+ * A stateful packer for real-time/online bin packing scenarios where items
965
+ * arrive one at a time and placement decisions must be made immediately.
966
+ *
967
+ * Key differences from offline packing:
968
+ * - Items are processed one at a time as they arrive
969
+ * - No knowledge of future items
970
+ * - Placement decisions are immediate and irreversible
971
+ * - State is maintained between item placements
972
+ */
973
+ /**
974
+ * Online Packer Class
975
+ *
976
+ * Handles real-time bin packing where items arrive sequentially.
977
+ */
978
+ export declare class OnlinePacker {
979
+ private options;
980
+ private binStates;
981
+ private binOrder;
982
+ private stats;
983
+ private eventListeners;
984
+ private autoAddCounter;
985
+ constructor(options?: OnlinePackerOptions & {
986
+ bins?: BinSpec[];
987
+ });
988
+ /**
989
+ * Add a new bin to the packer
990
+ */
991
+ addBin(bin: BinSpec): void;
992
+ /**
993
+ * Remove a bin from the packer
994
+ */
995
+ removeBin(binId: string): OnlineBinState | null;
996
+ /**
997
+ * Place a single item immediately
998
+ *
999
+ * This is the core method for online packing. It attempts to place
1000
+ * the item in one of the available bins using the configured algorithm.
1001
+ */
1002
+ placeItem(item: ItemSpec): PlacementResult;
1003
+ /**
1004
+ * Check if an item can possibly fit in the bin template
1005
+ */
1006
+ private canFitInTemplate;
1007
+ /**
1008
+ * Find a valid placement for an item across all bins
1009
+ */
1010
+ private findPlacement;
1011
+ /**
1012
+ * Find placement within a specific bin
1013
+ */
1014
+ private findPlacementInBin;
1015
+ /**
1016
+ * Update extreme points after placing an item
1017
+ */
1018
+ private updateExtremePoints;
1019
+ /**
1020
+ * Get bin order based on selection strategy
1021
+ */
1022
+ private getBinOrder;
1023
+ /**
1024
+ * Automatically add a new bin
1025
+ */
1026
+ private autoAddBin;
1027
+ /**
1028
+ * Update average utilization statistic
1029
+ */
1030
+ private updateAvgUtilization;
1031
+ /**
1032
+ * Get current statistics
1033
+ */
1034
+ getStats(): OnlinePackerStats;
1035
+ /**
1036
+ * Get state of a specific bin
1037
+ */
1038
+ getBinState(binId: string): OnlineBinState | null;
1039
+ /**
1040
+ * Get states of all bins
1041
+ */
1042
+ getAllBinStates(): OnlineBinState[];
1043
+ /**
1044
+ * Get list of bin IDs
1045
+ */
1046
+ getBinIds(): string[];
1047
+ /**
1048
+ * Reset the packer to initial state
1049
+ */
1050
+ reset(): void;
1051
+ /**
1052
+ * Subscribe to events
1053
+ */
1054
+ on(event: OnlinePackerEventType, listener: OnlinePackerEventListener): () => void;
1055
+ /**
1056
+ * Emit an event
1057
+ */
1058
+ private emit;
1059
+ /**
1060
+ * Generate initial extreme points considering exclude zones
1061
+ */
1062
+ private generateInitialExtremePoints;
1063
+ }
1064
+ /**
1065
+ * Pallet standard sizes
1066
+ */
1067
+ export interface PalletStandard {
1068
+ width: number;
1069
+ depth: number;
1070
+ height: number;
1071
+ name: string;
1072
+ }
1073
+ /**
1074
+ * Standard pallet sizes (in mm)
1075
+ */
1076
+ export declare const PALLET_STANDARDS: {
1077
+ readonly EUR1: {
1078
+ readonly width: 800;
1079
+ readonly depth: 1200;
1080
+ readonly height: 144;
1081
+ readonly name: "EUR1 (Euro Pallet)";
1082
+ };
1083
+ readonly EUR2: {
1084
+ readonly width: 1200;
1085
+ readonly depth: 1000;
1086
+ readonly height: 144;
1087
+ readonly name: "EUR2";
1088
+ };
1089
+ readonly EUR3: {
1090
+ readonly width: 1000;
1091
+ readonly depth: 1200;
1092
+ readonly height: 144;
1093
+ readonly name: "EUR3";
1094
+ };
1095
+ readonly EUR6: {
1096
+ readonly width: 600;
1097
+ readonly depth: 800;
1098
+ readonly height: 144;
1099
+ readonly name: "EUR6 (Half Pallet)";
1100
+ };
1101
+ readonly US: {
1102
+ readonly width: 1016;
1103
+ readonly depth: 1219;
1104
+ readonly height: 150;
1105
+ readonly name: "US (40\"\u00D748\")";
1106
+ };
1107
+ readonly US_GROCERY: {
1108
+ readonly width: 1016;
1109
+ readonly depth: 1219;
1110
+ readonly height: 150;
1111
+ readonly name: "US Grocery";
1112
+ };
1113
+ readonly ASIA: {
1114
+ readonly width: 1100;
1115
+ readonly depth: 1100;
1116
+ readonly height: 150;
1117
+ readonly name: "Asia Standard";
1118
+ };
1119
+ readonly AUSTRALIA: {
1120
+ readonly width: 1165;
1121
+ readonly depth: 1165;
1122
+ readonly height: 150;
1123
+ readonly name: "Australia Standard";
1124
+ };
1125
+ };
1126
+ export type PalletStandardName = keyof typeof PALLET_STANDARDS;
1127
+ /**
1128
+ * Get pallet standard by name
1129
+ */
1130
+ export declare function getPalletStandard(name: PalletStandardName): PalletStandard;
1131
+ /**
1132
+ * Pallet packing function
1133
+ */
1134
+ export interface PalletOptions {
1135
+ /** Pallet size - standard name or custom dimensions */
1136
+ palletSize?: PalletStandardName | {
1137
+ width: number;
1138
+ depth: number;
1139
+ };
1140
+ /** Maximum stack height (mm) */
1141
+ maxHeight?: number;
1142
+ /** Maximum weight (kg) */
1143
+ maxWeight?: number;
1144
+ /** Algorithm to use */
1145
+ algorithm?: "layer-building" | "eb-afit" | "extreme-point";
1146
+ /** Additional pack options */
1147
+ packOptions?: Partial<PackOptions>;
1148
+ }
1149
+ export interface PalletResult extends PackResult {
1150
+ /** Pallet specification used */
1151
+ palletSpec: BinSpec;
1152
+ }
1153
+ /**
1154
+ * Pack items onto a pallet
1155
+ */
1156
+ export declare function packPallet(items: ItemSpec[], options?: PalletOptions): PalletResult;
1157
+ /**
1158
+ * Container standard sizes
1159
+ */
1160
+ export interface ContainerStandard {
1161
+ width: number;
1162
+ height: number;
1163
+ depth: number;
1164
+ maxWeight: number;
1165
+ name: string;
1166
+ }
1167
+ /**
1168
+ * Standard container sizes (internal dimensions in mm, weight in kg)
1169
+ */
1170
+ export declare const CONTAINER_STANDARDS: {
1171
+ readonly "20ft": {
1172
+ readonly width: 2352;
1173
+ readonly height: 2393;
1174
+ readonly depth: 5898;
1175
+ readonly maxWeight: 21770;
1176
+ readonly name: "20ft Standard";
1177
+ };
1178
+ readonly "40ft": {
1179
+ readonly width: 2352;
1180
+ readonly height: 2393;
1181
+ readonly depth: 12032;
1182
+ readonly maxWeight: 26680;
1183
+ readonly name: "40ft Standard";
1184
+ };
1185
+ readonly "40ftHC": {
1186
+ readonly width: 2352;
1187
+ readonly height: 2698;
1188
+ readonly depth: 12032;
1189
+ readonly maxWeight: 26460;
1190
+ readonly name: "40ft High Cube";
1191
+ };
1192
+ readonly "45ftHC": {
1193
+ readonly width: 2352;
1194
+ readonly height: 2698;
1195
+ readonly depth: 13556;
1196
+ readonly maxWeight: 25600;
1197
+ readonly name: "45ft High Cube";
1198
+ };
1199
+ };
1200
+ export type ContainerStandardName = keyof typeof CONTAINER_STANDARDS;
1201
+ /**
1202
+ * Get container standard by name
1203
+ */
1204
+ export declare function getContainerStandard(name: ContainerStandardName): ContainerStandard;
1205
+ /**
1206
+ * Container packing function
1207
+ */
1208
+ export interface ContainerOptions {
1209
+ /** Container size - standard name or custom dimensions */
1210
+ containerSize?: ContainerStandardName | {
1211
+ width: number;
1212
+ height: number;
1213
+ depth: number;
1214
+ };
1215
+ /** Maximum weight (kg) */
1216
+ maxWeight?: number;
1217
+ /** Loading direction */
1218
+ loadingDirection?: "rear" | "side";
1219
+ /** Respect delivery order (LIFO) */
1220
+ respectDeliveryOrder?: boolean;
1221
+ /** Algorithm to use */
1222
+ algorithm?: "wall-building" | "extreme-point" | "layer-building";
1223
+ /** Additional pack options */
1224
+ packOptions?: Partial<PackOptions>;
1225
+ }
1226
+ export interface ContainerResult extends PackResult {
1227
+ /** Container specification used */
1228
+ containerSpec: BinSpec;
1229
+ }
1230
+ /**
1231
+ * Pack items into a container
1232
+ */
1233
+ export declare function packContainer(items: ItemSpec[], options?: ContainerOptions): ContainerResult;
1234
+ /**
1235
+ * Truck loading function
1236
+ */
1237
+ export interface TruckOptions {
1238
+ /** Truck cargo dimensions */
1239
+ truckSize: {
1240
+ width: number;
1241
+ height: number;
1242
+ depth: number;
1243
+ };
1244
+ /** Maximum weight (kg) */
1245
+ maxWeight?: number;
1246
+ /** Axle weight limits */
1247
+ axleWeights?: {
1248
+ front: number;
1249
+ rear: number;
1250
+ };
1251
+ /** Wheelbase position (distance from front) */
1252
+ wheelbase?: number;
1253
+ /** Front axle position from cargo area start */
1254
+ frontAxleOffset?: number;
1255
+ /** Algorithm to use */
1256
+ algorithm?: "wall-building" | "extreme-point";
1257
+ /** Additional pack options */
1258
+ packOptions?: Partial<PackOptions>;
1259
+ }
1260
+ export interface AxleWeightResult {
1261
+ front: number;
1262
+ rear: number;
1263
+ isValid: boolean;
1264
+ }
1265
+ export interface TruckResult extends PackResult {
1266
+ /** Truck specification used */
1267
+ truckSpec: BinSpec;
1268
+ /** Calculated axle weights */
1269
+ axleWeights: AxleWeightResult;
1270
+ }
1271
+ /**
1272
+ * Calculate axle weights based on item positions
1273
+ */
1274
+ export declare function calcAxleWeights(items: PlacedItem[], truckDepth: number, wheelbase?: number, frontAxleOffset?: number): AxleWeightResult;
1275
+ /**
1276
+ * Pack items into a truck
1277
+ */
1278
+ export declare function packTruck(items: ItemSpec[], options: TruckOptions): TruckResult;
1279
+
1280
+ export {};