feat: improve board review and connection optimization assumptions
Publish GitHub Pages output / publish (push) Successful in 45s

This commit is contained in:
2026-10-06 12:12:09 +09:00
parent 0b794edc80
commit d18972382a
8 changed files with 277 additions and 29 deletions
+16 -2
View File
@@ -172,6 +172,7 @@
let activeSearchChart: ExactSongChart | null = null;
let primaryRankings: RankedResult[] = [];
let searchPhase: 'idle' | 'screening' | 'exact' | 'probability' = 'idle';
$: searchStep = searchPhase === 'screening' ? 1 : searchPhase === 'probability' ? 4 : exactPass === 'refinement' ? 3 : 2;
let screeningProgress = 0;
let errorMessage = '';
let ready = false;
@@ -1379,7 +1380,14 @@
</label>
<p id="result-limit-guide" class="candidate-guide">다음 탐색부터 적용합니다. 결과 수를 늘리면 달성 확률 계산 시간이 늘어납니다. 분석한 조합이 적으면 선택한 수보다 적게 표시됩니다.</p>
{#if errorMessage}<p class="error" role="alert">{errorMessage}</p>{/if}
<button class="search" type="button" disabled={running} on:click={search}>{running ? searchPhase === 'screening' ? `후보 선별 중 ${Math.round(screeningProgress * 100)}%` : searchPhase === 'probability' ? `달성 확률 계산 중 ${Math.round(progress.evaluatedCandidates / Math.max(1, progress.totalCandidates) * 100)}%` : `정밀 분석 중 ${Math.round(progress.evaluatedCandidates / Math.max(1, progress.totalCandidates) * 100)}%` : '최적 조합 탐색'}</button>
{#if running}
<div class="search-step-status" role="status" aria-live="polite">
<strong class="search-step-badge" aria-label={`현재 단계 ${searchStep}/4`}>{searchStep}<span>/4</span></strong>
<div><small>현재 진행 단계</small><strong>{['후보 선별', '선별 후보 평가', '확장 후보 검증', '달성 확률 계산'][searchStep - 1]}</strong></div>
</div>
<p class="candidate-guide">퍼센트는 현재 단계의 진행률입니다. 확장 후보가 없으면 3단계는 건너뜁니다.</p>
{/if}
<button class="search" type="button" disabled={running} on:click={search}>{running ? searchPhase === 'screening' ? `후보 선별 중 ${Math.round(screeningProgress * 100)}%` : searchPhase === 'probability' ? `달성 확률 계산 중 ${Math.round(progress.evaluatedCandidates / Math.max(1, progress.totalCandidates) * 100)}%` : `${exactPass === 'refinement' ? '확장 후보 검증' : '선별 후보 평가'} ${Math.round(progress.evaluatedCandidates / Math.max(1, progress.totalCandidates) * 100)}%` : '최적 조합 탐색'}</button>
<label class="compute-option">
<input type="checkbox" bind:checked={maximizeCompute} disabled={running}>
<span aria-hidden="true"></span>
@@ -1391,7 +1399,7 @@
</section>
<section class="panel" aria-labelledby="result-title">
<div class="section-title"><div><span>02</span><h2 id="result-title">탐색 결과</h2></div>{#if result}<strong>{screenedCombinationCount.toLocaleString('ko-KR')}개 선별 · {exactCombinationCount}개 정밀 분석 · {comparableToBaseline ? '기준 조합 포함 ' : ''}상위 {displayedRankings.length}개</strong>{/if}</div>
<div class="section-title"><div><span>02</span><h2 id="result-title">탐색 결과</h2></div>{#if result}<strong>{screenedCombinationCount.toLocaleString('ko-KR')}개 선별 · {exactCombinationCount}개 후보 평가 · {comparableToBaseline ? '기준 조합 포함 ' : ''}상위 {displayedRankings.length}개</strong>{/if}</div>
{#if userDataChanged}<p class="baseline-guide" role="status">사용자 데이터가 변경되었습니다. 진행 중인 탐색과 아래 결과는 이전 데이터 기준이며, 다시 탐색하면 최신 데이터를 적용합니다.</p>{/if}
{#if !eventMode}<p class="baseline-guide">상세 점수·그래프·액티브 미발동 비교는 각 결과의 ‘배치 분석에서 보기’를 눌러 새 탭에서 확인할 수 있습니다.</p>{/if}
{#if transferError}<p class="error" role="alert">{transferError}</p>{/if}
@@ -1545,6 +1553,12 @@
.hint { margin: 13px 0 0; color: #858f9f; font-size: 13px; line-height: 1.6; }
.error { margin: 14px 0 0; color: #ff9f9f; font-size: 13px; }
.search { width: 100%; height: 46px; margin-top: 20px; border: 0; border-radius: 10px; color: #171019; background: #ed8bb5; font-weight: 900; cursor: pointer; }
.search-step-status { display: flex; align-items: center; gap: 14px; margin-top: 20px; padding: 14px 16px; border: 1px solid #b65c84; border-radius: 10px; background: #30212c; }
.search-step-badge { display: flex; align-items: baseline; gap: 3px; flex-shrink: 0; padding: 8px 12px; border-radius: 8px; background: #ed8bb5; color: #24131e; font-size: 26px; font-weight: 900; line-height: 1.2; font-variant-numeric: tabular-nums; }
.search-step-badge span { font-size: 16px; }
.search-step-status > div { display: grid; gap: 3px; }
.search-step-status small { color: #d6a1ba; font-size: 11px; font-weight: 700; }
.search-step-status > div > strong { color: #ffe4f0; font-size: 16px; }
.search:hover:not(:disabled) { background: #f2a0c2; }
.search:disabled { opacity: .55; cursor: default; }
.owned-cards-option, .compute-option { display: flex; align-items: center; gap: 9px; width: fit-content; margin-top: 12px; cursor: pointer; }