{"id":13454,"date":"2025-02-16T07:35:26","date_gmt":"2025-02-15T23:35:26","guid":{"rendered":"https:\/\/stooper.co\/?page_id=13454"},"modified":"2026-05-07T18:46:39","modified_gmt":"2026-05-07T10:46:39","slug":"incoterms-tools-2","status":"publish","type":"page","link":"https:\/\/stooper.co\/ms\/cbm-cargo-measurement-calculator\/","title":{"rendered":"Kalkulator 3D CBM dan Ukuran Kargo"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"13454\" class=\"elementor elementor-13454\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ae32bce e-con-full e-flex e-con e-parent\" data-id=\"ae32bce\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2addd96 e-flex e-con-boxed e-con e-parent\" data-id=\"2addd96\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-73eeb6c e-flex e-con-boxed e-con e-child\" data-id=\"73eeb6c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bf9df1e elementor-widget elementor-widget-heading\" data-id=\"bf9df1e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">3D CBM &amp; Cargo Measurement Calculator<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d4be337 elementor-widget elementor-widget-text-editor\" data-id=\"d4be337\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"0\" data-end=\"254\">Use this free CBM calculator to calculate cargo volume for cartons, pallets, bags, barrels, and other shipment packaging. CBM means cubic meter, which is commonly used in logistics, sea freight, air freight, warehouse planning, and container loading.<\/p><p data-start=\"256\" data-end=\"445\">Simply enter the length, width, height, unit, quantity, and weight of your cargo. The calculator will show the total CBM, gross weight, air freight volumetric weight, and chargeable weight.<\/p><p data-start=\"447\" data-end=\"716\" data-is-last-node=\"\" data-is-only-node=\"\">This CBM calculator is useful for exporters, importers, freight forwarders, warehouse teams, and business owners who need a fast and simple way to check cargo measurement before shipment. The 3D preview also helps users understand the cargo dimensions more clearly.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-f49427a e-flex e-con-boxed e-con e-parent\" data-id=\"f49427a\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-8386ce4 e-flex e-con-boxed e-con e-child\" data-id=\"8386ce4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e7ac3eb elementor-widget elementor-widget-html\" data-id=\"e7ac3eb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"stooper-cargo-calculator-v43\" class=\"stp43\">\r\n  <div class=\"stp43-header\">\r\n    <div>\r\n      <div class=\"stp43-kicker\">STOOPER LOGISTICS TOOL<\/div>\r\n      <h2>3D Cargo Measurement Calculator<\/h2>\r\n      <p>Calculate cartons, bags, barrels, pallets, pallet loading, CBM and chargeable weight.<\/p>\r\n    <\/div>\r\n    <div class=\"stp43-actions-top\">\r\n      <button type=\"button\" id=\"stp43-copy\">Copy Result<\/button>\r\n      <button type=\"button\" id=\"stp43-print\">Print<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"stp43-tabs\">\r\n    <button type=\"button\" class=\"active\" data-tab=\"mix\">Mixed Packaging<\/button>\r\n    <button type=\"button\" data-tab=\"pallet\">Pallet Only<\/button>\r\n    <button type=\"button\" data-tab=\"load\">Pallet Loading<\/button>\r\n  <\/div>\r\n\r\n  <div class=\"stp43-main\">\r\n    <div class=\"stp43-left\">\r\n      <div class=\"stp43-section active\" id=\"stp43-section-mix\">\r\n        <div class=\"stp43-toolbar\">\r\n          <button type=\"button\" data-add=\"carton\">+ Add Carton<\/button>\r\n          <button type=\"button\" data-add=\"bag\">+ Add Bag<\/button>\r\n          <button type=\"button\" data-add=\"barrel\">+ Add Barrel<\/button>\r\n        <\/div>\r\n        <div id=\"stp43-mix-list\"><\/div>\r\n      <\/div>\r\n\r\n      <div class=\"stp43-section\" id=\"stp43-section-pallet\">\r\n        <div class=\"stp43-toolbar\">\r\n          <button type=\"button\" data-add-pallet>+ Add Pallet<\/button>\r\n        <\/div>\r\n        <div id=\"stp43-pallet-list\"><\/div>\r\n      <\/div>\r\n\r\n      <div class=\"stp43-section\" id=\"stp43-section-load\">\r\n        <div class=\"stp43-load-card\">\r\n          <h3>Pallet Loading Calculator<\/h3>\r\n          <p>Enter carton size and pallet size. The system estimates cartons per layer, layers, and pallets required.<\/p>\r\n\r\n          <div class=\"stp43-load-grid\">\r\n            <label>Carton Length <input type=\"number\" data-load=\"cartonL\" value=\"50\"><\/label>\r\n            <label>Carton Width <input type=\"number\" data-load=\"cartonW\" value=\"40\"><\/label>\r\n            <label>Carton Height <input type=\"number\" data-load=\"cartonH\" value=\"30\"><\/label>\r\n            <label>Carton Unit\r\n              <select data-load=\"cartonUnit\">\r\n                <option value=\"cm\">CM<\/option>\r\n                <option value=\"mm\">MM<\/option>\r\n                <option value=\"inch\">INCH<\/option>\r\n                <option value=\"m\">METER<\/option>\r\n              <\/select>\r\n            <\/label>\r\n            <label>Total Cartons <input type=\"number\" data-load=\"totalCartons\" value=\"120\"><\/label>\r\n            <label>KG \/ Carton <input type=\"number\" data-load=\"cartonKg\" value=\"10\"><\/label>\r\n            <label>Pallet Length <input type=\"number\" data-load=\"palletL\" value=\"120\"><\/label>\r\n            <label>Pallet Width <input type=\"number\" data-load=\"palletW\" value=\"100\"><\/label>\r\n            <label>Max Loaded Height <input type=\"number\" data-load=\"palletH\" value=\"150\"><\/label>\r\n            <label>Pallet Unit\r\n              <select data-load=\"palletUnit\">\r\n                <option value=\"cm\">CM<\/option>\r\n                <option value=\"mm\">MM<\/option>\r\n                <option value=\"inch\">INCH<\/option>\r\n                <option value=\"m\">METER<\/option>\r\n              <\/select>\r\n            <\/label>\r\n            <label>Max KG \/ Pallet <input type=\"number\" data-load=\"maxPalletKg\" value=\"1000\"><\/label>\r\n          <\/div>\r\n\r\n          <div class=\"stp43-load-result\" id=\"stp43-load-result\"><\/div>\r\n\r\n          <div class=\"stp43-load-visual\">\r\n            <div class=\"stp43-pallet-base\">\r\n              <div id=\"stp43-load-boxes\"><\/div>\r\n            <\/div>\r\n            <div class=\"stp43-load-badge\" id=\"stp43-load-badge\">120 CTNS<\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"stp43-right\">\r\n      <div class=\"stp43-preview-card\">\r\n        <div class=\"stp43-preview-head\">\r\n          <div>\r\n            <strong id=\"stp43-preview-title\">Carton Preview<\/strong>\r\n            <small id=\"stp43-preview-sub\">50 \u00d7 40 \u00d7 30 CM<\/small>\r\n          <\/div>\r\n          <span id=\"stp43-preview-qty\">\u00d7 10<\/span>\r\n        <\/div>\r\n\r\n        <div class=\"stp43-stage is-box\">\r\n          <div id=\"stp43-shape-holder\"><\/div>\r\n\r\n          <div class=\"stp43-measure\">\r\n            <div class=\"stp43-line stp43-length\"><\/div>\r\n            <div class=\"stp43-line stp43-height\"><\/div>\r\n            <div class=\"stp43-line stp43-width\"><\/div>\r\n            <div class=\"stp43-label stp43-label-length\" id=\"stp43-length-label\">L 50 CM<\/div>\r\n            <div class=\"stp43-label stp43-label-height\" id=\"stp43-height-label\">H 30 CM<\/div>\r\n            <div class=\"stp43-label stp43-label-width\" id=\"stp43-width-label\">W 40 CM<\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"stp43-preview-note\" id=\"stp43-preview-note\">\r\n          Click any line item to preview its size and shape.\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"stp43-container-card\">\r\n        <h3>Sea Freight Container Estimate<\/h3>\r\n        <div id=\"stp43-container-estimate\"><\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"stp43-summary\">\r\n    <div><small>Total CBM<\/small><b id=\"stp43-total-cbm\">0.0000<\/b><em>m\u00b3<\/em><\/div>\r\n    <div><small>Total Gross Weight<\/small><b id=\"stp43-total-gw\">0.00<\/b><em>KG<\/em><\/div>\r\n    <div><small>Air Volumetric Weight<\/small><b id=\"stp43-total-air\">0.00<\/b><em>KG<\/em><\/div>\r\n    <div class=\"stp43-gold\"><small>Chargeable Weight<\/small><b id=\"stp43-total-charge\">0.00<\/b><em>KG<\/em><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"stp43-formula\">\r\n    CBM formula: Carton \/ Pallet = L \u00d7 W \u00d7 H. Bag \/ Barrel freight space = Diameter \/ Max Width \u00d7 Diameter \/ Max Width \u00d7 Height.\r\n  <\/div>\r\n<\/div>\r\n\r\n<style>\r\n.stp43{\r\n  max-width:1240px;\r\n  margin:32px auto;\r\n  padding:30px;\r\n  border-radius:32px;\r\n  background:\r\n    radial-gradient(circle at top left,rgba(14,165,233,.28),transparent 34%),\r\n    radial-gradient(circle at bottom right,rgba(250,204,21,.14),transparent 30%),\r\n    linear-gradient(135deg,#020617,#0f172a 52%,#111827);\r\n  color:#fff;\r\n  font-family:Inter,Arial,sans-serif;\r\n  box-shadow:0 36px 95px rgba(2,6,23,.5);\r\n  overflow:hidden;\r\n}\r\n.stp43 *{box-sizing:border-box;}\r\n.stp43-header{display:flex;justify-content:space-between;align-items:flex-start;gap:18px;margin-bottom:22px;}\r\n.stp43-kicker{color:#38bdf8;font-size:12px;font-weight:900;letter-spacing:.1em;margin-bottom:8px;}\r\n.stp43 h2{margin:0;font-size:34px;line-height:1.12;}\r\n.stp43-header p{margin:10px 0 0;color:#cbd5e1;}\r\n.stp43-actions-top,.stp43-tabs,.stp43-toolbar{display:flex;gap:10px;flex-wrap:wrap;}\r\n.stp43-tabs{margin-bottom:18px;}\r\n.stp43-actions-top button,.stp43-tabs button,.stp43-toolbar button{\r\n  border:0;border-radius:14px;padding:12px 17px;cursor:pointer;font-weight:900;background:#1e293b;color:#e5e7eb;transition:.2s ease;\r\n}\r\n.stp43-actions-top button{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.14);}\r\n.stp43-tabs button.active,.stp43-tabs button:hover,.stp43-toolbar button:hover,.stp43-actions-top button:hover{background:#38bdf8;color:#020617;}\r\n.stp43-main{display:grid;grid-template-columns:1.35fr .85fr;gap:22px;}\r\n.stp43-section{display:none;}\r\n.stp43-section.active{display:block;}\r\n.stp43-toolbar{margin-bottom:14px;}\r\n\r\n.stp43-row{\r\n  padding:16px;margin-bottom:12px;border-radius:22px;background:rgba(255,255,255,.075);\r\n  border:1px solid rgba(255,255,255,.12);cursor:pointer;transition:.18s ease;\r\n}\r\n.stp43-row:hover,.stp43-row.active{border-color:rgba(56,189,248,.58);box-shadow:0 0 0 3px rgba(56,189,248,.12);}\r\n.stp43-row-top{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:14px;}\r\n.stp43-row-name{font-weight:900;}\r\n.stp43-row-chip{\r\n  font-size:12px;color:#bae6fd;background:rgba(56,189,248,.12);border:1px solid rgba(56,189,248,.28);\r\n  padding:5px 9px;border-radius:999px;white-space:nowrap;\r\n}\r\n.stp43-fields{display:grid;grid-template-columns:1.15fr repeat(6,1fr) 42px;gap:10px;align-items:end;}\r\n.stp43-fields.round{grid-template-columns:1.15fr repeat(5,1fr) 42px;}\r\n.stp43-fields label,.stp43-load-grid label{display:block;color:#cbd5e1;font-size:12px;font-weight:800;}\r\n.stp43-fields input,.stp43-fields select,.stp43-load-grid input,.stp43-load-grid select{\r\n  width:100%;margin-top:6px;padding:11px 10px;border-radius:13px;background:#020617;\r\n  border:1px solid rgba(148,163,184,.35);color:#fff;outline:none;\r\n}\r\n.stp43-fields input:focus,.stp43-fields select:focus,.stp43-load-grid input:focus,.stp43-load-grid select:focus{\r\n  border-color:#38bdf8;box-shadow:0 0 0 3px rgba(56,189,248,.13);\r\n}\r\n.stp43-remove{width:42px;height:42px;border:0;border-radius:13px;background:#7f1d1d;color:#fff;font-size:22px;cursor:pointer;}\r\n.stp43-row-result{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px;}\r\n.stp43-row-result div{padding:10px 12px;border-radius:14px;background:rgba(2,6,23,.45);border:1px solid rgba(255,255,255,.08);}\r\n.stp43-row-result small{display:block;color:#94a3b8;font-size:11px;}\r\n.stp43-row-result b{color:#f8fafc;font-size:15px;}\r\n\r\n.stp43-preview-card,.stp43-container-card,.stp43-load-card{\r\n  border-radius:24px;background:linear-gradient(180deg,rgba(15,23,42,.88),rgba(2,6,23,.96));\r\n  border:1px solid rgba(255,255,255,.12);overflow:hidden;\r\n}\r\n.stp43-preview-head{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:16px 18px;border-bottom:1px solid rgba(255,255,255,.1);}\r\n.stp43-preview-head strong{display:block;font-size:16px;}\r\n.stp43-preview-head small{display:block;color:#cbd5e1;margin-top:3px;}\r\n#stp43-preview-qty{\r\n  padding:6px 10px;border-radius:999px;background:rgba(250,204,21,.12);color:#fde68a;\r\n  border:1px solid rgba(250,204,21,.32);font-weight:900;\r\n}\r\n.stp43-stage{\r\n  height:330px;position:relative;display:flex;align-items:center;justify-content:center;\r\n  background:radial-gradient(circle at center,rgba(56,189,248,.12),transparent 45%),linear-gradient(180deg,rgba(30,41,59,.45),rgba(2,6,23,.9));\r\n}\r\n#stp43-shape-holder{position:relative;z-index:2;width:240px;height:200px;display:flex;align-items:center;justify-content:center;}\r\n.stp43-iso-box{position:relative;width:var(--bw);height:var(--bh);transform-style:preserve-3d;transform:rotateX(-18deg) rotateY(35deg);}\r\n.stp43-iso-box .face{\r\n  position:absolute;top:0;left:0;border:2px solid rgba(255,255,255,.36);\r\n  background:linear-gradient(135deg,#facc15,#fb923c);box-shadow:inset 0 0 35px rgba(255,255,255,.16);\r\n}\r\n.stp43-iso-box .front,.stp43-iso-box .back{width:var(--bw);height:var(--bh);}\r\n.stp43-iso-box .front{transform:translateZ(calc(var(--bd) \/ 2));}\r\n.stp43-iso-box .back{transform:rotateY(180deg) translateZ(calc(var(--bd) \/ 2));}\r\n.stp43-iso-box .right,.stp43-iso-box .left{width:var(--bd);height:var(--bh);left:calc((var(--bw) - var(--bd)) \/ 2);}\r\n.stp43-iso-box .right{transform:rotateY(90deg) translateZ(calc(var(--bw) \/ 2));}\r\n.stp43-iso-box .left{transform:rotateY(-90deg) translateZ(calc(var(--bw) \/ 2));}\r\n.stp43-iso-box .top,.stp43-iso-box .bottom{width:var(--bw);height:var(--bd);top:calc((var(--bh) - var(--bd)) \/ 2);}\r\n.stp43-iso-box .top{transform:rotateX(90deg) translateZ(calc(var(--bh) \/ 2));}\r\n.stp43-iso-box .bottom{transform:rotateX(-90deg) translateZ(calc(var(--bh) \/ 2));}\r\n.stp43-iso-pallet .face{background:linear-gradient(135deg,#c08457,#92400e);}\r\n\r\n.stp43-bag{\r\n  width:120px;height:165px;border-radius:42% 42% 34% 34%;background:linear-gradient(135deg,#43d03f,#69dc2a);\r\n  box-shadow:inset 0 0 38px rgba(255,255,255,.18),0 28px 50px rgba(0,0,0,.28);\r\n  position:relative;transform:rotateX(-8deg) rotateY(15deg);\r\n}\r\n.stp43-bag:before{content:\"\";position:absolute;top:18px;left:18px;right:18px;height:20px;border-radius:50%;background:rgba(255,255,255,.15);}\r\n.stp43-bag:after{content:\"\";position:absolute;bottom:14px;left:16px;right:16px;height:10px;border-radius:50%;background:rgba(0,0,0,.12);}\r\n.stp43-barrel{\r\n  width:105px;height:165px;border-radius:55px;background:linear-gradient(90deg,#60a5fa,#2563eb 48%,#60a5fa);\r\n  box-shadow:inset 0 0 38px rgba(255,255,255,.2),0 28px 50px rgba(0,0,0,.28);\r\n  position:relative;transform:rotateX(-10deg) rotateY(18deg);\r\n}\r\n.stp43-barrel:before,.stp43-barrel:after{\r\n  content:\"\";position:absolute;left:6px;right:6px;height:26px;border-radius:50%;\r\n  border:2px solid rgba(255,255,255,.35);background:rgba(255,255,255,.12);\r\n}\r\n.stp43-barrel:before{top:4px;}\r\n.stp43-barrel:after{bottom:4px;}\r\n\r\n.stp43-measure{position:absolute;inset:0;pointer-events:none;z-index:3;}\r\n.stp43-line{position:absolute;border-color:rgba(226,232,240,.82);}\r\n.stp43-line:before,.stp43-line:after{\r\n  content:\"\";position:absolute;width:8px;height:8px;border-radius:50%;background:#38bdf8;box-shadow:0 0 10px rgba(56,189,248,.7);\r\n}\r\n.stp43-label{\r\n  position:absolute;padding:6px 10px;border-radius:999px;background:rgba(2,6,23,.88);\r\n  border:1px solid rgba(148,163,184,.35);color:#f8fafc;font-size:12px;font-weight:900;white-space:nowrap;\r\n}\r\n.stp43-length{left:23%;right:23%;bottom:52px;border-top:2px dashed rgba(226,232,240,.82);}\r\n.stp43-length:before{left:-2px;top:-5px;}\r\n.stp43-length:after{right:-2px;top:-5px;}\r\n.stp43-label-length{left:50%;bottom:22px;transform:translateX(-50%);}\r\n.stp43-height{top:74px;bottom:76px;right:70px;border-left:2px dashed rgba(226,232,240,.82);}\r\n.stp43-height:before{left:-5px;top:-2px;}\r\n.stp43-height:after{left:-5px;bottom:-2px;}\r\n.stp43-label-height{right:16px;top:50%;transform:translateY(-50%);}\r\n\r\n.stp43-stage.is-box .stp43-width{\r\n  width:105px;top:118px;right:118px;border-top:2px dashed rgba(226,232,240,.82);\r\n  transform:rotate(-20deg);transform-origin:left center;\r\n}\r\n.stp43-stage.is-box .stp43-width:before{left:-2px;top:-5px;}\r\n.stp43-stage.is-box .stp43-width:after{right:-2px;top:-5px;}\r\n.stp43-stage.is-box .stp43-label-width{top:86px;right:145px;}\r\n\r\n.stp43-stage.is-round .stp43-length,.stp43-stage.is-round .stp43-label-length{display:none!important;}\r\n.stp43-stage.is-round .stp43-width{\r\n  width:125px;left:50%;top:145px;right:auto;border-top:2px dashed rgba(226,232,240,.82);\r\n  transform:translateX(-50%);\r\n}\r\n.stp43-stage.is-round .stp43-width:before{left:-2px;top:-5px;}\r\n.stp43-stage.is-round .stp43-width:after{right:-2px;top:-5px;}\r\n.stp43-stage.is-round .stp43-label-width{left:50%;top:108px;right:auto;transform:translateX(-50%);}\r\n.stp43-stage.is-round .stp43-height{top:82px;bottom:72px;right:70px;}\r\n.stp43-stage.is-round .stp43-label-height{right:18px;top:50%;transform:translateY(-50%);}\r\n\r\n.stp43-preview-note{padding:14px 18px;color:#94a3b8;font-size:13px;border-top:1px solid rgba(255,255,255,.08);}\r\n.stp43-container-card{margin-top:14px;padding:18px;}\r\n.stp43-container-card h3,.stp43-load-card h3{margin:0 0 8px;font-size:18px;}\r\n.stp43-container-line{margin-top:10px;}\r\n.stp43-container-top{display:flex;justify-content:space-between;color:#e5e7eb;font-size:13px;margin-bottom:6px;}\r\n.stp43-bar{height:10px;border-radius:999px;background:rgba(148,163,184,.16);overflow:hidden;}\r\n.stp43-bar span{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#38bdf8,#facc15);}\r\n\r\n.stp43-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:20px;}\r\n.stp43-summary div{padding:18px;border-radius:20px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);}\r\n.stp43-summary small{display:block;color:#cbd5e1;margin-bottom:8px;}\r\n.stp43-summary b{font-size:28px;}\r\n.stp43-summary em{color:#94a3b8;font-style:normal;margin-left:5px;}\r\n.stp43-summary .stp43-gold{background:linear-gradient(135deg,rgba(250,204,21,.22),rgba(251,146,60,.13));border-color:rgba(250,204,21,.42);}\r\n.stp43-gold b{color:#fde68a;}\r\n.stp43-formula{margin-top:16px;text-align:center;color:#94a3b8;font-size:13px;}\r\n\r\n.stp43-load-card{padding:20px;}\r\n.stp43-load-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}\r\n.stp43-load-result{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:16px;}\r\n.stp43-load-result div{padding:14px;border-radius:16px;background:rgba(255,255,255,.075);border:1px solid rgba(255,255,255,.1);}\r\n.stp43-load-result small{display:block;color:#94a3b8;font-size:12px;}\r\n.stp43-load-result b{display:block;margin-top:6px;font-size:22px;color:#fff;}\r\n.stp43-load-visual{\r\n  margin-top:18px;min-height:160px;position:relative;border-radius:20px;\r\n  background:radial-gradient(circle at center,rgba(56,189,248,.13),rgba(2,6,23,.9));\r\n  border:1px solid rgba(255,255,255,.08);display:flex;justify-content:center;align-items:center;\r\n}\r\n.stp43-pallet-base{\r\n  width:220px;height:120px;border-radius:16px;background:linear-gradient(135deg,#92400e,#c08457);\r\n  transform:skewX(-14deg);box-shadow:0 28px 45px rgba(0,0,0,.28);position:relative;overflow:hidden;\r\n}\r\n#stp43-load-boxes{position:absolute;inset:12px;display:grid;grid-template-columns:repeat(5,1fr);gap:5px;}\r\n.stp43-mini-box{border-radius:5px;background:linear-gradient(135deg,#facc15,#fb923c);border:1px solid rgba(255,255,255,.35);}\r\n.stp43-load-badge{\r\n  position:absolute;right:18px;bottom:16px;padding:7px 12px;border-radius:999px;\r\n  background:rgba(2,6,23,.85);border:1px solid rgba(255,255,255,.16);color:#fde68a;font-weight:900;\r\n}\r\n\r\n@media(max-width:980px){\r\n  .stp43-main{grid-template-columns:1fr;}\r\n  .stp43-fields,.stp43-fields.round{grid-template-columns:1fr 1fr;}\r\n  .stp43-summary{grid-template-columns:1fr 1fr;}\r\n  .stp43-load-grid,.stp43-load-result{grid-template-columns:1fr 1fr;}\r\n}\r\n@media(max-width:560px){\r\n  .stp43{padding:20px;border-radius:22px;}\r\n  .stp43-header{flex-direction:column;}\r\n  .stp43 h2{font-size:26px;}\r\n  .stp43-tabs{flex-direction:column;}\r\n  .stp43-tabs button{width:100%;}\r\n  .stp43-fields,.stp43-fields.round,.stp43-row-result,.stp43-summary,.stp43-load-grid,.stp43-load-result{grid-template-columns:1fr;}\r\n}\r\n\r\n\/* Standard compact print *\/\r\n@media print{\r\n  @page{size:A4 landscape;margin:8mm;}\r\n  body *{visibility:hidden!important;}\r\n  #stooper-cargo-calculator-v43,#stooper-cargo-calculator-v43 *{visibility:visible!important;}\r\n  #stooper-cargo-calculator-v43{\r\n    position:absolute!important;left:0!important;top:0!important;width:100%!important;max-width:100%!important;\r\n    margin:0!important;padding:8px!important;border-radius:0!important;box-shadow:none!important;\r\n    background:#fff!important;color:#000!important;font-family:Arial,sans-serif!important;\r\n  }\r\n  .stp43-actions-top,.stp43-toolbar,.stp43-tabs,.stp43-right,.stp43-preview-card,.stp43-container-card,.stp43-load-visual{\r\n    display:none!important;\r\n  }\r\n  .stp43-header{margin-bottom:8px!important;padding-bottom:6px!important;border-bottom:1px solid #ccc!important;}\r\n  .stp43-kicker{color:#000!important;font-size:9px!important;margin-bottom:3px!important;}\r\n  .stp43 h2{font-size:18px!important;color:#000!important;margin:0!important;}\r\n  .stp43-header p{font-size:10px!important;color:#333!important;margin:3px 0 0!important;}\r\n  .stp43-main{display:block!important;}\r\n  .stp43-section{display:none!important;}\r\n  .stp43-section.active{display:block!important;}\r\n  .stp43-row{\r\n    padding:6px!important;margin-bottom:5px!important;border-radius:5px!important;background:#fff!important;\r\n    border:1px solid #bbb!important;break-inside:avoid!important;page-break-inside:avoid!important;\r\n  }\r\n  .stp43-row-top{margin-bottom:4px!important;}\r\n  .stp43-row-name{font-size:11px!important;color:#000!important;}\r\n  .stp43-row-chip{font-size:9px!important;color:#000!important;background:#f2f2f2!important;border:1px solid #ccc!important;padding:3px 6px!important;}\r\n  .stp43-fields,.stp43-fields.round{grid-template-columns:repeat(6,1fr)!important;gap:4px!important;}\r\n  .stp43-fields label,.stp43-load-grid label{font-size:8px!important;color:#333!important;}\r\n  .stp43-fields input,.stp43-fields select,.stp43-load-grid input,.stp43-load-grid select{\r\n    padding:3px!important;font-size:9px!important;border:1px solid #bbb!important;background:#fff!important;color:#000!important;border-radius:3px!important;\r\n  }\r\n  .stp43-remove{display:none!important;}\r\n  .stp43-row-result{grid-template-columns:repeat(3,1fr)!important;gap:4px!important;margin-top:5px!important;}\r\n  .stp43-row-result div{padding:4px!important;border-radius:4px!important;background:#f8f8f8!important;border:1px solid #ddd!important;}\r\n  .stp43-row-result small{font-size:8px!important;color:#555!important;}\r\n  .stp43-row-result b{font-size:10px!important;color:#000!important;}\r\n  .stp43-load-card{padding:8px!important;background:#fff!important;border:1px solid #ccc!important;}\r\n  .stp43-load-card h3{font-size:14px!important;color:#000!important;margin-bottom:3px!important;}\r\n  .stp43-load-card p{font-size:9px!important;color:#333!important;margin:0 0 5px!important;}\r\n  .stp43-load-grid{grid-template-columns:repeat(6,1fr)!important;gap:4px!important;}\r\n  .stp43-load-result{grid-template-columns:repeat(6,1fr)!important;gap:4px!important;margin-top:6px!important;}\r\n  .stp43-load-result div{padding:5px!important;background:#f8f8f8!important;border:1px solid #ddd!important;}\r\n  .stp43-load-result small{font-size:8px!important;color:#555!important;}\r\n  .stp43-load-result b{font-size:11px!important;color:#000!important;}\r\n  .stp43-summary{\r\n    grid-template-columns:repeat(4,1fr)!important;gap:5px!important;margin-top:7px!important;\r\n    break-inside:avoid!important;page-break-inside:avoid!important;\r\n  }\r\n  .stp43-summary div{padding:7px!important;border-radius:4px!important;background:#f8f8f8!important;border:1px solid #bbb!important;}\r\n  .stp43-summary small{font-size:8px!important;color:#555!important;margin-bottom:2px!important;}\r\n  .stp43-summary b{font-size:15px!important;color:#000!important;}\r\n  .stp43-summary em{font-size:9px!important;color:#333!important;}\r\n  .stp43-formula{margin-top:5px!important;font-size:8px!important;color:#555!important;}\r\n}\r\n<\/style>\r\n\r\n<script>\r\n(function(){\r\n  const root = document.getElementById(\"stooper-cargo-calculator-v43\");\r\n\r\n  function uid(){\r\n    return \"id\" + Math.random().toString(16).slice(2) + Date.now().toString(16);\r\n  }\r\n\r\n  const state = {\r\n    tab:\"mix\",\r\n    mix:[{id:uid(),type:\"carton\",l:50,w:40,h:30,unit:\"cm\",qty:10,kg:10}],\r\n    pallet:[{id:uid(),type:\"pallet\",l:120,w:100,h:150,unit:\"cm\",qty:1,kg:500}],\r\n    selectedMix:null,\r\n    selectedPallet:null,\r\n    load:{\r\n      cartonL:50,cartonW:40,cartonH:30,cartonUnit:\"cm\",cartonKg:10,totalCartons:120,\r\n      palletL:120,palletW:100,palletH:150,palletUnit:\"cm\",maxPalletKg:1000\r\n    }\r\n  };\r\n\r\n  state.selectedMix = state.mix[0].id;\r\n  state.selectedPallet = state.pallet[0].id;\r\n\r\n  function toCm(v,u){\r\n    v=parseFloat(v)||0;\r\n    if(u===\"mm\") return v\/10;\r\n    if(u===\"inch\") return v*2.54;\r\n    if(u===\"m\") return v*100;\r\n    return v;\r\n  }\r\n\r\n  function unitLabel(u){\r\n    if(u===\"inch\") return \"INCH\";\r\n    if(u===\"mm\") return \"MM\";\r\n    if(u===\"m\") return \"M\";\r\n    return \"CM\";\r\n  }\r\n\r\n  function labelName(type){\r\n    if(type===\"carton\") return \"Carton\";\r\n    if(type===\"bag\") return \"Bag \/ Sack\";\r\n    if(type===\"barrel\") return \"Barrel \/ Cylinder\";\r\n    if(type===\"pallet\") return \"Pallet\";\r\n    return \"Cargo\";\r\n  }\r\n\r\n  function isRoundPack(type){\r\n    return type===\"bag\" || type===\"barrel\";\r\n  }\r\n\r\n  function calcItem(item){\r\n    const qty=parseFloat(item.qty)||0;\r\n    const kg=parseFloat(item.kg)||0;\r\n\r\n    if(isRoundPack(item.type)){\r\n      const dia=toCm(item.w,item.unit);\r\n      const h=toCm(item.h,item.unit);\r\n      const freightCbmOne=(dia*dia*h)\/1000000;\r\n      const roundVolumeOne=(Math.PI*Math.pow(dia\/2,2)*h)\/1000000;\r\n      return {\r\n        l:dia,w:dia,h:h,dia:dia,qty:qty,kg:kg,\r\n        cbmOne:freightCbmOne,\r\n        roundVolumeOne:roundVolumeOne,\r\n        cbm:freightCbmOne*qty,\r\n        gw:kg*qty,\r\n        air:((dia*dia*h)\/6000)*qty\r\n      };\r\n    }\r\n\r\n    const l=toCm(item.l,item.unit);\r\n    const w=toCm(item.w,item.unit);\r\n    const h=toCm(item.h,item.unit);\r\n    const cbmOne=(l*w*h)\/1000000;\r\n\r\n    return {\r\n      l:l,w:w,h:h,qty:qty,kg:kg,\r\n      cbmOne:cbmOne,\r\n      roundVolumeOne:0,\r\n      cbm:cbmOne*qty,\r\n      gw:kg*qty,\r\n      air:((l*w*h)\/6000)*qty\r\n    };\r\n  }\r\n\r\n  function activeList(){\r\n    return state.tab===\"pallet\" ? state.pallet : state.mix;\r\n  }\r\n\r\n  function activeSelectedId(){\r\n    return state.tab===\"pallet\" ? state.selectedPallet : state.selectedMix;\r\n  }\r\n\r\n  function getSelectedItem(){\r\n    if(state.tab===\"load\"){\r\n      return {\r\n        id:\"load-preview\",type:\"pallet\",\r\n        l:state.load.palletL,w:state.load.palletW,h:state.load.palletH,\r\n        unit:state.load.palletUnit,qty:calcLoad().palletCount||0,kg:0\r\n      };\r\n    }\r\n    const list=activeList();\r\n    const selected=activeSelectedId();\r\n    return list.find(x=>x.id===selected)||list[0];\r\n  }\r\n\r\n  function rowHTML(item,index,kind){\r\n    const c=calcItem(item);\r\n    const isPallet=kind===\"pallet\";\r\n    const round=isRoundPack(item.type)&&!isPallet;\r\n\r\n    if(round){\r\n      return `\r\n        <div class=\"stp43-row\" data-kind=\"${kind}\" data-id=\"${item.id}\">\r\n          <div class=\"stp43-row-top\">\r\n            <div class=\"stp43-row-name\" data-row-name>${index+1}. ${labelName(item.type)}<\/div>\r\n            <div class=\"stp43-row-chip\" data-row-chip>${c.cbm.toFixed(4)} m\u00b3 \u00b7 ${c.gw.toFixed(2)} KG<\/div>\r\n          <\/div>\r\n          <div class=\"stp43-fields round\">\r\n            <label>Packaging\r\n              <select data-field=\"type\">\r\n                <option value=\"carton\">Carton<\/option>\r\n                <option value=\"bag\" ${item.type===\"bag\"?\"selected\":\"\"}>Bag \/ Sack<\/option>\r\n                <option value=\"barrel\" ${item.type===\"barrel\"?\"selected\":\"\"}>Barrel \/ Cylinder<\/option>\r\n              <\/select>\r\n            <\/label>\r\n            <label>Diameter \/ Max Width <input data-field=\"w\" type=\"number\" value=\"${item.w}\"><\/label>\r\n            <label>Height <input data-field=\"h\" type=\"number\" value=\"${item.h}\"><\/label>\r\n            <label>Unit\r\n              <select data-field=\"unit\">\r\n                <option value=\"cm\" ${item.unit===\"cm\"?\"selected\":\"\"}>CM<\/option>\r\n                <option value=\"mm\" ${item.unit===\"mm\"?\"selected\":\"\"}>MM<\/option>\r\n                <option value=\"inch\" ${item.unit===\"inch\"?\"selected\":\"\"}>INCH<\/option>\r\n                <option value=\"m\" ${item.unit===\"m\"?\"selected\":\"\"}>METER<\/option>\r\n              <\/select>\r\n            <\/label>\r\n            <label>Qty <input data-field=\"qty\" type=\"number\" value=\"${item.qty}\"><\/label>\r\n            <label>KG \/ Unit <input data-field=\"kg\" type=\"number\" value=\"${item.kg}\"><\/label>\r\n            <button type=\"button\" class=\"stp43-remove\" data-remove>\u00d7<\/button>\r\n          <\/div>\r\n          <div class=\"stp43-row-result\">\r\n            <div><small>Freight CBM \/ Unit<\/small><b data-cbm-one>${c.cbmOne.toFixed(4)} m\u00b3<\/b><\/div>\r\n            <div><small>Total Freight CBM<\/small><b data-cbm-total>${c.cbm.toFixed(4)} m\u00b3<\/b><\/div>\r\n            <div><small>Round Volume Reference<\/small><b data-air>${c.roundVolumeOne.toFixed(4)} m\u00b3<\/b><\/div>\r\n          <\/div>\r\n        <\/div>`;\r\n    }\r\n\r\n    return `\r\n      <div class=\"stp43-row\" data-kind=\"${kind}\" data-id=\"${item.id}\">\r\n        <div class=\"stp43-row-top\">\r\n          <div class=\"stp43-row-name\" data-row-name>${index+1}. ${labelName(item.type)}<\/div>\r\n          <div class=\"stp43-row-chip\" data-row-chip>${c.cbm.toFixed(4)} m\u00b3 \u00b7 ${c.gw.toFixed(2)} KG<\/div>\r\n        <\/div>\r\n        <div class=\"stp43-fields\">\r\n          <label>${isPallet ? \"Pallet Type\" : \"Packaging\"}\r\n            <select data-field=\"type\">\r\n              ${\r\n                isPallet\r\n                ? `<option value=\"pallet\" selected>Standard \/ Custom Pallet<\/option>`\r\n                : `\r\n                  <option value=\"carton\" ${item.type===\"carton\"?\"selected\":\"\"}>Carton<\/option>\r\n                  <option value=\"bag\" ${item.type===\"bag\"?\"selected\":\"\"}>Bag \/ Sack<\/option>\r\n                  <option value=\"barrel\" ${item.type===\"barrel\"?\"selected\":\"\"}>Barrel \/ Cylinder<\/option>`\r\n              }\r\n            <\/select>\r\n          <\/label>\r\n          <label>Length <input data-field=\"l\" type=\"number\" value=\"${item.l}\"><\/label>\r\n          <label>Width <input data-field=\"w\" type=\"number\" value=\"${item.w}\"><\/label>\r\n          <label>Height <input data-field=\"h\" type=\"number\" value=\"${item.h}\"><\/label>\r\n          <label>Unit\r\n            <select data-field=\"unit\">\r\n              <option value=\"cm\" ${item.unit===\"cm\"?\"selected\":\"\"}>CM<\/option>\r\n              <option value=\"mm\" ${item.unit===\"mm\"?\"selected\":\"\"}>MM<\/option>\r\n              <option value=\"inch\" ${item.unit===\"inch\"?\"selected\":\"\"}>INCH<\/option>\r\n              <option value=\"m\" ${item.unit===\"m\"?\"selected\":\"\"}>METER<\/option>\r\n            <\/select>\r\n          <\/label>\r\n          <label>Qty <input data-field=\"qty\" type=\"number\" value=\"${item.qty}\"><\/label>\r\n          <label>${isPallet ? \"KG \/ Pallet\" : \"KG \/ Unit\"} <input data-field=\"kg\" type=\"number\" value=\"${item.kg}\"><\/label>\r\n          <button type=\"button\" class=\"stp43-remove\" data-remove>\u00d7<\/button>\r\n        <\/div>\r\n        <div class=\"stp43-row-result\">\r\n          <div><small>${isPallet ? \"CBM \/ Pallet\" : \"CBM \/ Unit\"}<\/small><b data-cbm-one>${c.cbmOne.toFixed(4)} m\u00b3<\/b><\/div>\r\n          <div><small>Total CBM<\/small><b data-cbm-total>${c.cbm.toFixed(4)} m\u00b3<\/b><\/div>\r\n          <div><small>Air Vol. Weight<\/small><b data-air>${c.air.toFixed(2)} KG<\/b><\/div>\r\n        <\/div>\r\n      <\/div>`;\r\n  }\r\n\r\n  function renderMix(){\r\n    root.querySelector(\"#stp43-mix-list\").innerHTML=state.mix.map((item,index)=>rowHTML(item,index,\"mix\")).join(\"\");\r\n  }\r\n\r\n  function renderPallet(){\r\n    root.querySelector(\"#stp43-pallet-list\").innerHTML=state.pallet.map((item,index)=>rowHTML(item,index,\"pallet\")).join(\"\");\r\n  }\r\n\r\n  function updateOneRow(row,item,index){\r\n    const c=calcItem(item);\r\n    const name=row.querySelector(\"[data-row-name]\");\r\n    const chip=row.querySelector(\"[data-row-chip]\");\r\n    const cbmOne=row.querySelector(\"[data-cbm-one]\");\r\n    const cbmTotal=row.querySelector(\"[data-cbm-total]\");\r\n    const air=row.querySelector(\"[data-air]\");\r\n\r\n    if(name) name.textContent=`${index+1}. ${labelName(item.type)}`;\r\n    if(chip) chip.textContent=`${c.cbm.toFixed(4)} m\u00b3 \u00b7 ${c.gw.toFixed(2)} KG`;\r\n    if(cbmOne) cbmOne.textContent=`${c.cbmOne.toFixed(4)} m\u00b3`;\r\n    if(cbmTotal) cbmTotal.textContent=`${c.cbm.toFixed(4)} m\u00b3`;\r\n    if(air){\r\n      air.textContent=isRoundPack(item.type) ? `${c.roundVolumeOne.toFixed(4)} m\u00b3` : `${c.air.toFixed(2)} KG`;\r\n    }\r\n  }\r\n\r\n  function updateActiveRows(){\r\n    root.querySelectorAll(\".stp43-row\").forEach(row=>{\r\n      row.classList.remove(\"active\");\r\n      if(row.dataset.kind===\"mix\" && row.dataset.id===state.selectedMix) row.classList.add(\"active\");\r\n      if(row.dataset.kind===\"pallet\" && row.dataset.id===state.selectedPallet) row.classList.add(\"active\");\r\n    });\r\n  }\r\n\r\n  function scaleBox(item){\r\n    const l=toCm(item.l,item.unit), w=toCm(item.w,item.unit), h=toCm(item.h,item.unit);\r\n    const maxDim=Math.max(l,w,h,1);\r\n    return {\r\n      bw:Math.max(90,Math.min(180,(l\/maxDim)*180)),\r\n      bd:Math.max(65,Math.min(145,(w\/maxDim)*145)),\r\n      bh:Math.max(65,Math.min(150,(h\/maxDim)*150))\r\n    };\r\n  }\r\n\r\n  function updatePreview(){\r\n    const item=getSelectedItem();\r\n    const holder=root.querySelector(\"#stp43-shape-holder\");\r\n    const stage=root.querySelector(\".stp43-stage\");\r\n\r\n    if(!item){\r\n      holder.innerHTML=\"\";\r\n      return;\r\n    }\r\n\r\n    stage.classList.remove(\"is-box\",\"is-round\");\r\n\r\n    const u=unitLabel(item.unit);\r\n    root.querySelector(\"#stp43-preview-title\").textContent=`${labelName(item.type)} Preview`;\r\n    root.querySelector(\"#stp43-preview-qty\").textContent=`\u00d7 ${item.qty || 0}`;\r\n\r\n    if(isRoundPack(item.type)){\r\n      stage.classList.add(\"is-round\");\r\n      root.querySelector(\"#stp43-preview-sub\").textContent=`Diameter \/ Max Width ${item.w} \u00d7 Height ${item.h} ${u}`;\r\n      root.querySelector(\"#stp43-width-label\").textContent=`DIA ${item.w} ${u}`;\r\n      root.querySelector(\"#stp43-height-label\").textContent=`H ${item.h} ${u}`;\r\n\r\n      if(item.type===\"bag\"){\r\n        holder.innerHTML=`<div class=\"stp43-bag\"><\/div>`;\r\n        root.querySelector(\"#stp43-preview-note\").textContent=\"Bag uses Diameter \/ Max Width \u00d7 Diameter \/ Max Width \u00d7 Height for freight space CBM.\";\r\n      }else{\r\n        holder.innerHTML=`<div class=\"stp43-barrel\"><\/div>`;\r\n        root.querySelector(\"#stp43-preview-note\").textContent=\"Barrel uses Diameter \u00d7 Diameter \u00d7 Height for freight space CBM.\";\r\n      }\r\n      return;\r\n    }\r\n\r\n    stage.classList.add(\"is-box\");\r\n    root.querySelector(\"#stp43-preview-sub\").textContent=`${item.l} \u00d7 ${item.w} \u00d7 ${item.h} ${u}`;\r\n    root.querySelector(\"#stp43-length-label\").textContent=`L ${item.l} ${u}`;\r\n    root.querySelector(\"#stp43-width-label\").textContent=`W ${item.w} ${u}`;\r\n    root.querySelector(\"#stp43-height-label\").textContent=`H ${item.h} ${u}`;\r\n\r\n    const s=scaleBox(item);\r\n    const palletClass=item.type===\"pallet\" ? \"stp43-iso-pallet\" : \"\";\r\n    holder.innerHTML=`\r\n      <div class=\"stp43-iso-box ${palletClass}\" style=\"--bw:${s.bw}px;--bh:${s.bh}px;--bd:${s.bd}px;\">\r\n        <div class=\"face front\"><\/div><div class=\"face back\"><\/div><div class=\"face right\"><\/div>\r\n        <div class=\"face left\"><\/div><div class=\"face top\"><\/div><div class=\"face bottom\"><\/div>\r\n      <\/div>`;\r\n    root.querySelector(\"#stp43-preview-note\").textContent=\"Dimension guide lines are placed for cleaner reading.\";\r\n  }\r\n\r\n  function calcLoad(){\r\n    const d=state.load;\r\n    const cL=toCm(d.cartonL,d.cartonUnit), cW=toCm(d.cartonW,d.cartonUnit), cH=toCm(d.cartonH,d.cartonUnit);\r\n    const pL=toCm(d.palletL,d.palletUnit), pW=toCm(d.palletW,d.palletUnit), pH=toCm(d.palletH,d.palletUnit);\r\n    const totalCartons=parseFloat(d.totalCartons)||0;\r\n    const cartonKg=parseFloat(d.cartonKg)||0;\r\n    const maxPalletKg=parseFloat(d.maxPalletKg)||0;\r\n\r\n    const normalPerLayer=Math.floor(pL\/cL)*Math.floor(pW\/cW);\r\n    const rotatedPerLayer=Math.floor(pL\/cW)*Math.floor(pW\/cL);\r\n    const bestPerLayer=Math.max(normalPerLayer,rotatedPerLayer,0);\r\n    const rotated=rotatedPerLayer>normalPerLayer;\r\n    const layersByHeight=Math.floor(pH\/cH);\r\n    const layersByWeight=maxPalletKg>0 && cartonKg>0 && bestPerLayer>0 ? Math.floor(maxPalletKg\/(cartonKg*bestPerLayer)) : layersByHeight;\r\n    const layers=Math.max(0,Math.min(layersByHeight,layersByWeight));\r\n    const cartonsPerPallet=bestPerLayer*layers;\r\n    const palletCount=cartonsPerPallet>0 ? Math.ceil(totalCartons\/cartonsPerPallet) : 0;\r\n    const palletCbmOne=(pL*pW*pH)\/1000000;\r\n    const totalPalletCbm=palletCbmOne*palletCount;\r\n    const totalGw=totalCartons*cartonKg;\r\n    const totalAir=((pL*pW*pH)\/6000)*palletCount;\r\n\r\n    return {bestPerLayer,layers,cartonsPerPallet,palletCount,totalPalletCbm,rotated,totalCartons,totalGw,totalAir,charge:Math.max(totalGw,totalAir)};\r\n  }\r\n\r\n  function updateLoad(){\r\n    const r=calcLoad();\r\n\r\n    root.querySelector(\"#stp43-load-result\").innerHTML=`\r\n      <div><small>Cartons \/ Layer<\/small><b>${r.bestPerLayer}<\/b><\/div>\r\n      <div><small>Layers \/ Pallet<\/small><b>${r.layers}<\/b><\/div>\r\n      <div><small>Cartons \/ Pallet<\/small><b>${r.cartonsPerPallet}<\/b><\/div>\r\n      <div><small>Pallet Required<\/small><b>${r.palletCount}<\/b><\/div>\r\n      <div><small>Total Pallet CBM<\/small><b>${r.totalPalletCbm.toFixed(4)}<\/b><\/div>\r\n      <div><small>Best Orientation<\/small><b>${r.rotated ? \"Rotated\" : \"Normal\"}<\/b><\/div>`;\r\n\r\n    const boxes=root.querySelector(\"#stp43-load-boxes\");\r\n    boxes.innerHTML=\"\";\r\n    const showBoxes=Math.min(20,Math.max(0,r.bestPerLayer));\r\n    for(let i=0;i<showBoxes;i++){\r\n      boxes.insertAdjacentHTML(\"beforeend\",`<div class=\"stp43-mini-box\"><\/div>`);\r\n    }\r\n    root.querySelector(\"#stp43-load-badge\").textContent=`${r.totalCartons} CTNS \/ ${r.palletCount} PLTS`;\r\n  }\r\n\r\n  function currentTotals(){\r\n    if(state.tab===\"load\"){\r\n      const r=calcLoad();\r\n      return {cbm:r.totalPalletCbm,gw:r.totalGw,air:r.totalAir,charge:r.charge};\r\n    }\r\n\r\n    let cbm=0,gw=0,air=0;\r\n    activeList().forEach(item=>{\r\n      const c=calcItem(item);\r\n      cbm+=c.cbm;\r\n      gw+=c.gw;\r\n      air+=c.air;\r\n    });\r\n    return {cbm,gw,air,charge:Math.max(gw,air)};\r\n  }\r\n\r\n  function updateSummary(){\r\n    const t=currentTotals();\r\n    root.querySelector(\"#stp43-total-cbm\").textContent=t.cbm.toFixed(4);\r\n    root.querySelector(\"#stp43-total-gw\").textContent=t.gw.toFixed(2);\r\n    root.querySelector(\"#stp43-total-air\").textContent=t.air.toFixed(2);\r\n    root.querySelector(\"#stp43-total-charge\").textContent=t.charge.toFixed(2);\r\n    updateContainerEstimate(t.cbm);\r\n  }\r\n\r\n  function updateContainerEstimate(totalCbm){\r\n    const containers=[{name:\"20GP\",cbm:28},{name:\"40GP\",cbm:58},{name:\"40HC\",cbm:68}];\r\n\r\n    root.querySelector(\"#stp43-container-estimate\").innerHTML=containers.map(c=>{\r\n      const pct=c.cbm>0 ? Math.min(100,(totalCbm\/c.cbm)*100) : 0;\r\n      return `\r\n        <div class=\"stp43-container-line\">\r\n          <div class=\"stp43-container-top\"><span>${c.name}<\/span><b>${pct.toFixed(1)}%<\/b><\/div>\r\n          <div class=\"stp43-bar\"><span style=\"width:${pct}%\"><\/span><\/div>\r\n        <\/div>`;\r\n    }).join(\"\");\r\n  }\r\n\r\n  function setTab(tab){\r\n    state.tab=tab;\r\n\r\n    root.querySelectorAll(\".stp43-tabs button\").forEach(btn=>{\r\n      btn.classList.toggle(\"active\",btn.dataset.tab===tab);\r\n    });\r\n\r\n    root.querySelectorAll(\".stp43-section\").forEach(sec=>sec.classList.remove(\"active\"));\r\n    root.querySelector(\"#stp43-section-\"+tab).classList.add(\"active\");\r\n\r\n    updateActiveRows();\r\n    updateLoad();\r\n    updatePreview();\r\n    updateSummary();\r\n  }\r\n\r\n  function selectedTextSummary(){\r\n    const t=currentTotals();\r\n    let title=\"Stooper Cargo Measurement Result\";\r\n    if(state.tab===\"mix\") title=\"Mixed Packaging Result\";\r\n    if(state.tab===\"pallet\") title=\"Pallet Only Result\";\r\n    if(state.tab===\"load\") title=\"Pallet Loading Result\";\r\n\r\n    return `${title}\r\nTotal CBM: ${t.cbm.toFixed(4)} m\u00b3\r\nTotal Gross Weight: ${t.gw.toFixed(2)} KG\r\nAir Volumetric Weight: ${t.air.toFixed(2)} KG\r\nChargeable Weight: ${t.charge.toFixed(2)} KG`;\r\n  }\r\n\r\n  function copyText(text){\r\n    if(navigator.clipboard && navigator.clipboard.writeText){\r\n      return navigator.clipboard.writeText(text);\r\n    }\r\n    const ta=document.createElement(\"textarea\");\r\n    ta.value=text;\r\n    document.body.appendChild(ta);\r\n    ta.select();\r\n    document.execCommand(\"copy\");\r\n    document.body.removeChild(ta);\r\n    return Promise.resolve();\r\n  }\r\n\r\n  function renderAll(){\r\n    renderMix();\r\n    renderPallet();\r\n    updateActiveRows();\r\n    updatePreview();\r\n    updateLoad();\r\n    updateSummary();\r\n  }\r\n\r\n  root.addEventListener(\"click\",function(e){\r\n    const tabBtn=e.target.closest(\"[data-tab]\");\r\n    if(tabBtn){\r\n      setTab(tabBtn.dataset.tab);\r\n      return;\r\n    }\r\n\r\n    const add=e.target.closest(\"[data-add]\");\r\n    if(add){\r\n      const type=add.dataset.add;\r\n      const item=isRoundPack(type)\r\n        ? {id:uid(),type:type,w:50,h:type===\"barrel\"?88:90,unit:\"cm\",qty:1,kg:type===\"barrel\"?20:25}\r\n        : {id:uid(),type:type,l:50,w:40,h:30,unit:\"cm\",qty:1,kg:10};\r\n\r\n      state.mix.push(item);\r\n      state.selectedMix=item.id;\r\n      renderMix();\r\n      updateActiveRows();\r\n      updatePreview();\r\n      updateSummary();\r\n      return;\r\n    }\r\n\r\n    const addPallet=e.target.closest(\"[data-add-pallet]\");\r\n    if(addPallet){\r\n      const item={id:uid(),type:\"pallet\",l:120,w:100,h:150,unit:\"cm\",qty:1,kg:500};\r\n      state.pallet.push(item);\r\n      state.selectedPallet=item.id;\r\n      renderPallet();\r\n      updateActiveRows();\r\n      updatePreview();\r\n      updateSummary();\r\n      return;\r\n    }\r\n\r\n    const remove=e.target.closest(\"[data-remove]\");\r\n    if(remove){\r\n      const row=e.target.closest(\".stp43-row\");\r\n      const list=row.dataset.kind===\"mix\" ? state.mix : state.pallet;\r\n      const index=list.findIndex(x=>x.id===row.dataset.id);\r\n\r\n      if(index>=0) list.splice(index,1);\r\n\r\n      if(row.dataset.kind===\"mix\"){\r\n        state.selectedMix=state.mix[0] ? state.mix[0].id : null;\r\n        renderMix();\r\n      }else{\r\n        state.selectedPallet=state.pallet[0] ? state.pallet[0].id : null;\r\n        renderPallet();\r\n      }\r\n\r\n      updateActiveRows();\r\n      updatePreview();\r\n      updateSummary();\r\n      return;\r\n    }\r\n\r\n    const row=e.target.closest(\".stp43-row\");\r\n    if(row){\r\n      if(row.dataset.kind===\"mix\") state.selectedMix=row.dataset.id;\r\n      if(row.dataset.kind===\"pallet\") state.selectedPallet=row.dataset.id;\r\n      updateActiveRows();\r\n      updatePreview();\r\n      updateSummary();\r\n    }\r\n  });\r\n\r\n  root.addEventListener(\"input\",function(e){\r\n    const loadField=e.target.dataset.load;\r\n    if(loadField){\r\n      state.load[loadField]=e.target.value;\r\n      updateLoad();\r\n      updatePreview();\r\n      updateSummary();\r\n      return;\r\n    }\r\n\r\n    const field=e.target.dataset.field;\r\n    if(!field) return;\r\n\r\n    const row=e.target.closest(\".stp43-row\");\r\n    if(!row) return;\r\n\r\n    const list=row.dataset.kind===\"mix\" ? state.mix : state.pallet;\r\n    const item=list.find(x=>x.id===row.dataset.id);\r\n    if(!item) return;\r\n\r\n    item[field]=e.target.value;\r\n\r\n    const index=list.findIndex(x=>x.id===row.dataset.id);\r\n    updateOneRow(row,item,index);\r\n\r\n    if(row.dataset.kind===\"mix\") state.selectedMix=row.dataset.id;\r\n    if(row.dataset.kind===\"pallet\") state.selectedPallet=row.dataset.id;\r\n\r\n    updateActiveRows();\r\n    updatePreview();\r\n    updateSummary();\r\n  });\r\n\r\n  root.addEventListener(\"change\",function(e){\r\n    const loadField=e.target.dataset.load;\r\n    if(loadField){\r\n      state.load[loadField]=e.target.value;\r\n      updateLoad();\r\n      updatePreview();\r\n      updateSummary();\r\n      return;\r\n    }\r\n\r\n    const field=e.target.dataset.field;\r\n    if(!field) return;\r\n\r\n    const row=e.target.closest(\".stp43-row\");\r\n    if(!row) return;\r\n\r\n    const list=row.dataset.kind===\"mix\" ? state.mix : state.pallet;\r\n    const item=list.find(x=>x.id===row.dataset.id);\r\n    if(!item) return;\r\n\r\n    item[field]=e.target.value;\r\n\r\n    if(isRoundPack(item.type)){\r\n      if(!item.w) item.w=50;\r\n      if(!item.h) item.h=item.type===\"barrel\"?88:90;\r\n      delete item.l;\r\n    }else{\r\n      if(!item.l) item.l=50;\r\n      if(!item.w) item.w=40;\r\n      if(!item.h) item.h=30;\r\n    }\r\n\r\n    if(row.dataset.kind===\"mix\"){\r\n      state.selectedMix=row.dataset.id;\r\n      renderMix();\r\n    }else{\r\n      state.selectedPallet=row.dataset.id;\r\n      renderPallet();\r\n    }\r\n\r\n    updateActiveRows();\r\n    updatePreview();\r\n    updateSummary();\r\n  });\r\n\r\n  root.querySelector(\"#stp43-copy\").addEventListener(\"click\",function(){\r\n    const btn=this;\r\n    copyText(selectedTextSummary()).then(()=>{\r\n      const old=btn.textContent;\r\n      btn.textContent=\"Copied!\";\r\n      setTimeout(()=>btn.textContent=old,1200);\r\n    });\r\n  });\r\n\r\n  root.querySelector(\"#stp43-print\").addEventListener(\"click\",function(){\r\n    window.print();\r\n  });\r\n\r\n  renderAll();\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>3D CBM &amp; Cargo Measurement Calculator Use this free CBM calculator to calculate cargo volume for cartons, pallets, bags, barrels, and other shipment packaging. CBM means cubic meter, which is commonly used in logistics, sea freight, air freight, warehouse planning, and container loading. Simply enter the length, width, height, unit, quantity, and weight of your [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"cybocfi_hide_featured_image":"","footnotes":""},"class_list":["post-13454","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/pages\/13454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/comments?post=13454"}],"version-history":[{"count":19,"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/pages\/13454\/revisions"}],"predecessor-version":[{"id":13489,"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/pages\/13454\/revisions\/13489"}],"wp:attachment":[{"href":"https:\/\/stooper.co\/ms\/wp-json\/wp\/v2\/media?parent=13454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}