@mml-io/3d-web-experience-client 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { AvatarType } from "@mml-io/3d-web-avatar-selection-ui";
2
- import { AnimationConfig, EnvironmentConfiguration } from "@mml-io/3d-web-client-core";
1
+ import { AvatarConfiguration } from "@mml-io/3d-web-avatar-selection-ui";
2
+ import { AnimationConfig, EnvironmentConfiguration, LoadingScreenConfig } from "@mml-io/3d-web-client-core";
3
3
  import { StringToHslOptions } from "@mml-io/3d-web-text-chat";
4
4
  type MMLDocumentConfiguration = {
5
5
  url: string;
@@ -19,24 +19,29 @@ type MMLDocumentConfiguration = {
19
19
  z: number;
20
20
  };
21
21
  };
22
- export type AvatarConfiguration = {
23
- availableAvatars?: Array<AvatarType>;
24
- allowCustomAvatars?: boolean;
25
- };
26
22
  export type Networked3dWebExperienceClientConfig = {
23
+ userNetworkAddress: string;
27
24
  sessionToken: string;
28
- chatNetworkAddress?: string;
25
+ allowOrbitalCamera?: boolean;
29
26
  chatVisibleByDefault?: boolean;
30
27
  userNameToColorOptions?: StringToHslOptions;
31
- voiceChatAddress?: string;
32
- userNetworkAddress: string;
33
- mmlDocuments?: Array<MMLDocumentConfiguration>;
34
28
  animationConfig: AnimationConfig;
35
- environmentConfiguration?: EnvironmentConfiguration;
36
- skyboxHdrJpgUrl: string;
37
- enableTweakPane?: boolean;
29
+ voiceChatAddress?: string;
38
30
  updateURLLocation?: boolean;
31
+ onServerBroadcast?: (broadcast: {
32
+ broadcastType: string;
33
+ payload: any;
34
+ }) => void;
35
+ loadingScreen?: LoadingScreenConfig;
36
+ } & UpdatableConfig;
37
+ export type UpdatableConfig = {
38
+ chatNetworkAddress?: string | null;
39
+ mmlDocuments?: {
40
+ [key: string]: MMLDocumentConfiguration;
41
+ };
42
+ environmentConfiguration?: EnvironmentConfiguration;
39
43
  avatarConfiguration?: AvatarConfiguration;
44
+ enableTweakPane?: boolean;
40
45
  };
