1<!DOCTYPE HTML> 2<html> 3 4<!-- 5 pgn4web javascript chessboard 6 copyright (C) 2009-2015 Paolo Casaschi 7 see README file and http://pgn4web.casaschi.net 8 for credits, license and more details 9--> 10 11<head> 12 13<title>0.</title> 14 15<!-- use viewport settings when body.onresize adapts the chessboard to the available space --> 16<meta name="viewport" content="initial-scale=1, maximum-scale=1"> 17 18<link rel="icon" sizes="16x16" href="pawn.ico" /> 19 20<link href="analysis.css" type="text/css" rel="stylesheet" /> 21 22<script src="pgn4web.js" type="text/javascript"></script> 23<script src="fonts/chess-informant-NAG-symbols.js" type="text/javascript"></script> 24<script src="engine.js" type="text/javascript"></script> 25 26<script src="fide-lookup.js" type="text/javascript"></script> 27 28<script type="text/javascript"> 29 "use strict"; 30 31 var pgn4web_engineWindowUrlParameters = "as=66&ss=36&ps=29&pf=m&fms=14&fcs=22&lch=FFFFFF&dch=DDDDDD&hch=AAAAAA&ctch=808080&fpr=0"; 32 var pgn4web_engineWindowTarget = "pgn4webAnalysisBoardForAnalysis"; 33 var pgn4web_engineWindowHeight = ""; 34 var pgn4web_engineWindowWidth = ""; 35 36 var thisRegExp; 37 38 thisRegExp = /(&|\?)(help|h)=(true|t)(&|$)/i; 39 if (window.location.search.match(thisRegExp) !== null) { 40 alert("pgn4web analysis.html parameters" + "\n" + 41 " - pgnFile = filename.pgn" + "\n" + 42 " - initialGame = first | last | random | a number | a search expression (default first)" + "\n" + 43 " - initialVariation = a number (default 0)" + "\n" + 44 " - initialHalfmove = start | end | random | comment | variation | a number (default start)" + "\n" + 45 " - showLastNext = true | false (default false)" + "\n" + 46 " - showGamesList = true | false (default false)" + "\n" + 47 " - help = true"); 48 } 49 50 var pgnFilename = ""; 51 thisRegExp = /(&|\?)(pgnFile|pf)=([^&]*)(&|$)/i; 52 if (window.location.search.match(thisRegExp) !== null) { 53 pgnFilename = unescape(window.location.search.match(thisRegExp)[3]); 54 } else { 55 // accepts pgnData as alias for pgnFile for consistency with board.html 56 thisRegExp = /(&|\?)(pgnData|pd)=([^&]*)(&|$)/i; 57 if (window.location.search.match(thisRegExp) !== null) { 58 pgnFilename = unescape(window.location.search.match(thisRegExp)[3]); 59 } 60 } 61 if (pgnFilename !== "") { SetPgnUrl(pgnFilename); } 62 63 thisRegExp = /(&|\?)(initialGame|ig)=([^&]*)(&|$)/i; 64 if (window.location.search.match(thisRegExp) !== null) { 65 SetInitialGame(unescape(window.location.search.match(thisRegExp)[3])); 66 } 67 68 thisRegExp = /(&|\?)(initialVariation|iv)=([^&]*)(&|$)/i; 69 if (window.location.search.match(thisRegExp) !== null) { 70 SetInitialVariation(unescape(window.location.search.match(thisRegExp)[3])); 71 } 72 73 thisRegExp = /(&|\?)(initialHalfmove|ih)=([^&]*)(&|$)/i; 74 if (window.location.search.match(thisRegExp) !== null) { 75 SetInitialHalfmove(unescape(window.location.search.match(thisRegExp)[3]), false); 76 } 77 78 thisRegExp = /(&|\?)(showLastNext|sln)=(true|t)(&|$)/i; 79 var showLastNext = (window.location.search.match(thisRegExp) !== null); 80 81 thisRegExp = /(&|\?)(showGamesList|sgl)=(true|t)(&|$)/i; 82 var showGamesList = (window.location.search.match(thisRegExp) !== null); 83 84 SetImagePath("images/merida/39"); 85 SetImageType("png"); 86 SetHighlightOption(true); 87 SetGameSelectorOptions(null, true, 15, 15, 3, 15, 15, 3, 10); // (head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate); 88 SetCommentsIntoMoveText(true); // if changing this line, set accordingly the visibility of object with ID = "GameAnnotator" 89 SetCommentsOnSeparateLines(false); 90 SetAutoplayDelay(1000); // milliseconds 91 SetAutostartAutoplay(false); 92 SetAutoplayNextGame(false); 93 SetShortcutKeysEnabled(true); 94 95 // customShortcutKey_Shift_1 defined by fide-lookup.js 96 // customShortcutKey_Shift_2 defined by fide-lookup.js 97 98 function customShortcutKey_Shift_3() { toggleLastNext(); } 99 function customShortcutKey_Shift_4() { toggleGamesList(); } 100 function customShortcutKey_Shift_5() { showCurrentGameInfo(); } 101 102 // overwriting engine.js definitions 103 function customShortcutKey_Shift_8() { showAnalysisBoard(true); } 104 function customShortcutKey_Shift_9() { showAnalysisBoard(false); } 105 function customShortcutKey_Shift_0() { showAnalysisBoard(); } 106 107 if (!pgn4web_engineWindowDisableAnalysisBoard) { 108 boardShortcut("E8", "open/update analysis board", function(t,e){ showAnalysisBoard(e.shiftKey); }); 109 boardShortcut("F8", "close/pause analysis board", function(t,e){ if (!e.shiftKey) { hideAnalysisBoard(); } }); 110 } 111 boardShortcut("E7", "toggle last/next moves information", function(t,e){ toggleLastNext(); }); 112 boardShortcut("G7", "toggle show comments on separate lines", function(t,e){ if (e.shiftKey) { SetCommentsIntoMoveText(!commentsIntoMoveText); } else { SetCommentsOnSeparateLines(!commentsOnSeparateLines); } var oldPly = CurrentPly; var oldVar = CurrentVar; Init(); GoToMove(oldPly, oldVar); }); 113 boardShortcut("A6", "search previous annotator", function(t,e){ searchAnnotator(e.shiftKey, true); }); 114 boardShortcut("B6", "search next annotator", function(t,e){ searchAnnotator(e.shiftKey, false); }); 115 boardShortcut("G6", "scroll moves text to current move", function(t,e){ autoScrollToCurrentMoveIfEnabled(); }); 116 boardShortcut("H6", "scroll moves text to top", function(t,e){ document.getElementById("GameTextResult").scrollTop = 0; }); 117 boardShortcut("F5", "toggle games list", function(t,e){ toggleGamesList(); }); 118 boardShortcut("G5", "game info", function(t,e){ showCurrentGameInfo(); }); 119 boardShortcut("H5", "scroll moves text to bottom", function(t,e){ document.getElementById("GameTextResult").scrollTop = document.getElementById("GameTextResult").scrollHeight; }); 120 121 function FlipBoard() {} 122 123 window['defaultSetCommentsIntoMoveText'] = window['SetCommentsIntoMoveText']; 124 window['SetCommentsIntoMoveText'] = function(onOff) { 125 defaultSetCommentsIntoMoveText(onOff); 126 var theObj = document.getElementById("GameAnnotator"); 127 if (theObj) { theObj.style.display = onOff ? "" : "none"; } 128 }; 129 130 var firstCustomFunctionOnPgnTextLoad = true; 131 function customFunctionOnPgnTextLoad() { 132 myOnResize(); 133 if (firstCustomFunctionOnPgnTextLoad) { 134 firstCustomFunctionOnPgnTextLoad = false; 135 showEngineAnalysisBoard(true, true); // prepare analysis frame with an idle board 136 } 137 } 138 139 var currentGameInfo = ''; 140 141 function customFunctionOnPgnGameLoad() { 142 var theObj, theOther, whiteElo, blackElo, eco, annotator, newTitle; 143 if (theObj = document.getElementById('GameSiteEvent')) { 144 theObj.innerHTML = gameSite[currentGame]; 145 fixSiteInnerHTML('GameSiteEvent'); 146 if (theObj.innerHTML === "") { 147 theObj.innerHTML = gameEvent[currentGame]; 148 fixObjInnerHTML('GameSiteEvent'); 149 } 150 } 151 fixDateInnerHTML('GameDate'); 152 fixObjInnerHTML('GameWhite'); 153 fixObjInnerHTML('GameBlack'); 154 fixObjInnerHTML('GameResult'); 155 if (theObj = document.getElementById('GameNum')) { theObj.innerHTML = (currentGame + 1); } 156 fixObjInnerHTML('GameNum'); 157 whiteElo = customPgnHeaderTag('WhiteElo', 'GameWhiteElo'); 158 fixObjInnerHTML('GameWhiteElo'); 159 blackElo = customPgnHeaderTag('BlackElo', 'GameBlackElo'); 160 fixObjInnerHTML('GameBlackElo'); 161 eco = customPgnHeaderTag('ECO', 'GameECO'); 162 fixObjInnerHTML('GameECO'); 163 annotator = customPgnHeaderTag('Annotator', 'GameAnnotator'); 164 fixObjInnerHTML('GameAnnotator'); 165 theObj = document.getElementById('GameWhite'); 166 theOther = document.getElementById('GameWhiteElo'); 167 theOther.style.marginLeft = (theObj && theObj.innerHTML && theOther && theOther.innerHTML) ? '1.2ex' : ''; 168 theObj = document.getElementById('GameBlack'); 169 theOther = document.getElementById('GameBlackElo'); 170 theOther.style.marginLeft = (theObj && theObj.innerHTML && theOther && theOther.innerHTML) ? '1.2ex' : ''; 171 theObj = document.getElementById('GameSiteEvent'); 172 theOther = document.getElementById('GameDate'); 173 theOther.style.marginLeft = (theObj && theObj.innerHTML && theOther && theOther.innerHTML) ? '1.2ex' : ''; 174 175 newTitle = (currentGame + 1) + '.'; 176 if ((theObj = document.getElementById('GameWhite')) && (theObj.innerHTML)) { newTitle += ' ' + theObj.innerHTML; } 177 if ((theObj = document.getElementById('GameBlack')) && (theObj.innerHTML)) { newTitle += ' ' + theObj.innerHTML; } 178 if ((theObj = document.getElementById('GameResult')) && (theObj.innerHTML)) { newTitle += ' ' + theObj.innerHTML; } 179 if ((theObj = document.getElementById('GameSiteEvent')) && (theObj.innerHTML)) { newTitle += ' ' + theObj.innerHTML; } 180 if ((theObj = document.getElementById('GameDate')) && (theObj.innerHTML)) { newTitle += ' ' + theObj.innerHTML; } 181 document.title = simpleHtmlentitiesDecode(newTitle); 182 183 newTitle = ''; 184 if (gameEvent[currentGame]) { newTitle += '\nevent: ' + gameEvent[currentGame]; } 185 if (gameSite[currentGame]) { newTitle += '\nsite: ' + gameSite[currentGame]; } 186 if (gameDate[currentGame]) { newTitle += '\ndate: ' + gameDate[currentGame]; } 187 if (gameRound[currentGame]) { newTitle += '\nround: ' + gameRound[currentGame]; } 188 if (gameWhite[currentGame]) { 189 newTitle += '\nwhite: ' + gameWhite[currentGame]; 190 if (whiteElo) { newTitle += ' ' + whiteElo; } 191 } 192 if (gameBlack[currentGame]) { 193 newTitle += '\nblack: ' + gameBlack[currentGame]; 194 if (blackElo) { newTitle += ' ' + blackElo; } 195 } 196 if (gameResult[currentGame]) { newTitle += '\nresult: ' + gameResult[currentGame]; } 197 if (eco) { newTitle += '\neco: ' + eco; } 198 if (annotator) { newTitle += '\nnotes: ' + annotator; } 199 if (newTitle) { newTitle = '\n' + newTitle; } 200 newTitle = 'game ' + (currentGame + 1) + ' of ' + numberOfGames + newTitle; 201 if (theObj = document.getElementById('boardHeaderInfo')) { theObj.title = simpleHtmlentitiesDecode(newTitle); } 202 currentGameInfo = newTitle; 203 } 204 205 function fixObjInnerHTML(id) { 206 var theObj = document.getElementById(id); 207 if (theObj) { theObj.innerHTML = theObj.innerHTML.replace(/\.?\?[.?]*/, "").replace(/,(\w)/g, ", $1"); } 208 } 209 210 function fixDateInnerHTML(id) { 211 var theObj = document.getElementById(id); 212 if (theObj) { theObj.innerHTML = theObj.innerHTML.replace(/\.?\?[.?]*/, "").replace(/,(\w)/g, ", $1").replace(/^\s*(\d+)\D.*$/, "$1"); } 213 } 214 215 function fixSiteInnerHTML(id) { 216 var theObj = document.getElementById(id); 217 if (theObj) { theObj.innerHTML = theObj.innerHTML.replace(/\.?\?[.?]*/, "").replace(/,(\w)/g, ", $1").replace(/\s[A-Z]{3}$/, ""); } 218 } 219 220 function showCurrentGameInfo() { 221 if (confirm(currentGameInfo + "\n\nclick OK for the PGN source data")) { displayPgnData(true); } 222 } 223 224 function searchPlayer(name, FideId) { 225 if (typeof(openFidePlayerUrl) == "function") { openFidePlayerUrl(name, FideId); } 226 } 227 228 function searchAnnotator(same, backward) { 229 var fixedAnnotator = fixRegExp(customPgnHeaderTag("Annotator")); 230 searchPgnGame(same ? '\\[\\s*Annotator\\s*"' + fixedAnnotator + '"\\s*\\]' : '\\[\\s*Annotator\\s*"(?!' + fixedAnnotator + '"\\s*\\])', backward); 231 document.getElementById("GameTextResult").scrollTop = document.getElementById("GameTextResult").scrollHeight; 232 } 233 234 function myOnResize() { 235 var ww, wh, theObj; 236 if (window.innerWidth && window.innerHeight) { ww = window.innerWidth; wh = window.innerHeight; } 237 else if (document.documentElement && document.documentElement.clientWidth) { ww = document.documentElement.clientWidth; wh = document.documentElement.clientHeight; } 238 else if (document.body && document.body.clientWidth) { ww = document.body.clientWidth; wh = document.body.clientHeight; } 239 else { return; } 240 241 if (theObj = document.getElementById("GameTextResult")) { theObj.style.height = (wh - 60) + "px"; } 242 243 autoScrollToCurrentMoveIfEnabled(); 244 } 245 246 enableAutoScrollToCurrentMove("GameTextResult"); 247 248 249 var thisEngineWin; 250 var thisEngineWinShown = false; 251 252 function showAnalysisBoard(de) { 253 if (pgn4web_engineWindowDisableAnalysisBoard) { return; } 254 var theObj; 255 if ((thisEngineWin = showEngineAnalysisBoard(de)) && (!thisEngineWinShown)) { 256 if (theObj = document.getElementById("GameAnalysisFrame")) { theObj.style.visibility = ""; } 257 if (theObj = document.getElementById('analysisHeader')) { 258 theObj.style.left = "451px"; // 436px boardheaderDiv.width + 15px gametextresultDiv.paddingLeft 259 } 260 if (theObj = document.getElementById('GameTextResult')) { 261 theObj.style.marginLeft = "769px"; // 451px analysisHeader.left + 288px analysisHeader.width + 30px padding 262 } 263 setTimeout(autoScrollToCurrentMoveIfEnabled, 2100); 264 thisEngineWinShown = true; 265 } 266 } 267 268 function hideAnalysisBoard() { 269 if (pgn4web_engineWindowDisableAnalysisBoard) { return; } 270 var theObj; 271 if (thisEngineWinShown) { 272 if (theObj = document.getElementById('analysisHeader')) { 273 theObj.style.left = ""; 274 } 275 if (theObj = document.getElementById('GameTextResult')) { 276 theObj.style.marginLeft = ""; 277 } 278 setTimeout(autoScrollToCurrentMoveIfEnabled, 2100); 279 thisEngineWinShown = false; 280 } 281 if (typeof(thisEngineWin) != "undefined") { 282 if (typeof(thisEngineWin.StopBackgroundEngine) == "function") { thisEngineWin.StopBackgroundEngine(); } 283 if (typeof(thisEngineWin.autoUpdate) != "undefined") { thisEngineWin.autoUpdate = false; } 284 } 285 } 286 287 function toggleLastNext(sln) { 288 showLastNext = (typeof(sln) == "undefined") ? !showLastNext : sln; 289 var theObj = document.getElementById("GameLastNext"); 290 if (theObj) { 291 theObj.style.display = showLastNext ? "" : "none"; 292 } 293 } 294 295 function toggleGamesList(sgl) { 296 showGamesList = (typeof(sgl) == "undefined") ? !showGamesList : sgl; 297 var theObj = document.getElementById("GamesList"); 298 if (theObj) { 299 theObj.style.display = showGamesList ? "" : "none"; 300 } 301 } 302 303</script> 304 305</head> 306 307<body onResize="myOnResize();"> 308 309<!-- paste your PGN below and make sure you dont specify an external source with SetPgnUrl() --> 310<form style="display: none;"><textarea style="display: none;" id="pgnText"> 311 312</textarea></form> 313<!-- paste your PGN above and make sure you dont specify an external source with SetPgnUrl() --> 314 315<div class="analysisheaderDiv" id="analysisHeader"> 316<iframe class="gameAnalysisFrame" style="visibility: hidden;" id="GameAnalysisFrame" name="pgn4webAnalysisBoardForAnalysis" src="./blank.html" frameborder="0" scrolling="no" marginheight="0" marginwidth="0">your web browser and/or your host do not support iframes as required</iframe> 317</div> 318 319<div class="boardheaderDiv" id="boardHeader"> 320<div class="boardHeaderInfo" id="boardHeaderInfo"> 321<table cellspacing=0 cellpadding=0 border=0><tr> 322<td><div class="headerLine gameNum"><span id="GameNum">1</span>.</div></td> 323<td><div class="headerLine gameECO"><span id="GameECO"></span></div></td> 324</tr></table> 325<div class="shortRowSpace"> </div> 326<div class="headerLine"><a id="GameWhite" href="javascript:void(0);" onclick="searchPlayer(this.innerHTML, customPgnHeaderTag('WhiteFideId')); this.blur();"></a><span id="GameWhiteElo"></span></div> 327<div class="headerLine"><a id="GameBlack" href="javascript:void(0);" onclick="searchPlayer(this.innerHTML, customPgnHeaderTag('BlackFideId')); this.blur();"></a><span id="GameBlackElo"></span></div> 328<div class="shortRowSpace"> </div> 329<div class="headerLine gameSiteEventDate"><span id="GameSiteEvent"></span><span id="GameDate"></span></div> 330</div> 331<div class="gameBoard" id="GameBoard"></div> 332<div class="gameLastNext" id="GameLastNext" style="display: none;"> 333<div class="gameLastMove"> 334<span id="GameLastMove" title="last move"></span> <span id="GameLastVariations" title="last move alternatives"></span> 335</div> 336<div class="shortRowSpace"> </div> 337<div class="gameNextMove"> 338<span id="GameNextMove" title="next move"></span> <span id="GameNextVariations" title="next move alternatives"></span> 339</div> 340</div> 341<div class="gamesList" id="GamesList" style="display: none;"> 342<div class="gameSelector" id="GameSelector"></div> 343</div> 344</div> 345 346<div class="topSpacer"> </div> 347 348<div class="gametextresultDiv" id="GameTextResult"> 349<div id="GameText"></div> 350<div class="comment" style="line-height: 33%;"> </div> 351<a class="gameAnnotator" id="GameAnnotator" href="javascript:void(0);" onclick="searchAnnotator(!event.shiftKey, false); this.blur();"></a> 352<div id="GameResult"></div> 353</div> 354 355<a class="helpLink" title="pgn4web help" href="javascript:void(0);" onclick="displayHelp(); this.blur();">?</a> 356 357<script type="text/javascript"> 358 "use strict"; 359 360 toggleLastNext(showLastNext); 361 toggleGamesList(showGamesList); 362 363 function pgn4web_handleTouchEnd_Header(e) { 364 e.stopPropagation(); 365 var jj, deltaX, deltaY; 366 for (var ii = 0; ii < e.changedTouches.length; ii++) { 367 if ((jj = pgn4webOngoingTouchIndexById(e.changedTouches[ii].identifier)) != -1) { 368 if (pgn4webOngoingTouches.length == 1) { 369 deltaX = e.changedTouches[ii].clientX - pgn4webOngoingTouches[jj].clientX; 370 deltaY = e.changedTouches[ii].clientY - pgn4webOngoingTouches[jj].clientY; 371 if (Math.max(Math.abs(deltaX), Math.abs(deltaY)) >= 13) { 372 if (Math.abs(deltaX) > 1.5 * Math.abs(deltaY)) { 373 if (deltaX > 0) { // horizontal right 374 showAnalysisBoard(false); 375 } else { // horizontal left 376 hideAnalysisBoard(); 377 } 378 } else if (Math.abs(deltaY) > 1.5 * Math.abs(deltaX)) { // vertical up or down 379 SetCommentsIntoMoveText(!commentsIntoMoveText); 380 var oldPly = CurrentPly; 381 var oldVar = CurrentVar; 382 Init(); 383 GoToMove(oldPly, oldVar); 384 } 385 } 386 pgn4webMaxTouches = 0; 387 } 388 pgn4webOngoingTouches.splice(jj, 1); 389 } 390 } 391 clearSelectedText(); 392 } 393 394 if (touchEventEnabled) { 395 var theObj = document.getElementById("boardHeader"); 396 if (theObj) { 397 simpleAddEvent(theObj, "touchstart", pgn4web_handleTouchStart); 398 simpleAddEvent(theObj, "touchmove", pgn4web_handleTouchMove); 399 simpleAddEvent(theObj, "touchend", pgn4web_handleTouchEnd_Header); 400 simpleAddEvent(theObj, "touchleave", pgn4web_handleTouchEnd_Header); 401 simpleAddEvent(theObj, "touchcancel", pgn4web_handleTouchCancel); 402 } 403 theObj = document.getElementById("analysisHeader"); 404 if (theObj) { 405 simpleAddEvent(theObj, "touchstart", pgn4web_handleTouchStart); 406 simpleAddEvent(theObj, "touchmove", pgn4web_handleTouchMove); 407 simpleAddEvent(theObj, "touchend", pgn4web_handleTouchEnd_Header); 408 simpleAddEvent(theObj, "touchleave", pgn4web_handleTouchEnd_Header); 409 simpleAddEvent(theObj, "touchcancel", pgn4web_handleTouchCancel); 410 } 411 touchGestures_helpActions = touchGestures_helpActions.concat([ " ", "game header vertical swipe" ]); 412 touchGestures_helpText = touchGestures_helpText.concat([ "", "toggle show comments in game text" ]); 413 if (!pgn4web_engineWindowDisableAnalysisBoard) { 414 touchGestures_helpActions = touchGestures_helpActions.concat([ "game header left-right swipe", "game header right-left swipe" ]); 415 touchGestures_helpText = touchGestures_helpText.concat([ "open/update analysis board", "close/pause analysis board" ]); 416 } 417 } 418 419</script> 420 421</body> 422 423</html> 424