{"id":24977,"date":"2026-10-23T07:05:34","date_gmt":"2026-10-23T07:05:34","guid":{"rendered":"https:\/\/www.mechstream.com\/?p=24977"},"modified":"2026-10-23T07:05:37","modified_gmt":"2026-10-23T07:05:37","slug":"weld-cracking-susceptibility-assessment-calculator","status":"publish","type":"post","link":"https:\/\/www.mechstream.com\/fr\/weld-cracking-susceptibility-assessment-calculator\/","title":{"rendered":"Weld Cracking Susceptibility Assessment Calculator"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The Weld Cracking Susceptibility Assessment Calculator is a practical engineering tool designed to evaluate the potential risk of hydrogen-assisted cold cracking in steel welding applications. Using established formulas such as IIW Carbon Equivalent (CEV) and Pcm, this calculator helps welding engineers assess material hardenability, chemical composition, and cracking susceptibility. By entering steel alloying elements, plate thickness, diffusible hydrogen levels, welding heat input, and preheat temperature, users can identify potential cracking factors and evaluate welding conditions. Ideal for welding engineers, metallurgists, steel fabricators, and quality control professionals, the Weld Cracking Susceptibility Assessment Calculator supports preliminary weldability analysis, welding procedure planning, and material selection. Improve welding quality, reduce potential cracking concerns, and optimize fabrication processes with reliable, formula-based engineering assessments.<\/p>\n\n\n\n<div id=\"wcs-calculator\" class=\"wcs-root\" data-wcs-widget=\"weld-cracking-susceptibility\">\n<style>\n#wcs-calculator,#wcs-calculator *,#wcs-calculator *::before,#wcs-calculator *::after{box-sizing:border-box}\n#wcs-calculator{\n  --wcs-bg:#ffffff;--wcs-card:#ffffff;--wcs-navy:#16202e;--wcs-text:#2b3442;--wcs-muted:#5b6675;--wcs-soft:#808b99;\n  --wcs-line:#d5dbe3;--wcs-line-soft:#e6eaf0;--wcs-panel:#f6f8fb;--wcs-accent:#1d64c8;--wcs-accent-dark:#154c9a;--wcs-accent-soft:#e8f0fb;\n  --wcs-err:#b42318;--wcs-err-soft:#fdecea;--wcs-warn:#7a5200;--wcs-warn-soft:#fff6e0;--wcs-ok:#17643f;--wcs-ok-soft:#e7f5ee;\n  display:block;width:100%;max-width:1240px;margin:24px auto;padding:28px;background:var(--wcs-bg);color:var(--wcs-text);\n  border:1px solid var(--wcs-line-soft);border-radius:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif;\n  font-size:16px;line-height:1.55;font-weight:400;letter-spacing:normal;text-transform:none;text-indent:0;word-spacing:normal;-webkit-font-smoothing:antialiased;text-align:left;position:relative\n}\n#wcs-calculator .wcs-wrap{container-type:inline-size;container-name:wcs;width:100%}\n#wcs-calculator h1,#wcs-calculator h2,#wcs-calculator h3,#wcs-calculator h4,#wcs-calculator p,#wcs-calculator ul,#wcs-calculator ol,#wcs-calculator li,#wcs-calculator dl,#wcs-calculator dt,#wcs-calculator dd,#wcs-calculator figure,#wcs-calculator figcaption,#wcs-calculator details,#wcs-calculator summary,#wcs-calculator fieldset,#wcs-calculator legend,#wcs-calculator label,#wcs-calculator header,#wcs-calculator section,#wcs-calculator article,#wcs-calculator aside,#wcs-calculator table,#wcs-calculator th,#wcs-calculator td{\n  margin:0;padding:0;border:0;background:none;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;font-style:normal;line-height:inherit;text-indent:0;text-transform:none;letter-spacing:normal;text-shadow:none;box-shadow:none;float:none;width:auto;max-width:none;min-width:0\n}\n#wcs-calculator ul,#wcs-calculator ol{list-style:none}\n#wcs-calculator a{color:var(--wcs-accent);text-decoration:underline}\n#wcs-calculator sub,#wcs-calculator sup{font-size:.72em;line-height:0;position:relative;vertical-align:baseline}\n#wcs-calculator sub{bottom:-.25em}\n#wcs-calculator sup{top:-.5em}\n#wcs-calculator [hidden]{display:none!important}\n#wcs-calculator svg{display:block;max-width:100%;overflow:hidden}\n#wcs-calculator .wcs-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;align-items:start}\n#wcs-calculator .wcs-left{container-type:inline-size;container-name:wcsl;min-width:0}\n#wcs-calculator .wcs-right{min-width:0}\n#wcs-calculator .wcs-card{background:var(--wcs-card);border:1px solid var(--wcs-line-soft);border-radius:16px;padding:20px;box-shadow:0 1px 2px rgba(22,32,46,.04),0 4px 14px rgba(22,32,46,.05);min-width:0}\n#wcs-calculator .wcs-card+.wcs-card{margin-top:14px}\n#wcs-calculator .wcs-card-title{margin:0 0 4px;color:var(--wcs-navy);font-size:17.5px;font-weight:650;line-height:1.3;display:flex;align-items:center;gap:10px}\n#wcs-calculator .wcs-step{display:inline-flex;align-items:center;justify-content:center;flex:0 0 24px;width:24px;height:24px;border-radius:50%;background:var(--wcs-accent-soft);color:var(--wcs-accent);font-size:12.8px;font-weight:700}\n#wcs-calculator .wcs-card-note{color:var(--wcs-muted);font-size:14px;margin:0 0 14px}\n#wcs-calculator .wcs-sub{color:var(--wcs-navy);font-size:14.6px;font-weight:650;margin:18px 0 10px;padding-top:14px;border-top:1px solid var(--wcs-line-soft)}\n#wcs-calculator .wcs-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:14px 16px}\n#wcs-calculator .wcs-elgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}\n#wcs-calculator .wcs-field{min-width:0}\n#wcs-calculator .wcs-span{grid-column:1\/-1}\n#wcs-calculator .wcs-label{display:block;font-size:14px;font-weight:600;color:var(--wcs-navy);margin:0 0 6px;line-height:1.3}\n#wcs-calculator .wcs-label b{font-weight:700;color:var(--wcs-accent-dark)}\n#wcs-calculator .wcs-opt{color:var(--wcs-soft);font-weight:400;font-size:12.8px;margin-left:3px}\n#wcs-calculator .wcs-hint{display:block;color:var(--wcs-soft);font-size:12.7px;margin-top:5px;line-height:1.45}\n#wcs-calculator .wcs-error{display:block;color:var(--wcs-err);font-size:13px;margin-top:4px;line-height:1.4}\n#wcs-calculator .wcs-error:empty{display:none}\n#wcs-calculator .wcs-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:stretch}\n#wcs-calculator .wcs-unit{display:inline-flex;align-items:center;justify-content:center;min-width:52px;min-height:46px;padding:0 10px;border-radius:11px;background:#eef2f7;color:var(--wcs-muted);font-size:13.5px;font-weight:600;white-space:nowrap}\n#wcs-calculator input[type=number],#wcs-calculator input[type=text],#wcs-calculator select{\n  -webkit-appearance:none;appearance:none;display:block;width:100%;min-height:46px;height:auto;margin:0;padding:10px 12px;font:inherit;font-size:16px;line-height:1.3;\n  color:var(--wcs-text);background-color:#fff;border:1px solid var(--wcs-line);border-radius:11px;box-shadow:none;outline:none;max-width:none;transition:border-color .15s ease,box-shadow .15s ease\n}\n#wcs-calculator input[type=number]{-moz-appearance:textfield}\n#wcs-calculator input[type=number]::-webkit-inner-spin-button,#wcs-calculator input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}\n#wcs-calculator select{padding-right:34px;background-image:linear-gradient(45deg,transparent 50%,#5b6675 50%),linear-gradient(135deg,#5b6675 50%,transparent 50%);background-position:calc(100% - 18px) 20px,calc(100% - 13px) 20px;background-size:5px 5px,5px 5px;background-repeat:no-repeat;cursor:pointer}\n#wcs-calculator select.wcs-usel{width:auto;min-width:96px;background-color:#eef2f7;font-weight:600;font-size:14px;color:var(--wcs-muted)}\n#wcs-calculator input:focus,#wcs-calculator select:focus{border-color:var(--wcs-accent);box-shadow:0 0 0 4px rgba(29,100,200,.17)}\n#wcs-calculator input::placeholder{color:#a7b1be;opacity:1}\n#wcs-calculator .wcs-invalid{border-color:var(--wcs-err)!important;box-shadow:0 0 0 3px rgba(180,35,24,.12)!important}\n#wcs-calculator .wcs-mods{display:grid;grid-template-columns:minmax(0,1fr);gap:8px}\n#wcs-calculator .wcs-mod{padding:10px 12px;border:1px solid var(--wcs-line-soft);border-radius:12px;background:var(--wcs-panel)}\n#wcs-calculator .wcs-mod b{display:block;font-weight:650;font-size:14.4px;color:var(--wcs-navy);line-height:1.3}\n#wcs-calculator .wcs-mod small{display:block;font-size:12.4px;color:var(--wcs-muted);line-height:1.4;margin-top:2px}\n#wcs-calculator .wcs-mod em{display:inline-block;font-style:normal;font-size:11px;font-weight:700;padding:0 7px;border-radius:999px;margin-left:6px;vertical-align:1px}\n#wcs-calculator .wcs-mod em.wcs-q{background:var(--wcs-accent-soft);color:var(--wcs-accent-dark)}\n#wcs-calculator .wcs-mod em.wcs-ql{background:#efe8fb;color:#5b2ea6}\n#wcs-calculator .wcs-info{padding:12px 14px;border-radius:11px;background:var(--wcs-panel);border:1px solid var(--wcs-line-soft);font-size:13.5px;color:var(--wcs-muted);line-height:1.5}\n#wcs-calculator .wcs-info strong{color:var(--wcs-navy);font-weight:650}\n#wcs-calculator .wcs-check{display:flex;gap:10px;align-items:flex-start;font-size:14.2px;font-weight:600;color:var(--wcs-navy);cursor:pointer;line-height:1.4}\n#wcs-calculator .wcs-check input{flex:0 0 18px;width:18px;height:18px;margin:2px 0 0;accent-color:var(--wcs-accent);cursor:pointer}\n#wcs-calculator .wcs-check span small{display:block;font-weight:400;color:var(--wcs-soft);font-size:12.6px;margin-top:2px}\n#wcs-calculator .wcs-confirm{margin-top:16px;padding:12px 14px;border:1px solid #f0d9a6;background:var(--wcs-warn-soft);border-radius:12px}\n#wcs-calculator .wcs-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:16px}\n#wcs-calculator .wcs-btn{-webkit-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;min-height:46px;margin:0;padding:10px 16px;border-radius:999px;border:1px solid var(--wcs-line);background:#fff;color:var(--wcs-navy);font:inherit;font-size:14.6px;font-weight:600;line-height:1.2;cursor:pointer;text-decoration:none;text-transform:none;letter-spacing:normal;box-shadow:none;width:auto;height:auto;text-align:center;transition:background .15s,border-color .15s,color .15s}\n#wcs-calculator .wcs-btn:hover{border-color:var(--wcs-accent);color:var(--wcs-accent-dark)}\n#wcs-calculator .wcs-btn-primary{background:var(--wcs-accent);border-color:var(--wcs-accent);color:#fff;flex:1 1 100%;font-size:15.5px;min-height:50px}\n#wcs-calculator .wcs-btn-primary:hover{background:var(--wcs-accent-dark);border-color:var(--wcs-accent-dark);color:#fff}\n#wcs-calculator .wcs-btn[disabled]{opacity:.5;cursor:not-allowed}\n#wcs-calculator .wcs-btn:focus-visible{outline:3px solid rgba(29,100,200,.4);outline-offset:2px}\n#wcs-calculator .wcs-form-msg{text-align:center;color:var(--wcs-err);font-size:13.8px;margin-top:10px;min-height:1.3em}\n#wcs-calculator .wcs-form-msg.wcs-good{color:var(--wcs-ok)}\n#wcs-calculator .wcs-placeholder{color:var(--wcs-muted);font-size:14.5px;padding:18px;border:1px dashed var(--wcs-line);border-radius:12px;background:var(--wcs-panel);margin-top:12px}\n#wcs-calculator .wcs-results{scroll-margin-top:16px}\n#wcs-calculator .wcs-banner{margin:12px 0 14px;padding:14px 16px;border-radius:13px;border:1px solid #c9dbf3;background:var(--wcs-accent-soft)}\n#wcs-calculator .wcs-banner-t{display:block;font-weight:700;color:var(--wcs-navy);font-size:15.4px;line-height:1.35}\n#wcs-calculator .wcs-banner-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px}\n#wcs-calculator .wcs-banner-k{font-size:12.6px;font-weight:650;color:var(--wcs-muted)}\n#wcs-calculator .wcs-banner p{margin-top:8px;font-size:13.8px;color:var(--wcs-text)}\n#wcs-calculator .wcs-chip{display:inline-block;padding:2px 10px;border-radius:999px;font-size:12.4px;font-weight:700;line-height:1.55;white-space:nowrap}\n#wcs-calculator .wcs-l0{background:var(--wcs-ok-soft);color:var(--wcs-ok)}\n#wcs-calculator .wcs-l1{background:var(--wcs-warn-soft);color:var(--wcs-warn)}\n#wcs-calculator .wcs-l2{background:var(--wcs-err-soft);color:var(--wcs-err)}\n#wcs-calculator .wcs-lx{background:#eef1f5;color:#4d5866}\n#wcs-calculator .wcs-li{background:var(--wcs-accent-soft);color:var(--wcs-accent-dark)}\n#wcs-calculator .wcs-sec{color:var(--wcs-navy);font-size:15.2px;font-weight:650;margin:22px 0 8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}\n#wcs-calculator .wcs-sec small{font-size:11.5px;font-weight:700;padding:1px 8px;border-radius:999px;background:#eef1f5;color:var(--wcs-muted)}\n#wcs-calculator .wcs-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}\n#wcs-calculator .wcs-kpi{background:var(--wcs-panel);border:1px solid var(--wcs-line-soft);border-radius:12px;padding:11px 13px;min-width:0}\n#wcs-calculator .wcs-kpi.wcs-main{background:var(--wcs-accent-soft);border-color:#c9dbf3}\n#wcs-calculator .wcs-kpi-label{font-size:12.6px;font-weight:600;color:var(--wcs-muted);line-height:1.3}\n#wcs-calculator .wcs-kpi-value{font-size:clamp(17px,2vw,21px);font-weight:700;color:var(--wcs-navy);letter-spacing:-.01em;margin-top:3px;line-height:1.25;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}\n#wcs-calculator .wcs-kpi-value.wcs-na{color:var(--wcs-soft);font-size:15px}\n#wcs-calculator .wcs-kpi-sub{font-size:12.2px;color:var(--wcs-muted);margin-top:3px;line-height:1.4;overflow-wrap:anywhere}\n#wcs-calculator .wcs-facs{display:grid;gap:8px}\n#wcs-calculator .wcs-fac{border:1px solid var(--wcs-line-soft);border-radius:12px;padding:11px 13px;background:#fff}\n#wcs-calculator .wcs-fac-h{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px 10px}\n#wcs-calculator .wcs-fac-n{font-weight:650;color:var(--wcs-navy);font-size:14.4px}\n#wcs-calculator .wcs-fac-o{margin-top:6px;font-size:13.3px;color:var(--wcs-text)}\n#wcs-calculator .wcs-fac-o b,#wcs-calculator .wcs-fac-j b{font-weight:650;color:var(--wcs-muted);font-size:11.8px;text-transform:uppercase;letter-spacing:.04em;margin-right:6px}\n#wcs-calculator .wcs-fac-j{margin-top:4px;font-size:13.3px;color:var(--wcs-text);line-height:1.5}\n#wcs-calculator .wcs-fac-b{margin-top:4px;font-size:12.2px;color:var(--wcs-soft);line-height:1.45}\n#wcs-calculator .wcs-interp p{font-size:14.4px;line-height:1.6}\n#wcs-calculator .wcs-interp p+p{margin-top:8px}\n#wcs-calculator .wcs-recs{display:grid;gap:6px}\n#wcs-calculator .wcs-recs li{position:relative;padding:8px 12px 8px 32px;border-radius:10px;background:var(--wcs-panel);font-size:13.6px;line-height:1.5}\n#wcs-calculator .wcs-recs li::before{content:\"\";position:absolute;left:13px;top:15px;width:8px;height:8px;border-radius:50%;background:var(--wcs-accent)}\n#wcs-calculator .wcs-params{display:grid;grid-template-columns:minmax(0,1fr);gap:0;border:1px solid var(--wcs-line-soft);border-radius:12px;overflow:hidden}\n#wcs-calculator .wcs-params div{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:10px;padding:8px 12px;font-size:13.5px;border-top:1px solid var(--wcs-line-soft)}\n#wcs-calculator .wcs-params div:first-child{border-top:0}\n#wcs-calculator .wcs-params dt{color:var(--wcs-muted)}\n#wcs-calculator .wcs-params dd{color:var(--wcs-navy);font-weight:600;text-align:right;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}\n#wcs-calculator .wcs-tablewrap{overflow-x:auto;border:1px solid var(--wcs-line-soft);border-radius:12px}\n#wcs-calculator table.wcs-table{width:100%;border-collapse:collapse;font-size:13.3px;font-variant-numeric:tabular-nums}\n#wcs-calculator .wcs-table th,#wcs-calculator .wcs-table td{padding:7px 10px;border-top:1px solid var(--wcs-line-soft);text-align:right;white-space:nowrap}\n#wcs-calculator .wcs-table th:first-child,#wcs-calculator .wcs-table td:first-child{text-align:left}\n#wcs-calculator .wcs-table thead th{border-top:0;background:var(--wcs-panel);color:var(--wcs-muted);font-weight:650;font-size:12.4px}\n#wcs-calculator .wcs-table tfoot td{font-weight:700;color:var(--wcs-navy);background:var(--wcs-accent-soft)}\n#wcs-calculator .wcs-steps{display:grid;gap:6px}\n#wcs-calculator .wcs-steps li{padding:7px 12px;background:var(--wcs-panel);border:1px dashed var(--wcs-line);border-radius:10px;font-size:13.2px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}\n#wcs-calculator .wcs-steps li.wcs-step-total{background:var(--wcs-accent-soft);border-style:solid;border-color:#c9dbf3;font-weight:700;color:var(--wcs-navy)}\n#wcs-calculator .wcs-det{border:1px solid var(--wcs-line-soft);border-radius:12px;padding:0;margin-top:8px;background:#fff}\n#wcs-calculator .wcs-det summary{cursor:pointer;padding:10px 14px;font-weight:650;color:var(--wcs-navy);font-size:14.2px;list-style:none;display:flex;justify-content:space-between;gap:10px}\n#wcs-calculator .wcs-det summary::-webkit-details-marker{display:none}\n#wcs-calculator .wcs-det summary::after{content:\"+\";color:var(--wcs-soft);font-weight:700}\n#wcs-calculator .wcs-det[open] summary::after{content:\"\u2212\"}\n#wcs-calculator .wcs-det-body{padding:0 14px 12px;font-size:13.6px}\n#wcs-calculator .wcs-det-body p+p{margin-top:6px}\n#wcs-calculator .wcs-notes{display:grid;gap:7px}\n#wcs-calculator .wcs-notes li{padding:9px 12px 9px 14px;border-radius:10px;font-size:13.3px;line-height:1.5;border-left:4px solid #b7c3d2;background:var(--wcs-panel)}\n#wcs-calculator .wcs-notes li.wcs-n-e{border-left-color:var(--wcs-err);background:var(--wcs-err-soft);color:#6e1a12}\n#wcs-calculator .wcs-notes li.wcs-n-w{border-left-color:#d49b16;background:var(--wcs-warn-soft);color:#5c4300}\n#wcs-calculator .wcs-notes li strong{font-weight:650}\n@container wcsl (min-width:520px){\n  #wcs-calculator .wcs-elgrid{grid-template-columns:repeat(3,minmax(0,1fr))}\n  #wcs-calculator .wcs-grid{grid-template-columns:repeat(2,minmax(0,1fr))}\n  #wcs-calculator .wcs-mods{grid-template-columns:repeat(3,minmax(0,1fr))}\n  #wcs-calculator .wcs-btn-primary{flex:0 1 auto;min-width:260px}\n}\n@container wcs (min-width:620px){\n  #wcs-calculator .wcs-kpis{grid-template-columns:repeat(4,minmax(0,1fr))}\n}\n@media (max-width:700px){\n  #wcs-calculator{padding:18px 14px;border-radius:16px;margin:12px auto}\n  #wcs-calculator .wcs-card{padding:16px 14px;border-radius:14px}\n  #wcs-calculator .wcs-params div{grid-template-columns:minmax(0,1fr);gap:2px}\n  #wcs-calculator .wcs-params dd{text-align:left}\n}\n@media (prefers-reduced-motion:reduce){#wcs-calculator *{transition:none!important}}\n@media print{#wcs-calculator .wcs-actions,#wcs-calculator .wcs-form-msg{display:none!important}#wcs-calculator{border:0;padding:0}#wcs-calculator .wcs-card{box-shadow:none;break-inside:avoid}}\n<\/style>\n<div class=\"wcs-wrap\">\n<div class=\"wcs-layout\">\n<form class=\"wcs-left\" id=\"wcs-form\" novalidate onsubmit=\"return false;\">\n<section class=\"wcs-card\" aria-labelledby=\"wcs-h-mat\">\n<h2 class=\"wcs-card-title\" id=\"wcs-h-mat\"><span class=\"wcs-step\" aria-hidden=\"true\">1<\/span>Material and assessment options<\/h2>\n<p class=\"wcs-card-note\">All three assessment modules run together. Calculated quantities and qualitative observations are reported separately.<\/p>\n<div class=\"wcs-mods\">\n<div class=\"wcs-mod\"><b>Mode A \u00b7 IIW CEV <em class=\"wcs-q\">Calculated<\/em><\/b><small>Carbon equivalent indicating HAZ hardenability<\/small><\/div>\n<div class=\"wcs-mod\"><b>Mode B \u00b7 Pcm <em class=\"wcs-q\">Calculated<\/em><\/b><small>Composition-based crack susceptibility index<\/small><\/div>\n<div class=\"wcs-mod\"><b>Mode C \u00b7 Screening <em class=\"wcs-ql\">Qualitative<\/em><\/b><small>Hydrogen cracking factor review, no probability<\/small><\/div>\n<\/div>\n<div class=\"wcs-grid\" style=\"margin-top:14px\">\n<div class=\"wcs-field wcs-span\">\n<label class=\"wcs-label\" for=\"wcs-material\">Material category <span class=\"wcs-opt\">(optional, context only)<\/span><\/label>\n<select id=\"wcs-material\" aria-describedby=\"wcs-matinfo\">\n<option value=\"custom\" selected>Custom Steel<\/option>\n<option value=\"low\">Low Carbon Steel<\/option>\n<option value=\"structural\">Structural Steel<\/option>\n<option value=\"hsla\">High Strength Low Alloy Steel<\/option>\n<option value=\"pipeline\">Pipeline Steel<\/option>\n<option value=\"pv\">Pressure Vessel Steel<\/option>\n<\/select>\n<\/div>\n<div class=\"wcs-info wcs-span\" id=\"wcs-matinfo\" aria-live=\"polite\"><\/div>\n<\/div>\n<\/section>\n<section class=\"wcs-card\" aria-labelledby=\"wcs-h-comp\">\n<h2 class=\"wcs-card-title\" id=\"wcs-h-comp\"><span class=\"wcs-step\" aria-hidden=\"true\">2<\/span>Chemical composition<\/h2>\n<p class=\"wcs-card-note\">Enter weight percent (wt.%) from the mill test certificate or product analysis. Enter 0 only for a confirmed absence. Blank fields are <strong>not<\/strong> assumed to be zero.<\/p>\n<div class=\"wcs-elgrid\">\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-C\">Carbon (<b>C<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-C\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.12\" aria-describedby=\"wcs-C-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-C-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Si\">Silicon (<b>Si<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Si\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.25\" aria-describedby=\"wcs-Si-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Si-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Mn\">Manganese (<b>Mn<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Mn\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 1.40\" aria-describedby=\"wcs-Mn-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Mn-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Cr\">Chromium (<b>Cr<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Cr\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.20\" aria-describedby=\"wcs-Cr-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Cr-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Ni\">Nickel (<b>Ni<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Ni\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.10\" aria-describedby=\"wcs-Ni-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Ni-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Mo\">Molybdenum (<b>Mo<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Mo\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.05\" aria-describedby=\"wcs-Mo-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Mo-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-V\">Vanadium (<b>V<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-V\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.03\" aria-describedby=\"wcs-V-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-V-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-Cu\">Copper (<b>Cu<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-Cu\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.15\" aria-describedby=\"wcs-Cu-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">wt.%<\/span><\/div><span class=\"wcs-error\" id=\"wcs-Cu-err\" aria-live=\"polite\"><\/span><\/div>\n<div class=\"wcs-field\"><label class=\"wcs-label\" for=\"wcs-B\">Boron (<b>B<\/b>)<\/label><div class=\"wcs-row\"><input id=\"wcs-B\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 0.0005\" aria-describedby=\"wcs-B-hint wcs-B-err\"><select class=\"wcs-usel\" id=\"wcs-Bunit\" aria-label=\"Boron unit\"><option value=\"wt\" selected>wt.%<\/option><option value=\"ppm\">ppm<\/option><\/select><\/div><span class=\"wcs-hint\" id=\"wcs-B-hint\">1 ppm = 0.0001 wt.%<\/span><span class=\"wcs-error\" id=\"wcs-B-err\" aria-live=\"polite\"><\/span><\/div>\n<\/div>\n<div class=\"wcs-confirm\">\n<label class=\"wcs-check\" for=\"wcs-zero\"><input type=\"checkbox\" id=\"wcs-zero\"><span>Treat unspecified elements as zero for a preliminary calculation<small>Applies only to blank fields. Carbon and manganese must always be entered. Residual elements are rarely exactly zero, so this can underestimate CEV and Pcm.<\/small><\/span><\/label>\n<\/div>\n<\/section>\n<section class=\"wcs-card\" aria-labelledby=\"wcs-h-weld\">\n<h2 class=\"wcs-card-title\" id=\"wcs-h-weld\"><span class=\"wcs-step\" aria-hidden=\"true\">3<\/span>Welding conditions<\/h2>\n<p class=\"wcs-card-note\">These inputs feed the qualitative screening (Mode C). Heat input is optional, but the other factors are needed for a screening outcome.<\/p>\n<div class=\"wcs-grid\">\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-t\">Plate thickness<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-t\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 25\" aria-describedby=\"wcs-t-hint wcs-t-err\"><select class=\"wcs-usel\" id=\"wcs-tunit\" data-prev=\"mm\" aria-label=\"Thickness unit\"><option value=\"mm\" selected>mm<\/option><option value=\"in\">in<\/option><\/select><\/div>\n<span class=\"wcs-hint\" id=\"wcs-t-hint\">Thickness of the thicker part at the joint. Combined thickness methods (for example EN 1011-2) are not applied.<\/span>\n<span class=\"wcs-error\" id=\"wcs-t-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-restr\">Joint restraint<\/label>\n<select id=\"wcs-restr\" aria-describedby=\"wcs-restr-hint wcs-restr-err\">\n<option value=\"\" selected>Select restraint level<\/option>\n<option value=\"low\">Low Restraint<\/option>\n<option value=\"mod\">Moderate Restraint<\/option>\n<option value=\"high\">High Restraint<\/option>\n<\/select>\n<span class=\"wcs-hint\" id=\"wcs-restr-hint\">Descriptive categories only. They do not replace a quantitative restraint analysis.<\/span>\n<span class=\"wcs-error\" id=\"wcs-restr-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-hd\">Diffusible hydrogen (H<sub>D<\/sub>)<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-hd\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 8\" aria-describedby=\"wcs-hd-hint wcs-hd-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">mL\/100 g<\/span><\/div>\n<span class=\"wcs-hint\" id=\"wcs-hd-hint\">Measured or specified, per 100 g of deposited weld metal (for example ISO 3690 or AWS A4.3).<\/span>\n<span class=\"wcs-error\" id=\"wcs-hd-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-hdcat\">Consumable hydrogen designator <span class=\"wcs-opt\">(optional)<\/span><\/label>\n<select id=\"wcs-hdcat\" aria-describedby=\"wcs-hdcat-hint\">\n<option value=\"\" selected>None selected<\/option>\n<option value=\"H4\">AWS H4 (max 4 mL\/100 g)<\/option>\n<option value=\"H8\">AWS H8 (max 8 mL\/100 g)<\/option>\n<option value=\"H16\">AWS H16 (max 16 mL\/100 g)<\/option>\n<option value=\"H5\">ISO H5 (max 5 mL\/100 g)<\/option>\n<option value=\"H10\">ISO H10 (max 10 mL\/100 g)<\/option>\n<option value=\"H15\">ISO H15 (max 15 mL\/100 g)<\/option>\n<\/select>\n<span class=\"wcs-hint\" id=\"wcs-hdcat-hint\">Designators from AWS A5.x filler specifications and ISO consumable standards state a maximum, not a measured value. If H<sub>D<\/sub> is blank, the designator maximum is used and labelled as such.<\/span>\n<\/div>\n<\/div>\n<h3 class=\"wcs-sub\">Welding heat input<\/h3>\n<div class=\"wcs-grid\">\n<div class=\"wcs-field wcs-span\">\n<label class=\"wcs-label\" for=\"wcs-hmode\">Heat input entry<\/label>\n<select id=\"wcs-hmode\">\n<option value=\"calc\" selected>Calculate from current, voltage and travel speed<\/option>\n<option value=\"direct\">Enter heat input or arc energy directly<\/option>\n<option value=\"none\">Not specified<\/option>\n<\/select>\n<\/div>\n<div class=\"wcs-field\" data-h=\"calc\">\n<label class=\"wcs-label\" for=\"wcs-amp\">Welding current (I)<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-amp\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 160\" aria-describedby=\"wcs-amp-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">A<\/span><\/div>\n<span class=\"wcs-error\" id=\"wcs-amp-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\" data-h=\"calc\">\n<label class=\"wcs-label\" for=\"wcs-volt\">Arc voltage (U)<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-volt\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 24\" aria-describedby=\"wcs-volt-err\"><span class=\"wcs-unit\" aria-hidden=\"true\">V<\/span><\/div>\n<span class=\"wcs-error\" id=\"wcs-volt-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\" data-h=\"calc\">\n<label class=\"wcs-label\" for=\"wcs-spd\">Travel speed (v)<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-spd\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 150\" aria-describedby=\"wcs-spd-err\"><select class=\"wcs-usel\" id=\"wcs-spdunit\" data-prev=\"mmmin\" aria-label=\"Travel speed unit\"><option value=\"mmmin\" selected>mm\/min<\/option><option value=\"mms\">mm\/s<\/option><option value=\"inmin\">in\/min<\/option><\/select><\/div>\n<span class=\"wcs-error\" id=\"wcs-spd-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\" data-h=\"direct\">\n<label class=\"wcs-label\" for=\"wcs-hq\">Heat input value<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-hq\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" placeholder=\"e.g. 1.25\" aria-describedby=\"wcs-hq-err\"><select class=\"wcs-usel\" id=\"wcs-hqunit\" data-prev=\"kjmm\" aria-label=\"Heat input unit\"><option value=\"kjmm\" selected>kJ\/mm<\/option><option value=\"kjin\">kJ\/in<\/option><\/select><\/div>\n<span class=\"wcs-error\" id=\"wcs-hq-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\" data-h=\"direct\">\n<label class=\"wcs-label\" for=\"wcs-hqtype\">The entered value is<\/label>\n<select id=\"wcs-hqtype\">\n<option value=\"net\" selected>Net heat input Q (efficiency already applied)<\/option>\n<option value=\"arc\">Arc energy E (no efficiency applied)<\/option>\n<\/select>\n<\/div>\n<div class=\"wcs-field\" data-h=\"eta\">\n<label class=\"wcs-label\" for=\"wcs-proc\">Welding process \/ thermal efficiency (\u03b7)<\/label>\n<select id=\"wcs-proc\" aria-describedby=\"wcs-proc-hint wcs-proc-err\">\n<option value=\"\" selected>Select process for \u03b7<\/option>\n<option value=\"saw\">SAW (121), \u03b7 = 1.0<\/option>\n<option value=\"smaw\">SMAW \/ MMA (111), \u03b7 = 0.8<\/option>\n<option value=\"gmaw\">GMAW \/ MIG\/MAG (131, 135), \u03b7 = 0.8<\/option>\n<option value=\"fcaw\">FCAW (114, 136, 138), \u03b7 = 0.8<\/option>\n<option value=\"gtaw\">GTAW \/ TIG (141), \u03b7 = 0.6<\/option>\n<option value=\"paw\">PAW (15), \u03b7 = 0.6<\/option>\n<option value=\"custom\">Custom \u03b7 (justified value)<\/option>\n<\/select>\n<span class=\"wcs-hint\" id=\"wcs-proc-hint\">Factors as tabulated in EN 1011-1 \/ ISO\/TR 17671-1. Other codes may define heat input differently, so confirm against the governing standard.<\/span>\n<span class=\"wcs-error\" id=\"wcs-proc-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\" data-h=\"custom\">\n<label class=\"wcs-label\" for=\"wcs-eta\">Custom thermal efficiency (\u03b7)<\/label>\n<input id=\"wcs-eta\" type=\"number\" inputmode=\"decimal\" step=\"any\" min=\"0\" max=\"1\" placeholder=\"0 to 1\" aria-describedby=\"wcs-eta-err\">\n<span class=\"wcs-error\" id=\"wcs-eta-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<h3 class=\"wcs-sub\">Temperatures<\/h3>\n<div class=\"wcs-grid\">\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-pre\">Preheat temperature<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-pre\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"e.g. 75\" aria-describedby=\"wcs-pre-hint wcs-pre-err\"><select class=\"wcs-usel\" id=\"wcs-preunit\" data-prev=\"C\" aria-label=\"Preheat unit\"><option value=\"C\" selected>\u00b0C<\/option><option value=\"F\">\u00b0F<\/option><\/select><\/div>\n<span class=\"wcs-hint\" id=\"wcs-pre-hint\">The actual or planned preheat. The required preheat is not calculated.<\/span>\n<span class=\"wcs-error\" id=\"wcs-pre-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<div class=\"wcs-field\">\n<label class=\"wcs-label\" for=\"wcs-amb\">Ambient temperature<\/label>\n<div class=\"wcs-row\"><input id=\"wcs-amb\" type=\"number\" inputmode=\"decimal\" step=\"any\" placeholder=\"e.g. 15\" aria-describedby=\"wcs-amb-err\"><select class=\"wcs-usel\" id=\"wcs-ambunit\" data-prev=\"C\" aria-label=\"Ambient temperature unit\"><option value=\"C\" selected>\u00b0C<\/option><option value=\"F\">\u00b0F<\/option><\/select><\/div>\n<span class=\"wcs-error\" id=\"wcs-amb-err\" aria-live=\"polite\"><\/span>\n<\/div>\n<\/div>\n<\/section>\n<div class=\"wcs-actions\">\n<button type=\"button\" class=\"wcs-btn wcs-btn-primary\" id=\"wcs-calc\">Calculate<\/button>\n<\/div>\n<p class=\"wcs-form-msg\" id=\"wcs-msg\" role=\"status\" aria-live=\"polite\"><\/p>\n<\/form>\n<div class=\"wcs-right\">\n<section class=\"wcs-card wcs-results\" id=\"wcs-results\" aria-labelledby=\"wcs-h-res\" tabindex=\"-1\" hidden>\n<h2 class=\"wcs-card-title\" id=\"wcs-h-res\"><span class=\"wcs-step\" aria-hidden=\"true\">4<\/span>Assessment results<\/h2>\n<div id=\"wcs-res-body\" aria-live=\"polite\"><\/div>\n<\/section>\n<\/div>\n<\/div>\n<\/div>\n<script>\n(function () {\n  \"use strict\";\n  \/* =====================================================================\n     DEFINITIONS\n     All concentrations are handled internally in wt.%, lengths in mm,\n     heat input in kJ\/mm, temperatures in \u00b0C.\n     ===================================================================== *\/\n  var ELEMS = [\"C\", \"Si\", \"Mn\", \"Cr\", \"Ni\", \"Mo\", \"V\", \"Cu\", \"B\"];\n  var ENAME = { C: \"Carbon\", Si: \"Silicon\", Mn: \"Manganese\", Cr: \"Chromium\", Ni: \"Nickel\", Mo: \"Molybdenum\", V: \"Vanadium\", Cu: \"Copper\", B: \"Boron\" };\n  var ECOL = { C: \"#1d4ed8\", Mn: \"#0e7490\", Si: \"#7c3aed\", Cr: \"#b45309\", Ni: \"#15803d\", Mo: \"#be123c\", V: \"#a16207\", Cu: \"#c2410c\", B: \"#475569\" };\n  var MUST = [\"C\", \"Mn\"];\n  var FORM = {\n    cev: { id: \"cev\", name: \"IIW Carbon Equivalent (CEV)\", short: \"CEV\", color: \"#1d64c8\",\n      eq: \"CEV = C + Mn\/6 + (Cr + Mo + V)\/5 + (Ni + Cu)\/15\",\n      terms: [[\"C\", 1, 1, \"C\"], [\"Mn\", 1, 6, \"Mn\/6\"], [\"Cr\", 1, 5, \"Cr\/5\"], [\"Mo\", 1, 5, \"Mo\/5\"], [\"V\", 1, 5, \"V\/5\"], [\"Ni\", 1, 15, \"Ni\/15\"], [\"Cu\", 1, 15, \"Cu\/15\"]] },\n    pcm: { id: \"pcm\", name: \"Pcm Crack Susceptibility Index\", short: \"Pcm\", color: \"#b26a00\",\n      eq: \"Pcm = C + Si\/30 + Mn\/20 + Cu\/20 + Ni\/60 + Cr\/20 + Mo\/15 + V\/10 + 5B\",\n      terms: [[\"C\", 1, 1, \"C\"], [\"Si\", 1, 30, \"Si\/30\"], [\"Mn\", 1, 20, \"Mn\/20\"], [\"Cu\", 1, 20, \"Cu\/20\"], [\"Ni\", 1, 60, \"Ni\/60\"], [\"Cr\", 1, 20, \"Cr\/20\"], [\"Mo\", 1, 15, \"Mo\/15\"], [\"V\", 1, 10, \"V\/10\"], [\"B\", 5, 1, \"5B\"]] }\n  };\n  \/* Approximate composition range of the original Ito\u2013Bessyo study (wt.%) *\/\n  var PCM_RANGE = { C: [0.07, 0.22], Si: [0, 0.6], Mn: [0.4, 1.4], Cu: [0, 0.5], Ni: [0, 1.2], Cr: [0, 1.2], Mo: [0, 0.7], V: [0, 0.12], B: [0, 0.005] };\n  var MAT = {\n    custom: { name: \"Custom Steel\", info: \"Enter the composition exactly as reported on the mill test certificate or product analysis.\" },\n    low: { name: \"Low Carbon Steel\", info: \"Usually the most readily welded group. Thick sections, high restraint or high-hydrogen consumables can still cause cold cracking.\" },\n    structural: { name: \"Structural Steel\", info: \"Product standards such as EN 10025 or ASTM A6 often specify a maximum CEV per grade and thickness. Use the certificate chemistry and the standard's own limits.\" },\n    hsla: { name: \"High Strength Low Alloy Steel\", info: \"Low carbon with microalloying (Nb, V, Ti), often thermomechanically rolled. Pcm is frequently preferred. Higher-strength grades can be sensitive to hydrogen even at modest carbon equivalent.\" },\n    pipeline: { name: \"Pipeline Steel\", info: \"Line pipe specifications such as API 5L \/ ISO 3183 PSL 2 commonly limit CE Pcm when C \u2264 0.12 wt.% and CE IIW when C > 0.12 wt.%. Field girth welds are often made with fast cooling and high restraint.\" },\n    pv: { name: \"Pressure Vessel Steel\", info: \"Often thick C-Mn or Cr-Mo grades. Construction codes set preheat, interpass and post-weld heat treatment requirements by material group and thickness.\" }\n  };\n  var PROC = {\n    saw: { n: \"SAW (121)\", k: 1.0 }, smaw: { n: \"SMAW \/ MMA (111)\", k: 0.8 }, gmaw: { n: \"GMAW \/ MIG\/MAG (131, 135)\", k: 0.8 },\n    fcaw: { n: \"FCAW (114, 136, 138)\", k: 0.8 }, gtaw: { n: \"GTAW \/ TIG (141)\", k: 0.6 }, paw: { n: \"PAW (15)\", k: 0.6 }\n  };\n  var HDCAT = { H4: { v: 4, b: \"AWS\" }, H8: { v: 8, b: \"AWS\" }, H16: { v: 16, b: \"AWS\" }, H5: { v: 5, b: \"ISO\" }, H10: { v: 10, b: \"ISO\" }, H15: { v: 15, b: \"ISO\" } };\n  var RESTR = { low: \"Low Restraint\", mod: \"Moderate Restraint\", high: \"High Restraint\" };\n  var LV = [{ t: \"Lower\", c: \"wcs-l0\" }, { t: \"Review\", c: \"wcs-l1\" }, { t: \"Elevated\", c: \"wcs-l2\" }];\n  var OUT = {\n    lower: { t: \"Lower Concern\", c: \"wcs-l0\" },\n    review: { t: \"Additional Review Recommended\", c: \"wcs-l1\" },\n    elevated: { t: \"Elevated Concern\", c: \"wcs-l2\" },\n    insufficient: { t: \"Insufficient Data\", c: \"wcs-lx\" }\n  };\n  var BANNER = \"Preliminary Screening Only \u2014 Formal Welding Procedure Assessment Required.\";\n  \/* =====================================================================\n     NUMBER HELPERS (never display NaN or Infinity)\n     ===================================================================== *\/\n  function isNum(v) { return typeof v === \"number\" ? isFinite(v) : false; }\n  function fx(v, d) {\n    if (!isNum(v)) { return \"\u2014\"; }\n    var s = v.toFixed(d);\n    if (Number(s) === 0) { s = (0).toFixed(d); }\n    return s.charAt(0) === \"-\" ? \"\u2212\" + s.slice(1) : s;\n  }\n  function fin(v) { return isNum(v) ? String(Number(v.toPrecision(6))) : \"\u2014\"; }\n  function r3(v) { return Number(v.toFixed(3)); }\n  function cToF(c) { return c * 1.8 + 32; }\n  function tTxt(c) { return isNum(c) ? fx(c, 0) + \" \u00b0C (\" + fx(cToF(c), 0) + \" \u00b0F)\" : \"\u2014\"; }\n  function mmTxt(mm) { return isNum(mm) ? fin(Number(mm.toFixed(2))) + \" mm (\" + fx(mm \/ 25.4, 2) + \" in)\" : \"\u2014\"; }\n  function maxOf(a) { var m = null; a.forEach(function (x) { if (x !== null) { m = m === null ? x : Math.max(m, x); } }); return m; }\n  \/* =====================================================================\n     SCREENING BANDS (illustrative, documented in the notes)\n     ===================================================================== *\/\n  function lvlCEV(v) { var x = r3(v); return x < 0.35 ? 0 : (x <= 0.45 ? 1 : 2); }\n  function lvlHD(h) { return h <= 5 ? 0 : (h <= 10 ? 1 : 2); }\n  function hdScale(h) { return h > 15 ? \"A\" : (h > 10 ? \"B\" : (h > 5 ? \"C\" : (h > 3 ? \"D\" : \"E\"))); }\n  function lvlT(t) { return t <= 20 ? 0 : (t <= 50 ? 1 : 2); }\n  function lvlQ(q) { return q < 0.6 ? 2 : (q < 1.0 ? 1 : 0); }\n  function lvlR(r) { return r === \"low\" ? 0 : (r === \"mod\" ? 1 : (r === \"high\" ? 2 : null)); }\n  \/* =====================================================================\n     CALCULATION ENGINE\n     ===================================================================== *\/\n  function compute(fid, d) {\n    var f = FORM[fid], r = { id: fid, ok: false, value: null, terms: [], zero: [], missing: [], hard: [], invalid: [], reason: \"\" };\n    var sum = 0;\n    f.terms.forEach(function (t) {\n      var k = t[0], v = d.val[k];\n      if (d.err[k]) { r.invalid.push(k); return; }\n      if (v === null) {\n        if (MUST.indexOf(k) >= 0) { r.hard.push(k); return; }\n        if (!d.zero) { r.missing.push(k); return; }\n        r.zero.push(k);\n        v = 0;\n      }\n      var c = v * t[1] \/ t[2];\n      r.terms.push({ k: k, v: v, mult: t[1], div: t[2], txt: t[3], c: c, assumed: r.zero.indexOf(k) >= 0 });\n      sum += c;\n    });\n    if (r.invalid.length) { r.reason = \"Correct the invalid input: \" + r.invalid.join(\", \") + \".\"; return r; }\n    if (r.hard.length) { r.reason = \"Enter \" + r.hard.join(\" and \") + \". Carbon and manganese are never assumed to be zero.\"; return r; }\n    if (r.missing.length) { r.reason = \"Missing \" + r.missing.join(\", \") + \". Enter values or tick the option to treat blanks as zero.\"; return r; }\n    if (!isNum(sum)) { r.reason = \"The inputs produce a non-finite result.\"; return r; }\n    r.ok = true; r.value = sum;\n    return r;\n  }\n  function computeHeat(d) {\n    var h = { mode: d.hmode, status: \"none\", arc: null, net: null, eta: d.eta, etaSrc: d.etaSrc, steps: [], reason: \"\", missing: [] };\n    if (d.hmode === \"none\") { h.reason = \"Heat input not specified.\"; return h; }\n    if (d.hmode === \"calc\") {\n      var keys = [\"amp\", \"volt\", \"spd\"], bad = keys.filter(function (k) { return d.err[k] ? true : false; });\n      if (bad.length) { h.status = \"invalid\"; h.reason = \"Correct the welding parameter inputs.\"; return h; }\n      var blank = keys.filter(function (k) { return d[k] === null; });\n      if (blank.length === 3) { h.reason = \"Welding parameters not entered.\"; return h; }\n      if (blank.length) { h.status = \"partial\"; h.missing = blank; h.reason = \"Enter current, voltage and travel speed to calculate heat input.\"; return h; }\n      h.arc = 60 * d.volt * d.amp \/ (1000 * d.spd);\n      h.steps.push(\"Arc energy E = 60 \u00d7 U \u00d7 I \/ (1000 \u00d7 v) = 60 \u00d7 \" + fin(d.volt) + \" \u00d7 \" + fin(d.amp) + \" \/ (1000 \u00d7 \" + fin(d.spd) + \") = \" + fx(h.arc, 3) + \" kJ\/mm\");\n    } else {\n      if (d.err.hq) { h.status = \"invalid\"; h.reason = \"Correct the heat input value.\"; return h; }\n      if (d.hq === null) { h.reason = \"Heat input value not entered.\"; return h; }\n      if (d.hqtype === \"net\") { h.net = d.hq; h.steps.push(\"Net heat input Q entered directly = \" + fx(h.net, 3) + \" kJ\/mm\"); }\n      else { h.arc = d.hq; h.steps.push(\"Arc energy E entered directly = \" + fx(h.arc, 3) + \" kJ\/mm\"); }\n    }\n    if (h.net === null) {\n      if (d.eta !== null) {\n        h.net = d.eta * h.arc;\n        h.steps.push(\"Net heat input Q = \u03b7 \u00d7 E = \" + fin(d.eta) + \" \u00d7 \" + fx(h.arc, 3) + \" = \" + fx(h.net, 3) + \" kJ\/mm\");\n      } else {\n        h.status = \"arc\";\n        h.reason = \"Arc energy is known, but net heat input needs a justified thermal efficiency factor. Select the welding process or enter a custom \u03b7.\";\n        return h;\n      }\n    }\n    if (!isNum(h.net) ? true : (h.arc !== null ? !isNum(h.arc) : false)) { h.status = \"invalid\"; h.net = null; h.arc = null; h.reason = \"The inputs produce a non-finite heat input.\"; return h; }\n    h.status = \"ok\";\n    return h;\n  }\n  function buildFactors(d, res, heat) {\n    var F = {};\n    var cevOk = res.cev.ok, pcmOk = res.pcm.ok;\n    \/* Material hardenability *\/\n    var H = { key: \"hard\", name: \"Material hardenability\", lvl: null, obs: \"\", judg: \"\", basis: \"Illustrative IIW CEV bands: below 0.35%, 0.35\u20130.45%, above 0.45%. Pcm is reported without a universal threshold.\" };\n    if (cevOk) {\n      H.lvl = lvlCEV(res.cev.value);\n      H.obs = \"CEV = \" + fx(res.cev.value, 3) + \"%\" + (pcmOk ? \", Pcm = \" + fx(res.pcm.value, 3) + \"%\" : \"\");\n      H.judg = [\"CEV is in the lower illustrative band, suggesting comparatively low HAZ hardenability.\", \"CEV is in the intermediate illustrative band. HAZ hardenability is moderate, so hydrogen control and cooling conditions deserve review.\", \"CEV is in the upper illustrative band. Hard, crack-susceptible HAZ microstructures are more likely on fast cooling.\"][H.lvl] + \" Higher carbon equivalent may indicate increased HAZ hardenability.\";\n    } else if (pcmOk) {\n      H.obs = \"CEV not calculated, Pcm = \" + fx(res.pcm.value, 3) + \"%\";\n      H.judg = \"No universal Pcm threshold is applied, so hardenability is not classified. Complete the CEV elements to screen this factor.\";\n    } else {\n      H.obs = \"Composition incomplete\";\n      H.judg = \"Hardenability cannot be screened until CEV can be calculated. \" + res.cev.reason;\n    }\n    F.hard = H;\n    \/* Diffusible hydrogen *\/\n    var Y = { key: \"hyd\", name: \"Diffusible hydrogen\", lvl: null, obs: \"\", judg: \"\", basis: \"Descriptive hydrogen scales of EN 1011-2 Annex C: A > 15, B 10\u201315, C 5\u201310, D 3\u20135, E \u2264 3 mL\/100 g. Bands used here: D\/E lower, C review, A\/B elevated.\" };\n    if (d.hd !== null) {\n      Y.lvl = lvlHD(d.hd);\n      Y.obs = fin(d.hd) + \" mL\/100 g\" + (d.hdSrc === \"designator\" ? \" (maximum of designator \" + d.hdcat + \", not a measured value)\" : \"\") + \", scale \" + hdScale(d.hd);\n      Y.judg = [\"Low diffusible hydrogen level (scale D or E).\", \"Moderate diffusible hydrogen level (scale C).\", \"High diffusible hydrogen level (scale A or B).\"][Y.lvl] + \" Higher diffusible hydrogen content may increase hydrogen-assisted cracking susceptibility. A scale or designator alone does not establish cracking risk.\";\n    } else { Y.obs = \"Not entered\"; Y.judg = \"Enter the measured or specified diffusible hydrogen level, or select the consumable designator.\"; }\n    F.hyd = Y;\n    \/* Plate thickness *\/\n    var T = { key: \"thk\", name: \"Plate thickness\", lvl: null, obs: \"\", judg: \"\", basis: \"Illustrative bands: up to 20 mm lower, 20\u201350 mm review, above 50 mm elevated. Plate thickness only; combined thickness is not evaluated.\" };\n    if (d.tmm !== null) {\n      T.lvl = lvlT(d.tmm);\n      T.obs = mmTxt(d.tmm);\n      T.judg = [\"Comparatively thin section.\", \"Intermediate thickness.\", \"Heavy section.\"][T.lvl] + \" Greater thickness may influence cooling behavior and restraint, depending on joint geometry and welding conditions.\";\n    } else { T.obs = \"Not entered\"; T.judg = \"Enter the plate thickness.\"; }\n    F.thk = T;\n    \/* Heat input *\/\n    var Q = { key: \"heat\", name: \"Welding heat input\", lvl: null, obs: \"\", judg: \"\", basis: \"Illustrative net heat input bands: below 0.6 kJ\/mm elevated, 0.6\u20131.0 kJ\/mm review, 1.0 kJ\/mm or more lower (cooling-rate perspective only).\" };\n    if (heat.status === \"ok\") {\n      Q.lvl = lvlQ(heat.net);\n      Q.obs = \"Net Q = \" + fx(heat.net, 2) + \" kJ\/mm\" + (heat.arc !== null ? \", arc energy E = \" + fx(heat.arc, 2) + \" kJ\/mm\" : \"\");\n      Q.judg = [\"Higher net heat input generally slows cooling and lowers HAZ hardness. Confirm it stays within the qualified range, because toughness can be affected.\", \"Moderate-low net heat input. Cooling may be relatively fast, particularly in thicker sections.\", \"Low net heat input. Comparatively fast cooling is likely, particularly in thicker sections.\"][Q.lvl] + \" Heat input affects the weld thermal cycle and cooling rate; its influence must be interpreted with the material, thickness, process and procedure.\";\n    } else if (heat.status === \"arc\") {\n      Q.obs = \"Arc energy E = \" + fx(heat.arc, 2) + \" kJ\/mm, net heat input not determined\";\n      Q.judg = \"Not classified, because arc energy and net heat input must not be mixed. \" + heat.reason;\n    } else { Q.obs = \"Not available\"; Q.judg = heat.reason ? heat.reason : \"Heat input not specified.\"; }\n    F.heat = Q;\n    \/* Restraint *\/\n    var R = { key: \"res\", name: \"Joint restraint\", lvl: lvlR(d.restr), obs: d.restr ? RESTR[d.restr] : \"Not selected\", judg: \"\", basis: \"Descriptive category selected by the user. It does not replace a quantitative restraint analysis.\" };\n    R.judg = R.lvl === null ? \"Select a restraint category.\" : [\"Low restraint selected.\", \"Moderate restraint selected.\", \"High restraint selected.\"][R.lvl] + \" Higher restraint can increase tensile stress during cooling.\";\n    F.res = R;\n    \/* Cooling conditions (thickness and heat input, conservative maximum) *\/\n    var cool = T.lvl === null ? null : (Q.lvl === null ? T.lvl : Math.max(T.lvl, Q.lvl));\n    \/* Overall screening outcome: combination rule, no point totals *\/\n    var core = { hard: H.lvl, hyd: Y.lvl, res: R.lvl, cool: cool }, missing = [], outcome, why;\n    if (H.lvl === null) { missing.push(\"CEV (complete composition)\"); }\n    if (Y.lvl === null) { missing.push(\"diffusible hydrogen\"); }\n    if (T.lvl === null) { missing.push(\"plate thickness\"); }\n    if (R.lvl === null) { missing.push(\"joint restraint\"); }\n    if (missing.length) {\n      outcome = \"insufficient\";\n      why = \"A screening outcome needs all core factors. Missing: \" + missing.join(\", \") + \".\";\n    } else {\n      var st = Math.max(R.lvl, cool), all = Math.max(H.lvl, Y.lvl, R.lvl, cool);\n      var three = H.lvl >= 1 ? (Y.lvl >= 1 ? st >= 1 : false) : false;\n      if (three ? Math.max(H.lvl, Y.lvl, st) === 2 : false) {\n        outcome = \"elevated\";\n        why = \"Hardenability, hydrogen and stress or cooling conditions are all at least at review level, and at least one is elevated. This is the unfavorable combination associated with hydrogen-assisted cold cracking.\";\n      } else if (all === 0) {\n        outcome = \"lower\";\n        why = \"Every core factor (hardenability, hydrogen, thickness and heat input, restraint) is in its lower illustrative band.\";\n      } else {\n        outcome = \"review\";\n        why = three ? \"Hardenability, hydrogen and stress or cooling conditions are all at review level, but none is elevated.\" : \"At least one factor is outside its lower band, but the three conditions for cold cracking are not all present at review level or above.\";\n      }\n    }\n    \/* Preheat review (reported, never used to lower the outcome) *\/\n    var P = { key: \"pre\", name: \"Preheat review\", lvl: null, obs: \"\", judg: \"\", basis: \"This tool does not calculate required preheat. Use EN 1011-2, the alternative preheat methods in AWS D1.1, CSA W59 or a qualified procedure.\" };\n    var tail = \" Appropriate preheating may reduce cooling rate and support hydrogen diffusion, but the required temperature must be established using a suitable welding standard or qualified procedure.\";\n    P.obs = \"Preheat \" + (d.pre !== null ? tTxt(d.pre) : \"not entered\") + \", ambient \" + (d.amb !== null ? tTxt(d.amb) : \"not entered\");\n    if (d.pre === null) { P.judg = \"No preheat recorded.\"; }\n    else if (outcome === \"lower\") { P.lvl = 0; P.judg = \"The other factors are all in lower bands. Preheat is still governed by the WPS and the applicable standard.\"; }\n    else {\n      var above = d.amb === null ? d.pre > 20 : d.pre > d.amb;\n      if (above) { P.lvl = 1; P.judg = \"Preheat above ambient is recorded. Its adequacy is not evaluated here, so confirm it against the applicable standard or qualified procedure.\"; }\n      else { P.lvl = 2; P.judg = \"No preheat above ambient is recorded while other factors call for review. Establish whether preheat is required.\"; }\n    }\n    P.judg += tail;\n    F.pre = P;\n    return { F: F, cool: cool, core: core, outcome: outcome, why: why, missing: missing };\n  }\n  function buildNotes(d, res, heat) {\n    var N = [];\n    function W(lvl, text) { N.push({ lvl: lvl, text: text }); }\n    var v = d.val, total = 0, zero = {};\n    ELEMS.forEach(function (k) { if (v[k] !== null) { total += v[k]; } });\n    [\"cev\", \"pcm\"].forEach(function (id) { if (res[id].ok) { res[id].zero.forEach(function (k) { zero[k] = true; }); } });\n    if (total > 100) { W(\"e\", \"The entered elements total \" + fx(total, 3) + \" wt.%, which exceeds 100 wt.%. The composition is not physically possible. Check for unit or decimal errors.\"); }\n    if (v.C !== null) {\n      if (v.C > 2.1) { W(\"e\", \"C = \" + fin(v.C) + \" wt.% is above about 2.1 wt.%, the upper limit for steel. CEV and Pcm are not applicable.\"); }\n      else if (v.C > 0.6) { W(\"w\", \"C = \" + fin(v.C) + \" wt.% is a high-carbon steel, well beyond the steels these indices were developed for. Treat the results as indicative only.\"); }\n    }\n    if (v.Cr !== null ? v.Cr >= 10.5 : false) { W(\"e\", \"Cr \u2265 10.5 wt.% indicates a stainless steel. These carbon equivalent methods for ferritic steels do not apply.\"); }\n    else {\n      var hi = [];\n      if (v.Cr !== null ? v.Cr > 5 : false) { hi.push(\"Cr \" + fin(v.Cr)); }\n      if (v.Ni !== null ? v.Ni > 5 : false) { hi.push(\"Ni \" + fin(v.Ni)); }\n      if (v.Mo !== null ? v.Mo > 1.5 : false) { hi.push(\"Mo \" + fin(v.Mo)); }\n      if (v.Mn !== null ? v.Mn > 2 : false) { hi.push(\"Mn \" + fin(v.Mn)); }\n      if (v.V !== null ? v.V > 0.5 : false) { hi.push(\"V \" + fin(v.V)); }\n      if (v.Cu !== null ? v.Cu > 1.5 : false) { hi.push(\"Cu \" + fin(v.Cu)); }\n      if (v.Si !== null ? v.Si > 2 : false) { hi.push(\"Si \" + fin(v.Si)); }\n      if (hi.length) { W(\"w\", \"High alloy content (\" + hi.join(\", \") + \" wt.%) is outside the low-alloy range these linear formulas were derived for.\"); }\n    }\n    if (d.bRaw !== null ? d.val.B !== null : false) {\n      if (d.bUnit === \"ppm\") { W(\"i\", \"Boron converted from ppm: \" + fin(d.bRaw) + \" ppm \u00f7 10,000 = \" + fin(d.val.B) + \" wt.%.\"); }\n      if (d.val.B > 0.01) { W(\"w\", \"Boron = \" + fin(d.val.B) + \" wt.% (\" + fin(d.val.B * 10000) + \" ppm) is unusually high. Boron-treated steels typically contain about 5\u201330 ppm. Check whether the value is in ppm.\"); }\n      if (d.bUnit === \"ppm\" ? (d.bRaw > 0 ? d.bRaw < 1 : false) : false) { W(\"w\", \"Boron = \" + fin(d.bRaw) + \" ppm is very low for a reported value. If the report gives wt.% (for example 0.0005), switch the unit to wt.%.\"); }\n    }\n    var zk = Object.keys(zero);\n    if (zk.length) { W(\"w\", \"Treated as 0 wt.% at your request: \" + zk.join(\", \") + \". Residual elements are rarely exactly zero, so CEV and Pcm may be underestimated.\"); }\n    if (res.cev.ok) {\n      var x = r3(res.cev.value);\n      if (Math.abs(x - 0.35) <= 0.01 ? true : Math.abs(x - 0.45) <= 0.01) { W(\"w\", \"CEV is within \u00b10.01 of an illustrative band boundary. Analysis tolerance and heat versus product analysis can move it into the neighbouring band.\"); }\n    }\n    if (res.pcm.ok) {\n      var out = [];\n      Object.keys(PCM_RANGE).forEach(function (k) {\n        var y = v[k], rg = PCM_RANGE[k];\n        if (y === null) { return; }\n        if (y < rg[0] ? true : y > rg[1]) { out.push(k + \" \" + fin(y) + \" (\" + rg[0] + \"\u2013\" + rg[1] + \")\"); }\n      });\n      if (out.length) { W(\"w\", \"Outside the approximate composition range of the original Pcm study: \" + out.join(\"; \") + \" wt.%. Pcm may be less representative for this steel.\"); }\n    }\n    if (v.C !== null ? (v.C <= 0.12 ? (res.cev.ok ? true : res.pcm.ok) : false) : false) { W(\"i\", \"For C \u2264 0.12 wt.%, Pcm is often preferred over CEV (for example in API 5L \/ ISO 3183 PSL 2 line pipe).\"); }\n    if (v.C !== null ? (v.C > 0.12 ? res.pcm.ok : false) : false) { W(\"i\", \"For C > 0.12 wt.%, CEV is more commonly used. Pcm can understate the alloying effect in conventional C-Mn steels.\"); }\n    if (d.hd !== null) {\n      if (d.hdSrc === \"entered\" ? HDCAT[d.hdcat] : false) {\n        if (d.hd > HDCAT[d.hdcat].v) { W(\"w\", \"The entered diffusible hydrogen (\" + fin(d.hd) + \" mL\/100 g) exceeds the maximum of the selected designator \" + d.hdcat + \". Check the consumable classification and handling.\"); }\n      }\n      if (d.hdSrc === \"designator\") { W(\"i\", \"Diffusible hydrogen was taken as the maximum of designator \" + d.hdcat + \" (\" + fin(d.hd) + \" mL\/100 g). Actual levels depend on consumable condition, storage and welding conditions.\"); }\n      if (d.hd === 0) { W(\"w\", \"A diffusible hydrogen level of 0 mL\/100 g is not realistic for arc welding. Check the value.\"); }\n      if (d.hd > 30) { W(\"w\", \"Diffusible hydrogen above 30 mL\/100 g is very high, typical of uncontrolled cellulosic or damp consumables.\"); }\n    }\n    if (d.tmm !== null ? d.tmm > 150 : false) { W(\"i\", \"Very heavy section. Restraint, through-thickness properties and lamellar tearing should also be reviewed (lamellar tearing is not assessed here).\"); }\n    if (heat.status === \"ok\") {\n      if (heat.net > 6) { W(\"w\", \"Net heat input above 6 kJ\/mm is unusually high. Check the travel speed and its unit.\"); }\n      if (heat.net < 0.2) { W(\"w\", \"Net heat input below 0.2 kJ\/mm is unusually low for arc welding. Check the inputs and units.\"); }\n      if (heat.etaSrc === \"custom\") { W(\"i\", \"A custom thermal efficiency factor \u03b7 = \" + fin(heat.eta) + \" was used. Record the justification for this value.\"); }\n    }\n    if (d.pre !== null ? (d.amb !== null ? d.pre < d.amb : false) : false) { W(\"w\", \"The preheat temperature is lower than the ambient temperature. Check the values.\"); }\n    if (d.amb !== null) {\n      if (d.amb < 0) { W(\"w\", \"Ambient temperature below 0 \u00b0C. Moisture, frost or ice on the joint is a hydrogen source and the base metal cools faster. Many codes require warming before welding.\"); }\n      else if (d.amb < 5) { W(\"i\", \"Low ambient temperature. Check for condensation on the joint and the code requirements for welding in cold conditions.\"); }\n    }\n    W(\"i\", \"Only hydrogen-assisted cold cracking is screened. Solidification cracking, liquation cracking, reheat cracking and lamellar tearing have different causes and are not evaluated.\");\n    W(\"i\", \"IIW CEV and Pcm are different formulas on different scales. Do not compare a value from one with a limit written for the other.\");\n    return N;\n  }\n  function buildRecs(d, res, heat, fac) {\n    var R = [], F = fac.F;\n    R.push(\"Review the applicable welding procedure specification (WPS) and its supporting procedure qualification record.\");\n    R.push(\"Confirm the material chemistry from a reliable mill test certificate, using the analysis basis (heat or product analysis) required by the governing code.\");\n    var zeroUsed = res.cev.zero.length + res.pcm.zero.length > 0;\n    if (zeroUsed ? true : !res.cev.ok) { R.push(\"Obtain a complete chemical analysis. Results based on blank or assumed-zero elements are preliminary only.\"); }\n    if (F.hyd.lvl === null ? true : F.hyd.lvl >= 1) { R.push(\"Verify the diffusible hydrogen classification of the consumables and their handling: baking, holding ovens, exposure time, and clean, dry joint preparation.\"); }\n    else { R.push(\"Maintain consumable control so that the low diffusible hydrogen level is achieved in production, not only on the certificate.\"); }\n    if (F.res.lvl === null ? true : (F.res.lvl >= 1 ? true : (F.thk.lvl === null ? true : F.thk.lvl >= 1))) { R.push(\"Evaluate joint restraint and thickness, including combined thickness at the joint, fit-up, welding sequence and root pass size.\"); }\n    R.push(\"Review preheat and interpass temperature requirements using EN 1011-2, the alternative preheat methods in AWS D1.1, CSA W59 or the governing code. This calculator does not determine the required preheat.\");\n    if (heat.status !== \"ok\") { R.push(\"Determine the net heat input of the intended procedure, with a justified thermal efficiency factor, so that cooling conditions can be assessed.\"); }\n    if (fac.outcome === \"elevated\" ? true : fac.outcome === \"review\") { R.push(\"Consider an applicable hydrogen cracking assessment procedure, such as EN 1011-2 Method A or B or the hydrogen control method in AWS D1.1, and consider post-heating (hydrogen release) where the code permits.\"); }\n    if (fac.outcome === \"elevated\") { R.push(\"Perform welding procedure qualification or weldability testing (for example Tekken y-groove or CTS tests) where required, and specify a hold time before final NDT to detect delayed cracking.\"); }\n    else { R.push(\"Perform welding procedure qualification or testing where required by the governing code or contract.\"); }\n    if (d.amb !== null ? d.amb < 5 : false) { R.push(\"For welding at low ambient temperature, remove moisture from the joint and follow the code requirements for minimum base metal temperature.\"); }\n    return R;\n  }\n  function buildCompleteness(d, res, heat) {\n    function st(ok, txt) { return { ok: ok, t: txt }; }\n    var rows = [];\n    rows.push([\"IIW CEV composition\", res.cev.ok ? st(true, res.cev.zero.length ? \"Complete (assumed zero: \" + res.cev.zero.join(\", \") + \")\" : \"Complete\") : st(false, \"Incomplete\")]);\n    rows.push([\"Pcm composition\", res.pcm.ok ? st(true, res.pcm.zero.length ? \"Complete (assumed zero: \" + res.pcm.zero.join(\", \") + \")\" : \"Complete\") : st(false, \"Incomplete\")]);\n    rows.push([\"Plate thickness\", d.tmm !== null ? st(true, \"Entered\") : st(false, \"Missing\")]);\n    rows.push([\"Diffusible hydrogen\", d.hd !== null ? st(true, d.hdSrc === \"designator\" ? \"Designator maximum\" : \"Entered\") : st(false, \"Missing\")]);\n    rows.push([\"Net heat input\", heat.status === \"ok\" ? st(true, \"Determined\") : st(false, heat.status === \"arc\" ? \"Arc energy only\" : \"Not available\")]);\n    rows.push([\"Joint restraint\", d.restr ? st(true, \"Selected\") : st(false, \"Missing\")]);\n    rows.push([\"Preheat temperature\", d.pre !== null ? st(true, \"Entered\") : st(false, \"Missing\")]);\n    rows.push([\"Ambient temperature\", d.amb !== null ? st(true, \"Entered\") : st(false, \"Missing\")]);\n    var n = rows.filter(function (r) { return r[1].ok; }).length;\n    return { rows: rows, n: n, total: rows.length };\n  }\n  var ASSUMPTIONS = [\n    \"Screening addresses hydrogen-assisted cold cracking in carbon and low-alloy steels, mainly in the HAZ.\",\n    \"Compositions are in wt.% on the analysis basis entered; boron in ppm is divided by 10,000.\",\n    \"CEV, thickness and heat input bands are illustrative screening aids, not limits from a specific standard. Hydrogen bands use the descriptive EN 1011-2 Annex C scales.\",\n    \"Plate thickness is used as entered; combined thickness and joint geometry are not modelled.\",\n    \"Net heat input Q = \u03b7 \u00d7 60 \u00d7 U \u00d7 I \/ (1000 \u00d7 v), with \u03b7 from the selected process (EN 1011-1 \/ ISO\/TR 17671-1) or a user-justified value.\",\n    \"Cooling conditions take the more unfavorable of the thickness and heat input bands (conservative).\",\n    \"The screening outcome uses a stated combination rule, not a points total, and is not a probability of cracking.\",\n    \"Required preheat is not calculated, and recorded preheat is never used to lower the outcome.\"\n  ];\n  \/* =====================================================================\n     USER INTERFACE\n     ===================================================================== *\/\n  function init() {\n    var root = document.getElementById(\"wcs-calculator\");\n    if (!root) { return; }\n    if (root.getAttribute(\"data-wcs-init\") === \"1\") { return; }\n    root.setAttribute(\"data-wcs-init\", \"1\");\n    var SVGNS = \"http:\/\/www.w3.org\/2000\/svg\";\n    function q(id) { return root.querySelector(\"#\" + id); }\n    function radio(name) { var e = root.querySelector('input[name=\"' + name + '\"]:checked'); return e ? e.value : \"\"; }\n    function h(tag, a, kids) {\n      var n = document.createElement(tag);\n      if (a) { Object.keys(a).forEach(function (k) { if (k === \"class\") { n.className = a[k]; } else if (k === \"text\") { n.textContent = a[k]; } else if (k === \"html\") { n.innerHTML = a[k]; } else { n.setAttribute(k, a[k]); } }); }\n      add(n, kids);\n      return n;\n    }\n    function add(n, kids) {\n      if (kids === undefined ? true : kids === null) { return; }\n      if (Array.isArray(kids)) { kids.forEach(function (k) { add(n, k); }); return; }\n      if (typeof kids === \"string\" ? true : typeof kids === \"number\") { n.appendChild(document.createTextNode(String(kids))); return; }\n      n.appendChild(kids);\n    }\n    function sv(tag, a) {\n      var n = document.createElementNS(SVGNS, tag);\n      if (a) { Object.keys(a).forEach(function (k) { n.setAttribute(k, a[k]); }); }\n      return n;\n    }\n    function clear(n) { while (n.firstChild) { n.removeChild(n.firstChild); } }\n    var state = { last: null, live: false, timer: null };\n    var FIELDS = [\"C\", \"Si\", \"Mn\", \"Cr\", \"Ni\", \"Mo\", \"V\", \"Cu\", \"B\", \"t\", \"hd\", \"amp\", \"volt\", \"spd\", \"hq\", \"eta\", \"pre\", \"amb\", \"restr\", \"proc\"];\n    \/* ---------- reading and validating inputs ---------- *\/\n    function field(id) {\n      var el = q(id), s = String(el.value).trim();\n      if (s === \"\") { return { blank: true, bad: el.validity ? el.validity.badInput : false, n: null }; }\n      var n = Number(s);\n      if (!isFinite(n)) { return { blank: false, bad: true, n: null }; }\n      return { blank: false, bad: false, n: n };\n    }\n    function positive(d, key, id, max, maxMsg) {\n      var f = field(id);\n      d[key] = null;\n      if (f.bad) { d.err[key] = \"Enter a numeric value.\"; return null; }\n      if (f.blank) { return null; }\n      if (f.n <= 0) { d.err[key] = \"Enter a value greater than zero.\"; return null; }\n      if (f.n > max) { d.err[key] = maxMsg; return null; }\n      d[key] = f.n;\n      return f.n;\n    }\n    function temp(d, key, id, unitId, lo, hi, msg) {\n      var f = field(id), u = q(unitId).value;\n      d[key] = null;\n      if (f.bad) { d.err[key] = \"Enter a numeric value.\"; return; }\n      if (f.blank) { return; }\n      var c = u === \"F\" ? (f.n - 32) \/ 1.8 : f.n;\n      if (c < lo ? true : c > hi) { d.err[key] = msg; return; }\n      d[key] = c;\n    }\n    function readAll() {\n      var d = { val: {}, err: {}, bUnit: q(\"wcs-Bunit\").value, bRaw: null, zero: q(\"wcs-zero\").checked, material: q(\"wcs-material\").value };\n      ELEMS.forEach(function (k) {\n        var f = field(\"wcs-\" + k);\n        d.val[k] = null;\n        if (f.bad) { d.err[k] = \"Enter a numeric value.\"; return; }\n        if (f.blank) { return; }\n        var n = f.n;\n        if (n < 0) { d.err[k] = \"Negative concentrations are not allowed. Enter 0 for a confirmed absence.\"; return; }\n        var w = n;\n        if (k === \"B\") {\n          d.bRaw = n;\n          if (d.bUnit === \"ppm\") {\n            if (n > 10000) { d.err.B = \"More than 10,000 ppm (1 wt.%) boron is not plausible for steel.\"; return; }\n            w = n \/ 10000;\n          } else if (n > 1) { d.err.B = \"Boron of \" + fin(n) + \" wt.% is not plausible for steel. If the value is in ppm, switch the unit to ppm.\"; return; }\n        } else if (n > 100) { d.err[k] = \"A concentration cannot exceed 100 wt.%.\"; return; }\n        d.val[k] = w;\n      });\n      \/* thickness *\/\n      d.tUnit = q(\"wcs-tunit\").value; d.tmm = null;\n      var t = positive(d, \"t\", \"wcs-t\", d.tUnit === \"in\" ? 40 : 1000, \"Thickness above 1,000 mm (40 in) is outside the plausible range.\");\n      if (t !== null) { d.tmm = d.tUnit === \"in\" ? t * 25.4 : t; }\n      \/* diffusible hydrogen *\/\n      d.hdcat = q(\"wcs-hdcat\").value; d.hd = null; d.hdSrc = \"\";\n      var fh = field(\"wcs-hd\");\n      if (fh.bad) { d.err.hd = \"Enter a numeric value.\"; }\n      else if (!fh.blank) {\n        if (fh.n < 0) { d.err.hd = \"Diffusible hydrogen cannot be negative.\"; }\n        else if (fh.n > 100) { d.err.hd = \"Enter a value of at most 100 mL\/100 g.\"; }\n        else { d.hd = fh.n; d.hdSrc = \"entered\"; }\n      }\n      if (d.hd === null ? (d.err.hd ? false : (HDCAT[d.hdcat] ? true : false)) : false) { d.hd = HDCAT[d.hdcat].v; d.hdSrc = \"designator\"; }\n      \/* efficiency *\/\n      d.hmode = q(\"wcs-hmode\").value; d.proc = q(\"wcs-proc\").value; d.eta = null; d.etaSrc = \"\";\n      var etaUsed = d.hmode === \"calc\" ? true : (d.hmode === \"direct\" ? q(\"wcs-hqtype\").value === \"arc\" : false);\n      if (!etaUsed) { d.proc = \"\"; }\n      if (d.proc === \"custom\") {\n        var fe = field(\"wcs-eta\");\n        if (fe.bad) { d.err.eta = \"Enter a numeric value.\"; }\n        else if (!fe.blank) {\n          if (fe.n <= 0 ? true : fe.n > 1) { d.err.eta = \"\u03b7 must be greater than 0 and not more than 1.\"; }\n          else { d.eta = fe.n; d.etaSrc = \"custom\"; }\n        }\n      } else if (PROC[d.proc]) { d.eta = PROC[d.proc].k; d.etaSrc = PROC[d.proc].n; }\n      \/* heat input inputs *\/\n      d.amp = null; d.volt = null; d.spd = null; d.hq = null; d.hqtype = q(\"wcs-hqtype\").value;\n      if (d.hmode === \"calc\") {\n        positive(d, \"amp\", \"wcs-amp\", 3000, \"Current above 3,000 A is outside the plausible range.\");\n        positive(d, \"volt\", \"wcs-volt\", 100, \"Arc voltage above 100 V is outside the plausible range.\");\n        var su = q(\"wcs-spdunit\").value, sp = positive(d, \"spd\", \"wcs-spd\", 100000, \"Travel speed is outside the plausible range.\");\n        if (sp !== null) { d.spd = su === \"mms\" ? sp * 60 : (su === \"inmin\" ? sp * 25.4 : sp); }\n      } else if (d.hmode === \"direct\") {\n        var hu = q(\"wcs-hqunit\").value, hv = positive(d, \"hq\", \"wcs-hq\", hu === \"kjin\" ? 1000 : 40, \"Heat input is outside the plausible range. Check the unit.\");\n        if (hv !== null) { d.hq = hu === \"kjin\" ? hv \/ 25.4 : hv; }\n      }\n      \/* restraint and temperatures *\/\n      d.restr = q(\"wcs-restr\").value;\n      temp(d, \"pre\", \"wcs-pre\", \"wcs-preunit\", -60, 700, \"Preheat must be between \u221260 and 700 \u00b0C (\u221276 and 1292 \u00b0F).\");\n      temp(d, \"amb\", \"wcs-amb\", \"wcs-ambunit\", -60, 60, \"Ambient temperature must be between \u221260 and 60 \u00b0C (\u221276 and 140 \u00b0F).\");\n      return d;\n    }\n    function setErr(k, msg) {\n      var input = q(\"wcs-\" + k), e = q(\"wcs-\" + k + \"-err\");\n      if (e) { e.textContent = msg ? msg : \"\"; }\n      if (!input) { return; }\n      if (msg) { input.classList.add(\"wcs-invalid\"); input.setAttribute(\"aria-invalid\", \"true\"); }\n      else { input.classList.remove(\"wcs-invalid\"); input.removeAttribute(\"aria-invalid\"); }\n    }\n    function clearErrors() { FIELDS.forEach(function (k) { setErr(k, \"\"); }); }\n    function msg(text, good) { var m = q(\"wcs-msg\"); m.textContent = text ? text : \"\"; m.className = \"wcs-form-msg\" + (good ? \" wcs-good\" : \"\"); }\n    \/* ---------- dependent fields ---------- *\/\n    function updateVisibility() {\n      var mode = q(\"wcs-hmode\").value, proc = q(\"wcs-proc\").value, type = q(\"wcs-hqtype\").value;\n      var nodes = root.querySelectorAll(\"[data-h]\"), i;\n      for (i = 0; i < nodes.length; i++) {\n        var g = nodes[i].getAttribute(\"data-h\"), vis;\n        if (g === \"calc\") { vis = mode === \"calc\"; }\n        else if (g === \"direct\") { vis = mode === \"direct\"; }\n        else if (g === \"eta\") { vis = mode === \"calc\" ? true : (mode === \"direct\" ? type === \"arc\" : false); }\n        else { vis = (mode === \"calc\" ? true : (mode === \"direct\" ? type === \"arc\" : false)) ? proc === \"custom\" : false; }\n        nodes[i].hidden = !vis;\n      }\n    }\n    function updateBHint() {\n      var str = String(q(\"wcs-B\").value).trim(), u = q(\"wcs-Bunit\").value, n = Number(str), hint = q(\"wcs-B-hint\");\n      if (str === \"\" ? true : (!isFinite(n) ? true : n < 0)) { hint.textContent = \"1 ppm = 0.0001 wt.%. Select the unit used in your analysis report.\"; return; }\n      hint.textContent = u === \"ppm\" ? fin(n) + \" ppm = \" + fin(n \/ 10000) + \" wt.% (used in Pcm)\" : fin(n) + \" wt.% = \" + fin(n * 10000) + \" ppm\";\n    }\n    function updateMaterialInfo() {\n      var m = MAT[q(\"wcs-material\").value], box = q(\"wcs-matinfo\");\n      clear(box);\n      box.appendChild(h(\"strong\", { text: m.name + \". \" }));\n      box.appendChild(document.createTextNode(m.info + \" No composition values or preheat requirements are filled in from this selection.\"));\n    }\n    \/* converts already-entered values when a unit selector changes (not boron) *\/\n    var CONV = {\n      \"wcs-tunit\": { f: \"wcs-t\", to: function (v, u) { return u === \"in\" ? v * 25.4 : v; }, from: function (b, u) { return u === \"in\" ? b \/ 25.4 : b; } },\n      \"wcs-spdunit\": { f: \"wcs-spd\", to: function (v, u) { return u === \"mms\" ? v * 60 : (u === \"inmin\" ? v * 25.4 : v); }, from: function (b, u) { return u === \"mms\" ? b \/ 60 : (u === \"inmin\" ? b \/ 25.4 : b); } },\n      \"wcs-hqunit\": { f: \"wcs-hq\", to: function (v, u) { return u === \"kjin\" ? v \/ 25.4 : v; }, from: function (b, u) { return u === \"kjin\" ? b * 25.4 : b; } },\n      \"wcs-preunit\": { f: \"wcs-pre\", to: function (v, u) { return u === \"F\" ? (v - 32) \/ 1.8 : v; }, from: function (b, u) { return u === \"F\" ? b * 1.8 + 32 : b; } },\n      \"wcs-ambunit\": { f: \"wcs-amb\", to: function (v, u) { return u === \"F\" ? (v - 32) \/ 1.8 : v; }, from: function (b, u) { return u === \"F\" ? b * 1.8 + 32 : b; } }\n    };\n    function onUnitChange(sel) {\n      var c = CONV[sel.id], prev = sel.getAttribute(\"data-prev\"), now = sel.value;\n      sel.setAttribute(\"data-prev\", now);\n      if (!c ? true : (!prev ? true : prev === now)) { return; }\n      var el = q(c.f), s = String(el.value).trim();\n      if (s === \"\") { return; }\n      var n = Number(s);\n      if (!isFinite(n)) { return; }\n      el.value = String(Number(c.from(c.to(n, prev), now).toPrecision(6)));\n    }\n    \/* =====================================================================\n       RESULTS RENDERING\n       ===================================================================== *\/\n    function chip(lvl, txt) { return h(\"span\", { class: \"wcs-chip \" + (lvl === null ? \"wcs-lx\" : LV[lvl].c), text: txt ? txt : (lvl === null ? \"No data\" : LV[lvl].t) }); }\n    function kpi(label, value, sub, na, main) {\n      return h(\"div\", { class: \"wcs-kpi\" + (main ? \" wcs-main\" : \"\") }, [h(\"div\", { class: \"wcs-kpi-label\", text: label }), h(\"div\", { class: \"wcs-kpi-value\" + (na ? \" wcs-na\" : \"\"), text: value }), sub ? h(\"div\", { class: \"wcs-kpi-sub\", text: sub }) : null]);\n    }\n    function paramsList(rows) {\n      var dl = h(\"dl\", { class: \"wcs-params\" });\n      rows.forEach(function (p) { dl.appendChild(h(\"div\", {}, [h(\"dt\", { text: p[0] }), h(\"dd\", { text: p[1] })])); });\n      return dl;\n    }\n    function notesList(warn) {\n      var ul = h(\"ul\", { class: \"wcs-notes\" });\n      warn.forEach(function (w) {\n        var tag = w.lvl === \"e\" ? \"Critical: \" : (w.lvl === \"w\" ? \"Warning: \" : \"Note: \");\n        ul.appendChild(h(\"li\", { class: w.lvl === \"e\" ? \"wcs-n-e\" : (w.lvl === \"w\" ? \"wcs-n-w\" : \"\") }, [h(\"strong\", { text: tag }), w.text]));\n      });\n      return ul;\n    }\n    function stepLines(r) {\n      var f = FORM[r.id], L = [f.eq];\n      r.terms.forEach(function (t) {\n        var vin = fin(t.v) + (t.assumed ? \" (assumed 0)\" : \"\");\n        var expr = t.txt === \"C\" ? \"C = \" + vin : (t.mult !== 1 ? t.mult + \" \u00d7 \" + vin : vin + \" \/ \" + t.div);\n        L.push(t.txt === \"C\" ? expr + \" \u2192 \" + fx(t.c, 4) : t.txt + \" = \" + expr + \" = \" + fx(t.c, 4));\n      });\n      L.push(f.short + \" = \" + r.terms.map(function (t) { return fx(t.c, 4); }).join(\" + \") + \" = \" + fx(r.value, 4) + \" \u2248 \" + fx(r.value, 3) + \"%\");\n      return L;\n    }\n    function stepsBlock(title, lines, open) {\n      var det = h(\"details\", { class: \"wcs-det\" }, [h(\"summary\", { text: title })]);\n      if (open) { det.open = true; }\n      var ol = h(\"ol\", { class: \"wcs-steps\" });\n      lines.forEach(function (t, i) { ol.appendChild(h(\"li\", { class: i === lines.length - 1 ? \"wcs-step-total\" : \"\", text: t })); });\n      det.appendChild(h(\"div\", { class: \"wcs-det-body\" }, ol));\n      return det;\n    }\n    function compTable(L) {\n      var d = L.d, res = L.res;\n      function contrib(fid, k) {\n        var r = res[fid];\n        if (!r.ok) { return \"\u2014\"; }\n        var t = r.terms.filter(function (x) { return x.k === k; })[0];\n        return t ? fx(t.c, 4) : \"n\/a\";\n      }\n      var tb = h(\"tbody\");\n      ELEMS.forEach(function (k) {\n        var v = d.val[k], ent;\n        if (d.err[k]) { ent = \"Invalid\"; }\n        else if (v === null) { ent = d.zero ? \"Blank (0 assumed)\" : \"Not entered\"; }\n        else { ent = fin(v) + (k === \"B\" ? \" (\" + fin(v * 10000) + \" ppm)\" : \"\"); }\n        tb.appendChild(h(\"tr\", {}, [h(\"td\", { text: ENAME[k] + \" (\" + k + \")\" }), h(\"td\", { text: ent }), h(\"td\", { text: contrib(\"cev\", k) }), h(\"td\", { text: contrib(\"pcm\", k) })]));\n      });\n      var tf = h(\"tfoot\", {}, h(\"tr\", {}, [h(\"td\", { text: \"Total\" }), h(\"td\", { text: fx(totalComp(d), 4) }), h(\"td\", { text: res.cev.ok ? fx(res.cev.value, 4) : \"\u2014\" }), h(\"td\", { text: res.pcm.ok ? fx(res.pcm.value, 4) : \"\u2014\" })]));\n      var th = h(\"thead\", {}, h(\"tr\", {}, [h(\"th\", { text: \"Element\" }), h(\"th\", { text: \"Entered (wt.%)\" }), h(\"th\", { text: \"CEV term\" }), h(\"th\", { text: \"Pcm term\" })]));\n      return h(\"div\", { class: \"wcs-tablewrap\" }, h(\"table\", { class: \"wcs-table\" }, [th, tb, tf]));\n    }\n    function totalComp(d) { var s = 0; ELEMS.forEach(function (k) { if (d.val[k] !== null) { s += d.val[k]; } }); return s; }\n    function interpretation(L) {\n      var res = L.res, heat = L.heat, fac = L.fac, P = [];\n      if (res.cev.ok) { P.push(\"IIW CEV = \" + fx(res.cev.value, 3) + \"%. \" + fac.F.hard.judg.split(\" Higher\")[0]); }\n      else { P.push(\"IIW CEV was not calculated: \" + res.cev.reason); }\n      if (res.pcm.ok) { P.push(\"Pcm = \" + fx(res.pcm.value, 3) + \"%. Pcm gives carbon a larger relative weight and includes boron. It is a composition-based crack susceptibility index, not a probability of cracking, and no universal threshold is applied.\"); }\n      if (heat.status === \"ok\") { P.push(\"Net heat input Q = \" + fx(heat.net, 2) + \" kJ\/mm\" + (heat.arc !== null ? \" (arc energy \" + fx(heat.arc, 2) + \" kJ\/mm, \u03b7 = \" + fin(heat.eta) + \")\" : \"\") + \". Its effect on cooling depends on thickness, joint type, preheat and process.\"); }\n      P.push(\"Screening outcome: \" + OUT[fac.outcome].t + \". \" + fac.why + \" This is a preliminary engineering screening outcome, not a validated failure probability or an acceptance category, and it does not state that the weld is safe or unsafe. Neither CEV nor Pcm alone establishes an acceptable welding procedure.\");\n      return P;\n    }\n    function renderResults() {\n      var L = state.last, body = q(\"wcs-res-body\");\n      clear(body);\n      if (!L) { body.appendChild(h(\"p\", { class: \"wcs-placeholder\", html: \"Enter the composition and welding conditions, then press <strong>Calculate<\/strong>.\" })); return; }\n      var d = L.d, res = L.res, heat = L.heat, fac = L.fac, F = fac.F, o = OUT[fac.outcome];\n      \/* banner *\/\n      body.appendChild(h(\"div\", { class: \"wcs-banner\" }, [\n        h(\"strong\", { class: \"wcs-banner-t\", text: BANNER }),\n        h(\"div\", { class: \"wcs-banner-row\" }, [h(\"span\", { class: \"wcs-banner-k\", text: \"Preliminary hydrogen cracking screening:\" }), h(\"span\", { class: \"wcs-chip \" + o.c, text: o.t })]),\n        h(\"p\", { text: fac.why })\n      ]));\n      \/* primary results *\/\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\" }, [\"Primary results\", h(\"small\", { text: \"calculated and entered values\" })]));\n      body.appendChild(h(\"div\", { class: \"wcs-kpis\" }, [\n        res.cev.ok ? kpi(\"IIW Carbon Equivalent (CEV)\", fx(res.cev.value, 3) + \"%\", \"Mode A \u00b7 C + Mn\/6 + (Cr+Mo+V)\/5 + (Ni+Cu)\/15\", false, true) : kpi(\"IIW Carbon Equivalent (CEV)\", \"Not calculated\", res.cev.reason, true, true),\n        res.pcm.ok ? kpi(\"Pcm Crack Susceptibility Index\", fx(res.pcm.value, 3) + \"%\", \"Mode B \u00b7 composition index, not a probability\", false, true) : kpi(\"Pcm Crack Susceptibility Index\", \"Not calculated\", res.pcm.reason, true, true),\n        heat.status === \"ok\" ? kpi(\"Net welding heat input Q\", fx(heat.net, 2) + \" kJ\/mm\", heat.arc !== null ? \"Arc energy E = \" + fx(heat.arc, 2) + \" kJ\/mm, \u03b7 = \" + fin(heat.eta) : \"Entered as net heat input\") : (heat.status === \"arc\" ? kpi(\"Net welding heat input Q\", \"Not determined\", \"Arc energy E = \" + fx(heat.arc, 2) + \" kJ\/mm; select \u03b7 for net heat input\", true) : kpi(\"Net welding heat input Q\", \"Not available\", heat.reason, true)),\n        d.hd !== null ? kpi(\"Diffusible hydrogen\", fin(d.hd) + \" mL\/100 g\", (d.hdSrc === \"designator\" ? \"Designator \" + d.hdcat + \" maximum \u00b7 \" : \"\") + \"EN 1011-2 scale \" + hdScale(d.hd)) : kpi(\"Diffusible hydrogen\", \"Not entered\", \"\", true),\n        d.tmm !== null ? kpi(\"Plate thickness\", fin(Number(d.tmm.toFixed(2))) + \" mm\", fx(d.tmm \/ 25.4, 3) + \" in\") : kpi(\"Plate thickness\", \"Not entered\", \"\", true),\n        d.restr ? kpi(\"Joint restraint category\", RESTR[d.restr], \"Descriptive category\") : kpi(\"Joint restraint category\", \"Not selected\", \"\", true),\n        d.pre !== null ? kpi(\"Preheat temperature\", fx(d.pre, 0) + \" \u00b0C \/ \" + fx(cToF(d.pre), 0) + \" \u00b0F\", \"Ambient: \" + (d.amb !== null ? fx(d.amb, 0) + \" \u00b0C \/ \" + fx(cToF(d.amb), 0) + \" \u00b0F\" : \"not entered\")) : kpi(\"Preheat temperature\", \"Not entered\", \"Ambient: \" + (d.amb !== null ? fx(d.amb, 0) + \" \u00b0C \/ \" + fx(cToF(d.amb), 0) + \" \u00b0F\" : \"not entered\"), true),\n        kpi(\"Preliminary hydrogen cracking assessment\", o.t, \"Screening outcome, not a probability\", fac.outcome === \"insufficient\")\n      ]));\n      \/* qualitative observations *\/\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\" }, [\"Identified risk factors\", h(\"small\", { text: \"qualitative observations\" })]));\n      var list = h(\"div\", { class: \"wcs-facs\" });\n      [\"hard\", \"hyd\", \"thk\", \"heat\", \"res\", \"pre\"].forEach(function (k) {\n        var f = F[k];\n        list.appendChild(h(\"div\", { class: \"wcs-fac\" }, [\n          h(\"div\", { class: \"wcs-fac-h\" }, [h(\"span\", { class: \"wcs-fac-n\", text: f.name }), chip(f.lvl)]),\n          h(\"p\", { class: \"wcs-fac-o\" }, [h(\"b\", { text: \"Input\" }), f.obs]),\n          h(\"p\", { class: \"wcs-fac-j\" }, [h(\"b\", { text: \"Judgment\" }), f.judg]),\n          h(\"p\", { class: \"wcs-fac-b\", text: f.basis })\n        ]));\n      });\n      body.appendChild(list);\n      \/* interpretation *\/\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Engineering interpretation\" }));\n      body.appendChild(h(\"div\", { class: \"wcs-interp\" }, interpretation(L).map(function (t) { return h(\"p\", { text: t }); })));\n      \/* recommendations *\/\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Suggested follow-up assessments\" }));\n      body.appendChild(h(\"ul\", { class: \"wcs-recs\" }, L.recs.map(function (t) { return h(\"li\", { text: t }); })));\n      \/* secondary results *\/\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\" }, [\"Data completeness\", h(\"small\", { text: L.comp.n + \" of \" + L.comp.total + \" inputs\" })]));\n      body.appendChild(paramsList(L.comp.rows.map(function (r) { return [r[0], (r[1].ok ? \"\u2713 \" : \"\u2717 \") + r[1].t]; })));\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Chemical composition summary\" }));\n      body.appendChild(compTable(L));\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Calculation steps\" }));\n      if (res.cev.ok) { body.appendChild(stepsBlock(FORM.cev.name, stepLines(res.cev), true)); }\n      if (res.pcm.ok) {\n        var pl = stepLines(res.pcm);\n        if (d.bUnit === \"ppm\" ? d.val.B !== null : false) { pl.splice(1, 0, \"B = \" + fin(d.bRaw) + \" ppm \u00f7 10,000 = \" + fin(d.val.B) + \" wt.%\"); }\n        body.appendChild(stepsBlock(FORM.pcm.name, pl, false));\n      }\n      if (heat.steps.length) { body.appendChild(stepsBlock(\"Welding heat input\", heat.steps.concat([heat.status === \"ok\" ? \"Net heat input Q = \" + fx(heat.net, 3) + \" kJ\/mm\" : \"Net heat input not determined\"]), false)); }\n      if (!res.cev.ok ? (!res.pcm.ok ? !heat.steps.length : false) : false) { body.appendChild(h(\"p\", { class: \"wcs-placeholder\", text: \"No quantity could be calculated with the current inputs.\" })); }\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Relevant engineering assumptions\" }));\n      body.appendChild(h(\"ul\", { class: \"wcs-recs\" }, ASSUMPTIONS.map(function (t) { return h(\"li\", { text: t }); })));\n      body.appendChild(h(\"h3\", { class: \"wcs-sec\", text: \"Engineering notes and limitations\" }));\n      body.appendChild(notesList(L.notes));\n    }\n    \/* =====================================================================\n       RUN\n       ===================================================================== *\/\n    function run(fromButton) {\n      var d = readAll();\n      clearErrors();\n      Object.keys(d.err).forEach(function (k) { setErr(k, d.err[k]); });\n      if (fromButton) { msg(\"\"); }\n      var res = { cev: compute(\"cev\", d), pcm: compute(\"pcm\", d) };\n      var heat = computeHeat(d);\n      \/* field-level messages for missing data *\/\n      var need = {};\n      [\"cev\", \"pcm\"].forEach(function (id) {\n        res[id].hard.forEach(function (k) { need[k] = need[k] ? need[k] : { hard: true, f: [] }; need[k].f.push(FORM[id].short); });\n        res[id].missing.forEach(function (k) { need[k] = need[k] ? need[k] : { hard: false, f: [] }; need[k].f.push(FORM[id].short); });\n      });\n      Object.keys(need).forEach(function (k) {\n        var n = need[k];\n        setErr(k, n.hard ? ENAME[k] + \" must be entered. It is never assumed to be zero.\" : \"Required for \" + n.f.join(\" and \") + \". Enter a value, or tick the option to treat blanks as zero.\");\n      });\n      if (heat.status === \"partial\") { heat.missing.forEach(function (k) { setErr(k, \"Required to calculate heat input.\"); }); }\n      if (heat.status === \"arc\") { if (d.proc === \"custom\") { if (!d.err.eta) { setErr(\"eta\", \"Enter a justified \u03b7 to obtain net heat input.\"); } } else { setErr(\"proc\", \"Select the welding process (or a custom \u03b7) to obtain net heat input.\"); } }\n      var fac = buildFactors(d, res, heat);\n      if (fromButton) {\n        if (d.tmm === null ? !d.err.t : false) { setErr(\"t\", \"Required for the screening outcome.\"); }\n        if (d.hd === null ? !d.err.hd : false) { setErr(\"hd\", \"Required for the screening outcome. Enter a value or select a designator.\"); }\n        if (!d.restr) { setErr(\"restr\", \"Required for the screening outcome.\"); }\n      }\n      state.last = { d: d, res: res, heat: heat, fac: fac, notes: buildNotes(d, res, heat), recs: buildRecs(d, res, heat, fac), comp: buildCompleteness(d, res, heat) };\n      state.live = true;\n      if (fromButton) { q(\"wcs-results\").hidden = false; }\n      renderResults();\n      if (fromButton) {\n        var errs = Object.keys(d.err).length;\n        if (errs) { msg(\"Some inputs are invalid. See the highlighted fields.\"); }\n        else if (fac.outcome === \"insufficient\") { msg(\"Calculated what the inputs allow. Some data are missing for a screening outcome.\"); }\n        else { msg(\"Assessment updated.\", true); }\n        scrollToResults();\n      }\n    }\n    function scrollToResults() {\n      var el = q(\"wcs-results\");\n      var rect = el.getBoundingClientRect(), vh = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight;\n      if (rect.top < 0 ? true : rect.top > vh * 0.6) { if (el.scrollIntoView) { el.scrollIntoView({ behavior: \"smooth\", block: \"start\" }); } }\n      try { el.focus({ preventScroll: true }); } catch (e) { \/* ignore *\/ }\n    }\n    function scheduleLive() {\n      if (!state.live) { return; }\n      if (state.timer) { clearTimeout(state.timer); }\n      state.timer = setTimeout(function () { state.timer = null; run(false); }, 180);\n    }\n    var DEFAULT_SEL = { \"wcs-Bunit\": \"wt\", \"wcs-tunit\": \"mm\", \"wcs-spdunit\": \"mmmin\", \"wcs-hqunit\": \"kjmm\", \"wcs-preunit\": \"C\", \"wcs-ambunit\": \"C\", \"wcs-hmode\": \"calc\", \"wcs-hqtype\": \"net\", \"wcs-proc\": \"\", \"wcs-restr\": \"\", \"wcs-hdcat\": \"\", \"wcs-material\": \"custom\" };\n    var INPUTS = [\"wcs-C\", \"wcs-Si\", \"wcs-Mn\", \"wcs-Cr\", \"wcs-Ni\", \"wcs-Mo\", \"wcs-V\", \"wcs-Cu\", \"wcs-B\", \"wcs-t\", \"wcs-hd\", \"wcs-amp\", \"wcs-volt\", \"wcs-spd\", \"wcs-hq\", \"wcs-eta\", \"wcs-pre\", \"wcs-amb\"];\n    function setDefaults() {\n      INPUTS.forEach(function (id) { q(id).value = \"\"; });\n      Object.keys(DEFAULT_SEL).forEach(function (id) { var e = q(id); e.value = DEFAULT_SEL[id]; if (e.hasAttribute(\"data-prev\")) { e.setAttribute(\"data-prev\", DEFAULT_SEL[id]); } });\n      q(\"wcs-zero\").checked = false;\n    }\n    function resetAll() {\n      setDefaults();\n      if (state.timer) { clearTimeout(state.timer); state.timer = null; }\n      state.last = null; state.live = false;\n      clearErrors(); msg(\"\");\n      updateBHint(); updateMaterialInfo(); updateVisibility();\n      renderResults();\n      q(\"wcs-results\").hidden = true;\n    }\n    \/* =====================================================================\n       EVENTS (bound once)\n       ===================================================================== *\/\n    var form = q(\"wcs-form\");\n    form.addEventListener(\"input\", function (e) {\n      var t = e.target;\n      if (t ? t.id === \"wcs-B\" : false) { updateBHint(); }\n      if (t ? t.tagName === \"INPUT\" : false) { if (t.type === \"number\") { scheduleLive(); } }\n    });\n    form.addEventListener(\"change\", function (e) {\n      var t = e.target;\n      if (!t) { return; }\n      if (CONV[t.id]) { onUnitChange(t); }\n      if (t.id === \"wcs-Bunit\") { q(\"wcs-B\").placeholder = t.value === \"ppm\" ? \"e.g. 5\" : \"e.g. 0.0005\"; updateBHint(); }\n      if (t.id === \"wcs-material\") { updateMaterialInfo(); }\n      if (t.id === \"wcs-hmode\" ? true : (t.id === \"wcs-proc\" ? true : t.id === \"wcs-hqtype\")) { updateVisibility(); }\n      if (t.tagName === \"SELECT\" ? true : t.type === \"checkbox\") { scheduleLive(); }\n    });\n    form.addEventListener(\"keydown\", function (e) {\n      if (e.key === \"Enter\" ? (e.target ? e.target.tagName === \"INPUT\" : false) : false) { e.preventDefault(); run(true); }\n    });\n    q(\"wcs-calc\").addEventListener(\"click\", function () { run(true); });\n    root.wcsEngine = { compute: compute, computeHeat: computeHeat, buildFactors: buildFactors, FORM: FORM };\n    resetAll();\n  }\n  if (document.getElementById(\"wcs-calculator\")) { init(); }\n  else if (document.readyState === \"loading\") { document.addEventListener(\"DOMContentLoaded\", init); }\n  else { init(); }\n})();\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Weld Cracking Susceptibility Assessment Calculator is a practical engineering tool designed to evaluate the potential risk of hydrogen-assisted cold cracking in steel welding applications&#8230;.<\/p>","protected":false},"author":2,"featured_media":24978,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pmpro_default_level":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-24977","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","pmpro-has-access"],"acf":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/www.mechstream.com\/wp-content\/uploads\/2026\/10\/Weld-Cracking-Susceptibility-Assessment-Calculator.png","_links":{"self":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24977","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/comments?post=24977"}],"version-history":[{"count":1,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24977\/revisions"}],"predecessor-version":[{"id":24979,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/posts\/24977\/revisions\/24979"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/media\/24978"}],"wp:attachment":[{"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/media?parent=24977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/categories?post=24977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mechstream.com\/fr\/wp-json\/wp\/v2\/tags?post=24977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}