{
  "schemaVersion": 1,
  "slug": "container-loading-calculator",
  "category": "moving",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "1123142a9e756b6dc184d39bc0d9e85e8c9883330583b55728a0856be691b3e3",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/container-loading-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "N = ⌊L ÷ l⌋ × ⌊W ÷ w⌋ × ⌊H ÷ h⌋; N_real = 0.85 × min(N, ⌊P ÷ m⌋)",
    "vars": [
      [
        "L,W,H",
        "container inner dimensions in cm"
      ],
      [
        "l,w,h",
        "carton dimensions in cm"
      ],
      [
        "P",
        "payload limit in kg"
      ],
      [
        "m",
        "carton weight in kg"
      ],
      [
        "N",
        "theoretical cartons"
      ],
      [
        "N_real",
        "realistic cartons"
      ]
    ],
    "note": "Tests all six unique axis-aligned carton orientations against approximate CMA CGM internal dimensions and payload. The planning estimate applies an 85% allowance to the tighter of grid count and payload limit; it excludes pallets, clearances, equipment, voids, weight balance, and carton strength. Verify actual equipment specs."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const empty={along:null,across:null,high:null,totalCartons:null,realisticCartons:null,weightLimit:null,limitingFactor:null,volumeUsed:null};const fail=()=>({...empty,__error:'inputError'});const dims={'20':[590,235,239,30480,28250],'40':[1203,235,240,32500,26760],'40hc':[1203,235,270,32500,26760],'45hc':[1356,235,270,30480,25780]};const cont=dims[containerType],box=[Number(boxLength),Number(boxWidth),Number(boxHeight)],weight=Number(boxWeight);if(!cont||box.some(v=>!Number.isFinite(v)||v<=0||v>1000)||!Number.isFinite(weight)||weight<=0||weight>10000||!['yes','half','no'].includes(stackable))return fail();const [L,W,H,,payload]=cont;const perms=[...new Set([[box[0],box[1],box[2]],[box[0],box[2],box[1]],[box[1],box[0],box[2]],[box[1],box[2],box[0]],[box[2],box[0],box[1]],[box[2],box[1],box[0]]].map(x=>x.join(',')))].map(s=>s.split(',').map(Number));const fits=perms.filter(([x,y,z])=>x<=L&&y<=W&&z<=H).map(([x,y,z])=>{const maxH=stackable==='no'?z:stackable==='half'?H/2:H;const layers=stackable==='no'?1:Math.max(1,Math.floor(maxH/z));return{along:Math.floor(L/x),across:Math.floor(W/y),high:layers};}).map(a=>({...a,count:a.along*a.across*a.high})).sort((a,b)=>b.count-a.count);if(!fits.length)return fail();const best=fits[0],byWeight=Math.floor(payload/weight),limit=Math.min(best.count,byWeight),realistic=Math.floor(limit*0.85),usedM3=realistic*box[0]*box[1]*box[2]/1000000;return{along:best.along,across:best.across,high:best.high,totalCartons:best.count,realisticCartons:realistic,weightLimit:byWeight,limitingFactor:byWeight<best.count?'Weight limit reached first':'Space limit reached first',volumeUsed:usedM3};",
    "inputs": [
      {
        "name": "containerType",
        "type": "select",
        "default": "40hc",
        "options": [
          {
            "value": "20"
          },
          {
            "value": "40"
          },
          {
            "value": "40hc"
          },
          {
            "value": "45hc"
          }
        ]
      },
      {
        "name": "boxLength",
        "type": "number",
        "default": 60,
        "step": 0.1
      },
      {
        "name": "boxWidth",
        "type": "number",
        "default": 40,
        "step": 0.1
      },
      {
        "name": "boxHeight",
        "type": "number",
        "default": 40,
        "step": 0.1
      },
      {
        "name": "boxWeight",
        "type": "number",
        "default": 15,
        "step": 0.1
      },
      {
        "name": "stackable",
        "type": "select",
        "default": "yes",
        "options": [
          {
            "value": "yes"
          },
          {
            "value": "half"
          },
          {
            "value": "no"
          }
        ]
      }
    ],
    "outputs": [
      {
        "name": "along",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "across",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "high",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "totalCartons",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "realisticCartons",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "weightLimit",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "limitingFactor",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "volumeUsed",
        "precision": 2,
        "unit": "m³"
      }
    ],
    "interpret": null
  }
}
