{"id":10,"date":"2025-06-13T12:40:28","date_gmt":"2025-06-13T12:40:28","guid":{"rendered":"https:\/\/raidzfscalculator.com\/?page_id=10"},"modified":"2026-03-07T14:54:30","modified_gmt":"2026-03-07T14:54:30","slug":"raid-zfs-calculator","status":"publish","type":"page","link":"https:\/\/raidzfscalculator.com\/en\/","title":{"rendered":"Raid ZFS calculator"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;||0px|||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;1_2,1_2&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_blurb url=&#8221;https:\/\/raidzfscalculator.com\/&#8221; image=&#8221;https:\/\/www.raidzfscalculator.com\/en\/wp-content\/uploads\/2025\/11\/icons8-la-france-48.png&#8221; alt=&#8221;RAID ZFS CALCULATOR FIO  RESULT VIEWER&#8221; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p style=\"text-align: center;\"><strong>Site en Fran\u00e7ais<\/strong><\/p>\n<p>[\/et_pb_blurb][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_blurb url=&#8221;https:\/\/www.raidzfscalculator.com\/en\/&#8221; image=&#8221;https:\/\/www.raidzfscalculator.com\/en\/wp-content\/uploads\/2025\/11\/icons8-grande-bretagne-48.png&#8221; alt=&#8221;RAID ZFS CALCULATOR FIO RESULT VIEWER&#8221; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p style=\"text-align: center;\"><strong>Website in english<\/strong><\/p>\n<p>[\/et_pb_blurb][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.16&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; parallax__hover=&#8221;off&#8221; parallax_method__hover=&#8221;on&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_divider color=&#8221;#1ca5ff&#8221; divider_weight=&#8221;16px&#8221; _builder_version=&#8221;4.16&#8243; max_width=&#8221;48px&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_divider][et_pb_text _builder_version=&#8221;4.16&#8243; text_font=&#8221;||||||||&#8221; text_line_height=&#8221;2em&#8221; header_font=&#8221;Poppins|600|||||||&#8221; header_font_size=&#8221;50px&#8221; header_line_height=&#8221;1.3em&#8221; header_font_size_tablet=&#8221;30px&#8221; header_font_size_phone=&#8221;24px&#8221; header_font_size_last_edited=&#8221;on|phone&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h1>Raid &amp; ZFS calculator<\/h1>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]        <style>\n        .raid-calc{max-width:1200px;margin:0 auto;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}\n        .calc-container{background:#fff;border-radius:12px;box-shadow:0 4px 20px rgba(0,0,0,.1);padding:30px;margin:20px 0}\n        .calc-title{font-size:2.5rem;font-weight:700;color:#1a202c;margin-bottom:20px;text-align:center}\n        .warning{background:linear-gradient(135deg,#fff7ed 0%,#fed7aa 100%);border-left:5px solid #f97316;border-radius:8px;padding:20px;margin-bottom:30px;display:flex;align-items:flex-start;gap:15px}\n        .warning-text{font-size:14px;line-height:1.6;color:#9a3412}\n        .tabs{display:flex;border-bottom:2px solid #e2e8f0;margin-bottom:30px}\n        .tab-btn{background:none;border:none;padding:15px 25px;font-size:16px;font-weight:600;color:#64748b;cursor:pointer;border-bottom:3px solid transparent;transition:all .3s ease}\n        .tab-btn:hover{color:#334155;background:#f8fafc}\n        .tab-btn.active{color:#3b82f6;border-bottom-color:#3b82f6;background:#eff6ff}\n        .tab-content{display:none}\n        .tab-content.active{display:block}\n        .section{margin-bottom:40px}\n        .section h3{font-size:1.5rem;font-weight:600;color:#1e293b;margin-bottom:20px;border-bottom:2px solid #e2e8f0;padding-bottom:10px}\n        .config-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:25px;margin-bottom:30px}\n        .input-group{display:flex;flex-direction:column;gap:8px}\n        .input-group label{font-weight:600;color:#374151;font-size:14px}\n        .input-group input,.input-group select{padding:12px 16px;border:2px solid #d1d5db;border-radius:8px;font-size:15px;transition:all .3s ease}\n        .input-group input:focus,.input-group select:focus{outline:none;border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}\n        .add-disk-btn{background:linear-gradient(135deg,#10b981 0%,#059669 100%);color:#fff;border:none;padding:12px 24px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:15px;margin-top:8px}\n        .add-disk-btn:hover{background:linear-gradient(135deg,#059669 0%,#047857 100%);transform:translateY(-2px);box-shadow:0 4px 12px rgba(16,185,129,.4)}\n        .update-btn{background:linear-gradient(135deg,#f97316 0%,#ea580c 100%);color:#fff;border:none;padding:12px 24px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:15px;margin-top:8px}\n        .update-btn:hover{background:linear-gradient(135deg,#ea580c 0%,#c2410c 100%);transform:translateY(-2px);box-shadow:0 4px 12px rgba(249,115,22,.4)}\n        .disk-type-btns{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}\n        .type-btn{padding:10px 16px;border:2px solid #d1d5db;border-radius:6px;background:#fff;color:#374151;font-weight:500;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .type-btn:hover{border-color:#3b82f6;background:#eff6ff}\n        .type-btn.active{background:linear-gradient(135deg,#3b82f6 0%,#1d4ed8 100%);border-color:#1d4ed8;color:#fff;box-shadow:0 4px 12px rgba(59,130,246,.4)}\n        .raid-btns{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:30px}\n        .raid-btn{padding:12px 20px;border:2px solid #d1d5db;border-radius:8px;background:#fff;color:#374151;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .raid-btn:hover{border-color:#3b82f6;background:#eff6ff;transform:translateY(-1px)}\n        .raid-btn.active{background:linear-gradient(135deg,#3b82f6 0%,#1d4ed8 100%);border-color:#1d4ed8;color:#fff;box-shadow:0 4px 12px rgba(59,130,246,.4)}\n        .raid-btn.zfs{border-color:#16a34a;background:linear-gradient(135deg,#f0fdf4 0%,#dcfce7 100%);color:#166534}\n        .raid-btn.zfs.active{background:linear-gradient(135deg,#16a34a 0%,#15803d 100%);border-color:#15803d;color:#fff}\n        .disk-array-container{background:linear-gradient(135deg,#1e293b 0%,#334155 100%);border-radius:12px;padding:30px;margin-bottom:20px}\n        .disk-array{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:20px;justify-content:center}\n        .disk-slot{width: 80px; height: 100px; border:2px solid #64748b; border-radius:8px; background:rgba(148,163,184,.1); display:flex; flex-direction:column; align-items:center; justify-content:center; cursor:pointer; transition:all .3s ease; color:#94a3b8; font-size:12px; font-weight:500; flex-shrink: 0;}\n        .disk-slot:hover{border-color:#94a3b8;background:rgba(148,163,184,.2)}\n        .disk-slot.filled{border-color:#3b82f6;background:linear-gradient(135deg,#1e40af 0%,#3b82f6 100%);color:#fff;border-style:solid}\n        .disk-slot.filled.ssd{border-color:#7c3aed;background:linear-gradient(135deg,#6d28d9 0%,#7c3aed 100%)}\n        .disk-slot.filled:hover{background:linear-gradient(135deg,#1d4ed8 0%,#2563eb 100%);transform:translateY(-2px)}\n        .disk-slot.filled.ssd:hover{background:linear-gradient(135deg,#5b21b6 0%,#6d28d9 100%)}\n        .disk-counter{display:flex;justify-content:space-between;align-items:center;color:#e2e8f0;font-size:14px}\n        .reset-btn{background:linear-gradient(135deg,#ef4444 0%,#dc2626 100%);color:#fff;border:none;padding:10px 20px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .results{background:linear-gradient(135deg,#f8fafc 0%,#f1f5f9 100%);border-radius:12px;padding:30px;border:2px solid #e2e8f0;display:none}\n        .results.show{display:block}\n        .results-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:20px;margin-bottom:20px}\n        .result-item{text-align:center;background:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,.1)}\n        .result-value{font-size:1.8rem;font-weight:700;margin-bottom:8px}\n        .result-label{font-size:13px;color:#64748b;font-weight:500}\n        .total-display{padding:12px 16px;background:linear-gradient(135deg,#f0f9ff 0%,#e0f2fe 100%);border:2px solid #0284c7;border-radius:8px;font-weight:600;color:#0c4a6e;font-size:15px}\n        @media (max-width:768px){.disk-array{grid-template-columns:repeat(6,1fr)}.config-grid{grid-template-columns:1fr}.results-grid{grid-template-columns:repeat(2,1fr)}}\n        <\/style>\n\n        <div class=\"raid-calc\">\n            <div class=\"calc-container\">\n                <h1 class=\"calc-title\">RAID & TCO calculator<\/h1>\n                \n                <div class=\"warning\">\n                    <div style=\"font-size:24px;flex-shrink:0\">\u26a0\ufe0f<\/div>\n                    <div class=\"warning-text\">\n                        <strong>Important note :<\/strong> This calculator is provided for informational purposes only.\nActual performance may vary depending on the hardware used.\n                    <\/div>\n                <\/div>\n\n                <div class=\"tabs\">\n                    <button class=\"tab-btn active\" onclick=\"switchTab('raid')\">\ud83d\udcbe RAID configuration<\/button>\n                    <button class=\"tab-btn\" onclick=\"switchTab('tco')\">\ud83d\udcb0 TCO analysis<\/button>\n                <\/div>\n\n                <div id=\"raid-tab\" class=\"tab-content active\">\n                    <div class=\"section\">\n                        <h3>Add disks<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Disks capacity (GB)<\/label>\n                                <input type=\"number\" id=\"diskCapacity\" placeholder=\"Ex: 20000\" min=\"100\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Number of disks<\/label>\n                                <input type=\"number\" id=\"diskCount\" placeholder=\"Ex: 4\" min=\"1\" max=\"84\" value=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Type of disks<\/label>\n                                <div class=\"disk-type-btns\">\n                                    <button class=\"type-btn active\" onclick=\"setDiskType('hdd')\">\ud83d\udcbf HDD<\/button>\n                                    <button class=\"type-btn\" onclick=\"setDiskType('ssd')\">\u26a1 SSD<\/button>\n                                <\/div>\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>&nbsp;<\/label>\n                                <div style=\"display: flex; gap: 8px;\">\n                                    <button class=\"add-disk-btn\" onclick=\"addMultipleDisks()\" style=\"flex-grow: 1;\">\u2795 Add disks<\/button>\n                                    <button class=\"update-btn\" onclick=\"calculate()\" style=\"flex-grow: 1;\">\u2699\ufe0f Update calculations<\/button>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>Configuration<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Read speed (Mo\/s)<\/label>\n                                <input type=\"number\" id=\"driveReadSpeed\" placeholder=\"Ex: 285\" value=\"285\" min=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Write speed (Mo\/s)<\/label>\n                                <input type=\"number\" id=\"driveWriteSpeed\" placeholder=\"Ex: 250\" value=\"250\" min=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>IOPS (operations\/s)<\/label>\n                                <input type=\"number\" id=\"driveIOPS\" placeholder=\"Ex: 150\" value=\"150\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Read\/Write Ratio (%)<\/label>\n                                <input type=\"number\" id=\"readWriteRatio\" min=\"0\" max=\"100\" value=\"70\">\n                                <small id=\"ratioDisplay\">70% Read \/ 30% Write<\/small>\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>AFR disks (%)<\/label>\n                                <input type=\"number\" id=\"afr\" placeholder=\"Ex: 0.5\" value=\"0.5\" step=\"0.01\" min=\"0\">\n                                <small>Annual Failure Rate<\/small>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>RAID configuration<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Disks per RAID group<\/label>\n                                <input type=\"number\" id=\"drivesPerGroup\" min=\"2\" max=\"106\" value=\"4\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Number of RAID groups<\/label>\n                                <input type=\"number\" id=\"numberOfGroups\" min=\"1\" max=\"8\" value=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Total disks required<\/label>\n                                <div class=\"total-display\" id=\"totalRequired\">4 disks<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>RAID level<\/h3>\n                        <div class=\"raid-btns\" id=\"raidButtons\"><\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <div class=\"disk-array-container\">\n                            <div class=\"disk-array\" id=\"diskArray\">\n                                <!-- Disques ajout\u00e9s dynamiquement ici -->\n                            <\/div>\n                            <div class=\"disk-counter\">\n                                <span id=\"diskCountDisplay\">Selected disks : 0<\/span>\n                                <button class=\"reset-btn\" onclick=\"resetConfig()\">\ud83d\udd04 Reset<\/button>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"raidResults\" class=\"results\">\n                        <h3>RAID results<\/h3>\n                        <div id=\"raidSelectionReminder\" style=\"font-weight:600; font-size:1.1rem; color:#1e293b; margin-bottom:20px; padding:10px 0; border-bottom:1px solid #e2e8f0;\"><\/div>\n                        <div class=\"results-grid\" id=\"resultsGrid\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <div id=\"tco-tab\" class=\"tab-content\">\n                    <div class=\"section\">\n                        <h3>Cost parameters<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Unit price of HDD ($)<\/label>\n                                <input type=\"number\" id=\"hddPrice\" value=\"200\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>SSD unit price ($)<\/label>\n                                <input type=\"number\" id=\"ssdPrice\" value=\"400\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of disk replacement (Spare) ($)<\/label>\n                                <input type=\"number\" id=\"sparePrice\" value=\"300\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of RAID Controller ($)<\/label>\n                                <input type=\"number\" id=\"controllerCost\" value=\"500\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of Casing\/Chassis ($)<\/label>\n                                <input type=\"number\" id=\"enclosureCost\" value=\"2000\">\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>Energy & Annual Parameters<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>HDD Consommation (W)<\/label>\n                                <input type=\"number\" id=\"hddPower\" value=\"8\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>SSD Consommation (W)<\/label>\n                                <input type=\"number\" id=\"ssdPower\" value=\"5\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Electricity ($\/kWh)<\/label>\n                                <input type=\"number\" id=\"electricityRate\" step=\"0.01\" value=\"0.12\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Maintenance\/year ($)<\/label>\n                                <input type=\"number\" id=\"maintenanceCost\" value=\"200\">\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"tcoResults\" class=\"results\">\n                        <h3>TCO Results<\/h3>\n                        <div class=\"results-grid\" id=\"tcoGrid\"><\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <script>\n        let selectedDisks = [];\n        let currentDiskType = 'hdd';\n        let currentRaid = 'RAID 6';\n        \n        const raids = ['RAID 0','RAID 1','RAID 5','RAID 6','RAID 10','RAIDZ1','RAIDZ2','RAIDZ3'];\n\n        function formatTB(gb) {\n            return (gb \/ 1000).toFixed(2) + ' TB';\n        }\n        \n        function init() {\n            generateRaidButtons();\n            updateDisplay();\n            calculate(); \n            bindEvents();\n        }\n        \n        function generateRaidButtons() {\n            let html = '';\n            raids.forEach(r => {\n                html += '<button class=\"raid-btn ' + (r.includes('RAIDZ') ? 'zfs' : '') + ' ' + (r==='RAID 6' ? 'active' : '') + '\" onclick=\"setRaid(\\'' + r + '\\')\">' + r + '<\/button>';\n            });\n            document.getElementById('raidButtons').innerHTML = html;\n        }\n        \n        function setDiskType(type) {\n            currentDiskType = type;\n            document.querySelectorAll('.type-btn').forEach(b => b.classList.remove('active'));\n            event.target.classList.add('active');\n            \n            \/\/ Mise \u00e0 jour des valeurs par d\u00e9faut pour les vitesses de lecture et d'\u00e9criture, IOPS et AFR\n            const readSpeedInput = document.getElementById('driveReadSpeed');\n            const writeSpeedInput = document.getElementById('driveWriteSpeed');\n            const iopsInput = document.getElementById('driveIOPS');\n            const afrInput = document.getElementById('afr');\n\n            if (type === 'ssd') {\n                \/\/ SSD standard speeds and IOPS and AFR (typically lower than HDD)\n                readSpeedInput.value = '550';\n                writeSpeedInput.value = '500';\n                iopsInput.value = '7500';\n                afrInput.value = '0.35';\n            } else {\n                \/\/ HDD standard speeds and IOPS and AFR\n                readSpeedInput.value = '285';\n                writeSpeedInput.value = '250';\n                iopsInput.value = '150';\n                afrInput.value = '0.70';\n            }\n\n            \/\/ Nous n'appelons pas calculate() ici pour ne pas relancer le calcul \u00e0 chaque changement de type. \n            \/\/ L'utilisateur est encourag\u00e9 \u00e0 utiliser le bouton \"Mettre \u00e0 jour les calculs\".\n        }\n        \n        function addMultipleDisks() {\n            const capacity = parseInt(document.getElementById('diskCapacity').value);\n            const count = parseInt(document.getElementById('diskCount').value);\n            \n            if(!capacity || capacity < 100) {\n                alert('Please enter a valid capacity (minimum 100 GB)');\n                return;\n            }\n            \n            if(!count || count < 1) {\n                alert('Please enter a valid number of disks');\n                return;\n            }\n            \n            if(selectedDisks.length + count > 84) {\n                alert('Impossible d\\'ajouter ' + count + ' disques. Maximum: ' + (84 - selectedDisks.length) + ' disques restants');\n                return;\n            }\n            \n            for(let i = 0; i < count; i++) {\n                selectedDisks.push({\n                    size: formatTB(capacity),\n                    value: capacity,\n                    type: currentDiskType,\n                    id: Date.now() + i\n                });\n            }\n            \n            updateDisplay();\n            calculate(); \/\/ Calcul apr\u00e8s ajout de disques\n        }\n        \n        function removeDisk(i) {\n            selectedDisks.splice(i, 1);\n            updateDisplay();\n            calculate();\n        }\n        \n        function updateDisplay() {\n            let html = '';\n            \/\/ It\u00e8re uniquement sur les disques s\u00e9lectionn\u00e9s (affichage dynamique)\n            selectedDisks.forEach((disk, index) => {\n                const typeClass = disk.type === 'ssd' ? 'ssd' : '';\n                const typeIcon = disk.type === 'ssd' ? '\u26a1' : '\ud83d\udcbf';\n                html += '<div class=\"disk-slot filled ' + typeClass + '\" onclick=\"removeDisk(' + index + ')\"><div style=\"font-size:11px;font-weight:600\">' + disk.size + '<\/div><div style=\"font-size:9px\">' + typeIcon + ' ' + disk.type.toUpperCase() + '<\/div><\/div>';\n            });\n\n            document.getElementById('diskArray').innerHTML = html;\n            \n            const required = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n            let counterText = 'Selectionned disks : ' + selectedDisks.length;\n            if(required !== selectedDisks.length) {\n                counterText += ' <span style=\"color:#f59e0b\">(Required: ' + required + ')<\/span>';\n            }\n            document.getElementById('diskCountDisplay').innerHTML = counterText;\n        }\n        \n        function setRaid(r) {\n            currentRaid = r;\n            document.querySelectorAll('.raid-btn').forEach(b => b.classList.remove('active'));\n            event.target.classList.add('active');\n            calculate();\n        }\n        \n        function calculate() {\n            if(selectedDisks.length === 0) {\n                document.getElementById('raidResults').classList.remove('show');\n                document.getElementById('tcoResults').classList.remove('show');\n                return;\n            }\n            \n            const results = calcRAID();\n            if(results) {\n                displayResults(results);\n                \/\/ CORRECTION: Assurez-vous d'afficher les r\u00e9sultats RAID apr\u00e8s le calcul\n                document.getElementById('raidResults').classList.add('show');\n            }\n            calculateTCO();\n        }\n\n        function calcMTBF(totalDisks, tolerance, afrPercent) {\n            if (totalDisks === 0 || afrPercent === 0) return Infinity;\n            \n            const AFR = afrPercent \/ 100; \/\/ Taux de d\u00e9faillance annuel (0 \u00e0 1)\n            const MTTR_HOURS = 10; \/\/ Temps de reconstruction estim\u00e9 en heures (tr\u00e8s optimiste)\n            const DAYS_IN_YEAR = 365.25;\n            const HOURS_IN_YEAR = DAYS_IN_YEAR * 24;\n\n            \/\/ Simple calcul de fiabilit\u00e9 pour RAID-5\/6\/Z1\/Z2 bas\u00e9 sur n-1 ou n-2 d\u00e9faillances\n            \/\/ Convertir AFR en taux de d\u00e9faillance horaire (Lambda)\n            const lambda = AFR \/ HOURS_IN_YEAR; \n\n            if (tolerance === 0) {\n                 \/\/ RAID 0 \/ RAID 1\n                 \/\/ Taux de d\u00e9faillance total = Somme des lambdas individuels\n                 return (1 \/ (totalDisks * lambda)) \/ (24 * DAYS_IN_YEAR);\n            }\n            \n            \/\/ Calcul du MTBF pour RAID 5\/6 (protection contre 1 ou 2 pannes)\n            \/\/ Utilisation d'une approximation pour la fiabilit\u00e9 d'un syst\u00e8me redondant\n            \/\/ Formula for k-out-of-n system for 1 fault tolerance (RAID 5\/Z1): \n            \/\/ MTBF \u2248 (2 \/ (n * (n-1) * \u03bb^2 * MTTR)) \n            \/\/ Where n = totalDisks, \u03bb = lambda\n            if (tolerance === 1 && totalDisks >= 3) {\n                 const MTTR_YEARS = MTTR_HOURS \/ HOURS_IN_YEAR;\n                 const failureRate = totalDisks * (totalDisks - 1) * Math.pow(lambda, 2) * MTTR_YEARS \/ 2;\n                 return (1 \/ failureRate) \/ (24 * DAYS_IN_YEAR); \/\/ R\u00e9sultat en ann\u00e9es\n            }\n            \n            \/\/ Pour les tol\u00e9rances sup\u00e9rieures (RAID 6\/Z2\/Z3), le calcul est beaucoup plus complexe. \n            \/\/ Nous allons simplifier en estimant que chaque niveau de tol\u00e9rance double grossi\u00e8rement le MTBF initial.\n            \/\/ Ceci est une simplification.\n            let simpleMTBF = (1 \/ (totalDisks * lambda)) \/ (24 * DAYS_IN_YEAR);\n            if (tolerance > 1) {\n                \/\/ Tenter une approximation pour doubler pour chaque niveau de tol\u00e9rance suppl\u00e9mentaire\n                simpleMTBF = simpleMTBF * Math.pow(2, tolerance); \n            }\n            \n            return simpleMTBF;\n        }\n\n        function calcRAID() {\n            const totalDisks = selectedDisks.length;\n            const smallest = totalDisks > 0 ? Math.min(...selectedDisks.map(d => d.value)) : 0;\n            const totalRaw = selectedDisks.reduce((s,d) => s + d.value, 0);\n\n            \/\/ --- NOUVELLE LOGIQUE POUR LE CALCUL DES PERFORMANCES ---\n            const groupDisks = parseInt(document.getElementById('drivesPerGroup').value || 4); \/\/ Disques par groupe\n            const numGroups = parseInt(document.getElementById('numberOfGroups').value || 1);       \/\/ Nombre de groupes\n\n            const totalRequired = groupDisks * numGroups;\n            \n            \/\/ Si le nombre total de disques n'est pas suffisant pour la configuration requise\n            if (totalDisks < totalRequired || totalDisks === 0) {\n                \/\/ Pour que la capacit\u00e9 soit juste, mais que la performance soit 0 si la configuration est incompl\u00e8te\n                return {\n                    totalDisks: totalDisks,\n                    totalRaw: totalRaw,\n                    usable: 0,\n                    tolerance: 0,\n                    minDisks: totalRequired,\n                    speed: 0, \n                    efficiency: 0,\n                    readSpeed: 0, \n                    writeSpeed: 0,\n                    iops: 0,\n                    readIOPS: 0, \n                    writeIOPS: 0, \n                    wastedParity: totalRaw,\n                    wastedSize: 0,\n                    mtbf: calcMTBF(totalDisks, 0, parseFloat(document.getElementById('afr').value || 0.5)),\n                    valid: false\n                };\n            }\n            \n            \/\/ Variables pour les calculs de performance\n            const currentReadSpeed = parseInt(document.getElementById('driveReadSpeed').value || 285);\n            const currentWriteSpeed = parseInt(document.getElementById('driveWriteSpeed').value || 250);\n            const currentIOPS = parseInt(document.getElementById('driveIOPS').value || 150); \n            const afrPercent = parseFloat(document.getElementById('afr').value || 0.5); \/\/ Nouvelle AFR\n\n            const readRatio = parseInt(document.getElementById('readWriteRatio').value || 70) \/ 100;\n            const writeRatio = 1 - readRatio; \n            \n            \/\/ CALCULS EFFECTU\u00c9S SUR UN SEUL GROUPE (groupDisks)\n            let usablePerGroup = 0, tolerancePerGroup = 0, minDisksPerGroup = 1, readMultPerGroup = 1, writeMultPerGroup = 1;\n            \n            switch(currentRaid) {\n                case 'RAID 0':\n                    usablePerGroup = groupDisks * smallest; tolerancePerGroup = 0; minDisksPerGroup = 2;\n                    readMultPerGroup = groupDisks * 0.9; writeMultPerGroup = groupDisks * 0.9;\n                    break;\n                case 'RAID 1':\n                    usablePerGroup = smallest; tolerancePerGroup = Math.floor(groupDisks\/2); minDisksPerGroup = 2;\n                    readMultPerGroup = 1; writeMultPerGroup = 0.8;\n                    break;\n                case 'RAID 5':\n                    usablePerGroup = (groupDisks-1) * smallest; tolerancePerGroup = 1; minDisksPerGroup = 3;\n                    readMultPerGroup = (groupDisks-1) * 0.8; writeMultPerGroup = (groupDisks-1) * 0.42;\n                    break;\n                case 'RAID 6':\n                    usablePerGroup = (groupDisks-2) * smallest; tolerancePerGroup = 2; minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks-2) * 0.75; writeMultPerGroup = (groupDisks-2) * 0.32;\n                    break;\n                case 'RAID 10':\n                    \/\/ RAID 10 est g\u00e9r\u00e9 comme (N\/2) miroirs.\n                    \/\/ Capacit\u00e9 par groupe (groupDisks doit \u00eatre pair, par exemple 4 disques = 2 miroirs)\n                    usablePerGroup = Math.floor(groupDisks\/2) * smallest; \n                    tolerancePerGroup = Math.floor(groupDisks\/2); \n                    minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks\/2) * 0.88; \n                    writeMultPerGroup = (groupDisks\/2) * 0.75;\n                    break;\n                case 'RAIDZ1':\n                    usablePerGroup = (groupDisks-1) * smallest; tolerancePerGroup = 1; minDisksPerGroup = 3;\n                    readMultPerGroup = (groupDisks-1) * 0.7; writeMultPerGroup = (groupDisks-1) * 0.35;\n                    break;\n                case 'RAIDZ2':\n                    usablePerGroup = (groupDisks-2) * smallest; tolerancePerGroup = 2; minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks-2) * 0.65; writeMultPerGroup = (groupDisks-2) * 0.25;\n                    break;\n                case 'RAIDZ3':\n                    usablePerGroup = (groupDisks-3) * smallest; tolerancePerGroup = 3; minDisksPerGroup = 5;\n                    readMultPerGroup = (groupDisks-3) * 0.6; writeMultPerGroup = (groupDisks-3) * 0.18;\n                    break;\n                default:\n                    \/\/ Cas par d\u00e9faut (devrait pas arriver)\n                    return null;\n            }\n\n            \/\/ Validation de la taille du groupe\n            if (groupDisks < minDisksPerGroup) {\n                 return {\n                    totalDisks: totalDisks,\n                    totalRaw: totalRaw,\n                    usable: 0,\n                    tolerance: tolerancePerGroup,\n                    minDisks: totalRequired,\n                    speed: 0, \n                    efficiency: 0,\n                    readSpeed: 0, \n                    writeSpeed: 0,\n                    iops: 0,\n                    readIOPS: 0, \n                    writeIOPS: 0, \n                    wastedParity: totalRaw,\n                    wastedSize: 0,\n                    mtbf: calcMTBF(totalDisks, 0, afrPercent),\n                    valid: false\n                };\n            }\n            \n            \/\/ --- AGR\u00c9GATION POUR LA CONFIGURATION TOTALE ---\n            \n            \/\/ Capacit\u00e9 totale utilisable = capacit\u00e9 par groupe * nombre de groupes\n            const usable = usablePerGroup * numGroups;\n\n            \/\/ La tol\u00e9rance est bas\u00e9e sur la tol\u00e9rance par groupe (simplifi\u00e9)\n            const tolerance = tolerancePerGroup; \n\n            \/\/ Calcul du MTBF (bas\u00e9 sur totalDisks, mais avec la tol\u00e9rance par groupe)\n            const mtbfYears = calcMTBF(totalDisks, tolerancePerGroup, afrPercent);\n            \n            \/\/ Vitesse\/IOPS totale = performance par groupe * nombre de groupes\n            const effectiveReadSpeed = Math.round(currentReadSpeed * readMultPerGroup * 0.92 * numGroups);\n            const effectiveWriteSpeed = Math.round(currentWriteSpeed * writeMultPerGroup * 0.92 * numGroups);\n            const speed = Math.round((effectiveReadSpeed * readRatio) + (effectiveWriteSpeed * writeRatio));\n            \n            const effectiveReadIOPS = Math.round(currentIOPS * readMultPerGroup * 0.92 * numGroups);\n            const effectiveWriteIOPS = Math.round(currentIOPS * writeMultPerGroup * 0.92 * numGroups);\n            const iops = Math.round((effectiveReadIOPS * readRatio) + (effectiveWriteIOPS * writeRatio));\n\n            \/\/ Calcul des capacit\u00e9s et de l'espace gaspill\u00e9 (bas\u00e9 sur totalDisks)\n            const capacityUsedByParity = (totalRaw - usable);\n            const smallestDiskCapacity = selectedDisks.length > 0 ? smallest : 0;\n            const capacityWastedByMismatchedSize = (totalDisks * smallestDiskCapacity) - totalRaw;\n\n            const efficiency = ((usable\/totalRaw) * 100).toFixed(1);\n            \n            \/\/ Validit\u00e9 : le nombre total de disques doit correspondre exactement au requis\n            const valid = totalDisks === totalRequired && groupDisks >= minDisksPerGroup;\n\n            return {\n                totalDisks: totalDisks,\n                totalRaw: totalRaw,\n                usable: usable,\n                tolerance: tolerance, \/\/ Tol\u00e9rance par groupe\n                minDisks: totalRequired, \n                speed: speed, \n                efficiency: efficiency,\n                readSpeed: effectiveReadSpeed, \n                writeSpeed: effectiveWriteSpeed,\n                iops: iops,\n                readIOPS: effectiveReadIOPS, \n                writeIOPS: effectiveWriteIOPS, \n                wastedParity: capacityUsedByParity,\n                wastedSize: capacityWastedByMismatchedSize < 0 ? 0 : capacityWastedByMismatchedSize,\n                mtbf: mtbfYears, \n                valid: valid\n            };\n        }\n        \n        function displayResults(r) {\n            \/\/ Mise \u00e0 jour de l'\u00e9l\u00e9ment de rappel RAID\n            const groupDisks = parseInt(document.getElementById('drivesPerGroup').value || 4);\n            const numGroups = parseInt(document.getElementById('numberOfGroups').value || 1);\n            const groupText = numGroups > 1 ? `${numGroups} groups of ${groupDisks} disks` : `${groupDisks} disks`;\n\n            document.getElementById('raidSelectionReminder').innerHTML = `Calculated configuration: <strong>${currentRaid}<\/strong> (${groupText})`;\n\n            let html = '';\n            if(!r.valid) {\n                \/\/ Message d'erreur ajust\u00e9 pour la nouvelle logique de validation\n                const totalRequired = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                \n                let validationMessage = '';\n                if (r.totalDisks < totalRequired) {\n                    validationMessage = `Insufficient number of disks. You added ${r.totalDisks}, but ${totalRequired} are required check number of drives or RAID configuration .`;\n                } else {\n                    \/\/ Calcul du minimum de disques requis par le niveau RAID\n                    const tempResults = calcRAID(true); \/\/ Appel temporaire sans les groupes pour le minDisksPerGroup\n                    const minDisksPerGroup = tempResults.minDisks;\n                    if (groupDisks < minDisksPerGroup) {\n                         validationMessage = `${currentRaid} requires a minimum of ${minDisksPerGroup} disks per group.`;\n                    }\n                    else if(r.totalDisks > totalRequired) {\n                         validationMessage = `Too many discs added. The RAID configuration uses ${totalRequired} disks, but ${r.totalDisks} were added.`;\n                    }\n                }\n\n                html += `<div style=\"grid-column:1\/-1;background:#fef2f2;border:2px solid #f87171;border-radius:8px;padding:16px;color:#dc2626;text-align:center;font-weight:600;margin-bottom:20px\">\u26a0\ufe0f Invalid configuration: ${validationMessage}<\/div>`;\n            }\n            \n            \/\/ Affichage des capacit\u00e9s en TB\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#059669\">' + formatTB(r.totalRaw) + '<\/div><div class=\"result-label\">Raw capacity<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#059669\">' + formatTB(r.usable) + '<\/div><div class=\"result-label\">Usable<\/div><\/div>';\n            \n            \/\/ Affichage de la fiabilit\u00e9\n            const mtbfDisplay = r.mtbf === Infinity ? '\u221e' : r.mtbf.toFixed(1) + ' years';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">' + mtbfDisplay + '<\/div><div class=\"result-label\">MTBF (Reliability)<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#7c3aed\">' + r.tolerance + '<\/div><div class=\"result-label\">Tolerance \/ group<\/div><\/div>';\n            \n            \/\/ Affichage de l'espace perdu\n            const totalWasted = r.wastedParity + r.wastedSize;\n            if (totalWasted > 0) {\n                 html += '<div class=\"result-item\" style=\"grid-column:1\/-1; background:#fef3c7\"><div class=\"result-value\" style=\"color:#b45309; font-size:1.4rem\">' + formatTB(totalWasted) + '<\/div><div class=\"result-label\">Total wasted space<small style=\"display:block;color:#b45309;font-size:10px\">(Parity: ' + formatTB(r.wastedParity) + ' \/ Size: ' + formatTB(r.wastedSize) + ')<\/small><\/div><\/div>';\n            }\n            \n            \/\/ Ligne pour les d\u00e9bits et efficacit\u00e9\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">' + r.efficiency + '%<\/div><div class=\"result-label\">Efficacity<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + r.readSpeed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Read speed (R)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">' + r.writeSpeed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Write speed (W)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">' + r.speed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Mixed rate speed<\/div><small style=\"color:#64748b;font-size:10px\">R\/W Ratio<\/small><\/div>';\n            \n            \/\/ Ligne pour les IOPS\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + r.readIOPS.toLocaleString() + '<\/div><div class=\"result-label\">IOPS Read (R)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">' + r.writeIOPS.toLocaleString() + '<\/div><div class=\"result-label\">IOPS Write (W)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">' + r.iops.toLocaleString() + '<\/div><div class=\"result-label\">Mixed IOPS<\/div><small style=\"color:#64748b;font-size:10px\">R\/W Ratio<\/small><\/div>';\n            \n            document.getElementById('resultsGrid').innerHTML = html;\n        }\n        \n        function calculateTCO() {\n            if(selectedDisks.length === 0) {\n                 document.getElementById('tcoResults').classList.remove('show');\n                 return;\n            }\n            \n            \/\/ PARAM\u00c8TRES DE CO\u00dbT (Co\u00fbts initiaux)\n            const hddPrice = parseFloat(document.getElementById('hddPrice').value || 200);\n            const ssdPrice = parseFloat(document.getElementById('ssdPrice').value || 400);\n            const sparePrice = parseFloat(document.getElementById('sparePrice').value || 300); \/\/ Nouveau\n            const controllerCost = parseFloat(document.getElementById('controllerCost').value || 500); \/\/ Nouveau\n            const enclosureCost = parseFloat(document.getElementById('enclosureCost').value || 2000); \/\/ Nouveau\n\n            \/\/ PARAM\u00c8TRES ANNUELS\n            const hddPower = parseFloat(document.getElementById('hddPower').value || 8);\n            const ssdPower = parseFloat(document.getElementById('ssdPower').value || 5);\n            const elecRate = parseFloat(document.getElementById('electricityRate').value || 0.12);\n            const maintenanceCost = parseFloat(document.getElementById('maintenanceCost').value || 200);\n            \n            const totalDisks = selectedDisks.length;\n            const hddCount = selectedDisks.filter(d => d.type === 'hdd').length;\n            const ssdCount = selectedDisks.filter(d => d.type === 'ssd').length;\n            const totalTB = selectedDisks.reduce((s,d) => s + (d.value\/1000), 0);\n            \n            \/\/ CALCUL DES CO\u00dbTS INTIAUX\n            const diskCosts = (hddCount * hddPrice) + (ssdCount * ssdPrice);\n            \/\/ On ajoute le prix d'un disque de rechange (Hot Spare) au co\u00fbt initial\n            const initialDiskCost = diskCosts + sparePrice; \n\n            const infraCosts = controllerCost + enclosureCost;\n            const initialCost = initialDiskCost + infraCosts; \/\/ Co\u00fbt Initial Total\n\n            \/\/ CALCUL DES CO\u00dbTS ANNUELS\n            const HOURS_IN_YEAR = 8766; \/\/ 365.25 jours * 24 heures\n\n            \/\/ Co\u00fbt \u00c9nerg\u00e9tique (Seuls les disques actuellement s\u00e9lectionn\u00e9s consomment)\n            const totalPower = (hddCount * hddPower) + (ssdCount * ssdPower); \/\/ Consommation totale en Watts\n            const totalKWhPerYear = (totalPower * HOURS_IN_YEAR) \/ 1000; \/\/ Consommation totale en kWh\/an\n            const powerCostPerYear = totalKWhPerYear * elecRate; \/\/ Co\u00fbt mon\u00e9taire annuel\n            \n            \/\/ Co\u00fbt de Remplacement (estim\u00e9 \u00e0 5% des disques annuellement)\n            const replacementCostPerYear = diskCosts * 0.05; \n            \n            \/\/ Co\u00fbt Annuel Total (\u00e9nergie + maintenance + remplacement)\n            const totalAnnualCost = powerCostPerYear + maintenanceCost + replacementCostPerYear;\n            \n            \/\/ CALCUL DU TCO (sur 5 ans)\n            const totalTCO = initialCost + (totalAnnualCost * 5);\n            const costPerTBYear = totalTCO \/ (totalTB * 5);\n            \n            \/\/ AFFICHAGE DES R\u00c9SULTATS TCO\n            let html = '';\n\n            \/\/ CO\u00dbTS INITIAUX\n            html += '<div class=\"result-item\" style=\"grid-column:1\/span 2;\"><div class=\"result-value\" style=\"color:#10b981\">$' + initialCost.toLocaleString() + '<\/div><div class=\"result-label\">Total initial cost<\/div><small style=\"color:#64748b;font-size:10px\">Disks + Spare + Infra<\/small><\/div>';\n            \n            \/\/ CO\u00dbTS ANNUELS D\u00c9TAILL\u00c9S\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#f59e0b\">$' + totalAnnualCost.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Total annual cost<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + totalKWhPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + ' kWh<\/div><div class=\"result-label\">Annual consumption<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">$' + powerCostPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Energy\/year<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">$' + maintenanceCost.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Maintenance\/year<\/div><\/div>';\n\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">$' + replacementCostPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Remplacement\/year<\/div><\/div>';\n\n            \/\/ TCO GLOBAL\n            html += '<div class=\"result-item\" style=\"grid-column:span 2; background:#e0f2fe;\"><div class=\"result-value\" style=\"color:#0284c7\">$' + totalTCO.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">TCO GLOBAL (5 years)<\/div><\/div>';\n            \n            html += '<div class=\"result-item\" style=\"grid-column:span 2;\"><div class=\"result-value\" style=\"color:#10b981\">$' + costPerTBYear.toFixed(2) + '<\/div><div class=\"result-label\">$\/TB\/year<\/div><\/div>';\n\n\n            \/\/ AFFICHAGE DES INFOS G\u00c9N\u00c9RALES\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#7c3aed\">' + totalTB.toFixed(1) + ' TB<\/div><div class=\"result-label\">Total capacity<\/div><\/div>';\n            if(ssdCount > 0 && hddCount > 0) {\n                html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#6366f1\">' + hddCount + ' HDD \/ ' + ssdCount + ' SSD<\/div><div class=\"result-label\">Mixed configuration<\/div><\/div>';\n            }\n            \n            document.getElementById('tcoGrid').innerHTML = html;\n            document.getElementById('tcoResults').classList.add('show');\n        }\n        \n        function switchTab(tab) {\n            document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));\n            if(event.target) event.target.classList.add('active'); \/\/ Check event.target exists\n            document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));\n            document.getElementById(tab + '-tab').classList.add('active');\n            \/\/ Assurez-vous que le calcul RAID s'ex\u00e9cute pour rafra\u00eechir les r\u00e9sultats si on est sur l'onglet RAID\n            if(tab === 'raid') calculate(); \n            if(tab === 'tco') calculateTCO();\n        }\n        \n        function bindEvents() {\n            document.getElementById('readWriteRatio').addEventListener('input', function(e) {\n                const r = e.target.value;\n                document.getElementById('ratioDisplay').textContent = r + '% Read \/ ' + (100-r) + '% Write';\n                calculate();\n            });\n            \n            \/\/ CORRECTION: Les \u00e9couteurs de `drivesPerGroup` et `numberOfGroups`\n            \/\/ doivent forcer le recalcul. Ils utilisaient d\u00e9j\u00e0 calculate(), mais \n            \/\/ nous les laissons ainsi pour la clart\u00e9.\n            document.getElementById('drivesPerGroup').addEventListener('input', function() {\n                const total = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                document.getElementById('totalRequired').textContent = total + ' disques';\n                updateDisplay();\n                calculate();\n            });\n            \n            document.getElementById('numberOfGroups').addEventListener('input', function() {\n                const total = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                document.getElementById('totalRequired').textContent = total + ' disques';\n                updateDisplay();\n                calculate();\n            });\n            \n            \/\/ \u00c9couteurs pour les nouvelles entr\u00e9es RAID \/ Perf\n            document.getElementById('driveReadSpeed').addEventListener('input', calculate);\n            document.getElementById('driveWriteSpeed').addEventListener('input', calculate);\n            document.getElementById('driveIOPS').addEventListener('input', calculate);\n            document.getElementById('afr').addEventListener('input', calculate);\n\n            \/\/ \u00c9couteurs pour les co\u00fbts TCO (n\u00e9cessite calculateTCO() et non calculate() )\n            ['hddPrice','ssdPrice','sparePrice','controllerCost','enclosureCost',\n             'hddPower','ssdPower','electricityRate','maintenanceCost'].forEach(function(id) {\n                document.getElementById(id).addEventListener('input', calculateTCO);\n            });\n            \n            \/\/ Allow Enter key to add disks\n            document.getElementById('diskCapacity').addEventListener('keypress', function(e) {\n                if(e.key === 'Enter') addMultipleDisks();\n            });\n            document.getElementById('diskCount').addEventListener('keypress', function(e) {\n                if(e.key === 'Enter') addMultipleDisks();\n            });\n        }\n        \n        function resetConfig() {\n            selectedDisks = [];\n            updateDisplay();\n            calculate();\n        }\n        \n        document.addEventListener('DOMContentLoaded', init);\n        <\/script>\n        [\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_text _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2 data-path-to-node=\"9\"><strong>Everything you need to know about RAID &amp; ZFS calculations<\/strong><\/h2>\n<blockquote data-path-to-node=\"10\">\n<p data-path-to-node=\"10,0\">Choosing the right storage configuration is crucial for the security of your data. Whether you&#8217;re setting up a <strong>NAS<\/strong> with <strong>TrueNAS<\/strong>, <strong>Unraid<\/strong>, or a <strong>Proxmox<\/strong> server, our calculator helps you anticipate the actual available capacity after formatting and system space reservation (SLOP).<\/p>\n<h3 data-path-to-node=\"10,1\"><b data-path-to-node=\"10,1\" data-index-in-node=\"0\">Why use a ZFS calculator?<\/b><\/h3>\n<p data-path-to-node=\"10,2\">Unlike traditional hardware RAID, the ZFS file system manages data in storage &#8220;pools.&#8221; Understanding the difference between:<\/p>\n<ul data-path-to-node=\"10,3\">\n<li>\n<p data-path-to-node=\"10,3,0,0\"><b data-path-to-node=\"10,3,0,0\" data-index-in-node=\"0\">RAIDZ1 :<\/b> Tolerates the failure of a single disk (RAID 5 equivalent). Ideal for home storage.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"10,3,1,0\"><b data-path-to-node=\"10,3,1,0\" data-index-in-node=\"0\">RAIDZ2 :<\/b> Double parity for increased security (RAID 6 equivalent). Recommended for high-capacity disks.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"10,3,2,0\"><b data-path-to-node=\"10,3,2,0\" data-index-in-node=\"0\">Mise en miroir (Mirroring) :<\/b> Offers the best read\/write performance, but with a 50% loss of space (equivalent to RAID 10).<\/p>\n<\/li>\n<\/ul>\n<h3 data-path-to-node=\"10,4\"><b data-path-to-node=\"10,4\" data-index-in-node=\"0\">Performance and IOPS<\/b><\/h3>\n<p data-path-to-node=\"10,5\">Our tool does more than just calculate GB. It also estimates the write penalty and IOPS of your disk array, thus preventing unpleasant surprises when deploying your virtual machines or backups.<\/p>\n<\/blockquote>\n<p>[\/et_pb_text][et_pb_text _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; hover_enabled=&#8221;0&#8243; sticky_enabled=&#8221;0&#8243;]<\/p>\n<h2 data-path-to-node=\"4\">Why Use a ZFS RAID Calculator for Your Storage Server?<\/h2>\n<p data-path-to-node=\"5\"><i data-path-to-node=\"5\" data-index-in-node=\"0\">Paragraph:<\/i> <b data-path-to-node=\"5\" data-index-in-node=\"11\">ZFS<\/b> (Zettabyte File System) has become the gold standard for data integrity on platforms like <b data-path-to-node=\"5\" data-index-in-node=\"105\">TrueNAS<\/b>, Proxmox, and Ubuntu. However, calculating usable capacity after parity overhead (<b data-path-to-node=\"5\" data-index-in-node=\"195\">RAID-Z1, RAID-Z2, RAID-Z3<\/b>) or mirroring can be tricky. Our online tool helps you simulate <b data-path-to-node=\"5\" data-index-in-node=\"285\">Vdev<\/b> configurations and predict available storage space while accounting for &#8220;slop space,&#8221; swap partitions, and system reserves.<\/p>\n<h2 data-path-to-node=\"7\">Optimize Your Server Performance with Our Free Tools<\/h2>\n<p data-path-to-node=\"8\"><i data-path-to-node=\"8\" data-index-in-node=\"0\">Paragraph:<\/i> Beyond raw capacity, disk performance for HDDs and SSDs is critical for a stable build. We have developed a suite of specialized tools for sysadmins and hardware enthusiasts:<\/p>\n<ul data-path-to-node=\"9\">\n<li>\n<p data-path-to-node=\"9,0,0\"><b data-path-to-node=\"9,0,0\" data-index-in-node=\"0\"><a href=\"https:\/\/raidzfscalculator.com\/en\/fio-results-viewer\/\" target=\"_blank\" rel=\"noopener\" title=\"FIO Results Visualizer\">FIO Results Visualizer<\/a>:<\/b> Convert complex JSON logs into readable charts to compare IOPS, throughput, and latency.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"9,1,0\"><b data-path-to-node=\"9,1,0\" data-index-in-node=\"0\"><a href=\"https:\/\/raidzfscalculator.com\/en\/rebuild-time-calculator\/\" target=\"_blank\" rel=\"noopener\" title=\"RAID Rebuild Time Estimator\">RAID Rebuild Time Estimator<\/a>:<\/b> Calculate how long it will take to resilver your ZFS pool after a drive failure to assess your data loss risk.<\/p>\n<\/li>\n<li>\n<p data-path-to-node=\"9,2,0\"><b data-path-to-node=\"9,2,0\" data-index-in-node=\"0\"><a href=\"https:\/\/raidzfscalculator.com\/en\/bottleneck-analyzer\/\" target=\"_blank\" rel=\"noopener\" title=\"PC Bottleneck Calculator\">PC Bottleneck Calculator<\/a>:<\/b> Identify if your CPU or GPU is limiting your hardware performance in gaming or professional workloads.<\/p>\n<\/li>\n<\/ul>\n<p data-path-to-node=\"13\">[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_accordion _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_accordion_item title=&#8221;How much usable space do I get with RAIDZ2?&#8221; open=&#8221;on&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>RAIDZ2 requires at least 4 disks and uses 2 of them for parity. Your usable space is calculated as (N-2) times the smallest disk capacity. Our calculator also subtracts the ZFS overhead for more accuracy.<\/p>\n<p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Is RAIDZ1 safe for large hard drives?&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<\/p>\n<p>For modern high-capacity drives (8TB+), RAIDZ2 is highly recommended. The &#8220;resilver&#8221; (rebuild) time for large drives is long, and a second failure during this process would result in total data loss in RAIDZ1.<\/p>\n<p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;What is the ZFS SLOP space reservation?&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<\/p>\n<p>ZFS reserves about 3.2% (1\/32) of the pool capacity as &#8220;SLOP&#8221; space. This prevents the file system from becoming completely locked or extremely slow when it reaches near-full capacity.<\/p>\n<p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;Does this calculator work for TrueNAS and Unraid?&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<\/p>\n<p>Yes! While Unraid uses a different parity system for its main array, it supports ZFS pools. TrueNAS is built entirely on ZFS. Our tool provides accurate estimations for both systems.<\/p>\n<p>[\/et_pb_accordion_item][et_pb_accordion_item title=&#8221;What are IOPS in a RAID configuration?&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221; open=&#8221;off&#8221;]<\/p>\n<p>IOPS (Input\/Output Operations Per Second) represent the speed of your array. In a RAIDZ configuration, the write IOPS are generally limited to the speed of a single drive in the VDEV, while read IOPS scale with the number of data drives.<\/p>\n<p>[\/et_pb_accordion_item][\/et_pb_accordion][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; custom_padding=&#8221;13px|||||&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<!DOCTYPE html><!-- [et_pb_line_break_holder] --><html lang=\"fr\"><!-- [et_pb_line_break_holder] --><head><!-- [et_pb_line_break_holder] -->    <meta charset=\"UTF-8\"><!-- [et_pb_line_break_holder] -->    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><!-- [et_pb_line_break_holder] -->    <title>RAID ZFS Calculator &#8211; Introduction<\/title><!-- [et_pb_line_break_holder] -->    <\/p>\n<style><!-- [et_pb_line_break_holder] -->        .intro-container {<!-- [et_pb_line_break_holder] -->            max-width: 1200px;<!-- [et_pb_line_break_holder] -->            margin: 0 auto;<!-- [et_pb_line_break_holder] -->            padding: 40px 20px;<!-- [et_pb_line_break_holder] -->            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;<!-- [et_pb_line_break_holder] -->            line-height: 1.6;<!-- [et_pb_line_break_holder] -->            color: #334155;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .hero-section {<!-- [et_pb_line_break_holder] -->            text-align: center;<!-- [et_pb_line_break_holder] -->            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);<!-- [et_pb_line_break_holder] -->            color: white;<!-- [et_pb_line_break_holder] -->            padding: 80px 40px;<!-- [et_pb_line_break_holder] -->            border-radius: 20px;<!-- [et_pb_line_break_holder] -->            margin-bottom: 60px;<!-- [et_pb_line_break_holder] -->            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .hero-title {<!-- [et_pb_line_break_holder] -->            font-size: 3.5rem;<!-- [et_pb_line_break_holder] -->            font-weight: 800;<!-- [et_pb_line_break_holder] -->            margin-bottom: 20px;<!-- [et_pb_line_break_holder] -->            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .hero-subtitle {<!-- [et_pb_line_break_holder] -->            font-size: 1.3rem;<!-- [et_pb_line_break_holder] -->            opacity: 0.9;<!-- [et_pb_line_break_holder] -->            margin-bottom: 30px;<!-- [et_pb_line_break_holder] -->            max-width: 800px;<!-- [et_pb_line_break_holder] -->            margin-left: auto;<!-- [et_pb_line_break_holder] -->            margin-right: auto;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .hero-features {<!-- [et_pb_line_break_holder] -->            display: flex;<!-- [et_pb_line_break_holder] -->            justify-content: center;<!-- [et_pb_line_break_holder] -->            gap: 40px;<!-- [et_pb_line_break_holder] -->            margin-top: 40px;<!-- [et_pb_line_break_holder] -->            flex-wrap: wrap;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .hero-feature {<!-- [et_pb_line_break_holder] -->            display: flex;<!-- [et_pb_line_break_holder] -->            align-items: center;<!-- [et_pb_line_break_holder] -->            gap: 10px;<!-- [et_pb_line_break_holder] -->            font-weight: 600;<!-- [et_pb_line_break_holder] -->            font-size: 1.1rem;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .section {<!-- [et_pb_line_break_holder] -->            margin-bottom: 60px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .section-title {<!-- [et_pb_line_break_holder] -->            font-size: 2.5rem;<!-- [et_pb_line_break_holder] -->            font-weight: 700;<!-- [et_pb_line_break_holder] -->            color: #1e293b;<!-- [et_pb_line_break_holder] -->            margin-bottom: 30px;<!-- [et_pb_line_break_holder] -->            text-align: center;<!-- [et_pb_line_break_holder] -->            position: relative;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .section-title::after {<!-- [et_pb_line_break_holder] -->            content: '';<!-- [et_pb_line_break_holder] -->            position: absolute;<!-- [et_pb_line_break_holder] -->            bottom: -10px;<!-- [et_pb_line_break_holder] -->            left: 50%;<!-- [et_pb_line_break_holder] -->            transform: translateX(-50%);<!-- [et_pb_line_break_holder] -->            width: 80px;<!-- [et_pb_line_break_holder] -->            height: 4px;<!-- [et_pb_line_break_holder] -->            background: linear-gradient(90deg, #667eea, #764ba2);<!-- [et_pb_line_break_holder] -->            border-radius: 2px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .intro-grid {<!-- [et_pb_line_break_holder] -->            display: grid;<!-- [et_pb_line_break_holder] -->            grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));<!-- [et_pb_line_break_holder] -->            gap: 40px;<!-- [et_pb_line_break_holder] -->            margin: 40px 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .intro-card {<!-- [et_pb_line_break_holder] -->            background: white;<!-- [et_pb_line_break_holder] -->            padding: 40px;<!-- [et_pb_line_break_holder] -->            border-radius: 16px;<!-- [et_pb_line_break_holder] -->            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);<!-- [et_pb_line_break_holder] -->            transition: transform 0.3s ease, box-shadow 0.3s ease;<!-- [et_pb_line_break_holder] -->            border-left: 5px solid #667eea;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .intro-card:hover {<!-- [et_pb_line_break_holder] -->            transform: translateY(-5px);<!-- [et_pb_line_break_holder] -->            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .card-icon {<!-- [et_pb_line_break_holder] -->            font-size: 3rem;<!-- [et_pb_line_break_holder] -->            margin-bottom: 20px;<!-- [et_pb_line_break_holder] -->            display: block;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .card-title {<!-- [et_pb_line_break_holder] -->            font-size: 1.5rem;<!-- [et_pb_line_break_holder] -->            font-weight: 700;<!-- [et_pb_line_break_holder] -->            color: #1e293b;<!-- [et_pb_line_break_holder] -->            margin-bottom: 15px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .card-text {<!-- [et_pb_line_break_holder] -->            color: #64748b;<!-- [et_pb_line_break_holder] -->            line-height: 1.6;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .features-grid {<!-- [et_pb_line_break_holder] -->            display: grid;<!-- [et_pb_line_break_holder] -->            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));<!-- [et_pb_line_break_holder] -->            gap: 30px;<!-- [et_pb_line_break_holder] -->            margin: 40px 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .feature-item {<!-- [et_pb_line_break_holder] -->            display: flex;<!-- [et_pb_line_break_holder] -->            align-items: flex-start;<!-- [et_pb_line_break_holder] -->            gap: 20px;<!-- [et_pb_line_break_holder] -->            padding: 30px;<!-- [et_pb_line_break_holder] -->            background: #f8fafc;<!-- [et_pb_line_break_holder] -->            border-radius: 12px;<!-- [et_pb_line_break_holder] -->            transition: all 0.3s ease;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .feature-item:hover {<!-- [et_pb_line_break_holder] -->            background: #e2e8f0;<!-- [et_pb_line_break_holder] -->            transform: translateX(5px);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .feature-icon {<!-- [et_pb_line_break_holder] -->            font-size: 2rem;<!-- [et_pb_line_break_holder] -->            color: #667eea;<!-- [et_pb_line_break_holder] -->            flex-shrink: 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .feature-content h4 {<!-- [et_pb_line_break_holder] -->            font-size: 1.2rem;<!-- [et_pb_line_break_holder] -->            font-weight: 600;<!-- [et_pb_line_break_holder] -->            color: #1e293b;<!-- [et_pb_line_break_holder] -->            margin-bottom: 8px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .feature-content p {<!-- [et_pb_line_break_holder] -->            color: #64748b;<!-- [et_pb_line_break_holder] -->            margin: 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .stats-section {<!-- [et_pb_line_break_holder] -->            background: linear-gradient(135deg, #1e293b 0%, #334155 100%);<!-- [et_pb_line_break_holder] -->            color: white;<!-- [et_pb_line_break_holder] -->            padding: 60px 40px;<!-- [et_pb_line_break_holder] -->            border-radius: 16px;<!-- [et_pb_line_break_holder] -->            text-align: center;<!-- [et_pb_line_break_holder] -->            margin: 60px 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .stats-grid {<!-- [et_pb_line_break_holder] -->            display: grid;<!-- [et_pb_line_break_holder] -->            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));<!-- [et_pb_line_break_holder] -->            gap: 40px;<!-- [et_pb_line_break_holder] -->            margin-top: 40px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .stat-item {<!-- [et_pb_line_break_holder] -->            text-align: center;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .stat-number {<!-- [et_pb_line_break_holder] -->            font-size: 3rem;<!-- [et_pb_line_break_holder] -->            font-weight: 800;<!-- [et_pb_line_break_holder] -->            color: #60a5fa;<!-- [et_pb_line_break_holder] -->            display: block;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .stat-label {<!-- [et_pb_line_break_holder] -->            font-size: 1.1rem;<!-- [et_pb_line_break_holder] -->            opacity: 0.9;<!-- [et_pb_line_break_holder] -->            margin-top: 8px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .cta-section {<!-- [et_pb_line_break_holder] -->            background: linear-gradient(135deg, #10b981 0%, #059669 100%);<!-- [et_pb_line_break_holder] -->            color: white;<!-- [et_pb_line_break_holder] -->            padding: 60px 40px;<!-- [et_pb_line_break_holder] -->            border-radius: 16px;<!-- [et_pb_line_break_holder] -->            text-align: center;<!-- [et_pb_line_break_holder] -->            margin: 60px 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .cta-title {<!-- [et_pb_line_break_holder] -->            font-size: 2.5rem;<!-- [et_pb_line_break_holder] -->            font-weight: 700;<!-- [et_pb_line_break_holder] -->            margin-bottom: 20px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .cta-text {<!-- [et_pb_line_break_holder] -->            font-size: 1.2rem;<!-- [et_pb_line_break_holder] -->            opacity: 0.9;<!-- [et_pb_line_break_holder] -->            margin-bottom: 30px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .cta-button {<!-- [et_pb_line_break_holder] -->            background: white;<!-- [et_pb_line_break_holder] -->            color: #059669;<!-- [et_pb_line_break_holder] -->            padding: 15px 40px;<!-- [et_pb_line_break_holder] -->            border: none;<!-- [et_pb_line_break_holder] -->            border-radius: 50px;<!-- [et_pb_line_break_holder] -->            font-size: 1.1rem;<!-- [et_pb_line_break_holder] -->            font-weight: 600;<!-- [et_pb_line_break_holder] -->            cursor: pointer;<!-- [et_pb_line_break_holder] -->            transition: all 0.3s ease;<!-- [et_pb_line_break_holder] -->            text-decoration: none;<!-- [et_pb_line_break_holder] -->            display: inline-block;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .cta-button:hover {<!-- [et_pb_line_break_holder] -->            transform: translateY(-2px);<!-- [et_pb_line_break_holder] -->            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .warning-box {<!-- [et_pb_line_break_holder] -->            background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);<!-- [et_pb_line_break_holder] -->            border-left: 5px solid #f59e0b;<!-- [et_pb_line_break_holder] -->            padding: 30px;<!-- [et_pb_line_break_holder] -->            border-radius: 12px;<!-- [et_pb_line_break_holder] -->            margin: 40px 0;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .warning-title {<!-- [et_pb_line_break_holder] -->            font-size: 1.3rem;<!-- [et_pb_line_break_holder] -->            font-weight: 700;<!-- [et_pb_line_break_holder] -->            color: #92400e;<!-- [et_pb_line_break_holder] -->            margin-bottom: 15px;<!-- [et_pb_line_break_holder] -->            display: flex;<!-- [et_pb_line_break_holder] -->            align-items: center;<!-- [et_pb_line_break_holder] -->            gap: 10px;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        .warning-text {<!-- [et_pb_line_break_holder] -->            color: #92400e;<!-- [et_pb_line_break_holder] -->            line-height: 1.6;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        <!-- [et_pb_line_break_holder] -->        @media (max-width: 768px) {<!-- [et_pb_line_break_holder] -->            .hero-title {<!-- [et_pb_line_break_holder] -->                font-size: 2.5rem;<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->            <!-- [et_pb_line_break_holder] -->            .hero-features {<!-- [et_pb_line_break_holder] -->                flex-direction: column;<!-- [et_pb_line_break_holder] -->                gap: 20px;<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->            <!-- [et_pb_line_break_holder] -->            .section-title {<!-- [et_pb_line_break_holder] -->                font-size: 2rem;<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->            <!-- [et_pb_line_break_holder] -->            .intro-grid {<!-- [et_pb_line_break_holder] -->                grid-template-columns: 1fr;<!-- [et_pb_line_break_holder] -->                gap: 30px;<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->            <!-- [et_pb_line_break_holder] -->            .stats-grid {<!-- [et_pb_line_break_holder] -->                grid-template-columns: repeat(2, 1fr);<!-- [et_pb_line_break_holder] -->                gap: 30px;<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->    <\/style>\n<p><!-- [et_pb_line_break_holder] --><\/head><!-- [et_pb_line_break_holder] --><body><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"intro-container\"><!-- [et_pb_line_break_holder] -->        <!-- Hero Section --><!-- [et_pb_line_break_holder] -->        <\/p>\n<section class=\"hero-section\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h1 class=\"hero-title\">RAID &#038; ZFS Calculator<\/h1>\n<p><!-- [et_pb_line_break_holder] -->            <pee class=\"hero-subtitle\"><!-- [et_pb_line_break_holder] -->                This RAID performance calculator and total cost of ownership (TCO) analysis tool is designed to optimize your storage infrastructure.<!-- [et_pb_line_break_holder] -->Get accurate estimates and recommendations based on real-world business scenarios.<!-- [et_pb_line_break_holder] -->            <\/pee><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"hero-features\"><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"hero-feature\"><!-- [et_pb_line_break_holder] -->                    <span>\ud83d\udcbe<\/span><!-- [et_pb_line_break_holder] -->                    <span>Major RAID levels<\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"hero-feature\"><!-- [et_pb_line_break_holder] -->                    <span>\u26a1<\/span><!-- [et_pb_line_break_holder] -->                    <span> Real-time calculation <\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"hero-feature\"><!-- [et_pb_line_break_holder] -->                    <span>\ud83d\udcb0<\/span><!-- [et_pb_line_break_holder] -->                    <span> Complete TCO analysis <\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"hero-feature\"><!-- [et_pb_line_break_holder] -->                    <span>\ud83c\udfaf<\/span><!-- [et_pb_line_break_holder] -->                    <span>Realistic estimation <\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <!-- Introduction --><!-- [et_pb_line_break_holder] -->        <\/p>\n<section class=\"section\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h2 class=\"section-title\">Why use our raid zfs calculator ?<\/h2>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"intro-grid\"><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"intro-card\"><!-- [et_pb_line_break_holder] -->                    <span class=\"card-icon\">\ud83c\udfaf<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<h3 class=\"card-title\">Professionel precision <\/h3>\n<p><!-- [et_pb_line_break_holder] -->                    <pee class=\"card-text\"><!-- [et_pb_line_break_holder] -->                        Our algorithms incorporate real-world write penalties, controller overhead, and system limitations to provide results close to real-world performance.<!-- [et_pb_line_break_holder] -->                    <\/pee><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"intro-card\"><!-- [et_pb_line_break_holder] -->                    <span class=\"card-icon\">\u2696\ufe0f<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<h3 class=\"card-title\">Conservative approach<\/h3>\n<p><!-- [et_pb_line_break_holder] -->                    <pee class=\"card-text\"><!-- [et_pb_line_break_holder] -->                        Unlike optimistic calculators, we apply reduction factors<!-- [et_pb_line_break_holder] -->based on company experience to avoid unpleasant surprises.<!-- [et_pb_line_break_holder] -->                    <\/pee><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"intro-card\"><!-- [et_pb_line_break_holder] -->                    <span class=\"card-icon\">\ud83d\udca1<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<h3 class=\"card-title\">Economic analysis<\/h3>\n<p><!-- [et_pb_line_break_holder] -->                    <pee class=\"card-text\"><!-- [et_pb_line_break_holder] -->                        Calculate the total cost of ownership (TCO) over 5 years, including purchase, electricity, maintenance and replacement of components.<!-- [et_pb_line_break_holder] -->                    <\/pee><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <!-- Statistics --><!-- [et_pb_line_break_holder] -->        <\/p>\n<section class=\"stats-section\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h2 style=\"font-size: 2.5rem; margin-bottom: 20px;\">Supported data<\/h2>\n<p><!-- [et_pb_line_break_holder] -->            <pee style=\"font-size: 1.2rem; opacity: 0.9;\">A complete calculator for all your storage needs<\/pee><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"stats-grid\"><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"stat-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-number\">84<\/span><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-label\">HDD maximum<\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"stat-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-number\">8<\/span><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-label\">Supported RAID levels<\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"stat-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-number\">5<\/span><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-label\">Years of total cost of ownership analysis<\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"stat-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-number\">100%<\/span><!-- [et_pb_line_break_holder] -->                    <span class=\"stat-label\">Free and unlimited<\/span><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <!-- Features --><!-- [et_pb_line_break_holder] -->        <\/p>\n<section class=\"section\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h2 class=\"section-title\">Advanced Features<\/h2>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"features-grid\"><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\u2699\ufe0f<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>Flexible configuration<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>Adjust the number of disks per RAID group, multiple groups, and read\/write ratios according to your needs.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\ud83d\udcca<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>RAID &#038; ZFS support<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>All standard RAID levels (0, 1, 5, 6, 10) plus ZFS variants (RAIDZ1, RAIDZ2, RAIDZ3) with their specific features.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\ud83d\udd0d<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>Smart validation<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>The calculator automatically checks the validity of the configurations and warns you of any impossible configurations.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\ud83d\udcf1<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>Responsive interface<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>Usable on computers, tablets, and mobile devices with an intuitive interface and clear visualizations.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\ud83d\udcbb<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>Real-time calculations<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>Instant results during editing with separate display of read and write performance.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"feature-item\"><!-- [et_pb_line_break_holder] -->                    <span class=\"feature-icon\">\ud83c\udfe2<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<div class=\"feature-content\"><!-- [et_pb_line_break_holder] -->                        <\/p>\n<h4>Business scenarios<\/h4>\n<p><!-- [et_pb_line_break_holder] -->                        <pee>Pre-configured settings for different use cases: office automation, virtualization, databases, archiving.<\/pee><!-- [et_pb_line_break_holder] -->                    <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <!-- Warning Box --><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"warning-box\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h3 class=\"warning-title\"><!-- [et_pb_line_break_holder] -->                <span>\u26a0\ufe0f<\/span><!-- [et_pb_line_break_holder] -->                Important to remember<!-- [et_pb_line_break_holder] -->            <\/h3>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"warning-text\"><!-- [et_pb_line_break_holder] -->                <pee><strong>This calculator provides estimates<\/strong>Based on typical configurations and conservative factors. Actual performance may vary depending on :<\/pee><!-- [et_pb_line_break_holder] -->                <\/p>\n<ul style=\"margin: 15px 0; padding-left: 20px;\"><!-- [et_pb_line_break_holder] -->                    <\/p>\n<li>The model and specifications of the hard drives<\/li>\n<p><!-- [et_pb_line_break_holder] -->                    <\/p>\n<li>The RAID controller used (hardware vs. software)<\/li>\n<p><!-- [et_pb_line_break_holder] -->                    <\/p>\n<li>System configuration (CPU, RAM, data bus)<\/li>\n<p><!-- [et_pb_line_break_holder] -->                    <\/p>\n<li>The type of workload and access patterns<\/li>\n<p><!-- [et_pb_line_break_holder] -->                    <\/p>\n<li>Firmware and file system configuration<\/li>\n<p><!-- [et_pb_line_break_holder] -->                <\/ul>\n<p><!-- [et_pb_line_break_holder] -->                <pee><strong>Recommandation :<\/strong> Use these results as a basis for planning, then conduct tests with your specific equipment to validate actual performance.<\/pee><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->        <!-- Use Cases --><!-- [et_pb_line_break_holder] -->        <\/p>\n<section class=\"section\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<h2 class=\"section-title\">Typical use cases<\/h2>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"intro-grid\"><!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"intro-card\"><!-- [et_pb_line_break_holder] -->                    <span class=\"card-icon\">\ud83c\udfe2<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<h3 class=\"card-title\">IT integrator<\/h3>\n<p><!-- [et_pb_line_break_holder] -->                    <pee class=\"card-text\"><!-- [et_pb_line_break_holder] -->                        Quickly size your clients&#8217; storage infrastructure.<!-- [et_pb_line_break_holder] -->Present detailed total cost of ownership analyses and justify your technical choices.<!-- [et_pb_line_break_holder] -->                    <\/pee><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->                <!-- [et_pb_line_break_holder] -->                <\/p>\n<div class=\"intro-card\"><!-- [et_pb_line_break_holder] -->                    <span class=\"card-icon\">\ud83d\udcbc<\/span><!-- [et_pb_line_break_holder] -->                    <\/p>\n<h3 class=\"card-title\">Storage consulting<\/h3>\n<p><!-- [et_pb_line_break_holder] -->                    <pee class=\"card-text\"><!-- [et_pb_line_break_holder] -->                        Use this tools to evaluate the performance and costs of different RAID configurations during audits or migration projects.<!-- [et_pb_line_break_holder] -->                    <\/pee><!-- [et_pb_line_break_holder] -->                <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] -->        <\/section>\n<p><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] --><\/body><!-- [et_pb_line_break_holder] --><\/html>[\/et_pb_code][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]<script type=\"application\/ld+json\"><!-- [et_pb_line_break_holder] -->{<!-- [et_pb_line_break_holder] -->  \"@context\": \"https:\/\/schema.org\",<!-- [et_pb_line_break_holder] -->  \"@type\": \"FAQPage\",<!-- [et_pb_line_break_holder] -->  \"mainEntity\": [<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"How much usable space do I get with RAIDZ2?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"RAIDZ2 requires at least 4 disks and uses 2 of them for parity. Your usable space is calculated as (N-2) times the smallest disk capacity. Our calculator also subtracts the ZFS overhead for more accuracy.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"Is RAIDZ1 safe for large hard drives?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"For modern high-capacity drives (8TB+), RAIDZ2 is highly recommended. The resilver time for large drives is long, and a second failure during this process would result in total data loss in RAIDZ1.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"What is the ZFS SLOP space reservation?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"ZFS reserves about 3.2% (1\/32) of the pool capacity as SLOP space. This prevents the file system from becoming completely locked or slow when it reaches near-full capacity.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"Does this calculator work for TrueNAS and Unraid?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"Yes! While Unraid uses a different parity system for its main array, it supports ZFS pools. TrueNAS is built entirely on ZFS. Our tool provides accurate estimations for both.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    },<!-- [et_pb_line_break_holder] -->    {<!-- [et_pb_line_break_holder] -->      \"@type\": \"Question\",<!-- [et_pb_line_break_holder] -->      \"name\": \"What are IOPS in a RAID configuration?\",<!-- [et_pb_line_break_holder] -->      \"acceptedAnswer\": {<!-- [et_pb_line_break_holder] -->        \"@type\": \"Answer\",<!-- [et_pb_line_break_holder] -->        \"text\": \"IOPS represent the speed of your array. In RAIDZ, write IOPS are generally limited to the speed of a single drive in the VDEV, while read IOPS scale with the number of data drives.\"<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->  ]<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Site en Fran\u00e7aisWebsite in englishRaid &amp; ZFS calculator        <style>\n        .raid-calc{max-width:1200px;margin:0 auto;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}\n        .calc-container{background:#fff;border-radius:12px;box-shadow:0 4px 20px rgba(0,0,0,.1);padding:30px;margin:20px 0}\n        .calc-title{font-size:2.5rem;font-weight:700;color:#1a202c;margin-bottom:20px;text-align:center}\n        .warning{background:linear-gradient(135deg,#fff7ed 0%,#fed7aa 100%);border-left:5px solid #f97316;border-radius:8px;padding:20px;margin-bottom:30px;display:flex;align-items:flex-start;gap:15px}\n        .warning-text{font-size:14px;line-height:1.6;color:#9a3412}\n        .tabs{display:flex;border-bottom:2px solid #e2e8f0;margin-bottom:30px}\n        .tab-btn{background:none;border:none;padding:15px 25px;font-size:16px;font-weight:600;color:#64748b;cursor:pointer;border-bottom:3px solid transparent;transition:all .3s ease}\n        .tab-btn:hover{color:#334155;background:#f8fafc}\n        .tab-btn.active{color:#3b82f6;border-bottom-color:#3b82f6;background:#eff6ff}\n        .tab-content{display:none}\n        .tab-content.active{display:block}\n        .section{margin-bottom:40px}\n        .section h3{font-size:1.5rem;font-weight:600;color:#1e293b;margin-bottom:20px;border-bottom:2px solid #e2e8f0;padding-bottom:10px}\n        .config-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:25px;margin-bottom:30px}\n        .input-group{display:flex;flex-direction:column;gap:8px}\n        .input-group label{font-weight:600;color:#374151;font-size:14px}\n        .input-group input,.input-group select{padding:12px 16px;border:2px solid #d1d5db;border-radius:8px;font-size:15px;transition:all .3s ease}\n        .input-group input:focus,.input-group select:focus{outline:none;border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}\n        .add-disk-btn{background:linear-gradient(135deg,#10b981 0%,#059669 100%);color:#fff;border:none;padding:12px 24px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:15px;margin-top:8px}\n        .add-disk-btn:hover{background:linear-gradient(135deg,#059669 0%,#047857 100%);transform:translateY(-2px);box-shadow:0 4px 12px rgba(16,185,129,.4)}\n        .update-btn{background:linear-gradient(135deg,#f97316 0%,#ea580c 100%);color:#fff;border:none;padding:12px 24px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:15px;margin-top:8px}\n        .update-btn:hover{background:linear-gradient(135deg,#ea580c 0%,#c2410c 100%);transform:translateY(-2px);box-shadow:0 4px 12px rgba(249,115,22,.4)}\n        .disk-type-btns{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}\n        .type-btn{padding:10px 16px;border:2px solid #d1d5db;border-radius:6px;background:#fff;color:#374151;font-weight:500;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .type-btn:hover{border-color:#3b82f6;background:#eff6ff}\n        .type-btn.active{background:linear-gradient(135deg,#3b82f6 0%,#1d4ed8 100%);border-color:#1d4ed8;color:#fff;box-shadow:0 4px 12px rgba(59,130,246,.4)}\n        .raid-btns{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:30px}\n        .raid-btn{padding:12px 20px;border:2px solid #d1d5db;border-radius:8px;background:#fff;color:#374151;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .raid-btn:hover{border-color:#3b82f6;background:#eff6ff;transform:translateY(-1px)}\n        .raid-btn.active{background:linear-gradient(135deg,#3b82f6 0%,#1d4ed8 100%);border-color:#1d4ed8;color:#fff;box-shadow:0 4px 12px rgba(59,130,246,.4)}\n        .raid-btn.zfs{border-color:#16a34a;background:linear-gradient(135deg,#f0fdf4 0%,#dcfce7 100%);color:#166534}\n        .raid-btn.zfs.active{background:linear-gradient(135deg,#16a34a 0%,#15803d 100%);border-color:#15803d;color:#fff}\n        .disk-array-container{background:linear-gradient(135deg,#1e293b 0%,#334155 100%);border-radius:12px;padding:30px;margin-bottom:20px}\n        .disk-array{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:20px;justify-content:center}\n        .disk-slot{width: 80px; height: 100px; border:2px solid #64748b; border-radius:8px; background:rgba(148,163,184,.1); display:flex; flex-direction:column; align-items:center; justify-content:center; cursor:pointer; transition:all .3s ease; color:#94a3b8; font-size:12px; font-weight:500; flex-shrink: 0;}\n        .disk-slot:hover{border-color:#94a3b8;background:rgba(148,163,184,.2)}\n        .disk-slot.filled{border-color:#3b82f6;background:linear-gradient(135deg,#1e40af 0%,#3b82f6 100%);color:#fff;border-style:solid}\n        .disk-slot.filled.ssd{border-color:#7c3aed;background:linear-gradient(135deg,#6d28d9 0%,#7c3aed 100%)}\n        .disk-slot.filled:hover{background:linear-gradient(135deg,#1d4ed8 0%,#2563eb 100%);transform:translateY(-2px)}\n        .disk-slot.filled.ssd:hover{background:linear-gradient(135deg,#5b21b6 0%,#6d28d9 100%)}\n        .disk-counter{display:flex;justify-content:space-between;align-items:center;color:#e2e8f0;font-size:14px}\n        .reset-btn{background:linear-gradient(135deg,#ef4444 0%,#dc2626 100%);color:#fff;border:none;padding:10px 20px;border-radius:8px;font-weight:600;cursor:pointer;transition:all .3s ease;font-size:14px}\n        .results{background:linear-gradient(135deg,#f8fafc 0%,#f1f5f9 100%);border-radius:12px;padding:30px;border:2px solid #e2e8f0;display:none}\n        .results.show{display:block}\n        .results-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:20px;margin-bottom:20px}\n        .result-item{text-align:center;background:#fff;padding:20px;border-radius:10px;box-shadow:0 2px 8px rgba(0,0,0,.1)}\n        .result-value{font-size:1.8rem;font-weight:700;margin-bottom:8px}\n        .result-label{font-size:13px;color:#64748b;font-weight:500}\n        .total-display{padding:12px 16px;background:linear-gradient(135deg,#f0f9ff 0%,#e0f2fe 100%);border:2px solid #0284c7;border-radius:8px;font-weight:600;color:#0c4a6e;font-size:15px}\n        @media (max-width:768px){.disk-array{grid-template-columns:repeat(6,1fr)}.config-grid{grid-template-columns:1fr}.results-grid{grid-template-columns:repeat(2,1fr)}}\n        <\/style>\n\n        <div class=\"raid-calc\">\n            <div class=\"calc-container\">\n                <h1 class=\"calc-title\">RAID & TCO calculator<\/h1>\n                \n                <div class=\"warning\">\n                    <div style=\"font-size:24px;flex-shrink:0\">\u26a0\ufe0f<\/div>\n                    <div class=\"warning-text\">\n                        <strong>Important note :<\/strong> This calculator is provided for informational purposes only.\nActual performance may vary depending on the hardware used.\n                    <\/div>\n                <\/div>\n\n                <div class=\"tabs\">\n                    <button class=\"tab-btn active\" onclick=\"switchTab('raid')\">\ud83d\udcbe RAID configuration<\/button>\n                    <button class=\"tab-btn\" onclick=\"switchTab('tco')\">\ud83d\udcb0 TCO analysis<\/button>\n                <\/div>\n\n                <div id=\"raid-tab\" class=\"tab-content active\">\n                    <div class=\"section\">\n                        <h3>Add disks<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Disks capacity (GB)<\/label>\n                                <input type=\"number\" id=\"diskCapacity\" placeholder=\"Ex: 20000\" min=\"100\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Number of disks<\/label>\n                                <input type=\"number\" id=\"diskCount\" placeholder=\"Ex: 4\" min=\"1\" max=\"84\" value=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Type of disks<\/label>\n                                <div class=\"disk-type-btns\">\n                                    <button class=\"type-btn active\" onclick=\"setDiskType('hdd')\">\ud83d\udcbf HDD<\/button>\n                                    <button class=\"type-btn\" onclick=\"setDiskType('ssd')\">\u26a1 SSD<\/button>\n                                <\/div>\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>&nbsp;<\/label>\n                                <div style=\"display: flex; gap: 8px;\">\n                                    <button class=\"add-disk-btn\" onclick=\"addMultipleDisks()\" style=\"flex-grow: 1;\">\u2795 Add disks<\/button>\n                                    <button class=\"update-btn\" onclick=\"calculate()\" style=\"flex-grow: 1;\">\u2699\ufe0f Update calculations<\/button>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>Configuration<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Read speed (Mo\/s)<\/label>\n                                <input type=\"number\" id=\"driveReadSpeed\" placeholder=\"Ex: 285\" value=\"285\" min=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Write speed (Mo\/s)<\/label>\n                                <input type=\"number\" id=\"driveWriteSpeed\" placeholder=\"Ex: 250\" value=\"250\" min=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>IOPS (operations\/s)<\/label>\n                                <input type=\"number\" id=\"driveIOPS\" placeholder=\"Ex: 150\" value=\"150\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Read\/Write Ratio (%)<\/label>\n                                <input type=\"number\" id=\"readWriteRatio\" min=\"0\" max=\"100\" value=\"70\">\n                                <small id=\"ratioDisplay\">70% Read \/ 30% Write<\/small>\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>AFR disks (%)<\/label>\n                                <input type=\"number\" id=\"afr\" placeholder=\"Ex: 0.5\" value=\"0.5\" step=\"0.01\" min=\"0\">\n                                <small>Annual Failure Rate<\/small>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>RAID configuration<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Disks per RAID group<\/label>\n                                <input type=\"number\" id=\"drivesPerGroup\" min=\"2\" max=\"106\" value=\"4\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Number of RAID groups<\/label>\n                                <input type=\"number\" id=\"numberOfGroups\" min=\"1\" max=\"8\" value=\"1\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Total disks required<\/label>\n                                <div class=\"total-display\" id=\"totalRequired\">4 disks<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>RAID level<\/h3>\n                        <div class=\"raid-btns\" id=\"raidButtons\"><\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <div class=\"disk-array-container\">\n                            <div class=\"disk-array\" id=\"diskArray\">\n                                <!-- Disques ajout\u00e9s dynamiquement ici -->\n                            <\/div>\n                            <div class=\"disk-counter\">\n                                <span id=\"diskCountDisplay\">Selected disks : 0<\/span>\n                                <button class=\"reset-btn\" onclick=\"resetConfig()\">\ud83d\udd04 Reset<\/button>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"raidResults\" class=\"results\">\n                        <h3>RAID results<\/h3>\n                        <div id=\"raidSelectionReminder\" style=\"font-weight:600; font-size:1.1rem; color:#1e293b; margin-bottom:20px; padding:10px 0; border-bottom:1px solid #e2e8f0;\"><\/div>\n                        <div class=\"results-grid\" id=\"resultsGrid\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <div id=\"tco-tab\" class=\"tab-content\">\n                    <div class=\"section\">\n                        <h3>Cost parameters<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>Unit price of HDD ($)<\/label>\n                                <input type=\"number\" id=\"hddPrice\" value=\"200\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>SSD unit price ($)<\/label>\n                                <input type=\"number\" id=\"ssdPrice\" value=\"400\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of disk replacement (Spare) ($)<\/label>\n                                <input type=\"number\" id=\"sparePrice\" value=\"300\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of RAID Controller ($)<\/label>\n                                <input type=\"number\" id=\"controllerCost\" value=\"500\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Cost of Casing\/Chassis ($)<\/label>\n                                <input type=\"number\" id=\"enclosureCost\" value=\"2000\">\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"section\">\n                        <h3>Energy & Annual Parameters<\/h3>\n                        <div class=\"config-grid\">\n                            <div class=\"input-group\">\n                                <label>HDD Consommation (W)<\/label>\n                                <input type=\"number\" id=\"hddPower\" value=\"8\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>SSD Consommation (W)<\/label>\n                                <input type=\"number\" id=\"ssdPower\" value=\"5\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Electricity ($\/kWh)<\/label>\n                                <input type=\"number\" id=\"electricityRate\" step=\"0.01\" value=\"0.12\">\n                            <\/div>\n                            <div class=\"input-group\">\n                                <label>Maintenance\/year ($)<\/label>\n                                <input type=\"number\" id=\"maintenanceCost\" value=\"200\">\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div id=\"tcoResults\" class=\"results\">\n                        <h3>TCO Results<\/h3>\n                        <div class=\"results-grid\" id=\"tcoGrid\"><\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <script>\n        let selectedDisks = [];\n        let currentDiskType = 'hdd';\n        let currentRaid = 'RAID 6';\n        \n        const raids = ['RAID 0','RAID 1','RAID 5','RAID 6','RAID 10','RAIDZ1','RAIDZ2','RAIDZ3'];\n\n        function formatTB(gb) {\n            return (gb \/ 1000).toFixed(2) + ' TB';\n        }\n        \n        function init() {\n            generateRaidButtons();\n            updateDisplay();\n            calculate(); \n            bindEvents();\n        }\n        \n        function generateRaidButtons() {\n            let html = '';\n            raids.forEach(r => {\n                html += '<button class=\"raid-btn ' + (r.includes('RAIDZ') ? 'zfs' : '') + ' ' + (r==='RAID 6' ? 'active' : '') + '\" onclick=\"setRaid(\\'' + r + '\\')\">' + r + '<\/button>';\n            });\n            document.getElementById('raidButtons').innerHTML = html;\n        }\n        \n        function setDiskType(type) {\n            currentDiskType = type;\n            document.querySelectorAll('.type-btn').forEach(b => b.classList.remove('active'));\n            event.target.classList.add('active');\n            \n            \/\/ Mise \u00e0 jour des valeurs par d\u00e9faut pour les vitesses de lecture et d'\u00e9criture, IOPS et AFR\n            const readSpeedInput = document.getElementById('driveReadSpeed');\n            const writeSpeedInput = document.getElementById('driveWriteSpeed');\n            const iopsInput = document.getElementById('driveIOPS');\n            const afrInput = document.getElementById('afr');\n\n            if (type === 'ssd') {\n                \/\/ SSD standard speeds and IOPS and AFR (typically lower than HDD)\n                readSpeedInput.value = '550';\n                writeSpeedInput.value = '500';\n                iopsInput.value = '7500';\n                afrInput.value = '0.35';\n            } else {\n                \/\/ HDD standard speeds and IOPS and AFR\n                readSpeedInput.value = '285';\n                writeSpeedInput.value = '250';\n                iopsInput.value = '150';\n                afrInput.value = '0.70';\n            }\n\n            \/\/ Nous n'appelons pas calculate() ici pour ne pas relancer le calcul \u00e0 chaque changement de type. \n            \/\/ L'utilisateur est encourag\u00e9 \u00e0 utiliser le bouton \"Mettre \u00e0 jour les calculs\".\n        }\n        \n        function addMultipleDisks() {\n            const capacity = parseInt(document.getElementById('diskCapacity').value);\n            const count = parseInt(document.getElementById('diskCount').value);\n            \n            if(!capacity || capacity < 100) {\n                alert('Please enter a valid capacity (minimum 100 GB)');\n                return;\n            }\n            \n            if(!count || count < 1) {\n                alert('Please enter a valid number of disks');\n                return;\n            }\n            \n            if(selectedDisks.length + count > 84) {\n                alert('Impossible d\\'ajouter ' + count + ' disques. Maximum: ' + (84 - selectedDisks.length) + ' disques restants');\n                return;\n            }\n            \n            for(let i = 0; i < count; i++) {\n                selectedDisks.push({\n                    size: formatTB(capacity),\n                    value: capacity,\n                    type: currentDiskType,\n                    id: Date.now() + i\n                });\n            }\n            \n            updateDisplay();\n            calculate(); \/\/ Calcul apr\u00e8s ajout de disques\n        }\n        \n        function removeDisk(i) {\n            selectedDisks.splice(i, 1);\n            updateDisplay();\n            calculate();\n        }\n        \n        function updateDisplay() {\n            let html = '';\n            \/\/ It\u00e8re uniquement sur les disques s\u00e9lectionn\u00e9s (affichage dynamique)\n            selectedDisks.forEach((disk, index) => {\n                const typeClass = disk.type === 'ssd' ? 'ssd' : '';\n                const typeIcon = disk.type === 'ssd' ? '\u26a1' : '\ud83d\udcbf';\n                html += '<div class=\"disk-slot filled ' + typeClass + '\" onclick=\"removeDisk(' + index + ')\"><div style=\"font-size:11px;font-weight:600\">' + disk.size + '<\/div><div style=\"font-size:9px\">' + typeIcon + ' ' + disk.type.toUpperCase() + '<\/div><\/div>';\n            });\n\n            document.getElementById('diskArray').innerHTML = html;\n            \n            const required = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n            let counterText = 'Selectionned disks : ' + selectedDisks.length;\n            if(required !== selectedDisks.length) {\n                counterText += ' <span style=\"color:#f59e0b\">(Required: ' + required + ')<\/span>';\n            }\n            document.getElementById('diskCountDisplay').innerHTML = counterText;\n        }\n        \n        function setRaid(r) {\n            currentRaid = r;\n            document.querySelectorAll('.raid-btn').forEach(b => b.classList.remove('active'));\n            event.target.classList.add('active');\n            calculate();\n        }\n        \n        function calculate() {\n            if(selectedDisks.length === 0) {\n                document.getElementById('raidResults').classList.remove('show');\n                document.getElementById('tcoResults').classList.remove('show');\n                return;\n            }\n            \n            const results = calcRAID();\n            if(results) {\n                displayResults(results);\n                \/\/ CORRECTION: Assurez-vous d'afficher les r\u00e9sultats RAID apr\u00e8s le calcul\n                document.getElementById('raidResults').classList.add('show');\n            }\n            calculateTCO();\n        }\n\n        function calcMTBF(totalDisks, tolerance, afrPercent) {\n            if (totalDisks === 0 || afrPercent === 0) return Infinity;\n            \n            const AFR = afrPercent \/ 100; \/\/ Taux de d\u00e9faillance annuel (0 \u00e0 1)\n            const MTTR_HOURS = 10; \/\/ Temps de reconstruction estim\u00e9 en heures (tr\u00e8s optimiste)\n            const DAYS_IN_YEAR = 365.25;\n            const HOURS_IN_YEAR = DAYS_IN_YEAR * 24;\n\n            \/\/ Simple calcul de fiabilit\u00e9 pour RAID-5\/6\/Z1\/Z2 bas\u00e9 sur n-1 ou n-2 d\u00e9faillances\n            \/\/ Convertir AFR en taux de d\u00e9faillance horaire (Lambda)\n            const lambda = AFR \/ HOURS_IN_YEAR; \n\n            if (tolerance === 0) {\n                 \/\/ RAID 0 \/ RAID 1\n                 \/\/ Taux de d\u00e9faillance total = Somme des lambdas individuels\n                 return (1 \/ (totalDisks * lambda)) \/ (24 * DAYS_IN_YEAR);\n            }\n            \n            \/\/ Calcul du MTBF pour RAID 5\/6 (protection contre 1 ou 2 pannes)\n            \/\/ Utilisation d'une approximation pour la fiabilit\u00e9 d'un syst\u00e8me redondant\n            \/\/ Formula for k-out-of-n system for 1 fault tolerance (RAID 5\/Z1): \n            \/\/ MTBF \u2248 (2 \/ (n * (n-1) * \u03bb^2 * MTTR)) \n            \/\/ Where n = totalDisks, \u03bb = lambda\n            if (tolerance === 1 && totalDisks >= 3) {\n                 const MTTR_YEARS = MTTR_HOURS \/ HOURS_IN_YEAR;\n                 const failureRate = totalDisks * (totalDisks - 1) * Math.pow(lambda, 2) * MTTR_YEARS \/ 2;\n                 return (1 \/ failureRate) \/ (24 * DAYS_IN_YEAR); \/\/ R\u00e9sultat en ann\u00e9es\n            }\n            \n            \/\/ Pour les tol\u00e9rances sup\u00e9rieures (RAID 6\/Z2\/Z3), le calcul est beaucoup plus complexe. \n            \/\/ Nous allons simplifier en estimant que chaque niveau de tol\u00e9rance double grossi\u00e8rement le MTBF initial.\n            \/\/ Ceci est une simplification.\n            let simpleMTBF = (1 \/ (totalDisks * lambda)) \/ (24 * DAYS_IN_YEAR);\n            if (tolerance > 1) {\n                \/\/ Tenter une approximation pour doubler pour chaque niveau de tol\u00e9rance suppl\u00e9mentaire\n                simpleMTBF = simpleMTBF * Math.pow(2, tolerance); \n            }\n            \n            return simpleMTBF;\n        }\n\n        function calcRAID() {\n            const totalDisks = selectedDisks.length;\n            const smallest = totalDisks > 0 ? Math.min(...selectedDisks.map(d => d.value)) : 0;\n            const totalRaw = selectedDisks.reduce((s,d) => s + d.value, 0);\n\n            \/\/ --- NOUVELLE LOGIQUE POUR LE CALCUL DES PERFORMANCES ---\n            const groupDisks = parseInt(document.getElementById('drivesPerGroup').value || 4); \/\/ Disques par groupe\n            const numGroups = parseInt(document.getElementById('numberOfGroups').value || 1);       \/\/ Nombre de groupes\n\n            const totalRequired = groupDisks * numGroups;\n            \n            \/\/ Si le nombre total de disques n'est pas suffisant pour la configuration requise\n            if (totalDisks < totalRequired || totalDisks === 0) {\n                \/\/ Pour que la capacit\u00e9 soit juste, mais que la performance soit 0 si la configuration est incompl\u00e8te\n                return {\n                    totalDisks: totalDisks,\n                    totalRaw: totalRaw,\n                    usable: 0,\n                    tolerance: 0,\n                    minDisks: totalRequired,\n                    speed: 0, \n                    efficiency: 0,\n                    readSpeed: 0, \n                    writeSpeed: 0,\n                    iops: 0,\n                    readIOPS: 0, \n                    writeIOPS: 0, \n                    wastedParity: totalRaw,\n                    wastedSize: 0,\n                    mtbf: calcMTBF(totalDisks, 0, parseFloat(document.getElementById('afr').value || 0.5)),\n                    valid: false\n                };\n            }\n            \n            \/\/ Variables pour les calculs de performance\n            const currentReadSpeed = parseInt(document.getElementById('driveReadSpeed').value || 285);\n            const currentWriteSpeed = parseInt(document.getElementById('driveWriteSpeed').value || 250);\n            const currentIOPS = parseInt(document.getElementById('driveIOPS').value || 150); \n            const afrPercent = parseFloat(document.getElementById('afr').value || 0.5); \/\/ Nouvelle AFR\n\n            const readRatio = parseInt(document.getElementById('readWriteRatio').value || 70) \/ 100;\n            const writeRatio = 1 - readRatio; \n            \n            \/\/ CALCULS EFFECTU\u00c9S SUR UN SEUL GROUPE (groupDisks)\n            let usablePerGroup = 0, tolerancePerGroup = 0, minDisksPerGroup = 1, readMultPerGroup = 1, writeMultPerGroup = 1;\n            \n            switch(currentRaid) {\n                case 'RAID 0':\n                    usablePerGroup = groupDisks * smallest; tolerancePerGroup = 0; minDisksPerGroup = 2;\n                    readMultPerGroup = groupDisks * 0.9; writeMultPerGroup = groupDisks * 0.9;\n                    break;\n                case 'RAID 1':\n                    usablePerGroup = smallest; tolerancePerGroup = Math.floor(groupDisks\/2); minDisksPerGroup = 2;\n                    readMultPerGroup = 1; writeMultPerGroup = 0.8;\n                    break;\n                case 'RAID 5':\n                    usablePerGroup = (groupDisks-1) * smallest; tolerancePerGroup = 1; minDisksPerGroup = 3;\n                    readMultPerGroup = (groupDisks-1) * 0.8; writeMultPerGroup = (groupDisks-1) * 0.42;\n                    break;\n                case 'RAID 6':\n                    usablePerGroup = (groupDisks-2) * smallest; tolerancePerGroup = 2; minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks-2) * 0.75; writeMultPerGroup = (groupDisks-2) * 0.32;\n                    break;\n                case 'RAID 10':\n                    \/\/ RAID 10 est g\u00e9r\u00e9 comme (N\/2) miroirs.\n                    \/\/ Capacit\u00e9 par groupe (groupDisks doit \u00eatre pair, par exemple 4 disques = 2 miroirs)\n                    usablePerGroup = Math.floor(groupDisks\/2) * smallest; \n                    tolerancePerGroup = Math.floor(groupDisks\/2); \n                    minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks\/2) * 0.88; \n                    writeMultPerGroup = (groupDisks\/2) * 0.75;\n                    break;\n                case 'RAIDZ1':\n                    usablePerGroup = (groupDisks-1) * smallest; tolerancePerGroup = 1; minDisksPerGroup = 3;\n                    readMultPerGroup = (groupDisks-1) * 0.7; writeMultPerGroup = (groupDisks-1) * 0.35;\n                    break;\n                case 'RAIDZ2':\n                    usablePerGroup = (groupDisks-2) * smallest; tolerancePerGroup = 2; minDisksPerGroup = 4;\n                    readMultPerGroup = (groupDisks-2) * 0.65; writeMultPerGroup = (groupDisks-2) * 0.25;\n                    break;\n                case 'RAIDZ3':\n                    usablePerGroup = (groupDisks-3) * smallest; tolerancePerGroup = 3; minDisksPerGroup = 5;\n                    readMultPerGroup = (groupDisks-3) * 0.6; writeMultPerGroup = (groupDisks-3) * 0.18;\n                    break;\n                default:\n                    \/\/ Cas par d\u00e9faut (devrait pas arriver)\n                    return null;\n            }\n\n            \/\/ Validation de la taille du groupe\n            if (groupDisks < minDisksPerGroup) {\n                 return {\n                    totalDisks: totalDisks,\n                    totalRaw: totalRaw,\n                    usable: 0,\n                    tolerance: tolerancePerGroup,\n                    minDisks: totalRequired,\n                    speed: 0, \n                    efficiency: 0,\n                    readSpeed: 0, \n                    writeSpeed: 0,\n                    iops: 0,\n                    readIOPS: 0, \n                    writeIOPS: 0, \n                    wastedParity: totalRaw,\n                    wastedSize: 0,\n                    mtbf: calcMTBF(totalDisks, 0, afrPercent),\n                    valid: false\n                };\n            }\n            \n            \/\/ --- AGR\u00c9GATION POUR LA CONFIGURATION TOTALE ---\n            \n            \/\/ Capacit\u00e9 totale utilisable = capacit\u00e9 par groupe * nombre de groupes\n            const usable = usablePerGroup * numGroups;\n\n            \/\/ La tol\u00e9rance est bas\u00e9e sur la tol\u00e9rance par groupe (simplifi\u00e9)\n            const tolerance = tolerancePerGroup; \n\n            \/\/ Calcul du MTBF (bas\u00e9 sur totalDisks, mais avec la tol\u00e9rance par groupe)\n            const mtbfYears = calcMTBF(totalDisks, tolerancePerGroup, afrPercent);\n            \n            \/\/ Vitesse\/IOPS totale = performance par groupe * nombre de groupes\n            const effectiveReadSpeed = Math.round(currentReadSpeed * readMultPerGroup * 0.92 * numGroups);\n            const effectiveWriteSpeed = Math.round(currentWriteSpeed * writeMultPerGroup * 0.92 * numGroups);\n            const speed = Math.round((effectiveReadSpeed * readRatio) + (effectiveWriteSpeed * writeRatio));\n            \n            const effectiveReadIOPS = Math.round(currentIOPS * readMultPerGroup * 0.92 * numGroups);\n            const effectiveWriteIOPS = Math.round(currentIOPS * writeMultPerGroup * 0.92 * numGroups);\n            const iops = Math.round((effectiveReadIOPS * readRatio) + (effectiveWriteIOPS * writeRatio));\n\n            \/\/ Calcul des capacit\u00e9s et de l'espace gaspill\u00e9 (bas\u00e9 sur totalDisks)\n            const capacityUsedByParity = (totalRaw - usable);\n            const smallestDiskCapacity = selectedDisks.length > 0 ? smallest : 0;\n            const capacityWastedByMismatchedSize = (totalDisks * smallestDiskCapacity) - totalRaw;\n\n            const efficiency = ((usable\/totalRaw) * 100).toFixed(1);\n            \n            \/\/ Validit\u00e9 : le nombre total de disques doit correspondre exactement au requis\n            const valid = totalDisks === totalRequired && groupDisks >= minDisksPerGroup;\n\n            return {\n                totalDisks: totalDisks,\n                totalRaw: totalRaw,\n                usable: usable,\n                tolerance: tolerance, \/\/ Tol\u00e9rance par groupe\n                minDisks: totalRequired, \n                speed: speed, \n                efficiency: efficiency,\n                readSpeed: effectiveReadSpeed, \n                writeSpeed: effectiveWriteSpeed,\n                iops: iops,\n                readIOPS: effectiveReadIOPS, \n                writeIOPS: effectiveWriteIOPS, \n                wastedParity: capacityUsedByParity,\n                wastedSize: capacityWastedByMismatchedSize < 0 ? 0 : capacityWastedByMismatchedSize,\n                mtbf: mtbfYears, \n                valid: valid\n            };\n        }\n        \n        function displayResults(r) {\n            \/\/ Mise \u00e0 jour de l'\u00e9l\u00e9ment de rappel RAID\n            const groupDisks = parseInt(document.getElementById('drivesPerGroup').value || 4);\n            const numGroups = parseInt(document.getElementById('numberOfGroups').value || 1);\n            const groupText = numGroups > 1 ? `${numGroups} groups of ${groupDisks} disks` : `${groupDisks} disks`;\n\n            document.getElementById('raidSelectionReminder').innerHTML = `Calculated configuration: <strong>${currentRaid}<\/strong> (${groupText})`;\n\n            let html = '';\n            if(!r.valid) {\n                \/\/ Message d'erreur ajust\u00e9 pour la nouvelle logique de validation\n                const totalRequired = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                \n                let validationMessage = '';\n                if (r.totalDisks < totalRequired) {\n                    validationMessage = `Insufficient number of disks. You added ${r.totalDisks}, but ${totalRequired} are required check number of drives or RAID configuration .`;\n                } else {\n                    \/\/ Calcul du minimum de disques requis par le niveau RAID\n                    const tempResults = calcRAID(true); \/\/ Appel temporaire sans les groupes pour le minDisksPerGroup\n                    const minDisksPerGroup = tempResults.minDisks;\n                    if (groupDisks < minDisksPerGroup) {\n                         validationMessage = `${currentRaid} requires a minimum of ${minDisksPerGroup} disks per group.`;\n                    }\n                    else if(r.totalDisks > totalRequired) {\n                         validationMessage = `Too many discs added. The RAID configuration uses ${totalRequired} disks, but ${r.totalDisks} were added.`;\n                    }\n                }\n\n                html += `<div style=\"grid-column:1\/-1;background:#fef2f2;border:2px solid #f87171;border-radius:8px;padding:16px;color:#dc2626;text-align:center;font-weight:600;margin-bottom:20px\">\u26a0\ufe0f Invalid configuration: ${validationMessage}<\/div>`;\n            }\n            \n            \/\/ Affichage des capacit\u00e9s en TB\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#059669\">' + formatTB(r.totalRaw) + '<\/div><div class=\"result-label\">Raw capacity<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#059669\">' + formatTB(r.usable) + '<\/div><div class=\"result-label\">Usable<\/div><\/div>';\n            \n            \/\/ Affichage de la fiabilit\u00e9\n            const mtbfDisplay = r.mtbf === Infinity ? '\u221e' : r.mtbf.toFixed(1) + ' years';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">' + mtbfDisplay + '<\/div><div class=\"result-label\">MTBF (Reliability)<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#7c3aed\">' + r.tolerance + '<\/div><div class=\"result-label\">Tolerance \/ group<\/div><\/div>';\n            \n            \/\/ Affichage de l'espace perdu\n            const totalWasted = r.wastedParity + r.wastedSize;\n            if (totalWasted > 0) {\n                 html += '<div class=\"result-item\" style=\"grid-column:1\/-1; background:#fef3c7\"><div class=\"result-value\" style=\"color:#b45309; font-size:1.4rem\">' + formatTB(totalWasted) + '<\/div><div class=\"result-label\">Total wasted space<small style=\"display:block;color:#b45309;font-size:10px\">(Parity: ' + formatTB(r.wastedParity) + ' \/ Size: ' + formatTB(r.wastedSize) + ')<\/small><\/div><\/div>';\n            }\n            \n            \/\/ Ligne pour les d\u00e9bits et efficacit\u00e9\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">' + r.efficiency + '%<\/div><div class=\"result-label\">Efficacity<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + r.readSpeed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Read speed (R)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">' + r.writeSpeed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Write speed (W)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">' + r.speed.toLocaleString() + ' Mo\/s<\/div><div class=\"result-label\">Mixed rate speed<\/div><small style=\"color:#64748b;font-size:10px\">R\/W Ratio<\/small><\/div>';\n            \n            \/\/ Ligne pour les IOPS\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + r.readIOPS.toLocaleString() + '<\/div><div class=\"result-label\">IOPS Read (R)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">' + r.writeIOPS.toLocaleString() + '<\/div><div class=\"result-label\">IOPS Write (W)<\/div><\/div>';\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">' + r.iops.toLocaleString() + '<\/div><div class=\"result-label\">Mixed IOPS<\/div><small style=\"color:#64748b;font-size:10px\">R\/W Ratio<\/small><\/div>';\n            \n            document.getElementById('resultsGrid').innerHTML = html;\n        }\n        \n        function calculateTCO() {\n            if(selectedDisks.length === 0) {\n                 document.getElementById('tcoResults').classList.remove('show');\n                 return;\n            }\n            \n            \/\/ PARAM\u00c8TRES DE CO\u00dbT (Co\u00fbts initiaux)\n            const hddPrice = parseFloat(document.getElementById('hddPrice').value || 200);\n            const ssdPrice = parseFloat(document.getElementById('ssdPrice').value || 400);\n            const sparePrice = parseFloat(document.getElementById('sparePrice').value || 300); \/\/ Nouveau\n            const controllerCost = parseFloat(document.getElementById('controllerCost').value || 500); \/\/ Nouveau\n            const enclosureCost = parseFloat(document.getElementById('enclosureCost').value || 2000); \/\/ Nouveau\n\n            \/\/ PARAM\u00c8TRES ANNUELS\n            const hddPower = parseFloat(document.getElementById('hddPower').value || 8);\n            const ssdPower = parseFloat(document.getElementById('ssdPower').value || 5);\n            const elecRate = parseFloat(document.getElementById('electricityRate').value || 0.12);\n            const maintenanceCost = parseFloat(document.getElementById('maintenanceCost').value || 200);\n            \n            const totalDisks = selectedDisks.length;\n            const hddCount = selectedDisks.filter(d => d.type === 'hdd').length;\n            const ssdCount = selectedDisks.filter(d => d.type === 'ssd').length;\n            const totalTB = selectedDisks.reduce((s,d) => s + (d.value\/1000), 0);\n            \n            \/\/ CALCUL DES CO\u00dbTS INTIAUX\n            const diskCosts = (hddCount * hddPrice) + (ssdCount * ssdPrice);\n            \/\/ On ajoute le prix d'un disque de rechange (Hot Spare) au co\u00fbt initial\n            const initialDiskCost = diskCosts + sparePrice; \n\n            const infraCosts = controllerCost + enclosureCost;\n            const initialCost = initialDiskCost + infraCosts; \/\/ Co\u00fbt Initial Total\n\n            \/\/ CALCUL DES CO\u00dbTS ANNUELS\n            const HOURS_IN_YEAR = 8766; \/\/ 365.25 jours * 24 heures\n\n            \/\/ Co\u00fbt \u00c9nerg\u00e9tique (Seuls les disques actuellement s\u00e9lectionn\u00e9s consomment)\n            const totalPower = (hddCount * hddPower) + (ssdCount * ssdPower); \/\/ Consommation totale en Watts\n            const totalKWhPerYear = (totalPower * HOURS_IN_YEAR) \/ 1000; \/\/ Consommation totale en kWh\/an\n            const powerCostPerYear = totalKWhPerYear * elecRate; \/\/ Co\u00fbt mon\u00e9taire annuel\n            \n            \/\/ Co\u00fbt de Remplacement (estim\u00e9 \u00e0 5% des disques annuellement)\n            const replacementCostPerYear = diskCosts * 0.05; \n            \n            \/\/ Co\u00fbt Annuel Total (\u00e9nergie + maintenance + remplacement)\n            const totalAnnualCost = powerCostPerYear + maintenanceCost + replacementCostPerYear;\n            \n            \/\/ CALCUL DU TCO (sur 5 ans)\n            const totalTCO = initialCost + (totalAnnualCost * 5);\n            const costPerTBYear = totalTCO \/ (totalTB * 5);\n            \n            \/\/ AFFICHAGE DES R\u00c9SULTATS TCO\n            let html = '';\n\n            \/\/ CO\u00dbTS INITIAUX\n            html += '<div class=\"result-item\" style=\"grid-column:1\/span 2;\"><div class=\"result-value\" style=\"color:#10b981\">$' + initialCost.toLocaleString() + '<\/div><div class=\"result-label\">Total initial cost<\/div><small style=\"color:#64748b;font-size:10px\">Disks + Spare + Infra<\/small><\/div>';\n            \n            \/\/ CO\u00dbTS ANNUELS D\u00c9TAILL\u00c9S\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#f59e0b\">$' + totalAnnualCost.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Total annual cost<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#3b82f6\">' + totalKWhPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + ' kWh<\/div><div class=\"result-label\">Annual consumption<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#dc2626\">$' + powerCostPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Energy\/year<\/div><\/div>';\n            \n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#d97706\">$' + maintenanceCost.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Maintenance\/year<\/div><\/div>';\n\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#ef4444\">$' + replacementCostPerYear.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">Remplacement\/year<\/div><\/div>';\n\n            \/\/ TCO GLOBAL\n            html += '<div class=\"result-item\" style=\"grid-column:span 2; background:#e0f2fe;\"><div class=\"result-value\" style=\"color:#0284c7\">$' + totalTCO.toLocaleString(undefined, { maximumFractionDigits: 0 }) + '<\/div><div class=\"result-label\">TCO GLOBAL (5 years)<\/div><\/div>';\n            \n            html += '<div class=\"result-item\" style=\"grid-column:span 2;\"><div class=\"result-value\" style=\"color:#10b981\">$' + costPerTBYear.toFixed(2) + '<\/div><div class=\"result-label\">$\/TB\/year<\/div><\/div>';\n\n\n            \/\/ AFFICHAGE DES INFOS G\u00c9N\u00c9RALES\n            html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#7c3aed\">' + totalTB.toFixed(1) + ' TB<\/div><div class=\"result-label\">Total capacity<\/div><\/div>';\n            if(ssdCount > 0 && hddCount > 0) {\n                html += '<div class=\"result-item\"><div class=\"result-value\" style=\"color:#6366f1\">' + hddCount + ' HDD \/ ' + ssdCount + ' SSD<\/div><div class=\"result-label\">Mixed configuration<\/div><\/div>';\n            }\n            \n            document.getElementById('tcoGrid').innerHTML = html;\n            document.getElementById('tcoResults').classList.add('show');\n        }\n        \n        function switchTab(tab) {\n            document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));\n            if(event.target) event.target.classList.add('active'); \/\/ Check event.target exists\n            document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));\n            document.getElementById(tab + '-tab').classList.add('active');\n            \/\/ Assurez-vous que le calcul RAID s'ex\u00e9cute pour rafra\u00eechir les r\u00e9sultats si on est sur l'onglet RAID\n            if(tab === 'raid') calculate(); \n            if(tab === 'tco') calculateTCO();\n        }\n        \n        function bindEvents() {\n            document.getElementById('readWriteRatio').addEventListener('input', function(e) {\n                const r = e.target.value;\n                document.getElementById('ratioDisplay').textContent = r + '% Read \/ ' + (100-r) + '% Write';\n                calculate();\n            });\n            \n            \/\/ CORRECTION: Les \u00e9couteurs de `drivesPerGroup` et `numberOfGroups`\n            \/\/ doivent forcer le recalcul. Ils utilisaient d\u00e9j\u00e0 calculate(), mais \n            \/\/ nous les laissons ainsi pour la clart\u00e9.\n            document.getElementById('drivesPerGroup').addEventListener('input', function() {\n                const total = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                document.getElementById('totalRequired').textContent = total + ' disques';\n                updateDisplay();\n                calculate();\n            });\n            \n            document.getElementById('numberOfGroups').addEventListener('input', function() {\n                const total = parseInt(document.getElementById('drivesPerGroup').value || 4) * parseInt(document.getElementById('numberOfGroups').value || 1);\n                document.getElementById('totalRequired').textContent = total + ' disques';\n                updateDisplay();\n                calculate();\n            });\n            \n            \/\/ \u00c9couteurs pour les nouvelles entr\u00e9es RAID \/ Perf\n            document.getElementById('driveReadSpeed').addEventListener('input', calculate);\n            document.getElementById('driveWriteSpeed').addEventListener('input', calculate);\n            document.getElementById('driveIOPS').addEventListener('input', calculate);\n            document.getElementById('afr').addEventListener('input', calculate);\n\n            \/\/ \u00c9couteurs pour les co\u00fbts TCO (n\u00e9cessite calculateTCO() et non calculate() )\n            ['hddPrice','ssdPrice','sparePrice','controllerCost','enclosureCost',\n             'hddPower','ssdPower','electricityRate','maintenanceCost'].forEach(function(id) {\n                document.getElementById(id).addEventListener('input', calculateTCO);\n            });\n            \n            \/\/ Allow Enter key to add disks\n            document.getElementById('diskCapacity').addEventListener('keypress', function(e) {\n                if(e.key === 'Enter') addMultipleDisks();\n            });\n            document.getElementById('diskCount').addEventListener('keypress', function(e) {\n                if(e.key === 'Enter') addMultipleDisks();\n            });\n        }\n        \n        function resetConfig() {\n            selectedDisks = [];\n            updateDisplay();\n            calculate();\n        }\n        \n        document.addEventListener('DOMContentLoaded', init);\n        <\/script>\n        Everything you need to know about RAID &amp; ZFS calculations Choosing the right storage configuration is crucial for the security of your data. Whether you&#8217;re setting up a NAS with TrueNAS, Unraid, or a Proxmox server, our calculator helps you anticipate the actual available capacity after formatting and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-10","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/pages\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":9,"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/pages\/10\/revisions"}],"predecessor-version":[{"id":1085817,"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/pages\/10\/revisions\/1085817"}],"wp:attachment":[{"href":"https:\/\/raidzfscalculator.com\/en\/wp-json\/wp\/v2\/media?parent=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}