fix trivial cases of no-var
parent
39bd299c98
commit
1dba9f3a58
|
@ -18,10 +18,9 @@
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"@typescript-eslint/no-this-alias": "off",
|
"@typescript-eslint/no-this-alias": "off",
|
||||||
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
||||||
|
"@typescript-eslint/no-empty-interface": "off",
|
||||||
|
|
||||||
"eqeqeq": "off",
|
"eqeqeq": "off",
|
||||||
"no-var": "off",
|
|
||||||
"@typescript-eslint/no-empty-interface": "off",
|
|
||||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
"prefer-spread": "off",
|
"prefer-spread": "off",
|
||||||
"prefer-rest-params": "off",
|
"prefer-rest-params": "off",
|
||||||
|
|
|
@ -313,7 +313,7 @@ interface CashStatic {
|
||||||
declare module 'cash' {
|
declare module 'cash' {
|
||||||
export = $;
|
export = $;
|
||||||
}
|
}
|
||||||
declare var $: CashStatic;
|
declare const $: CashStatic;
|
||||||
/* export default cash; */
|
/* export default cash; */
|
||||||
/* export { Cash, CashStatic, Ele as Element, Selector, Comparator, Context }; */
|
/* export { Cash, CashStatic, Ele as Element, Selector, Comparator, Context }; */
|
||||||
/* end hacks */
|
/* end hacks */
|
||||||
|
|
|
@ -490,4 +490,4 @@ declare namespace PowerTip {
|
||||||
|
|
||||||
declare module '@yaireo/tagify';
|
declare module '@yaireo/tagify';
|
||||||
|
|
||||||
declare var lichess: Lichess;
|
declare const lichess: Lichess;
|
||||||
|
|
|
@ -18,13 +18,11 @@ export function make(cfg: ForecastData, data: AnalyseData, redraw: () => void):
|
||||||
}
|
}
|
||||||
|
|
||||||
function findStartingWithNode(node: ForecastStep): ForecastStep[][] {
|
function findStartingWithNode(node: ForecastStep): ForecastStep[][] {
|
||||||
return forecasts.filter(function (fc) {
|
return forecasts.filter(fc => contains(fc, [node]));
|
||||||
return contains(fc, [node]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function collides(fc1: ForecastStep[], fc2: ForecastStep[]): boolean {
|
function collides(fc1: ForecastStep[], fc2: ForecastStep[]): boolean {
|
||||||
for (var i = 0, max = Math.min(fc1.length, fc2.length); i < max; i++) {
|
for (let i = 0, max = Math.min(fc1.length, fc2.length); i < max; i++) {
|
||||||
if (fc1[i].uci !== fc2[i].uci) {
|
if (fc1[i].uci !== fc2[i].uci) {
|
||||||
if (cfg.onMyTurn) return i !== 0 && i % 2 === 0;
|
if (cfg.onMyTurn) return i !== 0 && i % 2 === 0;
|
||||||
return i % 2 === 1;
|
return i % 2 === 1;
|
||||||
|
@ -74,9 +72,7 @@ export function make(cfg: ForecastData, data: AnalyseData, redraw: () => void):
|
||||||
function isCandidate(fc: ForecastStep[]): boolean {
|
function isCandidate(fc: ForecastStep[]): boolean {
|
||||||
fc = truncate(fc);
|
fc = truncate(fc);
|
||||||
if (!isLongEnough(fc)) return false;
|
if (!isLongEnough(fc)) return false;
|
||||||
var collisions = forecasts.filter(function (f) {
|
const collisions = forecasts.filter(f => contains(f, fc));
|
||||||
return contains(f, fc);
|
|
||||||
});
|
|
||||||
if (collisions.length) return false;
|
if (collisions.length) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import { bind, dataIcon, spinner } from '../util';
|
||||||
import { fixCrazySan } from 'chess';
|
import { fixCrazySan } from 'chess';
|
||||||
|
|
||||||
function onMyTurn(ctrl: AnalyseCtrl, fctrl: ForecastCtrl, cNodes: ForecastStep[]): VNode | undefined {
|
function onMyTurn(ctrl: AnalyseCtrl, fctrl: ForecastCtrl, cNodes: ForecastStep[]): VNode | undefined {
|
||||||
var firstNode = cNodes[0];
|
const firstNode = cNodes[0];
|
||||||
if (!firstNode) return;
|
if (!firstNode) return;
|
||||||
var fcs = fctrl.findStartingWithNode(firstNode);
|
const fcs = fctrl.findStartingWithNode(firstNode);
|
||||||
if (!fcs.length) return;
|
if (!fcs.length) return;
|
||||||
var lines = fcs.filter(function (fc) {
|
const lines = fcs.filter(function (fc) {
|
||||||
return fc.length > 1;
|
return fc.length > 1;
|
||||||
});
|
});
|
||||||
return h(
|
return h(
|
||||||
|
|
|
@ -16,7 +16,7 @@ export function nextGlyphSymbol(
|
||||||
const len = mainline.length;
|
const len = mainline.length;
|
||||||
if (!len) return;
|
if (!len) return;
|
||||||
const fromIndex = fromPly - mainline[0].ply;
|
const fromIndex = fromPly - mainline[0].ply;
|
||||||
for (var i = 1; i < len; i++) {
|
for (let i = 1; i < len; i++) {
|
||||||
const node = mainline[(fromIndex + i) % len];
|
const node = mainline[(fromIndex + i) % len];
|
||||||
const found =
|
const found =
|
||||||
node.ply % 2 === (color === 'white' ? 1 : 0) &&
|
node.ply % 2 === (color === 'white' ? 1 : 0) &&
|
||||||
|
@ -32,11 +32,11 @@ export function nextGlyphSymbol(
|
||||||
export function evalSwings(mainline: Tree.Node[], nodeFilter: (node: Tree.Node) => boolean): Tree.Node[] {
|
export function evalSwings(mainline: Tree.Node[], nodeFilter: (node: Tree.Node) => boolean): Tree.Node[] {
|
||||||
const found: Tree.Node[] = [];
|
const found: Tree.Node[] = [];
|
||||||
const threshold = 0.1;
|
const threshold = 0.1;
|
||||||
for (var i = 1; i < mainline.length; i++) {
|
for (let i = 1; i < mainline.length; i++) {
|
||||||
var node = mainline[i];
|
const node = mainline[i];
|
||||||
var prev = mainline[i - 1];
|
const prev = mainline[i - 1];
|
||||||
if (nodeFilter(node) && node.eval && prev.eval) {
|
if (nodeFilter(node) && node.eval && prev.eval) {
|
||||||
var diff = Math.abs(winningChances.povDiff('white', prev.eval, node.eval));
|
const diff = Math.abs(winningChances.povDiff('white', prev.eval, node.eval));
|
||||||
if (diff > threshold && hasCompChild(prev)) found.push(node);
|
if (diff > threshold && hasCompChild(prev)) found.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ function renderNodesTxt(nodes: PgnNode[]): string {
|
||||||
if (!nodes[0]) return '';
|
if (!nodes[0]) return '';
|
||||||
if (!nodes[0].san) nodes = nodes.slice(1);
|
if (!nodes[0].san) nodes = nodes.slice(1);
|
||||||
if (!nodes[0]) return '';
|
if (!nodes[0]) return '';
|
||||||
var s = nodes[0].ply % 2 === 1 ? '' : Math.floor((nodes[0].ply + 1) / 2) + '... ';
|
let s = nodes[0].ply % 2 === 1 ? '' : Math.floor((nodes[0].ply + 1) / 2) + '... ';
|
||||||
nodes.forEach(function (node, i) {
|
nodes.forEach(function (node, i) {
|
||||||
if (node.ply === 0) return;
|
if (node.ply === 0) return;
|
||||||
if (node.ply % 2 === 1) s += (node.ply + 1) / 2 + '. ';
|
if (node.ply % 2 === 1) s += (node.ply + 1) / 2 + '. ';
|
||||||
|
@ -23,9 +23,9 @@ function renderNodesTxt(nodes: PgnNode[]): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderFullTxt(ctrl: AnalyseCtrl): string {
|
export function renderFullTxt(ctrl: AnalyseCtrl): string {
|
||||||
var g = ctrl.data.game;
|
const g = ctrl.data.game;
|
||||||
var txt = renderNodesTxt(ctrl.tree.getNodeList(ctrl.path));
|
let txt = renderNodesTxt(ctrl.tree.getNodeList(ctrl.path));
|
||||||
var tags: Array<[string, string]> = [];
|
const tags: Array<[string, string]> = [];
|
||||||
if (g.variant.key !== 'standard') tags.push(['Variant', g.variant.name]);
|
if (g.variant.key !== 'standard') tags.push(['Variant', g.variant.name]);
|
||||||
if (g.initialFen && g.initialFen !== initialFen) tags.push(['FEN', g.initialFen]);
|
if (g.initialFen && g.initialFen !== initialFen) tags.push(['FEN', g.initialFen]);
|
||||||
if (tags.length)
|
if (tags.length)
|
||||||
|
|
|
@ -116,11 +116,11 @@ export function make(root: AnalyseCtrl, color: Color): RetroCtrl {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkCeval(): void {
|
function checkCeval(): void {
|
||||||
var node = root.node,
|
const node = root.node,
|
||||||
cur = current();
|
cur = current();
|
||||||
if (!cur || feedback() !== 'eval' || cur.fault.node.ply !== node.ply) return;
|
if (!cur || feedback() !== 'eval' || cur.fault.node.ply !== node.ply) return;
|
||||||
if (isCevalReady(node)) {
|
if (isCevalReady(node)) {
|
||||||
var diff = winningChances.povDiff(color, node.ceval!, cur.prev.node.eval);
|
const diff = winningChances.povDiff(color, node.ceval!, cur.prev.node.eval);
|
||||||
if (diff > -0.035) onWin();
|
if (diff > -0.035) onWin();
|
||||||
else onFail();
|
else onFail();
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ export function make(send: SocketSend, ctrl: AnalyseCtrl): Socket {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStudyData(req: Req, isWrite = false): void {
|
function addStudyData(req: Req, isWrite = false): void {
|
||||||
var c = currentChapterId();
|
const c = currentChapterId();
|
||||||
if (c) {
|
if (c) {
|
||||||
req.ch = c;
|
req.ch = c;
|
||||||
if (isWrite) {
|
if (isWrite) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ function isWinning(node: Tree.Node, goalCp: number, color: Color): boolean | nul
|
||||||
function myMateIn(node: Tree.Node, color: Color): number | boolean | null {
|
function myMateIn(node: Tree.Node, color: Color): number | boolean | null {
|
||||||
if (!hasSolidEval(node)) return null;
|
if (!hasSolidEval(node)) return null;
|
||||||
if (!node.ceval!.mate) return false;
|
if (!node.ceval!.mate) return false;
|
||||||
var mateIn = node.ceval!.mate! * (color === 'white' ? 1 : -1);
|
const mateIn = node.ceval!.mate! * (color === 'white' ? 1 : -1);
|
||||||
return mateIn > 0 ? mateIn : false;
|
return mateIn > 0 ? mateIn : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ export function view(ctrl: StudyCtrl): VNode {
|
||||||
isOwner = members.isOwner();
|
isOwner = members.isOwner();
|
||||||
|
|
||||||
function username(member: StudyMember) {
|
function username(member: StudyMember) {
|
||||||
var u = member.user;
|
const u = member.user;
|
||||||
return h(
|
return h(
|
||||||
'span.user-link.ulpt',
|
'span.user-link.ulpt',
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,13 +152,13 @@ export function toYouTubeEmbed(url: string): string | undefined {
|
||||||
|
|
||||||
function toYouTubeEmbedUrl(url: string) {
|
function toYouTubeEmbedUrl(url: string) {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
var m = url.match(
|
const m = url.match(
|
||||||
/(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([^"&?\/ ]{11})(?:\?|&|)(\S*)/i
|
/(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([^"&?\/ ]{11})(?:\?|&|)(\S*)/i
|
||||||
);
|
);
|
||||||
if (!m) return;
|
if (!m) return;
|
||||||
var start = 0;
|
let start = 0;
|
||||||
m[2].split('&').forEach(function (p) {
|
m[2].split('&').forEach(function (p) {
|
||||||
var s = p.split('=');
|
const s = p.split('=');
|
||||||
if (s[0] === 't' || s[0] === 'start') {
|
if (s[0] === 't' || s[0] === 'start') {
|
||||||
if (s[1].match(/^\d+$/)) start = parseInt(s[1]);
|
if (s[1].match(/^\d+$/)) start = parseInt(s[1]);
|
||||||
else {
|
else {
|
||||||
|
@ -167,7 +167,7 @@ function toYouTubeEmbedUrl(url: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var params = 'modestbranding=1&rel=0&controls=2&iv_load_policy=3' + (start ? '&start=' + start : '');
|
const params = 'modestbranding=1&rel=0&controls=2&iv_load_policy=3' + (start ? '&start=' + start : '');
|
||||||
return 'https://www.youtube.com/embed/' + m[1] + '?' + params;
|
return 'https://www.youtube.com/embed/' + m[1] + '?' + params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ export default function (opts: ChallengeOpts, data: ChallengeData, redraw: () =>
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUser(user: ChallengeUser) {
|
function showUser(user: ChallengeUser) {
|
||||||
var rating = user.rating + (user.provisional ? '?' : '');
|
const rating = user.rating + (user.provisional ? '?' : '');
|
||||||
var fullName = (user.title ? user.title + ' ' : '') + user.name;
|
const fullName = (user.title ? user.title + ' ' : '') + user.name;
|
||||||
return fullName + ' (' + rating + ')';
|
return fullName + ' (' + rating + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ function execute(q: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function command(q: string) {
|
function command(q: string) {
|
||||||
var parts = q.split(' '),
|
const parts = q.split(' '),
|
||||||
exec = parts[0];
|
exec = parts[0];
|
||||||
|
|
||||||
const is = function (commands: string) {
|
const is = function (commands: string) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ function applyBackground(data: BackgroundData, list: Background[]) {
|
||||||
sheet = key == 'darkBoard' ? 'dark' : key;
|
sheet = key == 'darkBoard' ? 'dark' : key;
|
||||||
$('body').data('theme', sheet);
|
$('body').data('theme', sheet);
|
||||||
$('link[href*=".' + prev + '."]').each(function (this: HTMLLinkElement) {
|
$('link[href*=".' + prev + '."]').each(function (this: HTMLLinkElement) {
|
||||||
var link = document.createElement('link') as HTMLLinkElement;
|
const link = document.createElement('link') as HTMLLinkElement;
|
||||||
link.rel = 'stylesheet';
|
link.rel = 'stylesheet';
|
||||||
link.href = this.href.replace('.' + prev + '.', '.' + sheet + '.');
|
link.href = this.href.replace('.' + prev + '.', '.' + sheet + '.');
|
||||||
link.onload = () => setTimeout(() => this.remove(), 100);
|
link.onload = () => setTimeout(() => this.remove(), 100);
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default function (token: string) {
|
||||||
: 'san';
|
: 'san';
|
||||||
const speechSynthesisOn = localStorage.getItem('dgt-speech-synthesis') == 'true';
|
const speechSynthesisOn = localStorage.getItem('dgt-speech-synthesis') == 'true';
|
||||||
const voice = localStorage.getItem('dgt-speech-voice');
|
const voice = localStorage.getItem('dgt-speech-voice');
|
||||||
var keywords = {
|
let keywords = {
|
||||||
K: 'King',
|
K: 'King',
|
||||||
Q: 'Queen',
|
Q: 'Queen',
|
||||||
R: 'Rook',
|
R: 'Rook',
|
||||||
|
@ -56,15 +56,15 @@ export default function (token: string) {
|
||||||
/**
|
/**
|
||||||
* GLOBAL VARIABLES - Lichess Connectivity
|
* GLOBAL VARIABLES - Lichess Connectivity
|
||||||
*/
|
*/
|
||||||
var time = new Date(); //A Global time object
|
const time = new Date(); //A Global time object
|
||||||
var currentGameId = ''; //Track which is the current Game, in case there are several open games
|
let currentGameId = ''; //Track which is the current Game, in case there are several open games
|
||||||
var currentGameColor = ''; //Track which color is being currently played by the player. 'white' or 'black'
|
let currentGameColor = ''; //Track which color is being currently played by the player. 'white' or 'black'
|
||||||
var me: { id: string; username: string }; //Track my information
|
let me: { id: string; username: string }; //Track my information
|
||||||
var gameInfoMap = new Map(); //A collection of key values to store game immutable information of all open games
|
const gameInfoMap = new Map(); //A collection of key values to store game immutable information of all open games
|
||||||
var gameStateMap = new Map(); //A collection of key values to store the changing state of all open games
|
const gameStateMap = new Map(); //A collection of key values to store the changing state of all open games
|
||||||
var gameConnectionMap = new Map<string, { connected: boolean; lastEvent: number }>(); //A collection of key values to store the network status of a game
|
const gameConnectionMap = new Map<string, { connected: boolean; lastEvent: number }>(); //A collection of key values to store the network status of a game
|
||||||
var gameChessBoardMap = new Map<string, Chess>(); //A collection of chessops Boards representing the current board of the games
|
const gameChessBoardMap = new Map<string, Chess>(); //A collection of chessops Boards representing the current board of the games
|
||||||
var eventSteamStatus = { connected: false, lastEvent: time.getTime() }; //An object to store network status of the main eventStream
|
let eventSteamStatus = { connected: false, lastEvent: time.getTime() }; //An object to store network status of the main eventStream
|
||||||
const keywordsBase = [
|
const keywordsBase = [
|
||||||
'white',
|
'white',
|
||||||
'black',
|
'black',
|
||||||
|
@ -86,20 +86,20 @@ export default function (token: string) {
|
||||||
'illegal',
|
'illegal',
|
||||||
'move',
|
'move',
|
||||||
];
|
];
|
||||||
var lastSanMove: { player: string; move: string; by: string }; //Track last move in SAN format. This is because there is no easy way to keep history of san moves
|
let lastSanMove: { player: string; move: string; by: string }; //Track last move in SAN format. This is because there is no easy way to keep history of san moves
|
||||||
/**
|
/**
|
||||||
* Global Variables for DGT Board Connection (JACM)
|
* Global Variables for DGT Board Connection (JACM)
|
||||||
*/
|
*/
|
||||||
var localBoard: Chess = startingPosition(); //Board with valid moves played on Lichess and DGT Board. May be half move behind Lichess or half move in advance
|
let localBoard: Chess = startingPosition(); //Board with valid moves played on Lichess and DGT Board. May be half move behind Lichess or half move in advance
|
||||||
var DGTgameId = ''; //Used to track if DGT board was setup already with the lichess currentGameId
|
let DGTgameId = ''; //Used to track if DGT board was setup already with the lichess currentGameId
|
||||||
var boards = Array<{ serialnr: string; state: string }>(); //An array to store all the board recognized by DGT LiveChess
|
let boards = Array<{ serialnr: string; state: string }>(); //An array to store all the board recognized by DGT LiveChess
|
||||||
var liveChessConnection: WebSocket; //Connection Object to LiveChess through websocket
|
let liveChessConnection: WebSocket; //Connection Object to LiveChess through websocket
|
||||||
var isLiveChessConnected = false; //Used to track if a board there is a connection to DGT Live Chess
|
let isLiveChessConnected = false; //Used to track if a board there is a connection to DGT Live Chess
|
||||||
var currentSerialnr = '0'; //Public property to store the current serial number of the DGT Board in case there is more than one
|
let currentSerialnr = '0'; //Public property to store the current serial number of the DGT Board in case there is more than one
|
||||||
//subscription stores the information about the board being connected, most importantly the serialnr
|
//subscription stores the information about the board being connected, most importantly the serialnr
|
||||||
var subscription = { id: 2, call: 'subscribe', param: { feed: 'eboardevent', id: 1, param: { serialnr: '' } } };
|
const subscription = { id: 2, call: 'subscribe', param: { feed: 'eboardevent', id: 1, param: { serialnr: '' } } };
|
||||||
var lastLegalParam: { board: string; san: string[] }; //This can help prevent duplicate moves from LiveChess being detected as move from the other side, like a duplicate O-O
|
let lastLegalParam: { board: string; san: string[] }; //This can help prevent duplicate moves from LiveChess being detected as move from the other side, like a duplicate O-O
|
||||||
var lastLiveChessBoard: string; //Store last Board received by LiveChess
|
let lastLiveChessBoard: string; //Store last Board received by LiveChess
|
||||||
/***
|
/***
|
||||||
* Bind console output to HTML pre Element
|
* Bind console output to HTML pre Element
|
||||||
*/
|
*/
|
||||||
|
@ -121,7 +121,7 @@ export default function (token: string) {
|
||||||
console[name] = function () {
|
console[name] = function () {
|
||||||
//Return a promise so execution is not delayed by string manipulation
|
//Return a promise so execution is not delayed by string manipulation
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
var output = '';
|
let output = '';
|
||||||
for (let i = 0; i < arguments.length; i++) {
|
for (let i = 0; i < arguments.length; i++) {
|
||||||
const arg = arguments[i];
|
const arg = arguments[i];
|
||||||
if (arg == '*' || arg == ':') {
|
if (arg == '*' || arg == ':') {
|
||||||
|
@ -236,12 +236,12 @@ export default function (token: string) {
|
||||||
//Update connection status
|
//Update connection status
|
||||||
eventSteamStatus = { connected: true, lastEvent: time.getTime() };
|
eventSteamStatus = { connected: true, lastEvent: time.getTime() };
|
||||||
//Response may contain several JSON objects on the same chunk separated by \n . This may create an empty element at the end.
|
//Response may contain several JSON objects on the same chunk separated by \n . This may create an empty element at the end.
|
||||||
var jsonArray = value ? decoder.decode(value).split('\n') : [];
|
const jsonArray = value ? decoder.decode(value).split('\n') : [];
|
||||||
for (let i = 0; i < jsonArray.length; i++) {
|
for (let i = 0; i < jsonArray.length; i++) {
|
||||||
//Skip empty elements that may have happened witht the .split('\n')
|
//Skip empty elements that may have happened witht the .split('\n')
|
||||||
if (jsonArray[i].length > 2) {
|
if (jsonArray[i].length > 2) {
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(jsonArray[i]);
|
const data = JSON.parse(jsonArray[i]);
|
||||||
//JSON data found, let's check if this is a game that started. field type is mandatory except on http 4xx
|
//JSON data found, let's check if this is a game that started. field type is mandatory except on http 4xx
|
||||||
if (data.type == 'gameStart') {
|
if (data.type == 'gameStart') {
|
||||||
if (verbose) console.log('connectToEventStream - gameStart event arrived. GameId: ' + data.game.id);
|
if (verbose) console.log('connectToEventStream - gameStart event arrived. GameId: ' + data.game.id);
|
||||||
|
@ -333,12 +333,12 @@ export default function (token: string) {
|
||||||
//Update connection status
|
//Update connection status
|
||||||
gameConnectionMap.set(gameId, { connected: true, lastEvent: time.getTime() });
|
gameConnectionMap.set(gameId, { connected: true, lastEvent: time.getTime() });
|
||||||
//Response may contain several JSON objects on the same chunk separated by \n . This may create an empty element at the end.
|
//Response may contain several JSON objects on the same chunk separated by \n . This may create an empty element at the end.
|
||||||
var jsonArray = decoder.decode(value)!.split('\n');
|
const jsonArray = decoder.decode(value)!.split('\n');
|
||||||
for (let i = 0; i < jsonArray.length; i++) {
|
for (let i = 0; i < jsonArray.length; i++) {
|
||||||
//Skip empty elements that may have happened witht the .split('\n')
|
//Skip empty elements that may have happened witht the .split('\n')
|
||||||
if (jsonArray[i].length > 2) {
|
if (jsonArray[i].length > 2) {
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(jsonArray[i]);
|
const data = JSON.parse(jsonArray[i]);
|
||||||
//The first line is always of type gameFull.
|
//The first line is always of type gameFull.
|
||||||
if (data.type == 'gameFull') {
|
if (data.type == 'gameFull') {
|
||||||
if (!verbose) console.clear();
|
if (!verbose) console.clear();
|
||||||
|
@ -397,7 +397,7 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function formattedTimer(timer: number): string {
|
function formattedTimer(timer: number): string {
|
||||||
// Pad function to pad with 0 to 2 or 3 digits, default is 2
|
// Pad function to pad with 0 to 2 or 3 digits, default is 2
|
||||||
var pad = (n: number, z = 2) => `00${n}`.slice(-z);
|
const pad = (n: number, z = 2) => `00${n}`.slice(-z);
|
||||||
return pad((timer / 3.6e6) | 0) + ':' + pad(((timer % 3.6e6) / 6e4) | 0) + ':' + pad(((timer % 6e4) / 1000) | 0); //+ '.' + pad(timer % 1000, 3);
|
return pad((timer / 3.6e6) | 0) + ':' + pad(((timer % 3.6e6) / 6e4) | 0) + ':' + pad(((timer % 6e4) / 1000) | 0); //+ '.' + pad(timer % 1000, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ export default function (token: string) {
|
||||||
async function chooseCurrentGame() {
|
async function chooseCurrentGame() {
|
||||||
//Determine new value for currentGameId. First create an array with only the started games
|
//Determine new value for currentGameId. First create an array with only the started games
|
||||||
//So then there is none or more than one started game
|
//So then there is none or more than one started game
|
||||||
var playableGames = playableGamesArray();
|
const playableGames = playableGamesArray();
|
||||||
//If there is only one started game, then its easy
|
//If there is only one started game, then its easy
|
||||||
/*
|
/*
|
||||||
if (playableGames.length == 1) {
|
if (playableGames.length == 1) {
|
||||||
|
@ -521,16 +521,16 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function initializeChessBoard(gameId: string, data: { initialFen: string; state: { moves: string } }) {
|
function initializeChessBoard(gameId: string, data: { initialFen: string; state: { moves: string } }) {
|
||||||
try {
|
try {
|
||||||
var initialFen: string = INITIAL_FEN;
|
let initialFen: string = INITIAL_FEN;
|
||||||
if (data.initialFen != 'startpos') initialFen = data.initialFen;
|
if (data.initialFen != 'startpos') initialFen = data.initialFen;
|
||||||
var setup = parseFen(initialFen).unwrap();
|
const setup = parseFen(initialFen).unwrap();
|
||||||
var chess: Chess = Chess.fromSetup(setup).unwrap();
|
const chess: Chess = Chess.fromSetup(setup).unwrap();
|
||||||
var moves = data.state.moves.split(' ');
|
const moves = data.state.moves.split(' ');
|
||||||
for (let i = 0; i < moves.length; i++) {
|
for (let i = 0; i < moves.length; i++) {
|
||||||
if (moves[i] != '') {
|
if (moves[i] != '') {
|
||||||
//Make any move that may have been already played on the ChessBoard. Useful when reconnecting
|
//Make any move that may have been already played on the ChessBoard. Useful when reconnecting
|
||||||
var uciMove = <NormalMove>parseUci(moves[i]);
|
const uciMove = <NormalMove>parseUci(moves[i]);
|
||||||
var normalizedMove = chess.normalizeMove(uciMove); //This is because chessops uses UCI_960
|
const normalizedMove = chess.normalizeMove(uciMove); //This is because chessops uses UCI_960
|
||||||
if (normalizedMove && chess.isLegal(normalizedMove)) chess.play(normalizedMove);
|
if (normalizedMove && chess.isLegal(normalizedMove)) chess.play(normalizedMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,9 +553,9 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function updateChessBoard(gameId: string, currentState: { moves: string }, newState: { moves: string }) {
|
function updateChessBoard(gameId: string, currentState: { moves: string }, newState: { moves: string }) {
|
||||||
try {
|
try {
|
||||||
var chess = gameChessBoardMap.get(gameId);
|
const chess = gameChessBoardMap.get(gameId);
|
||||||
if (chess) {
|
if (chess) {
|
||||||
var pendingMoves: string;
|
let pendingMoves: string;
|
||||||
if (!currentState.moves) {
|
if (!currentState.moves) {
|
||||||
//No prior moves. Use the new moves
|
//No prior moves. Use the new moves
|
||||||
pendingMoves = newState.moves;
|
pendingMoves = newState.moves;
|
||||||
|
@ -563,12 +563,12 @@ export default function (token: string) {
|
||||||
//Get all the moves on the newState that are not present on the currentState
|
//Get all the moves on the newState that are not present on the currentState
|
||||||
pendingMoves = newState.moves.substring(currentState.moves.length, newState.moves.length);
|
pendingMoves = newState.moves.substring(currentState.moves.length, newState.moves.length);
|
||||||
}
|
}
|
||||||
var moves = pendingMoves.split(' ');
|
const moves = pendingMoves.split(' ');
|
||||||
for (let i = 0; i < moves.length; i++) {
|
for (let i = 0; i < moves.length; i++) {
|
||||||
if (moves[i] != '') {
|
if (moves[i] != '') {
|
||||||
//Make the new move
|
//Make the new move
|
||||||
var uciMove = <NormalMove>parseUci(moves[i]);
|
const uciMove = <NormalMove>parseUci(moves[i]);
|
||||||
var normalizedMove = chess.normalizeMove(uciMove); //This is because chessops uses UCI_960
|
const normalizedMove = chess.normalizeMove(uciMove); //This is because chessops uses UCI_960
|
||||||
if (normalizedMove && chess.isLegal(normalizedMove)) {
|
if (normalizedMove && chess.isLegal(normalizedMove)) {
|
||||||
//This is a good chance to get the move in SAN format
|
//This is a good chance to get the move in SAN format
|
||||||
if (chess.turn == 'black')
|
if (chess.turn == 'black')
|
||||||
|
@ -622,7 +622,7 @@ export default function (token: string) {
|
||||||
Timer: string;
|
Timer: string;
|
||||||
'Last Move': string;
|
'Last Move': string;
|
||||||
}> {
|
}> {
|
||||||
var playableGames: Array<{
|
const playableGames: Array<{
|
||||||
gameId: string;
|
gameId: string;
|
||||||
versus: string;
|
versus: string;
|
||||||
'vs rating': string;
|
'vs rating': string;
|
||||||
|
@ -630,17 +630,17 @@ export default function (token: string) {
|
||||||
Timer: string;
|
Timer: string;
|
||||||
'Last Move': string;
|
'Last Move': string;
|
||||||
}> = [];
|
}> = [];
|
||||||
var keys = Array.from(gameConnectionMap.keys());
|
const keys = Array.from(gameConnectionMap.keys());
|
||||||
//The for each iterator is not used since we don't want to continue execution. We want a synchronous result
|
//The for each iterator is not used since we don't want to continue execution. We want a synchronous result
|
||||||
//for (let [gameId, networkState] of gameConnectionMap) {
|
//for (let [gameId, networkState] of gameConnectionMap) {
|
||||||
// if (gameConnectionMap.get(gameId).connected && gameStateMap.get(gameId).status == "started") {
|
// if (gameConnectionMap.get(gameId).connected && gameStateMap.get(gameId).status == "started") {
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
if (gameConnectionMap.get(keys[i])?.connected && gameStateMap.get(keys[i])?.status == 'started') {
|
if (gameConnectionMap.get(keys[i])?.connected && gameStateMap.get(keys[i])?.status == 'started') {
|
||||||
//Game is good for commands
|
//Game is good for commands
|
||||||
var gameInfo = gameInfoMap.get(keys[i]);
|
const gameInfo = gameInfoMap.get(keys[i]);
|
||||||
//var gameState = gameStateMap.get(keys[i]);
|
//var gameState = gameStateMap.get(keys[i]);
|
||||||
var lastMove = getLastUCIMove(keys[i]);
|
const lastMove = getLastUCIMove(keys[i]);
|
||||||
var versus =
|
const versus =
|
||||||
gameInfo.black.id == me.id
|
gameInfo.black.id == me.id
|
||||||
? (gameInfo.white.title !== null ? gameInfo.white.title : '@') + ' ' + gameInfo.white.name
|
? (gameInfo.white.title !== null ? gameInfo.white.title : '@') + ' ' + gameInfo.white.name
|
||||||
: (gameInfo.black.title !== null ? gameInfo.black.title : '@') + ' ' + gameInfo.black.name;
|
: (gameInfo.black.title !== null ? gameInfo.black.title : '@') + ' ' + gameInfo.black.name;
|
||||||
|
@ -669,9 +669,9 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function logGameState(gameId: string) {
|
function logGameState(gameId: string) {
|
||||||
if (gameStateMap.has(gameId) && gameInfoMap.has(gameId)) {
|
if (gameStateMap.has(gameId) && gameInfoMap.has(gameId)) {
|
||||||
var gameInfo = gameInfoMap.get(gameId);
|
const gameInfo = gameInfoMap.get(gameId);
|
||||||
var gameState = gameStateMap.get(gameId);
|
const gameState = gameStateMap.get(gameId);
|
||||||
var lastMove = getLastUCIMove(gameId);
|
const lastMove = getLastUCIMove(gameId);
|
||||||
console.log(''); //process.stdout.write("\n"); Changed to support browser
|
console.log(''); //process.stdout.write("\n"); Changed to support browser
|
||||||
/* Log before migrating to browser
|
/* Log before migrating to browser
|
||||||
if (verbose) console.table({
|
if (verbose) console.table({
|
||||||
|
@ -682,7 +682,7 @@ export default function (token: string) {
|
||||||
'Last Move': { white: (lastMove.player == 'white' ? lastMove.move : '?'), black: (lastMove.player == 'black' ? lastMove.move : '?'), game: lastMove.player },
|
'Last Move': { white: (lastMove.player == 'white' ? lastMove.move : '?'), black: (lastMove.player == 'black' ? lastMove.move : '?'), game: lastMove.player },
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
var innerTable =
|
const innerTable =
|
||||||
`<table class="dgt-table"><tr><th> - </th><th>Title</th><th>Username</th><th>Rating</th><th>Timer</th><th>Last Move</th><th>gameId: ${gameInfo.id}</th></tr>` +
|
`<table class="dgt-table"><tr><th> - </th><th>Title</th><th>Username</th><th>Rating</th><th>Timer</th><th>Last Move</th><th>gameId: ${gameInfo.id}</th></tr>` +
|
||||||
`<tr><td>White</td><td>${gameInfo.white.title !== null ? gameInfo.white.title : '@'}</td><td>${
|
`<tr><td>White</td><td>${gameInfo.white.title !== null ? gameInfo.white.title : '@'}</td><td>${
|
||||||
gameInfo.white.name
|
gameInfo.white.name
|
||||||
|
@ -747,11 +747,11 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function getLastUCIMove(gameId: string): { player: string; move: string; by: string } {
|
function getLastUCIMove(gameId: string): { player: string; move: string; by: string } {
|
||||||
if (gameStateMap.has(gameId) && gameInfoMap.has(gameId)) {
|
if (gameStateMap.has(gameId) && gameInfoMap.has(gameId)) {
|
||||||
var gameInfo = gameInfoMap.get(gameId);
|
const gameInfo = gameInfoMap.get(gameId);
|
||||||
var gameState = gameStateMap.get(gameId);
|
const gameState = gameStateMap.get(gameId);
|
||||||
//This is the original code that does not used chessops objects and can be used to get the UCI move but not SAN.
|
//This is the original code that does not used chessops objects and can be used to get the UCI move but not SAN.
|
||||||
if (String(gameState.moves).length > 1) {
|
if (String(gameState.moves).length > 1) {
|
||||||
var moves = gameState.moves.split(' ');
|
const moves = gameState.moves.split(' ');
|
||||||
if (verbose)
|
if (verbose)
|
||||||
console.log(`getLastUCIMove - ${moves.length} moves detected. Last one: ${moves[moves.length - 1]}`);
|
console.log(`getLastUCIMove - ${moves.length} moves detected. Last one: ${moves[moves.length - 1]}`);
|
||||||
if (moves.length % 2 == 0) return { player: 'black', move: moves[moves.length - 1], by: gameInfo.black.id };
|
if (moves.length % 2 == 0) return { player: 'black', move: moves[moves.length - 1], by: gameInfo.black.id };
|
||||||
|
@ -772,7 +772,7 @@ export default function (token: string) {
|
||||||
function announcePlay(lastMove: { player: string; move: string; by: string }) {
|
function announcePlay(lastMove: { player: string; move: string; by: string }) {
|
||||||
//ttsSay(lastMove.player);
|
//ttsSay(lastMove.player);
|
||||||
//Now play it using text to speech library
|
//Now play it using text to speech library
|
||||||
var moveText: string;
|
let moveText: string;
|
||||||
if (announceMoveFormat && announceMoveFormat.toLowerCase() == 'san' && lastSanMove) {
|
if (announceMoveFormat && announceMoveFormat.toLowerCase() == 'san' && lastSanMove) {
|
||||||
moveText = lastSanMove.move;
|
moveText = lastSanMove.move;
|
||||||
ttsSay(replaceKeywords(padBeforeNumbers(lastSanMove.move)));
|
ttsSay(replaceKeywords(padBeforeNumbers(lastSanMove.move)));
|
||||||
|
@ -810,7 +810,7 @@ export default function (token: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function connectToLiveChess() {
|
async function connectToLiveChess() {
|
||||||
var SANMove: string; //a move in san format returned by liveChess
|
let SANMove: string; //a move in san format returned by liveChess
|
||||||
//Open the WebSocket
|
//Open the WebSocket
|
||||||
liveChessConnection = new WebSocket(liveChessURL ? liveChessURL : 'ws://localhost:1982/api/v1.0');
|
liveChessConnection = new WebSocket(liveChessURL ? liveChessURL : 'ws://localhost:1982/api/v1.0');
|
||||||
|
|
||||||
|
@ -836,7 +836,7 @@ export default function (token: string) {
|
||||||
|
|
||||||
liveChessConnection.onmessage = async e => {
|
liveChessConnection.onmessage = async e => {
|
||||||
if (verbose) console.info('Websocket onmessage with data:' + e.data);
|
if (verbose) console.info('Websocket onmessage with data:' + e.data);
|
||||||
var message = JSON.parse(e.data);
|
const message = JSON.parse(e.data);
|
||||||
//Store last board if received
|
//Store last board if received
|
||||||
if (message.response == 'feed' && !!message.param.board) {
|
if (message.response == 'feed' && !!message.param.board) {
|
||||||
lastLiveChessBoard = message.param.board;
|
lastLiveChessBoard = message.param.board;
|
||||||
|
@ -877,7 +877,7 @@ export default function (token: string) {
|
||||||
//Received move from board
|
//Received move from board
|
||||||
if (verbose) console.info('onmessage - san: ' + message.param.san);
|
if (verbose) console.info('onmessage - san: ' + message.param.san);
|
||||||
//get last move known to lichess and avoid calling multiple times this function
|
//get last move known to lichess and avoid calling multiple times this function
|
||||||
var lastMove = getLastUCIMove(currentGameId);
|
const lastMove = getLastUCIMove(currentGameId);
|
||||||
if (message.param.san.length == 0) {
|
if (message.param.san.length == 0) {
|
||||||
if (verbose) console.info('onmessage - san is empty');
|
if (verbose) console.info('onmessage - san is empty');
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -891,7 +891,7 @@ export default function (token: string) {
|
||||||
//A move was received
|
//A move was received
|
||||||
//Get all the moves on the param.san that are not present on lastLegalParam.san
|
//Get all the moves on the param.san that are not present on lastLegalParam.san
|
||||||
//it is possible to receive two new moves on the message. Don't assume only the last move is pending.
|
//it is possible to receive two new moves on the message. Don't assume only the last move is pending.
|
||||||
var movesToProcess = 1;
|
let movesToProcess = 1;
|
||||||
if (lastLegalParam !== undefined) movesToProcess = message.param.san.length - lastLegalParam.san.length;
|
if (lastLegalParam !== undefined) movesToProcess = message.param.san.length - lastLegalParam.san.length;
|
||||||
//Check border case in which DGT Board LiveChess detects the wrong move while pieces are still on the air
|
//Check border case in which DGT Board LiveChess detects the wrong move while pieces are still on the air
|
||||||
if (movesToProcess > 1) {
|
if (movesToProcess > 1) {
|
||||||
|
@ -900,7 +900,7 @@ export default function (token: string) {
|
||||||
if (localBoard.turn == currentGameColor) {
|
if (localBoard.turn == currentGameColor) {
|
||||||
//If more than one move is received when its the DGT board player's turn this may be a invalid move
|
//If more than one move is received when its the DGT board player's turn this may be a invalid move
|
||||||
//Move will be quarentined by 2.5 seconds
|
//Move will be quarentined by 2.5 seconds
|
||||||
var quarentinedlastLegalParam = lastLegalParam;
|
const quarentinedlastLegalParam = lastLegalParam;
|
||||||
await sleep(2500);
|
await sleep(2500);
|
||||||
//Check if a different move was recevied and processed during quarentine
|
//Check if a different move was recevied and processed during quarentine
|
||||||
if (JSON.stringify(lastLegalParam.san) != JSON.stringify(quarentinedlastLegalParam.san)) {
|
if (JSON.stringify(lastLegalParam.san) != JSON.stringify(quarentinedlastLegalParam.san)) {
|
||||||
|
@ -1027,8 +1027,8 @@ export default function (token: string) {
|
||||||
* @param chess - The chessops Chess object with the position on Lichess
|
* @param chess - The chessops Chess object with the position on Lichess
|
||||||
*/
|
*/
|
||||||
async function sendBoardToLiveChess(chess: Chess) {
|
async function sendBoardToLiveChess(chess: Chess) {
|
||||||
var fen = makeFen(chess.toSetup());
|
const fen = makeFen(chess.toSetup());
|
||||||
var setupMessage = {
|
const setupMessage = {
|
||||||
id: 3,
|
id: 3,
|
||||||
call: 'call',
|
call: 'call',
|
||||||
param: {
|
param: {
|
||||||
|
@ -1080,7 +1080,7 @@ export default function (token: string) {
|
||||||
await chooseCurrentGame();
|
await chooseCurrentGame();
|
||||||
}
|
}
|
||||||
//Now send the move
|
//Now send the move
|
||||||
var command = makeUci(boardMove);
|
const command = makeUci(boardMove);
|
||||||
sendMove(currentGameId, command);
|
sendMove(currentGameId, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1100,7 @@ export default function (token: string) {
|
||||||
if (uciMove.length > 1) {
|
if (uciMove.length > 1) {
|
||||||
//Log intention
|
//Log intention
|
||||||
//Automatically decline draws when making a move
|
//Automatically decline draws when making a move
|
||||||
var url = `/api/board/game/${gameId}/move/${uciMove}?offeringDraw=false`;
|
const url = `/api/board/game/${gameId}/move/${uciMove}?offeringDraw=false`;
|
||||||
if (verbose) console.log('sendMove - About to call ' + url);
|
if (verbose) console.log('sendMove - About to call ' + url);
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -1133,7 +1133,7 @@ export default function (token: string) {
|
||||||
* @returns {String} - The San move with words instead of letters
|
* @returns {String} - The San move with words instead of letters
|
||||||
*/
|
*/
|
||||||
function replaceKeywords(sanMove) {
|
function replaceKeywords(sanMove) {
|
||||||
var extendedSanMove = sanMove;
|
let extendedSanMove = sanMove;
|
||||||
for (let i = 0; i < keywordsBase.length; i++) {
|
for (let i = 0; i < keywordsBase.length; i++) {
|
||||||
try {
|
try {
|
||||||
extendedSanMove = extendedSanMove.replace(keywordsBase[i], ' ' + keywords[keywordsBase[i]].toLowerCase() + ' ');
|
extendedSanMove = extendedSanMove.replace(keywordsBase[i], ' ' + keywords[keywordsBase[i]].toLowerCase() + ' ');
|
||||||
|
@ -1151,7 +1151,7 @@ export default function (token: string) {
|
||||||
* @returns {String} - The move with spaces before the numbers for better TTS
|
* @returns {String} - The move with spaces before the numbers for better TTS
|
||||||
*/
|
*/
|
||||||
function padBeforeNumbers(moveString: string) {
|
function padBeforeNumbers(moveString: string) {
|
||||||
var paddedMoveString = '';
|
let paddedMoveString = '';
|
||||||
for (const c of moveString) {
|
for (const c of moveString) {
|
||||||
Number.isInteger(+c) ? (paddedMoveString += ` ${c} `) : (paddedMoveString += c);
|
Number.isInteger(+c) ? (paddedMoveString += ` ${c} `) : (paddedMoveString += c);
|
||||||
}
|
}
|
||||||
|
@ -1165,9 +1165,9 @@ export default function (token: string) {
|
||||||
//Check if Voice is disabled
|
//Check if Voice is disabled
|
||||||
if (verbose) console.log('TTS - for text: ' + text);
|
if (verbose) console.log('TTS - for text: ' + text);
|
||||||
if (!speechSynthesisOn) return;
|
if (!speechSynthesisOn) return;
|
||||||
var utterThis = new SpeechSynthesisUtterance(text);
|
const utterThis = new SpeechSynthesisUtterance(text);
|
||||||
var selectedOption = voice;
|
const selectedOption = voice;
|
||||||
var availableVoices = speechSynthesis.getVoices();
|
const availableVoices = speechSynthesis.getVoices();
|
||||||
for (let i = 0; i < availableVoices.length; i++) {
|
for (let i = 0; i < availableVoices.length; i++) {
|
||||||
if (availableVoices[i].name === selectedOption) {
|
if (availableVoices[i].name === selectedOption) {
|
||||||
utterThis.voice = availableVoices[i];
|
utterThis.voice = availableVoices[i];
|
||||||
|
@ -1192,14 +1192,14 @@ export default function (token: string) {
|
||||||
*/
|
*/
|
||||||
function compareMoves(lastMove: string, moveObject: NormalMove): boolean {
|
function compareMoves(lastMove: string, moveObject: NormalMove): boolean {
|
||||||
try {
|
try {
|
||||||
var uciMove = makeUci(moveObject);
|
const uciMove = makeUci(moveObject);
|
||||||
if (verbose) console.log(`Comparing ${lastMove} with ${uciMove}`);
|
if (verbose) console.log(`Comparing ${lastMove} with ${uciMove}`);
|
||||||
if (lastMove == uciMove) {
|
if (lastMove == uciMove) {
|
||||||
//it's the same move
|
//it's the same move
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (verbose) console.log('Moves look different. Check if this is a castling mismatch.');
|
if (verbose) console.log('Moves look different. Check if this is a castling mismatch.');
|
||||||
var castlingSide = localBoard.castlingSide(moveObject);
|
const castlingSide = localBoard.castlingSide(moveObject);
|
||||||
if (lastMove.length > 2 && castlingSide) {
|
if (lastMove.length > 2 && castlingSide) {
|
||||||
//It was a castling so it still may be the same move
|
//It was a castling so it still may be the same move
|
||||||
if (lastMove.startsWith(uciMove.substring(0, 2))) {
|
if (lastMove.startsWith(uciMove.substring(0, 2))) {
|
||||||
|
|
|
@ -315,7 +315,7 @@ export default class Setup {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$daysInput.each(function (this: HTMLInputElement) {
|
$daysInput.each(function (this: HTMLInputElement) {
|
||||||
var $input = $(this),
|
const $input = $(this),
|
||||||
$value = $input.siblings('span'),
|
$value = $input.siblings('span'),
|
||||||
$range = $input.siblings('.range');
|
$range = $input.siblings('.range');
|
||||||
$value.text($input.val() as string);
|
$value.text($input.val() as string);
|
||||||
|
@ -370,7 +370,7 @@ export default class Setup {
|
||||||
}
|
}
|
||||||
$timeModeSelect
|
$timeModeSelect
|
||||||
.on('change', function (this: HTMLElement) {
|
.on('change', function (this: HTMLElement) {
|
||||||
var timeMode = $(this).val();
|
const timeMode = $(this).val();
|
||||||
$form.find('.time_choice, .increment_choice').toggle(timeMode == '1');
|
$form.find('.time_choice, .increment_choice').toggle(timeMode == '1');
|
||||||
$form.find('.days_choice').toggle(timeMode == '2');
|
$form.find('.days_choice').toggle(timeMode == '2');
|
||||||
toggleButtons();
|
toggleButtons();
|
||||||
|
@ -378,11 +378,11 @@ export default class Setup {
|
||||||
})
|
})
|
||||||
.trigger('change');
|
.trigger('change');
|
||||||
|
|
||||||
var validateFen = debounce(() => {
|
const validateFen = debounce(() => {
|
||||||
$fenInput.removeClass('success failure');
|
$fenInput.removeClass('success failure');
|
||||||
var fen = $fenInput.val() as string;
|
const fen = $fenInput.val() as string;
|
||||||
if (fen) {
|
if (fen) {
|
||||||
var [path, params] = $fenInput.parent().data('validate-url').split('?'); // Separate "strict=1" for AI match
|
const [path, params] = $fenInput.parent().data('validate-url').split('?'); // Separate "strict=1" for AI match
|
||||||
xhr.text(xhr.url(path, { fen }) + (params ? `&${params}` : '')).then(
|
xhr.text(xhr.url(path, { fen }) + (params ? `&${params}` : '')).then(
|
||||||
data => {
|
data => {
|
||||||
$fenInput.addClass('success');
|
$fenInput.addClass('success');
|
||||||
|
@ -406,7 +406,7 @@ export default class Setup {
|
||||||
if (forceFormPosition) $variantSelect.val('' + 3);
|
if (forceFormPosition) $variantSelect.val('' + 3);
|
||||||
$variantSelect
|
$variantSelect
|
||||||
.on('change', function (this: HTMLElement) {
|
.on('change', function (this: HTMLElement) {
|
||||||
var isFen = $(this).val() == '3';
|
const isFen = $(this).val() == '3';
|
||||||
$fenPosition.toggle(isFen);
|
$fenPosition.toggle(isFen);
|
||||||
$modeChoicesWrap.toggle(!isFen);
|
$modeChoicesWrap.toggle(!isFen);
|
||||||
if (isFen) {
|
if (isFen) {
|
||||||
|
@ -421,7 +421,7 @@ export default class Setup {
|
||||||
$modeChoices.on('change', save);
|
$modeChoices.on('change', save);
|
||||||
|
|
||||||
$form.find('div.level').each(function (this: HTMLElement) {
|
$form.find('div.level').each(function (this: HTMLElement) {
|
||||||
var $infos = $(this).find('.ai_info > div');
|
const $infos = $(this).find('.ai_info > div');
|
||||||
$(this)
|
$(this)
|
||||||
.find('label')
|
.find('label')
|
||||||
.on('mouseenter', function (this: HTMLElement) {
|
.on('mouseenter', function (this: HTMLElement) {
|
||||||
|
@ -433,7 +433,7 @@ export default class Setup {
|
||||||
$(this)
|
$(this)
|
||||||
.find('#config_level')
|
.find('#config_level')
|
||||||
.on('mouseleave', function (this: HTMLElement) {
|
.on('mouseleave', function (this: HTMLElement) {
|
||||||
var level = $(this).find('input:checked').val();
|
const level = $(this).find('input:checked').val();
|
||||||
$infos
|
$infos
|
||||||
.hide()
|
.hide()
|
||||||
.filter('.sf_level_' + level)
|
.filter('.sf_level_' + level)
|
||||||
|
|
|
@ -167,7 +167,7 @@ function generic(n: Notification, url: string | undefined, icon: string, content
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawTime(n: Notification) {
|
function drawTime(n: Notification) {
|
||||||
var date = new Date(n.date);
|
const date = new Date(n.date);
|
||||||
return h(
|
return h(
|
||||||
'time.timeago',
|
'time.timeago',
|
||||||
{
|
{
|
||||||
|
|
|
@ -204,7 +204,7 @@ export function lastCaptured(movesGenerator: () => string[], pieceStyle: PieceSt
|
||||||
}
|
}
|
||||||
const oldSplitFen = oldFen.split(' ')[0];
|
const oldSplitFen = oldFen.split(' ')[0];
|
||||||
const newSplitFen = newFen.split(' ')[0];
|
const newSplitFen = newFen.split(' ')[0];
|
||||||
for (var p of 'kKqQrRbBnNpP') {
|
for (const p of 'kKqQrRbBnNpP') {
|
||||||
const diff = oldSplitFen.split(p).length - 1 - (newSplitFen.split(p).length - 1);
|
const diff = oldSplitFen.split(p).length - 1 - (newSplitFen.split(p).length - 1);
|
||||||
const pcolor = p.toUpperCase() === p ? 'white' : 'black';
|
const pcolor = p.toUpperCase() === p ? 'white' : 'black';
|
||||||
if (diff === 1) {
|
if (diff === 1) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { numberFormat } from 'common/number';
|
||||||
import PuzzleStreak from '../streak';
|
import PuzzleStreak from '../streak';
|
||||||
|
|
||||||
export function puzzleBox(ctrl: Controller): VNode {
|
export function puzzleBox(ctrl: Controller): VNode {
|
||||||
var data = ctrl.getData();
|
const data = ctrl.getData();
|
||||||
return h('div.puzzle__side__metas', [puzzleInfos(ctrl, data.puzzle), gameInfos(ctrl, data.game, data.puzzle)]);
|
return h('div.puzzle__side__metas', [puzzleInfos(ctrl, data.puzzle), gameInfos(ctrl, data.game, data.puzzle)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ interface Glyph {
|
||||||
}
|
}
|
||||||
|
|
||||||
const autoScroll = throttle(150, (ctrl: Controller, el) => {
|
const autoScroll = throttle(150, (ctrl: Controller, el) => {
|
||||||
var cont = el.parentNode;
|
const cont = el.parentNode;
|
||||||
var target = el.querySelector('.active');
|
const target = el.querySelector('.active');
|
||||||
if (!target) {
|
if (!target) {
|
||||||
cont.scrollTop = ctrl.vm.path === treePath.root ? 0 : 99999;
|
cont.scrollTop = ctrl.vm.path === treePath.root ? 0 : 99999;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,9 +14,9 @@ function square(name: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function squareDist(a: number, b: number) {
|
function squareDist(a: number, b: number) {
|
||||||
var x1 = a & 7,
|
const x1 = a & 7,
|
||||||
x2 = b & 7;
|
x2 = b & 7;
|
||||||
var y1 = a >> 3,
|
const y1 = a >> 3,
|
||||||
y2 = b >> 3;
|
y2 = b >> 3;
|
||||||
return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
|
return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
|
||||||
}
|
}
|
||||||
|
@ -63,15 +63,15 @@ function knightMovesTo(s: number) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var ROOK_DELTAS = [8, 1, -8, -1];
|
const ROOK_DELTAS = [8, 1, -8, -1];
|
||||||
var BISHOP_DELTAS = [9, -9, 7, -7];
|
const BISHOP_DELTAS = [9, -9, 7, -7];
|
||||||
var QUEEN_DELTAS = ROOK_DELTAS.concat(BISHOP_DELTAS);
|
const QUEEN_DELTAS = ROOK_DELTAS.concat(BISHOP_DELTAS);
|
||||||
|
|
||||||
function slidingMovesTo(s: number, deltas: number[], board: Board): number[] {
|
function slidingMovesTo(s: number, deltas: number[], board: Board): number[] {
|
||||||
var result: number[] = [];
|
const result: number[] = [];
|
||||||
deltas.forEach(function (delta) {
|
deltas.forEach(function (delta) {
|
||||||
for (
|
for (
|
||||||
var square = s + delta;
|
let square = s + delta;
|
||||||
square >= 0 && square < 64 && squareDist(square, square - delta) === 1;
|
square >= 0 && square < 64 && squareDist(square, square - delta) === 1;
|
||||||
square += delta
|
square += delta
|
||||||
) {
|
) {
|
||||||
|
@ -85,12 +85,12 @@ function slidingMovesTo(s: number, deltas: number[], board: Board): number[] {
|
||||||
function sanOf(board: Board, uci: string) {
|
function sanOf(board: Board, uci: string) {
|
||||||
if (uci.includes('@')) return fixCrazySan(uci);
|
if (uci.includes('@')) return fixCrazySan(uci);
|
||||||
|
|
||||||
var move = decomposeUci(uci);
|
const move = decomposeUci(uci);
|
||||||
var from = square(move[0]);
|
const from = square(move[0]);
|
||||||
var to = square(move[1]);
|
const to = square(move[1]);
|
||||||
var p = board.pieces[from];
|
const p = board.pieces[from];
|
||||||
var d = board.pieces[to];
|
const d = board.pieces[to];
|
||||||
var pt = board.pieces[from].toLowerCase();
|
const pt = board.pieces[from].toLowerCase();
|
||||||
|
|
||||||
// pawn moves
|
// pawn moves
|
||||||
if (pt === 'p') {
|
if (pt === 'p') {
|
||||||
|
@ -110,16 +110,16 @@ function sanOf(board: Board, uci: string) {
|
||||||
var san = pt.toUpperCase();
|
var san = pt.toUpperCase();
|
||||||
|
|
||||||
// disambiguate normal moves
|
// disambiguate normal moves
|
||||||
var candidates: number[] = [];
|
let candidates: number[] = [];
|
||||||
if (pt == 'k') candidates = kingMovesTo(to);
|
if (pt == 'k') candidates = kingMovesTo(to);
|
||||||
else if (pt == 'n') candidates = knightMovesTo(to);
|
else if (pt == 'n') candidates = knightMovesTo(to);
|
||||||
else if (pt == 'r') candidates = slidingMovesTo(to, ROOK_DELTAS, board);
|
else if (pt == 'r') candidates = slidingMovesTo(to, ROOK_DELTAS, board);
|
||||||
else if (pt == 'b') candidates = slidingMovesTo(to, BISHOP_DELTAS, board);
|
else if (pt == 'b') candidates = slidingMovesTo(to, BISHOP_DELTAS, board);
|
||||||
else if (pt == 'q') candidates = slidingMovesTo(to, QUEEN_DELTAS, board);
|
else if (pt == 'q') candidates = slidingMovesTo(to, QUEEN_DELTAS, board);
|
||||||
|
|
||||||
var rank = false,
|
let rank = false,
|
||||||
file = false;
|
file = false;
|
||||||
for (var i = 0; i < candidates.length; i++) {
|
for (let i = 0; i < candidates.length; i++) {
|
||||||
if (candidates[i] === from || board.pieces[candidates[i]] !== p) continue;
|
if (candidates[i] === from || board.pieces[candidates[i]] !== p) continue;
|
||||||
if (from >> 3 === candidates[i] >> 3) file = true;
|
if (from >> 3 === candidates[i] >> 3) file = true;
|
||||||
if ((from & 7) === (candidates[i] & 7)) rank = true;
|
if ((from & 7) === (candidates[i] & 7)) rank = true;
|
||||||
|
@ -135,10 +135,10 @@ function sanOf(board: Board, uci: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sanWriter(fen: string, ucis: string[]): SanToUci {
|
export function sanWriter(fen: string, ucis: string[]): SanToUci {
|
||||||
var board = readFen(fen);
|
const board = readFen(fen);
|
||||||
var sans: SanToUci = {};
|
const sans: SanToUci = {};
|
||||||
ucis.forEach(function (uci) {
|
ucis.forEach(function (uci) {
|
||||||
var san = sanOf(board, uci);
|
const san = sanOf(board, uci);
|
||||||
sans[san] = uci;
|
sans[san] = uci;
|
||||||
if (san.includes('x')) sans[san.replace('x', '')] = uci;
|
if (san.includes('x')) sans[san.replace('x', '')] = uci;
|
||||||
});
|
});
|
||||||
|
|
|
@ -110,9 +110,9 @@ function renderPromotion(
|
||||||
color: Color,
|
color: Color,
|
||||||
orientation: Color
|
orientation: Color
|
||||||
): MaybeVNode {
|
): MaybeVNode {
|
||||||
var left = (7 - key2pos(dest)[0]) * 12.5;
|
let left = (7 - key2pos(dest)[0]) * 12.5;
|
||||||
if (orientation === 'white') left = 87.5 - left;
|
if (orientation === 'white') left = 87.5 - left;
|
||||||
var vertical = color === orientation ? 'top' : 'bottom';
|
const vertical = color === orientation ? 'top' : 'bottom';
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
'div#promotion-choice.' + vertical,
|
'div#promotion-choice.' + vertical,
|
||||||
|
@ -126,7 +126,7 @@ function renderPromotion(
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
roles.map((serverRole, i) => {
|
roles.map((serverRole, i) => {
|
||||||
var top = (color === orientation ? i : 7 - i) * 12.5;
|
const top = (color === orientation ? i : 7 - i) * 12.5;
|
||||||
return h(
|
return h(
|
||||||
'square',
|
'square',
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as xhr from 'common/xhr';
|
import * as xhr from 'common/xhr';
|
||||||
|
|
||||||
export default function (publicKey: string) {
|
export default function (publicKey: string) {
|
||||||
var $checkout = $('div.plan_checkout');
|
const $checkout = $('div.plan_checkout');
|
||||||
var lifetime = {
|
const lifetime = {
|
||||||
cents: parseInt($checkout.data('lifetime-cents')),
|
cents: parseInt($checkout.data('lifetime-cents')),
|
||||||
usd: $checkout.data('lifetime-usd'),
|
usd: $checkout.data('lifetime-usd'),
|
||||||
};
|
};
|
||||||
var min = 100,
|
const min = 100,
|
||||||
max = 100 * 100000;
|
max = 100 * 100000;
|
||||||
|
|
||||||
if (location.hash === '#onetime') $('#freq_onetime').trigger('click');
|
if (location.hash === '#onetime') $('#freq_onetime').trigger('click');
|
||||||
|
@ -22,7 +22,7 @@ export default function (publicKey: string) {
|
||||||
$checkout.find('#plan_monthly_1000').trigger('click');
|
$checkout.find('#plan_monthly_1000').trigger('click');
|
||||||
|
|
||||||
const selectAmountGroup = function () {
|
const selectAmountGroup = function () {
|
||||||
var freq = getFreq();
|
const freq = getFreq();
|
||||||
$checkout.find('.amount_fixed').toggleClass('none', freq != 'lifetime');
|
$checkout.find('.amount_fixed').toggleClass('none', freq != 'lifetime');
|
||||||
$checkout.find('.amount_choice').toggleClass('none', freq == 'lifetime');
|
$checkout.find('.amount_choice').toggleClass('none', freq == 'lifetime');
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,7 @@ export default function (publicKey: string) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var cents = Math.round(amount * 100);
|
let cents = Math.round(amount * 100);
|
||||||
if (!cents) {
|
if (!cents) {
|
||||||
$(this).text($(this).data('trans-other'));
|
$(this).text($(this).data('trans-other'));
|
||||||
$checkout.find('#plan_monthly_1000').trigger('click');
|
$checkout.find('#plan_monthly_1000').trigger('click');
|
||||||
|
@ -46,7 +46,7 @@ export default function (publicKey: string) {
|
||||||
}
|
}
|
||||||
if (cents < min) cents = min;
|
if (cents < min) cents = min;
|
||||||
else if (cents > max) cents = max;
|
else if (cents > max) cents = max;
|
||||||
var usd = '$' + cents / 100;
|
const usd = '$' + cents / 100;
|
||||||
$(this).text(usd);
|
$(this).text(usd);
|
||||||
$(this).siblings('input').data('amount', cents).data('usd', usd);
|
$(this).siblings('input').data('amount', cents).data('usd', usd);
|
||||||
});
|
});
|
||||||
|
@ -56,8 +56,8 @@ export default function (publicKey: string) {
|
||||||
cents =
|
cents =
|
||||||
freq == 'lifetime' ? lifetime.cents : parseInt($checkout.find('group.amount input:checked').data('amount'));
|
freq == 'lifetime' ? lifetime.cents : parseInt($checkout.find('group.amount input:checked').data('amount'));
|
||||||
if (!cents || cents < min || cents > max) return;
|
if (!cents || cents < min || cents > max) return;
|
||||||
var amount = cents / 100;
|
const amount = cents / 100;
|
||||||
var $form = $checkout.find('form.paypal_checkout.' + freq);
|
const $form = $checkout.find('form.paypal_checkout.' + freq);
|
||||||
$form.find('input.amount').val('' + amount);
|
$form.find('input.amount').val('' + amount);
|
||||||
($form[0] as HTMLFormElement).submit();
|
($form[0] as HTMLFormElement).submit();
|
||||||
$checkout.find('.service').html(lichess.spinnerHtml);
|
$checkout.find('.service').html(lichess.spinnerHtml);
|
||||||
|
|
|
@ -5,14 +5,14 @@ import spinnerHtml from './component/spinner';
|
||||||
import Tagify from '@yaireo/tagify';
|
import Tagify from '@yaireo/tagify';
|
||||||
|
|
||||||
lichess.load.then(() => {
|
lichess.load.then(() => {
|
||||||
var $editor = $('.coach-edit');
|
const $editor = $('.coach-edit');
|
||||||
|
|
||||||
var todo = (function () {
|
const todo = (function () {
|
||||||
var $overview = $editor.find('.overview');
|
const $overview = $editor.find('.overview');
|
||||||
var $el = $overview.find('.todo');
|
const $el = $overview.find('.todo');
|
||||||
var $listed = $editor.find('#form3-listed');
|
const $listed = $editor.find('#form3-listed');
|
||||||
|
|
||||||
var must = [
|
const must = [
|
||||||
{
|
{
|
||||||
html: '<a href="/account/profile">Complete your lichess profile</a>',
|
html: '<a href="/account/profile">Complete your lichess profile</a>',
|
||||||
check() {
|
check() {
|
||||||
|
@ -50,7 +50,7 @@ lichess.load.then(() => {
|
||||||
const points: Cash[] = must.filter(o => !o.check()).map(o => $('<li>').html(o.html));
|
const points: Cash[] = must.filter(o => !o.check()).map(o => $('<li>').html(o.html));
|
||||||
const $ul = $el.find('ul').empty();
|
const $ul = $el.find('ul').empty();
|
||||||
points.forEach(p => $ul.append(p));
|
points.forEach(p => $ul.append(p));
|
||||||
var fail = !!points.length;
|
const fail = !!points.length;
|
||||||
$overview.toggleClass('with-todo', fail);
|
$overview.toggleClass('with-todo', fail);
|
||||||
if (fail) $listed.prop('checked', false);
|
if (fail) $listed.prop('checked', false);
|
||||||
$listed.prop('disabled', fail);
|
$listed.prop('disabled', fail);
|
||||||
|
|
|
@ -3,24 +3,24 @@ import sparkline from '@fnando/sparkline';
|
||||||
|
|
||||||
lichess.load.then(() => {
|
lichess.load.then(() => {
|
||||||
$('#trainer').each(function (this: HTMLElement) {
|
$('#trainer').each(function (this: HTMLElement) {
|
||||||
var $trainer = $(this);
|
const $trainer = $(this);
|
||||||
var $board = $('.coord-trainer__board .cg-wrap');
|
const $board = $('.coord-trainer__board .cg-wrap');
|
||||||
var ground;
|
let ground;
|
||||||
var $side = $('.coord-trainer__side');
|
const $side = $('.coord-trainer__side');
|
||||||
var $right = $('.coord-trainer__table');
|
const $right = $('.coord-trainer__table');
|
||||||
var $bar = $trainer.find('.progress_bar');
|
const $bar = $trainer.find('.progress_bar');
|
||||||
var $coords = [$('#next_coord0'), $('#next_coord1'), $('#next_coord2')];
|
const $coords = [$('#next_coord0'), $('#next_coord1'), $('#next_coord2')];
|
||||||
var $start = $right.find('.start');
|
const $start = $right.find('.start');
|
||||||
var $explanation = $right.find('.explanation');
|
const $explanation = $right.find('.explanation');
|
||||||
var $score = $('.coord-trainer__score');
|
const $score = $('.coord-trainer__score');
|
||||||
var scoreUrl = $trainer.data('score-url');
|
const scoreUrl = $trainer.data('score-url');
|
||||||
var duration = 30 * 1000;
|
const duration = 30 * 1000;
|
||||||
var tickDelay = 50;
|
const tickDelay = 50;
|
||||||
var colorPref = $trainer.data('color-pref');
|
let colorPref = $trainer.data('color-pref');
|
||||||
var color;
|
let color;
|
||||||
var startAt, score;
|
let startAt, score;
|
||||||
|
|
||||||
var showColor = function () {
|
const showColor = function () {
|
||||||
color = colorPref == 'random' ? ['white', 'black'][Math.round(Math.random())] : colorPref;
|
color = colorPref == 'random' ? ['white', 'black'][Math.round(Math.random())] : colorPref;
|
||||||
if (!ground)
|
if (!ground)
|
||||||
ground = window.Chessground($board[0], {
|
ground = window.Chessground($board[0], {
|
||||||
|
@ -42,8 +42,8 @@ lichess.load.then(() => {
|
||||||
const form = this,
|
const form = this,
|
||||||
$form = $(this);
|
$form = $(this);
|
||||||
$form.find('input').on('change', function () {
|
$form.find('input').on('change', function () {
|
||||||
var selected = $form.find('input:checked').val() as string;
|
const selected = $form.find('input:checked').val() as string;
|
||||||
var c = {
|
const c = {
|
||||||
1: 'white',
|
1: 'white',
|
||||||
2: 'random',
|
2: 'random',
|
||||||
3: 'black',
|
3: 'black',
|
||||||
|
@ -85,25 +85,25 @@ lichess.load.then(() => {
|
||||||
}
|
}
|
||||||
requestAnimationFrame(showCharts);
|
requestAnimationFrame(showCharts);
|
||||||
|
|
||||||
var centerRight = function () {
|
const centerRight = function () {
|
||||||
$right.css('top', 256 - $right.height() / 2 + 'px');
|
$right.css('top', 256 - $right.height() / 2 + 'px');
|
||||||
};
|
};
|
||||||
centerRight();
|
centerRight();
|
||||||
|
|
||||||
var clearCoords = function () {
|
const clearCoords = function () {
|
||||||
$.each($coords, function (_, e) {
|
$.each($coords, function (_, e) {
|
||||||
e.text('');
|
e.text('');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var newCoord = function (prevCoord) {
|
const newCoord = function (prevCoord) {
|
||||||
// disallow the previous coordinate's row or file from being selected
|
// disallow the previous coordinate's row or file from being selected
|
||||||
var files = 'abcdefgh';
|
let files = 'abcdefgh';
|
||||||
var fileIndex = files.indexOf(prevCoord[0]);
|
const fileIndex = files.indexOf(prevCoord[0]);
|
||||||
files = files.slice(0, fileIndex) + files.slice(fileIndex + 1, 8);
|
files = files.slice(0, fileIndex) + files.slice(fileIndex + 1, 8);
|
||||||
|
|
||||||
var rows = '12345678';
|
let rows = '12345678';
|
||||||
var rowIndex = rows.indexOf(prevCoord[1]);
|
const rowIndex = rows.indexOf(prevCoord[1]);
|
||||||
rows = rows.slice(0, rowIndex) + rows.slice(rowIndex + 1, 8);
|
rows = rows.slice(0, rowIndex) + rows.slice(rowIndex + 1, 8);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -111,9 +111,9 @@ lichess.load.then(() => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
var advanceCoords = function () {
|
const advanceCoords = function () {
|
||||||
$('#next_coord0').removeClass('nope');
|
$('#next_coord0').removeClass('nope');
|
||||||
var lastElement = $coords.shift()!;
|
const lastElement = $coords.shift()!;
|
||||||
$.each($coords, function (i, e) {
|
$.each($coords, function (i, e) {
|
||||||
e.attr('id', 'next_coord' + i);
|
e.attr('id', 'next_coord' + i);
|
||||||
});
|
});
|
||||||
|
@ -122,7 +122,7 @@ lichess.load.then(() => {
|
||||||
$coords.push(lastElement);
|
$coords.push(lastElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
var stop = function () {
|
const stop = function () {
|
||||||
clearCoords();
|
clearCoords();
|
||||||
$trainer.removeClass('play');
|
$trainer.removeClass('play');
|
||||||
centerRight();
|
centerRight();
|
||||||
|
@ -145,7 +145,7 @@ lichess.load.then(() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
var tick = function () {
|
var tick = function () {
|
||||||
var spent = Math.min(duration, new Date().getTime() - startAt);
|
const spent = Math.min(duration, new Date().getTime() - startAt);
|
||||||
$bar.css('width', (100 * spent) / duration + '%');
|
$bar.css('width', (100 * spent) / duration + '%');
|
||||||
if (spent < duration) setTimeout(tick, tickDelay);
|
if (spent < duration) setTimeout(tick, tickDelay);
|
||||||
else stop();
|
else stop();
|
||||||
|
@ -165,7 +165,7 @@ lichess.load.then(() => {
|
||||||
ground.set({
|
ground.set({
|
||||||
events: {
|
events: {
|
||||||
select(key) {
|
select(key) {
|
||||||
var hit = key == $coords[0].text();
|
const hit = key == $coords[0].text();
|
||||||
if (hit) {
|
if (hit) {
|
||||||
score++;
|
score++;
|
||||||
$score.text(score);
|
$score.text(score);
|
||||||
|
@ -181,7 +181,7 @@ lichess.load.then(() => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
$coords[0].text(newCoord('a1'));
|
$coords[0].text(newCoord('a1'));
|
||||||
var i;
|
let i;
|
||||||
for (i = 1; i < $coords.length; i++) $coords[i].text(newCoord($coords[i - 1].text()));
|
for (i = 1; i < $coords.length; i++) $coords[i].text(newCoord($coords[i - 1].text()));
|
||||||
tick();
|
tick();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
|
@ -60,7 +60,7 @@ lichess.load.then(() => {
|
||||||
};
|
};
|
||||||
matches = a.href.match(gameRegex);
|
matches = a.href.match(gameRegex);
|
||||||
if (matches && matches[1] && !notGames.includes(matches[1]) && a.text.match(gameRegex)) {
|
if (matches && matches[1] && !notGames.includes(matches[1]) && a.text.match(gameRegex)) {
|
||||||
var src = '/embed/' + matches[1];
|
let src = '/embed/' + matches[1];
|
||||||
if (matches[2]) src += '/' + matches[2]; // orientation
|
if (matches[2]) src += '/' + matches[2]; // orientation
|
||||||
if (matches[3]) src += matches[3]; // ply hash
|
if (matches[3]) src += matches[3]; // ply hash
|
||||||
return {
|
return {
|
||||||
|
@ -71,7 +71,7 @@ lichess.load.then(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function expandYoutube(a: Candidate) {
|
function expandYoutube(a: Candidate) {
|
||||||
var $iframe = $('<div class="embed"><iframe src="' + a.src + '"></iframe></div>');
|
const $iframe = $('<div class="embed"><iframe src="' + a.src + '"></iframe></div>');
|
||||||
$(a.element).replaceWith($iframe);
|
$(a.element).replaceWith($iframe);
|
||||||
return $iframe;
|
return $iframe;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ lichess.load.then(() => {
|
||||||
// Initially we only autocomplete by participants in the thread. As the user types more,
|
// Initially we only autocomplete by participants in the thread. As the user types more,
|
||||||
// we can autocomplete against all users on the site.
|
// we can autocomplete against all users on the site.
|
||||||
threadParticipants.then(function (participants) {
|
threadParticipants.then(function (participants) {
|
||||||
var forumParticipantCandidates = searchCandidates(term, participants);
|
const forumParticipantCandidates = searchCandidates(term, participants);
|
||||||
|
|
||||||
if (forumParticipantCandidates.length != 0) {
|
if (forumParticipantCandidates.length != 0) {
|
||||||
// We always prefer a match on the forum thread partcipants' usernames
|
// We always prefer a match on the forum thread partcipants' usernames
|
||||||
|
|
|
@ -15,9 +15,9 @@ lichess.load.then(() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function userChoices(row) {
|
function userChoices(row) {
|
||||||
var options = ["<option value=''></option>"];
|
const options = ["<option value=''></option>"];
|
||||||
var isSelected = function (row, rowClassName, user, dataKey) {
|
const isSelected = function (row, rowClassName, user, dataKey) {
|
||||||
var player = $form.data(dataKey);
|
const player = $form.data(dataKey);
|
||||||
return row.classList.contains(rowClassName) && player.length && user == player ? 'selected' : '';
|
return row.classList.contains(rowClassName) && player.length && user == player ? 'selected' : '';
|
||||||
};
|
};
|
||||||
getUsernames().forEach(function (user) {
|
getUsernames().forEach(function (user) {
|
||||||
|
@ -42,7 +42,7 @@ lichess.load.then(() => {
|
||||||
reloadUserChoices();
|
reloadUserChoices();
|
||||||
$usernames.on('input paste', reloadUserChoices);
|
$usernames.on('input paste', reloadUserChoices);
|
||||||
|
|
||||||
var toggleAiLevel = function () {
|
const toggleAiLevel = function () {
|
||||||
$form.find('.opponent select').each(function (this: HTMLSelectElement) {
|
$form.find('.opponent select').each(function (this: HTMLSelectElement) {
|
||||||
$form.find('.aiLevel').toggleClass('none', this.value != '1');
|
$form.find('.aiLevel').toggleClass('none', this.value != '1');
|
||||||
$form.find('.opponentName').toggleClass('none', this.value == '1');
|
$form.find('.opponentName').toggleClass('none', this.value == '1');
|
||||||
|
|
|
@ -21,7 +21,7 @@ function updateMeter(score: number): void {
|
||||||
const meter = document.querySelector('.password-complexity-meter');
|
const meter = document.querySelector('.password-complexity-meter');
|
||||||
const children = meter?.children || [];
|
const children = meter?.children || [];
|
||||||
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
(children[i] as HTMLElement).style.backgroundColor = i < score ? color : '';
|
(children[i] as HTMLElement).style.backgroundColor = i < score ? color : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ function splitOverlaping(lanes) {
|
||||||
let ret: any[] = [],
|
let ret: any[] = [],
|
||||||
i: number;
|
i: number;
|
||||||
lanes.forEach(lane => {
|
lanes.forEach(lane => {
|
||||||
var newLanes: any[] = [[]];
|
const newLanes: any[] = [[]];
|
||||||
lane.forEach(tour => {
|
lane.forEach(tour => {
|
||||||
let collision = true;
|
let collision = true;
|
||||||
for (i = 0; i < newLanes.length; i++) {
|
for (i = 0; i < newLanes.length; i++) {
|
||||||
|
|
|
@ -60,13 +60,13 @@ export function build(root: Tree.Node): TreeWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
function longestValidPathFrom(node: Tree.Node, path: Tree.Path): Tree.Path {
|
function longestValidPathFrom(node: Tree.Node, path: Tree.Path): Tree.Path {
|
||||||
var id = treePath.head(path);
|
const id = treePath.head(path);
|
||||||
const child = ops.childById(node, id);
|
const child = ops.childById(node, id);
|
||||||
return child ? id + longestValidPathFrom(child, treePath.tail(path)) : '';
|
return child ? id + longestValidPathFrom(child, treePath.tail(path)) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentNodesAfterPly(nodeList: Tree.Node[], mainline: Tree.Node[], ply: number): Tree.Node[] {
|
function getCurrentNodesAfterPly(nodeList: Tree.Node[], mainline: Tree.Node[], ply: number): Tree.Node[] {
|
||||||
var node,
|
let node,
|
||||||
nodes = [];
|
nodes = [];
|
||||||
for (const i in nodeList) {
|
for (const i in nodeList) {
|
||||||
node = nodeList[i];
|
node = nodeList[i];
|
||||||
|
@ -151,10 +151,10 @@ export function build(root: Tree.Node): TreeWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
function promoteAt(path: Tree.Path, toMainline: boolean): void {
|
function promoteAt(path: Tree.Path, toMainline: boolean): void {
|
||||||
var nodes = getNodeList(path);
|
const nodes = getNodeList(path);
|
||||||
for (var i = nodes.length - 2; i >= 0; i--) {
|
for (let i = nodes.length - 2; i >= 0; i--) {
|
||||||
var node = nodes[i + 1];
|
const node = nodes[i + 1];
|
||||||
var parent = nodes[i];
|
const parent = nodes[i];
|
||||||
if (parent.children[0].id !== node.id) {
|
if (parent.children[0].id !== node.id) {
|
||||||
ops.removeChild(parent, node.id);
|
ops.removeChild(parent, node.id);
|
||||||
parent.children.unshift(node);
|
parent.children.unshift(node);
|
||||||
|
@ -181,7 +181,7 @@ export function build(root: Tree.Node): TreeWrapper {
|
||||||
|
|
||||||
function deleteCommentAt(id: string, path: Tree.Path) {
|
function deleteCommentAt(id: string, path: Tree.Path) {
|
||||||
return updateAt(path, function (node) {
|
return updateAt(path, function (node) {
|
||||||
var comments = (node.comments || []).filter(function (c) {
|
const comments = (node.comments || []).filter(function (c) {
|
||||||
return c.id !== id;
|
return c.id !== id;
|
||||||
});
|
});
|
||||||
node.comments = comments.length ? comments : undefined;
|
node.comments = comments.length ? comments : undefined;
|
||||||
|
|
Loading…
Reference in New Issue