41
46
  export declare class Networked3dWebExperienceClient {
42
47
  private holderElement;
@@ -45,7 +50,7 @@ export declare class Networked3dWebExperienceClient {
45
50
  private canvasHolder;
46
51
  private scene;
47
52
  private composer;
48
- private tweakPane?;
53
+ private tweakPane;
49
54
  private audioListener;
50
55
  private cameraManager;
51
56
  private collisionsManager;
@@ -71,7 +76,10 @@ export declare class Networked3dWebExperienceClient {
71
76
  private loadingScreen;
72
77
  private errorScreen?;
73
78
  private currentRequestAnimationFrame;
79
+ private groundPlane;
74
80
  constructor(holderElement: HTMLElement, config: Networked3dWebExperienceClientConfig);
81
+ private setGroundPlaneEnabled;
82
+ updateConfig(config: Partial<UpdatableConfig>): void;
75
83
  static createFullscreenHolder(): HTMLDivElement;
76
84
  private resolveCharacterData;
77
85
  private updateUserProfile;
@@ -79,6 +87,7 @@ export declare class Networked3dWebExperienceClient {
79
87
  private sendChatMessageToServer;
80
88
  private sendIdentityUpdateToServer;
81
89
  private connectToVoiceChat;
90
+ private setupTweakPane;
82
91
  private connectToTextChat;
83
92
  private mountAvatarSelectionUI;
84
93
  update(): void;
@@ -86,5 +95,8 @@ export declare class Networked3dWebExperienceClient {
86
95
  private disposeWithError;
87
96
  dispose(): void;
88
97
  private setupMMLScene;
98
+ private createFrame;
99
+ private updateFrameAttributes;
100
+ private setMMLDocuments;
89
101
  }
90
102
  export {};
package/build/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // src/Networked3dWebExperienceClient.ts
2
- import { AvatarSelectionUI } from "@mml-io/3d-web-avatar-selection-ui";
2
+ import {
3
+ AvatarSelectionUI
4
+ } from "@mml-io/3d-web-avatar-selection-ui";
3
5
  import {
4
6
  CameraManager,
5
7
  CharacterManager,
@@ -10,6 +12,7 @@ import {
10
12
  ErrorScreen,
11
13
  getSpawnPositionInsideCircle,
12
14
  GroundPlane,
15
+ Key,
13
16
  KeyInputManager,
14
17
  LoadingScreen,
15
18
  MMLCompositionScene,
@@ -22,9 +25,10 @@ import {
22
25
  TextChatUI
23
26
  } from "@mml-io/3d-web-text-chat";
24
27
  import {
25
- AUTHENTICATION_FAILED_ERROR_TYPE,
26
- CONNECTION_LIMIT_REACHED_ERROR_TYPE,
27
- USER_UPDATE_MESSAGE_TYPE,
28
+ USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,
29
+ USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,
30
+ USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE,
31
+ USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,
28
32
  UserNetworkingClient,
29
33
  WebsocketStatus
30
34
  } from "@mml-io/3d-web-user-networking";
@@ -32,20 +36,22 @@ import { VoiceChatManager } from "@mml-io/3d-web-voice-chat";
32
36
  import {
33
37
  LoadingProgressManager,
34
38
  registerCustomElementsToWindow,
39
+ setGlobalDocumentTimeManager,
35
40
  setGlobalMMLScene
36
- } from "mml-web";
41
+ } from "@mml-io/mml-web";
37
42
  import { AudioListener, Euler, Scene, Vector3 } from "three";
38
43
  var Networked3dWebExperienceClient = class {
39
44
  constructor(holderElement, config) {
40
45
  this.holderElement = holderElement;
41
46
  this.config = config;
42
47
  this.scene = new Scene();
48
+ this.tweakPane = null;
43
49
  this.audioListener = new AudioListener();
44
50
  this.collisionsManager = new CollisionsManager(this.scene);
45
51
  this.characterModelLoader = new CharacterModelLoader();
46
52
  this.timeManager = new TimeManager();
47
53
  this.keyInputManager = new KeyInputManager();
48
- this.mmlFrames = [];
54
+ this.mmlFrames = {};
49
55
  this.clientId = null;
50
56
  this.remoteUserStates = /* @__PURE__ */ new Map();
51
57
  this.userProfiles = /* @__PURE__ */ new Map();
@@ -60,6 +66,7 @@ var Networked3dWebExperienceClient = class {
60
66
  this.initialLoadCompleted = false;
61
67
  this.loadingProgressManager = new LoadingProgressManager();
62
68
  this.currentRequestAnimationFrame = null;
69
+ this.groundPlane = null;
63
70
  var _a;
64
71
  this.element = document.createElement("div");
65
72
  this.element.style.position = "absolute";
@@ -80,28 +87,18 @@ var Networked3dWebExperienceClient = class {
80
87
  this.cameraManager.camera.add(this.audioListener);
81
88
  this.virtualJoystick = new VirtualJoystick(this.element, {
82
89
  radius: 70,
83
- inner_radius: 20,
84
- x: 70,
85
- y: 0,
86
- mouse_support: false
90
+ innerRadius: 20,
91
+ mouseSupport: false
87
92
  });
88
93
  this.composer = new Composer({
89
94
  scene: this.scene,
90
- camera: this.cameraManager.camera,
95
+ cameraManager: this.cameraManager,
91
96
  spawnSun: true,
92
97
  environmentConfiguration: this.config.environmentConfiguration
93
98
  });
94
- this.composer.useHDRJPG(this.config.skyboxHdrJpgUrl);
95
99
  this.canvasHolder.appendChild(this.composer.renderer.domElement);
96
100
  if (this.config.enableTweakPane !== false) {
97
- this.tweakPane = new TweakPane(
98
- this.element,
99
- this.composer.renderer,
100
- this.scene,
101
- this.composer.effectComposer
102
- );
103
- this.cameraManager.setupTweakPane(this.tweakPane);
104
- this.composer.setupTweakPane(this.tweakPane);
101
+ this.setupTweakPane();
105
102
  }
106
103
  const resizeObserver = new ResizeObserver(() => {
107
104
  this.composer.fitContainer();
@@ -144,15 +141,31 @@ var Networked3dWebExperienceClient = class {
144
141
  },
145
142
  onServerError: (error) => {
146
143
  switch (error.errorType) {
147
- case AUTHENTICATION_FAILED_ERROR_TYPE:
144
+ case USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE:
148
145
  this.disposeWithError(error.message);
149
146
  break;
150
- case CONNECTION_LIMIT_REACHED_ERROR_TYPE:
147
+ case USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE:
151
148
  this.disposeWithError(error.message);
152
149
  break;
150
+ case USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE:
151
+ this.disposeWithError(error.message || "Server shutdown");
152
+ break;
153
+ default:
154
+ console.error(`Unhandled server error: ${error.message}`);
155
+ this.disposeWithError(error.message);
153
156
  }
157
+ },
158
+ onServerBroadcast: (broadcast) => {
159
+ var _a2, _b;
160
+ (_b = (_a2 = this.config).onServerBroadcast) == null ? void 0 : _b.call(_a2, broadcast);
154
161
  }
155
162
  });
163
+ if (this.config.allowOrbitalCamera) {
164
+ this.keyInputManager.createKeyBinding(Key.C, () => {
165
+ this.cameraManager.toggleFlyCamera();
166
+ this.composer.fitContainer();
167
+ });
168
+ }
156
169
  this.characterManager = new CharacterManager({
157
170
  composer: this.composer,
158
171
  characterModelLoader: this.characterModelLoader,
@@ -173,13 +186,9 @@ var Networked3dWebExperienceClient = class {
173
186
  updateURLLocation: this.config.updateURLLocation !== false
174
187
  });
175
188
  this.scene.add(this.characterManager.group);
176
- if (((_a = this.config.environmentConfiguration) == null ? void 0 : _a.groundPlane) !== false) {
177
- const groundPlane = new GroundPlane();
178
- this.collisionsManager.addMeshesGroup(groundPlane);
179
- this.scene.add(groundPlane);
180
- }
189
+ this.setGroundPlaneEnabled(((_a = this.config.environmentConfiguration) == null ? void 0 : _a.groundPlane) ?? true);
181
190
  this.setupMMLScene();
182
- this.loadingScreen = new LoadingScreen(this.loadingProgressManager);
191
+ this.loadingScreen = new LoadingScreen(this.loadingProgressManager, this.config.loadingScreen);
183
192
  this.element.append(this.loadingScreen.element);
184
193
  this.loadingProgressManager.addProgressCallback(() => {
185
194
  const [, completed] = this.loadingProgressManager.toRatio();
@@ -193,6 +202,52 @@ var Networked3dWebExperienceClient = class {
193
202
  });
194
203
  this.loadingProgressManager.setInitialLoad(true);
195
204
  }
205
+ setGroundPlaneEnabled(enabled) {
206
+ if (enabled && this.groundPlane === null) {
207
+ this.groundPlane = new GroundPlane();
208
+ this.collisionsManager.addMeshesGroup(this.groundPlane);
209
+ this.scene.add(this.groundPlane);
210
+ } else if (!enabled && this.groundPlane !== null) {
211
+ this.collisionsManager.removeMeshesGroup(this.groundPlane);
212
+ this.scene.remove(this.groundPlane);
213
+ this.groundPlane = null;
214
+ }
215
+ }
216
+ updateConfig(config) {
217
+ var _a, _b;
218
+ this.config = {
219
+ ...this.config,
220
+ ...config
221
+ };
222
+ if (config.environmentConfiguration) {
223
+ this.composer.updateEnvironmentConfiguration(config.environmentConfiguration);
224
+ this.setGroundPlaneEnabled(config.environmentConfiguration.groundPlane ?? true);
225
+ }
226
+ if (config.avatarConfiguration && this.avatarSelectionUI) {
227
+ (_a = this.avatarSelectionUI) == null ? void 0 : _a.updateAvatarConfig(config.avatarConfiguration);
228
+ }
229
+ if (config.enableTweakPane !== void 0) {
230
+ if (config.enableTweakPane === false && this.tweakPane !== null) {
231
+ this.tweakPane.dispose();
232
+ this.tweakPane = null;
233
+ } else if (config.enableTweakPane === true && this.tweakPane === null) {
234
+ this.setupTweakPane();
235
+ }
236
+ }
237
+ if (config.chatNetworkAddress !== void 0) {
238
+ if (config.chatNetworkAddress === null && this.networkChat !== null) {
239
+ this.networkChat.stop();
240
+ this.networkChat = null;
241
+ (_b = this.textChatUI) == null ? void 0 : _b.dispose();
242
+ this.textChatUI = null;
243
+ } else {
244
+ this.connectToTextChat();
245
+ }
246
+ }
247
+ if (config.mmlDocuments) {
248
+ this.setMMLDocuments(config.mmlDocuments);
249
+ }
250
+ }
196
251
  static createFullscreenHolder() {
197
252
  document.body.style.margin = "0";
198
253
  document.body.style.overflow = "hidden";
@@ -253,7 +308,7 @@ var Networked3dWebExperienceClient = class {
253
308
  throw new Error("User profile not found");
254
309
  }
255
310
  this.networkClient.sendMessage({
256
- type: USER_UPDATE_MESSAGE_TYPE,
311
+ type: USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,
257
312
  userIdentity: {
258
313
  username: userProfile.username,
259
314
  characterDescription: {
@@ -278,6 +333,19 @@ var Networked3dWebExperienceClient = class {
278
333
  });
279
334
  }
280
335
  }
336
+ setupTweakPane() {
337
+ if (this.tweakPane) {
338
+ return;
339
+ }
340
+ this.tweakPane = new TweakPane(
341
+ this.element,
342
+ this.composer.renderer,
343
+ this.scene,
344
+ this.composer.effectComposer
345
+ );
346
+ this.cameraManager.setupTweakPane(this.tweakPane);
347
+ this.composer.setupTweakPane(this.tweakPane);
348
+ }
281
349
  connectToTextChat() {
282
350
  if (this.clientId === null) {
283
351
  return;
@@ -312,29 +380,22 @@ var Networked3dWebExperienceClient = class {
312
380
  const username = ((_a = this.userProfiles.get(clientId)) == null ? void 0 : _a.username) || "Unknown";
313
381
  this.textChatUI.addTextMessage(username, chatNetworkingUpdate.text);
314
382
  }
383
+ },
384
+ onServerError: (error) => {
385
+ console.error(`Chat server error: ${error.message}. errorType: ${error.errorType}`);
386
+ this.disposeWithError(error.message);
315
387
  }
316
388
  });
317
389
  }
318
390
  }
319
391
  mountAvatarSelectionUI() {
320
- var _a, _b, _c, _d, _e;
321
- if (!((_b = (_a = this.config.avatarConfiguration) == null ? void 0 : _a.availableAvatars) == null ? void 0 : _b.length) && !((_c = this.config.avatarConfiguration) == null ? void 0 : _c.allowCustomAvatars)) {
322
- return;
323
- }
324
- if (this.clientId === null) {
325
- throw new Error("Client ID not set");
326
- }
327
- const ownIdentity = this.userProfiles.get(this.clientId);
328
- if (!ownIdentity) {
329
- throw new Error("Own identity not found");
330
- }
392
+ var _a, _b;
331
393
  this.avatarSelectionUI = new AvatarSelectionUI({
332
394
  holderElement: this.element,
333
- clientId: this.clientId,
334
395
  visibleByDefault: false,
335
- availableAvatars: ((_d = this.config.avatarConfiguration) == null ? void 0 : _d.availableAvatars) ?? [],
336
396
  sendMessageToServerMethod: this.sendIdentityUpdateToServer.bind(this),
337
- enableCustomAvatar: (_e = this.config.avatarConfiguration) == null ? void 0 : _e.allowCustomAvatars
397
+ availableAvatars: ((_a = this.config.avatarConfiguration) == null ? void 0 : _a.availableAvatars) ?? [],
398
+ allowCustomAvatars: (_b = this.config.avatarConfiguration) == null ? void 0 : _b.allowCustomAvatars
338
399
  });
339
400
  this.avatarSelectionUI.init();
340
401
  }
@@ -402,23 +463,24 @@ var Networked3dWebExperienceClient = class {
402
463
  this.element.append(this.errorScreen.element);
403
464
  }
404
465
  dispose() {
405
- var _a, _b, _c;
466
+ var _a, _b, _c, _d;
406
467
  this.networkClient.stop();
407
468
  (_a = this.networkChat) == null ? void 0 : _a.stop();
408
- for (const mmlFrame of this.mmlFrames) {
409
- mmlFrame.remove();
469
+ for (const [key, element] of Object.entries(this.mmlFrames)) {
470
+ element.remove();
410
471
  }
411
- this.mmlFrames = [];
472
+ this.mmlFrames = {};
473
+ (_b = this.textChatUI) == null ? void 0 : _b.dispose();
412
474
  this.mmlCompositionScene.dispose();
413
475
  this.composer.dispose();
414
- (_b = this.tweakPane) == null ? void 0 : _b.dispose();
476
+ (_c = this.tweakPane) == null ? void 0 : _c.dispose();
415
477
  if (this.currentRequestAnimationFrame !== null) {
416
478
  cancelAnimationFrame(this.currentRequestAnimationFrame);
417
479
  this.currentRequestAnimationFrame = null;
418
480
  }
419
481
  this.cameraManager.dispose();
420
482
  this.loadingScreen.dispose();
421
- (_c = this.errorScreen) == null ? void 0 : _c.dispose();
483
+ (_d = this.errorScreen) == null ? void 0 : _d.dispose();
422
484
  }
423
485
  setupMMLScene() {
424
486
  registerCustomElementsToWindow(window);
@@ -435,35 +497,8 @@ var Networked3dWebExperienceClient = class {
435
497
  });
436
498
  this.scene.add(this.mmlCompositionScene.group);
437
499
  setGlobalMMLScene(this.mmlCompositionScene.mmlScene);
438
- if (this.config.mmlDocuments) {
439
- for (const mmlDocument of this.config.mmlDocuments) {
440
- const frameElement = document.createElement("m-frame");
441
- frameElement.setAttribute("src", mmlDocument.url);
442
- if (mmlDocument.position) {
443
- frameElement.setAttribute("x", mmlDocument.position.x.toString());
444
- frameElement.setAttribute("y", mmlDocument.position.y.toString());
445
- frameElement.setAttribute("z", mmlDocument.position.z.toString());
446
- }
447
- if (mmlDocument.rotation) {
448
- frameElement.setAttribute("rx", mmlDocument.rotation.x.toString());
449
- frameElement.setAttribute("ry", mmlDocument.rotation.y.toString());
450
- frameElement.setAttribute("rz", mmlDocument.rotation.z.toString());
451
- }
452
- if (mmlDocument.scale) {
453
- if (mmlDocument.scale.x !== void 0) {
454
- frameElement.setAttribute("sx", mmlDocument.scale.x.toString());
455
- }
456
- if (mmlDocument.scale.y !== void 0) {
457
- frameElement.setAttribute("sy", mmlDocument.scale.y.toString());
458
- }
459
- if (mmlDocument.scale.z !== void 0) {
460
- frameElement.setAttribute("sz", mmlDocument.scale.z.toString());
461
- }
462
- }
463
- document.body.appendChild(frameElement);
464
- this.mmlFrames.push(frameElement);
465
- }
466
- }
500
+ setGlobalDocumentTimeManager(this.mmlCompositionScene.documentTimeManager);
501
+ this.setMMLDocuments(this.config.mmlDocuments ?? {});
467
502
  const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager();
468
503
  this.loadingProgressManager.addLoadingDocument(mmlProgressManager, "mml", mmlProgressManager);
469
504
  mmlProgressManager.addProgressCallback(() => {
@@ -471,6 +506,71 @@ var Networked3dWebExperienceClient = class {
471
506
  });
472
507
  mmlProgressManager.setInitialLoad(true);
473
508
  }
509
+ createFrame(mmlDocument) {
510
+ const frameElement = document.createElement("m-frame");
511
+ frameElement.setAttribute("src", mmlDocument.url);
512
+ this.updateFrameAttributes(frameElement, mmlDocument);
513
+ return frameElement;
514
+ }
515
+ updateFrameAttributes(frameElement, mmlDocument) {
516
+ var _a, _b, _c;
517
+ const existingSrc = frameElement.getAttribute("src");
518
+ if (existingSrc !== mmlDocument.url) {
519
+ frameElement.setAttribute("src", mmlDocument.url);
520
+ }
521
+ if (mmlDocument.position) {
522
+ frameElement.setAttribute("x", mmlDocument.position.x.toString());
523
+ frameElement.setAttribute("y", mmlDocument.position.y.toString());
524
+ frameElement.setAttribute("z", mmlDocument.position.z.toString());
525
+ } else {
526
+ frameElement.setAttribute("x", "0");
527
+ frameElement.setAttribute("y", "0");
528
+ frameElement.setAttribute("z", "0");
529
+ }
530
+ if (mmlDocument.rotation) {
531
+ frameElement.setAttribute("rx", mmlDocument.rotation.x.toString());
532
+ frameElement.setAttribute("ry", mmlDocument.rotation.y.toString());
533
+ frameElement.setAttribute("rz", mmlDocument.rotation.z.toString());
534
+ } else {
535
+ frameElement.setAttribute("rx", "0");
536
+ frameElement.setAttribute("ry", "0");
537
+ frameElement.setAttribute("rz", "0");
538
+ }
539
+ if (((_a = mmlDocument.scale) == null ? void 0 : _a.x) !== void 0) {
540
+ frameElement.setAttribute("sx", mmlDocument.scale.x.toString());
541
+ } else {
542
+ frameElement.setAttribute("sx", "1");
543
+ }
544
+ if (((_b = mmlDocument.scale) == null ? void 0 : _b.y) !== void 0) {
545
+ frameElement.setAttribute("sy", mmlDocument.scale.y.toString());
546
+ } else {
547
+ frameElement.setAttribute("sy", "1");
548
+ }
549
+ if (((_c = mmlDocument.scale) == null ? void 0 : _c.z) !== void 0) {
550
+ frameElement.setAttribute("sz", mmlDocument.scale.z.toString());
551
+ } else {
552
+ frameElement.setAttribute("sz", "1");
553
+ }
554
+ }
555
+ setMMLDocuments(mmlDocuments) {
556
+ const newFramesMap = {};
557
+ for (const [key, mmlDocSpec] of Object.entries(mmlDocuments)) {
558
+ const existing = this.mmlFrames[key];
559
+ if (!existing) {
560
+ const frameElement = this.createFrame(mmlDocSpec);
561
+ document.body.appendChild(frameElement);
562
+ newFramesMap[key] = frameElement;
563
+ } else {
564
+ delete this.mmlFrames[key];
565
+ newFramesMap[key] = existing;
566
+ this.updateFrameAttributes(existing, mmlDocSpec);
567
+ }
568
+ }
569
+ for (const [key, element] of Object.entries(this.mmlFrames)) {
570
+ element.remove();
571
+ }
572
+ this.mmlFrames = newFramesMap;
573
+ }
474
574
  };
475
575
  export {
476
576
  Networked3dWebExperienceClient
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Networked3dWebExperienceClient.ts"],
4
- "sourcesContent": ["import { AvatarSelectionUI, AvatarType } from \"@mml-io/3d-web-avatar-selection-ui\";\nimport {\n AnimationConfig,\n CameraManager,\n CharacterDescription,\n CharacterManager,\n CharacterModelLoader,\n CharacterState,\n CollisionsManager,\n Composer,\n decodeCharacterAndCamera,\n EnvironmentConfiguration,\n ErrorScreen,\n getSpawnPositionInsideCircle,\n GroundPlane,\n KeyInputManager,\n LoadingScreen,\n MMLCompositionScene,\n TimeManager,\n TweakPane,\n VirtualJoystick,\n} from \"@mml-io/3d-web-client-core\";\nimport {\n ChatNetworkingClient,\n FromClientChatMessage,\n StringToHslOptions,\n TextChatUI,\n TextChatUIProps,\n} from \"@mml-io/3d-web-text-chat\";\nimport {\n AUTHENTICATION_FAILED_ERROR_TYPE,\n CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n ServerErrorType,\n USER_UPDATE_MESSAGE_TYPE,\n UserData,\n UserNetworkingClient,\n UserNetworkingClientUpdate,\n WebsocketStatus,\n} from \"@mml-io/3d-web-user-networking\";\nimport { VoiceChatManager } from \"@mml-io/3d-web-voice-chat\";\nimport {\n IMMLScene,\n LoadingProgressManager,\n registerCustomElementsToWindow,\n setGlobalMMLScene,\n} from \"mml-web\";\nimport { AudioListener, Euler, Scene, Vector3 } from \"three\";\n\ntype MMLDocumentConfiguration = {\n url: string;\n position?: {\n x: number;\n y: number;\n z: number;\n };\n rotation?: {\n x: number;\n y: number;\n z: number;\n };\n scale?: {\n x: number;\n y: number;\n z: number;\n };\n};\n\nexport type AvatarConfiguration = {\n availableAvatars?: Array<AvatarType>;\n allowCustomAvatars?: boolean;\n};\n\nexport type Networked3dWebExperienceClientConfig = {\n sessionToken: string;\n chatNetworkAddress?: string;\n chatVisibleByDefault?: boolean;\n userNameToColorOptions?: StringToHslOptions;\n voiceChatAddress?: string;\n userNetworkAddress: string;\n mmlDocuments?: Array<MMLDocumentConfiguration>;\n animationConfig: AnimationConfig;\n environmentConfiguration?: EnvironmentConfiguration;\n skyboxHdrJpgUrl: string;\n enableTweakPane?: boolean;\n updateURLLocation?: boolean;\n avatarConfiguration?: AvatarConfiguration;\n};\n\nexport class Networked3dWebExperienceClient {\n private element: HTMLDivElement;\n private canvasHolder: HTMLDivElement;\n\n private scene = new Scene();\n private composer: Composer;\n private tweakPane?: TweakPane;\n private audioListener = new AudioListener();\n\n private cameraManager: CameraManager;\n\n private collisionsManager = new CollisionsManager(this.scene);\n\n private characterModelLoader = new CharacterModelLoader();\n private characterManager: CharacterManager;\n\n private timeManager = new TimeManager();\n\n private keyInputManager = new KeyInputManager();\n private virtualJoystick: VirtualJoystick;\n\n private mmlCompositionScene: MMLCompositionScene;\n private mmlFrames: Array<HTMLElement> = [];\n\n private clientId: number | null = null;\n private networkClient: UserNetworkingClient;\n private remoteUserStates = new Map<number, CharacterState>();\n private userProfiles = new Map<number, UserData>();\n\n private networkChat: ChatNetworkingClient | null = null;\n private textChatUI: TextChatUI | null = null;\n\n private avatarSelectionUI: AvatarSelectionUI | null = null;\n\n private voiceChatManager: VoiceChatManager | null = null;\n private readonly latestCharacterObject = {\n characterState: null as null | CharacterState,\n };\n private characterControllerPaneSet: boolean = false;\n\n private initialLoadCompleted = false;\n private loadingProgressManager = new LoadingProgressManager();\n private loadingScreen: LoadingScreen;\n private errorScreen?: ErrorScreen;\n private currentRequestAnimationFrame: number | null = null;\n\n constructor(\n private holderElement: HTMLElement,\n private config: Networked3dWebExperienceClientConfig,\n ) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.holderElement.appendChild(this.element);\n\n document.addEventListener(\"mousedown\", () => {\n if (this.audioListener.context.state === \"suspended\") {\n this.audioListener.context.resume();\n }\n });\n\n this.canvasHolder = document.createElement(\"div\");\n this.canvasHolder.style.position = \"absolute\";\n this.canvasHolder.style.width = \"100%\";\n this.canvasHolder.style.height = \"100%\";\n this.element.appendChild(this.canvasHolder);\n\n this.cameraManager = new CameraManager(this.canvasHolder, this.collisionsManager);\n this.cameraManager.camera.add(this.audioListener);\n\n this.virtualJoystick = new VirtualJoystick(this.element, {\n radius: 70,\n inner_radius: 20,\n x: 70,\n y: 0,\n mouse_support: false,\n });\n\n this.composer = new Composer({\n scene: this.scene,\n camera: this.cameraManager.camera,\n spawnSun: true,\n environmentConfiguration: this.config.environmentConfiguration,\n });\n\n this.composer.useHDRJPG(this.config.skyboxHdrJpgUrl);\n this.canvasHolder.appendChild(this.composer.renderer.domElement);\n\n if (this.config.enableTweakPane !== false) {\n this.tweakPane = new TweakPane(\n this.element,\n this.composer.renderer,\n this.scene,\n this.composer.effectComposer,\n );\n this.cameraManager.setupTweakPane(this.tweakPane);\n this.composer.setupTweakPane(this.tweakPane);\n }\n\n const resizeObserver = new ResizeObserver(() => {\n this.composer.fitContainer();\n });\n resizeObserver.observe(this.element);\n\n const initialNetworkLoadRef = {};\n this.loadingProgressManager.addLoadingAsset(initialNetworkLoadRef, \"network\", \"network\");\n this.networkClient = new UserNetworkingClient({\n url: this.config.userNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n this.characterManager.clear();\n this.remoteUserStates.clear();\n this.clientId = null;\n }\n },\n assignedIdentity: (clientId: number) => {\n console.log(`Assigned ID: ${clientId}`);\n this.clientId = clientId;\n if (this.initialLoadCompleted) {\n // Already loaded - respawn the character\n this.spawnCharacter();\n } else {\n this.loadingProgressManager.completedLoadingAsset(initialNetworkLoadRef);\n }\n },\n clientUpdate: (\n remoteClientId: number,\n userNetworkingClientUpdate: null | UserNetworkingClientUpdate,\n ) => {\n if (userNetworkingClientUpdate === null) {\n this.remoteUserStates.delete(remoteClientId);\n } else {\n this.remoteUserStates.set(remoteClientId, userNetworkingClientUpdate);\n }\n },\n clientProfileUpdated: (\n clientId: number,\n username: string,\n characterDescription: CharacterDescription,\n ): void => {\n this.updateUserProfile(clientId, {\n username,\n characterDescription,\n });\n },\n onServerError: (error: { message: string; errorType: ServerErrorType }) => {\n switch (error.errorType) {\n case AUTHENTICATION_FAILED_ERROR_TYPE:\n this.disposeWithError(error.message);\n break;\n case CONNECTION_LIMIT_REACHED_ERROR_TYPE:\n this.disposeWithError(error.message);\n break;\n }\n },\n });\n\n this.characterManager = new CharacterManager({\n composer: this.composer,\n characterModelLoader: this.characterModelLoader,\n collisionsManager: this.collisionsManager,\n cameraManager: this.cameraManager,\n timeManager: this.timeManager,\n keyInputManager: this.keyInputManager,\n virtualJoystick: this.virtualJoystick,\n remoteUserStates: this.remoteUserStates,\n sendUpdate: (characterState: CharacterState) => {\n this.latestCharacterObject.characterState = characterState;\n this.networkClient.sendUpdate(characterState);\n },\n animationConfig: this.config.animationConfig,\n characterResolve: (characterId: number) => {\n return this.resolveCharacterData(characterId);\n },\n updateURLLocation: this.config.updateURLLocation !== false,\n });\n this.scene.add(this.characterManager.group);\n\n if (this.config.environmentConfiguration?.groundPlane !== false) {\n const groundPlane = new GroundPlane();\n this.collisionsManager.addMeshesGroup(groundPlane);\n this.scene.add(groundPlane);\n }\n\n this.setupMMLScene();\n\n this.loadingScreen = new LoadingScreen(this.loadingProgressManager);\n this.element.append(this.loadingScreen.element);\n\n this.loadingProgressManager.addProgressCallback(() => {\n const [, completed] = this.loadingProgressManager.toRatio();\n if (completed && !this.initialLoadCompleted) {\n this.initialLoadCompleted = true;\n /*\n When all content (in particular MML) has loaded, spawn the character (this is to avoid the character falling\n through as-yet-unloaded geometry)\n */\n this.connectToVoiceChat();\n this.connectToTextChat();\n this.mountAvatarSelectionUI();\n this.spawnCharacter();\n }\n });\n this.loadingProgressManager.setInitialLoad(true);\n }\n\n static createFullscreenHolder(): HTMLDivElement {\n document.body.style.margin = \"0\";\n document.body.style.overflow = \"hidden\";\n\n const holder = document.createElement(\"div\");\n holder.style.position = \"absolute\";\n holder.style.width = \"100%\";\n holder.style.height = \"100%\";\n holder.style.overflow = \"hidden\";\n document.body.appendChild(holder);\n return holder;\n }\n\n private resolveCharacterData(clientId: number): {\n username: string;\n characterDescription: CharacterDescription;\n } {\n const user = this.userProfiles.get(clientId)!;\n\n if (!user) {\n throw new Error(`Failed to resolve user for clientId ${clientId}`);\n }\n\n return {\n username: user.username,\n characterDescription: user.characterDescription,\n };\n }\n\n private updateUserProfile(id: number, userData: UserData) {\n console.log(`Update user_profile for id=${id} (username=${userData.username})`);\n\n this.userProfiles.set(id, userData);\n\n this.characterManager.respawnIfPresent(id);\n }\n\n private updateUserAvatar(avatar: AvatarType) {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n const newUser = {\n ...user,\n characterDescription: {\n meshFileUrl: avatar.meshFileUrl ?? undefined,\n mmlCharacterUrl: avatar.mmlCharacterUrl ?? undefined,\n mmlCharacterString: avatar.mmlCharacterString ?? undefined,\n },\n } as UserData;\n\n this.userProfiles.set(this.clientId, newUser);\n this.updateUserProfile(this.clientId, newUser);\n }\n\n private sendChatMessageToServer(message: string): void {\n this.mmlCompositionScene.onChatMessage(message);\n if (this.clientId === null || this.networkChat === null) return;\n this.networkChat.sendChatMessage(message);\n }\n\n private sendIdentityUpdateToServer(avatar: AvatarType) {\n if (!this.clientId) {\n throw new Error(\"Client ID not set\");\n }\n\n const userProfile = this.userProfiles.get(this.clientId);\n\n if (!userProfile) {\n throw new Error(\"User profile not found\");\n }\n\n this.networkClient.sendMessage({\n type: USER_UPDATE_MESSAGE_TYPE,\n userIdentity: {\n username: userProfile.username,\n characterDescription: {\n mmlCharacterString: avatar.mmlCharacterString,\n mmlCharacterUrl: avatar.mmlCharacterUrl,\n meshFileUrl: avatar.meshFileUrl,\n } as CharacterDescription,\n },\n });\n }\n\n private connectToVoiceChat() {\n if (this.clientId === null) return;\n\n if (this.voiceChatManager === null && this.config.voiceChatAddress) {\n this.voiceChatManager = new VoiceChatManager({\n url: this.config.voiceChatAddress,\n holderElement: this.element,\n userId: this.clientId,\n remoteUserStates: this.remoteUserStates,\n latestCharacterObj: this.latestCharacterObject,\n autoJoin: false,\n });\n }\n }\n\n private connectToTextChat() {\n if (this.clientId === null) {\n return;\n }\n if (this.networkChat === null && this.config.chatNetworkAddress) {\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n if (this.textChatUI === null) {\n const textChatUISettings: TextChatUIProps = {\n holderElement: this.element,\n clientname: user.username,\n sendMessageToServerMethod: this.sendChatMessageToServer.bind(this),\n visibleByDefault: this.config.chatVisibleByDefault,\n stringToHslOptions: this.config.userNameToColorOptions,\n };\n this.textChatUI = new TextChatUI(textChatUISettings);\n this.textChatUI.init();\n }\n\n this.networkChat = new ChatNetworkingClient({\n url: this.config.chatNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n }\n },\n clientChatUpdate: (\n clientId: number,\n chatNetworkingUpdate: null | FromClientChatMessage,\n ) => {\n if (chatNetworkingUpdate !== null && this.textChatUI !== null) {\n const username = this.userProfiles.get(clientId)?.username || \"Unknown\";\n this.textChatUI.addTextMessage(username, chatNetworkingUpdate.text);\n }\n },\n });\n }\n }\n\n private mountAvatarSelectionUI() {\n if (\n !this.config.avatarConfiguration?.availableAvatars?.length &&\n !this.config.avatarConfiguration?.allowCustomAvatars\n ) {\n return;\n }\n\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const ownIdentity = this.userProfiles.get(this.clientId);\n if (!ownIdentity) {\n throw new Error(\"Own identity not found\");\n }\n\n this.avatarSelectionUI = new AvatarSelectionUI({\n holderElement: this.element,\n clientId: this.clientId,\n visibleByDefault: false,\n availableAvatars: this.config.avatarConfiguration?.availableAvatars ?? [],\n sendMessageToServerMethod: this.sendIdentityUpdateToServer.bind(this),\n enableCustomAvatar: this.config.avatarConfiguration?.allowCustomAvatars,\n });\n this.avatarSelectionUI.init();\n }\n\n public update(): void {\n this.timeManager.update();\n this.characterManager.update();\n this.voiceChatManager?.speakingParticipants.forEach((value: boolean, id: number) => {\n this.characterManager.setSpeakingCharacter(id, value);\n });\n this.cameraManager.update();\n this.composer.sun?.updateCharacterPosition(this.characterManager.localCharacter?.position);\n this.composer.render(this.timeManager);\n if (this.tweakPane?.guiVisible) {\n this.tweakPane.updateStats(this.timeManager);\n this.tweakPane.updateCameraData(this.cameraManager);\n if (this.characterManager.localCharacter && this.characterManager.localController) {\n if (!this.characterControllerPaneSet) {\n this.characterControllerPaneSet = true;\n this.characterManager.setupTweakPane(this.tweakPane);\n } else {\n this.tweakPane.updateCharacterData(this.characterManager.localController);\n }\n }\n }\n this.currentRequestAnimationFrame = requestAnimationFrame(() => {\n this.update();\n });\n }\n\n private spawnCharacter() {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const spawnPosition = getSpawnPositionInsideCircle(3, 30, this.clientId!, 0.4);\n const spawnRotation = new Euler(0, 0, 0);\n let cameraPosition: Vector3 | null = null;\n if (window.location.hash && window.location.hash.length > 1) {\n const urlParams = decodeCharacterAndCamera(window.location.hash.substring(1));\n spawnPosition.copy(urlParams.character.position);\n spawnRotation.setFromQuaternion(urlParams.character.quaternion);\n cameraPosition = urlParams.camera.position;\n }\n const ownIdentity = this.userProfiles.get(this.clientId);\n if (!ownIdentity) {\n throw new Error(\"Own identity not found\");\n }\n\n this.characterManager.spawnLocalCharacter(\n this.clientId!,\n ownIdentity.username,\n ownIdentity.characterDescription,\n spawnPosition,\n spawnRotation,\n );\n\n if (cameraPosition !== null) {\n this.cameraManager.camera.position.copy(cameraPosition);\n this.cameraManager.setTarget(\n new Vector3().add(spawnPosition).add(this.characterManager.headTargetOffset),\n );\n this.cameraManager.reverseUpdateFromPositions();\n }\n }\n\n private disposeWithError(message: string) {\n this.dispose();\n this.errorScreen = new ErrorScreen(\"An error occurred\", message);\n this.element.append(this.errorScreen.element);\n }\n\n public dispose() {\n this.networkClient.stop();\n this.networkChat?.stop();\n for (const mmlFrame of this.mmlFrames) {\n mmlFrame.remove();\n }\n this.mmlFrames = [];\n this.mmlCompositionScene.dispose();\n this.composer.dispose();\n this.tweakPane?.dispose();\n if (this.currentRequestAnimationFrame !== null) {\n cancelAnimationFrame(this.currentRequestAnimationFrame);\n this.currentRequestAnimationFrame = null;\n }\n this.cameraManager.dispose();\n this.loadingScreen.dispose();\n this.errorScreen?.dispose();\n }\n\n private setupMMLScene() {\n registerCustomElementsToWindow(window);\n this.mmlCompositionScene = new MMLCompositionScene({\n targetElement: this.element,\n renderer: this.composer.renderer,\n scene: this.scene,\n camera: this.cameraManager.camera,\n audioListener: this.audioListener,\n collisionsManager: this.collisionsManager,\n getUserPositionAndRotation: () => {\n return this.characterManager.getLocalCharacterPositionAndRotation();\n },\n });\n this.scene.add(this.mmlCompositionScene.group);\n setGlobalMMLScene(this.mmlCompositionScene.mmlScene as IMMLScene);\n\n if (this.config.mmlDocuments) {\n for (const mmlDocument of this.config.mmlDocuments) {\n const frameElement = document.createElement(\"m-frame\");\n frameElement.setAttribute(\"src\", mmlDocument.url);\n if (mmlDocument.position) {\n frameElement.setAttribute(\"x\", mmlDocument.position.x.toString());\n frameElement.setAttribute(\"y\", mmlDocument.position.y.toString());\n frameElement.setAttribute(\"z\", mmlDocument.position.z.toString());\n }\n if (mmlDocument.rotation) {\n frameElement.setAttribute(\"rx\", mmlDocument.rotation.x.toString());\n frameElement.setAttribute(\"ry\", mmlDocument.rotation.y.toString());\n frameElement.setAttribute(\"rz\", mmlDocument.rotation.z.toString());\n }\n if (mmlDocument.scale) {\n if (mmlDocument.scale.x !== undefined) {\n frameElement.setAttribute(\"sx\", mmlDocument.scale.x.toString());\n }\n if (mmlDocument.scale.y !== undefined) {\n frameElement.setAttribute(\"sy\", mmlDocument.scale.y.toString());\n }\n if (mmlDocument.scale.z !== undefined) {\n frameElement.setAttribute(\"sz\", mmlDocument.scale.z.toString());\n }\n }\n document.body.appendChild(frameElement);\n this.mmlFrames.push(frameElement);\n }\n }\n\n const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager!()!;\n this.loadingProgressManager.addLoadingDocument(mmlProgressManager, \"mml\", mmlProgressManager);\n mmlProgressManager.addProgressCallback(() => {\n this.loadingProgressManager.updateDocumentProgress(mmlProgressManager);\n });\n mmlProgressManager.setInitialLoad(true);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
4
+ "sourcesContent": ["import {\n AvatarSelectionUI,\n AvatarType,\n AvatarConfiguration,\n} from \"@mml-io/3d-web-avatar-selection-ui\";\nimport {\n AnimationConfig,\n CameraManager,\n CharacterDescription,\n CharacterManager,\n CharacterModelLoader,\n CharacterState,\n CollisionsManager,\n Composer,\n decodeCharacterAndCamera,\n EnvironmentConfiguration,\n ErrorScreen,\n getSpawnPositionInsideCircle,\n GroundPlane,\n Key,\n KeyInputManager,\n LoadingScreen,\n LoadingScreenConfig,\n MMLCompositionScene,\n TimeManager,\n TweakPane,\n VirtualJoystick,\n} from \"@mml-io/3d-web-client-core\";\nimport {\n ChatNetworkingClient,\n ChatNetworkingClientChatMessage,\n ChatNetworkingServerErrorType,\n StringToHslOptions,\n TextChatUI,\n TextChatUIProps,\n} from \"@mml-io/3d-web-text-chat\";\nimport {\n USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE,\n USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE,\n USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE,\n USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,\n UserData,\n UserNetworkingClient,\n UserNetworkingClientUpdate,\n UserNetworkingServerErrorType,\n WebsocketStatus,\n} from \"@mml-io/3d-web-user-networking\";\nimport { VoiceChatManager } from \"@mml-io/3d-web-voice-chat\";\nimport {\n IMMLScene,\n LoadingProgressManager,\n registerCustomElementsToWindow,\n setGlobalDocumentTimeManager,\n setGlobalMMLScene,\n} from \"@mml-io/mml-web\";\nimport { AudioListener, Euler, Scene, Vector3 } from \"three\";\n\ntype MMLDocumentConfiguration = {\n url: string;\n position?: {\n x: number;\n y: number;\n z: number;\n };\n rotation?: {\n x: number;\n y: number;\n z: number;\n };\n scale?: {\n x: number;\n y: number;\n z: number;\n };\n};\n\nexport type Networked3dWebExperienceClientConfig = {\n userNetworkAddress: string;\n sessionToken: string;\n allowOrbitalCamera?: boolean;\n chatVisibleByDefault?: boolean;\n userNameToColorOptions?: StringToHslOptions;\n animationConfig: AnimationConfig;\n voiceChatAddress?: string;\n updateURLLocation?: boolean;\n onServerBroadcast?: (broadcast: { broadcastType: string; payload: any }) => void;\n loadingScreen?: LoadingScreenConfig;\n} & UpdatableConfig;\n\nexport type UpdatableConfig = {\n chatNetworkAddress?: string | null;\n mmlDocuments?: { [key: string]: MMLDocumentConfiguration };\n environmentConfiguration?: EnvironmentConfiguration;\n avatarConfiguration?: AvatarConfiguration;\n enableTweakPane?: boolean;\n};\n\nexport class Networked3dWebExperienceClient {\n private element: HTMLDivElement;\n private canvasHolder: HTMLDivElement;\n\n private scene = new Scene();\n private composer: Composer;\n private tweakPane: TweakPane | null = null;\n private audioListener = new AudioListener();\n\n private cameraManager: CameraManager;\n\n private collisionsManager = new CollisionsManager(this.scene);\n\n private characterModelLoader = new CharacterModelLoader();\n private characterManager: CharacterManager;\n\n private timeManager = new TimeManager();\n\n private keyInputManager = new KeyInputManager();\n private virtualJoystick: VirtualJoystick;\n\n private mmlCompositionScene: MMLCompositionScene;\n private mmlFrames: { [key: string]: HTMLElement } = {};\n\n private clientId: number | null = null;\n private networkClient: UserNetworkingClient;\n private remoteUserStates = new Map<number, CharacterState>();\n private userProfiles = new Map<number, UserData>();\n\n private networkChat: ChatNetworkingClient | null = null;\n private textChatUI: TextChatUI | null = null;\n\n private avatarSelectionUI: AvatarSelectionUI | null = null;\n\n private voiceChatManager: VoiceChatManager | null = null;\n private readonly latestCharacterObject = {\n characterState: null as null | CharacterState,\n };\n private characterControllerPaneSet: boolean = false;\n\n private initialLoadCompleted = false;\n private loadingProgressManager = new LoadingProgressManager();\n private loadingScreen: LoadingScreen;\n private errorScreen?: ErrorScreen;\n private currentRequestAnimationFrame: number | null = null;\n private groundPlane: GroundPlane | null = null;\n\n constructor(\n private holderElement: HTMLElement,\n private config: Networked3dWebExperienceClientConfig,\n ) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.holderElement.appendChild(this.element);\n\n document.addEventListener(\"mousedown\", () => {\n if (this.audioListener.context.state === \"suspended\") {\n this.audioListener.context.resume();\n }\n });\n\n this.canvasHolder = document.createElement(\"div\");\n this.canvasHolder.style.position = \"absolute\";\n this.canvasHolder.style.width = \"100%\";\n this.canvasHolder.style.height = \"100%\";\n this.element.appendChild(this.canvasHolder);\n\n this.cameraManager = new CameraManager(this.canvasHolder, this.collisionsManager);\n this.cameraManager.camera.add(this.audioListener);\n\n this.virtualJoystick = new VirtualJoystick(this.element, {\n radius: 70,\n innerRadius: 20,\n mouseSupport: false,\n });\n\n this.composer = new Composer({\n scene: this.scene,\n cameraManager: this.cameraManager,\n spawnSun: true,\n environmentConfiguration: this.config.environmentConfiguration,\n });\n this.canvasHolder.appendChild(this.composer.renderer.domElement);\n\n if (this.config.enableTweakPane !== false) {\n this.setupTweakPane();\n }\n\n const resizeObserver = new ResizeObserver(() => {\n this.composer.fitContainer();\n });\n resizeObserver.observe(this.element);\n\n const initialNetworkLoadRef = {};\n this.loadingProgressManager.addLoadingAsset(initialNetworkLoadRef, \"network\", \"network\");\n this.networkClient = new UserNetworkingClient({\n url: this.config.userNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n this.characterManager.clear();\n this.remoteUserStates.clear();\n this.clientId = null;\n }\n },\n assignedIdentity: (clientId: number) => {\n console.log(`Assigned ID: ${clientId}`);\n this.clientId = clientId;\n if (this.initialLoadCompleted) {\n // Already loaded - respawn the character\n this.spawnCharacter();\n } else {\n this.loadingProgressManager.completedLoadingAsset(initialNetworkLoadRef);\n }\n },\n clientUpdate: (\n remoteClientId: number,\n userNetworkingClientUpdate: null | UserNetworkingClientUpdate,\n ) => {\n if (userNetworkingClientUpdate === null) {\n this.remoteUserStates.delete(remoteClientId);\n } else {\n this.remoteUserStates.set(remoteClientId, userNetworkingClientUpdate);\n }\n },\n clientProfileUpdated: (\n clientId: number,\n username: string,\n characterDescription: CharacterDescription,\n ): void => {\n this.updateUserProfile(clientId, {\n username,\n characterDescription,\n });\n },\n onServerError: (error: { message: string; errorType: UserNetworkingServerErrorType }) => {\n switch (error.errorType) {\n case USER_NETWORKING_AUTHENTICATION_FAILED_ERROR_TYPE:\n this.disposeWithError(error.message);\n break;\n case USER_NETWORKING_CONNECTION_LIMIT_REACHED_ERROR_TYPE:\n this.disposeWithError(error.message);\n break;\n case USER_NETWORKING_SERVER_SHUTDOWN_ERROR_TYPE:\n this.disposeWithError(error.message || \"Server shutdown\");\n break;\n default:\n console.error(`Unhandled server error: ${error.message}`);\n this.disposeWithError(error.message);\n }\n },\n onServerBroadcast: (broadcast: { broadcastType: string; payload: any }) => {\n this.config.onServerBroadcast?.(broadcast);\n },\n });\n\n if (this.config.allowOrbitalCamera) {\n this.keyInputManager.createKeyBinding(Key.C, () => {\n this.cameraManager.toggleFlyCamera();\n this.composer.fitContainer();\n });\n }\n\n this.characterManager = new CharacterManager({\n composer: this.composer,\n characterModelLoader: this.characterModelLoader,\n collisionsManager: this.collisionsManager,\n cameraManager: this.cameraManager,\n timeManager: this.timeManager,\n keyInputManager: this.keyInputManager,\n virtualJoystick: this.virtualJoystick,\n remoteUserStates: this.remoteUserStates,\n sendUpdate: (characterState: CharacterState) => {\n this.latestCharacterObject.characterState = characterState;\n this.networkClient.sendUpdate(characterState);\n },\n animationConfig: this.config.animationConfig,\n characterResolve: (characterId: number) => {\n return this.resolveCharacterData(characterId);\n },\n updateURLLocation: this.config.updateURLLocation !== false,\n });\n this.scene.add(this.characterManager.group);\n\n this.setGroundPlaneEnabled(this.config.environmentConfiguration?.groundPlane ?? true);\n\n this.setupMMLScene();\n\n this.loadingScreen = new LoadingScreen(this.loadingProgressManager, this.config.loadingScreen);\n this.element.append(this.loadingScreen.element);\n\n this.loadingProgressManager.addProgressCallback(() => {\n const [, completed] = this.loadingProgressManager.toRatio();\n if (completed && !this.initialLoadCompleted) {\n this.initialLoadCompleted = true;\n /*\n When all content (in particular MML) has loaded, spawn the character (this is to avoid the character falling\n through as-yet-unloaded geometry)\n */\n this.connectToVoiceChat();\n this.connectToTextChat();\n this.mountAvatarSelectionUI();\n this.spawnCharacter();\n }\n });\n this.loadingProgressManager.setInitialLoad(true);\n }\n\n private setGroundPlaneEnabled(enabled: boolean) {\n if (enabled && this.groundPlane === null) {\n this.groundPlane = new GroundPlane();\n this.collisionsManager.addMeshesGroup(this.groundPlane);\n this.scene.add(this.groundPlane);\n } else if (!enabled && this.groundPlane !== null) {\n this.collisionsManager.removeMeshesGroup(this.groundPlane);\n this.scene.remove(this.groundPlane);\n this.groundPlane = null;\n }\n }\n\n public updateConfig(config: Partial<UpdatableConfig>) {\n this.config = {\n ...this.config,\n ...config,\n };\n if (config.environmentConfiguration) {\n this.composer.updateEnvironmentConfiguration(config.environmentConfiguration);\n this.setGroundPlaneEnabled(config.environmentConfiguration.groundPlane ?? true);\n }\n\n if (config.avatarConfiguration && this.avatarSelectionUI) {\n this.avatarSelectionUI?.updateAvatarConfig(config.avatarConfiguration);\n }\n\n if (config.enableTweakPane !== undefined) {\n if (config.enableTweakPane === false && this.tweakPane !== null) {\n this.tweakPane.dispose();\n this.tweakPane = null;\n } else if (config.enableTweakPane === true && this.tweakPane === null) {\n this.setupTweakPane();\n }\n }\n\n if (config.chatNetworkAddress !== undefined) {\n if (config.chatNetworkAddress === null && this.networkChat !== null) {\n this.networkChat.stop();\n this.networkChat = null;\n this.textChatUI?.dispose();\n this.textChatUI = null;\n } else {\n this.connectToTextChat();\n }\n }\n if (config.mmlDocuments) {\n this.setMMLDocuments(config.mmlDocuments);\n }\n }\n\n static createFullscreenHolder(): HTMLDivElement {\n document.body.style.margin = \"0\";\n document.body.style.overflow = \"hidden\";\n\n const holder = document.createElement(\"div\");\n holder.style.position = \"absolute\";\n holder.style.width = \"100%\";\n holder.style.height = \"100%\";\n holder.style.overflow = \"hidden\";\n document.body.appendChild(holder);\n return holder;\n }\n\n private resolveCharacterData(clientId: number): {\n username: string;\n characterDescription: CharacterDescription;\n } {\n const user = this.userProfiles.get(clientId)!;\n\n if (!user) {\n throw new Error(`Failed to resolve user for clientId ${clientId}`);\n }\n\n return {\n username: user.username,\n characterDescription: user.characterDescription,\n };\n }\n\n private updateUserProfile(id: number, userData: UserData) {\n console.log(`Update user_profile for id=${id} (username=${userData.username})`);\n\n this.userProfiles.set(id, userData);\n\n this.characterManager.respawnIfPresent(id);\n }\n\n private updateUserAvatar(avatar: AvatarType) {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n const newUser = {\n ...user,\n characterDescription: {\n meshFileUrl: avatar.meshFileUrl ?? undefined,\n mmlCharacterUrl: avatar.mmlCharacterUrl ?? undefined,\n mmlCharacterString: avatar.mmlCharacterString ?? undefined,\n },\n } as UserData;\n\n this.userProfiles.set(this.clientId, newUser);\n this.updateUserProfile(this.clientId, newUser);\n }\n\n private sendChatMessageToServer(message: string): void {\n this.mmlCompositionScene.onChatMessage(message);\n if (this.clientId === null || this.networkChat === null) return;\n this.networkChat.sendChatMessage(message);\n }\n\n private sendIdentityUpdateToServer(avatar: AvatarType) {\n if (!this.clientId) {\n throw new Error(\"Client ID not set\");\n }\n\n const userProfile = this.userProfiles.get(this.clientId);\n\n if (!userProfile) {\n throw new Error(\"User profile not found\");\n }\n\n this.networkClient.sendMessage({\n type: USER_NETWORKING_USER_UPDATE_MESSAGE_TYPE,\n userIdentity: {\n username: userProfile.username,\n characterDescription: {\n mmlCharacterString: avatar.mmlCharacterString,\n mmlCharacterUrl: avatar.mmlCharacterUrl,\n meshFileUrl: avatar.meshFileUrl,\n } as CharacterDescription,\n },\n });\n }\n\n private connectToVoiceChat() {\n if (this.clientId === null) return;\n\n if (this.voiceChatManager === null && this.config.voiceChatAddress) {\n this.voiceChatManager = new VoiceChatManager({\n url: this.config.voiceChatAddress,\n holderElement: this.element,\n userId: this.clientId,\n remoteUserStates: this.remoteUserStates,\n latestCharacterObj: this.latestCharacterObject,\n autoJoin: false,\n });\n }\n }\n\n private setupTweakPane() {\n if (this.tweakPane) {\n return;\n }\n this.tweakPane = new TweakPane(\n this.element,\n this.composer.renderer,\n this.scene,\n this.composer.effectComposer,\n );\n this.cameraManager.setupTweakPane(this.tweakPane);\n this.composer.setupTweakPane(this.tweakPane);\n }\n\n private connectToTextChat() {\n if (this.clientId === null) {\n return;\n }\n if (this.networkChat === null && this.config.chatNetworkAddress) {\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n if (this.textChatUI === null) {\n const textChatUISettings: TextChatUIProps = {\n holderElement: this.element,\n clientname: user.username,\n sendMessageToServerMethod: this.sendChatMessageToServer.bind(this),\n visibleByDefault: this.config.chatVisibleByDefault,\n stringToHslOptions: this.config.userNameToColorOptions,\n };\n this.textChatUI = new TextChatUI(textChatUISettings);\n this.textChatUI.init();\n }\n\n this.networkChat = new ChatNetworkingClient({\n url: this.config.chatNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n }\n },\n clientChatUpdate: (\n clientId: number,\n chatNetworkingUpdate: null | ChatNetworkingClientChatMessage,\n ) => {\n if (chatNetworkingUpdate !== null && this.textChatUI !== null) {\n const username = this.userProfiles.get(clientId)?.username || \"Unknown\";\n this.textChatUI.addTextMessage(username, chatNetworkingUpdate.text);\n }\n },\n onServerError: (error: { message: string; errorType: ChatNetworkingServerErrorType }) => {\n console.error(`Chat server error: ${error.message}. errorType: ${error.errorType}`);\n this.disposeWithError(error.message);\n },\n });\n }\n }\n\n private mountAvatarSelectionUI() {\n this.avatarSelectionUI = new AvatarSelectionUI({\n holderElement: this.element,\n visibleByDefault: false,\n sendMessageToServerMethod: this.sendIdentityUpdateToServer.bind(this),\n availableAvatars: this.config.avatarConfiguration?.availableAvatars ?? [],\n allowCustomAvatars: this.config.avatarConfiguration?.allowCustomAvatars,\n });\n this.avatarSelectionUI.init();\n }\n\n public update(): void {\n this.timeManager.update();\n this.characterManager.update();\n this.voiceChatManager?.speakingParticipants.forEach((value: boolean, id: number) => {\n this.characterManager.setSpeakingCharacter(id, value);\n });\n this.cameraManager.update();\n this.composer.sun?.updateCharacterPosition(this.characterManager.localCharacter?.position);\n this.composer.render(this.timeManager);\n if (this.tweakPane?.guiVisible) {\n this.tweakPane.updateStats(this.timeManager);\n this.tweakPane.updateCameraData(this.cameraManager);\n if (this.characterManager.localCharacter && this.characterManager.localController) {\n if (!this.characterControllerPaneSet) {\n this.characterControllerPaneSet = true;\n this.characterManager.setupTweakPane(this.tweakPane);\n } else {\n this.tweakPane.updateCharacterData(this.characterManager.localController);\n }\n }\n }\n this.currentRequestAnimationFrame = requestAnimationFrame(() => {\n this.update();\n });\n }\n\n private spawnCharacter() {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const spawnPosition = getSpawnPositionInsideCircle(3, 30, this.clientId!, 0.4);\n const spawnRotation = new Euler(0, 0, 0);\n let cameraPosition: Vector3 | null = null;\n if (window.location.hash && window.location.hash.length > 1) {\n const urlParams = decodeCharacterAndCamera(window.location.hash.substring(1));\n spawnPosition.copy(urlParams.character.position);\n spawnRotation.setFromQuaternion(urlParams.character.quaternion);\n cameraPosition = urlParams.camera.position;\n }\n const ownIdentity = this.userProfiles.get(this.clientId);\n if (!ownIdentity) {\n throw new Error(\"Own identity not found\");\n }\n\n this.characterManager.spawnLocalCharacter(\n this.clientId!,\n ownIdentity.username,\n ownIdentity.characterDescription,\n spawnPosition,\n spawnRotation,\n );\n\n if (cameraPosition !== null) {\n this.cameraManager.camera.position.copy(cameraPosition);\n this.cameraManager.setTarget(\n new Vector3().add(spawnPosition).add(this.characterManager.headTargetOffset),\n );\n this.cameraManager.reverseUpdateFromPositions();\n }\n }\n\n private disposeWithError(message: string) {\n this.dispose();\n this.errorScreen = new ErrorScreen(\"An error occurred\", message);\n this.element.append(this.errorScreen.element);\n }\n\n public dispose() {\n this.networkClient.stop();\n this.networkChat?.stop();\n for (const [key, element] of Object.entries(this.mmlFrames)) {\n element.remove();\n }\n this.mmlFrames = {};\n this.textChatUI?.dispose();\n this.mmlCompositionScene.dispose();\n this.composer.dispose();\n this.tweakPane?.dispose();\n if (this.currentRequestAnimationFrame !== null) {\n cancelAnimationFrame(this.currentRequestAnimationFrame);\n this.currentRequestAnimationFrame = null;\n }\n this.cameraManager.dispose();\n this.loadingScreen.dispose();\n this.errorScreen?.dispose();\n }\n\n private setupMMLScene() {\n registerCustomElementsToWindow(window);\n this.mmlCompositionScene = new MMLCompositionScene({\n targetElement: this.element,\n renderer: this.composer.renderer,\n scene: this.scene,\n camera: this.cameraManager.camera,\n audioListener: this.audioListener,\n collisionsManager: this.collisionsManager,\n getUserPositionAndRotation: () => {\n return this.characterManager.getLocalCharacterPositionAndRotation();\n },\n });\n this.scene.add(this.mmlCompositionScene.group);\n setGlobalMMLScene(this.mmlCompositionScene.mmlScene as IMMLScene);\n setGlobalDocumentTimeManager(this.mmlCompositionScene.documentTimeManager);\n\n this.setMMLDocuments(this.config.mmlDocuments ?? {});\n\n const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager!()!;\n this.loadingProgressManager.addLoadingDocument(mmlProgressManager, \"mml\", mmlProgressManager);\n mmlProgressManager.addProgressCallback(() => {\n this.loadingProgressManager.updateDocumentProgress(mmlProgressManager);\n });\n mmlProgressManager.setInitialLoad(true);\n }\n\n private createFrame(mmlDocument: MMLDocumentConfiguration) {\n const frameElement = document.createElement(\"m-frame\");\n frameElement.setAttribute(\"src\", mmlDocument.url);\n this.updateFrameAttributes(frameElement, mmlDocument);\n return frameElement;\n }\n\n private updateFrameAttributes(frameElement: HTMLElement, mmlDocument: MMLDocumentConfiguration) {\n const existingSrc = frameElement.getAttribute(\"src\");\n if (existingSrc !== mmlDocument.url) {\n frameElement.setAttribute(\"src\", mmlDocument.url);\n }\n if (mmlDocument.position) {\n frameElement.setAttribute(\"x\", mmlDocument.position.x.toString());\n frameElement.setAttribute(\"y\", mmlDocument.position.y.toString());\n frameElement.setAttribute(\"z\", mmlDocument.position.z.toString());\n } else {\n frameElement.setAttribute(\"x\", \"0\");\n frameElement.setAttribute(\"y\", \"0\");\n frameElement.setAttribute(\"z\", \"0\");\n }\n if (mmlDocument.rotation) {\n frameElement.setAttribute(\"rx\", mmlDocument.rotation.x.toString());\n frameElement.setAttribute(\"ry\", mmlDocument.rotation.y.toString());\n frameElement.setAttribute(\"rz\", mmlDocument.rotation.z.toString());\n } else {\n frameElement.setAttribute(\"rx\", \"0\");\n frameElement.setAttribute(\"ry\", \"0\");\n frameElement.setAttribute(\"rz\", \"0\");\n }\n if (mmlDocument.scale?.x !== undefined) {\n frameElement.setAttribute(\"sx\", mmlDocument.scale.x.toString());\n } else {\n frameElement.setAttribute(\"sx\", \"1\");\n }\n if (mmlDocument.scale?.y !== undefined) {\n frameElement.setAttribute(\"sy\", mmlDocument.scale.y.toString());\n } else {\n frameElement.setAttribute(\"sy\", \"1\");\n }\n if (mmlDocument.scale?.z !== undefined) {\n frameElement.setAttribute(\"sz\", mmlDocument.scale.z.toString());\n } else {\n frameElement.setAttribute(\"sz\", \"1\");\n }\n }\n\n private setMMLDocuments(mmlDocuments: { [key: string]: MMLDocumentConfiguration }) {\n const newFramesMap: { [key: string]: HTMLElement } = {};\n for (const [key, mmlDocSpec] of Object.entries(mmlDocuments)) {\n const existing = this.mmlFrames[key];\n if (!existing) {\n const frameElement = this.createFrame(mmlDocSpec);\n document.body.appendChild(frameElement);\n newFramesMap[key] = frameElement;\n } else {\n delete this.mmlFrames[key];\n newFramesMap[key] = existing;\n this.updateFrameAttributes(existing, mmlDocSpec);\n }\n }\n for (const [key, element] of Object.entries(this.mmlFrames)) {\n element.remove();\n }\n this.mmlFrames = newFramesMap;\n }\n}\n"],
5
+ "mappings": ";AAAA;AAAA,EACE;AAAA,OAGK;AACP;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAIA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAGA;AAAA,OACK;AACP,SAAS,wBAAwB;AACjC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe,OAAO,OAAO,eAAe;AA0C9C,IAAM,iCAAN,MAAqC;AAAA,EA+C1C,YACU,eACA,QACR;AAFQ;AACA;AA7CV,SAAQ,QAAQ,IAAI,MAAM;AAE1B,SAAQ,YAA8B;AACtC,SAAQ,gBAAgB,IAAI,cAAc;AAI1C,SAAQ,oBAAoB,IAAI,kBAAkB,KAAK,KAAK;AAE5D,SAAQ,uBAAuB,IAAI,qBAAqB;AAGxD,SAAQ,cAAc,IAAI,YAAY;AAEtC,SAAQ,kBAAkB,IAAI,gBAAgB;AAI9C,SAAQ,YAA4C,CAAC;AAErD,SAAQ,WAA0B;AAElC,SAAQ,mBAAmB,oBAAI,IAA4B;AAC3D,SAAQ,eAAe,oBAAI,IAAsB;AAEjD,SAAQ,cAA2C;AACnD,SAAQ,aAAgC;AAExC,SAAQ,oBAA8C;AAEtD,SAAQ,mBAA4C;AACpD,SAAiB,wBAAwB;AAAA,MACvC,gBAAgB;AAAA,IAClB;AACA,SAAQ,6BAAsC;AAE9C,SAAQ,uBAAuB;AAC/B,SAAQ,yBAAyB,IAAI,uBAAuB;AAG5D,SAAQ,+BAA8C;AACtD,SAAQ,cAAkC;AA9I5C;AAoJI,SAAK,UAAU,SAAS,cAAc,KAAK;AAC3C,SAAK,QAAQ,MAAM,WAAW;AAC9B,SAAK,QAAQ,MAAM,QAAQ;AAC3B,SAAK,QAAQ,MAAM,SAAS;AAC5B,SAAK,cAAc,YAAY,KAAK,OAAO;AAE3C,aAAS,iBAAiB,aAAa,MAAM;AAC3C,UAAI,KAAK,cAAc,QAAQ,UAAU,aAAa;AACpD,aAAK,cAAc,QAAQ,OAAO;AAAA,MACpC;AAAA,IACF,CAAC;AAED,SAAK,eAAe,SAAS,cAAc,KAAK;AAChD,SAAK,aAAa,MAAM,WAAW;AACnC,SAAK,aAAa,MAAM,QAAQ;AAChC,SAAK,aAAa,MAAM,SAAS;AACjC,SAAK,QAAQ,YAAY,KAAK,YAAY;AAE1C,SAAK,gBAAgB,IAAI,cAAc,KAAK,cAAc,KAAK,iBAAiB;AAChF,SAAK,cAAc,OAAO,IAAI,KAAK,aAAa;AAEhD,SAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS;AAAA,MACvD,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAED,SAAK,WAAW,IAAI,SAAS;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,eAAe,KAAK;AAAA,MACpB,UAAU;AAAA,MACV,0BAA0B,KAAK,OAAO;AAAA,IACxC,CAAC;AACD,SAAK,aAAa,YAAY,KAAK,SAAS,SAAS,UAAU;AAE/D,QAAI,KAAK,OAAO,oBAAoB,OAAO;AACzC,WAAK,eAAe;AAAA,IACtB;AAEA,UAAM,iBAAiB,IAAI,eAAe,MAAM;AAC9C,WAAK,SAAS,aAAa;AAAA,IAC7B,CAAC;AACD,mBAAe,QAAQ,KAAK,OAAO;AAEnC,UAAM,wBAAwB,CAAC;AAC/B,SAAK,uBAAuB,gBAAgB,uBAAuB,WAAW,SAAS;AACvF,SAAK,gBAAgB,IAAI,qBAAqB;AAAA,MAC5C,KAAK,KAAK,OAAO;AAAA,MACjB,cAAc,KAAK,OAAO;AAAA,MAC1B,kBAAkB,CAAC,QAAgB,IAAI,UAAU,GAAG;AAAA,MACpD,sBAAsB,CAAC,WAA4B;AACjD,YAAI,WAAW,gBAAgB,gBAAgB,WAAW,gBAAgB,cAAc;AAEtF,eAAK,iBAAiB,MAAM;AAC5B,eAAK,iBAAiB,MAAM;AAC5B,eAAK,WAAW;AAAA,QAClB;AAAA,MACF;AAAA,MACA,kBAAkB,CAAC,aAAqB;AACtC,gBAAQ,IAAI,gBAAgB,QAAQ,EAAE;AACtC,aAAK,WAAW;AAChB,YAAI,KAAK,sBAAsB;AAE7B,eAAK,eAAe;AAAA,QACtB,OAAO;AACL,eAAK,uBAAuB,sBAAsB,qBAAqB;AAAA,QACzE;AAAA,MACF;AAAA,MACA,cAAc,CACZ,gBACA,+BACG;AACH,YAAI,+BAA+B,MAAM;AACvC,eAAK,iBAAiB,OAAO,cAAc;AAAA,QAC7C,OAAO;AACL,eAAK,iBAAiB,IAAI,gBAAgB,0BAA0B;AAAA,QACtE;AAAA,MACF;AAAA,MACA,sBAAsB,CACpB,UACA,UACA,yBACS;AACT,aAAK,kBAAkB,UAAU;AAAA,UAC/B;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,eAAe,CAAC,UAAyE;AACvF,gBAAQ,MAAM,WAAW;AAAA,UACvB,KAAK;AACH,iBAAK,iBAAiB,MAAM,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,iBAAiB,MAAM,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,iBAAiB,MAAM,WAAW,iBAAiB;AACxD;AAAA,UACF;AACE,oBAAQ,MAAM,2BAA2B,MAAM,OAAO,EAAE;AACxD,iBAAK,iBAAiB,MAAM,OAAO;AAAA,QACvC;AAAA,MACF;AAAA,MACA,mBAAmB,CAAC,cAAuD;AA5PjF,YAAAA,KAAA;AA6PQ,eAAAA,MAAA,KAAK,QAAO,sBAAZ,wBAAAA,KAAgC;AAAA,MAClC;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO,oBAAoB;AAClC,WAAK,gBAAgB,iBAAiB,IAAI,GAAG,MAAM;AACjD,aAAK,cAAc,gBAAgB;AACnC,aAAK,SAAS,aAAa;AAAA,MAC7B,CAAC;AAAA,IACH;AAEA,SAAK,mBAAmB,IAAI,iBAAiB;AAAA,MAC3C,UAAU,KAAK;AAAA,MACf,sBAAsB,KAAK;AAAA,MAC3B,mBAAmB,KAAK;AAAA,MACxB,eAAe,KAAK;AAAA,MACpB,aAAa,KAAK;AAAA,MAClB,iBAAiB,KAAK;AAAA,MACtB,iBAAiB,KAAK;AAAA,MACtB,kBAAkB,KAAK;AAAA,MACvB,YAAY,CAAC,mBAAmC;AAC9C,aAAK,sBAAsB,iBAAiB;AAC5C,aAAK,cAAc,WAAW,cAAc;AAAA,MAC9C;AAAA,MACA,iBAAiB,KAAK,OAAO;AAAA,MAC7B,kBAAkB,CAAC,gBAAwB;AACzC,eAAO,KAAK,qBAAqB,WAAW;AAAA,MAC9C;AAAA,MACA,mBAAmB,KAAK,OAAO,sBAAsB;AAAA,IACvD,CAAC;AACD,SAAK,MAAM,IAAI,KAAK,iBAAiB,KAAK;AAE1C,SAAK,wBAAsB,UAAK,OAAO,6BAAZ,mBAAsC,gBAAe,IAAI;AAEpF,SAAK,cAAc;AAEnB,SAAK,gBAAgB,IAAI,cAAc,KAAK,wBAAwB,KAAK,OAAO,aAAa;AAC7F,SAAK,QAAQ,OAAO,KAAK,cAAc,OAAO;AAE9C,SAAK,uBAAuB,oBAAoB,MAAM;AACpD,YAAM,CAAC,EAAE,SAAS,IAAI,KAAK,uBAAuB,QAAQ;AAC1D,UAAI,aAAa,CAAC,KAAK,sBAAsB;AAC3C,aAAK,uBAAuB;AAK5B,aAAK,mBAAmB;AACxB,aAAK,kBAAkB;AACvB,aAAK,uBAAuB;AAC5B,aAAK,eAAe;AAAA,MACtB;AAAA,IACF,CAAC;AACD,SAAK,uBAAuB,eAAe,IAAI;AAAA,EACjD;AAAA,EAEQ,sBAAsB,SAAkB;AAC9C,QAAI,WAAW,KAAK,gBAAgB,MAAM;AACxC,WAAK,cAAc,IAAI,YAAY;AACnC,WAAK,kBAAkB,eAAe,KAAK,WAAW;AACtD,WAAK,MAAM,IAAI,KAAK,WAAW;AAAA,IACjC,WAAW,CAAC,WAAW,KAAK,gBAAgB,MAAM;AAChD,WAAK,kBAAkB,kBAAkB,KAAK,WAAW;AACzD,WAAK,MAAM,OAAO,KAAK,WAAW;AAClC,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEO,aAAa,QAAkC;AAjUxD;AAkUI,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL;AACA,QAAI,OAAO,0BAA0B;AACnC,WAAK,SAAS,+BAA+B,OAAO,wBAAwB;AAC5E,WAAK,sBAAsB,OAAO,yBAAyB,eAAe,IAAI;AAAA,IAChF;AAEA,QAAI,OAAO,uBAAuB,KAAK,mBAAmB;AACxD,iBAAK,sBAAL,mBAAwB,mBAAmB,OAAO;AAAA,IACpD;AAEA,QAAI,OAAO,oBAAoB,QAAW;AACxC,UAAI,OAAO,oBAAoB,SAAS,KAAK,cAAc,MAAM;AAC/D,aAAK,UAAU,QAAQ;AACvB,aAAK,YAAY;AAAA,MACnB,WAAW,OAAO,oBAAoB,QAAQ,KAAK,cAAc,MAAM;AACrE,aAAK,eAAe;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,OAAO,uBAAuB,QAAW;AAC3C,UAAI,OAAO,uBAAuB,QAAQ,KAAK,gBAAgB,MAAM;AACnE,aAAK,YAAY,KAAK;AACtB,aAAK,cAAc;AACnB,mBAAK,eAAL,mBAAiB;AACjB,aAAK,aAAa;AAAA,MACpB,OAAO;AACL,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AACA,QAAI,OAAO,cAAc;AACvB,WAAK,gBAAgB,OAAO,YAAY;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,OAAO,yBAAyC;AAC9C,aAAS,KAAK,MAAM,SAAS;AAC7B,aAAS,KAAK,MAAM,WAAW;AAE/B,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,MAAM,WAAW;AACxB,WAAO,MAAM,QAAQ;AACrB,WAAO,MAAM,SAAS;AACtB,WAAO,MAAM,WAAW;AACxB,aAAS,KAAK,YAAY,MAAM;AAChC,WAAO;AAAA,EACT;AAAA,EAEQ,qBAAqB,UAG3B;AACA,UAAM,OAAO,KAAK,aAAa,IAAI,QAAQ;AAE3C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,uCAAuC,QAAQ,EAAE;AAAA,IACnE;AAEA,WAAO;AAAA,MACL,UAAU,KAAK;AAAA,MACf,sBAAsB,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,kBAAkB,IAAY,UAAoB;AACxD,YAAQ,IAAI,8BAA8B,EAAE,cAAc,SAAS,QAAQ,GAAG;AAE9E,SAAK,aAAa,IAAI,IAAI,QAAQ;AAElC,SAAK,iBAAiB,iBAAiB,EAAE;AAAA,EAC3C;AAAA,EAEQ,iBAAiB,QAAoB;AAC3C,QAAI,KAAK,aAAa,MAAM;AAC1B,YAAM,IAAI,MAAM,mBAAmB;AAAA,IACrC;AACA,UAAM,OAAO,KAAK,aAAa,IAAI,KAAK,QAAQ;AAChD,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gBAAgB;AAAA,IAClC;AAEA,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,MACH,sBAAsB;AAAA,QACpB,aAAa,OAAO,eAAe;AAAA,QACnC,iBAAiB,OAAO,mBAAmB;AAAA,QAC3C,oBAAoB,OAAO,sBAAsB;AAAA,MACnD;AAAA,IACF;AAEA,SAAK,aAAa,IAAI,KAAK,UAAU,OAAO;AAC5C,SAAK,kBAAkB,KAAK,UAAU,OAAO;AAAA,EAC/C;AAAA,EAEQ,wBAAwB,SAAuB;AACrD,SAAK,oBAAoB,cAAc,OAAO;AAC9C,QAAI,KAAK,aAAa,QAAQ,KAAK,gBAAgB;AAAM;AACzD,SAAK,YAAY,gBAAgB,OAAO;AAAA,EAC1C;AAAA,EAEQ,2BAA2B,QAAoB;AACrD,QAAI,CAAC,KAAK,UAAU;AAClB,YAAM,IAAI,MAAM,mBAAmB;AAAA,IACrC;AAEA,UAAM,cAAc,KAAK,aAAa,IAAI,KAAK,QAAQ;AAEvD,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAEA,SAAK,cAAc,YAAY;AAAA,MAC7B,MAAM;AAAA,MACN,cAAc;AAAA,QACZ,UAAU,YAAY;AAAA,QACtB,sBAAsB;AAAA,UACpB,oBAAoB,OAAO;AAAA,UAC3B,iBAAiB,OAAO;AAAA,UACxB,aAAa,OAAO;AAAA,QACtB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,qBAAqB;AAC3B,QAAI,KAAK,aAAa;AAAM;AAE5B,QAAI,KAAK,qBAAqB,QAAQ,KAAK,OAAO,kBAAkB;AAClE,WAAK,mBAAmB,IAAI,iBAAiB;AAAA,QAC3C,KAAK,KAAK,OAAO;AAAA,QACjB,eAAe,KAAK;AAAA,QACpB,QAAQ,KAAK;AAAA,QACb,kBAAkB,KAAK;AAAA,QACvB,oBAAoB,KAAK;AAAA,QACzB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBAAiB;AACvB,QAAI,KAAK,WAAW;AAClB;AAAA,IACF;AACA,SAAK,YAAY,IAAI;AAAA,MACnB,KAAK;AAAA,MACL,KAAK,SAAS;AAAA,MACd,KAAK;AAAA,MACL,KAAK,SAAS;AAAA,IAChB;AACA,SAAK,cAAc,eAAe,KAAK,SAAS;AAChD,SAAK,SAAS,eAAe,KAAK,SAAS;AAAA,EAC7C;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,KAAK,aAAa,MAAM;AAC1B;AAAA,IACF;AACA,QAAI,KAAK,gBAAgB,QAAQ,KAAK,OAAO,oBAAoB;AAC/D,YAAM,OAAO,KAAK,aAAa,IAAI,KAAK,QAAQ;AAChD,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,gBAAgB;AAAA,MAClC;AAEA,UAAI,KAAK,eAAe,MAAM;AAC5B,cAAM,qBAAsC;AAAA,UAC1C,eAAe,KAAK;AAAA,UACpB,YAAY,KAAK;AAAA,UACjB,2BAA2B,KAAK,wBAAwB,KAAK,IAAI;AAAA,UACjE,kBAAkB,KAAK,OAAO;AAAA,UAC9B,oBAAoB,KAAK,OAAO;AAAA,QAClC;AACA,aAAK,aAAa,IAAI,WAAW,kBAAkB;AACnD,aAAK,WAAW,KAAK;AAAA,MACvB;AAEA,WAAK,cAAc,IAAI,qBAAqB;AAAA,QAC1C,KAAK,KAAK,OAAO;AAAA,QACjB,cAAc,KAAK,OAAO;AAAA,QAC1B,kBAAkB,CAAC,QAAgB,IAAI,UAAU,GAAG;AAAA,QACpD,sBAAsB,CAAC,WAA4B;AACjD,cAAI,WAAW,gBAAgB,gBAAgB,WAAW,gBAAgB,cAAc;AAAA,UAExF;AAAA,QACF;AAAA,QACA,kBAAkB,CAChB,UACA,yBACG;AA/fb;AAggBU,cAAI,yBAAyB,QAAQ,KAAK,eAAe,MAAM;AAC7D,kBAAM,aAAW,UAAK,aAAa,IAAI,QAAQ,MAA9B,mBAAiC,aAAY;AAC9D,iBAAK,WAAW,eAAe,UAAU,qBAAqB,IAAI;AAAA,UACpE;AAAA,QACF;AAAA,QACA,eAAe,CAAC,UAAyE;AACvF,kBAAQ,MAAM,sBAAsB,MAAM,OAAO,gBAAgB,MAAM,SAAS,EAAE;AAClF,eAAK,iBAAiB,MAAM,OAAO;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,yBAAyB;AA7gBnC;AA8gBI,SAAK,oBAAoB,IAAI,kBAAkB;AAAA,MAC7C,eAAe,KAAK;AAAA,MACpB,kBAAkB;AAAA,MAClB,2BAA2B,KAAK,2BAA2B,KAAK,IAAI;AAAA,MACpE,oBAAkB,UAAK,OAAO,wBAAZ,mBAAiC,qBAAoB,CAAC;AAAA,MACxE,qBAAoB,UAAK,OAAO,wBAAZ,mBAAiC;AAAA,IACvD,CAAC;AACD,SAAK,kBAAkB,KAAK;AAAA,EAC9B;AAAA,EAEO,SAAe;AAxhBxB;AAyhBI,SAAK,YAAY,OAAO;AACxB,SAAK,iBAAiB,OAAO;AAC7B,eAAK,qBAAL,mBAAuB,qBAAqB,QAAQ,CAAC,OAAgB,OAAe;AAClF,WAAK,iBAAiB,qBAAqB,IAAI,KAAK;AAAA,IACtD;AACA,SAAK,cAAc,OAAO;AAC1B,eAAK,SAAS,QAAd,mBAAmB,yBAAwB,UAAK,iBAAiB,mBAAtB,mBAAsC;AACjF,SAAK,SAAS,OAAO,KAAK,WAAW;AACrC,SAAI,UAAK,cAAL,mBAAgB,YAAY;AAC9B,WAAK,UAAU,YAAY,KAAK,WAAW;AAC3C,WAAK,UAAU,iBAAiB,KAAK,aAAa;AAClD,UAAI,KAAK,iBAAiB,kBAAkB,KAAK,iBAAiB,iBAAiB;AACjF,YAAI,CAAC,KAAK,4BAA4B;AACpC,eAAK,6BAA6B;AAClC,eAAK,iBAAiB,eAAe,KAAK,SAAS;AAAA,QACrD,OAAO;AACL,eAAK,UAAU,oBAAoB,KAAK,iBAAiB,eAAe;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AACA,SAAK,+BAA+B,sBAAsB,MAAM;AAC9D,WAAK,OAAO;AAAA,IACd,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB;AACvB,QAAI,KAAK,aAAa,MAAM;AAC1B,YAAM,IAAI,MAAM,mBAAmB;AAAA,IACrC;AACA,UAAM,gBAAgB,6BAA6B,GAAG,IAAI,KAAK,UAAW,GAAG;AAC7E,UAAM,gBAAgB,IAAI,MAAM,GAAG,GAAG,CAAC;AACvC,QAAI,iBAAiC;AACrC,QAAI,OAAO,SAAS,QAAQ,OAAO,SAAS,KAAK,SAAS,GAAG;AAC3D,YAAM,YAAY,yBAAyB,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC;AAC5E,oBAAc,KAAK,UAAU,UAAU,QAAQ;AAC/C,oBAAc,kBAAkB,UAAU,UAAU,UAAU;AAC9D,uBAAiB,UAAU,OAAO;AAAA,IACpC;AACA,UAAM,cAAc,KAAK,aAAa,IAAI,KAAK,QAAQ;AACvD,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAEA,SAAK,iBAAiB;AAAA,MACpB,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AAEA,QAAI,mBAAmB,MAAM;AAC3B,WAAK,cAAc,OAAO,SAAS,KAAK,cAAc;AACtD,WAAK,cAAc;AAAA,QACjB,IAAI,QAAQ,EAAE,IAAI,aAAa,EAAE,IAAI,KAAK,iBAAiB,gBAAgB;AAAA,MAC7E;AACA,WAAK,cAAc,2BAA2B;AAAA,IAChD;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAiB;AACxC,SAAK,QAAQ;AACb,SAAK,cAAc,IAAI,YAAY,qBAAqB,OAAO;AAC/D,SAAK,QAAQ,OAAO,KAAK,YAAY,OAAO;AAAA,EAC9C;AAAA,EAEO,UAAU;AA3lBnB;AA4lBI,SAAK,cAAc,KAAK;AACxB,eAAK,gBAAL,mBAAkB;AAClB,eAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,KAAK,SAAS,GAAG;AAC3D,cAAQ,OAAO;AAAA,IACjB;AACA,SAAK,YAAY,CAAC;AAClB,eAAK,eAAL,mBAAiB;AACjB,SAAK,oBAAoB,QAAQ;AACjC,SAAK,SAAS,QAAQ;AACtB,eAAK,cAAL,mBAAgB;AAChB,QAAI,KAAK,iCAAiC,MAAM;AAC9C,2BAAqB,KAAK,4BAA4B;AACtD,WAAK,+BAA+B;AAAA,IACtC;AACA,SAAK,cAAc,QAAQ;AAC3B,SAAK,cAAc,QAAQ;AAC3B,eAAK,gBAAL,mBAAkB;AAAA,EACpB;AAAA,EAEQ,gBAAgB;AACtB,mCAA+B,MAAM;AACrC,SAAK,sBAAsB,IAAI,oBAAoB;AAAA,MACjD,eAAe,KAAK;AAAA,MACpB,UAAU,KAAK,SAAS;AAAA,MACxB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK,cAAc;AAAA,MAC3B,eAAe,KAAK;AAAA,MACpB,mBAAmB,KAAK;AAAA,MACxB,4BAA4B,MAAM;AAChC,eAAO,KAAK,iBAAiB,qCAAqC;AAAA,MACpE;AAAA,IACF,CAAC;AACD,SAAK,MAAM,IAAI,KAAK,oBAAoB,KAAK;AAC7C,sBAAkB,KAAK,oBAAoB,QAAqB;AAChE,iCAA6B,KAAK,oBAAoB,mBAAmB;AAEzE,SAAK,gBAAgB,KAAK,OAAO,gBAAgB,CAAC,CAAC;AAEnD,UAAM,qBAAqB,KAAK,oBAAoB,SAAS,0BAA2B;AACxF,SAAK,uBAAuB,mBAAmB,oBAAoB,OAAO,kBAAkB;AAC5F,uBAAmB,oBAAoB,MAAM;AAC3C,WAAK,uBAAuB,uBAAuB,kBAAkB;AAAA,IACvE,CAAC;AACD,uBAAmB,eAAe,IAAI;AAAA,EACxC;AAAA,EAEQ,YAAY,aAAuC;AACzD,UAAM,eAAe,SAAS,cAAc,SAAS;AACrD,iBAAa,aAAa,OAAO,YAAY,GAAG;AAChD,SAAK,sBAAsB,cAAc,WAAW;AACpD,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,cAA2B,aAAuC;AAjpBlG;AAkpBI,UAAM,cAAc,aAAa,aAAa,KAAK;AACnD,QAAI,gBAAgB,YAAY,KAAK;AACnC,mBAAa,aAAa,OAAO,YAAY,GAAG;AAAA,IAClD;AACA,QAAI,YAAY,UAAU;AACxB,mBAAa,aAAa,KAAK,YAAY,SAAS,EAAE,SAAS,CAAC;AAChE,mBAAa,aAAa,KAAK,YAAY,SAAS,EAAE,SAAS,CAAC;AAChE,mBAAa,aAAa,KAAK,YAAY,SAAS,EAAE,SAAS,CAAC;AAAA,IAClE,OAAO;AACL,mBAAa,aAAa,KAAK,GAAG;AAClC,mBAAa,aAAa,KAAK,GAAG;AAClC,mBAAa,aAAa,KAAK,GAAG;AAAA,IACpC;AACA,QAAI,YAAY,UAAU;AACxB,mBAAa,aAAa,MAAM,YAAY,SAAS,EAAE,SAAS,CAAC;AACjE,mBAAa,aAAa,MAAM,YAAY,SAAS,EAAE,SAAS,CAAC;AACjE,mBAAa,aAAa,MAAM,YAAY,SAAS,EAAE,SAAS,CAAC;AAAA,IACnE,OAAO;AACL,mBAAa,aAAa,MAAM,GAAG;AACnC,mBAAa,aAAa,MAAM,GAAG;AACnC,mBAAa,aAAa,MAAM,GAAG;AAAA,IACrC;AACA,UAAI,iBAAY,UAAZ,mBAAmB,OAAM,QAAW;AACtC,mBAAa,aAAa,MAAM,YAAY,MAAM,EAAE,SAAS,CAAC;AAAA,IAChE,OAAO;AACL,mBAAa,aAAa,MAAM,GAAG;AAAA,IACrC;AACA,UAAI,iBAAY,UAAZ,mBAAmB,OAAM,QAAW;AACtC,mBAAa,aAAa,MAAM,YAAY,MAAM,EAAE,SAAS,CAAC;AAAA,IAChE,OAAO;AACL,mBAAa,aAAa,MAAM,GAAG;AAAA,IACrC;AACA,UAAI,iBAAY,UAAZ,mBAAmB,OAAM,QAAW;AACtC,mBAAa,aAAa,MAAM,YAAY,MAAM,EAAE,SAAS,CAAC;AAAA,IAChE,OAAO;AACL,mBAAa,aAAa,MAAM,GAAG;AAAA,IACrC;AAAA,EACF;AAAA,EAEQ,gBAAgB,cAA2D;AACjF,UAAM,eAA+C,CAAC;AACtD,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC5D,YAAM,WAAW,KAAK,UAAU,GAAG;AACnC,UAAI,CAAC,UAAU;AACb,cAAM,eAAe,KAAK,YAAY,UAAU;AAChD,iBAAS,KAAK,YAAY,YAAY;AACtC,qBAAa,GAAG,IAAI;AAAA,MACtB,OAAO;AACL,eAAO,KAAK,UAAU,GAAG;AACzB,qBAAa,GAAG,IAAI;AACpB,aAAK,sBAAsB,UAAU,UAAU;AAAA,MACjD;AAAA,IACF;AACA,eAAW,CAAC,KAAK,OAAO,KAAK,OAAO,QAAQ,KAAK,SAAS,GAAG;AAC3D,cAAQ,OAAO;AAAA,IACjB;AACA,SAAK,YAAY;AAAA,EACnB;AACF;",
6
+ "names": ["_a"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mml-io/3d-web-experience-client",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -18,17 +18,17 @@
18
18
  "lint-fix": "eslint \"./{src,test}/**/*.{js,jsx,ts,tsx}\" --fix"
19
19
  },
20
20
  "dependencies": {
21
- "@mml-io/3d-web-avatar-selection-ui": "^0.18.0",
22
- "@mml-io/3d-web-client-core": "^0.18.0",
23
- "@mml-io/3d-web-text-chat": "^0.18.0",
24
- "@mml-io/3d-web-user-networking": "^0.18.0",
25
- "@mml-io/3d-web-voice-chat": "^0.18.0",
26
- "mml-web": "^0.16.1",
21
+ "@mml-io/3d-web-avatar-selection-ui": "^0.20.0",
22
+ "@mml-io/3d-web-client-core": "^0.20.0",
23
+ "@mml-io/3d-web-text-chat": "^0.20.0",
24
+ "@mml-io/3d-web-user-networking": "^0.20.0",
25
+ "@mml-io/3d-web-voice-chat": "^0.20.0",
26
+ "@mml-io/mml-web": "0.19.0",
27
27
  "three": "0.163.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^20.14.10",
31
31
  "@types/three": "0.163.0"
32
32
  },
33
- "gitHead": "8eb8acbdc767b15eacf3e8d62c5a0c92d2690f37"
33
+ "gitHead": "8dada83f0324f46a9078f21de64fa58b90bb238d"
34
34
  }