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>pgn4web live chessboard</title> 14 15<link rel="icon" sizes="16x16" href="pawn.ico" /> 16 17<script src="pgn4web.js" type="text/javascript"></script> 18<script src="engine.js" type="text/javascript"></script> 19 20<script src="fide-lookup.js" type="text/javascript"></script> 21 22<script type="text/javascript"> 23 "use strict"; 24 25 var thisRegExp; 26 27 var readyToReceivePgn = false; 28 29 var useTextarea = false; 30 thisRegExp = /(&|\?)(useTextarea|ut)=([^&]*)(&|$)/i; 31 if (window.location.search.match(thisRegExp) !== null) { 32 var useTextareaValue = unescape(window.location.search.match(thisRegExp)[3]); 33 if ((useTextareaValue == "true") || (useTextareaValue == "t")) { useTextarea = true; } 34 } 35 36 var pgnFile_default = location.protocol + "//" + location.hostname + 37 location.pathname.replace(/\/[^\/]*$/, "/live/live.pgn"); 38 var pgnFile = pgnFile_default; 39 thisRegExp = /(&|\?)(pgnData|pd)=([^&]*)(&|$)/i; 40 if (window.location.search.match(thisRegExp) !== null) { 41 pgnFile = unescape(window.location.search.match(thisRegExp)[3]); 42 } else { 43 // accepts pgnData as alias for pgnFile for consistency with board.html 44 thisRegExp = /(&|\?)(pgnFile|pf)=([^&]*)(&|$)/i; 45 if (window.location.search.match(thisRegExp) !== null) { 46 pgnFile = unescape(window.location.search.match(thisRegExp)[3]); 47 } 48 } 49 50 var alertFlag = false; 51 var demoFlag = false; 52 thisRegExp = /(&|\?)(refreshDemo|rd|demo|d)=([^&]*)(&|$)/i; 53 if (window.location.search.match(thisRegExp) !== null) { 54 var refreshDemo = unescape(window.location.search.match(thisRegExp)[3]); 55 if ((refreshDemo == "true") || (refreshDemo == "t")) { alertFlag = demoFlag = true; } 56 } 57 58 var refreshMinutes_default = 1; 59 var refreshMinutes = refreshMinutes_default; 60 var stepFlag = true; 61 thisRegExp = /(&|\?)(refreshMinutes|rm)=([^&]*)(&|$)/i; 62 if (window.location.search.match(thisRegExp) !== null) { 63 refreshMinutes = parseFloat(unescape(window.location.search.match(thisRegExp)[3])); 64 if (isNaN(refreshMinutes)) { refreshMinutes = refreshMinutes_default; } 65 if (refreshMinutes <= 0) { refreshMinutes = refreshMinutes_default; } 66 } 67 68 var iniGame_default = 1; 69 var iniGame = iniGame_default; 70 thisRegExp = /(&|\?)(initialGame|ig)=([^&]*)(&|$)/i; 71 if (window.location.search.match(thisRegExp) !== null) { 72 iniGame = unescape(window.location.search.match(thisRegExp)[3]); 73 } 74 75 // set hideFinishedGamesClocks to true/false to hide/show the clocks of finished games 76 var hideFinishedGamesClocks = false; 77 78 thisRegExp = /(&|\?)(help|h)=(true|t)(&|$)/i; 79 if (window.location.search.match(thisRegExp) !== null) { 80 alert("pgn4web live-mosaic-stone.html parameters" + "\n" + 81 " - useTextarea = " + useTextarea + "; if set true uses textarea as PGN input (default false = use pgnData)" + "\n" + 82 " - pgnData = " + pgnFile + "; PGN file to load (default " + pgnFile_default + ")" + "\n" + 83 " - refreshMinutes = " + refreshMinutes + "; refresh interval in minutes, decimals allowed (default " + refreshMinutes_default + ")" + "\n" + 84 " - refreshDemo = " + demoFlag + "; sets live demo mode (default false)" + "\n" + 85 " - initialGame = " + iniGame + "; initial game number or search string" + "\n" + 86 " - help = true"); 87 } 88 89 if (!useTextarea) { SetPgnUrl(pgnFile); } 90 SetImagePath("images/alpha/24"); 91 SetImageType("png"); 92 SetHighlightOption(true); // true or false 93 SetCommentsIntoMoveText(false); 94 SetCommentsOnSeparateLines(false); 95 SetAutoplayDelay(1000); // milliseconds 96 SetAutostartAutoplay(false); 97 SetAutoplayNextGame(false); 98 SetInitialGame(iniGame); 99 SetInitialVariation(0); 100 SetInitialHalfmove("end", true); 101 SetShortcutKeysEnabled(false); 102 SetLiveBroadcast(refreshMinutes, demoFlag, alertFlag, stepFlag); 103 104 clearShortcutSquares("G", "8"); 105 clearShortcutSquares("BCEFG", "7"); 106 clearShortcutSquares("CDEF", "6"); 107 clearShortcutSquares("ABCDEFGH", "345"); 108 109 110 function swapId(id_A, id_B) { 111 var id_saved; 112 var obj_A = document.getElementById(id_A); 113 if (!obj_A) { return; } 114 var obj_B = document.getElementById(id_B); 115 if (!obj_B) { return; } 116 id_saved = obj_A.id; 117 obj_A.id = obj_B.id; 118 obj_B.id = id_saved; 119 } 120 121 window['defaultFlipBoard'] = window['FlipBoard']; 122 window['FlipBoard'] = function() { 123 var theObj; 124 swapId("GameWhiteResult", "GameBlackResult"); 125 swapId("GameWhiteClock", "GameBlackClock"); 126 if (theObj = document.getElementById("GameWhiteClock")) { theObj.title = "white clock"; } 127 if (theObj = document.getElementById("GameBlackClock")) { theObj.title = "black clock"; } 128 swapId("GameWhite", "GameBlack"); 129 swapId("GameWhiteMoveNum", "GameBlackMoveNum"); 130 swapId("GameWhiteFlag", "GameBlackFlag"); 131 if (theObj = document.getElementById("GameWhiteFlag")) { theObj.className = "whiteFlag"; } 132 if (theObj = document.getElementById("GameBlackFlag")) { theObj.className = "blackFlag"; } 133 defaultFlipBoard(); 134 }; 135 136 137 try { 138 var pcscsfcf, cscs; 139 if (parent && (parent !== window) && (pcscsfcf = parent.pgn4webClearShortCutSquaresForChildFrames)) { 140 for (cscs in pcscsfcf) { clearShortcutSquares(pcscsfcf[cscs][0], pcscsfcf[cscs][1]); } 141 } 142 if (parent && (parent !== window) && parent.displayPgnData && parent.savePgnData) { 143 boardShortcut("D8", "show full PGN source data", function(t,e){ if (e.shiftKey) { parent.savePgnData(); } else { parent.displayPgnData(); } }); 144 } 145 } catch(e) { myAlert("warning: failed accessing frame's parent for shortcut squares to clear", false); } 146 147 function addTagToTitle(tagLabel, tagValue, object) { 148 if (!tagValue || tagValue[1] == "?" || !object) { return; } 149 object.title += ((object.title && tagLabel) ? "\n" : (object.title ? " " : "")) + simpleHtmlentitiesDecode(tagLabel + tagValue); 150 } 151 152 function hideThisGame() { 153 try { 154 if (parent && (parent !== window) && parent.pgn4webHideChildFrameGame) { 155 parent.pgn4webHideChildFrameGame(gameEvent[currentGame], gameSite[currentGame], gameDate[currentGame], gameRound[currentGame], gameWhite[currentGame], gameBlack[currentGame]); 156 } 157 } catch(e) { myAlert("error: failed accessing frame's parent for hiding game", true); } 158 } 159 160 function customFunctionOnPgnTextLoad() { 161 var thisCurrentGame = currentGame; 162 163 // force reloading iniGame each time 164 SetInitialGame(iniGame); 165 setCurrentGameFromInitialGame(); 166 if (currentGame != thisCurrentGame) { 167 SetInitialVariation(0); 168 SetInitialHalfmove("end",true); 169 Init(); 170 GoToInitialHalfmove(); 171 } 172 173 } 174 175 function customFunctionOnPgnGameLoad() { 176 var theObj; 177 178 if (theObj = document.getElementById("GameWhiteResult")) { 179 if (gameResult[currentGame] == "1/2-1/2") { theObj.innerHTML = "½"; } 180 else if (gameResult[currentGame] == "1-0") { theObj.innerHTML = "1"; } 181 else if (gameResult[currentGame] == "0-1") { theObj.innerHTML = "0"; } 182 else { theObj.innerHTML = ""; } 183 theObj.style.display = theObj.innerHTML ? "" : "none"; 184 } 185 if (theObj = document.getElementById("GameBlackResult")) { 186 if (gameResult[currentGame] == "1/2-1/2") { theObj.innerHTML = "½"; } 187 else if (gameResult[currentGame] == "1-0") { theObj.innerHTML = "0"; } 188 else if (gameResult[currentGame] == "0-1") { theObj.innerHTML = "1"; } 189 else { theObj.innerHTML = ""; } 190 theObj.style.display = theObj.innerHTML ? "" : "none"; 191 } 192 193 theObj = document.getElementById("topContainer"); 194 if (theObj) { 195 theObj.title = numberOfGames > 1 ? "game " + (currentGame+1) + " of " + numberOfGames : ""; 196 addTagToTitle("event: ", gameEvent[currentGame], theObj); 197 addTagToTitle("", customPgnHeaderTag("Section"), theObj); 198 addTagToTitle("", customPgnHeaderTag("Stage"), theObj); 199 addTagToTitle("site: ", gameSite[currentGame], theObj); 200 addTagToTitle("date: ", gameDate[currentGame], theObj); 201 addTagToTitle("round: ", gameRound[currentGame], theObj); 202 addTagToTitle("white: ", gameWhite[currentGame], theObj); 203 addTagToTitle("", customPgnHeaderTag("WhiteTitle"), theObj); 204 addTagToTitle("", customPgnHeaderTag("WhiteElo"), theObj); 205 addTagToTitle("", customPgnHeaderTag("WhiteTeam"), theObj); 206 addTagToTitle("black: ", gameBlack[currentGame], theObj); 207 addTagToTitle("", customPgnHeaderTag("BlackTitle"), theObj); 208 addTagToTitle("", customPgnHeaderTag("BlackElo"), theObj); 209 addTagToTitle("", customPgnHeaderTag("BlackTeam"), theObj); 210 addTagToTitle("result: ", gameResult[currentGame], theObj); 211 addTagToTitle("termination: ", customPgnHeaderTag("Termination"), theObj); 212 addTagToTitle("timecontrol: ", customPgnHeaderTag("TimeControl"), theObj); 213 var theOther = document.getElementById("bottomContainer"); 214 if (theOther) { theOther.title = theObj.title; } 215 } 216 217 try { 218 if (parent && (parent !== window) && parent.pgn4webHideChildFrameGame) { 219 if (parent.barePadding === "") { 220 if (parent.pgn4webHideChildFrameGame(gameEvent[currentGame], gameSite[currentGame], gameDate[currentGame], gameRound[currentGame], gameWhite[currentGame], gameBlack[currentGame], true)) { 221 boardShortcut("A6", "hide this game", function(t,e){ hideThisGame(); }); 222 } else { 223 boardShortcut("A6", "hiding option unavailable for this game", function(t,e){} ); 224 } 225 } 226 } 227 } catch(e) { myAlert("warning: failed accessing frame's parent for hiding game option", false); } 228 } 229 230 function customFunctionOnMove() { 231 var theObj, hideClocks = ((hideFinishedGamesClocks) && (gameResult[currentGame] != "*")); 232 233 if (theObj = document.getElementById("GameWhiteClock")) { hideClocks = hideClocks || !theObj.innerHTML; } 234 if (theObj = document.getElementById("GameBlackClock")) { hideClocks = hideClocks || !theObj.innerHTML; } 235 236 if (theObj = document.getElementById("GameWhiteClock")) { theObj.style.display = hideClocks ? "none" : ""; } 237 if (theObj = document.getElementById("GameBlackClock")) { theObj.style.display = hideClocks ? "none" : ""; } 238 if (theObj = document.getElementById("topLeftHeaderItem")) { theObj.style.width = hideClocks ? "196px" : ""; } 239 if (theObj = document.getElementById("topRightHeaderItem")) { theObj.style.width = hideClocks ? "28px" : ""; } 240 if (theObj = document.getElementById("bottomLeftHeaderItem")) { theObj.style.width = hideClocks ? "196px" : ""; } 241 if (theObj = document.getElementById("bottomRightHeaderItem")) { theObj.style.width = hideClocks ? "28px" : ""; } 242 243 if (theObj = document.getElementById("GameWhiteFlag")) { 244 theObj.style.display = (CurrentPly % 2) ? "none" : ""; 245 theObj.title = "white to move"; 246 } 247 if (theObj = document.getElementById("GameWhiteMoveNum")) { 248 theObj.style.display = (CurrentPly % 2) ? "inline" : "none"; 249 theObj.innerHTML = ((CurrentPly > 0) && (!hideClocks)) ? Math.floor((CurrentPly + 1 ) / 2) : ""; 250 theObj.title = (CurrentPly > StartPly) ? Math.floor((CurrentPly + 1) / 2) + ". " + Moves[CurrentPly - 1] : ""; 251 if (CurrentPly < StartPly + PlyNumber) { 252 theObj.innerHTML = theObj.innerHTML ? "." + theObj.innerHTML : " ·"; 253 theObj.title += (theObj.title ? " " : "") + "..."; 254 } 255 if (!theObj.innerHTML) { theObj.innerHTML = " "; } 256 if (!theObj.title) { theObj.title = ":"; } 257 } 258 if (theObj = document.getElementById("GameBlackFlag")) { 259 theObj.style.display = (CurrentPly % 2 === 0) ? "none" : ""; 260 theObj.title = "black to move"; 261 } 262 if (theObj = document.getElementById("GameBlackMoveNum")) { 263 theObj.style.display = (CurrentPly % 2 === 0) ? "inline" : "none"; 264 theObj.innerHTML = ((CurrentPly > 0) && (!hideClocks)) ? Math.floor((CurrentPly + 1 ) / 2) : ""; 265 theObj.title = (CurrentPly > StartPly) ? Math.floor((CurrentPly + 1) / 2) + "... " + Moves[CurrentPly - 1] : ""; 266 if (CurrentPly < StartPly + PlyNumber) { 267 theObj.innerHTML = theObj.innerHTML ? "." + theObj.innerHTML : " ·"; 268 theObj.title += (theObj.title ? " " : "") + "..."; 269 } 270 if (!theObj.innerHTML) { theObj.innerHTML = " "; } 271 if (!theObj.title) { theObj.title = ":"; } 272 } 273 } 274 275 function gameKey(event, site, date, round, white, black) { 276 var key = ""; 277 key += "[" + (typeof(event) == "string" ? event : "") + "]"; 278 key += "[" + (typeof(site) == "string" ? site : "") + "]"; 279 key += "[" + (typeof(round) == "string" ? round : "") + "]"; 280 key += "[" + (typeof(white) == "string" ? white : "") + "]"; 281 key += "[" + (typeof(black) == "string" ? black : "") + "]"; 282 return key; 283 } 284 285 function replayPreviousMovesMosaic(force) { 286 replayPreviousMoves(2); 287 } 288 289 function customShortcutKey_Shift_0() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_0) { parent.customShortcutKey_Shift_0(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 290 291 // customShortcutKey_Shift_1 defined by fide-lookup.js 292 // customShortcutKey_Shift_2 defined by fide-lookup.js 293 294 function customShortcutKey_Shift_3() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_3) { parent.customShortcutKey_Shift_3(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 295 function customShortcutKey_Shift_4() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_4) { parent.customShortcutKey_Shift_4(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 296 function customShortcutKey_Shift_5() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_5) { parent.customShortcutKey_Shift_5(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 297 function customShortcutKey_Shift_6() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_6) { parent.customShortcutKey_Shift_6(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 298 function customShortcutKey_Shift_7() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_7) { parent.customShortcutKey_Shift_7(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 299 300 // overwriting engine.js definitions of customShortcutKey_Shift_8 9 0 301 function customShortcutKey_Shift_8() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_8) { parent.customShortcutKey_Shift_8(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 302 function customShortcutKey_Shift_9() { try { if (parent && (parent !== window) && parent.customShortcutKey_Shift_9) { parent.customShortcutKey_Shift_9(); } } catch(e) { myAlert("error: failed accessing frame's parent custom shortcut key function"); } } 303 304 function pgn4web_onload(e) { 305 var theObj; 306 start_pgn4web(); 307 readyToReceivePgn = true; 308 try { 309 if (parent && (parent !== window)) { 310 if (parent.readyToSendPgn) { 311 var boardId = parseInt(window.name.substr(5), 10); 312 if (!isNaN(boardId)) { parent.updateBoard(boardId); } 313 else { myAlert("warning: failed detecting board id", false); } 314 } 315 if (parent.document.body.style.backgroundColor) { 316 var RGB; 317 if (RGB = parent.document.body.style.backgroundColor.match(/^rgb\((\d+), (\d+), (\d+)\)$/)) { 318 // RGB to Luma conversion: Photometric/digital ITU-R 319 if ((0.2126 * parseInt(RGB[1],10) + 0.7152 * parseInt(RGB[2],10) + 0.0722 * parseInt(RGB[3],10)) < (256 * 0.45)) { 320 if (theObj = document.body) { theObj.style.color = "white"; } 321 if (theObj = document.getElementById("GameWhiteFlag")) { theObj.style.borderColor = "white"; } 322 if (theObj = document.getElementById("GameBlackFlag")) { theObj.style.borderColor = "white"; } 323 } 324 } 325 } 326 } else { myAlert("warning: parent not avalable", false); } 327 } catch(e) { myAlert("warning: failed accessing parent", false); } 328 } 329 330</script> 331 332<style type="text/css"> 333 334@import url("fonts/pgn4web-font-LiberationSans.css"); 335 336html, 337body { 338 margin: 0px; 339 padding: 0px; 340} 341 342body { 343 background: transparent; 344 color: black; 345 font-family: 'pgn4web Liberation Sans', sans-serif; 346 font-weight: bold; 347 font-size: 13px; 348 line-height: 17px; 349 padding: 13px; 350 351 -webkit-user-select: none; 352 -moz-user-select: none; 353 -ms-user-select: none; 354 -o-user-select: none; 355 user-select: none; 356 -webkit-text-size-adjust: none; 357 -moz-text-size-adjust: none; 358 -ms-text-size-adjust: none; 359 -o-text-size-adjust: none; 360 text-size-adjust: none; 361 -webkit-touch-callout: none; 362} 363 364a { 365 color: inherit; 366 text-decoration: none; 367} 368 369.boardTable { 370 border-style: solid; 371 border-color: #663300; 372 border-width: 3px; 373 background: #CC9966; 374 box-shadow: 0px 0px 9px #996633; 375 width: 230px; 376 height: 230px; 377} 378 379.pieceImage { 380 width: 24px; 381 height: 24px; 382} 383 384.whiteSquare, 385.blackSquare, 386.highlightWhiteSquare, 387.highlightBlackSquare { 388 width: 26px; 389 height: 26px; 390 border-style: solid; 391 border-width: 1px; 392} 393 394.whiteSquare, 395.highlightWhiteSquare { 396 border-color: #FFCC99; 397 background: #FFCC99; 398} 399 400.blackSquare, 401.highlightBlackSquare { 402 border-color: #CC9966; 403 background: #CC9966; 404} 405 406.highlightWhiteSquare, 407.highlightBlackSquare { 408 border-style: inset; 409 border-color: #CC9966; 410} 411 412.move, 413.variation, 414.comment { 415} 416 417.topContainer, 418.bottomContainer { 419 display: inline-block; 420 width: 224px; 421} 422 423.topContainer { 424 margin-bottom: 11px; 425} 426 427.bottomContainer { 428 margin-top: 15px; 429} 430 431.leftHeaderItem, 432.rightHeaderItem { 433 white-space: nowrap; 434 overflow: hidden; 435 /* text-overflow: ellipsis; */ 436} 437 438.leftHeaderItem { 439 clear: both; 440 float: left; 441 width: 140px; 442 text-align: left; 443} 444 445.rightHeaderItem { 446 float: right; 447 width: 77px; 448 text-align: right; 449} 450 451.gameResult, 452.flagMoves { 453 display: inline-block; 454 width: 28px; 455} 456 457.whiteFlag, 458.blackFlag { 459 display: inline-block; 460 width: 6px; 461 height: 6px; 462 border: solid 2px black; 463} 464 465.whiteFlag { 466 background: white; 467} 468 469.blackFlag { 470 background: black; 471} 472 473</style> 474 475</head> 476 477<body> 478 479<!-- paste your PGN below and make sure you dont specify an external source with SetPgnUrl() --> 480<form style="display: none;"><textarea style="display: none;" id="pgnText"> 481 482[Result "*"] 483 484</textarea></form> 485<!-- paste your PGN above and make sure you dont specify an external source with SetPgnUrl() --> 486 487<center> 488 489<div id="topContainer" class="topContainer"> 490<div id="topLeftHeaderItem" class="leftHeaderItem"><span id="GameBlackResult" class="gameResult"></span><span id="GameBlack" class="notranslate" onclick="if (typeof(openFidePlayerUrl) == 'function') { openFidePlayerUrl(IsRotated ? gameWhite[currentGame] : gameBlack[currentGame], customPgnHeaderTag(IsRotated ? 'WhiteFideId' : 'BlackFideId')); } this.blur();"></span></div><div id="topRightHeaderItem" class="rightHeaderItem"><span id="GameBlackClock" title="black clock"></span><span class="flagMoves" onclick="SetAutoplayDelayAndStart(Delay);"><span id="GameBlackFlag" class="blackFlag"></span><span style="display:none;" id="GameBlackMoveNum"></span></span></div> 491</div> 492 493<div id="GameBoard"></div> 494 495<div id="bottomContainer" class="bottomContainer"> 496<div id="bottomLeftHeaderItem" class="leftHeaderItem"><span id="GameWhiteResult" class="gameResult"></span><span id="GameWhite" class="notranslate" onclick="if (typeof(openFidePlayerUrl) == 'function') { openFidePlayerUrl(IsRotated ? gameBlack[currentGame] : gameWhite[currentGame], customPgnHeaderTag(IsRotated ? 'BlackFideId' : 'WhiteFideId')); } this.blur();"></span></div><div id="bottomRightHeaderItem" class="rightHeaderItem"><span id="GameWhiteClock" title="white clock"></span><span class="flagMoves" onclick="SetAutoplayDelayAndStart(Delay);"><span id="GameWhiteFlag" class="whiteFlag"></span><span style="display:none;" id="GameWhiteMoveNum"></span></span></div> 497</div> 498 499</center> 500 501</body> 502 503</html> 504