gameglue 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/gg.sdk.js +1 -0
- package/package.json +30 -0
- package/src/auth.js +148 -0
- package/src/index.js +70 -0
- package/src/listener.js +119 -0
- package/src/user.js +12 -0
- package/src/utils.js +12 -0
- package/webpack.config.js +10 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 GameGlue
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# GameGlueJS (Early Access)
|
|
2
|
+
## What is GameGlue?
|
|
3
|
+
GameGlue is a powerful platform that makes it trivial to build addons to your favorite games with nothing more than a little javascript.
|
|
4
|
+
|
|
5
|
+
Below is an example showing that with just ~10 lines of code.
|
|
6
|
+
## Early Access
|
|
7
|
+
GameGlue is brand new, and is missing some features. Perhaps, the most obvious is support for the number of games that we'd like.
|
|
8
|
+
Currently, only Microsoft Flight Simulator - a game near, and dear to my heart - is supported, but as soon as the platform itself is stable, and the user
|
|
9
|
+
experience, and perhaps more importantly, the developer experience, is at a place we're happy with, we'll begin adding support for more games.
|
|
10
|
+
|
|
11
|
+
In the meantime, please be patient with us, and be liberal with your feedback, suggestions, etc. Your engagement,
|
|
12
|
+
ultimately, is what will make GameGlue great.
|
|
13
|
+
|
|
14
|
+
## Getting started
|
|
15
|
+
|
|
16
|
+
First, [click here](https://developer.gameglue.gg) to sign up for a GameGlue account. Then, head to the [Developer Hub](https://developer.gameglue.gg) to register your app.
|
|
17
|
+
|
|
18
|
+
### Install using one of the following options
|
|
19
|
+
##### NPM
|
|
20
|
+
```shell
|
|
21
|
+
npm i gamegluejs
|
|
22
|
+
```
|
|
23
|
+
##### Yarn
|
|
24
|
+
```shell
|
|
25
|
+
yarn add gamegluejs
|
|
26
|
+
```
|
|
27
|
+
##### Script tag
|
|
28
|
+
```html
|
|
29
|
+
<script src="https://unpkg.com/gamegluejs@0.0.10/dist/gg.sdk.js"></script>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Initialize the SDK
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const ggClient = new GameGlue({
|
|
36
|
+
clientId: '<your-application-id>',
|
|
37
|
+
redirect_uri: '<your-application-url>',
|
|
38
|
+
scopes: ['<your-required-scopes>']
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Authenticate the user
|
|
43
|
+
```javascript
|
|
44
|
+
await ggClient.auth();
|
|
45
|
+
const userId = ggClient.getUserId();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Create a listener
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const userListener = await ggClient.createListener({
|
|
52
|
+
userId: userId,
|
|
53
|
+
gameId: '<your-game-id>'
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
### Use the listener
|
|
57
|
+
```javascript
|
|
58
|
+
userListener.on('update', (evt) => {
|
|
59
|
+
document.body.innerHTML = evt.data.ground_speed;
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
That's it!!
|
|
64
|
+
|
|
65
|
+
|
package/dist/gg.sdk.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{var t={249:function(t,e,s){var r;t.exports=(r=r||function(t,e){var r;if("undefined"!=typeof window&&window.crypto&&(r=window.crypto),"undefined"!=typeof self&&self.crypto&&(r=self.crypto),"undefined"!=typeof globalThis&&globalThis.crypto&&(r=globalThis.crypto),!r&&"undefined"!=typeof window&&window.msCrypto&&(r=window.msCrypto),!r&&void 0!==s.g&&s.g.crypto&&(r=s.g.crypto),!r)try{r=s(480)}catch(t){}var i=function(){if(r){if("function"==typeof r.getRandomValues)try{return r.getRandomValues(new Uint32Array(1))[0]}catch(t){}if("function"==typeof r.randomBytes)try{return r.randomBytes(4).readInt32LE()}catch(t){}}throw new Error("Native crypto module could not be used to get secure random number.")},n=Object.create||function(){function t(){}return function(e){var s;return t.prototype=e,s=new t,t.prototype=null,s}}(),o={},a=o.lib={},c=a.Base={extend:function(t){var e=n(this);return t&&e.mixIn(t),e.hasOwnProperty("init")&&this.init!==e.init||(e.init=function(){e.$super.init.apply(this,arguments)}),e.init.prototype=e,e.$super=this,e},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}},h=a.WordArray=c.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:4*t.length},toString:function(t){return(t||l).stringify(this)},concat:function(t){var e=this.words,s=t.words,r=this.sigBytes,i=t.sigBytes;if(this.clamp(),r%4)for(var n=0;n<i;n++){var o=s[n>>>2]>>>24-n%4*8&255;e[r+n>>>2]|=o<<24-(r+n)%4*8}else for(var a=0;a<i;a+=4)e[r+a>>>2]=s[a>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,s=this.sigBytes;e[s>>>2]&=4294967295<<32-s%4*8,e.length=t.ceil(s/4)},clone:function(){var t=c.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],s=0;s<t;s+=4)e.push(i());return new h.init(e,t)}}),u=o.enc={},l=u.Hex={stringify:function(t){for(var e=t.words,s=t.sigBytes,r=[],i=0;i<s;i++){var n=e[i>>>2]>>>24-i%4*8&255;r.push((n>>>4).toString(16)),r.push((15&n).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,s=[],r=0;r<e;r+=2)s[r>>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new h.init(s,e/2)}},d=u.Latin1={stringify:function(t){for(var e=t.words,s=t.sigBytes,r=[],i=0;i<s;i++){var n=e[i>>>2]>>>24-i%4*8&255;r.push(String.fromCharCode(n))}return r.join("")},parse:function(t){for(var e=t.length,s=[],r=0;r<e;r++)s[r>>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new h.init(s,e)}},p=u.Utf8={stringify:function(t){try{return decodeURIComponent(escape(d.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return d.parse(unescape(encodeURIComponent(t)))}},f=a.BufferedBlockAlgorithm=c.extend({reset:function(){this._data=new h.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=p.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var s,r=this._data,i=r.words,n=r.sigBytes,o=this.blockSize,a=n/(4*o),c=(a=e?t.ceil(a):t.max((0|a)-this._minBufferSize,0))*o,u=t.min(4*c,n);if(c){for(var l=0;l<c;l+=o)this._doProcessBlock(i,l);s=i.splice(0,c),r.sigBytes-=u}return new h.init(s,u)},clone:function(){var t=c.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),g=(a.Hasher=f.extend({cfg:c.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){f.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){return t&&this._append(t),this._doFinalize()},blockSize:16,_createHelper:function(t){return function(e,s){return new t.init(s).finalize(e)}},_createHmacHelper:function(t){return function(e,s){return new g.HMAC.init(t,s).finalize(e)}}}),o.algo={});return o}(Math),r)},269:function(t,e,s){var r,i,n;t.exports=(r=s(249),n=(i=r).lib.WordArray,i.enc.Base64={stringify:function(t){var e=t.words,s=t.sigBytes,r=this._map;t.clamp();for(var i=[],n=0;n<s;n+=3)for(var o=(e[n>>>2]>>>24-n%4*8&255)<<16|(e[n+1>>>2]>>>24-(n+1)%4*8&255)<<8|e[n+2>>>2]>>>24-(n+2)%4*8&255,a=0;a<4&&n+.75*a<s;a++)i.push(r.charAt(o>>>6*(3-a)&63));var c=r.charAt(64);if(c)for(;i.length%4;)i.push(c);return i.join("")},parse:function(t){var e=t.length,s=this._map,r=this._reverseMap;if(!r){r=this._reverseMap=[];for(var i=0;i<s.length;i++)r[s.charCodeAt(i)]=i}var o=s.charAt(64);if(o){var a=t.indexOf(o);-1!==a&&(e=a)}return function(t,e,s){for(var r=[],i=0,o=0;o<e;o++)if(o%4){var a=s[t.charCodeAt(o-1)]<<o%4*2|s[t.charCodeAt(o)]>>>6-o%4*2;r[i>>>2]|=a<<24-i%4*8,i++}return n.create(r,i)}(t,e,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},r.enc.Base64)},743:function(t,e,s){t.exports=s(249).enc.Utf8},153:function(t,e,s){var r;t.exports=(r=s(249),function(t){var e=r,s=e.lib,i=s.WordArray,n=s.Hasher,o=e.algo,a=[],c=[];!function(){function e(e){for(var s=t.sqrt(e),r=2;r<=s;r++)if(!(e%r))return!1;return!0}function s(t){return 4294967296*(t-(0|t))|0}for(var r=2,i=0;i<64;)e(r)&&(i<8&&(a[i]=s(t.pow(r,.5))),c[i]=s(t.pow(r,1/3)),i++),r++}();var h=[],u=o.SHA256=n.extend({_doReset:function(){this._hash=new i.init(a.slice(0))},_doProcessBlock:function(t,e){for(var s=this._hash.words,r=s[0],i=s[1],n=s[2],o=s[3],a=s[4],u=s[5],l=s[6],d=s[7],p=0;p<64;p++){if(p<16)h[p]=0|t[e+p];else{var f=h[p-15],g=(f<<25|f>>>7)^(f<<14|f>>>18)^f>>>3,_=h[p-2],y=(_<<15|_>>>17)^(_<<13|_>>>19)^_>>>10;h[p]=g+h[p-7]+y+h[p-16]}var m=r&i^r&n^i&n,w=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),b=d+((a<<26|a>>>6)^(a<<21|a>>>11)^(a<<7|a>>>25))+(a&u^~a&l)+c[p]+h[p];d=l,l=u,u=a,a=o+b|0,o=n,n=i,i=r,r=b+(w+m)|0}s[0]=s[0]+r|0,s[1]=s[1]+i|0,s[2]=s[2]+n|0,s[3]=s[3]+o|0,s[4]=s[4]+a|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+d|0},_doFinalize:function(){var e=this._data,s=e.words,r=8*this._nDataBytes,i=8*e.sigBytes;return s[i>>>5]|=128<<24-i%32,s[14+(i+64>>>9<<4)]=t.floor(r/4294967296),s[15+(i+64>>>9<<4)]=r,e.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var t=n.clone.call(this);return t._hash=this._hash.clone(),t}});e.SHA256=n._createHelper(u),e.HmacSHA256=n._createHmacHelper(u)}(Math),r.SHA256)},804:(t,e,s)=>{"use strict";var r=s(618),i=s(205),n=s(191),o=s(516),a=s(981);(t.exports=function(t,e){var s,i,c,h,u;return arguments.length<2||"string"!=typeof t?(h=e,e=t,t=null):h=arguments[2],r(t)?(s=a.call(t,"c"),i=a.call(t,"e"),c=a.call(t,"w")):(s=c=!0,i=!1),u={value:e,configurable:s,enumerable:i,writable:c},h?n(o(h),u):u}).gs=function(t,e,s){var c,h,u,l;return"string"!=typeof t?(u=s,s=e,e=t,t=null):u=arguments[3],r(e)?i(e)?r(s)?i(s)||(u=s,s=void 0):s=void 0:(u=e,e=s=void 0):e=void 0,r(t)?(c=a.call(t,"c"),h=a.call(t,"e")):(c=!0,h=!1),l={get:e,set:s,configurable:c,enumerable:h},u?n(o(u),l):l}},430:t=>{"use strict";t.exports=function(){}},191:(t,e,s)=>{"use strict";t.exports=s(560)()?Object.assign:s(346)},560:t=>{"use strict";t.exports=function(){var t,e=Object.assign;return"function"==typeof e&&(e(t={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),t.foo+t.bar+t.trzy==="razdwatrzy")}},346:(t,e,s)=>{"use strict";var r=s(103),i=s(745),n=Math.max;t.exports=function(t,e){var s,o,a,c=n(arguments.length,2);for(t=Object(i(t)),a=function(r){try{t[r]=e[r]}catch(t){s||(s=t)}},o=1;o<c;++o)r(e=arguments[o]).forEach(a);if(void 0!==s)throw s;return t}},914:(t,e,s)=>{"use strict";var r=s(430)();t.exports=function(t){return t!==r&&null!==t}},103:(t,e,s)=>{"use strict";t.exports=s(446)()?Object.keys:s(137)},446:t=>{"use strict";t.exports=function(){try{return Object.keys("primitive"),!0}catch(t){return!1}}},137:(t,e,s)=>{"use strict";var r=s(914),i=Object.keys;t.exports=function(t){return i(r(t)?Object(t):t)}},516:(t,e,s)=>{"use strict";var r=s(914),i=Array.prototype.forEach,n=Object.create,o=function(t,e){var s;for(s in t)e[s]=t[s]};t.exports=function(t){var e=n(null);return i.call(arguments,(function(t){r(t)&&o(Object(t),e)})),e}},290:t=>{"use strict";t.exports=function(t){if("function"!=typeof t)throw new TypeError(t+" is not a function");return t}},745:(t,e,s)=>{"use strict";var r=s(914);t.exports=function(t){if(!r(t))throw new TypeError("Cannot use null or undefined");return t}},981:(t,e,s)=>{"use strict";t.exports=s(591)()?String.prototype.contains:s(42)},591:t=>{"use strict";var e="razdwatrzy";t.exports=function(){return"function"==typeof e.contains&&!0===e.contains("dwa")&&!1===e.contains("foo")}},42:t=>{"use strict";var e=String.prototype.indexOf;t.exports=function(t){return e.call(this,t,arguments[1])>-1}},370:(t,e,s)=>{"use strict";var r,i,n,o,a,c,h,u=s(804),l=s(290),d=Function.prototype.apply,p=Function.prototype.call,f=Object.create,g=Object.defineProperty,_=Object.defineProperties,y=Object.prototype.hasOwnProperty,m={configurable:!0,enumerable:!1,writable:!0};i=function(t,e){var s,i;return l(e),i=this,r.call(this,t,s=function(){n.call(i,t,s),d.call(e,this,arguments)}),s.__eeOnceListener__=e,this},a={on:r=function(t,e){var s;return l(e),y.call(this,"__ee__")?s=this.__ee__:(s=m.value=f(null),g(this,"__ee__",m),m.value=null),s[t]?"object"==typeof s[t]?s[t].push(e):s[t]=[s[t],e]:s[t]=e,this},once:i,off:n=function(t,e){var s,r,i,n;if(l(e),!y.call(this,"__ee__"))return this;if(!(s=this.__ee__)[t])return this;if("object"==typeof(r=s[t]))for(n=0;i=r[n];++n)i!==e&&i.__eeOnceListener__!==e||(2===r.length?s[t]=r[n?0:1]:r.splice(n,1));else r!==e&&r.__eeOnceListener__!==e||delete s[t];return this},emit:o=function(t){var e,s,r,i,n;if(y.call(this,"__ee__")&&(i=this.__ee__[t]))if("object"==typeof i){for(s=arguments.length,n=new Array(s-1),e=1;e<s;++e)n[e-1]=arguments[e];for(i=i.slice(),e=0;r=i[e];++e)d.call(r,this,n)}else switch(arguments.length){case 1:p.call(i,this);break;case 2:p.call(i,this,arguments[1]);break;case 3:p.call(i,this,arguments[1],arguments[2]);break;default:for(s=arguments.length,n=new Array(s-1),e=1;e<s;++e)n[e-1]=arguments[e];d.call(i,this,n)}}},c={on:u(r),once:u(i),off:u(n),emit:u(o)},h=_({},c),t.exports=e=function(t){return null==t?f(h):_(Object(t),c)},e.methods=a},372:(t,e,s)=>{"use strict";var r=s(60);t.exports=function(t){if("function"!=typeof t)return!1;if(!hasOwnProperty.call(t,"length"))return!1;try{if("number"!=typeof t.length)return!1;if("function"!=typeof t.call)return!1;if("function"!=typeof t.apply)return!1}catch(t){return!1}return!r(t)}},940:(t,e,s)=>{"use strict";var r=s(618),i={object:!0,function:!0,undefined:!0};t.exports=function(t){return!!r(t)&&hasOwnProperty.call(i,typeof t)}},205:(t,e,s)=>{"use strict";var r=s(372),i=/^\s*class[\s{/}]/,n=Function.prototype.toString;t.exports=function(t){return!!r(t)&&!i.test(n.call(t))}},60:(t,e,s)=>{"use strict";var r=s(940);t.exports=function(t){if(!r(t))return!1;try{return!!t.constructor&&t.constructor.prototype===t}catch(t){return!1}}},618:t=>{"use strict";t.exports=function(t){return null!=t}},480:()=>{}},e={};function s(r){var i=e[r];if(void 0!==i)return i.exports;var n=e[r]={exports:{}};return t[r].call(n.exports,n,n.exports,s),n.exports}s.d=(t,e)=>{for(var r in e)s.o(e,r)&&!s.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{"use strict";var t={};s.r(t),s.d(t,{Decoder:()=>zt,Encoder:()=>Dt,PacketType:()=>Mt,protocol:()=>Ut});var e=s(249),r=s(153),i=s(269),n=s(743);function o(t){this.message=t}o.prototype=new Error,o.prototype.name="InvalidCharacterError";var a="undefined"!=typeof window&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new o("'atob' failed: The string to be decoded is not correctly encoded.");for(var s,r,i=0,n=0,a="";r=e.charAt(n++);~r&&(s=i%4?64*s+r:r,i++%4)?a+=String.fromCharCode(255&s>>(-2*i&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return a};function c(t){var e=t.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(t){return decodeURIComponent(a(t).replace(/(.)/g,(function(t,e){var s=e.charCodeAt(0).toString(16).toUpperCase();return s.length<2&&(s="0"+s),"%"+s})))}(e)}catch(t){return a(e)}}function h(t){this.message=t}h.prototype=new Error,h.prototype.name="InvalidTokenError";const u=function(t,e){if("string"!=typeof t)throw new h("Invalid token specified");var s=!0===(e=e||{}).header?0:1;try{return JSON.parse(c(t.split(".")[s]))}catch(t){throw new h("Invalid token specified: "+t.message)}};var l,d,p,f={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},g=(t=>(t[t.NONE=0]="NONE",t[t.ERROR=1]="ERROR",t[t.WARN=2]="WARN",t[t.INFO=3]="INFO",t[t.DEBUG=4]="DEBUG",t))(g||{});(p=g||(g={})).reset=function(){l=3,d=f},p.setLevel=function(t){if(!(0<=t&&t<=4))throw new Error("Invalid log level");l=t},p.setLogger=function(t){d=t};var _=class{constructor(t){this._name=t}debug(...t){l>=4&&d.debug(_._format(this._name,this._method),...t)}info(...t){l>=3&&d.info(_._format(this._name,this._method),...t)}warn(...t){l>=2&&d.warn(_._format(this._name,this._method),...t)}error(...t){l>=1&&d.error(_._format(this._name,this._method),...t)}throw(t){throw this.error(t),t}create(t){const e=Object.create(this);return e._method=t,e.debug("begin"),e}static createStatic(t,e){const s=new _(`${t}.${e}`);return s.debug("begin"),s}static _format(t,e){const s=`[${t}]`;return e?`${s} ${e}:`:s}static debug(t,...e){l>=4&&d.debug(_._format(t),...e)}static info(t,...e){l>=3&&d.info(_._format(t),...e)}static warn(t,...e){l>=2&&d.warn(_._format(t),...e)}static error(t,...e){l>=1&&d.error(_._format(t),...e)}};g.reset();var y=class{static _randomWord(){return e.lib.WordArray.random(1).words[0]}static generateUUIDv4(){return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,(t=>(+t^y._randomWord()&15>>+t/4).toString(16))).replace(/-/g,"")}static generateCodeVerifier(){return y.generateUUIDv4()+y.generateUUIDv4()+y.generateUUIDv4()}static generateCodeChallenge(t){try{const e=r(t);return i.stringify(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}catch(t){throw _.error("CryptoUtils.generateCodeChallenge",t),t}}static generateBasicAuth(t,e){const s=n.parse([t,e].join(":"));return i.stringify(s)}},m=class{constructor(t){this._name=t,this._logger=new _(`Event('${this._name}')`),this._callbacks=[]}addHandler(t){return this._callbacks.push(t),()=>this.removeHandler(t)}removeHandler(t){const e=this._callbacks.lastIndexOf(t);e>=0&&this._callbacks.splice(e,1)}raise(...t){this._logger.debug("raise:",...t);for(const e of this._callbacks)e(...t)}},w=class{static decode(t){try{return u(t)}catch(t){throw _.error("JwtUtils.decode",t),t}}},b=class extends m{constructor(){super(...arguments),this._logger=new _(`Timer('${this._name}')`),this._timerHandle=null,this._expiration=0,this._callback=()=>{const t=this._expiration-b.getEpochTime();this._logger.debug("timer completes in",t),this._expiration<=b.getEpochTime()&&(this.cancel(),super.raise())}}static getEpochTime(){return Math.floor(Date.now()/1e3)}init(t){const e=this._logger.create("init");t=Math.max(Math.floor(t),1);const s=b.getEpochTime()+t;if(this.expiration===s&&this._timerHandle)return void e.debug("skipping since already initialized for expiration at",this.expiration);this.cancel(),e.debug("using duration",t),this._expiration=s;const r=Math.min(t,5);this._timerHandle=setInterval(this._callback,1e3*r)}get expiration(){return this._expiration}cancel(){this._logger.create("cancel"),this._timerHandle&&(clearInterval(this._timerHandle),this._timerHandle=null)}},v=class{static readParams(t,e="query"){if(!t)throw new TypeError("Invalid URL");const s=new URL(t,window.location.origin)["fragment"===e?"hash":"search"];return new URLSearchParams(s.slice(1))}},k=class extends Error{constructor(t,e){var s,r,i;if(super(t.error_description||t.error||""),this.form=e,this.name="ErrorResponse",!t.error)throw _.error("ErrorResponse","No error passed"),new Error("No error passed");this.error=t.error,this.error_description=null!=(s=t.error_description)?s:null,this.error_uri=null!=(r=t.error_uri)?r:null,this.state=t.userState,this.session_state=null!=(i=t.session_state)?i:null}},S=class extends Error{constructor(t){super(t),this.name="ErrorTimeout"}},E=class{constructor(t=[],e=null){this._jwtHandler=e,this._logger=new _("JsonService"),this._contentTypes=[],this._contentTypes.push(...t,"application/json"),e&&this._contentTypes.push("application/jwt")}async fetchWithTimeout(t,e={}){const{timeoutInSeconds:s,...r}=e;if(!s)return await fetch(t,r);const i=new AbortController,n=setTimeout((()=>i.abort()),1e3*s);try{return await fetch(t,{...e,signal:i.signal})}catch(t){if(t instanceof DOMException&&"AbortError"===t.name)throw new S("Network timed out");throw t}finally{clearTimeout(n)}}async getJson(t,{token:e,credentials:s}={}){const r=this._logger.create("getJson"),i={Accept:this._contentTypes.join(", ")};let n;e&&(r.debug("token passed, setting Authorization header"),i.Authorization="Bearer "+e);try{r.debug("url:",t),n=await this.fetchWithTimeout(t,{method:"GET",headers:i,credentials:s})}catch(t){throw r.error("Network Error"),t}r.debug("HTTP response received, status",n.status);const o=n.headers.get("Content-Type");if(o&&!this._contentTypes.find((t=>o.startsWith(t)))&&r.throw(new Error(`Invalid response Content-Type: ${null!=o?o:"undefined"}, from URL: ${t}`)),n.ok&&this._jwtHandler&&(null==o?void 0:o.startsWith("application/jwt")))return await this._jwtHandler(await n.text());let a;try{a=await n.json()}catch(t){if(r.error("Error parsing JSON response",t),n.ok)throw t;throw new Error(`${n.statusText} (${n.status})`)}if(!n.ok){if(r.error("Error from server:",a),a.error)throw new k(a);throw new Error(`${n.statusText} (${n.status}): ${JSON.stringify(a)}`)}return a}async postForm(t,{body:e,basicAuth:s,timeoutInSeconds:r,initCredentials:i}){const n=this._logger.create("postForm"),o={Accept:this._contentTypes.join(", "),"Content-Type":"application/x-www-form-urlencoded"};let a;void 0!==s&&(o.Authorization="Basic "+s);try{n.debug("url:",t),a=await this.fetchWithTimeout(t,{method:"POST",headers:o,body:e,timeoutInSeconds:r,credentials:i})}catch(t){throw n.error("Network error"),t}n.debug("HTTP response received, status",a.status);const c=a.headers.get("Content-Type");if(c&&!this._contentTypes.find((t=>c.startsWith(t))))throw new Error(`Invalid response Content-Type: ${null!=c?c:"undefined"}, from URL: ${t}`);const h=await a.text();let u={};if(h)try{u=JSON.parse(h)}catch(t){if(n.error("Error parsing JSON response",t),a.ok)throw t;throw new Error(`${a.statusText} (${a.status})`)}if(!a.ok){if(n.error("Error from server:",u),u.error)throw new k(u,e);throw new Error(`${a.statusText} (${a.status}): ${JSON.stringify(u)}`)}return u}},T=class{constructor(t,e){this._settings=t,this._metadataService=e,this._logger=new _("TokenClient"),this._jsonService=new E(this._settings.revokeTokenAdditionalContentTypes)}async exchangeCode({grant_type:t="authorization_code",redirect_uri:e=this._settings.redirect_uri,client_id:s=this._settings.client_id,client_secret:r=this._settings.client_secret,...i}){const n=this._logger.create("exchangeCode");s||n.throw(new Error("A client_id is required")),e||n.throw(new Error("A redirect_uri is required")),i.code||n.throw(new Error("A code is required")),i.code_verifier||n.throw(new Error("A code_verifier is required"));const o=new URLSearchParams({grant_type:t,redirect_uri:e});for(const[t,e]of Object.entries(i))null!=e&&o.set(t,e);let a;switch(this._settings.client_authentication){case"client_secret_basic":if(!r)throw n.throw(new Error("A client_secret is required")),null;a=y.generateBasicAuth(s,r);break;case"client_secret_post":o.append("client_id",s),r&&o.append("client_secret",r)}const c=await this._metadataService.getTokenEndpoint(!1);n.debug("got token endpoint");const h=await this._jsonService.postForm(c,{body:o,basicAuth:a,initCredentials:this._settings.fetchRequestCredentials});return n.debug("got response"),h}async exchangeCredentials({grant_type:t="password",client_id:e=this._settings.client_id,client_secret:s=this._settings.client_secret,scope:r=this._settings.scope,...i}){const n=this._logger.create("exchangeCredentials");e||n.throw(new Error("A client_id is required"));const o=new URLSearchParams({grant_type:t,scope:r});for(const[t,e]of Object.entries(i))null!=e&&o.set(t,e);let a;switch(this._settings.client_authentication){case"client_secret_basic":if(!s)throw n.throw(new Error("A client_secret is required")),null;a=y.generateBasicAuth(e,s);break;case"client_secret_post":o.append("client_id",e),s&&o.append("client_secret",s)}const c=await this._metadataService.getTokenEndpoint(!1);n.debug("got token endpoint");const h=await this._jsonService.postForm(c,{body:o,basicAuth:a,initCredentials:this._settings.fetchRequestCredentials});return n.debug("got response"),h}async exchangeRefreshToken({grant_type:t="refresh_token",client_id:e=this._settings.client_id,client_secret:s=this._settings.client_secret,timeoutInSeconds:r,...i}){const n=this._logger.create("exchangeRefreshToken");e||n.throw(new Error("A client_id is required")),i.refresh_token||n.throw(new Error("A refresh_token is required"));const o=new URLSearchParams({grant_type:t});for(const[t,e]of Object.entries(i))null!=e&&o.set(t,e);let a;switch(this._settings.client_authentication){case"client_secret_basic":if(!s)throw n.throw(new Error("A client_secret is required")),null;a=y.generateBasicAuth(e,s);break;case"client_secret_post":o.append("client_id",e),s&&o.append("client_secret",s)}const c=await this._metadataService.getTokenEndpoint(!1);n.debug("got token endpoint");const h=await this._jsonService.postForm(c,{body:o,basicAuth:a,timeoutInSeconds:r,initCredentials:this._settings.fetchRequestCredentials});return n.debug("got response"),h}async revoke(t){var e;const s=this._logger.create("revoke");t.token||s.throw(new Error("A token is required"));const r=await this._metadataService.getRevocationEndpoint(!1);s.debug(`got revocation endpoint, revoking ${null!=(e=t.token_type_hint)?e:"default token type"}`);const i=new URLSearchParams;for(const[e,s]of Object.entries(t))null!=s&&i.set(e,s);i.set("client_id",this._settings.client_id),this._settings.client_secret&&i.set("client_secret",this._settings.client_secret),await this._jsonService.postForm(r,{body:i}),s.debug("got response")}},R=["nbf","jti","auth_time","nonce","acr","amr","azp","at_hash"],A=["sub","iss","aud","exp","iat"],C=class{constructor(t){this.id=t.id||y.generateUUIDv4(),this.data=t.data,t.created&&t.created>0?this.created=t.created:this.created=b.getEpochTime(),this.request_type=t.request_type}toStorageString(){return new _("State").create("toStorageString"),JSON.stringify({id:this.id,data:this.data,created:this.created,request_type:this.request_type})}static fromStorageString(t){return _.createStatic("State","fromStorageString"),new C(JSON.parse(t))}static async clearStaleState(t,e){const s=_.createStatic("State","clearStaleState"),r=b.getEpochTime()-e,i=await t.getAllKeys();s.debug("got keys",i);for(let e=0;e<i.length;e++){const n=i[e],o=await t.get(n);let a=!1;if(o)try{const t=C.fromStorageString(o);s.debug("got item from key:",n,t.created),t.created<=r&&(a=!0)}catch(t){s.error("Error parsing state for key:",n,t),a=!0}else s.debug("no item in storage for key:",n),a=!0;a&&(s.debug("removed item for key:",n),t.remove(n))}}},x=class extends C{constructor(t){super(t),!0===t.code_verifier?this.code_verifier=y.generateCodeVerifier():t.code_verifier&&(this.code_verifier=t.code_verifier),this.code_verifier&&(this.code_challenge=y.generateCodeChallenge(this.code_verifier)),this.authority=t.authority,this.client_id=t.client_id,this.redirect_uri=t.redirect_uri,this.scope=t.scope,this.client_secret=t.client_secret,this.extraTokenParams=t.extraTokenParams,this.response_mode=t.response_mode,this.skipUserInfo=t.skipUserInfo}toStorageString(){return new _("SigninState").create("toStorageString"),JSON.stringify({id:this.id,data:this.data,created:this.created,request_type:this.request_type,code_verifier:this.code_verifier,authority:this.authority,client_id:this.client_id,redirect_uri:this.redirect_uri,scope:this.scope,client_secret:this.client_secret,extraTokenParams:this.extraTokenParams,response_mode:this.response_mode,skipUserInfo:this.skipUserInfo})}static fromStorageString(t){_.createStatic("SigninState","fromStorageString");const e=JSON.parse(t);return new x(e)}},O=class{constructor(t){this.access_token="",this.token_type="",this.profile={},this.state=t.get("state"),this.session_state=t.get("session_state"),this.error=t.get("error"),this.error_description=t.get("error_description"),this.error_uri=t.get("error_uri"),this.code=t.get("code")}get expires_in(){if(void 0!==this.expires_at)return this.expires_at-b.getEpochTime()}set expires_in(t){"string"==typeof t&&(t=Number(t)),void 0!==t&&t>=0&&(this.expires_at=Math.floor(t)+b.getEpochTime())}get isOpenId(){var t;return(null==(t=this.scope)?void 0:t.split(" ").includes("openid"))||!!this.id_token}};const I={},P=(t,e)=>B()?localStorage.setItem(t,e):I[t]=e,N=t=>B()?localStorage.getItem(t):I[t],B=()=>!("object"==typeof process&&"[object process]"===String(process));class j{constructor(t){this._oidcSettings={authority:"https://auth.gameglue.gg/realms/GameGlue",client_id:t.clientId,redirect_uri:L(t.redirect_uri||window.location.href),post_logout_redirect_uri:L(window.location.href),response_type:"code",scope:`openid ${(t.scopes||[]).join(" ")}`,response_mode:"fragment",filterProtocolClaims:!0},this._oidcClient=new class{constructor(t){this._logger=new _("OidcClient"),this.settings=new class{constructor({authority:t,metadataUrl:e,metadata:s,signingKeys:r,metadataSeed:i,client_id:n,client_secret:o,response_type:a="code",scope:c="openid",redirect_uri:h,post_logout_redirect_uri:u,client_authentication:l="client_secret_post",prompt:d,display:p,max_age:f,ui_locales:g,acr_values:y,resource:m,response_mode:w="query",filterProtocolClaims:b=!0,loadUserInfo:v=!1,staleStateAgeInSeconds:k=900,clockSkewInSeconds:S=300,userInfoJwtIssuer:E="OP",mergeClaims:T=!1,stateStore:R,refreshTokenCredentials:A,revokeTokenAdditionalContentTypes:C,fetchRequestCredentials:x,refreshTokenAllowedScope:O,extraQueryParams:I={},extraTokenParams:P={}}){if(this.authority=t,e?this.metadataUrl=e:(this.metadataUrl=t,t&&(this.metadataUrl.endsWith("/")||(this.metadataUrl+="/"),this.metadataUrl+=".well-known/openid-configuration")),this.metadata=s,this.metadataSeed=i,this.signingKeys=r,this.client_id=n,this.client_secret=o,this.response_type=a,this.scope=c,this.redirect_uri=h,this.post_logout_redirect_uri=u,this.client_authentication=l,this.prompt=d,this.display=p,this.max_age=f,this.ui_locales=g,this.acr_values=y,this.resource=m,this.response_mode=w,this.filterProtocolClaims=null==b||b,this.loadUserInfo=!!v,this.staleStateAgeInSeconds=k,this.clockSkewInSeconds=S,this.userInfoJwtIssuer=E,this.mergeClaims=!!T,this.revokeTokenAdditionalContentTypes=C,x&&A&&console.warn("Both fetchRequestCredentials and refreshTokenCredentials is set. Only fetchRequestCredentials will be used."),this.fetchRequestCredentials=x||A||"same-origin",R)this.stateStore=R;else{const t="undefined"!=typeof window?window.localStorage:new class{constructor(){this._logger=new _("InMemoryWebStorage"),this._data={}}clear(){this._logger.create("clear"),this._data={}}getItem(t){return this._logger.create(`getItem('${t}')`),this._data[t]}setItem(t,e){this._logger.create(`setItem('${t}')`),this._data[t]=e}removeItem(t){this._logger.create(`removeItem('${t}')`),delete this._data[t]}get length(){return Object.getOwnPropertyNames(this._data).length}key(t){return Object.getOwnPropertyNames(this._data)[t]}};this.stateStore=new class{constructor({prefix:t="oidc.",store:e=localStorage}={}){this._logger=new _("WebStorageStateStore"),this._store=e,this._prefix=t}async set(t,e){this._logger.create(`set('${t}')`),t=this._prefix+t,await this._store.setItem(t,e)}async get(t){return this._logger.create(`get('${t}')`),t=this._prefix+t,await this._store.getItem(t)}async remove(t){this._logger.create(`remove('${t}')`),t=this._prefix+t;const e=await this._store.getItem(t);return await this._store.removeItem(t),e}async getAllKeys(){this._logger.create("getAllKeys");const t=await this._store.length,e=[];for(let s=0;s<t;s++){const t=await this._store.key(s);t&&0===t.indexOf(this._prefix)&&e.push(t.substr(this._prefix.length))}return e}}({store:t})}this.refreshTokenAllowedScope=O,this.extraQueryParams=I,this.extraTokenParams=P}}(t),this.metadataService=new class{constructor(t){this._settings=t,this._logger=new _("MetadataService"),this._jsonService=new E(["application/jwk-set+json"]),this._signingKeys=null,this._metadata=null,this._metadataUrl=this._settings.metadataUrl,this._settings.signingKeys&&(this._logger.debug("using signingKeys from settings"),this._signingKeys=this._settings.signingKeys),this._settings.metadata&&(this._logger.debug("using metadata from settings"),this._metadata=this._settings.metadata),this._settings.fetchRequestCredentials&&(this._logger.debug("using fetchRequestCredentials from settings"),this._fetchRequestCredentials=this._settings.fetchRequestCredentials)}resetSigningKeys(){this._signingKeys=null}async getMetadata(){const t=this._logger.create("getMetadata");if(this._metadata)return t.debug("using cached values"),this._metadata;if(!this._metadataUrl)throw t.throw(new Error("No authority or metadataUrl configured on settings")),null;t.debug("getting metadata from",this._metadataUrl);const e=await this._jsonService.getJson(this._metadataUrl,{credentials:this._fetchRequestCredentials});return t.debug("merging remote JSON with seed metadata"),this._metadata=Object.assign({},this._settings.metadataSeed,e),this._metadata}getIssuer(){return this._getMetadataProperty("issuer")}getAuthorizationEndpoint(){return this._getMetadataProperty("authorization_endpoint")}getUserInfoEndpoint(){return this._getMetadataProperty("userinfo_endpoint")}getTokenEndpoint(t=!0){return this._getMetadataProperty("token_endpoint",t)}getCheckSessionIframe(){return this._getMetadataProperty("check_session_iframe",!0)}getEndSessionEndpoint(){return this._getMetadataProperty("end_session_endpoint",!0)}getRevocationEndpoint(t=!0){return this._getMetadataProperty("revocation_endpoint",t)}getKeysEndpoint(t=!0){return this._getMetadataProperty("jwks_uri",t)}async _getMetadataProperty(t,e=!1){const s=this._logger.create(`_getMetadataProperty('${t}')`),r=await this.getMetadata();if(s.debug("resolved"),void 0===r[t]){if(!0===e)return void s.warn("Metadata does not contain optional property");s.throw(new Error("Metadata does not contain property "+t))}return r[t]}async getSigningKeys(){const t=this._logger.create("getSigningKeys");if(this._signingKeys)return t.debug("returning signingKeys from cache"),this._signingKeys;const e=await this.getKeysEndpoint(!1);t.debug("got jwks_uri",e);const s=await this._jsonService.getJson(e);if(t.debug("got key set",s),!Array.isArray(s.keys))throw t.throw(new Error("Missing keys on keyset")),null;return this._signingKeys=s.keys,this._signingKeys}}(this.settings),this._validator=new class{constructor(t,e){this._settings=t,this._metadataService=e,this._logger=new _("ResponseValidator"),this._userInfoService=new class{constructor(t,e){this._settings=t,this._metadataService=e,this._logger=new _("UserInfoService"),this._getClaimsFromJwt=async t=>{const e=this._logger.create("_getClaimsFromJwt");try{const s=w.decode(t);return e.debug("JWT decoding successful"),s}catch(t){throw e.error("Error parsing JWT response"),t}},this._jsonService=new E(void 0,this._getClaimsFromJwt)}async getClaims(t){const e=this._logger.create("getClaims");t||this._logger.throw(new Error("No token passed"));const s=await this._metadataService.getUserInfoEndpoint();e.debug("got userinfo url",s);const r=await this._jsonService.getJson(s,{token:t,credentials:this._settings.fetchRequestCredentials});return e.debug("got claims",r),r}}(this._settings,this._metadataService),this._tokenClient=new T(this._settings,this._metadataService)}async validateSigninResponse(t,e){const s=this._logger.create("validateSigninResponse");this._processSigninState(t,e),s.debug("state processed"),await this._processCode(t,e),s.debug("code processed"),t.isOpenId&&this._validateIdTokenAttributes(t),s.debug("tokens validated"),await this._processClaims(t,null==e?void 0:e.skipUserInfo,t.isOpenId),s.debug("claims processed")}async validateCredentialsResponse(t,e){const s=this._logger.create("validateCredentialsResponse");t.isOpenId&&this._validateIdTokenAttributes(t),s.debug("tokens validated"),await this._processClaims(t,e,t.isOpenId),s.debug("claims processed")}async validateRefreshResponse(t,e){const s=this._logger.create("validateRefreshResponse");t.userState=e.data,null!=t.session_state||(t.session_state=e.session_state),null!=t.scope||(t.scope=e.scope),t.isOpenId&&t.id_token&&(this._validateIdTokenAttributes(t,e.id_token),s.debug("ID Token validated")),t.id_token||(t.id_token=e.id_token,t.profile=e.profile);const r=t.isOpenId&&!!t.id_token;await this._processClaims(t,!1,r),s.debug("claims processed")}validateSignoutResponse(t,e){const s=this._logger.create("validateSignoutResponse");if(e.id!==t.state&&s.throw(new Error("State does not match")),s.debug("state validated"),t.userState=e.data,t.error)throw s.warn("Response was error",t.error),new k(t)}_processSigninState(t,e){const s=this._logger.create("_processSigninState");if(e.id!==t.state&&s.throw(new Error("State does not match")),e.client_id||s.throw(new Error("No client_id on state")),e.authority||s.throw(new Error("No authority on state")),this._settings.authority!==e.authority&&s.throw(new Error("authority mismatch on settings vs. signin state")),this._settings.client_id&&this._settings.client_id!==e.client_id&&s.throw(new Error("client_id mismatch on settings vs. signin state")),s.debug("state validated"),t.userState=e.data,null!=t.scope||(t.scope=e.scope),t.error)throw s.warn("Response was error",t.error),new k(t);e.code_verifier&&!t.code&&s.throw(new Error("Expected code in response")),!e.code_verifier&&t.code&&s.throw(new Error("Unexpected code in response"))}async _processClaims(t,e=!1,s=!0){const r=this._logger.create("_processClaims");if(t.profile=this._filterProtocolClaims(t.profile),e||!this._settings.loadUserInfo||!t.access_token)return void r.debug("not loading user info");r.debug("loading user info");const i=await this._userInfoService.getClaims(t.access_token);r.debug("user info claims received from user info endpoint"),s&&i.sub!==t.profile.sub&&r.throw(new Error("subject from UserInfo response does not match subject in ID Token")),t.profile=this._mergeClaims(t.profile,this._filterProtocolClaims(i)),r.debug("user info claims received, updated profile:",t.profile)}_mergeClaims(t,e){const s={...t};for(const[t,r]of Object.entries(e))for(const e of Array.isArray(r)?r:[r]){const r=s[t];r?Array.isArray(r)?r.includes(e)||r.push(e):s[t]!==e&&("object"==typeof e&&this._settings.mergeClaims?s[t]=this._mergeClaims(r,e):s[t]=[r,e]):s[t]=e}return s}_filterProtocolClaims(t){const e={...t};if(this._settings.filterProtocolClaims){let t;t=Array.isArray(this._settings.filterProtocolClaims)?this._settings.filterProtocolClaims:R;for(const s of t)A.includes(s)||delete e[s]}return e}async _processCode(t,e){const s=this._logger.create("_processCode");if(t.code){s.debug("Validating code");const r=await this._tokenClient.exchangeCode({client_id:e.client_id,client_secret:e.client_secret,code:t.code,redirect_uri:e.redirect_uri,code_verifier:e.code_verifier,...e.extraTokenParams});Object.assign(t,r)}else s.debug("No code to process")}_validateIdTokenAttributes(t,e){var s;const r=this._logger.create("_validateIdTokenAttributes");r.debug("decoding ID Token JWT");const i=w.decode(null!=(s=t.id_token)?s:"");if(i.sub||r.throw(new Error("ID Token is missing a subject claim")),e){const t=w.decode(e);t.sub!==i.sub&&r.throw(new Error("sub in id_token does not match current sub")),t.auth_time&&t.auth_time!==i.auth_time&&r.throw(new Error("auth_time in id_token does not match original auth_time")),t.azp&&t.azp!==i.azp&&r.throw(new Error("azp in id_token does not match original azp")),!t.azp&&i.azp&&r.throw(new Error("azp not in id_token, but present in original id_token"))}t.profile=i}}(this.settings,this.metadataService),this._tokenClient=new T(this.settings,this.metadataService)}async createSigninRequest({state:t,request:e,request_uri:s,request_type:r,id_token_hint:i,login_hint:n,skipUserInfo:o,nonce:a,response_type:c=this.settings.response_type,scope:h=this.settings.scope,redirect_uri:u=this.settings.redirect_uri,prompt:l=this.settings.prompt,display:d=this.settings.display,max_age:p=this.settings.max_age,ui_locales:f=this.settings.ui_locales,acr_values:g=this.settings.acr_values,resource:y=this.settings.resource,response_mode:m=this.settings.response_mode,extraQueryParams:w=this.settings.extraQueryParams,extraTokenParams:b=this.settings.extraTokenParams}){const v=this._logger.create("createSigninRequest");if("code"!==c)throw new Error("Only the Authorization Code flow (with PKCE) is supported");const k=await this.metadataService.getAuthorizationEndpoint();v.debug("Received authorization endpoint",k);const S=new class{constructor({url:t,authority:e,client_id:s,redirect_uri:r,response_type:i,scope:n,state_data:o,response_mode:a,request_type:c,client_secret:h,nonce:u,resource:l,skipUserInfo:d,extraQueryParams:p,extraTokenParams:f,...g}){if(this._logger=new _("SigninRequest"),!t)throw this._logger.error("ctor: No url passed"),new Error("url");if(!s)throw this._logger.error("ctor: No client_id passed"),new Error("client_id");if(!r)throw this._logger.error("ctor: No redirect_uri passed"),new Error("redirect_uri");if(!i)throw this._logger.error("ctor: No response_type passed"),new Error("response_type");if(!n)throw this._logger.error("ctor: No scope passed"),new Error("scope");if(!e)throw this._logger.error("ctor: No authority passed"),new Error("authority");this.state=new x({data:o,request_type:c,code_verifier:!0,client_id:s,authority:e,redirect_uri:r,response_mode:a,client_secret:h,scope:n,extraTokenParams:f,skipUserInfo:d});const y=new URL(t);y.searchParams.append("client_id",s),y.searchParams.append("redirect_uri",r),y.searchParams.append("response_type",i),y.searchParams.append("scope",n),u&&y.searchParams.append("nonce",u),y.searchParams.append("state",this.state.id),this.state.code_challenge&&(y.searchParams.append("code_challenge",this.state.code_challenge),y.searchParams.append("code_challenge_method","S256")),l&&(Array.isArray(l)?l:[l]).forEach((t=>y.searchParams.append("resource",t)));for(const[t,e]of Object.entries({response_mode:a,...g,...p}))null!=e&&y.searchParams.append(t,e.toString());this.url=y.href}}({url:k,authority:this.settings.authority,client_id:this.settings.client_id,redirect_uri:u,response_type:c,scope:h,state_data:t,prompt:l,display:d,max_age:p,ui_locales:f,id_token_hint:i,login_hint:n,acr_values:g,resource:y,request:e,request_uri:s,extraQueryParams:w,extraTokenParams:b,request_type:r,response_mode:m,client_secret:this.settings.client_secret,skipUserInfo:o,nonce:a});await this.clearStaleState();const E=S.state;return await this.settings.stateStore.set(E.id,E.toStorageString()),S}async readSigninResponseState(t,e=!1){const s=this._logger.create("readSigninResponseState"),r=new O(v.readParams(t,this.settings.response_mode));if(!r.state)throw s.throw(new Error("No state in response")),null;const i=await this.settings.stateStore[e?"remove":"get"](r.state);if(!i)throw s.throw(new Error("No matching state found in storage")),null;return{state:x.fromStorageString(i),response:r}}async processSigninResponse(t){const e=this._logger.create("processSigninResponse"),{state:s,response:r}=await this.readSigninResponseState(t,!0);return e.debug("received state from storage; validating response"),await this._validator.validateSigninResponse(r,s),r}async processResourceOwnerPasswordCredentials({username:t,password:e,skipUserInfo:s=!1,extraTokenParams:r={}}){const i=await this._tokenClient.exchangeCredentials({username:t,password:e,...r}),n=new O(new URLSearchParams);return Object.assign(n,i),await this._validator.validateCredentialsResponse(n,s),n}async useRefreshToken({state:t,timeoutInSeconds:e}){var s;const r=this._logger.create("useRefreshToken");let i;if(void 0===this.settings.refreshTokenAllowedScope)i=t.scope;else{const e=this.settings.refreshTokenAllowedScope.split(" ");i=((null==(s=t.scope)?void 0:s.split(" "))||[]).filter((t=>e.includes(t))).join(" ")}const n=await this._tokenClient.exchangeRefreshToken({refresh_token:t.refresh_token,scope:i,timeoutInSeconds:e}),o=new O(new URLSearchParams);return Object.assign(o,n),r.debug("validating response",o),await this._validator.validateRefreshResponse(o,{...t,scope:i}),o}async createSignoutRequest({state:t,id_token_hint:e,request_type:s,post_logout_redirect_uri:r=this.settings.post_logout_redirect_uri,extraQueryParams:i=this.settings.extraQueryParams}={}){const n=this._logger.create("createSignoutRequest"),o=await this.metadataService.getEndSessionEndpoint();if(!o)throw n.throw(new Error("No end session endpoint")),null;n.debug("Received end session endpoint",o);const a=new class{constructor({url:t,state_data:e,id_token_hint:s,post_logout_redirect_uri:r,extraQueryParams:i,request_type:n}){if(this._logger=new _("SignoutRequest"),!t)throw this._logger.error("ctor: No url passed"),new Error("url");const o=new URL(t);s&&o.searchParams.append("id_token_hint",s),r&&(o.searchParams.append("post_logout_redirect_uri",r),e&&(this.state=new C({data:e,request_type:n}),o.searchParams.append("state",this.state.id)));for(const[t,e]of Object.entries({...i}))null!=e&&o.searchParams.append(t,e.toString());this.url=o.href}}({url:o,id_token_hint:e,post_logout_redirect_uri:r,state_data:t,extraQueryParams:i,request_type:s});await this.clearStaleState();const c=a.state;return c&&(n.debug("Signout request has state to persist"),await this.settings.stateStore.set(c.id,c.toStorageString())),a}async readSignoutResponseState(t,e=!1){const s=this._logger.create("readSignoutResponseState"),r=new class{constructor(t){this.state=t.get("state"),this.error=t.get("error"),this.error_description=t.get("error_description"),this.error_uri=t.get("error_uri")}}(v.readParams(t,this.settings.response_mode));if(!r.state){if(s.debug("No state in response"),r.error)throw s.warn("Response was error:",r.error),new k(r);return{state:void 0,response:r}}const i=await this.settings.stateStore[e?"remove":"get"](r.state);if(!i)throw s.throw(new Error("No matching state found in storage")),null;return{state:C.fromStorageString(i),response:r}}async processSignoutResponse(t){const e=this._logger.create("processSignoutResponse"),{state:s,response:r}=await this.readSignoutResponseState(t,!0);return s?(e.debug("Received state from storage; validating response"),this._validator.validateSignoutResponse(r,s)):e.debug("No state from storage; skipping response validation"),r}clearStaleState(){return this._logger.create("clearStaleState"),C.clearStaleState(this.settings.stateStore,this.settings.staleStateAgeInSeconds)}async revokeToken(t,e){return this._logger.create("revokeToken"),await this._tokenClient.revoke({token:t,token_type_hint:e})}}(this._oidcSettings),this._refreshCallback=()=>{},this._refreshTimeout=null}setTokenRefreshTimeout(t){if(!t)return;clearTimeout(this._refreshTimeout);const e=1e3*u(t).exp-Date.now()-5e3;e>0&&(this._refreshTimeout=setTimeout((()=>{this.attemptRefresh()}),e))}setAccessToken(t){return this.setTokenRefreshTimeout(t),P("gg-auth-token",t)}getAccessToken(){let t=N("gg-auth-token");return this.setTokenRefreshTimeout(t),t}getUserId(){return u(this.getAccessToken()).sub}setRefreshToken(t){return P("gg-refresh-token",t)}getRefreshToken(t){return N("gg-refresh-token")}_shouldHandleRedirectResponse(){return location.hash.includes("state=")&&(location.hash.includes("code=")||location.hash.includes("error="))}async handleRedirectResponse(){let t=await this._oidcClient.processSigninResponse(window.location.href);!t.error&&t.access_token?(window.history.pushState("",document.title,window.location.pathname+window.location.search),this.setAccessToken(t.access_token),this.setRefreshToken(t.refresh_token)):console.error(t.error)}onTokenRefreshed(t){this._refreshCallback=t}async isAuthenticated(t){let e=this.getAccessToken();if(!e)return!1;const s=u(e),r=new Date(1e3*s.exp)<new Date;return r&&!t?(await this.attemptRefresh(),this.isAuthenticated(!0)):!(r&&t)}isTokenExpired(t){const e=u(t);return new Date(1e3*e.exp)<new Date}async attemptRefresh(){const t=`${this._oidcSettings.authority}/protocol/openid-connect/token`,e=this._oidcSettings.client_id,s=this.getRefreshToken();try{const r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:e,grant_type:"refresh_token",refresh_token:s})});if(200===r.status){const t=await r.json();this.setAccessToken(t.access_token),this.setRefreshToken(t.refresh_token),this._refreshCallback(t)}}catch(t){console.log("Error: ",t)}}_triggerAuthRedirect(){this._oidcClient.createSigninRequest({state:{bar:15}}).then((function(t){window.location=t.url})).catch((function(t){console.error(t)}))}async authenticate(){this._shouldHandleRedirectResponse()&&await this.handleRedirectResponse(),await this.isAuthenticated()||await this._triggerAuthRedirect()}}function L(t){return t.endsWith("/")?t.replace(/\/+$/,""):t}const q=Object.create(null);q.open="0",q.close="1",q.ping="2",q.pong="3",q.message="4",q.upgrade="5",q.noop="6";const U=Object.create(null);Object.keys(q).forEach((t=>{U[q[t]]=t}));const M={type:"error",data:"parser error"},D="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),z="function"==typeof ArrayBuffer,F=(t,e)=>{const s=new FileReader;return s.onload=function(){const t=s.result.split(",")[1];e("b"+(t||""))},s.readAsDataURL(t)},H=({type:t,data:e},s,r)=>{return D&&e instanceof Blob?s?r(e):F(e,r):z&&(e instanceof ArrayBuffer||(i=e,"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(i):i&&i.buffer instanceof ArrayBuffer))?s?r(e):F(new Blob([e]),r):r(q[t]+(e||""));var i},$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",K="undefined"==typeof Uint8Array?[]:new Uint8Array(256);for(let t=0;t<$.length;t++)K[$.charCodeAt(t)]=t;const J="function"==typeof ArrayBuffer,W=(t,e)=>{if(J){const s=(t=>{let e,s,r,i,n,o=.75*t.length,a=t.length,c=0;"="===t[t.length-1]&&(o--,"="===t[t.length-2]&&o--);const h=new ArrayBuffer(o),u=new Uint8Array(h);for(e=0;e<a;e+=4)s=K[t.charCodeAt(e)],r=K[t.charCodeAt(e+1)],i=K[t.charCodeAt(e+2)],n=K[t.charCodeAt(e+3)],u[c++]=s<<2|r>>4,u[c++]=(15&r)<<4|i>>2,u[c++]=(3&i)<<6|63&n;return h})(t);return V(s,e)}return{base64:!0,data:t}},V=(t,e)=>"blob"===e&&t instanceof ArrayBuffer?new Blob([t]):t,Y=(t,e)=>{if("string"!=typeof t)return{type:"message",data:V(t,e)};const s=t.charAt(0);return"b"===s?{type:"message",data:W(t.substring(1),e)}:U[s]?t.length>1?{type:U[s],data:t.substring(1)}:{type:U[s]}:M},Q=String.fromCharCode(30);function G(t){if(t)return function(t){for(var e in G.prototype)t[e]=G.prototype[e];return t}(t)}G.prototype.on=G.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},G.prototype.once=function(t,e){function s(){this.off(t,s),e.apply(this,arguments)}return s.fn=e,this.on(t,s),this},G.prototype.off=G.prototype.removeListener=G.prototype.removeAllListeners=G.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var s,r=this._callbacks["$"+t];if(!r)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i<r.length;i++)if((s=r[i])===e||s.fn===e){r.splice(i,1);break}return 0===r.length&&delete this._callbacks["$"+t],this},G.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),s=this._callbacks["$"+t],r=1;r<arguments.length;r++)e[r-1]=arguments[r];if(s){r=0;for(var i=(s=s.slice(0)).length;r<i;++r)s[r].apply(this,e)}return this},G.prototype.emitReserved=G.prototype.emit,G.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},G.prototype.hasListeners=function(t){return!!this.listeners(t).length};const X="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function Z(t,...e){return e.reduce(((e,s)=>(t.hasOwnProperty(s)&&(e[s]=t[s]),e)),{})}const tt=setTimeout,et=clearTimeout;function st(t,e){e.useNativeTimers?(t.setTimeoutFn=tt.bind(X),t.clearTimeoutFn=et.bind(X)):(t.setTimeoutFn=setTimeout.bind(X),t.clearTimeoutFn=clearTimeout.bind(X))}class rt extends Error{constructor(t,e,s){super(t),this.description=e,this.context=s,this.type="TransportError"}}class it extends G{constructor(t){super(),this.writable=!1,st(this,t),this.opts=t,this.query=t.query,this.readyState="",this.socket=t.socket}onError(t,e,s){return super.emitReserved("error",new rt(t,e,s)),this}open(){return"closed"!==this.readyState&&""!==this.readyState||(this.readyState="opening",this.doOpen()),this}close(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}send(t){"open"===this.readyState&&this.write(t)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(t){const e=Y(t,this.socket.binaryType);this.onPacket(e)}onPacket(t){super.emitReserved("packet",t)}onClose(t){this.readyState="closed",super.emitReserved("close",t)}}const nt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),ot={};let at,ct=0,ht=0;function ut(t){let e="";do{e=nt[t%64]+e,t=Math.floor(t/64)}while(t>0);return e}function lt(){const t=ut(+new Date);return t!==at?(ct=0,at=t):t+"."+ut(ct++)}for(;ht<64;ht++)ot[nt[ht]]=ht;function dt(t){let e="";for(let s in t)t.hasOwnProperty(s)&&(e.length&&(e+="&"),e+=encodeURIComponent(s)+"="+encodeURIComponent(t[s]));return e}let pt=!1;try{pt="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){}const ft=pt;function gt(t){const e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||ft))return new XMLHttpRequest}catch(t){}if(!e)try{return new(X[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}function _t(){}const yt=null!=new gt({xdomain:!1}).responseType;class mt extends G{constructor(t,e){super(),st(this,e),this.opts=e,this.method=e.method||"GET",this.uri=t,this.async=!1!==e.async,this.data=void 0!==e.data?e.data:null,this.create()}create(){const t=Z(this.opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this.opts.xd,t.xscheme=!!this.opts.xs;const e=this.xhr=new gt(t);try{e.open(this.method,this.uri,this.async);try{if(this.opts.extraHeaders){e.setDisableHeaderCheck&&e.setDisableHeaderCheck(!0);for(let t in this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(t)&&e.setRequestHeader(t,this.opts.extraHeaders[t])}}catch(t){}if("POST"===this.method)try{e.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{e.setRequestHeader("Accept","*/*")}catch(t){}"withCredentials"in e&&(e.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(e.timeout=this.opts.requestTimeout),e.onreadystatechange=()=>{4===e.readyState&&(200===e.status||1223===e.status?this.onLoad():this.setTimeoutFn((()=>{this.onError("number"==typeof e.status?e.status:0)}),0))},e.send(this.data)}catch(t){return void this.setTimeoutFn((()=>{this.onError(t)}),0)}"undefined"!=typeof document&&(this.index=mt.requestsCount++,mt.requests[this.index]=this)}onError(t){this.emitReserved("error",t,this.xhr),this.cleanup(!0)}cleanup(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.xhr.onreadystatechange=_t,t)try{this.xhr.abort()}catch(t){}"undefined"!=typeof document&&delete mt.requests[this.index],this.xhr=null}}onLoad(){const t=this.xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this.cleanup())}abort(){this.cleanup()}}function wt(){for(let t in mt.requests)mt.requests.hasOwnProperty(t)&&mt.requests[t].abort()}mt.requestsCount=0,mt.requests={},"undefined"!=typeof document&&("function"==typeof attachEvent?attachEvent("onunload",wt):"function"==typeof addEventListener&&addEventListener("onpagehide"in X?"pagehide":"unload",wt,!1));const bt="function"==typeof Promise&&"function"==typeof Promise.resolve?t=>Promise.resolve().then(t):(t,e)=>e(t,0),vt=X.WebSocket||X.MozWebSocket,kt="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),St={websocket:class extends it{constructor(t){super(t),this.supportsBinary=!t.forceBase64}get name(){return"websocket"}doOpen(){if(!this.check())return;const t=this.uri(),e=this.opts.protocols,s=kt?{}:Z(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=kt?new vt(t,e,s):e?new vt(t,e):new vt(t)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType||"arraybuffer",this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:"websocket connection closed",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError("websocket error",t)}write(t){this.writable=!1;for(let e=0;e<t.length;e++){const s=t[e],r=e===t.length-1;H(s,this.supportsBinary,(t=>{try{this.ws.send(t)}catch(t){}r&&bt((()=>{this.writable=!0,this.emitReserved("drain")}),this.setTimeoutFn)}))}}doClose(){void 0!==this.ws&&(this.ws.close(),this.ws=null)}uri(){let t=this.query||{};const e=this.opts.secure?"wss":"ws";let s="";this.opts.port&&("wss"===e&&443!==Number(this.opts.port)||"ws"===e&&80!==Number(this.opts.port))&&(s=":"+this.opts.port),this.opts.timestampRequests&&(t[this.opts.timestampParam]=lt()),this.supportsBinary||(t.b64=1);const r=dt(t);return e+"://"+(-1!==this.opts.hostname.indexOf(":")?"["+this.opts.hostname+"]":this.opts.hostname)+s+this.opts.path+(r.length?"?"+r:"")}check(){return!!vt}},polling:class extends it{constructor(t){if(super(t),this.polling=!1,"undefined"!=typeof location){const e="https:"===location.protocol;let s=location.port;s||(s=e?"443":"80"),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||s!==t.port,this.xs=t.secure!==e}const e=t&&t.forceBase64;this.supportsBinary=yt&&!e}get name(){return"polling"}doOpen(){this.poll()}pause(t){this.readyState="pausing";const e=()=>{this.readyState="paused",t()};if(this.polling||!this.writable){let t=0;this.polling&&(t++,this.once("pollComplete",(function(){--t||e()}))),this.writable||(t++,this.once("drain",(function(){--t||e()})))}else e()}poll(){this.polling=!0,this.doPoll(),this.emitReserved("poll")}onData(t){((t,e)=>{const s=t.split(Q),r=[];for(let t=0;t<s.length;t++){const i=Y(s[t],e);if(r.push(i),"error"===i.type)break}return r})(t,this.socket.binaryType).forEach((t=>{if("opening"===this.readyState&&"open"===t.type&&this.onOpen(),"close"===t.type)return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(t)})),"closed"!==this.readyState&&(this.polling=!1,this.emitReserved("pollComplete"),"open"===this.readyState&&this.poll())}doClose(){const t=()=>{this.write([{type:"close"}])};"open"===this.readyState?t():this.once("open",t)}write(t){this.writable=!1,((t,e)=>{const s=t.length,r=new Array(s);let i=0;t.forEach(((t,n)=>{H(t,!1,(t=>{r[n]=t,++i===s&&e(r.join(Q))}))}))})(t,(t=>{this.doWrite(t,(()=>{this.writable=!0,this.emitReserved("drain")}))}))}uri(){let t=this.query||{};const e=this.opts.secure?"https":"http";let s="";!1!==this.opts.timestampRequests&&(t[this.opts.timestampParam]=lt()),this.supportsBinary||t.sid||(t.b64=1),this.opts.port&&("https"===e&&443!==Number(this.opts.port)||"http"===e&&80!==Number(this.opts.port))&&(s=":"+this.opts.port);const r=dt(t);return e+"://"+(-1!==this.opts.hostname.indexOf(":")?"["+this.opts.hostname+"]":this.opts.hostname)+s+this.opts.path+(r.length?"?"+r:"")}request(t={}){return Object.assign(t,{xd:this.xd,xs:this.xs},this.opts),new mt(this.uri(),t)}doWrite(t,e){const s=this.request({method:"POST",data:t});s.on("success",e),s.on("error",((t,e)=>{this.onError("xhr post error",t,e)}))}doPoll(){const t=this.request();t.on("data",this.onData.bind(this)),t.on("error",((t,e)=>{this.onError("xhr poll error",t,e)})),this.pollXhr=t}}},Et=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Tt=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function Rt(t){const e=t,s=t.indexOf("["),r=t.indexOf("]");-1!=s&&-1!=r&&(t=t.substring(0,s)+t.substring(s,r).replace(/:/g,";")+t.substring(r,t.length));let i=Et.exec(t||""),n={},o=14;for(;o--;)n[Tt[o]]=i[o]||"";return-1!=s&&-1!=r&&(n.source=e,n.host=n.host.substring(1,n.host.length-1).replace(/;/g,":"),n.authority=n.authority.replace("[","").replace("]","").replace(/;/g,":"),n.ipv6uri=!0),n.pathNames=function(t,e){const s=e.replace(/\/{2,9}/g,"/").split("/");return"/"!=e.slice(0,1)&&0!==e.length||s.splice(0,1),"/"==e.slice(-1)&&s.splice(s.length-1,1),s}(0,n.path),n.queryKey=function(t,e){const s={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,e,r){e&&(s[e]=r)})),s}(0,n.query),n}class At extends G{constructor(t,e={}){super(),t&&"object"==typeof t&&(e=t,t=null),t?(t=Rt(t),e.hostname=t.host,e.secure="https"===t.protocol||"wss"===t.protocol,e.port=t.port,t.query&&(e.query=t.query)):e.host&&(e.hostname=Rt(e.host).host),st(this,e),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?"443":"80"),this.transports=e.transports||["polling","websocket"],this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!0},e),this.opts.path=this.opts.path.replace(/\/$/,"")+"/","string"==typeof this.opts.query&&(this.opts.query=function(t){let e={},s=t.split("&");for(let t=0,r=s.length;t<r;t++){let r=s[t].split("=");e[decodeURIComponent(r[0])]=decodeURIComponent(r[1])}return e}(this.opts.query)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingTimeoutTimer=null,"function"==typeof addEventListener&&(this.opts.closeOnBeforeunload&&(this.beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this.beforeunloadEventListener,!1)),"localhost"!==this.hostname&&(this.offlineEventListener=()=>{this.onClose("transport close",{description:"network connection lost"})},addEventListener("offline",this.offlineEventListener,!1))),this.open()}createTransport(t){const e=Object.assign({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);const s=Object.assign({},this.opts.transportOptions[t],this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port});return new St[t](s)}open(){let t;if(this.opts.rememberUpgrade&&At.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))t="websocket";else{if(0===this.transports.length)return void this.setTimeoutFn((()=>{this.emitReserved("error","No transports available")}),0);t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this.onDrain.bind(this)).on("packet",this.onPacket.bind(this)).on("error",this.onError.bind(this)).on("close",(t=>this.onClose("transport close",t)))}probe(t){let e=this.createTransport(t),s=!1;At.priorWebsocketSuccess=!1;const r=()=>{s||(e.send([{type:"ping",data:"probe"}]),e.once("packet",(t=>{if(!s)if("pong"===t.type&&"probe"===t.data){if(this.upgrading=!0,this.emitReserved("upgrading",e),!e)return;At.priorWebsocketSuccess="websocket"===e.name,this.transport.pause((()=>{s||"closed"!==this.readyState&&(h(),this.setTransport(e),e.send([{type:"upgrade"}]),this.emitReserved("upgrade",e),e=null,this.upgrading=!1,this.flush())}))}else{const t=new Error("probe error");t.transport=e.name,this.emitReserved("upgradeError",t)}})))};function i(){s||(s=!0,h(),e.close(),e=null)}const n=t=>{const s=new Error("probe error: "+t);s.transport=e.name,i(),this.emitReserved("upgradeError",s)};function o(){n("transport closed")}function a(){n("socket closed")}function c(t){e&&t.name!==e.name&&i()}const h=()=>{e.removeListener("open",r),e.removeListener("error",n),e.removeListener("close",o),this.off("close",a),this.off("upgrading",c)};e.once("open",r),e.once("error",n),e.once("close",o),this.once("close",a),this.once("upgrading",c),e.open()}onOpen(){if(this.readyState="open",At.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush(),"open"===this.readyState&&this.opts.upgrade&&this.transport.pause){let t=0;const e=this.upgrades.length;for(;t<e;t++)this.probe(this.upgrades[t])}}onPacket(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(this.emitReserved("packet",t),this.emitReserved("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"ping":this.resetPingTimeout(),this.sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong");break;case"error":const e=new Error("server error");e.code=t.data,this.onError(e);break;case"message":this.emitReserved("data",t.data),this.emitReserved("message",t.data)}}onHandshake(t){this.emitReserved("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this.upgrades=this.filterUpgrades(t.upgrades),this.pingInterval=t.pingInterval,this.pingTimeout=t.pingTimeout,this.maxPayload=t.maxPayload,this.onOpen(),"closed"!==this.readyState&&this.resetPingTimeout()}resetPingTimeout(){this.clearTimeoutFn(this.pingTimeoutTimer),this.pingTimeoutTimer=this.setTimeoutFn((()=>{this.onClose("ping timeout")}),this.pingInterval+this.pingTimeout),this.opts.autoUnref&&this.pingTimeoutTimer.unref()}onDrain(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emitReserved("drain"):this.flush()}flush(){if("closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this.getWritablePackets();this.transport.send(t),this.prevBufferLen=t.length,this.emitReserved("flush")}}getWritablePackets(){if(!(this.maxPayload&&"polling"===this.transport.name&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let s=0;s<this.writeBuffer.length;s++){const r=this.writeBuffer[s].data;if(r&&(t+="string"==typeof(e=r)?function(t){let e=0,s=0;for(let r=0,i=t.length;r<i;r++)e=t.charCodeAt(r),e<128?s+=1:e<2048?s+=2:e<55296||e>=57344?s+=3:(r++,s+=4);return s}(e):Math.ceil(1.33*(e.byteLength||e.size))),s>0&&t>this.maxPayload)return this.writeBuffer.slice(0,s);t+=2}var e;return this.writeBuffer}write(t,e,s){return this.sendPacket("message",t,e,s),this}send(t,e,s){return this.sendPacket("message",t,e,s),this}sendPacket(t,e,s,r){if("function"==typeof e&&(r=e,e=void 0),"function"==typeof s&&(r=s,s=null),"closing"===this.readyState||"closed"===this.readyState)return;(s=s||{}).compress=!1!==s.compress;const i={type:t,data:e,options:s};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),r&&this.once("flush",r),this.flush()}close(){const t=()=>{this.onClose("forced close"),this.transport.close()},e=()=>{this.off("upgrade",e),this.off("upgradeError",e),t()},s=()=>{this.once("upgrade",e),this.once("upgradeError",e)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",(()=>{this.upgrading?s():t()})):this.upgrading?s():t()),this}onError(t){At.priorWebsocketSuccess=!1,this.emitReserved("error",t),this.onClose("transport error",t)}onClose(t,e){"opening"!==this.readyState&&"open"!==this.readyState&&"closing"!==this.readyState||(this.clearTimeoutFn(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),"function"==typeof removeEventListener&&(removeEventListener("beforeunload",this.beforeunloadEventListener,!1),removeEventListener("offline",this.offlineEventListener,!1)),this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this.prevBufferLen=0)}filterUpgrades(t){const e=[];let s=0;const r=t.length;for(;s<r;s++)~this.transports.indexOf(t[s])&&e.push(t[s]);return e}}At.protocol=4,At.protocol;const Ct="function"==typeof ArrayBuffer,xt=Object.prototype.toString,Ot="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===xt.call(Blob),It="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===xt.call(File);function Pt(t){return Ct&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||Ot&&t instanceof Blob||It&&t instanceof File}function Nt(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,s=t.length;e<s;e++)if(Nt(t[e]))return!0;return!1}if(Pt(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return Nt(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&Nt(t[e]))return!0;return!1}function Bt(t){const e=[],s=t.data,r=t;return r.data=jt(s,e),r.attachments=e.length,{packet:r,buffers:e}}function jt(t,e){if(!t)return t;if(Pt(t)){const s={_placeholder:!0,num:e.length};return e.push(t),s}if(Array.isArray(t)){const s=new Array(t.length);for(let r=0;r<t.length;r++)s[r]=jt(t[r],e);return s}if("object"==typeof t&&!(t instanceof Date)){const s={};for(const r in t)Object.prototype.hasOwnProperty.call(t,r)&&(s[r]=jt(t[r],e));return s}return t}function Lt(t,e){return t.data=qt(t.data,e),delete t.attachments,t}function qt(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let s=0;s<t.length;s++)t[s]=qt(t[s],e);else if("object"==typeof t)for(const s in t)Object.prototype.hasOwnProperty.call(t,s)&&(t[s]=qt(t[s],e));return t}const Ut=5;var Mt;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(Mt||(Mt={}));class Dt{constructor(t){this.replacer=t}encode(t){return t.type!==Mt.EVENT&&t.type!==Mt.ACK||!Nt(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===Mt.EVENT?Mt.BINARY_EVENT:Mt.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==Mt.BINARY_EVENT&&t.type!==Mt.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=Bt(t),s=this.encodeAsString(e.packet),r=e.buffers;return r.unshift(s),r}}class zt extends G{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const s=e.type===Mt.BINARY_EVENT;s||e.type===Mt.BINARY_ACK?(e.type=s?Mt.EVENT:Mt.ACK,this.reconstructor=new Ft(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!Pt(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const s={type:Number(t.charAt(0))};if(void 0===Mt[s.type])throw new Error("unknown packet type "+s.type);if(s.type===Mt.BINARY_EVENT||s.type===Mt.BINARY_ACK){const r=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const i=t.substring(r,e);if(i!=Number(i)||"-"!==t.charAt(e))throw new Error("Illegal attachments");s.attachments=Number(i)}if("/"===t.charAt(e+1)){const r=e+1;for(;++e&&","!==t.charAt(e)&&e!==t.length;);s.nsp=t.substring(r,e)}else s.nsp="/";const r=t.charAt(e+1);if(""!==r&&Number(r)==r){const r=e+1;for(;++e;){const s=t.charAt(e);if(null==s||Number(s)!=s){--e;break}if(e===t.length)break}s.id=Number(t.substring(r,e+1))}if(t.charAt(++e)){const r=this.tryParse(t.substr(e));if(!zt.isPayloadValid(s.type,r))throw new Error("invalid payload");s.data=r}return s}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case Mt.CONNECT:return"object"==typeof e;case Mt.DISCONNECT:return void 0===e;case Mt.CONNECT_ERROR:return"string"==typeof e||"object"==typeof e;case Mt.EVENT:case Mt.BINARY_EVENT:return Array.isArray(e)&&e.length>0;case Mt.ACK:case Mt.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ft{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=Lt(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}function Ht(t,e,s){return t.on(e,s),function(){t.off(e,s)}}const $t=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class Kt extends G{constructor(t,e,s){super(),this.connected=!1,this.receiveBuffer=[],this.sendBuffer=[],this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=e,s&&s.auth&&(this.auth=s.auth),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[Ht(t,"open",this.onopen.bind(this)),Ht(t,"packet",this.onpacket.bind(this)),Ht(t,"error",this.onerror.bind(this)),Ht(t,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}open(){return this.connect()}send(...t){return t.unshift("message"),this.emit.apply(this,t),this}emit(t,...e){if($t.hasOwnProperty(t))throw new Error('"'+t.toString()+'" is a reserved event name');e.unshift(t);const s={type:Mt.EVENT,data:e,options:{}};if(s.options.compress=!1!==this.flags.compress,"function"==typeof e[e.length-1]){const t=this.ids++,r=e.pop();this._registerAckCallback(t,r),s.id=t}const r=this.io.engine&&this.io.engine.transport&&this.io.engine.transport.writable;return this.flags.volatile&&(!r||!this.connected)||(this.connected?(this.notifyOutgoingListeners(s),this.packet(s)):this.sendBuffer.push(s)),this.flags={},this}_registerAckCallback(t,e){const s=this.flags.timeout;if(void 0===s)return void(this.acks[t]=e);const r=this.io.setTimeoutFn((()=>{delete this.acks[t];for(let e=0;e<this.sendBuffer.length;e++)this.sendBuffer[e].id===t&&this.sendBuffer.splice(e,1);e.call(this,new Error("operation has timed out"))}),s);this.acks[t]=(...t)=>{this.io.clearTimeoutFn(r),e.apply(this,[null,...t])}}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){"function"==typeof this.auth?this.auth((t=>{this.packet({type:Mt.CONNECT,data:t})})):this.packet({type:Mt.CONNECT,data:this.auth})}onerror(t){this.connected||this.emitReserved("connect_error",t)}onclose(t,e){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,e)}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case Mt.CONNECT:if(t.data&&t.data.sid){const e=t.data.sid;this.onconnect(e)}else this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case Mt.EVENT:case Mt.BINARY_EVENT:this.onevent(t);break;case Mt.ACK:case Mt.BINARY_ACK:this.onack(t);break;case Mt.DISCONNECT:this.ondisconnect();break;case Mt.CONNECT_ERROR:this.destroy();const e=new Error(t.data.message);e.data=t.data.data,this.emitReserved("connect_error",e)}}onevent(t){const e=t.data||[];null!=t.id&&e.push(this.ack(t.id)),this.connected?this.emitEvent(e):this.receiveBuffer.push(Object.freeze(e))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const e=this._anyListeners.slice();for(const s of e)s.apply(this,t)}super.emit.apply(this,t)}ack(t){const e=this;let s=!1;return function(...r){s||(s=!0,e.packet({type:Mt.ACK,id:t,data:r}))}}onack(t){const e=this.acks[t.id];"function"==typeof e&&(e.apply(this,t.data),delete this.acks[t.id])}onconnect(t){this.id=t,this.connected=!0,this.emitBuffered(),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach((t=>this.emitEvent(t))),this.receiveBuffer=[],this.sendBuffer.forEach((t=>{this.notifyOutgoingListeners(t),this.packet(t)})),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach((t=>t())),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:Mt.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const e=this._anyListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const e=this._anyOutgoingListeners;for(let s=0;s<e.length;s++)if(t===e[s])return e.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const e=this._anyOutgoingListeners.slice();for(const s of e)s.apply(this,t.data)}}}function Jt(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}Jt.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),s=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-s:t+s}return 0|Math.min(t,this.max)},Jt.prototype.reset=function(){this.attempts=0},Jt.prototype.setMin=function(t){this.ms=t},Jt.prototype.setMax=function(t){this.max=t},Jt.prototype.setJitter=function(t){this.jitter=t};class Wt extends G{constructor(e,s){var r;super(),this.nsps={},this.subs=[],e&&"object"==typeof e&&(s=e,e=void 0),(s=s||{}).path=s.path||"/socket.io",this.opts=s,st(this,s),this.reconnection(!1!==s.reconnection),this.reconnectionAttempts(s.reconnectionAttempts||1/0),this.reconnectionDelay(s.reconnectionDelay||1e3),this.reconnectionDelayMax(s.reconnectionDelayMax||5e3),this.randomizationFactor(null!==(r=s.randomizationFactor)&&void 0!==r?r:.5),this.backoff=new Jt({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==s.timeout?2e4:s.timeout),this._readyState="closed",this.uri=e;const i=s.parser||t;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=!1!==s.autoConnect,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,this):this._reconnection}reconnectionAttempts(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}randomizationFactor(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}reconnectionDelayMax(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}open(t){if(~this._readyState.indexOf("open"))return this;this.engine=new At(this.uri,this.opts);const e=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const r=Ht(e,"open",(function(){s.onopen(),t&&t()})),i=Ht(e,"error",(e=>{s.cleanup(),s._readyState="closed",this.emitReserved("error",e),t?t(e):s.maybeReconnectOnOpen()}));if(!1!==this._timeout){const t=this._timeout;0===t&&r();const s=this.setTimeoutFn((()=>{r(),e.close(),e.emit("error",new Error("timeout"))}),t);this.opts.autoUnref&&s.unref(),this.subs.push((function(){clearTimeout(s)}))}return this.subs.push(r),this.subs.push(i),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const t=this.engine;this.subs.push(Ht(t,"ping",this.onping.bind(this)),Ht(t,"data",this.ondata.bind(this)),Ht(t,"error",this.onerror.bind(this)),Ht(t,"close",this.onclose.bind(this)),Ht(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}}ondecoded(t){bt((()=>{this.emitReserved("packet",t)}),this.setTimeoutFn)}onerror(t){this.emitReserved("error",t)}socket(t,e){let s=this.nsps[t];return s||(s=new Kt(this,t,e),this.nsps[t]=s),s}_destroy(t){const e=Object.keys(this.nsps);for(const t of e)if(this.nsps[t].active)return;this._close()}_packet(t){const e=this.encoder.encode(t);for(let s=0;s<e.length;s++)this.engine.write(e[s],t.options)}cleanup(){this.subs.forEach((t=>t())),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close"),this.engine&&this.engine.close()}disconnect(){return this._close()}onclose(t,e){this.cleanup(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",t,e),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const e=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn((()=>{t.skipReconnect||(this.emitReserved("reconnect_attempt",t.backoff.attempts),t.skipReconnect||t.open((e=>{e?(t._reconnecting=!1,t.reconnect(),this.emitReserved("reconnect_error",e)):t.onreconnect()})))}),e);this.opts.autoUnref&&s.unref(),this.subs.push((function(){clearTimeout(s)}))}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}const Vt={};function Yt(t,e){"object"==typeof t&&(e=t,t=void 0);const s=function(t,e="",s){let r=t;s=s||"undefined"!=typeof location&&location,null==t&&(t=s.protocol+"//"+s.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?s.protocol+t:s.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==s?s.protocol+"//"+t:"https://"+t),r=Rt(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";const i=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+i+":"+r.port+e,r.href=r.protocol+"://"+i+(s&&s.port===r.port?"":":"+r.port),r}(t,(e=e||{}).path||"/socket.io"),r=s.source,i=s.id,n=s.path,o=Vt[i]&&n in Vt[i].nsps;let a;return e.forceNew||e["force new connection"]||!1===e.multiplex||o?a=new Wt(r,e):(Vt[i]||(Vt[i]=new Wt(r,e)),a=Vt[i]),s.query&&!e.query&&(e.query=s.queryKey),a.socket(s.path,e)}Object.assign(Yt,{Manager:Wt,Socket:Kt,io:Yt,connect:Yt});const Qt=s(370);class Gt{constructor(t,e){this._config=e,this._socket=t,this._callbacks=[],this._fields=e.fields?[...e.fields]:null}async establishConnection(){if(!this._socket||!this._config.userId||!this._config.gameId)throw new Error("Missing arguments in establishConnection");return new Promise((t=>{let e;e=this._fields?{userId:this._config.userId,gameId:this._config.gameId,fields:this._fields}:`${this._config.userId}:${this._config.gameId}`,this._socket.timeout(5e3).emit("listen",e,((e,s)=>e?t({status:"failed",reason:"Listen request timed out."}):"success"===s.status?t({status:"success"}):t({status:"failed",reason:s.reason})))}))}setupEventListener(){return this._socket.on("update",this.emit.bind(this,"update")),this}async subscribe(t){if(!Array.isArray(t)||0===t.length)throw new Error("fields must be a non-empty array");if(this._fields)for(const e of t)this._fields.includes(e)||this._fields.push(e);else this._fields=[...t];return this._updateSubscription()}async unsubscribe(t){if(!Array.isArray(t)||0===t.length)throw new Error("fields must be a non-empty array");if(!this._fields)throw new Error("Cannot unsubscribe when receiving all fields. Use subscribe() first to set explicit field list.");return this._fields=this._fields.filter((e=>!t.includes(e))),this._updateSubscription()}getFields(){return this._fields?[...this._fields]:null}async _updateSubscription(){return new Promise((t=>{const e={userId:this._config.userId,gameId:this._config.gameId,fields:this._fields};this._socket.timeout(5e3).emit("listen-update",e,((e,s)=>t(e?{status:"failed",reason:"Update request timed out."}:s)))}))}}Qt(Gt.prototype);const Xt={msfs:!0};window&&(window.GameGlue=class extends j{constructor(t){super(t),this._socket=!1}async auth(){return await this.authenticate(),await this.isAuthenticated()&&await this.initialize(),this.getUserId()}async initialize(){return new Promise((t=>{const e=this.getAccessToken();this._socket=Yt("https://socks.gameglue.gg",{transports:["websocket"],auth:{token:e}}),this._socket.on("connect",(()=>{t()})),this.onTokenRefreshed(this.updateSocketAuth)}))}updateSocketAuth(t){this._socket.auth.token=t}async createListener(t){if(!t)throw new Error("Not a valid listener config");if(!t.gameId||!Xt[t.gameId])throw new Error("Not a valid Game ID");if(!t.userId)throw new Error("User ID not supplied");if(t.fields&&!Array.isArray(t.fields))throw new Error("fields must be an array");const e=new Gt(this._socket,t),s=await e.establishConnection();if(this._socket.io.on("reconnect_attempt",(t=>{console.log("Refresh Attempt"),this.updateSocketAuth(this.getAccessToken())})),this._socket.io.on("reconnect",(()=>{e.establishConnection()})),"success"!==s.status)throw new Error(`There was a problem setting up the listener. Reason: ${s.reason}`);return e.setupEventListener()}})})()})();
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gameglue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Javascript SDK for the GameGlue developer platform.",
|
|
5
|
+
"main": "dist/gg.sdk.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "webpack ",
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/GameGlue/GameGlueJS.git"
|
|
13
|
+
},
|
|
14
|
+
"author": "GameGlue",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://gameglue.gg",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url":"https://github.com/GameGlue/GameGlueJS/issues"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"event-emitter": "^0.3.5",
|
|
22
|
+
"jwt-decode": "^3.1.2",
|
|
23
|
+
"oidc-client-ts": "^2.2.1",
|
|
24
|
+
"socket.io-client": "^4.5.4"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"webpack": "^5.75.0",
|
|
28
|
+
"webpack-cli": "^5.0.1"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/auth.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { OidcClient } from 'oidc-client-ts';
|
|
2
|
+
import { storage } from './utils';
|
|
3
|
+
import jwt_decode from 'jwt-decode';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class GameGlueAuth {
|
|
7
|
+
constructor(cfg) {
|
|
8
|
+
this._oidcSettings = {
|
|
9
|
+
authority: "https://auth.gameglue.gg/realms/GameGlue",
|
|
10
|
+
client_id: cfg.clientId,
|
|
11
|
+
redirect_uri: removeTrailingSlashes(cfg.redirect_uri || window.location.href),
|
|
12
|
+
post_logout_redirect_uri: removeTrailingSlashes(window.location.href),
|
|
13
|
+
response_type: "code",
|
|
14
|
+
scope: `openid ${(cfg.scopes||[]).join(' ')}`,
|
|
15
|
+
response_mode: "fragment",
|
|
16
|
+
filterProtocolClaims: true
|
|
17
|
+
};
|
|
18
|
+
this._oidcClient = new OidcClient(this._oidcSettings);
|
|
19
|
+
this._refreshCallback = () => {}
|
|
20
|
+
this._refreshTimeout = null;
|
|
21
|
+
}
|
|
22
|
+
setTokenRefreshTimeout(token) {
|
|
23
|
+
if (!token) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
clearTimeout(this._refreshTimeout);
|
|
27
|
+
const timeUntilExp = (jwt_decode(token).exp * 1000) - Date.now() - 5000;
|
|
28
|
+
if (timeUntilExp > 0) {
|
|
29
|
+
this._refreshTimeout = setTimeout(() => {
|
|
30
|
+
this.attemptRefresh();
|
|
31
|
+
}, timeUntilExp);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
setAccessToken(token) {
|
|
35
|
+
this.setTokenRefreshTimeout(token);
|
|
36
|
+
return storage.set('gg-auth-token', token);
|
|
37
|
+
}
|
|
38
|
+
getAccessToken() {
|
|
39
|
+
let token = storage.get('gg-auth-token');
|
|
40
|
+
this.setTokenRefreshTimeout(token);
|
|
41
|
+
return token;
|
|
42
|
+
}
|
|
43
|
+
getUserId() {
|
|
44
|
+
const decoded = jwt_decode(this.getAccessToken());
|
|
45
|
+
return decoded.sub;
|
|
46
|
+
}
|
|
47
|
+
setRefreshToken(token) {
|
|
48
|
+
return storage.set('gg-refresh-token', token);
|
|
49
|
+
}
|
|
50
|
+
getRefreshToken(token) {
|
|
51
|
+
return storage.get('gg-refresh-token');
|
|
52
|
+
}
|
|
53
|
+
_shouldHandleRedirectResponse() {
|
|
54
|
+
return (location.hash.includes("state=") && (location.hash.includes("code=") || location.hash.includes("error=")));
|
|
55
|
+
}
|
|
56
|
+
async handleRedirectResponse() {
|
|
57
|
+
let response = await this._oidcClient.processSigninResponse(window.location.href);
|
|
58
|
+
if (response.error || !response.access_token) {
|
|
59
|
+
console.error(response.error);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
window.history.pushState("", document.title, window.location.pathname + window.location.search);
|
|
63
|
+
this.setAccessToken(response.access_token);
|
|
64
|
+
this.setRefreshToken(response.refresh_token);
|
|
65
|
+
}
|
|
66
|
+
onTokenRefreshed(callback) {
|
|
67
|
+
this._refreshCallback = callback;
|
|
68
|
+
}
|
|
69
|
+
async isAuthenticated(refreshAttempted) {
|
|
70
|
+
// 1. Get the access token
|
|
71
|
+
let access_token = this.getAccessToken();
|
|
72
|
+
|
|
73
|
+
// 2. If we don't have an access token, we're not authenticated
|
|
74
|
+
if (!access_token) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
// 3. Decode the token, then check to see if it has expired
|
|
78
|
+
const decoded = jwt_decode(access_token);
|
|
79
|
+
const expirationDate = new Date(decoded.exp*1000);
|
|
80
|
+
const isExpired = (expirationDate < new Date());
|
|
81
|
+
|
|
82
|
+
if (isExpired && !refreshAttempted) {
|
|
83
|
+
await this.attemptRefresh();
|
|
84
|
+
return this.isAuthenticated(true);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// This line might be a little confusing. Basically it's just saying if we tried to refresh the token,
|
|
88
|
+
// but it's STILL expired, return false, otherwise return true.
|
|
89
|
+
return !(isExpired && refreshAttempted);
|
|
90
|
+
}
|
|
91
|
+
isTokenExpired(token) {
|
|
92
|
+
const decoded = jwt_decode(token);
|
|
93
|
+
const expirationDate = new Date(decoded.exp*1000);
|
|
94
|
+
return (expirationDate < new Date());
|
|
95
|
+
}
|
|
96
|
+
async attemptRefresh() {
|
|
97
|
+
const url = `${this._oidcSettings.authority}/protocol/openid-connect/token`;
|
|
98
|
+
const client_id = this._oidcSettings.client_id;
|
|
99
|
+
const refresh_token = this.getRefreshToken();
|
|
100
|
+
const grant_type = 'refresh_token';
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const response = await fetch(url, {
|
|
104
|
+
method: 'POST',
|
|
105
|
+
headers:{
|
|
106
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
107
|
+
},
|
|
108
|
+
body: new URLSearchParams({
|
|
109
|
+
client_id,
|
|
110
|
+
grant_type,
|
|
111
|
+
refresh_token
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
if (response.status === 200) {
|
|
115
|
+
const resObj = await response.json();
|
|
116
|
+
this.setAccessToken(resObj.access_token);
|
|
117
|
+
this.setRefreshToken(resObj.refresh_token);
|
|
118
|
+
this._refreshCallback(resObj);
|
|
119
|
+
}
|
|
120
|
+
} catch(e) {
|
|
121
|
+
console.log('Error: ', e);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
_triggerAuthRedirect() {
|
|
125
|
+
this._oidcClient.createSigninRequest({ state: { bar: 15 } }).then(function(req) {
|
|
126
|
+
window.location = req.url;
|
|
127
|
+
}).catch(function(err) {
|
|
128
|
+
console.error(err);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
async authenticate() {
|
|
132
|
+
if (this._shouldHandleRedirectResponse()) {
|
|
133
|
+
await this.handleRedirectResponse();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let isAuthenticated = await this.isAuthenticated();
|
|
137
|
+
if (!isAuthenticated) {
|
|
138
|
+
await this._triggerAuthRedirect();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function removeTrailingSlashes(url) {
|
|
144
|
+
if (url.endsWith('/')) {
|
|
145
|
+
return url.replace(/\/+$/, '');
|
|
146
|
+
}
|
|
147
|
+
return url;
|
|
148
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GameGlueAuth } from './auth';
|
|
2
|
+
import { io } from "socket.io-client";
|
|
3
|
+
import { Listener} from "./listener";
|
|
4
|
+
|
|
5
|
+
const GAME_IDS = {
|
|
6
|
+
'msfs': true,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
class GameGlue extends GameGlueAuth {
|
|
10
|
+
constructor(cfg) {
|
|
11
|
+
super(cfg);
|
|
12
|
+
this._socket = false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async auth() {
|
|
16
|
+
await this.authenticate();
|
|
17
|
+
if (await this.isAuthenticated()) {
|
|
18
|
+
await this.initialize();
|
|
19
|
+
}
|
|
20
|
+
return this.getUserId();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async initialize() {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
const token = this.getAccessToken();
|
|
26
|
+
this._socket = io('https://socks.gameglue.gg', {
|
|
27
|
+
transports: ['websocket'],
|
|
28
|
+
auth: {
|
|
29
|
+
token
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
// TODO: Update this code to use the new refresh logic. Example in gg-client repo
|
|
33
|
+
this._socket.on('connect', () => {
|
|
34
|
+
resolve();
|
|
35
|
+
});
|
|
36
|
+
this.onTokenRefreshed(this.updateSocketAuth);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
updateSocketAuth(authToken) {
|
|
41
|
+
this._socket.auth.token = authToken;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async createListener(config) {
|
|
45
|
+
if (!config) throw new Error('Not a valid listener config');
|
|
46
|
+
if (!config.gameId || !GAME_IDS[config.gameId]) throw new Error('Not a valid Game ID');
|
|
47
|
+
if (!config.userId) throw new Error('User ID not supplied');
|
|
48
|
+
if (config.fields && !Array.isArray(config.fields)) throw new Error('fields must be an array');
|
|
49
|
+
|
|
50
|
+
const listener = new Listener(this._socket, config);
|
|
51
|
+
const establishConnectionResponse = await listener.establishConnection();
|
|
52
|
+
this._socket.io.on('reconnect_attempt', (d) => {
|
|
53
|
+
console.log('Refresh Attempt');
|
|
54
|
+
this.updateSocketAuth(this.getAccessToken());
|
|
55
|
+
});
|
|
56
|
+
this._socket.io.on('reconnect', () => {
|
|
57
|
+
listener.establishConnection();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (establishConnectionResponse.status !== 'success') {
|
|
61
|
+
throw new Error(`There was a problem setting up the listener. Reason: ${establishConnectionResponse.reason}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return listener.setupEventListener();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (window) {
|
|
69
|
+
window.GameGlue = GameGlue;
|
|
70
|
+
}
|
package/src/listener.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const EventEmitter = require('event-emitter');
|
|
2
|
+
|
|
3
|
+
export class Listener {
|
|
4
|
+
constructor(socket, config) {
|
|
5
|
+
this._config = config;
|
|
6
|
+
this._socket = socket;
|
|
7
|
+
this._callbacks = [];
|
|
8
|
+
this._fields = config.fields ? [...config.fields] : null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async establishConnection() {
|
|
12
|
+
if (!this._socket || !this._config.userId || !this._config.gameId) {
|
|
13
|
+
throw new Error('Missing arguments in establishConnection');
|
|
14
|
+
}
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
// Use object format if fields are specified, otherwise use legacy string format
|
|
17
|
+
let listenPayload;
|
|
18
|
+
if (this._fields) {
|
|
19
|
+
listenPayload = {
|
|
20
|
+
userId: this._config.userId,
|
|
21
|
+
gameId: this._config.gameId,
|
|
22
|
+
fields: this._fields
|
|
23
|
+
};
|
|
24
|
+
} else {
|
|
25
|
+
listenPayload = `${this._config.userId}:${this._config.gameId}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this._socket.timeout(5000).emit('listen', listenPayload, (error, response) => {
|
|
29
|
+
if (error) {
|
|
30
|
+
return resolve({status: 'failed', reason: 'Listen request timed out.'});
|
|
31
|
+
}
|
|
32
|
+
if (response.status === 'success') {
|
|
33
|
+
return resolve({status: 'success'});
|
|
34
|
+
} else {
|
|
35
|
+
return resolve({status: 'failed', reason: response.reason});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setupEventListener() {
|
|
42
|
+
this._socket.on('update', this.emit.bind(this, 'update'));
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to additional fields dynamically
|
|
48
|
+
* @param {string[]} fields - Array of field names to add
|
|
49
|
+
* @returns {Promise<{status: string, reason?: string}>}
|
|
50
|
+
*/
|
|
51
|
+
async subscribe(fields) {
|
|
52
|
+
if (!Array.isArray(fields) || fields.length === 0) {
|
|
53
|
+
throw new Error('fields must be a non-empty array');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Add new fields to existing list
|
|
57
|
+
if (!this._fields) {
|
|
58
|
+
this._fields = [...fields];
|
|
59
|
+
} else {
|
|
60
|
+
for (const field of fields) {
|
|
61
|
+
if (!this._fields.includes(field)) {
|
|
62
|
+
this._fields.push(field);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this._updateSubscription();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Unsubscribe from specific fields
|
|
72
|
+
* @param {string[]} fields - Array of field names to remove
|
|
73
|
+
* @returns {Promise<{status: string, reason?: string}>}
|
|
74
|
+
*/
|
|
75
|
+
async unsubscribe(fields) {
|
|
76
|
+
if (!Array.isArray(fields) || fields.length === 0) {
|
|
77
|
+
throw new Error('fields must be a non-empty array');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!this._fields) {
|
|
81
|
+
// Currently receiving all fields, create explicit list without these fields
|
|
82
|
+
throw new Error('Cannot unsubscribe when receiving all fields. Use subscribe() first to set explicit field list.');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this._fields = this._fields.filter(f => !fields.includes(f));
|
|
86
|
+
|
|
87
|
+
return this._updateSubscription();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get the current list of subscribed fields
|
|
92
|
+
* @returns {string[]|null} - Array of field names, or null if receiving all fields
|
|
93
|
+
*/
|
|
94
|
+
getFields() {
|
|
95
|
+
return this._fields ? [...this._fields] : null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Internal method to send subscription update to server
|
|
100
|
+
*/
|
|
101
|
+
async _updateSubscription() {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
const payload = {
|
|
104
|
+
userId: this._config.userId,
|
|
105
|
+
gameId: this._config.gameId,
|
|
106
|
+
fields: this._fields
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
this._socket.timeout(5000).emit('listen-update', payload, (error, response) => {
|
|
110
|
+
if (error) {
|
|
111
|
+
return resolve({status: 'failed', reason: 'Update request timed out.'});
|
|
112
|
+
}
|
|
113
|
+
return resolve(response);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
EventEmitter(Listener.prototype);
|
package/src/user.js
ADDED
package/src/utils.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const storageMap = {};
|
|
2
|
+
export const storage = {
|
|
3
|
+
set: (key, value) => {
|
|
4
|
+
return isBrowser() ? localStorage.setItem(key, value) : (storageMap[key] = value);
|
|
5
|
+
},
|
|
6
|
+
get: (key) => {
|
|
7
|
+
return isBrowser() ? localStorage.getItem(key) : storageMap[key];
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export const isBrowser = () => {
|
|
11
|
+
return !(typeof process === 'object' && String(process) === '[object process]');
|
|
12
|
+
}
|