├── Src ├── Files │ ├── Beep.wav │ ├── Robot.png │ ├── Tick.ogg │ ├── BeepBeep.wav │ ├── Favicon.ico │ ├── Favicon.png │ ├── Untitled.png │ ├── icon100.png │ ├── icon19.png │ ├── icon38.png │ ├── Challenger.wav │ ├── TickLast3.ogg │ ├── BackgroundR.png │ ├── NewYearTree.png │ ├── Background_Winter.png │ ├── DefaultUserBlack.png │ ├── DefaultUserWhite.png │ ├── BlackAndWhiteSource.jpg │ └── Fonts │ │ └── NotoEmoji │ │ ├── NotoEmoji-Regular.ttf │ │ └── LICENSE_OFL.txt ├── Common │ ├── Version.js │ ├── ListBase.js │ ├── BezierInterpolation.js │ ├── VerticalScroll.js │ ├── AboutWindow.js │ ├── Popup.js │ └── GameTimer.js ├── Main.js ├── Localizations │ ├── Localization.js │ ├── enUS.js │ ├── deDE.js │ └── frFR.js ├── MainGameRoom.js ├── IGS │ └── Client.js ├── KGS │ ├── Windows │ │ ├── UndoRequest.js │ │ ├── Information.js │ │ ├── RoomInfo.js │ │ ├── RoomList.js │ │ └── Window.js │ ├── UsersList.js │ ├── RoomList.js │ ├── AutomatchPreferences.js │ ├── PlayersList.js │ ├── User.js │ ├── Common.js │ ├── GameListRecord.js │ └── InGamePlayersList.js └── gameRoom.html ├── .gitmodules ├── GoBooklet └── FutureSummit2017 │ ├── files │ ├── GuLi.png │ ├── KeJie.png │ ├── pages.png │ ├── AlphaGo.png │ ├── ShiYue.png │ ├── ChenYaoye.png │ ├── LianXiao.png │ ├── MiYuting.png │ ├── TangWeixing.png │ └── ZhouRuiyang.png │ ├── styles.css │ └── main.js ├── README.md └── LICENSE.txt /Src/Files/Beep.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Beep.wav -------------------------------------------------------------------------------- /Src/Files/Robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Robot.png -------------------------------------------------------------------------------- /Src/Files/Tick.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Tick.ogg -------------------------------------------------------------------------------- /Src/Files/BeepBeep.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/BeepBeep.wav -------------------------------------------------------------------------------- /Src/Files/Favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Favicon.ico -------------------------------------------------------------------------------- /Src/Files/Favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Favicon.png -------------------------------------------------------------------------------- /Src/Files/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Untitled.png -------------------------------------------------------------------------------- /Src/Files/icon100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/icon100.png -------------------------------------------------------------------------------- /Src/Files/icon19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/icon19.png -------------------------------------------------------------------------------- /Src/Files/icon38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/icon38.png -------------------------------------------------------------------------------- /Src/Files/Challenger.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Challenger.wav -------------------------------------------------------------------------------- /Src/Files/TickLast3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/TickLast3.ogg -------------------------------------------------------------------------------- /Src/Files/BackgroundR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/BackgroundR.png -------------------------------------------------------------------------------- /Src/Files/NewYearTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/NewYearTree.png -------------------------------------------------------------------------------- /Src/Files/Background_Winter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Background_Winter.png -------------------------------------------------------------------------------- /Src/Files/DefaultUserBlack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/DefaultUserBlack.png -------------------------------------------------------------------------------- /Src/Files/DefaultUserWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/DefaultUserWhite.png -------------------------------------------------------------------------------- /Src/Files/BlackAndWhiteSource.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/BlackAndWhiteSource.jpg -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Src/External/GoProject"] 2 | path = Src/External/GoProject 3 | url = git@github.com:IlyaKirillov/GoProject.git 4 | -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/GuLi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/GuLi.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/KeJie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/KeJie.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/pages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/pages.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/AlphaGo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/AlphaGo.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/ShiYue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/ShiYue.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/ChenYaoye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/ChenYaoye.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/LianXiao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/LianXiao.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/MiYuting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/MiYuting.png -------------------------------------------------------------------------------- /Src/Files/Fonts/NotoEmoji/NotoEmoji-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/Src/Files/Fonts/NotoEmoji/NotoEmoji-Regular.ttf -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/TangWeixing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/TangWeixing.png -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/files/ZhouRuiyang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IlyaKirillov/GoUniverse/HEAD/GoBooklet/FutureSummit2017/files/ZhouRuiyang.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GoUniverse 2 | 3 | A universal Go/Baduk/Weiqi client based on Html5 and javascript. 4 | 5 | Supported servers: 6 | 7 | KGS (Kiseido Go Server) www.gokgs.com 8 | 9 | Current version: 1.5.8 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Src/Common/Version.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 07.07.2016 9 | * Time 1:44 10 | */ 11 | 12 | var g_sGoUniverseVersion = "1.5.11"; -------------------------------------------------------------------------------- /Src/Main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * User: Ilja.Kirillov 4 | * Date: 17.05.2016 5 | * Time: 12:48 6 | */ 7 | 8 | window.onload = OnDocumentReady; 9 | window.onbeforeunload = OnDocumentClose; 10 | window.onresize = OnDocumentResize; 11 | 12 | var oApp = null; 13 | function OnDocumentReady() 14 | { 15 | oApp = new CGoUniverseApplication(); 16 | oApp.Init(); 17 | } 18 | 19 | function OnDocumentClose() 20 | { 21 | if (oApp) 22 | oApp.Close(); 23 | } 24 | 25 | function OnDocumentResize() 26 | { 27 | if (oApp) 28 | oApp.OnResize(); 29 | } 30 | 31 | window.addEventListener("focus", function() 32 | { 33 | if (oApp) 34 | oApp.Focus(); 35 | }); 36 | 37 | window.addEventListener("blur", function() 38 | { 39 | if (oApp) 40 | oApp.Blur(); 41 | }); -------------------------------------------------------------------------------- /Src/Localizations/Localization.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 10.05.2017 9 | * Time 16:36 10 | */ 11 | 12 | var g_oDefaultLocalization = g_oLocalization_enUS; 13 | var g_oLocalization = g_oLocalization_enUS; 14 | 15 | var ExtendLocalization = function(original, base, key) 16 | { 17 | for (key in base) 18 | { 19 | if (base.hasOwnProperty(key)) 20 | { 21 | if (Object.prototype.toString.call(base[key]) === '[object Object]') 22 | original[key] = ExtendLocalization(original[key] || {}, base[key]); 23 | else if (!original.hasOwnProperty(key)) 24 | original[key] = base[key]; 25 | } 26 | } 27 | 28 | return original; 29 | }; 30 | -------------------------------------------------------------------------------- /Src/MainGameRoom.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * User: Ilja.Kirillov 4 | * Date: 21.07.2018 5 | * Time: 11:37 6 | */ 7 | 8 | window.onload = OnDocumentReady; 9 | window.onbeforeunload = OnDocumentClose; 10 | window.onresize = OnDocumentResize; 11 | 12 | 13 | var bc = null; 14 | function OnDocumentReady() 15 | { 16 | var sGameId = GetJsonFromUrl().id; 17 | 18 | bc = new BroadcastChannel("GoUniverse.GameRoom=" + sGameId); 19 | bc.postMessage({Type : "Ready"}); 20 | 21 | bc.onmessage = function(e) 22 | { 23 | var oMessage = e.data; 24 | var sType = oMessage.Type; 25 | 26 | switch(sType) 27 | { 28 | case "GameName": 29 | document.title = oMessage.GameName; 30 | break; 31 | } 32 | 33 | console.log(oMessage); 34 | } 35 | } 36 | 37 | function OnDocumentClose() 38 | { 39 | bc.close(); 40 | } 41 | 42 | function OnDocumentResize() 43 | { 44 | } 45 | -------------------------------------------------------------------------------- /Src/IGS/Client.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2017 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 29.10.2017 9 | * Time 11:50 10 | */ 11 | 12 | //var net = require('net'); 13 | 14 | function CIGSClient(oApp) 15 | { 16 | this.m_oApp = oApp; 17 | this.m_oGlobalSettings = oApp.GetGlobalSettings(); 18 | 19 | this.m_oSocket = new net.Socket(); 20 | } 21 | 22 | CIGSClient.prototype.Connect = function(sLogin, sPassword, sLocale) 23 | { 24 | this.private_SendMessage({ 25 | "type" : "LOGIN", 26 | "name" : sLogin, 27 | "password" : sPassword, 28 | "locale" : sLocale ? sLocale : "en_US" 29 | }); 30 | }; 31 | CIGSClient.prototype.private_SendMessage = function() 32 | { 33 | 34 | }; 35 | 36 | // client.connect(6969, 'igs.joyjoy.net', function() 37 | // { 38 | // console.log('Connected'); 39 | // client.write('Hello, server! Love, Client.'); 40 | // }); 41 | // 42 | // client.on('data', function(data) { 43 | // console.log('Received: ' + data); 44 | // client.destroy(); // kill client after server's response 45 | // }); 46 | // 47 | // client.on('close', function() { 48 | // console.log('Connection closed'); 49 | // }); -------------------------------------------------------------------------------- /Src/KGS/Windows/UndoRequest.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 01.10.2016 9 | * Time 15:38 10 | */ 11 | 12 | function CKGSUndoRequestWindow() 13 | { 14 | CKGSUndoRequestWindow.superclass.constructor.call(this); 15 | 16 | this.m_oButtonNeverUndo = null; 17 | } 18 | CommonExtend(CKGSUndoRequestWindow, CKGSWindowConfirmBase); 19 | 20 | CKGSUndoRequestWindow.prototype.Init = function(sDivId, oPr) 21 | { 22 | var oSize = this.private_CalculateWindowSize(); 23 | oPr.H = oSize.H; 24 | oPr.W = oSize.W; 25 | 26 | CKGSUndoRequestWindow.superclass.Init.call(this, sDivId, oPr); 27 | 28 | var oMainDiv = this.HtmlElement.InnerDiv; 29 | var oMainControl = this.HtmlElement.InnerControl; 30 | var oButtonsDiv = this.HtmlElement.OkCancelDiv; 31 | var _sDivId = oMainDiv.id; 32 | 33 | var sCaption = g_oLocalization.KGS.window.undoRequest.buttonNeverUndo; 34 | g_oTextMeasurer.SetFont("16px 'Segoe UI', Helvetica, Tahoma, Geneva, Verdana, sans-serif"); 35 | var nCaptionWidth = g_oTextMeasurer.Measure(sCaption); 36 | var sButtonNerverUndo = _sDivId + "NerverUndo"; 37 | var oButtonNeverUndoElement = this.protected_CreateDivElement(oButtonsDiv, sButtonNerverUndo); 38 | var oButtonNeverUndoControl = CreateControlContainerByElement(oButtonNeverUndoElement); 39 | oButtonNeverUndoControl.Bounds.SetParams(0, 9, 159, 1000, false, true, true, false, nCaptionWidth + 10, 21); 40 | oButtonNeverUndoControl.Anchor = (g_anchor_top | g_anchor_right); 41 | oMainControl.AddControl(oButtonNeverUndoControl); 42 | 43 | var oGameRoom = oPr.GameRoom; 44 | var oThis = this; 45 | var oButttonNeverUndo = new CDrawingButtonSimpleText(sCaption, function() 46 | { 47 | oGameRoom.ForbidUndo(); 48 | oThis.Close(); 49 | }, ""); 50 | oButttonNeverUndo.Init(sButtonNerverUndo, this); 51 | this.m_oButtonNeverUndo = oButttonNeverUndo; 52 | 53 | this.Update_Size(); 54 | }; 55 | CKGSUndoRequestWindow.prototype.Update_Size = function(bForce) 56 | { 57 | CKGSUndoRequestWindow.superclass.Update_Size.apply(this, arguments); 58 | 59 | if (this.m_oButtonNeverUndo) 60 | this.m_oButtonNeverUndo.Update_Size(bForce); 61 | }; 62 | CKGSUndoRequestWindow.prototype.private_CalculateWindowSize = function() 63 | { 64 | g_oTextMeasurer.SetFont("16px 'Segoe UI', Helvetica, Tahoma, Geneva, Verdana, sans-serif"); 65 | var nCaptionWidth = g_oTextMeasurer.Measure(g_oLocalization.KGS.window.undoRequest.buttonNeverUndo); 66 | 67 | return { 68 | W : Math.max(320, 7 + 10 + nCaptionWidth + 10 + 159 + 7), 69 | H : 140 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/styles.css: -------------------------------------------------------------------------------- 1 | .bookPage { 2 | width : 460px; 3 | height : 582px; 4 | } 5 | 6 | .oddPage { 7 | background : url(files/pages.png); 8 | } 9 | 10 | .evenPage { 11 | background : url(files/pages.png); 12 | background-position-x: -460px; 13 | } 14 | 15 | .bookCover { 16 | background : rgb(32, 77, 123); 17 | width : 460px; 18 | height : 582px; 19 | } 20 | 21 | .contentsHeading1 { 22 | font-weight : bold; 23 | font-size : 24px; 24 | width : 100%; 25 | text-align : center; 26 | } 27 | 28 | .contentsHeading2 { 29 | padding-left : 20px; 30 | font-weight : bold; 31 | font-size : 20px; 32 | cursor : pointer; 33 | } 34 | 35 | .contentsHeading2:hover { 36 | text-decoration : underline; 37 | } 38 | 39 | .contentsNormal { 40 | padding-left : 30px; 41 | font-size : 16px; 42 | cursor : pointer; 43 | } 44 | 45 | .contentsNormal:hover { 46 | text-decoration : underline; 47 | } 48 | 49 | 50 | .contentsPageNumber { 51 | padding-right:10px; 52 | font-size: 14px; 53 | text-align: right; 54 | } 55 | 56 | .oddPageNumber { 57 | position : absolute; 58 | left : 10px; 59 | top : 552px; 60 | width : 20px; 61 | height : 20px; 62 | line-height : 20px; 63 | text-align : center; 64 | font-size : 12px; 65 | color : silver; 66 | } 67 | 68 | .evenPageNumber { 69 | position : absolute; 70 | right : 10px; 71 | top : 552px; 72 | width : 20px; 73 | height : 20px; 74 | line-height : 20px; 75 | text-align : center; 76 | font-size : 12px; 77 | color : silver; 78 | } 79 | 80 | .gameHeader1 { 81 | font-size : 20px; 82 | margin-top : 100px; 83 | font-weight : bold; 84 | width : 100%; 85 | text-align : center; 86 | } 87 | 88 | .gameHeader2 { 89 | font-size : 14px; 90 | margin-top : 5px; 91 | width : 100%; 92 | text-align : center; 93 | } 94 | 95 | table.gameDescription { 96 | padding-right : 35px; 97 | padding-left : 35px; 98 | margin-top : 50px; 99 | } 100 | 101 | .gameDescriptionFieldName { 102 | font-size : 16px; 103 | font-weight : bold; 104 | text-align : left; 105 | } 106 | .gameDescriptionFieldValue { 107 | font-size : 16px; 108 | text-align : left; 109 | } 110 | 111 | .waitingGame { 112 | line-height : 582px; 113 | height : 582px; 114 | font-size : 25px; 115 | width : 100%; 116 | text-align : center; 117 | } 118 | 119 | .participantImg { 120 | padding-left : 35px; 121 | padding-top : 35px; 122 | padding-right : 10px; 123 | padding-bottom : 10px; 124 | float : left; 125 | } 126 | 127 | .participantHeading { 128 | font-weight : bold; 129 | font-size : 40px; 130 | width : 100%; 131 | margin-top : 100px; 132 | } 133 | 134 | .participantText { 135 | font-size : 16px; 136 | padding-left : 35px; 137 | padding-right : 35px; 138 | } -------------------------------------------------------------------------------- /Src/Common/ListBase.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 06.07.2016 9 | * Time 1:28 10 | */ 11 | 12 | function CListBase() 13 | { 14 | this.m_oHeaders = { 15 | Sizes : [], 16 | Count : 0 17 | }; 18 | 19 | this.m_nSortType = 0; 20 | } 21 | CListBase.prototype.Set_SortType = function(nColNum, nDirection) 22 | { 23 | if (nDirection > 0) 24 | this.m_nSortType = nColNum + 1; 25 | else 26 | this.m_nSortType = -(nColNum + 1); 27 | }; 28 | CListBase.prototype.private_PreSort = function(oRecord1, oRecord2) 29 | { 30 | return 0; 31 | }; 32 | CListBase.prototype.private_PostSort = function(oRecord1, oRecord2) 33 | { 34 | return 0; 35 | }; 36 | CListBase.prototype.private_Sort = function(oRecord1, oRecord2) 37 | { 38 | return 0; 39 | }; 40 | CListBase.prototype.SortFunction = function(oRecord1, oRecord2) 41 | { 42 | var nResult = this.private_PreSort(oRecord1, oRecord2); 43 | if (0 !== nResult) 44 | return nResult; 45 | 46 | nResult = this.private_Sort(oRecord1, oRecord2); 47 | if (0 !== nResult) 48 | return nResult; 49 | 50 | return this.private_PostSort(oRecord1, oRecord2); 51 | }; 52 | CListBase.prototype.Is_Sortable = function(nColNum) 53 | { 54 | return true; 55 | }; 56 | CListBase.prototype.Draw_Header = function(dX, dY, oContext, nColNum) 57 | { 58 | var eType = nColNum + 1; 59 | var nSortType = this.m_nSortType; 60 | 61 | var sHeaderText; 62 | if (eType === nSortType) 63 | sHeaderText = this.m_oHeaders[eType] + String.fromCharCode(0x25B2); 64 | else if (eType === -nSortType) 65 | sHeaderText = this.m_oHeaders[eType] + String.fromCharCode(0x25BC); 66 | else 67 | sHeaderText = this.m_oHeaders[eType]; 68 | 69 | oContext.fillStyle = "#000000"; 70 | oContext.fillText(sHeaderText, dX, dY); 71 | }; 72 | CListBase.prototype.Draw_Record = function(dX, dY, oContext, oRecord, nColNum) 73 | { 74 | var eType = nColNum + 1; 75 | oRecord.Draw(oContext, dX, dY, eType); 76 | }; 77 | CListBase.prototype.Get_Record = function() 78 | { 79 | return new CListRecordBase(); 80 | }; 81 | CListBase.prototype.Get_Key = function(aLine) 82 | { 83 | return aLine[1]; 84 | }; 85 | CListBase.prototype.Handle_DoubleClick = function(Record) 86 | { 87 | }; 88 | CListBase.prototype.Handle_RightClick = function(Record, e) 89 | { 90 | }; 91 | CListBase.prototype.GetHeadersCount = function() 92 | { 93 | return this.m_oHeaders.Count; 94 | }; 95 | CListBase.prototype.GetHeadersSize = function(nColNum) 96 | { 97 | return this.m_oHeaders.Sizes[nColNum]; 98 | }; 99 | CListBase.prototype.GetVerLinesPositions = function() 100 | { 101 | return [1]; 102 | }; 103 | CListBase.prototype.GetSortType = function() 104 | { 105 | return this.m_nSortType; 106 | }; 107 | CListBase.prototype.SetHeadersSizes = function(nColNum, nSize) 108 | { 109 | this.m_oHeaders.Sizes[nColNum] = nSize; 110 | }; 111 | 112 | function CListRecordBase() 113 | { 114 | } 115 | CListRecordBase.prototype.Draw = function(oContext, dX, dY, eType) 116 | { 117 | }; 118 | CListRecordBase.prototype.Get_Key = function() 119 | { 120 | return null; 121 | }; 122 | CListRecordBase.prototype.Update = function(aLine) 123 | { 124 | }; 125 | CListRecordBase.prototype.Compare = function(sKey) 126 | { 127 | }; -------------------------------------------------------------------------------- /Src/KGS/UsersList.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 21.12.2016 9 | * Time 23:52 10 | */ 11 | 12 | var EKGSUsersListRecord = { 13 | Name : 1, 14 | Notes : 2 15 | }; 16 | 17 | function CKGSUsersList(oApp) 18 | { 19 | CKGSUsersList.superclass.constructor.call(this); 20 | 21 | this.m_oHeaders = { 22 | Sizes : [0, 130], 23 | Count : 2, 24 | 1 : "Name", 25 | 2 : "Notes" 26 | }; 27 | 28 | this.m_nSortType = EKGSUsersListRecord.Name; 29 | this.m_oApp = oApp; 30 | 31 | this.m_fOnSelect = null; 32 | this.m_fOnUnselect = null; 33 | } 34 | 35 | CommonExtend(CKGSUsersList, CListBase); 36 | 37 | CKGSUsersList.prototype.private_Sort = function (oRecord1, oRecord2) 38 | { 39 | var SortType = this.m_nSortType; 40 | if (EKGSUsersListRecord.Name === SortType) 41 | { 42 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 43 | return -1; 44 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 45 | return 1; 46 | } 47 | else if (-EKGSUsersListRecord.Name === SortType) 48 | { 49 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 50 | return 1; 51 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 52 | return -1; 53 | } 54 | 55 | return 0; 56 | }; 57 | CKGSUsersList.prototype.Is_Sortable = function(nColNum) 58 | { 59 | if (0 === nColNum) 60 | return true; 61 | 62 | return false; 63 | }; 64 | CKGSUsersList.prototype.Get_Record = function(aLine) 65 | { 66 | var oRecord = new CKGSUsersListRecord(this.m_oApp.GetClient()); 67 | oRecord.Update(aLine); 68 | return oRecord; 69 | }; 70 | CKGSUsersList.prototype.Handle_DoubleClick = function(Record) 71 | { 72 | }; 73 | CKGSUsersList.prototype.Handle_RightClick = function(oRecord, e) 74 | { 75 | if (this.m_oApp && oRecord) 76 | return this.m_oApp.ShowUserContextMenu(e.pageX - 2, e.pageY + 2, oRecord.m_sName); 77 | 78 | return null; 79 | }; 80 | CKGSUsersList.prototype.Handle_Select = function(oRecord) 81 | { 82 | if (this.m_fOnSelect) 83 | this.m_fOnSelect(oRecord.m_sName, oRecord.m_sNotes); 84 | }; 85 | CKGSUsersList.prototype.Handle_Unselect = function() 86 | { 87 | if (this.m_fOnUnselect) 88 | this.m_fOnUnselect(); 89 | }; 90 | CKGSUsersList.prototype.SetSelectCallback = function(fCallBack) 91 | { 92 | this.m_fOnSelect = fCallBack; 93 | }; 94 | CKGSUsersList.prototype.SetUnselectCallback = function(fCallback) 95 | { 96 | this.m_fOnUnselect = fCallback; 97 | }; 98 | 99 | function CKGSUsersListRecord(oClient) 100 | { 101 | CKGSUsersListRecord.superclass.constructor.call(this); 102 | 103 | this.m_oClient = oClient; 104 | this.m_sName = ""; 105 | this.m_oUser = null; 106 | this.m_sNotes = ""; 107 | } 108 | 109 | CommonExtend(CKGSUsersListRecord, CListRecordBase); 110 | 111 | CKGSUsersListRecord.prototype.Draw = function(oContext, dX, dY, eType) 112 | { 113 | var sString = ""; 114 | switch(eType) 115 | { 116 | case EKGSUsersListRecord.Name : sString += this.m_sName + "[" + this.m_sRank + "]"; break; 117 | case EKGSUsersListRecord.Notes : sString += this.m_sNotes; 118 | } 119 | 120 | oContext.fillText(sString, dX, dY); 121 | }; 122 | CKGSUsersListRecord.prototype.Get_Key = function() 123 | { 124 | return this.m_sName.toLowerCase(); 125 | }; 126 | CKGSUsersListRecord.prototype.Update = function(aLine) 127 | { 128 | var oUserExt = aLine[1]; 129 | this.m_oUser = oUserExt.User; 130 | this.m_sName = this.m_oUser.GetName(); 131 | this.m_sRank = this.m_oUser.GetStringRank(); 132 | this.m_sNotes = oUserExt.Notes; 133 | }; 134 | CKGSUsersListRecord.prototype.Compare = function(sName) 135 | { 136 | if (this.m_sName === sName) 137 | return true; 138 | 139 | return false; 140 | }; -------------------------------------------------------------------------------- /Src/Common/BezierInterpolation.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 20.08.2016 9 | * Time 8:24 10 | */ 11 | 12 | (function() 13 | { 14 | var EPSILON = 1.0e-5; 15 | 16 | function CPoint(x, y) 17 | { 18 | this.x = undefined !== x ? x : 0; 19 | this.y = undefined !== y ? y : 0; 20 | } 21 | CPoint.prototype.Normalize = function() 22 | { 23 | var dNorma = Math.sqrt(this.x * this.x + this.y * this.y); 24 | if (dNorma < EPSILON) 25 | return; 26 | 27 | this.x /= dNorma; 28 | this.y /= dNorma; 29 | }; 30 | function pointMinus(l, r) 31 | { 32 | return new CPoint(l.x - r.x, l.y - r.y); 33 | } 34 | function pointPlus(l, r) 35 | { 36 | return new CPoint(l.x + r.x, l.y + r.y); 37 | } 38 | function pointMult(p, k) 39 | { 40 | return new CPoint(p.x * k, p.y * k); 41 | } 42 | 43 | function CSegment() 44 | { 45 | this.points = [new CPoint(), new CPoint(), new CPoint(), new CPoint()]; 46 | } 47 | 48 | function GetSpline(values) 49 | { 50 | var bezier = []; 51 | 52 | var n = values.length - 1; 53 | 54 | if (1 === n) 55 | { 56 | bezier[0] = new CSegment(); 57 | bezier[0].points[0] = bezier[0].points[1] = values[0]; 58 | bezier[0].points[2] = bezier[0].points[3] = values[1]; 59 | return bezier; 60 | } 61 | else if (0 === n) 62 | { 63 | bezier[0] = new CSegment(); 64 | bezier[0].points[0] = bezier[0].points[1] = values[0]; 65 | bezier[0].points[2] = bezier[0].points[3] = values[0]; 66 | return bezier; 67 | } 68 | else if (n < 0) 69 | { 70 | return []; 71 | } 72 | 73 | var tgL = new CPoint(); 74 | var tgR = new CPoint(); 75 | var cur = new CPoint(); 76 | var next = pointMinus(values[1], values[0]); 77 | next.Normalize(); 78 | 79 | var l1, l2, tmp, x; 80 | 81 | --n; 82 | for (var i = 0; i < n; ++i) 83 | { 84 | bezier[i] = new CSegment(); 85 | 86 | bezier[i].points[0] = bezier[i].points[1] = values[i]; 87 | bezier[i].points[2] = bezier[i].points[3] = values[i + 1]; 88 | 89 | cur = next; 90 | next = pointMinus(values[i + 2], values[i + 1]); 91 | next.Normalize(); 92 | 93 | tgL = tgR; 94 | 95 | tgR = pointPlus(cur, next); 96 | tgR.Normalize(); 97 | 98 | if (Math.abs(values[i + 1].y - values[i].y) < EPSILON) 99 | { 100 | l1 = l2 = 0.0; 101 | } 102 | else 103 | { 104 | tmp = values[i + 1].x - values[i].x; 105 | l1 = Math.abs(tgL.x) > EPSILON ? tmp / (2.0 * tgL.x) : 1.0; 106 | l2 = Math.abs(tgR.x) > EPSILON ? tmp / (2.0 * tgR.x) : 1.0; 107 | } 108 | 109 | if (Math.abs(tgL.x) > EPSILON && Math.abs(tgR.x) > EPSILON) 110 | { 111 | tmp = tgL.y / tgL.x - tgR.y / tgR.x; 112 | if (Math.abs(tmp) > EPSILON) 113 | { 114 | x = (values[i + 1].y - tgR.y / tgR.x * values[i + 1].x - values[i].y + tgL.y / tgL.x * values[i].x) / tmp; 115 | if (x > values[i].x && x < values[i + 1].x) 116 | { 117 | if (tgL.y > 0.0) 118 | { 119 | if (l1 > l2) 120 | l1 = 0.0; 121 | else 122 | l2 = 0.0; 123 | } 124 | else 125 | { 126 | if (l1 < l2) 127 | l1 = 0.0; 128 | else 129 | l2 = 0.0; 130 | } 131 | } 132 | } 133 | } 134 | 135 | bezier[i].points[1] = pointPlus(bezier[i].points[1], pointMult(tgL, l1)); 136 | bezier[i].points[2] = pointMinus(bezier[i].points[2], pointMult(tgR, l2)); 137 | } 138 | 139 | l1 = Math.abs(tgL.x) > EPSILON ? (values[n + 1].x - values[n].x) / (2.0 * tgL.x) : 1.0; 140 | 141 | bezier[n] = new CSegment(); 142 | bezier[n].points[0] = bezier[n].points[1] = values[n]; 143 | bezier[n].points[2] = bezier[n].points[3] = values[n + 1]; 144 | bezier[n].points[1] = pointPlus(bezier[n].points[1], pointMult(tgR, l1)); 145 | 146 | return bezier; 147 | } 148 | 149 | window["GetSpline"] = GetSpline; 150 | }()); -------------------------------------------------------------------------------- /Src/KGS/Windows/Information.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 26.06.2016 9 | * Time 2:33 10 | */ 11 | 12 | function CKGSInformationWindow() 13 | { 14 | CKGSInformationWindow.superclass.constructor.call(this); 15 | 16 | this.m_nDefW = 410; 17 | this.m_nDefH = 270; 18 | } 19 | CommonExtend(CKGSInformationWindow, CKGSWindowOKBase); 20 | 21 | CKGSInformationWindow.prototype.Init = function(sDivId, oPr) 22 | { 23 | if (oPr.H) 24 | this.m_nDefH = oPr.H; 25 | 26 | if (oPr.W) 27 | this.m_nDefW = oPr.W; 28 | 29 | CKGSInformationWindow.superclass.Init.call(this, sDivId, oPr, false); 30 | 31 | this.Set_Caption(oPr.Caption); 32 | 33 | var oMainDiv = this.HtmlElement.ConfirmInnerDiv; 34 | var oMainControl = this.HtmlElement.ConfirmInnerControl; 35 | 36 | oMainDiv.style.backgroundColor = "rgb(243, 243, 243)"; 37 | this.HtmlElement.OkCancelDiv.style.borderTop = ""; 38 | this.HtmlElement.OkCancelDiv.style.backgroundColor = "rgb(243, 243, 243)"; 39 | 40 | if (undefined !== oPr.Image) 41 | { 42 | var oImageElement = this.protected_CreateDivElement(oMainDiv, oMainDiv.id + "I"); 43 | var oTextElement = this.protected_CreateDivElement(oMainDiv, oMainDiv.id + "T"); 44 | 45 | var oImageControl = CreateControlContainer(oMainDiv.id + "I"); 46 | oImageControl.Bounds.SetParams(0, 0, 1000, 0, true, true, false, true, 70, -1); 47 | oImageControl.Anchor = (g_anchor_left | g_anchor_top | g_anchor_bottom); 48 | oMainControl.AddControl(oImageControl); 49 | 50 | oImageElement.style.display = "table"; 51 | var oInnerImage = document.createElement("div"); 52 | oInnerImage.className = "WarningText"; 53 | oImageElement.appendChild(oInnerImage); 54 | 55 | var oSpan = document.createElement("span"); 56 | oSpan.className = oPr.Image; 57 | oInnerImage.appendChild(oSpan); 58 | 59 | var oTextControl = CreateControlContainer(oMainDiv.id + "T"); 60 | oTextControl.Bounds.SetParams(70, 0, 5, 0, true, true, true, true, -1, -1); 61 | oTextControl.Anchor = (g_anchor_left | g_anchor_top | g_anchor_bottom | g_anchor_right); 62 | oMainControl.AddControl(oTextControl); 63 | 64 | oTextElement.style.display = "table"; 65 | var oInnerText = document.createElement("div"); 66 | oInnerText.className = "WarningText"; 67 | oTextElement.appendChild(oInnerText); 68 | Common.Set_InnerTextToElement(oInnerText, oPr.Text); 69 | } 70 | else 71 | { 72 | var oTextElement = oMainDiv; 73 | oTextElement.style.display = "table"; 74 | var oInnerText = document.createElement("div"); 75 | oInnerText.className = "WarningText"; 76 | oTextElement.appendChild(oInnerText); 77 | Common.Set_InnerTextToElement(oInnerText, oPr.Text); 78 | } 79 | 80 | if (oPr && oPr.Client) 81 | this.m_oClient = oPr.Client; 82 | 83 | this.Update_Size(true); 84 | this.Show(oPr); 85 | }; 86 | CKGSInformationWindow.prototype.Get_DefaultWindowSize = function() 87 | { 88 | return {W : this.m_nDefW, H : this.m_nDefH}; 89 | }; 90 | CKGSInformationWindow.prototype.Close = function() 91 | { 92 | CKGSInformationWindow.superclass.Close.call(this); 93 | RemoveWindow(this); 94 | }; 95 | 96 | function CKGSInformationIdleWindow() 97 | { 98 | CKGSInformationIdleWindow.superclass.constructor.call(this); 99 | 100 | this.m_nDefW = 412; 101 | this.m_nDefH = 220; 102 | } 103 | CommonExtend(CKGSInformationIdleWindow, CKGSInformationWindow); 104 | 105 | CKGSInformationIdleWindow.prototype.Init = function(sDivId, oPr) 106 | { 107 | oPr.Text = "It has been a long time since you used this client. In 10 minutes, the server will assume that you are gone and log you out. If you want to stay logged in, then just press the \"OK\" button in this window to let the server know that you want to stay."; 108 | oPr.Image = "WarningSpanWarning"; 109 | oPr.Caption = "Warning"; 110 | 111 | CKGSInformationIdleWindow.superclass.Init.call(this, sDivId, oPr); 112 | }; 113 | CKGSInformationIdleWindow.prototype.Close = function() 114 | { 115 | CKGSInformationIdleWindow.superclass.Close.call(this); 116 | this.m_oClient.WakeUp(); 117 | }; -------------------------------------------------------------------------------- /Src/KGS/RoomList.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 01.06.2016 9 | * Time 22:55 10 | */ 11 | 12 | var EKGSRoomListRecord = { 13 | Name : 1, 14 | Category : 2, 15 | Private : 3 16 | }; 17 | 18 | function CKGSRoomList(oApp) 19 | { 20 | CKGSRoomList.superclass.constructor.call(this); 21 | 22 | this.m_oHeaders = { 23 | Sizes : [0, 245, 365], 24 | Count : 3, 25 | 1 : g_oLocalization.KGS.window.roomsList.listHeaderName, 26 | 2 : g_oLocalization.KGS.window.roomsList.listHeaderCategory, 27 | 3 : "" 28 | }; 29 | 30 | this.m_nSortType = EKGSRoomListRecord.Name; 31 | this.m_oApp = oApp; 32 | } 33 | 34 | CommonExtend(CKGSRoomList, CListBase); 35 | 36 | CKGSRoomList.prototype.private_Sort = function(oRecord1, oRecord2) 37 | { 38 | var nRes = 0; 39 | var SortType = this.m_nSortType; 40 | 41 | if (EKGSRoomListRecord.Name === SortType) 42 | nRes = Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName); 43 | else if (-EKGSRoomListRecord.Name === SortType) 44 | nRes = Common.Compare_Strings(oRecord2.m_sName, oRecord1.m_sName); 45 | else if (EKGSRoomListRecord.Category === SortType) 46 | nRes = Common.Compare_Strings(oRecord1.m_sCategory, oRecord2.m_sCategory); 47 | else if (-EKGSRoomListRecord.Category === SortType) 48 | nRes = Common.Compare_Strings(oRecord2.m_sCategory, oRecord1.m_sCategory); 49 | 50 | if (0 !== nRes) 51 | return nRes; 52 | 53 | nRes = Common.Compare_Strings(oRecord1.m_sCategory, oRecord2.m_sCategory); 54 | if (0 !== nRes) 55 | return nRes; 56 | 57 | nRes = Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName); 58 | if (0 !== nRes) 59 | return nRes; 60 | 61 | if (oRecord1.m_nRoomId < oRecord2.m_nRoomId) 62 | return -1; 63 | else 64 | return 1; 65 | }; 66 | CKGSRoomList.prototype.Is_Sortable = function(nColNum) 67 | { 68 | if (2 === nColNum) 69 | return false; 70 | 71 | return true; 72 | }; 73 | CKGSRoomList.prototype.Get_Record = function(aLine) 74 | { 75 | var oRecord = new CKGSRoomListRecord(); 76 | oRecord.Update(aLine); 77 | return oRecord; 78 | }; 79 | CKGSRoomList.prototype.Handle_DoubleClick = function(Record) 80 | { 81 | if (this.m_oApp) 82 | this.m_oApp.SetCurrentChatRoomTab(Record.m_nRoomId); 83 | }; 84 | CKGSRoomList.prototype.GetVerLinesPositions = function() 85 | { 86 | return [1, 2]; 87 | }; 88 | 89 | function CKGSRoomListRecord() 90 | { 91 | CKGSRoomListRecord.superclass.constructor.call(this); 92 | 93 | this.m_nRoomId = -1; 94 | this.m_sName = ""; 95 | this.m_sCategory = ""; 96 | this.m_bPrivate = false; 97 | } 98 | 99 | CommonExtend(CKGSRoomListRecord, CListRecordBase); 100 | 101 | CKGSRoomListRecord.prototype.Draw = function(oContext, dX, dY, eType) 102 | { 103 | var sString = ""; 104 | switch (eType) 105 | { 106 | case EKGSRoomListRecord.Name: 107 | sString += this.m_sName; 108 | break; 109 | case EKGSRoomListRecord.Category: 110 | sString += this.m_sCategory; 111 | break; 112 | case EKGSRoomListRecord.Private: 113 | if (this.m_bPrivate) 114 | sString += "P"; 115 | break; 116 | } 117 | 118 | oContext.fillText(sString, dX, dY); 119 | }; 120 | CKGSRoomListRecord.prototype.Get_Key = function() 121 | { 122 | return this.m_nRoomId; 123 | }; 124 | CKGSRoomListRecord.prototype.Update = function(aLine) 125 | { 126 | this.m_nRoomId = aLine[1] | 0; 127 | this.m_sName = aLine[2]; 128 | this.m_sCategory = this.private_GetCategory(aLine[3]); 129 | this.m_bPrivate = aLine[4]; 130 | }; 131 | CKGSRoomListRecord.prototype.Compare = function(nRoomId) 132 | { 133 | if (this.m_nRoomId === nRoomId) 134 | return true; 135 | 136 | return false; 137 | }; 138 | CKGSRoomListRecord.prototype.private_GetCategory = function(sCategory) 139 | { 140 | switch(sCategory) 141 | { 142 | case "CLUBS" : return g_oLocalization.KGS.window.roomsList.categoryClubs; 143 | case "FRIENDLY" : return g_oLocalization.KGS.window.roomsList.categorySocial; 144 | case "MAIN" : return g_oLocalization.KGS.window.roomsList.categoryMain; 145 | case "NATIONAL" : return g_oLocalization.KGS.window.roomsList.categoryNational; 146 | case "TEMPORARY" : return g_oLocalization.KGS.window.roomsList.categoryNewRooms; 147 | case "LESSONS" : return g_oLocalization.KGS.window.roomsList.categoryLessons; 148 | case "TOURNAMENT" : return g_oLocalization.KGS.window.roomsList.categoryTournaments; 149 | } 150 | 151 | console.log("Unknown room category: " + this.m_sCategory); 152 | return ""; 153 | }; -------------------------------------------------------------------------------- /Src/Files/Fonts/NotoEmoji/LICENSE_OFL.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, 2 | Version 1.1. 3 | 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | ----------------------------------------------------------- 8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 9 | ----------------------------------------------------------- 10 | 11 | PREAMBLE 12 | The goals of the Open Font License (OFL) are to stimulate worldwide 13 | development of collaborative font projects, to support the font 14 | creation efforts of academic and linguistic communities, and to 15 | provide a free and open framework in which fonts may be shared and 16 | improved in partnership with others. 17 | 18 | The OFL allows the licensed fonts to be used, studied, modified and 19 | redistributed freely as long as they are not sold by themselves. The 20 | fonts, including any derivative works, can be bundled, embedded, 21 | redistributed and/or sold with any software provided that any reserved 22 | names are not used by derivative works. The fonts and derivatives, 23 | however, cannot be released under any other type of license. The 24 | requirement for fonts to remain under this license does not apply to 25 | any document created using the fonts or their derivatives. 26 | 27 | DEFINITIONS 28 | "Font Software" refers to the set of files released by the Copyright 29 | Holder(s) under this license and clearly marked as such. This may 30 | include source files, build scripts and documentation. 31 | 32 | "Reserved Font Name" refers to any names specified as such after the 33 | copyright statement(s). 34 | 35 | "Original Version" refers to the collection of Font Software 36 | components as distributed by the Copyright Holder(s). 37 | 38 | "Modified Version" refers to any derivative made by adding to, 39 | deleting, or substituting -- in part or in whole -- any of the 40 | components of the Original Version, by changing formats or by porting 41 | the Font Software to a new environment. 42 | 43 | "Author" refers to any designer, engineer, programmer, technical 44 | writer or other person who contributed to the Font Software. 45 | 46 | PERMISSION & CONDITIONS 47 | Permission is hereby granted, free of charge, to any person obtaining 48 | a copy of the Font Software, to use, study, copy, merge, embed, 49 | modify, redistribute, and sell modified and unmodified copies of the 50 | Font Software, subject to the following conditions: 51 | 52 | 1) Neither the Font Software nor any of its individual components, in 53 | Original or Modified Versions, may be sold by itself. 54 | 55 | 2) Original or Modified Versions of the Font Software may be bundled, 56 | redistributed and/or sold with any software, provided that each copy 57 | contains the above copyright notice and this license. These can be 58 | included either as stand-alone text files, human-readable headers or 59 | in the appropriate machine-readable metadata fields within text or 60 | binary files as long as those fields can be easily viewed by the user. 61 | 62 | 3) No Modified Version of the Font Software may use the Reserved Font 63 | Name(s) unless explicit written permission is granted by the 64 | corresponding Copyright Holder. This restriction only applies to the 65 | primary font name as presented to the users. 66 | 67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 68 | Software shall not be used to promote, endorse or advertise any 69 | Modified Version, except to acknowledge the contribution(s) of the 70 | Copyright Holder(s) and the Author(s) or with their explicit written 71 | permission. 72 | 73 | 5) The Font Software, modified or unmodified, in part or in whole, 74 | must be distributed entirely under this license, and must not be 75 | distributed under any other license. The requirement for fonts to 76 | remain under this license does not apply to any document created using 77 | the Font Software. 78 | 79 | TERMINATION 80 | This license becomes null and void if any of the above conditions are 81 | not met. 82 | 83 | DISCLAIMER 84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 92 | OTHER DEALINGS IN THE FONT SOFTWARE. 93 | -------------------------------------------------------------------------------- /Src/KGS/AutomatchPreferences.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 07.11.2016 9 | * Time 22:52 10 | */ 11 | 12 | function CKGSAutomatchPreferences() 13 | { 14 | this.m_nMaxHandicap = 6; 15 | this.m_sEstimadedRank = "27k"; 16 | this.m_bFree = true; 17 | this.m_bRanked = true; 18 | this.m_bRobot = true; 19 | this.m_bHuman = true; 20 | this.m_bUnranked = true; 21 | this.m_bBlitz = true; 22 | this.m_bMedium = true; 23 | this.m_bFast = true; 24 | } 25 | CKGSAutomatchPreferences.prototype.Parse = function(oMessage) 26 | { 27 | if (!oMessage) 28 | return; 29 | 30 | if (undefined !== oMessage["maxHandicap"]) 31 | this.m_nMaxHandicap = parseInt(oMessage["maxHandicap"]); 32 | 33 | if (undefined !== oMessage["estimatedRank"]) 34 | this.m_sEstimadedRank = oMessage["estimatedRank"]; 35 | 36 | if (undefined !== oMessage["freeOk"]) 37 | this.m_bFree = oMessage["freeOk"]; 38 | 39 | if (undefined !== oMessage["rankedOk"]) 40 | this.m_bRanked = oMessage["rankedOk"]; 41 | 42 | if (undefined !== oMessage["robotOk"]) 43 | this.m_bRobot = oMessage["robotOk"]; 44 | 45 | if (undefined !== oMessage["humanOk"]) 46 | this.m_bHuman = oMessage["humanOk"]; 47 | 48 | if (undefined !== oMessage["unrankedOk"]) 49 | this.m_bUnranked = oMessage["unrankedOk"]; 50 | 51 | if (undefined !== oMessage["blitzOk"]) 52 | this.m_bBlitz = oMessage["blitzOk"]; 53 | 54 | if (undefined !== oMessage["fastOk"]) 55 | this.m_bFast = oMessage["fastOk"]; 56 | 57 | if (undefined !== oMessage["mediumOk"]) 58 | this.m_bMedium = oMessage["mediumOk"]; 59 | }; 60 | CKGSAutomatchPreferences.prototype.CreateKGSMessage = function() 61 | { 62 | var oMessage = {}; 63 | 64 | oMessage["maxHandicap"] = this.m_nMaxHandicap; 65 | oMessage["estimatedRank"] = this.m_sEstimadedRank; 66 | oMessage["freeOk"] = this.m_bFree; 67 | oMessage["rankedOk"] = this.m_bRanked; 68 | oMessage["robotOk"] = this.m_bRobot; 69 | oMessage["humanOk"] = this.m_bHuman; 70 | oMessage["unrankedOk"] = this.m_bUnranked; 71 | oMessage["blitzOk"] = this.m_bBlitz; 72 | oMessage["fastOk"] = this.m_bFast; 73 | oMessage["mediumOk"] = this.m_bMedium; 74 | 75 | return oMessage; 76 | }; 77 | CKGSAutomatchPreferences.prototype.GetEstimatedRank = function() 78 | { 79 | return this.m_sEstimadedRank; 80 | }; 81 | CKGSAutomatchPreferences.prototype.GetMaxHandicap = function() 82 | { 83 | return this.m_nMaxHandicap; 84 | }; 85 | CKGSAutomatchPreferences.prototype.CanPlayFreeGames = function() 86 | { 87 | return this.m_bFree; 88 | }; 89 | CKGSAutomatchPreferences.prototype.CanPlayRankedGames = function() 90 | { 91 | return this.m_bRanked; 92 | }; 93 | CKGSAutomatchPreferences.prototype.CanPlayWithHuman = function() 94 | { 95 | return this.m_bHuman; 96 | }; 97 | CKGSAutomatchPreferences.prototype.CanPlayWithRobot = function() 98 | { 99 | return this.m_bRobot; 100 | }; 101 | CKGSAutomatchPreferences.prototype.CanPlayWithUnranked = function() 102 | { 103 | return this.m_bUnranked; 104 | }; 105 | CKGSAutomatchPreferences.prototype.CanPlayFast = function() 106 | { 107 | return this.m_bFast; 108 | }; 109 | CKGSAutomatchPreferences.prototype.CanPlayMedium = function() 110 | { 111 | return this.m_bMedium; 112 | }; 113 | CKGSAutomatchPreferences.prototype.CanPlayBlitz = function() 114 | { 115 | return this.m_bBlitz; 116 | }; 117 | CKGSAutomatchPreferences.prototype.SetEstimatedRank = function(sRank) 118 | { 119 | this.m_sEstimadedRank = sRank; 120 | }; 121 | CKGSAutomatchPreferences.prototype.SetMaxHandicap = function(nMax) 122 | { 123 | var _nMax = Math.max(0, Math.min(9, nMax)); 124 | this.m_nMaxHandicap = _nMax; 125 | }; 126 | CKGSAutomatchPreferences.prototype.SetFree = function(bValue) 127 | { 128 | this.m_bFree = bValue; 129 | }; 130 | CKGSAutomatchPreferences.prototype.SetRanked = function(bValue) 131 | { 132 | this.m_bRanked = bValue; 133 | }; 134 | CKGSAutomatchPreferences.prototype.SetMedium = function(bValue) 135 | { 136 | this.m_bMedium = bValue; 137 | }; 138 | CKGSAutomatchPreferences.prototype.SetFast = function(bValue) 139 | { 140 | this.m_bFast = bValue; 141 | }; 142 | CKGSAutomatchPreferences.prototype.SetBlitz = function(bValue) 143 | { 144 | this.m_bBlitz = bValue; 145 | }; 146 | CKGSAutomatchPreferences.prototype.SetHuman = function(bValue) 147 | { 148 | this.m_bHuman = bValue; 149 | }; 150 | CKGSAutomatchPreferences.prototype.SetRobot = function(bValue) 151 | { 152 | this.m_bRobot = bValue; 153 | }; 154 | CKGSAutomatchPreferences.prototype.SetUnranked = function(bValue) 155 | { 156 | this.m_bUnranked = bValue; 157 | }; -------------------------------------------------------------------------------- /Src/KGS/Windows/RoomInfo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 11.06.2016 9 | * Time 14:59 10 | */ 11 | 12 | function CKGSRoomInfoWindow() 13 | { 14 | CKGSRoomListWindow.superclass.constructor.call(this); 15 | 16 | this.m_oClient = null; 17 | this.m_oOwnerListView = new CListView(); 18 | this.m_nRoomId = -1; 19 | 20 | this.m_nInnerH = -1; 21 | this.m_nInnerW = -1; 22 | 23 | this.m_oFindInputElement = null; 24 | 25 | this.m_oInfoScroll = null; 26 | } 27 | CommonExtend(CKGSRoomInfoWindow, CKGSWindowBase); 28 | 29 | CKGSRoomInfoWindow.prototype.Init = function(sDivId, oPr) 30 | { 31 | CKGSRoomListWindow.superclass.Init.apply(this, arguments); 32 | 33 | this.m_nRoomId = oPr.RoomId; 34 | this.Set_Caption(g_oLocalization.KGS.window.roomInfo.caption + ": " + this.m_oClient.GetRoomName(oPr.RoomId)); 35 | 36 | var oMainDiv = this.HtmlElement.InnerDiv; 37 | var oMainControl = this.HtmlElement.InnerControl; 38 | 39 | oMainDiv.style.backgroundColor = "rgb(243, 243, 243)"; 40 | 41 | var oListControl = this.private_CreateOwnerList(oMainDiv); 42 | oListControl.Bounds.SetParams(0, 0, 0, 1000, false, false, true, false, 200, -1); 43 | oListControl.Anchor = (g_anchor_top |g_anchor_bottom | g_anchor_right); 44 | oListControl.HtmlElement.style.background = "#F3F3F3"; 45 | oMainControl.AddControl(oListControl); 46 | 47 | var oInfoControl = this.private_CreateInfoArea(oMainDiv); 48 | oInfoControl.Bounds.SetParams(5, 5, 205, 5, true, true, true, true, -1, -1); 49 | oInfoControl.Anchor = (g_anchor_top | g_anchor_bottom | g_anchor_right | g_anchor_left); 50 | oMainControl.AddControl(oInfoControl); 51 | 52 | this.Update_Size(true); 53 | this.Show(oPr); 54 | }; 55 | CKGSRoomInfoWindow.prototype.Update_Size = function(bForce) 56 | { 57 | CKGSRoomListWindow.superclass.Update_Size.call(this, bForce); 58 | 59 | var W = this.HtmlElement.InnerDiv.clientWidth; 60 | var H = this.HtmlElement.InnerDiv.clientHeight; 61 | 62 | if (true === bForce || Math.abs(W - this.m_nInnerW) > 0.001 || Math.abs(H - this.m_nInnerH) > 0.001) 63 | { 64 | this.m_nInnerW = W; 65 | this.m_nInnerH = H; 66 | this.m_oOwnerListView.Update(); 67 | this.m_oOwnerListView.Update_Size(); 68 | } 69 | 70 | if (this.m_oInfoScroll) 71 | this.m_oInfoScroll.CheckVisibility(); 72 | }; 73 | CKGSRoomInfoWindow.prototype.Get_DefaultWindowSize = function() 74 | { 75 | return {W : 700, H : 450}; 76 | }; 77 | CKGSRoomInfoWindow.prototype.private_CreateInfoArea = function(oParentDiv) 78 | { 79 | var oElement = document.createElement("div"); 80 | oElement.id = oParentDiv.id + "I"; 81 | oElement.style.position = "absolute"; 82 | oElement.style.border = "1px solid #BEBEBE"; 83 | oElement.style.background = "#F3F3F3"; 84 | oElement.className += " Selectable"; 85 | 86 | var oInfoArea = document.createElement("div"); 87 | oInfoArea.id = oElement.id + "I"; 88 | oInfoArea.style.position = "absolute"; 89 | oInfoArea.style.fontFamily = "'Segoe UI',Helvetica,Tahoma,Geneva,Verdana,sans-serif"; 90 | oInfoArea.style.fontSize = "14px"; 91 | oElement.appendChild(oInfoArea); 92 | oParentDiv.appendChild(oElement); 93 | 94 | var oControl = CreateControlContainer(oElement.id); 95 | 96 | var oAreaControl = CreateControlContainer(oInfoArea.id); 97 | oAreaControl.Bounds.SetParams(0, 0, 1000, 1000, false, false, false, false, -1, -1); 98 | oAreaControl.Anchor = (g_anchor_top | g_anchor_bottom | g_anchor_right | g_anchor_left); 99 | oControl.AddControl(oAreaControl); 100 | 101 | if (this.m_oClient) 102 | { 103 | var sRoomMessage = this.m_oClient.GetRoomGreetingMessage(this.m_nRoomId); 104 | 105 | var oDiv = oInfoArea; 106 | var oTextDiv = document.createElement("div"); 107 | oTextDiv.style.height = "100%"; 108 | var oTextSpan; 109 | 110 | var aLines = SplitTextToLines(sRoomMessage); 111 | for (var nIndex = 0, nCount = aLines.length; nIndex < nCount; ++nIndex) 112 | { 113 | oTextSpan = document.createElement("span"); 114 | oTextSpan.innerHTML = aLines[nIndex]; 115 | 116 | oTextDiv.appendChild(oTextSpan); 117 | oTextDiv.appendChild(document.createElement("br")); 118 | } 119 | 120 | ProcessUserLinks(oTextDiv, this.m_oClient); 121 | oDiv.appendChild(oTextDiv); 122 | 123 | this.m_oInfoScroll = new CVerticalScroll(); 124 | this.m_oInfoScroll.Init(oTextDiv, "VerScroll", "VerScrollActive", true); 125 | this.m_oInfoScroll.SetPaddings(-1, 0, 0); 126 | } 127 | 128 | return oControl; 129 | }; 130 | CKGSRoomInfoWindow.prototype.private_CreateOwnerList = function(oParentDiv) 131 | { 132 | var sListId = oParentDiv.id + "L"; 133 | var oListElement = this.protected_CreateDivElement(oParentDiv, sListId); 134 | this.m_oOwnerListView.Set_BGColor(243, 243, 243); 135 | var oListControl = this.m_oOwnerListView.Init(sListId, new CKGSPlayersList(this.m_oApp)); 136 | 137 | if (this.m_oClient) 138 | { 139 | var arrOwners = this.m_oClient.GetRoomOwners(this.m_nRoomId); 140 | 141 | for (var nIndex = 0, nCount = arrOwners.length; nIndex < nCount; ++nIndex) 142 | { 143 | var oUser = arrOwners[nIndex]; 144 | this.m_oOwnerListView.Handle_Record([0, oUser.GetName(), oUser.GetRank(), oUser.IsFriend(), oUser]); 145 | } 146 | } 147 | 148 | return oListControl; 149 | }; 150 | CKGSRoomInfoWindow.prototype.Close = function() 151 | { 152 | CKGSRoomInfoWindow.superclass.Close.call(this); 153 | RemoveWindow(this); 154 | }; -------------------------------------------------------------------------------- /Src/KGS/Windows/RoomList.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 03.06.2016 9 | * Time 22:53 10 | */ 11 | 12 | function CKGSRoomListWindow() 13 | { 14 | CKGSRoomListWindow.superclass.constructor.call(this); 15 | 16 | this.m_oClient = null; 17 | this.m_oRoomListView = new CListView(); 18 | this.m_oRoomListControl = null; 19 | 20 | this.m_nInnerH = -1; 21 | this.m_nInnerW = -1; 22 | 23 | this.m_oFindInputElement = null; 24 | } 25 | CommonExtend(CKGSRoomListWindow, CKGSWindowBase); 26 | 27 | CKGSRoomListWindow.prototype.Init = function(sDivId, oPr) 28 | { 29 | CKGSRoomListWindow.superclass.Init.apply(this, arguments); 30 | 31 | this.Set_Caption(g_oLocalization.KGS.window.roomsList.caption); 32 | 33 | var oMainDiv = this.HtmlElement.InnerDiv; 34 | var oMainControl = this.HtmlElement.InnerControl; 35 | 36 | oMainDiv.style.backgroundColor = "rgb(243, 243, 243)"; 37 | 38 | var sListId = sDivId + "L"; 39 | var oListElement = this.protected_CreateDivElement(oMainDiv, sListId); 40 | this.m_oRoomListView.Set_BGColor(243, 243, 243); 41 | var oListControl = this.m_oRoomListView.Init(sListId, new CKGSRoomList(this.m_oApp)); 42 | oListControl.Bounds.SetParams(0, 41, 0, 0, true, true, true, true, -1, -1); 43 | oListControl.Anchor = (g_anchor_left | g_anchor_top | g_anchor_bottom | g_anchor_right); 44 | oMainControl.AddControl(oListControl); 45 | this.m_oRoomListControl = oListControl; 46 | 47 | this.private_CreateFindInput(sDivId + "F", oMainDiv, oMainControl); 48 | 49 | if (oPr && oPr.Client) 50 | this.m_oClient = oPr.Client; 51 | 52 | this.Update_Size(true); 53 | this.Show(oPr); 54 | 55 | if (oPr.Text) 56 | { 57 | this.m_oFindInputElement.value = oPr.Text; 58 | this.private_OnInputChange(); 59 | } 60 | }; 61 | CKGSRoomListWindow.prototype.Show = function(oPr) 62 | { 63 | CKGSRoomListWindow.superclass.Show.call(this); 64 | 65 | if (this.m_oFindInputElement) 66 | { 67 | this.m_oFindInputElement.value = ""; 68 | this.m_oFindInputElement.focus(); 69 | } 70 | 71 | this.m_oRoomListView.Clear(); 72 | 73 | if (this.m_oClient) 74 | { 75 | var oRooms = this.m_oClient.GetAllRooms(); 76 | for (var nRoomId in oRooms) 77 | { 78 | var oRoom = oRooms[nRoomId]; 79 | if (oRoom.Name && "" !== oRoom.Name) 80 | this.m_oRoomListView.Handle_Record([0, oRoom.ChannelId, oRoom.Name, this.m_oClient.GetCategoryName(oRoom.Category), oRoom.Private]); 81 | } 82 | 83 | } 84 | 85 | this.m_oRoomListView.Update(); 86 | this.m_oRoomListView.Update_Size(); 87 | 88 | if (oPr.Text) 89 | { 90 | this.m_oFindInputElement.value = oPr.Text; 91 | this.private_OnInputChange(); 92 | } 93 | }; 94 | CKGSRoomListWindow.prototype.Update_Size = function(bForce) 95 | { 96 | CKGSRoomListWindow.superclass.Update_Size.call(this, bForce); 97 | 98 | var W = this.HtmlElement.InnerDiv.clientWidth; 99 | var H = this.HtmlElement.InnerDiv.clientHeight; 100 | 101 | if (true === bForce || Math.abs(W - this.m_nInnerW) > 0.001 || Math.abs(H - this.m_nInnerH) > 0.001) 102 | { 103 | this.m_nInnerW = W; 104 | this.m_nInnerH = H; 105 | this.m_oRoomListView.Update(); 106 | this.m_oRoomListView.Update_Size(); 107 | } 108 | }; 109 | CKGSRoomListWindow.prototype.Get_DefaultWindowSize = function() 110 | { 111 | return {W : 410, H : 670}; 112 | }; 113 | CKGSRoomListWindow.prototype.private_CreateFindInput = function(sInputId, oParentDiv, oParentControl) 114 | { 115 | var oFindInput = document.createElement("input"); 116 | oFindInput.setAttribute("id", sInputId); 117 | oFindInput.setAttribute("style", "position:absolute;padding:0;margin:0;"); 118 | oFindInput.setAttribute("oncontextmenu", "return false;"); 119 | 120 | oFindInput.type = "text"; 121 | oFindInput.maxLength = "256"; 122 | oFindInput["aria-label"] = g_oLocalization.KGS.window.roomsList.searchPlaceholder; 123 | oFindInput["placeholder"] = g_oLocalization.KGS.window.roomsList.searchPlaceholder; 124 | 125 | oFindInput.className += " inputKGSWindow"; 126 | oFindInput.style.padding = "0px 6px 0px 6px"; 127 | 128 | oParentDiv.appendChild(oFindInput); 129 | 130 | var oFindControl = CreateControlContainer(sInputId); 131 | oFindControl.Bounds.SetParams(5, 2, 5, -1, true, true, true, false, -1, 37); 132 | oFindControl.Anchor = (g_anchor_left | g_anchor_top | g_anchor_right); 133 | oParentControl.AddControl(oFindControl); 134 | 135 | var oThis = this; 136 | 137 | oFindInput.addEventListener("input", function() 138 | { 139 | oThis.private_OnInputChange(); 140 | }); 141 | 142 | this.m_oFindInputElement = oFindInput; 143 | }; 144 | CKGSRoomListWindow.prototype.private_OnInputChange = function() 145 | { 146 | var oClient = this.m_oClient; 147 | var oRoomListView = this.m_oRoomListView; 148 | 149 | if (!oClient || !oRoomListView) 150 | return; 151 | 152 | var sValue = this.m_oFindInputElement.value; 153 | var oRooms = oClient.GetAllRooms(); 154 | oRoomListView.Clear(); 155 | if ("" === sValue) 156 | { 157 | for (var nRoomId in oRooms) 158 | { 159 | var oRoom = oRooms[nRoomId]; 160 | if (oRoom.Name && "" !== oRoom.Name) 161 | oRoomListView.Handle_Record([0, oRoom.ChannelId, oRoom.Name, oRoom.CategoryName, oRoom.Private]); 162 | } 163 | } 164 | else 165 | { 166 | for (var nRoomId in oRooms) 167 | { 168 | var oRoom = oRooms[nRoomId]; 169 | if (oRoom.Name && "" !== oRoom.Name && -1 !== oRoom.Name.toLowerCase().indexOf(sValue.toLowerCase())) 170 | oRoomListView.Handle_Record([0, oRoom.ChannelId, oRoom.Name, oRoom.CategoryName, oRoom.Private]); 171 | } 172 | } 173 | 174 | oRoomListView.Update(); 175 | oRoomListView.Update_Size(); 176 | }; 177 | -------------------------------------------------------------------------------- /Src/Common/VerticalScroll.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 24.06.2016 9 | * Time 0:45 10 | */ 11 | 12 | function CVerticalScroll() 13 | { 14 | this.m_oDiv = null; 15 | this.m_oScrollDiv = null; 16 | 17 | this.m_sNormalClass = ""; 18 | this.m_sActiveClass = ""; 19 | 20 | this.m_nScrollW = 15; // 14 + Border (1) 21 | 22 | this.m_nTop = 0; 23 | this.m_nBottom = 0; 24 | this.m_nRight = 0; 25 | 26 | this.m_bAddPadding = false; 27 | 28 | var oThis = this; 29 | this.m_fOnScroll = function(e) 30 | { 31 | return oThis.private_OnScroll(e); 32 | }; 33 | 34 | this.m_nElementHeight = 0; 35 | this.m_bStopPropagation = false; 36 | } 37 | CVerticalScroll.prototype.Init = function(oDiv, sNormalClass, sActiveClass, bAddPaddingsOnShow) 38 | { 39 | this.m_sNormalClass = sNormalClass; 40 | this.m_sActiveClass = sActiveClass; 41 | this.m_oDiv = oDiv; 42 | this.m_bAddPadding = bAddPaddingsOnShow; 43 | 44 | var oParent = oDiv.parentNode; 45 | if (!oParent) 46 | return; 47 | 48 | var oScroll = document.createElement("div"); 49 | oParent.insertBefore(oScroll, oDiv.nextSibling); 50 | 51 | oScroll.style.display = "block"; 52 | oScroll.style.position = "absolute"; 53 | oScroll.style.top = "0px"; 54 | oScroll.style.left = "0px"; 55 | oScroll.style.width = "14px"; 56 | oScroll.style.height = "50px"; 57 | oScroll.className = sNormalClass; 58 | 59 | this.m_oScrollDiv = oScroll; 60 | 61 | oScroll.style.display = "none"; 62 | }; 63 | CVerticalScroll.prototype.SetPaddings = function(nTop, nBottom, nRight) 64 | { 65 | this.m_nTop = nTop; 66 | this.m_nBottom = nBottom; 67 | this.m_nRight = nRight; 68 | }; 69 | CVerticalScroll.prototype.Show = function(nElementHeight) 70 | { 71 | this.m_nElementHeight = nElementHeight; 72 | 73 | var oDiv = this.m_oDiv; 74 | var oVerScroll = this.m_oScrollDiv; 75 | 76 | if (true === this.m_bAddPadding) 77 | oDiv.style.paddingRight = this.m_nScrollW + 2; 78 | 79 | // sa - scroll area, va - visible area, pa - physical area 80 | var vaH = parseFloat(nElementHeight); 81 | var saY = this.m_nTop; 82 | var paH = parseFloat(oDiv.scrollHeight); 83 | var paY = parseFloat(oDiv.scrollTop); 84 | var saH = vaH - saY - this.m_nBottom; 85 | 86 | var sH = Math.max(20, ((vaH - saY) * vaH / paH)) | 0; 87 | var sY = Math.max(saY, Math.min(saY + saH - sH + 1, saY + paY * (saH - sH) / (paH - vaH))); 88 | var sX = parseFloat(oDiv.clientWidth + oDiv.offsetLeft) - this.m_nScrollW - this.m_nRight; 89 | 90 | oVerScroll.style.display = "block"; 91 | oVerScroll.style.height = sH + "px"; 92 | oVerScroll.style.top = (sY + oDiv.offsetTop) + "px"; 93 | oVerScroll.style.left = sX + "px"; 94 | 95 | var oThis = this; 96 | Common_DragHandler.Init(oVerScroll, null, sX, sX, saY + oDiv.offsetTop, saY + saH - sH + oDiv.offsetTop); 97 | oVerScroll.onDrag = function(sX, sY) 98 | { 99 | sY -= oDiv.offsetTop; 100 | oDiv.scrollTop = (sY - saY) * (paH - vaH) / (saH - sH); 101 | }; 102 | oVerScroll.onDragStart = function(sX, sY) 103 | { 104 | oVerScroll.className = oThis.m_sNormalClass + " " + oThis.m_sActiveClass; 105 | }; 106 | oVerScroll.onDragEnd = function(sX, sY) 107 | { 108 | oVerScroll.className = oThis.m_sNormalClass; 109 | }; 110 | oVerScroll.onclick = function(e) 111 | { 112 | if (oThis && oThis.m_bStopPropagation) 113 | { 114 | e.stopPropagation(); 115 | return false; 116 | } 117 | }; 118 | 119 | oVerScroll.addEventListener("DOMMouseScroll", this.m_fOnScroll, false); 120 | oVerScroll.addEventListener("mousewheel", this.m_fOnScroll, false); 121 | 122 | oDiv.addEventListener("DOMMouseScroll", this.m_fOnScroll, false); 123 | oDiv.addEventListener("mousewheel", this.m_fOnScroll, false); 124 | }; 125 | CVerticalScroll.prototype.Hide = function() 126 | { 127 | this.m_nElementHeight = 0; 128 | this.m_oScrollDiv.style.display = "none"; 129 | 130 | if (true === this.m_bAddPadding) 131 | this.m_oDiv.style.paddingRight = 0; 132 | 133 | this.m_oDiv.removeEventListener("DOMMouseScroll", this.m_fOnScroll, false); 134 | this.m_oDiv.removeEventListener("mousewheel", this.m_fOnScroll, false); 135 | }; 136 | CVerticalScroll.prototype.IsHidden = function() 137 | { 138 | return ("none" === this.m_oScrollDiv.style.display ? true : false); 139 | }; 140 | CVerticalScroll.prototype.CheckVisibility = function(bScrollBottomOnShow) 141 | { 142 | var oDiv = this.m_oDiv; 143 | if (oDiv.scrollHeight > oDiv.clientHeight) 144 | { 145 | var bHidden = this.IsHidden(); 146 | 147 | this.Show(oDiv.clientHeight); 148 | 149 | if (true === bHidden && true === bScrollBottomOnShow) 150 | this.m_oDiv.scrollTop = this.m_oDiv.clientHeight; 151 | } 152 | else 153 | { 154 | this.Hide(); 155 | } 156 | }; 157 | CVerticalScroll.prototype.private_OnScroll = function(e) 158 | { 159 | if (this.m_nElementHeight <= 1) 160 | { 161 | if (true === this.m_bStopPropagation) 162 | { 163 | e.stopPropagation(); 164 | return false; 165 | } 166 | return; 167 | } 168 | 169 | var delta = 0; 170 | if (undefined != e.wheelDelta && e.wheelDelta != 0) 171 | { 172 | delta = -45 * e.wheelDelta / 120; 173 | } 174 | else if (undefined != e.detail && e.detail != 0) 175 | { 176 | delta = 45 * e.detail / 3; 177 | } 178 | 179 | this.m_oDiv.scrollTop += delta; 180 | 181 | this.UpdatePosition(); 182 | 183 | if (true === this.m_bStopPropagation) 184 | { 185 | e.stopPropagation(); 186 | return false; 187 | } 188 | }; 189 | CVerticalScroll.prototype.UpdatePosition = function() 190 | { 191 | var oDiv = this.m_oDiv; 192 | var oVerScroll = this.m_oScrollDiv; 193 | 194 | var vaH = parseFloat(this.m_nElementHeight); 195 | var saY = this.m_nTop; 196 | var paH = parseFloat(oDiv.scrollHeight); 197 | var paY = parseFloat(oDiv.scrollTop); 198 | var saH = vaH - saY - this.m_nBottom; 199 | 200 | var sH = Math.max(20, ((vaH - saY) * vaH / paH)) | 0; 201 | var sY = Math.max(saY, Math.min(saY + saH - sH + 1, saY + paY * (saH - sH) / (paH - vaH))); 202 | 203 | oVerScroll.style.top = (sY + oDiv.offsetTop) + "px"; 204 | }; 205 | CVerticalScroll.prototype.CopyPosition = function(oOtherScroll) 206 | { 207 | this.m_oDiv.scrollTop = oOtherScroll.m_oDiv.scrollTop; 208 | this.UpdatePosition(); 209 | }; 210 | CVerticalScroll.prototype.SetStopPropagation = function(isStop) 211 | { 212 | this.m_bStopPropagation = isStop; 213 | }; -------------------------------------------------------------------------------- /Src/KGS/PlayersList.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * User: Ilja.Kirillov 4 | * Date: 26.09.14 5 | * Time: 18:03 6 | */ 7 | 8 | var EKGSPlayersListRecord = { 9 | Name : 1, 10 | Rank : 2 11 | }; 12 | 13 | function CKGSPlayersList(oApp) 14 | { 15 | CKGSPlayersList.superclass.constructor.call(this); 16 | 17 | this.m_oHeaders = { 18 | Sizes : [0, 105], 19 | Count : 2, 20 | 1 : g_oLocalization.mainRoom.playersList.listHeaderName, 21 | 2 : g_oLocalization.mainRoom.playersList.listHeaderRank 22 | }; 23 | 24 | this.m_nSortType = -EKGSPlayersListRecord.Rank; 25 | this.m_oApp = oApp; 26 | } 27 | 28 | CommonExtend(CKGSPlayersList, CListBase); 29 | 30 | CKGSPlayersList.prototype.private_Sort = function (oRecord1, oRecord2) 31 | { 32 | var SortType = this.m_nSortType; 33 | if (EKGSPlayersListRecord.Name === SortType) 34 | { 35 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 36 | return -1; 37 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 38 | return 1; 39 | } 40 | else if (-EKGSPlayersListRecord.Name === SortType) 41 | { 42 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 43 | return 1; 44 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 45 | return -1; 46 | } 47 | else if (EKGSPlayersListRecord.Rank === SortType) 48 | { 49 | if (oRecord1.m_nRank < oRecord2.m_nRank) 50 | return -1; 51 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 52 | return 1; 53 | } 54 | else if (-EKGSPlayersListRecord.Rank === SortType) 55 | { 56 | if (oRecord1.m_nRank < oRecord2.m_nRank) 57 | return 1; 58 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 59 | return -1; 60 | } 61 | 62 | return 0; 63 | }; 64 | CKGSPlayersList.prototype.private_PreSort = function(oRecord1, oRecord2) 65 | { 66 | if (true === oRecord1.IsFriend() && true !== oRecord2.IsFriend()) 67 | return -1; 68 | 69 | if (true !== oRecord1.IsFriend() && true === oRecord2.IsFriend()) 70 | return 1; 71 | 72 | return 0; 73 | }; 74 | CKGSPlayersList.prototype.private_PostSort = function(oRecord1, oRecord2) 75 | { 76 | // Сортируем по рейтингу, потом по имени 77 | if (oRecord1.m_nRank < oRecord2.m_nRank) 78 | return 1; 79 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 80 | return -1; 81 | 82 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 83 | return -1; 84 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 85 | return 1; 86 | 87 | // Сюда мы уже не должны попадать, потому что имена игроков не должны совпадать 88 | return 0; 89 | }; 90 | CKGSPlayersList.prototype.Get_Record = function(aLine) 91 | { 92 | var oRecord = new CKGSPlayersListRecord(this.m_oApp.GetClient()); 93 | oRecord.Update(aLine); 94 | return oRecord; 95 | }; 96 | CKGSPlayersList.prototype.Handle_DoubleClick = function(Record) 97 | { 98 | if (this.m_oApp && this.m_oApp.GetClient()) 99 | { 100 | this.m_oApp.GetClient().EnterPrivateChat(Record.m_sName); 101 | } 102 | }; 103 | CKGSPlayersList.prototype.Handle_RightClick = function(Record, e) 104 | { 105 | if (this.m_oApp && Record) 106 | { 107 | return this.m_oApp.ShowUserContextMenu(e.pageX, e.pageY, Record.m_sName); 108 | } 109 | }; 110 | 111 | function CKGSPlayersListRecord(oClient) 112 | { 113 | CKGSPlayersListRecord.superclass.constructor.call(this); 114 | 115 | this.m_oClient = oClient; 116 | this.m_sName = ""; 117 | this.m_nRank = 0; 118 | this.m_oUser = null; 119 | } 120 | 121 | CommonExtend(CKGSPlayersListRecord, CListRecordBase); 122 | 123 | CKGSPlayersListRecord.prototype.Draw = function(oContext, dX, dY, eType) 124 | { 125 | var oClient = this.m_oClient; 126 | var sFont = oContext.font; 127 | 128 | 129 | if (true !== this.m_oUser.IsSleeping()) 130 | oContext.fillStyle = "#000000"; 131 | else 132 | oContext.fillStyle = "#AAAAAA"; 133 | 134 | var bResetFont = false; 135 | if (oClient) 136 | { 137 | if (true === oClient.IsUserInFollowerList(this.m_sName)) 138 | { 139 | if (true !== this.m_oUser.IsSleeping()) 140 | oContext.fillStyle = "#008272"; 141 | else 142 | oContext.fillStyle = "#99C9C3"; 143 | 144 | oContext.font = "bold " + sFont; 145 | } 146 | else if (true === this.m_oUser.IsFriend()) 147 | { 148 | oContext.font = "bold " + sFont; 149 | } 150 | 151 | bResetFont = true; 152 | } 153 | 154 | var sString = ""; 155 | switch(eType) 156 | { 157 | case EKGSPlayersListRecord.Name : sString += this.m_sName; break; 158 | case EKGSPlayersListRecord.Rank : sString += this.private_GetRank(this.m_nRank); break; 159 | } 160 | 161 | oContext.fillText(sString, dX, dY); 162 | 163 | if (oClient) 164 | { 165 | if (true === oClient.IsUserInBlackList(this.m_sName) && eType === EKGSPlayersListRecord.Name) 166 | { 167 | var dOldLineWidth = oContext.lineWidth; 168 | var sOldStrokeStyle = oContext.strokeStyle; 169 | 170 | oContext.lineWidth = 1; 171 | oContext.strokeStyle = "#000"; 172 | 173 | var dTextW = oContext.measureText(sString).width; 174 | var dX0 = (dX | 0) + 0.5; 175 | var dY0 = ((dY - 4) | 0) + 0.5; 176 | var dX1 = ((dX + dTextW) | 0) + 0.5; 177 | 178 | oContext.beginPath(); 179 | oContext.moveTo(dX0, dY0); 180 | oContext.lineTo(dX1, dY0); 181 | oContext.stroke(); 182 | 183 | oContext.lineWidth = dOldLineWidth; 184 | oContext.strokeStyle = sOldStrokeStyle; 185 | } 186 | } 187 | 188 | if (true === bResetFont) 189 | oContext.font = sFont; 190 | }; 191 | CKGSPlayersListRecord.prototype.Get_Key = function() 192 | { 193 | return this.m_sName; 194 | }; 195 | CKGSPlayersListRecord.prototype.Update = function(aLine) 196 | { 197 | this.m_sName = aLine[1]; 198 | this.m_nRank = aLine[2] | 0; 199 | this.m_oUser = aLine[4]; 200 | }; 201 | CKGSPlayersListRecord.prototype.Compare = function(sName) 202 | { 203 | if (this.m_sName === sName) 204 | return true; 205 | 206 | return false; 207 | }; 208 | CKGSPlayersListRecord.prototype.private_GetRank = function(nRank) 209 | { 210 | if (nRank <= -2) 211 | return "?"; 212 | else if (nRank === -1) 213 | return "-"; 214 | else if (nRank <= 29) 215 | return (30 - nRank) + "k"; 216 | else if (nRank <= 49) 217 | return (nRank - 29) + "d"; 218 | else 219 | return (nRank - 49) + "p"; 220 | }; 221 | CKGSPlayersListRecord.prototype.IsFriend = function() 222 | { 223 | if (oApp && oApp.GetClient()) 224 | return oApp.GetClient().IsUserInFriendList(this.m_sName); 225 | 226 | return false; 227 | }; -------------------------------------------------------------------------------- /Src/KGS/User.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 19.06.2016 9 | * Time 17:16 10 | */ 11 | 12 | var KGSUSER_FLAGS_GUEST = 0x00000001; // 0 бит 13 | var KGSUSER_FLAGS_ONLINE = 0x00000002; // 0 бит 14 | var KGSUSER_FLAGS_DELETED = 0x00000004; 15 | var KGSUSER_FLAGS_SLEEPING = 0x00000008; 16 | var KGSUSER_FLAGS_AVATAR = 0x00000010; 17 | var KGSUSER_FLAGS_ROBOT = 0x00000020; 18 | var KGSUSER_FLAGS_WINNER = 0x00000040; 19 | var KGSUSER_FLAGS_RUNNERUP = 0x00000080; 20 | var KGSUSER_FLAGS_PLAYING = 0x00000100; 21 | var KGSUSER_FLAGS_PLAYING_T = 0x00000200; 22 | var KGSUSER_FLAGS_KGSPLUS = 0x00000400; 23 | var KGSUSER_FLAGS_MEIJIN = 0x00000800; 24 | var KGSUSER_FLAGS_RANKED = 0x00001000; 25 | var KGSUSER_FLAGS_TILDE = 0x00002000; 26 | 27 | var KGSUSER_LEVEL_USER = 0x01; 28 | var KGSUSER_LEVEL_ROBOT = 0x02; 29 | var KGSUSER_LEVEL_TEACHER = 0x04; 30 | var KGSUSER_LEVEL_JR_ADMIN = 0x08; 31 | var KGSUSER_LEVEL_SR_ADMIN = 0x10; 32 | var KGSUSER_LEVEL_SUPER_ADMIN = 0x20; 33 | 34 | function CKGSUser(oClient) 35 | { 36 | this.m_oClient = oClient; 37 | 38 | this.m_sName = ""; 39 | this.m_nRank = -2; 40 | this.m_nFlags = 0x00000000; 41 | this.m_nLevel = KGSUSER_LEVEL_USER; 42 | } 43 | 44 | CKGSUser.prototype.GetName = function() 45 | { 46 | return this.m_sName; 47 | }; 48 | CKGSUser.prototype.GetRank = function() 49 | { 50 | return this.m_nRank; 51 | }; 52 | CKGSUser.prototype.GetStringRank = function() 53 | { 54 | return this.m_oClient.GetStringRank(this.m_nRank); 55 | }; 56 | CKGSUser.prototype.IsFriend = function() 57 | { 58 | return this.m_oClient.IsUserInFriendList(this.m_sName); 59 | }; 60 | CKGSUser.prototype.Update = function(oUserRecord) 61 | { 62 | if (oUserRecord.name) 63 | this.m_sName = oUserRecord.name; 64 | 65 | this.m_nRank = this.m_oClient.GetRank(oUserRecord.rank); 66 | 67 | if (oUserRecord.flags) 68 | this.private_ParseFlags(oUserRecord.flags); 69 | else 70 | this.private_ParseFlags(""); 71 | 72 | if (oUserRecord.authLevel) 73 | this.private_ParseLevel(oUserRecord.authLevel); 74 | }; 75 | CKGSUser.prototype.IsRankHided = function() 76 | { 77 | return (this.GetRank() === -1); 78 | }; 79 | CKGSUser.prototype.IsTeacher = function() 80 | { 81 | return (this.m_nLevel === KGSUSER_LEVEL_TEACHER ? true : false); 82 | }; 83 | CKGSUser.prototype.IsAdmin = function() 84 | { 85 | return ((this.m_nLevel === KGSUSER_LEVEL_JR_ADMIN || this.m_nLevel === KGSUSER_LEVEL_SR_ADMIN || this.m_nLevel === KGSUSER_LEVEL_SUPER_ADMIN) ? true : false); 86 | }; 87 | CKGSUser.prototype.IsGuest = function() 88 | { 89 | return (this.m_nFlags & KGSUSER_FLAGS_GUEST ? true : false); 90 | }; 91 | CKGSUser.prototype.IsOnline = function() 92 | { 93 | return (this.m_nFlags & KGSUSER_FLAGS_ONLINE? true : false); 94 | }; 95 | CKGSUser.prototype.IsDeleted = function() 96 | { 97 | return (this.m_nFlags & KGSUSER_FLAGS_DELETED? true : false); 98 | }; 99 | CKGSUser.prototype.IsSleeping = function() 100 | { 101 | return (this.m_nFlags & KGSUSER_FLAGS_SLEEPING ? true : false); 102 | }; 103 | CKGSUser.prototype.HasAvatar = function() 104 | { 105 | return (this.m_nFlags & KGSUSER_FLAGS_AVATAR ? true : false); 106 | }; 107 | CKGSUser.prototype.IsRobot = function() 108 | { 109 | return (this.m_nFlags & KGSUSER_FLAGS_ROBOT ? true : false); 110 | }; 111 | CKGSUser.prototype.IsTournamentWinner = function() 112 | { 113 | return (this.m_nFlags & KGSUSER_FLAGS_WINNER ? true : false); 114 | }; 115 | CKGSUser.prototype.IsTournamentRunnerup = function() 116 | { 117 | return (this.m_nFlags & KGSUSER_FLAGS_RUNNERUP ? true : false); 118 | }; 119 | CKGSUser.prototype.IsPlaying = function() 120 | { 121 | return (((this.m_nFlags & KGSUSER_FLAGS_PLAYING) || (this.m_nFlags & KGSUSER_FLAGS_PLAYING_T)) ? true : false); 122 | }; 123 | CKGSUser.prototype.IsKgsPlusSubscriber = function() 124 | { 125 | return (this.m_nFlags & KGSUSER_FLAGS_KGSPLUS ? true : false); 126 | }; 127 | CKGSUser.prototype.IsMeijin = function() 128 | { 129 | return (this.m_nFlags & KGSUSER_FLAGS_MEIJIN ? true : false); 130 | }; 131 | CKGSUser.prototype.CanPlayRanked = function() 132 | { 133 | return (this.m_nFlags & KGSUSER_FLAGS_RANKED ? true : false); 134 | }; 135 | CKGSUser.prototype.IsTilde = function() 136 | { 137 | return (this.m_nFlags & KGSUSER_FLAGS_TILDE ? true : false); 138 | }; 139 | CKGSUser.prototype.private_ParseFlags = function(sFlags) 140 | { 141 | // Flags 142 | // g Guest 143 | // c Connected (logged in right now) 144 | // d Account has been deleted 145 | // s User is sleeping (more than 10 minutes since last interaction) 146 | // a User has an avatar. 147 | // r User is a robot. 148 | // T User has won a KGS tournament. 149 | // t User has been runner up in a KGS tournament. 150 | // p User is currently playing in a game. 151 | // P User is currently playing in a KGS tournament game. 152 | // * User is a KGS Plus subscriber. 153 | // ! User is KGS Meijin 154 | // = User can play ranked games. 155 | // ~ User plays stronger players far more often that weaker ones. 156 | 157 | this.m_nFlags = 0x00000000; 158 | for (var nPos = 0, nLength = sFlags.length; nPos < nLength; ++nPos) 159 | { 160 | var nChar = sFlags.charAt(nPos); 161 | if ('g' === nChar) 162 | this.m_nFlags |= KGSUSER_FLAGS_GUEST; 163 | else if ('c' === nChar) 164 | this.m_nFlags |= KGSUSER_FLAGS_ONLINE; 165 | else if ('d' === nChar) 166 | this.m_nFlags |= KGSUSER_FLAGS_DELETED; 167 | else if ('s' === nChar) 168 | this.m_nFlags |= KGSUSER_FLAGS_SLEEPING; 169 | else if ('a' === nChar) 170 | this.m_nFlags |= KGSUSER_FLAGS_AVATAR; 171 | else if ('r' === nChar) 172 | this.m_nFlags |= KGSUSER_FLAGS_ROBOT; 173 | else if ('T' === nChar) 174 | this.m_nFlags |= KGSUSER_FLAGS_WINNER; 175 | else if ('t' === nChar) 176 | this.m_nFlags |= KGSUSER_FLAGS_RUNNERUP; 177 | else if ('p' === nChar) 178 | this.m_nFlags |= KGSUSER_FLAGS_PLAYING; 179 | else if ('P' === nChar) 180 | this.m_nFlags |= KGSUSER_FLAGS_PLAYING_T; 181 | else if ('*' === nChar) 182 | this.m_nFlags |= KGSUSER_FLAGS_KGSPLUS; 183 | else if ('!' === nChar) 184 | this.m_nFlags |= KGSUSER_FLAGS_MEIJIN; 185 | else if ('=' === nChar) 186 | this.m_nFlags |= KGSUSER_FLAGS_RANKED; 187 | else if ('~' === nChar) 188 | this.m_nFlags |= KGSUSER_FLAGS_TILDE; 189 | } 190 | }; 191 | CKGSUser.prototype.private_ParseLevel = function(sLevel) 192 | { 193 | if ("robot_ranked" === sLevel) 194 | this.m_nLevel = KGSUSER_LEVEL_ROBOT; 195 | else if ("teacher" === sLevel) 196 | this.m_nLevel = KGSUSER_LEVEL_TEACHER; 197 | else if ("jr_admin" === sLevel) 198 | this.m_nLevel = KGSUSER_LEVEL_JR_ADMIN; 199 | else if ("sr_admin" === sLevel) 200 | this.m_nLevel = KGSUSER_LEVEL_SR_ADMIN; 201 | else if ("super_admin" === sLevel) 202 | this.m_nLevel = KGSUSER_LEVEL_SUPER_ADMIN; 203 | else //if ("normal" === sLevel) 204 | this.m_nLevel = KGSUSER_LEVEL_USER; 205 | }; 206 | 207 | function GetKGSUser(oUserRecord, oClient) 208 | { 209 | var oUser = new CKGSUser(oClient ? oClient : oApp.GetClient()); 210 | oUser.Update(oUserRecord); 211 | return oUser; 212 | } 213 | -------------------------------------------------------------------------------- /Src/Common/AboutWindow.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 07.07.2016 9 | * Time 2:05 10 | */ 11 | 12 | function CGoUniverseAboutWindow() 13 | { 14 | CGoUniverseAboutWindow.superclass.constructor.call(this); 15 | 16 | this.m_oApp = null; 17 | } 18 | CommonExtend(CGoUniverseAboutWindow, CDrawingWindow); 19 | 20 | CGoUniverseAboutWindow.prototype.Init = function(sDivId, oPr) 21 | { 22 | CGoUniverseAboutWindow.superclass.Init.call(this, sDivId, false); 23 | 24 | this.Set_Caption(g_oLocalization.common.about.caption); 25 | 26 | this.m_oApp = oPr.App; 27 | 28 | var oMainDiv = this.HtmlElement.InnerDiv; 29 | var oMainControl = this.HtmlElement.InnerControl; 30 | 31 | this.private_InitAboutPage(oMainDiv); 32 | 33 | this.private_UpdatePosition(); 34 | this.Update_Size(true); 35 | }; 36 | CGoUniverseAboutWindow.prototype.Get_DefaultWindowSize = function() 37 | { 38 | if (undefined !== g_oLocalization.common.about.translatedBy) 39 | return {W : 392, H : 264 + 40}; 40 | 41 | return {W : 392, H : 264}; 42 | }; 43 | CGoUniverseAboutWindow.prototype.Close = function() 44 | { 45 | CGoUniverseAboutWindow.superclass.Close.call(this); 46 | RemoveWindow(this); 47 | }; 48 | CGoUniverseAboutWindow.prototype.private_InitAboutPage = function(oDiv) 49 | { 50 | var oDivMainPart = document.createElement("div"); 51 | oDiv.appendChild(oDivMainPart); 52 | 53 | oDiv.style.overflowX = "hidden"; 54 | oDiv.style.overflowY = "hidden"; 55 | 56 | oDivMainPart.style.margin = "0"; 57 | oDivMainPart.style.padding = "10px 20px"; 58 | 59 | oDivMainPart.style.fontFamily = "Tahoma, Arial, Verdana"; 60 | oDivMainPart.style.fontSize = "12px"; 61 | oDivMainPart.style.color = "#666"; 62 | oDivMainPart.style.background = "#fff"; 63 | 64 | var oLogo = document.createElement("img"); 65 | oLogo.src = "Files/icon100.png"; 66 | oLogo.width = 100; 67 | oLogo.height = 100; 68 | oLogo.style['float'] = "left"; 69 | oDivMainPart.appendChild(oLogo); 70 | 71 | var oMargin = document.createElement("div"); 72 | oMargin.style.width = "10px"; 73 | oMargin.style.height = "100px"; 74 | oMargin.style['float'] = "left"; 75 | oDivMainPart.appendChild(oMargin); 76 | 77 | var oHeading = document.createElement("h1"); 78 | oHeading.style.marginLeft = "110px"; 79 | oDivMainPart.appendChild(oHeading); 80 | Common.Set_InnerTextToElement(oHeading, "Go Universe"); 81 | 82 | var oVersion = document.createElement("div"); 83 | oVersion.style.marginLeft = "110px"; 84 | oDivMainPart.appendChild(oVersion); 85 | Common.Set_InnerTextToElement(oVersion, g_oLocalization.common.about.version + " " + this.m_oApp.GetVersion()); 86 | 87 | var oString = document.createElement("div"); 88 | oString.style.marginLeft = "110px"; 89 | oString.style.paddingTop = "20px"; 90 | oDivMainPart.appendChild(oString); 91 | Common.Set_InnerTextToElement(oString, g_oLocalization.common.about.visitMessage); 92 | oString = document.createElement("a"); 93 | oString.style.marginLeft = "110px"; 94 | oString.target = "_blank"; 95 | oString.href = "https://github.com/IlyaKirillov/GoUniverse"; 96 | oDivMainPart.appendChild(oString); 97 | Common.Set_InnerTextToElement(oString, "https://github.com/IlyaKirillov/GoUniverse"); 98 | 99 | if (undefined !== g_oLocalization.common.about.translatedBy) 100 | { 101 | oString = document.createElement("div"); 102 | oString.style.marginLeft = "110px"; 103 | oString.style.paddingTop = "20px"; 104 | oDivMainPart.appendChild(oString); 105 | Common.Set_InnerTextToElement(oString, g_oLocalization.common.about.translatedBy); 106 | } 107 | 108 | oString = document.createElement("div"); 109 | oString.style.paddingTop = "30px"; 110 | oDivMainPart.appendChild(oString); 111 | Common.Set_InnerTextToElement(oString, "© Ilya Kirillov, 2016-2020. " + g_oLocalization.common.about.allRightReserved); 112 | 113 | var oDiv = document.createElement("div"); 114 | oDiv.innerHTML = '
\ 115 | \ 116 | \ 118 | \ 120 | \ 121 |
'; 122 | oDiv.style.paddingLeft = "123px"; 123 | oDiv.style.paddingTop = "20px"; 124 | oDivMainPart.appendChild(oDiv); 125 | }; 126 | CGoUniverseAboutWindow.prototype.private_UpdatePosition = function() 127 | { 128 | if (!this.m_oApp) 129 | return; 130 | 131 | var oWindowDiv = this.HtmlElement.Control.HtmlElement; 132 | 133 | var nWindowW = parseInt(oWindowDiv.style.width); 134 | var nWindowH = parseInt(oWindowDiv.style.height); 135 | 136 | var nX = Math.max(0, ((this.m_oApp.GetWidth() - nWindowW) / 2)); 137 | var nY = Math.max(0, ((this.m_oApp.GetHeight() - nWindowH) / 2)); 138 | 139 | oWindowDiv.style.left = nX + "px"; 140 | oWindowDiv.style.top = nY + "px"; 141 | }; -------------------------------------------------------------------------------- /Src/gameRoom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 25 | 26 | 27 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 97 | 98 |
99 | 100 | 101 | 102 |
103 | 104 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /Src/KGS/Common.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 14.09.2016 9 | * Time 01:30 10 | */ 11 | 12 | var EKGSGameType = { 13 | Challenge : 0, 14 | Demonstration : 1, 15 | Review : 2, 16 | RengoReview : 3, 17 | Teaching : 4, 18 | Simul : 5, 19 | Rengo : 6, 20 | Free : 7, 21 | Ranked : 8, 22 | Tournament : 9 23 | }; 24 | 25 | var EKGSGameRules = { 26 | Japanese : 0, 27 | Chinese : 1, 28 | Aga : 2, 29 | NewZealand : 3 30 | }; 31 | 32 | var KGSCommon = { 33 | 34 | /** 35 | * Parse a gameType string from KGS message. 36 | * @param {string} sGameType 37 | * @returns {EKGSGameType} 38 | */ 39 | GetGameType : function(sGameType) 40 | { 41 | if ("challenge" === sGameType) 42 | return EKGSGameType.Challenge; 43 | else if ("demonstration" === sGameType) 44 | return EKGSGameType.Demonstration; 45 | else if ("review" === sGameType) 46 | return EKGSGameType.Review; 47 | else if ("rengo_review" === sGameType) 48 | return EKGSGameType.RengoReview; 49 | else if ("teaching" === sGameType) 50 | return EKGSGameType.Teaching; 51 | else if ("simul" === sGameType) 52 | return EKGSGameType.Simul; 53 | else if ("rengo" === sGameType) 54 | return EKGSGameType.Rengo; 55 | else if ("free" === sGameType) 56 | return EKGSGameType.Free; 57 | else if ("ranked" === sGameType) 58 | return EKGSGameType.Ranked; 59 | else if ("tournament" === sGameType) 60 | return EKGSGameType.Tournament; 61 | 62 | return EKGSGameType.Free; 63 | }, 64 | /** 65 | * Convert a game type to KGS gameType string. 66 | * @param {EKGSGameType} nGameType 67 | * @returns {string} 68 | */ 69 | GameTypeToString : function(nGameType) 70 | { 71 | if (EKGSGameType.Challenge === nGameType) 72 | return "challenge"; 73 | else if (EKGSGameType.Demonstration === nGameType) 74 | return "demonstration"; 75 | else if (EKGSGameType.Review === nGameType) 76 | return "review"; 77 | else if (EKGSGameType.RengoReview === nGameType) 78 | return "rengo_review"; 79 | else if (EKGSGameType.Teaching === nGameType) 80 | return "teaching"; 81 | else if (EKGSGameType.Simul === nGameType) 82 | return "simul"; 83 | else if (EKGSGameType.Rengo === nGameType) 84 | return "rengo"; 85 | else if (EKGSGameType.Free === nGameType) 86 | return "free"; 87 | else if (EKGSGameType.Ranked === nGameType) 88 | return "ranked"; 89 | else if (EKGSGameType.Tournament === nGameType) 90 | return "tournament"; 91 | 92 | return "free"; 93 | }, 94 | /** 95 | * Parse rules string from KGS message. 96 | * @param {string} sRules 97 | * @returns {EKGSGameRules} 98 | */ 99 | GetGameRules : function(sRules) 100 | { 101 | if ("japanese" === sRules) 102 | return EKGSGameRules.Japanese; 103 | else if ("chinese" === sRules) 104 | return EKGSGameRules.Chinese; 105 | else if ("aga" === sRules) 106 | return EKGSGameRules.Aga; 107 | else if ("new_zealand" === sRules) 108 | return EKGSGameRules.NewZealand; 109 | 110 | return EKGSGameRules.Japanese; 111 | }, 112 | /** 113 | * Convert a rules type to KGS rules string. 114 | * @param {EKGSGameRules} nRules 115 | * @returns {string} 116 | */ 117 | GameRulesToString : function(nRules) 118 | { 119 | if (EKGSGameRules.Japanese === nRules) 120 | return "japanese"; 121 | else if (EKGSGameRules.Chinese === nRules) 122 | return "chinese"; 123 | else if (EKGSGameRules.Aga === nRules) 124 | return "aga"; 125 | else if (EKGSGameRules.NewZealand === nRules) 126 | return "new_zealand"; 127 | 128 | return "japanese"; 129 | }, 130 | 131 | /** 132 | * Convert a rules type to a readable string. 133 | * @param {EKGSGameRules} nRules 134 | * @returns {string} 135 | */ 136 | GameRulesToReadableString : function(nRules) 137 | { 138 | if (EKGSGameRules.Japanese === nRules) 139 | return g_oLocalization.common.rules.japanese; 140 | else if (EKGSGameRules.Chinese === nRules) 141 | return g_oLocalization.common.rules.chinese; 142 | else if (EKGSGameRules.Aga === nRules) 143 | return g_oLocalization.common.rules.aga; 144 | else if (EKGSGameRules.NewZealand === nRules) 145 | return g_oLocalization.common.rules.newZealand; 146 | 147 | return g_oLocalization.common.rules.japanese; 148 | }, 149 | 150 | /** 151 | * Convert a time system to KGS string. 152 | * @param {CTimeSettings} oTime 153 | * @returns {string} 154 | */ 155 | TimeSystemToString : function(oTime) 156 | { 157 | if (oTime.IsAbsolute()) 158 | return "absolute"; 159 | else if (oTime.IsByoYomi()) 160 | return "byo_yomi"; 161 | else if (oTime.IsCanadian()) 162 | return "canadian"; 163 | else if (oTime.IsNone()) 164 | return "none"; 165 | 166 | return "none"; 167 | }, 168 | 169 | /** 170 | * Convert iso language code to a KGS-allowable code 171 | * @param sCode 172 | * @constructor 173 | */ 174 | GetLanguageCode : function(sCode) 175 | { 176 | var sLanguage = "en_US"; 177 | switch (sCode) 178 | { 179 | case "bg" : 180 | case "bg-BG" : 181 | sLanguage = "bg_BG"; 182 | break; 183 | case "ca" : 184 | case "ca-ES" : 185 | sLanguage = "ca_ES"; 186 | break; 187 | case "cs" : 188 | case "cs-CZ" : 189 | sLanguage = "cs_CZ"; 190 | break; 191 | case "da" : 192 | case "da-DK" : 193 | sLanguage = "da_DK"; 194 | break; 195 | case "de" : 196 | case "de-AT" : 197 | case "de-CH" : 198 | case "de-DE" : 199 | case "de-LI" : 200 | case "de-LU" : 201 | sLanguage = "de_DE"; 202 | break; 203 | case "en" : 204 | case "en-AU" : 205 | case "en-BZ" : 206 | case "en-CA" : 207 | case "en-CB" : 208 | case "en-GB" : 209 | case "en-IE" : 210 | case "en-JM" : 211 | case "en-NZ" : 212 | case "en-PH" : 213 | case "en-TT" : 214 | case "en-US" : 215 | case "en-ZA" : 216 | case "en-ZW" : 217 | sLanguage = "en_US"; 218 | break; 219 | case "es" : 220 | case "es-AR" : 221 | case "es-BO" : 222 | case "es-CL" : 223 | case "es-CO" : 224 | case "es-CR" : 225 | case "es-DO" : 226 | case "es-EC" : 227 | case "es-ES" : 228 | case "es-GT" : 229 | case "es-HN" : 230 | case "es-MX" : 231 | case "es-NI" : 232 | case "es-PA" : 233 | case "es-PE" : 234 | case "es-PR" : 235 | case "es-PY" : 236 | case "es-SV" : 237 | case "es-UY" : 238 | case "es-VE" : 239 | sLanguage = "es_ES"; 240 | break; 241 | case "eu" : 242 | case "eu-ES" : 243 | sLanguage = "eu_ES"; 244 | break; 245 | case "fi" : 246 | case "fi-FI" : 247 | sLanguage = "fi_FI"; 248 | break; 249 | case "fr" : 250 | case "fr-BE" : 251 | case "fr-CA" : 252 | case "fr-CH" : 253 | case "fr-FR" : 254 | case "fr-LU" : 255 | case "fr-MC" : 256 | sLanguage = "fr_FR"; 257 | break; 258 | case "hu" : 259 | case "hu-HU" : 260 | sLanguage = "hu_HU"; 261 | break; 262 | case "it" : 263 | case "it-CH" : 264 | case "it-IT" : 265 | sLanguage = "it_IT"; 266 | break; 267 | case "ja" : 268 | case "ja-JP" : 269 | sLanguage = "ja_JP"; 270 | break; 271 | case "ko" : 272 | case "ko-KR" : 273 | sLanguage = "ko_KR"; 274 | break; 275 | case "lv" : 276 | case "lv-LV" : 277 | sLanguage = "lv_LV"; 278 | break; 279 | case "pl" : 280 | case "pl-PL" : 281 | sLanguage = "pl_PL"; 282 | break; 283 | case "pt" : 284 | case "pt-BR" : 285 | case "pt-PT" : 286 | sLanguage = "pt_BR"; 287 | break; 288 | case "ro" : 289 | case "ro-RO" : 290 | sLanguage = "ro_RO"; 291 | break; 292 | case "ru" : 293 | case "ru-RU" : 294 | sLanguage = "ru_RU"; 295 | break; 296 | case "sk" : 297 | case "sk-SK" : 298 | sLanguage = "sk_SK"; 299 | break; 300 | case "tr" : 301 | case "tr-TR" : 302 | sLanguage = "tr_TR"; 303 | break; 304 | case "vi" : 305 | case "vi-VN" : 306 | sLanguage = "vi_VN"; 307 | break; 308 | case "zh" : 309 | case "zh-CN" : 310 | case "zh-HK" : 311 | case "zh-MO" : 312 | case "zh-SG" : 313 | case "zh-TW" : 314 | sLanguage = "zh_CN"; 315 | break; 316 | } 317 | 318 | return sLanguage; 319 | } 320 | 321 | }; 322 | -------------------------------------------------------------------------------- /Src/Common/Popup.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 10.06.2016 9 | * Time 22:44 10 | */ 11 | 12 | function CVisualPopup(oApp, oHandler) 13 | { 14 | this.m_oApp = oApp; 15 | this.m_oHandler = oHandler; 16 | 17 | this.m_oHtmlElement = null; 18 | this.m_nShowId = null; 19 | this.m_nTransitionId = null; 20 | this.m_bDestroyOnHide = false; 21 | } 22 | CVisualPopup.prototype.Create = function(bDestroyOnHide) 23 | { 24 | this.m_oApp.RegisterPopup(this); 25 | 26 | if (undefined !== bDestroyOnHide) 27 | this.m_bDestroyOnHide = bDestroyOnHide; 28 | 29 | var oMainDiv = this.m_oApp.GetMainDiv(); 30 | 31 | var oElement = document.createElement("div"); 32 | oElement.style.position = "absolute"; 33 | oElement.style.top = "100px"; 34 | oElement.style.left = "100px"; 35 | oElement.style.width = "100px"; 36 | oElement.style.height = "100px"; 37 | oElement.style.background = "rgb(243, 243, 243)"; 38 | oElement.style.display = "block"; 39 | oElement.style.overflow = "hidden"; 40 | oMainDiv.appendChild(oElement); 41 | oElement.style.display = "none"; 42 | 43 | this.m_oHtmlElement = oElement; 44 | this.m_nShowId = null; 45 | this.m_nTransitionId = null; 46 | }; 47 | CVisualPopup.prototype.GetHtmlElement = function() 48 | { 49 | return this.m_oHtmlElement; 50 | }; 51 | CVisualPopup.prototype.Toggle = function() 52 | { 53 | if ("none" === this.m_oHtmlElement.style.display) 54 | { 55 | this.Show(false); 56 | } 57 | else 58 | { 59 | this.Hide(false); 60 | } 61 | }; 62 | CVisualPopup.prototype.Show = function(bFast) 63 | { 64 | var oThis = this; 65 | var oHandler = this.m_oHandler; 66 | 67 | if (null === this.m_nShowId) 68 | { 69 | if (oHandler.UpdatePopupPosition) 70 | oHandler.UpdatePopupPosition(oThis); 71 | 72 | if (true === bFast) 73 | { 74 | if (null !== oThis.m_nTransitionId) 75 | { 76 | clearTimeout(oThis.m_nTransitionId); 77 | oThis.m_nTransitionId = null; 78 | } 79 | 80 | oThis.m_oHtmlElement.style.display = "block"; 81 | 82 | if (oHandler.OnPreShowPopup) 83 | oHandler.OnPreShowPopup(oThis); 84 | 85 | if (oHandler.OnShowPopup) 86 | oHandler.OnShowPopup(oThis); 87 | 88 | oThis.m_nTransitionId = null; 89 | oThis.m_nShowId = null; 90 | } 91 | else 92 | { 93 | this.m_nShowId = setTimeout(function() 94 | { 95 | if (null !== oThis.m_nTransitionId) 96 | { 97 | clearTimeout(oThis.m_nTransitionId); 98 | oThis.m_nTransitionId = null; 99 | } 100 | 101 | oThis.m_oHtmlElement.style.display = "block"; 102 | 103 | if (oHandler.OnPreShowPopup) 104 | oHandler.OnPreShowPopup(oThis); 105 | 106 | oThis.m_nTransitionId = setTimeout(function() 107 | { 108 | if (oHandler.OnShowPopup) 109 | oHandler.OnShowPopup(oThis); 110 | 111 | oThis.m_nTransitionId = null; 112 | oThis.m_nShowId = null; 113 | }, 20); 114 | }, 20); 115 | } 116 | } 117 | }; 118 | CVisualPopup.prototype.Hide = function(bFast) 119 | { 120 | var oThis = this; 121 | var oHandler = this.m_oHandler; 122 | if ("none" !== this.m_oHtmlElement.style.display) 123 | { 124 | if (oHandler.OnHidePopup) 125 | oHandler.OnHidePopup(oThis); 126 | 127 | if (true === bFast) 128 | { 129 | this.m_oHtmlElement.style.display = "none"; 130 | 131 | if (true === this.m_bDestroyOnHide) 132 | this.Destroy(); 133 | } 134 | else 135 | { 136 | if (null !== oThis.m_nTransitionId) 137 | { 138 | clearTimeout(oThis.m_nTransitionId); 139 | oThis.m_nTransitionId = null; 140 | } 141 | 142 | if (null !== oThis.m_nShowId) 143 | { 144 | clearTimeout(oThis.m_nShowId); 145 | oThis.m_nShowId = null; 146 | } 147 | 148 | this.m_nTransitionId = setTimeout(function() 149 | { 150 | if (true === oThis.m_bDestroyOnHide) 151 | oThis.Destroy(); 152 | 153 | oThis.m_oHtmlElement.style.display = "none"; 154 | oThis.m_nTransitionId = null; 155 | }, 200); 156 | } 157 | } 158 | }; 159 | CVisualPopup.prototype.Destroy = function() 160 | { 161 | try 162 | { 163 | this.m_oApp.UnregisterPopup(this); 164 | var oMainDiv = this.m_oApp.GetMainDiv(); 165 | oMainDiv.removeChild(this.m_oHtmlElement); 166 | } 167 | catch(e) 168 | { 169 | } 170 | }; 171 | CVisualPopup.prototype.IsVisible = function() 172 | { 173 | return (this.m_oHtmlElement.style.display === "block" ? true : false); 174 | }; 175 | 176 | function CVisualContextMenu(oApp, nX, nY) 177 | { 178 | this.m_oApp = oApp; 179 | this.m_nX = nX; 180 | this.m_nY = nY; 181 | 182 | this.m_oPopup = new CVisualPopup(oApp, this); 183 | this.m_oPopup.Create(true); 184 | 185 | 186 | var oHtmlElement = this.m_oPopup.GetHtmlElement(); 187 | oHtmlElement.style.zIndex = 0xFFFFFFFF; 188 | oHtmlElement.style.position = "absolute"; 189 | oHtmlElement.style.top = "100px"; 190 | oHtmlElement.style.left = "100px"; 191 | oHtmlElement.style.display = "none"; 192 | oHtmlElement.className += "ContextMenu"; 193 | 194 | var oList = document.createElement("ul"); 195 | oHtmlElement.appendChild(oList); 196 | this.m_oList = oList; 197 | 198 | this.m_nMaxHeight = null; 199 | this.m_nHeight = 12; 200 | this.m_nWidth = 100; 201 | 202 | this.m_oScroll = null; 203 | 204 | this.m_oAdditionalInfo = {}; 205 | this.m_arrOnHideCallbacks = []; 206 | } 207 | CVisualContextMenu.prototype.AddListItem = function(sText, fAction, isDisabled, oAdditionalInfo) 208 | { 209 | var oListEntry = document.createElement("li"); 210 | oListEntry.className = true === isDisabled ? "ContextMenuItemDisabled" : "ContextMenuItem"; 211 | this.m_oList.appendChild(oListEntry); 212 | 213 | if (sText) 214 | { 215 | oListEntry.innerHTML = sText; 216 | 217 | g_oTextMeasurer.SetFont("16px 'Times New Roman', Times, serif"); 218 | var nWidth = (g_oTextMeasurer.Measure(sText) | 0) + 1; 219 | 220 | if (this.m_nWidth < 5 + nWidth + 5) 221 | this.m_nWidth = 5 + nWidth + 5; 222 | } 223 | 224 | if (fAction && true !== isDisabled) 225 | { 226 | oListEntry.addEventListener("click", function(e){ 227 | fAction(e, oAdditionalInfo); 228 | }, false); 229 | } 230 | 231 | this.m_nHeight += 20; 232 | 233 | return oListEntry; 234 | }; 235 | CVisualContextMenu.prototype.AddHorizontalLine = function() 236 | { 237 | var oListEntry = document.createElement("li"); 238 | oListEntry.className = "ContextMenuLine"; 239 | this.m_oList.appendChild(oListEntry); 240 | 241 | this.m_nHeight += 6; 242 | }; 243 | CVisualContextMenu.prototype.AddCheckBoxItem = function(bChecked, sText, fAction, isDisabled, oAdditionalInfo) 244 | { 245 | var oListEntry = document.createElement("li"); 246 | oListEntry.className = true === isDisabled ? "ContextMenuItemDisabled" : "ContextMenuItem"; 247 | this.m_oList.appendChild(oListEntry); 248 | 249 | var oCheckItem = document.createElement("div"); 250 | oCheckItem.style.paddingLeft = "3px"; 251 | oCheckItem.style.width = "20px"; 252 | oCheckItem.style.height = "20px"; 253 | oCheckItem.style['float'] = "left"; 254 | Common.Set_InnerTextToElement(oCheckItem, bChecked ? "✔" : ""); 255 | oListEntry.appendChild(oCheckItem); 256 | 257 | var oTextItem = document.createElement("div"); 258 | oTextItem.style.height = "20px"; 259 | oTextItem.style['float'] = "left"; 260 | oTextItem.style.overflow = "hidden"; 261 | Common.Set_InnerTextToElement(oTextItem, sText); 262 | oListEntry.appendChild(oTextItem); 263 | 264 | g_oTextMeasurer.SetFont("16px 'Times New Roman', Times, serif"); 265 | var nWidth = (g_oTextMeasurer.Measure(sText) | 0) + 1; 266 | 267 | if (this.m_nWidth < 5 + 3 + 20 + nWidth + 5) 268 | this.m_nWidth = 5 + 3 + 20 + nWidth + 5; 269 | 270 | if (fAction && true !== isDisabled) 271 | { 272 | oListEntry.addEventListener("click", function(e){ 273 | fAction(e, oAdditionalInfo); 274 | }, false); 275 | } 276 | 277 | this.m_nHeight += 20; 278 | 279 | return oListEntry; 280 | }; 281 | CVisualContextMenu.prototype.Show = function() 282 | { 283 | this.m_oPopup.Show(); 284 | }; 285 | CVisualContextMenu.prototype.Hide = function() 286 | { 287 | this.m_oPopup.Hide(); 288 | }; 289 | CVisualContextMenu.prototype.UpdatePopupPosition = function(oPopup) 290 | { 291 | var nHeight = this.m_nHeight; 292 | if (null !== this.m_nMaxHeight && nHeight > this.m_nMaxHeight) 293 | { 294 | nHeight = this.m_nMaxHeight; 295 | } 296 | 297 | var nWidth = this.m_nWidth; 298 | if (this.m_oScroll) 299 | { 300 | nWidth += 20; 301 | } 302 | 303 | var nAppHeight = this.m_oApp.GetHeight(); 304 | if (this.m_nY + nHeight > nAppHeight) 305 | this.m_nY = nAppHeight - nHeight; 306 | 307 | var nAppWidth = this.m_oApp.GetWidth(); 308 | 309 | if (this.m_nX + nWidth > nAppWidth) 310 | this.m_nX = nAppWidth - nWidth; 311 | 312 | var oHtmlElement = this.m_oPopup.GetHtmlElement(); 313 | oHtmlElement.style.left = this.m_nX + "px"; 314 | oHtmlElement.style.top = this.m_nY + "px"; 315 | }; 316 | CVisualContextMenu.prototype.OnHidePopup = function(oPopup) 317 | { 318 | var oHtmlElement = oPopup.GetHtmlElement(); 319 | oHtmlElement.style.height = "0px"; 320 | 321 | for (var nIndex = 0, nCount = this.m_arrOnHideCallbacks.length; nIndex < nCount; ++nIndex) 322 | { 323 | this.m_arrOnHideCallbacks[nIndex](); 324 | } 325 | }; 326 | CVisualContextMenu.prototype.OnPreShowPopup = function(oPopup) 327 | { 328 | var oHtmlElement = oPopup.GetHtmlElement(); 329 | oHtmlElement.style.height = "0px"; 330 | }; 331 | CVisualContextMenu.prototype.OnShowPopup = function(oPopup) 332 | { 333 | var bAddScroll = false; 334 | var nHeight = this.m_nHeight; 335 | if (null !== this.m_nMaxHeight && nHeight > this.m_nMaxHeight) 336 | { 337 | nHeight = this.m_nMaxHeight; 338 | bAddScroll = true; 339 | } 340 | var nWidth = this.m_nWidth; 341 | if (true === bAddScroll) 342 | { 343 | nWidth += 20; 344 | } 345 | 346 | var oHtmlElement = oPopup.GetHtmlElement(); 347 | oHtmlElement.style.width = nWidth + "px"; 348 | oHtmlElement.style.height = nHeight + "px"; 349 | 350 | if (true === bAddScroll && !this.m_oScroll) 351 | { 352 | if (!this.m_oScroll) 353 | { 354 | this.m_oList.style.height = (nHeight - 12) + "px"; 355 | this.m_oScroll = new CVerticalScroll(); 356 | this.m_oScroll.Init(this.m_oList, "VerScroll", "VerScrollActive", true); 357 | this.m_oScroll.SetPaddings(-2, 0, 0); 358 | this.m_oScroll.SetStopPropagation(true); 359 | } 360 | this.m_oScroll.CheckVisibility(); 361 | } 362 | }; 363 | CVisualContextMenu.prototype.GetWidth = function() 364 | { 365 | return this.m_nWidth; 366 | }; 367 | CVisualContextMenu.prototype.GetHeight = function() 368 | { 369 | return this.m_nHeight; 370 | }; 371 | CVisualContextMenu.prototype.SetAdditionalInfo = function(sKey, vValue) 372 | { 373 | this.m_oAdditionalInfo[sKey] = vValue; 374 | }; 375 | CVisualContextMenu.prototype.GetAdditionalInfo = function(sKey) 376 | { 377 | return this.m_oAdditionalInfo[sKey]; 378 | }; 379 | CVisualContextMenu.prototype.AddOnHideCallback = function(fCallback) 380 | { 381 | this.m_arrOnHideCallbacks.push(fCallback); 382 | }; 383 | CVisualContextMenu.prototype.SetMaxHeight = function(nMaxHeight) 384 | { 385 | this.m_nMaxHeight = nMaxHeight; 386 | }; 387 | 388 | -------------------------------------------------------------------------------- /Src/KGS/GameListRecord.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 06.07.2016 9 | * Time 1:05 10 | */ 11 | 12 | function CKGSGameListRecord(oClient) 13 | { 14 | this.m_oClient = oClient; 15 | this.m_oRooms = {}; 16 | 17 | this.m_nGameId = -1; 18 | this.m_nRoomId = -1; 19 | this.m_nGameType = EKGSGameType.Ranked; 20 | this.m_nMoveNumber = 0; 21 | this.m_nObservers = 0; 22 | this.m_sScore = null; 23 | this.m_oBlack = null; 24 | this.m_oWhite = null; 25 | this.m_oOwner = null; 26 | this.m_oBlack2 = null; 27 | this.m_oWhite2 = null; 28 | this.m_nHandicap = 0; 29 | this.m_nBoardSize = 19; 30 | this.m_bAdjourned = false; 31 | this.m_bEvent = false; 32 | this.m_bPrivate = false; 33 | 34 | this.m_oChallengeCreator = null; 35 | this.m_oProposal = null; 36 | this.m_sComment = ""; 37 | 38 | this.m_oLoadingGameTree = null; 39 | } 40 | CKGSGameListRecord.prototype.Update = function(oGameRecord) 41 | { 42 | this.private_ParseGameType(oGameRecord.gameType); 43 | 44 | this.m_nGameId = oGameRecord.channelId; 45 | this.m_nRoomId = oGameRecord.roomId; 46 | this.m_bPrivate = true === oGameRecord.private ? true : false; 47 | 48 | if (EKGSGameType.Challenge === this.m_nGameType) 49 | return this.private_ParseChallenge(oGameRecord); 50 | 51 | this.m_nMoveNumber = oGameRecord.moveNum; 52 | this.m_nObservers = undefined !== oGameRecord.observers ? oGameRecord.observers : 0; 53 | this.m_sScore = undefined !== oGameRecord.score ? this.m_oClient.private_ParseScore(oGameRecord.score) : null; 54 | 55 | if (oGameRecord.players.black) 56 | this.m_oBlack = GetKGSUser(oGameRecord.players.black); 57 | 58 | if (oGameRecord.players.white) 59 | this.m_oWhite = GetKGSUser(oGameRecord.players.white); 60 | 61 | if (oGameRecord.players.owner) 62 | this.m_oOwner = GetKGSUser(oGameRecord.players.owner); 63 | 64 | if (oGameRecord.players.black_2) 65 | this.m_oBlack2 = GetKGSUser(oGameRecord.players.black_2); 66 | 67 | if (oGameRecord.players.white_2) 68 | this.m_oWhite2 = GetKGSUser(oGameRecord.players.white_2); 69 | 70 | this.m_nHandicap = oGameRecord.handicap ? parseInt(oGameRecord.handicap) : 0; 71 | this.m_nBoardSize = oGameRecord.size ? oGameRecord.size : 19; 72 | 73 | this.m_bAdjourned = oGameRecord.adjourned ? oGameRecord.adjourned : false; 74 | this.m_bEvent = oGameRecord.event ? oGameRecord.event : false; 75 | }; 76 | CKGSGameListRecord.prototype.AddRoom = function(nRoomId) 77 | { 78 | this.m_oRooms[nRoomId] = nRoomId; 79 | }; 80 | CKGSGameListRecord.prototype.RemoveRoom = function(nRoomId) 81 | { 82 | delete this.m_oRooms[nRoomId]; 83 | 84 | for (var nId in this.m_oRooms) 85 | { 86 | return false; 87 | } 88 | 89 | return true; 90 | }; 91 | CKGSGameListRecord.prototype.GetBlack = function() 92 | { 93 | return this.m_oBlack; 94 | }; 95 | CKGSGameListRecord.prototype.GetWhite = function() 96 | { 97 | return this.m_oWhite; 98 | }; 99 | CKGSGameListRecord.prototype.GetOwner = function () 100 | { 101 | return this.m_oOwner; 102 | }; 103 | CKGSGameListRecord.prototype.GetBlack2 = function() 104 | { 105 | return this.m_oBlack2; 106 | }; 107 | CKGSGameListRecord.prototype.GetWhite2 = function() 108 | { 109 | return this.m_oWhite2; 110 | }; 111 | CKGSGameListRecord.prototype.GetObservers = function() 112 | { 113 | return this.m_nObservers; 114 | }; 115 | CKGSGameListRecord.prototype.GetGameType = function() 116 | { 117 | return this.m_nGameType; 118 | }; 119 | CKGSGameListRecord.prototype.private_ParseGameType = function(sGameType) 120 | { 121 | this.m_nGameType = KGSCommon.GetGameType(sGameType); 122 | }; 123 | CKGSGameListRecord.prototype.GetGameId = function() 124 | { 125 | return this.m_nGameId; 126 | }; 127 | CKGSGameListRecord.prototype.GetMoveNum = function() 128 | { 129 | return this.m_nMoveNumber; 130 | }; 131 | CKGSGameListRecord.prototype.GetScore = function() 132 | { 133 | return this.m_sScore; 134 | }; 135 | CKGSGameListRecord.prototype.IsPrivate = function() 136 | { 137 | return this.m_bPrivate; 138 | }; 139 | CKGSGameListRecord.prototype.IsAdjourned = function() 140 | { 141 | return this.m_bAdjourned; 142 | }; 143 | CKGSGameListRecord.prototype.IsEvent = function() 144 | { 145 | return this.m_bEvent; 146 | }; 147 | CKGSGameListRecord.prototype.GetRoomId = function() 148 | { 149 | return this.m_nRoomId; 150 | }; 151 | CKGSGameListRecord.prototype.GetBoardSize = function() 152 | { 153 | return this.m_nBoardSize; 154 | }; 155 | CKGSGameListRecord.prototype.GetHandicap = function() 156 | { 157 | return this.m_nHandicap; 158 | }; 159 | CKGSGameListRecord.prototype.private_ParseChallenge = function(oGameRecord) 160 | { 161 | if (oGameRecord.players.challengeCreator) 162 | this.m_oChallengeCreator = GetKGSUser(oGameRecord.players.challengeCreator); 163 | 164 | this.m_oProposal = new CKGSChallengeProposal(oGameRecord.initialProposal); 165 | this.m_sComment = oGameRecord.name ? oGameRecord.name : ""; 166 | }; 167 | CKGSGameListRecord.prototype.GetProposal = function() 168 | { 169 | return this.m_oProposal; 170 | }; 171 | CKGSGameListRecord.prototype.GetChallengeCreator = function() 172 | { 173 | return this.m_oChallengeCreator; 174 | }; 175 | CKGSGameListRecord.prototype.GetComment = function() 176 | { 177 | return this.m_sComment; 178 | }; 179 | CKGSGameListRecord.prototype.IsChallenge = function() 180 | { 181 | return (this.m_nGameType === EKGSGameType.Challenge ? true : false); 182 | }; 183 | CKGSGameListRecord.prototype.IsRobotChallenge = function() 184 | { 185 | var isChallenge = this.IsChallenge(); 186 | if (!isChallenge) 187 | return false; 188 | 189 | var oCreator = this.m_oChallengeCreator; 190 | if (!oCreator || true !== oCreator.IsRobot()) 191 | return false; 192 | 193 | return true; 194 | }; 195 | CKGSGameListRecord.prototype.IsProposalPrivate = function() 196 | { 197 | return this.m_oProposal.IsPrivate(); 198 | }; 199 | CKGSGameListRecord.prototype.GetGameTitle = function() 200 | { 201 | if (this.m_nGameType === EKGSGameType.Challenge) 202 | { 203 | if (this.m_oChallengeCreator) 204 | return "Challenge " + this.m_oChallengeCreator.GetName() + "[" + this.m_oChallengeCreator.GetStringRank() + "]"; 205 | else 206 | return "Challenge"; 207 | } 208 | else if (this.m_nGameType === EKGSGameType.Demonstration) 209 | { 210 | if (this.m_oOwner) 211 | return "Demonstration " + this.m_oOwner.GetName() + "[" + this.m_oOwner.GetStringRank() + "]"; 212 | else 213 | return "Demonstration"; 214 | } 215 | else 216 | { 217 | if (this.m_oBlack && this.m_oWhite && this.m_oBlack2 && this.m_oWhite2) 218 | return "Match " + this.m_oWhite.GetName() + "[" + this.m_oWhite.GetStringRank() + "], " + this.m_oWhite2.GetName() + "[" + this.m_oWhite2.GetStringRank() + "] vs. " + this.m_oBlack.GetName() + "[" + this.m_oBlack.GetStringRank() + "], " + this.m_oBlack2.GetName() + "[" + this.m_oBlack2.GetStringRank() + "]"; 219 | else if (this.m_oBlack && this.m_oWhite) 220 | return "Match " + this.m_oWhite.GetName() + "[" + this.m_oWhite.GetStringRank() + "] vs. " + this.m_oBlack.GetName() + "[" + this.m_oBlack.GetStringRank() + "]"; 221 | else 222 | return "Match"; 223 | } 224 | }; 225 | CKGSGameListRecord.prototype.GetLoadingGameTree = function() 226 | { 227 | return this.m_oLoadingGameTree; 228 | }; 229 | CKGSGameListRecord.prototype.SetLoadingGameTree = function(oGameTree) 230 | { 231 | this.m_oLoadingGameTree = oGameTree; 232 | }; 233 | CKGSGameListRecord.prototype.SetProposal = function(oProposal) 234 | { 235 | this.m_oProposal = oProposal; 236 | }; 237 | 238 | function CKGSChallengeProposal(oGameRecord) 239 | { 240 | this.m_nGameType = EKGSGameType.Free; 241 | this.m_nRules = EKGSGameRules.Japanese; 242 | this.m_sKomi = "6.5"; 243 | this.m_nHandicap = 0; 244 | this.m_nSize = 19; 245 | this.m_oTime = new CTimeSettings(); 246 | this.m_bNigiri = true === oGameRecord.nigiri ? true : false; 247 | this.m_arrPlayers = []; 248 | this.m_oWhite = null; 249 | this.m_oBlack = null; 250 | this.m_oWhite2 = null; 251 | this.m_oBlack2 = null; 252 | this.m_bPrivate = true === oGameRecord.private ? true : false; 253 | 254 | this.private_ParseGameType(oGameRecord.gameType); 255 | this.private_ParseRules(oGameRecord.rules); 256 | this.private_ParsePlayers(oGameRecord.players); 257 | } 258 | CKGSChallengeProposal.prototype.private_ParseGameType = function(sGameType) 259 | { 260 | this.m_nGameType = KGSCommon.GetGameType(sGameType); 261 | }; 262 | CKGSChallengeProposal.prototype.GetGameType = function() 263 | { 264 | return this.m_nGameType; 265 | }; 266 | CKGSChallengeProposal.prototype.GetRules = function() 267 | { 268 | return this.m_nRules; 269 | }; 270 | CKGSChallengeProposal.prototype.GetKomi = function() 271 | { 272 | return this.m_sKomi; 273 | }; 274 | CKGSChallengeProposal.prototype.GetHandicap = function() 275 | { 276 | return this.m_nHandicap; 277 | }; 278 | CKGSChallengeProposal.prototype.GetBoardSize = function() 279 | { 280 | return this.m_nSize; 281 | }; 282 | CKGSChallengeProposal.prototype.IsNigiri = function() 283 | { 284 | return this.m_bNigiri; 285 | }; 286 | CKGSChallengeProposal.prototype.private_ParseRules = function(oRules) 287 | { 288 | this.m_nRules = KGSCommon.GetGameRules(oRules.rules); 289 | this.m_sKomi = "" + oRules.komi; 290 | this.m_nSize = oRules.size ? oRules.size : 19; 291 | this.m_nHandicap = oRules.handicap ? oRules.handicap : 0; 292 | 293 | var sTimeType = oRules.timeSystem; 294 | if ("absolute" === sTimeType) 295 | this.m_oTime.SetAbsolute(oRules.mainTime); 296 | else if ("byo_yomi" === sTimeType) 297 | this.m_oTime.SetByoYomi(oRules.mainTime, oRules.byoYomiTime, oRules.byoYomiPeriods); 298 | else if ("canadian" === sTimeType) 299 | this.m_oTime.SetCanadian(oRules.mainTime, oRules.byoYomiTime, oRules.byoYomiStones); 300 | }; 301 | CKGSChallengeProposal.prototype.private_ParsePlayers = function(arrPlayers) 302 | { 303 | if (!arrPlayers || !arrPlayers.length) 304 | return; 305 | 306 | for (var nIndex = 0, nCount = arrPlayers.length; nIndex < nCount; ++nIndex) 307 | { 308 | var oRecord = arrPlayers[nIndex]; 309 | if ("white" === oRecord["role"] && oRecord["user"]) 310 | { 311 | this.m_oWhite = GetKGSUser(oRecord["user"]); 312 | } 313 | else if ("black" === oRecord["role"] && oRecord["user"]) 314 | { 315 | this.m_oBlack = GetKGSUser(oRecord["user"]); 316 | } 317 | else if ("white_2" === oRecord["role"] && oRecord["user"]) 318 | { 319 | this.m_oWhite2 = GetKGSUser(oRecord["user"]); 320 | } 321 | else if ("black_2" === oRecord["role"] && oRecord["user"]) 322 | { 323 | this.m_oBlack2 = GetKGSUser(oRecord["user"]); 324 | } 325 | } 326 | }; 327 | CKGSChallengeProposal.prototype.GetTimeSettingsString = function() 328 | { 329 | return this.m_oTime.GetTimeSystemString(); 330 | }; 331 | CKGSChallengeProposal.prototype.GetTimeSettings = function() 332 | { 333 | return this.m_oTime; 334 | }; 335 | CKGSChallengeProposal.prototype.GetBlack = function() 336 | { 337 | return this.m_oBlack; 338 | }; 339 | CKGSChallengeProposal.prototype.IsPrivate = function() 340 | { 341 | return this.m_bPrivate; 342 | }; 343 | CKGSChallengeProposal.prototype.GetBlack2 = function() 344 | { 345 | return this.m_oBlack2; 346 | }; 347 | CKGSChallengeProposal.prototype.GetWhite2 = function() 348 | { 349 | return this.m_oWhite2; 350 | }; -------------------------------------------------------------------------------- /GoBooklet/FutureSummit2017/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * User: Ilja.Kirillov 4 | * Date: 24.05.2017 5 | * Time: 16:29 6 | */ 7 | 8 | window.onload = OnDocumentReady; 9 | 10 | var oGame1 = null; 11 | var oGame2 = null; 12 | var oGame3 = null; 13 | var oGame4 = null; 14 | var oGame5 = null; 15 | 16 | function OnDocumentReady() 17 | { 18 | $('#booklet').turn({gradients: true, height : 582, width : 920}); 19 | $('#booklet').turn("resize"); 20 | 21 | $("#booklet").bind("turned", function(event, page, view) 22 | { 23 | if (!oGame1 && (6 === page || 7 === page)) 24 | { 25 | oGame1 = GoBoardApi.Embed("bookGame1", { 26 | boardMode : "viewer", 27 | width : 440, 28 | boardTheme : "BookStyle", 29 | sgfData : "(;EV[The Future of Go Summit, Match 1]RD[2017-05-23]PB[Ke Jie]BR[9 Dan]PW[AlphaGo]KM[7.5]SZ[19]; B[qd];W[pp];B[cc];W[cp];B[nc];W[fp];B[qq];W[pq];B[qp];W[qn];B[qo];W[po];B[rn];W[qr];B[rr];W[rm];B[pr];W[or];B[pn];W[qm];B[qs];W[on];B[dj];W[nk];B[ph];W[ch];B[cf];W[eh];B[ci];W[de];B[df];W[dc];B[cd];W[dd];B[ef];W[di];B[ei];W[dh];B[cj];W[ce];B[be];W[bf];B[bg];W[bd];B[af];W[bc];B[fi];W[cm];B[hq];W[ek];B[fh];W[gq];B[hp];W[ej];B[eq];W[gr];B[cq];W[dp];B[dq];W[ep];B[bp];W[bh];B[ah];W[bo];B[bq];W[fg];B[gg];W[kp];B[ko];W[jo];B[jn];W[in];B[jp];W[io];B[lp];W[kq];B[lq];W[kr];B[lr];W[ir];B[kn];W[il];B[oq];W[pf];B[nh];W[rf];B[od];W[qi];B[qg];W[rd];B[qf];W[qe];B[pe];W[re];B[qc];W[rg];B[kh];W[ic];B[gc];W[kc];B[jd];W[id];B[ge];W[hb];B[gb];W[jf];B[je];W[ie];B[ld];W[hg];B[eg];W[lc];B[le];W[hf];B[qh];W[rh];B[pi];W[qj];B[gk];W[fd];B[gd];W[lf];B[mf];W[lg];B[gm];W[gn];B[fn];W[go];B[dl];W[mo];B[oo];W[pm];B[op];W[mg];B[nf];W[lo];B[nn];W[lm];B[pn];W[dk];B[ck];W[cl];B[el];W[bk];B[bi];W[li];B[ii];W[ds];B[dr];W[hi];B[ik];W[jk];B[ij];W[md];B[mc];W[ke];B[me];W[kd];B[om];W[ls];B[ms];W[ks];B[nr];W[ng];B[og];W[es];B[cs];W[fr];B[er];W[fs];B[bs];W[hl];B[pl];W[ql];B[rc];W[ro];B[rp];W[sn];B[hm];W[im];B[kk];W[kj];B[lk];W[jl];B[mj];W[mi];B[nj];W[pk];B[fm];W[cn];B[ol];W[ok];B[ni];W[ih];B[ji];W[mb];B[nb];W[lb];B[fe];W[cb];B[mp];W[mm];B[eb];W[na];B[oa];W[ma];B[qb];W[bj];B[ai];W[aj];B[ag];W[gl];B[fk];W[bl];B[kg];W[kf];B[ib];W[jb];B[ga];W[ha];B[ed];W[ec];B[fc];W[gf];B[ff];W[gj];B[hk];W[hh];B[fj];W[no];B[fq];W[hr];B[kl];W[km];B[mn];W[ln];B[nl];W[db];B[da];W[ca];B[ea];W[np];B[nq];W[oj];B[oi];W[en];B[em];W[eo];B[dm];W[dn];B[sp];W[so];B[hn];W[ho];B[hc];W[ia];B[ao];W[an];B[ap];W[sc];B[sb];W[sd];B[jg];W[ad];B[gh];W[ae];B[ee];W[ml];B[mk];W[pj];B[bf];W[nm];B[on];W[he];B[ig];W[ki];B[jh];W[fl];B[jj];W[fo];B[hj];W[gi];B[ll];W[jm];B[lh];W[mh];B[lj];W[if];B[hd];)", 30 | booklet : true 31 | }); 32 | GoBoardApi.Set_ShowTarget(oGame1, false); 33 | GoBoardApi.Update_Size(oGame1); 34 | } 35 | 36 | if (!oGame2 && (8 === page || 9 === page)) 37 | { 38 | oGame2 = GoBoardApi.Embed("bookGame2", { 39 | boardMode : "viewer", 40 | width : 440, 41 | boardTheme : "BookStyle", 42 | sgfData : "(;EV[The Future of Go Summit, Match 2]RD[2017-05-25]PB[AlphaGo]BR[9 Dan]PW[Ke Jie]KM[7.5]SZ[19]RE[B+R];B[qp];W[pd];B[cq];W[cd];B[ec];W[oq];B[pn];W[df];B[nc];W[qf];B[pc];W[qc];B[qb];W[oc];B[pb];W[od];B[ob];W[rc];B[nd];W[mb];B[lc];W[lb];B[qd];W[rd];B[jc];W[mc];B[pe];W[oe];B[ld];W[kp];B[iq];W[fp];B[dn];W[io];B[ch];W[cl];B[eh];W[cg];B[bg];W[bf];B[fn];W[em];B[en];W[ek];B[kq];W[lq];B[lp];W[jq];B[kr];W[jp];B[jr];W[mq];B[ip];W[ho];B[gp];W[dq];B[go];W[cp];B[lo];W[kn];B[ln];W[km];B[dp];W[hp];B[hq];W[gq];B[gr];W[fq];B[hn];W[jo];B[fr];W[do];B[co];W[ep];B[bp];W[md];B[ne];W[of];B[lm];W[le];B[kl];W[jl];B[gl];W[kk];B[ll];W[jk];B[mj];W[gj];B[pq];W[pr];B[qr];W[po];B[qo];W[on];B[op];W[np];B[pm];W[om];B[no];W[bo];B[dp];W[oo];B[pp];W[cp];B[cn];W[nl];B[lk];W[mo];B[pl];W[nj];B[ni];W[ok];B[nf];W[mi];B[li];W[mh];B[og];W[pf];B[ki];W[ij];B[lg];W[nh];B[oi];W[oh];B[pj];W[ph];B[pk];W[bq];B[dp];W[jg];B[kg];W[cp];B[jn];W[in];B[dp];W[fo];B[cp];W[gn];B[ke];W[me];B[jf];W[jb];B[ic];W[ib];B[er];W[hc];B[cc];W[bc];B[dd];W[cb];B[ce];W[dc];B[cf];W[dg];B[be])", 43 | booklet : true 44 | }); 45 | GoBoardApi.Set_ShowTarget(oGame2, false); 46 | GoBoardApi.Update_Size(oGame2); 47 | } 48 | 49 | if (!oGame3 && (10 === page || 11 === page)) 50 | { 51 | oGame3 = GoBoardApi.Embed("bookGame3", { 52 | boardMode : "viewer", 53 | width : 440, 54 | boardTheme : "BookStyle", 55 | sgfData : "(;EV[The Future of Go Summit, Pair Go]RD[2017-05-26];PB[Gu Li + AlphaGo]PW[Lian Xiao + AlphaGo]SZ[19]KM[7.5];B[pd];W[cc];B[qp];W[dq];B[co];W[oq];B[pq];W[op];B[pn];W[kp];B[ep];W[fq];B[eq];W[er];B[dp];W[cq];B[dr];W[cr];B[fr];W[ds];B[gq];W[pf];B[hn];W[nc];B[nd];W[md];B[ne];W[oc];B[pe];W[qj];B[mr];W[mq];B[lq];W[pr];B[mp];W[mo];B[lp];W[pp];B[qq];W[qo];B[po];W[qn];B[qm];W[rm];B[pm];W[rp];B[rq];W[ro];B[qr];W[or];B[rl];W[qs];B[sr];W[rs];B[sm];W[rr];B[rn];W[sq];B[lo];W[qb];B[qh];W[di];B[dd];W[dc];B[fd];W[de];B[qf];W[lj];B[kd];W[jj];B[lb];W[lc];B[kc];W[mb];B[mj];W[li];B[mi];W[mk];B[mh];W[jm];B[kl];W[jl];B[ml];W[ed];B[fe];W[hc];B[gc];W[hd];B[hf];W[gf];B[ee];W[cd];B[gg];W[ge];B[fg];W[hg];B[eg];W[hh];B[if];W[je];B[jf];W[ke];B[hi];W[gh];B[ei];W[gi];B[gj];W[fj];B[ej];W[fk];B[cf];W[hb];B[jh];W[le];B[lh];W[ii];B[ek];W[fl];B[hl];W[go];B[gn];W[el];B[dl];W[dm];B[cm];W[df];B[dg];W[fo];B[fn];W[ll];B[lm];W[en];B[dn];W[em];B[eo];W[ho];B[io];W[hp];B[ip];W[hq];B[fp];W[in];B[hr];W[cl];B[dk];W[iq];B[jn];W[im];B[jq];W[jo];B[jp];W[hm];B[ir];W[bi];B[bh];W[ch];B[cg];W[bm];B[cn];W[ck];B[bj];W[cj];B[ai];W[bk];B[ci];W[rf];B[dh];W[qg];B[qe];W[pg];B[rh];W[rg];B[ng];W[rd];B[ph];W[bp];B[re];W[se];B[eb];W[lk];B[nk];W[bn];B[bo];W[ao];B[cp];W[bq];B[db];W[ec];B[gb];W[cb];B[ce];W[be];B[bf];W[fc];B[gd];W[fb];B[fa];W[ha];B[ga];W[ae];B[id];W[ie];B[he];W[ic];B[km];W[kn];B[kk];W[kj];B[mn];W[gm];B[gp];W[sf];B[jd];W[jb];B[hj];W[hk];B[ld];W[mc];B[ik];W[jk])", 56 | booklet : true 57 | }); 58 | GoBoardApi.Set_ShowTarget(oGame3, false); 59 | GoBoardApi.Update_Size(oGame3); 60 | } 61 | 62 | if (!oGame4 && (12 === page || 13 === page)) 63 | { 64 | oGame4 = GoBoardApi.Embed("bookGame4", { 65 | boardMode : "viewer", 66 | width : 440, 67 | boardTheme : "BookStyle", 68 | sgfData : "(;EV[The Future of Go Summit, Team Go]RD[2017-05-26];PB[Chen Yaoye, Zhou Ruiyang, Mi Yuting, Shi Yue, Tang Weixing]PW[AlphaGo]SZ[19]KM[7.5];B[pd];W[dd];B[qp];W[dp];B[fq];W[oq];B[cn];W[dn];B[dm];W[en];B[cp];W[cq];B[co];W[dq];B[gp];W[po];B[qo];W[pn];B[qm];W[iq];B[ip];W[jp];B[jq];W[kq];B[jr];W[hq];B[io];W[kr];B[gn];W[do];B[dl];W[fm];B[ci];W[ej];B[di];W[hl];B[il];W[hk];B[im];W[kp];B[jj];W[qc];B[pc];W[qd];B[qf];W[qe];B[pe];W[rf];B[fc];W[hc];B[fe];W[db];B[jc];W[hh];B[eb];W[ce];B[hf];W[if];B[ie];W[id];B[ig];W[jd];B[jf];W[lc];B[rg];W[qg];B[pf];W[rh];B[cb];W[da];B[dc];W[cc];B[ec];W[bb];B[ea];W[ca];B[jb];W[nc];B[ia];W[mf];B[pg];W[sg];B[mh];W[ng];B[qh];W[nh];B[rg];W[qi];B[pi];W[qg];B[ph];W[mi];B[rg];W[ke];B[re];W[qg];B[ba];W[aa];B[rg];W[qn];B[rn];W[qg];B[ne];W[me];B[rg];W[rm];B[rl];W[qg];B[pq];W[pr];B[rg];W[pm];B[sm];W[qg];B[op];W[pp];B[qq];W[nq];B[rg];W[pb];B[ob];W[qg];B[or];W[nr];B[rg];W[qb];B[oc];W[qg];B[fl];W[gm];B[rg];W[cm];B[sf];W[cl];B[ck];W[bn];B[bk];W[bm];B[pl];W[kh];B[om];W[ji];B[li];W[lh];B[mj];W[ni];B[df];W[cf];B[dg];W[oo];B[nj];W[rd];B[pa];W[nb];B[oa];W[gb];B[lb];W[kc];B[ek];W[qr];B[rr];W[lm];B[kl];W[oj];B[oi];W[nl];B[ml];W[nm];B[no];W[np];B[on];W[op];B[ol];W[nk];B[lj];W[nn];B[ok];W[ha];B[mb];W[kb];B[mc];W[md];B[nd];W[la];B[na];W[rs];B[rq];W[bh];B[gj];W[gi];B[fi];W[fh];B[ei];W[hj];B[ln];W[kn];B[mm];W[mn];B[lo];W[mo];B[km];W[er];B[fr];W[lp];B[ll];W[jn];B[hm];W[bi];B[fg];W[gk];B[fj];W[bj];B[ka];W[ja];B[eh];W[cj];B[dj];W[al];B[ka];W[ib];B[ma];W[ic];B[gh];W[hi];B[ak];W[aj];B[ki];W[jh];B[kf];W[lf];B[fo];W[in];B[hn];W[hg];B[gg];W[ir];B[dk];W[bl];B[fs];W[mk];B[lk];W[hp];B[ho];W[gd];B[de];W[ed];B[fd];W[ge];B[gf];W[ee];B[ef];W[cd];B[br];W[bp];)", 69 | booklet : true 70 | }); 71 | GoBoardApi.Set_ShowTarget(oGame4, false); 72 | GoBoardApi.Update_Size(oGame4); 73 | } 74 | 75 | if (!oGame5 && (14 === page || 15 === page)) 76 | { 77 | oGame5 = GoBoardApi.Embed("bookGame5", { 78 | boardMode : "viewer", 79 | width : 440, 80 | boardTheme : "BookStyle", 81 | sgfData : "(;EV[The Future of Go Summit, Match 3]RD[2017-05-27]PB[AlphaGo]WR[9 Dan]PW[Ke Jie]KM[7.5]SZ[19]RE[B+R];B[pp];W[dp];B[pc];W[dd];B[fq];W[cn];B[qh];W[qn];B[qo];W[pn];B[np];W[pk];B[qj];W[eq];B[fp];W[jq];B[lq];W[hq];B[fm];W[nr];B[dm];W[dn];B[en];W[el];B[em];W[bl];B[ck];W[qq];B[pq];W[pr];B[nq];W[pd];B[oc];W[oi];B[rq];W[pg];B[qd];W[qg];B[fr];W[go];B[cq];W[cl];B[dl];W[dk];B[cj];W[dj];B[di];W[fj];B[ch];W[cp];B[dq];W[bi];B[ci];W[ep];B[er];W[bq];B[br];W[hm];B[gi];W[gj];B[hj];W[fi];B[ej];W[rr];B[rp];W[lr];B[kr];W[mr];B[kq];W[jr];B[js];W[or];B[ko];W[jn];B[kn];W[jm];B[ll];W[rm];B[om];W[on];B[nm];W[nn];B[mn];W[qe];B[pe];W[rd];B[od];W[rf];B[gk];W[fk];B[gl];W[kl];B[lk];W[kk];B[gh];W[lj];B[mj];W[kj];B[fc];W[cf];B[db];W[cc];B[fe];W[gd];B[fd];W[cb];B[df];W[gg];B[fh];W[ef];B[de];W[ce];B[jd];W[lc];B[ld];W[gc];B[fb];W[kd];B[ke];W[kc];B[ic];W[le];B[md];W[je];B[kf];W[jf];B[jg];W[kg];B[lf];W[ig];B[jh];W[ih];B[ge];W[he];B[hd];W[ie];B[jc];W[hc];B[hb];W[id];B[gb];W[mo];B[lm];W[no];B[lo];W[nk];B[ir];W[iq];B[hr];W[qb];B[qc];W[rb];B[ql];W[pl];B[pm];W[qm];B[rl];W[ri];B[qk];W[qi];B[rc];W[sc];B[cm];W[bm];B[eo];W[bp];B[rn];W[sm];B[sr];W[ls];B[ks];W[sn];B[rs];W[qr];B[ro];W[qs];B[bk];W[ar];B[cr];W[an];B[mf];W[kh];B[cg];W[pb];B[ob];W[bg];B[bh];W[bf];B[oh];W[ph];B[ni];W[oj];B[ik];W[fg];B[ji];W[ii];B[jj];W[hi];B[il];W[eh];B[ek];W[mh];B[mi];W[ij];B[jk];W[nh];B[li];W[hk];B[hl])", 82 | booklet : true 83 | }); 84 | GoBoardApi.Set_ShowTarget(oGame5, false); 85 | GoBoardApi.Update_Size(oGame5); 86 | } 87 | }); 88 | 89 | document.getElementById("contentsAboutId").addEventListener("click", function() 90 | { 91 | $("#booklet").turn("page", 4); 92 | }, false); 93 | document.getElementById("contentsMatchesId").addEventListener("click", function() 94 | { 95 | $("#booklet").turn("page", 4); 96 | }, false); 97 | document.getElementById("contentsGame1Id").addEventListener("click", function() 98 | { 99 | $("#booklet").turn("page", 6); 100 | }, false); 101 | document.getElementById("contentsGame2Id").addEventListener("click", function() 102 | { 103 | $("#booklet").turn("page", 8); 104 | }, false); 105 | document.getElementById("contentsGame3Id").addEventListener("click", function() 106 | { 107 | $("#booklet").turn("page", 10); 108 | }, false); 109 | document.getElementById("contentsGame4Id").addEventListener("click", function() 110 | { 111 | $("#booklet").turn("page", 12); 112 | }, false); 113 | document.getElementById("contentsGame5Id").addEventListener("click", function() 114 | { 115 | $("#booklet").turn("page", 14); 116 | }, false); 117 | document.getElementById("contentsParticipantsId").addEventListener("click", function() 118 | { 119 | $("#booklet").turn("page", 16); 120 | }, false); 121 | document.getElementById("contentsAlphaGoId").addEventListener("click", function() 122 | { 123 | $("#booklet").turn("page", 18); 124 | }, false); 125 | document.getElementById("contentsKeJieId").addEventListener("click", function() 126 | { 127 | $("#booklet").turn("page", 18); 128 | }, false); 129 | document.getElementById("contentsGuLiId").addEventListener("click", function() 130 | { 131 | $("#booklet").turn("page", 20); 132 | }, false); 133 | document.getElementById("contentsLianXiaoId").addEventListener("click", function() 134 | { 135 | $("#booklet").turn("page", 20); 136 | }, false); 137 | document.getElementById("contentsChenYaoyeId").addEventListener("click", function() 138 | { 139 | $("#booklet").turn("page", 22); 140 | }, false); 141 | document.getElementById("contentsZhouRuiyangId").addEventListener("click", function() 142 | { 143 | $("#booklet").turn("page", 22); 144 | }, false); 145 | document.getElementById("contentsMiYutingId").addEventListener("click", function() 146 | { 147 | $("#booklet").turn("page", 24); 148 | }, false); 149 | document.getElementById("contentsShiYueId").addEventListener("click", function() 150 | { 151 | $("#booklet").turn("page", 24); 152 | }, false); 153 | document.getElementById("contentsTangWeixingId").addEventListener("click", function() 154 | { 155 | $("#booklet").turn("page", 26); 156 | }, false); 157 | } -------------------------------------------------------------------------------- /Src/KGS/Windows/Window.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 03.06.2016 9 | * Time 22:54 10 | */ 11 | 12 | var EKGSWindowType = { 13 | 14 | GoUniverseAbout : -1, 15 | 16 | RoomList : 0, 17 | UserInfo : 1, 18 | RoomInfo : 2, 19 | Information : 3, 20 | Idle : 4, 21 | SgfViewer : 5, 22 | Challenge : 6, 23 | ConfirmBase : 7, 24 | UndoRequest : 8, 25 | AutomatchPr : 9 26 | }; 27 | 28 | var g_aKGSWindows = {}; 29 | var g_nKGSWindowsCount = 0; 30 | var g_sParentDivId = "divIdGoUniverse"; 31 | 32 | function CreateKGSWindow(nWindowType, oPr) 33 | { 34 | var sParentId = g_sParentDivId; 35 | 36 | if (!g_aKGSWindows[sParentId]) 37 | g_aKGSWindows[sParentId] = {}; 38 | 39 | var oWindows = g_aKGSWindows[sParentId]; 40 | 41 | var sApp = "unknownwindow"; 42 | switch (nWindowType) 43 | { 44 | case EKGSWindowType.GoUniverseAbout : 45 | sApp = "GoUniverseAbout"; 46 | break; 47 | case EKGSWindowType.RoomList : 48 | sApp = "RoomList"; 49 | break; 50 | case EKGSWindowType.UserInfo : 51 | sApp = "UserInfo_" + oPr.UserName; 52 | break; 53 | case EKGSWindowType.RoomInfo : 54 | sApp = "RoomInfo_" + oPr.RoomId; 55 | break; 56 | case EKGSWindowType.Information : 57 | sApp = "Information" + (new Date()).getTime(); 58 | break; 59 | case EKGSWindowType.Idle : 60 | sApp = "Idle"; 61 | break; 62 | case EKGSWindowType.SgfViewer : 63 | sApp = "SgfViewer_" + oPr.Url; 64 | break; 65 | case EKGSWindowType.Challenge : 66 | sApp = "Challenge_" + oPr.ChannelId; 67 | break; 68 | case EKGSWindowType.ConfirmBase : 69 | sApp = "ConfirmBase_" + oPr.WindowId; 70 | break; 71 | case EKGSWindowType.UndoRequest: 72 | sApp = "UndoRequest_" + oPr.WindowId; 73 | break; 74 | case EKGSWindowType.AutomatchPr: 75 | sApp = "AutomatchSetup"; 76 | break; 77 | } 78 | var sId = sParentId + sApp; 79 | 80 | if (oWindows[sId]) 81 | { 82 | var oWindow = oWindows[sId]; 83 | oWindow.Show(oPr); 84 | return oWindow; 85 | } 86 | else 87 | { 88 | var oDiv = document.createElement("div"); 89 | oDiv.setAttribute("id", sId); 90 | oDiv.setAttribute("style", "position:absolute;padding:0;margin:0;width:500px;height:500px;left:300px;top:300px;"); 91 | oDiv.setAttribute("oncontextmenu", "return false;"); 92 | 93 | var oContainerDiv = document.getElementById(sParentId); 94 | oContainerDiv.appendChild(oDiv); 95 | 96 | var oWindow = null; 97 | 98 | switch (nWindowType) 99 | { 100 | case EKGSWindowType.GoUniverseAbout : 101 | oWindow = new CGoUniverseAboutWindow(); 102 | break; 103 | case EKGSWindowType.RoomList : 104 | oWindow = new CKGSRoomListWindow(); 105 | break; 106 | case EKGSWindowType.UserInfo : 107 | oWindow = new CKGSUserInfoWindow(); 108 | break; 109 | case EKGSWindowType.RoomInfo : 110 | oWindow = new CKGSRoomInfoWindow(); 111 | break; 112 | case EKGSWindowType.Information : 113 | oWindow = new CKGSInformationWindow(); 114 | break; 115 | case EKGSWindowType.Idle : 116 | oWindow = new CKGSInformationIdleWindow(); 117 | break; 118 | case EKGSWindowType.SgfViewer : 119 | oWindow = new CKGSSgfViewerWindow(); 120 | break; 121 | case EKGSWindowType.Challenge : 122 | oWindow = new CKGSChallengeWindow(); 123 | break; 124 | case EKGSWindowType.ConfirmBase : 125 | oWindow = new CKGSWindowConfirmBase(); 126 | break; 127 | case EKGSWindowType.UndoRequest: 128 | oWindow = new CKGSUndoRequestWindow(); 129 | break; 130 | case EKGSWindowType.AutomatchPr: 131 | oWindow = new CKGSAutomatchSetupWindow(); 132 | break; 133 | } 134 | 135 | oWindows[sId] = oWindow; 136 | 137 | if (null !== oWindow) 138 | { 139 | g_nKGSWindowsCount++; 140 | oWindow.Init(sId, oPr); 141 | oWindow.Update_Size(true); 142 | } 143 | 144 | return oWindow; 145 | } 146 | 147 | return null; 148 | } 149 | 150 | function RemoveWindow(oWindow) 151 | { 152 | var sParentId = g_sParentDivId; 153 | 154 | var sDivId = oWindow.Get_Id(); 155 | var oDiv = document.getElementById(sDivId); 156 | if (oDiv) 157 | { 158 | var oContainerDiv = document.getElementById(sParentId); 159 | oContainerDiv.removeChild(oDiv); 160 | } 161 | 162 | for (var sId in g_aKGSWindows[sParentId]) 163 | { 164 | if (oWindow === g_aKGSWindows[sParentId][sId]) 165 | { 166 | delete g_aKGSWindows[sParentId][sId]; 167 | g_nKGSWindowsCount--; 168 | break; 169 | } 170 | } 171 | } 172 | 173 | function RemoveAllWindows() 174 | { 175 | var sParentId = g_sParentDivId; 176 | 177 | for (var sId in g_aKGSWindows[sParentId]) 178 | { 179 | var oWindow = g_aKGSWindows[sParentId][sId]; 180 | var sDivId = oWindow.Get_Id(); 181 | var oDiv = document.getElementById(sDivId); 182 | if (oDiv) 183 | { 184 | var oContainerDiv = document.getElementById(sParentId); 185 | oContainerDiv.removeChild(oDiv); 186 | } 187 | 188 | delete g_aKGSWindows[sParentId][sId]; 189 | g_nKGSWindowsCount--; 190 | } 191 | 192 | g_aKGSWindows = {}; 193 | g_nKGSWindowsCount = 0; 194 | } 195 | 196 | 197 | function CKGSWindowBase() 198 | { 199 | CKGSWindowBase.superclass.constructor.call(this); 200 | 201 | this.m_oApp = null; 202 | this.m_oClient = null; 203 | } 204 | CommonExtend(CKGSWindowBase, CDrawingWindow); 205 | CKGSWindowBase.prototype.Init = function(sDivId, oPr, bResizeble) 206 | { 207 | CKGSWindowBase.superclass.Init.call(this, sDivId, bResizeble); 208 | this.m_oApp = oPr.App; 209 | this.m_oClient = oPr.Client; 210 | this.private_UpdatePosition(); 211 | this.HtmlElement.Control.HtmlElement.style.zIndex = g_nKGSWindowsCount; 212 | }; 213 | CKGSWindowBase.prototype.private_UpdatePosition = function() 214 | { 215 | if (!this.m_oApp) 216 | return; 217 | 218 | var oWindowDiv = this.HtmlElement.Control.HtmlElement; 219 | 220 | var nWindowW = parseInt(oWindowDiv.style.width); 221 | var nWindowH = parseInt(oWindowDiv.style.height); 222 | 223 | var nX = Math.max(0, ((this.m_oApp.GetWidth() - nWindowW) / 2)); 224 | var nY = Math.max(0, ((this.m_oApp.GetHeight() - nWindowH) / 2)); 225 | 226 | oWindowDiv.style.left = nX + "px"; 227 | oWindowDiv.style.top = nY + "px"; 228 | }; 229 | CKGSWindowBase.prototype.Update_Size = function(bForce) 230 | { 231 | CKGSWindowBase.superclass.Update_Size.call(this, bForce); 232 | 233 | // Проверяем, чтобы окно не вышло за пределы родительского окна 234 | if (this.m_oApp) 235 | { 236 | var nWidth = this.m_oApp.GetWidth(); 237 | var nHeight = this.m_oApp.GetHeight(); 238 | 239 | var nLeft = parseInt(this.HtmlElement.Control.HtmlElement.style.left); 240 | var nTop = parseInt(this.HtmlElement.Control.HtmlElement.style.top); 241 | 242 | if (nLeft <= 0) 243 | this.HtmlElement.Control.HtmlElement.style.left = "0px"; 244 | else if (nLeft >= nWidth - 20) 245 | this.HtmlElement.Control.HtmlElement.style.left = (nLeft - 20) + "px"; 246 | 247 | if (nTop <= 0) 248 | this.HtmlElement.Control.HtmlElement.style.top = "0px"; 249 | else if (nTop >= nHeight - 20) 250 | this.HtmlElement.Control.HtmlElement.style.top = (nHeight - 20) + "px"; 251 | } 252 | }; 253 | CKGSWindowBase.prototype.Focus = function() 254 | { 255 | this.private_OnFocus(); 256 | }; 257 | CKGSWindowBase.prototype.private_OnFocus = function() 258 | { 259 | // Вообще говоря, данную функцию надо бы перенести в самый базовый класс, и все окна собирать вместе в объект g_aWindows 260 | 261 | // Делаем данное окно верхним среди всех окон КГС 262 | if (this.m_oApp) 263 | { 264 | var nCurZIndex = parseInt(this.HtmlElement.Control.HtmlElement.style.zIndex); 265 | 266 | var sParentId = g_sParentDivId; 267 | for (var sId in g_aKGSWindows[sParentId]) 268 | { 269 | var oWindow = g_aKGSWindows[sParentId][sId]; 270 | var nZIndex = parseInt(oWindow.HtmlElement.Control.HtmlElement.style.zIndex); 271 | 272 | if (nZIndex >= nCurZIndex) 273 | oWindow.HtmlElement.Control.HtmlElement.style.zIndex = (nZIndex - 1); 274 | } 275 | this.HtmlElement.Control.HtmlElement.style.zIndex = g_nKGSWindowsCount; 276 | } 277 | }; 278 | 279 | function CKGSWindowOKBase() 280 | { 281 | CKGSWindowBase.superclass.constructor.call(this); 282 | 283 | this.m_oApp = null; 284 | } 285 | CommonExtend(CKGSWindowOKBase, CDrawingConfirmWindow); 286 | CKGSWindowOKBase.prototype.Init = function(sDivId, oPr, bResizeable) 287 | { 288 | CKGSWindowOKBase.superclass.Init.call(this, sDivId, bResizeable); 289 | this.m_oApp = oPr.App; 290 | this.m_oClient = oPr.Client; 291 | this.private_UpdatePosition(); 292 | this.HtmlElement.Control.HtmlElement.style.zIndex = g_nKGSWindowsCount; 293 | 294 | this.HtmlElement.CancelButton.HtmlElement.Control.HtmlElement.style.display = "none"; 295 | this.HtmlElement.OkButtonControl.Bounds.SetParams(0, 9, 11, 1000, false, true, true, false, 66, 21); 296 | }; 297 | CKGSWindowOKBase.prototype.Update_Size = function(bForce) 298 | { 299 | CKGSWindowOKBase.superclass.Update_Size.call(this, bForce); 300 | 301 | // Проверяем, чтобы окно не вышло за пределы родительского окна 302 | if (this.m_oApp) 303 | { 304 | var nWidth = this.m_oApp.GetWidth(); 305 | var nHeight = this.m_oApp.GetHeight(); 306 | 307 | var nLeft = parseInt(this.HtmlElement.Control.HtmlElement.style.left); 308 | var nTop = parseInt(this.HtmlElement.Control.HtmlElement.style.top); 309 | 310 | if (nLeft <= 0) 311 | this.HtmlElement.Control.HtmlElement.style.left = "0px"; 312 | else if (nLeft >= nWidth - 20) 313 | this.HtmlElement.Control.HtmlElement.style.left = (nLeft - 20) + "px"; 314 | 315 | if (nTop <= 0) 316 | this.HtmlElement.Control.HtmlElement.style.top = "0px"; 317 | else if (nTop >= nHeight - 20) 318 | this.HtmlElement.Control.HtmlElement.style.top = (nHeight - 20) + "px"; 319 | } 320 | }; 321 | CKGSWindowOKBase.prototype.private_UpdatePosition = CKGSWindowBase.prototype.private_UpdatePosition; 322 | CKGSWindowOKBase.prototype.private_OnFocus = CKGSWindowBase.prototype.private_OnFocus; 323 | 324 | function CKGSWindowConfirmBase() 325 | { 326 | CKGSWindowBase.superclass.constructor.call(this); 327 | 328 | this.m_oApp = null; 329 | this.m_oClient = null; 330 | this.m_fOkHandler = null; 331 | 332 | this.m_nDefW = 200; 333 | this.m_nDefH = 100; 334 | } 335 | CommonExtend(CKGSWindowConfirmBase, CDrawingConfirmWindow); 336 | CKGSWindowConfirmBase.prototype.Init = function(sDivId, oPr) 337 | { 338 | if (oPr.H) 339 | this.m_nDefH = oPr.H; 340 | 341 | if (oPr.W) 342 | this.m_nDefW = oPr.W; 343 | 344 | CKGSWindowConfirmBase.superclass.Init.call(this, sDivId, oPr.Resizeable); 345 | this.m_oApp = oPr.App; 346 | this.m_oClient = oPr.Client; 347 | this.private_UpdatePosition(); 348 | this.HtmlElement.Control.HtmlElement.style.zIndex = g_nKGSWindowsCount; 349 | 350 | this.Set_Caption(g_oLocalization.KGS.window.common.captionGameWarning); 351 | 352 | if (oPr.Text) 353 | { 354 | var oMainDiv = this.HtmlElement.ConfirmInnerDiv; 355 | var oMainControl = this.HtmlElement.ConfirmInnerControl; 356 | oMainDiv.style.backgroundColor = "rgb(243, 243, 243)"; 357 | 358 | var oTextElement = oMainDiv; 359 | oTextElement.style.display = "table"; 360 | var oInnerText = document.createElement("div"); 361 | oInnerText.className = "WarningText"; 362 | oTextElement.appendChild(oInnerText); 363 | Common.Set_InnerTextToElement(oInnerText, oPr.Text); 364 | } 365 | 366 | if (oPr.OkHandler) 367 | this.m_fOkHandler = oPr.OkHandler; 368 | }; 369 | CKGSWindowConfirmBase.prototype.Update_Size = function(bForce) 370 | { 371 | CKGSWindowConfirmBase.superclass.Update_Size.call(this, bForce); 372 | 373 | // Проверяем, чтобы окно не вышло за пределы родительского окна 374 | if (this.m_oApp) 375 | { 376 | var nWidth = this.m_oApp.GetWidth(); 377 | var nHeight = this.m_oApp.GetHeight(); 378 | 379 | var nLeft = parseInt(this.HtmlElement.Control.HtmlElement.style.left); 380 | var nTop = parseInt(this.HtmlElement.Control.HtmlElement.style.top); 381 | 382 | if (nLeft <= 0) 383 | this.HtmlElement.Control.HtmlElement.style.left = "0px"; 384 | else if (nLeft >= nWidth - 20) 385 | this.HtmlElement.Control.HtmlElement.style.left = (nLeft - 20) + "px"; 386 | 387 | if (nTop <= 0) 388 | this.HtmlElement.Control.HtmlElement.style.top = "0px"; 389 | else if (nTop >= nHeight - 20) 390 | this.HtmlElement.Control.HtmlElement.style.top = (nHeight - 20) + "px"; 391 | } 392 | }; 393 | CKGSWindowConfirmBase.prototype.Handle_OK = function() 394 | { 395 | if (this.m_fOkHandler) 396 | this.m_fOkHandler(); 397 | 398 | this.Close(); 399 | }; 400 | CKGSWindowConfirmBase.prototype.Close = function() 401 | { 402 | RemoveWindow(this); 403 | }; 404 | CKGSWindowConfirmBase.prototype.Get_DefaultWindowSize = function() 405 | { 406 | return { 407 | W : this.m_nDefW, 408 | H : this.m_nDefH 409 | }; 410 | }; 411 | CKGSWindowConfirmBase.prototype.private_UpdatePosition = CKGSWindowBase.prototype.private_UpdatePosition; 412 | CKGSWindowConfirmBase.prototype.private_OnFocus = CKGSWindowBase.prototype.private_OnFocus; -------------------------------------------------------------------------------- /Src/KGS/InGamePlayersList.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 06.07.2016 9 | * Time 1:06 10 | */ 11 | 12 | var EKGSInGamePlayersListRecord = { 13 | Type : 1, 14 | Name : 2, 15 | Rank : 3 16 | }; 17 | 18 | function CKGSInGamePlayersList(oApp, nGameId) 19 | { 20 | CKGSInGamePlayersList.superclass.constructor.call(this); 21 | 22 | this.m_oApp = oApp; 23 | 24 | this.m_oHeaders = { 25 | Sizes : [0, 20, 125], 26 | Count : 3, 27 | 1 : "", 28 | 2 : g_oLocalization.mainRoom.playersList.listHeaderName, 29 | 3 : g_oLocalization.mainRoom.playersList.listHeaderRank 30 | }; 31 | 32 | this.m_nSortType = -EKGSInGamePlayersListRecord.Rank; 33 | 34 | this.m_oBlack = null; 35 | this.m_oWhite = null; 36 | this.m_oOwner = null; 37 | this.m_oEditor = null; 38 | this.m_oBlack2 = null; 39 | this.m_oWhite2 = null; 40 | 41 | this.m_sUserName = oApp.GetClient().GetUserName(); 42 | this.m_nGameId = nGameId; 43 | } 44 | 45 | CommonExtend(CKGSInGamePlayersList, CListBase); 46 | 47 | CKGSInGamePlayersList.prototype.private_PreSort = function(oRecord1, oRecord2) 48 | { 49 | if (true === oRecord1.IsEditor() && true !== oRecord2.IsEditor()) 50 | return -1; 51 | if (true !== oRecord1.IsEditor() && true === oRecord2.IsEditor()) 52 | return 1; 53 | 54 | if (true === oRecord1.IsGameParticipant() && true !== oRecord2.IsGameParticipant()) 55 | return -1; 56 | if (true !== oRecord1.IsGameParticipant() && true === oRecord2.IsGameParticipant()) 57 | return 1; 58 | 59 | if (true === oRecord1.IsFriend() && true !== oRecord2.IsFriend()) 60 | return -1; 61 | 62 | if (true !== oRecord1.IsFriend() && true === oRecord2.IsFriend()) 63 | return 1; 64 | 65 | return 0; 66 | }; 67 | CKGSInGamePlayersList.prototype.private_PostSort = function(oRecord1, oRecord2) 68 | { 69 | // Сортируем по рейтингу, потом по имени 70 | if (oRecord1.m_nRank < oRecord2.m_nRank) 71 | return 1; 72 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 73 | return -1; 74 | 75 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 76 | return -1; 77 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 78 | return 1; 79 | 80 | // Сюда мы уже не должны попадать, потому что имена игроков не должны совпадать 81 | return 0; 82 | }; 83 | CKGSInGamePlayersList.prototype.private_Sort = function(oRecord1, oRecord2) 84 | { 85 | var nSortType = this.m_nSortType; 86 | if (EKGSInGamePlayersListRecord.Name === nSortType) 87 | { 88 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 89 | return -1; 90 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 91 | return 1; 92 | } 93 | else if (-EKGSInGamePlayersListRecord.Name === nSortType) 94 | { 95 | if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) < 0) 96 | return 1; 97 | else if (Common.Compare_Strings(oRecord1.m_sName, oRecord2.m_sName) > 0) 98 | return -1; 99 | } 100 | else if (EKGSInGamePlayersListRecord.Rank === nSortType) 101 | { 102 | if (oRecord1.m_nRank < oRecord2.m_nRank) 103 | return -1; 104 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 105 | return 1; 106 | } 107 | else if (-EKGSInGamePlayersListRecord.Rank === nSortType) 108 | { 109 | if (oRecord1.m_nRank < oRecord2.m_nRank) 110 | return 1; 111 | else if (oRecord1.m_nRank > oRecord2.m_nRank) 112 | return -1; 113 | } 114 | 115 | return 0; 116 | }; 117 | CKGSInGamePlayersList.prototype.Is_Sortable = function(nColNum) 118 | { 119 | if (0 !== nColNum) 120 | return true; 121 | 122 | return false; 123 | }; 124 | CKGSInGamePlayersList.prototype.Get_Record = function(aLine) 125 | { 126 | var oRecord = new CKGSInGamePlayersListRecord(this, this.m_oApp.GetClient()); 127 | oRecord.Update(aLine); 128 | return oRecord; 129 | }; 130 | CKGSInGamePlayersList.prototype.Handle_DoubleClick = function(Record) 131 | { 132 | if (this.m_oApp && this.m_oApp.GetClient()) 133 | { 134 | this.m_oApp.GetClient().EnterPrivateChat(Record.m_sName); 135 | } 136 | }; 137 | CKGSInGamePlayersList.prototype.Handle_RightClick = function(Record, e) 138 | { 139 | if (this.m_oApp && Record) 140 | { 141 | var nX = e.pageX, nY = e.pageY; 142 | var sUserName = Record.m_sName; 143 | var oClient = this.m_oApp.GetClient(); 144 | 145 | var oContextMenu = new CVisualContextMenu(this.m_oApp, nX, nY); 146 | var oThis = this; 147 | oContextMenu.AddCheckBoxItem(false, g_oLocalization.mainRoom.playersList.contextMenuTalkTo, function() 148 | { 149 | oClient.EnterPrivateChat(sUserName); 150 | }); 151 | oContextMenu.AddCheckBoxItem(false, g_oLocalization.mainRoom.playersList.contextMenuViewInfo, function() 152 | { 153 | oClient.LoadUserInfo(sUserName); 154 | }); 155 | oContextMenu.AddCheckBoxItem(false, g_oLocalization.mainRoom.playersList.contextMenuGiveControl, function() 156 | { 157 | oClient.GiveGameControl(oThis.m_nGameId, sUserName); 158 | }, (this.IsOwner(this.m_sUserName) || (this.IsEditor(this.m_sUserName) && this.IsOwner(sUserName)) ? false : true)); 159 | oContextMenu.AddHorizontalLine(); 160 | oContextMenu.AddCheckBoxItem(oClient.IsUserInFriendList(sUserName), g_oLocalization.mainRoom.playersList.contextMenuFriend, function() 161 | { 162 | if (oClient.IsUserInFriendList(sUserName)) 163 | oClient.RemoveFromFriendList(sUserName); 164 | else 165 | oClient.AddToFriendList(sUserName); 166 | }); 167 | oContextMenu.AddCheckBoxItem(oClient.IsUserInBlackList(sUserName), g_oLocalization.mainRoom.playersList.contextMenuCensored, function() 168 | { 169 | if (oClient.IsUserInBlackList(sUserName)) 170 | oClient.RemoveFromBlackList(sUserName); 171 | else 172 | oClient.AddToBlackList(sUserName); 173 | }); 174 | oContextMenu.AddCheckBoxItem(oClient.IsUserInFollowerList(sUserName), g_oLocalization.mainRoom.playersList.contextMenuFollow, function() 175 | { 176 | if (oClient.IsUserInFollowerList(sUserName)) 177 | oClient.RemoveFromFollowerList(sUserName); 178 | else 179 | oClient.AddToFollowerList(sUserName); 180 | }); 181 | oContextMenu.AddHorizontalLine(); 182 | oContextMenu.AddCheckBoxItem(false, g_oLocalization.mainRoom.playersList.contextMenuCopyLink, function() 183 | { 184 | var sMessage = "\\user=" + sUserName + ";"; 185 | 186 | var oCurrentTab = oThis.m_oApp.m_oGameRoomTabs.GetCurrent(); 187 | if (oCurrentTab) 188 | { 189 | var oInputArea = oCurrentTab.GetChatInputElement(); 190 | if (oInputArea) 191 | { 192 | if ("" !== oInputArea.value && ' ' !== oInputArea.value.charAt(oInputArea.value.length - 1)) 193 | oInputArea.value += " "; 194 | 195 | oInputArea.value += sMessage + " "; 196 | oInputArea.focus(); 197 | } 198 | } 199 | }); 200 | oContextMenu.Show(); 201 | 202 | return oContextMenu; 203 | } 204 | }; 205 | CKGSInGamePlayersList.prototype.SetBlack = function(oUser) 206 | { 207 | this.m_oBlack = oUser; 208 | }; 209 | CKGSInGamePlayersList.prototype.SetWhite = function(oUser) 210 | { 211 | this.m_oWhite = oUser; 212 | }; 213 | CKGSInGamePlayersList.prototype.SetOwner = function(oUser) 214 | { 215 | this.m_oOwner = oUser; 216 | }; 217 | CKGSInGamePlayersList.prototype.SetEditor = function(oUser) 218 | { 219 | this.m_oEditor = oUser; 220 | }; 221 | CKGSInGamePlayersList.prototype.IsBlack = function(sUserName) 222 | { 223 | if ((this.m_oBlack && sUserName === this.m_oBlack.GetName()) 224 | || (this.m_oBlack2 && sUserName === this.m_oBlack2.GetName())) 225 | return true; 226 | 227 | return false; 228 | }; 229 | CKGSInGamePlayersList.prototype.SetBlack2 = function(oUser) 230 | { 231 | this.m_oBlack2 = oUser; 232 | }; 233 | CKGSInGamePlayersList.prototype.SetWhite2 = function(oUser) 234 | { 235 | this.m_oWhite2 = oUser; 236 | }; 237 | CKGSInGamePlayersList.prototype.IsWhite = function(sUserName) 238 | { 239 | if ((this.m_oWhite && sUserName === this.m_oWhite.GetName()) 240 | || (this.m_oWhite2 && sUserName === this.m_oWhite2.GetName())) 241 | return true; 242 | 243 | return false; 244 | }; 245 | CKGSInGamePlayersList.prototype.IsOwner = function(sUserName) 246 | { 247 | if (this.m_oOwner && sUserName === this.m_oOwner.GetName()) 248 | return true; 249 | 250 | return false; 251 | }; 252 | CKGSInGamePlayersList.prototype.IsEditor = function(sUserName) 253 | { 254 | if (this.m_oEditor && sUserName === this.m_oEditor.GetName()) 255 | return true; 256 | 257 | return false; 258 | }; 259 | CKGSInGamePlayersList.prototype.GetVerLinesPositions = function() 260 | { 261 | return [2]; 262 | }; 263 | CKGSInGamePlayersList.prototype.SetGameId = function(nGameId) 264 | { 265 | this.m_nGameId = nGameId; 266 | }; 267 | 268 | function CKGSInGamePlayersListRecord(oListObject, oClient) 269 | { 270 | CKGSInGamePlayersListRecord.superclass.constructor.call(this); 271 | 272 | this.m_oListObject = oListObject; 273 | this.m_oClient = oClient; 274 | this.m_sName = ""; 275 | this.m_nRank = 0; 276 | this.m_oUser = null; 277 | } 278 | 279 | CommonExtend(CKGSInGamePlayersListRecord, CListRecordBase); 280 | 281 | CKGSInGamePlayersListRecord.prototype.Draw = function(oContext, dX, dY, eType) 282 | { 283 | var oClient = this.m_oClient; 284 | var sFont = oContext.font; 285 | 286 | if (true !== this.m_oUser.IsSleeping()) 287 | oContext.fillStyle = "#000000"; 288 | else 289 | oContext.fillStyle = "#AAAAAA"; 290 | 291 | var bResetFont = false; 292 | if (oClient && EKGSInGamePlayersListRecord.Type !== eType) 293 | { 294 | if (true === oClient.IsUserInFollowerList(this.m_sName)) 295 | { 296 | if (true !== this.m_oUser.IsSleeping()) 297 | oContext.fillStyle = "#008272"; 298 | else 299 | oContext.fillStyle = "#99C9C3"; 300 | 301 | oContext.font = "bold " + sFont; 302 | } 303 | else if (true === this.m_oUser.IsFriend()) 304 | { 305 | oContext.font = "bold " + sFont; 306 | } 307 | 308 | bResetFont = true; 309 | } 310 | else if (oClient && EKGSInGamePlayersListRecord.Type === eType) 311 | { 312 | oContext.font = "12px 'NotoEmoji'"; 313 | bResetFont = true; 314 | } 315 | 316 | var sString = ""; 317 | switch(eType) 318 | { 319 | case EKGSInGamePlayersListRecord.Type : sString += this.private_GetUserType(oContext); break; 320 | case EKGSInGamePlayersListRecord.Name : sString += this.m_sName; break; 321 | case EKGSInGamePlayersListRecord.Rank : sString += this.private_GetRank(this.m_nRank); break; 322 | } 323 | 324 | oContext.fillText(sString, dX, dY); 325 | 326 | if (eType === EKGSInGamePlayersListRecord.Type && "" !== sString) 327 | oContext.strokeText(sString, dX, dY); 328 | 329 | if (oClient) 330 | { 331 | if (true === oClient.IsUserInBlackList(this.m_sName) && eType === EKGSInGamePlayersListRecord.Name) 332 | { 333 | var dOldLineWidth = oContext.lineWidth; 334 | var sOldStrokeStyle = oContext.strokeStyle; 335 | 336 | oContext.lineWidth = 1; 337 | oContext.strokeStyle = "#000"; 338 | 339 | var dTextW = oContext.measureText(sString).width; 340 | var dX0 = (dX | 0) + 0.5; 341 | var dY0 = ((dY - 4) | 0) + 0.5; 342 | var dX1 = ((dX + dTextW) | 0) + 0.5; 343 | 344 | oContext.beginPath(); 345 | oContext.moveTo(dX0, dY0); 346 | oContext.lineTo(dX1, dY0); 347 | oContext.stroke(); 348 | 349 | oContext.lineWidth = dOldLineWidth; 350 | oContext.strokeStyle = sOldStrokeStyle; 351 | } 352 | } 353 | 354 | if (true === bResetFont) 355 | oContext.font = sFont; 356 | }; 357 | CKGSInGamePlayersListRecord.prototype.Get_Key = function() 358 | { 359 | return this.m_sName; 360 | }; 361 | CKGSInGamePlayersListRecord.prototype.Update = function(aLine) 362 | { 363 | this.m_sName = aLine[1]; 364 | this.m_oUser = aLine[2]; 365 | this.m_nRank = this.m_oUser.GetRank(); 366 | }; 367 | CKGSInGamePlayersListRecord.prototype.Compare = function(sName) 368 | { 369 | if (this.m_sName === sName) 370 | return true; 371 | 372 | return false; 373 | }; 374 | CKGSInGamePlayersListRecord.prototype.private_GetRank = function(nRank) 375 | { 376 | if (nRank <= -2) 377 | return "?"; 378 | else if (nRank === -1) 379 | return "-"; 380 | else if (nRank <= 29) 381 | return (30 - nRank) + "k"; 382 | else if (nRank <= 49) 383 | return (nRank - 29) + "d"; 384 | else 385 | return (nRank - 49) + "p"; 386 | }; 387 | CKGSInGamePlayersListRecord.prototype.IsFriend = function() 388 | { 389 | return this.m_oClient.IsUserInFriendList(this.m_sName); 390 | }; 391 | CKGSInGamePlayersListRecord.prototype.private_GetUserType = function(oContext) 392 | { 393 | if (this.m_oListObject.IsEditor(this.m_sName)) 394 | { 395 | oContext.fillStyle = "#FFF"; 396 | oContext.strokeStyle = "#000"; 397 | return String.fromCharCode(0x270E); 398 | } 399 | else if (this.m_oListObject.IsOwner(this.m_sName)) 400 | { 401 | oContext.fillStyle = "transparent"; 402 | oContext.strokeStyle = "#000"; 403 | return EncodeSurrogateChar(0x1F4FA); 404 | } 405 | else if (this.m_oListObject.IsBlack(this.m_sName)) 406 | { 407 | oContext.fillStyle = "#000"; 408 | oContext.strokeStyle = "#000"; 409 | return EncodeSurrogateChar(0x1F311); 410 | } 411 | else if (this.m_oListObject.IsWhite(this.m_sName)) 412 | { 413 | oContext.fillStyle = "#FFF"; 414 | oContext.strokeStyle = "#000"; 415 | return EncodeSurrogateChar(0x1F311); 416 | } 417 | 418 | return ""; 419 | }; 420 | CKGSInGamePlayersListRecord.prototype.IsEditor = function() 421 | { 422 | return this.m_oListObject.IsEditor(this.m_sName); 423 | }; 424 | CKGSInGamePlayersListRecord.prototype.IsGameParticipant = function() 425 | { 426 | if (this.m_oListObject.IsBlack(this.m_sName) 427 | || this.m_oListObject.IsWhite(this.m_sName) 428 | || this.m_oListObject.IsOwner(this.m_sName) 429 | || this.m_oListObject.IsEditor(this.m_sName)) 430 | return true; 431 | 432 | return false; 433 | }; -------------------------------------------------------------------------------- /Src/Common/GameTimer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 30.06.2016 9 | * Time 0:27 10 | */ 11 | 12 | function CGoUniverseTime() 13 | { 14 | this.m_nSeconds = 0; 15 | this.m_nCurSeconds = 0; 16 | 17 | this.m_nStartTime = 0; 18 | this.m_nTimerId = null; 19 | 20 | this.m_fOnTick = null; 21 | this.m_fOnEnd = null; 22 | } 23 | CGoUniverseTime.prototype.SetHandler = function(fOnTick, fOnEnd) 24 | { 25 | this.m_fOnTick = fOnTick; 26 | this.m_fOnEnd = fOnEnd; 27 | }; 28 | CGoUniverseTime.prototype.Start = function(s) 29 | { 30 | this.m_nSeconds = s; 31 | 32 | if (null !== this.m_nTimerId) 33 | clearTimeout(this.m_nTimerId); 34 | 35 | this.m_nStartTime = new Date().getTime(); 36 | 37 | var oThis = this; 38 | this.m_nTimerId = setTimeout(function(){oThis.private_Tick();}, 50); 39 | }; 40 | CGoUniverseTime.prototype.private_Tick = function() 41 | { 42 | if (null === this.m_nTimerId) 43 | return; 44 | 45 | var oThis = this; 46 | this.m_nTimerId = setTimeout(function(){oThis.private_Tick();}, 50); 47 | 48 | var nCurTime = new Date().getTime(); 49 | 50 | var nDiffTime = (nCurTime - this.m_nStartTime) / 1000; 51 | 52 | this.m_nCurSeconds = this.m_nSeconds - nDiffTime; 53 | 54 | if (this.m_nCurSeconds < 0.1) 55 | { 56 | this.Stop(); 57 | this.m_fOnEnd(); 58 | } 59 | 60 | if (this.m_fOnTick) 61 | this.m_fOnTick(this.m_nCurSeconds); 62 | }; 63 | CGoUniverseTime.prototype.Stop = function() 64 | { 65 | if (null !== this.m_nTimerId) 66 | clearTimeout(this.m_nTimerId); 67 | 68 | this.m_nTimerId = null; 69 | }; 70 | CGoUniverseTime.prototype.IsTick = function() 71 | { 72 | return (this.m_nTimerId === null ? false : true); 73 | }; 74 | 75 | var ETimeSettings = { 76 | None : 0, 77 | Absolute : 1, 78 | ByoYomi : 2, 79 | Canadian : 3 80 | }; 81 | function CTimeSettings() 82 | { 83 | this.m_nType = ETimeSettings.None; 84 | this.m_nMainTime = 0; 85 | this.m_nOverTime = 0; 86 | this.m_nOverTimeCur = 0; 87 | this.m_nOverCount = 1; 88 | this.m_nOverCountCur = 1; 89 | this.m_oTimer = new CGoUniverseTime(); 90 | this.m_bEnd = false; 91 | 92 | this.m_fOnTick = null; 93 | 94 | var oThis = this; 95 | this.m_oTimer.SetHandler(function(s) 96 | { 97 | oThis.private_OnTickTimer(s); 98 | }, function() 99 | { 100 | oThis.private_OnStopTimer(); 101 | }); 102 | } 103 | CTimeSettings.prototype.SetOnTick = function(fOnTick) 104 | { 105 | this.m_fOnTick = fOnTick; 106 | }; 107 | CTimeSettings.prototype.SetOnStop = function(fOnStop) 108 | { 109 | this.m_fOnStop = fOnStop; 110 | }; 111 | CTimeSettings.prototype.SetNone = function() 112 | { 113 | this.m_nType = ETimeSettings.None; 114 | this.m_nMainTime = 0; 115 | this.m_nOverTime = 0; 116 | this.m_nOverCount = 1; 117 | }; 118 | CTimeSettings.prototype.SetAbsolute = function(nTime) 119 | { 120 | this.m_nType = ETimeSettings.Absolute; 121 | this.m_nMainTime = nTime ? nTime : 0; 122 | }; 123 | CTimeSettings.prototype.SetByoYomi = function(nMainTime, nByoyomiTime, nByoyomiCount) 124 | { 125 | this.m_nType = ETimeSettings.ByoYomi; 126 | this.m_nMainTime = nMainTime ? nMainTime : 0; 127 | this.m_nOverTime = nByoyomiTime ? nByoyomiTime : 0; 128 | this.m_nOverCount = nByoyomiCount ? nByoyomiCount : 1; 129 | this.m_nOverTimeCur = this.m_nOverTime; 130 | this.m_nOverCountCur = this.m_nOverCount; 131 | }; 132 | CTimeSettings.prototype.SetCanadian = function(nMainTime, nOverTime, nMovesCount) 133 | { 134 | this.m_nType = ETimeSettings.Canadian; 135 | this.m_nMainTime = nMainTime ? nMainTime : 0; 136 | this.m_nOverTime = nOverTime ? nOverTime : 0; 137 | this.m_nOverCount = nMovesCount ? nMovesCount : 1; 138 | this.m_nOverTimeCur = this.m_nOverTime; 139 | this.m_nOverCountCur = this.m_nOverCount; 140 | }; 141 | CTimeSettings.prototype.CorrectMainTime = function(nTime) 142 | { 143 | if (nTime > 0) 144 | { 145 | if (this.m_oTimer.IsTick()) 146 | this.m_oTimer.Start(nTime); 147 | 148 | this.m_nOverTimeCur = this.m_nOverTime; 149 | this.m_nOverCountCur = this.m_nOverCount; 150 | } 151 | 152 | this.m_nMainTime = nTime; 153 | }; 154 | CTimeSettings.prototype.CorrectOverTime = function(nOverTime, nOverCount) 155 | { 156 | if (this.m_oTimer.IsTick()) 157 | this.m_oTimer.Start(nOverTime); 158 | 159 | this.m_nOverTimeCur = nOverTime; 160 | this.m_nOverCountCur = nOverCount; 161 | }; 162 | CTimeSettings.prototype.Start = function() 163 | { 164 | if (true === this.m_bEnd || this.m_oTimer.IsTick()) 165 | return; 166 | 167 | if (this.m_fOnTick) 168 | this.m_fOnTick(this.ToString()); 169 | 170 | switch (this.m_nType) 171 | { 172 | case ETimeSettings.None: 173 | { 174 | break; 175 | } 176 | case ETimeSettings.Absolute: 177 | { 178 | this.m_oTimer.Start(this.m_nMainTime); 179 | break; 180 | } 181 | case ETimeSettings.ByoYomi: 182 | case ETimeSettings.Canadian: 183 | { 184 | if (this.m_nMainTime > 0) 185 | this.m_oTimer.Start(this.m_nMainTime); 186 | else 187 | this.m_oTimer.Start(this.m_nOverTimeCur); 188 | break; 189 | } 190 | } 191 | }; 192 | CTimeSettings.prototype.Stop = function(bEnd) 193 | { 194 | if (true === this.m_bEnd) 195 | return; 196 | 197 | if (this.m_fOnTick) 198 | this.m_fOnTick(this.ToString()); 199 | 200 | this.m_oTimer.Stop(); 201 | 202 | if (true === bEnd) 203 | this.m_bEnd = true; 204 | }; 205 | CTimeSettings.prototype.private_OnTickTimer = function(nSecondsLeft) 206 | { 207 | switch (this.m_nType) 208 | { 209 | case ETimeSettings.Absolute: 210 | { 211 | this.m_nMainTime = Math.max(0, nSecondsLeft); 212 | 213 | if (this.m_fOnTick) 214 | this.m_fOnTick(this.private_SecondsToString(this.m_nMainTime, 10) + " SD"); 215 | 216 | break; 217 | } 218 | case ETimeSettings.ByoYomi: 219 | { 220 | if (this.m_nMainTime > 0) 221 | { 222 | this.m_nMainTime = Math.max(0, nSecondsLeft); 223 | if (this.m_fOnTick) 224 | this.m_fOnTick(this.private_SecondsToString(this.m_nMainTime)); 225 | } 226 | else 227 | { 228 | this.m_nOverTimeCur = Math.max(0, nSecondsLeft); 229 | if (this.m_fOnTick) 230 | this.m_fOnTick(this.private_SecondsToString(nSecondsLeft, 3) + " (" + this.m_nOverCountCur + ")"); 231 | } 232 | 233 | break; 234 | } 235 | case ETimeSettings.Canadian: 236 | { 237 | if (this.m_nMainTime > 0) 238 | { 239 | this.m_nMainTime = Math.max(0, nSecondsLeft); 240 | if (this.m_fOnTick) 241 | this.m_fOnTick(this.private_SecondsToString(this.m_nMainTime)); 242 | } 243 | else 244 | { 245 | this.m_nOverTimeCur = Math.max(0, nSecondsLeft); 246 | if (this.m_fOnTick) 247 | this.m_fOnTick(this.private_SecondsToString(nSecondsLeft, 3) + "/" + this.m_nOverCountCur); 248 | } 249 | break; 250 | } 251 | } 252 | }; 253 | CTimeSettings.prototype.private_OnStopTimer = function() 254 | { 255 | switch (this.m_nType) 256 | { 257 | case ETimeSettings.Absolute: 258 | { 259 | this.m_nMainTime = 0; 260 | 261 | if (this.m_fOnStop) 262 | this.m_fOnStop(); 263 | 264 | break; 265 | } 266 | case ETimeSettings.ByoYomi: 267 | { 268 | if (this.m_nMainTime > 0) 269 | { 270 | this.m_nMainTime = 0; 271 | this.m_oTimer.Stop(); 272 | this.m_oTimer.Start(this.m_nOverTime); 273 | } 274 | else 275 | { 276 | if (this.m_nOverCountCur > 1) 277 | { 278 | this.m_nOverCountCur--; 279 | this.m_oTimer.Stop(); 280 | this.m_oTimer.Start(this.m_nOverTime); 281 | } 282 | else 283 | { 284 | if (this.m_fOnStop) 285 | this.m_fOnStop(); 286 | } 287 | } 288 | 289 | break; 290 | } 291 | case ETimeSettings.Canadian: 292 | { 293 | if (this.m_nMainTime > 0) 294 | { 295 | this.m_nMainTime = 0; 296 | this.m_nOverTimeCur = this.m_nOverTime; 297 | this.m_oTimer.Stop(); 298 | this.m_oTimer.Start(this.m_nOverTimeCur); 299 | } 300 | else 301 | { 302 | if (this.m_fOnStop) 303 | this.m_fOnStop(); 304 | } 305 | break; 306 | } 307 | } 308 | }; 309 | CTimeSettings.prototype.IsNone = function() 310 | { 311 | return (this.m_nType === ETimeSettings.None ? true : false); 312 | }; 313 | CTimeSettings.prototype.IsAbsolute = function() 314 | { 315 | return (this.m_nType === ETimeSettings.Absolute ? true : false); 316 | }; 317 | CTimeSettings.prototype.IsByoYomi = function() 318 | { 319 | return (this.m_nType === ETimeSettings.ByoYomi ? true : false); 320 | }; 321 | CTimeSettings.prototype.IsCanadian = function() 322 | { 323 | return (this.m_nType === ETimeSettings.Canadian ? true : false); 324 | }; 325 | CTimeSettings.prototype.private_SecondsToString = function(_seconds, _msThreshold) 326 | { 327 | var nHours = Math.floor(_seconds / 3600); 328 | var nMinutes = Math.floor((_seconds - (nHours * 3600)) / 60); 329 | var nSeconds = Math.floor(_seconds - (nHours * 3600) - (nMinutes * 60)); 330 | var nMSeconds = (_seconds - (nSeconds + (nHours * 3600) + (nMinutes * 60))) * 10 | 0; 331 | 332 | var sHours = "" + nHours; 333 | var sMinutes = (nHours > 0 && nMinutes < 10 ? "0" + nMinutes : "" + nMinutes); 334 | var sSeconds = ((nHours > 0 || nMinutes > 0) && nSeconds < 10 ? "0" + nSeconds : "" + nSeconds); 335 | var sMSeconds = "" + nMSeconds; 336 | 337 | if (nHours > 0) 338 | return sHours + ':' + sMinutes + ':' + sSeconds; 339 | else if (nMinutes > 0) 340 | return sMinutes + ':' + sSeconds; 341 | else if (undefined === _msThreshold || sSeconds > _msThreshold - 1) 342 | return sSeconds; 343 | else 344 | return sSeconds + "." + sMSeconds; 345 | }; 346 | CTimeSettings.prototype.private_SecondsToString2 = function(_seconds) 347 | { 348 | var nHours = Math.floor(_seconds / 3600); 349 | var nMinutes = Math.floor((_seconds - (nHours * 3600)) / 60); 350 | var nSeconds = Math.floor(_seconds - (nHours * 3600) - (nMinutes * 60)); 351 | var sHours = "" + nHours; 352 | var sMinutes = (nMinutes < 10 ? "0" + nMinutes : "" + nMinutes); 353 | var sSeconds = (nSeconds < 10 ? "0" + nSeconds : "" + nSeconds); 354 | 355 | if (nHours > 0) 356 | return sHours + ':' + sMinutes + ':' + sSeconds; 357 | else 358 | return sMinutes + ':' + sSeconds; 359 | }; 360 | CTimeSettings.prototype.private_SecondsToString3 = function(_seconds) 361 | { 362 | var nMinutes = Math.floor(_seconds / 60); 363 | var nSeconds = Math.floor(_seconds - (nMinutes * 60)); 364 | var sMinutes = "" + nMinutes; 365 | var sSeconds = (nSeconds < 10 ? "0" + nSeconds : "" + nSeconds); 366 | 367 | if (nMinutes > 0) 368 | return sMinutes + ':' + sSeconds; 369 | else 370 | return sSeconds; 371 | }; 372 | CTimeSettings.prototype.ToString = function() 373 | { 374 | switch (this.m_nType) 375 | { 376 | case ETimeSettings.None: 377 | { 378 | return "--:--"; 379 | break; 380 | } 381 | case ETimeSettings.Absolute: 382 | { 383 | return (this.private_SecondsToString(this.m_nMainTime, 10) + " SD"); 384 | break; 385 | } 386 | case ETimeSettings.ByoYomi: 387 | { 388 | if (this.m_nMainTime > 0) 389 | { 390 | return this.private_SecondsToString(this.m_nMainTime); 391 | } 392 | else 393 | { 394 | return (this.private_SecondsToString(this.m_nOverTimeCur, 3) + " (" + this.m_nOverCountCur + ")"); 395 | } 396 | 397 | break; 398 | } 399 | case ETimeSettings.Canadian: 400 | { 401 | if (this.m_nMainTime > 0) 402 | { 403 | return this.private_SecondsToString(this.m_nMainTime); 404 | } 405 | else 406 | { 407 | return (this.private_SecondsToString(this.m_nOverTimeCur, 3) + "/" + this.m_nOverCountCur); 408 | } 409 | break; 410 | } 411 | } 412 | 413 | return "--:--"; 414 | }; 415 | CTimeSettings.prototype.GetTimeSystemString = function() 416 | { 417 | switch (this.m_nType) 418 | { 419 | case ETimeSettings.None: 420 | { 421 | return g_oLocalization.common.timeSystem.none.toLowerCase(); 422 | } 423 | case ETimeSettings.Absolute: 424 | { 425 | return this.private_SecondsToString2(this.m_nMainTime) + " " + g_oLocalization.common.timeSystem.absolute.toLowerCase(); 426 | } 427 | case ETimeSettings.ByoYomi: 428 | { 429 | return this.private_SecondsToString2(this.m_nMainTime) + ", " + (this.private_SecondsToString3(this.m_nOverTimeCur) + " (" + this.m_nOverCountCur + ")"); 430 | } 431 | case ETimeSettings.Canadian: 432 | { 433 | return this.private_SecondsToString2(this.m_nMainTime) + ", " + (this.private_SecondsToString3(this.m_nOverTimeCur) + "/" + this.m_nOverCountCur); 434 | } 435 | } 436 | 437 | return g_oLocalization.common.timeSystem.none.toLowerCase(); 438 | }; 439 | CTimeSettings.prototype.GetMainTimeString = function() 440 | { 441 | return this.private_SecondsToString2(this.m_nMainTime); 442 | }; 443 | CTimeSettings.prototype.GetByoYomiTimeString = function() 444 | { 445 | return this.private_SecondsToString2(this.m_nOverTimeCur); 446 | }; 447 | CTimeSettings.prototype.GetTypeInKGSString = function() 448 | { 449 | return KGSCommon.TimeSystemToString(this); 450 | }; 451 | CTimeSettings.prototype.GetMainTime = function() 452 | { 453 | return this.m_nMainTime; 454 | }; 455 | CTimeSettings.prototype.GetOverTime = function() 456 | { 457 | return this.m_nOverTime; 458 | }; 459 | CTimeSettings.prototype.GetOverCount = function() 460 | { 461 | return this.m_nOverCount; 462 | }; 463 | CTimeSettings.prototype.GetCurrentOverTime = function() 464 | { 465 | return this.m_nOverTimeCur; 466 | }; 467 | CTimeSettings.prototype.GetCurrentMainTime = function() 468 | { 469 | return this.m_nMainTime; 470 | }; 471 | CTimeSettings.prototype.IsCountDown = function() 472 | { 473 | if ((this.IsAbsolute() && this.GetCurrentMainTime() < 60 + 0.05) 474 | || (this.IsByoYomi() && this.GetCurrentMainTime() <= 0 && this.GetCurrentOverTime() < 10 + 0.05) 475 | || (this.IsCanadian() && this.GetCurrentMainTime() <= 0 && this.GetCurrentOverTime() < 60 + 0.05)) 476 | return true; 477 | 478 | return false; 479 | }; 480 | CTimeSettings.prototype.GetCountDownTime = function() 481 | { 482 | if (this.IsAbsolute()) 483 | return this.GetCurrentMainTime(); 484 | else if (this.IsByoYomi() || this.IsCanadian()) 485 | return this.GetCurrentOverTime(); 486 | 487 | return 0; 488 | }; 489 | CTimeSettings.prototype.GetCountDownLimit = function() 490 | { 491 | if (this.IsAbsolute() || this.IsCanadian()) 492 | return 60; 493 | else if (this.IsByoYomi()) 494 | return 10; 495 | 496 | return 0; 497 | }; 498 | CTimeSettings.prototype.GetType = function() 499 | { 500 | return this.m_nType; 501 | }; -------------------------------------------------------------------------------- /Src/Localizations/enUS.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 10.05.2017 9 | * Time 16:35 10 | */ 11 | 12 | var g_oLocalization_enUS = { 13 | 14 | locale : "en-US", 15 | 16 | loginScreen : { 17 | 18 | login : "Login", 19 | password : "Password", 20 | connect : "Play on KGS", 21 | remember : "Remember my password", 22 | 23 | about : "About" 24 | }, 25 | 26 | mainRoom : { 27 | roomsButton : "Rooms", 28 | playButton : "Play", 29 | exitButton : "Exit", 30 | 31 | playMenu : { 32 | createChallenge : "Create new challenge", 33 | yourChallenge : "Your challenge", 34 | cancelAutomatch : "Cancel automatch", 35 | startAutomatch : "Start automatch", 36 | automatchPreferences : "Automatch preferences", 37 | startDemonstration : "Start demonstration", 38 | loadFile : "Load file" 39 | }, 40 | 41 | findPlayer : "find a player", 42 | 43 | search : "Search", 44 | searchRoom : "Find room", 45 | searchRoomHint : "Search in the list of all rooms", 46 | chatWithPlayer : "Chat with player", 47 | chatWithPlayerHint : "Start private chat with the specified user", 48 | 49 | gamesTabs : { 50 | games : "Games", 51 | challenges : "Challenges", 52 | challengesNoBots : "Challenges (no bots)", 53 | room : "Room", 54 | followed : "Followed" 55 | }, 56 | 57 | statistics : { 58 | label : "Statistics of the room", 59 | users : "Users", 60 | games : "Games", 61 | challenges : "Challenges" 62 | }, 63 | 64 | gamesList : { 65 | contextMenuJoin : "Join", 66 | contextMenuObserve : "Observe", 67 | contextMenuCopyLink : "Copy the link to the chat", 68 | 69 | listHeaderType : "Type", 70 | listHeaderWhiteRank : "wr", 71 | listHeaderBlackRank : "br", 72 | listHeaderWhiteName : "White", 73 | listHeaderBlackName : "Black", 74 | listHeaderSize : "Size", 75 | listHeaderRules : "Rules", 76 | listHeaderRoom : "Room", 77 | listHeaderObservers : "Observers", 78 | listHeaderMove : "Move", 79 | listHeaderComment : "Comment", 80 | listHeaderRank : "Rank", 81 | listHeaderName : "Name", 82 | listHeaderTime : "Time", 83 | listHeaderKomi : "Komi", 84 | listHeaderResult : "Result", 85 | listHeaderDate : "Date", 86 | 87 | listAdditionalRobot : "robot" 88 | }, 89 | 90 | playersList : { 91 | contextMenuTalkTo : "Talk to...", 92 | contextMenuViewInfo : "View info", 93 | contextMenuFriend : "Buddy", 94 | contextMenuCensored : "Censored", 95 | contextMenuFollow : "Follow", 96 | contextMenuCopyLink : "Copy the link to the chat", 97 | contextMenuGiveControl : "Give control", 98 | 99 | listHeaderName : "Name", 100 | listHeaderRank : "Rank" 101 | }, 102 | 103 | roomsTabs : { 104 | hint : { 105 | close : "Close room", 106 | moveTabToStart : "Move this tab to the start of the list", 107 | userInfo : "User info", 108 | roomInfo : "Room info", 109 | soundOn : "Sound notification is on", 110 | soundOff : "Sound notification is off" 111 | } 112 | }, 113 | 114 | closeGameRoomHint : "Close game room" 115 | }, 116 | 117 | gameRoom : { 118 | 119 | gameStart : "Game start", 120 | gameOver : "Game over", 121 | move : "Move", 122 | pass : "Pass", 123 | 124 | points : "Points", 125 | captures : "Captures", 126 | 127 | blackToPlay : "Black to play", 128 | whiteToPlay : "White to play", 129 | 130 | backToGame : "Back to game", 131 | removeOwnChanges : "Remove own changes", 132 | returnControl : "Return control", 133 | editorControl : "Editor control", 134 | 135 | addMinute1 : "Add 1 minute", 136 | addMinute5 : "Add 5 minutes", 137 | 138 | startReview : "Start review", 139 | 140 | labelPlaceholder : "Label...", 141 | 142 | button : { 143 | undo : "Undo", 144 | resign : "Resign", 145 | pass : "Pass", 146 | analyze : "Analyze", 147 | 148 | hint : { 149 | forward1 : "Forward", 150 | forward5 : "Forward 5 moves", 151 | forwardEnd : "Go to the end", 152 | backward1 : "Back", 153 | backward5 : "Back 5 moves", 154 | backwardStart : "Back to the start", 155 | nextVariant : "Next variant", 156 | prevVariant : "Previous variant", 157 | 158 | editMode : "Select edit mode", 159 | editModeMoves : "Moves", 160 | editModeScores : "Counting scores", 161 | editModeEditor : "Editor", 162 | editModeTriangles : "Triangles", 163 | editModeSquares : "Squares", 164 | editModeCircles : "Circles", 165 | editModeXMarks : "X marks", 166 | editModeText : "Text labels", 167 | editModeNumbers : "Numeric labels", 168 | editModeColors : "Color marks", 169 | 170 | startAutoplay : "Start autoplay", 171 | stopAutoplay : "Stop autoplay", 172 | 173 | gameInfo : "Game info", 174 | 175 | showKifu : "Show kifu", 176 | toggleKifuMode : "Toggle kifu mode" 177 | } 178 | }, 179 | 180 | countingScores : { 181 | header : "Score counting phase", 182 | message : "Both players now select and agree upon which groups should be considered 'dead' for the purpose of scoring.", 183 | 184 | buttonAccept : "Accept", 185 | buttonResume : "Cancel and resume the game" 186 | }, 187 | 188 | toolbarCustomization : { 189 | mainNavigation : "Main navigation", 190 | treeNavigation : "Tree navigation", 191 | generalToolbar : "General toolbar", 192 | autoplay : "Autoplay", 193 | timelinePanel : "Timeline panel", 194 | kifuMode : "Kifu mode" 195 | }, 196 | 197 | menu : { 198 | 199 | hint : "Menu", 200 | 201 | downloadSGF : "Download as SGF", 202 | createSnapshot : "Create snapshot", 203 | exportToGif : "Export to GIF", 204 | convertToASCIIDiagram : "Convert to ASCII diagram", 205 | scoreEstimator : "Score estimator", 206 | toggleCoordinates : "Toggle coordinates", 207 | createNew : "Create new", 208 | loadFile : "Load from disk", 209 | loadFileFromClipboard : "Load from clipboard", 210 | gameInfo : "Game info", 211 | cropBoard : "Crop the board" 212 | }, 213 | 214 | window : { 215 | gameInfo : { 216 | caption : "Game info", 217 | 218 | gameName : "Game name", 219 | result : "Result", 220 | rules : "Rules", 221 | komi : "Komi", 222 | handicap : "Handicap", 223 | timeSettings : "Time settings", 224 | black : "Black", 225 | blackRank : "Black rank", 226 | white : "White", 227 | whiteRank : "White rank", 228 | copyright : "Copyright", 229 | date : "Date", 230 | event : "Event", 231 | round : "Round", 232 | place : "Place", 233 | annotator : "Annotator", 234 | fuseki : "Fuseki", 235 | source : "Source", 236 | transcriber : "Transcriber", 237 | gameInfo : "Game info" 238 | }, 239 | 240 | colorsCounter : { 241 | caption : "Colors counter", 242 | red : "Red", 243 | blue : "Blue", 244 | green : "Green", 245 | gray : "Gray" 246 | }, 247 | 248 | creatingGIF : { 249 | caption : "Creating Gif file..." 250 | }, 251 | 252 | asciiDiagram : { 253 | caption : "ASCII diagram" 254 | }, 255 | 256 | boardCropping : { 257 | caption : "Crop the board...", 258 | errorMessage : "Sorry, the cropped part can't be so small.", 259 | buttonReset : "Reset" 260 | }, 261 | 262 | error : { 263 | caption : "Error" 264 | }, 265 | 266 | kifu : { 267 | caption : "Kifu", 268 | end : "End", 269 | next : "Next" 270 | } 271 | 272 | } 273 | }, 274 | 275 | common : { 276 | 277 | gameResult : { 278 | resign : "Resign", 279 | time : "Time", 280 | forfeit : "Forfeit", 281 | even : "Even" 282 | }, 283 | 284 | black : "Black", 285 | white : "White", 286 | shortBlack : "B", 287 | shortWhite : "W", 288 | 289 | button : { 290 | ok : "OK", 291 | cancel : "Cancel", 292 | create : "Create", 293 | close : "Close", 294 | submit : "Submit", 295 | edit : "Edit", 296 | save : "Save", 297 | add : "Add", 298 | remove : "Remove", 299 | change : "Change" 300 | }, 301 | 302 | timeSystem : { 303 | absolute : "Absolute", 304 | byoYomi : "Byo-Yomi", 305 | canadian : "Canadian", 306 | none : "No time limit" 307 | }, 308 | 309 | rules : { 310 | japanese : "Japanese", 311 | chinese : "Chinese", 312 | aga : "AGA", 313 | newZealand : "New Zealand" 314 | }, 315 | 316 | connectionStatus : { 317 | online : "online", 318 | secondsAgo : function(nSeconds) 319 | { 320 | return nSeconds + " seconds ago"; 321 | }, 322 | minutesAgo : function(nMinutes) 323 | { 324 | return nMinutes + " minutes ago"; 325 | }, 326 | hoursAgo : function(nHours) 327 | { 328 | return nHours + " hours ago"; 329 | }, 330 | daysAgo : function(nDays) 331 | { 332 | return nDays + " days ago"; 333 | } 334 | }, 335 | 336 | months : { 337 | Jan : "Jan", 338 | Feb : "Feb", 339 | Mar : "Mar", 340 | Apr : "Apr", 341 | May : "May", 342 | Jun : "Jun", 343 | Jul : "Jul", 344 | Aug : "Aug", 345 | Sep : "Sep", 346 | Oct : "Oct", 347 | Nov : "Nov", 348 | Dec : "Dec" 349 | }, 350 | 351 | privateFlag : "Private", 352 | 353 | about : { 354 | caption : "About", 355 | version : "Version", 356 | visitMessage : "Visit our github project for feedback and issue reports:", 357 | allRightReserved : "All rights reserved." 358 | }, 359 | 360 | minimizeButtonHint : "Minimize", 361 | 362 | window : { 363 | captionError : "Error", 364 | captionWarning : "Warning", 365 | 366 | messageNoUserWithName : function(sUserName) 367 | { 368 | return "There is no user account named \"" + sUserName + "\" on this system."; 369 | }, 370 | messageNoUser : "There is no such user.", 371 | messageRoomIsPrivate : function(sRoomName) 372 | { 373 | return "Sorry, " + sRoomName + " is private. You cannot enter."; 374 | }, 375 | messageAlreadyPlaying : "Sorry, you are already playing in one game, so you can't start playing in another.", 376 | messageChallengeDeclined : "Your challenge has been declined." 377 | } 378 | 379 | }, 380 | 381 | KGS : { 382 | 383 | gameType : { 384 | free : "Free", 385 | ranked : "Ranked", 386 | teaching : "Teaching", 387 | simulation : "Simulation", 388 | demonstration : "Demonstration", 389 | rengo : "Rengo" 390 | }, 391 | 392 | window : { 393 | 394 | common : { 395 | captionGameWarning : "Game warning" 396 | }, 397 | 398 | roomsList : { 399 | caption : "Room list", 400 | searchPlaceholder : "Enter room name here", 401 | listHeaderName : "Name", 402 | listHeaderCategory : "Category", 403 | categoryMain : "Main", 404 | categoryClubs : "Clubs", 405 | categoryNational : "National", 406 | categoryNewRooms : "New rooms", 407 | categoryLessons : "Lessons", 408 | categorySocial : "Social", 409 | categoryTournaments : "Tournaments" 410 | }, 411 | 412 | automatchSetup : { 413 | caption : "Automatch setup", 414 | estimatedRank : "Rank", 415 | human : "Human", 416 | robot : "Robot", 417 | unranked : "Unranked opponent", 418 | maxHandicap : "Max handicap", 419 | ranked : "Ranked game", 420 | free : "Free game", 421 | medium : "Medium", 422 | fast : "Fast", 423 | blitz : "Blitz" 424 | }, 425 | 426 | challenge : { 427 | 428 | captionNewChallenge : "Create new challenge", 429 | captionNewDemo : "Create new demonstration", 430 | captionYourChallenge : "Your challenge", 431 | captionNewGameVs : "New game vs.", 432 | captionNewGame : "New game", 433 | captionPressOkToStart : "Press OK to start the game", 434 | captionWaiting : "Waiting...", 435 | 436 | privateFlag : "Private", 437 | commentPlaceHolder : "No comment", 438 | switchColorsHint : "Switch colors", 439 | fieldRoom : "Room", 440 | fieldRules : "Rules", 441 | fieldBorderSize : "Board size", 442 | fieldHandicap : "Handicap", 443 | fieldKomi : "Komi", 444 | fieldTimeSystem : "Time system", 445 | fieldMainTime : "Main time", 446 | fieldByoYomiTime : "Byo-yomi", 447 | fieldPeriods : "Periods", 448 | fieldStones : "Stones", 449 | 450 | buttonRetry : "Retry", 451 | buttonRetryHint : "Cancel current proposal", 452 | 453 | challengerHint : "View info", 454 | 455 | buttonDecline : "decline", 456 | buttonDeclineHint : "Decline this player" 457 | }, 458 | 459 | roomInfo : { 460 | caption : "Room info" 461 | }, 462 | 463 | undoRequest : { 464 | buttonNeverUndo : "Never undo", 465 | message : "The opponent has requested an undo for their last move. Do you want to perform an undo?" 466 | }, 467 | 468 | userInfo : { 469 | tabInfo : "Info", 470 | tabGames : "Games", 471 | tabRank : "Rank", 472 | tabFriends : "Friends", 473 | tabCensored : "Censored", 474 | tabFuns : "Fans", 475 | 476 | rankGraphReplacementText : "No rank data available", 477 | 478 | fieldUserName : "User name", 479 | fieldRealName : "Real name", 480 | fieldRank : "Rank", 481 | fieldLastOn : "Last on", 482 | fieldRegisteredOn : "Registered on", 483 | fieldLocale : "Locale", 484 | fieldEmail : "Email", 485 | fieldGames : "Games", 486 | fieldRecentGames : "Recent games", 487 | 488 | flagPrivateEmail : "Hide address from other users?", 489 | flagReceiveAnnouncements : "Receive KGS announcements?", 490 | flagOnlyRanked : "Only ranked games", 491 | 492 | emailPrivate : "private", 493 | 494 | userslistNamePlaceholder : "User name", 495 | userslistNotesPlaceholder : "Notes", 496 | 497 | gamesArchive : { 498 | contextMenu : { 499 | observe : "Observe", 500 | view : "View", 501 | download : "Download to disk", 502 | loadIn : "Load in...", 503 | loadPIn : "Load (P) in..." 504 | } 505 | } 506 | } 507 | 508 | } 509 | } 510 | }; -------------------------------------------------------------------------------- /Src/Localizations/deDE.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 11.06.2017 9 | * Time 14:56 10 | */ 11 | 12 | // The translation was made by Yvonne Limbach 13 | 14 | var g_oLocalization_deDE = { 15 | 16 | locale : "de-DE", 17 | 18 | loginScreen : { 19 | 20 | login : "Nutzername", 21 | password : "Passwort", 22 | connect : "Auf KGS spielen", 23 | remember : "Passwort merken", 24 | 25 | about : "About" 26 | }, 27 | 28 | mainRoom : { 29 | roomsButton : "Räume", 30 | playButton : "Spielen", 31 | exitButton : "Logout", 32 | 33 | playMenu : { 34 | createChallenge : "Neue Partie", 35 | yourChallenge : "Deine offene Partie", 36 | cancelAutomatch : "Automatch abbrechen", 37 | startAutomatch : "Automatch starten", 38 | automatchPreferences : "Automatch Einstellungen", 39 | startDemonstration : "Demonstration starten", 40 | loadFile : "Datei laden" 41 | }, 42 | 43 | findPlayer : "Spieler suchen", 44 | 45 | search : "Suche", 46 | searchRoom : "Raum suchen", 47 | searchRoomHint : "In der gesamten Raumliste suchen", 48 | chatWithPlayer : "Chat starten", 49 | chatWithPlayerHint : "Privaten Chat starten", 50 | 51 | gamesTabs : { 52 | games : "Aktive Partien", 53 | challenges : "Offene Partien", 54 | challengesNoBots : "Offene Partien (ohne Bots)", 55 | room : "Raum", 56 | followed : "Fanpartien" 57 | }, 58 | 59 | statistics : { 60 | label : "Raumstatistik", 61 | users : "Spieler", 62 | games : "Aktive Partien", 63 | challenges : "Offene Partien" 64 | }, 65 | 66 | gamesList : { 67 | contextMenuJoin : "Partie Beitreten", 68 | contextMenuObserve : "Zuschauen", 69 | contextMenuCopyLink : "Link in den Chat kopieren", 70 | 71 | listHeaderType : "Art", 72 | listHeaderWhiteRank : "WR", 73 | listHeaderBlackRank : "SR", 74 | listHeaderWhiteName : "Weiß", 75 | listHeaderBlackName : "Schwarz", 76 | listHeaderSize : "Brettgröße", 77 | listHeaderRules : "Regeln", 78 | listHeaderRoom : "Raum", 79 | listHeaderObservers : "Zuschauer", 80 | listHeaderMove : "Zug", 81 | listHeaderComment : "Kommentar", 82 | listHeaderRank : "Rang", 83 | listHeaderName : "Name", 84 | listHeaderTime : "Zeit", 85 | listHeaderKomi : "Komi", 86 | listHeaderResult : "Ergebnis", 87 | listHeaderDate : "Datum", 88 | 89 | listAdditionalRobot : "Bot" 90 | }, 91 | 92 | playersList : { 93 | contextMenuTalkTo : "Reden mit...", 94 | contextMenuViewInfo : "Spielerprofil ansehen", 95 | contextMenuFriend : "Freund", 96 | contextMenuCensored : "Zensiert", 97 | contextMenuFollow : "Fan", 98 | contextMenuCopyLink : "Link in den Chat kopieren", 99 | contextMenuGiveControl : "Kontrolle übergeben", 100 | 101 | listHeaderName : "Name", 102 | listHeaderRank : "Rang" 103 | }, 104 | 105 | roomsTabs : { 106 | hint : { 107 | close : "Raum verlassen", 108 | moveTabToStart : "Raum an den Anfang der Liste verschieben", 109 | userInfo : "Spielerprofil", 110 | roomInfo : "Rauminfo", 111 | soundOn : "Benachrichtigung an", 112 | soundOff : "Benachrichtigung aus" 113 | } 114 | }, 115 | 116 | closeGameRoomHint : "Raum verlassen" 117 | }, 118 | 119 | gameRoom : { 120 | 121 | gameStart : "Partie gestartet", 122 | gameOver : "Partie beendet", 123 | move : "Zug", 124 | pass : "Passen", 125 | 126 | points : "Punkte", 127 | captures : "Gefangene", 128 | 129 | blackToPlay : "Schwarz am Zug", 130 | whiteToPlay : "Weiß am Zug", 131 | 132 | backToGame : "Zurück zum Spiel", 133 | removeOwnChanges : "Eigene Änderungen rückgängig machen", 134 | returnControl : "Kontrolle zurückgeben", 135 | editorControl : "Reviewkontrolle", 136 | 137 | addMinute1 : "1 Minute hinzufügen", 138 | addMinute5 : "5 Minuten hinzufügen", 139 | 140 | startReview : "Partie analysieren", 141 | 142 | labelPlaceholder : "Text...", 143 | 144 | button : { 145 | undo : "Zug zurücknehmen", 146 | resign : "Aufgeben", 147 | pass : "Passen", 148 | analyze : "Analysieren", 149 | 150 | hint : { 151 | forward1 : "Nächster Zug", 152 | forward5 : "5 Züge vorwärts", 153 | forwardEnd : "Zum Ende der Partie", 154 | backward1 : "Letzter Zug", 155 | backward5 : "5 Züge zurück", 156 | backwardStart : "Zurück zum Anfang", 157 | nextVariant : "Nächste Variante", 158 | prevVariant : "Vorherige Variante", 159 | 160 | editMode : "Reviewtools", 161 | editModeMoves : "Züge", 162 | editModeScores : "Auszählen", 163 | editModeEditor : "Steine entfernen/hinzufügen", 164 | editModeTriangles : "Dreiecke", 165 | editModeSquares : "Quadrate", 166 | editModeCircles : "Kreise", 167 | editModeXMarks : "X-Markierungen", 168 | editModeText : "Textmarkierungen", 169 | editModeNumbers : "Zahlenmarkierungen", 170 | editModeColors : "Farbmarkierungen", 171 | 172 | startAutoplay : "Autoplay atarten", 173 | stopAutoplay : "Autoplay stoppen", 174 | 175 | gameInfo : "Partieinfo", 176 | 177 | showKifu : "Kifu anzeigen", 178 | toggleKifuMode : "Den nächsten Zug raten" 179 | } 180 | }, 181 | 182 | countingScores : { 183 | header : "Gefangene markieren", 184 | message : "Die Spieler markieren die aus ihrer Sicht toten Steine. Nachdem beide Seiten der Markierung zugestimmt haben steht der Gewinner fest.", 185 | 186 | buttonAccept : "OK", 187 | buttonResume : "Zurück zum Spiel" 188 | }, 189 | 190 | toolbarCustomization : { 191 | mainNavigation : "Hauptnavigation", 192 | treeNavigation : "Variante wechseln", 193 | generalToolbar : "Reviewfunktionen", 194 | autoplay : "Autoplay", 195 | timelinePanel : "Zeitleiste", 196 | kifuMode : "Kifu-Optionen" 197 | }, 198 | 199 | menu : { 200 | 201 | hint : "Menü", 202 | 203 | downloadSGF : "Partie als SGF herunterladen", 204 | createSnapshot : "Screenshot vom Brett aufnehmen", 205 | exportToGif : "Als GIF exportieren", 206 | convertToASCIIDiagram : "In ASCII-Diagramm konvertieren", 207 | scoreEstimator : "Ergebnis schätzen", 208 | toggleCoordinates : "Brettkoordinaten", 209 | createNew : "Neu", 210 | loadFile : "Von der Festplatte laden", 211 | loadFileFromClipboard : "Aus der Zwischenablage laden", 212 | gameInfo : "Partieinfo", 213 | cropBoard : "Brettausschnitt wählen" 214 | }, 215 | 216 | window : { 217 | gameInfo : { 218 | caption : "Partieinfo", 219 | 220 | gameName : "Name der Partie", 221 | result : "Ergebnis", 222 | rules : "Regeln", 223 | komi : "Komi", 224 | handicap : "Vorgabe", 225 | timeSettings : "Zeiteinstellungen", 226 | black : "Schwarz", 227 | blackRank : "Rang Schwarz", 228 | white : "Weiß", 229 | whiteRank : "Rang Weiß", 230 | copyright : "Copyright", 231 | date : "Datum", 232 | event : "Event", 233 | round : "Runde", 234 | place : "Ort", 235 | annotator : "Kommentator", 236 | fuseki : "Fuseki", 237 | source : "Quelle", 238 | transcriber : "Mitschreiber", 239 | gameInfo : "Partieinfo" 240 | }, 241 | 242 | colorsCounter : { 243 | caption : "Farbauswahl", 244 | red : "Rot", 245 | blue : "Blau", 246 | green : "Grün", 247 | gray : "Grau" 248 | }, 249 | 250 | creatingGIF : { 251 | caption : "GIF wird erzeugt..." 252 | }, 253 | 254 | asciiDiagram : { 255 | caption : "ASCII-Diagramm" 256 | }, 257 | 258 | boardCropping : { 259 | caption : "Brettausschnitt wählen", 260 | errorMessage : "Der gewählte Brettausschnitt ist zu klein.", 261 | buttonReset : "Zurücksetzen" 262 | }, 263 | 264 | error : { 265 | caption : "Fehler" 266 | }, 267 | 268 | kifu : { 269 | caption : "Kifu", 270 | end : "Ende", 271 | next : "Weiter" 272 | } 273 | 274 | } 275 | }, 276 | 277 | common : { 278 | 279 | gameResult : { 280 | resign : "Aufgabe", 281 | time : "Zeit", 282 | forfeit : "Verwirkt", 283 | even : "Jigo" 284 | }, 285 | 286 | black : "Schwarz", 287 | white : "Weiß", 288 | shortBlack : "S", 289 | shortWhite : "W", 290 | 291 | button : { 292 | ok : "OK", 293 | cancel : "Abbrechen", 294 | create : "Erstellen", 295 | close : "Schließen", 296 | submit : "Absenden", 297 | edit : "Bearbeiten", 298 | save : "Speichern", 299 | add : "Hinzufügen", 300 | remove : "Entfernen", 301 | change : "Ändern" 302 | }, 303 | 304 | timeSystem : { 305 | absolute : "Absolut", 306 | byoYomi : "Byoyomi", 307 | canadian : "Kanadisch", 308 | none : "Ohne Zeitlimit" 309 | }, 310 | 311 | rules : { 312 | japanese : "Japanisch", 313 | chinese : "Chinesisch", 314 | aga : "AGA", 315 | newZealand : "Neuseeländisch" 316 | }, 317 | 318 | connectionStatus : { 319 | online : "Online", 320 | secondsAgo : function(nSeconds) 321 | { 322 | return "vor " + nSeconds + " Sekunde(n)"; 323 | }, 324 | minutesAgo : function(nMinutes) 325 | { 326 | return "vor " + nMinutes + " Minute(n)"; 327 | }, 328 | hoursAgo : function(nHours) 329 | { 330 | return "vor " + nHours + " Stunde(n)"; 331 | }, 332 | daysAgo : function(nDays) 333 | { 334 | return "vor " + nDays + " Tag(en)"; 335 | } 336 | }, 337 | 338 | months : { 339 | Jan : "Jan", 340 | Feb : "Feb", 341 | Mar : "Mrz", 342 | Apr : "Apr", 343 | May : "Mai", 344 | Jun : "Jun", 345 | Jul : "Jul", 346 | Aug : "Aug", 347 | Sep : "Sep", 348 | Oct : "Okt", 349 | Nov : "Nov", 350 | Dec : "Dez" 351 | }, 352 | 353 | privateFlag : "Privat", 354 | 355 | about : { 356 | caption : "About", 357 | version : "Version", 358 | visitMessage : "Hinterlasse Feedback oder Fehlermeldungen beim Github-Projekt:", 359 | allRightReserved : "Alle Rechte vorbehalten.", 360 | translatedBy : "Übersetzt von Yvonne Limbach." 361 | }, 362 | 363 | minimizeButtonHint : "Minimieren", 364 | 365 | window : { 366 | captionError : "Fehler", 367 | captionWarning : "Warnung", 368 | 369 | messageNoUserWithName : function(sUserName) 370 | { 371 | return "Es gibt keinen User mit dem Namen \"" + sUserName + "\" auf diesem Server."; 372 | }, 373 | messageNoUser : "Dieser User existiert nicht.", 374 | messageRoomIsPrivate : function(sRoomName) 375 | { 376 | return "Der Raum " + sRoomName + " ist privat. Du kannst ihn nicht betreten."; 377 | }, 378 | messageAlreadyPlaying : "Du spielst bereits eine Partie. Du musst du die aktuelle Partie beenden bevor du eine Neue starten kannst.", 379 | messageChallengeDeclined : "Deine Herausforderung wurde abgelehnt." 380 | } 381 | 382 | }, 383 | 384 | KGS : { 385 | 386 | gameType : { 387 | free : "Frei", 388 | ranked : "Gewertet", 389 | teaching : "Lehrpartie", 390 | simulation : "Simultan", 391 | demonstration : "Demonstration", 392 | rengo : "Rengo" 393 | }, 394 | 395 | window : { 396 | 397 | common : { 398 | captionGameWarning : "Warnung" 399 | }, 400 | 401 | roomsList : { 402 | caption : "Raumliste", 403 | searchPlaceholder : "Raumnamen hier eingeben", 404 | listHeaderName : "Name", 405 | listHeaderCategory : "Kategorie", 406 | categoryMain : "Haupträume", 407 | categoryClubs : "Clubs", 408 | categoryNational : "Nationale Räume", 409 | categoryNewRooms : "Neue Räume", 410 | categoryLessons : "Lektionen", 411 | categorySocial : "Gesellschaftliche Räume", 412 | categoryTournaments : "Turniere" 413 | }, 414 | 415 | automatchSetup : { 416 | caption : "Automatch Einstellungen", 417 | estimatedRank : "Rang", 418 | human : "Mensch", 419 | robot : "Bot", 420 | unranked : "Gegner ohne Rang", 421 | maxHandicap : "Maximale Vorgabe", 422 | ranked : "Gewertete Partie", 423 | free : "Freie Partie", 424 | medium : "Mittel", 425 | fast : "Schnell", 426 | blitz : "Blitz" 427 | }, 428 | 429 | challenge : { 430 | 431 | captionNewChallenge : "Neue Partie", 432 | captionNewDemo : "Neue Demonstration", 433 | captionYourChallenge : "Deine offene Partie", 434 | captionNewGameVs : "Neue Partie gegen...", 435 | captionNewGame : "Neue Partie", 436 | captionPressOkToStart : "Klicke auf OK um die Partie zu starten.", 437 | captionWaiting : "Warte auf Rückmeldung des Gegners...", 438 | 439 | privateFlag : "Privat", 440 | commentPlaceHolder : "Kein Kommentar", 441 | switchColorsHint : "Farben wechseln", 442 | fieldRoom : "Raum", 443 | fieldRules : "Regeln", 444 | fieldBorderSize : "Brettgröße", 445 | fieldHandicap : "Vorgabe", 446 | fieldKomi : "Komi", 447 | fieldTimeSystem : "Zeitsystem", 448 | fieldMainTime : "Grundbedenkzeit", 449 | fieldByoYomiTime : "Byoyomi", 450 | fieldPeriods : "Perioden", 451 | fieldStones : "Züge", 452 | 453 | buttonRetry : "Abbrechen", 454 | buttonRetryHint : "Aktuelle Anfrage abbrechen", 455 | 456 | challengerHint : "Spielerprofil ansehen", 457 | 458 | buttonDecline : "Ablehnen", 459 | buttonDeclineHint : "Diesen Spieler ablehnen" 460 | }, 461 | 462 | roomInfo : { 463 | caption : "Rauminfo" 464 | }, 465 | 466 | undoRequest : { 467 | buttonNeverUndo : "Rücknahme generell ablehnen", 468 | message : "Dein Gegner hat um die Rücknahme seines letzten Zuges gebeten. Soll der letzte Zug rückgängig gemacht werden?" 469 | }, 470 | 471 | userInfo : { 472 | tabInfo : "Profil", 473 | tabGames : "Partien", 474 | tabRank : "Rang", 475 | tabFriends : "Freunde", 476 | tabCensored : "Zensiert", 477 | tabFuns : "Fans", 478 | 479 | rankGraphReplacementText : "Kein Ranggraph verfügbar", 480 | 481 | fieldUserName : "Spielername", 482 | fieldRealName : "Richtiger Name", 483 | fieldRank : "Rang", 484 | fieldLastOn : "Zuletzt online", 485 | fieldRegisteredOn : "Registriert am", 486 | fieldLocale : "Clientsprache", 487 | fieldEmail : "E-Mail", 488 | fieldGames : "Partien", 489 | fieldRecentGames : "Letzte Partien", 490 | 491 | flagPrivateEmail : "E-Mailadresse vor anderen Usern verbergen?", 492 | flagReceiveAnnouncements : "Nachrichten von KGS erhalten?", 493 | flagOnlyRanked : "Nur gewertete Partien", 494 | 495 | emailPrivate : "Privat", 496 | 497 | userslistNamePlaceholder : "Spielername", 498 | userslistNotesPlaceholder : "Text", 499 | 500 | gamesArchive : { 501 | contextMenu : { 502 | observe : "Live zuschauen", 503 | view : "Anschauen", 504 | download : "Speichern", 505 | loadIn : "Ladend in...", 506 | loadPIn : "Privat laden in..." 507 | } 508 | } 509 | } 510 | 511 | } 512 | } 513 | }; -------------------------------------------------------------------------------- /Src/Localizations/frFR.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * Copyright 2016 the GoUniverse project authors. 5 | * All rights reserved. 6 | * Project GoUniverse 7 | * Author Ilya Kirillov 8 | * Date 07.06.2017 9 | * Time 20:28 10 | */ 11 | 12 | var g_oLocalization_frFR = { 13 | 14 | locale : "fr-FR", 15 | 16 | loginScreen : { 17 | 18 | login : "Pseudo", 19 | password : "Mot de passe", 20 | connect : "Jouer sur KGS", 21 | remember : "Enregistrer mon mot de passe", 22 | 23 | about : "A propos" 24 | }, 25 | 26 | mainRoom : { 27 | roomsButton : "Salles", 28 | playButton : "Jouer", 29 | exitButton : "Quitter", 30 | 31 | playMenu : { 32 | createChallenge : "Créer nouvelle partie", 33 | yourChallenge : "Votre partie", 34 | cancelAutomatch : "Annuler l'automatch", 35 | startAutomatch : "Commencer l'automatch", 36 | automatchPreferences : "Préférences de l'automatch", 37 | startDemonstration : "Débuter démonstration", 38 | loadFile : "Charger le fichier" 39 | }, 40 | 41 | findPlayer : "Trouver un joueur", 42 | 43 | search : "Rechercher", 44 | searchRoom : "Rechercher une salle", 45 | searchRoomHint : "Rechercher dans la liste de toutes les salles", 46 | chatWithPlayer : "Parler au joueur", 47 | chatWithPlayerHint : "Commencer à parler en privé avec le joueur", 48 | 49 | gamesTabs : { 50 | games : "Jeux", 51 | challenges : "Parties", 52 | challengesNoBots : "Parties (pas de robots)", 53 | room : "Salle", 54 | followed : "Suivi" 55 | }, 56 | 57 | statistics : { 58 | label : "Statistiques de la salle", 59 | users : "Utilisateurs", 60 | games : "Jeux", 61 | challenges : "Parties" 62 | }, 63 | 64 | gamesList : { 65 | contextMenuJoin : "Rejoindre", 66 | contextMenuObserve : "Observer", 67 | contextMenuCopyLink : "Copier le lien dans le chat", 68 | 69 | listHeaderType : "Type", 70 | listHeaderWhiteRank : "wr", 71 | listHeaderBlackRank : "br", 72 | listHeaderWhiteName : "Blanc", 73 | listHeaderBlackName : "Noir", 74 | listHeaderSize : "Taille", 75 | listHeaderRules : "Règles", 76 | listHeaderRoom : "Salle", 77 | listHeaderObservers : "Observateurs", 78 | listHeaderMove : "Coup", 79 | listHeaderComment : "Commentaire", 80 | listHeaderRank : "Rang", 81 | listHeaderName : "Nom", 82 | listHeaderTime : "Temps", 83 | listHeaderKomi : "Komi", 84 | listHeaderResult : "Résultat", 85 | listHeaderDate : "Date", 86 | 87 | listAdditionalRobot : "robot" 88 | }, 89 | 90 | playersList : { 91 | contextMenuTalkTo : "Parler à...", 92 | contextMenuViewInfo : "Voir les infos", 93 | contextMenuFriend : "Amis", 94 | contextMenuCensored : "Bloqué", 95 | contextMenuFollow : "Suivi", 96 | contextMenuCopyLink : "Copier le lien dans le chat", 97 | contextMenuGiveControl : "Donner le contrôle", 98 | 99 | listHeaderName : "Nom", 100 | listHeaderRank : "Rang" 101 | }, 102 | 103 | roomsTabs : { 104 | hint : { 105 | close : "Fermer la salle", 106 | moveTabToStart : "Déplacer au début de la liste", 107 | userInfo : "Information de l'utilisateur", 108 | roomInfo : "Information de la salle", 109 | soundOn : "Le son est activé", 110 | soundOff : "Le son est désactivé" 111 | } 112 | }, 113 | 114 | closeGameRoomHint : "Fermer la salle" 115 | }, 116 | 117 | gameRoom : { 118 | 119 | gameStart : "Début de la partie", 120 | gameOver : "Fin de la partie", 121 | move : "Coup", 122 | pass : "Passer", 123 | 124 | points : "Points", 125 | captures : "Captures", 126 | 127 | blackToPlay : "A noir de jouer", 128 | whiteToPlay : "A blanc de jouer", 129 | 130 | backToGame : "Retour à la partie", 131 | removeOwnChanges : "Supprimer vos propres modifications", 132 | returnControl : "Rendre contrôle", 133 | editorControl : "Editer contrôle", 134 | 135 | addMinute1 : "Ajouter 1 minute", 136 | addMinute5 : "Ajouter 5 minutes", 137 | 138 | startReview : "Commencer la revue", 139 | 140 | labelPlaceholder : "Label...", 141 | 142 | button : { 143 | undo : "Refaire", 144 | resign : "Abandonner", 145 | pass : "Passer", 146 | analyze : "Analyser", 147 | 148 | hint : { 149 | forward1 : "En avant", 150 | forward5 : "En avant de 5 coups", 151 | forwardEnd : "Aller à la fin", 152 | backward1 : "En arrière", 153 | backward5 : "En arrière de 5 coups", 154 | backwardStart : "Retour au début", 155 | nextVariant : "Prochaine variation", 156 | prevVariant : "Précédente variation", 157 | 158 | editMode : "Sélectionner mode d'édition", 159 | editModeMoves : "Coup", 160 | editModeScores : "Compter score", 161 | editModeEditor : "Editer", 162 | editModeTriangles : "Triangles", 163 | editModeSquares : "Carrés", 164 | editModeCircles : "Cercles", 165 | editModeXMarks : "X marques", 166 | editModeText : "Label textuel", 167 | editModeNumbers : "Label numérique", 168 | editModeColors : "Couleurs", 169 | 170 | startAutoplay : "Commencer autoplay", 171 | stopAutoplay : "Stopper autoplay", 172 | 173 | gameInfo : "Information de la partie", 174 | 175 | showKifu : "Montrer kifu", 176 | toggleKifuMode : "Basculer en mode kifu" 177 | } 178 | }, 179 | 180 | countingScores : { 181 | header : "Phase de comptage", 182 | message : "Les deux joueurs déterminent maintenant quels groupes sont morts.", 183 | 184 | buttonAccept : "Accepter", 185 | buttonResume : "Annuler et résumer la partie" 186 | }, 187 | 188 | toolbarCustomization : { 189 | mainNavigation : "Menu principal", 190 | treeNavigation : "Menu arborescent", 191 | generalToolbar : "Barre d'outil principale", 192 | autoplay : "Autoplay", 193 | timelinePanel : "Ecran temporel", 194 | kifuMode : "Mode kifu" 195 | }, 196 | 197 | menu : { 198 | 199 | hint : "Menu", 200 | 201 | downloadSGF : "Télécharger en SGF", 202 | createSnapshot : "Créer capture d'écran", 203 | exportToGif : "Exporter en gif", 204 | convertToASCIIDiagram : "Convertir en diagramme ASCII", 205 | scoreEstimator : "Estimation du score", 206 | toggleCoordinates : "Changer les coordonnées", 207 | createNew : "Créer nouveau", 208 | loadFile : "Charger depuis le disque", 209 | loadFileFromClipboard : "Charger depuis le presse-papier", 210 | gameInfo : "Information de la partie", 211 | cropBoard : "Recadrer le tableau" 212 | }, 213 | 214 | window : { 215 | gameInfo : { 216 | caption : "Information de la partie", 217 | 218 | gameName : "Nom de la partie", 219 | result : "Résultat", 220 | rules : "Règles", 221 | komi : "Komi", 222 | handicap : "Handicap", 223 | timeSettings : "Paramètres de temps", 224 | black : "Noir", 225 | blackRank : "Rang de noir", 226 | white : "Blanc", 227 | whiteRank : "Rang de blanc", 228 | copyright : "Copyright", 229 | date : "Date", 230 | event : "Evènement", 231 | round : "Rond", 232 | place : "Place", 233 | annotator : "Annotation", 234 | fuseki : "Fuseki", 235 | source : "Source", 236 | transcriber : "Transcripteur", 237 | gameInfo : "Information de la partie" 238 | }, 239 | 240 | colorsCounter : { 241 | caption : "Jetor de couleur", 242 | red : "Rouge", 243 | blue : "Bleu", 244 | green : "Vert", 245 | gray : "Gris" 246 | }, 247 | 248 | creatingGIF : { 249 | caption : "Création d'un fichier GIF..." 250 | }, 251 | 252 | asciiDiagram : { 253 | caption : "Diagramme ASCII" 254 | }, 255 | 256 | boardCropping : { 257 | caption : "Recadrer le tableau...", 258 | errorMessage : "Désolé, la cellule ne peut pas être si petite.", 259 | buttonReset : "Réinitialiser" 260 | }, 261 | 262 | error : { 263 | caption : "Erreur" 264 | }, 265 | 266 | kifu : { 267 | caption : "Kifu", 268 | end : "Fin", 269 | next : "Suivant" 270 | } 271 | 272 | } 273 | }, 274 | 275 | common : { 276 | 277 | gameResult : { 278 | resign : "Abandonner", 279 | time : "Temps", 280 | forfeit : "Défaite", 281 | even : "Egalité" 282 | }, 283 | 284 | black : "Noir", 285 | white : "BLanc", 286 | shortBlack : "N", 287 | shortWhite : "B", 288 | 289 | button : { 290 | ok : "OK", 291 | cancel : "Annuler", 292 | create : "Créer", 293 | close : "Fermer", 294 | submit : "Envoyer", 295 | edit : "Editer", 296 | save : "Sauvegarder", 297 | add : "Ajouter", 298 | remove : "Enlever", 299 | change : "Changer" 300 | }, 301 | 302 | timeSystem : { 303 | absolute : "Absolue", 304 | byoYomi : "Byo-Yomi", 305 | canadian : "Canadien", 306 | none : "Pas de temps limite" 307 | }, 308 | 309 | rules : { 310 | japanese : "Japonnais", 311 | chinese : "Chinois", 312 | aga : "AGA", 313 | newZealand : "Nouvelle-Zélande" 314 | }, 315 | 316 | connectionStatus : { 317 | online : "En ligne", 318 | secondsAgo : function (nSeconds) 319 | { 320 | return "Il y a " + nSeconds + " secondes"; 321 | }, 322 | minutesAgo : function (nMinutes) 323 | { 324 | return "Il y a " + nMinutes + " minutes"; 325 | }, 326 | hoursAgo : function (nHours) 327 | { 328 | return "Il y a " + nHours + " heures"; 329 | }, 330 | daysAgo : function (nDays) 331 | { 332 | return "Il y a " + nDays + " jours"; 333 | } 334 | }, 335 | 336 | months : { 337 | Jan : "Jan", 338 | Feb : "Fév", 339 | Mar : "Mar", 340 | Apr : "Avr", 341 | May : "Mai", 342 | Jun : "Juin", 343 | Jul : "Juil", 344 | Aug : "Aoû", 345 | Sep : "Sep", 346 | Oct : "Oct", 347 | Nov : "Nov", 348 | Dec : "Déc" 349 | }, 350 | 351 | privateFlag : "Privé", 352 | 353 | about : { 354 | caption : "A propos", 355 | version : "Version", 356 | visitMessage : "Visiter la page github de notre projet pour donner vos retours:", 357 | allRightReserved : "Tous droits réservés.", 358 | translatedBy : "Traduit par Christopher Long." 359 | }, 360 | 361 | minimizeButtonHint : "Minimiser", 362 | 363 | window : { 364 | captionError : "Erreur", 365 | captionWarning : "Attention", 366 | 367 | messageNoUserWithName : function(sUserName) 368 | { 369 | return "Il n'y a pas d'utilisateur \"" + sUserName + "\" dans ce système."; 370 | }, 371 | messageNoUser : "Il n'y a pas de tel utilisateur.", 372 | messageRoomIsPrivate : function(sRoomName) 373 | { 374 | return "Désolé, " + sRoomName + " est privé. Vous ne pouvez pas entrer."; 375 | }, 376 | messageAlreadyPlaying : "Désolé, vous êtes déjà en train de jouer une partie, vous ne pouvez pas en commencer une autre.", 377 | messageChallengeDeclined : "Votre offre de partie a été décliné." 378 | } 379 | 380 | }, 381 | 382 | KGS : { 383 | 384 | gameType : { 385 | free : "Libre", 386 | ranked : "Comptabilisé", 387 | teaching : "Enseigner", 388 | simulation : "Simulation", 389 | demonstration : "Démonstration", 390 | rengo : "Rengo" 391 | }, 392 | 393 | window : { 394 | 395 | common : { 396 | captionGameWarning : "Avertissement de partie" 397 | }, 398 | 399 | roomsList : { 400 | caption : "Liste des salles", 401 | searchPlaceholder : "Enter un nom de salle ici", 402 | listHeaderName : "Nom", 403 | listHeaderCategory : "Categorie", 404 | categoryMain : "Principale", 405 | categoryClubs : "Clubs", 406 | categoryNational : "National", 407 | categoryNewRooms : "Nouvelles salles", 408 | categoryLessons : "Leçons", 409 | categorySocial : "Social", 410 | categoryTournaments : "Tournois" 411 | }, 412 | 413 | automatchSetup : { 414 | caption : "Installer automatch", 415 | estimatedRank : "Rang", 416 | human : "Humain", 417 | robot : "Robot", 418 | unranked : "Adversaire non classé", 419 | maxHandicap : "Handicap maximum", 420 | ranked : "Partie classée", 421 | free : "Partie libre", 422 | medium : "Moyen", 423 | fast : "Rapide", 424 | blitz : "Blitz" 425 | }, 426 | 427 | challenge : { 428 | 429 | captionNewChallenge : "Créer nouvelle partie", 430 | captionNewDemo : "Créer nouvelle démonstration", 431 | captionYourChallenge : "Votre partie", 432 | captionNewGameVs : "Nouvelle partie contre.", 433 | captionNewGame : "Nouvelle partie", 434 | captionPressOkToStart : "Appuyer sur OK pour commencer la partie", 435 | captionWaiting : "En attente...", 436 | 437 | privateFlag : "Privé", 438 | commentPlaceHolder : "Sans commentaire", 439 | switchColorsHint : "Changer les couleurs", 440 | fieldRoom : "Salle", 441 | fieldRules : "Règles", 442 | fieldBorderSize : "Taille du goban", 443 | fieldHandicap : "Handicap", 444 | fieldKomi : "Komi", 445 | fieldTimeSystem : "Système de temps", 446 | fieldMainTime : "Temps principal", 447 | fieldByoYomiTime : "Byo-yomi", 448 | fieldPeriods : "Périodes", 449 | fieldStones : "Pierres", 450 | 451 | buttonRetry : "Réessayer", 452 | buttonRetryHint : "Annuler proposition actuelle", 453 | 454 | challengerHint : "Voir les informations", 455 | 456 | buttonDecline : "Refuser", 457 | buttonDeclineHint : "Refuser ce joueur" 458 | }, 459 | 460 | roomInfo : { 461 | caption : "Information de la salle" 462 | }, 463 | 464 | undoRequest : { 465 | buttonNeverUndo : "Jamais refaire", 466 | message : "L'adversaire a demandé à reprendre son dernier coup. Voulez-vous l'autoriser ?" 467 | }, 468 | 469 | userInfo : { 470 | tabInfo : "Info", 471 | tabGames : "Parties", 472 | tabRank : "Rang", 473 | tabFriends : "Amis", 474 | tabCensored : "Bloqués", 475 | tabFuns : "Funs", 476 | 477 | rankGraphReplacementText : "Aucune donnée de rang disponible", 478 | 479 | fieldUserName : "Pseudo", 480 | fieldRealName : "Nom réel", 481 | fieldRank : "Rang", 482 | fieldLastOn : "Dernière sur", 483 | fieldRegisteredOn : "Enregistré sur", 484 | fieldLocale : "Lieu", 485 | fieldEmail : "Email", 486 | fieldGames : "Parties", 487 | fieldRecentGames : "Parties récentes", 488 | 489 | flagPrivateEmail : "Cacher l'adresse aux autres utilisateurs ?", 490 | flagReceiveAnnouncements : "Recevoir les annonces de KGS ?", 491 | flagOnlyRanked : "Seulement des parties comptabilisées", 492 | 493 | emailPrivate : "privé", 494 | 495 | userslistNamePlaceholder : "Nom utilisateur", 496 | userslistNotesPlaceholder : "Notes", 497 | 498 | gamesArchive : { 499 | contextMenu : { 500 | observe : "Observer", 501 | view : "Voir", 502 | download : "Télécharger", 503 | loadIn : "Charger dans...", 504 | loadPIn : "Charger (P) dans..." 505 | } 506 | } 507 | } 508 | 509 | } 510 | } 511 | }; 512 | 513 | ExtendLocalization(g_oLocalization_frFR, g_oDefaultLocalization); --------------------------------------------------------------------------------