diff options
31 files changed, 1373 insertions, 188 deletions
diff --git a/webcards/LICENSE b/webcards/LICENSE new file mode 100644 index 0000000..15d71cd --- /dev/null +++ b/webcards/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Kyle Gunger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/webcards/README.md b/webcards/README.md new file mode 100644 index 0000000..0c6b070 --- /dev/null +++ b/webcards/README.md @@ -0,0 +1,5 @@ +# WebCardsClient + +![WebCards](http://35.11.215.147:3000/CCGKyle/WebCardsClient/raw/branch/master/images/wc-icon-144.png) + +An in-browser client to play WebCards
\ No newline at end of file diff --git a/webcards/assets/standard/diamond.svg b/webcards/assets/standard/diamond.svg new file mode 100644 index 0000000..41f7cc2 --- /dev/null +++ b/webcards/assets/standard/diamond.svg @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + style="enable-background:new" + id="svg8" + version="1.1" + viewBox="0 0 33.866666 33.866668" + height="128" + width="128"> + <defs + id="defs2" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + transform="translate(0,-263.13332)" + style="opacity:1" + id="layer1"> + <path + id="path859" + d="M 16.933333,295.73051 5.3453296,280.06665 16.933332,264.40279 28.521336,280.06665 Z" + style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.49378231;stroke-opacity:1" /> + </g> +</svg> diff --git a/webcards/assets/standard/heart.svg b/webcards/assets/standard/heart.svg new file mode 100644 index 0000000..8cc32e4 --- /dev/null +++ b/webcards/assets/standard/heart.svg @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + width="128" + height="128" + viewBox="0 0 33.866666 33.866668" + version="1.1" + id="svg8" + style="enable-background:new"> + <defs + id="defs2" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <path + transform="matrix(0.26458334,0,0,0.26458334,1.2695285,1.26953)" + style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.3796902;stroke-opacity:1;enable-background:new" + d="M 31.880591,0.16895874 C 14.609272,3.6552705 -0.10970932,24.675453 6.162248e-4,42.266772 0.20206882,74.388447 59.172962,118.40354 59.172962,118.40354 c 0,0 59.020808,-44.003376 59.229928,-76.136768 C 118.51733,24.675491 103.79578,3.6475603 86.522912,0.16895874 76.21487,-1.9070223 59.229844,15.963831 59.229844,15.963831 c 0,0 -17.02625,-17.8786392 -27.349253,-15.79487226 z" + id="path815" /> +</svg> diff --git a/webcards/client.html b/webcards/client.html index 70d7f1d..0b06712 100644 --- a/webcards/client.html +++ b/webcards/client.html @@ -8,37 +8,54 @@ <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700&display=swap" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="styles/icofont.css"> + <link rel="stylesheet" type="text/css" href="styles/input.css"> + <link rel="stylesheet" type="text/css" href="styles/client/base.css"> <link rel="stylesheet" type="text/css" href="styles/client/desktop.css"> <link rel="stylesheet" type="text/css" href="styles/client/tablet.css"> <link rel="stylesheet" type="text/css" href="styles/client/mobile.css"> - - <!--<script src="scripts/libs/discord-rpc.js"></script>--> - <script src="scripts/client/message.js"></script> - <script src="scripts/client/sock.js"></script> - <script src="scripts/client/lobby.js"></script> - <script src="scripts/client/table.js"></script> - <script src="scripts/client/client.js"></script> + <link rel="stylesheet" type="text/css" href="styles/client/card.css"> + + <link rel="icon" sizes="32x32" href="images/wc-icon-32.png"> + <link rel="icon" sizes="48x48" href="images/wc-icon-48.png"> + <link rel="icon" sizes="96x96" href="images/wc-icon-96.png"> + <link rel="icon" sizes="144x144" href="images/wc-icon-144.png"> + <link rel="icon" sizes="288x288" href="images/wc-icon-288.png"> + + <script src="scripts/cards/card.js"></script> + <script src="scripts/cards/deck.js"></script> + <script src="scripts/cards/drag.js"></script> + + <script src="scripts/gui/input.js"></script> + <script src="scripts/gui/lobby.js"></script> + <script src="scripts/gui/table.js"></script> + + <script src="scripts/socket/message.js"></script> + <script src="scripts/socket/sock.js"></script> + + <script src="scripts/client.js"></script> + + <title>WebCards - Client</title> </head> <body> - <div class="table" style="visibility: hidden;"> + <div class="table" state="closed"> </div> <div class="topbar" style="height: auto;"> <div class="top-buttons"> - <button id="newgame" class="top-button" onclick="game.lob.newGameScreen()"></button> - <button id="settings" class="top-button" onclick="game.lob.mobileSettingsScreen()"></button> + <button id="newgame" class="top-button" onclick="game.lob.newGame()"></button> + <button id="settings" class="top-button" onclick="game.lob.mobileSettings()"></button> <button id="reset" class="top-button" onclick="game.reset()"></button> </div> <div class="new-game" style="display: none;"></div> - <div class="mobile-settings" style="display: none;"> - <span><input type="text" id="name" placeholder="Username"/></span> - <span><input type="color" id="usercolor" value="#f00"/></span> + <div class="settings mobile-settings" style="display: none;"> + <span><input type="text" placeholder="Username"/></span> + <span><input type="color" value="#f00"/></span> <button id="set">Accept Settings</button> </div> @@ -82,11 +99,10 @@ </div> </div> - <div class="settings"> - <span><input type="text" id="name" placeholder="Username"/></span> - <span><input type="color" id="usercolor" value="#f00"/></span> - - <button onclick="game.acceptSettings()">Accept Settings</button> + <div class="settings" > + <div class="input-container" type="color" onclick="this.getElementsByTagName('input')[0].click()"> + <input type="color"> + </div> </div> </div> </div> @@ -96,6 +112,36 @@ var params = new URLSearchParams((new URL(window.location)).search); var game = new Client(params.get("s"), params.get("g")); setTimeout(game.init.bind(game), 100); + + + // Live testing purposes only + var d = new MultiDrag(); + var c1 = new Card({ + all: [ + { + type: "image", + image: "assets/standard/diamond.svg" + } + ] + }); + var c2 = new Card({ + all: [ + { + type: "image", + image: "assets/standard/heart.svg" + } + ] + }); + function test() { + c1.e.addEventListener("mousedown", d.startDragging.bind(d)); + c1.e.addEventListener("mouseup", d.stopDraggingAll.bind(d)); + c2.e.addEventListener("mousedown", d.startDragging.bind(d)); + c2.e.addEventListener("mouseup", d.stopDraggingAll.bind(d)); + + game.tab.root.append(c1.e); + game.tab.root.append(c2.e); + game.tab.openTable(); + } </script> </body> diff --git a/webcards/favicon.ico b/webcards/favicon.ico Binary files differnew file mode 100644 index 0000000..91e0742 --- /dev/null +++ b/webcards/favicon.ico diff --git a/webcards/images/wc-icon-144.png b/webcards/images/wc-icon-144.png Binary files differnew file mode 100644 index 0000000..ecc4084 --- /dev/null +++ b/webcards/images/wc-icon-144.png diff --git a/webcards/images/wc-icon-288.png b/webcards/images/wc-icon-288.png Binary files differnew file mode 100644 index 0000000..04f6a07 --- /dev/null +++ b/webcards/images/wc-icon-288.png diff --git a/webcards/images/wc-icon-32.png b/webcards/images/wc-icon-32.png Binary files differnew file mode 100644 index 0000000..ec390c5 --- /dev/null +++ b/webcards/images/wc-icon-32.png diff --git a/webcards/images/wc-icon-48.png b/webcards/images/wc-icon-48.png Binary files differnew file mode 100644 index 0000000..e787102 --- /dev/null +++ b/webcards/images/wc-icon-48.png diff --git a/webcards/images/wc-icon-96.png b/webcards/images/wc-icon-96.png Binary files differnew file mode 100644 index 0000000..a10d0eb --- /dev/null +++ b/webcards/images/wc-icon-96.png diff --git a/webcards/index.html b/webcards/index.html index c7d2f71..c322ec1 100644 --- a/webcards/index.html +++ b/webcards/index.html @@ -8,14 +8,24 @@ <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700&display=swap" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="styles/icofont.css"> + <link rel="icon" sizes="32x32" href="images/wc-icon-32.png"> + <link rel="icon" sizes="48x48" href="images/wc-icon-48.png"> + <link rel="icon" sizes="96x96" href="images/wc-icon-96.png"> + <link rel="icon" sizes="144x144" href="images/wc-icon-144.png"> + <link rel="icon" sizes="288x288" href="images/wc-icon-288.png"> + <link rel="stylesheet" type="text/css" href="styles/home/base.css"> <link rel="stylesheet" type="text/css" href="styles/home/desktop.css"> <link rel="stylesheet" type="text/css" href="styles/home/mobile.css"> + + <link rel="stylesheet" type="text/css" href="styles/input.css"> + + <title>WebCards</title> </head> <body> <div class="content"> - <p style="font-size: 30px; font-weight: bold;"><span style="color: dodgerblue; font-weight: normal;">Web</span>Cards</p> + <p style="font-size: 30px; font-weight: normal;">Web<span style="color: #0084ff; font-weight: bold;">Cards</span></p> <div> <select id="type"> <option value="ws://" selected>ws</option> @@ -27,7 +37,7 @@ <input id="port" type="number" value="4040"> </div> - <a id="conn" href="client.html?s=ws://127.0.0.1:4040&g=-1">Connect</a> + <button id="conn" onclick="connect()">Connect</a> </div> <script> @@ -40,9 +50,10 @@ a.onchange = updateLink; p.onchange = updateLink; - function updateLink() { - var url = "client.html?s=" + t.value + a.value + ":" + p.value + "&g=-1"; - c.setAttribute("href", url); + function connect() { + var url = "./client.html?s=" + t.value + a.value + ":" + p.value + "&g=-1"; + //c.setAttribute("href", url); + window.location = url; } </script> </body> diff --git a/webcards/scripts/cards/card.js b/webcards/scripts/cards/card.js new file mode 100644 index 0000000..015995d --- /dev/null +++ b/webcards/scripts/cards/card.js @@ -0,0 +1,97 @@ +var CardPos = ["top", "topl", "topr", "mid", "midt", "midb", "bot", "botl", "botr", "all"]; + +// Card class represents one card. +// Every card should have a deck. +// Use deck.appendCard or deck.prependCard to make a card visible +function Card (data) { + this.e = this.generateElements(data); + this.e.style.left = "0px"; + this.e.style.top = "0px"; +} + +// Internal +Card.prototype = { + // Main generation func + generateElements: function (data) { + switch (typeof data) { + case "object": + return this.generateObjectCard(data); + case "string": + return this.generateBasicCard(data); + } + let e = document.createElement("card"); + let t = document.createElement("carea"); + t.className = "mid"; + t.innerText = "Card Error: data"; + e.append(t); + return e; + }, + + // Generate a card with basic text only + generateBasicCard: function (data) { + let e = document.createElement("card"); + let t = document.createElement("carea"); + t.className = "mid"; + t.innerText = data; + e.appendChild(t); + return e; + }, + + // Generate a card with rich visuals + generateObjectCard: function (data) { + let e = document.createElement("card"); + + // Check for an asset URL + if (typeof data.assetURL != "string") { + data.assetURL = ""; + } + + // Set card styles + for (let i in data.style) { + e.style[i] = data.style[i]; + } + + // Generate card areas. + for (let i in CardPos) { + if (typeof data[CardPos[i]] == "object") + e.appendChild(this.generateCArea(data[CardPos[i]], CardPos[i], data.assetURL)); + } + + return e; + }, + + generateCArea: function (data, carea, assetURL) { + // Create and set area + let area = document.createElement("carea"); + area.className = carea; + + // Create inner area text and images + for (let i in data) { + if (i == "style") + for (j in data.style) + area.style[j] = data.style[j]; + + if (data[i].type == "text") { + let e = document.createElement("ctext"); + + e.innerText = data[i].text; + + for (let j in data[i].style) { + e.style[j] = data[i].style[j]; + } + + area.appendChild(e); + + } else if (data[i].type == "image") { + let e = document.createElement("cimage"); + + e.style.backgroundImage = "url(\"" + assetURL + data[i].image + "\")"; + + area.appendChild(e); + } + } + + return area; + } + +};
\ No newline at end of file diff --git a/webcards/scripts/cards/deck.js b/webcards/scripts/cards/deck.js new file mode 100644 index 0000000..544a9ef --- /dev/null +++ b/webcards/scripts/cards/deck.js @@ -0,0 +1,106 @@ +// Deck class represents multiple cards. +// Can be arranged in multiple ways. +function Deck (options = {}){ + this.cards = []; + + // View mode + // infdraw - infinite draw. always appears as if there are multiple cards + // stack - stack mode + // strip + // horizontal + // left (strip-hl) + // right (strip-hr) + // vertical + // top (strip-vt) + // bottom (strip-vb) + this.mode = options.mode; + + // Select mode + // above + // below + // around + // one + // all + this.smode = options.smode; + + // Select count (-1 = all available) + // above - controls number of cards above clicked are selected + // below - controls number of cards below clicked are selected + // around + // number - number above and below selected + // array - [first number: number above selected] [second number: number below selected] + // one - no effect + // all - no effect + this.sct = options.sct; + + // Position + // array of where the deck is centered + this.x = options.pos[0]; + this.y = options.pos[1]; + + this.e = document.createElement("deck"); +} + +Deck.prototype = { + // Add a card to the front of the deck + appendCard: function(card) { + this.cards.push(card); + this.e.appendChild(card.e); + }, + + // Add a card to the back of the deck + prependCard: function(card) { + this.cards.unshift(card); + this.e.prepend(card.e); + }, + + // Add a card at the index specified + addCardAt: function(card, index) { + if(index < 0 || index > this.cards.length) + return + + if(index == 0) { + this.prependCard(card); + } else if (index == this.cards.length) { + this.appendCard(card); + } else { + let temp = this.cards.slice(0, index); + temp[temp.length - 1].e.after(card.e); + temp.push(card); + this.cards.unshift(...temp); + } + }, + + // Swap the cards at the specified indexes + swapCard: function(index1, index2) { + if(index1 < 0 || index1 >= this.cards.length || index2 < 0 || index2 >= this.cards.length) + return + + var temp = this.cards[index1] + this.cards[index1] = this.cards[index2]; + this.cards[index2] = temp; + + this.cards[index1 - 1].e.after(this.cards[index1]); + this.cards[index2 - 1].e.after(this.cards[index2]); + }, + + // Remove the card at the front of the deck (index length - 1), returns the card removed (if any) + removeFront: function() { + return this.removeCard(this.cards.length - 1); + }, + + // Remove the card at the back of the deck (index 0), returns the card removed (if any) + removeBack: function() { + return this.removeCard(0); + }, + + // Remove a card from the deck, returning the card element + removeCard: function(index) { + + if(index < 0 || index >= this.cards.length) + return + + this.e.removeChild(this.cards[index].e); + return this.cards.splice(index, 1)[0]; + } +};
\ No newline at end of file diff --git a/webcards/scripts/cards/drag.js b/webcards/scripts/cards/drag.js new file mode 100644 index 0000000..cce1e72 --- /dev/null +++ b/webcards/scripts/cards/drag.js @@ -0,0 +1,83 @@ +function MultiDrag() { + this.del = false; + this.drag = []; + window.addEventListener("mousemove", this.update.bind(this)); + document.body.addEventListener("mouseleave", this.stopDraggingAll.bind(this)); +} + +MultiDrag.prototype = { + addDragEl: function(el, ox, oy, px, py, pt) { + if(this.del) + return; + + el.style.transitionDuration = "0.04s"; + + this.drag.push({ + e: el, + osx: ox, + osy: oy, + prx: px, + pry: py, + ptd: pt + }); + + return this.drag.length - 1; + }, + + startDragging: function(mevent) { + if(this.del) + return; + + console.log(mevent); + + if(mevent.button != 0) + return; + + let pos = mevent.target.getBoundingClientRect(); + + return this.addDragEl( + mevent.currentTarget, + mevent.clientX - pos.left, + mevent.clientY - pos.top, + mevent.currentTarget.style.left, + mevent.currentTarget.style.top, + mevent.currentTarget.style.transitionDuration + ); + }, + + stopDragging: function(i) { + this.del = true; + + if (i < 0 || i >= this.drag.length) + return; + + this.drag[i].e.style.transitionDuration = this.drag[i].ptd; + this.drag[i].e.style.left = this.drag[i].prx; + this.drag[i].e.style.top = this.drag[i].pry; + + this.drag.splice(i, 1); + + this.del = false; + }, + + stopDraggingAll: function() { + this.del = true; + + while (this.drag.length > 0) { + this.drag[0].e.style.transitionDuration = this.drag[0].ptd; + this.drag[0].e.style.left = this.drag[0].prx; + this.drag[0].e.style.top = this.drag[0].pry; + + this.drag.shift(); + } + + this.del = false; + }, + + update: function(e) { + for (let i = 0; i < this.drag.length && !this.del; i++) { + this.drag[i].e.style.left = e.clientX - this.drag[i].osx + "px"; + this.drag[i].e.style.top = e.clientY - this.drag[i].osy + "px"; + } + } +};
\ No newline at end of file diff --git a/webcards/scripts/client/client.js b/webcards/scripts/client.js index b5dd4bf..ea62e26 100644 --- a/webcards/scripts/client/client.js +++ b/webcards/scripts/client.js @@ -13,12 +13,13 @@ function Client(serveraddr, game) { } Client.prototype = { + // Initialize the connection init: function() { this.soc.init(); }, - // Entry point for a message. - // If it's a close message, the + // Entry point for a message from the server. + // If it's a close message, we close the game if it is open and change the lobby to reflect the error/close. cb: function(m) { console.log(m); @@ -42,6 +43,7 @@ Client.prototype = { } }, + // Called when negotiating with the server for the first time and we are determining versions handshake: function(m) { switch (m.type) { case "verr": @@ -57,6 +59,7 @@ Client.prototype = { } }, + // Lobby switch, called when in the lobby and a message arrives from the server lobby: function (m) { switch (m.type) { case "plist": @@ -87,6 +90,7 @@ Client.prototype = { } }, + // Game switch, called when in game and a message arrives from the server game: function (m) { switch (m.type) { diff --git a/webcards/scripts/client/lobby.js b/webcards/scripts/client/lobby.js deleted file mode 100644 index 8d46352..0000000 --- a/webcards/scripts/client/lobby.js +++ /dev/null @@ -1,102 +0,0 @@ -// Lobby manages the players and games provided by the server and allows users to join or create their own games. -function Lobby(el){ - this.root = el; - - this.elements = { - status: this.root.getElementsByClassName("status")[0], - addr: this.root.getElementsByClassName("addr")[0], - - stats: { - game: document.getElementById("game"), - packs: document.getElementById("packs"), - online: document.getElementById("online"), - ingame: document.getElementById("ingame"), - pubgame: document.getElementById("pubgame") - }, - - settings: { - name: document.getElementById("name"), - color: document.getElementById("usercolor") - } - }; - - this.top = new TopBar(document.getElementsByClassName("topbar")[0]); - - this.init = false; - this.online = []; - this.games = []; - this.packs = []; - this.players = []; -} - -Lobby.prototype = { - packList: function(data){ - - this.elements.stats.packs.innerText = this.packs.length(); - }, - - gameList: function(data, game){ - - this.elements.stats.pubgame.innerText = this.games.length(); - }, - - players: function(data) { - - this.elements.stats.online.innerText = this.players.length(); - this.init = true; - }, - - addGame: function(data){ - - }, - - removeGame: function(data){ - - }, - - addPlayer: function(data){ - - }, - - movePlayer: function(data){ - - }, - - removePlayer: function(data){ - - }, - - newGameScreen: function(){ - if(this.init) return; - }, - - setState: function(text, color, server){ - this.elements.status.style.backgroundColor = color; - this.elements.status.innerText = text; - this.elements.addr.innerText = server; - this.top.setColor(color); - }, - - reset: function(){ - this.setState("Connecting", "#DA0", this.elements.addr.innerText); - this.init = false; - } -}; - -// ############### -// # TopBar Code # -// ############### - -function TopBar(el) { - this.root = el; - - this.newGame = el.getElementsByClassName("new-game")[0]; - this.mobileSettings = el.getElementsByClassName("mobile-settings")[0]; - this.status = el.getElementsByClassName("status")[0]; -} - -TopBar.prototype = { - setColor: function(color) { - this.status.style.backgroundColor = color; - } -}; diff --git a/webcards/scripts/client/table.js b/webcards/scripts/client/table.js deleted file mode 100644 index 911763a..0000000 --- a/webcards/scripts/client/table.js +++ /dev/null @@ -1,16 +0,0 @@ -// Table represents and manages the actual game. It accepts inputs from the server and tries to queries the server when the player makes a move. -function Table(el, soc) { - this.root = el; - this.soc = soc; -} - -Table.prototype = { - - handleClose: function() { - - }, - - reset: function() { - - } -}
\ No newline at end of file diff --git a/webcards/scripts/gui/input.js b/webcards/scripts/gui/input.js new file mode 100644 index 0000000..c349a07 --- /dev/null +++ b/webcards/scripts/gui/input.js @@ -0,0 +1,159 @@ +var inputFuncs = { + createInput: function(type = "text", wrapped = false, id) { + var el = document.createElement("input"); + el.setAttribute("type", type); + + if(typeof id == "string") + el.setAttribute("id", id); + + if(wrapped) { + var wrapper = document.createElement("div"); + wrapper.className = "input-container"; + wrapper.setAttribute("type", type); + wrapper.setAttribute("onclick", "this.firstElementChild.click()"); + wrapper.appendChild(el); + wrapper.input = el; + return wrapper; + } + + el.getValue = function () { + return this.value; + } + return el; + }, + + inputLabel(text, id) { + var el = document.createElement("label"); + el.innerText = text; + if(typeof id == "string") + el.setAttribute("for", id); + return el; + }, + + colorInput: function(value, id) { + var el = this.createInput("color", true, id); + el.value = value; + return el; + }, + + textInput: function(value, placeholder, id) { + var el = this.createInput("text", false, id); + el.setAttribute("placeholder", placeholder); + el.value = value; + return el; + }, + + numberInput: function(value, id) { + var el = this.createInput("number", false, id); + el.value = value; + return el; + }, + + fileInput: function(value, id) { + var el = this.createInput("file", true, id); + + el.value = value; + + el.setAttribute("data-files", "Choose a file"); + + el.firstElementChild.onchange = function () { + let text = ""; + switch (this.files.length) { + case 0: + text = "Choose a file"; + break; + case 1: + text = "File: " + this.files[0].name; + break; + default: + text = "Files: " + this.files[0].name + "..."; + break; + } + el.setAttribute("data-files", text); + } + + return el; + }, + + checkboxInput: function(checked = false, id) { + var el = this.createInput("checkbox", false, id); + if(checked) + el.setAttribute("checked"); + return el; + }, + + radioInput: function(group, value, checked = false, id) { + var el = this.createInput("radio", false, id); + el.setAttribute("name", group); + el.setAttribute("value", value); + if(checked) + el.checked = true; + return el; + }, + + radioInputs: function(group, names, values, checked = 0) { + var wrapper = document.createElement("div"); + wrapper.className = "input-container"; + wrapper.setAttribute("type", "radio"); + + wrapper.getValue = function() { + for(let i = 0; i < this.children.length; i++){ + if(this.children[i].checked) + return this.children[i].value; + } + }; + + for(let i = 0; i < values.length; i++) { + wrapper.appendChild(this.inputLabel(names[i], group+"-"+i)); + if(i == checked) + wrapper.appendChild(this.radioInput(group, values[i], true, group+"-"+i)); + else + wrapper.appendChild(this.radioInput(group, values[i], false, group+"-"+i)); + wrapper.appendChild(document.createElement("br")); + } + + return wrapper; + }, + + wrapInput: function(el) { + + } +}; + +function Settings () { + this.settings = { + username: { + type: "text", + args: [Math.floor(Math.random() * 100000), "Username", "userName"] + } + }; + + this.genSettings(); +} + +Settings.prototype = { + getSettings: function() { + var out = {}; + for(let key in this.settings) { + + } + }, + + putSettings: function (el) { + for(let key in this.settings) { + el.appendChild(this.settings[key]); + } + }, + + genSettings: function() { + for(let key in this.settings) { + switch(this.settings[key].type) { + case "radio": + this.settings[key] = inputFuncs.radioInputs(...this.settings[key].args); + default: + if(typeof inputFuncs[this.settings[key].type+"Input"] != null) + this.settings[key] = inputFuncs[this.settings[key].type+"Input"](...this.settings[key].args); + } + } + } +};
\ No newline at end of file diff --git a/webcards/scripts/gui/lobby.js b/webcards/scripts/gui/lobby.js new file mode 100644 index 0000000..731d9ec --- /dev/null +++ b/webcards/scripts/gui/lobby.js @@ -0,0 +1,196 @@ +// Lobby manages the players and games provided by the server and allows users to join or create their own games. +function Lobby(el){ + this.root = el; + + this.e = { + status: el.getElementsByClassName("status")[0], + addr: el.getElementsByClassName("addr")[0], + games: el.getElementsByClassName("games")[0], + settings: el.getElementsByClassName("settings")[0], + + stats: { + game: document.getElementById("game"), + packs: document.getElementById("packs"), + online: document.getElementById("online"), + ingame: document.getElementById("ingame"), + pubgame: document.getElementById("pubgame") + } + }; + + this.top = new TopBar(document.getElementsByClassName("topbar")[0]); + + this.init = false; + this.online = []; + this.games = []; + this.packs = []; + this.players = []; +} + +Lobby.prototype = { + // Set initial pack list + // {data array} array of strings representing pack names + packList: function(data) { + this.packs = data; + this.top.setPacks(this.packs) + this.e.stats.packs.innerText = this.packs.length(); + }, + + // Set initial game list. + // { data object } object containing {games} and {name} + // { data.name string } name of the game the server runs + // { data.games array } array of public games the server is running + // { data.games[n].name } room name + // { data.games[n].packs } list of the pack names used by this game + // { data.games[n].id } room identifier (uuid) + // { data.games[n].max } max players in room + gameList: function(data) { + while (this.e.games.firstChild != null) { + this.e.games.remove(this.elements.games.firstChild) + } + + for (let i in data.games) { + let gel = new GameEl(i.name, i.packs, i.id); + this.games.push(gel); + this.e.games.appendChild(gel.getElement()); + } + + this.e.stats.game.innerText = data.name; + this.e.stats.pubgame.innerText = this.games.length(); + }, + + // Set the initial player list. + // { data array } represents a list of player objects from the server + // { data[n].name string } name of the player + // { data[n].game string } id of the game room (empty if not in game). + // { data[n].color string } css color chosen by player. + // { data[n].uuid string } uuid of the player + players: function(data) { + + this.e.stats.online.innerText = this.players.length(); + this.init = true; + }, + + // Called when a new public game is created on the server + // { data object } the game object + // { data.name } room name + // { data.packs } list of the pack names used by this game + // { data.id } room identifier (uuid) + addGame: function(data) { + + }, + + // Called when a new public game is removed on the server + // { data string } the uuid of the game to delete + removeGame: function(data) { + + }, + + // Called when a new player enters the lobby. + // { data object } an object representing the player + // { data.name string } name of the player + // { data.game string } id of the game room (empty if not in game). + // { data.color string } css color chosen by player. + // { data.uuid string } uuid of the player + addPlayer: function(data) { + + }, + + // Called when a player modifies their settings in the lobby. + // { data object } new player settings + // { data.name string } non null if the player has changed their name + // { data.color string } non null if the player has changed their color + // { data.uuid string } uuid of player changing their settings + modPlayer: function(data) { + + }, + + // Called when a player moves between the lobby and a game, or between two games + // { data object } new location + // { data.player } uuid of player changing location + // { data.loc } uuid of room player is moving to (empty if moving to lobby) + movePlayer: function(data) { + + }, + + // Called when a player exits the game (from lobby or game) + // {data string } uuid of player + removePlayer: function(data) { + + }, + + // Called when the client wants to toggle the new game screen + newGame: function() { + //if(this.init) return; + this.top.toggleNewGame(); + }, + + // Called when the client wants to toggle the mobile settings screen + mobileSettings: function() { + //if(this.init) return; + this.top.toggleMobileSettings(); + }, + + // Called when the WebSocket state has changed. + setState: function(text, color, server) { + this.e.status.style.backgroundColor = color; + this.e.status.innerText = text; + this.e.addr.innerText = server; + this.top.setColor(color); + }, + + // Called when we are resetting the game. + reset: function() { + while (this.e.games.firstElementChild != null) { + this.e.games.removeChild(this.e.games.firstElementChild) + } + + this.setState("Connecting", "#DA0", this.e.addr.innerText); + this.init = false; + } +}; + +// ############### +// # TopBar Code # +// ############### + +// TopBar represents the bar at the top of the screen when client is in the lobby. + +function TopBar(el) { + this.root = el; + + this.newGame = el.getElementsByClassName("new-game")[0]; + this.mobileSettings = el.getElementsByClassName("mobile-settings")[0]; + this.status = el.getElementsByClassName("status")[0]; +} + +TopBar.prototype = { + // Set color of status bar + setColor: function(color) { + this.status.style.backgroundColor = color; + }, + + // Toggle showing the new game screen + toggleNewGame: function() { + if (this.newGame.style.display !== "none") + this.newGame.style.display = "none"; + else + this.newGame.style.display = "block"; + }, + + // Toggle showing the mobile settings + toggleMobileSettings: function() { + if (this.mobileSettings.style.display !== "none") + this.mobileSettings.style.display = "none"; + else + this.mobileSettings.style.display = "block"; + } +}; + +// ############# +// # Game code # +// ############# + +// GameEl represents a single game in the lobby view. It has methods for setting up the elements and such. +function GameEl(name, packs, maxp, id) { + +}
\ No newline at end of file diff --git a/webcards/scripts/gui/table.js b/webcards/scripts/gui/table.js new file mode 100644 index 0000000..db67529 --- /dev/null +++ b/webcards/scripts/gui/table.js @@ -0,0 +1,34 @@ +// Table represents and manages the actual game. It accepts inputs from the server and tries to queries the server when the player makes a move. +function Table(el, soc) { + this.root = el; + this.soc = soc; +} + +Table.prototype = { + + openTable: function(){ + let state = this.root.getAttribute("state") + if((state == "close" || state == "closed") && state != "") { + this.root.setAttribute("state", "closed"); + setTimeout(this.root.setAttribute.bind(this.root), 50, "state", "open"); + } + }, + + closeTable: function(){ + let state = this.root.getAttribute("state") + if(state != "close" && state != "closed") { + this.root.setAttribute("state", ""); + setTimeout(this.root.setAttribute.bind(this.root), 50, "state", "close"); + } + }, + + + + handleClose: function() { + this.reset(); + }, + + reset: function() { + this.closeTable(); + } +}
\ No newline at end of file diff --git a/webcards/scripts/libs/discord-rpc.js b/webcards/scripts/libs/discord-rpc.js deleted file mode 100644 index b51d10f..0000000 --- a/webcards/scripts/libs/discord-rpc.js +++ /dev/null @@ -1,8 +0,0 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.RPC=e():t.RPC=e()}(window,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=6)}([function(t,e,n){"use strict";(function(e){let r;try{const{app:t}=n(7);r=t.setAsDefaultProtocolClient.bind(t)}catch(t){try{r=n(8)}catch(t){}}"function"!=typeof r&&(r=()=>!1);t.exports={pid:function(){return void 0!==e?e.pid:null},register:r,uuid:()=>{let t="";for(let e=0;e<32;e+=1){let n;if(8!==e&&12!==e&&16!==e&&20!==e||(t+="-"),12===e)n=4;else{const t=16*Math.random()|0;n=16===e?3&t|0:t}t+=n.toString(16)}return t}}}).call(this,n(1))},function(t,e){var n,r,i=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(t){n=o}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(t){r=s}}();var a,c=[],f=!1,h=-1;function l(){f&&a&&(f=!1,a.length?c=a.concat(c):h=-1,c.length&&p())}function p(){if(!f){var t=u(l);f=!0;for(var e=c.length;e;){for(a=c,c=[];++h<e;)a&&a[h].run();h=-1,e=c.length}a=null,f=!1,function(t){if(r===clearTimeout)return clearTimeout(t);if((r===s||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(t)}}function d(t,e){this.fun=t,this.array=e}function E(){}i.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];c.push(new d(t,e)),1!==c.length||f||u(p)},d.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=E,i.addListener=E,i.once=E,i.off=E,i.removeListener=E,i.removeAllListeners=E,i.emit=E,i.prependListener=E,i.prependOnceListener=E,i.listeners=function(t){return[]},i.binding=function(t){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(t){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},function(t,e,n){"use strict";var r,i="object"==typeof Reflect?Reflect:null,o=i&&"function"==typeof i.apply?i.apply:function(t,e,n){return Function.prototype.apply.call(t,e,n)};r=i&&"function"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:function(t){return Object.getOwnPropertyNames(t)};var s=Number.isNaN||function(t){return t!=t};function u(){u.init.call(this)}t.exports=u,u.EventEmitter=u,u.prototype._events=void 0,u.prototype._eventsCount=0,u.prototype._maxListeners=void 0;var a=10;function c(t){if("function"!=typeof t)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}function f(t){return void 0===t._maxListeners?u.defaultMaxListeners:t._maxListeners}function h(t,e,n,r){var i,o,s,u;if(c(n),void 0===(o=t._events)?(o=t._events=Object.create(null),t._eventsCount=0):(void 0!==o.newListener&&(t.emit("newListener",e,n.listener?n.listener:n),o=t._events),s=o[e]),void 0===s)s=o[e]=n,++t._eventsCount;else if("function"==typeof s?s=o[e]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),(i=f(t))>0&&s.length>i&&!s.warned){s.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");a.name="MaxListenersExceededWarning",a.emitter=t,a.type=e,a.count=s.length,u=a,console&&console.warn&&console.warn(u)}return t}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(t,e,n){var r={fired:!1,wrapFn:void 0,target:t,type:e,listener:n},i=l.bind(r);return i.listener=n,r.wrapFn=i,i}function d(t,e,n){var r=t._events;if(void 0===r)return[];var i=r[e];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(t){for(var e=new Array(t.length),n=0;n<e.length;++n)e[n]=t[n].listener||t[n];return e}(i):_(i,i.length)}function E(t){var e=this._events;if(void 0!==e){var n=e[t];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function _(t,e){for(var n=new Array(e),r=0;r<e;++r)n[r]=t[r];return n}Object.defineProperty(u,"defaultMaxListeners",{enumerable:!0,get:function(){return a},set:function(t){if("number"!=typeof t||t<0||s(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");a=t}}),u.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},u.prototype.setMaxListeners=function(t){if("number"!=typeof t||t<0||s(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this},u.prototype.getMaxListeners=function(){return f(this)},u.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e.push(arguments[n]);var r="error"===t,i=this._events;if(void 0!==i)r=r&&void 0===i.error;else if(!r)return!1;if(r){var s;if(e.length>0&&(s=e[0]),s instanceof Error)throw s;var u=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw u.context=s,u}var a=i[t];if(void 0===a)return!1;if("function"==typeof a)o(a,this,e);else{var c=a.length,f=_(a,c);for(n=0;n<c;++n)o(f[n],this,e)}return!0},u.prototype.addListener=function(t,e){return h(this,t,e,!1)},u.prototype.on=u.prototype.addListener,u.prototype.prependListener=function(t,e){return h(this,t,e,!0)},u.prototype.once=function(t,e){return c(e),this.on(t,p(this,t,e)),this},u.prototype.prependOnceListener=function(t,e){return c(e),this.prependListener(t,p(this,t,e)),this},u.prototype.removeListener=function(t,e){var n,r,i,o,s;if(c(e),void 0===(r=this._events))return this;if(void 0===(n=r[t]))return this;if(n===e||n.listener===e)0==--this._eventsCount?this._events=Object.create(null):(delete r[t],r.removeListener&&this.emit("removeListener",t,n.listener||e));else if("function"!=typeof n){for(i=-1,o=n.length-1;o>=0;o--)if(n[o]===e||n[o].listener===e){s=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(t,e){for(;e+1<t.length;e++)t[e]=t[e+1];t.pop()}(n,i),1===n.length&&(r[t]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",t,s||e)}return this},u.prototype.off=u.prototype.removeListener,u.prototype.removeAllListeners=function(t){var e,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[t]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[t]),this;if(0===arguments.length){var i,o=Object.keys(n);for(r=0;r<o.length;++r)"removeListener"!==(i=o[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(e=n[t]))this.removeListener(t,e);else if(void 0!==e)for(r=e.length-1;r>=0;r--)this.removeListener(t,e[r]);return this},u.prototype.listeners=function(t){return d(this,t,!0)},u.prototype.rawListeners=function(t){return d(this,t,!1)},u.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):E.call(t,e)},u.prototype.listenerCount=E,u.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";var r=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r)return r;throw new Error("unable to locate global object")}();t.exports=e=r.fetch,e.default=r.fetch.bind(r),e.Headers=r.Headers,e.Request=r.Request,e.Response=r.Response},function(t,e,n){"use strict";function r(t){const e={};for(const n of t)e[n]=n;return e}e.browser="undefined"!=typeof window,e.RPCCommands=r(["DISPATCH","AUTHORIZE","AUTHENTICATE","GET_GUILD","GET_GUILDS","GET_CHANNEL","GET_CHANNELS","GET_RELATIONSHIPS","GET_USER","SUBSCRIBE","UNSUBSCRIBE","SET_USER_VOICE_SETTINGS","SET_USER_VOICE_SETTINGS_2","SELECT_VOICE_CHANNEL","GET_SELECTED_VOICE_CHANNEL","SELECT_TEXT_CHANNEL","GET_VOICE_SETTINGS","SET_VOICE_SETTINGS_2","SET_VOICE_SETTINGS","CAPTURE_SHORTCUT","SET_ACTIVITY","SEND_ACTIVITY_JOIN_INVITE","CLOSE_ACTIVITY_JOIN_REQUEST","ACTIVITY_INVITE_USER","ACCEPT_ACTIVITY_INVITE","INVITE_BROWSER","DEEP_LINK","CONNECTIONS_CALLBACK","BRAINTREE_POPUP_BRIDGE_CALLBACK","GIFT_CODE_BROWSER","OVERLAY","BROWSER_HANDOFF","SET_CERTIFIED_DEVICES","GET_IMAGE","CREATE_LOBBY","UPDATE_LOBBY","DELETE_LOBBY","UPDATE_LOBBY_MEMBER","CONNECT_TO_LOBBY","DISCONNECT_FROM_LOBBY","SEND_TO_LOBBY","SEARCH_LOBBIES","CONNECT_TO_LOBBY_VOICE","DISCONNECT_FROM_LOBBY_VOICE","SET_OVERLAY_LOCKED","OPEN_OVERLAY_ACTIVITY_INVITE","OPEN_OVERLAY_GUILD_INVITE","OPEN_OVERLAY_VOICE_SETTINGS","VALIDATE_APPLICATION","GET_ENTITLEMENT_TICKET","GET_APPLICATION_TICKET","START_PURCHASE","GET_SKUS","GET_ENTITLEMENTS","GET_NETWORKING_CONFIG","NETWORKING_SYSTEM_METRICS","NETWORKING_PEER_METRICS","NETWORKING_CREATE_TOKEN","SET_USER_ACHIEVEMENT","GET_USER_ACHIEVEMENTS"]),e.RPCEvents=r(["CURRENT_USER_UPDATE","GUILD_STATUS","GUILD_CREATE","CHANNEL_CREATE","RELATIONSHIP_UPDATE","VOICE_CHANNEL_SELECT","VOICE_STATE_CREATE","VOICE_STATE_DELETE","VOICE_STATE_UPDATE","VOICE_SETTINGS_UPDATE","VOICE_SETTINGS_UPDATE_2","VOICE_CONNECTION_STATUS","SPEAKING_START","SPEAKING_STOP","GAME_JOIN","GAME_SPECTATE","ACTIVITY_JOIN","ACTIVITY_JOIN_REQUEST","ACTIVITY_SPECTATE","ACTIVITY_INVITE","NOTIFICATION_CREATE","MESSAGE_CREATE","MESSAGE_UPDATE","MESSAGE_DELETE","LOBBY_DELETE","LOBBY_UPDATE","LOBBY_MEMBER_CONNECT","LOBBY_MEMBER_DISCONNECT","LOBBY_MEMBER_UPDATE","LOBBY_MESSAGE","CAPTURE_SHORTCUT_CHANGE","OVERLAY","OVERLAY_UPDATE","ENTITLEMENT_CREATE","ENTITLEMENT_DELETE","USER_ACHIEVEMENT_UPDATE","READY","ERROR"]),e.RPCErrors={CAPTURE_SHORTCUT_ALREADY_LISTENING:5004,GET_GUILD_TIMED_OUT:5002,INVALID_ACTIVITY_JOIN_REQUEST:4012,INVALID_ACTIVITY_SECRET:5005,INVALID_CHANNEL:4005,INVALID_CLIENTID:4007,INVALID_COMMAND:4002,INVALID_ENTITLEMENT:4015,INVALID_EVENT:4004,INVALID_GIFT_CODE:4016,INVALID_GUILD:4003,INVALID_INVITE:4011,INVALID_LOBBY:4013,INVALID_LOBBY_SECRET:4014,INVALID_ORIGIN:4008,INVALID_PAYLOAD:4e3,INVALID_PERMISSIONS:4006,INVALID_TOKEN:4009,INVALID_USER:4010,LOBBY_FULL:5007,NO_ELIGIBLE_ACTIVITY:5006,OAUTH2_ERROR:5e3,PURCHASE_CANCELED:5008,PURCHASE_ERROR:5009,RATE_LIMITED:5011,SELECT_CHANNEL_TIMED_OUT:5001,SELECT_VOICE_FORCE_REQUIRED:5003,SERVICE_UNAVAILABLE:1001,TRANSACTION_ABORTED:1002,UNAUTHORIZED_FOR_ACHIEVEMENT:5010,UNKNOWN_ERROR:1e3},e.RPCCloseCodes={CLOSE_NORMAL:1e3,CLOSE_UNSUPPORTED:1003,CLOSE_ABNORMAL:1006,INVALID_CLIENTID:4e3,INVALID_ORIGIN:4001,RATELIMITED:4002,TOKEN_REVOKED:4003,INVALID_VERSION:4004,INVALID_ENCODING:4005},e.LobbyTypes={PRIVATE:1,PUBLIC:2},e.RelationshipTypes={NONE:0,FRIEND:1,BLOCKED:2,PENDING_INCOMING:3,PENDING_OUTGOING:4,IMPLICIT:5}},function(t,e,n){"use strict";const r=n(0);t.exports={Client:n(9),register:t=>r.register(`discord-${t}`)}},function(t,e){},function(t,e){},function(t,e,n){"use strict";const r=n(2),{setTimeout:i,clearTimeout:o}=n(10),s=n(4),u=n(12),{RPCCommands:a,RPCEvents:c,RelationshipTypes:f}=n(5),{pid:h,uuid:l}=n(0);function p(t,e){return`${t}${JSON.stringify(e)}`}t.exports=class extends r{constructor(t={}){super(),this.options=t,this.accessToken=null,this.clientId=null,this.application=null,this.user=null;const e=u[t.transport];if(!e)throw new TypeError("RPC_INVALID_TRANSPORT",t.transport);this.fetch=(t,e,{data:n,query:r}={})=>s(`${this.fetch.endpoint}${e}${r?new URLSearchParams(r):""}`,{method:t,body:n,headers:{Authorization:`Bearer ${this.accessToken}`}}).then(t=>t.json()),this.fetch.endpoint="https://discordapp.com/api",this.transport=new e(this),this.transport.on("message",this._onRpcMessage.bind(this)),this._expecting=new Map,this._subscriptions=new Map,this._connectPromise=void 0}connect(t){return this._connectPromise||(this.clientId=t,this._connectPromise=new Promise((e,n)=>{this.clientId=t;const r=i(()=>n(new Error("RPC_CONNECTION_TIMEOUT")),1e4);r.unref(),this.once("connected",()=>{o(r),e(this)}),this.transport.once("close",()=>{this._expecting.forEach(t=>{t.reject(new Error("connection closed"))}),this.emit("disconnected"),n()}),this.transport.connect().catch(n)})),this._connectPromise}async login(t={}){let{clientId:e,accessToken:n}=t;return await this.connect(e),t.scopes?(n||(n=await this.authorize(t)),this.authenticate(n)):(this.emit("ready"),this)}request(t,e,n){return new Promise((r,i)=>{const o=l();this.transport.send({cmd:t,args:e,evt:n,nonce:o}),this._expecting.set(o,{resolve:r,reject:i})})}_onRpcMessage(t){if(t.cmd===a.DISPATCH&&t.evt===c.READY)t.data.user&&(this.user=t.data.user),this.emit("connected");else if(this._expecting.has(t.nonce)){const{resolve:e,reject:n}=this._expecting.get(t.nonce);if("ERROR"===t.evt){const e=new Error(t.data.message);e.code=t.data.code,e.data=t.data,n(e)}else e(t.data);this._expecting.delete(t.nonce)}else{const e=p(t.evt,t.args);if(!this._subscriptions.has(e))return;this._subscriptions.get(e)(t.data)}}async authorize({scopes:t,clientSecret:e,rpcToken:n,redirectUri:r}={}){if(e&&!0===n){n=(await this.fetch("POST","/oauth2/token/rpc",{data:new URLSearchParams({client_id:this.clientId,client_secret:e})})).rpc_token}const{code:i}=await this.request("AUTHORIZE",{scopes:t,client_id:this.clientId,rpc_token:n,redirect_uri:r});return(await this.fetch("POST","/oauth2/token",{data:new URLSearchParams({client_id:this.clientId,client_secret:e,code:i,grant_type:"authorization_code",redirect_uri:r})})).access_token}authenticate(t){return this.request("AUTHENTICATE",{access_token:t}).then(({application:e,user:n})=>(this.accessToken=t,this.application=e,this.user=n,this.emit("ready"),this))}getGuild(t,e){return this.request(a.GET_GUILD,{guild_id:t,timeout:e})}getGuilds(t){return this.request(a.GET_GUILDS,{timeout:t})}getChannel(t,e){return this.request(a.GET_CHANNEL,{channel_id:t,timeout:e})}async getChannels(t,e){const{channels:n}=await this.request(a.GET_CHANNELS,{timeout:e,guild_id:t});return n}setCertifiedDevices(t){return this.request(a.SET_CERTIFIED_DEVICES,{devices:t.map(t=>({type:t.type,id:t.uuid,vendor:t.vendor,model:t.model,related:t.related,echo_cancellation:t.echoCancellation,noise_suppression:t.noiseSuppression,automatic_gain_control:t.automaticGainControl,hardware_mute:t.hardwareMute}))})}setUserVoiceSettings(t,e){return this.request(a.SET_USER_VOICE_SETTINGS,{user_id:t,pan:e.pan,mute:e.mute,volume:e.volume})}selectVoiceChannel(t,{timeout:e,force:n=!1}={}){return this.request(a.SELECT_VOICE_CHANNEL,{channel_id:t,timeout:e,force:n})}selectTextChannel(t,{timeout:e,force:n=!1}={}){return this.request(a.SELECT_TEXT_CHANNEL,{channel_id:t,timeout:e,force:n})}getVoiceSettings(){return this.request(a.GET_VOICE_SETTINGS).then(t=>({automaticGainControl:t.automatic_gain_control,echoCancellation:t.echo_cancellation,noiseSuppression:t.noise_suppression,qos:t.qos,silenceWarning:t.silence_warning,deaf:t.deaf,mute:t.mute,input:{availableDevices:t.input.available_devices,device:t.input.device_id,volume:t.input.volume},output:{availableDevices:t.output.available_devices,device:t.output.device_id,volume:t.output.volume},mode:{type:t.mode.type,autoThreshold:t.mode.auto_threshold,threshold:t.mode.threshold,shortcut:t.mode.shortcut,delay:t.mode.delay}}))}setVoiceSettings(t){return this.request(a.SET_VOICE_SETTINGS,{automatic_gain_control:t.automaticGainControl,echo_cancellation:t.echoCancellation,noise_suppression:t.noiseSuppression,qos:t.qos,silence_warning:t.silenceWarning,deaf:t.deaf,mute:t.mute,input:t.input?{device_id:t.input.device,volume:t.input.volume}:void 0,output:t.output?{device_id:t.output.device,volume:t.output.volume}:void 0,mode:t.mode?{mode:t.mode.type,auto_threshold:t.mode.autoThreshold,threshold:t.mode.threshold,shortcut:t.mode.shortcut,delay:t.mode.delay}:void 0})}captureShortcut(t){const e=p(c.CAPTURE_SHORTCUT_CHANGE),n=()=>(this._subscriptions.delete(e),this.request(a.CAPTURE_SHORTCUT,{action:"STOP"}));return this._subscriptions.set(e,({shortcut:e})=>{t(e,n)}),this.request(a.CAPTURE_SHORTCUT,{action:"START"}).then(()=>n)}setActivity(t={},e=h()){let n,r,i,o;if(t.startTimestamp||t.endTimestamp){if(n={start:t.startTimestamp,end:t.endTimestamp},n.start instanceof Date&&(n.start=Math.round(n.start.getTime())),n.end instanceof Date&&(n.end=Math.round(n.end.getTime())),n.start>2147483647e3)throw new RangeError("timestamps.start must fit into a unix timestamp");if(n.end>2147483647e3)throw new RangeError("timestamps.end must fit into a unix timestamp")}return(t.largeImageKey||t.largeImageText||t.smallImageKey||t.smallImageText)&&(r={large_image:t.largeImageKey,large_text:t.largeImageText,small_image:t.smallImageKey,small_text:t.smallImageText}),(t.partySize||t.partyId||t.partyMax)&&(i={id:t.partyId},(t.partySize||t.partyMax)&&(i.size=[t.partySize,t.partyMax])),(t.matchSecret||t.joinSecret||t.spectateSecret)&&(o={match:t.matchSecret,join:t.joinSecret,spectate:t.spectateSecret}),this.request(a.SET_ACTIVITY,{pid:e,activity:{state:t.state,details:t.details,timestamps:n,assets:r,party:i,secrets:o,instance:!!t.instance}})}clearActivity(t=h()){return this.request(a.SET_ACTIVITY,{pid:t})}sendJoinInvite(t){return this.request(a.SEND_ACTIVITY_JOIN_INVITE,{user_id:t.id||t})}sendJoinRequest(t){return this.request(a.SEND_ACTIVITY_JOIN_REQUEST,{user_id:t.id||t})}closeJoinRequest(t){return this.request(a.CLOSE_ACTIVITY_JOIN_REQUEST,{user_id:t.id||t})}createLobby(t,e,n){return this.request(a.CREATE_LOBBY,{type:t,capacity:e,metadata:n})}updateLobby(t,{type:e,owner:n,capacity:r,metadata:i}={}){return this.request(a.UPDATE_LOBBY,{id:t.id||t,type:e,owner_id:n&&n.id||n,capacity:r,metadata:i})}deleteLobby(t){return this.request(a.DELETE_LOBBY,{id:t.id||t})}connectToLobby(t,e){return this.request(a.CONNECT_TO_LOBBY,{id:t,secret:e})}sendToLobby(t,e){return this.request(a.SEND_TO_LOBBY,{id:t.id||t,data:e})}disconnectFromLobby(t){return this.request(a.DISCONNECT_FROM_LOBBY,{id:t.id||t})}updateLobbyMember(t,e,n){return this.request(a.UPDATE_LOBBY_MEMBER,{lobby_id:t.id||t,user_id:e.id||e,metadata:n})}getRelationships(){const t=Object.keys(f);return this.request(a.GET_RELATIONSHIPS).then(e=>e.relationships.map(e=>({...e,type:t[e.type]})))}subscribe(t,e,n){return n||"function"!=typeof e||(n=e,e=void 0),this.request(a.SUBSCRIBE,e,t).then(()=>{const r=p(t,e);return this._subscriptions.set(r,n),{unsubscribe:()=>this.request(a.UNSUBSCRIBE,e,t).then(()=>this._subscriptions.delete(r))}})}async destroy(){this.transport.close()}}},function(t,e,n){(function(t){var r=void 0!==t&&t||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;function o(t,e){this._id=t,this._clearFn=e}e.setTimeout=function(){return new o(i.call(setTimeout,r,arguments),clearTimeout)},e.setInterval=function(){return new o(i.call(setInterval,r,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(r,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout((function(){t._onTimeout&&t._onTimeout()}),e))},n(11),e.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==t&&t.setImmediate||this&&this.setImmediate,e.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==t&&t.clearImmediate||this&&this.clearImmediate}).call(this,n(3))},function(t,e,n){(function(t,e){!function(t,n){"use strict";if(!t.setImmediate){var r,i,o,s,u,a=1,c={},f=!1,h=t.document,l=Object.getPrototypeOf&&Object.getPrototypeOf(t);l=l&&l.setTimeout?l:t,"[object process]"==={}.toString.call(t.process)?r=function(t){e.nextTick((function(){d(t)}))}:!function(){if(t.postMessage&&!t.importScripts){var e=!0,n=t.onmessage;return t.onmessage=function(){e=!1},t.postMessage("","*"),t.onmessage=n,e}}()?t.MessageChannel?((o=new MessageChannel).port1.onmessage=function(t){d(t.data)},r=function(t){o.port2.postMessage(t)}):h&&"onreadystatechange"in h.createElement("script")?(i=h.documentElement,r=function(t){var e=h.createElement("script");e.onreadystatechange=function(){d(t),e.onreadystatechange=null,i.removeChild(e),e=null},i.appendChild(e)}):r=function(t){setTimeout(d,0,t)}:(s="setImmediate$"+Math.random()+"$",u=function(e){e.source===t&&"string"==typeof e.data&&0===e.data.indexOf(s)&&d(+e.data.slice(s.length))},t.addEventListener?t.addEventListener("message",u,!1):t.attachEvent("onmessage",u),r=function(e){t.postMessage(s+e,"*")}),l.setImmediate=function(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n<e.length;n++)e[n]=arguments[n+1];var i={callback:t,args:e};return c[a]=i,r(a),a++},l.clearImmediate=p}function p(t){delete c[t]}function d(t){if(f)setTimeout(d,0,t);else{var e=c[t];if(e){f=!0;try{!function(t){var e=t.callback,n=t.args;switch(n.length){case 0:e();break;case 1:e(n[0]);break;case 2:e(n[0],n[1]);break;case 3:e(n[0],n[1],n[2]);break;default:e.apply(void 0,n)}}(e)}finally{p(t),f=!1}}}}}("undefined"==typeof self?void 0===t?this:t:self)}).call(this,n(3),n(1))},function(t,e,n){"use strict";t.exports={ipc:n(13),websocket:n(19)}},function(t,e,n){"use strict";(function(e,r){const i=n(18),o=n(2),s=n(4),{uuid:u}=n(0),a=0,c=1,f=2,h=3,l=4;function p(t=0){return new Promise((n,r)=>{const o=function(t){if("win32"===e.platform)return`\\\\?\\pipe\\discord-ipc-${t}`;const{env:{XDG_RUNTIME_DIR:n,TMPDIR:r,TMP:i,TEMP:o}}=e;return`${(n||r||i||o||"/tmp").replace(/\/$/,"")}/discord-ipc-${t}`}(t),s=()=>{t<10?n(p(t+1)):r(new Error("Could not connect"))},u=i.createConnection(o,()=>{u.removeListener("error",s),n(u)});u.once("error",s)})}function d(t,e){e=JSON.stringify(e);const n=r.byteLength(e),i=r.alloc(8+n);return i.writeInt32LE(t,0),i.writeInt32LE(n,4),i.write(e,8,n),i}const E={full:"",op:void 0};function _(t,e){const n=t.read();if(!n)return;let r,{op:i}=E;if(""===E.full){i=E.op=n.readInt32LE(0);const t=n.readInt32LE(4);r=n.slice(8,t+8)}else r=n.toString();try{e({op:i,data:JSON.parse(E.full+r)}),E.full="",E.op=void 0}catch(t){E.full+=r}_(t,e)}t.exports=class extends o{constructor(t){super(),this.client=t,this.socket=null}async connect(){const t=this.socket=await p();t.on("close",this.onClose.bind(this)),t.on("error",this.onClose.bind(this)),this.emit("open"),t.write(d(a,{v:1,client_id:this.client.clientId})),t.pause(),t.on("readable",()=>{_(t,({op:t,data:e})=>{switch(t){case h:this.send(e,l);break;case c:if(!e)return;"AUTHORIZE"===e.cmd&&"ERROR"!==e.evt&&async function t(e=0){if(e>30)throw new Error("Could not find endpoint");const n=`http://127.0.0.1:${6463+e%10}`;try{return 401!==(await s(n)).status?t(e+1):n}catch(n){return t(e+1)}}().then(t=>{this.client.request.endpoint=t}),this.emit("message",e);break;case f:this.emit("close",e)}})})}onClose(t){this.emit("close",t)}send(t,e=c){this.socket.write(d(e,t))}close(){this.send({},f),this.socket.end()}ping(){this.send(u(),h)}},t.exports.encode=d,t.exports.decode=_}).call(this,n(1),n(14).Buffer)},function(t,e,n){"use strict";(function(t){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh <http://feross.org> - * @license MIT - */ -var r=n(15),i=n(16),o=n(17);function s(){return a.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function u(t,e){if(s()<e)throw new RangeError("Invalid typed array length");return a.TYPED_ARRAY_SUPPORT?(t=new Uint8Array(e)).__proto__=a.prototype:(null===t&&(t=new a(e)),t.length=e),t}function a(t,e,n){if(!(a.TYPED_ARRAY_SUPPORT||this instanceof a))return new a(t,e,n);if("number"==typeof t){if("string"==typeof e)throw new Error("If encoding is specified then the first argument must be a string");return h(this,t)}return c(this,t,e,n)}function c(t,e,n,r){if("number"==typeof e)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer?function(t,e,n,r){if(e.byteLength,n<0||e.byteLength<n)throw new RangeError("'offset' is out of bounds");if(e.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");e=void 0===n&&void 0===r?new Uint8Array(e):void 0===r?new Uint8Array(e,n):new Uint8Array(e,n,r);a.TYPED_ARRAY_SUPPORT?(t=e).__proto__=a.prototype:t=l(t,e);return t}(t,e,n,r):"string"==typeof e?function(t,e,n){"string"==typeof n&&""!==n||(n="utf8");if(!a.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|d(e,n),i=(t=u(t,r)).write(e,n);i!==r&&(t=t.slice(0,i));return t}(t,e,n):function(t,e){if(a.isBuffer(e)){var n=0|p(e.length);return 0===(t=u(t,n)).length||e.copy(t,0,0,n),t}if(e){if("undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return"number"!=typeof e.length||(r=e.length)!=r?u(t,0):l(t,e);if("Buffer"===e.type&&o(e.data))return l(t,e.data)}var r;throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}(t,e)}function f(t){if("number"!=typeof t)throw new TypeError('"size" argument must be a number');if(t<0)throw new RangeError('"size" argument must not be negative')}function h(t,e){if(f(e),t=u(t,e<0?0:0|p(e)),!a.TYPED_ARRAY_SUPPORT)for(var n=0;n<e;++n)t[n]=0;return t}function l(t,e){var n=e.length<0?0:0|p(e.length);t=u(t,n);for(var r=0;r<n;r+=1)t[r]=255&e[r];return t}function p(t){if(t>=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|t}function d(t,e){if(a.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var r=!1;;)switch(e){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return G(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return k(t).length;default:if(r)return G(t).length;e=(""+e).toLowerCase(),r=!0}}function E(t,e,n){var r=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return L(this,e,n);case"utf8":case"utf-8":return C(this,e,n);case"ascii":return S(this,e,n);case"latin1":case"binary":return O(this,e,n);case"base64":return R(this,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,e,n);default:if(r)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),r=!0}}function _(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function T(t,e,n,r,i){if(0===t.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:t.length-1),n<0&&(n=t.length+n),n>=t.length){if(i)return-1;n=t.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof e&&(e=a.from(e,r)),a.isBuffer(e))return 0===e.length?-1:g(t,e,n,r,i);if("number"==typeof e)return e&=255,a.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,n):Uint8Array.prototype.lastIndexOf.call(t,e,n):g(t,[e],n,r,i);throw new TypeError("val must be string, number or Buffer")}function g(t,e,n,r,i){var o,s=1,u=t.length,a=e.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(t.length<2||e.length<2)return-1;s=2,u/=2,a/=2,n/=2}function c(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(i){var f=-1;for(o=n;o<u;o++)if(c(t,o)===c(e,-1===f?0:o-f)){if(-1===f&&(f=o),o-f+1===a)return f*s}else-1!==f&&(o-=o-f),f=-1}else for(n+a>u&&(n=u-a),o=n;o>=0;o--){for(var h=!0,l=0;l<a;l++)if(c(t,o+l)!==c(e,l)){h=!1;break}if(h)return o}return-1}function y(t,e,n,r){n=Number(n)||0;var i=t.length-n;r?(r=Number(r))>i&&(r=i):r=i;var o=e.length;if(o%2!=0)throw new TypeError("Invalid hex string");r>o/2&&(r=o/2);for(var s=0;s<r;++s){var u=parseInt(e.substr(2*s,2),16);if(isNaN(u))return s;t[n+s]=u}return s}function m(t,e,n,r){return j(G(e,t.length-n),t,n,r)}function I(t,e,n,r){return j(function(t){for(var e=[],n=0;n<t.length;++n)e.push(255&t.charCodeAt(n));return e}(e),t,n,r)}function v(t,e,n,r){return I(t,e,n,r)}function A(t,e,n,r){return j(k(e),t,n,r)}function w(t,e,n,r){return j(function(t,e){for(var n,r,i,o=[],s=0;s<t.length&&!((e-=2)<0);++s)n=t.charCodeAt(s),r=n>>8,i=n%256,o.push(i),o.push(r);return o}(e,t.length-n),t,n,r)}function R(t,e,n){return 0===e&&n===t.length?r.fromByteArray(t):r.fromByteArray(t.slice(e,n))}function C(t,e,n){n=Math.min(t.length,n);for(var r=[],i=e;i<n;){var o,s,u,a,c=t[i],f=null,h=c>239?4:c>223?3:c>191?2:1;if(i+h<=n)switch(h){case 1:c<128&&(f=c);break;case 2:128==(192&(o=t[i+1]))&&(a=(31&c)<<6|63&o)>127&&(f=a);break;case 3:o=t[i+1],s=t[i+2],128==(192&o)&&128==(192&s)&&(a=(15&c)<<12|(63&o)<<6|63&s)>2047&&(a<55296||a>57343)&&(f=a);break;case 4:o=t[i+1],s=t[i+2],u=t[i+3],128==(192&o)&&128==(192&s)&&128==(192&u)&&(a=(15&c)<<18|(63&o)<<12|(63&s)<<6|63&u)>65535&&a<1114112&&(f=a)}null===f?(f=65533,h=1):f>65535&&(f-=65536,r.push(f>>>10&1023|55296),f=56320|1023&f),r.push(f),i+=h}return function(t){var e=t.length;if(e<=4096)return String.fromCharCode.apply(String,t);var n="",r=0;for(;r<e;)n+=String.fromCharCode.apply(String,t.slice(r,r+=4096));return n}(r)}e.Buffer=a,e.SlowBuffer=function(t){+t!=t&&(t=0);return a.alloc(+t)},e.INSPECT_MAX_BYTES=50,a.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:function(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(t){return!1}}(),e.kMaxLength=s(),a.poolSize=8192,a._augment=function(t){return t.__proto__=a.prototype,t},a.from=function(t,e,n){return c(null,t,e,n)},a.TYPED_ARRAY_SUPPORT&&(a.prototype.__proto__=Uint8Array.prototype,a.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&a[Symbol.species]===a&&Object.defineProperty(a,Symbol.species,{value:null,configurable:!0})),a.alloc=function(t,e,n){return function(t,e,n,r){return f(e),e<=0?u(t,e):void 0!==n?"string"==typeof r?u(t,e).fill(n,r):u(t,e).fill(n):u(t,e)}(null,t,e,n)},a.allocUnsafe=function(t){return h(null,t)},a.allocUnsafeSlow=function(t){return h(null,t)},a.isBuffer=function(t){return!(null==t||!t._isBuffer)},a.compare=function(t,e){if(!a.isBuffer(t)||!a.isBuffer(e))throw new TypeError("Arguments must be Buffers");if(t===e)return 0;for(var n=t.length,r=e.length,i=0,o=Math.min(n,r);i<o;++i)if(t[i]!==e[i]){n=t[i],r=e[i];break}return n<r?-1:r<n?1:0},a.isEncoding=function(t){switch(String(t).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},a.concat=function(t,e){if(!o(t))throw new TypeError('"list" argument must be an Array of Buffers');if(0===t.length)return a.alloc(0);var n;if(void 0===e)for(e=0,n=0;n<t.length;++n)e+=t[n].length;var r=a.allocUnsafe(e),i=0;for(n=0;n<t.length;++n){var s=t[n];if(!a.isBuffer(s))throw new TypeError('"list" argument must be an Array of Buffers');s.copy(r,i),i+=s.length}return r},a.byteLength=d,a.prototype._isBuffer=!0,a.prototype.swap16=function(){var t=this.length;if(t%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var e=0;e<t;e+=2)_(this,e,e+1);return this},a.prototype.swap32=function(){var t=this.length;if(t%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var e=0;e<t;e+=4)_(this,e,e+3),_(this,e+1,e+2);return this},a.prototype.swap64=function(){var t=this.length;if(t%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var e=0;e<t;e+=8)_(this,e,e+7),_(this,e+1,e+6),_(this,e+2,e+5),_(this,e+3,e+4);return this},a.prototype.toString=function(){var t=0|this.length;return 0===t?"":0===arguments.length?C(this,0,t):E.apply(this,arguments)},a.prototype.equals=function(t){if(!a.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===a.compare(this,t)},a.prototype.inspect=function(){var t="",n=e.INSPECT_MAX_BYTES;return this.length>0&&(t=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(t+=" ... ")),"<Buffer "+t+">"},a.prototype.compare=function(t,e,n,r,i){if(!a.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===n&&(n=t?t.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),e<0||n>t.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&e>=n)return 0;if(r>=i)return-1;if(e>=n)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(e>>>=0),u=Math.min(o,s),c=this.slice(r,i),f=t.slice(e,n),h=0;h<u;++h)if(c[h]!==f[h]){o=c[h],s=f[h];break}return o<s?-1:s<o?1:0},a.prototype.includes=function(t,e,n){return-1!==this.indexOf(t,e,n)},a.prototype.indexOf=function(t,e,n){return T(this,t,e,n,!0)},a.prototype.lastIndexOf=function(t,e,n){return T(this,t,e,n,!1)},a.prototype.write=function(t,e,n,r){if(void 0===e)r="utf8",n=this.length,e=0;else if(void 0===n&&"string"==typeof e)r=e,n=this.length,e=0;else{if(!isFinite(e))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");e|=0,isFinite(n)?(n|=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-e;if((void 0===n||n>i)&&(n=i),t.length>0&&(n<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return y(this,t,e,n);case"utf8":case"utf-8":return m(this,t,e,n);case"ascii":return I(this,t,e,n);case"latin1":case"binary":return v(this,t,e,n);case"base64":return A(this,t,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return w(this,t,e,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},a.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function S(t,e,n){var r="";n=Math.min(t.length,n);for(var i=e;i<n;++i)r+=String.fromCharCode(127&t[i]);return r}function O(t,e,n){var r="";n=Math.min(t.length,n);for(var i=e;i<n;++i)r+=String.fromCharCode(t[i]);return r}function L(t,e,n){var r=t.length;(!e||e<0)&&(e=0),(!n||n<0||n>r)&&(n=r);for(var i="",o=e;o<n;++o)i+=x(t[o]);return i}function N(t,e,n){for(var r=t.slice(e,n),i="",o=0;o<r.length;o+=2)i+=String.fromCharCode(r[o]+256*r[o+1]);return i}function b(t,e,n){if(t%1!=0||t<0)throw new RangeError("offset is not uint");if(t+e>n)throw new RangeError("Trying to access beyond buffer length")}function P(t,e,n,r,i,o){if(!a.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||e<o)throw new RangeError('"value" argument is out of bounds');if(n+r>t.length)throw new RangeError("Index out of range")}function U(t,e,n,r){e<0&&(e=65535+e+1);for(var i=0,o=Math.min(t.length-n,2);i<o;++i)t[n+i]=(e&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function B(t,e,n,r){e<0&&(e=4294967295+e+1);for(var i=0,o=Math.min(t.length-n,4);i<o;++i)t[n+i]=e>>>8*(r?i:3-i)&255}function D(t,e,n,r,i,o){if(n+r>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function M(t,e,n,r,o){return o||D(t,0,n,4),i.write(t,e,n,r,23,4),n+4}function Y(t,e,n,r,o){return o||D(t,0,n,8),i.write(t,e,n,r,52,8),n+8}a.prototype.slice=function(t,e){var n,r=this.length;if((t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e<t&&(e=t),a.TYPED_ARRAY_SUPPORT)(n=this.subarray(t,e)).__proto__=a.prototype;else{var i=e-t;n=new a(i,void 0);for(var o=0;o<i;++o)n[o]=this[o+t]}return n},a.prototype.readUIntLE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=this[t],i=1,o=0;++o<e&&(i*=256);)r+=this[t+o]*i;return r},a.prototype.readUIntBE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=this[t+--e],i=1;e>0&&(i*=256);)r+=this[t+--e]*i;return r},a.prototype.readUInt8=function(t,e){return e||b(t,1,this.length),this[t]},a.prototype.readUInt16LE=function(t,e){return e||b(t,2,this.length),this[t]|this[t+1]<<8},a.prototype.readUInt16BE=function(t,e){return e||b(t,2,this.length),this[t]<<8|this[t+1]},a.prototype.readUInt32LE=function(t,e){return e||b(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},a.prototype.readUInt32BE=function(t,e){return e||b(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},a.prototype.readIntLE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=this[t],i=1,o=0;++o<e&&(i*=256);)r+=this[t+o]*i;return r>=(i*=128)&&(r-=Math.pow(2,8*e)),r},a.prototype.readIntBE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=e,i=1,o=this[t+--r];r>0&&(i*=256);)o+=this[t+--r]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*e)),o},a.prototype.readInt8=function(t,e){return e||b(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},a.prototype.readInt16LE=function(t,e){e||b(t,2,this.length);var n=this[t]|this[t+1]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt16BE=function(t,e){e||b(t,2,this.length);var n=this[t+1]|this[t]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt32LE=function(t,e){return e||b(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},a.prototype.readInt32BE=function(t,e){return e||b(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},a.prototype.readFloatLE=function(t,e){return e||b(t,4,this.length),i.read(this,t,!0,23,4)},a.prototype.readFloatBE=function(t,e){return e||b(t,4,this.length),i.read(this,t,!1,23,4)},a.prototype.readDoubleLE=function(t,e){return e||b(t,8,this.length),i.read(this,t,!0,52,8)},a.prototype.readDoubleBE=function(t,e){return e||b(t,8,this.length),i.read(this,t,!1,52,8)},a.prototype.writeUIntLE=function(t,e,n,r){(t=+t,e|=0,n|=0,r)||P(this,t,e,n,Math.pow(2,8*n)-1,0);var i=1,o=0;for(this[e]=255&t;++o<n&&(i*=256);)this[e+o]=t/i&255;return e+n},a.prototype.writeUIntBE=function(t,e,n,r){(t=+t,e|=0,n|=0,r)||P(this,t,e,n,Math.pow(2,8*n)-1,0);var i=n-1,o=1;for(this[e+i]=255&t;--i>=0&&(o*=256);)this[e+i]=t/o&255;return e+n},a.prototype.writeUInt8=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,1,255,0),a.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},a.prototype.writeUInt16LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):U(this,t,e,!0),e+2},a.prototype.writeUInt16BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):U(this,t,e,!1),e+2},a.prototype.writeUInt32LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):B(this,t,e,!0),e+4},a.prototype.writeUInt32BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},a.prototype.writeIntLE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);P(this,t,e,n,i-1,-i)}var o=0,s=1,u=0;for(this[e]=255&t;++o<n&&(s*=256);)t<0&&0===u&&0!==this[e+o-1]&&(u=1),this[e+o]=(t/s>>0)-u&255;return e+n},a.prototype.writeIntBE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);P(this,t,e,n,i-1,-i)}var o=n-1,s=1,u=0;for(this[e+o]=255&t;--o>=0&&(s*=256);)t<0&&0===u&&0!==this[e+o+1]&&(u=1),this[e+o]=(t/s>>0)-u&255;return e+n},a.prototype.writeInt8=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,1,127,-128),a.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},a.prototype.writeInt16LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):U(this,t,e,!0),e+2},a.prototype.writeInt16BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):U(this,t,e,!1),e+2},a.prototype.writeInt32LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,2147483647,-2147483648),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):B(this,t,e,!0),e+4},a.prototype.writeInt32BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},a.prototype.writeFloatLE=function(t,e,n){return M(this,t,e,!0,n)},a.prototype.writeFloatBE=function(t,e,n){return M(this,t,e,!1,n)},a.prototype.writeDoubleLE=function(t,e,n){return Y(this,t,e,!0,n)},a.prototype.writeDoubleBE=function(t,e,n){return Y(this,t,e,!1,n)},a.prototype.copy=function(t,e,n,r){if(n||(n=0),r||0===r||(r=this.length),e>=t.length&&(e=t.length),e||(e=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===t.length||0===this.length)return 0;if(e<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),t.length-e<r-n&&(r=t.length-e+n);var i,o=r-n;if(this===t&&n<e&&e<r)for(i=o-1;i>=0;--i)t[i+e]=this[i+n];else if(o<1e3||!a.TYPED_ARRAY_SUPPORT)for(i=0;i<o;++i)t[i+e]=this[i+n];else Uint8Array.prototype.set.call(t,this.subarray(n,n+o),e);return o},a.prototype.fill=function(t,e,n,r){if("string"==typeof t){if("string"==typeof e?(r=e,e=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===t.length){var i=t.charCodeAt(0);i<256&&(t=i)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!a.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof t&&(t&=255);if(e<0||this.length<e||this.length<n)throw new RangeError("Out of range index");if(n<=e)return this;var o;if(e>>>=0,n=void 0===n?this.length:n>>>0,t||(t=0),"number"==typeof t)for(o=e;o<n;++o)this[o]=t;else{var s=a.isBuffer(t)?t:G(new a(t,r).toString()),u=s.length;for(o=0;o<n-e;++o)this[o+e]=s[o%u]}return this};var V=/[^+\/0-9A-Za-z-_]/g;function x(t){return t<16?"0"+t.toString(16):t.toString(16)}function G(t,e){var n;e=e||1/0;for(var r=t.length,i=null,o=[],s=0;s<r;++s){if((n=t.charCodeAt(s))>55295&&n<57344){if(!i){if(n>56319){(e-=3)>-1&&o.push(239,191,189);continue}if(s+1===r){(e-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(e-=3)>-1&&o.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(e-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((e-=1)<0)break;o.push(n)}else if(n<2048){if((e-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((e-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function k(t){return r.toByteArray(function(t){if((t=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}(t).replace(V,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function j(t,e,n,r){for(var i=0;i<r&&!(i+n>=e.length||i>=t.length);++i)e[i+n]=t[i];return i}}).call(this,n(3))},function(t,e,n){"use strict";e.byteLength=function(t){var e=c(t),n=e[0],r=e[1];return 3*(n+r)/4-r},e.toByteArray=function(t){var e,n,r=c(t),s=r[0],u=r[1],a=new o(function(t,e,n){return 3*(e+n)/4-n}(0,s,u)),f=0,h=u>0?s-4:s;for(n=0;n<h;n+=4)e=i[t.charCodeAt(n)]<<18|i[t.charCodeAt(n+1)]<<12|i[t.charCodeAt(n+2)]<<6|i[t.charCodeAt(n+3)],a[f++]=e>>16&255,a[f++]=e>>8&255,a[f++]=255&e;2===u&&(e=i[t.charCodeAt(n)]<<2|i[t.charCodeAt(n+1)]>>4,a[f++]=255&e);1===u&&(e=i[t.charCodeAt(n)]<<10|i[t.charCodeAt(n+1)]<<4|i[t.charCodeAt(n+2)]>>2,a[f++]=e>>8&255,a[f++]=255&e);return a},e.fromByteArray=function(t){for(var e,n=t.length,i=n%3,o=[],s=0,u=n-i;s<u;s+=16383)o.push(f(t,s,s+16383>u?u:s+16383));1===i?(e=t[n-1],o.push(r[e>>2]+r[e<<4&63]+"==")):2===i&&(e=(t[n-2]<<8)+t[n-1],o.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"="));return o.join("")};for(var r=[],i=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=0,a=s.length;u<a;++u)r[u]=s[u],i[s.charCodeAt(u)]=u;function c(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var n=t.indexOf("=");return-1===n&&(n=e),[n,n===e?0:4-n%4]}function f(t,e,n){for(var i,o,s=[],u=e;u<n;u+=3)i=(t[u]<<16&16711680)+(t[u+1]<<8&65280)+(255&t[u+2]),s.push(r[(o=i)>>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return s.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(t,e){e.read=function(t,e,n,r,i){var o,s,u=8*i-r-1,a=(1<<u)-1,c=a>>1,f=-7,h=n?i-1:0,l=n?-1:1,p=t[e+h];for(h+=l,o=p&(1<<-f)-1,p>>=-f,f+=u;f>0;o=256*o+t[e+h],h+=l,f-=8);for(s=o&(1<<-f)-1,o>>=-f,f+=r;f>0;s=256*s+t[e+h],h+=l,f-=8);if(0===o)o=1-c;else{if(o===a)return s?NaN:1/0*(p?-1:1);s+=Math.pow(2,r),o-=c}return(p?-1:1)*s*Math.pow(2,o-r)},e.write=function(t,e,n,r,i,o){var s,u,a,c=8*o-i-1,f=(1<<c)-1,h=f>>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:o-1,d=r?1:-1,E=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(u=isNaN(e)?1:0,s=f):(s=Math.floor(Math.log(e)/Math.LN2),e*(a=Math.pow(2,-s))<1&&(s--,a*=2),(e+=s+h>=1?l/a:l*Math.pow(2,1-h))*a>=2&&(s++,a/=2),s+h>=f?(u=0,s=f):s+h>=1?(u=(e*a-1)*Math.pow(2,i),s+=h):(u=e*Math.pow(2,h-1)*Math.pow(2,i),s=0));i>=8;t[n+p]=255&u,p+=d,u/=256,i-=8);for(s=s<<i|u,c+=i;c>0;t[n+p]=255&s,p+=d,s/=256,c-=8);t[n+p-d]|=128*E}},function(t,e){var n={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==n.call(t)}},function(t,e){},function(t,e,n){"use strict";const r=n(2),{browser:i}=n(5),o=i?window.WebSocket:n(20);t.exports=class extends r{constructor(t){super(),this.client=t,this.ws=null,this.tries=0}async connect(t,e=this.tries){if(this.connected)return;const n=6463+e%10;this.hostAndPort=`localhost:${n}`;const r=this.ws=new o(`ws://${this.hostAndPort}/?v=1&client_id=${this.client.clientId}&encoding=json`);r.onopen=this.onOpen.bind(this),r.onclose=r.onerror=this.onClose.bind(this),r.onmessage=this.onMessage.bind(this)}send(t){var e;this.ws&&this.ws.send((e=t,JSON.stringify(e)))}close(){this.ws&&this.ws.close()}ping(){}onMessage(t){var e;this.emit("message",(e=t.data,JSON.parse(e)))}onOpen(){this.emit("open")}onClose(t){try{this.ws.close()}catch(t){}const e=t.code>=4e3&&t.code<5e3;t.code&&!e||(console.log(t),this.emit("close",t)),e||setTimeout(()=>this.connect(void 0,1006===t.code?++this.tries:0),250)}}},function(t,e){}])}));
\ No newline at end of file diff --git a/webcards/scripts/client/message.js b/webcards/scripts/socket/message.js index 5e821c4..5e821c4 100644 --- a/webcards/scripts/client/message.js +++ b/webcards/scripts/socket/message.js diff --git a/webcards/scripts/client/sock.js b/webcards/scripts/socket/sock.js index 78c4195..cf06a5e 100644 --- a/webcards/scripts/client/sock.js +++ b/webcards/scripts/socket/sock.js @@ -1,3 +1,4 @@ +// A wrapper around the wrapper function SockWorker(serveraddr, version, callback) { this.server = serveraddr; this.version = version; @@ -5,6 +6,7 @@ function SockWorker(serveraddr, version, callback) { } SockWorker.prototype = { + // Initialize the connection. init: function() { if(this.server == "" || this.server == null) { return; @@ -22,10 +24,13 @@ SockWorker.prototype = { } }, + // Called when the connection connects to the server o: function() { this.send("version", this.version); }, + // Called when the connection gets a message from the server + // Attempts to turn the message into a usable object and pass it to the callback msg: function(e) { if(typeof e.data == "string") { var dat = JSON.parse(e.data) @@ -33,18 +38,24 @@ SockWorker.prototype = { } }, + // Called when the connection closes. + // Passes a close object to the callback. c: function() { this.cb({type: "close", data: ""}); }, + // Called when the connection encounters an error. + // Passes an error to the callback err: function() { this.cb({type: "error", data: ""}); }, - + + // Call to close the connection to the server close: function() { this.socket.close(); }, + // Send a message to the server send: function(type, data) { var m = new Message(type, data); this.socket.send(m.stringify()) diff --git a/webcards/styles/client/base.css b/webcards/styles/client/base.css index cae61f6..fc8e310 100644 --- a/webcards/styles/client/base.css +++ b/webcards/styles/client/base.css @@ -13,7 +13,10 @@ html, body { } -.topbar { +/* Topbar rules */ + +.topbar +{ position: fixed; background-color: white; @@ -29,66 +32,75 @@ html, body { z-index: 1; } -.top-buttons { +.top-buttons +{ display: flex; } -button, input[type="button"] { - display: inline-block; - border: none; - background-color: dodgerblue; - padding: 10px; - font-size: medium; - border-radius: 5px; - box-sizing: border-box; -} - -button.top-button { +button.top-button +{ border-radius: 0; background-color: white; + color: black; flex: 1; border-left: 1px solid black; border-right: 1px solid black; + + transition-duration: 0.2s; } -.top-buttons > button:first-child { +button.top-button:hover { + background-color: #ddd; +} + +.top-buttons > button:first-child +{ border-left: none; } -.top-buttons > button:last-child { +.top-buttons > button:last-child +{ border-right: none; } -div.new-game { +div.new-game +{ flex: 1; flex-grow: 1; border-top: 2px solid black; } -div.mobile-settings { +div.mobile-settings +{ flex: 1; flex-grow: 1; border-top: 2px solid black; } -div.topbar > div.status { +div.topbar > div.status +{ height: 5px; flex-basis: auto; } -div.stats { +/* Content rules */ + +div.stats +{ padding: 5px; display: flex; flex-direction: column; } -div.stats > div { +div.stats > div +{ flex: 1; display: flex; } -div.stats > div > span { +div.stats > div > span +{ flex-basis: content; display: inline-block; } @@ -109,4 +121,52 @@ div.game { div.game:last-child { margin-bottom: none; -}
\ No newline at end of file +} + +div.settings { + display:flex; + flex-direction: column; + padding: 5px; +} + +/* Table rules */ + +.table { + position: absolute; + z-index: 2; + width: 100vw; + height: 100vh; + + animation-duration: 0.8s; + + background-color: rgba(0, 0, 0, 0.5); +} + +.table[state="open"] ,.table[state="close"]{ + animation-name: slide-in; + animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1); + animation-iteration-count: 1; + animation-direction: normal; + animation-fill-mode: forwards; +} + +.table[state="close"] { + animation-direction: reverse; +} + +.table[state="closed"] { + transform: translate(0, -100vh); + opacity: 0; +} + +@keyframes slide-in { + from { + transform: translate(0, -100vh); + opacity: 0; + } + + to { + transform: translate(0, 0); + opacity: 1; + } +} diff --git a/webcards/styles/client/card.css b/webcards/styles/client/card.css new file mode 100644 index 0000000..62b4054 --- /dev/null +++ b/webcards/styles/client/card.css @@ -0,0 +1,116 @@ +card +{ + position: absolute; + display: block; + width: 150px; + height: 225px; + background-color: white; + border: 6px double #bbb; + border-radius: 10px; + transition-duration: 0.2s; + cursor: pointer; + flex-direction: column; + overflow: hidden; + user-select: none; +} + +card:hover +{ + box-shadow: 0 0 10px #0f0; +} + +carea +{ + padding-left: 2px; + padding-right: 2px; + position: absolute; + display: flex; + vertical-align: middle; + width: 100%; +} + +carea.top, carea.topl, carea.topr +{ + top: 0; + height: 8%; + text-align: center; +} + +carea.topl +{ + width: 50%; + text-align: left; +} + +carea.topr +{ + right: 0; + width: 50%; + text-align: right; +} + +carea.mid +{ + top: 8%; + height: 84%; +} + +carea.midt +{ + top: 8%; + height: 42%; +} + +carea.midb +{ + + top: 50%; + height: 42%; +} + +carea.bot, carea.botl, carea.botr +{ + bottom: 0; + height: 8%; + text-align: center; +} + +carea.botl +{ + width: 50%; + text-align: left; +} + +carea.botr +{ + right: 0; + width: 50%; + text-align: right; +} + +carea.all +{ + top: 0; + height: 100%; +} + +ctext +{ + display: inline-block; + flex: 1; + font-size: small; + height: auto; +} + +cimage +{ + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + flex: 1; +} + +card[drag = "true"] +{ + z-index: 3; +} diff --git a/webcards/styles/client/desktop.css b/webcards/styles/client/desktop.css index 46dc83d..08e24fe 100644 --- a/webcards/styles/client/desktop.css +++ b/webcards/styles/client/desktop.css @@ -10,14 +10,6 @@ TopBar rules */ - button.top-button { - transition-duration: 0.2s; - } - - button.top-button:hover { - background-color: #ddd; - } - button#newgame:before{ content: "Create Game"; } @@ -101,7 +93,7 @@ padding: 10px; border-radius: 10px; background-color: #ddd; - flex: 4; + flex: 2; border: 5px solid #ddd; } diff --git a/webcards/styles/client/mobile.css b/webcards/styles/client/mobile.css index cea233d..4659ce6 100644 --- a/webcards/styles/client/mobile.css +++ b/webcards/styles/client/mobile.css @@ -1,4 +1,4 @@ -@media (max-width: 599px), (max-height: 500px) { +@media (max-width: 599px) or (max-height: 500px) { /* Hide stuff */ diff --git a/webcards/styles/client/tablet.css b/webcards/styles/client/tablet.css index 37750f8..b9b5bd1 100644 --- a/webcards/styles/client/tablet.css +++ b/webcards/styles/client/tablet.css @@ -38,4 +38,8 @@ margin-top: 0px; margin-left: 10px; } + + div.games { + flex: 4; + } } diff --git a/webcards/styles/home/base.css b/webcards/styles/home/base.css index 2ef3693..99bb148 100644 --- a/webcards/styles/home/base.css +++ b/webcards/styles/home/base.css @@ -33,21 +33,21 @@ div.content { align-items: center; } -a { +a, button { font-size: 24px; display: block; color: white; + box-sizing: border-box; border-radius: 5px; + border: none; padding: 5px; - background-color: dodgerblue; + background-color: #0084ff; transition-duration: 0.2s; text-decoration: none; margin-top: 10px; - - max-width: 100px; }
\ No newline at end of file diff --git a/webcards/styles/input.css b/webcards/styles/input.css new file mode 100644 index 0000000..16a5385 --- /dev/null +++ b/webcards/styles/input.css @@ -0,0 +1,296 @@ +/* Begin Input CSS */ + +/* All input */ + +input +{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + + margin: 5px; + + display: block; + z-index: 1; +} + +/* Button input */ + +input[type=button], input[type=submit], button +{ + padding: 10px; + box-sizing: border-box; + + border: none; + border-radius: 5px; + + color: white; + background-color: #0084ff; + + font-size: medium; + + transition-duration: 0.2s; + + cursor: pointer; +} + +input[type=button]:hover, input[type=submit]:hover, button:hover +{ + background-color: #3ea2ff; +} + +input[type=button]:active, input[type=submit]:active, button:active +{ + background-color: #0056a7; +} + +/* Text, date, number, and time input */ + +input[type=text], input[type=date], input[type=time], input[type="number"] +{ + border: 2px solid #555; + border-radius: 3px; + padding: 5px; + background-color: white; + font-size: 1em; +} + +input[type=text]:hover, input[type=date]:hover, input[type=time]:hover, input[type="number"]:hover +{ + border-color: black; +} + +input[type=text]:focus, input[type=date]:focus, input[type=time]:focus, input[type="number"]:focus +{ + border-color: #0084ff; +} + +/* Radial input */ + +input[type=radio] +{ + width: 20px; + height: 20px; + + border: 3px solid black; + border-radius: 50%; + + transition-duration: 0.2s; + + background-color: white; + + cursor: pointer; + + display: inline-block; + vertical-align: middle; +} + +input[type=radio]:checked, input[type=radio]:hover{ + border-width: 6px; +} + +input[type=radio]:checked +{ + background-color: black; + border-color: #0084ff; +} + +input[type=radio]:hover +{ + border-color: #3ea2ff; +} + +input[type=radio]:active +{ + border-color: black; +} + +/* Checkbox input */ + +input[type=checkbox] +{ + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + + display: inline-block; + vertical-align: middle; + + width: 20px; + height: 20px; + + border: 3px solid black; + + border-radius: 2px; + + transition-duration: 0.2s; + + background-color: white; + + cursor: pointer; +} + +input[type=checkbox]:checked +{ + border-width: 10px; + border-color: #0084ff; +} + +input[type=checkbox]:hover +{ + border-color: #3ea2ff; +} + +input[type=checkbox]:active +{ + border-color: black; +} + +input[type=checkbox]::after +{ + height: 16px; + width: 10px; + + box-sizing: border-box; + + position: relative; + + display: block; + + border-color: black; + border-style: solid; + border-width: 0px 0px 0px 0px; + + top: calc(50% - 10px); + left: calc(50% - 5px); + + transform-origin: center; + transform: rotate(45deg); + + content: ''; +} + +input[type=checkbox]:checked::after +{ + border-width: 0px 3px 3px 0px; +} + +/* Color input */ + +input[type=color] +{ + display: inline-block; + + vertical-align: middle; + + height: 20px; + width: 20px; + + margin: 0; + padding: 0; + + border: 0; + + cursor: pointer; +} + +/* File input */ + +input[type=file] +{ + display: none; +} + +/* Input container */ + +div.input-container { + margin: 5px; + padding: 5px; + + border-radius: 3px; +} + +/* Color container */ + +div.input-container[type=color] +{ + text-align: center; + + background-color: #0084ff; + color: white; + + transition-duration: 0.2s; + + cursor: pointer; + + width: max-content; +} + +div.input-container[type=color]::after +{ + display: inline; + + vertical-align: middle; + + content: ' Pick a color'; +} + +div.input-container[type=color]:hover +{ + background-color: #3ea2ff; +} + +div.input-container[type=color]:active +{ + background-color: #0056a7; +} + +/* File input container */ + +div.input-container[type=file] +{ + background-color: #0084ff; + color: white; + + transition-duration: 0.2s; + + cursor: pointer; + + text-align: center; + + width: max-content; + height: max-content; +} + +div.input-container[type=file]:hover +{ + background-color: #3ea2ff; +} + +div.input-container[type=file]:active +{ + background-color: #0056a7; +} + +div.input-container[type=file]::after +{ + display: inline; + + vertical-align: middle; + + content: attr(data-files); +} + +/* Radio input container */ + +div.input-container[type=radio]::before { + display: block; + content: 'Radio'; +} + +div.input-container[type=radio] +{ + background-color: rgba(255, 255, 255, 0.3); +} + +/* End Input CSS */
\ No newline at end of file |