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">&nbsp;</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">&nbsp;</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>&nbsp;&nbsp;<span id="GameLastVariations" title="last move alternatives"></span>&nbsp;
335</div>
336<div class="shortRowSpace">&nbsp;</div>
337<div class="gameNextMove">
338<span id="GameNextMove" title="next move"></span>&nbsp;&nbsp;<span id="GameNextVariations" title="next move alternatives"></span>&nbsp;
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">&nbsp;</div>
347
348<div class="gametextresultDiv" id="GameTextResult">
349<div id="GameText"></div>
350<div class="comment" style="line-height: 33%;">&nbsp;</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([ "&nbsp;", "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