1'use strict'; 2 3function moveListPgnResultToken(){ 4 if(!(onlineGameEnded || gameEnded || timeLost)) return ''; 5 const finalGame = buildGameFromHistory(masterHistory.length); 6 const finalState = gameOverForHistory(masterHistory.length, finalGame); 7 const result = typeof pgnResultFromState === 'function' ? pgnResultFromState(finalState) : ''; 8 return result === '1-0' || result === '0-1' || result === '1/2-1/2' ? result : ''; 9} 10function renderMoveList(){ 11 const theme = currentTheme(); 12 const themePly = currentThemePly(); 13 if(themeMoveNotice){ 14 themeMoveNotice.hidden = !theme; 15 themeMoveNotice.textContent = theme ? ('ð¯ Thementurnier: ' + theme.name + ' · ' + themePly + ' vorgegebene Halbzüge. Mit den Pfeilen lässt sich ihre Entstehung vollständig zurückverfolgen.') : ''; 16 } 17 const resultToken = moveListPgnResultToken(); 18 if(masterHistory.length === 0){ 19 let empty = moveListEl.firstElementChild; 20 if(!empty){ 21 empty = document.createElement('div'); 22 moveListEl.appendChild(empty); 23 } 24 empty.className = resultToken ? 'move-cell move-result' : ''; 25 empty.textContent = resultToken || 'â'; 26 empty.removeAttribute('data-move-index'); 27 while(moveListEl.children.length > 1) moveListEl.lastElementChild.remove(); 28 return; 29 } 30 const cells = []; 31 for(let i=0; i<masterHistory.length; i+=4){ 32 const num1 = Math.floor(i/2) + 1; 33 const num2 = num1 + 1; 34 cells.push({txt:num1 + '.', idx:null}, {txt:masterHistory[i]?.san || '', idx:i}, {txt:masterHistory[i+1]?.san || '', idx:i+1}); 35 cells.push({txt:masterHistory[i+2] || masterHistory[i+3] ? num2 + '.' : '', idx:null}, {txt:masterHistory[i+2]?.san || '', idx:i+2}, {txt:masterHistory[i+3]?.san || '', idx:i+3}); 36 } 37 if(resultToken) cells.push({txt:resultToken, idx:null, result:true}); 38 const navigationLocked = isMoveNavigationLocked(); 39 cells.forEach((c, cellIndex) => { 40 let div = moveListEl.children[cellIndex]; 41 if(!div){ 42 div = document.createElement('div'); 43 moveListEl.appendChild(div); 44 } 45 div.className = 'move-cell'; 46 if(c.result) div.classList.add('move-result'); 47 else if(cellIndex % 6 >= 3) div.classList.add('hide-mobile-pair'); 48 div.textContent = c.txt; 49 div.removeAttribute('data-move-index'); 50 div.title = ''; 51 div.style.cursor = ''; 52 if(c.idx !== null){ 53 div.dataset.moveIndex = String(c.idx); 54 if(c.idx < themePly) div.classList.add('theme-move'); 55 if(c.idx === themePly - 1) div.classList.add('theme-end'); 56 if(viewIndex === c.idx + 1) div.classList.add('current'); 57 if(navigationLocked){ 58 div.title = 'Bitte die Daily-Zugvorschau zuerst bestätigen oder zurücknehmen.'; 59 div.style.cursor = 'default'; 60 } else { 61 div.title = 'Zu dieser Stellung springen'; 62 div.style.cursor = 'pointer'; 63 } 64 } 65 }); 66 while(moveListEl.children.length > cells.length) moveListEl.lastElementChild.remove(); 67} 68function updateBoardNavControls(){ 69 if(!boardNavStartBtn || !boardNavBackBtn || !boardNavForwardBtn || !boardNavEndBtn) return; 70 let current = viewIndex; 71 let total = masterHistory.length; 72 let locked = isMoveNavigationLocked(); 73 let labels = ['Anfang der Partie','Einen Halbzug zurück','Einen Halbzug vor','Letzte Stellung']; 74 if(variationModeActive){ 75 current = variationHistory.length; 76 total = completeVariationLine().length; 77 locked = false; 78 labels = variationPurpose === 'conditional' 79 ? ['Ausgangsstellung der Bedingung','Einen vorbereiteten Zug zurück','Einen vorbereiteten Zug vor','Letzte vorbereitete Stellung'] 80 : ['Ausgangsstellung der Variante','Einen Variantenzug zurück','Einen Variantenzug vor','Letzte Variantenstellung']; 81 } 82 const buttons = [boardNavStartBtn,boardNavBackBtn,boardNavForwardBtn,boardNavEndBtn]; 83 buttons.forEach((button,index) => { 84 button.title = labels[index]; 85 button.setAttribute('aria-label',labels[index]); 86 }); 87 boardNavStartBtn.disabled = locked || total === 0 || current === 0; 88 boardNavBackBtn.disabled = locked || total === 0 || current === 0; 89 boardNavForwardBtn.disabled = locked || total === 0 || current === total; 90 boardNavEndBtn.disabled = locked || total === 0 || current === total; 91} 92function updateNavControls(){ 93 const total = masterHistory.length; 94 const locked = isMoveNavigationLocked(); 95 navStartBtn.disabled = locked || total === 0 || viewIndex === 0; 96 navBackBtn.disabled = locked || total === 0 || viewIndex === 0; 97 navForwardBtn.disabled = locked || total === 0 || viewIndex === total; 98 navEndBtn.disabled = locked || total === 0 || viewIndex === total; 99 movesInfoEl.textContent = total === 0 ? '0/0' : viewIndex + '/' + total; 100 updateBoardNavControls(); 101} 102function canExportCurrentGamePgn(){ 103 return masterHistory.length >
103 0 && !!(onlineGameEnded || gameEnded || timeLost); 104} 105function updatePgnExportUi(){ 106 const button = document.getElementById('copyPgnBtn'); 107 if(!button) return; 108 const available = canExportCurrentGamePgn(); 109 button.hidden = !available; 110 button.disabled = !available; 111 button.title = available ? 'Beendete Partie als PGN-Datei herunterladen' : 'PGN steht erst nach Partieende bereit'; 112} 113navStartBtn.addEventListener('click', () => { if(isMoveNavigationLocked()) return; viewIndex = 0; selected = null; renderBoard(); }); 114navBackBtn.addEventListener('click', () => { if(isMoveNavigationLocked()) return; viewIndex = Math.max(0, viewIndex - 1); selected = null; renderBoard(); }); 115navForwardBtn.addEventListener('click', () => { if(isMoveNavigationLocked()) return; viewIndex = Math.min(masterHistory.length, viewIndex + 1); selected = null; renderBoard(); }); 116navEndBtn.addEventListener('click', () => { if(isMoveNavigationLocked()) return; viewIndex = masterHistory.length; selected = null; renderBoard(); }); 117if(boardNavStartBtn) boardNavStartBtn.addEventListener('click', () => { 118 if(variationModeActive){ setVariationViewIndex(0); return; } 119 if(isMoveNavigationLocked()) return; 120 viewIndex = 0; 121 selected = null; 122 renderBoard(); 123}); 124if(boardNavBackBtn) boardNavBackBtn.addEventListener('click', () => { 125 if(variationModeActive){ setVariationViewIndex(variationHistory.length - 1); return; } 126 if(isMoveNavigationLocked()) return; 127 viewIndex = Math.max(0,viewIndex - 1); 128 selected = null; 129 renderBoard(); 130}); 131if(boardNavForwardBtn) boardNavForwardBtn.addEventListener('click', () => { 132 if(variationModeActive){ setVariationViewIndex(variationHistory.length + 1); return; } 133 if(isMoveNavigationLocked()) return; 134 viewIndex = Math.min(masterHistory.length,viewIndex + 1); 135 selected = null; 136 renderBoard(); 137}); 138if(boardNavEndBtn) boardNavEndBtn.addEventListener('click', () => { 139 if(variationModeActive){ setVariationViewIndex(completeVariationLine().length); return; } 140 if(isMoveNavigationLocked()) return; 141 viewIndex = masterHistory.length; 142 selected = null; 143 renderBoard(); 144});
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.