{"id":2662,"date":"2026-03-14T19:06:16","date_gmt":"2026-03-14T17:06:16","guid":{"rendered":"https:\/\/bio-me.bio\/?page_id=2662"},"modified":"2026-03-14T19:06:17","modified_gmt":"2026-03-14T17:06:17","slug":"outbreak-spread-simulator","status":"publish","type":"page","link":"https:\/\/bio-me.bio\/?page_id=2662","title":{"rendered":"Outbreak Spread Simulator"},"content":{"rendered":"\n<div class=\"eco-tool wp-block-group\" id=\"eco-tool-outbreak-5a1c7\">\n  <div class=\"eco-tool__header\">\n    <h2 class=\"eco-tool__title\">Outbreak Spread Simulator<\/h2>\n    <p class=\"eco-tool__lead\">\n      Simulate how an outbreak may grow or shrink over several transmission cycles based on starting cases, reproduction rate, and interventions.\n    <\/p>\n  <\/div>\n\n  <form class=\"eco-tool__form\" id=\"eco-outbreak-form-5a1c7\" novalidate>\n    <div class=\"eco-tool__grid3\">\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-start-5a1c7\">Starting cases<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-outbreak-start-5a1c7\" type=\"number\" min=\"1\" max=\"1000000\" step=\"1\" value=\"10\" inputmode=\"numeric\" \/>\n        <div class=\"eco-tool__hint\">Estimated number of infectious cases at the beginning.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-r-5a1c7\">Effective reproduction number (R)<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-outbreak-r-5a1c7\" type=\"number\" min=\"0.1\" max=\"10\" step=\"0.1\" value=\"1.4\" inputmode=\"decimal\" \/>\n        <div class=\"eco-tool__hint\">Above 1 means growth, below 1 means decline.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-cycles-5a1c7\">Transmission cycles<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-outbreak-cycles-5a1c7\" type=\"number\" min=\"1\" max=\"20\" step=\"1\" value=\"6\" inputmode=\"numeric\" \/>\n        <div class=\"eco-tool__hint\">Each cycle represents one round of spread.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-intervention-5a1c7\">Intervention strength<\/label>\n        <select class=\"eco-tool__input\" id=\"eco-outbreak-intervention-5a1c7\">\n          <option value=\"0\" selected>None<\/option>\n          <option value=\"0.1\">Light (-10%)<\/option>\n          <option value=\"0.2\">Moderate (-20%)<\/option>\n          <option value=\"0.3\">Strong (-30%)<\/option>\n          <option value=\"0.5\">Very strong (-50%)<\/option>\n        <\/select>\n        <div class=\"eco-tool__hint\">Reduces the effective reproduction rate.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-detection-5a1c7\">Case detection rate (%)<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-outbreak-detection-5a1c7\" type=\"number\" min=\"1\" max=\"100\" step=\"1\" value=\"60\" inputmode=\"numeric\" \/>\n        <div class=\"eco-tool__hint\">Optional rough estimate of how many cases are actually detected.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-outbreak-format-5a1c7\">Result format<\/label>\n        <select class=\"eco-tool__input\" id=\"eco-outbreak-format-5a1c7\">\n          <option value=\"cases\" selected>Show total cases<\/option>\n          <option value=\"detected\">Show detected vs estimated<\/option>\n        <\/select>\n        <div class=\"eco-tool__hint\">Switch between simple and expanded output.<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__actions\">\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn\" id=\"eco-outbreak-calc-5a1c7\">Calculate<\/button>\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn eco-tool__btn--ghost\" id=\"eco-outbreak-reset-5a1c7\">Reset<\/button>\n      <div class=\"eco-tool__error\" id=\"eco-outbreak-error-5a1c7\" aria-live=\"polite\"><\/div>\n    <\/div>\n  <\/form>\n\n  <div class=\"eco-tool__result\" id=\"eco-outbreak-result-5a1c7\" hidden>\n    <h3 class=\"eco-tool__subtitle\">Result<\/h3>\n\n    <div class=\"eco-tool__cards\">\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Adjusted reproduction rate<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"eco-outbreak-radj-5a1c7\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-outbreak-trend-5a1c7\"><\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Estimated cases after final cycle<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"eco-outbreak-final-5a1c7\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-outbreak-finalsub-5a1c7\"><\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__card eco-tool__card--wide\">\n      <div class=\"eco-tool__metric-label\">Cycle-by-cycle progression<\/div>\n      <div class=\"eco-tool__listbox\" id=\"eco-outbreak-list-5a1c7\">\u2014<\/div>\n    <\/div>\n\n    <p class=\"eco-tool__note\">\n      This is a simplified educational model. Real outbreaks are shaped by contact patterns, immunity, superspreading, behavior, and reporting delays.\n    <\/p>\n  <\/div>\n\n  <details class=\"eco-tool__details\">\n    <summary class=\"eco-tool__summary\">How we calculate<\/summary>\n    <div class=\"eco-tool__details-body\">\n      <p class=\"eco-tool__text\">\n        We apply the reproduction rate to each transmission cycle. Interventions reduce the effective R, and optional case detection estimates how many infections might actually be observed.\n      <\/p>\n    <\/div>\n  <\/details>\n<\/div>\n\n<style>\n.eco-tool{ border:1px solid rgba(0,0,0,.12); border-radius:12px; padding:16px; }\n.eco-tool__header{ margin-bottom:12px; }\n.eco-tool__title{ margin:0 0 8px; }\n.eco-tool__lead{ margin:0; opacity:.9; }\n.eco-tool__form{ margin-top:12px; }\n\n.eco-tool__grid3{ display:grid; grid-template-columns:1fr; gap:16px; }\n@media (min-width:860px){ .eco-tool__grid3{ grid-template-columns:1fr 1fr 1fr; } }\n\n.eco-tool__field{ display:flex; flex-direction:column; gap:6px; }\n.eco-tool__label{ font-weight:600; }\n\n.eco-tool__input{\n  width:100%;\n  height:44px;\n  padding:0 12px;\n  border:1px solid rgba(0,0,0,.20);\n  border-radius:10px;\n  background:#fff;\n  box-sizing:border-box;\n  font:inherit;\n}\n.eco-tool select.eco-tool__input{\n  appearance:none;\n  -webkit-appearance:none;\n  line-height:44px;\n  padding-right:40px;\n  background-image:\n    linear-gradient(45deg, transparent 50%, rgba(0,0,0,.60) 50%),\n    linear-gradient(135deg, rgba(0,0,0,.60) 50%, transparent 50%);\n  background-position:\n    calc(100% - 18px) 50%,\n    calc(100% - 12px) 50%;\n  background-size:6px 6px;\n  background-repeat:no-repeat;\n}\n\n.eco-tool__hint{ font-size:.92em; opacity:.78; min-height:38px; }\n\n.eco-tool__actions{ display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-top:16px; }\n.eco-tool__btn{ padding:10px 22px; }\n.eco-tool__btn--ghost{ background:transparent !important; border:1px solid rgba(0,0,0,.20) !important; }\n.eco-tool__btn--ghost:hover,.eco-tool__btn--ghost:focus{ background:rgba(0,0,0,.06) !important; border-color:rgba(0,0,0,.35) !important; }\n\n.eco-tool__error{ min-height:1.2em; font-weight:600; flex:1 1 240px; }\n\n.eco-tool__result{ margin-top:16px; }\n.eco-tool__subtitle{ margin:0 0 10px; }\n\n.eco-tool__cards{ display:grid; gap:10px; grid-template-columns:1fr; }\n@media (min-width:860px){ .eco-tool__cards{ grid-template-columns:1fr 1fr; } }\n\n.eco-tool__card{ border:1px solid rgba(0,0,0,.12); border-radius:12px; padding:12px; }\n.eco-tool__card--wide{ margin-top:10px; }\n.eco-tool__metric-label{ opacity:.85; font-weight:600; }\n.eco-tool__metric-value{ font-size:1.6em; font-weight:800; margin-top:6px; line-height:1.1; }\n.eco-tool__metric-sub{ opacity:.85; margin-top:6px; }\n\n.eco-tool__listbox{\n  margin-top:10px;\n  padding:12px;\n  border:1px solid rgba(0,0,0,.10);\n  border-radius:10px;\n  background:rgba(0,0,0,.02);\n  line-height:1.7;\n}\n\n.eco-tool__note{ margin:10px 0 0; opacity:.9; }\n.eco-tool__details{ margin-top:14px; }\n.eco-tool__summary{ cursor:pointer; font-weight:700; }\n.eco-tool__details-body{ margin-top:10px; }\n.eco-tool__text{ margin:0 0 10px; }\n<\/style>\n\n<script>\n(function(){\n  const S = \"5a1c7\";\n  const el = (id) => document.getElementById(id + \"-\" + S);\n\n  const startEl = el(\"eco-outbreak-start\");\n  const rEl = el(\"eco-outbreak-r\");\n  const cyclesEl = el(\"eco-outbreak-cycles\");\n  const interventionEl = el(\"eco-outbreak-intervention\");\n  const detectionEl = el(\"eco-outbreak-detection\");\n  const formatEl = el(\"eco-outbreak-format\");\n\n  const calcBtn = el(\"eco-outbreak-calc\");\n  const resetBtn = el(\"eco-outbreak-reset\");\n  const errorEl = el(\"eco-outbreak-error\");\n\n  const resultEl = el(\"eco-outbreak-result\");\n  const radjEl = el(\"eco-outbreak-radj\");\n  const trendEl = el(\"eco-outbreak-trend\");\n  const finalEl = el(\"eco-outbreak-final\");\n  const finalSubEl = el(\"eco-outbreak-finalsub\");\n  const listEl = el(\"eco-outbreak-list\");\n\n  function setError(msg){ errorEl.textContent = msg || \"\"; }\n\n  function calculate(){\n    setError(\"\");\n\n    const start = Number(startEl.value);\n    const r = Number(rEl.value);\n    const cycles = Number(cyclesEl.value);\n    const intervention = Number(interventionEl.value);\n    const detection = Number(detectionEl.value) \/ 100;\n\n    if (!Number.isFinite(start) || start <= 0){\n      setError(\"Please enter a valid starting number of cases.\");\n      resultEl.hidden = true;\n      return;\n    }\n    if (!Number.isFinite(r) || r <= 0){\n      setError(\"Please enter a valid reproduction rate.\");\n      resultEl.hidden = true;\n      return;\n    }\n    if (!Number.isFinite(cycles) || cycles < 1){\n      setError(\"Please enter a valid number of cycles.\");\n      resultEl.hidden = true;\n      return;\n    }\n    if (!Number.isFinite(detection) || detection <= 0 || detection > 1){\n      setError(\"Please enter a valid detection rate between 1 and 100.\");\n      resultEl.hidden = true;\n      return;\n    }\n\n    const adjustedR = r * (1 - intervention);\n    let cases = start;\n    let lines = [];\n\n    for (let i = 1; i <= cycles; i++){\n      cases = cases * adjustedR;\n      const estimated = Math.round(cases);\n      const detected = Math.round(cases * detection);\n\n      if (formatEl.value === \"detected\"){\n        lines.push(`Cycle ${i}: estimated ${estimated.toLocaleString()} \u00b7 detected ${detected.toLocaleString()}`);\n      } else {\n        lines.push(`Cycle ${i}: ${estimated.toLocaleString()} cases`);\n      }\n    }\n\n    let trend = \"\";\n    if (adjustedR < 1){\n      trend = \"Expected decline (R below 1)\";\n    } else if (adjustedR === 1){\n      trend = \"Flat spread (R near 1)\";\n    } else {\n      trend = \"Expected growth (R above 1)\";\n    }\n\n    radjEl.textContent = adjustedR.toFixed(2);\n    trendEl.textContent = trend;\n\n    if (formatEl.value === \"detected\"){\n      finalEl.textContent = `${Math.round(cases).toLocaleString()} estimated`;\n      finalSubEl.textContent = `${Math.round(cases * detection).toLocaleString()} may be detected at the final cycle.`;\n    } else {\n      finalEl.textContent = `${Math.round(cases).toLocaleString()} cases`;\n      finalSubEl.textContent = `After ${cycles} transmission cycles.`;\n    }\n\n    listEl.innerHTML = lines.join(\"<br>\");\n    resultEl.hidden = false;\n  }\n\n  function reset(){\n    setError(\"\");\n    startEl.value = \"10\";\n    rEl.value = \"1.4\";\n    cyclesEl.value = \"6\";\n    interventionEl.value = \"0\";\n    detectionEl.value = \"60\";\n    formatEl.value = \"cases\";\n    resultEl.hidden = true;\n  }\n\n  calcBtn.addEventListener(\"click\", calculate);\n  resetBtn.addEventListener(\"click\", reset);\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Outbreak Spread Simulator Simulate how an outbreak may grow or shrink over several transmission cycles based on starting cases, reproduction rate, and interventions. Starting cases Estimated number of infectious cases&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":2462,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","footnotes":""},"_links":{"self":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2662"}],"collection":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2662"}],"version-history":[{"count":1,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2662\/revisions"}],"predecessor-version":[{"id":2663,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2662\/revisions\/2663"}],"up":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2462"}],"wp:attachment":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}