@cristiancosano/pallet-builder 0.1.2 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"pallet-builder.js","sources":["../src/core/types.ts","../src/core/constants.ts","../src/core/presets/ScenePreset.ts","../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.development.js","../node_modules/.pnpm/react@19.2.4/node_modules/react/jsx-runtime.js","../src/context/PresetContext.tsx","../src/core/entities/StackedPallet.ts","../src/core/validation/collision.ts","../src/core/validation/bounds.ts","../src/core/validation/weight.ts","../src/core/validation/stacking.ts","../src/core/validation/gravity.ts","../src/core/validation/stability.ts","../src/core/validation/polygon.ts","../src/core/packing/ColumnStrategy.ts","../src/core/packing/BinPacking3D.ts","../src/core/packing/TypeGroupStrategy.ts","../src/core/packing/registry.ts","../src/core/factories/PalletFactory.ts","../src/core/factories/TruckFactory.ts","../src/core/factories/BoxFactory.ts","../src/hooks/usePhysicsValidation.ts","../src/hooks/usePalletMetrics.ts","../src/hooks/usePackingStrategy.ts","../src/hooks/useWarehouseValidation.ts","../src/components/primitives/Box/Box.tsx","../src/components/primitives/Pallet/Pallet.tsx","../src/components/primitives/Separator/Separator.tsx","../src/components/primitives/StackedPallet/StackedPallet.tsx","../src/components/primitives/Label/Label.tsx","../src/components/environments/WarehouseEnvironment/WarehouseEnvironment.tsx","../src/components/environments/TruckEnvironment/TruckEnvironment.tsx","../src/components/controls/CameraControls/CameraControls.tsx","../src/components/controls/ViewControls/ViewControls.tsx","../src/components/controls/MiniMap/MiniMap.tsx","../src/hooks/useCameraPosition.ts","../src/components/controls/CameraTracker/CameraTracker.tsx","../src/components/scenes/PalletScene/PalletScene.tsx","../src/components/scenes/TruckScene/TruckScene.tsx","../src/components/scenes/WarehouseScene/WarehouseScene.tsx"],"sourcesContent":["/**\n * Core types — Tipos base, interfaces y enums compartidos\n * TypeScript puro, sin dependencias de React ni Three.js\n */\n\n// ─── Value Objects ───────────────────────────────────────────────\n\n/** Dimensiones 3D en milímetros */\nexport interface Dimensions3D {\n width: number // mm (X)\n height: number // mm (Y)\n depth: number // mm (Z)\n}\n\n/** Posición 3D en milímetros */\nexport interface Position3D {\n x: number // mm — ancho\n y: number // mm — alto (vertical)\n z: number // mm — profundidad\n}\n\n/** Punto 2D en milímetros (planta) */\nexport interface Point2D {\n x: number // mm\n z: number // mm\n}\n\n/** Bounding box axis-aligned */\nexport interface BoundingBox {\n minX: number\n maxX: number\n minY: number\n maxY: number\n minZ: number\n maxZ: number\n}\n\n/** Rotación discreta: solo múltiplos de 90° */\nexport interface DiscreteRotation {\n x: 0 | 90 | 180 | 270\n y: 0 | 90 | 180 | 270\n z: 0 | 90 | 180 | 270\n}\n\n// ─── Validation ──────────────────────────────────────────────────\n\nexport interface ValidationResult {\n isValid: boolean\n violations: Violation[]\n}\n\nexport interface Violation {\n code: string\n severity: 'error' | 'warning'\n message: string\n involvedIds: string[]\n}\n\n// ─── Enums (const objects for erasableSyntaxOnly) ────────────────\n\nexport const PalletMaterial = {\n WOOD: 'WOOD',\n PLASTIC: 'PLASTIC',\n METAL: 'METAL',\n COMPOSITE: 'COMPOSITE',\n} as const\nexport type PalletMaterial = (typeof PalletMaterial)[keyof typeof PalletMaterial]\n\nexport const SeparatorMaterial = {\n CARDBOARD: 'CARDBOARD',\n WOOD: 'WOOD',\n PLASTIC: 'PLASTIC',\n} as const\nexport type SeparatorMaterial = (typeof SeparatorMaterial)[keyof typeof SeparatorMaterial]\n\nexport const TruckType = {\n BOX: 'BOX',\n REFRIGERATED: 'REFRIGERATED',\n FLATBED: 'FLATBED',\n TAUTLINER: 'TAUTLINER',\n CUSTOM: 'CUSTOM',\n} as const\nexport type TruckType = (typeof TruckType)[keyof typeof TruckType]\n\n// ─── Packing ─────────────────────────────────────────────────────\n\nexport interface PackingMetrics {\n volumeUtilization: number // 0–1\n weightUtilization: number // 0–1\n centerOfGravity: Position3D\n stabilityScore: number // 0–100\n}\n\n// ─── Presets ─────────────────────────────────────────────────────\n\nexport interface PalletPreset {\n dimensions: Dimensions3D\n material: PalletMaterial\n maxWeight: number\n maxStackHeight: number\n weight: number\n}\n\nexport interface TruckPreset {\n dimensions: Dimensions3D\n maxWeight: number\n}\n","/**\n * Constantes del sistema — presets de palets y camiones estándar\n */\n\nimport { PalletMaterial, TruckType } from './types'\nimport type { PalletPreset, TruckPreset } from './types'\n\n// ─── Palet Presets ───────────────────────────────────────────────\n/**\n * STANDARD_PALLETS — Dimensiones de palets estándar internacionales\n * \n * Incluye los tipos más comunes utilizados en logística mundial:\n * - EUR/EPAL: Palet europeo (Europa, ISO 6780)\n * - GMA/AMERICAN: Palet americano estándar (Norteamérica, 48\"×40\")\n * - UK: Palet estándar Reino Unido (1200×1000)\n * - ASIA: Palet estándar asiático (1100×1100, ISO 6780)\n * - AUSTRALIAN: Palet estándar australiano (1165×1165)\n * - HALF_EUR: Medio palet europeo (800×600)\n * - QUARTER_EUR: Cuarto de palet europeo (600×400)\n * - ISO_1: Palet ISO 1200×1000 (ISO 6780)\n * - ISO_2: Palet ISO 1200×800 (equivalente a EUR)\n */\nexport const STANDARD_PALLETS: Record<string, PalletPreset> = {\n /** Palet EUR/EPAL — Estándar europeo (1200×800×144mm, ISO 6780) */\n EUR: {\n dimensions: { width: 1200, height: 144, depth: 800 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n },\n /** Palet GMA/Americano — Estándar norteamericano (1219×1016×145mm, 48\"×40\") */\n GMA: {\n dimensions: { width: 1219, height: 145, depth: 1016 },\n material: PalletMaterial.WOOD,\n maxWeight: 1200,\n maxStackHeight: 2200,\n weight: 30,\n },\n /** Palet UK Standard — Reino Unido (1200×1000×150mm) */\n UK: {\n dimensions: { width: 1200, height: 150, depth: 1000 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet asiático estándar — Asia Pallet (1100×1100×150mm, ISO 6780) */\n ASIA: {\n dimensions: { width: 1100, height: 150, depth: 1100 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet australiano estándar — Australia (1165×1165×150mm) */\n AUSTRALIAN: {\n dimensions: { width: 1165, height: 150, depth: 1165 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 29,\n },\n /** Medio palet EUR — Half European Pallet (800×600×144mm) */\n HALF_EUR: {\n dimensions: { width: 800, height: 144, depth: 600 },\n material: PalletMaterial.WOOD,\n maxWeight: 500,\n maxStackHeight: 2200,\n weight: 12,\n },\n /** Cuarto de palet EUR — Quarter European Pallet (600×400×144mm) */\n QUARTER_EUR: {\n dimensions: { width: 600, height: 144, depth: 400 },\n material: PalletMaterial.WOOD,\n maxWeight: 250,\n maxStackHeight: 2200,\n weight: 6,\n },\n /** Palet ISO 1 — ISO 6780 (1200×1000×150mm) */\n ISO_1: {\n dimensions: { width: 1200, height: 150, depth: 1000 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet ISO 2 — ISO 6780 (1200×800×144mm, equivalente a EUR) */\n ISO_2: {\n dimensions: { width: 1200, height: 144, depth: 800 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n },\n} as const\n\n// Alias para compatibilidad con código existente\n/** @deprecated Use GMA instead */\nexport const AMERICAN_PALLET = STANDARD_PALLETS.GMA\n\n// ─── Truck Presets ───────────────────────────────────────────────\n\nexport const TRUCK_PRESETS: Record<Exclude<TruckType, 'CUSTOM'>, TruckPreset> = {\n [TruckType.BOX]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 24000,\n },\n [TruckType.REFRIGERATED]: {\n dimensions: { width: 2440, height: 2590, depth: 13100 },\n maxWeight: 22000,\n },\n [TruckType.FLATBED]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 25000,\n },\n [TruckType.TAUTLINER]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 24000,\n },\n} as const\n\n// ─── Separator Defaults ─────────────────────────────────────────\n\nexport const SEPARATOR_DEFAULTS = {\n thickness: 10, // mm\n weight: 2, // kg\n} as const\n\n// ─── Conversiones ────────────────────────────────────────────────\n\nexport const UNITS = {\n MM_TO_M: 0.001,\n M_TO_MM: 1000,\n} as const\n\n// ─── Validation ──────────────────────────────────────────────────\n\n/** Tolerancia en mm para detección AABB */\nexport const COLLISION_TOLERANCE = 1\n\n/** % mínimo de soporte bajo una caja */\nexport const MIN_SUPPORT_PERCENTAGE = 0.6\n\n/** Factor de seguridad de peso (warning a partir de este %) */\nexport const WEIGHT_WARNING_THRESHOLD = 0.9\n","/**\n * ScenePreset — Definiciones de estilos visuales predefinidos\n *\n * Cada preset define colores, materiales e indicadores para todos los\n * elementos de la escena (cajas, palets, separadores, environments).\n * El consumidor puede usar un preset tal cual, extenderlo o crear el suyo propio.\n */\n\n// ─── Tipos ───────────────────────────────────────────────────────\n\nexport interface BoxStyle {\n /** Color por defecto de las cajas */\n color: string\n /** Rugosidad del material (0–1) */\n roughness: number\n /** Metalicidad del material (0–1) */\n metalness: number\n /** Opacidad por defecto */\n opacity: number\n}\n\nexport interface PalletStyle {\n /** Color del palet */\n color: string\n /** Color del borde decorativo */\n edgeColor: string\n roughness: number\n metalness: number\n}\n\nexport interface SeparatorStyle {\n /** Override de color (null = usa color por material) */\n colorOverride: string | null\n roughness: number\n}\n\nexport interface SelectionStyle {\n /** Color del borde de selección */\n selectedColor: string\n /** Color del borde de highlight (hover) */\n highlightedColor: string\n}\n\nexport interface WarehouseStyle {\n /** Color del suelo */\n floorColor: string\n /** Rugosidad del suelo */\n floorRoughness: number\n /** Color de las paredes */\n wallColor: string\n /** Opacidad de las paredes */\n wallOpacity: number\n /** Color de la iluminación ambiente */\n ambientIntensity: number\n /** Intensidad de la luz direccional */\n directionalIntensity: number\n /** Mostrar grid por defecto */\n showGrid: boolean\n /** Color principal del grid */\n gridColor: string\n /** Color secundario del grid */\n gridSecondaryColor: string\n}\n\nexport interface TruckStyle {\n /** Color del suelo del remolque */\n floorColor: string\n /** Color de las paredes del remolque */\n wallColor: string\n /** Opacidad de las paredes */\n wallOpacity: number\n /** Mostrar grid en el suelo */\n showGrid: boolean\n /** Color principal del grid */\n gridColor: string\n /** Color secundario del grid */\n gridSecondaryColor: string\n /** Color de la cabina */\n cabColor: string\n /** Color del chasis / bastidor */\n chassisColor: string\n /** Color de las ruedas */\n wheelColor: string\n}\n\nexport interface ScenePreset {\n /** Nombre identificador del preset */\n readonly id: string\n /** Nombre legible */\n readonly name: string\n\n box: BoxStyle\n pallet: PalletStyle\n separator: SeparatorStyle\n selection: SelectionStyle\n warehouse: WarehouseStyle\n truck: TruckStyle\n}\n\n// ─── Presets incluidos ───────────────────────────────────────────\n\n/**\n * Preset UNSTYLED — geometría básica con colores planos.\n * Ideal para desarrollo, depuración o cuando el consumidor quiere\n * aplicar su propio estilo desde cero.\n */\nexport const PRESET_UNSTYLED: ScenePreset = {\n id: 'unstyled',\n name: 'Sin estilo',\n\n box: {\n color: '#e07b39',\n roughness: 0.6,\n metalness: 0.1,\n opacity: 1,\n },\n pallet: {\n color: '#c4a26e',\n edgeColor: '#8b7355',\n roughness: 0.85,\n metalness: 0.05,\n },\n separator: {\n colorOverride: null,\n roughness: 0.8,\n },\n selection: {\n selectedColor: '#ff0000',\n highlightedColor: '#42a5f5',\n },\n warehouse: {\n floorColor: '#8a8a8a',\n floorRoughness: 0.8,\n wallColor: '#d0d0d0',\n wallOpacity: 0.4,\n ambientIntensity: 0.4,\n directionalIntensity: 0.8,\n showGrid: true,\n gridColor: '#666666',\n gridSecondaryColor: '#999999',\n },\n truck: {\n floorColor: '#8a7e72',\n wallColor: '#b0b0b0',\n wallOpacity: 0.35,\n showGrid: true,\n gridColor: '#666666',\n gridSecondaryColor: '#999999',\n cabColor: '#3a5f8a',\n chassisColor: '#2a2a2a',\n wheelColor: '#1a1a1a',\n },\n}\n\n/**\n * Preset INDUSTRIAL — aspecto de almacén profesional.\n * Colores más saturados, iluminación más cálida, bordes contrastados.\n * Usa las texturas y HDR incluidos en /public como base.\n */\nexport const PRESET_INDUSTRIAL: ScenePreset = {\n id: 'industrial',\n name: 'Industrial',\n\n box: {\n color: '#d4895a',\n roughness: 0.7,\n metalness: 0.05,\n opacity: 1,\n },\n pallet: {\n color: '#a8854a',\n edgeColor: '#6b5030',\n roughness: 0.9,\n metalness: 0.02,\n },\n separator: {\n colorOverride: null,\n roughness: 0.85,\n },\n selection: {\n selectedColor: '#e53935',\n highlightedColor: '#29b6f6',\n },\n warehouse: {\n floorColor: '#5c5c5c',\n floorRoughness: 0.92,\n wallColor: '#b0b8be',\n wallOpacity: 0.5,\n ambientIntensity: 0.5,\n directionalIntensity: 1.0,\n showGrid: true,\n gridColor: '#4a4a4a',\n gridSecondaryColor: '#6a6a6a',\n },\n truck: {\n floorColor: '#6e6358',\n wallColor: '#9eaab4',\n wallOpacity: 0.4,\n showGrid: true,\n gridColor: '#4a4a4a',\n gridSecondaryColor: '#6a6a6a',\n cabColor: '#2e4a6b',\n chassisColor: '#1e1e1e',\n wheelColor: '#111111',\n },\n}\n\n/** Mapa de presets disponibles por ID */\nexport const SCENE_PRESETS: Record<string, ScenePreset> = {\n unstyled: PRESET_UNSTYLED,\n industrial: PRESET_INDUSTRIAL,\n}\n\n/** Preset por defecto si el consumidor no elige ninguno */\nexport const DEFAULT_PRESET: ScenePreset = PRESET_INDUSTRIAL\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * PresetContext — Provee el ScenePreset activo a todos los componentes del árbol.\n *\n * Uso:\n * <PresetProvider preset=\"industrial\">\n * <WarehouseScene ... />\n * </PresetProvider>\n *\n * O con un preset custom:\n * <PresetProvider preset={myCustomPreset}>\n * <TruckScene ... />\n * </PresetProvider>\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport { DEFAULT_PRESET, SCENE_PRESETS } from '@/core/presets'\nimport type { ScenePreset } from '@/core/presets'\n\nconst PresetContext = createContext<ScenePreset>(DEFAULT_PRESET)\n\nexport interface PresetProviderProps {\n /** ID de un preset incluido ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n children: ReactNode\n}\n\nexport function PresetProvider({ preset, children }: PresetProviderProps) {\n const resolved = useMemo<ScenePreset>(() => {\n if (!preset) return DEFAULT_PRESET\n if (typeof preset === 'string') return SCENE_PRESETS[preset] ?? DEFAULT_PRESET\n return preset\n }, [preset])\n\n return (\n <PresetContext.Provider value={resolved}>\n {children}\n </PresetContext.Provider>\n )\n}\n\n/** Hook para acceder al preset activo */\nexport function usePreset(): ScenePreset {\n return useContext(PresetContext)\n}\n","/**\n * StackedPallet — Composición vertical de pisos de palet con separadores\n */\n\nimport type { PalletFloor } from './PalletFloor'\nimport type { PlacedBox } from './PlacedBox'\n\nexport interface StackedPallet {\n id: string\n floors: PalletFloor[] // al menos 1\n metadata: Record<string, unknown>\n}\n\n// ─── Helpers puros ───────────────────────────────────────────────\n\n/** Calcula la altura total de un StackedPallet en mm */\nexport function getStackedPalletTotalHeight(stack: StackedPallet): number {\n let height = 0\n for (const floor of stack.floors) {\n height += floor.pallet.dimensions.height\n // Altura máxima de cajas en este piso\n const maxBoxTop = floor.boxes.reduce((max, pb) => {\n const boxTop = pb.position.y + pb.box.dimensions.height\n return Math.max(max, boxTop)\n }, 0)\n height += maxBoxTop\n if (floor.separatorAbove) {\n height += floor.separatorAbove.dimensions.height\n }\n }\n return height\n}\n\n/** Calcula el peso total de un StackedPallet en kg */\nexport function getStackedPalletTotalWeight(stack: StackedPallet): number {\n let weight = 0\n for (const floor of stack.floors) {\n weight += floor.pallet.weight\n weight += floor.boxes.reduce((sum, pb) => sum + pb.box.weight, 0)\n if (floor.separatorAbove) {\n weight += floor.separatorAbove.weight\n }\n }\n return weight\n}\n\n/**\n * Normaliza los IDs de todas las cajas en un StackedPallet para garantizar unicidad global.\n * \n * La librería debe asegurar que cada caja tenga un ID único, independientemente de cómo \n * el desarrollador construya el StackedPallet. Esto evita conflictos de selección cuando\n * hay múltiples pisos o cuando se reutilizan las mismas cajas base.\n * \n * Formato del ID generado: `{stackId}:f{floorIndex}:b{boxIndex}`\n * \n * @param stack - StackedPallet a normalizar\n * @param contextId - ID opcional de contexto (ej: placedPalletId en truck/warehouse)\n * @returns Nuevo StackedPallet con IDs únicos\n */\nexport function ensureUniqueBoxIds(\n stack: StackedPallet,\n contextId?: string,\n): StackedPallet {\n const baseId = contextId || stack.id\n \n const normalizedFloors: PalletFloor[] = stack.floors.map((floor, floorIdx) => {\n const normalizedBoxes: PlacedBox[] = floor.boxes.map((pb, boxIdx) => {\n // Generar ID único: contextId:f{floor}:b{box}\n const uniqueId = `${baseId}:f${floorIdx}:b${boxIdx}`\n \n // Actualizar referencias supportedBy/supporting para mantener consistencia\n const updateRefs = (refs: string[]) =>\n refs.map(refId => {\n // Si la referencia es un ID antiguo dentro de este floor, actualizarla\n const refBoxIdx = floor.boxes.findIndex(b => b.id === refId)\n return refBoxIdx >= 0 ? `${baseId}:f${floorIdx}:b${refBoxIdx}` : refId\n })\n\n return {\n ...pb,\n id: uniqueId,\n supportedBy: updateRefs(pb.supportedBy),\n supporting: updateRefs(pb.supporting),\n }\n })\n\n return {\n ...floor,\n boxes: normalizedBoxes,\n }\n })\n\n return {\n ...stack,\n floors: normalizedFloors,\n }\n}\n","/**\n * Collision detection — AABB helpers y detección de colisiones\n * BR-002: Sin colisiones entre cajas\n * BR-003: Sin colisiones entre palets\n */\n\nimport type { BoundingBox, ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport { getStackedPalletTotalHeight } from '../entities/StackedPallet'\nimport { COLLISION_TOLERANCE } from '../constants'\n\n// ─── Helpers ─────────────────────────────────────────────────────\n\n/** Calcula el bounding box de una PlacedBox (teniendo en cuenta rotación discreta en Y) */\nexport function getBoxBoundingBox(pb: PlacedBox): BoundingBox {\n let w = pb.box.dimensions.width\n let d = pb.box.dimensions.depth\n const h = pb.box.dimensions.height\n\n // Rotación en Y: intercambia width y depth a 90° y 270°\n if (pb.rotation.y === 90 || pb.rotation.y === 270) {\n ;[w, d] = [d, w]\n }\n\n return {\n minX: pb.position.x,\n maxX: pb.position.x + w,\n minY: pb.position.y,\n maxY: pb.position.y + h,\n minZ: pb.position.z,\n maxZ: pb.position.z + d,\n }\n}\n\n/** Calcula el bounding box de un PlacedPallet completo */\nexport function getPalletBoundingBox(pp: PlacedPallet): BoundingBox {\n const stack = pp.stackedPallet\n const basePallet = stack.floors[0].pallet\n const w = basePallet.dimensions.width\n const d = basePallet.dimensions.depth\n const totalH = getStackedPalletTotalHeight(stack)\n\n // Convertir rotación a radianes\n const rotRad = (pp.yRotation * Math.PI) / 180\n const cos = Math.cos(rotRad)\n const sin = Math.sin(rotRad)\n\n // Calcular las 4 esquinas en coordenadas locales (sin rotar)\n const localCorners = [\n { x: 0, z: 0 },\n { x: w, z: 0 },\n { x: w, z: d },\n { x: 0, z: d },\n ]\n\n // Rotar cada esquina usando la convención Three.js (R_y) y trasladar a posición mundial\n // Three.js Y-rotation: x' = x·cos + z·sin, z' = -x·sin + z·cos\n const worldCorners = localCorners.map(corner => ({\n x: pp.position.x + corner.x * cos + corner.z * sin,\n z: pp.position.z - corner.x * sin + corner.z * cos,\n }))\n\n // Encontrar límites del bounding box\n const minX = Math.min(...worldCorners.map(c => c.x))\n const maxX = Math.max(...worldCorners.map(c => c.x))\n const minZ = Math.min(...worldCorners.map(c => c.z))\n const maxZ = Math.max(...worldCorners.map(c => c.z))\n\n return {\n minX,\n maxX,\n minY: pp.position.y,\n maxY: pp.position.y + totalH,\n minZ,\n maxZ,\n }\n}\n\n/** Comprueba si dos AABBs se intersectan (con tolerancia) */\nexport function aabbIntersects(a: BoundingBox, b: BoundingBox, tolerance = COLLISION_TOLERANCE): boolean {\n return (\n a.minX < b.maxX - tolerance &&\n a.maxX > b.minX + tolerance &&\n a.minY < b.maxY - tolerance &&\n a.maxY > b.minY + tolerance &&\n a.minZ < b.maxZ - tolerance &&\n a.maxZ > b.minZ + tolerance\n )\n}\n\n// ─── Validación ──────────────────────────────────────────────────\n\n/** BR-002: Valida que no hay colisiones entre cajas */\nexport function validateNoBoxCollisions(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (let i = 0; i < boxes.length; i++) {\n for (let j = i + 1; j < boxes.length; j++) {\n const bbA = getBoxBoundingBox(boxes[i])\n const bbB = getBoxBoundingBox(boxes[j])\n if (aabbIntersects(bbA, bbB)) {\n violations.push({\n code: 'BR-002',\n severity: 'error',\n message: `Colisión entre cajas ${boxes[i].id} y ${boxes[j].id}`,\n involvedIds: [boxes[i].id, boxes[j].id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-003: Valida que no hay colisiones entre palets */\nexport function validateNoPalletCollisions(pallets: PlacedPallet[]): ValidationResult {\n const violations: Violation[] = []\n\n for (let i = 0; i < pallets.length; i++) {\n for (let j = i + 1; j < pallets.length; j++) {\n const bbA = getPalletBoundingBox(pallets[i])\n const bbB = getPalletBoundingBox(pallets[j])\n if (aabbIntersects(bbA, bbB)) {\n violations.push({\n code: 'BR-003',\n severity: 'error',\n message: `Colisión entre palets ${pallets[i].id} y ${pallets[j].id}`,\n involvedIds: [pallets[i].id, pallets[j].id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Bounds validation — Límites de contenedor\n * BR-001: Caja dentro de palet\n * BR-402: Palet dentro de camión\n * BR-403/404: Altura dentro de contenedor\n */\n\nimport type { ValidationResult, Violation, Dimensions3D } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport type { Truck } from '../entities/Truck'\nimport { getBoxBoundingBox, getPalletBoundingBox } from './collision'\n\n// ─── BR-001: Caja dentro de palet ────────────────────────────────\n\nexport function validateBoxInPalletBounds(box: PlacedBox, pallet: Pallet): ValidationResult {\n const violations: Violation[] = []\n const bb = getBoxBoundingBox(box)\n\n if (bb.minX < 0 || bb.maxX > pallet.dimensions.width) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} sobresale por el eje X del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n if (bb.minZ < 0 || bb.maxZ > pallet.dimensions.depth) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} sobresale por el eje Z del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n if (bb.maxY > pallet.maxStackHeight) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} excede la altura máxima de apilamiento del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** Valida todas las cajas de un piso contra los límites del palet */\nexport function validateAllBoxesInPalletBounds(boxes: PlacedBox[], pallet: Pallet): ValidationResult {\n const violations: Violation[] = []\n for (const box of boxes) {\n const result = validateBoxInPalletBounds(box, pallet)\n violations.push(...result.violations)\n }\n return { isValid: violations.length === 0, violations }\n}\n\n// ─── BR-402: Palet dentro de camión ──────────────────────────────\n\nexport function validatePalletInTruck(pallet: PlacedPallet, truck: Truck): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n const td: Dimensions3D = truck.dimensions\n\n if (bb.minX < 0 || bb.maxX > td.width) {\n violations.push({\n code: 'BR-402',\n severity: 'error',\n message: `Palet ${pallet.id} sobresale por el ancho del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n if (bb.minZ < 0 || bb.maxZ > td.depth) {\n violations.push({\n code: 'BR-402',\n severity: 'error',\n message: `Palet ${pallet.id} sobresale por la profundidad del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n // BR-404\n if (bb.maxY > td.height) {\n violations.push({\n code: 'BR-404',\n severity: 'error',\n message: `Palet ${pallet.id} excede la altura del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-403: Palet dentro de estancia (por altura) */\nexport function validatePalletHeight(pallet: PlacedPallet, ceilingHeight: number): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n\n if (bb.maxY > ceilingHeight) {\n violations.push({\n code: 'BR-403',\n severity: 'error',\n message: `Palet ${pallet.id} excede el techo de la estancia (${bb.maxY}mm > ${ceilingHeight}mm)`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Weight validation\n * BR-101: Peso máximo de palet\n * BR-102: Peso máximo de camión\n * BR-103: Peso sobre caja frágil\n * BR-104: Distribución de peso en palet\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport type { Truck } from '../entities/Truck'\nimport type { PalletFloor } from '../entities/PalletFloor'\nimport { getStackedPalletTotalWeight } from '../entities/StackedPallet'\nimport { WEIGHT_WARNING_THRESHOLD } from '../constants'\nimport { getBoxBoundingBox } from './collision'\n\n// ─── BR-101: Peso máximo de palet ────────────────────────────────\n\nexport function validatePalletWeight(floor: PalletFloor): ValidationResult {\n const violations: Violation[] = []\n const totalBoxWeight = floor.boxes.reduce((sum, pb) => sum + pb.box.weight, 0)\n const maxWeight = floor.pallet.maxWeight\n\n if (totalBoxWeight > maxWeight) {\n violations.push({\n code: 'BR-101',\n severity: 'error',\n message: `Peso de cajas (${totalBoxWeight.toFixed(1)}kg) excede el máximo del palet (${maxWeight}kg)`,\n involvedIds: [floor.pallet.id],\n })\n } else if (totalBoxWeight > maxWeight * WEIGHT_WARNING_THRESHOLD) {\n violations.push({\n code: 'BR-101',\n severity: 'warning',\n message: `Peso de cajas (${totalBoxWeight.toFixed(1)}kg) supera el 90% del máximo del palet (${maxWeight}kg)`,\n involvedIds: [floor.pallet.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n\n// ─── BR-102: Peso máximo de camión ───────────────────────────────\n\nexport function validateTruckWeight(truck: Truck): ValidationResult {\n const violations: Violation[] = []\n const totalWeight = truck.pallets.reduce(\n (sum, pp) => sum + getStackedPalletTotalWeight(pp.stackedPallet),\n 0,\n )\n\n if (totalWeight > truck.maxWeight) {\n violations.push({\n code: 'BR-102',\n severity: 'error',\n message: `Peso total (${totalWeight.toFixed(1)}kg) excede el máximo del camión (${truck.maxWeight}kg)`,\n involvedIds: [truck.id],\n })\n } else if (totalWeight > truck.maxWeight * WEIGHT_WARNING_THRESHOLD) {\n violations.push({\n code: 'BR-102',\n severity: 'warning',\n message: `Peso total (${totalWeight.toFixed(1)}kg) supera el 90% del máximo del camión (${truck.maxWeight}kg)`,\n involvedIds: [truck.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n\n// ─── BR-103: Peso sobre caja frágil ─────────────────────────────\n\nexport function validateFragileLoad(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n if (!pb.box.fragile) continue\n const maxAbove = pb.box.fragilityMaxWeight ?? 0\n const weightAbove = calculateWeightAboveBox(pb, boxes)\n if (weightAbove > maxAbove) {\n violations.push({\n code: 'BR-103',\n severity: 'error',\n message: `Caja frágil ${pb.id} soporta ${weightAbove.toFixed(1)}kg (máx: ${maxAbove}kg)`,\n involvedIds: [pb.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** Calcula el peso soportado encima de una caja */\nfunction calculateWeightAboveBox(target: PlacedBox, allBoxes: PlacedBox[]): number {\n const tbb = getBoxBoundingBox(target)\n let weight = 0\n\n for (const other of allBoxes) {\n if (other.id === target.id) continue\n const obb = getBoxBoundingBox(other)\n // La otra caja está encima y se solapa horizontalmente\n if (\n obb.minY >= tbb.maxY - 1 &&\n obb.minX < tbb.maxX &&\n obb.maxX > tbb.minX &&\n obb.minZ < tbb.maxZ &&\n obb.maxZ > tbb.minZ\n ) {\n weight += other.box.weight\n }\n }\n\n return weight\n}\n\n// ─── BR-104: Distribución de peso ────────────────────────────────\n\nexport function validateWeightDistribution(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const totalWeight = boxes.reduce((s, pb) => s + pb.box.weight, 0)\n if (totalWeight === 0) return { isValid: true, violations }\n\n // Centro de gravedad ponderado por peso\n let cogX = 0, cogZ = 0\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n const cx = (bb.minX + bb.maxX) / 2\n const cz = (bb.minZ + bb.maxZ) / 2\n cogX += cx * pb.box.weight\n cogZ += cz * pb.box.weight\n }\n cogX /= totalWeight\n cogZ /= totalWeight\n\n const centerX = pallet.dimensions.width / 2\n const centerZ = pallet.dimensions.depth / 2\n\n if (\n Math.abs(cogX - centerX) > pallet.dimensions.width / 6 ||\n Math.abs(cogZ - centerZ) > pallet.dimensions.depth / 6\n ) {\n violations.push({\n code: 'BR-104',\n severity: 'warning',\n message: `Centro de gravedad descentrado (${cogX.toFixed(0)}, ${cogZ.toFixed(0)}) respecto al centro del palet`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: true, violations }\n}\n","/**\n * Stacking validation\n * BR-201: Caja apilable\n * BR-202: Capacidad de soporte de caja\n * BR-203: Pirámide invertida\n * BR-301: Mismas dimensiones de planta en stack\n * BR-302: Separador obligatorio\n * BR-303: Altura total del stack\n * BR-304: Peso acumulado del stack\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { StackedPallet } from '../entities/StackedPallet'\nimport { getStackedPalletTotalHeight, getStackedPalletTotalWeight } from '../entities/StackedPallet'\nimport { getBoxBoundingBox } from './collision'\n\n// ─── Apilamiento de cajas ────────────────────────────────────────\n\n/** BR-201: Valida que solo cajas apilables tienen otras encima */\nexport function validateBoxStackability(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n if (pb.box.stackable) continue\n\n // Comprobar si hay algo encima\n const bb = getBoxBoundingBox(pb)\n for (const other of boxes) {\n if (other.id === pb.id) continue\n const obb = getBoxBoundingBox(other)\n if (\n obb.minY >= bb.maxY - 1 &&\n obb.minX < bb.maxX && obb.maxX > bb.minX &&\n obb.minZ < bb.maxZ && obb.maxZ > bb.minZ\n ) {\n violations.push({\n code: 'BR-201',\n severity: 'error',\n message: `Caja ${other.id} apilada sobre caja no apilable ${pb.id}`,\n involvedIds: [pb.id, other.id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-203: Pirámide invertida — caja pesada sobre caja ligera */\nexport function validateInvertedPyramid(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const bottom of boxes) {\n const bbb = getBoxBoundingBox(bottom)\n const bottomArea = (bbb.maxX - bbb.minX) * (bbb.maxZ - bbb.minZ)\n\n for (const top of boxes) {\n if (top.id === bottom.id) continue\n const tbb = getBoxBoundingBox(top)\n if (tbb.minY < bbb.maxY - 1) continue\n // Overlap check\n if (tbb.minX >= bbb.maxX || tbb.maxX <= bbb.minX || tbb.minZ >= bbb.maxZ || tbb.maxZ <= bbb.minZ) continue\n\n const topArea = (tbb.maxX - tbb.minX) * (tbb.maxZ - tbb.minZ)\n if (top.box.weight > bottom.box.weight * 1.5 && topArea > bottomArea * 1.2) {\n violations.push({\n code: 'BR-203',\n severity: 'warning',\n message: `Pirámide invertida: caja ${top.id} (${top.box.weight}kg) sobre caja ${bottom.id} (${bottom.box.weight}kg)`,\n involvedIds: [bottom.id, top.id],\n })\n }\n }\n }\n\n return { isValid: true, violations }\n}\n\n// ─── Apilamiento de palets ───────────────────────────────────────\n\n/** BR-301: Todos los palets en un stack deben tener mismas dimensiones de planta */\nexport function validateStackDimensions(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n if (stack.floors.length <= 1) return { isValid: true, violations }\n\n const base = stack.floors[0].pallet\n for (let i = 1; i < stack.floors.length; i++) {\n const p = stack.floors[i].pallet\n if (p.dimensions.width !== base.dimensions.width || p.dimensions.depth !== base.dimensions.depth) {\n violations.push({\n code: 'BR-301',\n severity: 'error',\n message: `Piso ${i}: dimensiones (${p.dimensions.width}×${p.dimensions.depth}) distintas a la base (${base.dimensions.width}×${base.dimensions.depth})`,\n involvedIds: [base.id, p.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-302: Separador obligatorio entre pisos */\nexport function validateSeparators(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n for (let i = 0; i < stack.floors.length - 1; i++) {\n if (!stack.floors[i].separatorAbove) {\n violations.push({\n code: 'BR-302',\n severity: 'error',\n message: `Falta separador entre piso ${i} y piso ${i + 1}`,\n involvedIds: [stack.id],\n })\n }\n }\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-303: Altura total del stack ≤ altura del contenedor */\nexport function validateStackHeight(stack: StackedPallet, containerHeight: number): ValidationResult {\n const violations: Violation[] = []\n const totalH = getStackedPalletTotalHeight(stack)\n\n if (totalH > containerHeight) {\n violations.push({\n code: 'BR-303',\n severity: 'error',\n message: `Altura del stack (${totalH}mm) excede la del contenedor (${containerHeight}mm)`,\n involvedIds: [stack.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-304: Peso total del stack ≤ maxWeight del palet base */\nexport function validateStackWeight(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n const totalWeight = getStackedPalletTotalWeight(stack)\n const baseMaxWeight = stack.floors[0].pallet.maxWeight\n\n // Descontar el peso del palet base, ya que maxWeight es la capacidad de carga\n const loadWeight = totalWeight - stack.floors[0].pallet.weight\n if (loadWeight > baseMaxWeight) {\n violations.push({\n code: 'BR-304',\n severity: 'error',\n message: `Peso de carga del stack (${loadWeight.toFixed(1)}kg) excede la capacidad del palet base (${baseMaxWeight}kg)`,\n involvedIds: [stack.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Gravity validation — BR-004: Objetos no flotan\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport { getBoxBoundingBox } from './collision'\nimport { MIN_SUPPORT_PERCENTAGE } from '../constants'\n\n/**\n * BR-004: Valida que toda caja tiene soporte debajo (suelo del palet u otra caja)\n * Al menos MIN_SUPPORT_PERCENTAGE del área base debe estar soportada\n */\nexport function validateSupport(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n\n // Si la caja está en el suelo (Y ≈ 0), tiene soporte\n if (bb.minY <= 1) continue\n\n const boxArea = (bb.maxX - bb.minX) * (bb.maxZ - bb.minZ)\n let supportedArea = 0\n\n for (const other of boxes) {\n if (other.id === pb.id) continue\n const obb = getBoxBoundingBox(other)\n\n // La otra caja está justo debajo (su top ≈ nuestra bottom)\n if (Math.abs(obb.maxY - bb.minY) > 2) continue\n\n // Calcular área de solapamiento en XZ\n const overlapX = Math.max(0, Math.min(bb.maxX, obb.maxX) - Math.max(bb.minX, obb.minX))\n const overlapZ = Math.max(0, Math.min(bb.maxZ, obb.maxZ) - Math.max(bb.minZ, obb.minZ))\n supportedArea += overlapX * overlapZ\n }\n\n if (boxArea > 0 && supportedArea / boxArea < MIN_SUPPORT_PERCENTAGE) {\n violations.push({\n code: 'BR-004',\n severity: 'error',\n message: `Caja ${pb.id} sin soporte suficiente (${((supportedArea / boxArea) * 100).toFixed(0)}% < ${MIN_SUPPORT_PERCENTAGE * 100}%)`,\n involvedIds: [pb.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Stability validation — Centro de gravedad y estabilidad\n * BR-501: Score de estabilidad mínimo\n * BR-502: Centro de gravedad dentro del polígono de soporte\n * BR-503: Altura del centro de gravedad\n */\n\nimport type { Position3D, ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport { getBoxBoundingBox } from './collision'\n\n/** Calcula el centro de gravedad de un conjunto de cajas */\nexport function calculateCenterOfGravity(boxes: PlacedBox[]): Position3D {\n if (boxes.length === 0) return { x: 0, y: 0, z: 0 }\n\n let totalWeight = 0\n let cogX = 0, cogY = 0, cogZ = 0\n\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n const cx = (bb.minX + bb.maxX) / 2\n const cy = (bb.minY + bb.maxY) / 2\n const cz = (bb.minZ + bb.maxZ) / 2\n const w = pb.box.weight\n\n cogX += cx * w\n cogY += cy * w\n cogZ += cz * w\n totalWeight += w\n }\n\n if (totalWeight === 0) return { x: 0, y: 0, z: 0 }\n\n return {\n x: cogX / totalWeight,\n y: cogY / totalWeight,\n z: cogZ / totalWeight,\n }\n}\n\n/** Calcula el score de estabilidad (0-100) */\nexport function calculateStabilityScore(pallet: Pallet, boxes: PlacedBox[]): number {\n if (boxes.length === 0) return 100\n\n const cog = calculateCenterOfGravity(boxes)\n const centerX = pallet.dimensions.width / 2\n const centerZ = pallet.dimensions.depth / 2\n\n // Distancia normalizada del CoG al centro\n const dx = Math.abs(cog.x - centerX) / (pallet.dimensions.width / 2)\n const dz = Math.abs(cog.z - centerZ) / (pallet.dimensions.depth / 2)\n const horizontalScore = Math.max(0, 100 - (dx + dz) * 50)\n\n // Penalizar CoG alto\n const maxBoxY = boxes.reduce((max, pb) => {\n const bb = getBoxBoundingBox(pb)\n return Math.max(max, bb.maxY)\n }, 0)\n const heightRatio = maxBoxY > 0 ? cog.y / maxBoxY : 0\n const verticalScore = Math.max(0, 100 - Math.max(0, heightRatio - 0.5) * 100)\n\n return Math.round((horizontalScore * 0.7 + verticalScore * 0.3))\n}\n\n/** BR-502: CoG dentro del polígono de soporte (planta del palet) */\nexport function validateCogInsideSupport(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const cog = calculateCenterOfGravity(boxes)\n\n if (cog.x < 0 || cog.x > pallet.dimensions.width || cog.z < 0 || cog.z > pallet.dimensions.depth) {\n violations.push({\n code: 'BR-502',\n severity: 'error',\n message: `Centro de gravedad (${cog.x.toFixed(0)}, ${cog.z.toFixed(0)}) fuera del palet`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-501 + BR-503: Score de estabilidad y CoG alto */\nexport function validateStability(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const score = calculateStabilityScore(pallet, boxes)\n\n if (score < 50) {\n violations.push({\n code: 'BR-501',\n severity: 'error',\n message: `Score de estabilidad bajo (${score}/100, mínimo: 50)`,\n involvedIds: [pallet.id],\n })\n } else if (score < 70) {\n violations.push({\n code: 'BR-501',\n severity: 'warning',\n message: `Score de estabilidad mejorable (${score}/100, recomendado: ≥70)`,\n involvedIds: [pallet.id],\n })\n }\n\n // BR-503: CoG alto\n const cog = calculateCenterOfGravity(boxes)\n const maxY = boxes.reduce((max, pb) => Math.max(max, getBoxBoundingBox(pb).maxY), 0)\n if (maxY > 0 && cog.y > maxY * 0.6) {\n violations.push({\n code: 'BR-503',\n severity: 'warning',\n message: `Centro de gravedad alto (${cog.y.toFixed(0)}mm, ${((cog.y / maxY) * 100).toFixed(0)}% de la altura)`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n","/**\n * Polygon validation — Point-in-polygon para estancias\n * BR-401: Palet dentro del polígono de la estancia\n */\n\nimport type { Point2D, ValidationResult, Violation } from '../types'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport type { Room } from '../entities/Room'\nimport { getPalletBoundingBox } from './collision'\n\n/**\n * Point-in-polygon test (ray casting algorithm)\n */\nexport function pointInPolygon(point: Point2D, polygon: Point2D[]): boolean {\n let inside = false\n const n = polygon.length\n\n for (let i = 0, j = n - 1; i < n; j = i++) {\n const xi = polygon[i].x, zi = polygon[i].z\n const xj = polygon[j].x, zj = polygon[j].z\n\n if (\n ((zi > point.z) !== (zj > point.z)) &&\n (point.x < (xj - xi) * (point.z - zi) / (zj - zi) + xi)\n ) {\n inside = !inside\n }\n }\n\n return inside\n}\n\n/** BR-401: Valida que un palet está completamente dentro del polígono de la estancia */\nexport function validatePalletInRoom(pallet: PlacedPallet, room: Room): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n\n // Test las 4 esquinas de la huella 2D del palet\n const corners: Point2D[] = [\n { x: bb.minX, z: bb.minZ },\n { x: bb.maxX, z: bb.minZ },\n { x: bb.maxX, z: bb.maxZ },\n { x: bb.minX, z: bb.maxZ },\n ]\n\n for (const corner of corners) {\n if (!pointInPolygon(corner, room.floorPolygon)) {\n violations.push({\n code: 'BR-401',\n severity: 'error',\n message: `Palet ${pallet.id} fuera de la estancia ${room.name} en (${corner.x}, ${corner.z})`,\n involvedIds: [pallet.id, room.id],\n })\n break // Una esquina fuera es suficiente\n }\n }\n\n // BR-403: Altura\n if (bb.maxY > room.ceilingHeight) {\n violations.push({\n code: 'BR-403',\n severity: 'error',\n message: `Palet ${pallet.id} excede el techo de la estancia ${room.name}`,\n involvedIds: [pallet.id, room.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * ColumnStrategy — Empaquetado en columnas verticales por tipo de caja\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\n\nexport class ColumnStrategy implements PackingStrategy {\n readonly id = 'column'\n readonly name = 'Columnas por tipo'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Agrupar cajas por tipo/SKU\n const groups = new Map<string, Box[]>()\n for (const box of boxes) {\n const key = box.type ?? box.sku ?? 'default'\n if (!groups.has(key)) groups.set(key, [])\n groups.get(key)!.push(box)\n }\n\n let cursorX = 0\n let placementId = 0\n\n for (const [, groupBoxes] of groups) {\n if (groupBoxes.length === 0) continue\n const refBox = groupBoxes[0]\n const colWidth = refBox.dimensions.width\n const colDepth = refBox.dimensions.depth\n const boxHeight = refBox.dimensions.height\n\n // ¿Cabe una nueva columna en X?\n if (cursorX + colWidth > pallet.dimensions.width) {\n unplacedBoxes.push(...groupBoxes)\n continue\n }\n\n let cursorZ = 0\n let cursorY = 0\n let boxIdx = 0\n\n while (boxIdx < groupBoxes.length) {\n const box = groupBoxes[boxIdx]\n\n // ¿Cabe en Z?\n if (cursorZ + colDepth > pallet.dimensions.depth) {\n // Nueva capa vertical\n cursorZ = 0\n cursorY += boxHeight\n if (cursorY + boxHeight > pallet.maxStackHeight) {\n // No cabe más en esta columna\n unplacedBoxes.push(...groupBoxes.slice(boxIdx))\n break\n }\n continue\n }\n\n placements.push({\n id: `placed-${++placementId}`,\n box,\n position: { x: cursorX, y: cursorY, z: cursorZ },\n rotation: { x: 0, y: 0, z: 0 },\n supportedBy: [],\n supporting: [],\n })\n\n cursorZ += colDepth\n boxIdx++\n }\n\n cursorX += colWidth\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n const cog = calculateCenterOfGravity(placements)\n const stability = calculateStabilityScore(pallet, placements)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: cog,\n stabilityScore: stability,\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * BinPacking3D — Optimización volumétrica (First Fit Decreasing Height)\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\nimport { getBoxBoundingBox, aabbIntersects } from '../validation/collision'\n\ninterface Space {\n x: number\n y: number\n z: number\n width: number\n height: number\n depth: number\n}\n\nexport class BinPacking3DStrategy implements PackingStrategy {\n readonly id = 'bin-packing-3d'\n readonly name = 'Bin Packing 3D (FFD Height)'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Ordenar por volumen descendente (First Fit Decreasing)\n const sorted = [...boxes].sort((a, b) => {\n const va = a.dimensions.width * a.dimensions.height * a.dimensions.depth\n const vb = b.dimensions.width * b.dimensions.height * b.dimensions.depth\n return vb - va\n })\n\n // Espacios libres: empezamos con el palet completo\n const spaces: Space[] = [\n {\n x: 0,\n y: 0,\n z: 0,\n width: pallet.dimensions.width,\n height: pallet.maxStackHeight,\n depth: pallet.dimensions.depth,\n },\n ]\n\n let placementId = 0\n\n for (const box of sorted) {\n let placed = false\n\n // Intentar colocar en cada espacio libre\n // Probar orientaciones: normal y rotada 90° en Y\n const orientations = [\n { w: box.dimensions.width, h: box.dimensions.height, d: box.dimensions.depth, rot: 0 as const },\n { w: box.dimensions.depth, h: box.dimensions.height, d: box.dimensions.width, rot: 90 as const },\n ]\n\n for (let si = 0; si < spaces.length && !placed; si++) {\n const space = spaces[si]\n\n for (const ori of orientations) {\n if (ori.w <= space.width && ori.h <= space.height && ori.d <= space.depth) {\n const newPlacement: PlacedBox = {\n id: `placed-${++placementId}`,\n box,\n position: { x: space.x, y: space.y, z: space.z },\n rotation: { x: 0, y: ori.rot, z: 0 },\n supportedBy: [],\n supporting: [],\n }\n\n // Verificar colisiones con colocaciones existentes\n const newBB = getBoxBoundingBox(newPlacement)\n const collides = placements.some(existing =>\n aabbIntersects(getBoxBoundingBox(existing), newBB),\n )\n\n if (!collides) {\n placements.push(newPlacement)\n placed = true\n\n // Subdividir espacio restante (3 nuevos espacios)\n spaces.splice(si, 1)\n\n // Espacio a la derecha\n if (space.width - ori.w > 0) {\n spaces.push({\n x: space.x + ori.w,\n y: space.y,\n z: space.z,\n width: space.width - ori.w,\n height: space.height,\n depth: space.depth,\n })\n }\n // Espacio arriba\n if (space.height - ori.h > 0) {\n spaces.push({\n x: space.x,\n y: space.y + ori.h,\n z: space.z,\n width: ori.w,\n height: space.height - ori.h,\n depth: ori.d,\n })\n }\n // Espacio detrás\n if (space.depth - ori.d > 0) {\n spaces.push({\n x: space.x,\n y: space.y,\n z: space.z + ori.d,\n width: ori.w,\n height: space.height,\n depth: space.depth - ori.d,\n })\n }\n\n // Ordenar espacios por posición (preferir abajo, izquierda, delante)\n spaces.sort((a, b) => a.y - b.y || a.x - b.x || a.z - b.z)\n break\n }\n }\n }\n }\n\n if (!placed) {\n unplacedBoxes.push(box)\n }\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: calculateCenterOfGravity(placements),\n stabilityScore: calculateStabilityScore(pallet, placements),\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * TypeGroupStrategy — Agrupación por tipo, relleno capa a capa\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\n\nexport class TypeGroupStrategy implements PackingStrategy {\n readonly id = 'type-group'\n readonly name = 'Agrupación por tipo'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Ordenar por tipo, y dentro de tipo por peso desc (frágiles al final/arriba)\n const sorted = [...boxes].sort((a, b) => {\n const typeA = a.type ?? a.sku ?? 'z'\n const typeB = b.type ?? b.sku ?? 'z'\n if (typeA !== typeB) return typeA.localeCompare(typeB)\n // Frágiles después (irán arriba)\n if (a.fragile !== b.fragile) return a.fragile ? 1 : -1\n return b.weight - a.weight\n })\n\n let cursorX = 0\n let cursorZ = 0\n let cursorY = 0\n let layerMaxHeight = 0\n let placementId = 0\n\n for (const box of sorted) {\n const w = box.dimensions.width\n const h = box.dimensions.height\n const d = box.dimensions.depth\n\n // ¿Cabe en X?\n if (cursorX + w > pallet.dimensions.width) {\n cursorX = 0\n cursorZ += layerMaxHeight > 0 ? d : 0\n // Use previous depth if available\n }\n\n // ¿Cabe en Z?\n if (cursorZ + d > pallet.dimensions.depth) {\n // Nueva capa vertical\n cursorX = 0\n cursorZ = 0\n cursorY += layerMaxHeight\n layerMaxHeight = 0\n }\n\n // ¿Cabe en Y?\n if (cursorY + h > pallet.maxStackHeight) {\n unplacedBoxes.push(box)\n continue\n }\n\n // ¿Cabe en X después del reset?\n if (cursorX + w > pallet.dimensions.width) {\n unplacedBoxes.push(box)\n continue\n }\n\n if (cursorZ + d > pallet.dimensions.depth) {\n unplacedBoxes.push(box)\n continue\n }\n\n placements.push({\n id: `placed-${++placementId}`,\n box,\n position: { x: cursorX, y: cursorY, z: cursorZ },\n rotation: { x: 0, y: 0, z: 0 },\n supportedBy: [],\n supporting: [],\n })\n\n cursorX += w\n layerMaxHeight = Math.max(layerMaxHeight, h)\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: calculateCenterOfGravity(placements),\n stabilityScore: calculateStabilityScore(pallet, placements),\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * PackingRegistry — Registro de estrategias de empaquetado\n */\n\nimport type { PackingStrategy } from './PackingStrategy'\nimport { ColumnStrategy } from './ColumnStrategy'\nimport { BinPacking3DStrategy } from './BinPacking3D'\nimport { TypeGroupStrategy } from './TypeGroupStrategy'\n\nexport class PackingRegistry {\n private strategies = new Map<string, PackingStrategy>()\n\n constructor() {\n // Registrar estrategias built-in\n this.register(new ColumnStrategy())\n this.register(new BinPacking3DStrategy())\n this.register(new TypeGroupStrategy())\n }\n\n register(strategy: PackingStrategy): void {\n this.strategies.set(strategy.id, strategy)\n }\n\n get(id: string): PackingStrategy {\n const strategy = this.strategies.get(id)\n if (!strategy) {\n throw new Error(`Packing strategy \"${id}\" not found. Available: ${this.listIds().join(', ')}`)\n }\n return strategy\n }\n\n list(): PackingStrategy[] {\n return Array.from(this.strategies.values())\n }\n\n listIds(): string[] {\n return Array.from(this.strategies.keys())\n }\n\n has(id: string): boolean {\n return this.strategies.has(id)\n }\n}\n\n/** Instancia global del registro (singleton de conveniencia) */\nexport const defaultRegistry = new PackingRegistry()\n","/**\n * PalletFactory — Factories para crear palets estándar y custom\n * \n * Proporciona métodos para instanciar los principales tipos de palets\n * utilizados en logística internacional (EUR, GMA, UK, Asia, etc.)\n */\n\nimport type { Pallet } from '../entities/Pallet'\nimport type { Dimensions3D } from '../types'\nimport { PalletMaterial } from '../types'\nimport { STANDARD_PALLETS } from '../constants'\n\nlet _palletCounter = 0\n\nfunction nextPalletId(): string {\n return `pallet-${++_palletCounter}`\n}\n\nexport class PalletFactory {\n // ═══ Palets estándar internacionales ═══════════════════════════\n\n /** Palet EUR/EPAL — Estándar europeo (1200×800×144mm, ISO 6780, madera, 1000kg) */\n static euro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('EUR', overrides)\n }\n\n /** Palet GMA — Estándar norteamericano (1219×1016×145mm, 48\"×40\", madera, 1200kg) */\n static gma(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('GMA', overrides)\n }\n\n /** @deprecated Use gma() instead. Alias para compatibilidad. */\n static american(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.gma(overrides)\n }\n\n /** Palet UK Standard — Reino Unido (1200×1000×150mm, madera, 1000kg) */\n static uk(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('UK', overrides)\n }\n\n /** Palet Asia — Estándar asiático (1100×1100×150mm, ISO 6780, madera, 1000kg) */\n static asia(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ASIA', overrides)\n }\n\n /** Palet australiano — Estándar de Australia (1165×1165×150mm, madera, 1000kg) */\n static australian(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('AUSTRALIAN', overrides)\n }\n\n /** Medio palet EUR — Half European Pallet (800×600×144mm, madera, 500kg) */\n static halfEuro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('HALF_EUR', overrides)\n }\n\n /** Cuarto de palet EUR — Quarter European Pallet (600×400×144mm, madera, 250kg) */\n static quarterEuro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('QUARTER_EUR', overrides)\n }\n\n /** Palet ISO 1 — ISO 6780 (1200×1000×150mm, igual que UK) */\n static iso1(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ISO_1', overrides)\n }\n\n /** Palet ISO 2 — ISO 6780 (1200×800×144mm, equivalente a EUR) */\n static iso2(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ISO_2', overrides)\n }\n\n // ═══ Método genérico desde preset ═════════════════════════════\n\n /**\n * Crea un palet desde un preset por su clave\n * @param presetKey - Clave del preset (EUR, GMA, UK, ASIA, etc.)\n * @param overrides - Propiedades a sobrescribir\n */\n static fromPreset(\n presetKey: keyof typeof STANDARD_PALLETS,\n overrides?: Partial<Pallet>,\n ): Pallet {\n const preset = STANDARD_PALLETS[presetKey]\n if (!preset) {\n throw new Error(`Unknown pallet preset: ${presetKey}`)\n }\n return {\n id: nextPalletId(),\n dimensions: { ...preset.dimensions },\n material: preset.material,\n maxWeight: preset.maxWeight,\n maxStackHeight: preset.maxStackHeight,\n weight: preset.weight,\n metadata: { preset: presetKey },\n ...overrides,\n }\n }\n\n // ═══ Palet custom ══════════════════════════════════════════════\n\n /** Palet custom con dimensiones arbitrarias */\n static custom(dims: Dimensions3D, opts?: Partial<Pallet>): Pallet {\n return {\n id: nextPalletId(),\n dimensions: { ...dims },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n metadata: {},\n ...opts,\n }\n }\n\n // ═══ Utilidades ════════════════════════════════════════════════\n\n /**\n * Lista todos los presets disponibles con sus características\n */\n static listPresets(): Array<{\n key: string\n dimensions: Dimensions3D\n maxWeight: number\n weight: number\n }> {\n return Object.entries(STANDARD_PALLETS).map(([key, preset]) => ({\n key,\n dimensions: preset.dimensions,\n maxWeight: preset.maxWeight,\n weight: preset.weight,\n }))\n }\n}\n","/**\n * TruckFactory — Factories para crear camiones por preset o custom\n */\n\nimport type { Truck } from '../entities/Truck'\nimport type { Dimensions3D } from '../types'\nimport { TruckType } from '../types'\nimport { TRUCK_PRESETS } from '../constants'\n\nlet _truckCounter = 0\n\nfunction nextTruckId(): string {\n return `truck-${++_truckCounter}`\n}\n\nexport class TruckFactory {\n /** Crea un camión a partir de un preset de tipo */\n static fromPreset(type: Exclude<TruckType, 'CUSTOM'>, overrides?: Partial<Truck>): Truck {\n const preset = TRUCK_PRESETS[type]\n return {\n id: nextTruckId(),\n name: `Camión ${type}`,\n truckType: type,\n dimensions: { ...preset.dimensions },\n maxWeight: preset.maxWeight,\n pallets: [],\n metadata: {},\n ...overrides,\n }\n }\n\n /** Crea un camión custom con dimensiones y peso arbitrarios */\n static custom(dims: Dimensions3D, maxWeight: number, overrides?: Partial<Truck>): Truck {\n return {\n id: nextTruckId(),\n name: 'Camión Custom',\n truckType: TruckType.CUSTOM,\n dimensions: { ...dims },\n maxWeight,\n pallets: [],\n metadata: {},\n ...overrides,\n }\n }\n}\n","/**\n * BoxFactory — Helper para crear cajas con defaults\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Dimensions3D } from '../types'\n\nlet _boxCounter = 0\n\nfunction nextBoxId(): string {\n return `box-${++_boxCounter}`\n}\n\nexport class BoxFactory {\n /** Crea una caja con valores por defecto razonables */\n static create(dims: Dimensions3D, opts?: Partial<Box>): Box {\n return {\n id: nextBoxId(),\n dimensions: { ...dims },\n weight: 5,\n fragile: false,\n stackable: true,\n metadata: {},\n ...opts,\n }\n }\n\n /** Caja frágil con peso máximo encima */\n static fragile(dims: Dimensions3D, fragilityMaxWeight: number, opts?: Partial<Box>): Box {\n return BoxFactory.create(dims, {\n fragile: true,\n fragilityMaxWeight,\n ...opts,\n })\n }\n\n /** Caja pesada y no apilable */\n static heavy(dims: Dimensions3D, weight: number, opts?: Partial<Box>): Box {\n return BoxFactory.create(dims, {\n weight,\n stackable: false,\n ...opts,\n })\n }\n}\n","/**\n * usePhysicsValidation — Ejecuta todas las validaciones físicas sobre un piso de palet\n */\n\nimport { useMemo } from 'react'\nimport type { PlacedBox } from '@/core/entities/PlacedBox'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { ValidationResult, Violation } from '@/core/types'\nimport { validateNoBoxCollisions } from '@/core/validation/collision'\nimport { validateAllBoxesInPalletBounds } from '@/core/validation/bounds'\nimport { validatePalletWeight } from '@/core/validation/weight'\nimport { validateFragileLoad, validateWeightDistribution } from '@/core/validation/weight'\nimport { validateSupport } from '@/core/validation/gravity'\nimport { validateBoxStackability, validateInvertedPyramid } from '@/core/validation/stacking'\nimport { validateStability, validateCogInsideSupport } from '@/core/validation/stability'\nimport type { PalletFloor } from '@/core/entities/PalletFloor'\n\nexport interface PhysicsValidationResult {\n isValid: boolean\n violations: Violation[]\n collisions: ValidationResult\n bounds: ValidationResult\n weight: ValidationResult\n gravity: ValidationResult\n stacking: ValidationResult\n stability: ValidationResult\n fragile: ValidationResult\n distribution: ValidationResult\n}\n\nexport function usePhysicsValidation(\n boxes: PlacedBox[],\n pallet: Pallet,\n): PhysicsValidationResult {\n return useMemo(() => {\n const collisions = validateNoBoxCollisions(boxes)\n const bounds = validateAllBoxesInPalletBounds(boxes, pallet)\n const floor: PalletFloor = { level: 0, pallet, boxes }\n const weight = validatePalletWeight(floor)\n const gravity = validateSupport(boxes)\n const stackability = validateBoxStackability(boxes)\n const invertedPyramid = validateInvertedPyramid(boxes)\n const stability = validateStability(pallet, boxes)\n const cogValid = validateCogInsideSupport(pallet, boxes)\n const fragile = validateFragileLoad(boxes)\n const distribution = validateWeightDistribution(pallet, boxes)\n\n const stackingViolations = [...stackability.violations, ...invertedPyramid.violations]\n const stabilityViolations = [...stability.violations, ...cogValid.violations]\n\n const allViolations: Violation[] = [\n ...collisions.violations,\n ...bounds.violations,\n ...weight.violations,\n ...gravity.violations,\n ...stackingViolations,\n ...stabilityViolations,\n ...fragile.violations,\n ...distribution.violations,\n ]\n\n return {\n isValid: allViolations.filter(v => v.severity === 'error').length === 0,\n violations: allViolations,\n collisions,\n bounds,\n weight,\n gravity,\n stacking: {\n isValid: stackability.isValid,\n violations: stackingViolations,\n },\n stability: {\n isValid: stability.isValid && cogValid.isValid,\n violations: stabilityViolations,\n },\n fragile,\n distribution,\n }\n }, [boxes, pallet])\n}\n","/**\n * usePalletMetrics — Calcula métricas de un StackedPallet\n */\n\nimport { useMemo } from 'react'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { getStackedPalletTotalHeight, getStackedPalletTotalWeight } from '@/core/entities/StackedPallet'\nimport type { Position3D, PackingMetrics } from '@/core/types'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '@/core/validation/stability'\n\nexport interface PalletMetricsResult extends PackingMetrics {\n totalHeight: number // mm\n totalWeight: number // kg\n boxCount: number\n floorCount: number\n}\n\nexport function usePalletMetrics(stack: StackedPallet | null): PalletMetricsResult {\n return useMemo(() => {\n if (!stack || stack.floors.length === 0) {\n return {\n volumeUtilization: 0,\n weightUtilization: 0,\n centerOfGravity: { x: 0, y: 0, z: 0 } as Position3D,\n stabilityScore: 100,\n totalHeight: 0,\n totalWeight: 0,\n boxCount: 0,\n floorCount: 0,\n }\n }\n\n const totalHeight = getStackedPalletTotalHeight(stack)\n const totalWeight = getStackedPalletTotalWeight(stack)\n const basePallet = stack.floors[0].pallet\n const allBoxes = stack.floors.flatMap(f => f.boxes)\n const boxCount = allBoxes.length\n const floorCount = stack.floors.length\n\n // Volumen total disponible\n const totalVolume = basePallet.dimensions.width * basePallet.maxStackHeight * basePallet.dimensions.depth\n const usedVolume = allBoxes.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n\n const cog = calculateCenterOfGravity(allBoxes)\n const stability = calculateStabilityScore(basePallet, allBoxes)\n\n return {\n volumeUtilization: totalVolume > 0 ? usedVolume / totalVolume : 0,\n weightUtilization: basePallet.maxWeight > 0 ? totalWeight / basePallet.maxWeight : 0,\n centerOfGravity: cog,\n stabilityScore: stability,\n totalHeight,\n totalWeight,\n boxCount,\n floorCount,\n }\n }, [stack])\n}\n","/**\n * usePackingStrategy — Accede al registry, ejecuta estrategia seleccionada\n */\n\nimport { useMemo, useCallback } from 'react'\nimport type { Box } from '@/core/entities/Box'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { PackingResult } from '@/core/packing/PackingStrategy'\nimport { PackingRegistry, defaultRegistry } from '@/core/packing/registry'\n\nexport interface UsePackingStrategyReturn {\n availableStrategies: { id: string; name: string }[]\n pack: (boxes: Box[], pallet: Pallet) => PackingResult\n}\n\nexport function usePackingStrategy(\n strategyId: string,\n registry: PackingRegistry = defaultRegistry,\n): UsePackingStrategyReturn {\n const availableStrategies = useMemo(\n () => registry.list().map(s => ({ id: s.id, name: s.name })),\n [registry],\n )\n\n const pack = useCallback(\n (boxes: Box[], pallet: Pallet): PackingResult => {\n const strategy = registry.get(strategyId)\n return strategy.pack(boxes, pallet)\n },\n [strategyId, registry],\n )\n\n return { availableStrategies, pack }\n}\n","/**\n * useWarehouseValidation — Valida palets dentro de habitaciones\n */\n\nimport { useMemo } from 'react'\nimport type { Room } from '@/core/entities/Room'\nimport type { ValidationResult, Violation } from '@/core/types'\nimport { validatePalletInRoom } from '@/core/validation/polygon'\nimport { validateNoPalletCollisions } from '@/core/validation/collision'\n\nexport interface WarehouseValidationResult {\n isValid: boolean\n violations: Violation[]\n palletInRoom: ValidationResult\n palletCollisions: ValidationResult\n}\n\nexport function useWarehouseValidation(room: Room): WarehouseValidationResult {\n return useMemo(() => {\n // Validar que cada palet esté dentro del polígono de la habitación\n const roomViolations: Violation[] = []\n for (const placedPallet of room.pallets) {\n const result = validatePalletInRoom(placedPallet, room)\n roomViolations.push(...result.violations)\n }\n\n // Validar que no haya colisiones entre palets\n const collisions = validateNoPalletCollisions(room.pallets)\n\n const allViolations: Violation[] = [\n ...roomViolations,\n ...collisions.violations,\n ]\n\n return {\n isValid: allViolations.filter(v => v.severity === 'error').length === 0,\n violations: allViolations,\n palletInRoom: {\n isValid: roomViolations.length === 0,\n violations: roomViolations,\n },\n palletCollisions: collisions,\n }\n }, [room])\n}\n","/**\n * Box — Componente primitivo 3D para una caja\n * Controlado, memo, conversión mm→metros interna\n */\n\nimport { memo, useCallback, useRef, useMemo } from 'react'\nimport { Html } from '@react-three/drei'\nimport * as THREE from 'three'\nimport type { PlacedBox } from '@/core/entities/PlacedBox'\nimport { UNITS } from '@/core/constants'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface BoxProps {\n placedBox: PlacedBox\n selected?: boolean\n highlighted?: boolean\n showLabel?: boolean\n color?: string\n opacity?: number\n selectedColor?: string\n highlightedColor?: string\n onClick?: (id: string) => void\n onHover?: (id: string | null) => void\n}\n\nexport const BoxComponent = memo<BoxProps>(function BoxComponent({\n placedBox,\n selected = false,\n highlighted = false,\n showLabel = false,\n color,\n opacity,\n selectedColor,\n highlightedColor,\n onClick,\n onHover,\n}) {\n const meshRef = useRef<THREE.Mesh>(null)\n const preset = usePreset()\n\n const { box, position, rotation } = placedBox\n const s = UNITS.MM_TO_M\n\n // Resolver estilos: prop > preset\n const resolvedColor = color ?? box.color ?? preset.box.color\n const resolvedOpacity = opacity ?? preset.box.opacity\n const resolvedSelectedColor = selectedColor ?? preset.selection.selectedColor\n const resolvedHighlightedColor = highlightedColor ?? preset.selection.highlightedColor\n\n // Dimensiones (teniendo en cuenta rotación en Y)\n let w = box.dimensions.width\n let d = box.dimensions.depth\n if (rotation.y === 90 || rotation.y === 270) {\n ;[w, d] = [d, w]\n }\n\n const scaledDims = useMemo(\n () => [w * s, box.dimensions.height * s, d * s] as [number, number, number],\n [w, d, box.dimensions.height, s],\n )\n\n // Posición: convertir mm→m, centrar geometría en Y\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n )\n\n const borderColor = selected ? resolvedSelectedColor : highlighted ? resolvedHighlightedColor : null\n\n const handleClick = useCallback(\n (e: { stopPropagation: () => void }) => {\n e.stopPropagation()\n onClick?.(placedBox.id)\n },\n [onClick, placedBox.id],\n )\n\n const handlePointerOver = useCallback(\n (e: { stopPropagation: () => void }) => {\n e.stopPropagation()\n onHover?.(placedBox.id)\n },\n [onHover, placedBox.id],\n )\n\n const handlePointerOut = useCallback(() => {\n onHover?.(null)\n }, [onHover])\n\n return (\n <group>\n <mesh\n ref={meshRef}\n position={pos}\n onClick={handleClick}\n onPointerOver={handlePointerOver}\n onPointerOut={handlePointerOut}\n castShadow\n receiveShadow\n >\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial\n color={resolvedColor}\n transparent={resolvedOpacity < 1}\n opacity={resolvedOpacity}\n roughness={preset.box.roughness}\n metalness={preset.box.metalness}\n />\n </mesh>\n\n {/* Borde de señalización (selección o highlight) — mesh escalado para grosor visible */}\n {borderColor && (\n <mesh position={pos}>\n <boxGeometry args={scaledDims} />\n <meshBasicMaterial\n color={borderColor}\n wireframe\n wireframeLinewidth={1}\n transparent\n opacity={0.9}\n depthTest={false}\n />\n </mesh>\n )}\n {borderColor && (\n <lineSegments position={pos} renderOrder={999}>\n <edgesGeometry args={[new THREE.BoxGeometry(...scaledDims)]} />\n <lineBasicMaterial color={borderColor} />\n </lineSegments>\n )}\n\n {/* Label */}\n {showLabel && (\n <Html\n position={[pos.x, pos.y + scaledDims[1] / 2 + 0.05, pos.z]}\n center\n style={{\n background: 'rgba(0,0,0,0.75)',\n color: 'white',\n padding: '2px 6px',\n borderRadius: '3px',\n fontSize: '11px',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n }}\n >\n {box.sku ?? box.type ?? box.id}\n </Html>\n )}\n </group>\n )\n})\n","/**\n * Pallet — Componente primitivo 3D para la base física de un palet\n */\n\nimport { memo, useMemo } from 'react'\nimport * as THREE from 'three'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface PalletComponentProps {\n pallet: Pallet\n position?: Position3D\n color?: string\n edgeColor?: string\n}\n\nexport const PalletComponent = memo<PalletComponentProps>(function PalletComponent({\n pallet,\n position = { x: 0, y: 0, z: 0 },\n color,\n edgeColor,\n}) {\n const preset = usePreset()\n const resolvedColor = color ?? preset.pallet.color\n const resolvedEdgeColor = edgeColor ?? preset.pallet.edgeColor\n const s = UNITS.MM_TO_M\n const dims = pallet.dimensions\n\n const scaledDims = useMemo(\n () => [dims.width * s, dims.height * s, dims.depth * s] as [number, number, number],\n [dims, s],\n )\n\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n )\n\n return (\n <group>\n {/* Tabla superior */}\n <mesh position={pos} castShadow receiveShadow>\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial color={resolvedColor} roughness={preset.pallet.roughness} metalness={preset.pallet.metalness} />\n </mesh>\n\n {/* Bordes */}\n <lineSegments position={pos}>\n <edgesGeometry args={[new THREE.BoxGeometry(...scaledDims)]} />\n <lineBasicMaterial color={resolvedEdgeColor} />\n </lineSegments>\n </group>\n )\n})\n","/**\n * Separator — Componente primitivo 3D para un separador entre pisos\n */\n\nimport { memo, useMemo } from 'react'\nimport * as THREE from 'three'\nimport type { Separator } from '@/core/entities/Separator'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { SeparatorMaterial } from '@/core/types'\n\nconst MATERIAL_COLORS: Record<SeparatorMaterial, string> = {\n [SeparatorMaterial.CARDBOARD]: '#b5926b',\n [SeparatorMaterial.WOOD]: '#c4a26e',\n [SeparatorMaterial.PLASTIC]: '#90a4ae',\n}\n\nexport interface SeparatorComponentProps {\n separator: Separator\n position?: Position3D\n}\n\nexport const SeparatorComponent = memo<SeparatorComponentProps>(function SeparatorComponent({\n separator,\n position = { x: 0, y: 0, z: 0 },\n}) {\n const s = UNITS.MM_TO_M\n const dims = separator.dimensions\n\n const scaledDims = useMemo(\n () => [dims.width * s, dims.height * s, dims.depth * s] as [number, number, number],\n [dims, s],\n )\n\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n )\n\n const color = MATERIAL_COLORS[separator.material]\n\n return (\n <mesh position={pos} receiveShadow>\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial\n color={color}\n roughness={0.9}\n metalness={0}\n transparent\n opacity={0.85}\n />\n </mesh>\n )\n})\n","/**\n * StackedPallet — Renderiza un palet apilado completo\n * (base + pisos + separadores + cajas)\n */\n\nimport { memo, useMemo } from 'react'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { ensureUniqueBoxIds } from '@/core/entities/StackedPallet'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { PalletComponent } from '../Pallet'\nimport { BoxComponent } from '../Box'\nimport { SeparatorComponent } from '../Separator'\n\nexport interface StackedPalletComponentProps {\n stackedPallet: StackedPallet\n position?: Position3D\n /** Rotación Y en grados (0, 90, 180, 270) */\n yRotation?: 0 | 90 | 180 | 270\n /** ID del palet contenedor. Si se proporciona, se usa como contexto \n * para generar IDs únicos de cajas. La librería garantiza automáticamente\n * que no hay conflictos de IDs entre pisos o palets. */\n palletId?: string\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (por defecto: rojo #ff0000) */\n selectedColor?: string\n /** Color del borde de highlight/hover (por defecto: azul #42a5f5) */\n highlightedColor?: string\n showLabels?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n}\n\nexport const StackedPalletComponent = memo<StackedPalletComponentProps>(\n function StackedPalletComponent({\n stackedPallet,\n position = { x: 0, y: 0, z: 0 },\n yRotation = 0,\n palletId,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n onBoxClick,\n onBoxHover,\n }) {\n // Normalizar automáticamente los IDs de las cajas para garantizar unicidad\n // La librería se encarga de esto internamente, el desarrollador no necesita preocuparse\n const normalizedStack = useMemo(\n () => ensureUniqueBoxIds(stackedPallet, palletId),\n [stackedPallet, palletId],\n )\n\n const s = UNITS.MM_TO_M\n const rotationY = useMemo(() => (yRotation * Math.PI) / 180, [yRotation])\n\n // Calcular las alturas acumuladas de cada piso\n const floorOffsets = useMemo(() => {\n const offsets: number[] = []\n let currentY = 0\n for (const floor of normalizedStack.floors) {\n offsets.push(currentY)\n currentY += floor.pallet.dimensions.height\n // Altura de las cajas: máximo top\n const maxBoxTop = floor.boxes.reduce(\n (max, pb) => Math.max(max, pb.position.y + pb.box.dimensions.height),\n 0,\n )\n currentY += maxBoxTop\n if (floor.separatorAbove) {\n currentY += floor.separatorAbove.dimensions.height\n }\n }\n return offsets\n }, [normalizedStack])\n\n return (\n <group\n position={[position.x * s, position.y * s, position.z * s]}\n rotation={[0, rotationY, 0]}\n >\n {normalizedStack.floors.map((floor, idx) => {\n const floorY = floorOffsets[idx]\n const palletTopY = floorY + floor.pallet.dimensions.height\n\n return (\n <group key={`floor-${idx}`}>\n {/* Palet base de este piso */}\n <PalletComponent\n pallet={floor.pallet}\n position={{ x: 0, y: floorY, z: 0 }}\n />\n\n {/* Cajas en posición relativa al top del palet */}\n {floor.boxes.map(pb => {\n return (\n <BoxComponent\n key={pb.id}\n placedBox={{\n ...pb,\n position: {\n x: pb.position.x,\n y: pb.position.y + palletTopY,\n z: pb.position.z,\n },\n }}\n selected={selectedBoxId === pb.id}\n highlighted={highlightedBoxId === pb.id}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabel={showLabels}\n onClick={onBoxClick}\n onHover={onBoxHover}\n />\n )\n })}\n\n {/* Separador encima (si hay) */}\n {floor.separatorAbove && (\n <SeparatorComponent\n separator={floor.separatorAbove}\n position={{\n x: 0,\n y:\n palletTopY +\n floor.boxes.reduce(\n (max, pb) => Math.max(max, pb.position.y + pb.box.dimensions.height),\n 0,\n ),\n z: 0,\n }}\n />\n )}\n </group>\n )\n })}\n </group>\n )\n },\n)\n","/**\n * Label — Etiqueta flotante con <Html> de drei\n */\n\nimport { memo } from 'react'\nimport { Html } from '@react-three/drei'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\n\nexport interface LabelProps {\n text: string\n position: Position3D\n visible?: boolean\n fontSize?: number\n color?: string\n background?: string\n}\n\nexport const Label = memo<LabelProps>(function Label({\n text,\n position,\n visible = true,\n fontSize = 12,\n color = 'white',\n background = 'rgba(0,0,0,0.75)',\n}) {\n if (!visible) return null\n\n const s = UNITS.MM_TO_M\n\n return (\n <Html\n position={[position.x * s, position.y * s, position.z * s]}\n center\n style={{\n background,\n color,\n padding: '2px 8px',\n borderRadius: '4px',\n fontSize: `${fontSize}px`,\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n {text}\n </Html>\n )\n})\n","/**\n * WarehouseEnvironment — Decorado de escena almacén\n * Suelo, paredes (según polígono de Room), techo, grid, iluminación\n */\n\nimport { memo, useMemo, type ReactNode } from 'react'\nimport * as THREE from 'three'\nimport { UNITS } from '@/core/constants'\nimport type { Room } from '@/core/entities/Room'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface WarehouseEnvironmentProps {\n room: Room\n floorColor?: string\n wallColor?: string\n showGrid?: boolean\n children?: ReactNode\n}\n\nexport const WarehouseEnvironment = memo<WarehouseEnvironmentProps>(\n function WarehouseEnvironment({\n room,\n floorColor,\n wallColor,\n showGrid,\n children,\n }) {\n const preset = usePreset()\n const resolvedFloorColor = floorColor ?? preset.warehouse.floorColor\n const resolvedWallColor = wallColor ?? preset.warehouse.wallColor\n const resolvedShowGrid = showGrid ?? preset.warehouse.showGrid\n const s = UNITS.MM_TO_M\n const ceilingH = room.ceilingHeight * s\n\n // Calcular bounding box del polígono para el suelo y grid\n const { shape, minX, maxX, minZ, maxZ } = useMemo(() => {\n const pts = room.floorPolygon\n let mnX = Infinity, mxX = -Infinity, mnZ = Infinity, mxZ = -Infinity\n for (const p of pts) {\n mnX = Math.min(mnX, p.x * s)\n mxX = Math.max(mxX, p.x * s)\n mnZ = Math.min(mnZ, p.z * s)\n mxZ = Math.max(mxZ, p.z * s)\n }\n\n // Crear shape en 2D (XY). Cuando se rota -90° en X, Y → -Z\n // Por eso usamos -pts[i].z para que quede correctamente orientado\n const sh = new THREE.Shape()\n sh.moveTo(pts[0].x * s, -pts[0].z * s)\n for (let i = 1; i < pts.length; i++) {\n sh.lineTo(pts[i].x * s, -pts[i].z * s)\n }\n sh.closePath()\n\n return { shape: sh, minX: mnX, maxX: mxX, minZ: mnZ, maxZ: mxZ }\n }, [room.floorPolygon, s])\n\n // Geometría de paredes: extruir el polígono del suelo\n const wallGeometry = useMemo(() => {\n const pts = room.floorPolygon\n const positions: number[] = []\n const indices: number[] = []\n\n for (let i = 0; i < pts.length; i++) {\n const curr = pts[i]\n const next = pts[(i + 1) % pts.length]\n\n const baseIdx = i * 4\n // Quad: 4 vértices por segmento de pared\n positions.push(\n curr.x * s, 0, curr.z * s,\n next.x * s, 0, next.z * s,\n next.x * s, ceilingH, next.z * s,\n curr.x * s, ceilingH, curr.z * s,\n )\n indices.push(\n baseIdx, baseIdx + 1, baseIdx + 2,\n baseIdx, baseIdx + 2, baseIdx + 3,\n )\n }\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n geo.setIndex(indices)\n geo.computeVertexNormals()\n return geo\n }, [room.floorPolygon, ceilingH, s])\n\n const sizeX = maxX - minX\n const sizeZ = maxZ - minZ\n const centerX = (minX + maxX) / 2\n const centerZ = (minZ + maxZ) / 2\n\n // Grid rectangular personalizado (gridHelper solo crea grids cuadrados)\n const gridGeometry = useMemo(() => {\n if (!resolvedShowGrid) return null\n \n const spacing = 0.5 // 500mm\n const y = 0.01\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = minX; x <= maxX; x += spacing) {\n positions.push(x, y, minZ, x, y, maxZ)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = minZ; z <= maxZ; z += spacing) {\n positions.push(minX, y, z, maxX, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [resolvedShowGrid, minX, maxX, minZ, maxZ])\n\n return (\n <group>\n {/* Suelo */}\n <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.005, 0]} receiveShadow>\n <shapeGeometry args={[shape]} />\n <meshStandardMaterial \n color={resolvedFloorColor} \n side={THREE.DoubleSide} \n roughness={preset.warehouse.floorRoughness}\n />\n </mesh>\n\n {/* Paredes */}\n <mesh geometry={wallGeometry} position={[0, 0, 0]} receiveShadow>\n <meshStandardMaterial\n color={resolvedWallColor}\n side={THREE.DoubleSide}\n roughness={0.7}\n transparent\n opacity={preset.warehouse.wallOpacity}\n />\n </mesh>\n\n {/* Grid personalizado */}\n {resolvedShowGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color={preset.warehouse.gridColor} \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* Iluminación almacén */}\n <ambientLight intensity={preset.warehouse.ambientIntensity} />\n <directionalLight\n position={[centerX + sizeX, ceilingH * 0.8, centerZ + sizeZ]}\n intensity={preset.warehouse.directionalIntensity}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <pointLight\n position={[centerX, ceilingH * 0.9, centerZ]}\n intensity={0.5}\n distance={Math.max(sizeX, sizeZ) * 2}\n />\n\n {/* Children (palets, etc.) */}\n {children}\n </group>\n )\n },\n)\n","/**\n * TruckEnvironment — Escena de camión con forma realista\n *\n * El centro de la escena es el interior del remolque (zona de carga).\n * La superficie donde se colocan los palets es únicamente el suelo del remolque.\n * Elementos visuales adicionales (cabina, chasis, ruedas) dan forma de camión real.\n */\n\nimport { memo, useMemo, type ReactNode } from 'react'\nimport * as THREE from 'three'\nimport type { Truck } from '@/core/entities/Truck'\nimport { UNITS } from '@/core/constants'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface TruckEnvironmentProps {\n truck: Truck\n /** Mostrar/ocultar grid en el suelo del remolque (por defecto usa preset) */\n showGrid?: boolean\n /** Opacidad de las paredes (0 = invisible, 1 = opaco). Por defecto: 0.3 */\n wallOpacity?: number\n /** Mostrar/ocultar el techo del remolque. Por defecto: false (oculto para ver interior) */\n showRoof?: boolean\n /** Mostrar/ocultar paredes laterales. Por defecto: true */\n showSideWalls?: boolean\n children?: ReactNode\n}\n\n// ─── Componente de rueda ─────────────────────────────────────────\n\ninterface WheelProps {\n position: [number, number, number]\n radius: number\n width: number\n color: string\n}\n\nconst Wheel = memo<WheelProps>(function Wheel({ position, radius, width, color }) {\n return (\n <group position={position}>\n {/* Neumático */}\n <mesh rotation={[0, 0, Math.PI / 2]} castShadow>\n <cylinderGeometry args={[radius, radius, width, 24]} />\n <meshStandardMaterial color={color} roughness={0.9} metalness={0.1} />\n </mesh>\n {/* Rin */}\n <mesh rotation={[0, 0, Math.PI / 2]}>\n <cylinderGeometry args={[radius * 0.55, radius * 0.55, width + 0.005, 16]} />\n <meshStandardMaterial color=\"#888888\" roughness={0.3} metalness={0.7} />\n </mesh>\n </group>\n )\n})\n\n// ─── Componente principal ────────────────────────────────────────\n\nexport const TruckEnvironment = memo<TruckEnvironmentProps>(function TruckEnvironment({\n truck,\n showGrid,\n wallOpacity = 0.3,\n showRoof = false,\n showSideWalls = true,\n children,\n}) {\n const preset = usePreset()\n const truckStyle = preset.truck\n const resolvedShowGrid = showGrid ?? truckStyle.showGrid\n\n const s = UNITS.MM_TO_M\n const tw = truck.dimensions.width * s // ancho remolque\n const th = truck.dimensions.height * s // alto remolque\n const td = truck.dimensions.depth * s // profundidad remolque\n\n // ── Dimensiones derivadas ──\n const wallThickness = 0.05\n const floorThickness = 0.08\n const wheelRadius = 0.28\n const wheelWidth = 0.18\n const groundClearance = 0.15 // distancia del suelo a la parte inferior del chasis\n const chassisH = 0.25 // altura del bastidor\n const wheelY = wheelRadius + groundClearance // ruedas apoyadas con clearance\n const chassisY = wheelY + wheelRadius + 0.1 // chasis sobre las ruedas\n const remolqueFloorY = chassisY + chassisH / 2 + floorThickness / 2 // remolque sobre el chasis\n \n const cabW = tw + wallThickness * 2 // la cabina tiene el mismo ancho exterior\n const cabD = tw * 0.65 // profundidad de la cabina\n const cabH = th * 0.85 // altura de la cabina\n const cabGap = 0.15 // separación entre cabina y remolque\n const cabZ = td + wallThickness + cabGap // posición Z de la cabina\n const cabFloorY = remolqueFloorY // cabina al mismo nivel que el remolque\n\n // Grid rectangular personalizado para el remolque\n const gridGeometry = useMemo(() => {\n if (!resolvedShowGrid) return null\n \n const spacing = 0.5 // 500mm\n const y = remolqueFloorY + 0.002\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = 0; x <= tw; x += spacing) {\n positions.push(x, y, 0, x, y, td)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = 0; z <= td; z += spacing) {\n positions.push(0, y, z, tw, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [resolvedShowGrid, tw, td, remolqueFloorY])\n\n const solidWallMaterial = useMemo(\n () => (\n <meshStandardMaterial\n color={truckStyle.wallColor}\n roughness={0.5}\n metalness={0.3}\n transparent={wallOpacity < 1}\n opacity={wallOpacity}\n side={THREE.DoubleSide}\n depthWrite={wallOpacity >= 0.95}\n />\n ),\n [truckStyle.wallColor, wallOpacity],\n )\n\n return (\n <group>\n {/* ═══════════════════════════════════════════════════════\n * REMOLQUE (zona de carga) − centrado en el origen\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Suelo del remolque */}\n <mesh\n position={[tw / 2, remolqueFloorY, td / 2]}\n rotation={[-Math.PI / 2, 0, 0]}\n receiveShadow\n >\n <planeGeometry args={[tw, td]} />\n <meshStandardMaterial color={truckStyle.floorColor} roughness={0.85} />\n </mesh>\n\n {/* Grosor del suelo (cuerpo visible) */}\n <mesh position={[tw / 2, remolqueFloorY - floorThickness / 2, td / 2]} castShadow receiveShadow>\n <boxGeometry args={[tw + wallThickness * 2, floorThickness, td + wallThickness]} />\n <meshStandardMaterial color={truckStyle.floorColor} roughness={0.85} metalness={0.1} />\n </mesh>\n\n {/* Pared izquierda */}\n {showSideWalls && (\n <mesh position={[-wallThickness / 2, remolqueFloorY + th / 2, td / 2]} castShadow>\n <boxGeometry args={[wallThickness, th, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Pared derecha */}\n {showSideWalls && (\n <mesh position={[tw + wallThickness / 2, remolqueFloorY + th / 2, td / 2]} castShadow>\n <boxGeometry args={[wallThickness, th, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Pared trasera (fondo del remolque — lado cabina) */}\n <mesh position={[tw / 2, remolqueFloorY + th / 2, td + wallThickness / 2]} castShadow>\n <boxGeometry args={[tw + wallThickness * 2, th, wallThickness]} />\n {solidWallMaterial}\n </mesh>\n\n {/* Techo del remolque */}\n {showRoof && (\n <mesh position={[tw / 2, remolqueFloorY + th, td / 2]} castShadow>\n <boxGeometry args={[tw + wallThickness * 2, wallThickness, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Grid del suelo del remolque */}\n {resolvedShowGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color={truckStyle.gridColor} \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* ═══════════════════════════════════════════════════════\n * CHASIS / BASTIDOR\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Largueros del chasis (dos vigas longitudinales) */}\n <mesh position={[tw * 0.25, chassisY, (td + cabD + cabGap) / 2]} castShadow>\n <boxGeometry args={[0.12, chassisH, td + cabD + cabGap]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n <mesh position={[tw * 0.75, chassisY, (td + cabD + cabGap) / 2]} castShadow>\n <boxGeometry args={[0.12, chassisH, td + cabD + cabGap]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n\n {/* Travesaños */}\n {[0.15, 0.35, 0.55, 0.75, 0.95].map((frac) => (\n <mesh key={frac} position={[tw / 2, chassisY, td * frac]} castShadow>\n <boxGeometry args={[tw * 0.6, 0.06, 0.06]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n ))}\n\n {/* ═══════════════════════════════════════════════════════\n * RUEDAS\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Ejes traseros del remolque (doble eje) */}\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, td * 0.12]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, td * 0.12]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, td * 0.22]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, td * 0.22]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n\n {/* Ruedas del eje de la cabina */}\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, cabZ + cabD * 0.5]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, cabZ + cabD * 0.5]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n\n {/* ═══════════════════════════════════════════════════════\n * CABINA\n * ═══════════════════════════════════════════════════════ */}\n <group position={[tw / 2, cabFloorY, cabZ]}>\n {/* Cuerpo principal de la cabina */}\n <mesh position={[0, cabH / 2, cabD / 2]} castShadow receiveShadow>\n <boxGeometry args={[cabW, cabH, cabD]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Parabrisas (frontal) */}\n <mesh\n position={[0, cabH * 0.6, cabD + 0.01]}\n castShadow\n >\n <planeGeometry args={[cabW * 0.75, cabH * 0.4]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.5}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Ventanilla izquierda */}\n <mesh position={[-cabW / 2 - 0.01, cabH * 0.6, cabD * 0.55]} rotation={[0, Math.PI / 2, 0]}>\n <planeGeometry args={[cabD * 0.5, cabH * 0.3]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.4}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Ventanilla derecha */}\n <mesh position={[cabW / 2 + 0.01, cabH * 0.6, cabD * 0.55]} rotation={[0, -Math.PI / 2, 0]}>\n <planeGeometry args={[cabD * 0.5, cabH * 0.3]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.4}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Techo de la cabina (ligeramente redondeado con box) */}\n <mesh position={[0, cabH + 0.04, cabD / 2]}>\n <boxGeometry args={[cabW * 0.95, 0.08, cabD * 0.9]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Deflector de aire encima de la cabina */}\n <mesh position={[0, cabH + 0.25, cabD * 0.1]} rotation={[-0.3, 0, 0]}>\n <boxGeometry args={[cabW * 0.9, 0.04, cabD * 0.5]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Faros delanteros */}\n <mesh position={[-cabW * 0.35, cabH * 0.2, cabD + 0.02]}>\n <boxGeometry args={[cabW * 0.15, 0.08, 0.02]} />\n <meshStandardMaterial color=\"#ffffcc\" emissive=\"#ffffaa\" emissiveIntensity={0.3} />\n </mesh>\n <mesh position={[cabW * 0.35, cabH * 0.2, cabD + 0.02]}>\n <boxGeometry args={[cabW * 0.15, 0.08, 0.02]} />\n <meshStandardMaterial color=\"#ffffcc\" emissive=\"#ffffaa\" emissiveIntensity={0.3} />\n </mesh>\n\n {/* Parachoques delantero */}\n <mesh position={[0, 0.06, cabD + 0.04]} castShadow>\n <boxGeometry args={[cabW * 1.02, 0.12, 0.06]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.5} metalness={0.6} />\n </mesh>\n </group>\n\n {/* ═══════════════════════════════════════════════════════\n * GUARDABARROS\n * ═══════════════════════════════════════════════════════ */}\n {/* Guardabarros traseros */}\n {[-1, 1].map(side => (\n <mesh\n key={`fender-rear-${side}`}\n position={[\n side === -1 ? -wallThickness - wheelWidth * 0.5 : tw + wallThickness + wheelWidth * 0.5,\n wheelY + wheelRadius * 0.6,\n td * 0.17,\n ]}\n castShadow\n >\n <boxGeometry args={[wheelWidth + 0.04, 0.04, wheelRadius * 2.5]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.6} metalness={0.4} />\n </mesh>\n ))}\n\n {/* ═══════════════════════════════════════════════════════\n * LUCES TRASERAS (puerta del remolque)\n * ═══════════════════════════════════════════════════════ */}\n <mesh position={[-wallThickness / 2 + 0.01, remolqueFloorY + th * 0.3, -0.01]}>\n <boxGeometry args={[0.08, 0.12, 0.02]} />\n <meshStandardMaterial color=\"#ff3333\" emissive=\"#ff0000\" emissiveIntensity={0.3} />\n </mesh>\n <mesh position={[tw + wallThickness / 2 - 0.01, remolqueFloorY + th * 0.3, -0.01]}>\n <boxGeometry args={[0.08, 0.12, 0.02]} />\n <meshStandardMaterial color=\"#ff3333\" emissive=\"#ff0000\" emissiveIntensity={0.3} />\n </mesh>\n\n {/* ═══════════════════════════════════════════════════════\n * ILUMINACIÓN\n * ═══════════════════════════════════════════════════════ */}\n <ambientLight intensity={0.45} />\n <directionalLight\n position={[tw / 2, remolqueFloorY + th * 1.5, td * 0.8]}\n intensity={0.75}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <pointLight position={[tw / 2, remolqueFloorY + th * 0.7, td / 2]} intensity={0.35} />\n {/* Luz interior (dentro del remolque) */}\n <pointLight position={[tw / 2, remolqueFloorY + th * 0.9, td * 0.3]} intensity={0.25} />\n\n {/* ═══════════════════════════════════════════════════════\n * CONTENIDO (palets) - elevados al nivel del suelo del remolque\n * ═══════════════════════════════════════════════════════ */}\n <group position={[0, remolqueFloorY, 0]}>\n {children}\n </group>\n </group>\n )\n})\n","/**\n * CameraControls — Wrapper de OrbitControls con presets de posición\n */\n\nimport { memo, useEffect, useRef } from 'react'\nimport { OrbitControls } from '@react-three/drei'\nimport { useThree } from '@react-three/fiber'\nimport * as THREE from 'three'\n\nexport type CameraPreset = 'perspective' | 'top' | 'front' | 'side' | 'isometric'\n\nexport interface CameraControlsProps {\n preset?: CameraPreset\n autoRotate?: boolean\n enablePan?: boolean\n enableZoom?: boolean\n target?: [number, number, number]\n minDistance?: number\n maxDistance?: number\n /** Tamaño de la escena para calcular posiciones relativas */\n sceneSize?: { width: number; height: number; depth: number }\n}\n\n/**\n * Calcula posiciones de cámara relativas al tamaño de la escena.\n * Usa un factor multiplicador basado en la diagonal del bounding box.\n */\nfunction calculatePresetPosition(\n preset: CameraPreset,\n target: [number, number, number],\n sceneSize?: { width: number; height: number; depth: number },\n): [number, number, number] {\n // Si no hay tamaño de escena, usar valores por defecto\n if (!sceneSize) {\n const defaults: Record<CameraPreset, [number, number, number]> = {\n perspective: [3, 3, 3],\n isometric: [4, 4, 4],\n top: [0, 5, 0],\n front: [0, 1.5, 5],\n side: [5, 1.5, 0],\n }\n return defaults[preset]\n }\n\n const { width, height, depth } = sceneSize\n const [tx, ty, tz] = target\n \n // Calcular la diagonal del bounding box para determinar la distancia óptima\n const diagonal = Math.sqrt(width ** 2 + height ** 2 + depth ** 2)\n const distance = diagonal * 3.0 // Factor de distancia para ver toda la escena\n \n switch (preset) {\n case 'perspective':\n // Vista perspectiva ajustada: 45° en horizontal, 30° en vertical\n return [\n tx + distance * 0.6,\n ty + distance * 0.5,\n tz + distance * 0.6,\n ]\n \n case 'isometric':\n // Vista isométrica pura: igual distancia en X, Y, Z\n return [\n tx + distance * 0.577,\n ty + distance * 0.577,\n tz + distance * 0.577,\n ]\n \n case 'top':\n // Vista superior: solo altura\n return [tx, ty + Math.max(distance, height * 2), tz]\n \n case 'front':\n // Vista frontal: desde el frente\n return [tx, ty + height * 0.5, tz + Math.max(distance, depth * 1.5)]\n \n case 'side':\n // Vista lateral: desde el lado\n return [tx + Math.max(distance, width * 1.5), ty + height * 0.5, tz]\n }\n}\n\nexport const CameraControlsComponent = memo<CameraControlsProps>(function CameraControlsComponent({\n preset = 'perspective',\n autoRotate = false,\n enablePan = true,\n enableZoom = true,\n target = [0, 0, 0],\n minDistance = 0.5,\n maxDistance = 50,\n sceneSize,\n}) {\n const { camera } = useThree()\n const controlsRef = useRef<any>(null)\n\n // Actualizar la posición de la cámara con animación suave cuando cambia el preset\n useEffect(() => {\n const pos = calculatePresetPosition(preset, target, sceneSize)\n const targetPos = new THREE.Vector3(pos[0], pos[1], pos[2])\n const targetLookAt = new THREE.Vector3(...target)\n \n // Animación suave de transición (usando un simple lerp)\n const startPos = camera.position.clone()\n const duration = 1000 // ms\n const startTime = Date.now()\n \n const animate = () => {\n const elapsed = Date.now() - startTime\n const progress = Math.min(elapsed / duration, 1)\n \n // Ease-out cubic para una animación más natural\n const eased = 1 - Math.pow(1 - progress, 3)\n \n camera.position.lerpVectors(startPos, targetPos, eased)\n \n if (controlsRef.current) {\n controlsRef.current.target.lerp(targetLookAt, eased)\n controlsRef.current.update()\n }\n \n if (progress < 1) {\n requestAnimationFrame(animate)\n }\n }\n \n animate()\n }, [preset, sceneSize, camera, target])\n\n return (\n <OrbitControls\n ref={controlsRef}\n target={target}\n autoRotate={autoRotate}\n autoRotateSpeed={0.5}\n enablePan={enablePan}\n enableZoom={enableZoom}\n enableRotate\n minDistance={minDistance}\n maxDistance={maxDistance}\n enableDamping\n dampingFactor={0.05}\n rotateSpeed={0.5}\n zoomSpeed={0.8}\n panSpeed={0.5}\n makeDefault\n />\n )\n})\n","/**\n * ViewControls — Botones flotantes para cambio rápido de vista de cámara\n */\n\nimport { memo } from 'react'\nimport type { CameraPreset } from '../CameraControls'\nimport './ViewControls.css'\n\nexport interface ViewControlsProps {\n currentPreset: CameraPreset\n onPresetChange: (preset: CameraPreset) => void\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\n}\n\nconst PRESET_LABELS: Record<CameraPreset, { label: string; icon: string }> = {\n perspective: { label: 'Perspectiva', icon: '📐' },\n isometric: { label: 'Isométrica', icon: '🔲' },\n top: { label: 'Superior', icon: '⬇️' },\n front: { label: 'Frontal', icon: '➡️' },\n side: { label: 'Lateral', icon: '⬅️' },\n}\n\nexport const ViewControls = memo<ViewControlsProps>(function ViewControls({\n currentPreset,\n onPresetChange,\n position = 'top-right',\n}) {\n const presets: CameraPreset[] = ['perspective', 'isometric', 'top', 'front', 'side']\n\n return (\n <div className={`view-controls view-controls--${position}`}>\n <div className=\"view-controls__title\">Vista</div>\n <div className=\"view-controls__buttons\">\n {presets.map((preset) => {\n const { label, icon } = PRESET_LABELS[preset]\n const isActive = currentPreset === preset\n\n return (\n <button\n key={preset}\n className={`view-controls__button ${isActive ? 'view-controls__button--active' : ''}`}\n onClick={() => onPresetChange(preset)}\n title={label}\n aria-label={label}\n >\n <span className=\"view-controls__icon\" role=\"img\" aria-hidden=\"true\">\n {icon}\n </span>\n <span className=\"view-controls__label\">{label}</span>\n </button>\n )\n })}\n </div>\n </div>\n )\n})\n","/**\n * MiniMap — Mini-mapa 2D con vista superior para orientación espacial\n */\n\nimport { memo, useMemo } from 'react'\nimport './MiniMap.css'\n\nexport interface MiniMapProps {\n /** Ancho de la escena en metros */\n sceneWidth: number\n /** Profundidad de la escena en metros */\n sceneDepth: number\n /** Tipo de escena: 'truck' | 'warehouse' */\n sceneType: 'truck' | 'warehouse'\n /** Polígono del suelo (solo para warehouse) */\n floorPolygon?: Array<{ x: number; z: number }>\n /** Posición de la cámara actual en la escena */\n cameraPosition?: { x: number; z: number }\n /** Posición del objetivo/target de la cámara */\n targetPosition?: { x: number; z: number }\n /** Posición: 'bottom-left' | 'bottom-right' */\n position?: 'bottom-left' | 'bottom-right'\n}\n\nexport const MiniMap = memo<MiniMapProps>(function MiniMap({\n sceneWidth,\n sceneDepth,\n sceneType,\n floorPolygon,\n cameraPosition,\n targetPosition,\n position = 'bottom-left',\n}) {\n const mapSize = 150 // tamaño del minimap en px\n const padding = 10\n\n // Calcular escala para que el contenido quepa en el minimap\n const scale = useMemo(() => {\n const maxDimension = Math.max(sceneWidth, sceneDepth)\n return (mapSize - padding * 2) / maxDimension\n }, [sceneWidth, sceneDepth])\n\n // Convertir coordenadas de mundo a coordenadas del minimap\n const worldToMap = (x: number, z: number): { x: number; y: number } => {\n return {\n x: padding + x * scale,\n y: padding + z * scale,\n }\n }\n\n // Path del polígono para warehouse\n const polygonPath = useMemo(() => {\n if (sceneType !== 'warehouse' || !floorPolygon || floorPolygon.length === 0) {\n return ''\n }\n\n const points = floorPolygon.map((p) => {\n const mapped = worldToMap(p.x, p.z)\n return `${mapped.x},${mapped.y}`\n })\n\n return `M ${points.join(' L ')} Z`\n }, [sceneType, floorPolygon, scale])\n\n // Rectángulo para truck\n const truckRect = useMemo(() => {\n if (sceneType !== 'truck') return null\n const topLeft = worldToMap(0, 0)\n return {\n x: topLeft.x,\n y: topLeft.y,\n width: sceneWidth * scale,\n height: sceneDepth * scale,\n }\n }, [sceneType, sceneWidth, sceneDepth, scale])\n\n // Posiciones de cámara y target en minimap\n const cameraMapPos = cameraPosition ? worldToMap(cameraPosition.x, cameraPosition.z) : null\n const targetMapPos = targetPosition ? worldToMap(targetPosition.x, targetPosition.z) : null\n\n return (\n <div className={`minimap minimap--${position}`}>\n <div className=\"minimap__title\">Mapa</div>\n <svg\n className=\"minimap__canvas\"\n width={mapSize}\n height={mapSize}\n viewBox={`0 0 ${mapSize} ${mapSize}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Fondo */}\n <rect width={mapSize} height={mapSize} fill=\"#1a1a2e\" />\n\n {/* Escena: Warehouse (polígono) o Truck (rectángulo) */}\n {sceneType === 'warehouse' && polygonPath && (\n <path d={polygonPath} fill=\"rgba(96, 165, 250, 0.15)\" stroke=\"#60a5fa\" strokeWidth=\"2\" />\n )}\n\n {sceneType === 'truck' && truckRect && (\n <rect\n x={truckRect.x}\n y={truckRect.y}\n width={truckRect.width}\n height={truckRect.height}\n fill=\"rgba(96, 165, 250, 0.15)\"\n stroke=\"#60a5fa\"\n strokeWidth=\"2\"\n />\n )}\n\n {/* Grid */}\n <defs>\n <pattern\n id=\"minimap-grid\"\n width={scale}\n height={scale}\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n d={`M ${scale} 0 L 0 0 0 ${scale}`}\n fill=\"none\"\n stroke=\"rgba(255, 255, 255, 0.08)\"\n strokeWidth=\"0.5\"\n />\n </pattern>\n </defs>\n {sceneType === 'truck' && truckRect && (\n <rect\n x={truckRect.x}\n y={truckRect.y}\n width={truckRect.width}\n height={truckRect.height}\n fill=\"url(#minimap-grid)\"\n />\n )}\n\n {/* Target (punto de enfoque) */}\n {targetMapPos && (\n <g>\n <circle cx={targetMapPos.x} cy={targetMapPos.y} r=\"3\" fill=\"#f87171\" opacity=\"0.6\" />\n <circle cx={targetMapPos.x} cy={targetMapPos.y} r=\"5\" fill=\"none\" stroke=\"#f87171\" strokeWidth=\"1.5\" />\n </g>\n )}\n\n {/* Cámara */}\n {cameraMapPos && (\n <g>\n <circle cx={cameraMapPos.x} cy={cameraMapPos.y} r=\"4\" fill=\"#60a5fa\" />\n {/* Línea desde cámara a target */}\n {targetMapPos && (\n <line\n x1={cameraMapPos.x}\n y1={cameraMapPos.y}\n x2={targetMapPos.x}\n y2={targetMapPos.y}\n stroke=\"#60a5fa\"\n strokeWidth=\"1\"\n strokeDasharray=\"2,2\"\n opacity=\"0.6\"\n />\n )}\n </g>\n )}\n </svg>\n\n {/* Leyenda */}\n <div className=\"minimap__legend\">\n <div className=\"minimap__legend-item\">\n <span className=\"minimap__legend-dot minimap__legend-dot--camera\"></span>\n <span className=\"minimap__legend-text\">Cámara</span>\n </div>\n <div className=\"minimap__legend-item\">\n <span className=\"minimap__legend-dot minimap__legend-dot--target\"></span>\n <span className=\"minimap__legend-text\">Objetivo</span>\n </div>\n </div>\n </div>\n )\n})\n","/**\n * useCameraPosition — Hook para rastrear la posición de la cámara en tiempo real\n */\n\nimport { useEffect, useState } from 'react'\nimport { useThree } from '@react-three/fiber'\n\nexport interface CameraPosition {\n x: number\n y: number\n z: number\n}\n\nexport function useCameraPosition(): CameraPosition {\n const { camera } = useThree()\n const [position, setPosition] = useState<CameraPosition>({\n x: camera.position.x,\n y: camera.position.y,\n z: camera.position.z,\n })\n\n useEffect(() => {\n let frameId: number\n\n const updatePosition = () => {\n setPosition({\n x: camera.position.x,\n y: camera.position.y,\n z: camera.position.z,\n })\n frameId = requestAnimationFrame(updatePosition)\n }\n\n frameId = requestAnimationFrame(updatePosition)\n\n return () => {\n if (frameId) {\n cancelAnimationFrame(frameId)\n }\n }\n }, [camera])\n\n return position\n}\n","/**\n * CameraTracker — Componente interno para rastrear la posición de cámara\n * y pasarla a componentes externos\n */\n\nimport { useEffect } from 'react'\nimport { useCameraPosition } from '@/hooks/useCameraPosition'\n\nexport interface CameraTrackerProps {\n onPositionChange: (position: { x: number; y: number; z: number }) => void\n}\n\nexport function CameraTracker({ onPositionChange }: CameraTrackerProps) {\n const position = useCameraPosition()\n\n useEffect(() => {\n onPositionChange(position)\n }, [position, onPositionChange])\n\n return null\n}\n","/**\n * PalletScene — Escena completa para un palet individual\n * Canvas + iluminación + CameraControls + StackedPallet\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport * as THREE from 'three'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { getStackedPalletTotalHeight } from '@/core/entities/StackedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface PalletSceneProps {\n stackedPallet: StackedPallet\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n cameraPreset?: CameraPreset\n showGrid?: boolean\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const PalletScene = memo<PalletSceneProps>(function PalletScene({\n stackedPallet,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n cameraPreset = 'perspective',\n showGrid = true,\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const s = UNITS.MM_TO_M\n const basePallet = stackedPallet.floors[0]?.pallet\n \n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n \n // Dimensiones del palet para cálculo de cámara adaptativa\n const sceneSize = useMemo(() => {\n if (!basePallet) return { width: 1.2, height: 1, depth: 0.8 }\n return {\n width: basePallet.dimensions.width * s,\n height: getStackedPalletTotalHeight(stackedPallet) * s,\n depth: basePallet.dimensions.depth * s,\n }\n }, [basePallet, stackedPallet, s])\n \n // Memorizar el target para evitar recreaciones\n const target = useMemo<[number, number, number]>(() => {\n const centerX = basePallet ? (basePallet.dimensions.width * s) / 2 : 0\n const centerZ = basePallet ? (basePallet.dimensions.depth * s) / 2 : 0\n const centerY = sceneSize.height / 2\n return [centerX, centerY, centerZ]\n }, [basePallet, s, sceneSize.height])\n \n // Posición inicial de cámara optimizada\n const initialCameraPosition = useMemo<[number, number, number]>(() => {\n const diagonal = Math.sqrt(\n sceneSize.width ** 2 + sceneSize.height ** 2 + sceneSize.depth ** 2\n )\n const distance = diagonal * 3.5\n return [\n target[0] + distance * 0.7,\n target[1] + distance * 0.6,\n target[2] + distance * 0.7,\n ]\n }, [target, sceneSize])\n\n // Grid rectangular personalizado del tamaño del pallet\n const gridGeometry = useMemo(() => {\n if (!showGrid || !basePallet) return null\n \n const pw = basePallet.dimensions.width * s\n const pd = basePallet.dimensions.depth * s\n const spacing = 0.2 // 200mm entre líneas (más fino para palets individuales)\n const y = 0.001\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = 0; x <= pw; x += spacing) {\n positions.push(x, y, 0, x, y, pd)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = 0; z <= pd; z += spacing) {\n positions.push(0, y, z, pw, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [showGrid, basePallet, s])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 100 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n {/* Iluminación */}\n <ambientLight intensity={0.4} />\n <directionalLight\n position={[5, 8, 5]}\n intensity={0.8}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <hemisphereLight intensity={0.3} color=\"#ffffff\" groundColor=\"#444444\" />\n\n {/* Controls */}\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n minDistance={0.3}\n maxDistance={Math.max(sceneSize.width, sceneSize.height, sceneSize.depth) * 4}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n {/* Suelo - ligeramente más grande que el pallet */}\n <mesh rotation={[-Math.PI / 2, 0, 0]} position={[target[0], -0.002, target[2]]} receiveShadow>\n <planeGeometry args={[\n basePallet ? basePallet.dimensions.width * s * 1.5 : 3,\n basePallet ? basePallet.dimensions.depth * s * 1.5 : 3\n ]} />\n <meshStandardMaterial color=\"#e0e0e0\" roughness={0.9} />\n </mesh>\n\n {/* Grid personalizado */}\n {showGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color=\"#aaaaaa\" \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* Palet */}\n <StackedPalletComponent\n stackedPallet={stackedPallet}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n\n {/* Custom children */}\n {children}\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && basePallet && (\n <MiniMap\n sceneWidth={sceneSize.width}\n sceneDepth={sceneSize.depth}\n sceneType=\"truck\"\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n","/**\n * TruckScene — Escena completa de un camión con palets cargados\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport type { Truck } from '@/core/entities/Truck'\nimport type { PlacedPallet } from '@/core/entities/PlacedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { TruckEnvironment } from '@/components/environments/TruckEnvironment'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { validatePalletInTruck } from '@/core/validation/bounds'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface TruckSceneProps {\n truck: Truck\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n /** Mostrar/ocultar el grid del suelo del remolque */\n showGrid?: boolean\n /** Opacidad de las paredes (0-1). Por defecto: 0.3 */\n wallOpacity?: number\n /** Mostrar/ocultar el techo. Por defecto: false */\n showRoof?: boolean\n /** Mostrar/ocultar paredes laterales. Por defecto: true */\n showSideWalls?: boolean\n cameraPreset?: CameraPreset\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const TruckScene = memo<TruckSceneProps>(function TruckScene({\n truck,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n showGrid,\n wallOpacity = 0.3,\n showRoof = false,\n showSideWalls = true,\n cameraPreset = 'perspective',\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n const s = UNITS.MM_TO_M\n const w = truck.dimensions.width * s\n const h = truck.dimensions.height * s\n const d = truck.dimensions.depth * s\n \n // Memorizar el target (centro de la zona de carga)\n const target = useMemo<[number, number, number]>(\n () => [w / 2, h / 2, d / 2],\n [w, h, d],\n )\n \n // Tamaño de la escena para cálculo de cámara adaptativa\n const sceneSize = useMemo(\n () => ({ width: w, height: h, depth: d }),\n [w, h, d],\n )\n \n // Calcular posición inicial de cámara basada en el tamaño del camión\n const initialCameraPosition = useMemo<[number, number, number]>(() => {\n // Vista elevada ligeramente hacia el interior para mejor visualización\n return [w * 0.8, h * 1.2, d * 0.4]\n }, [w, h, d])\n\n // Filtrar palets válidos - no renderizar los que estén fuera del camión\n const validPallets = useMemo<PlacedPallet[]>(() => {\n return truck.pallets.filter(pp => {\n const validation = validatePalletInTruck(pp, truck)\n if (!validation.isValid) {\n console.error(\n `[TruckScene] Palet \"${pp.id}\" fuera de los límites del camión.`,\n 'Violaciones:',\n validation.violations,\n )\n return false\n }\n return true\n })\n }, [truck])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 200 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n maxDistance={Math.max(w, h, d) * 3}\n minDistance={0.5}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n <TruckEnvironment \n truck={truck} \n showGrid={showGrid}\n wallOpacity={wallOpacity}\n showRoof={showRoof}\n showSideWalls={showSideWalls}\n >\n {validPallets.map(pp => (\n <StackedPalletComponent\n key={pp.id}\n stackedPallet={pp.stackedPallet}\n position={pp.position}\n yRotation={pp.yRotation}\n palletId={pp.id}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n ))}\n {children}\n </TruckEnvironment>\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && (\n <MiniMap\n sceneWidth={w}\n sceneDepth={d}\n sceneType=\"truck\"\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n","/**\n * WarehouseScene — Escena completa de un almacén con estancias y palets\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport type { Room } from '@/core/entities/Room'\nimport type { PlacedPallet } from '@/core/entities/PlacedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { WarehouseEnvironment } from '@/components/environments/WarehouseEnvironment'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { validatePalletInRoom } from '@/core/validation/polygon'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface WarehouseSceneProps {\n room: Room\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n cameraPreset?: CameraPreset\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const WarehouseScene = memo<WarehouseSceneProps>(function WarehouseScene({\n room,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n cameraPreset = 'perspective',\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const s = UNITS.MM_TO_M\n \n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n \n // Calcular bounding box del almacén\n const { target, sceneSize, initialCameraPosition } = useMemo(() => {\n const pts = room.floorPolygon\n let minX = Infinity, maxX = -Infinity\n let minZ = Infinity, maxZ = -Infinity\n \n for (const p of pts) {\n minX = Math.min(minX, p.x * s)\n maxX = Math.max(maxX, p.x * s)\n minZ = Math.min(minZ, p.z * s)\n maxZ = Math.max(maxZ, p.z * s)\n }\n \n const width = maxX - minX\n const depth = maxZ - minZ\n const height = room.ceilingHeight * s\n const cx = (minX + maxX) / 2\n const cz = (minZ + maxZ) / 2\n \n // Target en el centro del almacén, a media altura\n const targetPos: [number, number, number] = [cx, height / 2, cz]\n \n // Tamaño de la escena\n const size = { width, height, depth }\n \n // Posición inicial de cámara (vista isométrica)\n const diagonal = Math.sqrt(width ** 2 + height ** 2 + depth ** 2)\n const distance = diagonal * 0.8\n const initialPos: [number, number, number] = [\n cx + distance * 0.6,\n height + distance * 0.5,\n cz + distance * 0.6,\n ]\n \n return {\n target: targetPos,\n sceneSize: size,\n initialCameraPosition: initialPos,\n }\n }, [room.floorPolygon, room.ceilingHeight, s])\n\n // Convertir polígono para MiniMap (metros a escala del mundo)\n const floorPolygonForMap = useMemo(() => {\n return room.floorPolygon.map(p => ({ x: p.x * s, z: p.z * s }))\n }, [room.floorPolygon, s])\n\n // Filtrar palets válidos - no renderizar los que estén fuera de la estancia\n const validPallets = useMemo<PlacedPallet[]>(() => {\n return room.pallets.filter(pp => {\n const validation = validatePalletInRoom(pp, room)\n if (!validation.isValid) {\n console.error(\n `[WarehouseScene] Palet \"${pp.id}\" fuera de los límites de la estancia \"${room.name}\".`,\n 'Violaciones:',\n validation.violations,\n )\n return false\n }\n return true\n })\n }, [room])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 300 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n maxDistance={Math.max(sceneSize.width, sceneSize.height, sceneSize.depth) * 4}\n minDistance={0.5}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n <WarehouseEnvironment room={room}>\n {validPallets.map(pp => (\n <StackedPalletComponent\n key={pp.id}\n stackedPallet={pp.stackedPallet}\n position={pp.position}\n yRotation={pp.yRotation}\n palletId={pp.id}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n ))}\n {children}\n </WarehouseEnvironment>\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && (\n <MiniMap\n sceneWidth={sceneSize.width}\n sceneDepth={sceneSize.depth}\n sceneType=\"warehouse\"\n floorPolygon={floorPolygonForMap}\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n"],"names":["PalletMaterial","SeparatorMaterial","TruckType","STANDARD_PALLETS","TRUCK_PRESETS","SEPARATOR_DEFAULTS","UNITS","COLLISION_TOLERANCE","MIN_SUPPORT_PERCENTAGE","WEIGHT_WARNING_THRESHOLD","PRESET_UNSTYLED","PRESET_INDUSTRIAL","SCENE_PRESETS","DEFAULT_PRESET","REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","PresetContext","createContext","PresetProvider","preset","resolved","useMemo","usePreset","useContext","getStackedPalletTotalHeight","stack","height","floor","maxBoxTop","max","pb","boxTop","getStackedPalletTotalWeight","weight","sum","ensureUniqueBoxIds","contextId","baseId","normalizedFloors","floorIdx","normalizedBoxes","boxIdx","uniqueId","updateRefs","refs","refId","refBoxIdx","b","getBoxBoundingBox","w","d","h","getPalletBoundingBox","pp","basePallet","totalH","rotRad","cos","sin","worldCorners","corner","minX","c","maxX","minZ","maxZ","aabbIntersects","a","tolerance","validateNoBoxCollisions","boxes","violations","i","j","bbA","bbB","validateNoPalletCollisions","pallets","validateBoxInPalletBounds","box","pallet","bb","validateAllBoxesInPalletBounds","result","validatePalletInTruck","truck","td","validatePalletHeight","ceilingHeight","validatePalletWeight","totalBoxWeight","maxWeight","v","validateTruckWeight","totalWeight","validateFragileLoad","maxAbove","weightAbove","calculateWeightAboveBox","target","allBoxes","tbb","other","obb","validateWeightDistribution","s","cogX","cogZ","cx","cz","centerX","centerZ","validateBoxStackability","validateInvertedPyramid","bottom","bbb","bottomArea","top","topArea","validateStackDimensions","base","p","validateSeparators","validateStackHeight","containerHeight","validateStackWeight","baseMaxWeight","loadWeight","validateSupport","boxArea","supportedArea","overlapX","overlapZ","calculateCenterOfGravity","cogY","cy","calculateStabilityScore","cog","dx","dz","horizontalScore","maxBoxY","heightRatio","verticalScore","validateCogInsideSupport","validateStability","score","maxY","pointInPolygon","point","polygon","inside","n","xi","zi","xj","zj","validatePalletInRoom","room","corners","ColumnStrategy","placements","unplacedBoxes","groups","cursorX","placementId","groupBoxes","refBox","colWidth","colDepth","boxHeight","cursorZ","cursorY","palletVolume","usedVolume","stability","BinPacking3DStrategy","sorted","va","spaces","placed","orientations","si","space","ori","newPlacement","newBB","existing","TypeGroupStrategy","typeA","typeB","layerMaxHeight","PackingRegistry","strategy","id","defaultRegistry","_palletCounter","nextPalletId","PalletFactory","overrides","presetKey","dims","opts","_truckCounter","nextTruckId","TruckFactory","_boxCounter","nextBoxId","BoxFactory","fragilityMaxWeight","usePhysicsValidation","collisions","bounds","gravity","stackability","invertedPyramid","cogValid","fragile","distribution","stackingViolations","stabilityViolations","allViolations","usePalletMetrics","totalHeight","f","boxCount","floorCount","totalVolume","usePackingStrategy","strategyId","registry","availableStrategies","pack","useCallback","useWarehouseValidation","roomViolations","placedPallet","BoxComponent","memo","placedBox","selected","highlighted","showLabel","color","opacity","selectedColor","highlightedColor","onClick","onHover","meshRef","useRef","position","rotation","resolvedColor","resolvedOpacity","resolvedSelectedColor","resolvedHighlightedColor","scaledDims","pos","THREE","borderColor","handleClick","e","handlePointerOver","handlePointerOut","jsxs","jsx","Html","PalletComponent","edgeColor","resolvedEdgeColor","MATERIAL_COLORS","SeparatorComponent","separator","StackedPalletComponent","stackedPallet","yRotation","palletId","selectedBoxId","highlightedBoxId","showLabels","onBoxClick","onBoxHover","normalizedStack","rotationY","floorOffsets","offsets","currentY","idx","floorY","palletTopY","Label","text","visible","fontSize","background","WarehouseEnvironment","floorColor","wallColor","showGrid","resolvedFloorColor","resolvedWallColor","resolvedShowGrid","ceilingH","shape","pts","mnX","mxX","mnZ","mxZ","sh","wallGeometry","positions","indices","curr","next","baseIdx","geo","sizeX","sizeZ","gridGeometry","spacing","y","x","z","Wheel","radius","width","TruckEnvironment","wallOpacity","showRoof","showSideWalls","truckStyle","tw","th","wallThickness","floorThickness","wheelRadius","wheelWidth","groundClearance","chassisH","wheelY","chassisY","remolqueFloorY","cabW","cabD","cabH","cabGap","cabZ","cabFloorY","solidWallMaterial","frac","side","calculatePresetPosition","sceneSize","depth","tx","ty","tz","distance","CameraControlsComponent","autoRotate","enablePan","enableZoom","minDistance","maxDistance","camera","useThree","controlsRef","useEffect","targetPos","targetLookAt","startPos","duration","startTime","animate","elapsed","progress","eased","OrbitControls","PRESET_LABELS","currentPreset","onPresetChange","presets","label","icon","isActive","MiniMap","sceneWidth","sceneDepth","sceneType","floorPolygon","cameraPosition","targetPosition","scale","worldToMap","polygonPath","mapped","truckRect","topLeft","cameraMapPos","targetMapPos","useCameraPosition","setPosition","useState","frameId","updatePosition","CameraTracker","onPositionChange","PalletScene","cameraPreset","showMiniMap","style","setCameraPosition","handleCameraPositionChange","centerY","initialCameraPosition","pw","pd","Canvas","TruckScene","validPallets","validation","WarehouseScene","size","initialPos","floorPolygonForMap"],"mappings":"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","x_google_ignoreList":[3,4,5]}
1
+ {"version":3,"file":"pallet-builder.js","sources":["../src/core/types.ts","../src/core/constants.ts","../src/core/presets/ScenePreset.ts","../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.production.js","../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.development.js","../node_modules/.pnpm/react@19.2.4/node_modules/react/jsx-runtime.js","../src/context/PresetContext.tsx","../src/core/entities/StackedPallet.ts","../src/core/validation/collision.ts","../src/core/validation/bounds.ts","../src/core/validation/weight.ts","../src/core/validation/stacking.ts","../src/core/validation/gravity.ts","../src/core/validation/stability.ts","../src/core/validation/polygon.ts","../src/core/packing/ColumnStrategy.ts","../src/core/packing/BinPacking3D.ts","../src/core/packing/TypeGroupStrategy.ts","../src/core/packing/MaterialGroupingStrategy.ts","../src/core/packing/registry.ts","../src/core/factories/PalletFactory.ts","../src/core/factories/TruckFactory.ts","../src/core/factories/BoxFactory.ts","../src/hooks/usePhysicsValidation.ts","../src/hooks/usePalletMetrics.ts","../src/hooks/usePackingStrategy.ts","../src/hooks/useWarehouseValidation.ts","../src/components/primitives/Box/Box.tsx","../src/components/primitives/Pallet/Pallet.tsx","../src/components/primitives/Separator/Separator.tsx","../src/components/primitives/StackedPallet/StackedPallet.tsx","../src/components/primitives/Label/Label.tsx","../src/components/environments/WarehouseEnvironment/WarehouseEnvironment.tsx","../src/components/environments/TruckEnvironment/TruckEnvironment.tsx","../src/components/controls/CameraControls/CameraControls.tsx","../src/components/controls/ViewControls/ViewControls.tsx","../src/components/controls/MiniMap/MiniMap.tsx","../src/hooks/useCameraPosition.ts","../src/components/controls/CameraTracker/CameraTracker.tsx","../src/components/scenes/PalletScene/PalletScene.tsx","../src/components/scenes/TruckScene/TruckScene.tsx","../src/components/scenes/WarehouseScene/WarehouseScene.tsx"],"sourcesContent":["/**\n * Core types — Tipos base, interfaces y enums compartidos\n * TypeScript puro, sin dependencias de React ni Three.js\n */\n\n// ─── Value Objects ───────────────────────────────────────────────\n\n/** Dimensiones 3D en milímetros */\nexport interface Dimensions3D {\n width: number // mm (X)\n height: number // mm (Y)\n depth: number // mm (Z)\n}\n\n/** Posición 3D en milímetros */\nexport interface Position3D {\n x: number // mm — ancho\n y: number // mm — alto (vertical)\n z: number // mm — profundidad\n}\n\n/** Punto 2D en milímetros (planta) */\nexport interface Point2D {\n x: number // mm\n z: number // mm\n}\n\n/** Bounding box axis-aligned */\nexport interface BoundingBox {\n minX: number\n maxX: number\n minY: number\n maxY: number\n minZ: number\n maxZ: number\n}\n\n/** Rotación discreta: solo múltiplos de 90° */\nexport interface DiscreteRotation {\n x: 0 | 90 | 180 | 270\n y: 0 | 90 | 180 | 270\n z: 0 | 90 | 180 | 270\n}\n\n// ─── Validation ──────────────────────────────────────────────────\n\nexport interface ValidationResult {\n isValid: boolean\n violations: Violation[]\n}\n\nexport interface Violation {\n code: string\n severity: 'error' | 'warning'\n message: string\n involvedIds: string[]\n}\n\n// ─── Enums (const objects for erasableSyntaxOnly) ────────────────\n\nexport const PalletMaterial = {\n WOOD: 'WOOD',\n PLASTIC: 'PLASTIC',\n METAL: 'METAL',\n COMPOSITE: 'COMPOSITE',\n} as const\nexport type PalletMaterial = (typeof PalletMaterial)[keyof typeof PalletMaterial]\n\nexport const SeparatorMaterial = {\n CARDBOARD: 'CARDBOARD',\n WOOD: 'WOOD',\n PLASTIC: 'PLASTIC',\n} as const\nexport type SeparatorMaterial = (typeof SeparatorMaterial)[keyof typeof SeparatorMaterial]\n\nexport const TruckType = {\n BOX: 'BOX',\n REFRIGERATED: 'REFRIGERATED',\n FLATBED: 'FLATBED',\n TAUTLINER: 'TAUTLINER',\n CUSTOM: 'CUSTOM',\n} as const\nexport type TruckType = (typeof TruckType)[keyof typeof TruckType]\n\n// ─── Packing ─────────────────────────────────────────────────────\n\nexport interface PackingMetrics {\n volumeUtilization: number // 0–1\n weightUtilization: number // 0–1\n centerOfGravity: Position3D\n stabilityScore: number // 0–100\n}\n\n// ─── Presets ─────────────────────────────────────────────────────\n\nexport interface PalletPreset {\n dimensions: Dimensions3D\n material: PalletMaterial\n maxWeight: number\n maxStackHeight: number\n weight: number\n}\n\nexport interface TruckPreset {\n dimensions: Dimensions3D\n maxWeight: number\n}\n","/**\n * Constantes del sistema — presets de palets y camiones estándar\n */\n\nimport { PalletMaterial, TruckType } from './types'\nimport type { PalletPreset, TruckPreset } from './types'\n\n// ─── Palet Presets ───────────────────────────────────────────────\n/**\n * STANDARD_PALLETS — Dimensiones de palets estándar internacionales\n * \n * Incluye los tipos más comunes utilizados en logística mundial:\n * - EUR/EPAL: Palet europeo (Europa, ISO 6780)\n * - GMA/AMERICAN: Palet americano estándar (Norteamérica, 48\"×40\")\n * - UK: Palet estándar Reino Unido (1200×1000)\n * - ASIA: Palet estándar asiático (1100×1100, ISO 6780)\n * - AUSTRALIAN: Palet estándar australiano (1165×1165)\n * - HALF_EUR: Medio palet europeo (800×600)\n * - QUARTER_EUR: Cuarto de palet europeo (600×400)\n * - ISO_1: Palet ISO 1200×1000 (ISO 6780)\n * - ISO_2: Palet ISO 1200×800 (equivalente a EUR)\n */\nexport const STANDARD_PALLETS: Record<string, PalletPreset> = {\n /** Palet EUR/EPAL — Estándar europeo (1200×800×144mm, ISO 6780) */\n EUR: {\n dimensions: { width: 1200, height: 144, depth: 800 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n },\n /** Palet GMA/Americano — Estándar norteamericano (1219×1016×145mm, 48\"×40\") */\n GMA: {\n dimensions: { width: 1219, height: 145, depth: 1016 },\n material: PalletMaterial.WOOD,\n maxWeight: 1200,\n maxStackHeight: 2200,\n weight: 30,\n },\n /** Palet UK Standard — Reino Unido (1200×1000×150mm) */\n UK: {\n dimensions: { width: 1200, height: 150, depth: 1000 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet asiático estándar — Asia Pallet (1100×1100×150mm, ISO 6780) */\n ASIA: {\n dimensions: { width: 1100, height: 150, depth: 1100 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet australiano estándar — Australia (1165×1165×150mm) */\n AUSTRALIAN: {\n dimensions: { width: 1165, height: 150, depth: 1165 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 29,\n },\n /** Medio palet EUR — Half European Pallet (800×600×144mm) */\n HALF_EUR: {\n dimensions: { width: 800, height: 144, depth: 600 },\n material: PalletMaterial.WOOD,\n maxWeight: 500,\n maxStackHeight: 2200,\n weight: 12,\n },\n /** Cuarto de palet EUR — Quarter European Pallet (600×400×144mm) */\n QUARTER_EUR: {\n dimensions: { width: 600, height: 144, depth: 400 },\n material: PalletMaterial.WOOD,\n maxWeight: 250,\n maxStackHeight: 2200,\n weight: 6,\n },\n /** Palet ISO 1 — ISO 6780 (1200×1000×150mm) */\n ISO_1: {\n dimensions: { width: 1200, height: 150, depth: 1000 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 28,\n },\n /** Palet ISO 2 — ISO 6780 (1200×800×144mm, equivalente a EUR) */\n ISO_2: {\n dimensions: { width: 1200, height: 144, depth: 800 },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n },\n} as const\n\n// Alias para compatibilidad con código existente\n/** @deprecated Use GMA instead */\nexport const AMERICAN_PALLET = STANDARD_PALLETS.GMA\n\n// ─── Truck Presets ───────────────────────────────────────────────\n\nexport const TRUCK_PRESETS: Record<Exclude<TruckType, 'CUSTOM'>, TruckPreset> = {\n [TruckType.BOX]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 24000,\n },\n [TruckType.REFRIGERATED]: {\n dimensions: { width: 2440, height: 2590, depth: 13100 },\n maxWeight: 22000,\n },\n [TruckType.FLATBED]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 25000,\n },\n [TruckType.TAUTLINER]: {\n dimensions: { width: 2480, height: 2700, depth: 13600 },\n maxWeight: 24000,\n },\n} as const\n\n// ─── Separator Defaults ─────────────────────────────────────────\n\nexport const SEPARATOR_DEFAULTS = {\n thickness: 10, // mm\n weight: 2, // kg\n} as const\n\n// ─── Conversiones ────────────────────────────────────────────────\n\nexport const UNITS = {\n MM_TO_M: 0.001,\n M_TO_MM: 1000,\n} as const\n\n// ─── Validation ──────────────────────────────────────────────────\n\n/** Tolerancia en mm para detección AABB */\nexport const COLLISION_TOLERANCE = 1\n\n/** % mínimo de soporte bajo una caja */\nexport const MIN_SUPPORT_PERCENTAGE = 0.6\n\n/** Factor de seguridad de peso (warning a partir de este %) */\nexport const WEIGHT_WARNING_THRESHOLD = 0.9\n","/**\n * ScenePreset — Definiciones de estilos visuales predefinidos\n *\n * Cada preset define colores, materiales e indicadores para todos los\n * elementos de la escena (cajas, palets, separadores, environments).\n * El consumidor puede usar un preset tal cual, extenderlo o crear el suyo propio.\n */\n\n// ─── Tipos ───────────────────────────────────────────────────────\n\nexport interface BoxStyle {\n /** Color por defecto de las cajas */\n color: string\n /** Rugosidad del material (0–1) */\n roughness: number\n /** Metalicidad del material (0–1) */\n metalness: number\n /** Opacidad por defecto */\n opacity: number\n}\n\nexport interface PalletStyle {\n /** Color del palet */\n color: string\n /** Color del borde decorativo */\n edgeColor: string\n roughness: number\n metalness: number\n}\n\nexport interface SeparatorStyle {\n /** Override de color (null = usa color por material) */\n colorOverride: string | null\n roughness: number\n}\n\nexport interface SelectionStyle {\n /** Color del borde de selección */\n selectedColor: string\n /** Color del borde de highlight (hover) */\n highlightedColor: string\n}\n\nexport interface WarehouseStyle {\n /** Color del suelo */\n floorColor: string\n /** Rugosidad del suelo */\n floorRoughness: number\n /** Color de las paredes */\n wallColor: string\n /** Opacidad de las paredes */\n wallOpacity: number\n /** Color de la iluminación ambiente */\n ambientIntensity: number\n /** Intensidad de la luz direccional */\n directionalIntensity: number\n /** Mostrar grid por defecto */\n showGrid: boolean\n /** Color principal del grid */\n gridColor: string\n /** Color secundario del grid */\n gridSecondaryColor: string\n}\n\nexport interface TruckStyle {\n /** Color del suelo del remolque */\n floorColor: string\n /** Color de las paredes del remolque */\n wallColor: string\n /** Opacidad de las paredes */\n wallOpacity: number\n /** Mostrar grid en el suelo */\n showGrid: boolean\n /** Color principal del grid */\n gridColor: string\n /** Color secundario del grid */\n gridSecondaryColor: string\n /** Color de la cabina */\n cabColor: string\n /** Color del chasis / bastidor */\n chassisColor: string\n /** Color de las ruedas */\n wheelColor: string\n}\n\nexport interface ScenePreset {\n /** Nombre identificador del preset */\n readonly id: string\n /** Nombre legible */\n readonly name: string\n\n box: BoxStyle\n pallet: PalletStyle\n separator: SeparatorStyle\n selection: SelectionStyle\n warehouse: WarehouseStyle\n truck: TruckStyle\n}\n\n// ─── Presets incluidos ───────────────────────────────────────────\n\n/**\n * Preset UNSTYLED — geometría básica con colores planos.\n * Ideal para desarrollo, depuración o cuando el consumidor quiere\n * aplicar su propio estilo desde cero.\n */\nexport const PRESET_UNSTYLED: ScenePreset = {\n id: 'unstyled',\n name: 'Sin estilo',\n\n box: {\n color: '#e07b39',\n roughness: 0.6,\n metalness: 0.1,\n opacity: 1,\n },\n pallet: {\n color: '#c4a26e',\n edgeColor: '#8b7355',\n roughness: 0.85,\n metalness: 0.05,\n },\n separator: {\n colorOverride: null,\n roughness: 0.8,\n },\n selection: {\n selectedColor: '#ff0000',\n highlightedColor: '#42a5f5',\n },\n warehouse: {\n floorColor: '#8a8a8a',\n floorRoughness: 0.8,\n wallColor: '#d0d0d0',\n wallOpacity: 0.4,\n ambientIntensity: 0.4,\n directionalIntensity: 0.8,\n showGrid: true,\n gridColor: '#666666',\n gridSecondaryColor: '#999999',\n },\n truck: {\n floorColor: '#8a7e72',\n wallColor: '#b0b0b0',\n wallOpacity: 0.35,\n showGrid: true,\n gridColor: '#666666',\n gridSecondaryColor: '#999999',\n cabColor: '#3a5f8a',\n chassisColor: '#2a2a2a',\n wheelColor: '#1a1a1a',\n },\n}\n\n/**\n * Preset INDUSTRIAL — aspecto de almacén profesional.\n * Colores más saturados, iluminación más cálida, bordes contrastados.\n * Usa las texturas y HDR incluidos en /public como base.\n */\nexport const PRESET_INDUSTRIAL: ScenePreset = {\n id: 'industrial',\n name: 'Industrial',\n\n box: {\n color: '#d4895a',\n roughness: 0.7,\n metalness: 0.05,\n opacity: 1,\n },\n pallet: {\n color: '#a8854a',\n edgeColor: '#6b5030',\n roughness: 0.9,\n metalness: 0.02,\n },\n separator: {\n colorOverride: null,\n roughness: 0.85,\n },\n selection: {\n selectedColor: '#e53935',\n highlightedColor: '#29b6f6',\n },\n warehouse: {\n floorColor: '#5c5c5c',\n floorRoughness: 0.92,\n wallColor: '#b0b8be',\n wallOpacity: 0.5,\n ambientIntensity: 0.5,\n directionalIntensity: 1.0,\n showGrid: true,\n gridColor: '#4a4a4a',\n gridSecondaryColor: '#6a6a6a',\n },\n truck: {\n floorColor: '#6e6358',\n wallColor: '#9eaab4',\n wallOpacity: 0.4,\n showGrid: true,\n gridColor: '#4a4a4a',\n gridSecondaryColor: '#6a6a6a',\n cabColor: '#2e4a6b',\n chassisColor: '#1e1e1e',\n wheelColor: '#111111',\n },\n}\n\n/** Mapa de presets disponibles por ID */\nexport const SCENE_PRESETS: Record<string, ScenePreset> = {\n unstyled: PRESET_UNSTYLED,\n industrial: PRESET_INDUSTRIAL,\n}\n\n/** Preset por defecto si el consumidor no elige ninguno */\nexport const DEFAULT_PRESET: ScenePreset = PRESET_INDUSTRIAL\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/**\n * PresetContext — Provee el ScenePreset activo a todos los componentes del árbol.\n *\n * Uso:\n * <PresetProvider preset=\"industrial\">\n * <WarehouseScene ... />\n * </PresetProvider>\n *\n * O con un preset custom:\n * <PresetProvider preset={myCustomPreset}>\n * <TruckScene ... />\n * </PresetProvider>\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport { DEFAULT_PRESET, SCENE_PRESETS } from '@/core/presets'\nimport type { ScenePreset } from '@/core/presets'\n\nconst PresetContext = createContext<ScenePreset>(DEFAULT_PRESET)\n\nexport interface PresetProviderProps {\n /** ID de un preset incluido ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n children: ReactNode\n}\n\nexport function PresetProvider({ preset, children }: PresetProviderProps) {\n const resolved = useMemo<ScenePreset>(() => {\n if (!preset) return DEFAULT_PRESET\n if (typeof preset === 'string') return SCENE_PRESETS[preset] ?? DEFAULT_PRESET\n return preset\n }, [preset])\n\n return (\n <PresetContext.Provider value={resolved}>\n {children}\n </PresetContext.Provider>\n )\n}\n\n/** Hook para acceder al preset activo */\nexport function usePreset(): ScenePreset {\n return useContext(PresetContext)\n}\n","/**\n * StackedPallet — Composición vertical de pisos de palet con separadores\n */\n\nimport type { PalletFloor } from './PalletFloor'\nimport type { PlacedBox } from './PlacedBox'\n\nexport interface StackedPallet {\n id: string\n floors: PalletFloor[] // al menos 1\n metadata: Record<string, unknown>\n}\n\n// ─── Helpers puros ───────────────────────────────────────────────\n\n/** Calcula la altura total de un StackedPallet en mm */\nexport function getStackedPalletTotalHeight(stack: StackedPallet): number {\n let height = 0\n for (const floor of stack.floors) {\n height += floor.pallet.dimensions.height\n // Altura máxima de cajas en este piso\n const maxBoxTop = floor.boxes.reduce((max, pb) => {\n const boxTop = pb.position.y + pb.box.dimensions.height\n return Math.max(max, boxTop)\n }, 0)\n height += maxBoxTop\n if (floor.separatorAbove) {\n height += floor.separatorAbove.dimensions.height\n }\n }\n return height\n}\n\n/** Calcula el peso total de un StackedPallet en kg */\nexport function getStackedPalletTotalWeight(stack: StackedPallet): number {\n let weight = 0\n for (const floor of stack.floors) {\n weight += floor.pallet.weight\n weight += floor.boxes.reduce((sum, pb) => sum + pb.box.weight, 0)\n if (floor.separatorAbove) {\n weight += floor.separatorAbove.weight\n }\n }\n return weight\n}\n\n/**\n * Normaliza los IDs de todas las cajas en un StackedPallet para garantizar unicidad global.\n * \n * La librería debe asegurar que cada caja tenga un ID único, independientemente de cómo \n * el desarrollador construya el StackedPallet. Esto evita conflictos de selección cuando\n * hay múltiples pisos o cuando se reutilizan las mismas cajas base.\n * \n * Formato del ID generado: `{stackId}:f{floorIndex}:b{boxIndex}`\n * \n * @param stack - StackedPallet a normalizar\n * @param contextId - ID opcional de contexto (ej: placedPalletId en truck/warehouse)\n * @returns Nuevo StackedPallet con IDs únicos\n */\nexport function ensureUniqueBoxIds(\n stack: StackedPallet,\n contextId?: string,\n): StackedPallet {\n const baseId = contextId || stack.id\n \n const normalizedFloors: PalletFloor[] = stack.floors.map((floor, floorIdx) => {\n const normalizedBoxes: PlacedBox[] = floor.boxes.map((pb, boxIdx) => {\n // Generar ID único: contextId:f{floor}:b{box}\n const uniqueId = `${baseId}:f${floorIdx}:b${boxIdx}`\n \n // Actualizar referencias supportedBy/supporting para mantener consistencia\n const updateRefs = (refs: string[]) =>\n refs.map(refId => {\n // Si la referencia es un ID antiguo dentro de este floor, actualizarla\n const refBoxIdx = floor.boxes.findIndex(b => b.id === refId)\n return refBoxIdx >= 0 ? `${baseId}:f${floorIdx}:b${refBoxIdx}` : refId\n })\n\n return {\n ...pb,\n id: uniqueId,\n supportedBy: updateRefs(pb.supportedBy),\n supporting: updateRefs(pb.supporting),\n }\n })\n\n return {\n ...floor,\n boxes: normalizedBoxes,\n }\n })\n\n return {\n ...stack,\n floors: normalizedFloors,\n }\n}\n","/**\n * Collision detection — AABB helpers y detección de colisiones\n * BR-002: Sin colisiones entre cajas\n * BR-003: Sin colisiones entre palets\n */\n\nimport type { BoundingBox, ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport { getStackedPalletTotalHeight } from '../entities/StackedPallet'\nimport { COLLISION_TOLERANCE } from '../constants'\n\n// ─── Helpers ─────────────────────────────────────────────────────\n\n/** Calcula el bounding box de una PlacedBox (teniendo en cuenta rotación discreta en Y) */\nexport function getBoxBoundingBox(pb: PlacedBox): BoundingBox {\n let w = pb.box.dimensions.width\n let d = pb.box.dimensions.depth\n const h = pb.box.dimensions.height\n\n // Rotación en Y: intercambia width y depth a 90° y 270°\n if (pb.rotation.y === 90 || pb.rotation.y === 270) {\n ;[w, d] = [d, w]\n }\n\n return {\n minX: pb.position.x,\n maxX: pb.position.x + w,\n minY: pb.position.y,\n maxY: pb.position.y + h,\n minZ: pb.position.z,\n maxZ: pb.position.z + d,\n }\n}\n\n/** Calcula el bounding box de un PlacedPallet completo */\nexport function getPalletBoundingBox(pp: PlacedPallet): BoundingBox {\n const stack = pp.stackedPallet\n const basePallet = stack.floors[0].pallet\n const w = basePallet.dimensions.width\n const d = basePallet.dimensions.depth\n const totalH = getStackedPalletTotalHeight(stack)\n\n // Convertir rotación a radianes\n const rotRad = (pp.yRotation * Math.PI) / 180\n const cos = Math.cos(rotRad)\n const sin = Math.sin(rotRad)\n\n // Calcular las 4 esquinas en coordenadas locales (sin rotar)\n const localCorners = [\n { x: 0, z: 0 },\n { x: w, z: 0 },\n { x: w, z: d },\n { x: 0, z: d },\n ]\n\n // Rotar cada esquina usando la convención Three.js (R_y) y trasladar a posición mundial\n // Three.js Y-rotation: x' = x·cos + z·sin, z' = -x·sin + z·cos\n const worldCorners = localCorners.map(corner => ({\n x: pp.position.x + corner.x * cos + corner.z * sin,\n z: pp.position.z - corner.x * sin + corner.z * cos,\n }))\n\n // Encontrar límites del bounding box\n const minX = Math.min(...worldCorners.map(c => c.x))\n const maxX = Math.max(...worldCorners.map(c => c.x))\n const minZ = Math.min(...worldCorners.map(c => c.z))\n const maxZ = Math.max(...worldCorners.map(c => c.z))\n\n return {\n minX,\n maxX,\n minY: pp.position.y,\n maxY: pp.position.y + totalH,\n minZ,\n maxZ,\n }\n}\n\n/** Comprueba si dos AABBs se intersectan (con tolerancia) */\nexport function aabbIntersects(a: BoundingBox, b: BoundingBox, tolerance = COLLISION_TOLERANCE): boolean {\n return (\n a.minX < b.maxX - tolerance &&\n a.maxX > b.minX + tolerance &&\n a.minY < b.maxY - tolerance &&\n a.maxY > b.minY + tolerance &&\n a.minZ < b.maxZ - tolerance &&\n a.maxZ > b.minZ + tolerance\n )\n}\n\n// ─── Validación ──────────────────────────────────────────────────\n\n/** BR-002: Valida que no hay colisiones entre cajas */\nexport function validateNoBoxCollisions(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (let i = 0; i < boxes.length; i++) {\n for (let j = i + 1; j < boxes.length; j++) {\n const bbA = getBoxBoundingBox(boxes[i])\n const bbB = getBoxBoundingBox(boxes[j])\n if (aabbIntersects(bbA, bbB)) {\n violations.push({\n code: 'BR-002',\n severity: 'error',\n message: `Colisión entre cajas ${boxes[i].id} y ${boxes[j].id}`,\n involvedIds: [boxes[i].id, boxes[j].id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-003: Valida que no hay colisiones entre palets */\nexport function validateNoPalletCollisions(pallets: PlacedPallet[]): ValidationResult {\n const violations: Violation[] = []\n\n for (let i = 0; i < pallets.length; i++) {\n for (let j = i + 1; j < pallets.length; j++) {\n const bbA = getPalletBoundingBox(pallets[i])\n const bbB = getPalletBoundingBox(pallets[j])\n if (aabbIntersects(bbA, bbB)) {\n violations.push({\n code: 'BR-003',\n severity: 'error',\n message: `Colisión entre palets ${pallets[i].id} y ${pallets[j].id}`,\n involvedIds: [pallets[i].id, pallets[j].id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Bounds validation — Límites de contenedor\n * BR-001: Caja dentro de palet\n * BR-402: Palet dentro de camión\n * BR-403/404: Altura dentro de contenedor\n */\n\nimport type { ValidationResult, Violation, Dimensions3D } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport type { Truck } from '../entities/Truck'\nimport { getBoxBoundingBox, getPalletBoundingBox } from './collision'\n\n// ─── BR-001: Caja dentro de palet ────────────────────────────────\n\nexport function validateBoxInPalletBounds(box: PlacedBox, pallet: Pallet): ValidationResult {\n const violations: Violation[] = []\n const bb = getBoxBoundingBox(box)\n\n if (bb.minX < 0 || bb.maxX > pallet.dimensions.width) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} sobresale por el eje X del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n if (bb.minZ < 0 || bb.maxZ > pallet.dimensions.depth) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} sobresale por el eje Z del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n if (bb.maxY > pallet.maxStackHeight) {\n violations.push({\n code: 'BR-001',\n severity: 'error',\n message: `Caja ${box.id} excede la altura máxima de apilamiento del palet`,\n involvedIds: [box.id, pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** Valida todas las cajas de un piso contra los límites del palet */\nexport function validateAllBoxesInPalletBounds(boxes: PlacedBox[], pallet: Pallet): ValidationResult {\n const violations: Violation[] = []\n for (const box of boxes) {\n const result = validateBoxInPalletBounds(box, pallet)\n violations.push(...result.violations)\n }\n return { isValid: violations.length === 0, violations }\n}\n\n// ─── BR-402: Palet dentro de camión ──────────────────────────────\n\nexport function validatePalletInTruck(pallet: PlacedPallet, truck: Truck): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n const td: Dimensions3D = truck.dimensions\n\n if (bb.minX < 0 || bb.maxX > td.width) {\n violations.push({\n code: 'BR-402',\n severity: 'error',\n message: `Palet ${pallet.id} sobresale por el ancho del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n if (bb.minZ < 0 || bb.maxZ > td.depth) {\n violations.push({\n code: 'BR-402',\n severity: 'error',\n message: `Palet ${pallet.id} sobresale por la profundidad del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n // BR-404\n if (bb.maxY > td.height) {\n violations.push({\n code: 'BR-404',\n severity: 'error',\n message: `Palet ${pallet.id} excede la altura del camión`,\n involvedIds: [pallet.id, truck.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-403: Palet dentro de estancia (por altura) */\nexport function validatePalletHeight(pallet: PlacedPallet, ceilingHeight: number): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n\n if (bb.maxY > ceilingHeight) {\n violations.push({\n code: 'BR-403',\n severity: 'error',\n message: `Palet ${pallet.id} excede el techo de la estancia (${bb.maxY}mm > ${ceilingHeight}mm)`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Weight validation\n * BR-101: Peso máximo de palet\n * BR-102: Peso máximo de camión\n * BR-103: Peso sobre caja frágil\n * BR-104: Distribución de peso en palet\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport type { Truck } from '../entities/Truck'\nimport type { PalletFloor } from '../entities/PalletFloor'\nimport { getStackedPalletTotalWeight } from '../entities/StackedPallet'\nimport { WEIGHT_WARNING_THRESHOLD } from '../constants'\nimport { getBoxBoundingBox } from './collision'\n\n// ─── BR-101: Peso máximo de palet ────────────────────────────────\n\nexport function validatePalletWeight(floor: PalletFloor): ValidationResult {\n const violations: Violation[] = []\n const totalBoxWeight = floor.boxes.reduce((sum, pb) => sum + pb.box.weight, 0)\n const maxWeight = floor.pallet.maxWeight\n\n if (totalBoxWeight > maxWeight) {\n violations.push({\n code: 'BR-101',\n severity: 'error',\n message: `Peso de cajas (${totalBoxWeight.toFixed(1)}kg) excede el máximo del palet (${maxWeight}kg)`,\n involvedIds: [floor.pallet.id],\n })\n } else if (totalBoxWeight > maxWeight * WEIGHT_WARNING_THRESHOLD) {\n violations.push({\n code: 'BR-101',\n severity: 'warning',\n message: `Peso de cajas (${totalBoxWeight.toFixed(1)}kg) supera el 90% del máximo del palet (${maxWeight}kg)`,\n involvedIds: [floor.pallet.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n\n// ─── BR-102: Peso máximo de camión ───────────────────────────────\n\nexport function validateTruckWeight(truck: Truck): ValidationResult {\n const violations: Violation[] = []\n const totalWeight = truck.pallets.reduce(\n (sum, pp) => sum + getStackedPalletTotalWeight(pp.stackedPallet),\n 0,\n )\n\n if (totalWeight > truck.maxWeight) {\n violations.push({\n code: 'BR-102',\n severity: 'error',\n message: `Peso total (${totalWeight.toFixed(1)}kg) excede el máximo del camión (${truck.maxWeight}kg)`,\n involvedIds: [truck.id],\n })\n } else if (totalWeight > truck.maxWeight * WEIGHT_WARNING_THRESHOLD) {\n violations.push({\n code: 'BR-102',\n severity: 'warning',\n message: `Peso total (${totalWeight.toFixed(1)}kg) supera el 90% del máximo del camión (${truck.maxWeight}kg)`,\n involvedIds: [truck.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n\n// ─── BR-103: Peso sobre caja frágil ─────────────────────────────\n\nexport function validateFragileLoad(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n if (!pb.box.fragile) continue\n const maxAbove = pb.box.fragilityMaxWeight ?? 0\n const weightAbove = calculateWeightAboveBox(pb, boxes)\n if (weightAbove > maxAbove) {\n violations.push({\n code: 'BR-103',\n severity: 'error',\n message: `Caja frágil ${pb.id} soporta ${weightAbove.toFixed(1)}kg (máx: ${maxAbove}kg)`,\n involvedIds: [pb.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** Calcula el peso soportado encima de una caja */\nfunction calculateWeightAboveBox(target: PlacedBox, allBoxes: PlacedBox[]): number {\n const tbb = getBoxBoundingBox(target)\n let weight = 0\n\n for (const other of allBoxes) {\n if (other.id === target.id) continue\n const obb = getBoxBoundingBox(other)\n // La otra caja está encima y se solapa horizontalmente\n if (\n obb.minY >= tbb.maxY - 1 &&\n obb.minX < tbb.maxX &&\n obb.maxX > tbb.minX &&\n obb.minZ < tbb.maxZ &&\n obb.maxZ > tbb.minZ\n ) {\n weight += other.box.weight\n }\n }\n\n return weight\n}\n\n// ─── BR-104: Distribución de peso ────────────────────────────────\n\nexport function validateWeightDistribution(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const totalWeight = boxes.reduce((s, pb) => s + pb.box.weight, 0)\n if (totalWeight === 0) return { isValid: true, violations }\n\n // Centro de gravedad ponderado por peso\n let cogX = 0, cogZ = 0\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n const cx = (bb.minX + bb.maxX) / 2\n const cz = (bb.minZ + bb.maxZ) / 2\n cogX += cx * pb.box.weight\n cogZ += cz * pb.box.weight\n }\n cogX /= totalWeight\n cogZ /= totalWeight\n\n const centerX = pallet.dimensions.width / 2\n const centerZ = pallet.dimensions.depth / 2\n\n if (\n Math.abs(cogX - centerX) > pallet.dimensions.width / 6 ||\n Math.abs(cogZ - centerZ) > pallet.dimensions.depth / 6\n ) {\n violations.push({\n code: 'BR-104',\n severity: 'warning',\n message: `Centro de gravedad descentrado (${cogX.toFixed(0)}, ${cogZ.toFixed(0)}) respecto al centro del palet`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: true, violations }\n}\n","/**\n * Stacking validation\n * BR-201: Caja apilable\n * BR-202: Capacidad de soporte de caja\n * BR-203: Pirámide invertida\n * BR-301: Mismas dimensiones de planta en stack\n * BR-302: Separador obligatorio\n * BR-303: Altura total del stack\n * BR-304: Peso acumulado del stack\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { StackedPallet } from '../entities/StackedPallet'\nimport { getStackedPalletTotalHeight, getStackedPalletTotalWeight } from '../entities/StackedPallet'\nimport { getBoxBoundingBox } from './collision'\n\n// ─── Apilamiento de cajas ────────────────────────────────────────\n\n/** BR-201: Valida que solo cajas apilables tienen otras encima */\nexport function validateBoxStackability(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n if (pb.box.stackable) continue\n\n // Comprobar si hay algo encima\n const bb = getBoxBoundingBox(pb)\n for (const other of boxes) {\n if (other.id === pb.id) continue\n const obb = getBoxBoundingBox(other)\n if (\n obb.minY >= bb.maxY - 1 &&\n obb.minX < bb.maxX && obb.maxX > bb.minX &&\n obb.minZ < bb.maxZ && obb.maxZ > bb.minZ\n ) {\n violations.push({\n code: 'BR-201',\n severity: 'error',\n message: `Caja ${other.id} apilada sobre caja no apilable ${pb.id}`,\n involvedIds: [pb.id, other.id],\n })\n }\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-203: Pirámide invertida — caja pesada sobre caja ligera */\nexport function validateInvertedPyramid(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const bottom of boxes) {\n const bbb = getBoxBoundingBox(bottom)\n const bottomArea = (bbb.maxX - bbb.minX) * (bbb.maxZ - bbb.minZ)\n\n for (const top of boxes) {\n if (top.id === bottom.id) continue\n const tbb = getBoxBoundingBox(top)\n if (tbb.minY < bbb.maxY - 1) continue\n // Overlap check\n if (tbb.minX >= bbb.maxX || tbb.maxX <= bbb.minX || tbb.minZ >= bbb.maxZ || tbb.maxZ <= bbb.minZ) continue\n\n const topArea = (tbb.maxX - tbb.minX) * (tbb.maxZ - tbb.minZ)\n if (top.box.weight > bottom.box.weight * 1.5 && topArea > bottomArea * 1.2) {\n violations.push({\n code: 'BR-203',\n severity: 'warning',\n message: `Pirámide invertida: caja ${top.id} (${top.box.weight}kg) sobre caja ${bottom.id} (${bottom.box.weight}kg)`,\n involvedIds: [bottom.id, top.id],\n })\n }\n }\n }\n\n return { isValid: true, violations }\n}\n\n// ─── Apilamiento de palets ───────────────────────────────────────\n\n/** BR-301: Todos los palets en un stack deben tener mismas dimensiones de planta */\nexport function validateStackDimensions(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n if (stack.floors.length <= 1) return { isValid: true, violations }\n\n const base = stack.floors[0].pallet\n for (let i = 1; i < stack.floors.length; i++) {\n const p = stack.floors[i].pallet\n if (p.dimensions.width !== base.dimensions.width || p.dimensions.depth !== base.dimensions.depth) {\n violations.push({\n code: 'BR-301',\n severity: 'error',\n message: `Piso ${i}: dimensiones (${p.dimensions.width}×${p.dimensions.depth}) distintas a la base (${base.dimensions.width}×${base.dimensions.depth})`,\n involvedIds: [base.id, p.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-302: Separador obligatorio entre pisos */\nexport function validateSeparators(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n for (let i = 0; i < stack.floors.length - 1; i++) {\n if (!stack.floors[i].separatorAbove) {\n violations.push({\n code: 'BR-302',\n severity: 'error',\n message: `Falta separador entre piso ${i} y piso ${i + 1}`,\n involvedIds: [stack.id],\n })\n }\n }\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-303: Altura total del stack ≤ altura del contenedor */\nexport function validateStackHeight(stack: StackedPallet, containerHeight: number): ValidationResult {\n const violations: Violation[] = []\n const totalH = getStackedPalletTotalHeight(stack)\n\n if (totalH > containerHeight) {\n violations.push({\n code: 'BR-303',\n severity: 'error',\n message: `Altura del stack (${totalH}mm) excede la del contenedor (${containerHeight}mm)`,\n involvedIds: [stack.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-304: Peso total del stack ≤ maxWeight del palet base */\nexport function validateStackWeight(stack: StackedPallet): ValidationResult {\n const violations: Violation[] = []\n const totalWeight = getStackedPalletTotalWeight(stack)\n const baseMaxWeight = stack.floors[0].pallet.maxWeight\n\n // Descontar el peso del palet base, ya que maxWeight es la capacidad de carga\n const loadWeight = totalWeight - stack.floors[0].pallet.weight\n if (loadWeight > baseMaxWeight) {\n violations.push({\n code: 'BR-304',\n severity: 'error',\n message: `Peso de carga del stack (${loadWeight.toFixed(1)}kg) excede la capacidad del palet base (${baseMaxWeight}kg)`,\n involvedIds: [stack.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Gravity validation — BR-004: Objetos no flotan\n */\n\nimport type { ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport { getBoxBoundingBox } from './collision'\nimport { MIN_SUPPORT_PERCENTAGE } from '../constants'\n\n/**\n * BR-004: Valida que toda caja tiene soporte debajo (suelo del palet u otra caja)\n * Al menos MIN_SUPPORT_PERCENTAGE del área base debe estar soportada\n */\nexport function validateSupport(boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n\n // Si la caja está en el suelo (Y ≈ 0), tiene soporte\n if (bb.minY <= 1) continue\n\n const boxArea = (bb.maxX - bb.minX) * (bb.maxZ - bb.minZ)\n let supportedArea = 0\n\n for (const other of boxes) {\n if (other.id === pb.id) continue\n const obb = getBoxBoundingBox(other)\n\n // La otra caja está justo debajo (su top ≈ nuestra bottom)\n if (Math.abs(obb.maxY - bb.minY) > 2) continue\n\n // Calcular área de solapamiento en XZ\n const overlapX = Math.max(0, Math.min(bb.maxX, obb.maxX) - Math.max(bb.minX, obb.minX))\n const overlapZ = Math.max(0, Math.min(bb.maxZ, obb.maxZ) - Math.max(bb.minZ, obb.minZ))\n supportedArea += overlapX * overlapZ\n }\n\n if (boxArea > 0 && supportedArea / boxArea < MIN_SUPPORT_PERCENTAGE) {\n violations.push({\n code: 'BR-004',\n severity: 'error',\n message: `Caja ${pb.id} sin soporte suficiente (${((supportedArea / boxArea) * 100).toFixed(0)}% < ${MIN_SUPPORT_PERCENTAGE * 100}%)`,\n involvedIds: [pb.id],\n })\n }\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * Stability validation — Centro de gravedad y estabilidad\n * BR-501: Score de estabilidad mínimo\n * BR-502: Centro de gravedad dentro del polígono de soporte\n * BR-503: Altura del centro de gravedad\n */\n\nimport type { Position3D, ValidationResult, Violation } from '../types'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { Pallet } from '../entities/Pallet'\nimport { getBoxBoundingBox } from './collision'\n\n/** Calcula el centro de gravedad de un conjunto de cajas */\nexport function calculateCenterOfGravity(boxes: PlacedBox[]): Position3D {\n if (boxes.length === 0) return { x: 0, y: 0, z: 0 }\n\n let totalWeight = 0\n let cogX = 0, cogY = 0, cogZ = 0\n\n for (const pb of boxes) {\n const bb = getBoxBoundingBox(pb)\n const cx = (bb.minX + bb.maxX) / 2\n const cy = (bb.minY + bb.maxY) / 2\n const cz = (bb.minZ + bb.maxZ) / 2\n const w = pb.box.weight\n\n cogX += cx * w\n cogY += cy * w\n cogZ += cz * w\n totalWeight += w\n }\n\n if (totalWeight === 0) return { x: 0, y: 0, z: 0 }\n\n return {\n x: cogX / totalWeight,\n y: cogY / totalWeight,\n z: cogZ / totalWeight,\n }\n}\n\n/** Calcula el score de estabilidad (0-100) */\nexport function calculateStabilityScore(pallet: Pallet, boxes: PlacedBox[]): number {\n if (boxes.length === 0) return 100\n\n const cog = calculateCenterOfGravity(boxes)\n const centerX = pallet.dimensions.width / 2\n const centerZ = pallet.dimensions.depth / 2\n\n // Distancia normalizada del CoG al centro\n const dx = Math.abs(cog.x - centerX) / (pallet.dimensions.width / 2)\n const dz = Math.abs(cog.z - centerZ) / (pallet.dimensions.depth / 2)\n const horizontalScore = Math.max(0, 100 - (dx + dz) * 50)\n\n // Penalizar CoG alto\n const maxBoxY = boxes.reduce((max, pb) => {\n const bb = getBoxBoundingBox(pb)\n return Math.max(max, bb.maxY)\n }, 0)\n const heightRatio = maxBoxY > 0 ? cog.y / maxBoxY : 0\n const verticalScore = Math.max(0, 100 - Math.max(0, heightRatio - 0.5) * 100)\n\n return Math.round((horizontalScore * 0.7 + verticalScore * 0.3))\n}\n\n/** BR-502: CoG dentro del polígono de soporte (planta del palet) */\nexport function validateCogInsideSupport(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const cog = calculateCenterOfGravity(boxes)\n\n if (cog.x < 0 || cog.x > pallet.dimensions.width || cog.z < 0 || cog.z > pallet.dimensions.depth) {\n violations.push({\n code: 'BR-502',\n severity: 'error',\n message: `Centro de gravedad (${cog.x.toFixed(0)}, ${cog.z.toFixed(0)}) fuera del palet`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n\n/** BR-501 + BR-503: Score de estabilidad y CoG alto */\nexport function validateStability(pallet: Pallet, boxes: PlacedBox[]): ValidationResult {\n const violations: Violation[] = []\n if (boxes.length === 0) return { isValid: true, violations }\n\n const score = calculateStabilityScore(pallet, boxes)\n\n if (score < 50) {\n violations.push({\n code: 'BR-501',\n severity: 'error',\n message: `Score de estabilidad bajo (${score}/100, mínimo: 50)`,\n involvedIds: [pallet.id],\n })\n } else if (score < 70) {\n violations.push({\n code: 'BR-501',\n severity: 'warning',\n message: `Score de estabilidad mejorable (${score}/100, recomendado: ≥70)`,\n involvedIds: [pallet.id],\n })\n }\n\n // BR-503: CoG alto\n const cog = calculateCenterOfGravity(boxes)\n const maxY = boxes.reduce((max, pb) => Math.max(max, getBoxBoundingBox(pb).maxY), 0)\n if (maxY > 0 && cog.y > maxY * 0.6) {\n violations.push({\n code: 'BR-503',\n severity: 'warning',\n message: `Centro de gravedad alto (${cog.y.toFixed(0)}mm, ${((cog.y / maxY) * 100).toFixed(0)}% de la altura)`,\n involvedIds: [pallet.id],\n })\n }\n\n return { isValid: violations.filter(v => v.severity === 'error').length === 0, violations }\n}\n","/**\n * Polygon validation — Point-in-polygon para estancias\n * BR-401: Palet dentro del polígono de la estancia\n */\n\nimport type { Point2D, ValidationResult, Violation } from '../types'\nimport type { PlacedPallet } from '../entities/PlacedPallet'\nimport type { Room } from '../entities/Room'\nimport { getPalletBoundingBox } from './collision'\n\n/**\n * Point-in-polygon test (ray casting algorithm)\n */\nexport function pointInPolygon(point: Point2D, polygon: Point2D[]): boolean {\n let inside = false\n const n = polygon.length\n\n for (let i = 0, j = n - 1; i < n; j = i++) {\n const xi = polygon[i].x, zi = polygon[i].z\n const xj = polygon[j].x, zj = polygon[j].z\n\n if (\n ((zi > point.z) !== (zj > point.z)) &&\n (point.x < (xj - xi) * (point.z - zi) / (zj - zi) + xi)\n ) {\n inside = !inside\n }\n }\n\n return inside\n}\n\n/** BR-401: Valida que un palet está completamente dentro del polígono de la estancia */\nexport function validatePalletInRoom(pallet: PlacedPallet, room: Room): ValidationResult {\n const violations: Violation[] = []\n const bb = getPalletBoundingBox(pallet)\n\n // Test las 4 esquinas de la huella 2D del palet\n const corners: Point2D[] = [\n { x: bb.minX, z: bb.minZ },\n { x: bb.maxX, z: bb.minZ },\n { x: bb.maxX, z: bb.maxZ },\n { x: bb.minX, z: bb.maxZ },\n ]\n\n for (const corner of corners) {\n if (!pointInPolygon(corner, room.floorPolygon)) {\n violations.push({\n code: 'BR-401',\n severity: 'error',\n message: `Palet ${pallet.id} fuera de la estancia ${room.name} en (${corner.x}, ${corner.z})`,\n involvedIds: [pallet.id, room.id],\n })\n break // Una esquina fuera es suficiente\n }\n }\n\n // BR-403: Altura\n if (bb.maxY > room.ceilingHeight) {\n violations.push({\n code: 'BR-403',\n severity: 'error',\n message: `Palet ${pallet.id} excede el techo de la estancia ${room.name}`,\n involvedIds: [pallet.id, room.id],\n })\n }\n\n return { isValid: violations.length === 0, violations }\n}\n","/**\n * ColumnStrategy — Empaquetado en columnas verticales por tipo de caja\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\n\nexport class ColumnStrategy implements PackingStrategy {\n readonly id = 'column'\n readonly name = 'Columnas por tipo'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Agrupar cajas por tipo/SKU\n const groups = new Map<string, Box[]>()\n for (const box of boxes) {\n const key = box.type ?? box.sku ?? 'default'\n if (!groups.has(key)) groups.set(key, [])\n groups.get(key)!.push(box)\n }\n\n let cursorX = 0\n let placementId = 0\n\n for (const [, groupBoxes] of groups) {\n if (groupBoxes.length === 0) continue\n const refBox = groupBoxes[0]\n const colWidth = refBox.dimensions.width\n const colDepth = refBox.dimensions.depth\n const boxHeight = refBox.dimensions.height\n\n // ¿Cabe una nueva columna en X?\n if (cursorX + colWidth > pallet.dimensions.width) {\n unplacedBoxes.push(...groupBoxes)\n continue\n }\n\n let cursorZ = 0\n let cursorY = 0\n let boxIdx = 0\n\n while (boxIdx < groupBoxes.length) {\n const box = groupBoxes[boxIdx]\n\n // ¿Cabe en Z?\n if (cursorZ + colDepth > pallet.dimensions.depth) {\n // Nueva capa vertical\n cursorZ = 0\n cursorY += boxHeight\n if (cursorY + boxHeight > pallet.maxStackHeight) {\n // No cabe más en esta columna\n unplacedBoxes.push(...groupBoxes.slice(boxIdx))\n break\n }\n continue\n }\n\n placements.push({\n id: `placed-${++placementId}`,\n box,\n position: { x: cursorX, y: cursorY, z: cursorZ },\n rotation: { x: 0, y: 0, z: 0 },\n supportedBy: [],\n supporting: [],\n })\n\n cursorZ += colDepth\n boxIdx++\n }\n\n cursorX += colWidth\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n const cog = calculateCenterOfGravity(placements)\n const stability = calculateStabilityScore(pallet, placements)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: cog,\n stabilityScore: stability,\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * BinPacking3D — Optimización volumétrica (First Fit Decreasing Height)\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\nimport { getBoxBoundingBox, aabbIntersects } from '../validation/collision'\n\ninterface Space {\n x: number\n y: number\n z: number\n width: number\n height: number\n depth: number\n}\n\nexport class BinPacking3DStrategy implements PackingStrategy {\n readonly id = 'bin-packing-3d'\n readonly name = 'Bin Packing 3D (FFD Height)'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Ordenar por volumen descendente (First Fit Decreasing)\n const sorted = [...boxes].sort((a, b) => {\n const va = a.dimensions.width * a.dimensions.height * a.dimensions.depth\n const vb = b.dimensions.width * b.dimensions.height * b.dimensions.depth\n return vb - va\n })\n\n // Espacios libres: empezamos con el palet completo\n const spaces: Space[] = [\n {\n x: 0,\n y: 0,\n z: 0,\n width: pallet.dimensions.width,\n height: pallet.maxStackHeight,\n depth: pallet.dimensions.depth,\n },\n ]\n\n let placementId = 0\n\n for (const box of sorted) {\n let placed = false\n\n // Intentar colocar en cada espacio libre\n // Probar orientaciones: normal y rotada 90° en Y\n const orientations = [\n { w: box.dimensions.width, h: box.dimensions.height, d: box.dimensions.depth, rot: 0 as const },\n { w: box.dimensions.depth, h: box.dimensions.height, d: box.dimensions.width, rot: 90 as const },\n ]\n\n for (let si = 0; si < spaces.length && !placed; si++) {\n const space = spaces[si]\n\n for (const ori of orientations) {\n if (ori.w <= space.width && ori.h <= space.height && ori.d <= space.depth) {\n const newPlacement: PlacedBox = {\n id: `placed-${++placementId}`,\n box,\n position: { x: space.x, y: space.y, z: space.z },\n rotation: { x: 0, y: ori.rot, z: 0 },\n supportedBy: [],\n supporting: [],\n }\n\n // Verificar colisiones con colocaciones existentes\n const newBB = getBoxBoundingBox(newPlacement)\n const collides = placements.some(existing =>\n aabbIntersects(getBoxBoundingBox(existing), newBB),\n )\n\n if (!collides) {\n placements.push(newPlacement)\n placed = true\n\n // Subdividir espacio restante (3 nuevos espacios)\n spaces.splice(si, 1)\n\n // Espacio a la derecha\n if (space.width - ori.w > 0) {\n spaces.push({\n x: space.x + ori.w,\n y: space.y,\n z: space.z,\n width: space.width - ori.w,\n height: space.height,\n depth: space.depth,\n })\n }\n // Espacio arriba\n if (space.height - ori.h > 0) {\n spaces.push({\n x: space.x,\n y: space.y + ori.h,\n z: space.z,\n width: ori.w,\n height: space.height - ori.h,\n depth: ori.d,\n })\n }\n // Espacio detrás\n if (space.depth - ori.d > 0) {\n spaces.push({\n x: space.x,\n y: space.y,\n z: space.z + ori.d,\n width: ori.w,\n height: space.height,\n depth: space.depth - ori.d,\n })\n }\n\n // Ordenar espacios por posición (preferir abajo, izquierda, delante)\n spaces.sort((a, b) => a.y - b.y || a.x - b.x || a.z - b.z)\n break\n }\n }\n }\n }\n\n if (!placed) {\n unplacedBoxes.push(box)\n }\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: calculateCenterOfGravity(placements),\n stabilityScore: calculateStabilityScore(pallet, placements),\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * TypeGroupStrategy — Agrupación por tipo, relleno capa a capa\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Pallet } from '../entities/Pallet'\nimport type { PlacedBox } from '../entities/PlacedBox'\nimport type { PackingStrategy, PackingResult } from './PackingStrategy'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '../validation/stability'\n\nexport class TypeGroupStrategy implements PackingStrategy {\n readonly id = 'type-group'\n readonly name = 'Agrupación por tipo'\n\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n const placements: PlacedBox[] = []\n const unplacedBoxes: Box[] = []\n\n // Ordenar por tipo, y dentro de tipo por peso desc (frágiles al final/arriba)\n const sorted = [...boxes].sort((a, b) => {\n const typeA = a.type ?? a.sku ?? 'z'\n const typeB = b.type ?? b.sku ?? 'z'\n if (typeA !== typeB) return typeA.localeCompare(typeB)\n // Frágiles después (irán arriba)\n if (a.fragile !== b.fragile) return a.fragile ? 1 : -1\n return b.weight - a.weight\n })\n\n let cursorX = 0\n let cursorZ = 0\n let cursorY = 0\n let layerMaxHeight = 0\n let placementId = 0\n\n for (const box of sorted) {\n const w = box.dimensions.width\n const h = box.dimensions.height\n const d = box.dimensions.depth\n\n // ¿Cabe en X?\n if (cursorX + w > pallet.dimensions.width) {\n cursorX = 0\n cursorZ += layerMaxHeight > 0 ? d : 0\n // Use previous depth if available\n }\n\n // ¿Cabe en Z?\n if (cursorZ + d > pallet.dimensions.depth) {\n // Nueva capa vertical\n cursorX = 0\n cursorZ = 0\n cursorY += layerMaxHeight\n layerMaxHeight = 0\n }\n\n // ¿Cabe en Y?\n if (cursorY + h > pallet.maxStackHeight) {\n unplacedBoxes.push(box)\n continue\n }\n\n // ¿Cabe en X después del reset?\n if (cursorX + w > pallet.dimensions.width) {\n unplacedBoxes.push(box)\n continue\n }\n\n if (cursorZ + d > pallet.dimensions.depth) {\n unplacedBoxes.push(box)\n continue\n }\n\n placements.push({\n id: `placed-${++placementId}`,\n box,\n position: { x: cursorX, y: cursorY, z: cursorZ },\n rotation: { x: 0, y: 0, z: 0 },\n supportedBy: [],\n supporting: [],\n })\n\n cursorX += w\n layerMaxHeight = Math.max(layerMaxHeight, h)\n }\n\n // Métricas\n const palletVolume = pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth\n const usedVolume = placements.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n const totalWeight = placements.reduce((s, pb) => s + pb.box.weight, 0)\n\n return {\n placements,\n metrics: {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization: pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: calculateCenterOfGravity(placements),\n stabilityScore: calculateStabilityScore(pallet, placements),\n },\n unplacedBoxes,\n }\n }\n}\n","/**\n * MaterialGroupingStrategy — Layer-based packing with material weight ordering and product grouping\n *\n * This strategy combines multiple algorithms to create stable, well-organized pallets:\n * - Multi-criteria sorting (material resistance → product grouping → dimensions)\n * - Layer-based construction (horizontal layers from bottom to top)\n * - Maximal Rectangles algorithm for 2D bin packing per layer\n * - Product column grouping (same product in vertical columns for easy picking)\n *\n * ## Algorithm Overview\n *\n * 1. **Pre-processing**: Sort boxes by materialWeight (desc) → product → area (desc)\n * 2. **Layer Construction**: Build horizontal layers from bottom to top\n * - Prioritize uniform height layers with 100% coverage\n * - Allow mixed heights if necessary to fill space\n * - Maintain product grouping in vertical columns\n * 3. **2D Packing**: Use Maximal Rectangles for each layer\n * 4. **Scoring**: Prioritize positions that continue product columns\n *\n * ## Material Weight System\n *\n * Boxes with higher `materialWeight` are more resistant and placed lower:\n * - materialWeight: 10 → Maximum resistance → Bottom layers\n * - materialWeight: 5 → Medium resistance → Middle layers\n * - materialWeight: 0 → Fragile → Top layers\n *\n * ## Product Grouping\n *\n * Boxes with the same `product` value are grouped in vertical columns.\n * This facilitates picking: all boxes of Product A can be extracted as a column.\n *\n * @example\n * ```typescript\n * const strategy = new MaterialGroupingStrategy()\n * const boxes = [\n * BoxFactory.create({ width: 600, height: 400, depth: 400 }, {\n * product: 'PROD-A',\n * materialWeight: 6\n * }),\n * BoxFactory.create({ width: 600, height: 400, depth: 400 }, {\n * product: 'PROD-B',\n * materialWeight: 0\n * }),\n * ]\n * const pallet = PalletFactory.euro()\n * const result = strategy.pack(boxes, pallet)\n * // Result: PROD-A on bottom (materialWeight=6), PROD-B on top (materialWeight=0)\n * ```\n */\n\nimport type { Box } from \"../entities/Box\";\nimport type { Pallet } from \"../entities/Pallet\";\nimport type { PlacedBox } from \"../entities/PlacedBox\";\nimport type { PackingStrategy, PackingResult } from \"./PackingStrategy\";\nimport {\n calculateCenterOfGravity,\n calculateStabilityScore,\n} from \"../validation/stability\";\n\n// ─── Auxiliary Interfaces ────────────────────────────────────────────\n\n/**\n * Represents a horizontal layer in the pallet\n */\ninterface Layer {\n /** Vertical position (Y coordinate) where this layer starts */\n y: number;\n /** Height of this layer (max height of boxes in it) */\n height: number;\n /** Boxes placed in this layer */\n placements: PlacedBox[];\n /** Coverage percentage of pallet area (0-100) */\n coverage: number;\n}\n\n/**\n * Represents a free rectangular space where a box can be placed\n * Used by the Maximal Rectangles algorithm\n */\ninterface Rectangle {\n /** X coordinate of bottom-left corner */\n x: number;\n /** Z coordinate of bottom-left corner */\n z: number;\n /** Width of the rectangle */\n width: number;\n /** Depth of the rectangle */\n depth: number;\n}\n\n/**\n * Box orientation (rotation around Y axis)\n */\ninterface Orientation {\n /** Effective width after rotation */\n width: number;\n /** Effective depth after rotation */\n depth: number;\n /** Rotation angle in degrees (0 or 90) */\n rotation: 0 | 90;\n}\n\n// ─── MaterialGroupingStrategy ────────────────────────────────────────\n\nexport class MaterialGroupingStrategy implements PackingStrategy {\n readonly id = \"material-grouping\";\n readonly name = \"Material & Product Grouping\";\n\n /**\n * Packs boxes into a pallet using layer-based approach with material ordering\n *\n * @param boxes - Boxes to pack\n * @param pallet - Target pallet\n * @returns Packing result with placements and metrics\n */\n pack(boxes: Box[], pallet: Pallet): PackingResult {\n if (boxes.length === 0) {\n return this.emptyResult();\n }\n\n // Phase 1: Sort boxes by material weight, product, and dimensions\n const sortedBoxes = this.sortBoxes(boxes);\n\n // Phase 2: Group by material weight\n const materialGroups = this.groupByMaterialWeight(sortedBoxes);\n\n // Phase 3: Build layers from bottom to top\n const layers = this.buildLayers(materialGroups, pallet);\n\n // Phase 4: Convert layers to placements\n const placements = layers.flatMap((layer) => layer.placements);\n\n // Phase 5: Calculate metrics\n const unplacedBoxes = boxes.filter(\n (box) => !placements.some((p) => p.box.id === box.id),\n );\n\n const metrics = this.calculateMetrics(placements, pallet);\n\n return {\n placements,\n metrics,\n unplacedBoxes,\n };\n }\n\n // ─── Phase 1: Sorting ──────────────────────────────────────────────\n\n /**\n * Sorts boxes by multiple criteria:\n * 1. Material weight (descending) - more resistant boxes first\n * 2. Product (alphabetical) - group same products together\n * 3. Base area (descending) - larger boxes first for stable base\n * 4. Height (descending) - taller boxes first for better layer filling\n *\n * @param boxes - Boxes to sort\n * @returns Sorted boxes array\n */\n private sortBoxes(boxes: Box[]): Box[] {\n return [...boxes].sort((a, b) => {\n // 1. Material weight (descending) - more resistant = lower in pallet\n const weightA = a.materialWeight ?? 5;\n const weightB = b.materialWeight ?? 5;\n if (weightA !== weightB) {\n return weightB - weightA;\n }\n\n // 2. Product (alphabetical grouping)\n const productA = a.product ?? \"\";\n const productB = b.product ?? \"\";\n if (productA !== productB) {\n return productA.localeCompare(productB);\n }\n\n // 3. Base area (descending) - larger boxes first\n const areaA = a.dimensions.width * a.dimensions.depth;\n const areaB = b.dimensions.width * b.dimensions.depth;\n if (areaA !== areaB) {\n return areaB - areaA;\n }\n\n // 4. Height (descending) - taller boxes first\n return b.dimensions.height - a.dimensions.height;\n });\n }\n\n /**\n * Groups boxes by material weight for layer construction\n *\n * @param boxes - Sorted boxes\n * @returns Map of material weight → boxes with that weight\n */\n private groupByMaterialWeight(boxes: Box[]): Map<number, Box[]> {\n const groups = new Map<number, Box[]>();\n\n for (const box of boxes) {\n const weight = box.materialWeight ?? 5;\n if (!groups.has(weight)) {\n groups.set(weight, []);\n }\n groups.get(weight)!.push(box);\n }\n\n // Sort groups by material weight (descending)\n return new Map([...groups.entries()].sort((a, b) => b[0] - a[0]));\n }\n\n // ─── Phase 2: Layer Construction ──────────────────────────────────\n\n /**\n * Builds layers from bottom to top, processing each material weight group\n *\n * @param materialGroups - Boxes grouped by material weight\n * @param pallet - Target pallet\n * @returns Array of layers\n */\n private buildLayers(\n materialGroups: Map<number, Box[]>,\n pallet: Pallet,\n ): Layer[] {\n const layers: Layer[] = [];\n const occupiedColumns = new Map<string, string>(); // \"x,z\" → product\n const allPlacements: PlacedBox[] = []; // All placements from all layers\n let currentY = 0;\n\n // Process each material group (from highest weight to lowest)\n for (const [, boxes] of materialGroups) {\n let remainingBoxes = [...boxes];\n\n // Build layers until all boxes of this material are placed\n while (remainingBoxes.length > 0) {\n const layer = this.buildNextLayer(\n remainingBoxes,\n pallet,\n currentY,\n occupiedColumns,\n allPlacements,\n );\n\n if (layer.placements.length === 0) {\n // No boxes could be placed, stop trying\n break;\n }\n\n layers.push(layer);\n allPlacements.push(...layer.placements); // Add new placements to history\n currentY += layer.height;\n\n // Remove placed boxes from remaining\n const placedIds = new Set(layer.placements.map((p) => p.box.id));\n remainingBoxes = remainingBoxes.filter((b) => !placedIds.has(b.id));\n\n // Check if we exceeded pallet height\n if (currentY >= pallet.maxStackHeight) {\n break;\n }\n }\n }\n\n return layers;\n }\n\n /**\n * Builds the next layer using available boxes\n *\n * Strategy:\n * 1. Try uniform height layer with 100% coverage\n * 2. If not possible, try mixed height layer\n * 3. If still not possible, use partial coverage (last resort)\n *\n * @param availableBoxes - Boxes available for this layer\n * @param pallet - Target pallet\n * @param currentY - Current vertical position\n * @param occupiedColumns - Track which (x,z) positions have which product\n * @param allPreviousPlacements - All placements from previous layers (for support calculation)\n * @returns Constructed layer\n */\n private buildNextLayer(\n availableBoxes: Box[],\n pallet: Pallet,\n currentY: number,\n occupiedColumns: Map<string, string>,\n allPreviousPlacements: PlacedBox[],\n ): Layer {\n // Strategy 1: Uniform height layer\n const uniformLayer = this.tryUniformHeightLayer(\n availableBoxes,\n pallet,\n currentY,\n occupiedColumns,\n allPreviousPlacements,\n );\n\n if (uniformLayer && uniformLayer.coverage >= 95) {\n return uniformLayer;\n }\n\n // Strategy 2: Mixed height layer (fallback)\n const mixedLayer = this.tryMixedHeightLayer(\n availableBoxes,\n pallet,\n currentY,\n occupiedColumns,\n allPreviousPlacements,\n );\n\n if (mixedLayer && mixedLayer.coverage >= 95) {\n return mixedLayer;\n }\n\n // Strategy 3: Use best available (even if partial coverage)\n const bestLayer =\n (uniformLayer?.coverage ?? 0) > (mixedLayer?.coverage ?? 0)\n ? uniformLayer\n : mixedLayer;\n\n return bestLayer ?? this.emptyLayer(currentY);\n }\n\n /**\n * Attempts to create a layer with boxes of uniform height\n *\n * @param boxes - Available boxes\n * @param pallet - Target pallet\n * @param currentY - Current vertical position\n * @param occupiedColumns - Occupied column tracker\n * @param allPreviousPlacements - All placements from previous layers\n * @returns Layer or null if not possible\n */\n private tryUniformHeightLayer(\n boxes: Box[],\n pallet: Pallet,\n currentY: number,\n occupiedColumns: Map<string, string>,\n allPreviousPlacements: PlacedBox[],\n ): Layer | null {\n // Group boxes by height\n const heightGroups = new Map<number, Box[]>();\n for (const box of boxes) {\n const h = box.dimensions.height;\n if (!heightGroups.has(h)) {\n heightGroups.set(h, []);\n }\n heightGroups.get(h)!.push(box);\n }\n\n // Try each height group, starting with most common\n const sortedHeights = [...heightGroups.entries()].sort(\n (a, b) => b[1].length - a[1].length,\n );\n\n for (const [height, boxesOfHeight] of sortedHeights) {\n // Check if layer would exceed pallet height\n if (currentY + height > pallet.maxStackHeight) {\n continue;\n }\n\n const layer = this.placeBoxesInLayer(\n boxesOfHeight,\n pallet,\n currentY,\n height,\n occupiedColumns,\n allPreviousPlacements,\n );\n\n if (layer.coverage >= 95) {\n return layer;\n }\n }\n\n return null;\n }\n\n /**\n * Attempts to create a layer with boxes of mixed heights\n *\n * @param boxes - Available boxes\n * @param pallet - Target pallet\n * @param currentY - Current vertical position\n * @param occupiedColumns - Occupied column tracker\n * @param allPreviousPlacements - All placements from previous layers\n * @returns Layer or null if not possible\n */\n private tryMixedHeightLayer(\n boxes: Box[],\n pallet: Pallet,\n currentY: number,\n occupiedColumns: Map<string, string>,\n allPreviousPlacements: PlacedBox[],\n ): Layer | null {\n // Allow any height (no filtering)\n return this.placeBoxesInLayer(\n boxes,\n pallet,\n currentY,\n null,\n occupiedColumns,\n allPreviousPlacements,\n );\n }\n\n // ─── Phase 3: Maximal Rectangles 2D Packing ───────────────────────\n\n /**\n * Places boxes in a layer using Maximal Rectangles algorithm\n *\n * @param boxes - Boxes to place\n * @param pallet - Target pallet\n * @param currentY - Y coordinate of this layer\n * @param targetHeight - If specified, only use boxes of this height\n * @param occupiedColumns - Track product columns\n * @param allPreviousPlacements - All placements from previous layers (for support calculation)\n * @returns Constructed layer\n */\n private placeBoxesInLayer(\n boxes: Box[],\n pallet: Pallet,\n currentY: number,\n targetHeight: number | null,\n occupiedColumns: Map<string, string>,\n allPreviousPlacements: PlacedBox[],\n ): Layer {\n // Initialize with full pallet as single free rectangle\n const freeRectangles: Rectangle[] = [\n {\n x: 0,\n z: 0,\n width: pallet.dimensions.width,\n depth: pallet.dimensions.depth,\n },\n ];\n\n const placements: PlacedBox[] = [];\n\n // Group boxes by product for grouping priority\n const productGroups = this.groupByProduct(boxes);\n\n // Sort product groups by count (more boxes = higher priority)\n const sortedGroups = [...productGroups.entries()].sort(\n (a, b) => b[1].length - a[1].length,\n );\n\n let placementId = 0;\n\n // For each product group\n for (const [product, productBoxes] of sortedGroups) {\n // Filter by target height if specified\n const validBoxes = targetHeight\n ? productBoxes.filter((b) => b.dimensions.height === targetHeight)\n : productBoxes;\n\n // Try to place each box\n for (const box of validBoxes) {\n // Check if layer would exceed pallet height\n if (currentY + box.dimensions.height > pallet.maxStackHeight) {\n continue;\n }\n\n // Try both orientations (0° and 90°)\n const orientations: Orientation[] = [\n {\n width: box.dimensions.width,\n depth: box.dimensions.depth,\n rotation: 0,\n },\n {\n width: box.dimensions.depth,\n depth: box.dimensions.width,\n rotation: 90,\n },\n ];\n\n for (const orientation of orientations) {\n // Combine previous placements with current layer placements for support calculation\n const allPlacementsForSupport = [\n ...allPreviousPlacements,\n ...placements,\n ];\n\n const bestRect = this.findBestRectangle(\n orientation,\n freeRectangles,\n occupiedColumns,\n product,\n currentY,\n allPlacementsForSupport,\n );\n\n if (bestRect) {\n // Place the box\n const placement: PlacedBox = {\n id: `placed-${++placementId}`,\n box,\n position: { x: bestRect.x, y: currentY, z: bestRect.z },\n rotation: { x: 0, y: orientation.rotation, z: 0 },\n supportedBy: [],\n supporting: [],\n };\n\n placements.push(placement);\n\n // Update occupied columns\n this.updateOccupiedColumns(\n occupiedColumns,\n bestRect.x,\n bestRect.z,\n product,\n );\n\n // Update free rectangles (Maximal Rectangles algorithm)\n this.updateFreeRectangles(\n freeRectangles,\n bestRect,\n orientation.width,\n orientation.depth,\n );\n\n break; // Box placed, try next box\n }\n }\n }\n }\n\n // Calculate layer metrics\n const palletArea = pallet.dimensions.width * pallet.dimensions.depth;\n const usedArea = placements.reduce((sum, p) => {\n const w =\n p.rotation.y === 90 ? p.box.dimensions.depth : p.box.dimensions.width;\n const d =\n p.rotation.y === 90 ? p.box.dimensions.width : p.box.dimensions.depth;\n return sum + w * d;\n }, 0);\n\n const maxHeight =\n placements.length > 0\n ? Math.max(...placements.map((p) => p.box.dimensions.height))\n : 0;\n\n return {\n y: currentY,\n height: maxHeight,\n placements,\n coverage: (usedArea / palletArea) * 100,\n };\n }\n\n /**\n * Finds the best free rectangle for a box using scoring\n *\n * @param boxDims - Box dimensions (with rotation applied)\n * @param freeRectangles - Available free spaces\n * @param occupiedColumns - Product column tracker\n * @param product - Product identifier\n * @param currentY - Current layer Y position\n * @param existingPlacements - Already placed boxes in this layer and below\n * @param pallet - Pallet dimensions\n * @returns Best rectangle or null if none fit\n */\n private findBestRectangle(\n boxDims: Orientation,\n freeRectangles: Rectangle[],\n occupiedColumns: Map<string, string>,\n product: string,\n currentY: number,\n existingPlacements: PlacedBox[],\n ): Rectangle | null {\n let bestRect: Rectangle | null = null;\n let bestScore = -Infinity;\n\n for (const rect of freeRectangles) {\n // Check if box fits\n if (boxDims.width <= rect.width && boxDims.depth <= rect.depth) {\n // Validate support\n const supportArea = this.calculateSupportArea(\n rect.x,\n rect.z,\n boxDims.width,\n boxDims.depth,\n currentY,\n existingPlacements,\n );\n\n const boxBaseArea = boxDims.width * boxDims.depth;\n const supportPercentage = supportArea / boxBaseArea;\n\n // Require at least 70% support (unless on ground level which returns 100%)\n if (supportPercentage < 0.7) {\n continue; // Skip this position - insufficient support\n }\n\n // Check if box would extend beyond the lower layer footprint\n // This ensures we always use the lower layer as a base and don't stack\n // boxes that hang over edges when space is available in the lower layer\n if (\n this.boxExtendsBeyondLowerLayer(\n rect.x,\n rect.z,\n boxDims.width,\n boxDims.depth,\n currentY,\n existingPlacements,\n )\n ) {\n continue; // Skip this position - extends beyond lower layer\n }\n\n const score = this.scoreRectangle(\n rect,\n boxDims,\n occupiedColumns,\n product,\n );\n\n if (score > bestScore) {\n bestScore = score;\n bestRect = rect;\n }\n }\n }\n\n return bestRect;\n }\n\n /**\n * Calculates the area of support a box would have at a given position\n *\n * @param x - X position of box\n * @param z - Z position of box\n * @param width - Width of box\n * @param depth - Depth of box\n * @param currentY - Y position where box will be placed\n * @param existingPlacements - Boxes already placed in current and previous layers\n * @param pallet - Pallet dimensions\n * @returns Supported area in mm²\n */\n private calculateSupportArea(\n x: number,\n z: number,\n width: number,\n depth: number,\n currentY: number,\n existingPlacements: PlacedBox[],\n ): number {\n let supportedArea = 0;\n\n // If on ground level (Y=0), full support from pallet\n if (currentY === 0) {\n return width * depth;\n }\n\n // Calculate intersection with boxes in layers below\n for (const placement of existingPlacements) {\n const boxW =\n placement.rotation.y === 90\n ? placement.box.dimensions.depth\n : placement.box.dimensions.width;\n const boxD =\n placement.rotation.y === 90\n ? placement.box.dimensions.width\n : placement.box.dimensions.depth;\n\n const boxTop = placement.position.y + placement.box.dimensions.height;\n\n // Only consider boxes whose top surface is at currentY (directly below)\n // Allow small tolerance for floating point errors\n const tolerance = 1; // 1mm tolerance\n if (Math.abs(boxTop - currentY) > tolerance) {\n continue; // Not directly below\n }\n\n const intersection = this.calculateRectangleIntersection(\n x,\n z,\n width,\n depth,\n placement.position.x,\n placement.position.z,\n boxW,\n boxD,\n );\n supportedArea += intersection;\n }\n\n return supportedArea;\n }\n\n /**\n * Calculates intersection area between two rectangles\n *\n * @returns Intersection area in mm²\n */\n private calculateRectangleIntersection(\n x1: number,\n z1: number,\n w1: number,\n d1: number,\n x2: number,\n z2: number,\n w2: number,\n d2: number,\n ): number {\n const overlapX = Math.max(0, Math.min(x1 + w1, x2 + w2) - Math.max(x1, x2));\n const overlapZ = Math.max(0, Math.min(z1 + d1, z2 + d2) - Math.max(z1, z2));\n\n return overlapX * overlapZ;\n }\n\n /**\n * Checks if a box would extend beyond the footprint of boxes in the layer directly below\n *\n * This ensures that boxes in upper layers are always stacked on top of lower boxes,\n * preventing boxes from \"hanging\" over edges when there's available space in the lower layer.\n *\n * @param x - X position of box\n * @param z - Z position of box\n * @param width - Width of box\n * @param depth - Depth of box\n * @param currentY - Y position where box will be placed\n * @param existingPlacements - Boxes already placed in current and previous layers\n * @returns true if box extends beyond lower layer footprint\n */\n private boxExtendsBeyondLowerLayer(\n x: number,\n z: number,\n width: number,\n depth: number,\n currentY: number,\n existingPlacements: PlacedBox[],\n ): boolean {\n // Ground level - no issue\n if (currentY === 0) {\n return false;\n }\n\n // Find all boxes in the layer directly below\n const boxesDirectlyBelow = existingPlacements.filter((p) => {\n const boxTop = p.position.y + p.box.dimensions.height;\n const tolerance = 1; // 1mm tolerance\n return Math.abs(boxTop - currentY) <= tolerance;\n });\n\n // No boxes below - this shouldn't happen if support was validated\n if (boxesDirectlyBelow.length === 0) {\n return true; // Reject - no base to stack on\n }\n\n // Calculate the bounding box of all boxes in the layer directly below\n let minX = Infinity;\n let maxX = -Infinity;\n let minZ = Infinity;\n let maxZ = -Infinity;\n\n for (const p of boxesDirectlyBelow) {\n const boxW =\n p.rotation.y === 90 ? p.box.dimensions.depth : p.box.dimensions.width;\n const boxD =\n p.rotation.y === 90 ? p.box.dimensions.width : p.box.dimensions.depth;\n\n minX = Math.min(minX, p.position.x);\n maxX = Math.max(maxX, p.position.x + boxW);\n minZ = Math.min(minZ, p.position.z);\n maxZ = Math.max(maxZ, p.position.z + boxD);\n }\n\n // Check if our box would extend beyond this bounding box\n const boxRight = x + width;\n const boxBack = z + depth;\n const tolerance = 1; // 1mm tolerance\n\n const extendsBeyond =\n x < minX - tolerance ||\n boxRight > maxX + tolerance ||\n z < minZ - tolerance ||\n boxBack > maxZ + tolerance;\n\n return extendsBeyond;\n }\n\n /**\n * Scores a rectangle position based on multiple criteria\n *\n * Higher score = better position\n *\n * @param rect - Free rectangle\n * @param boxDims - Box dimensions\n * @param occupiedColumns - Product column tracker\n * @param product - Product identifier\n * @returns Score value\n */\n private scoreRectangle(\n rect: Rectangle,\n boxDims: Orientation,\n occupiedColumns: Map<string, string>,\n product: string,\n ): number {\n let score = 0;\n\n const columnKey = `${rect.x},${rect.z}`;\n\n // +100: Column continuation (same product in vertical column)\n if (occupiedColumns.get(columnKey) === product) {\n score += 100;\n }\n\n // -50: Column mixing (different product in same column)\n if (\n occupiedColumns.has(columnKey) &&\n occupiedColumns.get(columnKey) !== product\n ) {\n score -= 50;\n }\n\n // +50: Best fit (minimize wasted area)\n const wastedArea = rect.width * rect.depth - boxDims.width * boxDims.depth;\n score += 50 / (1 + wastedArea / 10000);\n\n // +30: Bottom-left preference (more stable)\n score += 30 / (1 + rect.x / 1000 + rect.z / 1000);\n\n return score;\n }\n\n /**\n * Updates free rectangles after placing a box (Maximal Rectangles algorithm)\n *\n * @param freeRects - Current free rectangles\n * @param usedRect - Rectangle being used by the new box\n * @param boxWidth - Width of placed box\n * @param boxDepth - Depth of placed box\n */\n private updateFreeRectangles(\n freeRects: Rectangle[],\n usedRect: Rectangle,\n boxWidth: number,\n boxDepth: number,\n ): void {\n const newRects: Rectangle[] = [];\n\n for (let i = freeRects.length - 1; i >= 0; i--) {\n const rect = freeRects[i];\n\n // Check if this rectangle intersects with the placed box\n if (this.rectanglesIntersect(rect, usedRect, boxWidth, boxDepth)) {\n // Remove this rectangle\n freeRects.splice(i, 1);\n\n // Generate new rectangles from the split\n\n // Left rectangle\n if (usedRect.x > rect.x) {\n newRects.push({\n x: rect.x,\n z: rect.z,\n width: usedRect.x - rect.x,\n depth: rect.depth,\n });\n }\n\n // Right rectangle\n if (usedRect.x + boxWidth < rect.x + rect.width) {\n newRects.push({\n x: usedRect.x + boxWidth,\n z: rect.z,\n width: rect.x + rect.width - (usedRect.x + boxWidth),\n depth: rect.depth,\n });\n }\n\n // Top rectangle\n if (usedRect.z > rect.z) {\n newRects.push({\n x: rect.x,\n z: rect.z,\n width: rect.width,\n depth: usedRect.z - rect.z,\n });\n }\n\n // Bottom rectangle\n if (usedRect.z + boxDepth < rect.z + rect.depth) {\n newRects.push({\n x: rect.x,\n z: usedRect.z + boxDepth,\n width: rect.width,\n depth: rect.z + rect.depth - (usedRect.z + boxDepth),\n });\n }\n }\n }\n\n // Add new rectangles\n freeRects.push(...newRects);\n\n // Remove rectangles that are contained within others (optimization)\n this.removeContainedRectangles(freeRects);\n }\n\n /**\n * Checks if two rectangles intersect\n */\n private rectanglesIntersect(\n rect: Rectangle,\n usedRect: Rectangle,\n boxWidth: number,\n boxDepth: number,\n ): boolean {\n return !(\n usedRect.x + boxWidth <= rect.x ||\n usedRect.x >= rect.x + rect.width ||\n usedRect.z + boxDepth <= rect.z ||\n usedRect.z >= rect.z + rect.depth\n );\n }\n\n /**\n * Removes rectangles that are fully contained within other rectangles\n */\n private removeContainedRectangles(rectangles: Rectangle[]): void {\n for (let i = rectangles.length - 1; i >= 0; i--) {\n const rect = rectangles[i];\n\n for (let j = 0; j < rectangles.length; j++) {\n if (i === j) continue;\n\n const other = rectangles[j];\n\n // Check if rect is contained in other\n if (\n rect.x >= other.x &&\n rect.z >= other.z &&\n rect.x + rect.width <= other.x + other.width &&\n rect.z + rect.depth <= other.z + other.depth\n ) {\n rectangles.splice(i, 1);\n break;\n }\n }\n }\n }\n\n /**\n * Updates the occupied columns map after placing a box\n */\n private updateOccupiedColumns(\n occupiedColumns: Map<string, string>,\n x: number,\n z: number,\n product: string,\n ): void {\n // Mark this position as occupied by this product\n const columnKey = `${x},${z}`;\n if (!occupiedColumns.has(columnKey)) {\n occupiedColumns.set(columnKey, product);\n }\n }\n\n // ─── Utility Methods ───────────────────────────────────────────────\n\n /**\n * Groups boxes by product identifier\n */\n private groupByProduct(boxes: Box[]): Map<string, Box[]> {\n const groups = new Map<string, Box[]>();\n\n for (const box of boxes) {\n const product = box.product ?? \"default\";\n if (!groups.has(product)) {\n groups.set(product, []);\n }\n groups.get(product)!.push(box);\n }\n\n return groups;\n }\n\n /**\n * Creates an empty layer\n */\n private emptyLayer(y: number): Layer {\n return {\n y,\n height: 0,\n placements: [],\n coverage: 0,\n };\n }\n\n /**\n * Creates an empty packing result\n */\n private emptyResult(): PackingResult {\n return {\n placements: [],\n metrics: {\n volumeUtilization: 0,\n weightUtilization: 0,\n centerOfGravity: { x: 0, y: 0, z: 0 },\n stabilityScore: 100,\n },\n unplacedBoxes: [],\n };\n }\n\n /**\n * Calculates packing metrics\n */\n private calculateMetrics(placements: PlacedBox[], pallet: Pallet) {\n const palletVolume =\n pallet.dimensions.width * pallet.maxStackHeight * pallet.dimensions.depth;\n\n const usedVolume = placements.reduce((sum, p) => {\n const d = p.box.dimensions;\n return sum + d.width * d.height * d.depth;\n }, 0);\n\n const totalWeight = placements.reduce((sum, p) => sum + p.box.weight, 0);\n\n return {\n volumeUtilization: palletVolume > 0 ? usedVolume / palletVolume : 0,\n weightUtilization:\n pallet.maxWeight > 0 ? totalWeight / pallet.maxWeight : 0,\n centerOfGravity: calculateCenterOfGravity(placements),\n stabilityScore: calculateStabilityScore(pallet, placements),\n };\n }\n}\n","/**\n * PackingRegistry — Registry for packing strategies\n *\n * Maintains a collection of available packing strategies and provides\n * methods to register, retrieve, and list them.\n */\n\nimport type { PackingStrategy } from './PackingStrategy'\nimport { ColumnStrategy } from './ColumnStrategy'\nimport { BinPacking3DStrategy } from './BinPacking3D'\nimport { TypeGroupStrategy } from './TypeGroupStrategy'\nimport { MaterialGroupingStrategy } from './MaterialGroupingStrategy'\n\nexport class PackingRegistry {\n private strategies = new Map<string, PackingStrategy>()\n\n constructor() {\n // Register built-in strategies\n this.register(new ColumnStrategy())\n this.register(new BinPacking3DStrategy())\n this.register(new TypeGroupStrategy())\n this.register(new MaterialGroupingStrategy())\n }\n\n register(strategy: PackingStrategy): void {\n this.strategies.set(strategy.id, strategy)\n }\n\n get(id: string): PackingStrategy {\n const strategy = this.strategies.get(id)\n if (!strategy) {\n throw new Error(`Packing strategy \"${id}\" not found. Available: ${this.listIds().join(', ')}`)\n }\n return strategy\n }\n\n list(): PackingStrategy[] {\n return Array.from(this.strategies.values())\n }\n\n listIds(): string[] {\n return Array.from(this.strategies.keys())\n }\n\n has(id: string): boolean {\n return this.strategies.has(id)\n }\n}\n\n/** Instancia global del registro (singleton de conveniencia) */\nexport const defaultRegistry = new PackingRegistry()\n","/**\n * PalletFactory — Factories para crear palets estándar y custom\n * \n * Proporciona métodos para instanciar los principales tipos de palets\n * utilizados en logística internacional (EUR, GMA, UK, Asia, etc.)\n */\n\nimport type { Pallet } from '../entities/Pallet'\nimport type { Dimensions3D } from '../types'\nimport { PalletMaterial } from '../types'\nimport { STANDARD_PALLETS } from '../constants'\n\nlet _palletCounter = 0\n\nfunction nextPalletId(): string {\n return `pallet-${++_palletCounter}`\n}\n\nexport class PalletFactory {\n // ═══ Palets estándar internacionales ═══════════════════════════\n\n /** Palet EUR/EPAL — Estándar europeo (1200×800×144mm, ISO 6780, madera, 1000kg) */\n static euro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('EUR', overrides)\n }\n\n /** Palet GMA — Estándar norteamericano (1219×1016×145mm, 48\"×40\", madera, 1200kg) */\n static gma(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('GMA', overrides)\n }\n\n /** @deprecated Use gma() instead. Alias para compatibilidad. */\n static american(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.gma(overrides)\n }\n\n /** Palet UK Standard — Reino Unido (1200×1000×150mm, madera, 1000kg) */\n static uk(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('UK', overrides)\n }\n\n /** Palet Asia — Estándar asiático (1100×1100×150mm, ISO 6780, madera, 1000kg) */\n static asia(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ASIA', overrides)\n }\n\n /** Palet australiano — Estándar de Australia (1165×1165×150mm, madera, 1000kg) */\n static australian(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('AUSTRALIAN', overrides)\n }\n\n /** Medio palet EUR — Half European Pallet (800×600×144mm, madera, 500kg) */\n static halfEuro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('HALF_EUR', overrides)\n }\n\n /** Cuarto de palet EUR — Quarter European Pallet (600×400×144mm, madera, 250kg) */\n static quarterEuro(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('QUARTER_EUR', overrides)\n }\n\n /** Palet ISO 1 — ISO 6780 (1200×1000×150mm, igual que UK) */\n static iso1(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ISO_1', overrides)\n }\n\n /** Palet ISO 2 — ISO 6780 (1200×800×144mm, equivalente a EUR) */\n static iso2(overrides?: Partial<Pallet>): Pallet {\n return PalletFactory.fromPreset('ISO_2', overrides)\n }\n\n // ═══ Método genérico desde preset ═════════════════════════════\n\n /**\n * Crea un palet desde un preset por su clave\n * @param presetKey - Clave del preset (EUR, GMA, UK, ASIA, etc.)\n * @param overrides - Propiedades a sobrescribir\n */\n static fromPreset(\n presetKey: keyof typeof STANDARD_PALLETS,\n overrides?: Partial<Pallet>,\n ): Pallet {\n const preset = STANDARD_PALLETS[presetKey]\n if (!preset) {\n throw new Error(`Unknown pallet preset: ${presetKey}`)\n }\n return {\n id: nextPalletId(),\n dimensions: { ...preset.dimensions },\n material: preset.material,\n maxWeight: preset.maxWeight,\n maxStackHeight: preset.maxStackHeight,\n weight: preset.weight,\n metadata: { preset: presetKey },\n ...overrides,\n }\n }\n\n // ═══ Palet custom ══════════════════════════════════════════════\n\n /** Palet custom con dimensiones arbitrarias */\n static custom(dims: Dimensions3D, opts?: Partial<Pallet>): Pallet {\n return {\n id: nextPalletId(),\n dimensions: { ...dims },\n material: PalletMaterial.WOOD,\n maxWeight: 1000,\n maxStackHeight: 2200,\n weight: 25,\n metadata: {},\n ...opts,\n }\n }\n\n // ═══ Utilidades ════════════════════════════════════════════════\n\n /**\n * Lista todos los presets disponibles con sus características\n */\n static listPresets(): Array<{\n key: string\n dimensions: Dimensions3D\n maxWeight: number\n weight: number\n }> {\n return Object.entries(STANDARD_PALLETS).map(([key, preset]) => ({\n key,\n dimensions: preset.dimensions,\n maxWeight: preset.maxWeight,\n weight: preset.weight,\n }))\n }\n}\n","/**\n * TruckFactory — Factories para crear camiones por preset o custom\n */\n\nimport type { Truck } from '../entities/Truck'\nimport type { Dimensions3D } from '../types'\nimport { TruckType } from '../types'\nimport { TRUCK_PRESETS } from '../constants'\n\nlet _truckCounter = 0\n\nfunction nextTruckId(): string {\n return `truck-${++_truckCounter}`\n}\n\nexport class TruckFactory {\n /** Crea un camión a partir de un preset de tipo */\n static fromPreset(type: Exclude<TruckType, 'CUSTOM'>, overrides?: Partial<Truck>): Truck {\n const preset = TRUCK_PRESETS[type]\n return {\n id: nextTruckId(),\n name: `Camión ${type}`,\n truckType: type,\n dimensions: { ...preset.dimensions },\n maxWeight: preset.maxWeight,\n pallets: [],\n metadata: {},\n ...overrides,\n }\n }\n\n /** Crea un camión custom con dimensiones y peso arbitrarios */\n static custom(dims: Dimensions3D, maxWeight: number, overrides?: Partial<Truck>): Truck {\n return {\n id: nextTruckId(),\n name: 'Camión Custom',\n truckType: TruckType.CUSTOM,\n dimensions: { ...dims },\n maxWeight,\n pallets: [],\n metadata: {},\n ...overrides,\n }\n }\n}\n","/**\n * BoxFactory — Helper for creating boxes with sensible defaults\n *\n * Provides factory methods for common box configurations.\n */\n\nimport type { Box } from '../entities/Box'\nimport type { Dimensions3D } from '../types'\n\nlet _boxCounter = 0\n\nfunction nextBoxId(): string {\n return `box-${++_boxCounter}`\n}\n\nexport class BoxFactory {\n /**\n * Creates a box with default values\n *\n * @param dims - Box dimensions in millimeters\n * @param opts - Optional overrides for any Box property\n * @returns A new Box instance with defaults applied\n *\n * @example\n * const box = BoxFactory.create(\n * { width: 600, height: 400, depth: 400 },\n * { product: 'PROD-A', materialWeight: 6 }\n * )\n */\n static create(dims: Dimensions3D, opts?: Partial<Box>): Box {\n return {\n id: nextBoxId(),\n dimensions: { ...dims },\n weight: 5,\n materialWeight: 5, // Default: medium resistance\n fragile: false,\n stackable: true,\n metadata: {},\n ...opts,\n }\n }\n\n /**\n * Creates a fragile box with maximum weight limit\n *\n * @param dims - Box dimensions in millimeters\n * @param fragilityMaxWeight - Maximum weight (kg) this box can support on top\n * @param opts - Optional overrides\n * @returns A fragile Box instance\n *\n * @example\n * const fragileBox = BoxFactory.fragile(\n * { width: 400, height: 300, depth: 300 },\n * 10, // Can support max 10kg on top\n * { materialWeight: 0, product: 'PROD-FRAGILE' }\n * )\n */\n static fragile(dims: Dimensions3D, fragilityMaxWeight: number, opts?: Partial<Box>): Box {\n return BoxFactory.create(dims, {\n fragile: true,\n fragilityMaxWeight,\n materialWeight: 0, // Fragile boxes go on top\n ...opts,\n })\n }\n\n /**\n * Creates a heavy, non-stackable box\n *\n * @param dims - Box dimensions in millimeters\n * @param weight - Box weight in kilograms\n * @param opts - Optional overrides\n * @returns A heavy Box instance\n *\n * @example\n * const heavyBox = BoxFactory.heavy(\n * { width: 800, height: 600, depth: 600 },\n * 50, // 50kg\n * { materialWeight: 8, product: 'PROD-HEAVY' }\n * )\n */\n static heavy(dims: Dimensions3D, weight: number, opts?: Partial<Box>): Box {\n return BoxFactory.create(dims, {\n weight,\n stackable: false,\n materialWeight: 8, // Heavy boxes have high resistance\n ...opts,\n })\n }\n}\n","/**\n * usePhysicsValidation — Ejecuta todas las validaciones físicas sobre un piso de palet\n */\n\nimport { useMemo } from 'react'\nimport type { PlacedBox } from '@/core/entities/PlacedBox'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { ValidationResult, Violation } from '@/core/types'\nimport { validateNoBoxCollisions } from '@/core/validation/collision'\nimport { validateAllBoxesInPalletBounds } from '@/core/validation/bounds'\nimport { validatePalletWeight } from '@/core/validation/weight'\nimport { validateFragileLoad, validateWeightDistribution } from '@/core/validation/weight'\nimport { validateSupport } from '@/core/validation/gravity'\nimport { validateBoxStackability, validateInvertedPyramid } from '@/core/validation/stacking'\nimport { validateStability, validateCogInsideSupport } from '@/core/validation/stability'\nimport type { PalletFloor } from '@/core/entities/PalletFloor'\n\nexport interface PhysicsValidationResult {\n isValid: boolean\n violations: Violation[]\n collisions: ValidationResult\n bounds: ValidationResult\n weight: ValidationResult\n gravity: ValidationResult\n stacking: ValidationResult\n stability: ValidationResult\n fragile: ValidationResult\n distribution: ValidationResult\n}\n\nexport function usePhysicsValidation(\n boxes: PlacedBox[],\n pallet: Pallet,\n): PhysicsValidationResult {\n return useMemo(() => {\n const collisions = validateNoBoxCollisions(boxes)\n const bounds = validateAllBoxesInPalletBounds(boxes, pallet)\n const floor: PalletFloor = { level: 0, pallet, boxes }\n const weight = validatePalletWeight(floor)\n const gravity = validateSupport(boxes)\n const stackability = validateBoxStackability(boxes)\n const invertedPyramid = validateInvertedPyramid(boxes)\n const stability = validateStability(pallet, boxes)\n const cogValid = validateCogInsideSupport(pallet, boxes)\n const fragile = validateFragileLoad(boxes)\n const distribution = validateWeightDistribution(pallet, boxes)\n\n const stackingViolations = [...stackability.violations, ...invertedPyramid.violations]\n const stabilityViolations = [...stability.violations, ...cogValid.violations]\n\n const allViolations: Violation[] = [\n ...collisions.violations,\n ...bounds.violations,\n ...weight.violations,\n ...gravity.violations,\n ...stackingViolations,\n ...stabilityViolations,\n ...fragile.violations,\n ...distribution.violations,\n ]\n\n return {\n isValid: allViolations.filter(v => v.severity === 'error').length === 0,\n violations: allViolations,\n collisions,\n bounds,\n weight,\n gravity,\n stacking: {\n isValid: stackability.isValid,\n violations: stackingViolations,\n },\n stability: {\n isValid: stability.isValid && cogValid.isValid,\n violations: stabilityViolations,\n },\n fragile,\n distribution,\n }\n }, [boxes, pallet])\n}\n","/**\n * usePalletMetrics — Calcula métricas de un StackedPallet\n */\n\nimport { useMemo } from 'react'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { getStackedPalletTotalHeight, getStackedPalletTotalWeight } from '@/core/entities/StackedPallet'\nimport type { Position3D, PackingMetrics } from '@/core/types'\nimport { calculateCenterOfGravity, calculateStabilityScore } from '@/core/validation/stability'\n\nexport interface PalletMetricsResult extends PackingMetrics {\n totalHeight: number // mm\n totalWeight: number // kg\n boxCount: number\n floorCount: number\n}\n\nexport function usePalletMetrics(stack: StackedPallet | null): PalletMetricsResult {\n return useMemo(() => {\n if (!stack || stack.floors.length === 0) {\n return {\n volumeUtilization: 0,\n weightUtilization: 0,\n centerOfGravity: { x: 0, y: 0, z: 0 } as Position3D,\n stabilityScore: 100,\n totalHeight: 0,\n totalWeight: 0,\n boxCount: 0,\n floorCount: 0,\n }\n }\n\n const totalHeight = getStackedPalletTotalHeight(stack)\n const totalWeight = getStackedPalletTotalWeight(stack)\n const basePallet = stack.floors[0].pallet\n const allBoxes = stack.floors.flatMap(f => f.boxes)\n const boxCount = allBoxes.length\n const floorCount = stack.floors.length\n\n // Volumen total disponible\n const totalVolume = basePallet.dimensions.width * basePallet.maxStackHeight * basePallet.dimensions.depth\n const usedVolume = allBoxes.reduce((s, pb) => {\n const d = pb.box.dimensions\n return s + d.width * d.height * d.depth\n }, 0)\n\n const cog = calculateCenterOfGravity(allBoxes)\n const stability = calculateStabilityScore(basePallet, allBoxes)\n\n return {\n volumeUtilization: totalVolume > 0 ? usedVolume / totalVolume : 0,\n weightUtilization: basePallet.maxWeight > 0 ? totalWeight / basePallet.maxWeight : 0,\n centerOfGravity: cog,\n stabilityScore: stability,\n totalHeight,\n totalWeight,\n boxCount,\n floorCount,\n }\n }, [stack])\n}\n","/**\n * usePackingStrategy — Accede al registry, ejecuta estrategia seleccionada\n */\n\nimport { useMemo, useCallback } from 'react'\nimport type { Box } from '@/core/entities/Box'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { PackingResult } from '@/core/packing/PackingStrategy'\nimport { PackingRegistry, defaultRegistry } from '@/core/packing/registry'\n\nexport interface UsePackingStrategyReturn {\n availableStrategies: { id: string; name: string }[]\n pack: (boxes: Box[], pallet: Pallet) => PackingResult\n}\n\nexport function usePackingStrategy(\n strategyId: string,\n registry: PackingRegistry = defaultRegistry,\n): UsePackingStrategyReturn {\n const availableStrategies = useMemo(\n () => registry.list().map(s => ({ id: s.id, name: s.name })),\n [registry],\n )\n\n const pack = useCallback(\n (boxes: Box[], pallet: Pallet): PackingResult => {\n const strategy = registry.get(strategyId)\n return strategy.pack(boxes, pallet)\n },\n [strategyId, registry],\n )\n\n return { availableStrategies, pack }\n}\n","/**\n * useWarehouseValidation — Valida palets dentro de habitaciones\n */\n\nimport { useMemo } from 'react'\nimport type { Room } from '@/core/entities/Room'\nimport type { ValidationResult, Violation } from '@/core/types'\nimport { validatePalletInRoom } from '@/core/validation/polygon'\nimport { validateNoPalletCollisions } from '@/core/validation/collision'\n\nexport interface WarehouseValidationResult {\n isValid: boolean\n violations: Violation[]\n palletInRoom: ValidationResult\n palletCollisions: ValidationResult\n}\n\nexport function useWarehouseValidation(room: Room): WarehouseValidationResult {\n return useMemo(() => {\n // Validar que cada palet esté dentro del polígono de la habitación\n const roomViolations: Violation[] = []\n for (const placedPallet of room.pallets) {\n const result = validatePalletInRoom(placedPallet, room)\n roomViolations.push(...result.violations)\n }\n\n // Validar que no haya colisiones entre palets\n const collisions = validateNoPalletCollisions(room.pallets)\n\n const allViolations: Violation[] = [\n ...roomViolations,\n ...collisions.violations,\n ]\n\n return {\n isValid: allViolations.filter(v => v.severity === 'error').length === 0,\n violations: allViolations,\n palletInRoom: {\n isValid: roomViolations.length === 0,\n violations: roomViolations,\n },\n palletCollisions: collisions,\n }\n }, [room])\n}\n","/**\n * Box — Componente primitivo 3D para una caja\n * Controlado, memo, conversión mm→metros interna\n */\n\nimport { memo, useCallback, useRef, useMemo } from \"react\";\nimport { Html, Edges } from \"@react-three/drei\";\nimport * as THREE from \"three\";\nimport type { PlacedBox } from \"@/core/entities/PlacedBox\";\nimport { UNITS } from \"@/core/constants\";\nimport { usePreset } from \"@/context/PresetContext\";\n\nexport interface BoxProps {\n placedBox: PlacedBox;\n selected?: boolean;\n highlighted?: boolean;\n showLabel?: boolean;\n color?: string;\n opacity?: number;\n selectedColor?: string;\n highlightedColor?: string;\n onClick?: (id: string) => void;\n onHover?: (id: string | null) => void;\n}\n\nexport const BoxComponent = memo<BoxProps>(function BoxComponent({\n placedBox,\n selected = false,\n highlighted = false,\n showLabel = false,\n color,\n opacity,\n selectedColor,\n highlightedColor,\n onClick,\n onHover,\n}) {\n const meshRef = useRef<THREE.Mesh>(null);\n const preset = usePreset();\n\n const { box, position, rotation } = placedBox;\n const s = UNITS.MM_TO_M;\n\n // Resolver estilos: prop > preset\n const resolvedColor = color ?? box.color ?? preset.box.color;\n const resolvedOpacity = opacity ?? preset.box.opacity;\n const resolvedSelectedColor = selectedColor ?? preset.selection.selectedColor;\n const resolvedHighlightedColor =\n highlightedColor ?? preset.selection.highlightedColor;\n\n // Dimensiones (teniendo en cuenta rotación en Y)\n let w = box.dimensions.width;\n let d = box.dimensions.depth;\n if (rotation.y === 90 || rotation.y === 270) {\n [w, d] = [d, w];\n }\n\n const scaledDims = useMemo(\n () => [w * s, box.dimensions.height * s, d * s] as [number, number, number],\n [w, d, box.dimensions.height, s],\n );\n\n // Posición: convertir mm→m, centrar geometría en Y\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n );\n\n const borderColor = selected\n ? resolvedSelectedColor\n : highlighted\n ? resolvedHighlightedColor\n : null;\n\n const handleClick = useCallback(\n (e: { stopPropagation: () => void }) => {\n e.stopPropagation();\n onClick?.(placedBox.id);\n },\n [onClick, placedBox.id],\n );\n\n const handlePointerOver = useCallback(\n (e: { stopPropagation: () => void }) => {\n e.stopPropagation();\n onHover?.(placedBox.id);\n },\n [onHover, placedBox.id],\n );\n\n const handlePointerOut = useCallback(() => {\n onHover?.(null);\n }, [onHover]);\n\n return (\n <group>\n <mesh\n ref={meshRef}\n position={pos}\n onClick={handleClick}\n onPointerOver={handlePointerOver}\n onPointerOut={handlePointerOut}\n castShadow\n receiveShadow\n >\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial\n color={resolvedColor}\n transparent={resolvedOpacity < 1}\n opacity={resolvedOpacity}\n roughness={preset.box.roughness}\n metalness={preset.box.metalness}\n polygonOffset\n polygonOffsetFactor={1}\n polygonOffsetUnits={1}\n />\n {/* Bordes permanentes para distinguir cajas adyacentes del mismo color */}\n <Edges\n linewidth={2}\n scale={1.001}\n threshold={15}\n color={borderColor ?? \"#000000\"}\n opacity={borderColor ? 1 : 0.6}\n transparent\n />\n </mesh>\n\n {/* Borde de señalización adicional para selección/highlight */}\n {borderColor && (\n <mesh position={pos}>\n <boxGeometry args={scaledDims} />\n <meshBasicMaterial\n color={borderColor}\n wireframe\n wireframeLinewidth={2}\n transparent\n opacity={0.9}\n depthTest={false}\n />\n </mesh>\n )}\n\n {/* Label */}\n {showLabel && (\n <Html\n position={[pos.x, pos.y + scaledDims[1] / 2 + 0.05, pos.z]}\n center\n style={{\n background: \"rgba(0,0,0,0.75)\",\n color: \"white\",\n padding: \"2px 6px\",\n borderRadius: \"3px\",\n fontSize: \"11px\",\n whiteSpace: \"nowrap\",\n pointerEvents: \"none\",\n }}\n >\n {box.sku ?? box.type ?? box.id}\n </Html>\n )}\n </group>\n );\n});\n","/**\n * Pallet — Componente primitivo 3D para la base física de un palet\n */\n\nimport { memo, useMemo } from 'react'\nimport * as THREE from 'three'\nimport type { Pallet } from '@/core/entities/Pallet'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface PalletComponentProps {\n pallet: Pallet\n position?: Position3D\n color?: string\n edgeColor?: string\n}\n\nexport const PalletComponent = memo<PalletComponentProps>(function PalletComponent({\n pallet,\n position = { x: 0, y: 0, z: 0 },\n color,\n edgeColor,\n}) {\n const preset = usePreset()\n const resolvedColor = color ?? preset.pallet.color\n const resolvedEdgeColor = edgeColor ?? preset.pallet.edgeColor\n const s = UNITS.MM_TO_M\n const dims = pallet.dimensions\n\n const scaledDims = useMemo(\n () => [dims.width * s, dims.height * s, dims.depth * s] as [number, number, number],\n [dims, s],\n )\n\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n )\n\n return (\n <group>\n {/* Tabla superior */}\n <mesh position={pos} castShadow receiveShadow>\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial color={resolvedColor} roughness={preset.pallet.roughness} metalness={preset.pallet.metalness} />\n </mesh>\n\n {/* Bordes */}\n <lineSegments position={pos}>\n <edgesGeometry args={[new THREE.BoxGeometry(...scaledDims)]} />\n <lineBasicMaterial color={resolvedEdgeColor} />\n </lineSegments>\n </group>\n )\n})\n","/**\n * Separator — Componente primitivo 3D para un separador entre pisos\n */\n\nimport { memo, useMemo } from 'react'\nimport * as THREE from 'three'\nimport type { Separator } from '@/core/entities/Separator'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { SeparatorMaterial } from '@/core/types'\n\nconst MATERIAL_COLORS: Record<SeparatorMaterial, string> = {\n [SeparatorMaterial.CARDBOARD]: '#b5926b',\n [SeparatorMaterial.WOOD]: '#c4a26e',\n [SeparatorMaterial.PLASTIC]: '#90a4ae',\n}\n\nexport interface SeparatorComponentProps {\n separator: Separator\n position?: Position3D\n}\n\nexport const SeparatorComponent = memo<SeparatorComponentProps>(function SeparatorComponent({\n separator,\n position = { x: 0, y: 0, z: 0 },\n}) {\n const s = UNITS.MM_TO_M\n const dims = separator.dimensions\n\n const scaledDims = useMemo(\n () => [dims.width * s, dims.height * s, dims.depth * s] as [number, number, number],\n [dims, s],\n )\n\n const pos = useMemo(\n () =>\n new THREE.Vector3(\n position.x * s + scaledDims[0] / 2,\n position.y * s + scaledDims[1] / 2,\n position.z * s + scaledDims[2] / 2,\n ),\n [position, scaledDims, s],\n )\n\n const color = MATERIAL_COLORS[separator.material]\n\n return (\n <mesh position={pos} receiveShadow>\n <boxGeometry args={scaledDims} />\n <meshStandardMaterial\n color={color}\n roughness={0.9}\n metalness={0}\n transparent\n opacity={0.85}\n />\n </mesh>\n )\n})\n","/**\n * StackedPallet — Renderiza un palet apilado completo\n * (base + pisos + separadores + cajas)\n */\n\nimport { memo, useMemo } from 'react'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { ensureUniqueBoxIds } from '@/core/entities/StackedPallet'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\nimport { PalletComponent } from '../Pallet'\nimport { BoxComponent } from '../Box'\nimport { SeparatorComponent } from '../Separator'\n\nexport interface StackedPalletComponentProps {\n stackedPallet: StackedPallet\n position?: Position3D\n /** Rotación Y en grados (0, 90, 180, 270) */\n yRotation?: 0 | 90 | 180 | 270\n /** ID del palet contenedor. Si se proporciona, se usa como contexto \n * para generar IDs únicos de cajas. La librería garantiza automáticamente\n * que no hay conflictos de IDs entre pisos o palets. */\n palletId?: string\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (por defecto: rojo #ff0000) */\n selectedColor?: string\n /** Color del borde de highlight/hover (por defecto: azul #42a5f5) */\n highlightedColor?: string\n showLabels?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n}\n\nexport const StackedPalletComponent = memo<StackedPalletComponentProps>(\n function StackedPalletComponent({\n stackedPallet,\n position = { x: 0, y: 0, z: 0 },\n yRotation = 0,\n palletId,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n onBoxClick,\n onBoxHover,\n }) {\n // Normalizar automáticamente los IDs de las cajas para garantizar unicidad\n // La librería se encarga de esto internamente, el desarrollador no necesita preocuparse\n const normalizedStack = useMemo(\n () => ensureUniqueBoxIds(stackedPallet, palletId),\n [stackedPallet, palletId],\n )\n\n const s = UNITS.MM_TO_M\n const rotationY = useMemo(() => (yRotation * Math.PI) / 180, [yRotation])\n\n // Calcular las alturas acumuladas de cada piso\n const floorOffsets = useMemo(() => {\n const offsets: number[] = []\n let currentY = 0\n for (const floor of normalizedStack.floors) {\n offsets.push(currentY)\n currentY += floor.pallet.dimensions.height\n // Altura de las cajas: máximo top\n const maxBoxTop = floor.boxes.reduce(\n (max, pb) => Math.max(max, pb.position.y + pb.box.dimensions.height),\n 0,\n )\n currentY += maxBoxTop\n if (floor.separatorAbove) {\n currentY += floor.separatorAbove.dimensions.height\n }\n }\n return offsets\n }, [normalizedStack])\n\n return (\n <group\n position={[position.x * s, position.y * s, position.z * s]}\n rotation={[0, rotationY, 0]}\n >\n {normalizedStack.floors.map((floor, idx) => {\n const floorY = floorOffsets[idx]\n const palletTopY = floorY + floor.pallet.dimensions.height\n\n return (\n <group key={`floor-${idx}`}>\n {/* Palet base de este piso */}\n <PalletComponent\n pallet={floor.pallet}\n position={{ x: 0, y: floorY, z: 0 }}\n />\n\n {/* Cajas en posición relativa al top del palet */}\n {floor.boxes.map(pb => {\n return (\n <BoxComponent\n key={pb.id}\n placedBox={{\n ...pb,\n position: {\n x: pb.position.x,\n y: pb.position.y + palletTopY,\n z: pb.position.z,\n },\n }}\n selected={selectedBoxId === pb.id}\n highlighted={highlightedBoxId === pb.id}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabel={showLabels}\n onClick={onBoxClick}\n onHover={onBoxHover}\n />\n )\n })}\n\n {/* Separador encima (si hay) */}\n {floor.separatorAbove && (\n <SeparatorComponent\n separator={floor.separatorAbove}\n position={{\n x: 0,\n y:\n palletTopY +\n floor.boxes.reduce(\n (max, pb) => Math.max(max, pb.position.y + pb.box.dimensions.height),\n 0,\n ),\n z: 0,\n }}\n />\n )}\n </group>\n )\n })}\n </group>\n )\n },\n)\n","/**\n * Label — Etiqueta flotante con <Html> de drei\n */\n\nimport { memo } from 'react'\nimport { Html } from '@react-three/drei'\nimport type { Position3D } from '@/core/types'\nimport { UNITS } from '@/core/constants'\n\nexport interface LabelProps {\n text: string\n position: Position3D\n visible?: boolean\n fontSize?: number\n color?: string\n background?: string\n}\n\nexport const Label = memo<LabelProps>(function Label({\n text,\n position,\n visible = true,\n fontSize = 12,\n color = 'white',\n background = 'rgba(0,0,0,0.75)',\n}) {\n if (!visible) return null\n\n const s = UNITS.MM_TO_M\n\n return (\n <Html\n position={[position.x * s, position.y * s, position.z * s]}\n center\n style={{\n background,\n color,\n padding: '2px 8px',\n borderRadius: '4px',\n fontSize: `${fontSize}px`,\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n {text}\n </Html>\n )\n})\n","/**\n * WarehouseEnvironment — Decorado de escena almacén\n * Suelo, paredes (según polígono de Room), techo, grid, iluminación\n */\n\nimport { memo, useMemo, type ReactNode } from 'react'\nimport * as THREE from 'three'\nimport { UNITS } from '@/core/constants'\nimport type { Room } from '@/core/entities/Room'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface WarehouseEnvironmentProps {\n room: Room\n floorColor?: string\n wallColor?: string\n showGrid?: boolean\n children?: ReactNode\n}\n\nexport const WarehouseEnvironment = memo<WarehouseEnvironmentProps>(\n function WarehouseEnvironment({\n room,\n floorColor,\n wallColor,\n showGrid,\n children,\n }) {\n const preset = usePreset()\n const resolvedFloorColor = floorColor ?? preset.warehouse.floorColor\n const resolvedWallColor = wallColor ?? preset.warehouse.wallColor\n const resolvedShowGrid = showGrid ?? preset.warehouse.showGrid\n const s = UNITS.MM_TO_M\n const ceilingH = room.ceilingHeight * s\n\n // Calcular bounding box del polígono para el suelo y grid\n const { shape, minX, maxX, minZ, maxZ } = useMemo(() => {\n const pts = room.floorPolygon\n let mnX = Infinity, mxX = -Infinity, mnZ = Infinity, mxZ = -Infinity\n for (const p of pts) {\n mnX = Math.min(mnX, p.x * s)\n mxX = Math.max(mxX, p.x * s)\n mnZ = Math.min(mnZ, p.z * s)\n mxZ = Math.max(mxZ, p.z * s)\n }\n\n // Crear shape en 2D (XY). Cuando se rota -90° en X, Y → -Z\n // Por eso usamos -pts[i].z para que quede correctamente orientado\n const sh = new THREE.Shape()\n sh.moveTo(pts[0].x * s, -pts[0].z * s)\n for (let i = 1; i < pts.length; i++) {\n sh.lineTo(pts[i].x * s, -pts[i].z * s)\n }\n sh.closePath()\n\n return { shape: sh, minX: mnX, maxX: mxX, minZ: mnZ, maxZ: mxZ }\n }, [room.floorPolygon, s])\n\n // Geometría de paredes: extruir el polígono del suelo\n const wallGeometry = useMemo(() => {\n const pts = room.floorPolygon\n const positions: number[] = []\n const indices: number[] = []\n\n for (let i = 0; i < pts.length; i++) {\n const curr = pts[i]\n const next = pts[(i + 1) % pts.length]\n\n const baseIdx = i * 4\n // Quad: 4 vértices por segmento de pared\n positions.push(\n curr.x * s, 0, curr.z * s,\n next.x * s, 0, next.z * s,\n next.x * s, ceilingH, next.z * s,\n curr.x * s, ceilingH, curr.z * s,\n )\n indices.push(\n baseIdx, baseIdx + 1, baseIdx + 2,\n baseIdx, baseIdx + 2, baseIdx + 3,\n )\n }\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n geo.setIndex(indices)\n geo.computeVertexNormals()\n return geo\n }, [room.floorPolygon, ceilingH, s])\n\n const sizeX = maxX - minX\n const sizeZ = maxZ - minZ\n const centerX = (minX + maxX) / 2\n const centerZ = (minZ + maxZ) / 2\n\n // Grid rectangular personalizado (gridHelper solo crea grids cuadrados)\n const gridGeometry = useMemo(() => {\n if (!resolvedShowGrid) return null\n \n const spacing = 0.5 // 500mm\n const y = 0.01\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = minX; x <= maxX; x += spacing) {\n positions.push(x, y, minZ, x, y, maxZ)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = minZ; z <= maxZ; z += spacing) {\n positions.push(minX, y, z, maxX, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [resolvedShowGrid, minX, maxX, minZ, maxZ])\n\n return (\n <group>\n {/* Suelo */}\n <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.005, 0]} receiveShadow>\n <shapeGeometry args={[shape]} />\n <meshStandardMaterial \n color={resolvedFloorColor} \n side={THREE.DoubleSide} \n roughness={preset.warehouse.floorRoughness}\n />\n </mesh>\n\n {/* Paredes */}\n <mesh geometry={wallGeometry} position={[0, 0, 0]} receiveShadow>\n <meshStandardMaterial\n color={resolvedWallColor}\n side={THREE.DoubleSide}\n roughness={0.7}\n transparent\n opacity={preset.warehouse.wallOpacity}\n />\n </mesh>\n\n {/* Grid personalizado */}\n {resolvedShowGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color={preset.warehouse.gridColor} \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* Iluminación almacén */}\n <ambientLight intensity={preset.warehouse.ambientIntensity} />\n <directionalLight\n position={[centerX + sizeX, ceilingH * 0.8, centerZ + sizeZ]}\n intensity={preset.warehouse.directionalIntensity}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <pointLight\n position={[centerX, ceilingH * 0.9, centerZ]}\n intensity={0.5}\n distance={Math.max(sizeX, sizeZ) * 2}\n />\n\n {/* Children (palets, etc.) */}\n {children}\n </group>\n )\n },\n)\n","/**\n * TruckEnvironment — Escena de camión con forma realista\n *\n * El centro de la escena es el interior del remolque (zona de carga).\n * La superficie donde se colocan los palets es únicamente el suelo del remolque.\n * Elementos visuales adicionales (cabina, chasis, ruedas) dan forma de camión real.\n */\n\nimport { memo, useMemo, type ReactNode } from 'react'\nimport * as THREE from 'three'\nimport type { Truck } from '@/core/entities/Truck'\nimport { UNITS } from '@/core/constants'\nimport { usePreset } from '@/context/PresetContext'\n\nexport interface TruckEnvironmentProps {\n truck: Truck\n /** Mostrar/ocultar grid en el suelo del remolque (por defecto usa preset) */\n showGrid?: boolean\n /** Opacidad de las paredes (0 = invisible, 1 = opaco). Por defecto: 0.3 */\n wallOpacity?: number\n /** Mostrar/ocultar el techo del remolque. Por defecto: false (oculto para ver interior) */\n showRoof?: boolean\n /** Mostrar/ocultar paredes laterales. Por defecto: true */\n showSideWalls?: boolean\n children?: ReactNode\n}\n\n// ─── Componente de rueda ─────────────────────────────────────────\n\ninterface WheelProps {\n position: [number, number, number]\n radius: number\n width: number\n color: string\n}\n\nconst Wheel = memo<WheelProps>(function Wheel({ position, radius, width, color }) {\n return (\n <group position={position}>\n {/* Neumático */}\n <mesh rotation={[0, 0, Math.PI / 2]} castShadow>\n <cylinderGeometry args={[radius, radius, width, 24]} />\n <meshStandardMaterial color={color} roughness={0.9} metalness={0.1} />\n </mesh>\n {/* Rin */}\n <mesh rotation={[0, 0, Math.PI / 2]}>\n <cylinderGeometry args={[radius * 0.55, radius * 0.55, width + 0.005, 16]} />\n <meshStandardMaterial color=\"#888888\" roughness={0.3} metalness={0.7} />\n </mesh>\n </group>\n )\n})\n\n// ─── Componente principal ────────────────────────────────────────\n\nexport const TruckEnvironment = memo<TruckEnvironmentProps>(function TruckEnvironment({\n truck,\n showGrid,\n wallOpacity = 0.3,\n showRoof = false,\n showSideWalls = true,\n children,\n}) {\n const preset = usePreset()\n const truckStyle = preset.truck\n const resolvedShowGrid = showGrid ?? truckStyle.showGrid\n\n const s = UNITS.MM_TO_M\n const tw = truck.dimensions.width * s // ancho remolque\n const th = truck.dimensions.height * s // alto remolque\n const td = truck.dimensions.depth * s // profundidad remolque\n\n // ── Dimensiones derivadas ──\n const wallThickness = 0.05\n const floorThickness = 0.08\n const wheelRadius = 0.28\n const wheelWidth = 0.18\n const groundClearance = 0.15 // distancia del suelo a la parte inferior del chasis\n const chassisH = 0.25 // altura del bastidor\n const wheelY = wheelRadius + groundClearance // ruedas apoyadas con clearance\n const chassisY = wheelY + wheelRadius + 0.1 // chasis sobre las ruedas\n const remolqueFloorY = chassisY + chassisH / 2 + floorThickness / 2 // remolque sobre el chasis\n \n const cabW = tw + wallThickness * 2 // la cabina tiene el mismo ancho exterior\n const cabD = tw * 0.65 // profundidad de la cabina\n const cabH = th * 0.85 // altura de la cabina\n const cabGap = 0.15 // separación entre cabina y remolque\n const cabZ = td + wallThickness + cabGap // posición Z de la cabina\n const cabFloorY = remolqueFloorY // cabina al mismo nivel que el remolque\n\n // Grid rectangular personalizado para el remolque\n const gridGeometry = useMemo(() => {\n if (!resolvedShowGrid) return null\n \n const spacing = 0.5 // 500mm\n const y = remolqueFloorY + 0.002\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = 0; x <= tw; x += spacing) {\n positions.push(x, y, 0, x, y, td)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = 0; z <= td; z += spacing) {\n positions.push(0, y, z, tw, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [resolvedShowGrid, tw, td, remolqueFloorY])\n\n const solidWallMaterial = useMemo(\n () => (\n <meshStandardMaterial\n color={truckStyle.wallColor}\n roughness={0.5}\n metalness={0.3}\n transparent={wallOpacity < 1}\n opacity={wallOpacity}\n side={THREE.DoubleSide}\n depthWrite={wallOpacity >= 0.95}\n />\n ),\n [truckStyle.wallColor, wallOpacity],\n )\n\n return (\n <group>\n {/* ═══════════════════════════════════════════════════════\n * REMOLQUE (zona de carga) − centrado en el origen\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Suelo del remolque */}\n <mesh\n position={[tw / 2, remolqueFloorY, td / 2]}\n rotation={[-Math.PI / 2, 0, 0]}\n receiveShadow\n >\n <planeGeometry args={[tw, td]} />\n <meshStandardMaterial color={truckStyle.floorColor} roughness={0.85} />\n </mesh>\n\n {/* Grosor del suelo (cuerpo visible) */}\n <mesh position={[tw / 2, remolqueFloorY - floorThickness / 2, td / 2]} castShadow receiveShadow>\n <boxGeometry args={[tw + wallThickness * 2, floorThickness, td + wallThickness]} />\n <meshStandardMaterial color={truckStyle.floorColor} roughness={0.85} metalness={0.1} />\n </mesh>\n\n {/* Pared izquierda */}\n {showSideWalls && (\n <mesh position={[-wallThickness / 2, remolqueFloorY + th / 2, td / 2]} castShadow>\n <boxGeometry args={[wallThickness, th, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Pared derecha */}\n {showSideWalls && (\n <mesh position={[tw + wallThickness / 2, remolqueFloorY + th / 2, td / 2]} castShadow>\n <boxGeometry args={[wallThickness, th, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Pared trasera (fondo del remolque — lado cabina) */}\n <mesh position={[tw / 2, remolqueFloorY + th / 2, td + wallThickness / 2]} castShadow>\n <boxGeometry args={[tw + wallThickness * 2, th, wallThickness]} />\n {solidWallMaterial}\n </mesh>\n\n {/* Techo del remolque */}\n {showRoof && (\n <mesh position={[tw / 2, remolqueFloorY + th, td / 2]} castShadow>\n <boxGeometry args={[tw + wallThickness * 2, wallThickness, td + wallThickness]} />\n {solidWallMaterial}\n </mesh>\n )}\n\n {/* Grid del suelo del remolque */}\n {resolvedShowGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color={truckStyle.gridColor} \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* ═══════════════════════════════════════════════════════\n * CHASIS / BASTIDOR\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Largueros del chasis (dos vigas longitudinales) */}\n <mesh position={[tw * 0.25, chassisY, (td + cabD + cabGap) / 2]} castShadow>\n <boxGeometry args={[0.12, chassisH, td + cabD + cabGap]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n <mesh position={[tw * 0.75, chassisY, (td + cabD + cabGap) / 2]} castShadow>\n <boxGeometry args={[0.12, chassisH, td + cabD + cabGap]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n\n {/* Travesaños */}\n {[0.15, 0.35, 0.55, 0.75, 0.95].map((frac) => (\n <mesh key={frac} position={[tw / 2, chassisY, td * frac]} castShadow>\n <boxGeometry args={[tw * 0.6, 0.06, 0.06]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.7} metalness={0.5} />\n </mesh>\n ))}\n\n {/* ═══════════════════════════════════════════════════════\n * RUEDAS\n * ═══════════════════════════════════════════════════════ */}\n\n {/* Ejes traseros del remolque (doble eje) */}\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, td * 0.12]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, td * 0.12]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, td * 0.22]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, td * 0.22]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n\n {/* Ruedas del eje de la cabina */}\n <Wheel position={[-wheelWidth / 2 - wallThickness, wheelY, cabZ + cabD * 0.5]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n <Wheel position={[tw + wheelWidth / 2 + wallThickness, wheelY, cabZ + cabD * 0.5]} radius={wheelRadius} width={wheelWidth} color={truckStyle.wheelColor} />\n\n {/* ═══════════════════════════════════════════════════════\n * CABINA\n * ═══════════════════════════════════════════════════════ */}\n <group position={[tw / 2, cabFloorY, cabZ]}>\n {/* Cuerpo principal de la cabina */}\n <mesh position={[0, cabH / 2, cabD / 2]} castShadow receiveShadow>\n <boxGeometry args={[cabW, cabH, cabD]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Parabrisas (frontal) */}\n <mesh\n position={[0, cabH * 0.6, cabD + 0.01]}\n castShadow\n >\n <planeGeometry args={[cabW * 0.75, cabH * 0.4]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.5}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Ventanilla izquierda */}\n <mesh position={[-cabW / 2 - 0.01, cabH * 0.6, cabD * 0.55]} rotation={[0, Math.PI / 2, 0]}>\n <planeGeometry args={[cabD * 0.5, cabH * 0.3]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.4}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Ventanilla derecha */}\n <mesh position={[cabW / 2 + 0.01, cabH * 0.6, cabD * 0.55]} rotation={[0, -Math.PI / 2, 0]}>\n <planeGeometry args={[cabD * 0.5, cabH * 0.3]} />\n <meshStandardMaterial\n color=\"#88bbdd\"\n transparent\n opacity={0.4}\n roughness={0.1}\n metalness={0.6}\n side={THREE.DoubleSide}\n />\n </mesh>\n\n {/* Techo de la cabina (ligeramente redondeado con box) */}\n <mesh position={[0, cabH + 0.04, cabD / 2]}>\n <boxGeometry args={[cabW * 0.95, 0.08, cabD * 0.9]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Deflector de aire encima de la cabina */}\n <mesh position={[0, cabH + 0.25, cabD * 0.1]} rotation={[-0.3, 0, 0]}>\n <boxGeometry args={[cabW * 0.9, 0.04, cabD * 0.5]} />\n <meshStandardMaterial color={truckStyle.cabColor} roughness={0.4} metalness={0.3} />\n </mesh>\n\n {/* Faros delanteros */}\n <mesh position={[-cabW * 0.35, cabH * 0.2, cabD + 0.02]}>\n <boxGeometry args={[cabW * 0.15, 0.08, 0.02]} />\n <meshStandardMaterial color=\"#ffffcc\" emissive=\"#ffffaa\" emissiveIntensity={0.3} />\n </mesh>\n <mesh position={[cabW * 0.35, cabH * 0.2, cabD + 0.02]}>\n <boxGeometry args={[cabW * 0.15, 0.08, 0.02]} />\n <meshStandardMaterial color=\"#ffffcc\" emissive=\"#ffffaa\" emissiveIntensity={0.3} />\n </mesh>\n\n {/* Parachoques delantero */}\n <mesh position={[0, 0.06, cabD + 0.04]} castShadow>\n <boxGeometry args={[cabW * 1.02, 0.12, 0.06]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.5} metalness={0.6} />\n </mesh>\n </group>\n\n {/* ═══════════════════════════════════════════════════════\n * GUARDABARROS\n * ═══════════════════════════════════════════════════════ */}\n {/* Guardabarros traseros */}\n {[-1, 1].map(side => (\n <mesh\n key={`fender-rear-${side}`}\n position={[\n side === -1 ? -wallThickness - wheelWidth * 0.5 : tw + wallThickness + wheelWidth * 0.5,\n wheelY + wheelRadius * 0.6,\n td * 0.17,\n ]}\n castShadow\n >\n <boxGeometry args={[wheelWidth + 0.04, 0.04, wheelRadius * 2.5]} />\n <meshStandardMaterial color={truckStyle.chassisColor} roughness={0.6} metalness={0.4} />\n </mesh>\n ))}\n\n {/* ═══════════════════════════════════════════════════════\n * LUCES TRASERAS (puerta del remolque)\n * ═══════════════════════════════════════════════════════ */}\n <mesh position={[-wallThickness / 2 + 0.01, remolqueFloorY + th * 0.3, -0.01]}>\n <boxGeometry args={[0.08, 0.12, 0.02]} />\n <meshStandardMaterial color=\"#ff3333\" emissive=\"#ff0000\" emissiveIntensity={0.3} />\n </mesh>\n <mesh position={[tw + wallThickness / 2 - 0.01, remolqueFloorY + th * 0.3, -0.01]}>\n <boxGeometry args={[0.08, 0.12, 0.02]} />\n <meshStandardMaterial color=\"#ff3333\" emissive=\"#ff0000\" emissiveIntensity={0.3} />\n </mesh>\n\n {/* ═══════════════════════════════════════════════════════\n * ILUMINACIÓN\n * ═══════════════════════════════════════════════════════ */}\n <ambientLight intensity={0.45} />\n <directionalLight\n position={[tw / 2, remolqueFloorY + th * 1.5, td * 0.8]}\n intensity={0.75}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <pointLight position={[tw / 2, remolqueFloorY + th * 0.7, td / 2]} intensity={0.35} />\n {/* Luz interior (dentro del remolque) */}\n <pointLight position={[tw / 2, remolqueFloorY + th * 0.9, td * 0.3]} intensity={0.25} />\n\n {/* ═══════════════════════════════════════════════════════\n * CONTENIDO (palets) - elevados al nivel del suelo del remolque\n * ═══════════════════════════════════════════════════════ */}\n <group position={[0, remolqueFloorY, 0]}>\n {children}\n </group>\n </group>\n )\n})\n","/**\n * CameraControls — Wrapper de OrbitControls con presets de posición\n */\n\nimport { memo, useEffect, useRef } from 'react'\nimport { OrbitControls } from '@react-three/drei'\nimport { useThree } from '@react-three/fiber'\nimport * as THREE from 'three'\n\nexport type CameraPreset = 'perspective' | 'top' | 'front' | 'side' | 'isometric'\n\nexport interface CameraControlsProps {\n preset?: CameraPreset\n autoRotate?: boolean\n enablePan?: boolean\n enableZoom?: boolean\n target?: [number, number, number]\n minDistance?: number\n maxDistance?: number\n /** Tamaño de la escena para calcular posiciones relativas */\n sceneSize?: { width: number; height: number; depth: number }\n}\n\n/**\n * Calcula posiciones de cámara relativas al tamaño de la escena.\n * Usa un factor multiplicador basado en la diagonal del bounding box.\n */\nfunction calculatePresetPosition(\n preset: CameraPreset,\n target: [number, number, number],\n sceneSize?: { width: number; height: number; depth: number },\n): [number, number, number] {\n // Si no hay tamaño de escena, usar valores por defecto\n if (!sceneSize) {\n const defaults: Record<CameraPreset, [number, number, number]> = {\n perspective: [3, 3, 3],\n isometric: [4, 4, 4],\n top: [0, 5, 0],\n front: [0, 1.5, 5],\n side: [5, 1.5, 0],\n }\n return defaults[preset]\n }\n\n const { width, height, depth } = sceneSize\n const [tx, ty, tz] = target\n \n // Calcular la diagonal del bounding box para determinar la distancia óptima\n const diagonal = Math.sqrt(width ** 2 + height ** 2 + depth ** 2)\n const distance = diagonal * 3.0 // Factor de distancia para ver toda la escena\n \n switch (preset) {\n case 'perspective':\n // Vista perspectiva ajustada: 45° en horizontal, 30° en vertical\n return [\n tx + distance * 0.6,\n ty + distance * 0.5,\n tz + distance * 0.6,\n ]\n \n case 'isometric':\n // Vista isométrica pura: igual distancia en X, Y, Z\n return [\n tx + distance * 0.577,\n ty + distance * 0.577,\n tz + distance * 0.577,\n ]\n \n case 'top':\n // Vista superior: solo altura\n return [tx, ty + Math.max(distance, height * 2), tz]\n \n case 'front':\n // Vista frontal: desde el frente\n return [tx, ty + height * 0.5, tz + Math.max(distance, depth * 1.5)]\n \n case 'side':\n // Vista lateral: desde el lado\n return [tx + Math.max(distance, width * 1.5), ty + height * 0.5, tz]\n }\n}\n\nexport const CameraControlsComponent = memo<CameraControlsProps>(function CameraControlsComponent({\n preset = 'perspective',\n autoRotate = false,\n enablePan = true,\n enableZoom = true,\n target = [0, 0, 0],\n minDistance = 0.5,\n maxDistance = 50,\n sceneSize,\n}) {\n const { camera } = useThree()\n const controlsRef = useRef<any>(null)\n\n // Actualizar la posición de la cámara con animación suave cuando cambia el preset\n useEffect(() => {\n const pos = calculatePresetPosition(preset, target, sceneSize)\n const targetPos = new THREE.Vector3(pos[0], pos[1], pos[2])\n const targetLookAt = new THREE.Vector3(...target)\n \n // Animación suave de transición (usando un simple lerp)\n const startPos = camera.position.clone()\n const duration = 1000 // ms\n const startTime = Date.now()\n \n const animate = () => {\n const elapsed = Date.now() - startTime\n const progress = Math.min(elapsed / duration, 1)\n \n // Ease-out cubic para una animación más natural\n const eased = 1 - Math.pow(1 - progress, 3)\n \n camera.position.lerpVectors(startPos, targetPos, eased)\n \n if (controlsRef.current) {\n controlsRef.current.target.lerp(targetLookAt, eased)\n controlsRef.current.update()\n }\n \n if (progress < 1) {\n requestAnimationFrame(animate)\n }\n }\n \n animate()\n }, [preset, sceneSize, camera, target])\n\n return (\n <OrbitControls\n ref={controlsRef}\n target={target}\n autoRotate={autoRotate}\n autoRotateSpeed={0.5}\n enablePan={enablePan}\n enableZoom={enableZoom}\n enableRotate\n minDistance={minDistance}\n maxDistance={maxDistance}\n enableDamping\n dampingFactor={0.05}\n rotateSpeed={0.5}\n zoomSpeed={0.8}\n panSpeed={0.5}\n makeDefault\n />\n )\n})\n","/**\n * ViewControls — Botones flotantes para cambio rápido de vista de cámara\n */\n\nimport { memo } from 'react'\nimport type { CameraPreset } from '../CameraControls'\nimport './ViewControls.css'\n\nexport interface ViewControlsProps {\n currentPreset: CameraPreset\n onPresetChange: (preset: CameraPreset) => void\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\n}\n\nconst PRESET_LABELS: Record<CameraPreset, { label: string; icon: string }> = {\n perspective: { label: 'Perspectiva', icon: '📐' },\n isometric: { label: 'Isométrica', icon: '🔲' },\n top: { label: 'Superior', icon: '⬇️' },\n front: { label: 'Frontal', icon: '➡️' },\n side: { label: 'Lateral', icon: '⬅️' },\n}\n\nexport const ViewControls = memo<ViewControlsProps>(function ViewControls({\n currentPreset,\n onPresetChange,\n position = 'top-right',\n}) {\n const presets: CameraPreset[] = ['perspective', 'isometric', 'top', 'front', 'side']\n\n return (\n <div className={`view-controls view-controls--${position}`}>\n <div className=\"view-controls__title\">Vista</div>\n <div className=\"view-controls__buttons\">\n {presets.map((preset) => {\n const { label, icon } = PRESET_LABELS[preset]\n const isActive = currentPreset === preset\n\n return (\n <button\n key={preset}\n className={`view-controls__button ${isActive ? 'view-controls__button--active' : ''}`}\n onClick={() => onPresetChange(preset)}\n title={label}\n aria-label={label}\n >\n <span className=\"view-controls__icon\" role=\"img\" aria-hidden=\"true\">\n {icon}\n </span>\n <span className=\"view-controls__label\">{label}</span>\n </button>\n )\n })}\n </div>\n </div>\n )\n})\n","/**\n * MiniMap — Mini-mapa 2D con vista superior para orientación espacial\n */\n\nimport { memo, useMemo } from 'react'\nimport './MiniMap.css'\n\nexport interface MiniMapProps {\n /** Ancho de la escena en metros */\n sceneWidth: number\n /** Profundidad de la escena en metros */\n sceneDepth: number\n /** Tipo de escena: 'truck' | 'warehouse' */\n sceneType: 'truck' | 'warehouse'\n /** Polígono del suelo (solo para warehouse) */\n floorPolygon?: Array<{ x: number; z: number }>\n /** Posición de la cámara actual en la escena */\n cameraPosition?: { x: number; z: number }\n /** Posición del objetivo/target de la cámara */\n targetPosition?: { x: number; z: number }\n /** Posición: 'bottom-left' | 'bottom-right' */\n position?: 'bottom-left' | 'bottom-right'\n}\n\nexport const MiniMap = memo<MiniMapProps>(function MiniMap({\n sceneWidth,\n sceneDepth,\n sceneType,\n floorPolygon,\n cameraPosition,\n targetPosition,\n position = 'bottom-left',\n}) {\n const mapSize = 150 // tamaño del minimap en px\n const padding = 10\n\n // Calcular escala para que el contenido quepa en el minimap\n const scale = useMemo(() => {\n const maxDimension = Math.max(sceneWidth, sceneDepth)\n return (mapSize - padding * 2) / maxDimension\n }, [sceneWidth, sceneDepth])\n\n // Convertir coordenadas de mundo a coordenadas del minimap\n const worldToMap = (x: number, z: number): { x: number; y: number } => {\n return {\n x: padding + x * scale,\n y: padding + z * scale,\n }\n }\n\n // Path del polígono para warehouse\n const polygonPath = useMemo(() => {\n if (sceneType !== 'warehouse' || !floorPolygon || floorPolygon.length === 0) {\n return ''\n }\n\n const points = floorPolygon.map((p) => {\n const mapped = worldToMap(p.x, p.z)\n return `${mapped.x},${mapped.y}`\n })\n\n return `M ${points.join(' L ')} Z`\n }, [sceneType, floorPolygon, scale])\n\n // Rectángulo para truck\n const truckRect = useMemo(() => {\n if (sceneType !== 'truck') return null\n const topLeft = worldToMap(0, 0)\n return {\n x: topLeft.x,\n y: topLeft.y,\n width: sceneWidth * scale,\n height: sceneDepth * scale,\n }\n }, [sceneType, sceneWidth, sceneDepth, scale])\n\n // Posiciones de cámara y target en minimap\n const cameraMapPos = cameraPosition ? worldToMap(cameraPosition.x, cameraPosition.z) : null\n const targetMapPos = targetPosition ? worldToMap(targetPosition.x, targetPosition.z) : null\n\n return (\n <div className={`minimap minimap--${position}`}>\n <div className=\"minimap__title\">Mapa</div>\n <svg\n className=\"minimap__canvas\"\n width={mapSize}\n height={mapSize}\n viewBox={`0 0 ${mapSize} ${mapSize}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Fondo */}\n <rect width={mapSize} height={mapSize} fill=\"#1a1a2e\" />\n\n {/* Escena: Warehouse (polígono) o Truck (rectángulo) */}\n {sceneType === 'warehouse' && polygonPath && (\n <path d={polygonPath} fill=\"rgba(96, 165, 250, 0.15)\" stroke=\"#60a5fa\" strokeWidth=\"2\" />\n )}\n\n {sceneType === 'truck' && truckRect && (\n <rect\n x={truckRect.x}\n y={truckRect.y}\n width={truckRect.width}\n height={truckRect.height}\n fill=\"rgba(96, 165, 250, 0.15)\"\n stroke=\"#60a5fa\"\n strokeWidth=\"2\"\n />\n )}\n\n {/* Grid */}\n <defs>\n <pattern\n id=\"minimap-grid\"\n width={scale}\n height={scale}\n patternUnits=\"userSpaceOnUse\"\n >\n <path\n d={`M ${scale} 0 L 0 0 0 ${scale}`}\n fill=\"none\"\n stroke=\"rgba(255, 255, 255, 0.08)\"\n strokeWidth=\"0.5\"\n />\n </pattern>\n </defs>\n {sceneType === 'truck' && truckRect && (\n <rect\n x={truckRect.x}\n y={truckRect.y}\n width={truckRect.width}\n height={truckRect.height}\n fill=\"url(#minimap-grid)\"\n />\n )}\n\n {/* Target (punto de enfoque) */}\n {targetMapPos && (\n <g>\n <circle cx={targetMapPos.x} cy={targetMapPos.y} r=\"3\" fill=\"#f87171\" opacity=\"0.6\" />\n <circle cx={targetMapPos.x} cy={targetMapPos.y} r=\"5\" fill=\"none\" stroke=\"#f87171\" strokeWidth=\"1.5\" />\n </g>\n )}\n\n {/* Cámara */}\n {cameraMapPos && (\n <g>\n <circle cx={cameraMapPos.x} cy={cameraMapPos.y} r=\"4\" fill=\"#60a5fa\" />\n {/* Línea desde cámara a target */}\n {targetMapPos && (\n <line\n x1={cameraMapPos.x}\n y1={cameraMapPos.y}\n x2={targetMapPos.x}\n y2={targetMapPos.y}\n stroke=\"#60a5fa\"\n strokeWidth=\"1\"\n strokeDasharray=\"2,2\"\n opacity=\"0.6\"\n />\n )}\n </g>\n )}\n </svg>\n\n {/* Leyenda */}\n <div className=\"minimap__legend\">\n <div className=\"minimap__legend-item\">\n <span className=\"minimap__legend-dot minimap__legend-dot--camera\"></span>\n <span className=\"minimap__legend-text\">Cámara</span>\n </div>\n <div className=\"minimap__legend-item\">\n <span className=\"minimap__legend-dot minimap__legend-dot--target\"></span>\n <span className=\"minimap__legend-text\">Objetivo</span>\n </div>\n </div>\n </div>\n )\n})\n","/**\n * useCameraPosition — Hook para rastrear la posición de la cámara en tiempo real\n */\n\nimport { useEffect, useState } from 'react'\nimport { useThree } from '@react-three/fiber'\n\nexport interface CameraPosition {\n x: number\n y: number\n z: number\n}\n\nexport function useCameraPosition(): CameraPosition {\n const { camera } = useThree()\n const [position, setPosition] = useState<CameraPosition>({\n x: camera.position.x,\n y: camera.position.y,\n z: camera.position.z,\n })\n\n useEffect(() => {\n let frameId: number\n\n const updatePosition = () => {\n setPosition({\n x: camera.position.x,\n y: camera.position.y,\n z: camera.position.z,\n })\n frameId = requestAnimationFrame(updatePosition)\n }\n\n frameId = requestAnimationFrame(updatePosition)\n\n return () => {\n if (frameId) {\n cancelAnimationFrame(frameId)\n }\n }\n }, [camera])\n\n return position\n}\n","/**\n * CameraTracker — Componente interno para rastrear la posición de cámara\n * y pasarla a componentes externos\n */\n\nimport { useEffect } from 'react'\nimport { useCameraPosition } from '@/hooks/useCameraPosition'\n\nexport interface CameraTrackerProps {\n onPositionChange: (position: { x: number; y: number; z: number }) => void\n}\n\nexport function CameraTracker({ onPositionChange }: CameraTrackerProps) {\n const position = useCameraPosition()\n\n useEffect(() => {\n onPositionChange(position)\n }, [position, onPositionChange])\n\n return null\n}\n","/**\n * PalletScene — Escena completa para un palet individual\n * Canvas + iluminación + CameraControls + StackedPallet\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport * as THREE from 'three'\nimport type { StackedPallet } from '@/core/entities/StackedPallet'\nimport { getStackedPalletTotalHeight } from '@/core/entities/StackedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface PalletSceneProps {\n stackedPallet: StackedPallet\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n cameraPreset?: CameraPreset\n showGrid?: boolean\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const PalletScene = memo<PalletSceneProps>(function PalletScene({\n stackedPallet,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n cameraPreset = 'perspective',\n showGrid = true,\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const s = UNITS.MM_TO_M\n const basePallet = stackedPallet.floors[0]?.pallet\n \n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n \n // Dimensiones del palet para cálculo de cámara adaptativa\n const sceneSize = useMemo(() => {\n if (!basePallet) return { width: 1.2, height: 1, depth: 0.8 }\n return {\n width: basePallet.dimensions.width * s,\n height: getStackedPalletTotalHeight(stackedPallet) * s,\n depth: basePallet.dimensions.depth * s,\n }\n }, [basePallet, stackedPallet, s])\n \n // Memorizar el target para evitar recreaciones\n const target = useMemo<[number, number, number]>(() => {\n const centerX = basePallet ? (basePallet.dimensions.width * s) / 2 : 0\n const centerZ = basePallet ? (basePallet.dimensions.depth * s) / 2 : 0\n const centerY = sceneSize.height / 2\n return [centerX, centerY, centerZ]\n }, [basePallet, s, sceneSize.height])\n \n // Posición inicial de cámara optimizada\n const initialCameraPosition = useMemo<[number, number, number]>(() => {\n const diagonal = Math.sqrt(\n sceneSize.width ** 2 + sceneSize.height ** 2 + sceneSize.depth ** 2\n )\n const distance = diagonal * 3.5\n return [\n target[0] + distance * 0.7,\n target[1] + distance * 0.6,\n target[2] + distance * 0.7,\n ]\n }, [target, sceneSize])\n\n // Grid rectangular personalizado del tamaño del pallet\n const gridGeometry = useMemo(() => {\n if (!showGrid || !basePallet) return null\n \n const pw = basePallet.dimensions.width * s\n const pd = basePallet.dimensions.depth * s\n const spacing = 0.2 // 200mm entre líneas (más fino para palets individuales)\n const y = 0.001\n const positions: number[] = []\n \n // Líneas verticales (eje X)\n for (let x = 0; x <= pw; x += spacing) {\n positions.push(x, y, 0, x, y, pd)\n }\n \n // Líneas horizontales (eje Z)\n for (let z = 0; z <= pd; z += spacing) {\n positions.push(0, y, z, pw, y, z)\n }\n \n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))\n return geo\n }, [showGrid, basePallet, s])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 100 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n {/* Iluminación */}\n <ambientLight intensity={0.4} />\n <directionalLight\n position={[5, 8, 5]}\n intensity={0.8}\n castShadow\n shadow-mapSize-width={1024}\n shadow-mapSize-height={1024}\n />\n <hemisphereLight intensity={0.3} color=\"#ffffff\" groundColor=\"#444444\" />\n\n {/* Controls */}\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n minDistance={0.3}\n maxDistance={Math.max(sceneSize.width, sceneSize.height, sceneSize.depth) * 4}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n {/* Suelo - ligeramente más grande que el pallet */}\n <mesh rotation={[-Math.PI / 2, 0, 0]} position={[target[0], -0.002, target[2]]} receiveShadow>\n <planeGeometry args={[\n basePallet ? basePallet.dimensions.width * s * 1.5 : 3,\n basePallet ? basePallet.dimensions.depth * s * 1.5 : 3\n ]} />\n <meshStandardMaterial color=\"#e0e0e0\" roughness={0.9} />\n </mesh>\n\n {/* Grid personalizado */}\n {showGrid && gridGeometry && (\n <lineSegments geometry={gridGeometry}>\n <lineBasicMaterial \n color=\"#aaaaaa\" \n opacity={0.5} \n transparent \n depthWrite={false}\n />\n </lineSegments>\n )}\n\n {/* Palet */}\n <StackedPalletComponent\n stackedPallet={stackedPallet}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n\n {/* Custom children */}\n {children}\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && basePallet && (\n <MiniMap\n sceneWidth={sceneSize.width}\n sceneDepth={sceneSize.depth}\n sceneType=\"truck\"\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n","/**\n * TruckScene — Escena completa de un camión con palets cargados\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport type { Truck } from '@/core/entities/Truck'\nimport type { PlacedPallet } from '@/core/entities/PlacedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { TruckEnvironment } from '@/components/environments/TruckEnvironment'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { validatePalletInTruck } from '@/core/validation/bounds'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface TruckSceneProps {\n truck: Truck\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n /** Mostrar/ocultar el grid del suelo del remolque */\n showGrid?: boolean\n /** Opacidad de las paredes (0-1). Por defecto: 0.3 */\n wallOpacity?: number\n /** Mostrar/ocultar el techo. Por defecto: false */\n showRoof?: boolean\n /** Mostrar/ocultar paredes laterales. Por defecto: true */\n showSideWalls?: boolean\n cameraPreset?: CameraPreset\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const TruckScene = memo<TruckSceneProps>(function TruckScene({\n truck,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n showGrid,\n wallOpacity = 0.3,\n showRoof = false,\n showSideWalls = true,\n cameraPreset = 'perspective',\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n const s = UNITS.MM_TO_M\n const w = truck.dimensions.width * s\n const h = truck.dimensions.height * s\n const d = truck.dimensions.depth * s\n \n // Memorizar el target (centro de la zona de carga)\n const target = useMemo<[number, number, number]>(\n () => [w / 2, h / 2, d / 2],\n [w, h, d],\n )\n \n // Tamaño de la escena para cálculo de cámara adaptativa\n const sceneSize = useMemo(\n () => ({ width: w, height: h, depth: d }),\n [w, h, d],\n )\n \n // Calcular posición inicial de cámara basada en el tamaño del camión\n const initialCameraPosition = useMemo<[number, number, number]>(() => {\n // Vista elevada ligeramente hacia el interior para mejor visualización\n return [w * 0.8, h * 1.2, d * 0.4]\n }, [w, h, d])\n\n // Filtrar palets válidos - no renderizar los que estén fuera del camión\n const validPallets = useMemo<PlacedPallet[]>(() => {\n return truck.pallets.filter(pp => {\n const validation = validatePalletInTruck(pp, truck)\n if (!validation.isValid) {\n console.error(\n `[TruckScene] Palet \"${pp.id}\" fuera de los límites del camión.`,\n 'Violaciones:',\n validation.violations,\n )\n return false\n }\n return true\n })\n }, [truck])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 200 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n maxDistance={Math.max(w, h, d) * 3}\n minDistance={0.5}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n <TruckEnvironment \n truck={truck} \n showGrid={showGrid}\n wallOpacity={wallOpacity}\n showRoof={showRoof}\n showSideWalls={showSideWalls}\n >\n {validPallets.map(pp => (\n <StackedPalletComponent\n key={pp.id}\n stackedPallet={pp.stackedPallet}\n position={pp.position}\n yRotation={pp.yRotation}\n palletId={pp.id}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n ))}\n {children}\n </TruckEnvironment>\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && (\n <MiniMap\n sceneWidth={w}\n sceneDepth={d}\n sceneType=\"truck\"\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n","/**\n * WarehouseScene — Escena completa de un almacén con estancias y palets\n */\n\nimport { memo, useMemo, useState, useCallback, type ReactNode } from 'react'\nimport { Canvas } from '@react-three/fiber'\nimport type { Room } from '@/core/entities/Room'\nimport type { PlacedPallet } from '@/core/entities/PlacedPallet'\nimport type { CameraPreset } from '@/components/controls/CameraControls'\nimport type { ScenePreset } from '@/core/presets'\nimport { CameraControlsComponent, MiniMap, CameraTracker } from '@/components/controls'\nimport { WarehouseEnvironment } from '@/components/environments/WarehouseEnvironment'\nimport { StackedPalletComponent } from '@/components/primitives/StackedPallet'\nimport { validatePalletInRoom } from '@/core/validation/polygon'\nimport { PresetProvider } from '@/context/PresetContext'\nimport { UNITS } from '@/core/constants'\n\nexport interface WarehouseSceneProps {\n room: Room\n /** ID de preset ('unstyled' | 'industrial') o un ScenePreset custom */\n preset?: string | ScenePreset\n selectedBoxId?: string | null\n highlightedBoxId?: string | null\n /** Color del borde de selección (override del preset) */\n selectedColor?: string\n /** Color del borde de highlight/hover (override del preset) */\n highlightedColor?: string\n showLabels?: boolean\n cameraPreset?: CameraPreset\n /** Mostrar mini-mapa (por defecto: false) */\n showMiniMap?: boolean\n onBoxClick?: (id: string) => void\n onBoxHover?: (id: string | null) => void\n children?: ReactNode\n style?: React.CSSProperties\n}\n\nexport const WarehouseScene = memo<WarehouseSceneProps>(function WarehouseScene({\n room,\n preset,\n selectedBoxId,\n highlightedBoxId,\n selectedColor,\n highlightedColor,\n showLabels = false,\n cameraPreset = 'perspective',\n showMiniMap = false,\n onBoxClick,\n onBoxHover,\n children,\n style,\n}) {\n const s = UNITS.MM_TO_M\n \n const [cameraPosition, setCameraPosition] = useState<{ x: number; z: number }>({ x: 0, z: 0 })\n\n const handleCameraPositionChange = useCallback((pos: { x: number; y: number; z: number }) => {\n setCameraPosition({ x: pos.x, z: pos.z })\n }, [])\n \n // Calcular bounding box del almacén\n const { target, sceneSize, initialCameraPosition } = useMemo(() => {\n const pts = room.floorPolygon\n let minX = Infinity, maxX = -Infinity\n let minZ = Infinity, maxZ = -Infinity\n \n for (const p of pts) {\n minX = Math.min(minX, p.x * s)\n maxX = Math.max(maxX, p.x * s)\n minZ = Math.min(minZ, p.z * s)\n maxZ = Math.max(maxZ, p.z * s)\n }\n \n const width = maxX - minX\n const depth = maxZ - minZ\n const height = room.ceilingHeight * s\n const cx = (minX + maxX) / 2\n const cz = (minZ + maxZ) / 2\n \n // Target en el centro del almacén, a media altura\n const targetPos: [number, number, number] = [cx, height / 2, cz]\n \n // Tamaño de la escena\n const size = { width, height, depth }\n \n // Posición inicial de cámara (vista isométrica)\n const diagonal = Math.sqrt(width ** 2 + height ** 2 + depth ** 2)\n const distance = diagonal * 0.8\n const initialPos: [number, number, number] = [\n cx + distance * 0.6,\n height + distance * 0.5,\n cz + distance * 0.6,\n ]\n \n return {\n target: targetPos,\n sceneSize: size,\n initialCameraPosition: initialPos,\n }\n }, [room.floorPolygon, room.ceilingHeight, s])\n\n // Convertir polígono para MiniMap (metros a escala del mundo)\n const floorPolygonForMap = useMemo(() => {\n return room.floorPolygon.map(p => ({ x: p.x * s, z: p.z * s }))\n }, [room.floorPolygon, s])\n\n // Filtrar palets válidos - no renderizar los que estén fuera de la estancia\n const validPallets = useMemo<PlacedPallet[]>(() => {\n return room.pallets.filter(pp => {\n const validation = validatePalletInRoom(pp, room)\n if (!validation.isValid) {\n console.error(\n `[WarehouseScene] Palet \"${pp.id}\" fuera de los límites de la estancia \"${room.name}\".`,\n 'Violaciones:',\n validation.violations,\n )\n return false\n }\n return true\n })\n }, [room])\n\n return (\n <div style={{ position: 'relative', width: '100%', height: '100%' }}>\n <Canvas\n shadows\n camera={{ \n position: initialCameraPosition, \n fov: 45, \n near: 0.01, \n far: 300 \n }}\n style={{ width: '100%', height: '100%', ...style }}\n >\n <PresetProvider preset={preset}>\n <CameraControlsComponent\n preset={cameraPreset}\n target={target}\n sceneSize={sceneSize}\n maxDistance={Math.max(sceneSize.width, sceneSize.height, sceneSize.depth) * 4}\n minDistance={0.5}\n />\n <CameraTracker onPositionChange={handleCameraPositionChange} />\n\n <WarehouseEnvironment room={room}>\n {validPallets.map(pp => (\n <StackedPalletComponent\n key={pp.id}\n stackedPallet={pp.stackedPallet}\n position={pp.position}\n yRotation={pp.yRotation}\n palletId={pp.id}\n selectedBoxId={selectedBoxId}\n highlightedBoxId={highlightedBoxId}\n selectedColor={selectedColor}\n highlightedColor={highlightedColor}\n showLabels={showLabels}\n onBoxClick={onBoxClick}\n onBoxHover={onBoxHover}\n />\n ))}\n {children}\n </WarehouseEnvironment>\n </PresetProvider>\n </Canvas>\n\n {showMiniMap && (\n <MiniMap\n sceneWidth={sceneSize.width}\n sceneDepth={sceneSize.depth}\n sceneType=\"warehouse\"\n floorPolygon={floorPolygonForMap}\n cameraPosition={cameraPosition}\n targetPosition={{ x: target[0], z: target[2] }}\n position=\"bottom-left\"\n />\n )}\n </div>\n )\n})\n"],"names":["PalletMaterial","SeparatorMaterial","TruckType","STANDARD_PALLETS","TRUCK_PRESETS","SEPARATOR_DEFAULTS","UNITS","COLLISION_TOLERANCE","MIN_SUPPORT_PERCENTAGE","WEIGHT_WARNING_THRESHOLD","PRESET_UNSTYLED","PRESET_INDUSTRIAL","SCENE_PRESETS","DEFAULT_PRESET","REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","PresetContext","createContext","PresetProvider","preset","resolved","useMemo","usePreset","useContext","getStackedPalletTotalHeight","stack","height","floor","maxBoxTop","max","pb","boxTop","getStackedPalletTotalWeight","weight","sum","ensureUniqueBoxIds","contextId","baseId","normalizedFloors","floorIdx","normalizedBoxes","boxIdx","uniqueId","updateRefs","refs","refId","refBoxIdx","b","getBoxBoundingBox","w","d","h","getPalletBoundingBox","pp","basePallet","totalH","rotRad","cos","sin","worldCorners","corner","minX","c","maxX","minZ","maxZ","aabbIntersects","a","tolerance","validateNoBoxCollisions","boxes","violations","i","j","bbA","bbB","validateNoPalletCollisions","pallets","validateBoxInPalletBounds","box","pallet","bb","validateAllBoxesInPalletBounds","result","validatePalletInTruck","truck","td","validatePalletHeight","ceilingHeight","validatePalletWeight","totalBoxWeight","maxWeight","v","validateTruckWeight","totalWeight","validateFragileLoad","maxAbove","weightAbove","calculateWeightAboveBox","target","allBoxes","tbb","other","obb","validateWeightDistribution","s","cogX","cogZ","cx","cz","centerX","centerZ","validateBoxStackability","validateInvertedPyramid","bottom","bbb","bottomArea","top","topArea","validateStackDimensions","base","p","validateSeparators","validateStackHeight","containerHeight","validateStackWeight","baseMaxWeight","loadWeight","validateSupport","boxArea","supportedArea","overlapX","overlapZ","calculateCenterOfGravity","cogY","cy","calculateStabilityScore","cog","dx","dz","horizontalScore","maxBoxY","heightRatio","verticalScore","validateCogInsideSupport","validateStability","score","maxY","pointInPolygon","point","polygon","inside","n","xi","zi","xj","zj","validatePalletInRoom","room","corners","ColumnStrategy","placements","unplacedBoxes","groups","cursorX","placementId","groupBoxes","refBox","colWidth","colDepth","boxHeight","cursorZ","cursorY","palletVolume","usedVolume","stability","BinPacking3DStrategy","sorted","va","spaces","placed","orientations","si","space","ori","newPlacement","newBB","existing","TypeGroupStrategy","typeA","typeB","layerMaxHeight","MaterialGroupingStrategy","sortedBoxes","materialGroups","layer","metrics","weightA","weightB","productA","productB","areaA","areaB","layers","occupiedColumns","allPlacements","currentY","remainingBoxes","placedIds","availableBoxes","allPreviousPlacements","uniformLayer","mixedLayer","heightGroups","sortedHeights","boxesOfHeight","targetHeight","freeRectangles","sortedGroups","product","productBoxes","validBoxes","orientation","allPlacementsForSupport","bestRect","placement","palletArea","usedArea","maxHeight","boxDims","existingPlacements","bestScore","rect","supportArea","boxBaseArea","x","z","width","depth","boxW","boxD","intersection","x1","z1","w1","d1","x2","z2","w2","d2","boxesDirectlyBelow","boxRight","boxBack","columnKey","wastedArea","freeRects","usedRect","boxWidth","boxDepth","newRects","rectangles","y","PackingRegistry","strategy","id","defaultRegistry","_palletCounter","nextPalletId","PalletFactory","overrides","presetKey","dims","opts","_truckCounter","nextTruckId","TruckFactory","_boxCounter","nextBoxId","BoxFactory","fragilityMaxWeight","usePhysicsValidation","collisions","bounds","gravity","stackability","invertedPyramid","cogValid","fragile","distribution","stackingViolations","stabilityViolations","allViolations","usePalletMetrics","totalHeight","f","boxCount","floorCount","totalVolume","usePackingStrategy","strategyId","registry","availableStrategies","pack","useCallback","useWarehouseValidation","roomViolations","placedPallet","BoxComponent","memo","placedBox","selected","highlighted","showLabel","color","opacity","selectedColor","highlightedColor","onClick","onHover","meshRef","useRef","position","rotation","resolvedColor","resolvedOpacity","resolvedSelectedColor","resolvedHighlightedColor","scaledDims","pos","THREE","borderColor","handleClick","e","handlePointerOver","handlePointerOut","jsxs","jsx","Edges","Html","PalletComponent","edgeColor","resolvedEdgeColor","MATERIAL_COLORS","SeparatorComponent","separator","StackedPalletComponent","stackedPallet","yRotation","palletId","selectedBoxId","highlightedBoxId","showLabels","onBoxClick","onBoxHover","normalizedStack","rotationY","floorOffsets","offsets","idx","floorY","palletTopY","Label","text","visible","fontSize","background","WarehouseEnvironment","floorColor","wallColor","showGrid","resolvedFloorColor","resolvedWallColor","resolvedShowGrid","ceilingH","shape","pts","mnX","mxX","mnZ","mxZ","sh","wallGeometry","positions","indices","curr","next","baseIdx","geo","sizeX","sizeZ","gridGeometry","spacing","Wheel","radius","TruckEnvironment","wallOpacity","showRoof","showSideWalls","truckStyle","tw","th","wallThickness","floorThickness","wheelRadius","wheelWidth","groundClearance","chassisH","wheelY","chassisY","remolqueFloorY","cabW","cabD","cabH","cabGap","cabZ","cabFloorY","solidWallMaterial","frac","side","calculatePresetPosition","sceneSize","tx","ty","tz","distance","CameraControlsComponent","autoRotate","enablePan","enableZoom","minDistance","maxDistance","camera","useThree","controlsRef","useEffect","targetPos","targetLookAt","startPos","duration","startTime","animate","elapsed","progress","eased","OrbitControls","PRESET_LABELS","currentPreset","onPresetChange","presets","label","icon","isActive","MiniMap","sceneWidth","sceneDepth","sceneType","floorPolygon","cameraPosition","targetPosition","scale","worldToMap","polygonPath","mapped","truckRect","topLeft","cameraMapPos","targetMapPos","useCameraPosition","setPosition","useState","frameId","updatePosition","CameraTracker","onPositionChange","PalletScene","cameraPreset","showMiniMap","style","setCameraPosition","handleCameraPositionChange","centerY","initialCameraPosition","pw","pd","Canvas","TruckScene","validPallets","validation","WarehouseScene","size","initialPos","floorPolygonForMap"],"mappings":"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","x_google_ignoreList":[3,4,5]}