1/* ============================================================ 2 NBé¢é · çªèéï¼å ¨å±æ¬æµ®ï¼ 3 ------------------------------------------------------------ 4 åªå¨ãæ¤ç¼ä¸»é¢ãä¸åºç°ãæå¨å³ä¸è§ï¼åªä¸ªé¡µé¢é½å¨ï¼ 5 å页é¢ä¸ä¼éç½® ââ å ³é®æ¯ä¸åãè¿å©å¤å°ç§ãï¼èæ¯å 6 ãè¿ä¸è½®ä»ä¹æ¶åç»æãçç»å¯¹æ¶é´æ³ï¼å页忿¶é´æ³éç®ã 7 8 çªèéè§åï¼ç»å ¸çé£å¥ï¼ï¼ 9 䏿³¨ 25 åé â ç伿¯ 5 åé 10 æ¯å®æ 4 è½®ä¸æ³¨ â é¿ä¼æ¯ 15 åé 11 12 ç¶æå localStorageï¼ 13 nb_pomo = { phase, endsAt, running, remain, rounds, day } 14 phase work | short | long 15 endsAt æ¬è½®ç»æçç»å¯¹æ¶å»ï¼æ¯«ç§ï¼ 16 remain æåæ¶å©ä¸çæ¯«ç§æ°ï¼æåæç¨å¾å°ï¼ 17 rounds ä»å¤©å·²å®æå è½®ä¸æ³¨ 18 day è®°å½å±äºåªä¸å¤©ï¼è·¨å¤©èªå¨æ¸ é¶ 19 ============================================================ */ 20(function () { 21 'use strict'; 22 23 var KEY = 'nb_pomo'; 24 var DUR = { work: 25 * 60 * 1000, short: 5 * 60 * 1000, long: 15 * 60 * 1000 }; 25 var NAME = { work: '䏿³¨ä¸', short: 'ç伿¯', long: 'é¿ä¼æ¯' }; 26 var CSS_ID = 'nbPomoCss'; 27 var BOX_ID = 'nbPomoBox'; 28 29 /* ---------- 主é¢å¤æ ---------- */ 30 function isEyecare() { 31 return document.documentElement.getAttribute('theme') === 'eyecare'; 32 } 33 34 /* ---------- ç¶æ ---------- */ 35 function today() { 36 var d = new Date(); 37 return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); 38 } 39 function load() { 40 var st = null; 41 try { st = JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) {} 42 if (!st || typeof st !== 'object') st = {}; 43 if (st.day !== today()) { st.rounds = 0; st.day = today(); } 44 if (st.phase !== 'work' && st.phase !== 'short' && st.phase !== 'long') st.phase = 'work'; 45 if (typeof st.running !== 'boolean') st.running = false; 46 if (typeof st.rounds !== 'number') st.rounds = 0; 47 if (typeof st.remain !== 'number' || st.remain <= 0) st.remain = -1; /* å ä½ï¼ä¸é¢æ min éç® */ 48 if (typeof st.endsAt !== 'number') st.endsAt = 0; 49 /* èªå®ä¹ç䏿®µæ¶é¿ï¼åéï¼ï¼æ²¡è®¾è¿å°±ç¨é»è®¤ç 25/5/15 */ 50 if (!st.min || typeof st.min !== 'object') st.min = {}; 51 ['work', 'short', 'long'].forEach(function (k) { 52 var v = parseInt(st.min[k], 10); 53 if (!(v >= 1 && v <= 180)) st.min[k] = DUR[k] / 60000; 54 }); 55 if (typeof st.total !== 'number') st.total = 0; /* 仿¥ä¸æ³¨æ»åé */ 56 if (st.remain === -1) st.remain = durOf(st, st.phase); 57 return st; 58 } 59 function save(st) { 60 try { localStorage.setItem(KEY, JSON.stringify(st)); } catch (e) {} 61 } 62 /* å½åè¿å©å¤å°æ¯«ç§ */ 63 function remainOf(st) { 64 if (!st.running) return st.remain; 65 var r = st.endsAt - Date.now(); 66 return r > 0 ? r : 0; 67 } 68 /* åæä¸é¶æ®µå½åçæ¶é¿ï¼æ¯«ç§ï¼ï¼ä»¥ç¨æ·è®¾ç½®ä¸ºå */ 69 function durOf(st, phase) { 70 return (st.min && st.min[phase] ? st.min[phase] : DUR[phase] / 60000) * 60000; 71 } 72 function fmt(ms) { 73 var s = Math.max(0, Math.ceil(ms / 1000)); 74 var m = Math.floor(s / 60); 75 s = s % 60; 76 return (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s; 77 } 78 79 /* ---------- æ¨è¿å°ä¸ä¸é¶æ®µ ---------- */ 80 function advance(st) { 81 if (st.phase === 'work') { 82 st.rounds += 1; 83 st.total += st.min.work; /* ç´¯è®¡ä»æ¥ä¸æ³¨åé */ 84 st.phase = (st.rounds % 4 === 0) ? 'long' : 'short'; 85 } else { 86 st.phase = 'work'; 87 } 88 st.remain = durOf(st, st.phase); 89 st.endsAt = Date.now() + st.remain; 90 st.running = true; 91 } 92 93 /* ---------- æ ·å¼ ---------- */ 94 var CSS = [ 95 /* bottom è¦é¿å¼é¡µé¢å³ä¸è§çãåå°é¡¶é¨ãæé®ï¼ 96 宿¯ fixed; right:26px; bottom:26px; 46x46ï¼ 97 ä¹å°±æ¯å å° 72px é«ãæä»¥è¿éä» 88px èµ·ï¼ 98 æ£å¥½åå¨å®ä¸é¢ï¼ä¸é´ç 16px 空éã 99 ç§»å¨ç«¯å®åæ right:18px; bottom:18px; 42x42ï¼å 60pxï¼ï¼ 100 å¯¹åºæªå° 76pxã */ 101 '#nbPomoBox{position:fixed;right:24px;bottom:88px;z-index:9998;', 102 ' font-family:system-ui,-apple-system,"Microsoft YaHei",sans-serif;}', 103 /* æ¬æµ®å°ç */ 104 '.nb-pomo-ball{width:52px;height:52px;border-radius:50%;cursor:pointer;', 105 ' border:none;padding:0;font-size:24px;line-height:1;', 106 ' background:radial-gradient(circle at 34% 30%,#ff8b7a,#c0392b 70%);', 107 ' box-shadow:0 6px 20px -6px rgba(140,47,35,.7),0 2px 6px rgba(0,0,0,.25);', 108 ' transition:transform .18s ease;display:flex;align-items:center;justify-content:center;}', 109 '.nb-pomo-ball:hover{transform:scale(1.07);}', 110 '.nb-pomo-ball .ring{position:absolute;inset:-4px;border-radius:50%;', 111 ' border:2px solid rgba(140,47,35,.35);}', 112 '.nb-pomo-ball .mini{position:absolute;bottom:-2px;right:-2px;', 113 ' background:#3a3630;color:#f4f0e6;font-size:10px;font-weight:700;', 114 ' padding:1px 5px;border-radius:8px;letter-spacing:.5px;}', 115 /* å±å¼ç颿¿ */ 116 /* 颿¿è¦ç»å®åºï¼æ¤ç¼ä¸»é¢é£è¾¹çè§åä¼è¦çèæ¯ç±»å±æ§ï¼ 117 ä¸å !important ä¼ååéæï¼åé¢çæ£æé䏿¥å¾ç³ */ 118 '.nb-pomo-panel{position:absolute;right:0;bottom:68px;width:250px;', 119 ' background:#fdfbf6 !important;border:1px solid rgba(58,54,48,.2) !important;', 120 ' border-radius:14px;
120box-shadow:0 20px 48px -20px rgba(40,34,26,.55);', 121 ' padding:18px 18px 14px;display:none;}', 122 '.nb-pomo-panel.open{display:block;animation:nbPomoIn .18s ease-out;}', 123 '@keyframes nbPomoIn{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}', 124 '.nb-pomo-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;}', 125 '.nb-pomo-head .t{font-size:.78rem;letter-spacing:2px;color:#6b6459;font-weight:700;}', 126 '.nb-pomo-head .x{border:none;background:transparent;cursor:pointer;', 127 ' color:#8b8375;font-size:1.1rem;line-height:1;padding:2px 4px;}', 128 '.nb-pomo-head .x:hover{color:#8c2f23;}', 129 '.nb-pomo-mid{display:flex;align-items:center;gap:14px;}', 130 '.nb-pomo-ring{position:relative;width:96px;height:96px;flex:0 0 auto;}', 131 '.nb-pomo-ring svg{display:block;transform:rotate(-90deg);}', 132 '.nb-pomo-ring .tk{fill:none;stroke:rgba(58,54,48,.14);stroke-width:8;}', 133 '.nb-pomo-ring .br{fill:none;stroke:#8c2f23;stroke-width:8;stroke-linecap:round;', 134 ' transition:stroke-dashoffset .95s linear,stroke .35s;}', 135 '.nb-pomo-ring.rest .br{stroke:#7a8a55;}', 136 '.nb-pomo-ring .time{position:absolute;inset:0;display:flex;align-items:center;', 137 ' justify-content:center;font-size:1.32rem;font-weight:300;color:#2e2a24 !important;', 138 ' font-variant-numeric:tabular-nums;letter-spacing:1px;}', 139 '.nb-pomo-side .ph{font-size:.92rem;font-weight:800;color:#2e2a24 !important;letter-spacing:2px;}', 140 '.nb-pomo-side .rd{margin-top:8px;font-size:.72rem;color:#7a7266;line-height:1.8;}', 141 '.nb-pomo-side .rd b{color:#8c2f23;}', 142 '.nb-pomo-btns{display:flex;gap:6px;margin-top:14px;flex-wrap:wrap;}', 143 '.nb-pomo-btns button{flex:1;min-width:58px;padding:7px 6px;border-radius:7px;cursor:pointer;', 144 ' font-family:inherit;font-size:.72rem;letter-spacing:.5px;border:none;', 145 ' background:#6b5a3e;color:#e0d9cb;}', 146 '.nb-pomo-btns button:hover{background:#544730;}', 147 '.nb-pomo-btns button.gh{background:transparent;color:#6b5a3e;', 148 ' border:1px solid rgba(107,90,62,.4);}', 149 '.nb-pomo-btns button.gh:hover{background:rgba(107,90,62,.12);}', 150 '.nb-pomo-tip{margin-top:10px;font-size:.68rem;color:#8b8375;line-height:1.7;}', 151 /* å 嵿¨¡å¼ï¼é¦é¡µé£åï¼ï¼æ´è¡æå®½ï¼æ¨ªåæå¸ */ 152 /* å 嵿¨¡å¼ä¸å°çè¦æ¾ç¤ºï¼ä½é£ä¸ªæµ®å¨é¢æ¿ä¸è½ååºæ¥ 153 ï¼å 容已ç»å¨å åµé£åéäºï¼åæ¥ä¸ä¸ªå°±éå¤ï¼ */ 154 '#nbPomoBox.nb-pomo-inline .nb-pomo-panel{', 155 ' position:relative;right:auto;bottom:auto;width:100%;max-width:none;', 156 ' display:block !important;animation:none;}', 157 '#nbPomoBox.nb-pomo-inline{position:relative;right:auto;bottom:auto;', 158 ' width:100%;display:block;}', 159 '#nbPomoBox.nb-pomo-inline .nb-pomo-ball{', 160 ' position:fixed;right:24px;bottom:88px;z-index:9998;}', 161 '#nbPomoBox.nb-pomo-inline .nb-pomo-panel{padding:26px 30px 22px;}', 162 '#nbPomoBox.nb-pomo-inline .nb-pomo-ring{width:126px;height:126px;}', 163 '#nbPomoBox.nb-pomo-inline .nb-pomo-ring svg{width:126px;height:126px;}', 164 '#nbPomoBox.nb-pomo-inline .nb-pomo-ring .time{font-size:1.85rem;}', 165 '#nbPomoBox.nb-pomo-inline .nb-pomo-side .ph{font-size:1.12rem;}', 166 /* 横å䏿®µï¼åç¯ | ç¶æä¸è®°å½ | æé® */ 167 '#nbPomoBox.nb-pomo-inline .nb-pomo-mid{gap:34px;}', 168 '#nbPomoBox.nb-pomo-inline .nb-pomo-body{display:flex;align-items:center;', 169 ' justify-content:space-between;gap:34px;flex-wrap:wrap;}', 170 '#nbPomoBox.nb-pomo-inline .nb-pomo-side{flex:1;min-width:190px;}', 171 '#nbPomoBox.nb-pomo-inline .nb-pomo-btns{margin-top:0;flex:0 0 auto;', 172 ' flex-direction:column;min-width:120px;}', 173 '#nbPomoBox.nb-pomo-inline .nb-pomo-btns button{width:100%;padding:9px 18px;', 174 ' font-size:.78rem;}', 175 '#nbPomoBox.nb-pomo-inline .nb-pomo-head .t{font-size:.86rem;}', 176 '#nbPomoBox.nb-pomo-inline .nb-pomo-head .stat{font-size:.78rem;color:#6b6459;}', 177 '#nbPomoBox.nb-pomo-inline .nb-pomo-head .stat b{color:#8c2f23;font-size:.95rem;}', 178 /* 仿¥çªèè®°å½ç¹ */ 179 '.nb-pomo-dots{display:flex;gap:5px;margin-top:11px;flex-wrap:wrap;}', 180 '.nb-pomo-dots i{width:13px;height:13px;border-radius:50%;display:block;', 181 ' background:rgba(58,54,48,.16);}', 182 '.nb-pomo-dots i.on{background:#c0392b;}', 183 '.nb-pomo-dots i.now{box-shadow:0 0 0 2px rgba(192,57,43,.3);}', 184 /* æ¶é¿è®¾ç½® */ 185 '.nb-pomo-cfg{display:flex;gap:20px;flex-wrap:wrap;margin-top:18px;', 186 ' padding-top:16px;border-top:1px dashed rgba(58,54,48,.16);', 187 ' font-size:.74rem;color:#7a7266;align-items:center;}', 188 '.nb-pomo-cfg label{display:flex;align-items:center;gap:7px;}', 189 '.nb-pomo-cfg input{width:56px;padding:5px 7px;border-radius:6px;text-align:center;', 190 ' border:1px solid rgba(58,54,48,.24);background:#fff;color:#3a3630;', 191 ' font-family:inherit;font-size:.78rem;outline:none;}', 192 '.nb-pomo-cfg input:focus{border-color:#8c2f23;}', 193 '.nb-pomo-cfg .reset{margin-left:auto;padding:5px 12px;border-radius:6px;', 194 ' cursor:pointer;font-family:inherit;font-size:.72rem;border:none;', 195 ' background:rgba(107,90,62,.14);color:#6b5a3e;}', 196 '.nb-pomo-cfg .reset:hover{background:rgba(107,90,62,.26);}', 197 '@media(max-width:520px){', 198 ' #nbPomoBox{right:16px;bottom:76px;}', 199 ' .nb-pomo-panel{width:calc(100vw - 32px);right:0;}', 200 '}', 201 '@media(prefers-reduced-motion:reduce){', 202 ' .nb-pomo-panel.open{animation:none;}', 203 ' .nb-pomo-ball{transition:none;}', 204 '}' 205 ].join('\n'); 206 207 /* ---------- 颿¿ HTML ---------- */ 208 var R = 42, CIRC = 2 * Math.PI * R; 209 210 function build() { 211 if (document.getElementById(BOX_ID)) return; 212 if (!isEyecare()) return; 213
214 /* 页é¢ä¸å¦æç»äºå åµå®¹å¨ï¼é¦é¡µå°±æï¼ï¼å°±æ¸²æå°é£å¿å»ï¼ 215 è¿ç§æ åµä¸ä¸å建å³ä¸è§çæ¬æµ®çï¼å å¾ä¸¤å¤éå¤ã */ 216 var inlineHost = document.getElementById('nbPomoInline'); 217 218 if (!document.getElementById(CSS_ID)) { 219 var st = document.createElement('style'); 220 st.id = CSS_ID; 221 st.textContent = CSS; 222 document.head.appendChild(st); 223 } 224 225 var box = document.createElement('div'); 226 box.id = BOX_ID; 227 if (inlineHost) box.className = 'nb-pomo-inline'; 228 box.innerHTML = 229 '<div class="nb-pomo-panel" data-panel>' + 230 '<div class="nb-pomo-head">' + 231 '<span class="t">ð çªèé</span>' + 232 '<span class="stat" data-stat></span>' + 233 '<button class="x" data-close title="æ¶èµ·">Ã</button>' + 234 '</div>' + 235 '<div class="nb-pomo-body">' + 236 '<div class="nb-pomo-mid">' + 237 '<div class="nb-pomo-ring" data-ring>' + 238 '<svg width="96" height="96" viewBox="0 0 96 96">' + 239 '<circle class="tk" cx="48" cy="48" r="' + R + '"/>' + 240 '<circle class="br" cx="48" cy="48" r="' + R + '" ' + 241 'stroke-dasharray="' + CIRC.toFixed(1) + '" stroke-dashoffset="0"/>' + 242 '</svg>' + 243 '<div class="time" data-time>25:00</div>' + 244 '</div>' + 245 '<div class="nb-pomo-side">' + 246 '<div class="ph" data-phase>è¿æ²¡å¼å§</div>' + 247 '<div class="rd"><span data-hint>ç¹ãå¼å§ãè¿å ¥ä¸æ³¨</span></div>' + 248 '<div class="nb-pomo-dots" data-dots></div>' + 249 '</div>' + 250 '</div>' + 251 '<div class="nb-pomo-btns">' + 252 '<button data-act="toggle">å¼å§</button>' + 253 '<button class="gh" data-act="skip">è·³è¿</button>' + 254 '<button class="gh" data-act="reset">éç½®</button>' + 255 '</div>' + 256 '</div>' + 257 '<div class="nb-pomo-cfg">' + 258 '<label>䏿³¨ <input type="number" min="1" max="180" data-min="work"> å</label>' + 259 '<label>ç伿¯ <input type="number" min="1" max="60" data-min="short"> å</label>' + 260 '<label>é¿ä¼æ¯ <input type="number" min="1" max="90" data-min="long"> å</label>' + 261 '<button class="reset" data-act="defdur">æ¢å¤é»è®¤</button>' + 262 '</div>' + 263 '<div class="nb-pomo-tip">å页é¢ä¸ä¼éç½® ââ è¿åº¦ææ¶é´æ³ç®ï¼' + 264 'æ¢é¡µåæ¥æ¥çèµ°ãæ¯ 4 è½®ä¸æ³¨åèªå¨è¿é¿ä¼æ¯</div>' + 265 '</div>' + 266 '<button class="nb-pomo-ball" data-ball title="çªèé">' + 267 '<span>ð </span><span class="mini" data-mini></span>' + 268 '</button>'; 269 270 (inlineHost || document.body).appendChild(box); 271 272 var panel = box.querySelector('[data-panel]'); 273 var ringEl = box.querySelector('[data-ring]'); 274 var barEl = box.querySelector('.br'); 275 var timeEl = box.querySelector('[data-time]'); 276 var phaseEl = box.querySelector('[data-phase]'); 277 var statEl = box.querySelector('[data-stat]'); 278 var dotsEl = box.querySelector('[data-dots]'); 279 var hintEl = box.querySelector('[data-hint]'); 280 var miniEl = box.querySelector('[data-mini]'); 281 var toggleBtn = box.querySelector('[data-act="toggle"]'); 282 var ballEl = box.querySelector('[data-ball]'); 283 284 /* å 嵿¨¡å¼ï¼å åµé£å颿¿å¸¸å¼ï¼å®æ¬æ¥å°±æ¯é¡µé¢çä¸é¨åï¼ã 285 注æè¿æ®µå¿ é¡»æ¾å¨ä¸é¢é£æ¹ querySelector ä¹å ââ 286 ä¹ååå¨äº appendChild åé¢ï¼panel è¿æ¯ undefinedï¼ 287 ä¸è° classList å°±æéï¼åé¢ç render() å ¨æ²¡æ§è¡ã 288 289 å°çå¨é¦é¡µãä¹ä¿çãï¼ç«é¿è¯´å³ä¸è§é£ä¸ªæ´é¡ºæï¼ 290 å¨å«ç页é¢ç¨æ¯äºï¼åé¦é¡µåèæ¾ä¸å°ã 291 ç¹å®çè¡ä¸ºå¨ä¸é¢å两ç§å¤çã */ 292 if (inlineHost) { 293 panel.classList.add('open'); 294 } 295 296 /* ç¹å°çï¼ 297 é¦é¡µï¼æå åµé¢æ¿ï¼â å¹³æ»æ»å°å åµé£åï¼ä¸å¦å¼æµ®å± 298 å«çé¡µé¢ â ç §æ§å±å¼ / æ¶èµ·æµ®å¨é¢æ¿ */ 299 ballEl.addEventListener('click', function () { 300 if (inlineHost) { 301 inlineHost.scrollIntoView({ behavior: 'smooth', block: 'center' }); 302 return; 303 } 304 panel.classList.toggle('open'); 305 }); 306 box.querySelector('[data-close]').addEventListener('click', function () { 307 panel.classList.remove('open'); 308 }); 309 310 /* æä½ */ 311 toggleBtn.addEventListener('click', function () { 312 var st = load(); 313 if (st.running) { /* æåï¼æå©ä½åºå䏿¥ */ 314 st.remain = remainOf(st); 315 st.running = false;
316 } else { /* ç»§ç»ï¼ä»å©ä½éæ°èµ·ç® */ 317 st.endsAt = Date.now() + st.remain; 318 st.running = true; 319 } 320 save(st); 321 render(); 322 }); 323 box.querySelector('[data-act="skip"]').addEventListener('click', function () { 324 var st = load(); 325 advance(st); 326 save(st); 327 render(); 328 }); 329 box.querySelector('[data-act="reset"]').addEventListener('click', function () { 330 var st = load(); 331 st.phase = 'work'; 332 st.remain = durOf(st, 'work'); 333 st.running = false; 334 st.endsAt = 0; 335 save(st); 336 render(); 337 }); 338 339 /* ---------- æ¶é¿è®¾ç½® ---------- */ 340 box.querySelectorAll('[data-min]').forEach(function (inp) { 341 inp.addEventListener('change', function () { 342 var st = load(); 343 var v = parseInt(inp.value, 10); 344 if (!(v >= 1 && v <= 180)) { inp.value = st.min[inp.dataset.min]; return; } 345 st.min[inp.dataset.min] = v; 346 /* æ¹çæ£å¥½æ¯å½åé¶æ®µãåæ²¡å¨è·ï¼å°±é¡ºææå©ä½æ¶é´ä¹æ´æ° */ 347 if (st.phase === inp.dataset.min && !st.running) { 348 st.remain = durOf(st, st.phase); 349 } 350 save(st); 351 render(); 352 }); 353 }); 354 box.querySelector('[data-act="defdur"]').addEventListener('click', function () { 355 var st = load(); 356 st.min = { work: 25, short: 5, long: 15 }; 357 st.remain = durOf(st, st.phase); 358 if (st.running) st.endsAt = Date.now() + st.remain; 359 save(st); 360 render(); 361 }); 362 363 /* ---------- 渲æ ---------- */ 364 function render() { 365 var st = load(); 366 var left = remainOf(st); 367 368 /* æ¶é´å°äºï¼èªå¨æ¨è¿ï¼å¯è½æ¯å ³ç页颿¶èµ°å®çï¼æä»¥ç¨ whileï¼ */ 369 var guard = 0; 370 while (st.running && left <= 0 && guard++ < 8) { 371 advance(st); 372 save(st); 373 st = load(); 374 left = remainOf(st); 375 } 376 377 var total = durOf(st, st.phase); 378 var ratio = total > 0 ? Math.max(0, left) / total : 0; 379 barEl.style.strokeDashoffset = (CIRC * (1 - ratio)).toFixed(1); 380 ringEl.classList.toggle('rest', st.phase !== 'work'); 381 382 timeEl.textContent = fmt(left); 383 384 /* é¡¶é¨ç»è®¡ */ 385 var hh = Math.floor(st.total / 60), mm = st.total % 60; 386 if (statEl) statEl.innerHTML = '仿¥ <b>' + st.rounds + '</b> è½®' + 387 (st.total > 0 ? ' · 䏿³¨ <b>' + (hh > 0 ? hh + ' æ¶ ' : '') + mm + '</b> å' : ''); 388 389 /* 仿¥çªèè®°å½ç¹ï¼8 ä¸ªæ ¼åï¼è¶ åºå°±æå æ¾ç¤º */ 390 var SHOW = 8; 391 var n = Math.min(st.rounds, SHOW); 392 var html = ''; 393 for (var i = 0; i < SHOW; i++) { 394 var cls = i < n ? 'on' : ''; 395 if (i === n && st.phase === 'work' && st.running) cls += ' now'; 396 html += '<i class="' + cls + '"></i>'; 397 } 398 if (st.rounds > SHOW) html += '<span style="font-size:.7rem;color:#8c2f23;' + 399 'align-self:center;margin-left:4px">+' + (st.rounds - SHOW) + '</span>'; 400 if (dotsEl) dotsEl.innerHTML = html; 401 402 if (st.running) { 403 phaseEl.textContent = NAME[st.phase]; 404 hintEl.textContent = st.phase === 'work' 405 ? (st.rounds % 4 === 3 ? 'è¿è½®ç»æå°±é¿ä¼æ¯' : 'å«ç¢°ææº') 406 : 'èµ·æ¥èµ°èµ°ï¼ççè¿å¤'; 407 toggleBtn.textContent = 'æå'; 408 } else { 409 phaseEl.textContent = left < total ? 'å·²æå' : 'è¿æ²¡å¼å§'; 410 hintEl.textContent = 'ç¹ãå¼å§ãè¿å ¥ä¸æ³¨'; 411 toggleBtn.textContent = left < total ? 'ç»§ç»' : 'å¼å§'; 412 } 413 miniEl.textContent = fmt(left); 414 415 /* æ¶é¿è¾å ¥æ¡åæ¥ï¼å«å¨ç¨æ·æ£å¨è¾å ¥æ¶è¦çï¼ */ 416 box.querySelectorAll('[data-min]').forEach(function (inp) { 417 if (document.activeElement === inp) return; 418 var v = st.min[inp.dataset.min]; 419 if (inp.value !== String(v)) inp.value = v; 420 }); 421 422 /* æ ç¾é¡µæ é¢ä¹å¸¦ä¸ï¼åå°å«çæ ç¾ä¹è½çè§ */ 423 var base = document.title.replace(/^ð [\d:]+ · /, ''); 424 document.title = (st.running ? 'ð ' + fmt(left) + ' · ' : '') + base; 425 } 426 427 render(); 428 setInterval(render, 1000); 429 430 /* 页é¢ä»åå°å忥æ¶ç«å»å·æ°ä¸æ¬¡ï¼æµè§å¨ä¼èæµå®æ¶å¨ï¼ */ 431 document.addEventListener('visibilitychange', function () { 432 if (!document.hidden) render(); 433 }); 434 435 /* ç¹å¨é¢æ¿å¤æ¶èµ·ï¼å 嵿¨¡å¼ä¸æ¶èµ·ï¼ */ 436 if (!inlineHost) { 437 document.addEventListener('click', function (e) { 438 if (!box.contains(e.target)) panel.classList.remove('open'); 439 }); 440 } 441 } 442 443 function destroy() { 444 var b = document.getElementById(BOX_ID); 445 if (b) b.remove(); 446 var c = document.getElementById(CSS_ID); 447 if (c) c.remove(); 448 } 449 450 function boot() { 451 build(); 452 /* 主é¢åæ¢æ¶è·çæ¾ç¤º / éè */ 453 window.addEventListener('nb-theme-change', function () { 454 destroy(); 455 build(); 456 }); 457 } 458 459 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot); 460 else boot(); 461 /* ç»å¤é¢è°ï¼é¦é¡µé£è¾¹æä¸å åµå®¹å¨åä¼åä¸å£°ï¼è¿ééå»ºä¸æ¬¡ */ 462 window.NBPomo = { 463 rebuild: function () { destroy(); build(); }, 464 KEY: KEY, 465 DUR: DUR 466 }; 467 468})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.