(function () { 'use strict'; const { Store, api, chips } = App; if (!Store.name) { location.replace('/'); return; } const $ = (id) => document.getElementById(id); const form = $('form'); const nameInput = $('table-name'); const stackInput = $('stack'); const sbInput = $('sb'); const bbInput = $('bb'); const timerInput = $('timer'); const intervalInput = $('interval'); const scheduleEl = $('schedule'); const blindHint = $('blind-hint'); const errorEl = $('error'); const submitBtn = $('submit'); // ブラインドを手で変えるまではスタックに追従させる let blindsTouched = false; async function suggestName() { try { const { name } = await api('GET', '/api/tables/suggest-name'); nameInput.value = name; } catch { /* 失敗時は手入力 */ } } const int = (el) => { const n = Number(el.value); return Number.isInteger(n) ? n : NaN; }; function applyDefaultBlinds() { const stack = int(stackInput); if (!(stack >= 10)) return; const { sb, bb } = Blinds.defaultBlinds(stack); sbInput.value = sb; bbInput.value = bb; } function updateHint() { const stack = int(stackInput); const bb = int(bbInput); if (blindsTouched && stack > 0 && bb > 0) { blindHint.innerHTML = `開始スタック = ${Math.floor(stack / bb)} BB ・ おすすめに戻す`; } else { blindHint.textContent = 'スタックに合わせて自動設定(BB ≒ スタックの1/100)'; } } function updateSchedule() { const sb = int(sbInput); const bb = int(bbInput); const on = timerInput.checked; intervalInput.disabled = !on; scheduleEl.hidden = !on || !(sb > 0 && bb >= sb); if (scheduleEl.hidden) return; const mins = int(intervalInput) > 0 ? int(intervalInput) : 0; scheduleEl.innerHTML = Blinds.schedule(sb, bb, 8) .map((l, i) => `Lv.${l.level} ${chips(l.sb)}/${chips(l.bb)}${mins ? ` · ${i * mins}分〜` : ''}`) .join(''); } function refresh() { updateHint(); updateSchedule(); } stackInput.addEventListener('input', () => { if (!blindsTouched) applyDefaultBlinds(); refresh(); }); [sbInput, bbInput].forEach((el) => el.addEventListener('input', () => { blindsTouched = true; if (el === sbInput && int(sbInput) > 0) bbInput.value = int(sbInput) * 2; refresh(); }) ); blindHint.addEventListener('click', (e) => { if (e.target.id !== 'reset-blinds') return; e.preventDefault(); blindsTouched = false; applyDefaultBlinds(); refresh(); }); timerInput.addEventListener('change', refresh); intervalInput.addEventListener('input', refresh); $('reroll').addEventListener('click', suggestName); function validate() { const name = nameInput.value.trim(); const stack = int(stackInput); const sb = int(sbInput); const bb = int(bbInput); const interval = int(intervalInput); if (!name) return [nameInput, 'テーブル名を入力してください']; if (!(stack >= 10)) return [stackInput, '開始スタックは10以上の整数にしてください']; if (!(sb >= 1)) return [sbInput, 'SBは1以上の整数にしてください']; if (!(bb >= sb)) return [bbInput, 'BBはSB以上にしてください']; if (bb > stack) return [bbInput, 'BBが開始スタックより大きいです']; if (timerInput.checked && !(interval >= 1 && interval <= 240)) return [intervalInput, 'インターバルは1〜240分にしてください']; return null; } form.addEventListener('submit', async (e) => { e.preventDefault(); form.querySelectorAll('.invalid').forEach((el) => el.classList.remove('invalid')); const problem = validate(); if (problem) { problem[0].classList.add('invalid'); problem[0].focus(); errorEl.textContent = problem[1]; return; } errorEl.textContent = ''; submitBtn.disabled = true; try { const { id } = await api('POST', '/api/tables', { name: nameInput.value.trim(), startingStack: int(stackInput), smallBlind: int(sbInput), bigBlind: int(bbInput), blindTimerEnabled: timerInput.checked, blindIntervalMin: int(intervalInput), token: Store.token, }); location.href = '/table/' + encodeURIComponent(id); } catch (err) { errorEl.textContent = err.message; submitBtn.disabled = false; } }); applyDefaultBlinds(); refresh(); suggestName(); })();