{"id":1004,"date":"2026-06-11T09:00:00","date_gmt":"2026-06-11T09:00:00","guid":{"rendered":"https:\/\/ksambulance.weebly.com\/cpr-tool.html"},"modified":"2026-06-11T09:00:00","modified_gmt":"2026-06-11T09:00:00","slug":"cpr-tool","status":"publish","type":"page","link":"https:\/\/ksambulance.com\/cms\/cpr-tool\/","title":{"rendered":"\u7dda\u4e0a CPR \u7bc0\u62cd\u5668\u8207\u5faa\u74b0\u8a08\u6642\u5de5\u5177 | \u4eac\u5b89\u6551\u8b77"},"content":{"rendered":"<div class=\"wsite-section-wrap\">\n<div class=\"wsite-section wsite-body-section wsite-background-48\"  >\n<div class=\"wsite-section-content\">\n<div class=\"container\">\n<div class=\"wsite-section-elements\">\n<h2 class=\"wsite-content-title\">&#20351;&#29992; CPR &#21161;&#25163;&#26178;&#65292;&#35531;&#23559;&#38899;&#37327;&#35519;&#33267;&#26368;&#22823;<\/h2>\n<div>\n<div id=\"874863285821868222\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\">\n<div id=\"cpr-continuous-v5\" class=\"cpr-v5-container\">\n<div id=\"cpr-card-cont\" class=\"cpr-card\">\n<div class=\"cpr-content\">\n<div class=\"cpr-header\">\n<div class=\"cpr-title\">\u9023\u7e8c\u6309\u58d3<\/div>\n<div class=\"cpr-subtitle\">(\u4e00\u822c\u6c11\u773e)<\/div>\n<\/p><\/div>\n<div id=\"cpr-timer-cont\" class=\"cpr-timer\">00:00<\/div>\n<p>            <button id=\"cpr-btn-cont\" class=\"cpr-btn btn-start\" style=\"pointer-events: none;\"><br \/>\n                \u9ede\u64ca\u958b\u59cb<br \/>\n            <\/button>\n        <\/div>\n<\/p><\/div>\n<\/div>\n<style>\n    \/* \u5bb9\u5668\u8207\u5b57\u9ad4 *\/\n    #cpr-continuous-v5 { display: flex; justify-content: center; align-items: center; padding: 20px; font-family: Arial, sans-serif; }<\/p>\n<p>    \/* \u5361\u7247\u4e3b\u9ad4 *\/\n    #cpr-continuous-v5 .cpr-card {\n        width: 300px; height: 300px;\n        background-color: #fff; border: 2px solid #333; border-radius: 12px;\n        display: flex; flex-direction: column; justify-content: center; align-items: center;\n        text-align: center; box-shadow: 0 6px 15px rgba(0,0,0,0.15);\n        cursor: pointer; position: relative; overflow: hidden;\n        user-select: none; -webkit-tap-highlight-color: transparent;\n        transition: transform 0.1s ease-out, background-color 0.1s;\n    }<\/p>\n<p>    \/* \u6392\u7248\u8207\u6587\u5b57 *\/\n    #cpr-continuous-v5 .cpr-title { font-size: 32px; font-weight: 900; color: #333; line-height: 1.2; }\n    #cpr-continuous-v5 .cpr-subtitle { font-size: 16px; color: #666; margin-bottom: 10px; min-height: 19px; \/* \u56fa\u5b9a\u9ad8\u5ea6\u4fdd\u6301\u5c0d\u9f4a *\/ }\n    #cpr-continuous-v5 .cpr-timer { font-size: 64px; font-weight: 700; color: #222; font-family: Arial, monospace; margin: 10px 0 20px 0; line-height: 1; }<\/p>\n<p>    \/* \u6309\u9215 *\/\n    #cpr-continuous-v5 .cpr-btn {\n        width: 80%; padding: 12px 0; font-size: 24px; font-weight: 700; color: #fff;\n        border: none; border-radius: 8px; transition: background-color 0.2s;\n    }\n    .btn-start { background-color: #5cb85c; }\n    .btn-stop { background-color: #d9534f; }<\/p>\n<p>    \/* \u52d5\u756b\uff1a\u6309\u58d3 (\u7d05\u5149 + \u5fc3\u8df3\u7e2e\u653e) *\/\n    .cpr-flash-active {\n        background-color: #d9534f !important;\n        border-color: #c9302c !important;\n        transform: scale(1.02); \/* \u5fc3\u8df3\u9707\u52d5\u6548\u679c *\/\n    }\n    .cpr-flash-active .cpr-title, \n    .cpr-flash-active .cpr-subtitle, \n    .cpr-flash-active .cpr-timer { color: #ffffff !important; }\n<\/style>\n<p><script>\n(function() {\n    \/\/ \u9023\u7e8c\u6309\u58d3\u53c3\u6578\n    const bpm = 120;<\/p>\n<p>    let state = 'IDLE'; \n    let startTime = 0;\n    let timerInterval = null;\n    let loopTimeout = null;\n    let audioCtx = null;\n    let wakeLock = null;\n    let lastBeatTime = 0;<\/p>\n<p>    const el = {\n        card: document.getElementById('cpr-card-cont'),\n        timer: document.getElementById('cpr-timer-cont'),\n        btn: document.getElementById('cpr-btn-cont')\n    };<\/p>\n<p>    function playSound() {\n        if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n        if (audioCtx.state === 'suspended') audioCtx.resume();\n        const osc = audioCtx.createOscillator();\n        const gain = audioCtx.createGain();\n        osc.type = 'square'; osc.frequency.value = 3300;\n        gain.gain.setValueAtTime(1.0, audioCtx.currentTime);\n        gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1);\n        osc.connect(gain); gain.connect(audioCtx.destination);\n        osc.start(); osc.stop(audioCtx.currentTime + 0.1);\n    }<\/p>\n<p>    async function enableWakeLock() {\n        if ('wakeLock' in navigator) { try { wakeLock = await navigator.wakeLock.request('screen'); } catch(e){} }\n    }<\/p>\n<p>    function updateTimer() {\n        const diff = Math.floor((Date.now() - startTime) \/ 1000);\n        const mm = Math.floor(diff \/ 60).toString().padStart(2,'0');\n        const ss = (diff % 60).toString().padStart(2,'0');\n        el.timer.textContent = `${mm}:${ss}`;\n    }<\/p>\n<p>    function flash() {\n        el.card.classList.add('cpr-flash-active');\n        setTimeout(() => el.card.classList.remove('cpr-flash-active'), 150);\n    }<\/p>\n<p>    function runLoop() {\n        if (state !== 'RUNNING') return;\n        const now = Date.now();\n        const interval = 60000 \/ bpm;<\/p>\n<p>        if (now - lastBeatTime >= interval) {\n            lastBeatTime = now;\n            playSound();\n            flash();\n        }\n        loopTimeout = setTimeout(runLoop, 15);\n    }<\/p>\n<p>    el.card.addEventListener('click', function(e) {\n        e.stopPropagation();\n        if (state === 'IDLE') {\n            state = 'RUNNING';\n            startTime = Date.now();\n            enableWakeLock();\n            timerInterval = setInterval(updateTimer, 250);\n            el.btn.textContent = \"\u505c\u6b62 (AED)\";\n            el.btn.className = \"cpr-btn btn-stop\";\n            lastBeatTime = Date.now();\n            playSound(); flash();\n            runLoop();\n        } else if (state === 'RUNNING') {\n            state = 'PAUSED';\n            clearTimeout(loopTimeout);\n            el.btn.textContent = \"\u7e7c\u7e8c\u6309\u58d3\";\n        } else if (state === 'PAUSED') {\n            state = 'RUNNING'; \/\/ \u9023\u7e8c\u7248\u76f4\u63a5\u6062\u5fa9\n            el.btn.textContent = \"\u505c\u6b62 (AED)\";\n            if (!wakeLock) enableWakeLock();\n            lastBeatTime = Date.now();\n            playSound(); flash();\n            runLoop();\n        }\n    });\n})();\n<\/script><\/div>\n<\/div>\n<div>\n<div id=\"266071399402278593\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\">\n<div id=\"cpr-adult-v5\" class=\"cpr-v5-container\">\n<div id=\"cpr-card-adult\" class=\"cpr-card\">\n<div id=\"content-c-adult\">\n<div class=\"cpr-header\">\n<div class=\"cpr-title\">\u6210\u4eba 30:2<\/div>\n<div class=\"cpr-subtitle\">&nbsp;<\/div>\n<\/p><\/div>\n<div id=\"timer-adult\" class=\"cpr-timer\">00:00<\/div>\n<p>            <button id=\"btn-adult\" class=\"cpr-btn btn-start\" style=\"pointer-events: none;\"><br \/>\n                \u9ede\u64ca\u958b\u59cb<br \/>\n            <\/button>\n        <\/div>\n<div id=\"content-b-adult\" class=\"cpr-breath-overlay\" style=\"display: none;\">\n<div class=\"cpr-breath-text\">\u7d66\u6c27<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<style>\n    \/* CSS \u7d50\u69cb\u8207\u4e0a\u65b9\u5b8c\u5168\u4e00\u81f4\uff0c\u50c5 ID \u4e0d\u540c *\/\n    #cpr-adult-v5 { display: flex; justify-content: center; align-items: center; padding: 20px; font-family: Arial, sans-serif; }<\/p>\n<p>    #cpr-adult-v5 .cpr-card {\n        width: 300px; height: 300px;\n        background-color: #fff; border: 2px solid #333; border-radius: 12px;\n        display: flex; flex-direction: column; justify-content: center; align-items: center;\n        text-align: center; box-shadow: 0 6px 15px rgba(0,0,0,0.15);\n        cursor: pointer; position: relative; overflow: hidden;\n        user-select: none; -webkit-tap-highlight-color: transparent;\n        transition: transform 0.1s ease-out;\n    }<\/p>\n<p>    #cpr-adult-v5 .cpr-title { font-size: 32px; font-weight: 900; color: #333; line-height: 1.2; }\n    #cpr-adult-v5 .cpr-subtitle { font-size: 16px; color: #666; margin-bottom: 10px; min-height: 19px; }\n    #cpr-adult-v5 .cpr-timer { font-size: 64px; font-weight: 700; color: #222; font-family: Arial, monospace; margin: 10px 0 20px 0; line-height: 1; }<\/p>\n<p>    #cpr-adult-v5 .cpr-btn {\n        width: 80%; padding: 12px 0; font-size: 24px; font-weight: 700; color: #fff;\n        border: none; border-radius: 8px; transition: background-color 0.2s;\n    }\n    .btn-start { background-color: #5cb85c; }\n    .btn-stop { background-color: #d9534f; }<\/p>\n<p>    \/* \u7d66\u6c27\u8986\u84cb\u5c64 *\/\n    .cpr-breath-overlay {\n        position: absolute; top: 0; left: 0; width: 100%; height: 100%;\n        display: flex; align-items: center; justify-content: center;\n        background-color: #428bca; \/* \u57fa\u5e95\u85cd *\/\n    }\n    #cpr-adult-v5 .cpr-breath-text { font-size: 80px; font-weight: 900; color: #ffffff; \/* \u5f37\u5236\u767d\u5b57 *\/ }<\/p>\n<p>    \/* \u52d5\u756b\uff1a\u6309\u58d3 (\u7d05\u5149 + \u9707\u52d5) *\/\n    .cpr-flash-active {\n        background-color: #d9534f !important; border-color: #c9302c !important;\n        transform: scale(1.02);\n    }\n    .cpr-flash-active .cpr-title, .cpr-flash-active .cpr-timer { color: #ffffff !important; }<\/p>\n<p>    \/* \u52d5\u756b\uff1a\u7d66\u6c27 (\u85cd\u8272\u547c\u5438\u71c8\u6548 - \u4e0d\u8b8a\u9ed1) *\/\n    @keyframes blue-breath {\n        0% { background-color: #428bca; transform: scale(1); }\n        50% { background-color: #5bc0de; transform: scale(1.02); } \/* \u8b8a\u4eae\u85cd + \u5fae\u653e\u5927 *\/\n        100% { background-color: #428bca; transform: scale(1); }\n    }\n    .mode-breath-anim {\n        animation: blue-breath 1s ease-in-out forwards;\n    }\n<\/style>\n<p><script>\n(function() {\n    const config = { limit: 30, bpm: 120, breathCount: 2, breathDuration: 1000 };\n    let state = 'IDLE'; let count = 0; let breathCycle = 0;\n    let startTime = 0; let loopTimeout = null; let audioCtx = null; let wakeLock = null; let lastBeatTime = 0;<\/p>\n<p>    const el = {\n        card: document.getElementById('cpr-card-adult'),\n        contentC: document.getElementById('content-c-adult'),\n        contentB: document.getElementById('content-b-adult'),\n        timer: document.getElementById('timer-adult'),\n        btn: document.getElementById('btn-adult')\n    };<\/p>\n<p>    function playSound(type) {\n        if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n        if (audioCtx.state === 'suspended') audioCtx.resume();\n        const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain();\n        osc.type = 'square'; osc.frequency.value = 3300;\n        const now = audioCtx.currentTime;\n        const duration = (type === 'long') ? 0.8 : 0.1;\n        gain.gain.setValueAtTime(1.0, now);\n        gain.gain.exponentialRampToValueAtTime(0.01, now + duration);\n        osc.connect(gain); gain.connect(audioCtx.destination);\n        osc.start(); osc.stop(now + duration);\n    }\n    async function enableWakeLock() { if ('wakeLock' in navigator) try { wakeLock = await navigator.wakeLock.request('screen'); } catch(e){} }\n    function updateTimer() {\n        const d = Math.floor((Date.now() - startTime) \/ 1000);\n        el.timer.textContent = `${Math.floor(d\/60).toString().padStart(2,'0')}:${(d%60).toString().padStart(2,'0')}`;\n    }\n    function flash() {\n        el.card.classList.add('cpr-flash-active');\n        setTimeout(() => el.card.classList.remove('cpr-flash-active'), 150);\n    }<\/p>\n<p>    function runLoop() {\n        if (state !== 'COMPRESS') return;\n        const now = Date.now();\n        if (now - lastBeatTime >= (60000 \/ config.bpm)) {\n            lastBeatTime = now;\n            count++;\n            playSound('short'); flash();\n            if (count >= config.limit) { loopTimeout = setTimeout(startBreath, (60000 \/ config.bpm)); return; }\n        }\n        loopTimeout = setTimeout(runLoop, 15);\n        if(state === 'COMPRESS') requestAnimationFrame(updateTimer); \/\/ \u9806\u4fbf\u66f4\u65b0\u6642\u9593\n    }<\/p>\n<p>    function startBreath() {\n        state = 'BREATH'; breathCycle = 0;\n        el.contentC.style.display = 'none'; el.contentB.style.display = 'flex';\n        runBreathStep();\n    }\n    function runBreathStep() {\n        if (state !== 'BREATH') return;\n        if (breathCycle >= config.breathCount) { backToCompressInstant(); return; }\n        breathCycle++;\n        playSound('long');\n        el.contentB.classList.remove('mode-breath-anim');\n        void el.contentB.offsetWidth; \/\/ Reset animation\n        el.contentB.classList.add('mode-breath-anim');\n        loopTimeout = setTimeout(runBreathStep, config.breathDuration);\n    }\n    function backToCompressInstant() {\n        state = 'COMPRESS';\n        el.contentB.style.display = 'none'; el.contentC.style.display = 'block';\n        lastBeatTime = Date.now(); count = 1; \n        playSound('short'); flash();\n        runLoop();\n    }<\/p>\n<p>    el.card.addEventListener('click', function(e) {\n        e.stopPropagation();\n        if (state === 'IDLE') {\n            state = 'COMPRESS'; startTime = Date.now(); enableWakeLock();\n            setInterval(updateTimer, 250);\n            el.btn.textContent = \"\u505c\u6b62 (AED)\"; el.btn.className = \"cpr-btn btn-stop\";\n            backToCompressInstant();\n        } else if (state === 'COMPRESS' || state === 'BREATH') {\n            state = 'PAUSED'; clearTimeout(loopTimeout);\n            el.contentB.style.display = 'none'; el.contentC.style.display = 'block';\n            el.btn.textContent = \"\u7e7c\u7e8c\u6309\u58d3\";\n        } else if (state === 'PAUSED') {\n            el.btn.textContent = \"\u505c\u6b62 (AED)\"; if(!wakeLock) enableWakeLock();\n            backToCompressInstant();\n        }\n    });\n})();\n<\/script><\/div>\n<\/div>\n<div>\n<div id=\"298889423658065796\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\">\n<div id=\"cpr-child-v5\" class=\"cpr-v5-container\">\n<div id=\"cpr-card-child\" class=\"cpr-card\">\n<div id=\"content-c-child\">\n<div class=\"cpr-header\">\n<div class=\"cpr-title\">\u5c0f\u5152 15:2<\/div>\n<div class=\"cpr-subtitle\">&nbsp;<\/div>\n<\/p><\/div>\n<div id=\"timer-child\" class=\"cpr-timer\">00:00<\/div>\n<p>            <button id=\"btn-child\" class=\"cpr-btn btn-start\" style=\"pointer-events: none;\"><br \/>\n                \u9ede\u64ca\u958b\u59cb<br \/>\n            <\/button>\n        <\/div>\n<div id=\"content-b-child\" class=\"cpr-breath-overlay\" style=\"display: none;\">\n<div class=\"cpr-breath-text\">\u7d66\u6c27<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<style>\n    \/* CSS \u91cd\u8907\u4f7f\u7528\uff0cID \u9650\u5b9a\u7bc4\u570d *\/\n    #cpr-child-v5 { display: flex; justify-content: center; align-items: center; padding: 20px; font-family: Arial, sans-serif; }<\/p>\n<p>    #cpr-child-v5 .cpr-card {\n        width: 300px; height: 300px;\n        background-color: #fff; border: 2px solid #333; border-radius: 12px;\n        display: flex; flex-direction: column; justify-content: center; align-items: center;\n        text-align: center; box-shadow: 0 6px 15px rgba(0,0,0,0.15);\n        cursor: pointer; position: relative; overflow: hidden;\n        user-select: none; -webkit-tap-highlight-color: transparent;\n        transition: transform 0.1s ease-out;\n    }<\/p>\n<p>    #cpr-child-v5 .cpr-title { font-size: 32px; font-weight: 900; color: #333; line-height: 1.2; }\n    #cpr-child-v5 .cpr-subtitle { font-size: 16px; color: #666; margin-bottom: 10px; min-height: 19px; }\n    #cpr-child-v5 .cpr-timer { font-size: 64px; font-weight: 700; color: #222; font-family: Arial, monospace; margin: 10px 0 20px 0; line-height: 1; }<\/p>\n<p>    #cpr-child-v5 .cpr-btn {\n        width: 80%; padding: 12px 0; font-size: 24px; font-weight: 700; color: #fff;\n        border: none; border-radius: 8px; transition: background-color 0.2s;\n    }\n    .btn-start { background-color: #5cb85c; }\n    .btn-stop { background-color: #d9534f; }<\/p>\n<p>    .cpr-breath-overlay {\n        position: absolute; top: 0; left: 0; width: 100%; height: 100%;\n        display: flex; align-items: center; justify-content: center;\n        background-color: #428bca;\n    }\n    #cpr-child-v5 .cpr-breath-text { font-size: 80px; font-weight: 900; color: #ffffff; }<\/p>\n<p>    .cpr-flash-active {\n        background-color: #d9534f !important; border-color: #c9302c !important;\n        transform: scale(1.02);\n    }\n    .cpr-flash-active .cpr-title, .cpr-flash-active .cpr-timer { color: #ffffff !important; }<\/p>\n<p>    @keyframes blue-breath {\n        0% { background-color: #428bca; transform: scale(1); }\n        50% { background-color: #5bc0de; transform: scale(1.02); }\n        100% { background-color: #428bca; transform: scale(1); }\n    }\n    .mode-breath-anim { animation: blue-breath 1s ease-in-out forwards; }\n<\/style>\n<p><script>\n(function() {\n    const config = { limit: 15, bpm: 120, breathCount: 2, breathDuration: 1000 };\n    let state = 'IDLE'; let count = 0; let breathCycle = 0;\n    let startTime = 0; let loopTimeout = null; let audioCtx = null; let wakeLock = null; let lastBeatTime = 0;<\/p>\n<p>    const el = {\n        card: document.getElementById('cpr-card-child'),\n        contentC: document.getElementById('content-c-child'),\n        contentB: document.getElementById('content-b-child'),\n        timer: document.getElementById('timer-child'),\n        btn: document.getElementById('btn-child')\n    };<\/p>\n<p>    function playSound(type) {\n        if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n        if (audioCtx.state === 'suspended') audioCtx.resume();\n        const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain();\n        osc.type = 'square'; osc.frequency.value = 3300;\n        const now = audioCtx.currentTime;\n        const duration = (type === 'long') ? 0.8 : 0.1;\n        gain.gain.setValueAtTime(1.0, now);\n        gain.gain.exponentialRampToValueAtTime(0.01, now + duration);\n        osc.connect(gain); gain.connect(audioCtx.destination);\n        osc.start(); osc.stop(now + duration);\n    }\n    async function enableWakeLock() { if ('wakeLock' in navigator) try { wakeLock = await navigator.wakeLock.request('screen'); } catch(e){} }\n    function updateTimer() {\n        const d = Math.floor((Date.now() - startTime) \/ 1000);\n        el.timer.textContent = `${Math.floor(d\/60).toString().padStart(2,'0')}:${(d%60).toString().padStart(2,'0')}`;\n    }\n    function flash() {\n        el.card.classList.add('cpr-flash-active');\n        setTimeout(() => el.card.classList.remove('cpr-flash-active'), 150);\n    }<\/p>\n<p>    function runLoop() {\n        if (state !== 'COMPRESS') return;\n        const now = Date.now();\n        if (now - lastBeatTime >= (60000 \/ config.bpm)) {\n            lastBeatTime = now;\n            count++;\n            playSound('short'); flash();\n            if (count >= config.limit) { loopTimeout = setTimeout(startBreath, (60000 \/ config.bpm)); return; }\n        }\n        loopTimeout = setTimeout(runLoop, 15);\n        if(state === 'COMPRESS') requestAnimationFrame(updateTimer);\n    }<\/p>\n<p>    function startBreath() {\n        state = 'BREATH'; breathCycle = 0;\n        el.contentC.style.display = 'none'; el.contentB.style.display = 'flex';\n        runBreathStep();\n    }\n    function runBreathStep() {\n        if (state !== 'BREATH') return;\n        if (breathCycle >= config.breathCount) { backToCompressInstant(); return; }\n        breathCycle++;\n        playSound('long');\n        el.contentB.classList.remove('mode-breath-anim');\n        void el.contentB.offsetWidth;\n        el.contentB.classList.add('mode-breath-anim');\n        loopTimeout = setTimeout(runBreathStep, config.breathDuration);\n    }\n    function backToCompressInstant() {\n        state = 'COMPRESS';\n        el.contentB.style.display = 'none'; el.contentC.style.display = 'block';\n        lastBeatTime = Date.now(); count = 1; \n        playSound('short'); flash();\n        runLoop();\n    }<\/p>\n<p>    el.card.addEventListener('click', function(e) {\n        e.stopPropagation();\n        if (state === 'IDLE') {\n            state = 'COMPRESS'; startTime = Date.now(); enableWakeLock();\n            setInterval(updateTimer, 250);\n            el.btn.textContent = \"\u505c\u6b62 (AED)\"; el.btn.className = \"cpr-btn btn-stop\";\n            backToCompressInstant();\n        } else if (state === 'COMPRESS' || state === 'BREATH') {\n            state = 'PAUSED'; clearTimeout(loopTimeout);\n            el.contentB.style.display = 'none'; el.contentC.style.display = 'block';\n            el.btn.textContent = \"\u7e7c\u7e8c\u6309\u58d3\";\n        } else if (state === 'PAUSED') {\n            el.btn.textContent = \"\u505c\u6b62 (AED)\"; if(!wakeLock) enableWakeLock();\n            backToCompressInstant();\n        }\n    });\n})();\n<\/script><\/div>\n<\/div>\n<div>\n<div style=\"height: 20px; overflow: hidden; width: 100%;\"><\/div>\n<hr class=\"styled-hr\" style=\"width:100%;\"><\/hr>\n<div style=\"height: 20px; overflow: hidden; width: 100%;\"><\/div>\n<\/div>\n<div>\n<div id=\"504296797902590489\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\">\n<div id=\"jingan-cpr-widget\" style=\"width: 100%; max-width: 1200px; margin: 0 auto; background: #121212; border-radius: 12px; overflow: hidden; font-family: Arial, sans-serif; position: relative; border: 1px solid #333;\">\n<style>\n        \/* \u5c40\u90e8\u6a23\u5f0f\u9694\u96e2 *\/\n        #jingan-cpr-widget {\n            --widget-height: 600px;\n            height: var(--widget-height);\n            display: grid;\n            grid-template-columns: 30% 35% 35%; \/* \u5de6\u4e2d\u53f3\u6bd4\u4f8b *\/\n            gap: 8px;\n            padding: 10px;\n            box-sizing: border-box;\n            color: #e0e0e0;\n            font-family: Arial, sans-serif;\n        }<\/p>\n<p>        \/* \u97ff\u61c9\u5f0f *\/\n        @media (max-width: 768px) {\n            #jingan-cpr-widget {\n                grid-template-columns: 1fr;\n                grid-template-rows: auto auto auto;\n                height: auto;\n                overflow-y: auto;\n            }\n        }<\/p>\n<p>        #jingan-cpr-widget .panel {\n            background-color: #1e1e1e;\n            border-radius: 8px;\n            padding: 8px;\n            display: flex;\n            flex-direction: column;\n            border: 1px solid #333;\n            min-height: 0;\n            position: relative;\n        }<\/p>\n<p>        #jingan-cpr-widget h2 { margin: 0 0 8px 0; font-size: 1.1rem; text-transform: uppercase; color: #888; text-align: center; font-weight: bold; letter-spacing: 1px; }<\/p>\n<p>        \/* === \u5de6\u5074\uff1a\u7bc0\u62cd\u5668 === *\/\n        .ja-ring-container {\n            width: 160px; height: 160px;\n            margin: 5px auto;\n            position: relative;\n            display: flex; justify-content: center; align-items: center;\n        }<\/p>\n<p>        .ja-progress-ring__circle {\n            transition: stroke-dashoffset 0.1s linear;\n            transform: rotate(-90deg);\n            transform-origin: 50% 50%;\n        }<\/p>\n<p>        .ja-timer-content {\n            position: absolute;\n            top: 50%; left: 50%;\n            transform: translate(-50%, -50%);\n            text-align: center;\n            z-index: 2;\n        }<\/p>\n<p>        #ja-cpr-display { font-size: 2.5rem; font-weight: bold; font-variant-numeric: tabular-nums; line-height: 1; text-shadow: 0 0 10px rgba(0,0,0,0.8); }\n        #ja-status-text { font-size: 0.85rem; color: #bbb; margin-top: 2px; font-weight: bold;}\n        #ja-breath-hint { font-size: 0.9rem; color: #29b6f6; margin-top: 2px; height: 1.2em; font-weight: bold;}<\/p>\n<p>        \/* \u6309\u9215\u7fa4 *\/\n        .ja-mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; margin-top: 5px; }\n        .ja-btn { background: #333; border: none; color: #fff; padding: 12px 2px; border-radius: 6px; cursor: pointer; font-size: 0.85rem; font-family: Arial, sans-serif; font-weight: bold; transition: background 0.2s; }\n        .ja-btn:hover { background: #444; }\n        .ja-btn.active { background: #2979ff; color: black; }<\/p>\n<p>        .ja-metro-toggle { width: 100%; background: #424242; color: #fff; margin-top: 10px; padding: 10px; border-radius: 6px; border: 1px solid #555; cursor: pointer; font-weight: bold; display: flex; justify-content: center; align-items: center; gap: 5px; font-size: 1rem;}\n        .ja-metro-toggle.on { background: #00e676; color: black; border-color: #00e676; }<\/p>\n<p>        .ja-shock-area { margin-top: 10px; border-top: 1px solid #333; padding-top: 10px; display: flex; flex-direction: column; gap: 5px;}\n        .ja-aed-btn { background: #d32f2f; color: white; width: 100%; padding: 12px; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; font-size: 1rem; }\n        .ja-manual-row { display: flex; gap: 5px; }\n        .ja-joule-select, .ja-ecg-select { flex: 1; background: #333; color: white; border: 1px solid #555; border-radius: 6px; text-align: center; font-weight: bold; font-size: 0.9rem; padding: 5px;}\n        .ja-manual-btn { flex: 2; background: #b71c1c; color: white; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; padding: 10px; }\n        .ja-ecg-select { width: 100%; padding: 10px; margin-top: 5px; background: #263238; border-color: #455a64; color: #90a4ae; }<\/p>\n<p>        \/* === \u4e2d\u9593\uff1a\u85e5\u7269 === *\/\n        #ja-epi-btn { \n            background: #333; color: white; border: 2px solid #00e676; padding: 15px; \n            border-radius: 8px; cursor: pointer; margin-bottom: 5px; position: relative; overflow: hidden;\n            font-weight: bold; text-align: center; font-size: 1.1rem;\n            transition: background 0.2s; \/* \u5e73\u6ed1\u904e\u6e21 *\/\n            z-index: 1;\n        }<\/p>\n<p>        \/* Epinephrine \u8b66\u5831\u6a23\u5f0f (\u6642\u9593\u5230\u6642\u89f8\u767c) *\/\n        #ja-epi-btn.epi-alert {\n            background-color: #00e676; \/* \u5be6\u5fc3\u7da0 *\/\n            color: #000; \/* \u9ed1\u5b57\u5c0d\u6bd4 *\/\n            border-color: #00e676;\n            animation: ja-breathing-solid 1.5s infinite ease-in-out;\n            \/* \u79fb\u9664 box-shadow \u5149\u6688 *\/\n        }<\/p>\n<p>        \/* \u7d14\u8272\u584a\u547c\u5438\u52d5\u756b *\/\n        @keyframes ja-breathing-solid {\n            0% { background-color: #00e676; } \n            50% { background-color: #00a855; } \/* \u8b8a\u6697\u4e00\u9ede *\/\n            100% { background-color: #00e676; }\n        }<\/p>\n<p>        #ja-epi-progress { \n            position: absolute; bottom: 0; left: 0; height: 5px; background: #00e676; width: 0%; \n            z-index: 0;\n        }\n        \/* \u8b66\u5831\u6642\u96b1\u85cf\u9032\u5ea6\u689d (\u56e0\u70ba\u80cc\u666f\u5df2\u7d93\u5168\u7da0) *\/\n        #ja-epi-btn.epi-alert #ja-epi-progress { display: none; }<\/p>\n<p>        .ja-med-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }\n        .ja-rosc-btn { grid-column: span 2; background: #004d40; border: 1px solid #00695c; color: #fff; margin-top: 5px; }\n        .ja-rosc-btn.active { background: #00e676; color: black; box-shadow: 0 0 10px #00e676; }\n        .ja-type-btn { background: #4a148c; border: 1px solid #7b1fa2; color: #e1bee7; }<\/p>\n<p>        \/* === \u53f3\u5074\uff1a\u8a08\u6642\u8207\u7d00\u9304 === *\/\n        .ja-header-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; }\n        .ja-stop-btn { background: #b71c1c; color: white; border: none; border-radius: 4px; padding: 5px 10px; cursor: pointer; font-size: 0.8rem; font-weight: bold;}<\/p>\n<p>        #ja-global-timer { font-size: 3.5rem; text-align: center; font-weight: 800; color: white; margin: 0 0 10px 0; font-variant-numeric: tabular-nums;}<\/p>\n<p>        #ja-log-stream { \n            flex: 1; \n            background: #111; \n            border-radius: 6px; \n            overflow-y: auto; \n            padding: 5px; \n            font-family: Arial, sans-serif; \n            font-size: 0.95rem; \n            border: 1px solid #333;\n            display: flex; \n            flex-direction: column-reverse; \n            max-height: 400px; \n        }<\/p>\n<p>        .ja-log-entry { border-bottom: 1px solid #222; padding: 6px 4px; display: flex; justify-content: space-between; flex-shrink: 0;}\n        .ja-log-entry span:first-child { color: #888; font-size: 0.85rem; margin-right: 8px; min-width: 60px;}\n        .ja-log-entry.shock { color: #ff1744; font-weight: bold; } \n        .ja-log-entry.drug { color: #2979ff; }\n        .ja-log-entry.rosc { color: #00e676; font-weight: bold; border: 1px solid #004d40; background: #00251a; }\n        .ja-log-entry.end { color: #888; font-style: italic; border-top: 1px solid #666; }\n        .ja-log-entry.type { color: #ba68c8; font-weight: bold; }\n        .ja-log-entry.ecg { color: #ffca28; font-weight: bold; } <\/p>\n<p>        \/* \u8986\u84cb\u5c64 *\/\n        #ja-overlay {\n            position: absolute; top: 0; left: 0; width: 100%; height: 100%;\n            background: rgba(0,0,0,0.92); z-index: 50;\n            display: flex; justify-content: center; align-items: center; flex-direction: column;\n            border-radius: 12px;\n        }\n        #ja-start-btn { padding: 15px 40px; font-size: 1.5rem; background: #00e676; border: none; border-radius: 30px; cursor: pointer; font-weight: bold; box-shadow: 0 0 15px rgba(0,230,118,0.4); }<\/p>\n<p>        \/* \u7d66\u6c27\u63d0\u793a (\u7c21\u5316\u6587\u5b57) *\/\n        .ja-vent-alert { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #29b6f6; font-weight: bold; display: none; background: rgba(0,0,0,0.9); padding: 5px 10px; border-radius: 4px; border: 2px solid #29b6f6; z-index: 10; box-shadow: 0 0 20px #29b6f6;}\n    <\/style>\n<div id=\"ja-overlay\">\n<h2 style=\"color:white; margin-bottom: 20px; font-size: 1.5rem;\">\u4eac\u5b89\u6551\u8b77 Code Blue Leader<\/h2>\n<p>        <button id=\"ja-start-btn\" onclick=\"jaStart()\">\u555f\u52d5\u6025\u6551\u6d41\u7a0b<\/button><\/p>\n<p style=\"color:#666; margin-top:20px; font-size:0.9rem;\">v2.3<\/p>\n<\/p><\/div>\n<div class=\"panel\">\n<div class=\"ja-header-row\">\n<h2>\u7bc0\u62cd\u5668<\/h2>\n<\/p><\/div>\n<div class=\"ja-ring-container\">\n            <svg class=\"ja-progress-ring\" width=\"160\" height=\"160\">\n                <circle class=\"ja-progress-ring__circle--bg\" stroke=\"#333\" stroke-width=\"8\" fill=\"transparent\" r=\"70\" cx=\"80\" cy=\"80\"\/>\n                <circle id=\"ja-breath-ring\" class=\"ja-progress-ring__circle\" stroke=\"#00e676\" stroke-width=\"8\" fill=\"transparent\" r=\"70\" cx=\"80\" cy=\"80\" stroke-dasharray=\"439.8\" stroke-dashoffset=\"0\"\/>\n            <\/svg><\/p>\n<div class=\"ja-timer-content\">\n<div id=\"ja-cpr-display\">02:00<\/div>\n<div id=\"ja-status-text\">CPR \u9032\u884c\u4e2d<\/div>\n<div id=\"ja-breath-hint\">\u6e96\u5099\u4e2d&#8230;<\/div>\n<\/p><\/div>\n<div class=\"ja-vent-alert\" id=\"ja-vent\">\u7d66\u6c27<\/div>\n<\/p><\/div>\n<p>        <button id=\"ja-metro-btn\" class=\"ja-metro-toggle on\" onclick=\"jaToggleMetro()\"><br \/>\n            \u7bc0\u62cd\u5668\uff1a\u958b<br \/>\n        <\/button><\/p>\n<div class=\"ja-mode-grid\">\n            <button class=\"ja-btn active\" onclick=\"jaSetMode('30:2', this)\">30:2<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaSetMode('15:2', this)\">15:2<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaSetMode('CONT', this)\">\u9023\u7e8c\u6309\u58d3<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaSetMode('LUCAS', this)\">6\u79d2\u7d66\u6c27<\/button>\n        <\/div>\n<div class=\"ja-shock-area\">\n            <button class=\"ja-aed-btn\" onclick=\"jaLogAED()\">AED \u96fb\u64ca<\/button><\/p>\n<div class=\"ja-manual-row\">\n                <select id=\"ja-joule-select\" class=\"ja-joule-select\"><option value=\"120\">120J<\/option><option value=\"150\">150J<\/option><option value=\"200\" selected>200J<\/option><option value=\"270\">270J<\/option><option value=\"360\">360J<\/option><\/select><br \/>\n                <button class=\"ja-manual-btn\" onclick=\"jaLogManualShock()\">\u624b\u52d5\u96fb\u64ca<\/button>\n            <\/div>\n<p>            <select id=\"ja-ecg-select\" class=\"ja-ecg-select\" onchange=\"jaLogECG(this)\"><option value=\"\" disabled selected>\u7d00\u9304\u5fc3\u5f8b (ECG Rhythm)<\/option><option value=\"VF\">VF<\/option><option value=\"pVT\">pVT<\/option><option value=\"Asystole\">Asystole<\/option><option value=\"PEA\">PEA<\/option><option value=\"NSR\">NSR<\/option><option value=\"SB\">SB<\/option><option value=\"ST\">ST<\/option><option value=\"SVT\">SVT<\/option><option value=\"VT\">VT<\/option><option value=\"AFib\">AFib<\/option><option value=\"AFlutter\">AFlutter<\/option><option value=\"AVB\">AVB<\/option><option value=\"Others\">Others<\/option><\/select>\n        <\/div>\n<\/p><\/div>\n<div class=\"panel\">\n<h2>\u7d66\u85e5 \/ \u8655\u7f6e<\/h2>\n<div id=\"ja-epi-btn\" onclick=\"jaEpi()\">\n            Epinephrine 1mg<\/p>\n<div id=\"ja-epi-status\" style=\"font-size:0.8rem; font-weight:normal; margin-top: 2px; position:relative; z-index:2;\">\u6e96\u5099\u5c31\u7dd2<\/div>\n<div id=\"ja-epi-progress\"><\/div>\n<\/p><\/div>\n<div class=\"ja-med-grid\">\n            <button class=\"ja-btn\" onclick=\"jaLog('Amio 300mg', 'drug')\">Amio 300mg<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaLog('Amio 150mg', 'drug')\">Amio 150mg<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaLog('Lidocaine 100mg', 'drug')\">Lidocaine 100mg<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaLog('Atropine 1mg', 'drug')\">Atropine 1mg<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaLog('Midazolam 5mg', 'drug')\">Midazolam 5mg<\/button><br \/>\n            <button class=\"ja-btn\" onclick=\"jaLog('\u5efa\u7acb IV\/IO', 'drug')\">\u5efa\u7acb IV\/IO<\/button><br \/>\n            <button class=\"ja-btn\" style=\"color:#2979ff; grid-column: span 2;\" onclick=\"jaLog('\u5efa\u7acb\u9032\u968e\u547c\u5438\u9053', 'drug')\">\u5efa\u7acb\u9032\u968e\u547c\u5438\u9053 (Endo\/LMA)<\/button><\/p>\n<p>            <button class=\"ja-btn ja-rosc-btn\" id=\"ja-rosc-trigger\" onclick=\"jaTriggerROSC()\">ROSC \u6062\u5fa9\u81ea\u767c\u5faa\u74b0<\/button><\/p>\n<p>            <button class=\"ja-btn ja-type-btn\" onclick=\"jaLog('\u60a3\u8005\u985e\u5225: OHCA', 'type')\">OHCA<\/button><br \/>\n            <button class=\"ja-btn ja-type-btn\" onclick=\"jaLog('\u60a3\u8005\u985e\u5225: IHCA', 'type')\">IHCA<\/button>\n        <\/div>\n<\/p><\/div>\n<div class=\"panel\">\n<div class=\"ja-header-row\">\n<h2>\u8a08\u6642 \/ \u7d00\u9304<\/h2>\n<p>            <button class=\"ja-stop-btn\" onclick=\"jaStopAll()\">\u7d50\u675f\u4efb\u52d9<\/button>\n        <\/div>\n<div id=\"ja-global-timer\">00:00:00<\/div>\n<div id=\"ja-log-stream\">\n<div class=\"ja-log-entry\"><span>&#8211;:&#8211;<\/span><span>\u7cfb\u7d71\u5f85\u547d&#8230;<\/span><\/div>\n<\/p><\/div>\n<div style=\"display:flex; gap:5px; margin-top:auto; padding-top: 10px;\">\n            <button class=\"ja-btn\" style=\"flex:1\" onclick=\"jaLog('H\\'s &#038; T\\'s \u8a55\u4f30')\">H&#8217;s &#038; T&#8217;s<\/button><br \/>\n            <button class=\"ja-btn\" style=\"flex:1\" onclick=\"jaExport()\">\u8f38\u51fa\u7d00\u9304<\/button>\n        <\/div>\n<\/p><\/div>\n<p>    <script>\n        (function() {\n            let audioCtx; \n            let globalTimer, cprTimer, metroTimer, epiInt;\n            let startTime, cprLeft = 120, mode = '30:2';\n            let beat = 0; \n            let paused = false;\n            let metroEnabled = true;<\/p>\n<p>            const circle = document.getElementById('ja-breath-ring');\n            const radius = circle.r.baseVal.value;\n            const circumference = radius * 2 * Math.PI;\n            circle.style.strokeDasharray = `${circumference} ${circumference}`;\n            circle.style.strokeDashoffset = 0; <\/p>\n<p>            \/\/ \u6a21\u5f0f\u53c3\u6578\n            const MODES = {\n                '30:2': { limit: 30, type: 'ratio' }, \n                '15:2': { limit: 15, type: 'ratio' },\n                'CONT': { limit: 0, type: 'cont' }, \n                'LUCAS': { limit: 12, type: 'lucas' }, \/\/ 12 ticks = 6 sec\n                'ROSC': { limit: 12, type: 'lucas' }\n            };<\/p>\n<p>            \/\/ === \u6838\u5fc3\u529f\u80fd ===<\/p>\n<p>            window.jaStart = function() {\n                const AC = window.AudioContext || window.webkitAudioContext;\n                audioCtx = new AC();\n                document.getElementById('ja-overlay').style.display = 'none';\n                startTime = new Date();\n                globalTimer = setInterval(updateGlobal, 1000);\n                startCPR();\n                startMetro();\n                jaLog('\u6025\u6551\u6d41\u7a0b\u555f\u52d5 (Code Blue Started)');\n            };<\/p>\n<p>            window.jaStopAll = function() {\n                clearInterval(globalTimer);\n                clearInterval(cprTimer);\n                clearInterval(metroTimer);\n                clearInterval(epiInt);<\/p>\n<p>                document.getElementById('ja-status-text').innerText = \"\u4efb\u52d9\u5df2\u7d50\u675f\";\n                document.getElementById('ja-cpr-display').innerText = \"STOP\";\n                document.getElementById('ja-cpr-display').style.color = \"#ff1744\";\n                document.getElementById('ja-breath-hint').innerText = \"\";\n                circle.style.strokeDashoffset = 0;<\/p>\n<p>                \/\/ \u91cd\u7f6e Epi \u6309\u9215\u72c0\u614b\n                const epiBtn = document.getElementById('ja-epi-btn');\n                epiBtn.classList.remove('epi-alert'); \/\/ \u79fb\u9664\u8b66\u793a\n                document.getElementById('ja-epi-status').innerText = \"\u6e96\u5099\u5c31\u7dd2\";\n                document.getElementById('ja-epi-progress').style.width = '0%';<\/p>\n<p>                document.getElementById('ja-metro-btn').classList.remove('on');\n                document.getElementById('ja-metro-btn').innerText = \"\u5df2\u505c\u6b62\";\n                jaLog('\u4efb\u52d9\u7d50\u675f (Mission Ended)', 'end');\n            };<\/p>\n<p>            window.jaSetMode = function(m, btn) {\n                document.querySelectorAll('.ja-mode-grid .ja-btn').forEach(b => b.classList.remove('active'));\n                document.getElementById('ja-rosc-trigger').classList.remove('active');\n                if(btn) btn.classList.add('active');<\/p>\n<p>                mode = m; \n                resetBeatCounter(); <\/p>\n<p>                let text = \"CPR \u9032\u884c\u4e2d\";\n                let logText = m;<\/p>\n<p>                if (m === 'LUCAS') {\n                    text = \"\";\n                    logText = \"6\u79d2\u7d66\u6c27\"; \n                }\n                if (m === 'CONT') {\n                    text = \"CPR \u9032\u884c\u4e2d\";\n                    logText = \"\u9023\u7e8c\u6309\u58d3\"; \n                }\n                if (m === 'ROSC') {\n                    text = \"ROSC \/ \u547c\u5438\u7167\u8b77\";\n                    document.getElementById('ja-rosc-trigger').classList.add('active');\n                    logText = \"ROSC\";\n                }<\/p>\n<p>                document.getElementById('ja-status-text').innerText = text;\n                jaLog('\u6a21\u5f0f\u5207\u63db: ' + logText);\n            };<\/p>\n<p>            window.jaTriggerROSC = function() {\n                jaSetMode('ROSC', null);\n                jaLog('\u60a3\u8005\u6062\u5fa9\u81ea\u767c\u5faa\u74b0 (ROSC) - \u9032\u5165\u7167\u8b77\u6a21\u5f0f', 'rosc');\n            };<\/p>\n<p>            window.jaToggleMetro = function() {\n                metroEnabled = !metroEnabled;\n                const btn = document.getElementById('ja-metro-btn');\n                if(metroEnabled) {\n                    btn.classList.add('on');\n                    btn.innerHTML = '\u7bc0\u62cd\u5668\uff1a\u958b';\n                    startMetro(); \n                } else {\n                    btn.classList.remove('on');\n                    btn.innerHTML = '\u7bc0\u62cd\u5668\uff1a\u95dc';\n                    if(metroTimer) clearInterval(metroTimer);\n                    resetBeatCounter(); \n                }\n            };<\/p>\n<p>            function resetBeatCounter() {\n                beat = 0;\n                paused = false;\n                circle.style.strokeDashoffset = 0;\n                document.getElementById('ja-breath-hint').innerText = \"\u6e96\u5099\u4e2d...\";\n                if(metroEnabled) startMetro();\n            }<\/p>\n<p>            \/\/ === \u96fb\u64ca\u8207\u5fc3\u5f8b ===\n            window.jaLogAED = function() {\n                jaLog('AED \u96fb\u64ca', 'shock');\n                resetCPRCycle();\n            };<\/p>\n<p>            window.jaLogManualShock = function() {\n                const j = document.getElementById('ja-joule-select').value;\n                jaLog(`\u624b\u52d5\u96fb\u64ca ${j}J (Manual Shock)`, 'shock');\n                resetCPRCycle();\n            };<\/p>\n<p>            window.jaLogECG = function(select) {\n                const val = select.value;\n                if(val) {\n                    jaLog(`\u5fc3\u5f8b\u8a55\u4f30: ${val}`, 'ecg');\n                    select.selectedIndex = 0;\n                }\n            };<\/p>\n<p>            function resetCPRCycle() {\n                cprLeft = 120; \n                updateCPR();\n                jaLog('\u5faa\u74b0\u91cd\u7f6e (Cycle Reset)');\n            }<\/p>\n<p>            \/\/ === Epinephrine (\u908f\u8f2f\u4fee\u6b63\u7248) ===\n            window.jaEpi = function() {\n                const btn = document.getElementById('ja-epi-btn');\n                const stat = document.getElementById('ja-epi-status');\n                const bar = document.getElementById('ja-epi-progress');<\/p>\n<p>                jaLog('\u7d66\u4e88 Epinephrine 1mg', 'drug');<\/p>\n<p>                \/\/ \u91cd\u7f6e\u72c0\u614b\n                btn.classList.remove('epi-alert');<\/p>\n<p>                \/\/ 3\u5206\u9418\u5012\u6578 = 180s\n                const epiTime = 180; <\/p>\n<p>                \/\/ \u9032\u5ea6\u689d\u52d5\u756b\n                bar.style.transition = 'none'; bar.style.width = '0%';\n                \/\/ \u986f\u793a\u9032\u5ea6\u689d\n                bar.style.display = 'block';<\/p>\n<p>                setTimeout(() => { bar.style.transition = `width ${epiTime}s linear`; bar.style.width = '100%'; }, 50);<\/p>\n<p>                let t = epiTime; \n                if(epiInt) clearInterval(epiInt);\n                stat.innerText = `\u4e0b\u5291\u5012\u6578: 03:00`;<\/p>\n<p>                epiInt = setInterval(() => {\n                    t--;\n                    let m = Math.floor(t\/60), s = t%60;\n                    stat.innerText = `\u4e0b\u5291\u5012\u6578: ${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`;<\/p>\n<p>                    \/\/ \u6642\u9593\u5230\n                    if(t<=0) { \n                        clearInterval(epiInt); \n                        stat.innerText = \"\u8acb\u7acb\u5373\u7d66\u85e5 (GIVE NOW)!\"; \n                        tone(1500, 500); \/\/ \u8b66\u793a\u97f3\n\n                        \/\/ \u89f8\u767c\u5be6\u5fc3\u7da0\u8272\u8272\u584a + \u547c\u5438\u71c8\n                        btn.classList.add('epi-alert');\n                    }\n                }, 1000);\n            };\n\n            window.jaLog = function(txt, type='') {\n                const div = document.createElement('div');\n                div.className = `ja-log-entry ${type}`;\n                const now = new Date();\n                const h = now.getHours().toString().padStart(2,'0');\n                const m = now.getMinutes().toString().padStart(2,'0');\n                const s = now.getSeconds().toString().padStart(2,'0');\n                div.innerHTML = `<span>${h}:${m}:${s}<\/span><span>${txt}<\/span>`;\n                document.getElementById('ja-log-stream').prepend(div);\n            };<\/p>\n<p>            window.jaExport = function() {\n                 let t = \"\u4eac\u5b89\u6551\u8b77 Code Blue \u7d00\u9304\\n=======================\\n\";\n                 document.querySelectorAll('.ja-log-entry').forEach(e => {\n                     t += e.innerText.replace(\/\\n\/g, ' ') + \"\\n\";\n                 });\n                 const b = new Blob([t], {type:'text\/plain'});\n                 const a = document.createElement('a');\n                 a.href = URL.createObjectURL(b); a.download = `JingAn_Log_${new Date().getTime()}.txt`;\n                 a.click();\n            };<\/p>\n<p>            \/\/ === \u8a08\u6642\u8207\u908f\u8f2f ===<\/p>\n<p>            function updateGlobal() {\n                const d = new Date() - startTime;\n                const s = Math.floor((d\/1000)%60);\n                const m = Math.floor((d\/60000)%60);\n                const h = Math.floor(d\/3600000);\n                document.getElementById('ja-global-timer').innerText = \n                    `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`;\n            }<\/p>\n<p>            function startCPR() {\n                if(cprTimer) clearInterval(cprTimer);\n                cprLeft = 120; updateCPR();\n                cprTimer = setInterval(() => {\n                    cprLeft--; updateCPR();\n                    if(cprLeft===20 && mode !== 'ROSC') tone(800, 200); \n                    if(cprLeft<=0) { \n                        if (mode !== 'ROSC') tone(2000, 1000); \n                        cprLeft = 120; \n                        if (mode !== 'ROSC') jaLog('\u5169\u5206\u9418\u5faa\u74b0\u7d50\u675f (Cycle Finished)');\n                    }\n                }, 1000);\n            }\n\n            function updateCPR() {\n                document.getElementById('ja-cpr-display').innerText = \n                    `${Math.floor(cprLeft\/60).toString().padStart(2,'0')}:${(cprLeft%60).toString().padStart(2,'0')}`;\n\n                const disp = document.getElementById('ja-cpr-display');\n                if (cprLeft <= 20 &#038;&#038; mode !== 'ROSC') {\n                     disp.style.color = '#ffea00';\n                } else {\n                     disp.style.color = '#e0e0e0';\n                }\n            }\n\n            function setCountdown(percentDone) {\n                const offset = (percentDone \/ 100) * circumference;\n                circle.style.strokeDashoffset = offset;\n            }\n\n            function startMetro() {\n                if(metroTimer) clearInterval(metroTimer);\n                if(!metroEnabled) return;\n\n                metroTimer = setInterval(() => {\n                    const cfg = MODES[mode];\n                    if(paused) return; <\/p>\n<p>                    beat++;<\/p>\n<p>                    \/\/ CONT: \u7d14\u6309\u58d3\n                    if (cfg.type === 'cont') {\n                        if(metroEnabled) tone(3300, 50);\n                        circle.style.strokeDashoffset = 0; \n                        document.getElementById('ja-breath-hint').innerText = \"\u6301\u7e8c\u6309\u58d3\";\n                        return;\n                    }<\/p>\n<p>                    \/\/ LUCAS: \u5012\u6578\u79d2\u6578\n                    if (cfg.type === 'lucas') {\n                        let remainTicks = cfg.limit - beat;\n                        let remainSeconds = Math.ceil(remainTicks \/ 2);<\/p>\n<p>                        let percentDone = (beat \/ cfg.limit) * 100;\n                        setCountdown(percentDone);<\/p>\n<p>                        document.getElementById('ja-breath-hint').innerText = `\u5012\u6578: ${remainSeconds}s`;<\/p>\n<p>                        if (beat >= cfg.limit) {\n                            if(metroEnabled) tone(1000, 800);\n                            flash();\n                            beat = 0; \n                            setTimeout(() => { circle.style.strokeDashoffset = 0; }, 200);\n                        }\n                        return;\n                    }<\/p>\n<p>                    \/\/ 30:2 \/ 15:2\n                    if(metroEnabled) tone(3300, 50); <\/p>\n<p>                    let percentDone = (beat \/ cfg.limit) * 100;\n                    setCountdown(percentDone);\n                    document.getElementById('ja-breath-hint').innerText = `\u8a08\u6578: ${beat}`;<\/p>\n<p>                    if(beat >= cfg.limit) {\n                        paused = true;\n                        beat = 0;\n                        \/\/ \u4fee\u6b63\uff1a\u6587\u5b57\u50c5\u986f\u793a\u300c\u7d66\u6c27\u300d\n                        document.getElementById('ja-breath-hint').innerText = \"\u7d66\u6c27\";\n                        runDoubleBreathSequence(); \n                    }<\/p>\n<p>                }, 500); \n            }<\/p>\n<p>            function runDoubleBreathSequence() {\n                circle.style.strokeDashoffset = circumference; <\/p>\n<p>                if(metroEnabled) tone(1000, 800); \n                flash();<\/p>\n<p>                setTimeout(() => {\n                    if(metroEnabled) tone(1000, 800); \n                    flash();\n                }, 1200); <\/p>\n<p>                setTimeout(() => {\n                    paused = false;\n                    circle.style.strokeDashoffset = 0;\n                    document.getElementById('ja-breath-hint').innerText = \"\u6e96\u5099\u4e2d...\";\n                }, 2400);\n            }<\/p>\n<p>            function tone(f, d) {\n                if(!audioCtx) return;\n                const o = audioCtx.createOscillator();\n                const g = audioCtx.createGain();\n                o.type = 'square'; \n                o.frequency.value = f;\n                const volume = 0.5; \n                g.gain.setValueAtTime(volume, audioCtx.currentTime);\n                g.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + d\/1000);\n                o.connect(g); \n                g.connect(audioCtx.destination);\n                o.start(); \n                o.stop(audioCtx.currentTime + d\/1000);\n            }<\/p>\n<p>            function flash() {\n                const a = document.getElementById('ja-vent');\n                a.style.display='block'; \n                setTimeout(()=>a.style.display='none', 800);\n            }<\/p>\n<p>        })();\n    <\/script>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<div style=\"height: 20px; overflow: hidden; width: 100%;\"><\/div>\n<hr class=\"styled-hr\" style=\"width:100%;\"><\/hr>\n<div style=\"height: 20px; overflow: hidden; width: 100%;\"><\/div>\n<\/div>\n<div class=\"paragraph\">&#21487;&#19979;&#36617;&#19979;&#26041;QRcode&#35069;&#20316;&#25104;&#36028;&#32025;&#24373;&#36028;&#26044;&#36554;&#20839;&#12289;&#25812;&#26550;&#65292;&#25110;DIY&#21514;&#29260;&#12290;<\/div>\n<div style=\"text-align:left;\">\n<a class=\"wsite-button wsite-button-small wsite-button-normal\" href=\"\/wp-content\/uploads\/weebly-migration\/20218817\/cpr%E5%8A%A9%E6%89%8B_qrcode.pdf\" ><br \/>\n<span class=\"wsite-button-inner\">\u4e0b\u8f09QR code<\/span><br \/>\n<\/a>\n<\/div>\n<div>\n<div id=\"706208695694511369\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\">\n<div style=\"text-align: center; font-family: 'Microsoft JhengHei', sans-serif; padding: 20px; max-width: 500px; margin: 0 auto;\">\n<p>    <button onclick=\"showInstallInstruction()\" style=\"background-color: #d9534f; color: white; padding: 15px 25px; border: none; border-radius: 10px; font-size: 18px; font-weight: bold; cursor: pointer; width: 100%; box-shadow: 0 4px 6px rgba(0,0,0,0.2); transition: 0.3s;\"><br \/>\n       \u5c07\u6b64\u5de5\u5177\u52a0\u5165\u624b\u6a5f\u684c\u9762<br \/>\n    <\/button><\/p>\n<div style=\"margin-top: 30px; padding: 15px; background-color: #f9f9f9; border-radius: 8px; border: 1px dashed #ccc;\">\n<h4 style=\"margin: 0 0 10px 0; color: #333; font-size: 16px;\">\u95dc\u65bc\u6b64\u5de5\u5177<\/h4>\n<p style=\"color: #666; font-size: 14px; line-height: 1.8; text-align: left; margin: 0;\">\n            \u9019\u662f\u4e00\u500b\u70ba\u4e86\u6025\u6551\u73fe\u5834\u800c\u751f\u7684\u5de5\u5177\uff0c\u672c\u300c\u7dda\u4e0a CPR \u8f14\u52a9\u5de5\u5177\u300d\u7531\u5927\u96b1\u65bc\u5e02\u8a2d\u8a08\u5de5\u4f5c\u5ba4\u5354\u529b\u958b\u767c\u8a2d\u8a08\uff0c\u7248\u6b0a\u6240\u6709\u3002<\/p>\n<p>            \u672c\u5de5\u5177\u50c5\u4f9b\u6025\u6551\u6559\u5b78\u8207\u6025\u6551\u4eba\u54e1\u8f14\u52a9\u4f7f\u7528\uff0c\u5c07\u6b64\u5de5\u5177\u7121\u511f\u958b\u653e\u4e88\u793e\u6703\u5927\u773e\u53ca\u7b2c\u4e00\u7dda\u5925\u4f34\u4f7f\u7528\u3002\u6b61\u8fce\u5ee3\u70ba\u6d41\u50b3\uff0c\u4f46\u8acb\u5c0a\u91cd\u667a\u6167\u8ca1\u7522\u6b0a\uff0c\u672a\u7d93\u7248\u6b0a\u6240\u6709\u8005\u66f8\u9762\u6388\u6b0a\uff0c\u7981\u6b62\u4efb\u4f55\u5f62\u5f0f\u4e4b\u5546\u696d\u71df\u5229\u3001\u7a0b\u5f0f\u78bc\u91cd\u88fd\u6216\u4fee\u6539\u5f8c\u91cd\u65b0\u767c\u4f48\u3002\n        <\/p>\n<\/p><\/div>\n<p style=\"color: #999; font-size: 12px; margin-top: 10px;\">\u00a9 2026 \u5927\u96b1\u65bc\u5e02 All Rights Reserved.<\/p>\n<\/div>\n<p><script>\nfunction showInstallInstruction() {\n    var userAgent = navigator.userAgent || navigator.vendor || window.opera;\n    if (\/iPad|iPhone|iPod\/.test(userAgent) && !window.MSStream) {\n        alert(\"\u3010 iPhone \/ iOS \u6559\u5b78 \u3011\\n\\n1. \u9ede\u9078\u700f\u89bd\u5668\u4e0b\u65b9\u300c\u5206\u4eab\u300d\u6309\u9215 (\u7bad\u982d\u5716\u793a)\\n2. \u9078\u64c7\u300c\u52a0\u5165\u4e3b\u756b\u9762\u300d\\n\\n\u5b8c\u6210\u5f8c\uff0c\u684c\u9762\u6703\u51fa\u73fe\u5716\u793a\uff0c\u958b\u555f\u5f8c\u70ba\u5168\u87a2\u5e55\u6a21\u5f0f\u3002\");\n    } else if (\/android\/i.test(userAgent)) {\n        alert(\"\u3010 Android \u6559\u5b78 \u3011\\n\\n1. \u9ede\u9078\u700f\u89bd\u5668\u53f3\u4e0a\u89d2\u300c\u4e09\u9ede\u9078\u55ae\u300d\\n2. \u9ede\u9078\u300c\u52a0\u5230\u4e3b\u756b\u9762\u300d\\n\\n\u5b8c\u6210\u5f8c\u5373\u53ef\u50cf APP \u4e00\u6a23\u5feb\u901f\u958b\u555f\u3002\");\n    } else {\n        alert(\"\u8acb\u5728\u624b\u6a5f\u4e0a\u958b\u555f\u6b64\u7db2\u9801\uff0c\u5373\u53ef\u5b89\u88dd\u5230\u684c\u9762\u4f7f\u7528\u3002\");\n    }\n}\n<\/script><\/div>\n<\/div>\n<div>\n<div id=\"454449223892190058\" align=\"left\" style=\"width: 100%; overflow-y: hidden;\" class=\"wcustomhtml\"><script async src=\"\/\/busuanzi.ibruce.info\/busuanzi\/2.3\/busuanzi.pure.mini.js\"><\/script><\/p>\n<style>\n  .cpr-counter {\n    font-family: \"Microsoft JhengHei\", sans-serif;\n    font-size: 14px;\n    color: #888;\n    text-align: center;\n    padding: 10px 0;\n    margin-top: 20px;\n    border-top: 1px solid #eee; \/* \u4e0a\u65b9\u52a0\u4e00\u689d\u7d30\u7dda\u505a\u5340\u9694 *\/\n  }\n  .cpr-number {\n    font-weight: bold;\n    color: #d9534f; \/* \u7dad\u6301\u6551\u8b77\u7d05\u8272\u7cfb *\/\n    font-size: 16px;\n    margin: 0 4px;\n  }\n<\/style>\n<div class=\"cpr-counter\">\n  <span id=\"busuanzi_container_page_pv\" style=\"display:none\"><br \/>\n    CPR \u52a9\u624b\u7d2f\u8a08\u8a2a\u5ba2\uff1a<span id=\"busuanzi_value_page_pv\" class=\"cpr-number\">&#8230;<\/span> \u6b21<br \/>\n  <\/span>\n<\/div>\n<\/div>\n<\/div><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u5c08\u70ba\u4e00\u822c\u6c11\u773e EMT \u8207\u6025\u6551\u4eba\u54e1\u8a2d\u8a08\u7684\u7dda\u4e0a CPR \u8f14\u52a9\u7db2\u9801\u3002\u5167\u5efa 120bpm \u7bc0\u62cd\u5668\u3001CPR \u5faa\u74b0\u5012\u6578\u74b0\uff0c\u652f\u63f4ACLS\u7d00\u9304\u8207\u63d0\u9192\u3002\u514d\u5b89\u88dd APP\uff0c\u700f\u89bd\u5668\u5373\u958b\u5373\u7528\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1004","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/pages\/1004","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/comments?post=1004"}],"version-history":[{"count":0,"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/pages\/1004\/revisions"}],"wp:attachment":[{"href":"https:\/\/ksambulance.com\/cms\/wp-json\/wp\/v2\/media?parent=1004"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}