├── 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 = '
';
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);
--------------------------------------------------------------------------------