{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/App.vue?1c0e","webpack:///./src/persistence/model.ts","webpack:///./src/App.vue?fc03","webpack:///./src/dialog/JoinRoom.vue?46f7","webpack:///./src/persistence/connection.ts","webpack:///./src/dialog/JoinRoom.vue?a7df","webpack:///./src/dialog/JoinRoom.vue?c23c","webpack:///./src/dialog/JoinRoom.vue","webpack:///./src/dialog/RequestRestart.vue?96ce","webpack:///./src/dialog/RequestRestart.vue?fbd7","webpack:///./src/dialog/RequestRestart.vue?1f74","webpack:///./src/dialog/RequestRestart.vue","webpack:///./src/dialog/Tutorial.vue?74fa","webpack:///./src/dialog/Tutorial.vue?b558","webpack:///./src/dialog/Tutorial.vue?d9de","webpack:///./src/dialog/Tutorial.vue","webpack:///./src/tutorial.ts","webpack:///./src/App.vue?5dd0","webpack:///./src/App.vue?aea5","webpack:///./src/App.vue","webpack:///./src/plugins/vuetify.ts","webpack:///./src/main.ts"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","GameEvent","Suite","_vm","this","_h","$createElement","_c","_self","attrs","drawerWidth","scopedSlots","_u","fn","nativeOn","$event","type","indexOf","_k","keyCode","ctrlKey","shiftKey","altKey","metaKey","preventDefault","playerMsg","postMessage","on","_v","proxy","model","callback","$$v","expression","drawerOpen","staticClass","_l","msg","ref","messages","refInFor","class","color","_s","sender","time","content","roomJoined","showTutorial","unreadMessages","_e","stopPropagation","alertType","alertMsg","restartRequest","beginTutorial","table","$vuetify","breakpoint","mdAndUp","style","borderRadius","tableSize","item","tableCardStyles","cardSize","turn","winners","id","card","label","prettyMap","suite","tableLockTime","progressSize","progressWidth","_g","xs","selectedCard","cardIndex","sendToPile","smAndUp","iconMap","x","active","toggle","overlayMsgs","restartRequestees","requestGameRestart","allowedPlayers","v","playerID","endTutorial","stepTutorial","notification","staticRenderFns","showDialog","headline","isJoin","dialogText","formValid","nameRules","player","roomRules","roomName","playersRules","players","numPlayers","loading","roomCreated","Label","suitePrettyMap","h","suiteIndices","labelRanks","2","3","4","5","6","7","8","9","10","J","Q","K","A","playerId","sendMessage","room","event","createRoom","playerJoin","playerTurn","persist","onEvent","playerWins","gameOver","gameRestart","ConnectionProvider","errorCallbacks","disconnectCallbacks","socketErrorCallbacks","undefined","callbacks","JSON","parse","console","debug","stringify","forEach","filter","warn","withConnection","ws","send","conn","protocol","location","url","host","pathname","endsWith","socket","WebSocket","onopen","onmessage","e","onMessage","onerror","onclose","JoinRoomProps","extend","props","Boolean","Array","$emit","toLocaleLowerCase","onError","playerExists","roomMissing","roomExists","joinRoom","components","component","VBtn","VCard","VCardActions","VCardText","VCardTitle","VCol","VDialog","VForm","VListItem","VRow","VSelect","VSwitch","VTextField","cancelRequest","sendRequest","RequestProps","fromPlayer","String","VIcon","reset","steps","stepi","stepBack","stepForward","TutorialProps","playerNeedsHelp","msgs","handleStep","stepInfo","ALLOWED_PLAYERS","START_ANGLE","Math","PI","TABLE_LOCK_TIME_MS","TURN_WAIT_MS","COLORS","searchSortedIndex","items","newItem","compare","first","second","getColorForPlayer","sum","split","reduce","old","charCodeAt","idx","turnNotifyTimeoutId","canNotify","hasFocus","gameBegun","indexMap","hand","previousTurnLength","total","angle","cos","y","sin","transition","transform","position","resetGameState","prepareForNotifications","addListeners","keys","sort","a","b","map","labels","document","addEventListener","hidden","Notification","permission","requestPermission","then","showError","onPlayerJoin","playerJoined","onPlayerTurn","handlePlayerTurn","onPlayerWin","playerWon","onGameOver","gameEnded","onPlayerMsg","addMessage","onGameRestart","gameRestarted","onGameRequest","restartRequested","onSocketError","showAlert","onSocketClose","log","showCard","trim","sendMsg","resp","response","escaped","turnIdx","diff","max","previousLength","currentLength","clearTimeout","updateStuff","updateHand","turnPlayer","findIndex","setTimeout","body","timeout","initiateTableLockdown","date","Date","hours","getHours","substring","mins","getMinutes","el","$refs","lastMessage","$el","scrollIntoView","Number","POSITIVE_INFINITY","requestNewGmae","ty","remaining","floor","newHand","initial","updated","pop","c1","c2","itemsEmpty","step","screen","width","transPos","JoinRoom","RequestRestart","Tutorial","VAlert","VApp","VAppBar","VBadge","VContainer","VContent","VFabTransition","VFooter","VItem","VItemGroup","VNavigationDrawer","VOverlay","VProgressCircular","VSlideYTransition","VSnackbar","VTextarea","VToolbarTitle","VToolbar","VTooltip","use","icons","iconfont","theme","dark","config","productionTip","vuetify","render","$mount"],"mappings":"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","file":"js/app.21011c75.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","import mod from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/vuetify-loader/lib/loader.js!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&id=ab151f20&scoped=true&lang=css&\"; export default mod; export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/vuetify-loader/lib/loader.js!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&id=ab151f20&scoped=true&lang=css&\"","/* Server models */\n\ninterface ClientMessage {\n player: string;\n room: string;\n event: GameEvent;\n data: T;\n msg?: string;\n}\n\ninterface ServerMessage {\n player: string;\n room: string;\n msg: string;\n event: GameEvent;\n response: T;\n}\n\ninterface RoomCreationRequest {\n players: number;\n}\n\ninterface TurnRequest {\n card: Card;\n}\n\ninterface RoomResponse {\n players: string[];\n max: number;\n escaped: string[];\n turnIdx: number;\n}\n\ninterface DealResponse {\n hand: Card[];\n table: PlayerCard[];\n isDealer: boolean;\n ourTurn: boolean;\n turnPlayer: string;\n}\n\nenum GameEvent {\n createRoom = 'RoomCreate',\n playerJoin = 'PlayerJoin',\n playerExists = 'PlayerExists',\n roomMissing = 'RoomMissing',\n roomExists = 'RoomExists',\n playerTurn = 'PlayerTurn',\n playerMsg = 'PlayerMsg',\n playerWins = 'PlayerWin',\n gameOver = 'GameOver',\n gameRestart = 'GameRestart',\n restartRequest = 'GameRestartRequest',\n}\n\ninterface PlayerCard {\n id: string;\n card: Card;\n}\n\ninterface Card {\n label: Label;\n suite: Suite;\n}\n\nenum Suite {\n Diamond = 'd',\n Clover = 'c',\n Heart = 'h',\n Spade = 's',\n}\n\nconst suitePrettyMap: any = {\n d: '♦',\n c: '♣',\n h: '♥',\n s: '♠',\n};\n\nenum Label {\n Two = '2',\n Three = '3',\n Four = '4',\n Five = '5',\n Six = '6',\n Seven = '7',\n Eight = '8',\n Nine = '9',\n Ten = '10',\n Jack = 'J',\n Queen = 'Q',\n King = 'K',\n Ace = 'A',\n}\n\n/** Index map for placing suites. */\nconst suiteIndices: any = {\n d: 0,\n c: 1,\n h: 2,\n s: 3,\n};\n\n/** Score map for sorting labels */\nconst labelRanks: any = {\n 2: 2,\n 3: 3,\n 4: 4,\n 5: 5,\n 6: 6,\n 7: 7,\n 8: 8,\n 9: 9,\n 10: 10,\n J: 11,\n Q: 12,\n K: 13,\n A: 14,\n};\n\nexport {\n Card, Label, Suite, labelRanks, suiteIndices, suitePrettyMap,\n DealResponse, RoomResponse, GameEvent, RoomCreationRequest,\n ClientMessage, ServerMessage, PlayerCard, TurnRequest,\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('v-app',[_c('v-navigation-drawer',{attrs:{\"temporary\":\"\",\"width\":_vm.drawerWidth,\"app\":\"\"},scopedSlots:_vm._u([{key:\"append\",fn:function(){return [_c('v-textarea',{attrs:{\"placeholder\":\"Send a message.\",\"rows\":\"3\",\"solo\":\"\",\"no-resize\":\"\"},nativeOn:{\"keydown\":[function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }if(!$event.shiftKey){ return null; }if($event.ctrlKey||$event.altKey||$event.metaKey){ return null; }_vm.playerMsg = _vm.playerMsg + '\\n'}],\"keyup\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }return _vm.postMessage($event)}},scopedSlots:_vm._u([{key:\"append\",fn:function(){return [_c('v-btn',{attrs:{\"icon\":\"\"},on:{\"click\":_vm.postMessage}},[_c('v-icon',[_vm._v(\"mdi-comment\")])],1)]},proxy:true}]),model:{value:(_vm.playerMsg),callback:function ($$v) {_vm.playerMsg=$$v},expression:\"playerMsg\"}})]},proxy:true}]),model:{value:(_vm.drawerOpen),callback:function ($$v) {_vm.drawerOpen=$$v},expression:\"drawerOpen\"}},[_c('v-row',{staticClass:\"d-flex flex-column mx-2 my-4 caption\"},_vm._l((_vm.messages),function(msg,i){return _c('v-card',{key:i,ref:(i === _vm.messages.length - 1) ? 'lastMessage' : null,refInFor:true,staticClass:\"my-1\"},[_c('v-row',{staticClass:\"px-2\"},[_c('v-col',{class:['pb-0', 'body-2', msg.color + '--text']},[_vm._v(_vm._s(msg.sender))]),_c('v-col',{class:['pb-0', 'text-right']},[_vm._v(_vm._s(msg.time))])],1),_c('v-card-text',{staticClass:\"pa-2 caption\"},[_vm._v(_vm._s(msg.content))])],1)}),1)],1),_c('v-app-bar',{attrs:{\"app\":\"\"}},[(_vm.roomJoined && !_vm.showTutorial)?_c('v-badge',{attrs:{\"color\":\"red\",\"overlap\":\"\"},scopedSlots:_vm._u([{key:\"badge\",fn:function(){return [(_vm.unreadMessages > 0)?_c('span',[_vm._v(_vm._s(_vm.unreadMessages))]):_vm._e()]},proxy:true}],null,false,2946340479)},[_c('v-btn',{attrs:{\"icon\":\"\"},on:{\"click\":function($event){$event.stopPropagation();_vm.drawerOpen = !_vm.drawerOpen; _vm.unreadMessages = 0;}}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-comment\")])],1)],1):_vm._e(),_c('v-toolbar-title'),_c('v-row',{staticClass:\"d-flex justify-center\"},[_c('v-slide-y-transition',[(_vm.alertMsg)?_c('v-alert',{attrs:{\"border\":\"top\",\"colored-border\":\"\",\"type\":_vm.alertType,\"elevation\":\"2\"}},[_vm._v(_vm._s(_vm.alertMsg))]):_vm._e()],1)],1),_c('v-btn',{attrs:{\"disabled\":_vm.roomJoined === null,\"icon\":\"\"},on:{\"click\":function($event){_vm.restartRequest = true}}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-restart\")])],1),_c('v-btn',{attrs:{\"disabled\":true,\"icon\":\"\"},on:{\"click\":_vm.beginTutorial}},[_c('v-icon',[_vm._v(\"mdi-help-circle-outline\")])],1)],1),_c('v-content',[_c('v-container',{attrs:{\"fluid\":\"\"}},[_c('v-row',{staticClass:\"my-5\"}),_c('v-row',{staticClass:\"d-flex flex-column flex-md-row\"},[(_vm.table.length)?_c('v-row',{class:[{\n 'mx-10': _vm.$vuetify.breakpoint.mdAndUp\n }, 'mb-10']},[_c('v-card',{staticClass:\"mx-auto my-auto\",style:({ borderRadius: '50%' }),attrs:{\"width\":_vm.tableSize,\"height\":_vm.tableSize}},[_c('transition-group',{attrs:{\"name\":\"fade\"}},_vm._l((_vm.table),function(item,i){return _c('v-card',{key:i + 0,staticClass:\"d-flex flex-column align-center justify-center\",style:(_vm.tableCardStyles(i)),attrs:{\"height\":0.9 * _vm.cardSize,\"width\":0.9 * _vm.cardSize,\"elevation\":item.turn ? 8 : 2,\"color\":_vm.winners.indexOf(item.id) >= 0 ? 'green darken-3' : (item.turn ? 'cyan darken-3' : '' )}},[(item.card)?_c('div',{staticClass:\"headline\"},[_vm._v(_vm._s(item.card.label)+\" \"+_vm._s(_vm.prettyMap[item.card.suite]))]):(_vm.winners.indexOf(item.id) >= 0)?_c('div',[_vm._v(\"[no cards]\")]):(item.turn)?_c('div',[_vm._v(\"???\")]):_c('div',[_vm._v(\"-\")]),_c('div',{staticClass:\"caption\"},[_vm._v(_vm._s(item.id))])])}),1),(_vm.tableLockTime !== null)?_c('transition',{attrs:{\"name\":\"fade\"}},[_c('v-progress-circular',{style:(_vm.progressStyle),attrs:{\"color\":\"red accent-2\",\"value\":_vm.tableLockTime,\"size\":_vm.progressSize,\"width\":_vm.progressWidth}})],1):_vm._e()],1)],1):_vm._e(),_c('v-row',{staticClass:\"d-flex justify-center align-center mt-5 mb-5\",style:({\n 'flex-grow': _vm.$vuetify.breakpoint.mdAndUp ? '0' : '1',\n })},[(_vm.roomJoined && !_vm.showTutorial)?_c('v-tooltip',{attrs:{\"bottom\":\"\"},scopedSlots:_vm._u([{key:\"activator\",fn:function(ref){\n var on = ref.on;\nreturn [_c('v-fab-transition',[_c('v-btn',_vm._g({attrs:{\"fab\":\"\",\"icon\":\"\",\"width\":_vm.$vuetify.breakpoint.xs ? 80 : 100,\"height\":_vm.$vuetify.breakpoint.xs ? 80 : 100,\"color\":_vm.selectedCard ? (_vm.selectedCard.suite === 'h' || _vm.selectedCard.suite === 'd') ? 'red' : 'blue' : '',\"disabled\":_vm.cardIndex === null || _vm.tableLockTime !== null},on:{\"click\":_vm.sendToPile}},_vm.$vuetify.breakpoint.smAndUp ? on : {}),[_c('v-icon',{class:{\n 'display-3': _vm.$vuetify.breakpoint.xs,\n 'display-4': _vm.$vuetify.breakpoint.smAndUp,\n }},[_vm._v(_vm._s(_vm.cardIndex !== null ? _vm.iconMap[_vm.selectedCard.suite] : 'mdi-cards-playing-outline'))])],1)],1)]}}],null,false,712488326)},[_c('span',[_vm._v(\"Add your card to the pile\")])]):_vm._e()],1),_c('v-col',{class:[{\n 'mx-5': _vm.$vuetify.breakpoint.xs,\n }, {\n 'mx-10': _vm.$vuetify.breakpoint.smAndUp,\n }, 'my-auto'],attrs:{\"cols\":_vm.$vuetify.breakpoint.mdAndUp ? '5' : 'auto'}},[_c('v-item-group',{attrs:{\"mandatory\":_vm.cardIndex !== null},model:{value:(_vm.cardIndex),callback:function ($$v) {_vm.cardIndex=$$v},expression:\"cardIndex\"}},_vm._l((_vm.hand),function(item,x){return _c('v-row',{key:x,staticClass:\"d-flex my-4\"},[_c('transition-group',{staticClass:\"row\",attrs:{\"name\":\"card-group\"}},_vm._l((item.labels),function(l){return _c('v-item',{key:l.label + item.suite,scopedSlots:_vm._u([{key:\"default\",fn:function(ref){\n var active = ref.active;\n var toggle = ref.toggle;\nreturn [_c('v-card',{staticClass:\"d-flex justify-center align-center\",attrs:{\"color\":active ? ( item.suite === 'h' || item.suite === 'd' ? 'red' : 'blue' ) : '',\"height\":_vm.cardSize,\"width\":_vm.cardSize},on:{\"click\":function () { _vm.selectedCard = { suite: item.suite, label: l.label }; toggle(); }}},[_c('span',{class:{\n 'headline': _vm.$vuetify.breakpoint.xs,\n 'display-1': _vm.$vuetify.breakpoint.smAndUp,\n }},[_vm._v(_vm._s(l.label)+\" \"+_vm._s(_vm.prettyMap[item.suite]))])])]}}],null,true)})}),1)],1)}),1)],1)],1),(_vm.overlayMsgs.length > 0)?_c('v-overlay',{attrs:{\"opacity\":\"0.5\"}},[_c('div',[_c('span',{staticClass:\"display-1\"},[_vm._v(_vm._s(_vm.overlayMsgs[0]))]),_c('v-btn',{staticClass:\"mb-4 ml-3\",attrs:{\"icon\":\"\",\"color\":\"blue\"},on:{\"click\":function($event){return _vm.overlayMsgs.splice(0, 1)}}},[_c('v-icon',[_vm._v(\"mdi-close\")])],1)],1)]):_vm._e()],1),_c('RequestRestart',{attrs:{\"showDialog\":_vm.restartRequest,\"fromPlayer\":_vm.restartRequestees ? _vm.restartRequestees[_vm.restartRequestees.length - 1] : null},on:{\"cancel\":function($event){_vm.restartRequest = false},\"request\":_vm.requestGameRestart}}),_c('JoinRoom',{attrs:{\"players\":_vm.allowedPlayers,\"showDialog\":_vm.roomJoined === null},on:{\"player-set\":function (v) { return _vm.playerID = v; }}}),_c('Tutorial',{attrs:{\"playerNeedsHelp\":_vm.showTutorial},on:{\"close\":_vm.endTutorial,\"tutorial-step\":_vm.stepTutorial}})],1),(_vm.notification !== null)?_c('v-snackbar',{staticClass:\"mt-4\",attrs:{\"value\":true,\"timeout\":0}},[_vm._v(\"\\n \"+_vm._s(_vm.notification)+\"\\n \"),_c('v-btn',{attrs:{\"color\":\"pink\",\"text\":\"\"},on:{\"click\":function($event){_vm.notification = null}}},[_vm._v(\"close\")])],1):_vm._e(),_c('v-footer',{attrs:{\"app\":\"\"}})],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('v-dialog',{attrs:{\"hide-overlay\":true,\"max-width\":\"400\",\"persistent\":\"\"},model:{value:(_vm.showDialog),callback:function ($$v) {_vm.showDialog=$$v},expression:\"showDialog\"}},[_c('v-card',[_c('v-list-item',[_c('v-card-title',{staticClass:\"headline\"},[_vm._v(_vm._s(_vm.headline)+\" Room\")]),_c('v-row',{attrs:{\"align\":\"center\",\"justify\":\"end\"}},[_c('v-switch',{class:{\n 'mx-3': _vm.$vuetify.breakpoint.xs,\n 'mx-5': _vm.$vuetify.breakpoint.smAndUp,\n },attrs:{\"label\":\"Existing?\"},model:{value:(_vm.isJoin),callback:function ($$v) {_vm.isJoin=$$v},expression:\"isJoin\"}})],1)],1),_c('v-card-text',{staticClass:\"pl-8\"},[_vm._v(_vm._s(_vm.dialogText))]),_c('v-row',{staticClass:\"mb-6\",attrs:{\"no-gutters\":\"\"}},[_c('v-col'),_c('v-col',{attrs:{\"cols\":8}},[_c('v-form',{model:{value:(_vm.formValid),callback:function ($$v) {_vm.formValid=$$v},expression:\"formValid\"}},[_c('v-text-field',{attrs:{\"rules\":_vm.nameRules,\"label\":\"Your name\",\"required\":\"\"},model:{value:(_vm.player),callback:function ($$v) {_vm.player=$$v},expression:\"player\"}}),_c('v-text-field',{attrs:{\"rules\":_vm.roomRules,\"label\":\"Room name\",\"required\":\"\"},model:{value:(_vm.roomName),callback:function ($$v) {_vm.roomName=$$v},expression:\"roomName\"}}),(!_vm.isJoin)?_c('v-select',{attrs:{\"rules\":_vm.playersRules,\"label\":\"No. of players\",\"items\":_vm.players,\"required\":\"\"},model:{value:(_vm.numPlayers),callback:function ($$v) {_vm.numPlayers=$$v},expression:\"numPlayers\"}}):_vm._e()],1)],1),_c('v-col'),_c('v-col')],1),_c('v-card-actions',[_c('v-btn',{staticClass:\"mx-auto my-5 px-5\",attrs:{\"color\":\"red\",\"loading\":_vm.loading,\"disabled\":!_vm.formValid || _vm.loading,\"depressed\":\"\"},on:{\"click\":_vm.roomCreated}},[_vm._v(_vm._s(_vm.headline))])],1)],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","import {\n ClientMessage, ServerMessage,\n RoomResponse, GameEvent, DealResponse, Card,\n} from './model';\n\nimport GameEventHub from './';\n\ninterface Callback {\n persist: boolean | undefined;\n callback: F;\n}\n\n/**\n * Provides a wrapper for `Websocket` object and exposes the messaging interface.\n *\n * This uses statics and is global for the app i.e., only one websocket is created\n * and used throughout the app. Same applies to added event listeners.\n */\nexport default class ConnectionProvider implements GameEventHub {\n\n private static conn: WebSocket | null = null;\n\n private static callbacks: { [key in GameEvent]?: Array void>> } = {};\n\n private static errorCallbacks: Array void>> = [];\n\n private static socketErrorCallbacks: Array void>> = [];\n\n private static disconnectCallbacks: Array void>> = [];\n\n /* Interface methods */\n\n public createRoom(playerId: string, roomName: string, numPlayers: number) {\n this.sendMessage({\n player: playerId,\n room: roomName,\n event: GameEvent.createRoom,\n data: {\n players: numPlayers,\n },\n });\n }\n\n public joinRoom(playerId: string, roomName: string) {\n this.sendMessage({\n player: playerId,\n room: roomName,\n event: GameEvent.playerJoin,\n data: {},\n });\n }\n\n public showCard(playerId: string, roomName: string, card: Card) {\n this.sendMessage({\n player: playerId,\n room: roomName,\n event: GameEvent.playerTurn,\n data: {\n card,\n },\n });\n }\n\n public requestNewGmae(playerId: string, roomName: string) {\n this.sendMessage({\n player: playerId,\n room: roomName,\n event: GameEvent.restartRequest,\n data: {},\n });\n }\n\n public sendMsg(playerId: string, roomName: string, msg: string) {\n this.sendMessage({\n player: playerId,\n room: roomName,\n event: GameEvent.playerMsg,\n data: {},\n msg,\n });\n }\n\n public onPlayerJoin(callback: (resp: ServerMessage) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerJoin, callback, persist);\n }\n\n public onPlayerTurn(callback: (resp: ServerMessage) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerTurn, callback, persist);\n }\n\n public onPlayerMsg(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerMsg, callback, persist);\n }\n\n public onPlayerWin(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerWins, callback, persist);\n }\n\n public onGameOver(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.gameOver, callback, persist);\n }\n\n public onGameRequest(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.restartRequest, callback, persist);\n }\n\n public onGameRestart(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.gameRestart, callback, persist);\n }\n\n public onError(callback: (msg: string, event: GameEvent) => void, persist?: boolean) {\n ConnectionProvider.errorCallbacks.push({\n callback,\n persist,\n });\n }\n\n public onSocketClose(callback: () => void, persist?: boolean) {\n ConnectionProvider.disconnectCallbacks.push({\n callback,\n persist,\n });\n }\n\n public onSocketError(callback: () => void, persist?: boolean) {\n ConnectionProvider.socketErrorCallbacks.push({\n callback,\n persist,\n });\n }\n\n /**\n * Generic event listener for all game events.\n *\n * @param event Game event.\n * @param callback Callback to be called with server response.\n * @param persist Whether to persist that callback or destroy it after the first call.\n */\n private onEvent(event: GameEvent, callback: (resp: ServerMessage) => void, persist?: boolean) {\n if (ConnectionProvider.callbacks[event] === undefined) {\n ConnectionProvider.callbacks[event] = [];\n }\n\n ConnectionProvider.callbacks[event]!.push({\n callback,\n persist,\n });\n }\n\n /**\n * Generic message listener for an open websocket.\n *\n * @param event Websocket message event.\n */\n private onMessage(event: MessageEvent) {\n const data: ServerMessage = JSON.parse(event.data);\n console.debug('Incoming message', JSON.stringify(data));\n const callbacks = ConnectionProvider.callbacks[data.event];\n if (callbacks) {\n callbacks.forEach((c) => {\n c.callback(data);\n });\n\n ConnectionProvider.callbacks[data.event] = callbacks.filter((c) => c.persist);\n } else if (data.msg !== '' && ConnectionProvider.errorCallbacks) {\n ConnectionProvider.errorCallbacks.forEach((c) => {\n c.callback(data.msg, data.event);\n });\n\n ConnectionProvider.errorCallbacks = ConnectionProvider.errorCallbacks.filter((c) => c.persist);\n } else {\n console.warn('Ignoring unknown event response', data);\n }\n }\n\n /**\n * Generic sender for messages.\n *\n * @param msg JSON object.\n */\n private sendMessage(msg: ClientMessage) {\n this.withConnection((ws) => {\n ws.send(JSON.stringify(msg));\n });\n }\n\n /**\n * Provides the `WebSocket` object to the caller through a callback.\n * Instantiates or reuses the websocket as required.\n */\n private withConnection(callback: (ws: WebSocket) => void) {\n if (ConnectionProvider.conn) {\n return callback(ConnectionProvider.conn);\n }\n\n let protocol = 'wss';\n if (window.location.protocol.indexOf('https') < 0) {\n protocol = 'ws';\n }\n\n let url = `${protocol}://${window.location.host}${window.location.pathname}`;\n if (!url.endsWith('/')) {\n url += '/';\n }\n url += 'ws';\n\n const socket = new WebSocket(url);\n socket.onopen = () => {\n ConnectionProvider.conn = socket;\n callback(socket);\n };\n\n socket.onmessage = (e) => {\n this.onMessage(e);\n };\n\n socket.onerror = () => {\n ConnectionProvider.socketErrorCallbacks.forEach((c) => c.callback());\n ConnectionProvider.socketErrorCallbacks = ConnectionProvider.socketErrorCallbacks.filter((c) => c.persist);\n };\n\n socket.onclose = () => {\n ConnectionProvider.disconnectCallbacks.forEach((c) => c.callback());\n ConnectionProvider.disconnectCallbacks = ConnectionProvider.disconnectCallbacks.filter((c) => c.persist);\n };\n }\n}\n\nexport { Callback };\n","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport Component from 'vue-class-component';\n\nimport ConnectionProvider from '../persistence/connection';\nimport { RoomCreationRequest, GameEvent } from '../persistence/model';\n\nconst JoinRoomProps = Vue.extend({\n props: {\n showDialog: Boolean,\n players: Array,\n },\n});\n\n@Component({\n components: {},\n})\nexport default class JoinRoom extends JoinRoomProps {\n /**\n * Headline for the modal.\n */\n private get headline(): string {\n return this.isJoin ? 'Join' : 'Create';\n }\n\n /** Subtitle for the modal. */\n private get dialogText(): string {\n return this.isJoin ? 'Join an existing room.' : 'Create a new room for playing.';\n }\n\n /** Whether player input for this dialog is valid. */\n private formValid: boolean = false;\n\n /** Whether the player is trying to join a room rather than creating one. */\n private isJoin: boolean = false;\n\n /** Validation rules for player name. */\n private nameRules: Array<(v: any) => boolean | string> = [\n (v) => !!v || 'Name is required',\n (v) => (v && v.length >= 3 && v.length <= 10) || 'Name must be 3-10 characters',\n ];\n\n /** Room name. */\n private roomName: string = '';\n\n /** Player ID. */\n private player: string = '';\n\n /** Validation rules for room name. */\n private get roomRules(): Array<(v: any) => boolean | string> {\n if (!this.isJoin) {\n return [];\n }\n\n return [\n (v) => !!v || 'Room name required',\n ];\n }\n\n /** Number of players allowed in this room (for creation). */\n private numPlayers: number | null = null;\n\n /** Validation rules for player count. */\n private playersRules: Array<(v: any) => boolean | string> = [\n (v) => !!v || 'Player count is required',\n ];\n\n /** Loading of dialog button. */\n private loading: boolean = false;\n\n private conn = new ConnectionProvider();\n\n /**\n * Callback initiated once the player has created a room.\n */\n private roomCreated() {\n this.loading = true;\n // Emit an event to the parent with the room name.\n this.$emit('player-set', this.player.toLocaleLowerCase());\n\n this.conn.onError((msg, e) => {\n if (e === GameEvent.playerExists || e === GameEvent.roomMissing || e === GameEvent.roomExists) {\n this.loading = false;\n }\n });\n\n if (this.isJoin) {\n this.conn.joinRoom(this.player, this.roomName);\n } else {\n this.conn.createRoom(this.player, this.roomName, this.numPlayers!);\n }\n }\n}\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./JoinRoom.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./JoinRoom.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./JoinRoom.vue?vue&type=template&id=064b15f7&\"\nimport script from \"./JoinRoom.vue?vue&type=script&lang=ts&\"\nexport * from \"./JoinRoom.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports\n\n/* vuetify-loader */\nimport installComponents from \"!../../node_modules/vuetify-loader/lib/runtime/installComponents.js\"\nimport { VBtn } from 'vuetify/lib/components/VBtn';\nimport { VCard } from 'vuetify/lib/components/VCard';\nimport { VCardActions } from 'vuetify/lib/components/VCard';\nimport { VCardText } from 'vuetify/lib/components/VCard';\nimport { VCardTitle } from 'vuetify/lib/components/VCard';\nimport { VCol } from 'vuetify/lib/components/VGrid';\nimport { VDialog } from 'vuetify/lib/components/VDialog';\nimport { VForm } from 'vuetify/lib/components/VForm';\nimport { VListItem } from 'vuetify/lib/components/VList';\nimport { VRow } from 'vuetify/lib/components/VGrid';\nimport { VSelect } from 'vuetify/lib/components/VSelect';\nimport { VSwitch } from 'vuetify/lib/components/VSwitch';\nimport { VTextField } from 'vuetify/lib/components/VTextField';\ninstallComponents(component, {VBtn,VCard,VCardActions,VCardText,VCardTitle,VCol,VDialog,VForm,VListItem,VRow,VSelect,VSwitch,VTextField})\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('v-dialog',{attrs:{\"max-width\":\"500\",\"persistent\":\"\"},model:{value:(_vm.showDialog),callback:function ($$v) {_vm.showDialog=$$v},expression:\"showDialog\"}},[_c('v-card',[_c('v-list-item',[_c('v-card-title',{staticClass:\"headline\"},[_vm._v(\"Restart Game?\")])],1),_c('v-card-text',{staticClass:\"pl-8\"},[_vm._v(_vm._s(_vm.dialogText))]),_c('v-card-text',{staticClass:\"pl-8\"},[_vm._v(\"The game will restart once a majority of players are in consensus.\")]),_c('v-card-actions',[_c('div',{staticClass:\"flex-grow-1\"}),_c('v-btn',{attrs:{\"color\":\"red\",\"icon\":\"\"},on:{\"click\":_vm.cancelRequest}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-close-circle-outline\")])],1),_c('v-btn',{attrs:{\"color\":\"green\",\"icon\":\"\"},on:{\"click\":_vm.sendRequest}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-check-circle-outline\")])],1)],1)],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport Component from 'vue-class-component';\n\nconst RequestProps = Vue.extend({\n props: {\n showDialog: Boolean,\n fromPlayer: String,\n },\n});\n\n@Component({\n components: {},\n})\nexport default class RequestRestart extends RequestProps {\n\n private get dialogText(): string {\n return (!this.fromPlayer) ?\n 'Do you want to request a restart of this game?' :\n `Player ${this.fromPlayer} wants to restart the game. Do you want to?`;\n }\n\n private sendRequest() {\n this.$emit('request');\n }\n\n private cancelRequest() {\n this.$emit('cancel');\n }\n}\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./RequestRestart.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./RequestRestart.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./RequestRestart.vue?vue&type=template&id=46f7eb71&\"\nimport script from \"./RequestRestart.vue?vue&type=script&lang=ts&\"\nexport * from \"./RequestRestart.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports\n\n/* vuetify-loader */\nimport installComponents from \"!../../node_modules/vuetify-loader/lib/runtime/installComponents.js\"\nimport { VBtn } from 'vuetify/lib/components/VBtn';\nimport { VCard } from 'vuetify/lib/components/VCard';\nimport { VCardActions } from 'vuetify/lib/components/VCard';\nimport { VCardText } from 'vuetify/lib/components/VCard';\nimport { VCardTitle } from 'vuetify/lib/components/VCard';\nimport { VDialog } from 'vuetify/lib/components/VDialog';\nimport { VIcon } from 'vuetify/lib/components/VIcon';\nimport { VListItem } from 'vuetify/lib/components/VList';\ninstallComponents(component, {VBtn,VCard,VCardActions,VCardText,VCardTitle,VDialog,VIcon,VListItem})\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('v-dialog',{attrs:{\"value\":_vm.showDialog,\"max-width\":\"550\",\"persistent\":\"\"}},[_c('v-card',[_c('v-list-item',[_c('v-card-title',{staticClass:\"headline\"},[_vm._v(\"Tour of Ace Away!\")]),_c('v-row',{staticClass:\"pr-1\",attrs:{\"align\":\"center\",\"justify\":\"end\"}},[_c('v-btn',{attrs:{\"color\":\"red\",\"icon\":\"\"},on:{\"click\":_vm.reset}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-close-circle-outline\")])],1)],1)],1),_vm._l((_vm.steps[_vm.stepi].msgs),function(msg,i){return _c('v-card-text',{key:i,staticClass:\"pl-8\"},[_vm._v(_vm._s(msg))])}),_c('v-card-actions',[_c('div',{staticClass:\"flex-grow-1\"}),_c('v-btn',{attrs:{\"disabled\":_vm.stepi <= 1,\"color\":\"green\",\"icon\":\"\"},on:{\"click\":_vm.stepBack}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-chevron-left-circle-outline\")])],1),_c('v-btn',{attrs:{\"disabled\":_vm.stepi == _vm.steps.length - 1,\"color\":\"green\",\"icon\":\"\"},on:{\"click\":_vm.stepForward}},[_c('v-icon',{attrs:{\"large\":\"\"}},[_vm._v(\"mdi-chevron-right-circle-outline\")])],1)],1)],2)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport Component from 'vue-class-component';\n\ninterface TutorialStep {\n msgs?: string[];\n room?: string | null;\n}\n\nconst TutorialProps = Vue.extend({\n props: {\n playerNeedsHelp: Boolean,\n },\n});\n\n@Component({\n components: {},\n})\nexport default class Tutorial extends TutorialProps {\n\n private get showDialog(): boolean {\n return this.playerNeedsHelp && this.steps[this.stepi].msgs !== undefined;\n }\n\n private set showDialog(v: boolean) {\n // We don't need to set anything, because the dialog is persistent\n // and when it gets closed, we notify the parent anyway.\n }\n\n private stepi: number = 0;\n\n private steps: TutorialStep[] = [{\n msgs: [\n `This takes you on a tour on how to play this game.\n You can skip this and start playing whenever you feel like.`,\n ],\n }, {\n msgs: [\n `Ace is a game of cards.`,\n `For a single deck of cards, 4-6 players can play at a time. Although,\n there's nothing stopping 2 or even 10 players from playing - only that the game\n wouldn't be as interesting.`,\n `The goal is to get rid of all cards in\n your hand as soon as possible and \"escape\" the room.\n The player with leftover cards loses the game.`,\n ],\n room: 'test',\n }, {\n msgs: [\n `The game begins with cards distributed across a set number of players.`,\n `For the purpose of this tutorial, let's start a game with 4 players.`,\n ],\n }];\n\n private reset() {\n this.stepi = 0;\n this.$emit('close');\n }\n\n private stepBack() {\n this.stepi -= 1;\n this.handleStep();\n }\n\n private stepForward() {\n this.stepi += 1;\n this.handleStep();\n }\n\n private handleStep() {\n const stepInfo = this.steps[this.stepi];\n this.$emit('tutorial-step', stepInfo);\n if (!stepInfo.msgs) {\n this.showDialog = false;\n }\n }\n}\n\nexport { TutorialStep };\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Tutorial.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/vuetify-loader/lib/loader.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Tutorial.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./Tutorial.vue?vue&type=template&id=5e6db56c&\"\nimport script from \"./Tutorial.vue?vue&type=script&lang=ts&\"\nexport * from \"./Tutorial.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports\n\n/* vuetify-loader */\nimport installComponents from \"!../../node_modules/vuetify-loader/lib/runtime/installComponents.js\"\nimport { VBtn } from 'vuetify/lib/components/VBtn';\nimport { VCard } from 'vuetify/lib/components/VCard';\nimport { VCardActions } from 'vuetify/lib/components/VCard';\nimport { VCardText } from 'vuetify/lib/components/VCard';\nimport { VCardTitle } from 'vuetify/lib/components/VCard';\nimport { VDialog } from 'vuetify/lib/components/VDialog';\nimport { VIcon } from 'vuetify/lib/components/VIcon';\nimport { VListItem } from 'vuetify/lib/components/VList';\nimport { VRow } from 'vuetify/lib/components/VGrid';\ninstallComponents(component, {VBtn,VCard,VCardActions,VCardText,VCardTitle,VDialog,VIcon,VListItem,VRow})\n","import {\n Card, ServerMessage, RoomResponse, GameEvent, DealResponse,\n} from './persistence/model';\nimport { Callback } from './persistence/connection';\n\nimport GameEventHub from './persistence';\n\nexport default class TutorialProvider implements GameEventHub {\n\n private callbacks: { [key in GameEvent]?: Array void>> } = {};\n\n private errorCallbacks: Array void>> = [];\n\n public createRoom(playerId: string, roomName: string, numPlayers: number) {\n console.warn(`Ignoring room creation request for tutorial.`);\n }\n\n public joinRoom(playerId: string, roomName: string) {\n console.warn(`Ignoring room joining request for tutorial.`);\n }\n\n public sendMsg(playerId: string, roomName: string, msg: string) {\n console.warn(`Ignoring player message during tutorial.`);\n }\n\n public showCard(playerId: string, roomName: string, card: Card) {\n //\n }\n\n public requestNewGmae(playerId: string, roomName: string) {\n //\n }\n\n public onPlayerJoin(callback: (resp: ServerMessage) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerJoin, callback, persist);\n }\n\n public onPlayerTurn(callback: (resp: ServerMessage) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerTurn, callback, persist);\n }\n\n public onPlayerMsg(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n console.warn(`Ignoring message response for tutorial.`);\n }\n\n public onPlayerWin(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n this.onEvent(GameEvent.playerWins, callback, persist);\n }\n\n public onGameOver(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n //\n }\n\n public onGameRequest(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n //\n }\n\n public onGameRestart(callback: (resp: ServerMessage<{}>) => void, persist?: boolean) {\n //\n }\n\n public onError(callback: (msg: string, event: GameEvent) => void, persist?: boolean) {\n this.errorCallbacks.push({\n callback,\n persist,\n });\n }\n\n public onSocketClose(callback: () => void, persist?: boolean) {\n //\n }\n\n public onSocketError(callback: () => void, persist?: boolean) {\n //\n }\n\n public propagateMessage(data: ServerMessage) {\n const callbacks = this.callbacks[data.event];\n if (callbacks) {\n callbacks.forEach((c) => {\n c.callback(data);\n });\n\n this.callbacks[data.event] = callbacks.filter((c) => c.persist);\n } else if (data.msg !== '' && this.errorCallbacks) {\n this.errorCallbacks.forEach((c) => {\n c.callback(data.msg, data.event);\n });\n\n this.errorCallbacks = this.errorCallbacks.filter((c) => c.persist);\n } else {\n console.warn('Ignoring unknown event response', data);\n }\n }\n\n private onEvent(event: GameEvent, callback: (resp: ServerMessage) => void, persist?: boolean) {\n if (this.callbacks[event] === undefined) {\n this.callbacks[event] = [];\n }\n\n this.callbacks[event]!.push({\n callback,\n persist,\n });\n }\n}\n","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport Component from 'vue-class-component';\n\nimport JoinRoom from './dialog/JoinRoom.vue';\nimport RequestRestart from './dialog/RequestRestart.vue';\nimport Tutorial, { TutorialStep } from './dialog/Tutorial.vue';\nimport {\n Card, Suite, suitePrettyMap, Label, PlayerCard,\n GameEvent, suiteIndices, labelRanks, DealResponse,\n} from './persistence/model';\nimport { ClientMessage, RoomCreationRequest, ServerMessage, RoomResponse } from './persistence/model';\nimport ConnectionProvider from './persistence/connection';\nimport TutorialProvider from './tutorial';\nimport GameEventHub from './persistence';\n\nconst ALLOWED_PLAYERS: number[] = [3, 4, 5, 6];\nconst START_ANGLE = Math.PI / 2;\nconst TABLE_LOCK_TIME_MS = 5000;\nconst TURN_WAIT_MS = 10000;\n\n// All colors from https://vuetifyjs.com/en/styles/colors#material-colors.\nconst COLORS = [\n 'indigo',\n 'pink',\n 'light-green',\n 'deep-purple',\n 'grey',\n 'lime',\n 'blue',\n 'light-blue',\n 'blue-grey',\n 'brown',\n 'cyan',\n 'orange',\n 'green',\n 'amber',\n 'yellow',\n 'teal',\n 'red',\n 'purple',\n 'deep-orange',\n];\n\nconst iconMap = {\n h: 'mdi-cards-heart',\n s: 'mdi-cards-spade',\n c: 'mdi-cards-club',\n d: 'mdi-cards-diamond',\n};\n\n/** Label for some suite. */\ninterface CardLabel {\n label: string;\n updated: boolean;\n}\n\n/** Suite in hand. Also holds the labels grouped under that suite. */\ninterface HandItem {\n suite: string;\n labels: CardLabel[];\n}\n\n/** Item in table. Holds player and card information. */\ninterface TableItem {\n id: string;\n card: Card | null;\n turn: boolean;\n}\n\n/** Message object containing a message received from the server. */\ninterface Message {\n sender: string;\n color: string;\n time: string;\n content: string;\n}\n\n/**\n * Performs a linear search through the array and finds the index for inserting\n * the new element using the given compare function. If the element already exists,\n * then its index is returned.\n *\n * @param items Array to be searched.\n * @param newItem New element to be inserted.\n * @param compare Compare function that returns a number.\n */\nfunction searchSortedIndex(items: T[], newItem: T, compare: (e1: T, e2: T) => number) {\n if (items.length === 0 || compare(items[0], newItem) >= 0) {\n return 0;\n }\n\n let i = 1;\n for (i; i < items.length; i++) {\n const first = compare(items[i - 1], newItem);\n if (first === 0) {\n return i - 1;\n }\n\n const second = compare(items[i], newItem);\n if (second === 0) {\n return i;\n }\n\n if (first < 0 && second > 0) {\n return i;\n }\n }\n\n return i;\n}\n\n/** Returns the color for a player from known palette using the player ID. */\nfunction getColorForPlayer(id: string): string {\n const sum = id.split('').reduce((old, value) => old + value.charCodeAt(0), 0);\n const idx = sum % COLORS.length;\n return COLORS[idx];\n}\n\n@Component({\n components: {\n JoinRoom,\n RequestRestart,\n Tutorial,\n },\n})\nexport default class App extends Vue {\n\n /* Internal properties */\n\n private conn: GameEventHub = new ConnectionProvider();\n\n /** ID of the most recently set timeout for notifying player turn. */\n private turnNotifyTimeoutId: number = -1;\n\n /** Whether the player has allowed notifications. */\n private canNotify: boolean = false;\n\n /** Whether the user is focusing on the app. */\n private hasFocus: boolean = false;\n\n /** Whether this is a running game. */\n private gameBegun: boolean = false;\n\n /* Constants used by models */\n\n /** Allowed choices for players in rooms. */\n private readonly allowedPlayers: number[] = ALLOWED_PLAYERS;\n\n /** Object for mapping suites to their unicode representations. */\n private readonly prettyMap: any = suitePrettyMap;\n\n /** Object for mapping suites to their indices in hand. */\n private readonly indexMap: any = suiteIndices;\n\n /** Object for mapping suites to their MD icons. */\n private readonly iconMap: any = iconMap;\n\n /* Readonly models (models that shouldn't be updated manually). */\n\n /** Whether the app drawer is open. */\n private readonly drawerOpen: boolean = false;\n\n /** Name set by the player (propagated by `JoinRoom`, after creating/joining a room). */\n private readonly playerID: string = '';\n\n /* Models */\n\n /** Whether the modal should be shown for player to issue a restart request */\n private restartRequest: boolean = false;\n\n /** Players who've requested restarts. */\n private restartRequestees: string[] = [];\n\n /** Whether the player has opened tutorial. */\n private showTutorial: boolean = false;\n\n /** Name of the room joined by the player (set after creating/joining a room). */\n private roomJoined: string | null = null;\n\n /** Notifications from the server shown as a snackbar at the bottom. */\n private notification: string | null = null;\n\n /** Alert message shown in app bar. */\n private alertMsg: string | null = null;\n\n /** Type of the alert. */\n private alertType: string = 'info';\n\n /** Message shown in overlay. */\n private overlayMsgs: string[] = [];\n\n /** Card selected by the player. */\n private selectedCard: Card | null = null;\n\n /** Index of `selectedCard`. **Only used for resetting selection. Don't use this directly.** */\n private cardIndex: number | null = null;\n\n /** Player's hand containing their cards sorted by their labels and suites. */\n private hand: HandItem[] = [];\n\n /** Table containing the cards from all players for that round. */\n private table: TableItem[] = [];\n\n /** Winners in this room. */\n private winners: string[] = [];\n\n /** Number of cards in table in the previous round */\n private previousTurnLength: number = 0;\n\n /** Number indicating whether the table is locked (happens at the end of each round). */\n private tableLockTime: number | null = null;\n\n /** Message written by the player. */\n private playerMsg: string = '';\n\n /** Unread messages since this player has opened the drawer. */\n private unreadMessages: number = 0;\n\n /** Messages received from the server. */\n private messages: Message[] = [];\n\n /* Style thingies */\n\n /** Width of nav drawer. */\n private drawerWidth: number = 300;\n\n /** Size of the card based on viewports. */\n private get cardSize(): number {\n if (screen.width <= 600) {\n return 85;\n } else if (screen.width <= 960) {\n return 95;\n } else {\n return 100;\n }\n }\n\n /** Size of the table based on viewports. */\n private get tableSize(): number {\n if (screen.width <= 600) {\n return 300;\n } else if (screen.width <= 960) {\n return 400;\n } else {\n return 450;\n }\n }\n\n /** Progress bar size (px). */\n private progressSize: number = this.tableSize / 2;\n\n /** Progress bar width (px). */\n private progressWidth: number = 8;\n\n /** Styles for progress bar. */\n private get progressStyle(): object {\n const transPos = this.tableSize / 2 - this.progressSize / 2 + this.progressWidth / 2;\n return {\n position: 'absolute',\n transform: `translate(${transPos}px, ${transPos}px)`,\n };\n }\n\n /** Styles applied to the cards within the table. */\n private tableCardStyles(idx: number): object {\n const total = this.table.length ? this.table.length : 1;\n const angle = 2 * Math.PI / total;\n const x = (this.tableSize / 2) + Math.cos(START_ANGLE + idx * angle) * (this.tableSize / 2) - this.cardSize / 2;\n const y = (this.tableSize / 2) + Math.sin(START_ANGLE + idx * angle) * (this.tableSize / 2) - this.cardSize / 2;\n\n return {\n transition: `all 500ms ease`,\n transform: `translate(${x}px, ${y}px)`,\n position: 'absolute',\n borderRadius: '4px',\n };\n }\n\n /* Vue methods */\n\n private created() {\n this.resetGameState();\n this.prepareForNotifications();\n this.addListeners();\n }\n\n /* Init helpers */\n\n /** Reset the game state in this component. */\n private resetGameState() {\n this.showTutorial = false;\n this.winners = [];\n this.previousTurnLength = 0;\n this.tableLockTime = null;\n this.cardIndex = null;\n this.selectedCard = null;\n this.conn = new ConnectionProvider();\n\n this.hand = Object.keys(suiteIndices)\n .sort((a, b) => suiteIndices[a] - suiteIndices[b])\n .map((s) => {\n return {\n suite: s,\n labels: [],\n };\n });\n\n this.table.forEach((i) => {\n i.card = null;\n });\n }\n\n /** Prepare this view for notifying the player. */\n private prepareForNotifications() {\n document.addEventListener('visibilitychange', () => {\n this.hasFocus = !document.hidden;\n });\n\n if (!('Notification' in window)) {\n console.warn('This browser does not support desktop notifications.');\n return;\n }\n\n if (Notification.permission !== 'denied') {\n Notification.requestPermission().then((permission) => {\n this.canNotify = Notification.permission === 'granted';\n });\n }\n }\n\n /* Add event listeners for changing game state on notifications. */\n private addListeners() {\n this.conn.onError(this.showError, true);\n this.conn.onPlayerJoin(this.playerJoined, true);\n this.conn.onPlayerTurn(this.handlePlayerTurn, true);\n this.conn.onPlayerWin(this.playerWon, true);\n this.conn.onGameOver(this.gameEnded, true);\n this.conn.onPlayerMsg(this.addMessage, true);\n this.conn.onGameRestart(this.gameRestarted, true);\n this.conn.onGameRequest(this.restartRequested, true);\n this.conn.onSocketError(() => {\n this.showAlert(`Error requesting server. You're probably disconnected.`, 'error');\n }, true);\n this.conn.onSocketClose(() => {\n this.showAlert(`You're now offline.`, 'error');\n }, true);\n }\n\n /* Game events */\n\n /** Sends the player-selected card to the pile of cards in the table. */\n private sendToPile() {\n console.log(`Player placing ${this.selectedCard!.label}${this.prettyMap[this.selectedCard!.suite]}`);\n this.conn.showCard(this.playerID, this.roomJoined!, this.selectedCard!);\n this.cardIndex = null;\n }\n\n /** Posts a message to everyone in the room. */\n private postMessage() {\n this.playerMsg = this.playerMsg.trim();\n if (this.playerMsg !== '') {\n this.conn.sendMsg(this.playerID, this.roomJoined!, this.playerMsg);\n }\n\n this.playerMsg = '';\n }\n\n /** A player has joined the room. */\n private playerJoined(resp: ServerMessage) {\n this.roomJoined = resp.room;\n\n resp.response.escaped.forEach((id) => {\n if (this.winners.indexOf(id) === -1) {\n this.winners.push(id);\n }\n });\n\n // Set player states.\n this.table = resp.response.players.map((id, i) => {\n return {\n id,\n card: null,\n turn: resp.response.turnIdx === i,\n };\n });\n\n // Notify if we're waiting on player(s) joining.\n const diff = resp.response.max - resp.response.players.length;\n if (diff > 0) {\n this.alertType = 'info';\n this.alertMsg = `Waiting for ${diff} more player(s) in room ${resp.room}.`;\n } else if (this.gameBegun) {\n this.showAlert(`Yay! Let's continue playing!`);\n } else {\n this.showAlert(`Yay! Let's begin!`);\n this.gameBegun = true;\n }\n }\n\n /** A player has made their turn. Prepare for next turn. */\n private handlePlayerTurn(resp: ServerMessage) {\n const previousLength = this.previousTurnLength;\n const currentLength = resp.response.table.length;\n this.previousTurnLength = currentLength;\n clearTimeout(this.turnNotifyTimeoutId);\n\n const updateStuff = () => {\n // Sort the hand based on suites followed by labels.\n this.updateHand(resp.response.hand);\n\n // Reset states of cards in our table (if the table isn't locked).\n this.table.forEach((v) => {\n v.card = null;\n v.turn = v.id === resp.response.turnPlayer;\n });\n\n // Get the cards and set them in our table.\n resp.response.table.forEach((c) => {\n const idx = this.table.findIndex((v) => v.id === c.id); // This will exist.\n this.table[idx].card = c.card;\n });\n\n // If it's player's turn, notify them if they haven't played for a while.\n if (this.canNotify && resp.response.turnPlayer === this.playerID) {\n this.turnNotifyTimeoutId = setTimeout(() => {\n if (this.table.findIndex((v) => v.id === this.playerID && v.turn) !== -1) {\n const n = new Notification(`Your turn!`, {\n body: `Player(s) are waiting on your turn.`,\n });\n }\n }, TURN_WAIT_MS);\n }\n };\n\n if (currentLength < previousLength) {\n // If the table is getting cleared, lock the table and\n // pause for a moment for players to see what happened.\n // We're fine delaying this turn because we don't allow the\n // players to place a card in this interval, and so we won't\n // get any `playerTurn` events.\n const timeout = this.initiateTableLockdown();\n setTimeout(() => {\n this.showAlert('Table cleared');\n updateStuff();\n }, timeout);\n } else {\n updateStuff();\n }\n }\n\n /** Adds incoming message from the server and notifies player if needed. */\n private addMessage(resp: ServerMessage<{}>) {\n const sender = resp.player;\n const msg = resp.msg;\n\n const date = new Date();\n let hours = String(date.getHours());\n hours = ('00' + hours).substring(hours.length);\n let mins = String(date.getMinutes());\n mins = ('00' + mins).substring(mins.length);\n const time = `${hours}:${mins}`;\n const color = getColorForPlayer(sender);\n\n this.messages.push({\n color,\n sender: sender === this.playerID ? 'You' : sender,\n content: msg,\n time,\n });\n\n if (sender !== this.playerID && (!this.hasFocus || !this.drawerOpen)) {\n this.unreadMessages += 1;\n }\n\n if (!this.hasFocus && this.canNotify && sender !== this.playerID) {\n const n = new Notification(`Message from ${sender} in room ${this.roomJoined}`, {\n body: msg,\n });\n }\n\n // Offer gracious amount of time to render.\n setTimeout(() => {\n let el: any;\n if (this.$refs.lastMessage instanceof Array && this.$refs.lastMessage.length > 0) {\n el = this.$refs.lastMessage[0];\n }\n\n if (el.$el !== undefined) {\n el = el.$el;\n }\n\n el.scrollIntoView();\n }, 500);\n }\n\n /** We've been notified that some player has ditched all their cards. */\n private playerWon(resp: ServerMessage<{}>) {\n const idx = this.table.findIndex((i) => i.id === resp.player);\n if (this.winners.indexOf(resp.player) === -1) {\n this.winners.push(resp.player);\n }\n\n if (this.playerID === resp.player) {\n this.overlayMsgs.push(`Congrats! You've escaped!`);\n } else {\n this.overlayMsgs.push(`${resp.player} escapes.`);\n }\n }\n\n /** We've been notified that the game has ended. */\n private gameEnded(resp: ServerMessage<{}>) {\n this.restartRequestees = [];\n // Reset game state and prompt the player for restarting the game after some delay.\n setTimeout(() => {\n this.resetGameState();\n this.restartRequest = true;\n }, 5000);\n\n if (this.playerID === resp.player) {\n this.overlayMsgs.push(`You've got leftover cards. You lose.`);\n } else if (resp.player !== '') {\n this.overlayMsgs.push(`${resp.player} has leftover card(s) and loses.`);\n } else {\n this.overlayMsgs.push(`It's a tie!`);\n }\n }\n\n /** The game has been restarted by the server. */\n private gameRestarted(resp: ServerMessage<{}>) {\n this.resetGameState();\n // Reset player notifications and dialogs.\n this.restartRequest = false;\n this.restartRequestees = [];\n this.overlayMsgs = [];\n // This will automatically initiate a cooldown for refreshing the table.\n this.previousTurnLength = Number.POSITIVE_INFINITY;\n this.showAlert('Majority of players want to restart the game.', 'info');\n }\n\n /** Request restart for the current game. */\n private requestGameRestart() {\n this.restartRequest = false;\n this.conn.requestNewGmae(this.playerID, this.roomJoined!);\n }\n\n /** A restart request has been received. */\n private restartRequested(resp: ServerMessage<{}>) {\n const idx = this.restartRequestees.findIndex((id) => id === resp.player);\n if (idx >= 0) {\n this.restartRequestees.splice(idx, 1);\n }\n\n this.restartRequestees.push(resp.player);\n if (this.restartRequestees.findIndex((id) => id === this.playerID) === -1) {\n this.restartRequest = true;\n }\n }\n\n /** Sets the snackbar message. */\n private showError(msg: string) {\n this.notification = msg;\n }\n\n /* Helper methods */\n\n /** Shows alert as an alert notification in the app bar. */\n private showAlert(msg: string, ty: string = 'success') {\n this.alertType = ty;\n this.alertMsg = msg;\n setTimeout(() => {\n this.alertMsg = null;\n }, 3000);\n }\n\n /**\n * Initiates a cooldown time by locking the table and hence preventing\n * the players from placing any more cards. This is done in the end of\n * each round.\n *\n * @returns Timeout (in ms) until the table is locked.\n */\n private initiateTableLockdown(): number {\n const remaining = Math.floor(TABLE_LOCK_TIME_MS / 1000);\n this.tableLockTime = 100;\n for (let i = 1; i <= remaining; i++) {\n setTimeout(() => {\n this.tableLockTime = ((remaining - i) / remaining) * 100;\n if (i === remaining) {\n setTimeout(() => {\n this.tableLockTime = null;\n }, 500);\n }\n }, i * 1000);\n }\n\n return remaining * 1000;\n }\n\n /**\n * Updates the player's hand with new cards from the server.\n *\n * Even though we could maintain the same structure (`[]Card`) and let Vue\n * show the transitions, we don't, because we need to group based on suites\n * and sort them. This means we're (mostly) on our own. So, we find the diff\n * off the existing hand, and then go about adding/subtracting the cards.\n *\n * @param newHand Updated hand from the server.\n * @param timeout Timeout for each card update (add/remove).\n * @param initial Internal param for recursion.\n */\n private updateHand(newHand: Card[], timeout: number | null = null, initial: boolean = true) {\n if (initial) {\n // Mark all cards as old.\n this.hand.forEach((item) => {\n item.labels.forEach((l) => {\n l.updated = false;\n });\n });\n }\n\n setTimeout(() => {\n let card = newHand.pop();\n while (card !== undefined) {\n const i = suiteIndices[card.suite];\n const labels = this.hand[i].labels;\n const label = { label: card.label, updated: true };\n const j = searchSortedIndex(labels, label, (c1, c2) => labelRanks[c1.label] - labelRanks[c2.label]);\n if (labels[j] && labels[j].label === card.label) {\n // If this card already exists, then mark it as updated and progress.\n labels[j].updated = true;\n card = newHand.pop();\n } else {\n // This is a new card (+ diff). Recurse with a timeout.\n labels.splice(j, 0, label);\n this.updateHand(newHand, null, false);\n break;\n }\n }\n\n // If we don't have any cards left, then progress to removal.\n if (card === undefined) {\n let itemsEmpty = true;\n this.hand.forEach((item) => {\n const idx = item.labels.findIndex((c) => !c.updated);\n if (idx >= 0) {\n item.labels.splice(idx, 1);\n }\n\n itemsEmpty = itemsEmpty && idx < 0;\n });\n\n if (!itemsEmpty) {\n // We have removed cards in this run. Recurse (- diff) with a timeout.\n this.updateHand(newHand, null, false);\n }\n }\n }, timeout ? timeout : 50);\n }\n\n /** Player has requested for a tutorial. */\n private beginTutorial() {\n this.showTutorial = true;\n this.conn = new TutorialProvider();\n this.addListeners();\n }\n\n /** Player has progressed (to/fro) in tutorial. */\n private stepTutorial(step: TutorialStep) {\n if (step.room !== undefined) {\n this.roomJoined = step.room;\n }\n }\n\n /** Player has ended the tutorial. */\n private endTutorial() {\n this.roomJoined = null;\n this.resetGameState();\n // NOTE: We shouldn't add listeners again here (ConnectionProvider uses statics).\n }\n}\nexport { ALLOWED_PLAYERS };\n","import mod from \"-!../node_modules/cache-loader/dist/cjs.js??ref--13-0!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js??ref--13-3!../node_modules/vuetify-loader/lib/loader.js!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../node_modules/cache-loader/dist/cjs.js??ref--13-0!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js??ref--13-3!../node_modules/vuetify-loader/lib/loader.js!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./App.vue?vue&type=template&id=ab151f20&scoped=true&\"\nimport script from \"./App.vue?vue&type=script&lang=ts&\"\nexport * from \"./App.vue?vue&type=script&lang=ts&\"\nimport style0 from \"./App.vue?vue&type=style&index=0&id=ab151f20&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"ab151f20\",\n null\n \n)\n\nexport default component.exports\n\n/* vuetify-loader */\nimport installComponents from \"!../node_modules/vuetify-loader/lib/runtime/installComponents.js\"\nimport { VAlert } from 'vuetify/lib/components/VAlert';\nimport { VApp } from 'vuetify/lib/components/VApp';\nimport { VAppBar } from 'vuetify/lib/components/VAppBar';\nimport { VBadge } from 'vuetify/lib/components/VBadge';\nimport { VBtn } from 'vuetify/lib/components/VBtn';\nimport { VCard } from 'vuetify/lib/components/VCard';\nimport { VCardText } from 'vuetify/lib/components/VCard';\nimport { VCol } from 'vuetify/lib/components/VGrid';\nimport { VContainer } from 'vuetify/lib/components/VGrid';\nimport { VContent } from 'vuetify/lib/components/VContent';\nimport { VFabTransition } from 'vuetify/lib/components/transitions';\nimport { VFooter } from 'vuetify/lib/components/VFooter';\nimport { VIcon } from 'vuetify/lib/components/VIcon';\nimport { VItem } from 'vuetify/lib/components/VItemGroup';\nimport { VItemGroup } from 'vuetify/lib/components/VItemGroup';\nimport { VNavigationDrawer } from 'vuetify/lib/components/VNavigationDrawer';\nimport { VOverlay } from 'vuetify/lib/components/VOverlay';\nimport { VProgressCircular } from 'vuetify/lib/components/VProgressCircular';\nimport { VRow } from 'vuetify/lib/components/VGrid';\nimport { VSlideYTransition } from 'vuetify/lib/components/transitions';\nimport { VSnackbar } from 'vuetify/lib/components/VSnackbar';\nimport { VTextarea } from 'vuetify/lib/components/VTextarea';\nimport { VToolbarTitle } from 'vuetify/lib/components/VToolbar';\nimport { VTooltip } from 'vuetify/lib/components/VTooltip';\ninstallComponents(component, {VAlert,VApp,VAppBar,VBadge,VBtn,VCard,VCardText,VCol,VContainer,VContent,VFabTransition,VFooter,VIcon,VItem,VItemGroup,VNavigationDrawer,VOverlay,VProgressCircular,VRow,VSlideYTransition,VSnackbar,VTextarea,VToolbarTitle,VTooltip})\n","import Vue from 'vue';\nimport Vuetify from 'vuetify/lib';\n\nVue.use(Vuetify);\n\nexport default new Vuetify({\n icons: {\n iconfont: 'mdi',\n },\n theme: {\n dark: true,\n },\n});\n","import Vue from 'vue';\nimport App from './App.vue';\nimport vuetify from './plugins/vuetify';\n\nVue.config.productionTip = false;\n\nnew Vue({\n vuetify,\n render: (h) => h(App),\n}).$mount('#app');\n"],"sourceRoot":""}