multyx-client 0.1.5 → 0.1.6

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.
@@ -115,7 +115,6 @@ class Controller {
115
115
  * @param anchor Anchor the origin at a specific spot on the canvas
116
116
  */
117
117
  mapCanvasPosition(canvas, position) {
118
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
119
118
  const t = 'top' in position;
120
119
  const b = 'bottom' in position;
121
120
  const l = 'left' in position;
@@ -180,12 +179,12 @@ class Controller {
180
179
  return error(true, 'bottom');
181
180
  position.bottom = 0;
182
181
  if (l) {
183
- (_a = position.top) !== null && _a !== void 0 ? _a : (position.top = Math.abs(hToW * position.left * 2));
184
- (_b = position.right) !== null && _b !== void 0 ? _b : (position.right = -position.left);
182
+ position.top = Math.abs(hToW * position.left * 2);
183
+ position.right = -position.left;
185
184
  }
186
185
  else if (r) {
187
- (_c = position.top) !== null && _c !== void 0 ? _c : (position.top = Math.abs(hToW * position.right * 2));
188
- (_d = position.left) !== null && _d !== void 0 ? _d : (position.left = -position.right);
186
+ position.top = Math.abs(hToW * position.right * 2);
187
+ position.left = -position.right;
189
188
  }
190
189
  else {
191
190
  position.left = -Math.abs(wToH * position.top / 2);
@@ -199,12 +198,12 @@ class Controller {
199
198
  return error(true, 'top');
200
199
  position.top = 0;
201
200
  if (l) {
202
- (_e = position.bottom) !== null && _e !== void 0 ? _e : (position.bottom = Math.abs(hToW * position.left * 2));
203
- (_f = position.right) !== null && _f !== void 0 ? _f : (position.right = -position.left);
201
+ position.bottom = Math.abs(hToW * position.left * 2);
202
+ position.right = -position.left;
204
203
  }
205
204
  else if (r) {
206
- (_g = position.bottom) !== null && _g !== void 0 ? _g : (position.bottom = Math.abs(hToW * position.right * 2));
207
- (_h = position.left) !== null && _h !== void 0 ? _h : (position.left = -position.right);
205
+ position.bottom = Math.abs(hToW * position.right * 2);
206
+ position.left = -position.right;
208
207
  }
209
208
  else {
210
209
  position.left = -Math.abs(wToH * position.bottom / 2);
@@ -218,12 +217,12 @@ class Controller {
218
217
  return error(true, 'left');
219
218
  position.left = 0;
220
219
  if (t) {
221
- (_j = position.right) !== null && _j !== void 0 ? _j : (position.right = -Math.abs(wToH * position.top * 2));
222
- (_k = position.bottom) !== null && _k !== void 0 ? _k : (position.bottom = -position.top);
220
+ position.right = -Math.abs(wToH * position.top * 2);
221
+ position.bottom = -position.top;
223
222
  }
224
223
  else if (b) {
225
- (_l = position.right) !== null && _l !== void 0 ? _l : (position.right = Math.abs(wToH * position.bottom * 2));
226
- (_m = position.top) !== null && _m !== void 0 ? _m : (position.top = -position.bottom);
224
+ position.right = Math.abs(wToH * position.bottom * 2);
225
+ position.top = -position.bottom;
227
226
  }
228
227
  else {
229
228
  position.top = -Math.abs(hToW * position.right / 2);
@@ -237,12 +236,12 @@ class Controller {
237
236
  return error(true, 'right');
238
237
  position.right = 0;
239
238
  if (t) {
240
- (_o = position.left) !== null && _o !== void 0 ? _o : (position.left = -Math.abs(wToH * position.top * 2));
241
- (_p = position.bottom) !== null && _p !== void 0 ? _p : (position.bottom = -position.top);
239
+ position.left = -Math.abs(wToH * position.top * 2);
240
+ position.bottom = -position.top;
242
241
  }
243
242
  else if (b) {
244
- (_q = position.left) !== null && _q !== void 0 ? _q : (position.left = Math.abs(wToH * position.bottom * 2));
245
- (_r = position.top) !== null && _r !== void 0 ? _r : (position.top = -position.bottom);
243
+ position.left = Math.abs(wToH * position.bottom * 2);
244
+ position.top = -position.bottom;
246
245
  }
247
246
  else {
248
247
  position.top = -Math.abs(hToW * position.right / 2);
@@ -294,14 +293,14 @@ class Controller {
294
293
  position.left = Math.abs(wToH * position.top);
295
294
  }
296
295
  const ctx = canvas.getContext("2d");
297
- ctx.setTransform(1, 0, 0, 1, 0, 0);
296
+ ctx === null || ctx === void 0 ? void 0 : ctx.setTransform(1, 0, 0, 1, 0, 0);
298
297
  canvas.width = Math.floor(Math.abs(position.right - position.left));
299
298
  canvas.height = Math.floor(Math.abs(position.bottom - position.top));
300
299
  if (position.right < position.left)
301
- ctx.scale(-1, 1);
300
+ ctx === null || ctx === void 0 ? void 0 : ctx.scale(-1, 1);
302
301
  if (position.top > position.bottom)
303
- ctx.scale(1, -1);
304
- ctx.translate(-position.left, -position.top);
302
+ ctx === null || ctx === void 0 ? void 0 : ctx.scale(1, -1);
303
+ ctx === null || ctx === void 0 ? void 0 : ctx.translate(-position.left, -position.top);
305
304
  }
306
305
  /**
307
306
  * @param centerX Anchor x-value corresponding to mouse position x-value of 0
@@ -329,15 +328,15 @@ class Controller {
329
328
  */
330
329
  mapMouseToCanvas(canvas) {
331
330
  const ctx = canvas.getContext("2d");
332
- const transform = ctx.getTransform();
331
+ const transform = ctx === null || ctx === void 0 ? void 0 : ctx.getTransform();
333
332
  const bounding = canvas.getBoundingClientRect();
334
333
  // Ratio between canvas scale to unit pixels
335
334
  const canvasRatioX = bounding.width / canvas.width;
336
335
  const canvasRatioY = bounding.height / canvas.height;
337
- this.mouse.centerX = bounding.left + transform.e * canvasRatioX;
338
- this.mouse.centerY = bounding.top + transform.f * canvasRatioY;
339
- this.mouse.scaleX = canvasRatioX * transform.a;
340
- this.mouse.scaleY = canvasRatioY * transform.d;
336
+ this.mouse.centerX = bounding.left + (transform === null || transform === void 0 ? void 0 : transform.e) * canvasRatioX;
337
+ this.mouse.centerY = bounding.top + (transform === null || transform === void 0 ? void 0 : transform.f) * canvasRatioY;
338
+ this.mouse.scaleX = canvasRatioX * (transform === null || transform === void 0 ? void 0 : transform.a);
339
+ this.mouse.scaleY = canvasRatioY * (transform === null || transform === void 0 ? void 0 : transform.d);
341
340
  }
342
341
  /**
343
342
  * Utilize mouse coordinates of another object
package/dist/index.js CHANGED
@@ -12,8 +12,10 @@ class Multyx {
12
12
  // Queue of functions to be called after each frame
13
13
  this[_a] = [];
14
14
  this.options = Object.assign(Object.assign({}, options_1.DefaultOptions), options);
15
- const url = `ws${this.options.secure ? 's' : ''}://${this.options.uri.split('/')[0]}:${this.options.port}/${(_b = this.options.uri.split('/')[1]) !== null && _b !== void 0 ? _b : ''}`;
16
- this.ws = new WebSocket(url);
15
+ if (!this.options.uri)
16
+ throw new Error('URI is required');
17
+ const uri = `ws${this.options.secure ? 's' : ''}://${this.options.uri.split('/')[0]}:${this.options.port}/${(_b = this.options.uri.split('/')[1]) !== null && _b !== void 0 ? _b : ''}`;
18
+ this.ws = new WebSocket(uri);
17
19
  this.ping = 0;
18
20
  this.space = 'default';
19
21
  this.events = new Map();
@@ -108,7 +110,7 @@ class Multyx {
108
110
  * @param msg Message to parse
109
111
  */
110
112
  parseNativeEvent(msg) {
111
- var _b, _c, _d, _e;
113
+ var _b, _c, _d, _e, _f;
112
114
  msg.data = msg.data.map(message_1.UncompressUpdate);
113
115
  if (this.options.logUpdateFrame)
114
116
  console.log(msg.data);
@@ -172,9 +174,10 @@ class Multyx {
172
174
  }
173
175
  // Response to client
174
176
  case 'resp': {
175
- const promiseResolve = this.events.get(Symbol.for("_" + update.name))[0];
177
+ const promiseResolve = (_f = this.events.get(Symbol.for("_" + update.name))) === null || _f === void 0 ? void 0 : _f[0];
176
178
  this.events.delete(Symbol.for("_" + update.name));
177
- this[utils_1.Done].push(() => promiseResolve(update.response));
179
+ if (promiseResolve)
180
+ this[utils_1.Done].push(() => promiseResolve(update.response));
178
181
  break;
179
182
  }
180
183
  default: {
@@ -1,12 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.MultyxClientValue = exports.MultyxClientObject = exports.MultyxClientList = void 0;
4
7
  exports.IsMultyxClientItem = IsMultyxClientItem;
5
- const list_1 = require("./list");
8
+ const list_1 = __importDefault(require("./list"));
6
9
  exports.MultyxClientList = list_1.default;
7
- const object_1 = require("./object");
10
+ const object_1 = __importDefault(require("./object"));
8
11
  exports.MultyxClientObject = object_1.default;
9
- const value_1 = require("./value");
12
+ const value_1 = __importDefault(require("./value"));
10
13
  exports.MultyxClientValue = value_1.default;
11
14
  function IsMultyxClientItem(value) {
12
15
  return value instanceof list_1.default || value instanceof object_1.default || value instanceof value_1.default;
@@ -1,6 +1,6 @@
1
1
  import Multyx from '../';
2
2
  import { type MultyxClientItem, type MultyxClientObject, MultyxClientValue } from '.';
3
- import { EditWrapper, Unpack } from '../utils';
3
+ import { Edit, EditWrapper, Unpack } from '../utils';
4
4
  export default class MultyxClientList {
5
5
  protected list: MultyxClientItem[];
6
6
  private multyx;
@@ -21,9 +21,10 @@ export default class MultyxClientList {
21
21
  * @param shift Shift amount, positive for right, negative for left
22
22
  */
23
23
  private handleShiftOperation;
24
- constructor(multyx: Multyx, list: any[] | EditWrapper<any[]>, propertyPath: string[], editable: boolean);
24
+ [index: number]: MultyxClientItem | undefined;
25
+ constructor(multyx: Multyx, list: any[] | EditWrapper<any[]>, propertyPath: string[] | undefined, editable: boolean);
25
26
  has(index: number): boolean;
26
- get(index: number | string[]): MultyxClientItem;
27
+ get(index: number | string[]): MultyxClientItem | undefined;
27
28
  private recursiveSet;
28
29
  set(index: number | string[], value: any): boolean;
29
30
  delete(index: number, native?: boolean): boolean;
@@ -34,9 +35,9 @@ export default class MultyxClientList {
34
35
  */
35
36
  await(index: number): Promise<unknown>;
36
37
  push(...items: any): number;
37
- pop(): MultyxClientItem | null;
38
+ pop(): MultyxClientItem | undefined;
38
39
  unshift(...items: any[]): number;
39
- shift(): MultyxClientList | MultyxClientObject | MultyxClientValue;
40
+ shift(): MultyxClientList | MultyxClientObject | MultyxClientValue | undefined;
40
41
  slice(start?: number, end?: number): (MultyxClientList | MultyxClientObject | MultyxClientValue)[];
41
42
  splice(start: number, deleteCount?: number, ...items: any[]): (MultyxClientList | MultyxClientObject | MultyxClientValue)[];
42
43
  setSplice(start: number, deleteCount?: number, ...items: any[]): void;
@@ -51,10 +52,11 @@ export default class MultyxClientList {
51
52
  forEach(callbackfn: (value: any, index: number, array: MultyxClientList) => void): void;
52
53
  every(predicate: (value: any, index: number, array: MultyxClientList) => boolean): boolean;
53
54
  some(predicate: (value: any, index: number, array: MultyxClientList) => boolean): boolean;
54
- find(predicate: (value: any, index: number, array: MultyxClientList) => boolean): MultyxClientList | MultyxClientObject | MultyxClientValue;
55
+ find(predicate: (value: any, index: number, array: MultyxClientList) => boolean): MultyxClientList | MultyxClientObject | MultyxClientValue | undefined;
55
56
  findIndex(predicate: (value: any, index: number, array: MultyxClientList) => boolean): number;
56
57
  entries(): [any, number][];
57
58
  keys(): number[];
59
+ [Edit](): void;
58
60
  [Unpack](constraints: any[]): void;
59
61
  [Symbol.iterator](): Iterator<MultyxClientItem>;
60
62
  toString: () => string;
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  var _a;
3
6
  Object.defineProperty(exports, "__esModule", { value: true });
4
7
  const _1 = require(".");
5
8
  const utils_1 = require("../utils");
6
- const router_1 = require("./router");
9
+ const router_1 = __importDefault(require("./router"));
7
10
  const message_1 = require("../message");
8
11
  class MultyxClientList {
9
12
  addEditCallback(callback) {
@@ -151,6 +154,7 @@ class MultyxClientList {
151
154
  return next.set(path.slice(1), value);
152
155
  }
153
156
  set(index, value) {
157
+ var _b, _c;
154
158
  if (Array.isArray(index))
155
159
  return this.recursiveSet(index, value);
156
160
  const oldValue = this.get(index);
@@ -174,7 +178,7 @@ class MultyxClientList {
174
178
  this.list[index] = new ((0, router_1.default)(value))(this.multyx, serverSet ? new utils_1.EditWrapper(value) : value, [...this.propertyPath, index.toString()], this.editable);
175
179
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.') + '.' + index);
176
180
  if (this.multyx.events.has(propSymbol)) {
177
- this.multyx[utils_1.Done].push(...this.multyx.events.get(propSymbol).map(e => () => e(this.list[index])));
181
+ this.multyx[utils_1.Done].push(...((_c = (_b = this.multyx.events.get(propSymbol)) === null || _b === void 0 ? void 0 : _b.map(e => () => e(this.list[index]))) !== null && _c !== void 0 ? _c : []));
178
182
  }
179
183
  // We have to push into queue, since object may not be fully created
180
184
  // and there may still be more updates to parse
@@ -225,7 +229,7 @@ class MultyxClientList {
225
229
  }
226
230
  pop() {
227
231
  if (this.length === 0)
228
- return null;
232
+ return undefined;
229
233
  const res = this.get(this.length);
230
234
  this.delete(this.length);
231
235
  return res;
@@ -255,7 +259,7 @@ class MultyxClientList {
255
259
  return this.list.slice(start, end);
256
260
  }
257
261
  splice(start, deleteCount, ...items) {
258
- return this.list.splice(start, deleteCount, ...items);
262
+ return this.list.splice(start, deleteCount !== null && deleteCount !== void 0 ? deleteCount : 0, ...items);
259
263
  }
260
264
  setSplice(start, deleteCount, ...items) {
261
265
  if (deleteCount === undefined) {
@@ -385,6 +389,7 @@ class MultyxClientList {
385
389
  keys() {
386
390
  return Array(this.length).fill(0).map((_, i) => i);
387
391
  }
392
+ [utils_1.Edit]() { }
388
393
  [utils_1.Unpack](constraints) {
389
394
  var _b;
390
395
  for (let i = 0; i < this.length; i++) {
@@ -1,19 +1,21 @@
1
1
  import { RawObject } from '../types';
2
2
  import { Edit, EditWrapper, Unpack } from "../utils";
3
3
  import type Multyx from '../index';
4
- import { type MultyxClientItem } from ".";
4
+ import { type MultyxClientList, type MultyxClientItem } from ".";
5
+ import MultyxClientValue from "./value";
5
6
  export default class MultyxClientObject {
6
7
  protected object: RawObject<MultyxClientItem>;
7
8
  private multyx;
8
9
  propertyPath: string[];
9
10
  editable: boolean;
10
11
  private editCallbacks;
11
- get value(): {};
12
+ get value(): RawObject<MultyxClientList | MultyxClientObject | MultyxClientValue>;
12
13
  addEditCallback(callback: (key: any, value: any) => void): void;
13
14
  [Edit](updatePath: string[], value: any): void;
14
- constructor(multyx: Multyx, object: RawObject | EditWrapper<RawObject>, propertyPath: string[], editable: boolean);
15
+ [key: string]: any;
16
+ constructor(multyx: Multyx, object: RawObject | EditWrapper<RawObject>, propertyPath: string[] | undefined, editable: boolean);
15
17
  has(property: any): boolean;
16
- get(property: string | string[]): MultyxClientItem;
18
+ get(property: string | string[]): MultyxClientItem | undefined;
17
19
  private recursiveSet;
18
20
  set(property: string | string[], value: any): boolean;
19
21
  delete(property: any, native?: boolean): boolean;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  const message_1 = require("../message");
4
7
  const utils_1 = require("../utils");
5
8
  const _1 = require(".");
6
- const router_1 = require("./router");
7
- const value_1 = require("./value");
9
+ const router_1 = __importDefault(require("./router"));
10
+ const value_1 = __importDefault(require("./value"));
8
11
  class MultyxClientObject {
9
12
  get value() {
10
13
  const parsed = {};
@@ -16,6 +19,7 @@ class MultyxClientObject {
16
19
  this.editCallbacks.push(callback);
17
20
  }
18
21
  [utils_1.Edit](updatePath, value) {
22
+ var _a;
19
23
  if (updatePath.length == 1) {
20
24
  this.set(updatePath[0], new utils_1.EditWrapper(value));
21
25
  return;
@@ -26,7 +30,7 @@ class MultyxClientObject {
26
30
  if (!this.has(updatePath[0])) {
27
31
  this.set(updatePath[0], new utils_1.EditWrapper({}));
28
32
  }
29
- this.get(updatePath[0])[utils_1.Edit](updatePath.slice(1), value);
33
+ (_a = this.get(updatePath[0])) === null || _a === void 0 ? void 0 : _a[utils_1.Edit](updatePath.slice(1), value);
30
34
  }
31
35
  constructor(multyx, object, propertyPath = [], editable) {
32
36
  this.editCallbacks = [];
@@ -105,6 +109,7 @@ class MultyxClientObject {
105
109
  return next.set(path.slice(1), value);
106
110
  }
107
111
  set(property, value) {
112
+ var _a, _b;
108
113
  if (Array.isArray(property))
109
114
  return this.recursiveSet(property, value);
110
115
  const serverSet = value instanceof utils_1.EditWrapper;
@@ -128,7 +133,7 @@ class MultyxClientObject {
128
133
  this.object[property] = new ((0, router_1.default)(value))(this.multyx, serverSet ? new utils_1.EditWrapper(value) : value, [...this.propertyPath, property], this.editable);
129
134
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.') + '.' + property);
130
135
  if (this.multyx.events.has(propSymbol)) {
131
- this.multyx[utils_1.Done].push(...this.multyx.events.get(propSymbol).map(e => () => e(this.object[property])));
136
+ this.multyx[utils_1.Done].push(...((_b = (_a = this.multyx.events.get(propSymbol)) === null || _a === void 0 ? void 0 : _a.map(e => () => e(this.object[property]))) !== null && _b !== void 0 ? _b : []));
132
137
  }
133
138
  return true;
134
139
  }
@@ -16,7 +16,7 @@ export default class MultyxClientValue {
16
16
  addReadModifier(modifier: (value: Value) => Value): void;
17
17
  addEditCallback(callback: (value: Value, previousValue: Value) => void): void;
18
18
  [Edit](updatePath: string[], value: any): void;
19
- constructor(multyx: Multyx, value: Value | EditWrapper<Value>, propertyPath: string[], editable: boolean);
19
+ constructor(multyx: Multyx, value: Value | EditWrapper<Value>, propertyPath: string[] | undefined, editable: boolean);
20
20
  set(value: Value | EditWrapper<Value>): boolean;
21
21
  bindElement(element: HTMLElement): void;
22
22
  /**
@@ -22,6 +22,7 @@ class MultyxClientValue {
22
22
  this.set(new utils_1.EditWrapper(value));
23
23
  }
24
24
  constructor(multyx, value, propertyPath = [], editable) {
25
+ var _b, _c;
25
26
  this.readModifiers = [];
26
27
  this.editCallbacks = [];
27
28
  /* Native methods to allow MultyxValue to be treated as primitive */
@@ -35,7 +36,7 @@ class MultyxClientValue {
35
36
  this.set(value);
36
37
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.'));
37
38
  if (this.multyx.events.has(propSymbol)) {
38
- this.multyx[utils_1.Done].push(...this.multyx.events.get(propSymbol).map(e => () => e(this.value)));
39
+ this.multyx[utils_1.Done].push(...((_c = (_b = this.multyx.events.get(propSymbol)) === null || _b === void 0 ? void 0 : _b.map(e => () => e(this.value))) !== null && _c !== void 0 ? _c : []));
39
40
  }
40
41
  }
41
42
  set(value) {
package/dist/message.d.ts CHANGED
@@ -107,7 +107,7 @@ export declare function UncompressUpdate(str: string): {
107
107
  uuid?: undefined;
108
108
  publicData?: undefined;
109
109
  clientUUID?: undefined;
110
- };
110
+ } | undefined;
111
111
  export declare function CompressUpdate(update: Update): string;
112
112
  export declare class Message {
113
113
  name: string;
package/dist/message.js CHANGED
@@ -54,9 +54,9 @@ function CompressUpdate(update) {
54
54
  code = 2;
55
55
  pieces = [update.name, JSON.stringify(update.response)];
56
56
  }
57
- if (!pieces)
57
+ if (!pieces || !code)
58
58
  return '';
59
- let compressed = code;
59
+ let compressed = code.toString();
60
60
  for (let i = 0; i < pieces.length; i++) {
61
61
  compressed += pieces[i].replace(/;/g, ';_');
62
62
  if (i < pieces.length - 1)
package/multyx.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multyx=e():t.Multyx=e()}(self,(()=>(()=>{"use strict";var t={376:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Controller=void 0;const i=s(210);e.Controller=class{constructor(t){this.listening=new Set,this.ws=t,this.preventDefault=!1,this.keys={},this.mouse={x:NaN,y:NaN,down:!1,centerX:0,centerY:0,scaleX:1,scaleY:1},document.addEventListener("keydown",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();this.keys[e]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:e}),this.keys[t.code]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:t.code}),this.listening.has(e)&&!this.keys[e]&&this.relayInput("keydown",{code:t.key}),this.listening.has(t.code)&&!this.keys[t.code]&&this.relayInput("keydown",{code:t.code}),this.keys[e]=!0,this.keys[t.code]=!0})),document.addEventListener("keyup",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();delete this.keys[e],delete this.keys[t.code],this.listening.has(e)&&this.relayInput("keyup",{code:e}),this.listening.has(t.code)&&this.relayInput("keyup",{code:t.code})})),document.addEventListener("mousedown",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!0,this.listening.has("mousedown")&&this.relayInput("mousedown",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mouseup",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!1,this.listening.has("mouseup")&&this.relayInput("mouseup",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mousemove",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.listening.has("mousemove")&&this.relayInput("mousemove",{x:this.mouse.x,y:this.mouse.y})}))}mapCanvasPosition(t,e){var s,i,o,n,r,l,h,a,u,c,p,d,f,m,g,y;const b="top"in e,v="bottom"in e,w="left"in e,x="right"in e,M=e.anchor,S=t.getBoundingClientRect(),j=(t,...e)=>{const s=t?"Cannot include value for ":"Must include value for ",i=1==e.length?e[0]:e.slice(0,-1).join(", ")+(t?" and ":" or ")+e.slice(-1)[0],o=M?" if anchoring at "+M:" if not anchoring";console.error(s+i+o)},k=S.width/S.height,E=S.height/S.width;if((Number.isNaN(k)||Number.isNaN(E))&&console.error("Canvas element bounding box is flat, canvas must be present on the screen"),M){if("center"==M){if(b&&v&&e.top!==-e.bottom||w&&x&&e.left!==-e.right)return j(!0,"top","bottom","left","right");b?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.top),e.right=w?-e.left:x?e.right:Math.abs(k*e.top),e.bottom=-e.top):v?(e.left=w?e.left:x?-e.right:-Math.abs(k*e.bottom),e.right=w?-e.left:x?e.right:Math.abs(k*e.bottom),e.top=-e.bottom):w?(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.left),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.left),e.right=-e.left):x&&(e.top=b?e.top:v?-e.bottom:-Math.abs(E*e.right),e.bottom=b?-e.top:v?e.bottom:Math.abs(E*e.right),e.left=-e.right)}else if("bottom"==M){if(!w&&!x&&!b)return j(!1,"left","right","top");if(e.bottom)return j(!0,"bottom");e.bottom=0,w?(null!==(s=e.top)&&void 0!==s||(e.top=Math.abs(E*e.left*2)),null!==(i=e.right)&&void 0!==i||(e.right=-e.left)):x?(null!==(o=e.top)&&void 0!==o||(e.top=Math.abs(E*e.right*2)),null!==(n=e.left)&&void 0!==n||(e.left=-e.right)):(e.left=-Math.abs(k*e.top/2),e.right=-e.left)}else if("top"==M){if(!w&&!x&&!v)return j(!1,"left","right","bottom");if(e.top)return j(!0,"top");e.top=0,w?(null!==(r=e.bottom)&&void 0!==r||(e.bottom=Math.abs(E*e.left*2)),null!==(l=e.right)&&void 0!==l||(e.right=-e.left)):x?(null!==(h=e.bottom)&&void 0!==h||(e.bottom=Math.abs(E*e.right*2)),null!==(a=e.left)&&void 0!==a||(e.left=-e.right)):(e.left=-Math.abs(k*e.bottom/2),e.right=-e.left)}else if("left"==M){if(!b&&!v&&!x)return j(!1,"top","bottom","right");if(w)return j(!0,"left");e.left=0,b?(null!==(u=e.right)&&void 0!==u||(e.right=-Math.abs(k*e.top*2)),null!==(c=e.bottom)&&void 0!==c||(e.bottom=-e.top)):v?(null!==(p=e.right)&&void 0!==p||(e.right=Math.abs(k*e.bottom*2)),null!==(d=e.top)&&void 0!==d||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("right"==M){if(!b&&!v&&!w)return j(!1,"top","bottom","left");if(x)return j(!0,"right");e.right=0,b?(null!==(f=e.left)&&void 0!==f||(e.left=-Math.abs(k*e.top*2)),null!==(m=e.bottom)&&void 0!==m||(e.bottom=-e.top)):v?(null!==(g=e.left)&&void 0!==g||(e.left=Math.abs(k*e.bottom*2)),null!==(y=e.top)&&void 0!==y||(e.top=-e.bottom)):(e.top=-Math.abs(E*e.right/2),e.bottom=-e.top)}else if("topleft"==M){if(!x&&!v)return j(!1,"right","bottom");if(w||b)return j(!0,"left","top");e.left=e.top=0,x?e.bottom=Math.abs(E*e.right):e.right=Math.abs(k*e.bottom)}else if("topright"==M){if(!w&&!v)return j(!1,"left","bottom");if(x||b)return j(!0,"right","top");e.right=e.top=0,w?e.bottom=Math.abs(E*e.left):e.left=Math.abs(k*e.bottom)}else if("bottomleft"==M){if(!x&&!b)return j(!1,"right","top");if(v||w)return j(!0,"bottom","left");e.left=e.bottom=0,x?e.top=Math.abs(E*e.right):e.right=Math.abs(k*e.top)}else if("bottomright"==M){if(!b&&!w)return j(!1,"top","left");if(x||v)return j(!0,"bottom","right");e.right=e.bottom=0,w?e.top=Math.abs(E*e.left):e.left=Math.abs(k*e.top)}}else{if(!b&&!v)return j(!1,"top","bottom");if(v?b||(e.top=e.bottom-t.height):e.bottom=e.top+t.height,!w&&!x)return j(!1,"left","right");x?w||(e.left=e.right-t.width):e.right=e.left+t.width}const C=t.getContext("2d");C.setTransform(1,0,0,1,0,0),t.width=Math.floor(Math.abs(e.right-e.left)),t.height=Math.floor(Math.abs(e.bottom-e.top)),e.right<e.left&&C.scale(-1,1),e.top>e.bottom&&C.scale(1,-1),C.translate(-e.left,-e.top)}mapMousePosition(t,e,s=document.body,i=1,o=i){const n=window.innerWidth/(s instanceof HTMLCanvasElement?s.width:s.clientWidth),r=window.innerHeight/(s instanceof HTMLCanvasElement?s.height:s.clientHeight),l=s.getBoundingClientRect();this.mouse.centerX=l.left+t*n,this.mouse.centerY=l.top+e*r,this.mouse.scaleX=i*n,this.mouse.scaleY=o*r}mapMouseToCanvas(t){const e=t.getContext("2d").getTransform(),s=t.getBoundingClientRect(),i=s.width/t.width,o=s.height/t.height;this.mouse.centerX=s.left+e.e*i,this.mouse.centerY=s.top+e.f*o,this.mouse.scaleX=i*e.a,this.mouse.scaleY=o*e.d}setMouseAs(t){this.mouseGetter=t}relayInput(t,e){if(1!==this.ws.readyState)throw new Error("Websocket connection is "+(2==this.ws.readyState?"closing":"closed"));this.ws.send(i.Message.Native(Object.assign({instruction:"input",input:t},e?{data:e}:{})))}}},34:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.MultyxClientValue=e.MultyxClientObject=e.MultyxClientList=void 0,e.IsMultyxClientItem=function(t){return t instanceof i.default||t instanceof o.default||t instanceof n.default};const i=s(70);e.MultyxClientList=i.default;const o=s(614);e.MultyxClientObject=o.default;const n=s(501);e.MultyxClientValue=n.default},70:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(34),n=s(787),r=s(735),l=s(210);class h{addEditCallback(t){this.editCallbacks.push(t)}get value(){var t;const e=[];for(let s=0;s<this.length;s++)e[s]=null===(t=this.get(s))||void 0===t?void 0:t.value;return e}get length(){return this.list.length}set length(t){this.list.length=t}handleShiftOperation(t,e){const s=t>=0?e>=0?"right":"left":0==e?"reverse":e<0?"length":"unknown";switch(s){case"reverse":for(let t=0;t<Math.floor(this.length/2);t++){const e=this.list[t];this.list[t]=this.list[this.length-1-t],this.list[this.length-1-t]=e}break;case"left":for(let s=t;s<this.length;s++)s+e<0||(this.list[s+e]=this.list[s]);break;case"right":for(let s=this.length-1;s>=t;s--)this.list[s+e]=this.list[s];break;case"length":this.length+=e;break;default:this.multyx.options.verbose&&console.error("Unknown shift operation: "+s)}}constructor(t,e,s=[],o){this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.list=[],this.propertyPath=s,this.multyx=t,this.editable=o;const r=e instanceof n.EditWrapper;e instanceof h&&(e=e.value),e instanceof n.EditWrapper&&(e=e.value);for(let t=0;t<e.length;t++)this.set(t,r?new n.EditWrapper(e[t]):e[t]);return new Proxy(this,{has:(t,e)=>"number"==typeof e?t.has(e):e in t,get:(t,e)=>e in t?t[e]:(isNaN(parseInt(e))||(e=parseInt(e)),t.get(e)),set:(t,e,s)=>e in t?(t[e]=s,!0):!!t.set(e,s),deleteProperty:(t,e)=>"number"==typeof e&&t.delete(e)})}has(t){return t>=0&&t<this.length}get(t){if("number"==typeof t)return this.list[t];if(0==t.length)return this;if(1==t.length)return this.list[parseInt(t[0])];const e=this.list[parseInt(t[0])];return!e||e instanceof o.MultyxClientValue?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientList with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if("shift"==t[0]&&e instanceof n.EditWrapper)return this.handleShiftOperation(parseInt(t[1]),e.value),!0;if(1==t.length)return this.set(parseInt(t[0]),e);let s=this.get(parseInt(t[0]));return(s instanceof o.MultyxClientValue||null==s)&&(this.set(parseInt(t[0]),new n.EditWrapper({})),s=this.get(parseInt(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=this.get(t),i=e instanceof n.EditWrapper,l=i||this.editable;if((i||(0,o.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,i);if(this.list[t]instanceof o.MultyxClientValue&&"object"!=typeof e)return this.list[t].set(i?new n.EditWrapper(e):e);if(!l)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.list[t]=new((0,r.default)(e))(this.multyx,i?new n.EditWrapper(e):e,[...this.propertyPath,t.toString()],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);this.multyx.events.has(h)&&this.multyx[n.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.list[t]))));for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,this.get(t),s)));return!0}delete(t,e=!1){const s=this.get(t);if("string"==typeof t&&(t=parseInt(t)),!this.editable&&!e)return this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1;delete this.list[t];for(const e of this.editCallbacks)this.multyx[n.Add]((()=>e(t,void 0,s)));return e||this.multyx.ws.send(l.Message.Native({instruction:"edit",path:[...this.propertyPath,t.toString()],value:void 0})),!0}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}push(...t){for(const e of t)this.set(this.length,e);return this.length}pop(){if(0===this.length)return null;const t=this.get(this.length);return this.delete(this.length),t}unshift(...t){for(let e=this.length-1;e>=0;e--)e>=t.length?this.set(e,this.get(e-t.length)):this.set(e,t[e]);return this.length}shift(){if(0==this.length)return;this.length--;const t=this.get(0);for(let t=0;t<this.length;t++)this.set(t,this.get(t+1));return t}slice(t,e){return this.list.slice(t,e)}splice(t,e,...s){return this.list.splice(t,e,...s)}setSplice(t,e,...s){void 0===e&&(e=this.length-t);let i=s.length-e;if(i>0)for(let s=this.length-1;s>=t+e;s--)this.set(s+i,this.get(s));else if(i<0){for(let s=t+e;s<this.length;s++)this.set(s+i,this.get(s));const s=this.length;for(let t=s+i;t<s;t++)this.set(t,void 0)}for(let e=t;e<s.length;e++)this.set(e,s[e])}filter(t){return this.list.filter(((e,s)=>t(e,s,this)))}setFilter(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));let s=0;for(let t=0;t<e.length;t++)e[t]&&s&&this.set(t-s,this.get(t)),e[t]||s--}map(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));return e}flat(){return this.list.flat()}setFlat(){for(let t=0;t<this.length;t++){const e=this.get(t);if(e instanceof h)for(let s=0;s<e.length;s++)t++,this.set(t,e[s])}}reduce(t,e){for(let s=0;s<this.length;s++)e=t(e,this.get(s),s,this);return e}reduceRight(t,e){for(let s=this.length-1;s>=0;s--)e=t(e,this.get(s),s,this);return e}reverse(){let t=this.length-1;for(let e=0;e<t;e++){const s=this.get(e),i=this.get(t);this.set(e,i),this.set(t,s)}return this}forEach(t){for(let e=0;e<this.length;e++)t(this.get(e),e,this)}every(t){for(let e=0;e<this.length;e++)if(!t(this.get(e),e,this))return!1;return!0}some(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return!0;return!1}find(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return this.get(e)}findIndex(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return e;return-1}entries(){const t=[];for(let e=0;e<this.length;e++)t.push([this.get(e),e]);return t}keys(){return Array(this.length).fill(0).map(((t,e)=>e))}[n.Unpack](t){var e;for(let s=0;s<this.length;s++)null===(e=this.get(s))||void 0===e||e[n.Unpack](t[s])}[Symbol.iterator](){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e);return t[Symbol.iterator]()}}i=Symbol.toPrimitive,e.default=h},614:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0});const i=s(210),o=s(787),n=s(34),r=s(735),l=s(501);class h{get value(){const t={};for(const e in this.object)t[e]=this.object[e];return t}addEditCallback(t){this.editCallbacks.push(t)}[o.Edit](t,e){1!=t.length?(0==t.length&&this.multyx.options.verbose&&console.error("Update path is empty. Attempting to edit MultyxClientObject with no path."),this.has(t[0])||this.set(t[0],new o.EditWrapper({})),this.get(t[0])[o.Edit](t.slice(1),e)):this.set(t[0],new o.EditWrapper(e))}constructor(t,e,s=[],i){this.editCallbacks=[],this.object={},this.propertyPath=s,this.multyx=t,this.editable=i;const n=e instanceof o.EditWrapper;e instanceof h&&(e=e.value),e instanceof o.EditWrapper&&(e=e.value);for(const t in e)this.set(t,n?new o.EditWrapper(e[t]):e[t]);if(this.constructor===h)return new Proxy(this,{has:(t,e)=>t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}has(t){return t in this.object}get(t){if("string"==typeof t)return this.object[t];if(0==t.length)return this;if(1==t.length)return this.object[t[0]];const e=this.object[t[0]];return!e||e instanceof l.default?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientObject with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if(1==t.length)return this.set(t[0],e);let s=this.get(t[0]);return(s instanceof l.default||null==s)&&(isNaN(parseInt(t[1]))?(this.set(t[0],new o.EditWrapper({})),s=this.get(t[0])):(this.set(t[0],new o.EditWrapper([])),s=this.get(t[0]))),s.set(t.slice(1),e)}set(t,e){if(Array.isArray(t))return this.recursiveSet(t,e);const s=e instanceof o.EditWrapper,i=s||this.editable;if((s||(0,n.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,s);if(this.object[t]instanceof l.default&&"object"!=typeof e)return this.object[t].set(s?new o.EditWrapper(e):e);if(!i)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.object[t]=new((0,r.default)(e))(this.multyx,s?new o.EditWrapper(e):e,[...this.propertyPath,t],this.editable);const h=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return this.multyx.events.has(h)&&this.multyx[o.Done].push(...this.multyx.events.get(h).map((e=>()=>e(this.object[t])))),!0}delete(t,e=!1){return this.editable||e?(delete this.object[t],e||this.multyx.ws.send(i.Message.Native({instruction:"edit",path:[...this.propertyPath,t],value:void 0})),!0):(this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1)}keys(){return Object.keys(this.object)}values(){return Object.values(this.object)}entries(){const t=[];for(let e in this.object)t.push([e,this.get(e)]);return t}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}[o.Unpack](t){var e;for(const s in t)null===(e=this.object[s])||void 0===e||e[o.Unpack](t[s])}}e.default=h},735:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return Array.isArray(t)?s(70).default:"object"==typeof t?s(614).default:s(501).default}},501:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const o=s(210),n=s(787);class r{get value(){return this.readModifiers.reduce(((t,e)=>e(t)),this._value)}set value(t){this._value=t}addReadModifier(t){this.readModifiers.push(t)}addEditCallback(t){this.editCallbacks.push(t)}[n.Edit](t,e){0==t.length&&this.set(new n.EditWrapper(e))}constructor(t,e,s=[],o){this.readModifiers=[],this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.propertyPath=s,this.editable=o,this.multyx=t,this.constraints={},this.set(e);const r=Symbol.for("_"+this.propertyPath.join("."));this.multyx.events.has(r)&&this.multyx[n.Done].push(...this.multyx.events.get(r).map((t=>()=>t(this.value))))}set(t){if(t instanceof n.EditWrapper){const e=this.value;return this.value=t.value,this.editCallbacks.forEach((s=>s(t.value,e))),!0}if(!this.editable)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")}' to ${t}`),!1;let e=t;for(const s in this.constraints)if(e=(0,this.constraints[s])(e),null===e)return this.multyx.options.verbose&&console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join(".")}' to ${t}, stopped by constraint '${s}'`),!1;return this.value===e?(this.value=e,!0):(this.value=e,this.multyx.ws.send(o.Message.Native({instruction:"edit",path:this.propertyPath,value:e})),!0)}bindElement(t){this.addEditCallback(((e,s)=>{e!==s&&(t.innerText=e.toString())}))}[n.Unpack](t){for(const[e,s]of Object.entries(t)){const t=(0,n.BuildConstraint)(e,s);t&&(this.constraints[e]=t)}}}i=Symbol.toPrimitive,e.default=r},210:(t,e)=>{function s(t){let e,s;if("edit"==t.instruction?(e=0,s=[t.path.join("."),JSON.stringify(t.value)]):"input"==t.instruction?(e=1,s=[t.input,JSON.stringify(t.data)]):"resp"==t.instruction&&(e=2,s=[t.name,JSON.stringify(t.response)]),!s)return"";let i=e;for(let t=0;t<s.length;t++)i+=s[t].replace(/;/g,";_"),t<s.length-1&&(i+=";,");return JSON.stringify([i])}Object.defineProperty(e,"__esModule",{value:!0}),e.Message=void 0,e.UncompressUpdate=function(t){const[e,...s]=t.split(/;,/),i=e[0],o=e.slice(1).replace(/;_/g,";"),n=s.map((t=>t.replace(/;_/g,";"))).map((t=>"undefined"==t?void 0:JSON.parse(t)));return"0"==i?{instruction:"edit",team:!1,path:o.split("."),value:n[0]}:"1"==i?{instruction:"edit",team:!0,path:o.split("."),value:n[0]}:"2"==i?{instruction:"self",property:"controller",data:JSON.parse(o)}:"3"==i?{instruction:"self",property:"uuid",data:JSON.parse(o)}:"4"==i?{instruction:"self",property:"constraint",data:JSON.parse(o)}:"9"==i?{instruction:"self",property:"space",data:JSON.parse(o)}:"5"==i?{instruction:"resp",name:o,response:n[0]}:"6"==i?{instruction:"conn",uuid:o,publicData:n[0]}:"7"==i?{instruction:"dcon",clientUUID:o}:"8"==i?{instruction:"init",client:JSON.parse(o),tps:n[0],constraintTable:n[1],clients:n[2],teams:n[3],space:n[4]}:void 0},e.CompressUpdate=s;class i{constructor(t,e,s=!1){this.name=t,this.data=e,this.time=Date.now(),this.native=s}static BundleOperations(t,e){return Array.isArray(e)||(e=[e]),JSON.stringify(new i("_",{operations:e,deltaTime:t}))}static Native(t){return s(t)}static Parse(t){var e,s;const o=JSON.parse(t);return Array.isArray(o)?new i("_",o,!0):new i(null!==(e=o.name)&&void 0!==e?e:"",null!==(s=o.data)&&void 0!==s?s:"",!1)}static Create(t,e){if(0==t.length)throw new Error("Multyx message cannot have empty name");if("_"==t[0]&&(t="_"+t),"function"==typeof e)throw new Error("Multyx data must be JSON storable");return JSON.stringify(new i(t,e))}}e.Message=i},944:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DefaultOptions=void 0,e.DefaultOptions={port:8443,secure:!1,uri:"localhost",verbose:!1,logUpdateFrame:!1}},787:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EditWrapper=e.Edit=e.Add=e.Done=e.Unpack=void 0,e.Interpolate=function(t,e,s){let i={value:t[e],time:Date.now()},o={value:t[e],time:Date.now()};Object.defineProperty(t,e,{get:()=>{const t=o.time-i.time;let e=s[0],n=s[0];for(const i of s)t>i.time&&i.time>e.time&&(e=i),t<i.time&&i.time<n.time&&(n=i);const r=(t-e.time)/(n.time-e.time),l=e.progress+r*(n.progress-e.progress);return Number.isNaN(l)?i.value:o.value*l+i.value*(1-l)},set:t=>Date.now()-o.time<10?(o.value=t,!0):(i=Object.assign({},o),o={value:t,time:Date.now()},!0)})},e.BuildConstraint=function(t,e){return"min"==t?t=>t>=e[0]?t:e[0]:"max"==t?t=>t<=e[0]?t:e[0]:"int"==t?t=>Math.floor(t):"ban"==t?t=>e.includes(t)?null:t:"disabled"==t?t=>e[0]?null:t:t=>t},e.Unpack=Symbol("unpack"),e.Done=Symbol("done"),e.Add=Symbol("add"),e.Edit=Symbol("edit"),e.EditWrapper=class{constructor(t){this.value=t}}}},e={};function s(i){var o=e[i];if(void 0!==o)return o.exports;var n=e[i]={exports:{}};return t[i](n,n.exports,s),n.exports}var i={};return(()=>{var t,e=i;const o=s(210),n=s(787),r=s(376),l=s(34),h=s(944);class a{constructor(e={},s){var i;this[t]=[],this.options=Object.assign(Object.assign({},h.DefaultOptions),e);const n=`ws${this.options.secure?"s":""}://${this.options.uri.split("/")[0]}:${this.options.port}/${null!==(i=this.options.uri.split("/")[1])&&void 0!==i?i:""}`;this.ws=new WebSocket(n),this.ping=0,this.space="default",this.events=new Map,this.self={},this.tps=0,this.all={},this.teams=new l.MultyxClientObject(this,{},[],!0),this.clients={},this.controller=new r.Controller(this.ws),null==s||s(),this.ws.onmessage=t=>{var e,s,i,n;const r=o.Message.Parse(t.data);this.ping=2*(Date.now()-r.time),r.native?(this.parseNativeEvent(r),null===(e=this.events.get(a.Native))||void 0===e||e.forEach((t=>t(r)))):(null===(s=this.events.get(r.name))||void 0===s||s.forEach((t=>{const e=t(r.data);void 0!==e&&this.send(r.name,e)})),null===(i=this.events.get(a.Custom))||void 0===i||i.forEach((t=>t(r)))),null===(n=this.events.get(a.Any))||void 0===n||n.forEach((t=>t(r)))}}on(t,e){var s;const i=null!==(s=this.events.get(t))&&void 0!==s?s:[];i.push(e),this.events.set(t,i)}send(t,e){"_"===t[0]&&(t="_"+t);const s={instruction:"resp",name:t,response:e};this.ws.send(o.Message.Native(s))}await(t,e){return this.send(t,e),new Promise((e=>this.events.set(Symbol.for("_"+t),[e])))}loop(t,e){if(e)this.on(a.Start,(()=>setInterval(t,Math.round(1e3/e))));else{const e=()=>{t(),requestAnimationFrame(e)};this.on(a.Start,(()=>requestAnimationFrame(e)))}}[(t=n.Done,n.Add)](t){this[n.Done].push(t)}parseNativeEvent(t){var e,s,i,r;t.data=t.data.map(o.UncompressUpdate),this.options.logUpdateFrame&&console.log(t.data);for(const o of t.data)switch(o.instruction){case"init":this.initialize(o);for(const t of null!==(e=this.events.get(a.Start))&&void 0!==e?e:[])this[n.Done].push((()=>t(o)));this.events.has(a.Start)&&(this.events.get(a.Start).length=0);break;case"edit":if(1==o.path.length)o.team?this.teams.set(o.path[0],new n.EditWrapper(o.value)):this.clients[o.path[0]]=new l.MultyxClientObject(this,new n.EditWrapper(o.value),[o.path[0]],!1);else{const t=o.team?this.teams.get(o.path[0]):this.clients[o.path[0]];if(!t)return;t.set(o.path.slice(1),new n.EditWrapper(o.value))}for(const t of null!==(s=this.events.get(a.Edit))&&void 0!==s?s:[])this[n.Done].push((()=>t(o)));break;case"self":this.parseSelf(o);break;case"conn":this.clients[o.uuid]=new l.MultyxClientObject(this,o.data,[o.uuid],!1);for(const t of null!==(i=this.events.get(a.Connection))&&void 0!==i?i:[])this[n.Done].push((()=>t(this.clients[o.uuid])));break;case"dcon":for(const t of null!==(r=this.events.get(a.Disconnect))&&void 0!==r?r:[]){const e=this.clients[o.client].value;this[n.Done].push((()=>t(e)))}delete this.clients[o.client];break;case"resp":{const t=this.events.get(Symbol.for("_"+o.name))[0];this.events.delete(Symbol.for("_"+o.name)),this[n.Done].push((()=>t(o.response)));break}default:this.options.verbose&&console.error("Server error: Unknown native Multyx instruction")}this[n.Done].forEach((t=>t())),this[n.Done].length=0}initialize(t){this.tps=t.tps,this.uuid=t.client.uuid,this.joinTime=t.client.joinTime,this.controller.listening=new Set(t.client.controller);for(const e of Object.keys(t.teams))this.teams[e]=new n.EditWrapper(t.teams[e]);this.all=this.teams.all,this.clients={};for(const[e,s]of Object.entries(t.clients))e!=this.uuid&&(this.clients[e]=new l.MultyxClientObject(this,new n.EditWrapper(s),[e],!1));const e=new l.MultyxClientObject(this,new n.EditWrapper(t.client.self),[this.uuid],!0);this.self=e,this.clients[this.uuid]=e;for(const[e,s]of Object.entries(t.constraintTable))(this.uuid==e?this.self:this.teams[e])[n.Unpack](s)}parseSelf(t){if("controller"==t.property)this.controller.listening=new Set(t.data);else if("uuid"==t.property)this.uuid=t.data;else if("constraint"==t.property){let e=this.uuid==t.data.path[0]?this.self:this.teams[t.data.path[0]];for(const s of t.data.path.slice(1))e=null==e?void 0:e[s];if(void 0===e)return;e[n.Unpack]({[t.data.name]:t.data.args})}else"space"==t.property&&(this.space=t.data,this.updateSpace())}updateSpace(){"default"!=this.space?document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display=t.dataset.multyxSpace==this.space?"block":"none",t.style.pointerEvents=t.dataset.multyxSpace==this.space?"auto":"none"})):document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display="block",t.style.pointerEvents="auto"}))}}a.Start=Symbol("start"),a.Connection=Symbol("connection"),a.Disconnect=Symbol("disconnect"),a.Edit=Symbol("edit"),a.Native=Symbol("native"),a.Custom=Symbol("custom"),a.Any=Symbol("any"),e.default=a})(),i.default})()));
1
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Multyx=e():t.Multyx=e()}(self,(()=>(()=>{"use strict";var t={376:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Controller=void 0;const i=s(210);e.Controller=class{constructor(t){this.listening=new Set,this.ws=t,this.preventDefault=!1,this.keys={},this.mouse={x:NaN,y:NaN,down:!1,centerX:0,centerY:0,scaleX:1,scaleY:1},document.addEventListener("keydown",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();this.keys[e]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:e}),this.keys[t.code]&&this.listening.has("keyhold")&&this.relayInput("keyhold",{code:t.code}),this.listening.has(e)&&!this.keys[e]&&this.relayInput("keydown",{code:t.key}),this.listening.has(t.code)&&!this.keys[t.code]&&this.relayInput("keydown",{code:t.code}),this.keys[e]=!0,this.keys[t.code]=!0})),document.addEventListener("keyup",(t=>{this.preventDefault&&t.preventDefault;const e=t.key.toLowerCase();delete this.keys[e],delete this.keys[t.code],this.listening.has(e)&&this.relayInput("keyup",{code:e}),this.listening.has(t.code)&&this.relayInput("keyup",{code:t.code})})),document.addEventListener("mousedown",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!0,this.listening.has("mousedown")&&this.relayInput("mousedown",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mouseup",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.mouse.down=!1,this.listening.has("mouseup")&&this.relayInput("mouseup",{x:this.mouse.x,y:this.mouse.y})})),document.addEventListener("mousemove",(t=>{if(this.preventDefault&&t.preventDefault,this.mouseGetter){const t=this.mouseGetter();this.mouse.x=t.x,this.mouse.y=t.y}else this.mouse.x=(t.clientX-this.mouse.centerX)/this.mouse.scaleX,this.mouse.y=(t.clientY-this.mouse.centerY)/this.mouse.scaleY;this.listening.has("mousemove")&&this.relayInput("mousemove",{x:this.mouse.x,y:this.mouse.y})}))}mapCanvasPosition(t,e){const s="top"in e,i="bottom"in e,n="left"in e,o="right"in e,r=e.anchor,l=t.getBoundingClientRect(),h=(t,...e)=>{const s=t?"Cannot include value for ":"Must include value for ",i=1==e.length?e[0]:e.slice(0,-1).join(", ")+(t?" and ":" or ")+e.slice(-1)[0],n=r?" if anchoring at "+r:" if not anchoring";console.error(s+i+n)},a=l.width/l.height,u=l.height/l.width;if((Number.isNaN(a)||Number.isNaN(u))&&console.error("Canvas element bounding box is flat, canvas must be present on the screen"),r){if("center"==r){if(s&&i&&e.top!==-e.bottom||n&&o&&e.left!==-e.right)return h(!0,"top","bottom","left","right");s?(e.left=n?e.left:o?-e.right:-Math.abs(a*e.top),e.right=n?-e.left:o?e.right:Math.abs(a*e.top),e.bottom=-e.top):i?(e.left=n?e.left:o?-e.right:-Math.abs(a*e.bottom),e.right=n?-e.left:o?e.right:Math.abs(a*e.bottom),e.top=-e.bottom):n?(e.top=s?e.top:i?-e.bottom:-Math.abs(u*e.left),e.bottom=s?-e.top:i?e.bottom:Math.abs(u*e.left),e.right=-e.left):o&&(e.top=s?e.top:i?-e.bottom:-Math.abs(u*e.right),e.bottom=s?-e.top:i?e.bottom:Math.abs(u*e.right),e.left=-e.right)}else if("bottom"==r){if(!n&&!o&&!s)return h(!1,"left","right","top");if(e.bottom)return h(!0,"bottom");e.bottom=0,n?(e.top=Math.abs(u*e.left*2),e.right=-e.left):o?(e.top=Math.abs(u*e.right*2),e.left=-e.right):(e.left=-Math.abs(a*e.top/2),e.right=-e.left)}else if("top"==r){if(!n&&!o&&!i)return h(!1,"left","right","bottom");if(e.top)return h(!0,"top");e.top=0,n?(e.bottom=Math.abs(u*e.left*2),e.right=-e.left):o?(e.bottom=Math.abs(u*e.right*2),e.left=-e.right):(e.left=-Math.abs(a*e.bottom/2),e.right=-e.left)}else if("left"==r){if(!s&&!i&&!o)return h(!1,"top","bottom","right");if(n)return h(!0,"left");e.left=0,s?(e.right=-Math.abs(a*e.top*2),e.bottom=-e.top):i?(e.right=Math.abs(a*e.bottom*2),e.top=-e.bottom):(e.top=-Math.abs(u*e.right/2),e.bottom=-e.top)}else if("right"==r){if(!s&&!i&&!n)return h(!1,"top","bottom","left");if(o)return h(!0,"right");e.right=0,s?(e.left=-Math.abs(a*e.top*2),e.bottom=-e.top):i?(e.left=Math.abs(a*e.bottom*2),e.top=-e.bottom):(e.top=-Math.abs(u*e.right/2),e.bottom=-e.top)}else if("topleft"==r){if(!o&&!i)return h(!1,"right","bottom");if(n||s)return h(!0,"left","top");e.left=e.top=0,o?e.bottom=Math.abs(u*e.right):e.right=Math.abs(a*e.bottom)}else if("topright"==r){if(!n&&!i)return h(!1,"left","bottom");if(o||s)return h(!0,"right","top");e.right=e.top=0,n?e.bottom=Math.abs(u*e.left):e.left=Math.abs(a*e.bottom)}else if("bottomleft"==r){if(!o&&!s)return h(!1,"right","top");if(i||n)return h(!0,"bottom","left");e.left=e.bottom=0,o?e.top=Math.abs(u*e.right):e.right=Math.abs(a*e.top)}else if("bottomright"==r){if(!s&&!n)return h(!1,"top","left");if(o||i)return h(!0,"bottom","right");e.right=e.bottom=0,n?e.top=Math.abs(u*e.left):e.left=Math.abs(a*e.top)}}else{if(!s&&!i)return h(!1,"top","bottom");if(i?s||(e.top=e.bottom-t.height):e.bottom=e.top+t.height,!n&&!o)return h(!1,"left","right");o?n||(e.left=e.right-t.width):e.right=e.left+t.width}const c=t.getContext("2d");null==c||c.setTransform(1,0,0,1,0,0),t.width=Math.floor(Math.abs(e.right-e.left)),t.height=Math.floor(Math.abs(e.bottom-e.top)),e.right<e.left&&(null==c||c.scale(-1,1)),e.top>e.bottom&&(null==c||c.scale(1,-1)),null==c||c.translate(-e.left,-e.top)}mapMousePosition(t,e,s=document.body,i=1,n=i){const o=window.innerWidth/(s instanceof HTMLCanvasElement?s.width:s.clientWidth),r=window.innerHeight/(s instanceof HTMLCanvasElement?s.height:s.clientHeight),l=s.getBoundingClientRect();this.mouse.centerX=l.left+t*o,this.mouse.centerY=l.top+e*r,this.mouse.scaleX=i*o,this.mouse.scaleY=n*r}mapMouseToCanvas(t){const e=t.getContext("2d"),s=null==e?void 0:e.getTransform(),i=t.getBoundingClientRect(),n=i.width/t.width,o=i.height/t.height;this.mouse.centerX=i.left+(null==s?void 0:s.e)*n,this.mouse.centerY=i.top+(null==s?void 0:s.f)*o,this.mouse.scaleX=n*(null==s?void 0:s.a),this.mouse.scaleY=o*(null==s?void 0:s.d)}setMouseAs(t){this.mouseGetter=t}relayInput(t,e){if(1!==this.ws.readyState)throw new Error("Websocket connection is "+(2==this.ws.readyState?"closing":"closed"));this.ws.send(i.Message.Native(Object.assign({instruction:"input",input:t},e?{data:e}:{})))}}},34:function(t,e,s){var i=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.MultyxClientValue=e.MultyxClientObject=e.MultyxClientList=void 0,e.IsMultyxClientItem=function(t){return t instanceof n.default||t instanceof o.default||t instanceof r.default};const n=i(s(70));e.MultyxClientList=n.default;const o=i(s(614));e.MultyxClientObject=o.default;const r=i(s(501));e.MultyxClientValue=r.default},70:function(t,e,s){var i,n=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});const o=s(34),r=s(787),l=n(s(735)),h=s(210);class a{addEditCallback(t){this.editCallbacks.push(t)}get value(){var t;const e=[];for(let s=0;s<this.length;s++)e[s]=null===(t=this.get(s))||void 0===t?void 0:t.value;return e}get length(){return this.list.length}set length(t){this.list.length=t}handleShiftOperation(t,e){const s=t>=0?e>=0?"right":"left":0==e?"reverse":e<0?"length":"unknown";switch(s){case"reverse":for(let t=0;t<Math.floor(this.length/2);t++){const e=this.list[t];this.list[t]=this.list[this.length-1-t],this.list[this.length-1-t]=e}break;case"left":for(let s=t;s<this.length;s++)s+e<0||(this.list[s+e]=this.list[s]);break;case"right":for(let s=this.length-1;s>=t;s--)this.list[s+e]=this.list[s];break;case"length":this.length+=e;break;default:this.multyx.options.verbose&&console.error("Unknown shift operation: "+s)}}constructor(t,e,s=[],n){this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.list=[],this.propertyPath=s,this.multyx=t,this.editable=n;const o=e instanceof r.EditWrapper;e instanceof a&&(e=e.value),e instanceof r.EditWrapper&&(e=e.value);for(let t=0;t<e.length;t++)this.set(t,o?new r.EditWrapper(e[t]):e[t]);return new Proxy(this,{has:(t,e)=>"number"==typeof e?t.has(e):e in t,get:(t,e)=>e in t?t[e]:(isNaN(parseInt(e))||(e=parseInt(e)),t.get(e)),set:(t,e,s)=>e in t?(t[e]=s,!0):!!t.set(e,s),deleteProperty:(t,e)=>"number"==typeof e&&t.delete(e)})}has(t){return t>=0&&t<this.length}get(t){if("number"==typeof t)return this.list[t];if(0==t.length)return this;if(1==t.length)return this.list[parseInt(t[0])];const e=this.list[parseInt(t[0])];return!e||e instanceof o.MultyxClientValue?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientList with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if("shift"==t[0]&&e instanceof r.EditWrapper)return this.handleShiftOperation(parseInt(t[1]),e.value),!0;if(1==t.length)return this.set(parseInt(t[0]),e);let s=this.get(parseInt(t[0]));return(s instanceof o.MultyxClientValue||null==s)&&(this.set(parseInt(t[0]),new r.EditWrapper({})),s=this.get(parseInt(t[0]))),s.set(t.slice(1),e)}set(t,e){var s,i;if(Array.isArray(t))return this.recursiveSet(t,e);const n=this.get(t),h=e instanceof r.EditWrapper,a=h||this.editable;if((h||(0,o.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,h);if(this.list[t]instanceof o.MultyxClientValue&&"object"!=typeof e)return this.list[t].set(h?new r.EditWrapper(e):e);if(!a)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.list[t]=new((0,l.default)(e))(this.multyx,h?new r.EditWrapper(e):e,[...this.propertyPath,t.toString()],this.editable);const u=Symbol.for("_"+this.propertyPath.join(".")+"."+t);this.multyx.events.has(u)&&this.multyx[r.Done].push(...null!==(i=null===(s=this.multyx.events.get(u))||void 0===s?void 0:s.map((e=>()=>e(this.list[t]))))&&void 0!==i?i:[]);for(const e of this.editCallbacks)this.multyx[r.Add]((()=>e(t,this.get(t),n)));return!0}delete(t,e=!1){const s=this.get(t);if("string"==typeof t&&(t=parseInt(t)),!this.editable&&!e)return this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1;delete this.list[t];for(const e of this.editCallbacks)this.multyx[r.Add]((()=>e(t,void 0,s)));return e||this.multyx.ws.send(h.Message.Native({instruction:"edit",path:[...this.propertyPath,t.toString()],value:void 0})),!0}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}push(...t){for(const e of t)this.set(this.length,e);return this.length}pop(){if(0===this.length)return;const t=this.get(this.length);return this.delete(this.length),t}unshift(...t){for(let e=this.length-1;e>=0;e--)e>=t.length?this.set(e,this.get(e-t.length)):this.set(e,t[e]);return this.length}shift(){if(0==this.length)return;this.length--;const t=this.get(0);for(let t=0;t<this.length;t++)this.set(t,this.get(t+1));return t}slice(t,e){return this.list.slice(t,e)}splice(t,e,...s){return this.list.splice(t,null!=e?e:0,...s)}setSplice(t,e,...s){void 0===e&&(e=this.length-t);let i=s.length-e;if(i>0)for(let s=this.length-1;s>=t+e;s--)this.set(s+i,this.get(s));else if(i<0){for(let s=t+e;s<this.length;s++)this.set(s+i,this.get(s));const s=this.length;for(let t=s+i;t<s;t++)this.set(t,void 0)}for(let e=t;e<s.length;e++)this.set(e,s[e])}filter(t){return this.list.filter(((e,s)=>t(e,s,this)))}setFilter(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));let s=0;for(let t=0;t<e.length;t++)e[t]&&s&&this.set(t-s,this.get(t)),e[t]||s--}map(t){const e=[];for(let s=0;s<this.length;s++)e.push(t(this.get(s),s,this));return e}flat(){return this.list.flat()}setFlat(){for(let t=0;t<this.length;t++){const e=this.get(t);if(e instanceof a)for(let s=0;s<e.length;s++)t++,this.set(t,e[s])}}reduce(t,e){for(let s=0;s<this.length;s++)e=t(e,this.get(s),s,this);return e}reduceRight(t,e){for(let s=this.length-1;s>=0;s--)e=t(e,this.get(s),s,this);return e}reverse(){let t=this.length-1;for(let e=0;e<t;e++){const s=this.get(e),i=this.get(t);this.set(e,i),this.set(t,s)}return this}forEach(t){for(let e=0;e<this.length;e++)t(this.get(e),e,this)}every(t){for(let e=0;e<this.length;e++)if(!t(this.get(e),e,this))return!1;return!0}some(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return!0;return!1}find(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return this.get(e)}findIndex(t){for(let e=0;e<this.length;e++)if(t(this.get(e),e,this))return e;return-1}entries(){const t=[];for(let e=0;e<this.length;e++)t.push([this.get(e),e]);return t}keys(){return Array(this.length).fill(0).map(((t,e)=>e))}[r.Edit](){}[r.Unpack](t){var e;for(let s=0;s<this.length;s++)null===(e=this.get(s))||void 0===e||e[r.Unpack](t[s])}[Symbol.iterator](){const t=[];for(let e=0;e<this.length;e++)t[e]=this.get(e);return t[Symbol.iterator]()}}i=Symbol.toPrimitive,e.default=a},614:function(t,e,s){var i=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});const n=s(210),o=s(787),r=s(34),l=i(s(735)),h=i(s(501));class a{get value(){const t={};for(const e in this.object)t[e]=this.object[e];return t}addEditCallback(t){this.editCallbacks.push(t)}[o.Edit](t,e){var s;1!=t.length?(0==t.length&&this.multyx.options.verbose&&console.error("Update path is empty. Attempting to edit MultyxClientObject with no path."),this.has(t[0])||this.set(t[0],new o.EditWrapper({})),null===(s=this.get(t[0]))||void 0===s||s[o.Edit](t.slice(1),e)):this.set(t[0],new o.EditWrapper(e))}constructor(t,e,s=[],i){this.editCallbacks=[],this.object={},this.propertyPath=s,this.multyx=t,this.editable=i;const n=e instanceof o.EditWrapper;e instanceof a&&(e=e.value),e instanceof o.EditWrapper&&(e=e.value);for(const t in e)this.set(t,n?new o.EditWrapper(e[t]):e[t]);if(this.constructor===a)return new Proxy(this,{has:(t,e)=>t.has(e),get:(t,e)=>e in t?t[e]:t.get(e),set:(t,e,s)=>e in t?(t[e]=s,!0):t.set(e,s),deleteProperty:(t,e)=>t.delete(e,!1)})}has(t){return t in this.object}get(t){if("string"==typeof t)return this.object[t];if(0==t.length)return this;if(1==t.length)return this.object[t[0]];const e=this.object[t[0]];return!e||e instanceof h.default?void 0:e.get(t.slice(1))}recursiveSet(t,e){if(0==t.length)return this.multyx.options.verbose&&console.error(`Attempting to edit MultyxClientObject with no path. Setting '${this.propertyPath.join(".")}' to ${e}`),!1;if(1==t.length)return this.set(t[0],e);let s=this.get(t[0]);return(s instanceof h.default||null==s)&&(isNaN(parseInt(t[1]))?(this.set(t[0],new o.EditWrapper({})),s=this.get(t[0])):(this.set(t[0],new o.EditWrapper([])),s=this.get(t[0]))),s.set(t.slice(1),e)}set(t,e){var s,i;if(Array.isArray(t))return this.recursiveSet(t,e);const n=e instanceof o.EditWrapper,a=n||this.editable;if((n||(0,r.IsMultyxClientItem)(e))&&(e=e.value),void 0===e)return this.delete(t,n);if(this.object[t]instanceof h.default&&"object"!=typeof e)return this.object[t].set(n?new o.EditWrapper(e):e);if(!a)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")+"."+t}' to ${e}`),!1;this.object[t]=new((0,l.default)(e))(this.multyx,n?new o.EditWrapper(e):e,[...this.propertyPath,t],this.editable);const u=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return this.multyx.events.has(u)&&this.multyx[o.Done].push(...null!==(i=null===(s=this.multyx.events.get(u))||void 0===s?void 0:s.map((e=>()=>e(this.object[t]))))&&void 0!==i?i:[]),!0}delete(t,e=!1){return this.editable||e?(delete this.object[t],e||this.multyx.ws.send(n.Message.Native({instruction:"edit",path:[...this.propertyPath,t],value:void 0})),!0):(this.multyx.options.verbose&&console.error(`Attempting to delete property that is not editable. Deleting '${this.propertyPath.join(".")+"."+t}'`),!1)}keys(){return Object.keys(this.object)}values(){return Object.values(this.object)}entries(){const t=[];for(let e in this.object)t.push([e,this.get(e)]);return t}await(t){if(this.has(t))return Promise.resolve(this.get(t));const e=Symbol.for("_"+this.propertyPath.join(".")+"."+t);return new Promise((t=>this.multyx.on(e,t)))}[o.Unpack](t){var e;for(const s in t)null===(e=this.object[s])||void 0===e||e[o.Unpack](t[s])}}e.default=a},735:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t){return Array.isArray(t)?s(70).default:"object"==typeof t?s(614).default:s(501).default}},501:(t,e,s)=>{var i;Object.defineProperty(e,"__esModule",{value:!0});const n=s(210),o=s(787);class r{get value(){return this.readModifiers.reduce(((t,e)=>e(t)),this._value)}set value(t){this._value=t}addReadModifier(t){this.readModifiers.push(t)}addEditCallback(t){this.editCallbacks.push(t)}[o.Edit](t,e){0==t.length&&this.set(new o.EditWrapper(e))}constructor(t,e,s=[],n){var r,l;this.readModifiers=[],this.editCallbacks=[],this.toString=()=>this.value.toString(),this.valueOf=()=>this.value,this[i]=()=>this.value,this.propertyPath=s,this.editable=n,this.multyx=t,this.constraints={},this.set(e);const h=Symbol.for("_"+this.propertyPath.join("."));this.multyx.events.has(h)&&this.multyx[o.Done].push(...null!==(l=null===(r=this.multyx.events.get(h))||void 0===r?void 0:r.map((t=>()=>t(this.value))))&&void 0!==l?l:[])}set(t){if(t instanceof o.EditWrapper){const e=this.value;return this.value=t.value,this.editCallbacks.forEach((s=>s(t.value,e))),!0}if(!this.editable)return this.multyx.options.verbose&&console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join(".")}' to ${t}`),!1;let e=t;for(const s in this.constraints)if(e=(0,this.constraints[s])(e),null===e)return this.multyx.options.verbose&&console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join(".")}' to ${t}, stopped by constraint '${s}'`),!1;return this.value===e?(this.value=e,!0):(this.value=e,this.multyx.ws.send(n.Message.Native({instruction:"edit",path:this.propertyPath,value:e})),!0)}bindElement(t){this.addEditCallback(((e,s)=>{e!==s&&(t.innerText=e.toString())}))}[o.Unpack](t){for(const[e,s]of Object.entries(t)){const t=(0,o.BuildConstraint)(e,s);t&&(this.constraints[e]=t)}}}i=Symbol.toPrimitive,e.default=r},210:(t,e)=>{function s(t){let e,s;if("edit"==t.instruction?(e=0,s=[t.path.join("."),JSON.stringify(t.value)]):"input"==t.instruction?(e=1,s=[t.input,JSON.stringify(t.data)]):"resp"==t.instruction&&(e=2,s=[t.name,JSON.stringify(t.response)]),!s||!e)return"";let i=e.toString();for(let t=0;t<s.length;t++)i+=s[t].replace(/;/g,";_"),t<s.length-1&&(i+=";,");return JSON.stringify([i])}Object.defineProperty(e,"__esModule",{value:!0}),e.Message=void 0,e.UncompressUpdate=function(t){const[e,...s]=t.split(/;,/),i=e[0],n=e.slice(1).replace(/;_/g,";"),o=s.map((t=>t.replace(/;_/g,";"))).map((t=>"undefined"==t?void 0:JSON.parse(t)));return"0"==i?{instruction:"edit",team:!1,path:n.split("."),value:o[0]}:"1"==i?{instruction:"edit",team:!0,path:n.split("."),value:o[0]}:"2"==i?{instruction:"self",property:"controller",data:JSON.parse(n)}:"3"==i?{instruction:"self",property:"uuid",data:JSON.parse(n)}:"4"==i?{instruction:"self",property:"constraint",data:JSON.parse(n)}:"9"==i?{instruction:"self",property:"space",data:JSON.parse(n)}:"5"==i?{instruction:"resp",name:n,response:o[0]}:"6"==i?{instruction:"conn",uuid:n,publicData:o[0]}:"7"==i?{instruction:"dcon",clientUUID:n}:"8"==i?{instruction:"init",client:JSON.parse(n),tps:o[0],constraintTable:o[1],clients:o[2],teams:o[3],space:o[4]}:void 0},e.CompressUpdate=s;class i{constructor(t,e,s=!1){this.name=t,this.data=e,this.time=Date.now(),this.native=s}static BundleOperations(t,e){return Array.isArray(e)||(e=[e]),JSON.stringify(new i("_",{operations:e,deltaTime:t}))}static Native(t){return s(t)}static Parse(t){var e,s;const n=JSON.parse(t);return Array.isArray(n)?new i("_",n,!0):new i(null!==(e=n.name)&&void 0!==e?e:"",null!==(s=n.data)&&void 0!==s?s:"",!1)}static Create(t,e){if(0==t.length)throw new Error("Multyx message cannot have empty name");if("_"==t[0]&&(t="_"+t),"function"==typeof e)throw new Error("Multyx data must be JSON storable");return JSON.stringify(new i(t,e))}}e.Message=i},944:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DefaultOptions=void 0,e.DefaultOptions={port:8443,secure:!1,uri:"localhost",verbose:!1,logUpdateFrame:!1}},787:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.EditWrapper=e.Edit=e.Add=e.Done=e.Unpack=void 0,e.Interpolate=function(t,e,s){let i={value:t[e],time:Date.now()},n={value:t[e],time:Date.now()};Object.defineProperty(t,e,{get:()=>{const t=n.time-i.time;let e=s[0],o=s[0];for(const i of s)t>i.time&&i.time>e.time&&(e=i),t<i.time&&i.time<o.time&&(o=i);const r=(t-e.time)/(o.time-e.time),l=e.progress+r*(o.progress-e.progress);return Number.isNaN(l)?i.value:n.value*l+i.value*(1-l)},set:t=>Date.now()-n.time<10?(n.value=t,!0):(i=Object.assign({},n),n={value:t,time:Date.now()},!0)})},e.BuildConstraint=function(t,e){return"min"==t?t=>t>=e[0]?t:e[0]:"max"==t?t=>t<=e[0]?t:e[0]:"int"==t?t=>Math.floor(t):"ban"==t?t=>e.includes(t)?null:t:"disabled"==t?t=>e[0]?null:t:t=>t},e.Unpack=Symbol("unpack"),e.Done=Symbol("done"),e.Add=Symbol("add"),e.Edit=Symbol("edit"),e.EditWrapper=class{constructor(t){this.value=t}}}},e={};function s(i){var n=e[i];if(void 0!==n)return n.exports;var o=e[i]={exports:{}};return t[i].call(o.exports,o,o.exports,s),o.exports}var i={};return(()=>{var t,e=i;const n=s(210),o=s(787),r=s(376),l=s(34),h=s(944);class a{constructor(e={},s){var i;if(this[t]=[],this.options=Object.assign(Object.assign({},h.DefaultOptions),e),!this.options.uri)throw new Error("URI is required");const o=`ws${this.options.secure?"s":""}://${this.options.uri.split("/")[0]}:${this.options.port}/${null!==(i=this.options.uri.split("/")[1])&&void 0!==i?i:""}`;this.ws=new WebSocket(o),this.ping=0,this.space="default",this.events=new Map,this.self={},this.tps=0,this.all={},this.teams=new l.MultyxClientObject(this,{},[],!0),this.clients={},this.controller=new r.Controller(this.ws),null==s||s(),this.ws.onmessage=t=>{var e,s,i,o;const r=n.Message.Parse(t.data);this.ping=2*(Date.now()-r.time),r.native?(this.parseNativeEvent(r),null===(e=this.events.get(a.Native))||void 0===e||e.forEach((t=>t(r)))):(null===(s=this.events.get(r.name))||void 0===s||s.forEach((t=>{const e=t(r.data);void 0!==e&&this.send(r.name,e)})),null===(i=this.events.get(a.Custom))||void 0===i||i.forEach((t=>t(r)))),null===(o=this.events.get(a.Any))||void 0===o||o.forEach((t=>t(r)))}}on(t,e){var s;const i=null!==(s=this.events.get(t))&&void 0!==s?s:[];i.push(e),this.events.set(t,i)}send(t,e){"_"===t[0]&&(t="_"+t);const s={instruction:"resp",name:t,response:e};this.ws.send(n.Message.Native(s))}await(t,e){return this.send(t,e),new Promise((e=>this.events.set(Symbol.for("_"+t),[e])))}loop(t,e){if(e)this.on(a.Start,(()=>setInterval(t,Math.round(1e3/e))));else{const e=()=>{t(),requestAnimationFrame(e)};this.on(a.Start,(()=>requestAnimationFrame(e)))}}[(t=o.Done,o.Add)](t){this[o.Done].push(t)}parseNativeEvent(t){var e,s,i,r,h;t.data=t.data.map(n.UncompressUpdate),this.options.logUpdateFrame&&console.log(t.data);for(const n of t.data)switch(n.instruction){case"init":this.initialize(n);for(const t of null!==(e=this.events.get(a.Start))&&void 0!==e?e:[])this[o.Done].push((()=>t(n)));this.events.has(a.Start)&&(this.events.get(a.Start).length=0);break;case"edit":if(1==n.path.length)n.team?this.teams.set(n.path[0],new o.EditWrapper(n.value)):this.clients[n.path[0]]=new l.MultyxClientObject(this,new o.EditWrapper(n.value),[n.path[0]],!1);else{const t=n.team?this.teams.get(n.path[0]):this.clients[n.path[0]];if(!t)return;t.set(n.path.slice(1),new o.EditWrapper(n.value))}for(const t of null!==(s=this.events.get(a.Edit))&&void 0!==s?s:[])this[o.Done].push((()=>t(n)));break;case"self":this.parseSelf(n);break;case"conn":this.clients[n.uuid]=new l.MultyxClientObject(this,n.data,[n.uuid],!1);for(const t of null!==(i=this.events.get(a.Connection))&&void 0!==i?i:[])this[o.Done].push((()=>t(this.clients[n.uuid])));break;case"dcon":for(const t of null!==(r=this.events.get(a.Disconnect))&&void 0!==r?r:[]){const e=this.clients[n.client].value;this[o.Done].push((()=>t(e)))}delete this.clients[n.client];break;case"resp":{const t=null===(h=this.events.get(Symbol.for("_"+n.name)))||void 0===h?void 0:h[0];this.events.delete(Symbol.for("_"+n.name)),t&&this[o.Done].push((()=>t(n.response)));break}default:this.options.verbose&&console.error("Server error: Unknown native Multyx instruction")}this[o.Done].forEach((t=>t())),this[o.Done].length=0}initialize(t){this.tps=t.tps,this.uuid=t.client.uuid,this.joinTime=t.client.joinTime,this.controller.listening=new Set(t.client.controller);for(const e of Object.keys(t.teams))this.teams[e]=new o.EditWrapper(t.teams[e]);this.all=this.teams.all,this.clients={};for(const[e,s]of Object.entries(t.clients))e!=this.uuid&&(this.clients[e]=new l.MultyxClientObject(this,new o.EditWrapper(s),[e],!1));const e=new l.MultyxClientObject(this,new o.EditWrapper(t.client.self),[this.uuid],!0);this.self=e,this.clients[this.uuid]=e;for(const[e,s]of Object.entries(t.constraintTable))(this.uuid==e?this.self:this.teams[e])[o.Unpack](s)}parseSelf(t){if("controller"==t.property)this.controller.listening=new Set(t.data);else if("uuid"==t.property)this.uuid=t.data;else if("constraint"==t.property){let e=this.uuid==t.data.path[0]?this.self:this.teams[t.data.path[0]];for(const s of t.data.path.slice(1))e=null==e?void 0:e[s];if(void 0===e)return;e[o.Unpack]({[t.data.name]:t.data.args})}else"space"==t.property&&(this.space=t.data,this.updateSpace())}updateSpace(){"default"!=this.space?document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display=t.dataset.multyxSpace==this.space?"block":"none",t.style.pointerEvents=t.dataset.multyxSpace==this.space?"auto":"none"})):document.querySelectorAll("[data-multyx-space]").forEach((t=>{t.style.display="block",t.style.pointerEvents="auto"}))}}a.Start=Symbol("start"),a.Connection=Symbol("connection"),a.Disconnect=Symbol("disconnect"),a.Edit=Symbol("edit"),a.Native=Symbol("native"),a.Custom=Symbol("custom"),a.Any=Symbol("any"),e.default=a})(),i.default})()));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multyx-client",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Framework designed to simplify the creation of multiplayer browser games by addressing the complexities of managing server-client communication, shared state, and input handling",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/controller.ts CHANGED
@@ -159,32 +159,32 @@ export class Controller {
159
159
  // mb bruh jus trust it works
160
160
  if(!a) {
161
161
  if(!t && !b) return error(false, 'top', 'bottom');
162
- else if(!b) position.bottom = position.top + canvas.height;
163
- else if(!t) position.top = position.bottom - canvas.height;
162
+ else if(!b) position.bottom = position.top! + canvas.height;
163
+ else if(!t) position.top = position.bottom! - canvas.height;
164
164
 
165
165
  if(!l && !r) return error(false, 'left', 'right');
166
- else if(!r) position.right = position.left + canvas.width;
167
- else if(!l) position.left = position.right - canvas.width;
166
+ else if(!r) position.right = position.left! + canvas.width;
167
+ else if(!l) position.left = position.right! - canvas.width;
168
168
  } else if(a == 'center') {
169
- if(t && b && position.top !== -position.bottom
170
- || l && r && position.left !== -position.right) return error(true, 'top', 'bottom', 'left', 'right');
169
+ if(t && b && position.top !== -position.bottom!
170
+ || l && r && position.left !== -position.right!) return error(true, 'top', 'bottom', 'left', 'right');
171
171
 
172
172
  if(t) {
173
- position.left = l ? position.left : r ? -position.right : -Math.abs(wToH * position.top);
174
- position.right = l ? -position.left : r ? position.right : Math.abs(wToH * position.top);
175
- position.bottom = -position.top;
173
+ position.left = l ? position.left! : r ? -position.right! : -Math.abs(wToH * position.top!);
174
+ position.right = l ? -position.left! : r ? position.right! : Math.abs(wToH * position.top!);
175
+ position.bottom = -position.top!;
176
176
  } else if(b) {
177
- position.left = l ? position.left : r ? -position.right : -Math.abs(wToH * position.bottom);
178
- position.right = l ? -position.left : r ? position.right : Math.abs(wToH * position.bottom);
179
- position.top = -position.bottom;
177
+ position.left = l ? position.left! : r ? -position.right! : -Math.abs(wToH * position.bottom!);
178
+ position.right = l ? -position.left! : r ? position.right! : Math.abs(wToH * position.bottom!);
179
+ position.top = -position.bottom!;
180
180
  } else if(l) {
181
- position.top = t ? position.top : b ? -position.bottom : -Math.abs(hToW * position.left);
182
- position.bottom = t ? -position.top : b ? position.bottom : Math.abs(hToW * position.left);
183
- position.right = -position.left;
181
+ position.top = t ? position.top! : b ? -position.bottom! : -Math.abs(hToW * position.left!);
182
+ position.bottom = t ? -position.top! : b ? position.bottom! : Math.abs(hToW * position.left!);
183
+ position.right = -position.left!;
184
184
  } else if(r) {
185
- position.top = t ? position.top : b ? -position.bottom : -Math.abs(hToW * position.right);
186
- position.bottom = t ? -position.top : b ? position.bottom : Math.abs(hToW * position.right);
187
- position.left = -position.right;
185
+ position.top = t ? position.top! : b ? -position.bottom! : -Math.abs(hToW * position.right!);
186
+ position.bottom = t ? -position.top! : b ? position.bottom! : Math.abs(hToW * position.right!);
187
+ position.left = -position.right!;
188
188
  }
189
189
  } else if(a == 'bottom') {
190
190
  if(!l && !r && !t) return error(false, 'left', 'right', 'top');
@@ -192,14 +192,14 @@ export class Controller {
192
192
  position.bottom = 0;
193
193
 
194
194
  if(l) {
195
- position.top ??= Math.abs(hToW * position.left * 2);
196
- position.right ??= -position.left;
195
+ position.top = Math.abs(hToW * position.left! * 2);
196
+ position.right = -position.left!;
197
197
  } else if(r) {
198
- position.top ??= Math.abs(hToW * position.right * 2);
199
- position.left ??= -position.right;
198
+ position.top = Math.abs(hToW * position.right! * 2);
199
+ position.left = -position.right!;
200
200
  } else {
201
- position.left = -Math.abs(wToH * position.top / 2);
202
- position.right = -position.left;
201
+ position.left = -Math.abs(wToH * position.top! / 2);
202
+ position.right = -position.left!;
203
203
  }
204
204
  } else if(a == 'top') {
205
205
  if(!l && !r && !b) return error(false, 'left', 'right', 'bottom');
@@ -207,14 +207,14 @@ export class Controller {
207
207
  position.top = 0;
208
208
 
209
209
  if(l) {
210
- position.bottom ??= Math.abs(hToW * position.left * 2);
211
- position.right ??= -position.left;
210
+ position.bottom = Math.abs(hToW * position.left! * 2);
211
+ position.right = -position.left!;
212
212
  } else if(r) {
213
- position.bottom ??= Math.abs(hToW * position.right * 2);
214
- position.left ??= -position.right;
213
+ position.bottom = Math.abs(hToW * position.right! * 2);
214
+ position.left = -position.right!;
215
215
  } else {
216
- position.left = -Math.abs(wToH * position.bottom / 2);
217
- position.right = -position.left;
216
+ position.left = -Math.abs(wToH * position.bottom! / 2);
217
+ position.right = -position.left!;
218
218
  }
219
219
  } else if(a == 'left') {
220
220
  if(!t && !b && !r) return error(false, 'top', 'bottom', 'right');
@@ -222,14 +222,14 @@ export class Controller {
222
222
  position.left = 0;
223
223
 
224
224
  if(t) {
225
- position.right ??= -Math.abs(wToH * position.top * 2);
226
- position.bottom ??= -position.top;
225
+ position.right = -Math.abs(wToH * position.top! * 2);
226
+ position.bottom = -position.top!;
227
227
  } else if(b) {
228
- position.right ??= Math.abs(wToH * position.bottom * 2);
229
- position.top ??= -position.bottom;
228
+ position.right = Math.abs(wToH * position.bottom! * 2);
229
+ position.top = -position.bottom!;
230
230
  } else {
231
- position.top = -Math.abs(hToW * position.right / 2);
232
- position.bottom = -position.top;
231
+ position.top = -Math.abs(hToW * position.right! / 2);
232
+ position.bottom = -position.top!;
233
233
  }
234
234
  } else if(a == 'right') {
235
235
  if(!t && !b && !l) return error(false, 'top', 'bottom', 'left');
@@ -237,54 +237,54 @@ export class Controller {
237
237
  position.right = 0;
238
238
 
239
239
  if(t) {
240
- position.left ??= -Math.abs(wToH * position.top * 2);
241
- position.bottom ??= -position.top;
240
+ position.left = -Math.abs(wToH * position.top! * 2);
241
+ position.bottom = -position.top!;
242
242
  } else if(b) {
243
- position.left ??= Math.abs(wToH * position.bottom * 2);
244
- position.top ??= -position.bottom;
243
+ position.left = Math.abs(wToH * position.bottom! * 2);
244
+ position.top = -position.bottom!;
245
245
  } else {
246
- position.top = -Math.abs(hToW * position.right / 2);
247
- position.bottom = -position.top;
246
+ position.top = -Math.abs(hToW * position.right! / 2);
247
+ position.bottom = -position.top!;
248
248
  }
249
249
  } else if(a == 'topleft') {
250
250
  if(!r && !b) return error(false, 'right', 'bottom');
251
251
  if(l || t) return error(true, 'left', 'top');
252
252
  position.left = position.top = 0;
253
253
 
254
- if(r) position.bottom = Math.abs(hToW * position.right);
255
- else position.right = Math.abs(wToH * position.bottom);
254
+ if(r) position.bottom = Math.abs(hToW * position.right!);
255
+ else position.right = Math.abs(wToH * position.bottom!);
256
256
  } else if(a == 'topright') {
257
257
  if(!l && !b) return error(false, 'left', 'bottom');
258
258
  if(r || t) return error(true, 'right', 'top');
259
259
  position.right = position.top = 0;
260
260
 
261
- if(l) position.bottom = Math.abs(hToW * position.left);
262
- else position.left = Math.abs(wToH * position.bottom);
261
+ if(l) position.bottom = Math.abs(hToW * position.left!);
262
+ else position.left = Math.abs(wToH * position.bottom!);
263
263
  } else if(a == 'bottomleft') {
264
264
  if(!r && !t) return error(false, 'right', 'top');
265
265
  if(b || l) return error(true, 'bottom', 'left');
266
266
  position.left = position.bottom = 0;
267
267
 
268
- if(r) position.top = Math.abs(hToW * position.right);
269
- else position.right = Math.abs(wToH * position.top);
268
+ if(r) position.top = Math.abs(hToW * position.right!);
269
+ else position.right = Math.abs(wToH * position.top!);
270
270
  } else if(a == 'bottomright') {
271
271
  if(!t && !l) return error(false, 'top', 'left');
272
272
  if(r || b) return error(true, 'bottom', 'right');
273
- position.right = position.bottom = 0;
273
+ position.right = position.bottom = 0 as any;
274
274
 
275
- if(l) position.top = Math.abs(hToW * position.left);
276
- else position.left = Math.abs(wToH * position.top);
275
+ if(l) position.top = Math.abs(hToW * position.left!);
276
+ else position.left = Math.abs(wToH * position.top!);
277
277
  }
278
278
 
279
279
  const ctx = canvas.getContext("2d");
280
- ctx.setTransform(1, 0, 0, 1, 0, 0);
280
+ ctx?.setTransform(1, 0, 0, 1, 0, 0);
281
281
 
282
- canvas.width = Math.floor(Math.abs(position.right-position.left));
283
- canvas.height = Math.floor(Math.abs(position.bottom-position.top));
284
- if(position.right < position.left) ctx.scale(-1, 1);
285
- if(position.top > position.bottom) ctx.scale(1, -1);
282
+ canvas.width = Math.floor(Math.abs(position.right!-position.left!));
283
+ canvas.height = Math.floor(Math.abs(position.bottom!-position.top!));
284
+ if(position.right! < position.left!) ctx?.scale(-1, 1);
285
+ if(position.top! > position.bottom!) ctx?.scale(1, -1);
286
286
 
287
- ctx.translate(-position.left, -position.top);
287
+ ctx?.translate(-position.left!, -position.top!);
288
288
  }
289
289
 
290
290
  /**
@@ -317,18 +317,18 @@ export class Controller {
317
317
  */
318
318
  mapMouseToCanvas(canvas: HTMLCanvasElement) {
319
319
  const ctx = canvas.getContext("2d");
320
- const transform = ctx.getTransform();
320
+ const transform = ctx?.getTransform();
321
321
  const bounding = canvas.getBoundingClientRect();
322
322
 
323
323
  // Ratio between canvas scale to unit pixels
324
324
  const canvasRatioX = bounding.width / canvas.width;
325
325
  const canvasRatioY = bounding.height / canvas.height;
326
326
 
327
- this.mouse.centerX = bounding.left + transform.e * canvasRatioX;
328
- this.mouse.centerY = bounding.top + transform.f * canvasRatioY;
327
+ this.mouse.centerX = bounding.left + transform?.e! * canvasRatioX;
328
+ this.mouse.centerY = bounding.top + transform?.f! * canvasRatioY;
329
329
 
330
- this.mouse.scaleX = canvasRatioX * transform.a;
331
- this.mouse.scaleY = canvasRatioY * transform.d;
330
+ this.mouse.scaleX = canvasRatioX * transform?.a!;
331
+ this.mouse.scaleY = canvasRatioY * transform?.d!;
332
332
  }
333
333
 
334
334
  /**
package/src/index.ts CHANGED
@@ -34,8 +34,9 @@ export default class Multyx {
34
34
  constructor(options: Options = {}, callback?: () => void) {
35
35
  this.options = { ...DefaultOptions, ...options };
36
36
 
37
- const url = `ws${this.options.secure ? 's' : ''}://${this.options.uri.split('/')[0]}:${this.options.port}/${this.options.uri.split('/')[1] ?? ''}`;
38
- this.ws = new WebSocket(url);
37
+ if(!this.options.uri) throw new Error('URI is required');
38
+ const uri = `ws${this.options.secure ? 's' : ''}://${this.options.uri.split('/')[0]}:${this.options.port}/${this.options.uri.split('/')[1] ?? ''}`;
39
+ this.ws = new WebSocket(uri);
39
40
  this.ping = 0;
40
41
  this.space = 'default';
41
42
  this.events = new Map();
@@ -147,7 +148,7 @@ export default class Multyx {
147
148
  }
148
149
 
149
150
  // Clear start event as it will never be called again
150
- if(this.events.has(Multyx.Start)) this.events.get(Multyx.Start).length = 0;
151
+ if(this.events.has(Multyx.Start)) this.events.get(Multyx.Start)!.length = 0;
151
152
  break;
152
153
  }
153
154
 
@@ -211,9 +212,9 @@ export default class Multyx {
211
212
 
212
213
  // Response to client
213
214
  case 'resp': {
214
- const promiseResolve = this.events.get(Symbol.for("_" + update.name))[0];
215
+ const promiseResolve = this.events.get(Symbol.for("_" + update.name))?.[0];
215
216
  this.events.delete(Symbol.for("_" + update.name));
216
- this[Done].push(() => promiseResolve(update.response));
217
+ if(promiseResolve) this[Done].push(() => promiseResolve(update.response));
217
218
  break;
218
219
  }
219
220
 
package/src/items/list.ts CHANGED
@@ -82,6 +82,8 @@ export default class MultyxClientList {
82
82
  }
83
83
  }
84
84
 
85
+ [index: number]: MultyxClientItem | undefined;
86
+
85
87
  constructor(multyx: Multyx, list: any[] | EditWrapper<any[]>, propertyPath: string[] = [], editable: boolean){
86
88
  this.list = [];
87
89
  this.propertyPath = propertyPath;
@@ -127,7 +129,7 @@ export default class MultyxClientList {
127
129
  return index >= 0 && index < this.length;
128
130
  }
129
131
 
130
- get(index: number | string[]): MultyxClientItem {
132
+ get(index: number | string[]): MultyxClientItem | undefined{
131
133
  if(typeof index === 'number') return this.list[index];
132
134
  if(index.length == 0) return this;
133
135
  if(index.length == 1) return this.list[parseInt(index[0])];
@@ -192,9 +194,9 @@ export default class MultyxClientList {
192
194
 
193
195
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.') + '.' + index);
194
196
  if(this.multyx.events.has(propSymbol)) {
195
- this.multyx[Done].push(...this.multyx.events.get(propSymbol).map(e =>
197
+ this.multyx[Done].push(...(this.multyx.events.get(propSymbol)?.map(e =>
196
198
  () => e(this.list[index])
197
- ));
199
+ ) ?? []));
198
200
  }
199
201
 
200
202
  // We have to push into queue, since object may not be fully created
@@ -252,8 +254,8 @@ export default class MultyxClientList {
252
254
  return this.length;
253
255
  }
254
256
 
255
- pop(): MultyxClientItem | null {
256
- if(this.length === 0) return null;
257
+ pop(): MultyxClientItem | undefined {
258
+ if(this.length === 0) return undefined;
257
259
 
258
260
  const res = this.get(this.length);
259
261
  this.delete(this.length);
@@ -288,7 +290,7 @@ export default class MultyxClientList {
288
290
  }
289
291
 
290
292
  splice(start: number, deleteCount?: number, ...items: any[]) {
291
- return this.list.splice(start, deleteCount, ...items);
293
+ return this.list.splice(start, deleteCount ?? 0, ...items);
292
294
  }
293
295
 
294
296
  setSplice(start: number, deleteCount?: number, ...items: any[]) {
@@ -433,6 +435,8 @@ export default class MultyxClientList {
433
435
  return Array(this.length).fill(0).map((_, i) => i);
434
436
  }
435
437
 
438
+ [Edit](){}
439
+
436
440
  [Unpack](constraints: any[]) {
437
441
  for(let i=0; i<this.length; i++) {
438
442
  this.get(i)?.[Unpack](constraints[i]);
@@ -443,7 +447,7 @@ export default class MultyxClientList {
443
447
  [Symbol.iterator](): Iterator<MultyxClientItem> {
444
448
  const values = [];
445
449
  for(let i=0; i<this.length; i++) values[i] = this.get(i);
446
- return values[Symbol.iterator]();
450
+ return values[Symbol.iterator]() as Iterator<MultyxClientItem>;
447
451
  }
448
452
  toString = () => this.value.toString();
449
453
  valueOf = () => this.value;
@@ -16,7 +16,7 @@ export default class MultyxClientObject {
16
16
  private editCallbacks: ((key: any, value: any) => void)[] = [];
17
17
 
18
18
  get value() {
19
- const parsed = {};
19
+ const parsed: RawObject<MultyxClientItem> = {};
20
20
  for(const prop in this.object) parsed[prop] = this.object[prop];
21
21
  return parsed;
22
22
  }
@@ -38,9 +38,11 @@ export default class MultyxClientObject {
38
38
  if(!this.has(updatePath[0])) {
39
39
  this.set(updatePath[0], new EditWrapper({}));
40
40
  }
41
- this.get(updatePath[0])[Edit](updatePath.slice(1), value);
41
+ this.get(updatePath[0])?.[Edit](updatePath.slice(1), value);
42
42
  }
43
43
 
44
+ [key: string]: any;
45
+
44
46
  constructor(multyx: Multyx, object: RawObject | EditWrapper<RawObject>, propertyPath: string[] = [], editable: boolean) {
45
47
  this.object = {};
46
48
  this.propertyPath = propertyPath;
@@ -85,7 +87,7 @@ export default class MultyxClientObject {
85
87
  return property in this.object;
86
88
  }
87
89
 
88
- get(property: string | string[]): MultyxClientItem {
90
+ get(property: string | string[]): MultyxClientItem | undefined {
89
91
  if(typeof property === 'string') return this.object[property];
90
92
  if(property.length == 0) return this;
91
93
  if(property.length == 1) return this.object[property[0]];
@@ -148,9 +150,9 @@ export default class MultyxClientObject {
148
150
 
149
151
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.') + '.' + property);
150
152
  if(this.multyx.events.has(propSymbol)) {
151
- this.multyx[Done].push(...this.multyx.events.get(propSymbol).map(e =>
153
+ this.multyx[Done].push(...(this.multyx.events.get(propSymbol)?.map(e =>
152
154
  () => e(this.object[property])
153
- ));
155
+ ) ?? []));
154
156
  }
155
157
 
156
158
  return true;
@@ -44,9 +44,9 @@ export default class MultyxClientValue {
44
44
 
45
45
  const propSymbol = Symbol.for("_" + this.propertyPath.join('.'));
46
46
  if(this.multyx.events.has(propSymbol)) {
47
- this.multyx[Done].push(...this.multyx.events.get(propSymbol).map(e =>
47
+ this.multyx[Done].push(...(this.multyx.events.get(propSymbol)?.map(e =>
48
48
  () => e(this.value)
49
- ));
49
+ ) ?? []));
50
50
  }
51
51
  }
52
52
 
@@ -66,7 +66,7 @@ export default class MultyxClientValue {
66
66
  return false;
67
67
  }
68
68
 
69
- let nv = value;
69
+ let nv: Value | null = value;
70
70
  for(const constraint in this.constraints) {
71
71
  const fn = this.constraints[constraint];
72
72
  nv = fn(nv);
package/src/message.ts CHANGED
@@ -45,8 +45,8 @@ export function CompressUpdate(update: Update) {
45
45
  pieces = [update.name, JSON.stringify(update.response)];
46
46
  }
47
47
 
48
- if(!pieces) return '';
49
- let compressed = code;
48
+ if(!pieces || !code) return '';
49
+ let compressed = code.toString();
50
50
  for(let i = 0; i < pieces.length; i++) {
51
51
  compressed += pieces[i].replace(/;/g, ';_');
52
52
  if(i < pieces.length - 1) compressed += ';,';
package/tsconfig.json CHANGED
@@ -6,5 +6,10 @@
6
6
  "declaration": true,
7
7
  "outDir": "./dist",
8
8
  "rootDir": "./src", // Specify the root directory of your TypeScript source files.
9
+ "esModuleInterop": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "strict": true,
12
+ "strictPropertyInitialization": false,
13
+ "skipLibCheck": true
9
14
  }
10
15
  }