gameglue 1.0.0 → 1.1.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # GameGlueJS (Early Access)
2
+
2
3
  ## 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
+ GameGlue is a powerful platform that makes it trivial to build addons to your favorite games with nothing more than a little javascript. The SDK supports **bidirectional data flow** - receive telemetry from games and send commands back to control the simulation.
4
5
 
5
- Below is an example showing that with just ~10 lines of code.
6
6
  ## Early Access
7
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
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
@@ -35,7 +35,7 @@ yarn add gamegluejs
35
35
  const ggClient = new GameGlue({
36
36
  clientId: '<your-application-id>',
37
37
  redirect_uri: '<your-application-url>',
38
- scopes: ['<your-required-scopes>']
38
+ scopes: ['msfs:read', 'msfs:write'] // Include 'write' scope to send commands
39
39
  });
40
40
  ```
41
41
 
@@ -48,18 +48,88 @@ const userId = ggClient.getUserId();
48
48
  ### Create a listener
49
49
 
50
50
  ```javascript
51
- const userListener = await ggClient.createListener({
51
+ const listener = await ggClient.createListener({
52
52
  userId: userId,
53
- gameId: '<your-game-id>'
53
+ gameId: 'msfs'
54
54
  });
55
55
  ```
56
- ### Use the listener
56
+
57
+ You can optionally subscribe to specific fields only:
58
+ ```javascript
59
+ const listener = await ggClient.createListener({
60
+ userId: userId,
61
+ gameId: 'msfs',
62
+ fields: ['indicated_altitude', 'airspeed_indicated', 'heading_indicator']
63
+ });
64
+ ```
65
+
66
+ ### Receive telemetry updates
57
67
  ```javascript
58
- userListener.on('update', (evt) => {
59
- document.body.innerHTML = evt.data.ground_speed;
68
+ listener.on('update', (evt) => {
69
+ console.log('Altitude:', evt.data.indicated_altitude);
70
+ console.log('Airspeed:', evt.data.airspeed_indicated);
60
71
  });
61
72
  ```
62
73
 
63
- That's it!!
74
+ ### Send commands to the simulator
75
+ ```javascript
76
+ // Turn autopilot on
77
+ await listener.sendCommand('AUTOPILOT_ON', true);
78
+
79
+ // Toggle flight director
80
+ await listener.sendCommand('TOGGLE_FLIGHT_DIRECTOR', true);
81
+
82
+ // Set heading hold
83
+ await listener.sendCommand('AP_HDG_HOLD_ON', true);
84
+ ```
85
+
86
+ The `sendCommand` method returns a promise with the result:
87
+ ```javascript
88
+ const result = await listener.sendCommand('AUTOPILOT_ON', true);
89
+ if (result.status === 'success') {
90
+ console.log('Command sent!');
91
+ } else {
92
+ console.error('Command failed:', result.reason);
93
+ }
94
+ ```
95
+
96
+ ### Dynamic field subscription
97
+ You can add or remove fields from your subscription at any time:
98
+
99
+ ```javascript
100
+ // Subscribe to additional fields
101
+ await listener.subscribe(['vertical_speed', 'autopilot_master']);
102
+
103
+ // Unsubscribe from fields you no longer need
104
+ await listener.unsubscribe(['heading_indicator']);
105
+
106
+ // Get current list of subscribed fields
107
+ const fields = listener.getFields(); // Returns array or null (all fields)
108
+ ```
109
+
110
+ ## API Reference
111
+
112
+ ### GameGlue
113
+
114
+ | Method | Description |
115
+ |--------|-------------|
116
+ | `auth()` | Authenticates the user and returns their user ID |
117
+ | `getUserId()` | Returns the authenticated user's ID |
118
+ | `isAuthenticated()` | Returns true if user is authenticated |
119
+ | `createListener(config)` | Creates a listener for game telemetry |
120
+
121
+ ### Listener
122
+
123
+ | Method | Description |
124
+ |--------|-------------|
125
+ | `on('update', callback)` | Subscribe to telemetry updates |
126
+ | `sendCommand(field, value)` | Send a command to the game/simulator |
127
+ | `subscribe(fields)` | Add fields to your subscription |
128
+ | `unsubscribe(fields)` | Remove fields from your subscription |
129
+ | `getFields()` | Get current subscribed fields (null = all) |
130
+
131
+ ## Examples
132
+
133
+ See the `examples/` directory for a complete flight dashboard example demonstrating bidirectional data flow
64
134
 
65
135
 
package/dist/gg.sdk.js CHANGED
@@ -1 +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()}})})()})();
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 sendCommand(t,e){if(!t||"string"!=typeof t)throw new Error("field must be a non-empty string");return new Promise((s=>{const r={userId:this._config.userId,gameId:this._config.gameId,data:{fieldName:t,value:e}};this._socket.timeout(5e3).emit("set",r,((t,e)=>s(t?{status:"failed",reason:"Command request timed out."}:e)))}))}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");this._socket||await this.initialize();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()}})})()})();
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDCTCCAfGgAwIBAgIUZXGMIC2Uuk1I1QG+eG/1s9uZJ34wDQYJKoZIhvcNAQEL
3
+ BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDEwODE5NDkyMFoXDTI3MDEw
4
+ ODE5NDkyMFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
5
+ AAOCAQ8AMIIBCgKCAQEAkCPhr3I3q1CryuS4BVIOCK5AQGFXYt5oulnjxZo/75NE
6
+ VevxNrk7UjbVFlYR6AlkaP+XhaJxQ72uAfwX7MGokll9b0wpGy0sNW/jKLuCf77N
7
+ 7z44+4USccqBkCGusmgD2HieETKGCBqFp03I0KI3rHAHz8DDwj4T46L/Ct8NTerf
8
+ C57cmV88MxhdYb9ercW1Cn4IwNt77v45SDzydWymnT4faCG8yYEZLXKMUOL7LYcp
9
+ arGZ1NBuoHzzsyaa4hYbQkMwYElu73vfL+bUXga/mk+wi3/+aliy1HpartIcG/IJ
10
+ vLaFvopRNEK2dxU7AdCq/6SlFm7QqL8fVGLxTJepWwIDAQABo1MwUTAdBgNVHQ4E
11
+ FgQU2/15GMPIvKd58vd4ufKEO3u114UwHwYDVR0jBBgwFoAU2/15GMPIvKd58vd4
12
+ ufKEO3u114UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZ6TF
13
+ Wxam0vDi3Pp0pgas/Q6MhO+8KBJSXLzCNxI2C7GrsTX+mupbeTyT1K0mmL2dISTG
14
+ OWsJX3mRUZL13pYrtfL8JPkEVgoBFpGll4f+fXvJ1zq2olCo2vX33WanRiPNm+cI
15
+ l9ibEN8srVwcbh7l6mLFiQdeSy3WzI26d5bIfhj5CD5yZM6K6hkTdmAzFAzBwl40
16
+ qpHmyYedcTCSfrcnhDPMBQr885vYhgvGrUnQl6OWqQqG1hIXrIowyQ9J1tWeUrez
17
+ qp9kY9hPOxuXeAiM2aYENbK1GST8lAjDqnKkRSFqcAj98836oa/0zfbLYYYrml/O
18
+ ELTRqgDKTaz5TrFiiQ==
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCQI+GvcjerUKvK
3
+ 5LgFUg4IrkBAYVdi3mi6WePFmj/vk0RV6/E2uTtSNtUWVhHoCWRo/5eFonFDva4B
4
+ /BfswaiSWX1vTCkbLSw1b+Mou4J/vs3vPjj7hRJxyoGQIa6yaAPYeJ4RMoYIGoWn
5
+ TcjQojescAfPwMPCPhPjov8K3w1N6t8LntyZXzwzGF1hv16txbUKfgjA23vu/jlI
6
+ PPJ1bKadPh9oIbzJgRktcoxQ4vsthylqsZnU0G6gfPOzJpriFhtCQzBgSW7ve98v
7
+ 5tReBr+aT7CLf/5qWLLUelqu0hwb8gm8toW+ilE0QrZ3FTsB0Kr/pKUWbtCovx9U
8
+ YvFMl6lbAgMBAAECgf8icHBRUHj8oHRrheUctaj6FKhFZFH8zXyNtJc3dM4nRTM5
9
+ VFEjQh6/sK+OfAIgmXM5oy1mQJR6GwKjIW3rTlojSD6Fg9ej0VHpcqepPnlvtvx9
10
+ V+Ca4rCwKjJ1aEGACa+MM/A7K6yFQyZWqGnSxO+IbpFvPMozyaFMQnsC80hlKofu
11
+ hpIaOXknDRaPPOsVwJ6J8NNyqUY61opnUTlaOQtrBAc5MXjbsNZ+88DgpmOFJ3ED
12
+ 3uQ2E6VECdsmsU+KcRoET2QqsxA5dyl+omuknjayp10PN4n1EsHHEwtUTJR0/oaq
13
+ 0nZDYre1/GhmIJsMKx+KdUIGV72R+1OdKWZ9AeECgYEAx5F625GTgtdgDTu/INK6
14
+ 0Y4LigCV/lSPx1D+nEb+y3o+DqRQE422jb/0vw17ocnMzih9KaTgNRRlf+pfAgkk
15
+ vUuRmAezCgHex10k8oK5t5NJ7KVHbgUNWcUO47qttGIWrCmSJP93uqgVbfFvdjTE
16
+ 1//M/nVMtiZFge7ty9K1kLsCgYEAuOYF/8v3Wk8P5PXmhnGyJIjAfR/jmfYJkFgZ
17
+ h7HKXP0UhPO4bboQLSzM+evqxMwuT2PGneHyOB0b00CN3DrwEs010PGrDg2Uf+y4
18
+ eMK5wEDGuqLrbBdlp89A9k96lWO/iNgjI7PaKriqWFmOCG265EJ3iLTw3MrJkSM9
19
+ SGxRj+ECgYBcYHr+J+SgLBHKDl3qU6EmXxn4R00m7P2gxV0V+cb3aR5QqL5oTrCx
20
+ 7Kjdxt/zg/XJd/R30ln2N/rDuzk/N/xJozFBrk6x0yvMHNF9cAWHdCZD5D2sL6p+
21
+ YzkBMOg3FzBngNalSZuiSyugOKHflY2Ibl/1aVaY+h4yhuaL8n0ZAQKBgQCUFWXo
22
+ oGrSoU+RiH/AXX7XU88WZ1vaCvtN58FKtFHmd6rfcHLdLo+WHrNr1k6Inx7X5olE
23
+ GZns5yNJ5gG3yFxOMpxPY74j2yx76BM2ZH5wQ3DmOWVjhLmd1Jeqraz3yJO1/aTn
24
+ CzxHyu5jJBZlGbz8417o1kGyE5er7hU+08HfAQKBgQC/CEfOYsNYYWAwgzHptEaS
25
+ bpDkdLZ4ffFzfhi14578hE5A+Vs1I8s3NP9d6mq4Cn+SPbVOOaHCi6Df7ItDgnhk
26
+ WkrdYLNi7XsQxGJ1mrL9BEspS7i8n2GsixpEHGp7nDvJQ/MUQfe6sB5y8PoFZbkU
27
+ QWnvYOpyXa326sePIRjRGA==
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,401 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>GameGlue Flight Dashboard Example</title>
7
+ <style>
8
+ * {
9
+ box-sizing: border-box;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+ body {
14
+ font-family: 'Segoe UI', -apple-system, sans-serif;
15
+ background: #0f172a;
16
+ color: #e2e8f0;
17
+ min-height: 100vh;
18
+ padding: 2rem;
19
+ }
20
+ .container {
21
+ max-width: 800px;
22
+ margin: 0 auto;
23
+ }
24
+ h1 {
25
+ font-size: 1.5rem;
26
+ margin-bottom: 0.5rem;
27
+ color: #3cff8f;
28
+ }
29
+ .subtitle {
30
+ color: #64748b;
31
+ margin-bottom: 2rem;
32
+ }
33
+ .status {
34
+ display: inline-block;
35
+ padding: 0.25rem 0.75rem;
36
+ border-radius: 9999px;
37
+ font-size: 0.875rem;
38
+ margin-bottom: 1.5rem;
39
+ }
40
+ .status.disconnected { background: #7f1d1d; color: #fca5a5; }
41
+ .status.connecting { background: #78350f; color: #fcd34d; }
42
+ .status.connected { background: #14532d; color: #86efac; }
43
+
44
+ .card {
45
+ background: #1e293b;
46
+ border-radius: 0.75rem;
47
+ padding: 1.5rem;
48
+ margin-bottom: 1.5rem;
49
+ }
50
+ .card h2 {
51
+ font-size: 1rem;
52
+ color: #94a3b8;
53
+ margin-bottom: 1rem;
54
+ text-transform: uppercase;
55
+ letter-spacing: 0.05em;
56
+ }
57
+ .telemetry-grid {
58
+ display: grid;
59
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
60
+ gap: 1rem;
61
+ }
62
+ .telemetry-item {
63
+ background: #0f172a;
64
+ padding: 1rem;
65
+ border-radius: 0.5rem;
66
+ }
67
+ .telemetry-label {
68
+ font-size: 0.75rem;
69
+ color: #64748b;
70
+ text-transform: uppercase;
71
+ margin-bottom: 0.25rem;
72
+ }
73
+ .telemetry-value {
74
+ font-size: 1.5rem;
75
+ font-weight: 600;
76
+ font-family: 'SF Mono', 'Consolas', monospace;
77
+ }
78
+ .telemetry-unit {
79
+ font-size: 0.875rem;
80
+ color: #64748b;
81
+ margin-left: 0.25rem;
82
+ }
83
+
84
+ .controls-grid {
85
+ display: grid;
86
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
87
+ gap: 1rem;
88
+ }
89
+ .control-btn {
90
+ background: #334155;
91
+ border: none;
92
+ color: #e2e8f0;
93
+ padding: 1rem;
94
+ border-radius: 0.5rem;
95
+ font-size: 0.875rem;
96
+ cursor: pointer;
97
+ transition: all 0.15s;
98
+ display: flex;
99
+ flex-direction: column;
100
+ align-items: center;
101
+ gap: 0.5rem;
102
+ }
103
+ .control-btn:hover {
104
+ background: #475569;
105
+ }
106
+ .control-btn:active {
107
+ transform: scale(0.98);
108
+ }
109
+ .control-btn.active {
110
+ background: #166534;
111
+ color: #86efac;
112
+ }
113
+ .control-btn .icon {
114
+ font-size: 1.5rem;
115
+ }
116
+
117
+ .auth-section {
118
+ text-align: center;
119
+ padding: 3rem;
120
+ }
121
+ .auth-btn {
122
+ background: #3cff8f;
123
+ color: #0f172a;
124
+ border: none;
125
+ padding: 0.75rem 2rem;
126
+ border-radius: 0.5rem;
127
+ font-size: 1rem;
128
+ font-weight: 600;
129
+ cursor: pointer;
130
+ transition: all 0.15s;
131
+ }
132
+ .auth-btn:hover {
133
+ background: #22c55e;
134
+ }
135
+
136
+ .log {
137
+ background: #0f172a;
138
+ border-radius: 0.5rem;
139
+ padding: 1rem;
140
+ font-family: 'SF Mono', 'Consolas', monospace;
141
+ font-size: 0.75rem;
142
+ max-height: 200px;
143
+ overflow-y: auto;
144
+ }
145
+ .log-entry {
146
+ color: #64748b;
147
+ margin-bottom: 0.25rem;
148
+ }
149
+ .log-entry.command {
150
+ color: #fcd34d;
151
+ }
152
+ .log-entry.error {
153
+ color: #f87171;
154
+ }
155
+
156
+ .hidden { display: none; }
157
+ </style>
158
+ </head>
159
+ <body>
160
+ <div class="container">
161
+ <h1>/GameGlue Flight Dashboard</h1>
162
+ <p class="subtitle">Example app demonstrating bidirectional data flow</p>
163
+
164
+ <!-- Auth Section (shown when not authenticated) -->
165
+ <div id="auth-section" class="card auth-section">
166
+ <p style="margin-bottom: 1rem; color: #94a3b8;">Connect to GameGlue to view flight telemetry and send commands</p>
167
+ <button class="auth-btn" onclick="authenticate()">Connect with GameGlue</button>
168
+ </div>
169
+
170
+ <!-- Dashboard (shown when authenticated) -->
171
+ <div id="dashboard" class="hidden">
172
+ <span id="status" class="status disconnected">Waiting for MSFS...</span>
173
+
174
+ <!-- Telemetry Card -->
175
+ <div class="card">
176
+ <h2>Flight Data</h2>
177
+ <div class="telemetry-grid">
178
+ <div class="telemetry-item">
179
+ <div class="telemetry-label">Altitude</div>
180
+ <div>
181
+ <span id="altitude" class="telemetry-value">---</span>
182
+ <span class="telemetry-unit">ft</span>
183
+ </div>
184
+ </div>
185
+ <div class="telemetry-item">
186
+ <div class="telemetry-label">Airspeed</div>
187
+ <div>
188
+ <span id="airspeed" class="telemetry-value">---</span>
189
+ <span class="telemetry-unit">kts</span>
190
+ </div>
191
+ </div>
192
+ <div class="telemetry-item">
193
+ <div class="telemetry-label">Ground Speed</div>
194
+ <div>
195
+ <span id="ground-speed" class="telemetry-value">---</span>
196
+ <span class="telemetry-unit">kts</span>
197
+ </div>
198
+ </div>
199
+ <div class="telemetry-item">
200
+ <div class="telemetry-label">Vertical Speed</div>
201
+ <div>
202
+ <span id="vertical-speed" class="telemetry-value">---</span>
203
+ <span class="telemetry-unit">fpm</span>
204
+ </div>
205
+ </div>
206
+ <div class="telemetry-item">
207
+ <div class="telemetry-label">Heading</div>
208
+ <div>
209
+ <span id="heading" class="telemetry-value">---</span>
210
+ <span class="telemetry-unit">&deg;</span>
211
+ </div>
212
+ </div>
213
+ <div class="telemetry-item">
214
+ <div class="telemetry-label">Autopilot</div>
215
+ <div>
216
+ <span id="autopilot-status" class="telemetry-value">---</span>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+
222
+ <!-- Controls Card -->
223
+ <div class="card">
224
+ <h2>Aircraft Controls</h2>
225
+ <div class="controls-grid">
226
+ <button class="control-btn" onclick="sendCommand('AUTOPILOT_ON', true)">
227
+ <span class="icon">AP</span>
228
+ <span>Autopilot ON</span>
229
+ </button>
230
+ <button class="control-btn" onclick="sendCommand('AUTOPILOT_OFF', true)">
231
+ <span class="icon">AP</span>
232
+ <span>Autopilot OFF</span>
233
+ </button>
234
+ <button class="control-btn" onclick="sendCommand('TOGGLE_FLIGHT_DIRECTOR', true)">
235
+ <span class="icon">FD</span>
236
+ <span>Toggle Flight Director</span>
237
+ </button>
238
+ <button class="control-btn" onclick="sendCommand('AP_HDG_HOLD_ON', true)">
239
+ <span class="icon">HDG</span>
240
+ <span>Heading Hold ON</span>
241
+ </button>
242
+ <button class="control-btn" onclick="sendCommand('AP_ALT_HOLD_ON', true)">
243
+ <span class="icon">ALT</span>
244
+ <span>Altitude Hold ON</span>
245
+ </button>
246
+ <button class="control-btn" onclick="sendCommand('TOGGLE_NAV_LIGHTS', true)">
247
+ <span class="icon">NAV</span>
248
+ <span>Toggle Nav Lights</span>
249
+ </button>
250
+ </div>
251
+ </div>
252
+
253
+ <!-- Log Card -->
254
+ <div class="card">
255
+ <h2>Event Log</h2>
256
+ <div id="log" class="log"></div>
257
+ </div>
258
+ </div>
259
+ </div>
260
+
261
+ <!-- Load GameGlue SDK from local build -->
262
+ <script src="../dist/gg.sdk.js"></script>
263
+ <script>
264
+ // Configuration
265
+ const CLIENT_ID = 'gameglue-sdk-examples';
266
+ const REDIRECT_URI = window.location.href.split('?')[0];
267
+
268
+ let ggClient = null;
269
+ let listener = null;
270
+
271
+ // Initialize GameGlue client
272
+ function initGameGlue() {
273
+ ggClient = new GameGlue({
274
+ clientId: CLIENT_ID,
275
+ redirect_uri: REDIRECT_URI,
276
+ scopes: ['msfs:read', 'msfs:write']
277
+ });
278
+ }
279
+
280
+ // Authenticate with GameGlue
281
+ async function authenticate() {
282
+ try {
283
+ log('Authenticating with GameGlue...');
284
+ const userId = await ggClient.auth();
285
+
286
+ if (userId) {
287
+ log('Authenticated! User ID: ' + userId);
288
+ showDashboard();
289
+ await setupListener(userId);
290
+ }
291
+ } catch (err) {
292
+ log('Authentication failed: ' + err.message, 'error');
293
+ }
294
+ }
295
+
296
+ // Check if already authenticated on page load
297
+ async function checkAuth() {
298
+ if (await ggClient.isAuthenticated()) {
299
+ const userId = ggClient.getUserId();
300
+ log('Already authenticated. User ID: ' + userId);
301
+ showDashboard();
302
+ await setupListener(userId);
303
+ }
304
+ }
305
+
306
+ // Set up telemetry listener
307
+ async function setupListener(userId) {
308
+ try {
309
+ log('Creating listener for MSFS telemetry...');
310
+
311
+ listener = await ggClient.createListener({
312
+ userId: userId,
313
+ gameId: 'msfs'
314
+ });
315
+
316
+ listener.on('update', (evt) => {
317
+ updateTelemetry(evt.data);
318
+ });
319
+
320
+ setStatus('connected', 'Connected to MSFS');
321
+ log('Listener active. Waiting for telemetry...');
322
+ } catch (err) {
323
+ log('Failed to create listener: ' + err.message, 'error');
324
+ setStatus('disconnected', 'Connection failed');
325
+ }
326
+ }
327
+
328
+ // Update telemetry display
329
+ function updateTelemetry(data) {
330
+ if (data.indicated_altitude !== undefined) {
331
+ document.getElementById('altitude').textContent = Math.round(data.indicated_altitude);
332
+ }
333
+ if (data.airspeed_indicated !== undefined) {
334
+ document.getElementById('airspeed').textContent = Math.round(data.airspeed_indicated);
335
+ }
336
+ if (data.ground_velocity !== undefined) {
337
+ document.getElementById('ground-speed').textContent = Math.round(data.ground_velocity);
338
+ }
339
+ if (data.vertical_speed !== undefined) {
340
+ document.getElementById('vertical-speed').textContent = Math.round(data.vertical_speed);
341
+ }
342
+ if (data.heading_indicator !== undefined) {
343
+ document.getElementById('heading').textContent = Math.round(data.heading_indicator);
344
+ }
345
+ if (data.autopilot_master !== undefined) {
346
+ document.getElementById('autopilot-status').textContent = data.autopilot_master ? 'ON' : 'OFF';
347
+ document.getElementById('autopilot-status').style.color = data.autopilot_master ? '#86efac' : '#f87171';
348
+ }
349
+ }
350
+
351
+ // Send command to aircraft
352
+ async function sendCommand(field, value) {
353
+ if (!listener) {
354
+ log('Not connected - cannot send command', 'error');
355
+ return;
356
+ }
357
+
358
+ log(`Sending command: ${field} = ${value}`, 'command');
359
+
360
+ try {
361
+ const result = await listener.sendCommand(field, value);
362
+ if (result.status === 'success') {
363
+ log(`Command sent successfully: ${field}`, 'command');
364
+ } else {
365
+ log(`Command failed: ${result.reason}`, 'error');
366
+ }
367
+ } catch (err) {
368
+ log(`Command error: ${err.message}`, 'error');
369
+ }
370
+ }
371
+
372
+ // UI Helpers
373
+ function showDashboard() {
374
+ document.getElementById('auth-section').classList.add('hidden');
375
+ document.getElementById('dashboard').classList.remove('hidden');
376
+ }
377
+
378
+ function setStatus(state, text) {
379
+ const el = document.getElementById('status');
380
+ el.className = 'status ' + state;
381
+ el.textContent = text;
382
+ }
383
+
384
+ function log(message, type = '') {
385
+ const logEl = document.getElementById('log');
386
+ const entry = document.createElement('div');
387
+ entry.className = 'log-entry ' + type;
388
+ entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
389
+ logEl.appendChild(entry);
390
+ logEl.scrollTop = logEl.scrollHeight;
391
+ console.log(message);
392
+ }
393
+
394
+ // Initialize on page load
395
+ window.onload = () => {
396
+ initGameGlue();
397
+ checkAuth();
398
+ };
399
+ </script>
400
+ </body>
401
+ </html>
@@ -0,0 +1,95 @@
1
+ const https = require('https');
2
+ const http = require('http');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const PORT = process.env.PORT || 3000;
7
+ const USE_HTTPS = process.env.HTTPS === 'true' || fs.existsSync(path.join(__dirname, 'certs', 'key.pem'));
8
+
9
+ const MIME_TYPES = {
10
+ '.html': 'text/html',
11
+ '.js': 'application/javascript',
12
+ '.css': 'text/css',
13
+ '.json': 'application/json',
14
+ '.png': 'image/png',
15
+ '.jpg': 'image/jpeg',
16
+ '.svg': 'image/svg+xml',
17
+ '.ico': 'image/x-icon',
18
+ };
19
+
20
+ function handleRequest(req, res) {
21
+ let filePath = req.url === '/' ? '/flight-dashboard.html' : req.url;
22
+
23
+ // Remove query string
24
+ filePath = filePath.split('?')[0];
25
+
26
+ // Security: prevent directory traversal
27
+ filePath = path.normalize(filePath).replace(/^(\.\.[\/\\])+/, '');
28
+
29
+ // Check if requesting SDK from parent dist folder
30
+ if (filePath.startsWith('/dist/')) {
31
+ filePath = path.join(__dirname, '..', filePath);
32
+ } else {
33
+ filePath = path.join(__dirname, filePath);
34
+ }
35
+
36
+ const ext = path.extname(filePath).toLowerCase();
37
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
38
+
39
+ fs.readFile(filePath, (err, content) => {
40
+ if (err) {
41
+ if (err.code === 'ENOENT') {
42
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
43
+ res.end('404 Not Found');
44
+ } else {
45
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
46
+ res.end('500 Internal Server Error');
47
+ }
48
+ return;
49
+ }
50
+
51
+ res.writeHead(200, { 'Content-Type': contentType });
52
+ res.end(content);
53
+ });
54
+ }
55
+
56
+ function startServer() {
57
+ let server;
58
+ let protocol;
59
+
60
+ if (USE_HTTPS) {
61
+ const certPath = path.join(__dirname, 'certs');
62
+
63
+ if (!fs.existsSync(path.join(certPath, 'key.pem'))) {
64
+ console.log('\nNo SSL certificates found. Generate them with:');
65
+ console.log(' mkdir -p examples/certs');
66
+ console.log(' openssl req -x509 -newkey rsa:2048 -keyout examples/certs/key.pem -out examples/certs/cert.pem -days 365 -nodes -subj "/CN=localhost"\n');
67
+ console.log('Falling back to HTTP...\n');
68
+ server = http.createServer(handleRequest);
69
+ protocol = 'http';
70
+ } else {
71
+ const options = {
72
+ key: fs.readFileSync(path.join(certPath, 'key.pem')),
73
+ cert: fs.readFileSync(path.join(certPath, 'cert.pem')),
74
+ };
75
+ server = https.createServer(options, handleRequest);
76
+ protocol = 'https';
77
+ }
78
+ } else {
79
+ server = http.createServer(handleRequest);
80
+ protocol = 'http';
81
+ }
82
+
83
+ server.listen(PORT, () => {
84
+ console.log(`\n GameGlue Example Server`);
85
+ console.log(` -----------------------`);
86
+ console.log(` ${protocol.toUpperCase()} server running at:`);
87
+ console.log(` ${protocol}://localhost:${PORT}/\n`);
88
+
89
+ if (protocol === 'http') {
90
+ console.log(` Note: OAuth may require HTTPS. Set HTTPS=true or add certs.\n`);
91
+ }
92
+ });
93
+ }
94
+
95
+ startServer();
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "gameglue",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Javascript SDK for the GameGlue developer platform.",
5
- "main": "dist/gg.sdk.js",
5
+ "main": "dist/gs.sdk.js",
6
6
  "scripts": {
7
7
  "build": "webpack ",
8
+ "serve": "node examples/server.js",
9
+ "serve:https": "HTTPS=true node examples/server.js",
8
10
  "test": "echo \"Error: no test specified\" && exit 1"
9
11
  },
10
12
  "repository": {
package/src/index.js CHANGED
@@ -23,6 +23,7 @@ class GameGlue extends GameGlueAuth {
23
23
  async initialize() {
24
24
  return new Promise((resolve) => {
25
25
  const token = this.getAccessToken();
26
+ // For local development, use 'http://localhost:3031'
26
27
  this._socket = io('https://socks.gameglue.gg', {
27
28
  transports: ['websocket'],
28
29
  auth: {
@@ -47,6 +48,11 @@ class GameGlue extends GameGlueAuth {
47
48
  if (!config.userId) throw new Error('User ID not supplied');
48
49
  if (config.fields && !Array.isArray(config.fields)) throw new Error('fields must be an array');
49
50
 
51
+ // Ensure socket is initialized (handles page reload case)
52
+ if (!this._socket) {
53
+ await this.initialize();
54
+ }
55
+
50
56
  const listener = new Listener(this._socket, config);
51
57
  const establishConnectionResponse = await listener.establishConnection();
52
58
  this._socket.io.on('reconnect_attempt', (d) => {
package/src/listener.js CHANGED
@@ -95,6 +95,36 @@ export class Listener {
95
95
  return this._fields ? [...this._fields] : null;
96
96
  }
97
97
 
98
+ /**
99
+ * Send a command to the broadcaster (game client)
100
+ * @param {string} field - The field/action name to set
101
+ * @param {any} value - The value to set
102
+ * @returns {Promise<{status: string, reason?: string}>}
103
+ */
104
+ async sendCommand(field, value) {
105
+ if (!field || typeof field !== 'string') {
106
+ throw new Error('field must be a non-empty string');
107
+ }
108
+
109
+ return new Promise((resolve) => {
110
+ const payload = {
111
+ userId: this._config.userId,
112
+ gameId: this._config.gameId,
113
+ data: {
114
+ fieldName: field,
115
+ value
116
+ }
117
+ };
118
+
119
+ this._socket.timeout(5000).emit('set', payload, (error, response) => {
120
+ if (error) {
121
+ return resolve({ status: 'failed', reason: 'Command request timed out.' });
122
+ }
123
+ return resolve(response);
124
+ });
125
+ });
126
+ }
127
+
98
128
  /**
99
129
  * Internal method to send subscription update to server
100
130
  */