{"id":415,"date":"2025-08-26T16:40:21","date_gmt":"2025-08-26T16:40:21","guid":{"rendered":"https:\/\/tomchan.hk\/?page_id=415"},"modified":"2025-08-26T18:16:25","modified_gmt":"2025-08-26T18:16:25","slug":"neonatal-bp","status":"publish","type":"page","link":"https:\/\/tomchan.hk\/?page_id=415","title":{"rendered":"Neonatal BP"},"content":{"rendered":"<!-- Neonatal BP Calculator & Percentile Charts (WordPress-ready) -->\r\n<!-- Paste this into a WordPress HTML block or a shortcode that allows raw HTML\/JS. -->\r\n<div id=\"neo-bp-app\" class=\"neo-bp\">\r\n  <style>\r\n    .neo-bp { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\"; }\r\n    .neo-bp .card { background:#fff; border:1px solid #ebeae7; box-shadow:0 2px 10px rgba(0,0,0,.05); border-radius:14px; padding:16px; margin:10px 0; }\r\n    .neo-bp h2 { font-size:18px; margin:0 0 8px; color:#177e94; }\r\n    .neo-bp .row { display:flex; flex-wrap:wrap; gap:12px; }\r\n    .neo-bp .field { flex:1 1 160px; min-width:160px; }\r\n    .neo-bp label { display:block; font-size:12px; color:#333; margin-bottom:6px; }\r\n    .neo-bp select, .neo-bp input { width:100%; padding:9px 10px; border-radius:10px; border:1px solid #badbce; outline:none; }\r\n    .neo-bp .note { font-size:12px; color:#555; background:#f9fafb; border:1px dashed #cfc398; padding:8px; border-radius:10px; }\r\n    .neo-bp .charts { display:grid; grid-template-columns:1fr; gap:14px; }\r\n    @media (min-width: 980px) { .neo-bp .charts { grid-template-columns:1fr 1fr; } }\r\n    .chart-wrap { position: relative; width: 100%; aspect-ratio: 16 \/ 9; background:#fff; border:1px solid #ebeae7; border-radius:14px; padding:8px; }\r\n    .legend-chip { display:inline-flex; align-items:center; gap:6px; margin-right:10px; font-size:12px; }\r\n    .chip { width:12px; height:12px; display:inline-block; border-radius:3px; }\r\n    .ref { font-size:12px; color:#444; }\r\n    .summary { font-size:14px; color:#222; }\r\n    .muted { color:#666; }\r\n\r\n    \/* Tiny badge for MAP mode *\/\r\n    .map-badge {\r\n      position:absolute; top:10px; left:10px;\r\n      font-size:11px; line-height:1; padding:6px 8px;\r\n      border-radius:999px; border:1px solid #ebeae7;\r\n      background:#f9fafb; color:#333;\r\n      box-shadow:0 1px 3px rgba(0,0,0,.06);\r\n      pointer-events:none; user-select:none;\r\n    }\r\n    .map-badge.auto { background:#eef8f3; border-color:#badbce; }\r\n    .map-badge.manual { background:#fff7e6; border-color:#f0d38a; }\r\n  <\/style>\r\n\r\n  <div class=\"card\">\r\n    <h2>Neonatal Blood Pressure Calculator<\/h2>\r\n    <div class=\"row\">\r\n      <div class=\"field\">\r\n        <label for=\"ga\">Gestational age at birth (weeks)<\/label>\r\n        <select id=\"ga\"><\/select>\r\n      <\/div>\r\n      <div class=\"field\">\r\n        <label for=\"dol\">Day of life (0\u201330)<\/label>\r\n        <select id=\"dol\"><\/select>\r\n      <\/div>\r\n      <div class=\"field\">\r\n        <label for=\"sbp\">Patient SBP (mmHg)<\/label>\r\n        <input id=\"sbp\" type=\"number\" inputmode=\"decimal\" placeholder=\"e.g., 52\" \/>\r\n      <\/div>\r\n      <div class=\"field\">\r\n        <label for=\"dbp\">Patient DBP (mmHg)<\/label>\r\n        <input id=\"dbp\" type=\"number\" inputmode=\"decimal\" placeholder=\"e.g., 34\" \/>\r\n      <\/div>\r\n      <div class=\"field\">\r\n        <label for=\"map\">Patient MAP (mmHg)<\/label>\r\n        <input id=\"map\" type=\"number\" inputmode=\"decimal\" placeholder=\"auto if left blank\" \/>\r\n      <\/div>\r\n    <\/div>\r\n    <div id=\"context-note\" class=\"note\" style=\"margin-top:10px; display:none;\"><\/div>\r\n    <div style=\"margin-top:8px; font-size:12px; color:#666;\">\r\n      Color key:\r\n      <span class=\"legend-chip\"><span class=\"chip\" style=\"background:#be594a\"><\/span>95th<\/span>\r\n      <span class=\"legend-chip\"><span class=\"chip\" style=\"background:#177e94\"><\/span>Mean<\/span>\r\n      <span class=\"legend-chip\"><span class=\"chip\" style=\"background:#87b4bd\"><\/span>5th<\/span>\r\n      <span class=\"legend-chip\"><span class=\"chip\" style=\"background:#f1e207\"><\/span>Patient<\/span>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"charts\">\r\n    <div class=\"chart-wrap\"><canvas id=\"chart-sbp\"><\/canvas><\/div>\r\n    <div class=\"chart-wrap\"><canvas id=\"chart-dbp\"><\/canvas><\/div>\r\n\r\n    <!-- MAP chart with badge -->\r\n    <div class=\"chart-wrap\" id=\"map-wrap\">\r\n      <canvas id=\"chart-map\"><\/canvas>\r\n      <div id=\"map-badge\" class=\"map-badge auto\">MAP: auto<\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"card\">\r\n    <h2>Summary<\/h2>\r\n    <div id=\"summary\" class=\"summary\">Adjust an input to see the summary\u2026<\/div>\r\n    <div class=\"ref\" style=\"margin-top:8px\">\r\n      Sources: Preterm Day-1 and corrected PCA curves extracted from Zubrow AB, Hulman S, Kushner H, et al. Philadelphia Neonatal Blood Pressure Study Group. <em>J Perinatol<\/em> 1995;15(6):470\u2013479. Full-term days 0\u20134 combine Zubrow Day-1 (for day 0 anchor) and days 1\u20134 from Allison Kent, Zsuzsoka Kecskes, Bruce Shadbolt, Michale Falk, et al. <em>Pediatr Nephrol<\/em> 2007;22:1335\u20131341 (table on p. 1337).\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.1\/dist\/chart.umd.min.js\"><\/script>\r\n<script>\r\n(function(){\r\n  \/\/ Color palette\r\n  const COLORS = {\r\n    mean: '#177e94',\r\n    p95: '#be594a',\r\n    p5: '#87b4bd',\r\n    patient: '#f1e207',\r\n    grid: '#ebeae7',\r\n    soft1: '#badbce',\r\n    soft2: '#cfc398'\r\n  };\r\n  const BAND_ALPHA = 0.18; \/\/ fill opacity for 5th\u201395th band\r\n\r\n  \/\/ ===== Data =====\r\n  const T1_WEEKS = [22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42];\r\n  const T1 = {\r\n    SBP: { p95:[55,56,57,58,60,61,63,64,66,68,69,70,71,73,75,76,77,79,81,82,84],\r\n           mean:[39,40,42,43,44,45,47,48,50,51,52,53,55,57,59,60,61,62,64,65,67],\r\n           p5:[22,23,25,26,27,29,31,33,35,36,37,38,40,41,42,44,46,47,48,50,51] },\r\n    DBP: { p95:[31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],\r\n           mean:[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],\r\n           p5:[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34] },\r\n    MAP: { p95:[39,40,41,42,43,44,46,47,48,49,50,51,52,54,55,56,57,58,60,61,62],\r\n           mean:[28,29,31,32,33,34,35,36,37,38,39,40,42,43,44,45,46,47,49,50,51],\r\n           p5:[17,18,19,20,21,22,24,25,26,27,28,29,31,32,33,34,35,36,37,39,40] }\r\n  };\r\n\r\n  const T2_WEEKS = [24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46];\r\n  const T2 = {\r\n    SBP: { p95:[68,69,70,71,72,73,75,78,80,81,83,84,87,89,90,91,92,93,95,97,98,100,102],\r\n           mean:[49,51,52,54,55,56,59,61,62,63,66,69,71,72,75,78,80,81,82,83,86,88,89],\r\n           p5:[33,36,38,40,41,42,43,46,48,50,51,52,55,57,59,60,61,62,63,65,67,69,71] },\r\n    DBP: { p95:[46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,60,61,62,63,64,65,66,66],\r\n           mean:[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,44,46,47,48,49,50,51],\r\n           p5:[14,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,30,31,32,33,34,35,36] },\r\n    MAP: { p95:[53,54,55,56,57,58,60,61,63,64,65,66,68,69,70,70,71,72,74,75,76,77,78],\r\n           mean:[36,37,38,39,40,41,43,44,45,46,48,50,51,52,54,55,56,58,59,60,61,63,64],\r\n           p5:[20,22,24,25,26,27,28,30,31,33,34,35,36,38,39,40,40,41,42,44,45,46,48] }\r\n  };\r\n\r\n  const TERM_DAYS = [1,2,3,4];\r\n  const TERM = {\r\n    SBP: { p95:[77,83,85,86], mean:[65,68,69,70], p5:[53,56,58,60] },\r\n    DBP: { p95:[50,52,53,54], mean:[40,41,42,43], p5:[30,31,32,33] },\r\n    MAP: { p95:[57,58,60,60], mean:[48,51,52,53], p5:[38,38,39,40] }\r\n  };\r\n\r\n  \/\/ ===== Helpers =====\r\n  const $ = (id) => document.getElementById(id);\r\n  const rgba = (hex, a) => {\r\n    const h = hex.replace('#','');\r\n    const bigint = parseInt(h, 16);\r\n    const r = (bigint >> 16) & 255;\r\n    const g = (bigint >> 8) & 255;\r\n    const b = bigint & 255;\r\n    return `rgba(${r},${g},${b},${a})`;\r\n  };\r\n\r\n  function fillSelect(el, start, end){\r\n    el.innerHTML = '';\r\n    for(let v=start; v<=end; v++){\r\n      const opt = document.createElement('option');\r\n      opt.value = v; opt.textContent = v;\r\n      el.appendChild(opt);\r\n    }\r\n  }\r\n\r\n  function makeLinePoints(xs, ys){\r\n    return xs.map((x,i) => ({x, y: ys[i]}));\r\n  }\r\n\r\n  function buildPretermD1Datasets(metric){\r\n    const xs = T1_WEEKS;\r\n    return {\r\n      xLabel: 'Gestational age at birth (weeks) \u2014 Zubrow 1995',\r\n      xMin: 22, xMax: 42,\r\n      datasets: [\r\n        {label:'95th', data: makeLinePoints(xs, T1[metric].p95), borderColor: COLORS.p95, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:false, tension:.25, pointRadius:0, pointHoverRadius:0},\r\n        {label:'5th', data: makeLinePoints(xs, T1[metric].p5), borderColor: COLORS.p5, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:'-1', tension:.25, pointRadius:0, pointHoverRadius:0},\r\n        {label:'Mean', data: makeLinePoints(xs, T1[metric].mean), borderColor: COLORS.mean, backgroundColor: COLORS.mean, fill:false, tension:.25, pointRadius:0, pointHoverRadius:0}\r\n      ]\r\n    };\r\n  }\r\n\r\n  function buildPretermPCADatasets(metric){\r\n    const xs = T2_WEEKS;\r\n    return {\r\n      xLabel: 'Corrected post-conceptional age (weeks) \u2014 Zubrow 1995',\r\n      xMin: 24, xMax: 46,\r\n      datasets: [\r\n        {label:'95th', data: makeLinePoints(xs, T2[metric].p95), borderColor: COLORS.p95, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:false, tension:.25, pointRadius:0, pointHoverRadius:0},\r\n        {label:'5th', data: makeLinePoints(xs, T2[metric].p5), borderColor: COLORS.p5, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:'-1', tension:.25, pointRadius:0, pointHoverRadius:0},\r\n        {label:'Mean', data: makeLinePoints(xs, T2[metric].mean), borderColor: COLORS.mean, backgroundColor: COLORS.mean, fill:false, tension:.25, pointRadius:0, pointHoverRadius:0}\r\n      ]\r\n    };\r\n  }\r\n\r\n  function buildTermDatasets(metric, ga){\r\n    const gaClamped = Math.max(37, Math.min(42, ga));\r\n    const idx = T1_WEEKS.indexOf(gaClamped);\r\n    const day0 = {\r\n      p95: T1[metric].p95[idx],\r\n      mean: T1[metric].mean[idx],\r\n      p5: T1[metric].p5[idx]\r\n    };\r\n    const xs = [0, ...TERM_DAYS];\r\n    const series = {\r\n      p95: [day0.p95, ...TERM[metric].p95],\r\n      mean: [day0.mean, ...TERM[metric].mean],\r\n      p5: [day0.p5, ...TERM[metric].p5]\r\n    };\r\n    return {\r\n      xLabel: 'Day of life \u2014 Day 0 from Zubrow 1995; Days 1\u20134 from Kent 2007',\r\n      xMin: 0, xMax: 4,\r\n      datasets: [\r\n        {label:'95th', data: makeLinePoints(xs, series.p95), borderColor: COLORS.p95, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:false, tension:.25, spanGaps:true, pointRadius:0, pointHoverRadius:0},\r\n        {label:'5th', data: makeLinePoints(xs, series.p5), borderColor: COLORS.p5, backgroundColor: rgba(COLORS.soft1, BAND_ALPHA), fill:'-1', tension:.25, spanGaps:true, pointRadius:0, pointHoverRadius:0},\r\n        {label:'Mean', data: makeLinePoints(xs, series.mean), borderColor: COLORS.mean, backgroundColor: COLORS.mean, fill:false, tension:.25, spanGaps:true, pointRadius:0, pointHoverRadius:0}\r\n      ]\r\n    };\r\n  }\r\n\r\n  function patientPointDataset(x, y){\r\n    if (y==null || isNaN(y)) return null;\r\n    return {\r\n      type: 'scatter',\r\n      label: 'Patient',\r\n      data: [{x: x, y: y}],\r\n      pointBackgroundColor: COLORS.patient,\r\n      pointBorderColor: '#333',\r\n      pointBorderWidth: 1,\r\n      pointRadius: 5,\r\n      showLine: false\r\n    };\r\n  }\r\n\r\n  \/\/ ===== Chart setup =====\r\n  const ctxSBP = $('chart-sbp').getContext('2d');\r\n  const ctxDBP = $('chart-dbp').getContext('2d');\r\n  const ctxMAP = $('chart-map').getContext('2d');\r\n\r\n  function makeChart(ctx, title){\r\n    return new Chart(ctx, {\r\n      type: 'line',\r\n      data: { datasets: [] },\r\n      options: {\r\n        responsive: true,\r\n        maintainAspectRatio: false,\r\n        interaction: { mode: 'nearest', intersect: false },\r\n        plugins: {\r\n          title: { display: true, text: title, color:'#177e94', font:{ size: 14, weight:'600' } },\r\n          legend: { position: 'bottom' }\r\n        },\r\n        scales: {\r\n          x: {\r\n            type: 'linear',\r\n            grid: { color: COLORS.grid },\r\n            title: { display: true, text: '' }\r\n          },\r\n          y: {\r\n            beginAtZero: false,\r\n            grid: { color: COLORS.grid },\r\n            title: { display: true, text: 'mmHg' }\r\n            \/\/ min\/max set dynamically\r\n          }\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  const chartSBP = makeChart(ctxSBP, 'Systolic BP (mmHg)');\r\n  const chartDBP = makeChart(ctxDBP, 'Diastolic BP (mmHg)');\r\n  const chartMAP = makeChart(ctxMAP, 'Mean Arterial Pressure (mmHg)');\r\n\r\n  function nearest(arr, x){\r\n    let bestIdx = 0, bestDiff = Infinity;\r\n    for (let i=0;i<arr.length;i++){\r\n      const d = Math.abs(arr[i]-x);\r\n      if (d < bestDiff){ bestDiff = d; bestIdx = i; }\r\n    }\r\n    return bestIdx;\r\n  }\r\n\r\n  function summarize(metricLabel, metric, mode, xValue, ga){\r\n    let p5, mean, p95, ref;\r\n    if (mode === 'term') {\r\n      if (xValue <= 0) {\r\n        const gaClamped = Math.max(37, Math.min(42, ga));\r\n        const iGA = T1_WEEKS.indexOf(gaClamped);\r\n        p5 = T1[metric].p5[iGA];\r\n        mean = T1[metric].mean[iGA];\r\n        p95 = T1[metric].p95[iGA];\r\n        ref = 'Zubrow 1995 (Day 0 via Day-1 GA curve)';\r\n      } else {\r\n        const i = nearest(TERM_DAYS, Math.max(1, Math.min(4, Math.round(xValue))));\r\n        p5 = TERM[metric].p5[i];\r\n        mean = TERM[metric].mean[i];\r\n        p95 = TERM[metric].p95[i];\r\n        ref = 'Kent 2007 (Days 1\u20134)';\r\n      }\r\n    } else if (mode === 'preterm-pca') {\r\n      const i = nearest(T2_WEEKS, Math.max(24, Math.min(46, Math.round(xValue))));\r\n      p5 = T2[metric].p5[i];\r\n      mean = T2[metric].mean[i];\r\n      p95 = T2[metric].p95[i];\r\n      ref = 'Zubrow 1995 (PCA)';\r\n    } else { \/\/ preterm-d1\r\n      const i = nearest(T1_WEEKS, Math.max(22, Math.min(42, Math.round(xValue))));\r\n      p5 = T1[metric].p5[i];\r\n      mean = T1[metric].mean[i];\r\n      p95 = T1[metric].p95[i];\r\n      ref = 'Zubrow 1995 (Day 1)';\r\n    }\r\n    return {p5, mean, p95, ref};\r\n  }\r\n\r\n  function whereIs(value, p5, mean, p95){\r\n    if (value==null || isNaN(value)) return '\u2014';\r\n    const v = Number(value);\r\n    if (v < p5) return 'below 5th percentile';\r\n    if (v === p5) return 'at the 5th percentile';\r\n    if (v > p5 && v < mean) return 'between 5th and mean';\r\n    if (v === mean) return 'at the mean';\r\n    if (v > mean && v < p95) return 'between mean and 95th';\r\n    if (v === p95) return 'at the 95th percentile';\r\n    return 'above 95th percentile';\r\n  }\r\n\r\n  function dynamicYScale(chart, datasets){\r\n    \/\/ Collect y-values from the reference curves and patient point\r\n    const ys = [];\r\n    datasets.forEach(ds => {\r\n      if (!ds || !ds.data) return;\r\n      ds.data.forEach(pt => {\r\n        if (pt && typeof pt.y === 'number' && isFinite(pt.y)) ys.push(pt.y);\r\n      });\r\n    });\r\n    if (ys.length === 0) return;\r\n    let ymin = Math.min(...ys);\r\n    let ymax = Math.max(...ys);\r\n    \/\/ Add margin (\u22652 mmHg, otherwise 8% of range) for space around 5th\/95th\r\n    const range = Math.max(1, ymax - ymin);\r\n    const margin = Math.max(2, range * 0.08);\r\n    ymin = Math.floor(ymin - margin);\r\n    ymax = Math.ceil(ymax + margin);\r\n    chart.options.scales.y.min = ymin;\r\n    chart.options.scales.y.max = ymax;\r\n  }\r\n\r\n  \/\/ ===== State for MAP manual\/auto tracking =====\r\n  let suppressMapListener = false; \/\/ prevents loop when we write to the input programmatically\r\n  const mapEl = $('map');\r\n  const mapBadge = $('map-badge');\r\n  mapEl.dataset.manual = '0'; \/\/ \"1\" once user types a value\r\n\r\n  mapEl.addEventListener('input', () => {\r\n    if (suppressMapListener) return;\r\n    mapEl.dataset.manual = mapEl.value.trim().length ? '1' : '0';\r\n    updateCharts(); \/\/ reflect badge & summary immediately\r\n  });\r\n\r\n  \/\/ ===== Main update =====\r\n  function updateCharts(){\r\n    const ga = parseInt($('ga').value, 10);\r\n    const dol = parseInt($('dol').value, 10);\r\n    const sbp = parseFloat($('sbp').value);\r\n    const dbp = parseFloat($('dbp').value);\r\n\r\n    \/\/ Auto-MAP unless user typed a value (manual mode)\r\n    const mapManual = mapEl.dataset.manual === '1';\r\n    let mapVal = parseFloat(mapEl.value);\r\n    let map;\r\n\r\n    if (mapManual && isFinite(mapVal)) {\r\n      map = mapVal; \/\/ user-entered MAP wins\r\n      mapBadge.textContent = 'MAP: manual';\r\n      mapBadge.classList.remove('auto');\r\n      mapBadge.classList.add('manual');\r\n    } else if (isFinite(sbp) && isFinite(dbp)) {\r\n      map = dbp + (sbp - dbp) \/ 3; \/\/ \u2248 (SBP + 2*DBP)\/3\r\n      suppressMapListener = true;\r\n      mapEl.value = Math.round(map * 10) \/ 10; \/\/ surface the auto value\r\n      mapEl.dataset.manual = '0';\r\n      suppressMapListener = false;\r\n      mapBadge.textContent = 'MAP: auto';\r\n      mapBadge.classList.remove('manual');\r\n      mapBadge.classList.add('auto');\r\n    } else {\r\n      map = NaN; \/\/ insufficient data\r\n      mapBadge.textContent = 'MAP: auto';\r\n      mapBadge.classList.remove('manual');\r\n      mapBadge.classList.add('auto');\r\n    }\r\n\r\n    \/\/ Context notes & mode routing\r\n    const note = $('context-note');\r\n    note.style.display = 'none';\r\n    note.textContent = '';\r\n\r\n    let mode = 'preterm-d1';\r\n    if (ga >= 37) {\r\n      mode = 'term';\r\n      if (dol > 4) {\r\n        note.style.display = 'block';\r\n        note.innerHTML = 'Full-term reference curves are available for days 0\u20134 only; your selection is beyond that range.';\r\n      }\r\n    } else {\r\n      mode = (dol > 1) ? 'preterm-pca' : 'preterm-d1';\r\n      if (mode === 'preterm-pca') {\r\n        const pcaExact = ga + (dol - 1) \/ 7; \/\/ weeks\r\n        const pcaRounded = Math.round(pcaExact);\r\n        if (pcaRounded < 24 || pcaRounded > 46) {\r\n          note.style.display = 'block';\r\n          note.innerHTML = 'For preterm infants with DOL > 1, corrected post-conceptional age (PCA) curves span 24\u201346 weeks. Your PCA is outside this range; curves will still render for the available range.';\r\n        }\r\n      }\r\n    }\r\n\r\n    function applyToChart(chart, metric, patientY){\r\n      let conf;\r\n      if (mode === 'term') conf = buildTermDatasets(metric, ga);\r\n      else if (mode === 'preterm-pca') conf = buildPretermPCADatasets(metric);\r\n      else conf = buildPretermD1Datasets(metric);\r\n\r\n      let patientX = null;\r\n      if (mode === 'term') patientX = Math.max(0, Math.min(4, dol)); \/\/ x = day of life (0\u20134 shown)\r\n      else if (mode === 'preterm-pca') patientX = ga + (dol - 1) \/ 7; \/\/ PCA in weeks\r\n      else patientX = ga; \/\/ Day 1 preterm: x = GA at birth\r\n\r\n      const ds = [...conf.datasets];\r\n      const patientDS = patientPointDataset(patientX, patientY);\r\n      if (patientDS) ds.push(patientDS);\r\n\r\n      chart.data.datasets = ds;\r\n      chart.options.scales.x.title.text = conf.xLabel;\r\n      chart.options.scales.x.min = conf.xMin;\r\n      chart.options.scales.x.max = conf.xMax;\r\n\r\n      \/\/ Dynamic Y scaling with headroom\/footroom around 5th\/95th (and patient)\r\n      dynamicYScale(chart, ds);\r\n\r\n      chart.update();\r\n    }\r\n\r\n    applyToChart(chartSBP, 'SBP', isFinite(sbp) ? sbp : null);\r\n    applyToChart(chartDBP, 'DBP', isFinite(dbp) ? dbp : null);\r\n    applyToChart(chartMAP, 'MAP', isFinite(map) ? map : null);\r\n\r\n    \/\/ ===== Summary =====\r\n    let xForSummary;\r\n    if (mode === 'term') xForSummary = dol;\r\n    else if (mode === 'preterm-pca') xForSummary = ga + (dol - 1)\/7;\r\n    else xForSummary = ga;\r\n\r\n    const sSBP = summarize('SBP','SBP',mode,xForSummary,ga);\r\n    const sDBP = summarize('DBP','DBP',mode,xForSummary,ga);\r\n    const sMAP = summarize('MAP','MAP',mode,xForSummary,ga);\r\n\r\n    const posSBP = whereIs(sbp, sSBP.p5, sSBP.mean, sSBP.p95);\r\n    const posDBP = whereIs(dbp, sDBP.p5, sDBP.mean, sDBP.p95);\r\n    const posMAP = whereIs(map, sMAP.p5, sMAP.mean, sMAP.p95);\r\n\r\n    const refUsed = (mode==='term') ? 'Full-term (Day 0 from Zubrow 1995; Days 1\u20134 from Kent 2007)' : (mode==='preterm-pca' ? 'Preterm PCA (Zubrow 1995)' : 'Preterm Day 1 (Zubrow 1995)');\r\n\r\n    $('summary').innerHTML = `\r\n      <div><strong>Reference used:<\/strong> ${refUsed}<\/div>\r\n      <div class=\"muted\" style=\"margin:6px 0 10px\">Shown values are nearest published percentiles to your selection.<\/div>\r\n      <table style=\"width:100%; border-collapse:collapse; font-size:13px\">\r\n        <thead>\r\n          <tr>\r\n            <th style=\"text-align:left; padding:6px 4px; border-bottom:1px solid #ebeae7\">Metric<\/th>\r\n            <th style=\"text-align:left; padding:6px 4px; border-bottom:1px solid #ebeae7\">5th<\/th>\r\n            <th style=\"text-align:left; padding:6px 4px; border-bottom:1px solid #ebeae7\">Mean<\/th>\r\n            <th style=\"text-align:left; padding:6px 4px; border-bottom:1px solid #ebeae7\">95th<\/th>\r\n            <th style=\"text-align:left; padding:6px 4px; border-bottom:1px solid #ebeae7\">Patient position<\/th>\r\n          <\/tr>\r\n        <\/thead>\r\n        <tbody>\r\n          <tr>\r\n            <td style=\"padding:6px 4px\">SBP (mmHg)<\/td>\r\n            <td style=\"padding:6px 4px\">${sSBP.p5}<\/td>\r\n            <td style=\"padding:6px 4px\">${sSBP.mean}<\/td>\r\n            <td style=\"padding:6px 4px\">${sSBP.p95}<\/td>\r\n            <td style=\"padding:6px 4px\">${posSBP}<\/td>\r\n          <\/tr>\r\n          <tr>\r\n            <td style=\"padding:6px 4px\">DBP (mmHg)<\/td>\r\n            <td style=\"padding:6px 4px\">${sDBP.p5}<\/td>\r\n            <td style=\"padding:6px 4px\">${sDBP.mean}<\/td>\r\n            <td style=\"padding:6px 4px\">${sDBP.p95}<\/td>\r\n            <td style=\"padding:6px 4px\">${posDBP}<\/td>\r\n          <\/tr>\r\n          <tr>\r\n            <td style=\"padding:6px 4px\">MAP (mmHg)<\/td>\r\n            <td style=\"padding:6px 4px\">${sMAP.p5}<\/td>\r\n            <td style=\"padding:6px 4px\">${sMAP.mean}<\/td>\r\n            <td style=\"padding:6px 4px\">${sMAP.p95}<\/td>\r\n            <td style=\"padding:6px 4px\">${posMAP}<\/td>\r\n          <\/tr>\r\n        <\/tbody>\r\n      <\/table>\r\n    `;\r\n  }\r\n\r\n  \/\/ Init selectors\r\n  fillSelect($('ga'), 22, 42);\r\n  fillSelect($('dol'), 0, 30);\r\n  $('ga').value = 38; $('dol').value = 0;\r\n\r\n  \/\/ Auto-update on any change\r\n  ['ga','dol','sbp','dbp'].forEach(id => {\r\n    const el = $(id);\r\n    el.addEventListener('change', updateCharts);\r\n    el.addEventListener('input', updateCharts);\r\n  });\r\n\r\n  \/\/ First paint\r\n  updateCharts();\r\n})();\r\n<\/script>\r\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-full.php","meta":{"footnotes":""},"tags":[],"class_list":["post-415","page","type-page","status-publish","article"],"_links":{"self":[{"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/pages\/415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tomchan.hk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=415"}],"version-history":[{"count":1,"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/pages\/415\/revisions"}],"predecessor-version":[{"id":416,"href":"https:\/\/tomchan.hk\/index.php?rest_route=\/wp\/v2\/pages\/415\/revisions\/416"}],"wp:attachment":[{"href":"https:\/\/tomchan.hk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=415"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tomchan.hk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}