{"id":193,"date":"2026-02-11T17:19:10","date_gmt":"2026-02-11T10:19:10","guid":{"rendered":"https:\/\/www.e2connection.com\/?page_id=193"},"modified":"2026-02-11T18:11:55","modified_gmt":"2026-02-11T11:11:55","slug":"pile-deviation-report","status":"publish","type":"page","link":"https:\/\/www.e2connection.com\/?page_id=193","title":{"rendered":"Pile Deviation Report"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"th\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n      <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Sarabun:wght@300;400;600;700&#038;display=swap\" rel=\"stylesheet\">\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <style>\n      :root {\n            --primary: #2563eb;\n            --secondary: #475569;\n            --success: #16a34a;\n            --danger: #dc2626;\n            --bg: #f8fafc;\n            --card-bg: #ffffff;\n            --border: #e2e8f0;\n        }\n\n       \n\n        .container {\n            width: 100%;\n            max-width: 210mm;\n            margin: 0 auto;\n            background: white;\n            padding: 20px;\n            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n            min-height: 297mm;\n            box-sizing: border-box;\n            display: flex;\n            flex-direction: column;\n        }\n\n      \n\n        header h1 {\n            margin: 0;\n            font-size: 1.4rem;\n            color: var(--primary);\n            text-transform: uppercase;\n        }\n\n        header .meta {\n            text-align: right;\n            font-size: 0.85rem;\n            color: var(--secondary);\n            line-height: 1.4;\n        }\n\n        .btn-export {\n            background: var(--danger);\n            color: white;\n            border: none;\n            padding: 8px 16px;\n            border-radius: 6px;\n            cursor: pointer;\n            font-weight: bold;\n            display: inline-flex;\n            align-items: center;\n            gap: 6px;\n            font-size: 0.9rem;\n            transition: background 0.2s;\n        }\n        \n        .btn-export:hover {\n            background: #b91c1c;\n        }\n\n        \/* --- SECTION 1: Input & Table (Side by Side) --- *\/\n        .section-1 {\n            display: grid;\n            grid-template-columns: 240px 1fr; \n            gap: 15px; \n            margin-bottom: 20px;\n            align-items: start;\n        }\n\n        @media (max-width: 850px) {\n            .section-1 {\n                grid-template-columns: 1fr;\n            }\n        }\n\n        \/* --- CARDS --- *\/\n        .input-card, .table-card, .section-2 {\n            background: #f1f5f9;\n            padding: 15px;\n            border-radius: 8px;\n            border: 1px solid var(--border);\n        }\n\n        .input-card h3, .table-card h3, .section-2 h3 {\n            margin-top: 0;\n            color: var(--primary);\n            font-size: 1rem;\n            border-bottom: 2px solid #cbd5e1;\n            padding-bottom: 5px;\n            margin-bottom: 10px;\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        \/* --- INPUTS --- *\/\n        .input-group {\n            margin-bottom: 10px;\n        }\n\n        .input-group label {\n            display: block;\n            font-size: 0.8rem;\n            font-weight: 600;\n            margin-bottom: 2px;\n        }\n\n        .input-group input {\n            width: 100%;\n            padding: 6px;\n            border: 1px solid #cbd5e1;\n            border-radius: 4px;\n            box-sizing: border-box;\n            font-family: inherit;\n        }\n\n        .result-summary-mini {\n            margin-top: 15px;\n            padding-top: 10px;\n            border-top: 2px dashed #cbd5e1;\n        }\n\n        .res-row {\n            display: flex;\n            justify-content: space-between;\n            margin-bottom: 5px;\n            font-size: 0.9rem;\n        }\n\n        \/* --- TABLE --- *\/\n        .table-card {\n            display: flex;\n            flex-direction: column;\n        }\n\n        .table-header {\n            background: var(--primary);\n            color: white;\n            padding: 8px 15px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin: -15px -15px 15px -15px;\n            border-radius: 8px 8px 0 0;\n        }\n\n        .table-header h3 {\n            margin: 0;\n            border: none;\n            color: white;\n        }\n\n        .btn-add {\n            background: white;\n            color: var(--primary);\n            border: none;\n            padding: 4px 10px;\n            border-radius: 4px;\n            font-size: 0.8rem;\n            cursor: pointer;\n            font-weight: bold;\n        }\n\n        .table-responsive {\n            overflow-x: auto;\n            width: 100%;\n        }\n\n        \/* FIXED TABLE LAYOUT to prevent overflow *\/\n        table {\n            width: 100%;\n            border-collapse: collapse;\n            font-size: 0.8rem;\n            table-layout: fixed; \/* Force table to respect width *\/\n        }\n\n        th, td {\n            padding: 4px 2px; \/* Tight padding *\/\n            text-align: center;\n            border-bottom: 1px solid #e2e8f0;\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n        }\n\n        th {\n            background-color: #f8fafc;\n            color: #334155;\n            font-weight: 600;\n        }\n\n        .bg-design { background-color: #f0f9ff; }\n        .bg-dev { background-color: #fffbeb; }\n\n        td input[type=\"number\"] {\n            width: 100%;\n            padding: 2px;\n            text-align: center;\n            border: 1px solid #cbd5e1;\n            border-radius: 3px;\n            font-size: 0.8rem;\n            box-sizing: border-box;\n        }\n\n        .pile-name-input {\n            width: 100%;\n            border: none;\n            background: transparent;\n            font-weight: 700;\n            color: #1e293b;\n            text-align: center;\n            padding: 2px;\n            cursor: text;\n        }\n        .pile-name-input:hover, .pile-name-input:focus {\n            background: #fff;\n            box-shadow: 0 0 0 1px var(--primary);\n            border-radius: 2px;\n            outline: none;\n        }\n\n        .table-footer {\n            background: #f1f5f9;\n            padding: 10px 15px;\n            border-top: 1px solid #cbd5e1;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            font-size: 0.9rem;\n            color: var(--secondary);\n            flex-wrap: wrap;\n            gap: 10px;\n            margin: 15px -15px -15px -15px;\n            border-radius: 0 0 8px 8px;\n        }\n\n        .summary-item {\n            display: flex;\n            gap: 5px;\n            align-items: center;\n        }\n\n        .btn-del {\n            background: #fee2e2;\n            color: #dc2626;\n            border: none;\n            width: 24px;\n            height: 24px;\n            border-radius: 4px;\n            cursor: pointer;\n            display: inline-flex;\n            align-items: center;\n            justify-content: center;\n        }\n\n        .check-btn {\n            background: transparent;\n            border: none;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            padding: 2px;\n        }\n        .check-btn i.fa-check-circle { color: var(--success); font-size: 1.1rem; }\n        .check-btn i.fa-circle { color: #cbd5e1; font-size: 1.1rem; }\n\n        \/* --- SECTION 2: Visualization (Full Width Bottom) --- *\/\n        .section-2 {\n            margin-top: 10px;\n            display: flex;\n            flex-direction: column;\n            height: 400px; \/* Taller for better view *\/\n        }\n\n        .canvas-wrapper {\n            position: relative;\n            flex: 1;\n            width: 100%;\n            border: 1px dashed #cbd5e1;\n            background: #fafafa;\n        }\n\n        canvas {\n            display: block;\n        }\n\n        .legend {\n            display: flex;\n            justify-content: center;\n            gap: 15px;\n            margin-top: 10px;\n            font-size: 0.8rem;\n            flex-wrap: wrap;\n        }\n\n        \/* --- APPENDICES --- *\/\n        .formula-section {\n            display: none;\n            padding: 20px 40px;\n            font-family: 'Times New Roman', serif;\n        }\n\n        .formula-block {\n            margin-bottom: 20px;\n            padding: 15px;\n            background: #f8fafc;\n            border-left: 4px solid var(--primary);\n            page-break-inside: avoid;\n        }\n        \n        .formula-block h4 {\n            margin: 0 0 10px 0;\n            color: var(--primary);\n            font-family: 'Sarabun', sans-serif;\n        }\n\n        .math-eq {\n            font-size: 1.1rem;\n            margin: 10px 0;\n            text-align: center;\n            font-style: italic;\n        }\n        \n        .math-left {\n            text-align: left;\n            margin-left: 20px;\n        }\n\n        \/* --- PRINT STYLES --- *\/\n        @media print {\n            body { background: white; padding: 0; font-size: 12pt; }\n            .container {\n                box-shadow: none;\n                margin: 0;\n                width: 100%;\n                padding: 10mm;\n                max-width: none;\n                display: block;\n            }\n            .no-print-btn, .btn-add, .btn-del, .btn-export { display: none !important; }\n            \n            .section-1 { \n                grid-template-columns: 210px 1fr !important; \n                gap: 10px !important;\n            }\n            \n            table { font-size: 8pt !important; table-layout: fixed; }\n            th, td { padding: 3px 1px !important; border: 0.5pt solid #000; }\n            .pile-name-input { width: 30px; }\n\n            .section-2 {\n                height: 400px;\n                page-break-inside: avoid;\n                margin-top: 20px;\n            }\n\n            .formula-section { display: block; page-break-before: always; }\n            \n            * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }\n        }\n    <\/style>\n<\/head>\n<body>\n\n    <div class=\"container\">\n        <header>\n            <div style=\"display:flex; align-items:center; gap:10px;\">\n                <i class=\"fas fa-project-diagram\" style=\"font-size:24px; color:var(--primary)\"><\/i>\n                <div>\n                    <h1>Pile Deviation Report<\/h1>\n                    <div style=\"font-size:0.8rem; color:#64748b; font-weight:600\">Rigid Body Analysis Method<\/div>\n                <\/div>\n            <\/div>\n            \n            <div style=\"display:flex; align-items:center; gap:15px;\">\n                <div class=\"meta\">\n                    <div><strong>Footing:<\/strong> <span id=\"headerFooting\">&#8211;<\/span><\/div>\n                    <div><strong>Grid Line:<\/strong> <span id=\"headerGrid\">&#8211;<\/span><\/div>\n                    <div><strong>Date:<\/strong> <span id=\"currentDate\">&#8211;<\/span><\/div>\n                <\/div>\n                <button type=\"button\" class=\"btn-export no-print-btn\" onclick=\"window.print()\">\n                    <i class=\"fas fa-file-pdf\"><\/i> Export PDF\n                <\/button>\n            <\/div>\n        <\/header>\n\n        <!-- SECTION 1: Inputs & Table -->\n        <div class=\"section-1\">\n            <div class=\"input-card\">\n                <h3><i class=\"fas fa-sliders-h\"><\/i> Design Inputs<\/h3>\n                \n                <div class=\"input-group\">\n                    <label>Footing No.<\/label>\n                    <input type=\"text\" id=\"inputFooting\" value=\"F1\" oninput=\"app.updateMeta()\">\n                <\/div>\n                <div style=\"display:flex; gap:10px;\">\n                    <div class=\"input-group\" style=\"flex:1\">\n                        <label>Grid X<\/label>\n                        <input type=\"text\" id=\"inputGridX\" value=\"A\" oninput=\"app.updateMeta()\">\n                    <\/div>\n                    <div class=\"input-group\" style=\"flex:1\">\n                        <label>Grid Y<\/label>\n                        <input type=\"text\" id=\"inputGridY\" value=\"1\" oninput=\"app.updateMeta()\">\n                    <\/div>\n                <\/div>\n                <hr style=\"margin: 10px 0; border: none; border-top: 1px solid #cbd5e1;\">\n                \n                <div class=\"input-group\">\n                    <label>Axial Load (P) [Tons]<\/label>\n                    <input type=\"number\" id=\"loadP\" value=\"150\" oninput=\"app.calculate()\">\n                <\/div>\n                <div style=\"display:flex; gap:10px;\">\n                    <div class=\"input-group\" style=\"flex:1\">\n                        <label>Mx [T-m]<\/label>\n                        <input type=\"number\" id=\"loadMx\" value=\"0\" oninput=\"app.calculate()\">\n                    <\/div>\n                    <div class=\"input-group\" style=\"flex:1\">\n                        <label>My [T-m]<\/label>\n                        <input type=\"number\" id=\"loadMy\" value=\"0\" oninput=\"app.calculate()\">\n                    <\/div>\n                <\/div>\n                <div class=\"input-group\">\n                    <label>Safe Load [T\/Pile]<\/label>\n                    <input type=\"number\" id=\"safeLoad\" value=\"40\" oninput=\"app.calculate()\">\n                <\/div>\n\n                <div class=\"result-summary-mini\">\n                    <div class=\"res-row\"><span>Total Piles:<\/span><strong id=\"resN\">0<\/strong><\/div>\n                    <div class=\"res-row\"><span>New C.G.:<\/span><strong id=\"resCG\">0, 0<\/strong><\/div>\n                    <div class=\"res-row\"><span>Max Rx:<\/span><strong id=\"resMaxR\" style=\"color:var(--primary)\">0.00 T<\/strong><\/div>\n                    <div class=\"res-row\"><span>Status:<\/span><strong id=\"overallStatus\">CHECKING<\/strong><\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"table-card\">\n                <div class=\"table-header\">\n                    <h3><i class=\"fas fa-table\"><\/i> Pile Data<\/h3>\n                    <div style=\"display:flex; gap:10px\">\n                        <button type=\"button\" class=\"btn-add no-print-btn\" onclick=\"app.toggleAll()\" style=\"background:#e0f2fe; color:var(--primary)\">\n                            <i class=\"fas fa-check-double\"><\/i> All\n                        <\/button>\n                        <button type=\"button\" class=\"btn-add\" onclick=\"app.addPile()\"><i class=\"fas fa-plus\"><\/i> Add<\/button>\n                    <\/div>\n                <\/div>\n                <div class=\"table-responsive\"> \n                    <table id=\"pileTable\">\n                        <thead>\n                            <tr>\n                                <th rowspan=\"2\" style=\"width:13%;\">No.<\/th>\n                                <th colspan=\"2\" class=\"bg-design\" style=\"width:24%;\">Design (m)<\/th>\n                                <th colspan=\"2\" class=\"bg-dev\" style=\"width:20%;\">Deviation (m)<\/th>\n                                <th colspan=\"2\" style=\"width:20%;\">Actual (m)<\/th>\n                                <th rowspan=\"2\" style=\"width:12%;\">Reaction<br>(T)<\/th>\n                                <th rowspan=\"2\" style=\"width:6%;\">Sts<\/th>\n                                <th rowspan=\"2\" class=\"no-print-btn\" style=\"width:5%;\"><\/th>\n                            <\/tr>\n                            <tr>\n                                <th class=\"bg-design\">x<\/th>\n                                <th class=\"bg-design\">y<\/th>\n                                <th class=\"bg-dev\">Dx<\/th>\n                                <th class=\"bg-dev\">Dy<\/th>\n                                <th>x&#8217;<\/th>\n                                <th>y&#8217;<\/th>\n                            <\/tr>\n                        <\/thead>\n                        <tbody><\/tbody>\n                    <\/table>\n                <\/div>\n                <div style=\"flex:1\"><\/div>\n                <div class=\"table-footer\">\n                    <div style=\"display:flex; gap:10px; flex-wrap:wrap; font-size:0.85rem\">\n                        <div class=\"summary-item\">Min:<strong id=\"sumMin\" style=\"color:#059669\">0.00<\/strong><\/div>\n                        <div class=\"summary-item\">Max:<strong id=\"sumMax\" style=\"color:#dc2626\">0.00<\/strong><\/div>\n                        <div class=\"summary-item\">Avg:<strong id=\"sumAvg\" style=\"color:#2563eb\">0.00<\/strong><\/div>\n                    <\/div>\n                    <div class=\"summary-item\" style=\"background:#fff; padding:4px 10px; border-radius:4px; border:1px solid #cbd5e1; font-weight:700\">\n                        \u03a3R: <span id=\"sumTotal\" style=\"color:#0f172a\">0.00 T<\/span>\n                        <span id=\"checkTotal\" style=\"font-size:0.8rem; margin-left:5px\"><\/span>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- SECTION 2: Visualization -->\n        <div class=\"section-2\">\n            <h3><i class=\"fas fa-map-marked-alt\"><\/i> Plan View<\/h3>\n            <div class=\"canvas-wrapper\" id=\"canvasWrapper\">\n                <canvas id=\"pileCanvas\"><\/canvas>\n            <\/div>\n            <div class=\"legend\">\n                <div style=\"display:flex;align-items:center\"><span style=\"display:inline-block;width:10px;height:10px;border:2px solid #64748b;border-radius:50%;margin-right:4px\"><\/span> Design<\/div>\n                <div style=\"display:flex;align-items:center\"><span style=\"display:inline-block;width:10px;height:10px;background:#3b82f6;border-radius:50%;margin-right:4px\"><\/span> OK<\/div>\n                <div style=\"display:flex;align-items:center\"><span style=\"display:inline-block;width:10px;height:10px;background:#ef4444;border-radius:50%;margin-right:4px\"><\/span> Fail<\/div>\n                <div style=\"display:flex;align-items:center\"><i class=\"fas fa-plus\" style=\"color:red; margin-right:4px\"><\/i> Group C.G.<\/div>\n            <\/div>\n        <\/div>\n\n        <!-- APPENDIX A: CALCULATION BASIS -->\n        <div class=\"formula-section\">\n            <h2 style=\"border-bottom: 2px solid #000; padding-bottom: 10px;\">APPENDIX A: CALCULATION BASIS<\/h2>\n            <div class=\"formula-block\">\n                <h4>1. Coordinate &#038; Inertia Properties<\/h4>\n                <div class=\"math-eq\">\n                    X = x&#8217; &#8211; X<sub>cg<\/sub> , Y = y&#8217; &#8211; Y<sub>cg<\/sub><br>\n                    I<sub>x<\/sub> = &Sigma;Y<sup>2<\/sup> , I<sub>y<\/sub> = &Sigma;X<sup>2<\/sup> , I<sub>xy<\/sub> = &Sigma;XY\n                <\/div>\n            <\/div>\n            <div class=\"formula-block\">\n                <h4>2. Moment Correction (Transfer Load P to C.G.)<\/h4>\n                <div class=\"math-eq\">\n                    M<sub>x<\/sub> = M<sub>xo<\/sub> + P &middot; Y<sub>cg<\/sub> <br>\n                    M<sub>y<\/sub> = M<sub>yo<\/sub> &#8211; P &middot; X<sub>cg<\/sub>\n                <\/div>\n            <\/div>\n            <div class=\"formula-block\">\n                <h4>3. New Coefficients m, n &#038; Reaction Formula<\/h4>\n                <div class=\"math-eq\">\n                    m = \\frac{M_y I_x &#8211; M_x I_{xy}}{I_x I_y &#8211; (I_{xy})^2} , n = \\frac{M_x I_y &#8211; M_y I_{xy}}{I_x I_y &#8211; (I_{xy})^2}<br>\n                    <strong>R = (P \/ N) + (m \\cdot X) + (n \\cdot Y)<\/strong>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- APPENDIX B: DETAILED CALCULATIONS -->\n        <div id=\"example-section\" class=\"formula-section\">\n            <h2 style=\"border-bottom: 2px solid #000; padding-bottom: 10px;\">APPENDIX B: STEP-BY-STEP CALCULATION<\/h2>\n            <div id=\"example-content\"><\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n        document.getElementById('currentDate').innerText = new Date().toLocaleDateString('th-TH');\n\n        const app = {\n            data: [\n                { id: 1, name: 'P1', x: 0, y: 0, dx: 0, dy: 0, selected: true }, \n                { id: 2, name: 'P2', x: -1.0, y: 1.0, dx: 0, dy: 0, selected: false },\n                { id: 3, name: 'P3', x: 1.0, y: 1.0, dx: 0, dy: 0, selected: false },\n                { id: 4, name: 'P4', x: -1.0, y: -1.0, dx: 0, dy: 0, selected: false },\n                { id: 5, name: 'P5', x: 1.0, y: -1.0, dx: 0, dy: 0, selected: false }\n            ],\n            \n            init: function() {\n                this.renderTable();\n                this.updateMeta();\n                this.calculate();\n                setTimeout(() => this.drawCanvas(), 200); \/\/ Increased delay for layout settle\n                window.addEventListener('resize', () => this.drawCanvas());\n            },\n\n            updateMeta: function() {\n                const footing = document.getElementById('inputFooting').value || '-';\n                const gridX = document.getElementById('inputGridX').value || '';\n                const gridY = document.getElementById('inputGridY').value || '';\n                document.getElementById('headerFooting').innerText = footing;\n                document.getElementById('headerGrid').innerText = gridX + (gridX && gridY ? '\/' : '') + gridY || '-';\n            },\n\n            addPile: function() {\n                const newId = this.data.length > 0 ? Math.max(...this.data.map(p => p.id)) + 1 : 1;\n                this.data.push({ id: newId, name: 'P' + newId, x: 0, y: 0, dx: 0, dy: 0, selected: false });\n                this.renderTable();\n                this.calculate();\n            },\n\n            removePile: function(id) {\n                this.data = this.data.filter(p => p.id !== id);\n                this.renderTable();\n                this.calculate();\n            },\n\n            updatePile: function(id, field, value) {\n                const pile = this.data.find(p => p.id === id);\n                if (pile) {\n                    pile[field] = parseFloat(value) || 0;\n                    this.calculate();\n                }\n            },\n\n            updatePileName: function(id, newName) {\n                const pile = this.data.find(p => p.id === id);\n                if (pile) {\n                    pile.name = newName;\n                    this.calculate();\n                }\n            },\n            \n            toggleSelection: function(id) {\n                const pile = this.data.find(p => p.id === id);\n                if(pile) {\n                    pile.selected = !pile.selected;\n                    this.renderTable();\n                    this.calculate();\n                }\n            },\n\n            toggleAll: function() {\n                const allSelected = this.data.every(p => p.selected);\n                this.data.forEach(p => p.selected = !allSelected);\n                this.renderTable();\n                this.calculate();\n            },\n\n            renderTable: function() {\n                const tbody = document.querySelector('#pileTable tbody');\n                tbody.innerHTML = '';\n                this.data.forEach(pile => {\n                    const tr = document.createElement('tr');\n                    const checkIcon = pile.selected ? 'fas fa-check-circle' : 'far fa-circle';\n                    tr.innerHTML = `\n                        <td style=\"text-align:left; padding-left:10px;\">\n                            <div style=\"display:flex; align-items:center; gap:5px;\">\n                                <button class=\"check-btn\" onclick=\"app.toggleSelection(${pile.id})\">\n                                    <i class=\"${checkIcon}\"><\/i>\n                                <\/button>\n                                <input type=\"text\" class=\"pile-name-input\" value=\"${pile.name}\" oninput=\"app.updatePileName(${pile.id}, this.value)\">\n                            <\/div>\n                        <\/td>\n                        <td class=\"bg-design\"><input type=\"number\" step=\"0.0001\" value=\"${pile.x}\" oninput=\"app.updatePile(${pile.id}, 'x', this.value)\"><\/td>\n                        <td class=\"bg-design\"><input type=\"number\" step=\"0.0001\" value=\"${pile.y}\" oninput=\"app.updatePile(${pile.id}, 'y', this.value)\"><\/td>\n                        <td class=\"bg-dev\"><input type=\"number\" step=\"0.0001\" value=\"${pile.dx}\" oninput=\"app.updatePile(${pile.id}, 'dx', this.value)\"><\/td>\n                        <td class=\"bg-dev\"><input type=\"number\" step=\"0.0001\" value=\"${pile.dy}\" oninput=\"app.updatePile(${pile.id}, 'dy', this.value)\"><\/td>\n                        <td style=\"color:#64748b\"><span id=\"xp_${pile.id}\"><\/span><\/td>\n                        <td style=\"color:#64748b\"><span id=\"yp_${pile.id}\"><\/span><\/td>\n                        <td id=\"reaction_${pile.id}\" style=\"font-weight:700\"><\/td>\n                        <td id=\"status_${pile.id}\"><\/td>\n                        <td class=\"no-print-btn\"><button type=\"button\" class=\"btn-del\" onclick=\"app.removePile(${pile.id})\"><i class=\"fas fa-trash-alt\"><\/i><\/button><\/td>\n                    `;\n                    tbody.appendChild(tr);\n                });\n            },\n\n            calculate: function() {\n                const P = parseFloat(document.getElementById('loadP').value) || 0;\n                const Mx_input = parseFloat(document.getElementById('loadMx').value) || 0;\n                const My_input = parseFloat(document.getElementById('loadMy').value) || 0;\n                const safeLoad = parseFloat(document.getElementById('safeLoad').value) || 0;\n                const N = this.data.length;\n\n                if (N === 0) return;\n\n                let sumXp = 0, sumYp = 0;\n                this.data.forEach(p => {\n                    p.xp = p.x + p.dx;\n                    p.yp = p.y + p.dy;\n                    sumXp += p.xp;\n                    sumYp += p.yp;\n                    document.getElementById(`xp_${p.id}`).innerText = p.xp.toFixed(3);\n                    document.getElementById(`yp_${p.id}`).innerText = p.yp.toFixed(3);\n                });\n\n                this.cgX = sumXp \/ N;\n                this.cgY = sumYp \/ N;\n\n                let sumX2 = 0, sumY2 = 0, sumXY = 0;\n                this.data.forEach(p => {\n                    p.relX = p.xp - this.cgX;\n                    p.relY = p.yp - this.cgY;\n                    sumY2 += p.relY * p.relY; \n                    sumX2 += p.relX * p.relX; \n                    sumXY += p.relX * p.relY;\n                });\n\n                const Ix = sumY2, Iy = sumX2, Ixy = sumXY;\n                \n                \/\/ Requested Logic: ex = 0 + CG, ey = 0 + CG\n                const ex = this.cgX, ey = this.cgY;\n                const Mx_total = Mx_input + (P * ey);\n                const My_total = My_input - (P * ex);\n                const denom = (Ix * Iy) - (Ixy * Ixy);\n                \n                let m = 0, n = 0;\n                if (Math.abs(denom) > 1e-12) {\n                    m = (My_total * Ix - Mx_total * Ixy) \/ denom;\n                    n = (Mx_total * Iy - My_total * Ixy) \/ denom;\n                }\n\n                let maxR = -Infinity, minR = Infinity, totalR = 0, allSafe = true;\n                this.data.forEach(p => {\n                    let R = (P \/ N) + (m * p.relX) + (n * p.relY);\n                    p.reaction = R;\n                    p.isFail = (safeLoad > 0 && R > safeLoad);\n                    if (R > maxR) maxR = R;\n                    if (R < minR) minR = R;\n                    totalR += R;\n                    if (p.isFail) allSafe = false;\n\n                    const rCell = document.getElementById(`reaction_${p.id}`);\n                    const sCell = document.getElementById(`status_${p.id}`);\n                    rCell.innerText = R.toFixed(2);\n                    rCell.style.color = p.isFail ? 'var(--danger)' : '#0f172a';\n                    sCell.innerHTML = safeLoad > 0 ? (p.isFail ? '<span style=\"color:var(--danger);font-weight:700\">FAIL<\/span>' : '<span style=\"color:var(--success);font-weight:700\">OK<\/span>') : '-';\n                });\n\n                document.getElementById('resN').innerText = N;\n                document.getElementById('resCG').innerText = `${this.cgX.toFixed(3)}, ${this.cgY.toFixed(3)}`;\n                document.getElementById('resMaxR').innerText = maxR.toFixed(2) + \" T\";\n                document.getElementById('sumMin').innerText = minR.toFixed(2) + \" T\";\n                document.getElementById('sumMax').innerText = maxR.toFixed(2) + \" T\";\n                document.getElementById('sumAvg').innerText = (totalR \/ N).toFixed(2) + \" T\";\n                document.getElementById('sumTotal').innerText = totalR.toFixed(2) + \" T\";\n                \n                const checkEl = document.getElementById('checkTotal');\n                const diff = Math.abs(totalR - P);\n                checkEl.innerHTML = diff < 0.05 ? '<i class=\"fas fa-check-circle\" style=\"color:var(--success)\"><\/i>' : `<i class=\"fas fa-exclamation-triangle\" style=\"color:var(--danger)\"><\/i>`;\n                \n                const statusEl = document.getElementById('overallStatus');\n                if (safeLoad > 0) {\n                    statusEl.innerText = allSafe ? \"PASSED\" : \"FAILED\";\n                    statusEl.style.color = allSafe ? \"var(--success)\" : \"var(--danger)\";\n                }\n\n                this.drawCanvas();\n                this.renderExample(P, Mx_input, My_input, Mx_total, My_total, Ix, Iy, Ixy, denom, m, n, N, ex, ey);\n            },\n\n            renderExample: function(P, Mx_in, My_in, Mx_t, My_t, Ix, Iy, Ixy, Det, m, n, N, ex, ey) {\n                const exDiv = document.getElementById('example-content');\n                if(!exDiv) return;\n                let html = `\n                    <div class=\"formula-block\">\n                        <h4>1. New Centroid & Group Inertia Summary<\/h4>\n                        <div class=\"math-left\" style=\"font-size:1rem; line-height:1.6\">\n                            X<sub>cg<\/sub> = ${this.cgX.toFixed(3)} m, Y<sub>cg<\/sub> = ${this.cgY.toFixed(3)} m <br>\n                            I<sub>x<\/sub> = ${Ix.toFixed(3)}, I<sub>y<\/sub> = ${Iy.toFixed(3)}, I<sub>xy<\/sub> = ${Ixy.toFixed(3)} <br>\n                            <strong>Denominator (D)<\/strong> = ${Det.toFixed(3)}\n                        <\/div>\n                    <\/div>\n                    <div class=\"formula-block\">\n                        <h4>2. Forces & Coefficients<\/h4>\n                        <div class=\"math-left\" style=\"font-size:1rem; line-height:1.6\">\n                             e<sub>x<\/sub> = ${ex.toFixed(3)} m, e<sub>y<\/sub> = ${ey.toFixed(3)} m <br>\n                             M<sub>x_cg<\/sub> = ${Mx_t.toFixed(3)} T-m, M<sub>y_cg<\/sub> = ${My_t.toFixed(3)} T-m <br>\n                             m = ${m.toFixed(6)}, n = ${n.toFixed(6)}\n                        <\/div>\n                    <\/div>\n                `;\n\n                const selectedPiles = this.data.filter(p => p.selected);\n                if (selectedPiles.length === 0) {\n                    html += `<div style=\"padding:20px; text-align:center; color:#64748b; border:1px dashed #cbd5e1; border-radius:8px\">No piles selected for detail.<\/div>`;\n                } else {\n                    selectedPiles.forEach(p => {\n                        html += `\n                        <div class=\"formula-block\" style=\"background:#fff; border:1px solid #e2e8f0; border-left:4px solid #0f172a; margin-top:15px;\">\n                            <h4>Detailed Analysis: Pile ${p.name}<\/h4>\n                            <div class=\"math-left\" style=\"font-size:1rem; line-height:1.6\">\n                                <strong>Relative Position:<\/strong> X = ${p.relX.toFixed(3)}, Y = ${p.relY.toFixed(3)}<br>\n                                <strong>Reaction Calculation:<\/strong><br>\n                                R = (${P}\/${N}) + (${m.toFixed(5)} &middot; ${p.relX.toFixed(3)}) + (${n.toFixed(5)} &middot; ${p.relY.toFixed(3)}) <br>\n                                R = ${(P\/N).toFixed(2)} + ${(m*p.relX).toFixed(2)} + ${(n*p.relY).toFixed(2)} = <span style=\"color:var(--primary);font-weight:700\">${p.reaction.toFixed(2)} Tons<\/span>\n                            <\/div>\n                        <\/div>\n                        `;\n                    });\n                }\n                exDiv.innerHTML = html;\n            },\n\n            drawCanvas: function() {\n                const wrapper = document.getElementById('canvasWrapper');\n                const canvas = document.getElementById('pileCanvas');\n                if(!wrapper || !canvas) return;\n                const ctx = canvas.getContext('2d');\n                canvas.width = wrapper.offsetWidth;\n                canvas.height = wrapper.offsetHeight;\n                const w = canvas.width, h = canvas.height;\n                ctx.clearRect(0, 0, w, h);\n                if (this.data.length === 0) return;\n\n                let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n                const points = [...this.data.map(p => ({x: p.xp, y: p.yp})), {x:0, y:0}, {x: this.cgX, y: this.cgY}];\n                points.forEach(p => {\n                    if (p.x < minX) minX = p.x; if (p.x > maxX) maxX = p.x;\n                    if (p.y < minY) minY = p.y; if (p.y > maxY) maxY = p.y;\n                });\n\n                const rangeX = maxX - minX || 2, rangeY = maxY - minY || 2;\n                const scale = Math.min(w \/ (rangeX * 1.3), h \/ (rangeY * 1.3)); \n                const toCx = (v) => (v - (minX + maxX)\/2) * scale + w\/2;\n                const toCy = (v) => h\/2 - (v - (minY + maxY)\/2) * scale;\n\n                ctx.setLineDash([5, 5]); ctx.strokeStyle = '#cbd5e1';\n                ctx.beginPath(); ctx.moveTo(toCx(0), 0); ctx.lineTo(toCx(0), h); ctx.stroke();\n                ctx.beginPath(); ctx.moveTo(0, toCy(0)); ctx.lineTo(w, toCy(0)); ctx.stroke();\n                ctx.setLineDash([]); ctx.fillStyle = '#64748b'; ctx.font = 'bold 12px Sarabun';\n                ctx.fillText(\"CENTER (0,0)\", toCx(0) + 5, toCy(0) - 5);\n\n                const cgCx = toCx(this.cgX), cgCy = toCy(this.cgY);\n                ctx.strokeStyle = 'red'; \n                ctx.lineWidth = 3; \n                ctx.beginPath(); \n                ctx.moveTo(cgCx-20, cgCy); ctx.lineTo(cgCx+20, cgCy); \n                ctx.stroke();\n                ctx.beginPath(); \n                ctx.moveTo(cgCx, cgCy-20); ctx.lineTo(cgCx, cgCy+20); \n                ctx.stroke();\n                ctx.lineWidth = 1; \n\n                this.data.forEach(p => {\n                    const desX = toCx(p.x), desY = toCy(p.y);\n                    const actX = toCx(p.xp), actY = toCy(p.yp);\n                    ctx.strokeStyle = '#e2e8f0'; ctx.lineWidth = 1;\n                    ctx.beginPath(); ctx.moveTo(desX, desY); ctx.lineTo(actX, actY); ctx.stroke();\n                    ctx.strokeStyle = '#64748b'; ctx.lineWidth = 1.5;\n                    ctx.beginPath(); ctx.arc(desX, desY, 5, 0, Math.PI*2); ctx.stroke();\n                    ctx.fillStyle = p.isFail ? '#ef4444' : '#3b82f6';\n                    ctx.beginPath(); ctx.arc(actX, actY, 7, 0, Math.PI*2);\n                    ctx.fill();\n                    \n                    ctx.fillStyle = '#1e293b'; ctx.textAlign = 'center'; \n                    ctx.font = '700 16px Sarabun';\n                    ctx.fillText(p.name, actX, actY - 18); \n                    \n                    ctx.font = 'bold 14px Sarabun';\n                    \/\/ Show 2 decimal places in canvas to match table\n                    ctx.fillText(`${p.reaction.toFixed(2)}`, actX, actY + 24);\n                });\n            }\n        };\n\n        window.onload = () => app.init();\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pile Deviation Report Rigid Body Analysis Method Footing: &#8211; Grid Line: &#8211; Date: &#8211; Export PDF Design Inputs Footing No. Grid X Grid Y Axial Load (P) [Tons] Mx [T-m] My [T-m] Safe Load [T\/Pile] Total Piles:0 New C.G.:0, 0 Max Rx:0.00 T Status:CHECKING Pile Data All Add No. Design (m) Deviation (m) Actual (m) Reaction(T) Sts x y Dx Dy x&#8217; y&#8217; Min:0.00 Max:0.00 Avg:0.00 \u03a3R: 0.00 T Plan View Design OK Fail Group C.G. APPENDIX A: CALCULATION BASIS 1. Coordinate &#038; Inertia Properties X = x&#8217; &#8211; Xcg , Y = y&#8217; &#8211; Ycg Ix = &Sigma;Y2 ,<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-basic","meta":{"footnotes":""},"class_list":["post-193","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/pages\/193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.e2connection.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=193"}],"version-history":[{"count":21,"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/pages\/193\/revisions"}],"predecessor-version":[{"id":244,"href":"https:\/\/www.e2connection.com\/index.php?rest_route=\/wp\/v2\/pages\/193\/revisions\/244"}],"wp:attachment":[{"href":"https:\/\/www.e2connection.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}