From e9773c2cb5c897732c96e803a50eade229ed5a2d Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Mon, 26 Jan 2015 13:42:53 +0100 Subject: [PATCH 01/23] fix round button style --- ui/round/src/view/button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/round/src/view/button.js b/ui/round/src/view/button.js index 8397925ea8..6b9a5372ae 100644 --- a/ui/round/src/view/button.js +++ b/ui/round/src/view/button.js @@ -8,7 +8,7 @@ var m = require('mithril'); module.exports = { standard: function(ctrl, condition, icon, hint, socketMsg) { return condition(ctrl.data) ? m('button', { - class: 'button hint--bottom', + class: 'button hint--bottom ' + socketMsg, 'data-hint': ctrl.trans(hint), onclick: partial(ctrl.socket.send, socketMsg, null) }, m('span', { From 50904aae7ec4c37ad3bf524c56aaabd4ebc73082 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Mon, 26 Jan 2015 14:30:03 +0100 Subject: [PATCH 02/23] fix cs messages --- conf/messages.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/messages.cs b/conf/messages.cs index f01c625d0a..faa77b45a9 100644 --- a/conf/messages.cs +++ b/conf/messages.cs @@ -382,7 +382,7 @@ gameBehavior=Chování hry premovesPlayingDuringOpponentTurn=Předtahy (hraní během protivníkova tahu) takebacksWithOpponentApproval=Vrácení tahu (s protivníkovým souhlasem) promoteToQueenAutomatically=Povýšit na královnu automaticky -claimDrawOnThreefoldRepetitionAutomatically=Vyžádat remízu při %trojím opakování pozic%s automaticky +claimDrawOnThreefoldRepetitionAutomatically=Vyžádat remízu při %strojím opakování pozic%s automaticky privacy=Soukromí letOtherPlayersFollowYou=Umožnit ostatním hráčům následovat Tě letOtherPlayersChallengeYou=Umožnit ostatním hráčům vyzvat Tě From 3337f657b19c0d027e3fd47eca0ec4679c7aa45a Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 09:03:58 +0100 Subject: [PATCH 03/23] da "Dansk" translation #12501. Author: bogerner. --- conf/messages.da | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/conf/messages.da b/conf/messages.da index 710cb4d469..2340ca257c 100644 --- a/conf/messages.da +++ b/conf/messages.da @@ -347,3 +347,23 @@ blog=Blog questionsAndAnswers=Spørgsmål & svar notes=Noter materialDifference=Materialeforskel +chessClock=Ur +tenthsOfSeconds=Tiendedele sekunder +never=Aldrig +soundWhenTimeGetsCritical=Lyd, når tiden bliver kritisk +gameBehavior=Spil adfærd +letOtherPlayersFollowYou=Lad andre spillere følge dig +letOtherPlayersChallengeYou=Lad andre spillere udfordre dig +sound=Lys +yourPreferencesHaveBeenSaved=Dine præferencer er blevet gemt. +none=Ingen +fast=Hurtigt +normal=Normalt +slow=Langsomt +insideTheBoard=På brættet +outsideTheBoard=Udenfor brættet +always=Altid +difficultyEasy=Nemt +difficultyNormal=Normalt +difficultyHard=Svært +timeline=Tidslinje From bee6c93e0242f00e9c530c5bc839ebc67a8cef9f Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 09:03:59 +0100 Subject: [PATCH 04/23] =?UTF-8?q?fa=20"=D9=81=D8=A7=D8=B1=D8=B3=DB=8C"=20t?= =?UTF-8?q?ranslation=20#12502.=20Author:=20gambi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/messages.fa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/messages.fa b/conf/messages.fa index 0a0a6abf7c..ec0e54a588 100644 --- a/conf/messages.fa +++ b/conf/messages.fa @@ -1,7 +1,7 @@ playWithAFriend=بازی دوستانه playWithTheMachine=بازی با رایانه -toInviteSomeoneToPlayGiveThisUrl=فراخواندن برای بازی با استفاده از این لینک -gameOver=بازنده شدید +toInviteSomeoneToPlayGiveThisUrl=%برای دعوت کردن حریف این پیوند را برای او بفرستید% +gameOver=%پایان بازی% waitingForOpponent=منتظر حریف waiting=انتظار yourTurn=نوبت شماست @@ -361,6 +361,7 @@ materialDifference=تفاوت ماده closeAccount=بستن اکانت closeYourAccount=بستن اکانت شما changedMindDoNotCloseAccount=نظرم را عوض کردم اکانتم را نمی بندم +closeAccountExplanation=در صورت بستن حساب کاربری دیگر قادر نخواهید بود آنرا بازگزدانید. و صفحه کاربری از دسترس خارج خواهد شد . آیا اطمینان دارید ؟؟ thisAccountIsClosed=این اکانت بسته شده است invalidUsernameOrPassword=نام کاربری و رمز عبور نادرست است emailMeALink=یک لینک به من ایمیل کنید @@ -385,6 +386,7 @@ privacy=خلوت letOtherPlayersFollowYou=بقیه بازیکنان شما را دنبال کنند letOtherPlayersChallengeYou=بقیه بازیکنان با شما بازی کنند sound=صدا +soundControlInTheTopBarOfEveryPage=%کنترل صدا در همه صفحات بالا سمت راست قرار دارد% yourPreferencesHaveBeenSaved=تغییرات شما ذخیره شده است none=هیچ کدام fast=سریع From dabceafe36720304deb18fe8c1d2421ca04722c2 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 09:04:01 +0100 Subject: [PATCH 05/23] hu "Magyar" translation #12506. Author: WMage. --- conf/messages.hu | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/conf/messages.hu b/conf/messages.hu index e610805589..a270987bb3 100644 --- a/conf/messages.hu +++ b/conf/messages.hu @@ -338,18 +338,20 @@ message=Üzenet createTheTopic=Topik létrehozása reportAUser=Jelenteni egy felhasználót user=Felhasználó -reason=Indoklás -whatIsIheMatter=Mi újság -cheat=Csevegő +reason=Ok +whatIsIheMatter=Probléma meghatározása +cheat=Csalás insult=Sértegetés troll=Trollkodás -other=Más +other=Egyéb +reportDescriptionHelp=Játék(ok) linkje és a játékos viselkedésében tapasztalt probléma kifejtése by=%s által thisTopicIsNowClosed=Ez a téma jelenleg lezárt theming=Kinézet donate=Támogatás blog=Blog map=Térkép +realTimeWorldMapOfChessMoves=Valós idejő földtérkép a sakk-lépésekről questionsAndAnswers=Kérdések & Válaszok notes=Jegyzetek typePrivateNotesHere=Ide írd a saját jegyzeteidet @@ -359,6 +361,7 @@ materialDifference=Különböző anyagok closeAccount=Fiók zárolása closeYourAccount=Fiók zárolása changedMindDoNotCloseAccount=Meggondoltam magam, mégsem zárolom a fiókomat +closeAccountExplanation=Biztos hogy zárolod a fiókodat? A zárolás végleges. Nem leszel képes bejelentkezni, és a profilod sem lesz elérhető. thisAccountIsClosed=Ez a fiók zárolva van invalidUsernameOrPassword=Érvénytelen felhasználónév vagy jelszó emailMeALink=Link küldése E-mailban @@ -373,9 +376,12 @@ tenthsOfSeconds=Tizedmásodpercek never=Soha whenTimeRemainingLessThanTenSeconds=Amikor a hátralevő idő < 10 másodperc horizontalGreenProgressBars=Vízszintes zöld folyamatjelző +soundWhenTimeGetsCritical=Figyelmeztető hang, mikor a hátralevő idő kritikus alá csökken +gameBehavior=Játék működése premovesPlayingDuringOpponentTurn=Előre meghatározott lépések (Lépés meghatározása, míg az ellenfél van soron) takebacksWithOpponentApproval=Visszalépés (Ellenfél beleegyezésével) promoteToQueenAutomatically=Bejutott paraszt automatikus királynőre cseréje +privacy=Személyes letOtherPlayersFollowYou=Követésed engedélyezése a többi játékosnak letOtherPlayersChallengeYou=Kihívásod engedélyezése a többi játékosnak sound=Hangok From b33410d11a4df855db736de84373337325740771 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 09:04:02 +0100 Subject: [PATCH 06/23] =?UTF-8?q?lv=20"latvie=C5=A1u=20valoda"=20translati?= =?UTF-8?q?on=20#12507.=20Author:=20krauzand.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/messages.lv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/messages.lv b/conf/messages.lv index b771be1ffb..0f32b8883b 100644 --- a/conf/messages.lv +++ b/conf/messages.lv @@ -415,3 +415,5 @@ allInformationIsPublicAndOptional=Visa informācija ir publiska un nav obligāta yourCityRegionOrDepartment=Tava pilsēta, novads vai nodaļa. biographyDescription=Pastāsti par sevi, kāpēc tev patīk šahs, savas mīļākās atklātes, spēles, šahistus ... maximumNbCharacters=Maksimums: %s simboli. +blocks=%s bloķētie +listBlockedPlayers=Parādīt bloķēto spēlētāju sarakstu From bf7ed9ba5391d6f83dc15162297ed9eee74653fe Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 09:04:02 +0100 Subject: [PATCH 07/23] =?UTF-8?q?he=20"=D7=A2=D6=B4=D7=91=D6=B0=D7=A8?= =?UTF-8?q?=D6=B4=D7=99=D7=AA"=20translation=20#12508.=20Author:=20=5FPure?= =?UTF-8?q?lySmart.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/messages.he | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/conf/messages.he b/conf/messages.he index c2334dc393..3db85bb679 100644 --- a/conf/messages.he +++ b/conf/messages.he @@ -310,20 +310,38 @@ nbGamesInPlay=%s משחקים בתהליך automaticallyProceedToNextGameAfterMoving=המשך אוטומטית למשחק הבא אחרי מהלך autoSwitch=החלפה אוטומטית openingId=פתיחה%s +findNbStrongMoves=מצא %s מהלכים חזקים thisMoveGivesYourOpponentTheAdvantage=מהלך זה נותן ליריבך את היתרון openingFailed=פתיחה נכשלה openingSolved=פתיחה נפתרה recentlyPlayedOpenings=פתיחות אחרונות ששוחקו puzzles=פאזלים +coordinates=קואורדינטות openings=פתיחות +latestUpdates=עדכונים אחרונים +tournamentWinners=מנצחי הטורנירים name=שם +description=תיאור no=לא yes=כן help=:עזרה createANewTopic=צור נושא חדש topics=נושאים +posts=אשכולות +lastPost=אשכול אחרון views=צפיות replies=תגובות +replyToThisTopic=הגב לאשכול זה +reply=הגב +message=הודעה +createTheTopic=צור אשכול +reportAUser=דווח על משתמש +user=משתמש +reason=סיבה +whatIsIheMatter=מה הבעיה? +cheat=רמאות +insult=העלבה +troll=טרול other=אחר donate=תרום blog=בלוג From c7b848a80657f2ec761dc0eae678a95b339162fa Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 10:38:29 +0100 Subject: [PATCH 08/23] cancel premove on takeback - fixes #276 --- ui/round/src/ctrl.js | 5 +++++ ui/round/src/view/button.js | 2 +- ui/round/src/view/table.js | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/round/src/ctrl.js b/ui/round/src/ctrl.js index a0b761724c..c114576e53 100644 --- a/ui/round/src/ctrl.js +++ b/ui/round/src/ctrl.js @@ -128,6 +128,11 @@ module.exports = function(opts) { }.bind(this); setQuietMode(); + this.takebackYes = function() { + this.socket.send('takeback-yes'); + this.chessground.cancelPremove(); + }.bind(this); + this.moveOn = new moveOn(this, 'lichess.move_on'); this.replay = new replayCtrl(this); diff --git a/ui/round/src/view/button.js b/ui/round/src/view/button.js index 6b9a5372ae..6c6e33971c 100644 --- a/ui/round/src/view/button.js +++ b/ui/round/src/view/button.js @@ -71,7 +71,7 @@ module.exports = { ctrl.trans('yourOpponentProposesATakeback'), m('br'), m('a.button.text[data-icon=E]', { - onclick: partial(ctrl.socket.send, 'takeback-yes', null) + onclick: partial(ctrl.takebackYes), }, ctrl.trans('accept')), m.trust(' '), m('a.button.text[data-icon=L]', { diff --git a/ui/round/src/view/table.js b/ui/round/src/view/table.js index 677c98eb88..5b02480807 100644 --- a/ui/round/src/view/table.js +++ b/ui/round/src/view/table.js @@ -85,7 +85,11 @@ function renderTablePlay(ctrl) { renderReplay(ctrl.replay), m('div.control.icons', [ button.standard(ctrl, game.abortable, 'L', 'abortGame', 'abort'), - button.standard(ctrl, game.takebackable, 'i', 'proposeATakeback', 'takeback-yes'), + game.takebackable ? m('button', { + class: 'button hint--bottom takeback-yes', + 'data-hint': ctrl.trans('proposeATakeback'), + onclick: partial(ctrl.takebackYes) + }, m('span[data-icon=i]')) : null, button.standard(ctrl, game.drawable, '2', 'offerDraw', 'draw-yes'), button.standard(ctrl, game.resignable, 'b', 'resign', 'resign') ]), From 710f8083526fbb629cfa16ccf6d0718aa6701c79 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 10:49:17 +0100 Subject: [PATCH 09/23] don't batch single messages --- modules/round/src/main/Socket.scala | 6 ++++-- public/javascripts/big.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/round/src/main/Socket.scala b/modules/round/src/main/Socket.scala index 62c87edef3..d9ae9fecb0 100644 --- a/modules/round/src/main/Socket.scala +++ b/modules/round/src/main/Socket.scala @@ -188,8 +188,10 @@ private[round] final class Socket( } def batch(member: Member, vevents: List[VersionedEvent]) { - if (vevents.nonEmpty) { - member push makeMessage("b", vevents map (_ jsFor member)) + vevents match { + case Nil => + case List(one) => member push one.jsFor(member) + case many => member push makeMessage("b", many map (_ jsFor member)) } } diff --git a/public/javascripts/big.js b/public/javascripts/big.js index d41cd3af48..02a3dc5b26 100644 --- a/public/javascripts/big.js +++ b/public/javascripts/big.js @@ -50,7 +50,7 @@ lichess.StrongSocket.defaults = { pingDelay: 1000, // time between pong and ping autoReconnectDelay: 1000, lagTag: false, // jQuery object showing ping lag - ignoreUnknownMessages: false, + ignoreUnknownMessages: true, baseUrls: ['socket.' + document.domain].concat( ($('body').data('ports') + '').split(',').map(function(port) { return 'socket.' + document.domain + ':' + port; From 333da1035bea8c125c991c26640cd39f4fd29061 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 11:10:49 +0100 Subject: [PATCH 10/23] don't cancel draw offer on move - resolves #277 --- modules/round/src/main/Player.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/round/src/main/Player.scala b/modules/round/src/main/Player.scala index efc21c174c..59a096855e 100644 --- a/modules/round/src/main/Player.scala +++ b/modules/round/src/main/Player.scala @@ -38,8 +38,8 @@ private[round] final class Player( case Some(color) => round ! Cheat(color) case None => if (progress.game.playableByAi) round ! AiPlay - if (game.player.isOfferingDraw) round ! DrawNo(game.player.id) - if (game.player.isProposingTakeback) round ! TakebackNo(game.player.id) + if (pov.opponent.isOfferingDraw) round ! DrawNo(pov.player.id) + if (pov.player.isProposingTakeback) round ! TakebackNo(pov.player.id) } inject progress.events }) } From e3ae3d9b69a97b48116c8155badcd82e93448de2 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 12:00:54 +0100 Subject: [PATCH 11/23] fix integer overflow in correspondence games - fixes #278 --- modules/game/src/main/Game.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/game/src/main/Game.scala b/modules/game/src/main/Game.scala index 6fe2f8eca1..e12efe0c12 100644 --- a/modules/game/src/main/Game.scala +++ b/modules/game/src/main/Game.scala @@ -90,7 +90,7 @@ case class Game( } orElse updatedAt.map(_.getMillis / 100) private def lastMoveTimeDate: Option[DateTime] = castleLastMoveTime.lastMoveTime map { lmt => - createdAt plusMillis (lmt * 100) + createdAt plus (lmt * 100l) } orElse updatedAt def updatedAtOrCreatedAt = updatedAt | createdAt From 0f2d59b93ad558f198cd4dcf78e56e691183944e Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Tue, 27 Jan 2015 14:18:41 +0100 Subject: [PATCH 12/23] show previous moves in correspondence analysis screen - resolves #274 --- app/controllers/UserAnalysis.scala | 12 +++--- app/views/board/userAnalysis.scala.html | 5 ++- modules/round/src/main/JsonView.scala | 53 +++++++++++++------------ 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/app/controllers/UserAnalysis.scala b/app/controllers/UserAnalysis.scala index c413492392..547ebb8d73 100644 --- a/app/controllers/UserAnalysis.scala +++ b/app/controllers/UserAnalysis.scala @@ -18,9 +18,9 @@ object UserAnalysis extends LilaController with BaseGame { val decodedFen = fenStr.map { java.net.URLDecoder.decode(_, "UTF-8").trim }.filter(_.nonEmpty) val situation = (decodedFen flatMap Forsyth.<<<) | SituationPlus(Situation(chess.variant.Standard), 1) val pov = makePov(situation) - val data = Env.round.jsonView.userAnalysisJson(pov, ctx.pref) - makeListMenu map { listMenu => - Ok(html.board.userAnalysis(listMenu, data, none)) + Env.round.jsonView.userAnalysisJson(pov, ctx.pref) zip makeListMenu map { + case (data, listMenu) => + Ok(html.board.userAnalysis(listMenu, data, none)) } } @@ -42,9 +42,9 @@ object UserAnalysis extends LilaController with BaseGame { def game(id: String, color: String) = Open { implicit ctx => OptionFuOk(GameRepo game id) { game => val pov = Pov(game, chess.Color(color == "white")) - val data = Env.round.jsonView.userAnalysisJson(pov, ctx.pref) - makeListMenu map { listMenu => - html.board.userAnalysis(listMenu, data, pov.some) + Env.round.jsonView.userAnalysisJson(pov, ctx.pref) zip makeListMenu map { + case (data, listMenu) => + html.board.userAnalysis(listMenu, data, pov.some) } } } diff --git a/app/views/board/userAnalysis.scala.html b/app/views/board/userAnalysis.scala.html index 9fbf8f1596..7736835b44 100644 --- a/app/views/board/userAnalysis.scala.html +++ b/app/views/board/userAnalysis.scala.html @@ -14,7 +14,10 @@ data: @Html(play.api.libs.json.Json.stringify(data)), routes: roundRoutes.controllers, i18n: @round.jsI18n() }; -lichess.user_analysis.data.inGame = @pov.isDefined; +@pov.map { p => +lichess.user_analysis.data.inGame = true; +lichess.user_analysis.data.path = "@p.game.turns"; +} } } diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index 1d1764ad16..bdb3a1bc85 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -224,31 +224,34 @@ final class JsonView( ).noNull } - def userAnalysisJson(pov: Pov, pref: Pref) = { - import pov._ - val fen = Forsyth >> game.toChess - Json.obj( - "game" -> Json.obj( - "id" -> gameId, - "variant" -> variantJson(game.variant), - "initialFen" -> fen, - "fen" -> fen, - "player" -> game.turnColor.name, - "status" -> statusJson(game.status)), - "player" -> Json.obj( - "color" -> color.name - ), - "opponent" -> Json.obj( - "color" -> opponent.color.name - ), - "pref" -> Json.obj( - "animationDuration" -> animationDuration(pov, pref), - "highlight" -> pref.highlight, - "destination" -> pref.destination, - "coords" -> pref.coords - ), - "userAnalysis" -> true) - } + def userAnalysisJson(pov: Pov, pref: Pref) = + GameRepo.initialFen(pov.game) map { initialFen => + import pov._ + val fen = Forsyth >> game.toChess + Json.obj( + "game" -> Json.obj( + "id" -> gameId, + "variant" -> variantJson(game.variant), + "initialFen" -> (initialFen | chess.format.Forsyth.initial), + "fen" -> fen, + "moves" -> game.pgnMoves.mkString(" "), + "turns" -> game.turns, + "player" -> game.turnColor.name, + "status" -> statusJson(game.status)), + "player" -> Json.obj( + "color" -> color.name + ), + "opponent" -> Json.obj( + "color" -> opponent.color.name + ), + "pref" -> Json.obj( + "animationDuration" -> animationDuration(pov, pref), + "highlight" -> pref.highlight, + "destination" -> pref.destination, + "coords" -> pref.coords + ), + "userAnalysis" -> true) + } private def blurs(game: Game, player: lila.game.Player) = { val percent = game.playerBlurPercent(player.color) From f73c2c42a063132a6d3f3c790465c05eacab7e77 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 28 Jan 2015 00:13:58 +0100 Subject: [PATCH 13/23] link to actual game initial position --- app/views/game/side.scala.html | 2 +- app/views/game/variantLink.scala.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/game/side.scala.html b/app/views/game/side.scala.html index 2c594723b5..a0c25bb72b 100644 --- a/app/views/game/side.scala.html +++ b/app/views/game/side.scala.html @@ -20,7 +20,7 @@ } } • @if(game.variant.exotic) { - @variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top") + @variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top", initialFen = initialFen) } else { @game.perfType.map { pt => @pt.name.toUpperCase diff --git a/app/views/game/variantLink.scala.html b/app/views/game/variantLink.scala.html index 675d80ab64..840553de8d 100644 --- a/app/views/game/variantLink.scala.html +++ b/app/views/game/variantLink.scala.html @@ -1,4 +1,4 @@ -@(variant: chess.variant.Variant, name: String, hintAsTitle: Boolean = false, cssClass: String = "hint--bottom") +@(variant: chess.variant.Variant, name: String, hintAsTitle: Boolean = false, cssClass: String = "hint--bottom", initialFen: Option[String] = None) @url = { @variant match { case chess.variant.Standard => {https://en.wikipedia.org/wiki/Chess} @@ -6,7 +6,7 @@ case chess.variant.Chess960 => {https://en.wikipedia.org/wiki/Chess960} case chess.variant.KingOfTheHill => {@routes.Page.kingOfTheHill} case chess.variant.ThreeCheck => {http://en.wikipedia.org/wiki/Three-check_chess} case chess.variant.Antichess => {http://en.wikipedia.org/wiki/Losing_chess} -case chess.variant.FromPosition => {@routes.Editor.index} +case chess.variant.FromPosition => {@routes.Editor.index?fen=@initialFen} case chess.variant.Atomic => {http://www.freechess.org/Help/HelpFiles/atomic.html} case _ => {} } From f569990549324bb9fdaf194be3289298f1def60a Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 28 Jan 2015 00:51:41 +0100 Subject: [PATCH 14/23] send a reload message on failed force resign --- modules/round/src/main/Round.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/round/src/main/Round.scala b/modules/round/src/main/Round.scala index 4385dde599..c573944ff5 100644 --- a/modules/round/src/main/Round.scala +++ b/modules/round/src/main/Round.scala @@ -75,7 +75,7 @@ private[round] final class Round( (pov.game.resignable && !pov.game.hasAi && pov.game.hasClock) ?? { socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap { case true => finisher(pov.game, _.Timeout, Some(pov.color)) - case _ => fufail("[round] cannot force resign of " + pov) + case _ => fuccess(List(Event.Reload)) } } } @@ -88,7 +88,7 @@ private[round] final class Round( (pov.game.drawable && !pov.game.hasAi && pov.game.hasClock) ?? { socketHub ? Ask(pov.gameId, IsGone(!pov.color)) flatMap { case true => finisher(pov.game, _.Timeout, None) - case _ => fufail("[round] cannot force draw of " + pov) + case _ => fuccess(List(Event.Reload)) } } } From 50ba278b8664dc3fc129b4a1ee6ff323edfe5f58 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 28 Jan 2015 08:55:08 +0100 Subject: [PATCH 15/23] =?UTF-8?q?lv=20"latvie=C5=A1u=20valoda"=20translati?= =?UTF-8?q?on=20#12512.=20Author:=20krauzand.=20fixed=20translation=20erro?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/messages.lv | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/conf/messages.lv b/conf/messages.lv index 0f32b8883b..131437dd99 100644 --- a/conf/messages.lv +++ b/conf/messages.lv @@ -233,7 +233,7 @@ xToYMinutes=%s līdz %s minūtes textIsTooShort=Teksts ir par īsu. textIsTooLong=Teksts ir par garu. required=Obligāts. -openTournaments=Atvērt turnīrus +openTournaments=Atvērtie turnīri duration=Ilgums winner=Uzvarētājs standing=Pozīcija @@ -339,23 +339,23 @@ createTheTopic=Izveidot jaunu tematu reportAUser=Ziņot lietotājam user=Lietotājs reason=Cēlonis -whatIsIheMatter=Kāds ir Jūsu jautājums? -cheat=Apkrāpšana -insult=Aizvainišana -troll=Trollis +whatIsIheMatter=Kas par lietu? +cheat=Krāpšanās +insult=Apvainošana +troll=Troļļošana other=Cits -reportDescriptionHelp=Ielikt atsauci spēlē un izskaidrot kas nav kārtībā lietotāja uzvedībā. +reportDescriptionHelp=Iekopē saiti uz spēli un paskaidro, kas nav kārtībā ar lietotāja uzvedību. by=No %s -thisTopicIsNowClosed=Šis temats tagad ir slēgts! +thisTopicIsNowClosed=Šis temats tagad ir slēgts. theming=Tēmas donate=Ziedot blog=Blogs map=Karte -realTimeWorldMapOfChessMoves=Šahveida gaitu karte reālā laikā +realTimeWorldMapOfChessMoves=Šaha gājienu reāllaika pasaules karte questionsAndAnswers=Jautājumi un Atbildes notes=Piezīmes -typePrivateNotesHere=Uzrakstīt privāto piezīmi šeit -gameDisplay=Spēļu displejs +typePrivateNotesHere=Šeit vari rakstīt savas slepenās piezīmes +gameDisplay=Spēļu ekrāns pieceAnimation=Figūru animācija materialDifference=Materiāla starpība closeAccount=Slēgt kontu From 2734b5edbeec91ed783ae27b0efa3eda7654367d Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 28 Jan 2015 08:56:30 +0100 Subject: [PATCH 16/23] upgrade chess module --- modules/chess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/chess b/modules/chess index acbe2c7a81..a4c0115193 160000 --- a/modules/chess +++ b/modules/chess @@ -1 +1 @@ -Subproject commit acbe2c7a81c82ef078566eddb6782fc4cdfce738 +Subproject commit a4c01151936ffdd12faeccfd259f03bdc8cafcc6 From dced15d7c7589360777da1d1036e830ef30fdc72 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Wed, 28 Jan 2015 17:32:23 +0100 Subject: [PATCH 17/23] fix swiss tournament UI --- ui/tournament/src/view/swiss.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/tournament/src/view/swiss.js b/ui/tournament/src/view/swiss.js index 3ae7c1500f..8761e19bcd 100644 --- a/ui/tournament/src/view/swiss.js +++ b/ui/tournament/src/view/swiss.js @@ -2,6 +2,7 @@ var m = require('mithril'); var partial = require('chessground').util.partial; var tournament = require('../tournament'); var util = require('./util'); +var button = require('./button'); var legend = m('th.legend', [ m('span.streakstarter', 'Streak starter'), @@ -45,6 +46,9 @@ function playerTrs(ctrl, maxScore, player) { ] }, { tag: 'tr', + attrs: { + key: player.id + '.bar' + }, children: [ m('td', { class: 'around-bar', From 7d8c10e860d926473283118b8b8131453315c28a Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 29 Jan 2015 12:01:59 +0100 Subject: [PATCH 18/23] fix analysis board from FEN --- modules/round/src/main/JsonView.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index bdb3a1bc85..3aff8ba9e4 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -225,14 +225,17 @@ final class JsonView( } def userAnalysisJson(pov: Pov, pref: Pref) = - GameRepo.initialFen(pov.game) map { initialFen => + (pov.game.pgnMoves.nonEmpty ?? GameRepo.initialFen(pov.game)) map { initialFen => import pov._ val fen = Forsyth >> game.toChess Json.obj( "game" -> Json.obj( "id" -> gameId, "variant" -> variantJson(game.variant), - "initialFen" -> (initialFen | chess.format.Forsyth.initial), + "initialFen" -> { + if (pov.game.pgnMoves.isEmpty) fen + else (initialFen | chess.format.Forsyth.initial) + }, "fen" -> fen, "moves" -> game.pgnMoves.mkString(" "), "turns" -> game.turns, From 62bb5c63d5780ec54cfa045817ae04583bbe519a Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 29 Jan 2015 15:30:31 +0100 Subject: [PATCH 19/23] analysis action menu --- public/font31/fonts/lichess.eot | Bin 19800 -> 0 bytes public/font31/fonts/lichess.svg | 101 ---- public/font31/fonts/lichess.ttf | Bin 19636 -> 0 bytes public/font31/fonts/lichess.woff | Bin 14304 -> 0 bytes public/font31/icons-reference.html | 797 ----------------------------- public/font31/styles.css | 313 ----------- public/stylesheets/analyse.css | 25 +- public/stylesheets/common.css | 4 +- ui/analyse/src/actionMenu.js | 42 ++ ui/analyse/src/ctrl.js | 5 +- ui/analyse/src/view.js | 40 +- 11 files changed, 78 insertions(+), 1249 deletions(-) delete mode 100644 public/font31/fonts/lichess.eot delete mode 100644 public/font31/fonts/lichess.svg delete mode 100644 public/font31/fonts/lichess.ttf delete mode 100644 public/font31/fonts/lichess.woff delete mode 100644 public/font31/icons-reference.html delete mode 100644 public/font31/styles.css create mode 100644 ui/analyse/src/actionMenu.js diff --git a/public/font31/fonts/lichess.eot b/public/font31/fonts/lichess.eot deleted file mode 100644 index b200a61b7e1f76e3d9431db0feb7f077516f343a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19800 zcmd6Pd6-;Rb?3Wp-(S_Mx75CG-D>qx)m0^_C3R`BY%R7H%UHH#AsI_DUgZU2v!#M< zmYBs60TRpy8e#$@j0ZdrCeBQvIQcRGL*g&MU@(jL;3EVQK?orXN!s%}?^U}4PSTzIaE4? z^H;p;*5jvzQzstA$nM6!dg}OHr=NQcEpdBJ%PJ9E-|K!%= z_nzh+V>Mh~hx77n$8SB+`^wk8!Ew7($n=u2HYFDo1>B(?lT0rbh(M>d^cC( z%J`0Oclz9hZv$g!AYDdDx|h#6Xp^B1< z-&SrLx1GC$+s*CaF6XY~uHg1^`?&q+)dp?>qhHT$X}I z4Lu)l24`YV+1yTU2j_5?atSVp`AKmeW+31$<3e;DyDAzw4THu>|EoWAu{YehZTls= z_gsGE6?^yXKd@n8-TIB2HgDOrc<`!MTz$=f%Bi1LapV=Gi)Aq;hZ#W(21I~rS6^XkO=abds&r*9*A4>hgyWabV_j5n( z-{617zYu&d_(8Zed@P+vUy=T;^v^R}vugI1?4!9v{zLgc%>TU5Ec~?i7o`uDzh7CZ z(w=5m{hjQiSh_Vh>4ZUnd5T=CR9nqWY<|#RV7>W%C-9NEh9R>z-)dGBxxm=lbzN0; zed$7c)b`xCM^faJBFTQRG4NRf7auiMe9T8twaVMI+B#QLVxlSNa$7-lG!;lwMloffo z^MgKpqjt~+r33ctTr-`_XZ+&a*30G%S9fJwR5eL8la-~%B~jyf$(2M^mJGe@v5)E^ z+ccF;sYz3HJu^Gm$V;lEYqrKpX)p9kg<{dPssowV+^>Ert6QpC|AR8mWM1Y)Q4r;S zH)T~`dcPp@qQqV;W5ygq_p0A8WWJ({sw7IHWhMndG{2(Bs>p0zlr`Ov$^tK$Sf6N5 zVU9kB9Zj4FbFaw07X~GURDY3$=xO(A}jcqRwE`9;1zH`vS;*=80^2oB@< z!wh1I*~WY4I;Daa)YFP;uB})JE4`6&3Z>3_s?~*s9aet*ZqwrhiRT&P880wiWI6^Z ziO7@KbS6vX-m$PyWoNupwbrcWik_X%hHlB=dCJ*StEP6JoR~~!_&HAy1YTwWwS+H| zc%7+&qKKC02-!w+vPv$rn zHj4;%ld#BldIQW@ACuARugn2Mc_K6(e}1RLypCUDeo!OIB9dy+gpMb9(8pbhj4pkC zO{<;`oJ2OS3#MQ?UV3e#8H8cF-aLNO>`XS7%g)U9f_!Z)uW2F^F=_blf}rvu=8dlg zUM{~DJR>@znV<<7e?Tp+ytbAPF5h6-v+XsNdMc$fCq18?ajaaX5Qd?hNb?G>38Ld< zvW0v$XE_bet5n*pTE+9EjLGx385S)13Zg2CyvkI`E0rqkN;S3gmmp+W6q$gIiQ_w? zEczp&s+p0R%reutYP}J9{>FNxRKQY1^cb&439^a9R1mWOuNcoE4z$rW^AV{<^yn~~ zS7e7_TTTnKM*Iw$W;oF7g1dApoq*@E-qH~-tEcYHil!nsrXTpGBPgbLq?6KZGrYcz zohh5LmM~?LC%V&c28z_Xww<>H*GZ%U_Nbd@z3-*6+0^$8dv8k6Bwm#jMOJx96NXj$ zm44tRFG=%E6g2_4G&us31q~Cy%XMAzbl&v6R8Y)wgc`XdXzwSGdb=QFU&YR%|ksgzrmQle{kn&cb0h6`Ykye#v&1U?FOX84lk8LpUO`v+fr_eOhX1w^t z6`Jx$ipBe$q!=-OVh<}{$hKItEwBy>V>aLG@66@d;hlafpKF*_$}i+Arek8`XerN4 z3QW2nF(K)CDNPlz-_1(C;HNAzVIIhOk9yeyW`c<`3;7_Oxir5pqh!(x4bS%z2~+12 z2BxK|>6V>xu`rl>H)UHM`vY4l4qTeMd_h4>}?FVir!y(~i) zz%Pko5=qCzjDnQ7O_o#$ds$LciS0Ek>jul#w7eonA_&i7U}rJ}AQ-#IYoelQOco&) z!EFlxfmG2Hxo!&vOQzEkja<%~tVstTC3QV z?cZn1fD!cbxNR88LN1lFEhU*u`MQ?G*5*|~mUTfv2l&qs(`AAv__Mk!8k%WnmJb0g zS(cIWG(GS{H6ONvP?pe^p7@-j8*1H4Dpk)#SMrVYD8g!xU2MInIp)O+ym0bykQ9jOamWxp)=J{OehVnxCoPA~w-juP zXdR^i$Ot3?dK+(?sQWQjp+%0y6$b2)^fS$way}pU>80;I)1IEZ%=g$mNiUb3Y94J) zWpiFK=@yFZi9-_;g@T)8Y^L$GjA;b^hW<0z$$DdAdU|$TE~+#;)0`|66Rw*m7ABjZ zaeie^4d^OdBN>TyOj8)tpFgoNPT?jRb>H*+dV`5CnvxT&Pgf35k*_aL?8*#7zo9w# zD*Gz9x(6)@`rsmKDSp>a&DW|BPQKUe02{PIrPgbB4r>v)1AD$ByDi)JjKcGe@UqAr z;S;aDa1Z;GK6}rMo^Xt9`c7OgHkhWMfFSc95ZAr-AMg2cLZ7*3R@b)~F%Mg&oe(H{ zF_xOEcNj5rkV_Hk1WLL%3$$YWmzs%&EFO*-$q@A7it;@xV_!}je9;WC6C)6rD7e5P zCji0Z-;5?}xdKh>J6=3-(K-zeSldkmj9-elZ8x@vqQnq1`kFGt6P3 zG6)A)-w+*v*03y5K@8|2pmL|g2kh!Y_x1bt9rACv<<07;v>~dakxCnsrEgRc4-e&p zJbXCu-K*SNZ*{M_cm4Wr%j$`DOOCj0nz3IL$ zclQgprvNtkl6Pg7MmHli`!ct~{chtv%FeKzkeD2Y`^lspVX=U;LUu+PNeTQzS!0~6 zuuZ0dlaXRVH-o%|W#kwz&%0m+aDlnGq*COurqfIgrlCO;ncS*kvjiOokY#yql1XniW|L$r!Q>|vw)s?-E+1Ug; z2WBM}ThHS~L_Tpg34HoS8zL5Zv{Q)qD7!@%097N675s}m`#d%k29uWKfT);NupPtn z+@2_+fqidJW?!U1e^xwHzK-@ zb+ZewOT~0X=yVgKfnEG!?R-*9BON_b(_?lQqu3HGN78#lU@Cd&75&f$1HkqcB_MNv zd}x{s$h_`Me{qQZYT|p?UQ;suI6{c0=Q?of>51 z8T5?j%INHQ_8jb5m!Qiv=zsG~FnIJPQcQwS2?qhFoK!n>wAGu3-J=5ZRA3m3UzwlA zpakeJt@%E5$U(ov*x8^xePFS!*ss963nyjOwAb5aR<6x#+1=YzOYD1&+m~3YYwT65a| z4$8xPJMSG_m&PHz?x06!PJtaOINng6m+{B;dHKATc0TbjJ4dOU{jpCtX-Xxs;?fe9 zCkvp;u=Wl1SJ2OWoPb6n@+E$=2^=+IIqa__?VW}oYT{1$oth*Y>^6ga(o){}6;oo; zPFZ>Aoggb37A%#Qvv0Bg1WP8-6Ccyed?ZmyK%gXI*tgWbZs`DN?^4w!9S{C@6y41vbJ7xOr_wgJ6rtjt|$h&$ZVLUHhEv{^|2i&yGgr_PTZLav7Sx zT|W2xQ(BiHH)Q9)Ct$^3N=pfq3Oje~?C9(v@Vt#7h~`-Y-hjE z-XEbTTGD0gf^8m?4*f>kGv1`p!b1-KzS>evY|(?NVIoNhwFQ=~96YF)R+EjlQ}pNlo923rCtq|ff^8fx7TGK@QaS) zFMZK-5(&p+*^~1p@yEVYyqGudJI>!l*(YhOCb$XqHTE^w8Q{rtI|12Z=ELr)RzLRm zo8I*Jn|^lkWbf3e9{U>7Z+iSLN}oD~`pX!9O@xt2yIun^6EP05my=K&>xG17BJB`l zK-8FwZD<%qWD5gAla<5Z4R!E@!?CnoeY$hDx^$sBJ6mOLb@sx`6pEYp-HQbwEH3J> z^YG|gi&-RQJ>Fmuc0#Wr+ew7Bifn=Ji~;_|s|~8Nth^A_hOrTTIV%DtKw$ao{M=}6 zKAT5RZUf9v6yOobWR}HD38(}{ISChJY3ZBegbqe1%B()FAd5H$->Gkyp2}x3`Kjp* zb&}|qmxOKtjg#e4kVR8Z&>YC(V|1Ii7BzvkmKz40^FUp@*=N~j$Ml08(Xxdxj-BTD z$nFLJz(dJ>&E)RglYGui-um#ZNjGD%N%?386+xLoMx3igV_7$0I(XwLWo*|I6 zFo3Cn!EPD=laIoIDB41@Xqtj`@^wu0D;rvim*?Oj`0(wF`D7-BfiIJSUDGwv%*42z zx|y1~9Gkl&U0vs`P%9iP?)=lsL?xY_&K0cU>?K?G{!G~0Dns?+^^}*^^|YHc(=59o z;Rt5Geqb+*2Mkzg1blG}BjHlvpnM+b^XH@dv&bJ&KKKMXfByX0D1U@XzXsh98Z`?P zf#4IM`65%GU(peqJE9Vj1%ob_1bd?-d_YuTc7;4#cefx5659Z*cNEGgKYIs;Cb6Tk zy!2TGhG|*&L7oYc@?%_sFOZ23(3AR)(2Edmx~Bga9p6!?yKYV3 z;4ukx#!FAhPbnhG2~WlVWa+l}_@s!EqVg26|J8kA(3ql|&VbZq!s9C&I^v^a7C>q| z9a+^IUL5y^of-E=K+(82)F1fdp`Shrytis@UUpiP z*DEkr2+9{gGUCO_fHjd{JrS4!VwQ>=Pl2pp3Z8$ji(`M;VGr1Ym>dciq+R#(q}G1AX-+{HBe{1TX-uCnOj zsx)o^J}zPY{tdLB#02+EDQHXmPckS-R8P* zV#0e0Z^Rj>Iue3fXuX%`1lm`O=|~+UHZjHxByVB|?TVc~QX)zJr|FBtPl+tiW7E>I zhCeeuv8KWcEkR^*s$8r-Uo9`Db8d??j*+SxhSn%dv?gPHDOIjnJbRwfdG@f{GUx?-&;?Q9pn0qv&`9UwXtYdKT7gl%zDv=2$0!gvf z9>V8UCu21kdf|VAPcU-VB%uQrp@YHiAihT;)fiH3_{C}G-0Xf{Qo;672i#N1YMGqx zCIO>V@I`(nQR5jX@MjWdyX60iXeWNRf}zy6a;QK z#<1l3LBIzbV-YIr0sYlreOf*qpRQD?*$=IY9O)1(iQ1w&re6tPT-^uZGle-s1=|uA=@{Qcd;rDzOkl-p@H;deR%w)?=TG0IFh=K>{UBHLhHexY`E`QI?u|-Xd&5%ikL@^ zz+qzSaP6h@Q6a4L()sfv6reu%i1hkj?AH**@d||Pk(VA*tH>d+3^qr!mC=(5EO&!0 zK}zflZ2uWHJGSLjTeW7b85W^3Mu?O=@AO~8{|rxdz7C*6M*$(m7C%2a_-K(5@o$L- zLo31Ck9xf*7lyNb=ZC(w*0yXIiyRkjNXIiYMPLm$e7E&IK}x1FiflOWSEh1nNykna zh5V#0DWYsxis+|Q+f6F6nbJf%A5Or+B&J_!0dU%Z0r;8pb++^ai0*V6Hwcr@=x|co zl4%LsFOh78PhhiJ5L9XQCRqxm+f85|0feWfT?I|)@c!#bmr1%PXl|-mXc<^=N2=!% zQwbFYAB0K3lch4*6nJCpnuf~Q@5&m2OLW9uFwyi8av~+nq{h@x;^7cS1ql%?@BzcM zuK^`ffThEw*iYHdVKd4@6Ws>ve>)=N9^!tR`#ARm_dmI>bKj>mBgG_MktoK*LsSIj z8|&1phO)zxcQKx9S{+3O(_TI$9D%P=gkghh>M~9U;|w}|aF7pA~8!cH2d)S}6{uIRIIzto#aPBC6LbMPp^e|AW(gtBjZNq?jPFUJ1 zNqnQpD>A=_y<4zK4a^TRLafa?pcPT}Bu8QT(pTUcWlYh91Pq>{HRY(^6r2Q;RIw_5 zQqn9qOi1IA#Dt5;qRZp)NbKhV8b=2G)|jYQnZm0IkXXWz;EH!7(R7j}o?WHp zChx6yP#(<5*@eJBP)f?qhU%fYOdFvR6Ll+>PR*N;Mu?7(N|;bsw8?74cpWGmvMR%4 z^Mr_L0*kv3BjW)cz}3qw)?!ISrw7nF=@Z{g)^UeM8Xr3Vj= z>m!H*kWOH^k}e5Zeh=`a(5OiYct89Q0#7ll0W_%rs1qhy3ioOC!~S5J*-F@g&Lj(v z0};@P97wl$c@30DPg7Wsl0bAtl|B0v+#6KIkOh8>Cs6w)X_El$)3YLW)?PYLR zl%ky$l>h_BDYoAi6j)&$Cn#L8p|GdkXy#Sbbu(*r+qPY||GiMy-)NVzilVt%w!R-u zl0?$ZDgpfU*=(zsf19EtJg=~!*)Hs*Xz5c-=E_%X&4S^IzR_@ZdcM&z?JXI=)K9f@&3XG1%J9!gk~Xk;CJjf*mUCCTk(MQY6!eNzD&la7OHn1YYFWnm;xiLY`g@|C6O@ zByCeU6H+;!$B)@iMO!kAnHg{uTU^J6qhoA%7nRbpz_yl^n%_dAys$TqU!!sJm7-`G z(+|!VrYNpEi^-urJ{|QDw7b&3mO`e%a1ah!@%?{Vo}Det%;L8^8{g%0l#X+vcFM2= zoX1$9*>adfxB}-x1$5tX_!_xbTZ0+Cx5#GLAYA0TC5q8gO1#gi+h=CB&+NCeLVcm; z^4*}`RqA;SMpi>oF#wE`6$M49_<10k^0}pRrstW%+1ayn)Rc#h&B{6(KF2Zk zXHA53>ZWmT~oybTMD1o66vuvEQC-;0uW5-Vf_Pms(NyFIx5B4Sx|9e#yLKB?;D0 zVvy>CzR(3PK=jeL$Deu`rk=&4()1Cg^*)wTr{%uPw8Ybkxa7$?m!u{hJueV%Zr#>(kHkmF3lo89JD9` zD`VsmLQ9z;_D`%b0zwo&wHy_JsfOZxcvrvIXzrQsH5=~CXRsqF{s%It0_l{5D5_96Harca+rID^yi7jY^qr*(4vd!=yNly5ioXB+ zzu$TODXy}&#}$?LV0vVjrki*#5MVlV?B zK+3{^eO(nqu~V%Ep>4UK=2E3O-90)pT`qblE6|g(lhXtCHb8NCR}EesMMCTz>@1bf zusf1fn7lMMZKkq<5aQljI2U96d(vuQz9Qfc7d@=y0~z9!y0RGt)oFeJ2`aacy_q$? zUYgOaMC_iueSJ^s+3iZH&G^dPj(iws&QRuCfHbymx7pucIj3#QWwu?q(aOE4Gu=1! zN`Aso7q-{)o$T6B-kZ)DTG{e95p;sZZHV!ceDQ%t+dz9{-H!qZq8${HbwAoZO<`=M z=tBvnNa&uAxgw25rtKE?JQ)0gu*r^2_3!x59fPTeH~R(bC>``XKo{_Z37F6yEg^k73eX){ zhA`Ct|D+Fg5i%NGgeDSZf=to{>T#1ug(|Q5&^86ZlM@1BieY3c`cM{l_Os2Me!kRd zO)eZfxG>pjmGb@0X7Nji_!5dL4Cj6}3&UD%_6iZ|1NI4G2VkoGG4@9v&o^BK?euNj zyU@#?Ed|R=DvWRv4Di_bv9dVBYKWYPnA{?(`AQF42{Z01O)y}Hbhy(xaqVTs7AUJO z#7r>ac)dYD<0hsUbHI3Fq6P+4FhrR>C74A7*^72&-DP|4n44Brgw(HH_wYKl7NJ;z zs;*^oa~aReOzZk?U$DikqG#*Y4VRLuXt7hQ%|;7cEUp=4FnyUMqJCx7vQ&i1CS=(O zXkig~TuLt<+PrzHS$v0KuPYSUXZuXFoiI~QX68=syKLRG3j6f*+}tz_;_7t&xB8i6 zKcAER7M=zeSjid7{PP_rZg|%XYl=nC)9&6(y*RtY&1C8sIbph{sX@Rc^|lF=(aZ); zvCy1aTs*Xx-es)Y20FiJb92D2z^hU#VF9EIR9gV7bcDhmkp-L?kwYEFm&^|@Rg_Q2 zp8SdU@Od26go?AAEGw_ah5PUXOl_r14(`3>Ty{jzgaZQpq5}^@$bM1WkAnpcvr!Nh zfC^r7v5XC#vLFZ>kPFhmSgr+4eJt`z0e3|Brq^vLU7)=vTo=SKAJKj!nEPG!V5d>9 zH#*1r*Iv{6wPr4#%QvAvwcG2b>s8z3*{)jchFb0TJ@*{XW%lG?nX{#SyOqnViSBn0 z%IafCVHP8QPaoP~w8zM*0gF3rFzl%yjOL3rAGR3nGpGj0r|(J%JMd<~P=&CYRyC{} z_87EpM=#|w79NOGrDoktSL+CjmhJFHS+#SE#dfoh<@sDTYr84U$jgnojEHBezj^PK zfotVmflW+IP1k~K#>j@5BHO$P=7D6wEadIb6(lQdPbLuN4og8o%_ST>)+62(KLddn zM(j-uI&PbLANLIg+!{r!5%eE~5yx2O6@z|qd>*lmL0=(YS;OEkUZi3}cr@6^^4i1H zjH5#_JtPWeRwB;{Vq)TA_CrS2h($$E(#P~g3aJmnJFG!u7{nS!IFusU9crWn9?+r* zt~Fb|7L>0sBpsm1P7hB5k!guo1PtO4E2KUqslPAT#C#P!S=GiMdYI@X8~KTs+R$!q zNPSl~EJp)0wMuOcx4 zdd6p^xC=mAG!P++;;=9)rdo=MBf>`#VIG=5%-kQeVFY9q0Ww2GNGj8@X^a5$Dzw|Y zY%|?adAN4Kyy0fndAcO??f+LLRZ-E-3u}FU9Uj$K*Y>W#=nTz?M#|v0Mr>A=Mt#E^ z>{g(3(?w8|ZYTJ(B$RYmg!lgFlrortqg+DF z9y4E18IcJuSs4cTxVEQXtW6>dPfcQPd=(Y|JQY7s24QMWg0<%d$&<%#SmN$Gvh{Bs zed83n=5N#I&PBWxKargx32QwtO?|8;MCdP83&wDqP`iM57TD?Ghw*DXmv7rwtsh=@ z|NT!qP`?UR_^n5eZryhDXl;nkmM!_beO3K|C+@%hy5ah(Z1#re+P1Anm!8`~1!Dbk z2)+FrIJ|=td311@6Xk&v$SSaPP-`Xj`p#@}fQ5 z8)rqkGS(1ZA`1_A#z8)jHc0`@LF7++ep~TlpcQQTRkpCq*VG&Db6;XC85p?k2@Ub4ER8%a7GBnis`kjyt9L}-7y zP;M8l-Vh@AMbmiCEpI)3e5(c}eZ$p-b}J}2@Uh6c2!~_YooKn`*|%+N1#5Di8RplB z>Rh$#<_aBe>Eof9t2l+iuyOUL3v252YN1fA(4krV2kyJH8!GByXTc3~2V4WBMgOifK3Zn#%$Z5KA3aLtsV1a9H3OLG5c zX0NDDHim`Gzfq{h_Z#2$QG$AOx1}FP_axvqBt+)YbG`yFaD)8=_Rg)`uXFDugsy;V z#`KD51=xaSKHo#sGKoo=|6ZJn`LTQ zBhdFt{McBzIwB+A!ky(Fg+J{v?s53k{)GD$_dTHJ4m_8Apd27Q(vL%>I!#)1w1eOW zi^9)oC)uo(s?lDFz4JgpfK-ayg_8g-vvDJ&mjP&#Eg7+-Jv_KXE_)9qO+37WU_#ts z0Xpdn>(bhVxCuQv0K#cd52|p%`T=f44n156$vF%-yoT>}YvBEec7(7YSc(GOR9PtSSZm#Mr zzbCI16L7h@f|FlxH60pS0+B9;0wlC`hjKOVuv1{x{983%>Xq{Kx7^M0Q_VN>^?a!Z z@0R#h?E$431bMc!RDq8*X1AybyR&K{k{kAkS{oJUK!@i*eb|!}BgV z$&`Q_RpG{uXa*EQccpvB^{F7#fv7i1)Q32Su98%td(t<)Z|r6I&UJ7_%1Sv1QaRsF z`x0#Aa6KX(-m*k7q*o`{mXwlIUa^C);M#7+V)J zg|uo_YJp>>lbC#~jrR^f`%z73;ewa0WilxZE?Cj1Te>Z3MkWD}sn`j)^|Rm-l9POM z60#my$rOyD2#%7bZ9Qa9!$WHng5272t`elcrNpG5rY#H#Asecy0sdR~Gbt_FnjHcU zV;W6IO_Zx%K4}&^zG}(lM!0dwdkR-Cv;jmv?#Eja!1Z`VE@pjIPwH7rM;=f9mkD`%H7ohUMytD2j?(m@)*Y1qdS$v>b+=lo`0MYL}ZP1Lp!8 z8^@)O09}VVc<<8N6Ct(6)a#gg4x2>D)TG~gD2Elur&9&Axt!b zF1zU~?`x;oDBXVgSR!#OF@h__Gs#tAdc~9Xo-D$VLVgt%{g#Ji`ipYPuvB~`UNk&I&k9DYi>DyCx>?Fl~;F1$2;*_tP@-r7CU(#g4R-T)N%j4zh#(Gh-2+>cx1{cpcXa%%BJhvTo{vGf{Uk1=X>mXm7utv3^Gfjd{5qQROc;b=XdPLDO@!O89mA5EWxe7OgWv2#< rG<_J}-~>enDWVQ~S}8JMV%@JpZtNeTylCuybM!BNMJKD@+4X+_4JFU( diff --git a/public/font31/fonts/lichess.svg b/public/font31/fonts/lichess.svg deleted file mode 100644 index fee823d0e2..0000000000 --- a/public/font31/fonts/lichess.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - -Generated by Fontastic.me - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/font31/fonts/lichess.ttf b/public/font31/fonts/lichess.ttf deleted file mode 100644 index eca02427954fb9210c1c2e068e7d59a9842a8796..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19636 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

f^&v>>SY>oJ0-Uw&pa7LK^JFIAcl% zXiU4j7AHo~Nf&dM>PXsViuPk~h~n=d_;8_yR4dK;cyZbq^HCQ+qT-K+pr*3TIl7KJ z>qVsE&$&#QZe(hENNkfdXw;`qsdt>OPUEUI1t~n`XbFu{7vZ8~pmYl_nv06C2M!M` zR!xoqLP}r@loSimWr$IMmR~D$H?Wdris)WK2&Cu1lr~^ei75AB#ghm8ih<({lB#4R zbPHCDF{S)j8(UkLSK;=vW7*MdsjkZ7T{f^%5BWM+-uq}tK|6`XyXVHA@(?27zrxFk zA%}~#DIwWjvIVdyndu24Jgd&V%g?$r)@!lVOH5K9n*ll+1iXt3sNGg(N{22gU5V6B zvX!nA4kZ+h6j;X5QQ(o6hEak=5{G2MTt`t@7*mp2IPOmMYo1;d!~hhAnKTxbHzi&dZ^L@Kj29W z)NxO!elz=v4XF+$c@Xn}o6g?M&lkp|_w!jHiRQHj+VH4f_6RqsOEyVYSrqgC0F|Wb zM&ZEfcED0)yd$9(fZd_v-#o?7CMYN#m^XNUPd*>)lHZ(rJvY=wwp;$o_dqD^#FZZU=6;`-(JQiWqnBOxJ--ltJ-NZ6=bG5!(r zOBcuMLdSV`@I&7%zA9RUVk3Psw4l~028x{dw}3t|VVBTa`7_+g(mhD~=>^LkLbG_5 z-hIBzGd>QwuL0Z<(E5iREW^9D6;6o<(K1@VS-0pegS0KXc(ikB|K6(PxS!VOkDh_< z7ogOd8Fz5yOntm=tg<0G!h(FJIDzi{1Gz!#R~{D&geqoMSiE1=HJE=%d|CIg=*8Nxs^zs(ZPoBq92hqMdon%%-Zie4|?d$1^!3 zV^=&1{h83H)>foVUq!)I>sf3}A4SLysoCfi(E_{Nc>JhmrS%%FJ=#KSemnhBdpU)h z-!{2cn~6K7rPBIHbT~VN4|f%ehBaSuIQk(lQXFNs(0FD^m3|NB+%`0I5;r>s#Te{; zK2l*IQom-^X7-0%qO2cQ7@goY=PK`xdU5cI`svlx#gqrYUa}L<@LB#u^fikiAt5d< zqrwR3Y2e+Tkry);SIhv8)Fa`w!r%!GXiBzwtN5nim<((pzh7m_CLg4+BG+PHJ#R2W zR#Mskuk7Gn#I1$bcw~lDM-GC9Y3mUB+C0zS(+hthw1-!#`SF6h8%DD%24nNqx9f_B zw$JYf$}JlexN=bN9-1~k?Uob6Hl=Ne?rN}{#4$RR4%aI$Lo)>PBgb$do}+$`y%-A{pS!85t(chycEJ4 z+-q9%84=|GU0{Y4s)?ixw>lKAsavP0YJHa=JORQmiN?-uW5B};uR5;u37tFoL#pqopZh+@W7)~C|H0_Sv^f$Ezq zi@6x7&2k2|a|Z)+B_l{aU7F&$RAz_JIYZ1D{ML_H!ektmAt7rTGEBz4zmZ;(_K>`P zTYp-dY75y*>>^@mXz0;Jwldg3_9-d8^2+$L`rr|ryS&muSsAk9J&&uLy!5z|P>yCj zcZ6Qq1zsF2ERk>_I))N9uH=j--ZUK6w8Z>6~COV<>%Hs7AwFhq$FU)lQ@%uq+ z7aBDI&6f!49g&tdIO=TskW;)WQ`$J5+QJaF3_gr5l?9b;TWldO)HQ3#Q7cgb$^pS&tgcaaPy7wq1UdhZ zY)O13^f&5M16$ZZ4uoEm<)%VqUR&b0Va<`KD)qMDUKL4FE;D!?^=`Y2?c@{h$jm8? z_3F$JC>%DMw?d9e1nbCHtY6U#uW9KLF=ZqMch)!w@#&-NE|-1!W2@<8w#D!6lkeF9 zsG?`o9EQ9nK39JwV)zX0q({fz3ub2qd2cpsJ-yy@b~}ejbR8^z2l+D`B~Qn9TiSMK zrjo^W4Ie&#d6xsanop@UCm4xL^(LvM#G8+3r{~^xdQkd6I@;=bJK}teZ)@m;7EOoz zHLbCTwfot%aBR@n!dtR{haF5^;$;vq-nU@3*v(tc4sv59+%FBv+8nXz4&&6Qb_P9b zKn%FvGqHXtcZj3CgvMb;)=!Nt!~-)6UpsH_9tTU-(%*9RQacFsJ}dp{lfT1+vAG#i z<2B=ZaP{8n0|-*?f8)aYA$OVF294rrPoh+z6L53?38I!B4?WD?!~da^DG`z~%*ouk zU?1&-%)uRQU4kCmzals;cmlp~b_Wa`swb8tPY|4B`*4<`HbWV8v~PU+Q{;_^o4_IO{SFAgBpV2Dar4#y3bbFY z?I#Oc#0wk2IQtfIXzv^5W+6DXjmhcD8mf?Pu#<4i?q$awGS^djdYQ-NNHT;6ln00N zjA=do@kXOIx}|qaMkA4g7E!p(VE|I!*Sz6y-!`GV1P5#5M!J|yX*I? zPpS4gyO<-d$W%OY0ccba3)1tVAW(Y=N36a>bm7b>k=N8OfQ{!zf**h*^?t(u zgV>>3(zZiVcF$#+6j{bN!hcA_y2ayo9(OxsP4kW=ouwfKmkFScEhGd;_Rl{5#1$KX z?FVm^vPliB7TizmB}*HBu3=&^IQb#l_Z(L zBpa2BqJlD7?4!v;Ljj2l_Bd`ox8)6Vdri&W<>qz{cY>&XR{*R%hqifpJj^Vd%{=@P zIFS^S_qbtOaDNP^wwl6JWzI+8x=RBD}do+|C703gl|6R49CXVU05gWJxYl z&{PVy3)$h{C9!nZbe>~8L})v$W)QISTaW+wFTukx_9^F(Dt3IGDhl#MbTY4v39xbs zJk{a#!#N&oAo#iT&b2C)dSu#<4!XHFGGGVoc~gJFd|~dqclQ4gJn@(uuVX~|wazcV zew^8fc;qDs&l(Hu~2=Tr<^G3@baM|Onim%S|&;#4>Joc|A;A^4bvVq@L zt3(l^0@CpLuQANYhhTHe1#u*_6aI*k+E2;VAfo59C8~LbKh(^qk9svUlrye`cY-sa zs-n1=G)LG!a>Qy4C)rDu?= zis)Gz2N|Ds#n*~e;3MFNPPCVo^^Y=w^Mzo${HlBlfNg~r4YTG@)t%W&WCY5#mUSL< z;;XxZrRse@z;P{M>My19&xPeZWHyk!Uc0Bw+;fRkrQCv}@L)LgDFuO7-6yPPzJgd8 z()6>j=LfT9X}%{660%*R#^(~N1WO$BlK0EPJCjyspSsg)N^V>EgK}YV46KP1wAG4D zU&CL+;Ru7n=uSpq^R;JCEKa^NY~}M(jRLEMatO_0h+=rY)-dn%_3`vgb>Wfr2Fc1^ z(nG7`Y9Vh9QbJ3my(Fq9fpWuyh{MZejg3thJR}~|@uab%Pm;uu$<*}jjf2BlD(4CV z40lB3IC$uHe6VjL0-9v7y8)#Gd`$8o3fBu`Ojg*(xI8tu#%eid z%T7|mm`&5^HcJ0!^Jqj+xDa$-ijdfkl*vE;+5SO-x`38{omX*LDCg_z#3jJy_>0rp zN%*Feg0D&mtfz!&yDwm$6qQ{mmv{DU!y^!`>0Rr5A@-TQ3!F8}Z^`wJQsADYpay@H z7^YaeImZdOM*Tp1ge5pZ_08fxR(WI1D1_oc`CQ7Ppi&`w%Ndu{lv)ss5l8zKU0DK| z7i>`K1DGzOODw#funC_No}I)ArqE8N->eSl`S(-_-fn@H9@RSNPNM{%l?}9-#NbNF zzignA@PSI=)#RzWii~iN)(@-qRqPTJ<{&bH$oY$`u;68axW1>%v}I*Lp1`0Leuf)= zPHeaPK(1Pc=si5!$ZDcQXqb_>;1UAKBd9FXJ@GgL@sJWQLxLP3P}9HskHU7HrwD>TF3rsIms@p3;tTS+h?4OfcD@BQ zQgwvH>ij*eA_w?M9p_qnw4!0SCLZ{z5YN?AVK1e6Df1?}bkBr)t`4J-$Rt9AUtKr|5~>d(FN4oIiQ~;dShitL zVHTI&4x-k2KG{|}=s`#3@Mbnq7GjIe0*X4ipc|lx&tMQ2r~0`&3o-q_&Ik@TM>Sq5 z-Z~lywzmlgRJVPeH4Xvr@hzP zn1N8h*uB`ja7_3$+^y4HY&&}cfMDbnjAU5(0`23Ed1+lz$zeQV!%|g6%Dm|0AsjVw zaf}u@OSLJBG!=qg0G-uuxFKj6ZuOA0rZGpAGc~yHz=I`%Qtk>;FG=^g+k1q{FhcGl z7V4ek$5etB7lZh!M-Q=dz%1zz8glgQ30<-XrfrnCiUWlFzf4Y2LRgR|Cr2jC<`^>B z%OOE*Tc$|bz199v6j+MQ_B_-zzSo9~WdIQ{sYnsg0Zs`S!ug_Zx+6HGmIw(E>UPa! z>HSjA$H(p$$w$kOBBOt@8=E9;$)H`V@`n#qQ~F2T8K-C)^n3=>RenERk}u< zbo=!KI%!dU*4kAFo)sJ7F>=&~0eYcd;OZuUnoW?Ae72<>{=O{R)!FIl%#hESX)F9&5(}FxkeMfQr(o>`*B|0= zfM&kWA5u$gK6P#{EUKp!mS>1zCmdjBqU|jv{=Hxq^Sj;DyQ>a7vtEBmuPaoft<1(9 z_*6B6s7;_ZdnbX&#ZFdnKN>p%YSR_FLS-H!o=+>~RUG{#AeXK@6+PLxZnHssBli8X z#iJ)qN{{`sqVmL?l)5;sr`qbCnlZtN&hn2E#5s344?NIXED=X+|HlLhO`*=-W3WUP zpOPxrO6@3G%sbu-s6FQ_Ee}2=BgrHMw|pbcB)Z(;6|Jv}vPF{Z{Hx?SAWet@PQK322;2omIUjl?OLpRp4pal+jnm@@jIwn!kEbYD&y>NBdkB!#2w=uY~ zvc*;H#WH7kdg-#X$&v0tBKd_yzGoKJ*cU-pXIk}fsrrAV9G@^QYyAQXr2a;?)#g-O zJJ{h&%3_BtTHN0DJ&nZI2i4*KBnF+d(bwtU*6hAo-v>UP*OWZo-nEJ&T4)=@*rK*4 zMeerVZ+5d@`RYu9>tl^=t^*L}egV^k!P)Rpm8F^JmX{8otmk)ZIWeA>W+}7}* zDf!S)INUl3US*I?QPfRBt`REo;Kk@rIoboGn+e7R-5w7rptSiEO%b-kxi_8w5!J+| z<4d@F;k}{L+z`5@K%3QhyV0>N8sE5@TXO|fdf~l9>xueN}E!3R$UuCrTuzgN#!I4+4v*~m3Ovrq6ny7K{n zF2R`K)ybu5_ovV2eLx@W??!$tjNILA@h2#(#^I34AG)UCXAeRyjZlw!dyZ2gmtx)6 z{;XK~%$FW5@4wGNo;5RDwb2h_Q=4Phqv(DiuMv0AaNYMaFT+dWN@wfiS#k%sHO4lH z%-E^&5WTgU%9X(%`D!*<#%*r>Z>@0Ih%s<7H%}uL7i*a25?>yEiujp39#V+S! z7pp=qAyq3Qq#{V0xe@B+f`W)q$;u`b{QRlfkU`m~w-goyq2JgHg(7pI_dYbVwKXL2 zu4ilO<73+b94C2ts(cW+tFrg$xZ38r3zXjZ)z6=<-U6GqJ{{u)s@OMx!NqrjMAV0T zuaYkHfq}S5Dpbx7yFaaN`wQvo5N4zAU&c=^Q=hjGyekNJ-QAFV zAYeL%)ZFf6uqB-~2mX^{fH zJtCpj1PL;NbA&6yB?oDyclWv>+B^QD{lhHlmeHzAnh$l)IKv-!986zb2y|{42A;-3Cv}K*ACqkni2Cnnwi01 zYCP;LynTJWEowVzyhNiP@yAPCgj}yHPHzn0MAU#7T{^^vjpKEgN+JRYYV^Omnvym3 z@A?zy=#dJwP!TSTyIfBVqZMAS7EaM$zRFIGsDU{PZgFFz(1hkcql@42-l!w#pv4mr zpkzb#G|F0%DnBW|H*~d|bF0V0=9pHb{si`!sw%doA1yI-qmeX6<*h$5gn=Xy?qWF% zKlhYM5@n0|9AWkSiD6k3-#GQ4m%Kf1O|dSOqq2=|qhmD|7vsyJNBq@OvhXg-!gHkq`equANKY)*m^&d}5? z)OGKdMNXKtccCc6hWzyT9M=UmP^AN@>lJ-3K2I6w%3(>=2J){C}SGkJyMm zI@SZI&Ut*BC_HBzOwXcq5GFoW3qH{Ut?4pK41S49IKC{|KK&C7tyRXX5ME}gl*IIc zLV^q~A?HF$0*l9!IPwev7pWKs_FLA3l}qy2!dwCJiLvv*4!0Sy&15$450QpKQA&Nq z6U?qAgJ(?-2+_0hsnj8GzQ1eack@{ZOyqat+ctV~;7tq3T`88mse?WA8OkD5m9WtU zK(#DLM1)JAjPHxusS(Inf09>1n!B&u8Pe&teGuK8?4oataQr%R7~OvwZCR7A;;2_$ zFM7zf<~%Z&?X>C3mQ2y9J?zcRYg3sYPci7D?d{FrW4g&9o0h#P48UV$W!A=XlgJ~f zBTXG;G2Fj7oKlglwPCNZSb?T0pFCW?4C=&!XAOOH-4_ye+U?6U{!G})@3UJvm?VFQ zJuY9mKe#hE8!h6W%gOom_Ksg0)F9Ax>>|yg{xsGqZEtvTEyD=x)|!w$s-=fc4|1im3l< zdZU8#i~l3>^8Kh@@bfH#x1D2nCZ}Haow{=(p`~LdjZn&;^Sj|Lu2pU+Kt`qQ2w zUFBZEjF7|k*S@{Zbll?lm*wSI5mC;e0T8o&U%_)X7|Xa=3-B}}C#dZ0ZF_z#LfbmT zUsfktCRstW+mZ4H{mVFjPLOr)!KuMMz+^L@{{9m+*7&Dw45{q8PYZ-vL}UU6N5zJU z?h>!+XVsS+UkB@7ip!Ct&Z6V{@IdS!5fk}+S6%t`qZ3l_Ahg=H&m%C>~k zV>sxMkWxm^#4?3WC3=&^ET30Nl!a&XyH7xEM&M1v>@O5-=I|?HpOJdvE%$91uf*7E zi}Y1LOdst&rHC zpp4SXhH|fXZiq<{`Qx|q?Vo^=&zCdN$M$XNY9#&%B`WJv#3eI*mY)`4%V8)Dy7Nb-#WaI@q(hg+xko({yrfbJJ6pL-+qh-@~-w@+l;B% ztw^Xj*t)*1xCxr_*>x35gY~4j2JL$zD@E+b)MSymhexoHcvHa5Ge^>BSJ0l3Q@pI{ z6xyz=+_;!UM2ZN!Wg8)bT6a*x-ObX0j2$zz2W+#mX;MtH>pi$_D_Ykx9D9E?3o1U> zBUQZHkm=LQaiWz^MVx(Iv}reah67zN`%5l%EmhHO0r^P^4!rt0DckESD`{teGfK;z ztxRfS;-|qoCeFlJbWb9j51ze`K}m<6POw+k6<^kV51L}pf|4pU>1b#>XcNJ zR5UG2NIovz-jv>y?rIy2alr1GYsqZ2MH_GZ8e4Vpg81uot7h3FovM7)6z}F-I;Z?& zRQcxz6ninE4ojMrqo{?q>5|ba3FpeapXv75-rHN2DSl6CUXJtkxxy|ZwW9LQWzOYW zs__|U8Zt9glYRMdrSDC01)*^ix-!x~ZPiVGKp!RYrtYV7jtBvTC`T)#izGLy?Eki3 z8<{cBVTo&PuD*c)-O(LHvRlm;X`UOf)t^KWV) z!WNv-bmcdMrB?dsiN^Ug8$dQ5t>#6xl^g{!g&v0pk2iKai$>lJG|u^>Z6Wu^UXC)1 z8RR-&g;^@ZHVwsu**p2tkMtm{yD;DU6LMxf#2PlfyRux}Ms89kmOK5s%z;XPtKWrWyL)1ylgdg-94J3Nq3UBQXL~rSWS)EfTq7dX#M@Ocz%1FO!GDc0~2{j1p$;o~)7#I;=ov}!RWZ%t)8EFP+b zHOc$iE`g$9e3N_{MaaT3K&oZyFu^?svroUTz1Km(fUouYU`3{{4y*>tgj{qpAdi+u zR6oPZ8hML}a&6Ni&!xihBu2l{*z*eFkjn`0<$M>42uZ;I>-FJnbLDG1r{MdjqTj(G zmL}8V$gj%3(o8Kc=1-b}J+IA-JHGc=jNPvh{cnul@%jMkEI66VO$WxUzWM0!p)2On z9r+2q&tXthN}l!5Qs=x~bU4JmIfFF?tjpGM2KfEUuzww@T{!nhB_>4=EuWuoCI6r! z)}K$nd_@p_)&zOU)m;NaSXnv6WA-X`?d zQ?Mtd=AMT^r=+v#lYXjZ->t8HraNdnCrsUtnhe;!Qo(pOam7OKxMU(-`u?@$OkHlB z2eP^tc}d%PRoul1qVzjphfVyeq1)E}=fRzW-4>V5t7+&<$Oo|Y3F!S$67vbra(yvs z1FBD@+cYexFp5W%odPYcsw|J0x*h(;*Xer98-j1QzC63wfnI4--u}%{&};H?VaP!B zE`sLSj?XsFY6naoQobq^iz;#Gdw6^A<+TYaj=k^q-cB)e@8xTpiif1txGLJrDF$Sy zS%iDUU7c^TH_~#d;-g6%8q2mJOCj^x5UV<=99<7yC)FoKHAUURd~k9wH(yUaqU8ve zLyeQBBI?}0_v}254Lk6?zdf)r#alEa*H~PIZjgmCMNcSWC)<86y5!L& zqxzzDqF$_g$qfh@O42A@4~jz^FQk+#kp`yF8u+4&OKzifZu=$=#hPii^Zs4Gmw&uW z1Wu)uk#yNEJ6KRrj#FNwOiuPq=1W5moAN*Aizyl^^2KLB2*d(pS#ZX0M$G(d>`a1R zPF|22(^Nv3@(*WS}ceDntY!^@}u@T$0LT0&M=lsK% zZDrC}dinGhFfWBru!1xrG11sj+Ug*RBq_I&@V<}B%Z%EJFjL1; zSw4%Tp%oZZEGt9Hvwj(-r@Oya11MR$8iW1CsP6AQF)2VrBKXUHxB9E4NHK>$^-*Ko z&_(xjsS(mliDBYS<9$|UK@1&%eetv_t3 zHwzqz;^;`d&+JTNICfNUM0gmx2fN<;zuNzuWC|}s7_3fZ|KyfuF*G_9W65EHj3Wgj zwKEOw-nE$O_y=A#OKo1G);xg-jBfLyWGM5Q;llYKEm^>j08E#bd1YT2bF)Wc^i5T^ z3N$XOmvv|Em1s8E58pSnbGZ8#(ziS1t9zdQ^9UU~=UQFUzhDB9OeZ6*jkm4zCe1N0W)R zHH}!_F@0!OIhGC9Y`o{u*1d+WH{x5Mq4rAFo0(5z0i^buRAWO{p}fw3wnH2#mq@IF z?2gsm_+WB2&7JM0TfQh)k^UBskd#fE->l7dZctxNwQ+8o8w?WPGU%k*WW4R9V>E~T z*+c|IY+J6sGvN&=R9YqticJ-%X0&k06%vDq9#HSpN&13@dqI+{%8Uz9OQX>?YF??- zsPbmVO3e8|Nw$zCT5hzYe^XqcW)%6G8H5Lf^_8t4IYtH+b|a8`?}+A1xDU~k=`t2E zK1Cl|evXhc;z8IRT_(E<=laF>kv;_dpD~fJKV4Oi%qxUCez^+Zd19`np<1!f!jW$D z$W>%!{5wia!)*ADx>;e$;SBnyQndCr=k)Ns46NPEV9HeY&b@C$om>TNyvQQ18|`t! zs_a@}7=nx1?*}sfwmLsL-noHX<|l)Wa1JfTd6ah_1CCJ*rJS|f9A1;&Oc;xBG-Ncb z#$8F+;FgiI7*n)`#9XB`d;KN4v<85U($+PbJI+p_+1wr$zpZvHnM9?q7Be+o#Fsc} z=J=&`;-__KQmGJd9681X1B-^bD_#9gLSoFeEV;(EUgASmlV`*8ciNm1O_)CaFmI9p ztW3TRx&gBCd$bLvRFX3Zz3p+HUfCW@z1BYT!fdQ@0Er{B-DYk0O^|}0?`#58(_Stn z{`-|D8`%$Qhk_j2qR4xE!SECAnTU8cf}9zvP9|?Vk>L|8Enxdvd6;f~FK&IfF5%9y zOz@_OtF-gINGmh#5<0?(18xF+U8KwK$!ggdJ|nKeJ{{c*z_adBkC%Qzk9OXc7sLS5 z=vTY}N{WyCz-$~nhaclc&qwJv@T7`}K)~%)JBd{Q!&rgm46)6BFAd3I;`3(K;0{pN zOSH2ttHA99xH(75AdHxTOfZ~l_qP67f+Irc9KHMSg)ijzn;^LSSr_z!@;DVBXTMiD z?)6&(@0UQBccP@K=;!j}mS8HbJ@-)n=vLBo%6H<8XRfJ{k&zil@V(Qxf6ytMhhjtc z0*K*H8210(Gcz*U12=(zLN+onf*7(QwgA1y2Km7X68}GaEliAZ2L}EO44w{Wjtva# zA(r*CNU^jsF)=YWIS3Gq*SXuL776yabYugVGZlZdUMRZwI`2)WQq?*vTXN4Rp^c?`ErEPU|Zo@qwNJ zc`;d1w7m1ikuS_ju>=k3Q_rmv7kD0{ow`C-z=Uv`}7C|5Tn8xnmZIXd6H&z$yypw&6BHS=@qF}x!~3* z2%h44OQfuuw5`9#_vZpB`amVms5buB0}zwrg!iw}`%Pc-Jqr_%p#S;=1TufGbKod9 zF*=C*8GPgac=GL;2?!WJWjGKxU?%~kHUI&_77fPny~gtK%&@~u@Zv=I-6M%*viiXh zzruugFnTIf!|Aw12Ij$2cY0tkdnhT`9mgK!k{RN}rq`ScLfIV7y zL8LPedVECOQL;VU-KJ@=e|8MFDgeZa%ONcqiUM^^(vsKF`K{i7+s&Es4ihlVH4w`P z6yoof15pA2(fiMw+~NflhMBM>4L4eU1RR?(j=B{q`r$s#`&98UG5fT7vAeFNuekB2i1KS;p=`kB sBzczm*OXeo`5Z%e6M;9DOaSvU7GRD$=D(g<2tmcd|0gpp9t86L0r0}3?EnA( diff --git a/public/font31/icons-reference.html b/public/font31/icons-reference.html deleted file mode 100644 index 1f6b73512e..0000000000 --- a/public/font31/icons-reference.html +++ /dev/null @@ -1,797 +0,0 @@ - - - - - - - Font Reference - lichess - - - - - -

-

lichess

-

This font was created withFontastic

-

CSS mapping

-
    -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • - - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
-

Character mapping

-
    -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
  • -
    - -
  • -
-
- - \ No newline at end of file diff --git a/public/font31/styles.css b/public/font31/styles.css deleted file mode 100644 index 456fce06f4..0000000000 --- a/public/font31/styles.css +++ /dev/null @@ -1,313 +0,0 @@ -@charset "UTF-8"; - -@font-face { - font-family: "lichess"; - src:url("fonts/lichess.eot"); - src:url("fonts/lichess.eot?#iefix") format("embedded-opentype"), - url("fonts/lichess.woff") format("woff"), - url("fonts/lichess.ttf") format("truetype"), - url("fonts/lichess.svg#lichess") format("svg"); - font-weight: normal; - font-style: normal; - -} - -[data-icon]:before { - font-family: "lichess" !important; - content: attr(data-icon); - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: "lichess" !important; - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-fontawesome-webfont-1:before { - content: "a"; -} -.icon-fontawesome-webfont-2:before { - content: "b"; -} -.icon-fontawesome-webfont-3:before { - content: "c"; -} -.icon-fontawesome-webfont-4:before { - content: "d"; -} -.icon-fontawesome-webfont-5:before { - content: "e"; -} -.icon-fontawesome-webfont-6:before { - content: "f"; -} -.icon-fontawesome-webfont-7:before { - content: "g"; -} -.icon-fontawesome-webfont-8:before { - content: "h"; -} -.icon-fontawesome-webfont-9:before { - content: "j"; -} -.icon-fontawesome-webfont-10:before { - content: "k"; -} -.icon-fontawesome-webfont-11:before { - content: "l"; -} -.icon-fontawesome-webfont-12:before { - content: "m"; -} -.icon-fontawesome-webfont-15:before { - content: "p"; -} -.icon-fontawesome-webfont-17:before { - content: "r"; -} -.icon-fontawesome-webfont-18:before { - content: "s"; -} -.icon-fontawesome-webfont-19:before { - content: "t"; -} -.icon-fontawesome-webfont-20:before { - content: "u"; -} -.icon-eye-view-1:before { - content: "v"; -} -.icon-fontawesome-webfont-21:before { - content: "w"; -} -.icon-fontawesome-webfont-22:before { - content: "x"; -} -.icon-fontawesome-webfont-23:before { - content: "z"; -} -.icon-microscope:before { - content: "A"; -} -.icon-crown-king-1:before { - content: "C"; -} -.icon-fontawesome-webfont-24:before { - content: "D"; -} -.icon-fontawesome-webfont-25:before { - content: "E"; -} -.icon-fontawesome-webfont-26:before { - content: "F"; -} -.icon-fontawesome-webfont-27:before { - content: "G"; -} -.icon-fontawesome-webfont-28:before { - content: "H"; -} -.icon-fontawesome-webfont-29:before { - content: "I"; -} -.icon-fontawesome-webfont-30:before { - content: "J"; -} -.icon-fontawesome-webfont-31:before { - content: "K"; -} -.icon-loop-alt2:before { - content: "B"; -} -.icon-arrow-full-lowerright:before { - content: "M"; -} -.icon-arrow-full-upperright:before { - content: "N"; -} -.icon-fontawesome-webfont-32:before { - content: "L"; -} -.icon-plus-squared:before { - content: "O"; -} -.icon-plus-circled:before { - content: "O"; -} -.icon-fontawesome-webfont-33:before { - content: "O"; -} -.icon-fontawesome-webfont-34:before { - content: "Q"; -} -.icon-fire-station-24:before { - content: "Q"; -} -.icon-burning-fire:before { - content: "Q"; -} -.icon-arrow-sans-down:before { - content: "R"; -} -.icon-arrow-sans-up:before { - content: "S"; -} -.icon-fontawesome-webfont-34:before { - content: "T"; -} -.icon-crossed-swords-small:before { - content: "U"; -} -.icon-fontawesome-webfont-35:before { - content: "V"; -} -.icon-fontawesome-webfont-36:before { - content: "W"; -} -.icon-fontawesome-webfont-37:before { - content: "X"; -} -.icon-fontawesome-webfont-38:before { - content: "Y"; -} -.icon-fontawesome-webfont-39:before { - content: "Z"; -} -.icon-fontawesome-webfont-40:before { - content: "!"; -} -.icon-fontawesome-webfont-41:before { - content: "P"; -} -.icon-fontawesome-webfont:before { - content: "i"; -} -.icon-hand-stop:before { - content: "2"; -} -.icon-ionicons:before { - content: "3"; -} -.icon-fontawesome-webfont-42:before { - content: "0"; -} -.icon-television-tv:before { - content: "1"; -} -.icon-moon:before { - content: "4"; -} -.icon-sun:before { - content: "5"; -} -.icon-ink-pen:before { - content: "6"; -} -.icon-chart-line:before { - content: "9"; -} -.icon-link:before { - content: "\""; -} -.icon-ionicons-1:before { - content: "7"; -} -.icon-unmute:before { - content: "#"; -} -.icon-mute:before { - content: "$"; -} -.icon-gear:before { - content: "%"; -} -.icon-repo:before { - content: "&"; -} -.icon-tag:before { - content: "o"; -} -.icon-trash-bin:before { - content: "q"; -} -.icon-search-find:before { - content: "y"; -} -.icon-sheriff-badge:before { - content: "n"; -} -.icon-crown:before { - content: "8"; -} -.icon-die-six:before { - content: "'"; -} -.icon-flag:before { - content: "("; -} -.icon-flame:before { - content: ")"; -} -.icon-hourglass:before { - content: "+"; -} -.icon-droplet:before { - content: ","; -} -.icon-arrow-streamline-target:before { - content: "-"; -} -.icon-buffer:before { - content: "."; -} -.icon-upload-cloud:before { - content: "/"; -} -.icon-feather:before { - content: "*"; -} -.icon-gears-setting:before { - content: ":"; -} -.icon-email-plane:before { - content: ";"; -} -.icon-zoom-in:before { - content: "<"; -} -.icon-screen-full:before { - content: "="; -} -.icon-list:before { - content: "?"; -} -.icon-atom:before { - content: ">"; -} -.icon-book:before { - content: "]"; -} -.icon-body-cut:before { - content: "`"; -} -.icon-antichess:before { - content: "@"; -} -.icon-hubot:before { - content: "^"; -} diff --git a/public/stylesheets/analyse.css b/public/stylesheets/analyse.css index 081d24c109..ba48c78ba7 100644 --- a/public/stylesheets/analyse.css +++ b/public/stylesheets/analyse.css @@ -100,12 +100,13 @@ div.fen_pgn input.fen { div.game_control { margin-top: 10px; text-align: center; - white-space: nowrap + width: 244px; + white-space: nowrap; } div.game_control a { font-size: 12px; + width: 25px; height: 17px; - width: 12px; display: inline-block; -webkit-user-select: none; -moz-user-select: none; @@ -113,14 +114,32 @@ div.game_control a { margin: 0 -1px; } div.game_control .jumps { + display: inline-block; margin-right: 10px; } -.lichess_ground .replay { +.lichess_ground .replay, +.lichess_ground .action_menu { height: calc(100% - 40px); overflow: auto; overflow-x: hidden; border: 1px solid #ccc; } +.lichess_ground .action_menu { + border-color: transparent; +} +.lichess_ground .action_menu .inner { + position: relative; + top: 50%; + transform: translateY(-50%); +} +.lichess_ground .action_menu .button { + display: block; + margin: 15px 0; + padding: 10px; +} +.lichess_ground .action_menu .button::before { + font-size: 2em; +} .lichess_ground .replay .turn > .index { display: inline-block; width: 26px; diff --git a/public/stylesheets/common.css b/public/stylesheets/common.css index b42a5d0be4..48017412dc 100644 --- a/public/stylesheets/common.css +++ b/public/stylesheets/common.css @@ -70,8 +70,8 @@ time { } @font-face { font-family: "lichess"; - src: url("../font31/fonts/lichess.eot"); - src: url("../font31/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font31/fonts/lichess.woff") format("woff"), url("../font31/fonts/lichess.ttf") format("truetype"), url("../font31/fonts/lichess.svg#lichess") format("svg"); + src: url("../font32/fonts/lichess.eot"); + src: url("../font32/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font32/fonts/lichess.woff") format("woff"), url("../font32/fonts/lichess.ttf") format("truetype"), url("../font32/fonts/lichess.svg#lichess") format("svg"); font-weight: normal; font-style: normal; } diff --git a/ui/analyse/src/actionMenu.js b/ui/analyse/src/actionMenu.js new file mode 100644 index 0000000000..d835722116 --- /dev/null +++ b/ui/analyse/src/actionMenu.js @@ -0,0 +1,42 @@ +var m = require('mithril'); + +module.exports = { + controller: function() { + + this.open = false; + + this.toggle = function() { + this.open = !this.open + }.bind(this); + }, + view: function(ctrl) { + var flipAttrs = {}; + if (ctrl.data.userAnalysis) flipAttrs.onclick = ctrl.flip; + else flipAttrs.href = ctrl.router.Round.watcher(ctrl.data.game.id, ctrl.data.opponent.color).url; + + return m('div.action_menu', + m('div.inner', [ + m('a.button.text[data-icon=B]', flipAttrs, ctrl.trans('flipBoard')), + ctrl.data.inGame ? null : m('a.button.text[data-icon=m]', { + href: ctrl.data.userAnalysis ? '/editor?fen=' + ctrl.vm.situation.fen : '/' + ctrl.data.game.id + '/edit?fen=' + ctrl.vm.situation.fen, + rel: 'nofollow' + }, ctrl.trans('boardEditor')), + ctrl.data.inGame ? null : m('a.button.text[data-icon=U]', { + onclick: function() { + $.modal($('.continue_with.' + ctrl.data.game.id)); + } + }, ctrl.trans('continueFromHere')), + m('div.continue_with.' + ctrl.data.game.id, [ + m('a.button', { + href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen, + rel: 'nofollow' + }, ctrl.trans('playWithTheMachine')), + m('br'), + m('a.button', { + href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#friend' : ctrl.router.Round.continue(ctrl.data.game.id, 'friend').url + '?fen=' + ctrl.vm.situation.fen, + rel: 'nofollow' + }, ctrl.trans('playWithAFriend')) + ]) + ])); + } +}; diff --git a/ui/analyse/src/ctrl.js b/ui/analyse/src/ctrl.js index d05474a1d7..7145b28737 100644 --- a/ui/analyse/src/ctrl.js +++ b/ui/analyse/src/ctrl.js @@ -5,12 +5,14 @@ var analyse = require('./analyse'); var ground = require('./ground'); var keyboard = require('./keyboard'); var treePath = require('./path'); +var actionMenu = require('./actionMenu').controller; var m = require('mithril'); module.exports = function(cfg, router, i18n, onChange) { this.data = data({}, cfg); this.analyse = new analyse(this.data.game, this.data.analysis); + this.actionMenu = new actionMenu(); var initialPath = cfg.path ? treePath.read(cfg.path) : treePath.default(); @@ -19,7 +21,8 @@ module.exports = function(cfg, router, i18n, onChange) { pathStr: treePath.write(initialPath), situation: null, comments: true, - flip: false + flip: false, + play: false }; this.flip = function() { diff --git a/ui/analyse/src/view.js b/ui/analyse/src/view.js index 2faf0f6280..1ff1c7220d 100644 --- a/ui/analyse/src/view.js +++ b/ui/analyse/src/view.js @@ -7,6 +7,7 @@ var renderStatus = require('game').view.status; var mod = require('game').view.mod; var treePath = require('./path'); var control = require('./control'); +var actionMenu = require('./actionMenu').view; function renderEval(e) { e = Math.round(e / 10) / 10; @@ -266,17 +267,9 @@ function blindBoard(ctrl) { } function buttons(ctrl) { - var nbMoves = ctrl.data.game.moves.length; - var flipAttrs = { - 'data-hint': ctrl.trans('flipBoard'), - }; - if (ctrl.data.userAnalysis) flipAttrs.onclick = ctrl.flip; - else flipAttrs.href = ctrl.router.Round.watcher(ctrl.data.game.id, ctrl.data.opponent.color).url; return [ m('div.game_control', [ - m('div.jumps.hint--bottom', { - 'data-hint': 'Tip: use your keyboard arrow keys!' - }, [ + m('div.jumps.hint--bottom', [ ['first', 'W', control.first, ], ['prev', 'Y', control.prev], ['next', 'X', control.next], @@ -294,29 +287,12 @@ function buttons(ctrl) { } }; })), - m('a.button.hint--bottom', flipAttrs, m('span[data-icon=B]')), - ctrl.data.inGame ? null : m('a.button.hint--bottom', { - 'data-hint': ctrl.trans('boardEditor'), - href: ctrl.data.userAnalysis ? '/editor?fen=' + ctrl.vm.situation.fen : '/' + ctrl.data.game.id + '/edit?fen=' + ctrl.vm.situation.fen, - rel: 'nofollow' - }, m('span[data-icon=m]')), - ctrl.data.inGame ? null : m('a.button.hint--bottom', { - 'data-hint': ctrl.trans('continueFromHere'), - onclick: function() { - $.modal($('.continue_with.' + ctrl.data.game.id)); - } - }, m('span[data-icon=U]')) - ]), - m('div.continue_with.' + ctrl.data.game.id, [ m('a.button', { - href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen, - rel: 'nofollow' - }, ctrl.trans('playWithTheMachine')), - m('br'), - m('a.button', { - href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#friend' : ctrl.router.Round.continue(ctrl.data.game.id, 'friend').url + '?fen=' + ctrl.vm.situation.fen, - rel: 'nofollow' - }, ctrl.trans('playWithAFriend')) + onclick: ctrl.actionMenu.toggle, + class: ctrl.actionMenu.open ? 'active' : '' + }, m('span', { + 'data-icon': '[' + })) ]) ]; } @@ -332,7 +308,7 @@ module.exports = function(ctrl) { }, [ ctrl.data.blind ? blindBoard(ctrl) : visualBoard(ctrl), m('div.lichess_ground', - m('div.replay', { + ctrl.actionMenu.open ? actionMenu(ctrl) : m('div.replay', { config: function(el, isUpdate) { autoScroll(el); if (!isUpdate) setTimeout(partial(autoScroll, el), 100); From 5bc341729f87f24d401691242e606cc2a8013eef Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 29 Jan 2015 16:05:10 +0100 Subject: [PATCH 20/23] analysis autoplay --- ui/analyse/src/actionMenu.js | 8 ++++++-- ui/analyse/src/autoplay.js | 40 ++++++++++++++++++++++++++++++++++++ ui/analyse/src/control.js | 2 ++ ui/analyse/src/ctrl.js | 16 +++++++++++++-- ui/analyse/src/view.js | 17 ++++++++------- 5 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 ui/analyse/src/autoplay.js diff --git a/ui/analyse/src/actionMenu.js b/ui/analyse/src/actionMenu.js index d835722116..7033092e31 100644 --- a/ui/analyse/src/actionMenu.js +++ b/ui/analyse/src/actionMenu.js @@ -17,15 +17,19 @@ module.exports = { return m('div.action_menu', m('div.inner', [ m('a.button.text[data-icon=B]', flipAttrs, ctrl.trans('flipBoard')), - ctrl.data.inGame ? null : m('a.button.text[data-icon=m]', { + m('a.button.text[data-icon=m]', { href: ctrl.data.userAnalysis ? '/editor?fen=' + ctrl.vm.situation.fen : '/' + ctrl.data.game.id + '/edit?fen=' + ctrl.vm.situation.fen, rel: 'nofollow' }, ctrl.trans('boardEditor')), - ctrl.data.inGame ? null : m('a.button.text[data-icon=U]', { + m('a.button.text[data-icon=U]', { onclick: function() { $.modal($('.continue_with.' + ctrl.data.game.id)); } }, ctrl.trans('continueFromHere')), + m('a.button[data-icon=G]', { + class: 'text' + (ctrl.autoplay.active() ? ' active' : ''), + onclick: ctrl.togglePlay + }, 'Auto play'), m('div.continue_with.' + ctrl.data.game.id, [ m('a.button', { href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen, diff --git a/ui/analyse/src/autoplay.js b/ui/analyse/src/autoplay.js new file mode 100644 index 0000000000..f6401c23ec --- /dev/null +++ b/ui/analyse/src/autoplay.js @@ -0,0 +1,40 @@ +var control = require('./control'); +var partial = require('chessground').util.partial; +var m = require('mithril'); + +module.exports = function(ctrl) { + + var interval; + var delay = 1000; + + var next = function() { + if (control.canGoForward(ctrl)) { + var p = ctrl.vm.path; + p[p.length - 1].ply++; + ctrl.jump(p); + m.redraw(); + } else this.stop(); + }.bind(this); + + this.start = function() { + this.stop(); + next(); + interval = setInterval(next, delay); + }.bind(this); + + this.stop = function() { + if (interval) { + clearInterval(interval); + interval = null; + } + }.bind(this); + + this.toggle = function() { + if (this.active()) this.stop(); + else this.start(); + }.bind(this); + + this.active = function() { + return !!interval; + }.bind(this); +}; diff --git a/ui/analyse/src/control.js b/ui/analyse/src/control.js index 2aca52b570..3b5c8aeaf2 100644 --- a/ui/analyse/src/control.js +++ b/ui/analyse/src/control.js @@ -15,6 +15,8 @@ function canGoForward(ctrl) { module.exports = { + canGoForward: canGoForward, + next: function(ctrl) { if (!canGoForward(ctrl)) return; var p = ctrl.vm.path; diff --git a/ui/analyse/src/ctrl.js b/ui/analyse/src/ctrl.js index 7145b28737..b51e194da7 100644 --- a/ui/analyse/src/ctrl.js +++ b/ui/analyse/src/ctrl.js @@ -6,6 +6,8 @@ var ground = require('./ground'); var keyboard = require('./keyboard'); var treePath = require('./path'); var actionMenu = require('./actionMenu').controller; +var autoplay = require('./autoplay'); +var control = require('./control'); var m = require('mithril'); module.exports = function(cfg, router, i18n, onChange) { @@ -13,6 +15,7 @@ module.exports = function(cfg, router, i18n, onChange) { this.data = data({}, cfg); this.analyse = new analyse(this.data.game, this.data.analysis); this.actionMenu = new actionMenu(); + this.autoplay = new autoplay(this); var initialPath = cfg.path ? treePath.read(cfg.path) : treePath.default(); @@ -21,8 +24,7 @@ module.exports = function(cfg, router, i18n, onChange) { pathStr: treePath.write(initialPath), situation: null, comments: true, - flip: false, - play: false + flip: false }; this.flip = function() { @@ -32,6 +34,16 @@ module.exports = function(cfg, router, i18n, onChange) { }); }.bind(this); + this.togglePlay = function() { + this.autoplay.toggle(); + this.actionMenu.open = false; + }.bind(this); + + this.control = function(command) { + this.autoplay.stop(); + control[command](this); + }.bind(this); + var gameVariantChessId = function() { switch (this.data.game.variant.key) { case 'chess960': diff --git a/ui/analyse/src/view.js b/ui/analyse/src/view.js index 1ff1c7220d..5058c5cd0a 100644 --- a/ui/analyse/src/view.js +++ b/ui/analyse/src/view.js @@ -6,7 +6,6 @@ var partial = require('chessground').util.partial; var renderStatus = require('game').view.status; var mod = require('game').view.mod; var treePath = require('./path'); -var control = require('./control'); var actionMenu = require('./actionMenu').view; function renderEval(e) { @@ -236,8 +235,8 @@ function renderAnalyse(ctrl) { } function wheel(ctrl, e) { - if (e.deltaY > 0) control.next(ctrl); - else if (e.deltaY < 0) control.prev(ctrl); + if (e.deltaY > 0) ctrl.control('next'); + else if (e.deltaY < 0) ctrl.control('prev'); m.redraw(); e.preventDefault(); return false; @@ -270,10 +269,10 @@ function buttons(ctrl) { return [ m('div.game_control', [ m('div.jumps.hint--bottom', [ - ['first', 'W', control.first, ], - ['prev', 'Y', control.prev], - ['next', 'X', control.next], - ['last', 'V', control.last] + ['first', 'W', 'first', ], + ['prev', 'Y', 'prev'], + ['next', 'X', 'next'], + ['last', 'V', 'last'] ].map(function(b) { return { tag: 'a', @@ -283,11 +282,11 @@ function buttons(ctrl) { glowing: ctrl.vm.late && b[0] === 'last' }), 'data-icon': b[1], - onclick: partial(b[2], ctrl) + onclick: partial(ctrl.control, b[2]) } }; })), - m('a.button', { + ctrl.data.inGame ? null : m('a.button', { onclick: ctrl.actionMenu.toggle, class: ctrl.actionMenu.open ? 'active' : '' }, m('span', { From 8bc6dc7661b65c14eebf9a5dc2cba549e147982c Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 29 Jan 2015 17:47:59 +0100 Subject: [PATCH 21/23] autoplay fast and slow --- ui/analyse/src/actionMenu.js | 18 +++++++++++++----- ui/analyse/src/autoplay.js | 22 +++++++++++++--------- ui/analyse/src/ctrl.js | 4 ++-- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ui/analyse/src/actionMenu.js b/ui/analyse/src/actionMenu.js index 7033092e31..d665d41595 100644 --- a/ui/analyse/src/actionMenu.js +++ b/ui/analyse/src/actionMenu.js @@ -1,3 +1,4 @@ +var partial = require('chessground').util.partial; var m = require('mithril'); module.exports = { @@ -25,11 +26,18 @@ module.exports = { onclick: function() { $.modal($('.continue_with.' + ctrl.data.game.id)); } - }, ctrl.trans('continueFromHere')), - m('a.button[data-icon=G]', { - class: 'text' + (ctrl.autoplay.active() ? ' active' : ''), - onclick: ctrl.togglePlay - }, 'Auto play'), + }, ctrl.trans('continueFromHere')), [{ + name: 'fast', + delay: 1000 + }, { + name: 'slow', + delay: 5000 + }].map(function(speed) { + return m('a.button[data-icon=G]', { + class: 'text' + (ctrl.autoplay.active(speed.delay) ? ' active' : ''), + onclick: partial(ctrl.togglePlay, speed.delay) + }, 'Auto play ' + speed.name); + }), m('div.continue_with.' + ctrl.data.game.id, [ m('a.button', { href: ctrl.data.userAnalysis ? '/?fen=' + ctrl.vm.situation.fen + '#ai' : ctrl.router.Round.continue(ctrl.data.game.id, 'ai').url + '?fen=' + ctrl.vm.situation.fen, diff --git a/ui/analyse/src/autoplay.js b/ui/analyse/src/autoplay.js index f6401c23ec..82745e14af 100644 --- a/ui/analyse/src/autoplay.js +++ b/ui/analyse/src/autoplay.js @@ -5,7 +5,8 @@ var m = require('mithril'); module.exports = function(ctrl) { var interval; - var delay = 1000; + + this.delay = null; var next = function() { if (control.canGoForward(ctrl)) { @@ -16,10 +17,10 @@ module.exports = function(ctrl) { } else this.stop(); }.bind(this); - this.start = function() { + var start = function(delay) { + this.delay = delay; this.stop(); - next(); - interval = setInterval(next, delay); + interval = setInterval(next, this.delay); }.bind(this); this.stop = function() { @@ -29,12 +30,15 @@ module.exports = function(ctrl) { } }.bind(this); - this.toggle = function() { - if (this.active()) this.stop(); - else this.start(); + this.toggle = function(delay) { + if (this.active(delay)) this.stop(); + else { + if (!this.active()) next(); + start(delay); + } }.bind(this); - this.active = function() { - return !!interval; + this.active = function(delay) { + return (!delay || delay === this.delay) && !!interval; }.bind(this); }; diff --git a/ui/analyse/src/ctrl.js b/ui/analyse/src/ctrl.js index b51e194da7..e42556bfff 100644 --- a/ui/analyse/src/ctrl.js +++ b/ui/analyse/src/ctrl.js @@ -34,8 +34,8 @@ module.exports = function(cfg, router, i18n, onChange) { }); }.bind(this); - this.togglePlay = function() { - this.autoplay.toggle(); + this.togglePlay = function(delay) { + this.autoplay.toggle(delay); this.actionMenu.open = false; }.bind(this); From a5591bdb8f71148176bbac8bdda6a2ef24d945ce Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Thu, 29 Jan 2015 18:35:09 +0100 Subject: [PATCH 22/23] realtime replay --- app/controllers/Analyse.scala | 34 +++++++++++++----------- modules/api/src/main/RoundApi.scala | 7 +++-- modules/round/src/main/JsonView.scala | 4 ++- ui/analyse/src/actionMenu.js | 3 +++ ui/analyse/src/autoplay.js | 37 ++++++++++++++++++++------- ui/analyse/src/control.js | 8 +++--- ui/analyse/src/ctrl.js | 14 +++++----- ui/analyse/src/keyboard.js | 2 +- ui/analyse/src/view.js | 17 ++++++------ 9 files changed, 79 insertions(+), 47 deletions(-) diff --git a/app/controllers/Analyse.scala b/app/controllers/Analyse.scala index 9ea82bc88f..ed224df7bb 100644 --- a/app/controllers/Analyse.scala +++ b/app/controllers/Analyse.scala @@ -8,10 +8,10 @@ import play.api.mvc._ import play.twirl.api.Html import lila.analyse.{ Analysis, TimeChart, AdvantageChart, Accuracy } -import lila.evaluation.GameResults import lila.api.Context import lila.app._ import lila.common.HTTPRequest +import lila.evaluation.GameResults import lila.game.{ Pov, Game => GameModel, GameRepo, PgnDump } import lila.hub.actorApi.map.Tell import lila.round.actorApi.AnalysisAvailable @@ -60,17 +60,21 @@ object Analyse extends LilaController { GameRepo initialFen pov.game.id flatMap { initialFen => (env.analyser get pov.game.id) zip (pov.game.tournamentId ?? lila.tournament.TournamentRepo.byId) zip - Env.game.crosstableApi(pov.game) flatMap { - case ((analysis, tour), crosstable) => - val division = - if (HTTPRequest.isBot(ctx.req)) divider.empty - else divider(pov.game, initialFen) - val pgn = Env.game.pgnDump(pov.game, initialFen) - val assessResults = if (isGranted(_.MarkEngine)) Env.mod.assessApi.getResultsByGameId(pov.game.id) - else fuccess(GameResults(None, None)) - assessResults flatMap { - results => - Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, tv = none, analysis.map(pgn -> _), initialFen = initialFen.some) map { data => { + Env.game.crosstableApi(pov.game) flatMap { + case ((analysis, tour), crosstable) => + val division = + if (HTTPRequest.isBot(ctx.req)) divider.empty + else divider(pov.game, initialFen) + val pgn = Env.game.pgnDump(pov.game, initialFen) + val assessResults = if (isGranted(_.MarkEngine)) Env.mod.assessApi.getResultsByGameId(pov.game.id) + else fuccess(GameResults(None, None)) + assessResults flatMap { + results => + Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, + tv = none, + analysis.map(pgn -> _), + initialFen = initialFen.some, + withMoveTimes = true) map { data => Ok(html.analyse.replay( pov, data, @@ -83,8 +87,8 @@ object Analyse extends LilaController { userTv, division, results)) - } } - } - } + } + } + } } } diff --git a/modules/api/src/main/RoundApi.scala b/modules/api/src/main/RoundApi.scala index 4c07654132..c66e414a19 100644 --- a/modules/api/src/main/RoundApi.scala +++ b/modules/api/src/main/RoundApi.scala @@ -31,9 +31,12 @@ private[api] final class RoundApi( def watcher(pov: Pov, apiVersion: Int, tv: Option[Boolean], analysis: Option[(Pgn, Analysis)] = None, - initialFen: Option[Option[String]] = None)(implicit ctx: Context): Fu[JsObject] = + initialFen: Option[Option[String]] = None, + withMoveTimes: Boolean = false)(implicit ctx: Context): Fu[JsObject] = jsonView.watcherJson(pov, ctx.pref, apiVersion, ctx.me, tv, - withBlurs = ctx.me ?? Granter(_.ViewBlurs), initialFen = initialFen) zip + withBlurs = ctx.me ?? Granter(_.ViewBlurs), + initialFen = initialFen, + withMoveTimes = withMoveTimes) zip (pov.game.tournamentId ?? TournamentRepo.byId) zip (ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map { case ((json, tourOption), note) => ( diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index 3aff8ba9e4..dc810399e8 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -138,7 +138,8 @@ final class JsonView( user: Option[User], tv: Option[Boolean], withBlurs: Boolean, - initialFen: Option[Option[String]] = None) = + initialFen: Option[Option[String]] = None, + withMoveTimes: Boolean) = initialFen.fold(GameRepo initialFen pov.game)(fuccess) zip getSocketStatus(pov.game.id) zip getWatcherChat(pov.game, user) zip @@ -163,6 +164,7 @@ final class JsonView( "rematch" -> game.next, "source" -> game.source.map(sourceJson), "moves" -> game.pgnMoves.mkString(" "), + "moveTimes" -> withMoveTimes.option(game.moveTimes), "opening" -> game.opening.map { o => Json.obj( "code" -> o.code, diff --git a/ui/analyse/src/actionMenu.js b/ui/analyse/src/actionMenu.js index d665d41595..d9b4b8cddd 100644 --- a/ui/analyse/src/actionMenu.js +++ b/ui/analyse/src/actionMenu.js @@ -32,6 +32,9 @@ module.exports = { }, { name: 'slow', delay: 5000 + }, { + name: 'realtime', + delay: true }].map(function(speed) { return m('a.button[data-icon=G]', { class: 'text' + (ctrl.autoplay.active(speed.delay) ? ' active' : ''), diff --git a/ui/analyse/src/autoplay.js b/ui/analyse/src/autoplay.js index 82745e14af..3f35bdfaa6 100644 --- a/ui/analyse/src/autoplay.js +++ b/ui/analyse/src/autoplay.js @@ -4,41 +4,60 @@ var m = require('mithril'); module.exports = function(ctrl) { - var interval; + var timeout; this.delay = null; - var next = function() { + var move = function() { if (control.canGoForward(ctrl)) { var p = ctrl.vm.path; p[p.length - 1].ply++; ctrl.jump(p); m.redraw(); - } else this.stop(); + return true; + } + this.stop(); + m.redraw(); + return false; + }.bind(this); + + var nextDelay = function() { + if (this.delay === true) { + // in a variation + if (ctrl.vm.path.length > 1) return 2000; + return (ctrl.data.game.moveTimes[ctrl.vm.path[0].ply] * 100) || 2000; + } + return this.delay; + }.bind(this); + + var schedule = function() { + timeout = setTimeout(function() { + if (move()) schedule(); + }, nextDelay()); }.bind(this); var start = function(delay) { this.delay = delay; this.stop(); - interval = setInterval(next, this.delay); + schedule(); }.bind(this); this.stop = function() { - if (interval) { - clearInterval(interval); - interval = null; + if (timeout) { + clearTimeout(timeout); + timeout = null; } }.bind(this); this.toggle = function(delay) { if (this.active(delay)) this.stop(); else { - if (!this.active()) next(); + if (!this.active()) move(); start(delay); } }.bind(this); this.active = function(delay) { - return (!delay || delay === this.delay) && !!interval; + return (!delay || delay === this.delay) && !!timeout; }.bind(this); }; diff --git a/ui/analyse/src/control.js b/ui/analyse/src/control.js index 3b5c8aeaf2..f88657589a 100644 --- a/ui/analyse/src/control.js +++ b/ui/analyse/src/control.js @@ -21,7 +21,7 @@ module.exports = { if (!canGoForward(ctrl)) return; var p = ctrl.vm.path; p[p.length - 1].ply++; - ctrl.jump(p); + ctrl.userJump(p); }, prev: function(ctrl) { @@ -38,18 +38,18 @@ module.exports = { if (p[len - 2].ply > 1) p[len - 2].ply--; } } - ctrl.jump(p); + ctrl.userJump(p); }, last: function(ctrl) { - ctrl.jump([{ + ctrl.userJump([{ ply: ctrl.analyse.tree[ctrl.analyse.tree.length - 1].ply, variation: null }]); }, first: function(ctrl) { - ctrl.jump([{ + ctrl.userJump([{ ply: 0, variation: null }]); diff --git a/ui/analyse/src/ctrl.js b/ui/analyse/src/ctrl.js index e42556bfff..60ad3a72a2 100644 --- a/ui/analyse/src/ctrl.js +++ b/ui/analyse/src/ctrl.js @@ -39,11 +39,6 @@ module.exports = function(cfg, router, i18n, onChange) { this.actionMenu.open = false; }.bind(this); - this.control = function(command) { - this.autoplay.stop(); - control[command](this); - }.bind(this); - var gameVariantChessId = function() { switch (this.data.game.variant.key) { case 'chess960': @@ -147,8 +142,13 @@ module.exports = function(cfg, router, i18n, onChange) { showGround(); }.bind(this); + this.userJump = function(path) { + this.autoplay.stop(); + this.jump(path); + }.bind(this); + this.jumpToMain = function(ply) { - this.jump([{ + this.userJump([{ ply: ply, variation: null }]); @@ -163,7 +163,7 @@ module.exports = function(cfg, router, i18n, onChange) { to: dest, promotion: (dest[1] == 1 || dest[1] == 8) ? 'q' : null }); - if (move) this.jump(this.analyse.explore(this.vm.path, move.san)); + if (move) this.userJump(this.analyse.explore(this.vm.path, move.san)); else this.chessground.set(this.vm.situation); m.redraw(); }.bind(this); diff --git a/ui/analyse/src/keyboard.js b/ui/analyse/src/keyboard.js index 3f16a0542b..95e772e995 100644 --- a/ui/analyse/src/keyboard.js +++ b/ui/analyse/src/keyboard.js @@ -36,7 +36,7 @@ module.exports = function(ctrl) { if (!ctrl.vm.comments && ctrl.vm.path.length > 1) { path = [ctrl.vm.path[0]]; path[0].variation = null; - ctrl.jump(path); + ctrl.userJump(path); } m.redraw(); })); diff --git a/ui/analyse/src/view.js b/ui/analyse/src/view.js index 5058c5cd0a..c8c4670a34 100644 --- a/ui/analyse/src/view.js +++ b/ui/analyse/src/view.js @@ -6,6 +6,7 @@ var partial = require('chessground').util.partial; var renderStatus = require('game').view.status; var mod = require('game').view.mod; var treePath = require('./path'); +var control = require('./control'); var actionMenu = require('./actionMenu').view; function renderEval(e) { @@ -224,7 +225,7 @@ function renderAnalyse(ctrl) { var path = e.target.getAttribute('data-path') || e.target.parentNode.getAttribute('data-path'); if (path) { e.preventDefault(); - ctrl.jump(treePath.read(path)); + ctrl.userJump(treePath.read(path)); } }, onclick: function(e) { @@ -235,8 +236,8 @@ function renderAnalyse(ctrl) { } function wheel(ctrl, e) { - if (e.deltaY > 0) ctrl.control('next'); - else if (e.deltaY < 0) ctrl.control('prev'); + if (e.deltaY > 0) control.next(ctrl); + else if (e.deltaY < 0) control.prev(ctrl); m.redraw(); e.preventDefault(); return false; @@ -269,10 +270,10 @@ function buttons(ctrl) { return [ m('div.game_control', [ m('div.jumps.hint--bottom', [ - ['first', 'W', 'first', ], - ['prev', 'Y', 'prev'], - ['next', 'X', 'next'], - ['last', 'V', 'last'] + ['first', 'W', control.first, ], + ['prev', 'Y', control.prev], + ['next', 'X', control.next], + ['last', 'V', control.last] ].map(function(b) { return { tag: 'a', @@ -282,7 +283,7 @@ function buttons(ctrl) { glowing: ctrl.vm.late && b[0] === 'last' }), 'data-icon': b[1], - onclick: partial(ctrl.control, b[2]) + onclick: partial(b[2], ctrl) } }; })), From 3124c9e1d215b78625a068b644b1230f3066cd5e Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Fri, 30 Jan 2015 01:20:10 +0100 Subject: [PATCH 23/23] add missing font --- public/font32/fonts/lichess.eot | Bin 0 -> 19920 bytes public/font32/fonts/lichess.svg | 102 ++++ public/font32/fonts/lichess.ttf | Bin 0 -> 19756 bytes public/font32/fonts/lichess.woff | Bin 0 -> 14344 bytes public/font32/icons-reference.html | 805 +++++++++++++++++++++++++++++ public/font32/styles.css | 316 +++++++++++ 6 files changed, 1223 insertions(+) create mode 100644 public/font32/fonts/lichess.eot create mode 100644 public/font32/fonts/lichess.svg create mode 100644 public/font32/fonts/lichess.ttf create mode 100644 public/font32/fonts/lichess.woff create mode 100644 public/font32/icons-reference.html create mode 100644 public/font32/styles.css diff --git a/public/font32/fonts/lichess.eot b/public/font32/fonts/lichess.eot new file mode 100644 index 0000000000000000000000000000000000000000..92cab51d2211d7f1d7da572a547ec1cc402b6334 GIT binary patch literal 19920 zcmd6Pd6*n$d1rlfUtQH*T}R*dHKWlS-P7IDjHGEDmaW6qVF}BY5R#E(<3pAYjLqTn zVsnMd5m$nFKp`eT!aCrEuyJ-binC8PV3T+QEQdM70}mlM5rh!J64Kt^Th%ifU%UTq zA5~v{^_}nce(zoN)Ri1Jg+JqXjy^mmX<-664>C&a-W#5x%<#B;{o3@CSFOq(CoS$4 z?p53?xf{8Y+@1JxoW<=&`UdXRxO1Gl135nTGUVKWyRYJI<4$uWZjPJgX2Y`2uZ>LV zFvblzf!n)%`++NO-}K)9$#GZ4k(;}G+hyCicW^Ss`BPk%_FO&F-t(tN&ZE*HT)*s< zw;n%p;o**~^USl)q9tzkk8oeT;g)+(J#$e0KF3MhIPS6yH=aCxg8#Mk z72Nw4{=FNKAx`rW+H-MTyYbe$?lA{S3fG^;^)5mW;+56Vlp60lnL*%{r%x!nxrPb8mLH{c5UkK-h`Cav7`n9jHH~b4{ zMCPk#6e?sIg0c0}vK6BN|(GNCEtQO-2aMfby&sLJw340B$=N>~8;P{S_ zjOW;coW!YYH#>#v%g5(`;nEyta|suyELB+k>^*ha32wlZx!1A_&tAY7qPycV(F~#v zkv_~h%k_||uln|J?Qo|t{(4xZgmUY+Dz5t68@QXpk{tRO09`uVM0mZ6D{>`#hv=O? zr}3?04t1nUC`o;JoQ*aa>QEki2l!KO1EAu5F2ij`>UNYHpu_?E=~Ker!

cF-KX1 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 literal 0 HcmV?d00001 diff --git a/public/font32/fonts/lichess.svg b/public/font32/fonts/lichess.svg new file mode 100644 index 0000000000..8f03aa3f06 --- /dev/null +++ b/public/font32/fonts/lichess.svg @@ -0,0 +1,102 @@ + + + +Generated by Fontastic.me + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/font32/fonts/lichess.ttf b/public/font32/fonts/lichess.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cdf3b46089191b774101a028c448095332cfb60e GIT binary patch literal 19756 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 literal 0 HcmV?d00001 diff --git a/public/font32/fonts/lichess.woff b/public/font32/fonts/lichess.woff new file mode 100644 index 0000000000000000000000000000000000000000..17d3ee9ff826c52fca64e5cc205d1d65a7e47cf0 GIT binary patch literal 14344 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 literal 0 HcmV?d00001 diff --git a/public/font32/icons-reference.html b/public/font32/icons-reference.html new file mode 100644 index 0000000000..8469b837be --- /dev/null +++ b/public/font32/icons-reference.html @@ -0,0 +1,805 @@ + + + + + + + Font Reference - lichess + + + + + +

+

lichess

+

This font was created withFontastic

+

CSS mapping

+
    +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • + + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
+

Character mapping

+
    +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
  • +
    + +
  • +
+
+ + \ No newline at end of file diff --git a/public/font32/styles.css b/public/font32/styles.css new file mode 100644 index 0000000000..217d39486c --- /dev/null +++ b/public/font32/styles.css @@ -0,0 +1,316 @@ +@charset "UTF-8"; + +@font-face { + font-family: "lichess"; + src:url("fonts/lichess.eot"); + src:url("fonts/lichess.eot?#iefix") format("embedded-opentype"), + url("fonts/lichess.woff") format("woff"), + url("fonts/lichess.ttf") format("truetype"), + url("fonts/lichess.svg#lichess") format("svg"); + font-weight: normal; + font-style: normal; + +} + +[data-icon]:before { + font-family: "lichess" !important; + content: attr(data-icon); + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +[class^="icon-"]:before, +[class*=" icon-"]:before { + font-family: "lichess" !important; + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-fontawesome-webfont-1:before { + content: "a"; +} +.icon-fontawesome-webfont-2:before { + content: "b"; +} +.icon-fontawesome-webfont-3:before { + content: "c"; +} +.icon-fontawesome-webfont-4:before { + content: "d"; +} +.icon-fontawesome-webfont-5:before { + content: "e"; +} +.icon-fontawesome-webfont-6:before { + content: "f"; +} +.icon-fontawesome-webfont-7:before { + content: "g"; +} +.icon-fontawesome-webfont-8:before { + content: "h"; +} +.icon-fontawesome-webfont-9:before { + content: "j"; +} +.icon-fontawesome-webfont-10:before { + content: "k"; +} +.icon-fontawesome-webfont-11:before { + content: "l"; +} +.icon-fontawesome-webfont-12:before { + content: "m"; +} +.icon-fontawesome-webfont-15:before { + content: "p"; +} +.icon-fontawesome-webfont-17:before { + content: "r"; +} +.icon-fontawesome-webfont-18:before { + content: "s"; +} +.icon-fontawesome-webfont-19:before { + content: "t"; +} +.icon-fontawesome-webfont-20:before { + content: "u"; +} +.icon-eye-view-1:before { + content: "v"; +} +.icon-fontawesome-webfont-21:before { + content: "w"; +} +.icon-fontawesome-webfont-22:before { + content: "x"; +} +.icon-fontawesome-webfont-23:before { + content: "z"; +} +.icon-microscope:before { + content: "A"; +} +.icon-crown-king-1:before { + content: "C"; +} +.icon-fontawesome-webfont-24:before { + content: "D"; +} +.icon-fontawesome-webfont-25:before { + content: "E"; +} +.icon-fontawesome-webfont-26:before { + content: "F"; +} +.icon-fontawesome-webfont-27:before { + content: "G"; +} +.icon-fontawesome-webfont-28:before { + content: "H"; +} +.icon-fontawesome-webfont-29:before { + content: "I"; +} +.icon-fontawesome-webfont-30:before { + content: "J"; +} +.icon-fontawesome-webfont-31:before { + content: "K"; +} +.icon-loop-alt2:before { + content: "B"; +} +.icon-arrow-full-lowerright:before { + content: "M"; +} +.icon-arrow-full-upperright:before { + content: "N"; +} +.icon-fontawesome-webfont-32:before { + content: "L"; +} +.icon-plus-squared:before { + content: "O"; +} +.icon-plus-circled:before { + content: "O"; +} +.icon-fontawesome-webfont-33:before { + content: "O"; +} +.icon-fontawesome-webfont-34:before { + content: "Q"; +} +.icon-fire-station-24:before { + content: "Q"; +} +.icon-burning-fire:before { + content: "Q"; +} +.icon-arrow-sans-down:before { + content: "R"; +} +.icon-arrow-sans-up:before { + content: "S"; +} +.icon-fontawesome-webfont-34:before { + content: "T"; +} +.icon-crossed-swords-small:before { + content: "U"; +} +.icon-fontawesome-webfont-35:before { + content: "V"; +} +.icon-fontawesome-webfont-36:before { + content: "W"; +} +.icon-fontawesome-webfont-37:before { + content: "X"; +} +.icon-fontawesome-webfont-38:before { + content: "Y"; +} +.icon-fontawesome-webfont-39:before { + content: "Z"; +} +.icon-fontawesome-webfont-40:before { + content: "!"; +} +.icon-fontawesome-webfont-41:before { + content: "P"; +} +.icon-fontawesome-webfont:before { + content: "i"; +} +.icon-hand-stop:before { + content: "2"; +} +.icon-ionicons:before { + content: "3"; +} +.icon-fontawesome-webfont-42:before { + content: "0"; +} +.icon-television-tv:before { + content: "1"; +} +.icon-moon:before { + content: "4"; +} +.icon-sun:before { + content: "5"; +} +.icon-ink-pen:before { + content: "6"; +} +.icon-chart-line:before { + content: "9"; +} +.icon-link:before { + content: "\""; +} +.icon-ionicons-1:before { + content: "7"; +} +.icon-unmute:before { + content: "#"; +} +.icon-mute:before { + content: "$"; +} +.icon-gear:before { + content: "%"; +} +.icon-repo:before { + content: "&"; +} +.icon-tag:before { + content: "o"; +} +.icon-trash-bin:before { + content: "q"; +} +.icon-search-find:before { + content: "y"; +} +.icon-sheriff-badge:before { + content: "n"; +} +.icon-crown:before { + content: "8"; +} +.icon-die-six:before { + content: "'"; +} +.icon-flag:before { + content: "("; +} +.icon-flame:before { + content: ")"; +} +.icon-hourglass:before { + content: "+"; +} +.icon-droplet:before { + content: ","; +} +.icon-arrow-streamline-target:before { + content: "-"; +} +.icon-buffer:before { + content: "."; +} +.icon-upload-cloud:before { + content: "/"; +} +.icon-feather:before { + content: "*"; +} +.icon-gears-setting:before { + content: ":"; +} +.icon-email-plane:before { + content: ";"; +} +.icon-zoom-in:before { + content: "<"; +} +.icon-screen-full:before { + content: "="; +} +.icon-list:before { + content: "?"; +} +.icon-atom:before { + content: ">"; +} +.icon-book:before { + content: "]"; +} +.icon-body-cut:before { + content: "`"; +} +.icon-antichess:before { + content: "@"; +} +.icon-hubot:before { + content: "^"; +} +.icon-reorder:before { + content: "["; +}