var LNVue = (function (){ let _unique = new Date().getTime(); function uniqueID(){ return _unique++; } let currentPromises = {}; /*\ |*| |*| Base64 / binary data / UTF-8 strings utilities (#1) |*| |*| https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding |*| |*| Author: madmurphy |*| \*/ /* Array of bytes to base64 string decoding */ function b64ToUint6 (nChr) { return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0; } function base64DecToArr (sBase64, nBlockSize) { var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen); for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) { nMod4 = nInIdx & 3; nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4; if (nMod4 === 3 || nInLen - nInIdx === 1) { for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255; } nUint24 = 0; } } return aBytes; } /* Base64 string to array encoding */ function uint6ToB64 (nUint6) { return nUint6 < 26 ? nUint6 + 65 : nUint6 < 52 ? nUint6 + 71 : nUint6 < 62 ? nUint6 - 4 : nUint6 === 62 ? 43 : nUint6 === 63 ? 47 : 65; } function base64EncArr (aBytes) { var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = ""; for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { nMod3 = nIdx % 3; /* Uncomment the following line in order to split the output in lines 76-character long: */ /* if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; } */ nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24); if (nMod3 === 2 || aBytes.length - nIdx === 1) { sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63)); nUint24 = 0; } } return eqLen === 0 ? sB64Enc : sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "=="); } class LNVuePromise { constructor(label,executor){ this.promise = new Promise( (resolve,reject) => { executor( (v) => { this._s.state = "ready"; resolve(v); this.release(); }, (e) => { this._s.state = "failed"; reject(e); this.release(); } ); } ); if (!label) label = "N.D."; this._s = { label, state: "waiting" }; this.idx = uniqueID(); currentPromises[this.idx] = this._s; } label(){ return this._s.label; } state(){ return this._s.state; } release(){ setTimeout(()=>{ Vue.delete(currentPromises, this.idx); },1000); } then(){ return this.promise.then.apply(this.promise, arguments); } } class LNVueWebSocket { constructor(lnvue,o){ this.LNVue = lnvue; this.options = Object.assign({},o); if (!this.options.url) this.options.url = this.constructURL(); this._id = 1; this.defaultTimeout = 30000; this.websocket = null; this.callbacks = {}; this._state = "initialized"; this._retry = null; this.closing = false; } constructURL(){ var pageURI = window.location; var scheme = pageURI.scheme == "https" ? "wss:" : "ws:"; var host = pageURI.host; return scheme + "//" + host + "/socket"; } open(){ if (this._retry){ clearTimeout(this._retry); } this.closing = false; this.websocket = new WebSocket(this.options.url); this.websocket.onopen = (e) =>{ console.log("WebSocket connected"); this._state = "ONLINE"; }; this.websocket.onclose = (e)=>{ this._onclose(e); this._state = "OFFLINE"; }; this.websocket.onerror = (e)=>{ this._onerror(e); this._state = "ERROR"; }; this.websocket.onmessage = (e)=>{ this._onmessage(e); }; return this; } close(){ if (this.websocket){ this.closing = true; this.websocket.close(200,"close() called"); } } request(msgtype,msg,timeout){ let message = { id: this._id++, type: msgtype, message: msg, } if (!timeout) timeout = this.defaultTimeout; if (timeout != -1){ return new Promise((resolve,reject)=>{ let to = setTimeout(()=>{ delete this.callbacks[message.id]; reject("timed out"); },timeout); this.callbacks[message.id] = (msgtype,msg)=>{ clearTimeout(to); delete this.callbacks[message.id]; if (msgtype == "error") reject(msg); else resolve({type: msgtype,message: msg}); }; this.websocket.send( JSON.stringify(message) ); }); } else { new Promise((resolve,reject)=>{ this.websocket.send( JSON.stringify(message) ); resolve(); }); } } _onclose(evt){ this.websocket = null; this.options.onclose && this.options.onclose(evt); if (!this.closing) { this._retry = setTimeout(() => { this._retry = null; console.log("reconnect...") this.open(); }, 5000); } } _onerror(evt){ this.options.onerror && this.options.onerror(evt); } _onmessage(evt){ try { let j = JSON.parse(evt.data); let cb = this.callbacks[ j.id ]; cb && cb(j.type,j.message); } catch(exc){ console.log(exc,evt.data); } } } class LNVue { constructor(el,options = {}){ this.options = Object.assign({ routes: [], data: {}, }, options ); this._el = el; this.data = Object.assign({}, options.data, { LNVue: this, msg: "Hello World" }); this.promises = []; this.globals = { currentPromises, }; this.statusText = "LNVue preparing"; Vue.prototype.$LNVue = this; LNVue.$_ = this; this.navigation = {}; this.identity = { uniqueID: null, identityName: "", }; Promise .all(LNVue.promises) .then(()=>{ this.status("LNVue: starting"); LNVue.vueRouter.addRoutes([{ path: "*", component: { template: `