@viji-dev/core 0.1.0-alpha.1 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -343,6 +343,26 @@ await core.setVideoStream(videoStream);
343
343
  await core.setVideoStream(null);
344
344
  ```
345
345
 
346
+ #### Interaction Management
347
+
348
+ ```typescript
349
+ // Enable or disable user interactions at runtime
350
+ await core.setInteractionEnabled(true); // Enable mouse, keyboard, and touch
351
+ await core.setInteractionEnabled(false); // Disable all interactions
352
+
353
+ // Get current interaction state
354
+ const isInteractionEnabled = core.getInteractionEnabled();
355
+
356
+ // Interaction state affects:
357
+ // - Mouse, keyboard, and touch event processing
358
+ // - Parameter visibility (interaction category parameters)
359
+ // - Scene behavior that depends on user input
360
+
361
+ // Note: Interaction state is separate from initialization config
362
+ // You can toggle interactions regardless of initial allowUserInteraction value
363
+ // The interaction system is always available for runtime control
364
+ ```
365
+
346
366
  #### Capability Change Monitoring
347
367
 
348
368
  ```typescript
@@ -362,6 +382,12 @@ core.onCapabilitiesChange((capabilities) => {
362
382
  } else {
363
383
  hideVideoControls();
364
384
  }
385
+
386
+ if (capabilities.hasInteraction) {
387
+ showInteractionControls();
388
+ } else {
389
+ hideInteractionControls();
390
+ }
365
391
  });
366
392
  ```
367
393
 
@@ -312,6 +312,8 @@
312
312
  }
313
313
  }
314
314
  class InteractionSystem {
315
+ // Interaction enabled state
316
+ isEnabled = true;
315
317
  // Mouse interaction state
316
318
  mouseState = {
317
319
  x: 0,
@@ -408,6 +410,7 @@
408
410
  * Handle mouse update messages from the host
409
411
  */
410
412
  handleMouseUpdate(data) {
413
+ if (!this.isEnabled) return;
411
414
  this.mouseState.x = data.x;
412
415
  this.mouseState.y = data.y;
413
416
  this.mouseState.isInCanvas = data.isInCanvas !== void 0 ? data.isInCanvas : true;
@@ -430,6 +433,7 @@
430
433
  * Handle keyboard update messages from the host
431
434
  */
432
435
  handleKeyboardUpdate(data) {
436
+ if (!this.isEnabled) return;
433
437
  const key = data.key.toLowerCase();
434
438
  if (data.type === "keydown") {
435
439
  if (!this.keyboardState.activeKeys.has(key)) {
@@ -451,6 +455,7 @@
451
455
  * Handle touch update messages from the host
452
456
  */
453
457
  handleTouchUpdate(data) {
458
+ if (!this.isEnabled) return;
454
459
  this.touchState.started = [];
455
460
  this.touchState.moved = [];
456
461
  this.touchState.ended = [];
@@ -550,6 +555,70 @@
550
555
  tapPosition: null
551
556
  });
552
557
  }
558
+ /**
559
+ * Enable or disable interaction processing
560
+ */
561
+ setInteractionEnabled(enabled) {
562
+ this.isEnabled = enabled;
563
+ if (!enabled) {
564
+ this.resetInteractionStates();
565
+ }
566
+ }
567
+ /**
568
+ * Get current interaction enabled state
569
+ */
570
+ getInteractionEnabled() {
571
+ return this.isEnabled;
572
+ }
573
+ /**
574
+ * Reset all interaction states to default values
575
+ */
576
+ resetInteractionStates() {
577
+ this.mouseState.x = 0;
578
+ this.mouseState.y = 0;
579
+ this.mouseState.isInCanvas = false;
580
+ this.mouseState.isPressed = false;
581
+ this.mouseState.leftButton = false;
582
+ this.mouseState.rightButton = false;
583
+ this.mouseState.middleButton = false;
584
+ this.mouseState.velocity.x = 0;
585
+ this.mouseState.velocity.y = 0;
586
+ this.mouseState.deltaX = 0;
587
+ this.mouseState.deltaY = 0;
588
+ this.mouseState.wheelDelta = 0;
589
+ this.mouseState.wheelX = 0;
590
+ this.mouseState.wheelY = 0;
591
+ this.mouseState.wasPressed = false;
592
+ this.mouseState.wasReleased = false;
593
+ this.mouseState.wasMoved = false;
594
+ this.keyboardState.activeKeys.clear();
595
+ this.keyboardState.pressedThisFrame.clear();
596
+ this.keyboardState.releasedThisFrame.clear();
597
+ this.keyboardState.lastKeyPressed = "";
598
+ this.keyboardState.lastKeyReleased = "";
599
+ this.keyboardState.shift = false;
600
+ this.keyboardState.ctrl = false;
601
+ this.keyboardState.alt = false;
602
+ this.keyboardState.meta = false;
603
+ this.touchState.points = [];
604
+ this.touchState.count = 0;
605
+ this.touchState.started = [];
606
+ this.touchState.moved = [];
607
+ this.touchState.ended = [];
608
+ this.touchState.primary = null;
609
+ this.touchState.gestures.isPinching = false;
610
+ this.touchState.gestures.isRotating = false;
611
+ this.touchState.gestures.isPanning = false;
612
+ this.touchState.gestures.isTapping = false;
613
+ this.touchState.gestures.pinchScale = 1;
614
+ this.touchState.gestures.pinchDelta = 0;
615
+ this.touchState.gestures.rotationAngle = 0;
616
+ this.touchState.gestures.rotationDelta = 0;
617
+ this.touchState.gestures.panDelta = { x: 0, y: 0 };
618
+ this.touchState.gestures.tapCount = 0;
619
+ this.touchState.gestures.lastTapTime = 0;
620
+ this.touchState.gestures.tapPosition = null;
621
+ }
553
622
  }
554
623
  class VideoSystem {
555
624
  // ✅ CORRECT: Worker-owned OffscreenCanvas (transferred from host)
@@ -1065,6 +1134,9 @@
1065
1134
  case "touch-update":
1066
1135
  this.handleTouchUpdate(message);
1067
1136
  break;
1137
+ case "interaction-enabled":
1138
+ this.handleInteractionEnabled(message);
1139
+ break;
1068
1140
  case "performance-update":
1069
1141
  this.handlePerformanceUpdate(message);
1070
1142
  break;
@@ -1258,6 +1330,9 @@
1258
1330
  handleTouchUpdate(message) {
1259
1331
  this.interactionSystem.handleTouchUpdate(message.data);
1260
1332
  }
1333
+ handleInteractionEnabled(message) {
1334
+ this.interactionSystem.setInteractionEnabled(message.data.enabled);
1335
+ }
1261
1336
  }
1262
1337
  const runtime = new VijiWorkerRuntime();
1263
1338
  let renderFunction = null;
@@ -1284,4 +1359,4 @@
1284
1359
  }
1285
1360
  self.setSceneCode = setSceneCode;
1286
1361
  })();
1287
- //# sourceMappingURL=viji.worker-Cozsmke0.js.map
1362
+ //# sourceMappingURL=viji.worker-BWGhBqAc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viji.worker-BWGhBqAc.js","sources":["../src/worker/ParameterSystem.ts","../src/worker/InteractionSystem.ts","../src/worker/VideoSystem.ts","../src/worker/VijiWorkerRuntime.ts","../src/worker/viji.worker.ts"],"sourcesContent":["import { \r\n ParameterGroup, \r\n ParameterDefinition, \r\n ParameterValue,\r\n SliderParameter,\r\n ColorParameter,\r\n ToggleParameter,\r\n SelectParameter,\r\n TextParameter,\r\n NumberParameter,\r\n SliderConfig,\r\n ColorConfig,\r\n ToggleConfig,\r\n SelectConfig,\r\n TextConfig,\r\n NumberConfig\r\n} from '../types/index.js';\r\n\r\nexport class ParameterSystem {\r\n // Parameter system for Phase 2 (new object-based approach)\r\n private parameterDefinitions = new Map<string, ParameterDefinition>();\r\n private parameterGroups = new Map<string, ParameterGroup>();\r\n private parameterValues = new Map<string, ParameterValue>();\r\n private parameterObjects = new Map<string, any>(); // Maps parameter names to their objects\r\n private parametersDefined = false;\r\n private initialValuesSynced = false; // Track if initial values have been synced from host\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n\r\n // Message posting callback\r\n private postMessageCallback: (type: string, data?: any) => void;\r\n\r\n constructor(postMessageCallback: (type: string, data?: any) => void) {\r\n this.postMessageCallback = postMessageCallback;\r\n }\r\n\r\n // Parameter helper function implementations (return parameter objects)\r\n public createSliderParameter(defaultValue: number, config: SliderConfig): SliderParameter {\r\n const paramName = config.label;\r\n const sliderObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'slider',\r\n defaultValue,\r\n label: sliderObject.label,\r\n description: sliderObject.description,\r\n group: sliderObject.group,\r\n category: sliderObject.category,\r\n config: {\r\n min: sliderObject.min,\r\n max: sliderObject.max,\r\n step: sliderObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, sliderObject);\r\n return sliderObject;\r\n }\r\n\r\n public createColorParameter(defaultValue: string, config: ColorConfig): ColorParameter {\r\n const paramName = config.label;\r\n const colorObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general',\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'color',\r\n defaultValue,\r\n label: colorObject.label,\r\n description: colorObject.description,\r\n group: colorObject.group,\r\n category: colorObject.category,\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, colorObject);\r\n return colorObject;\r\n }\r\n\r\n public createToggleParameter(defaultValue: boolean, config: ToggleConfig): ToggleParameter {\r\n const paramName = config.label;\r\n const toggleObject = {\r\n value: defaultValue,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'toggle',\r\n defaultValue,\r\n label: toggleObject.label,\r\n description: toggleObject.description,\r\n group: toggleObject.group,\r\n category: toggleObject.category\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, toggleObject);\r\n return toggleObject;\r\n }\r\n\r\n public createSelectParameter(defaultValue: string | number, config: SelectConfig): SelectParameter {\r\n const paramName = config.label;\r\n const selectObject = {\r\n value: defaultValue,\r\n options: config.options,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'select',\r\n defaultValue,\r\n label: selectObject.label,\r\n description: selectObject.description,\r\n group: selectObject.group,\r\n category: selectObject.category,\r\n config: {\r\n options: selectObject.options\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, selectObject);\r\n return selectObject;\r\n }\r\n\r\n public createTextParameter(defaultValue: string, config: TextConfig): TextParameter {\r\n const paramName = config.label;\r\n const textObject = {\r\n value: defaultValue,\r\n maxLength: config.maxLength ?? 1000,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'text',\r\n defaultValue,\r\n label: textObject.label,\r\n description: textObject.description,\r\n group: textObject.group,\r\n category: textObject.category,\r\n config: {\r\n maxLength: textObject.maxLength\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, textObject);\r\n return textObject;\r\n }\r\n\r\n public createNumberParameter(defaultValue: number, config: NumberConfig): NumberParameter {\r\n const paramName = config.label;\r\n const numberObject = {\r\n value: defaultValue,\r\n min: config.min ?? 0,\r\n max: config.max ?? 100,\r\n step: config.step ?? 1,\r\n label: config.label,\r\n description: config.description ?? '',\r\n group: config.group ?? 'general',\r\n category: config.category ?? 'general'\r\n };\r\n\r\n const definition: ParameterDefinition = {\r\n type: 'number',\r\n defaultValue,\r\n label: numberObject.label,\r\n description: numberObject.description,\r\n group: numberObject.group,\r\n category: numberObject.category,\r\n config: {\r\n min: numberObject.min,\r\n max: numberObject.max,\r\n step: numberObject.step\r\n }\r\n };\r\n\r\n this.storeParameterDefinition(paramName, definition);\r\n this.parameterObjects.set(paramName, numberObject);\r\n return numberObject;\r\n }\r\n\r\n private storeParameterDefinition(name: string, definition: ParameterDefinition): void {\r\n // This is called during scene initialization, not during define()\r\n // We'll collect these and send them when the scene is fully loaded\r\n this.parameterDefinitions.set(name, definition);\r\n this.parameterValues.set(name, definition.defaultValue);\r\n }\r\n\r\n public updateParameterValue(name: string, value: ParameterValue): boolean {\r\n const definition = this.parameterDefinitions.get(name);\r\n if (!definition) {\r\n console.warn(`Unknown parameter: ${name}. Available parameters:`, Array.from(this.parameterDefinitions.keys()));\r\n return false;\r\n }\r\n\r\n // Validation\r\n if (!this.validateParameterValue(name, value, definition)) {\r\n console.warn(`Validation failed for parameter ${name} = ${value}`);\r\n return false;\r\n }\r\n\r\n // Check if value actually changed (but always allow initial sync)\r\n const currentValue = this.parameterValues.get(name);\r\n const isInitialSync = !this.initialValuesSynced; // During initial parameter sync from host\r\n \r\n if (currentValue === value && !isInitialSync) {\r\n return false; // No change (but allow initial sync even if values match)\r\n }\r\n\r\n // Update value in both storage and parameter object\r\n this.parameterValues.set(name, value);\r\n \r\n // Update the parameter object's value property\r\n const parameterObject = this.parameterObjects.get(name);\r\n if (parameterObject) {\r\n parameterObject.value = value;\r\n }\r\n \r\n return true;\r\n }\r\n\r\n private validateParameterValue(name: string, value: ParameterValue, definition: ParameterDefinition): boolean {\r\n // Custom validation function\r\n if (definition.validate && !definition.validate(value)) {\r\n console.error(`Custom validation failed for parameter '${name}': ${value}`);\r\n return false;\r\n }\r\n\r\n // Type validation\r\n switch (definition.type) {\r\n case 'slider':\r\n case 'number':\r\n if (typeof value !== 'number' || isNaN(value)) {\r\n console.error(`Parameter '${name}' must be a number, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.min !== undefined && value < definition.config.min) {\r\n console.error(`Parameter '${name}' value ${value} is below minimum ${definition.config.min}`);\r\n return false;\r\n }\r\n if (definition.config?.max !== undefined && value > definition.config.max) {\r\n console.error(`Parameter '${name}' value ${value} is above maximum ${definition.config.max}`);\r\n return false;\r\n }\r\n break;\r\n case 'color':\r\n if (typeof value !== 'string' || !/^#[0-9A-Fa-f]{6}$/.test(value)) {\r\n console.error(`Parameter '${name}' must be a valid hex color, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'toggle':\r\n if (typeof value !== 'boolean') {\r\n console.error(`Parameter '${name}' must be a boolean, got: ${value}`);\r\n return false;\r\n }\r\n break;\r\n case 'select':\r\n if (!definition.config?.options || !definition.config.options.includes(value as string & number)) {\r\n console.error(`Parameter '${name}' value ${value} is not in options: ${definition.config?.options}`);\r\n return false;\r\n }\r\n break;\r\n case 'text':\r\n if (typeof value !== 'string') {\r\n console.error(`Parameter '${name}' must be a string, got: ${value}`);\r\n return false;\r\n }\r\n if (definition.config?.maxLength && value.length > definition.config.maxLength) {\r\n console.error(`Parameter '${name}' text too long: ${value.length} > ${definition.config.maxLength}`);\r\n return false;\r\n }\r\n break;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Reset parameter state (called when loading new scene)\r\n public resetParameterState(): void {\r\n this.parametersDefined = false;\r\n this.initialValuesSynced = false;\r\n this.parameterDefinitions.clear();\r\n this.parameterGroups.clear();\r\n this.parameterValues.clear();\r\n this.parameterObjects.clear();\r\n }\r\n\r\n // Send all parameters (from helper functions) to host\r\n public sendAllParametersToHost(): void {\r\n // Don't send if already sent or if no parameters defined\r\n if (this.parametersDefined || this.parameterDefinitions.size === 0) {\r\n return;\r\n }\r\n\r\n try {\r\n // Group parameters by their group property\r\n const groups = new Map<string, ParameterGroup>();\r\n\r\n for (const [paramName, paramDef] of this.parameterDefinitions) {\r\n const groupName = paramDef.group || 'general';\r\n \r\n if (!groups.has(groupName)) {\r\n // Use the parameter's category if available, otherwise default to 'general'\r\n const category = paramDef.category || 'general';\r\n groups.set(groupName, {\r\n groupName,\r\n category,\r\n parameters: {}\r\n });\r\n }\r\n\r\n const group = groups.get(groupName)!;\r\n group.parameters[paramName] = paramDef;\r\n }\r\n\r\n this.parametersDefined = true;\r\n\r\n // Send parameter definitions to host for UI generation\r\n this.postMessageCallback('parameters-defined', {\r\n groups: Array.from(groups.values()),\r\n timestamp: performance.now()\r\n });\r\n\r\n this.debugLog(`All parameters sent to host: ${this.parameterDefinitions.size} parameters in ${groups.size} groups`);\r\n } catch (error) {\r\n this.postMessageCallback('parameter-validation-error', {\r\n message: `Failed to send parameters to host: ${(error as Error).message}`,\r\n code: 'PARAMETER_SENDING_ERROR'\r\n });\r\n }\r\n }\r\n\r\n // Mark initial values as synced\r\n public markInitialValuesSynced(): void {\r\n this.initialValuesSynced = true;\r\n }\r\n\r\n // Get parameter count for performance reporting\r\n public getParameterCount(): number {\r\n return this.parameterDefinitions.size;\r\n }\r\n} ","import { MouseAPI, KeyboardAPI, TouchAPI, TouchPoint } from '../types/index.js';\r\n\r\n/**\r\n * Manages user interaction state and APIs for the worker runtime.\r\n * Handles mouse, keyboard, and touch input processing for Phase 7.\r\n * \r\n * This system provides:\r\n * - Real-time interaction state management\r\n * - Frame-based event processing\r\n * - Clean API generation for artist code\r\n * - Message handling for interaction updates\r\n */\r\nexport class InteractionSystem {\r\n // Interaction enabled state\r\n private isEnabled: boolean = true;\r\n\r\n // Mouse interaction state\r\n private mouseState: MouseAPI = {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n };\r\n\r\n // Keyboard interaction state\r\n private keyboardState: KeyboardAPI = {\r\n isPressed: (key: string) => this.keyboardState.activeKeys.has(key.toLowerCase()),\r\n wasPressed: (key: string) => this.keyboardState.pressedThisFrame.has(key.toLowerCase()),\r\n wasReleased: (key: string) => this.keyboardState.releasedThisFrame.has(key.toLowerCase()),\r\n activeKeys: new Set<string>(),\r\n pressedThisFrame: new Set<string>(),\r\n releasedThisFrame: new Set<string>(),\r\n lastKeyPressed: '',\r\n lastKeyReleased: '',\r\n shift: false,\r\n ctrl: false,\r\n alt: false,\r\n meta: false\r\n };\r\n\r\n // Touch interaction state\r\n private touchState: TouchAPI = {\r\n points: [],\r\n count: 0,\r\n started: [],\r\n moved: [],\r\n ended: [],\r\n primary: null,\r\n gestures: {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n }\r\n };\r\n\r\n constructor() {\r\n // Bind methods for proper context when used as callbacks\r\n this.handleMouseUpdate = this.handleMouseUpdate.bind(this);\r\n this.handleKeyboardUpdate = this.handleKeyboardUpdate.bind(this);\r\n this.handleTouchUpdate = this.handleTouchUpdate.bind(this);\r\n this.frameStart = this.frameStart.bind(this);\r\n }\r\n\r\n /**\r\n * Get the interaction APIs for inclusion in the viji object\r\n */\r\n public getInteractionAPIs() {\r\n return {\r\n mouse: this.mouseState,\r\n keyboard: this.keyboardState,\r\n touches: this.touchState\r\n };\r\n }\r\n\r\n /**\r\n * Called at the start of each frame to reset frame-based events\r\n */\r\n public frameStart(): void {\r\n // Reset mouse frame events\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n\r\n // Reset keyboard frame events\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n\r\n // Reset touch frame events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n }\r\n\r\n /**\r\n * Handle mouse update messages from the host\r\n */\r\n public handleMouseUpdate(data: {\r\n x: number;\r\n y: number;\r\n buttons: number;\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDeltaX: number;\r\n wheelDeltaY: number;\r\n isInCanvas?: boolean;\r\n timestamp: number;\r\n wasPressed?: boolean;\r\n wasReleased?: boolean;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Update mouse position and button states\r\n this.mouseState.x = data.x;\r\n this.mouseState.y = data.y;\r\n this.mouseState.isInCanvas = data.isInCanvas !== undefined ? data.isInCanvas : true;\r\n this.mouseState.leftButton = (data.buttons & 1) !== 0;\r\n this.mouseState.rightButton = (data.buttons & 2) !== 0;\r\n this.mouseState.middleButton = (data.buttons & 4) !== 0;\r\n this.mouseState.isPressed = data.buttons > 0;\r\n \r\n // Update movement deltas and wheel\r\n this.mouseState.deltaX = data.deltaX || 0;\r\n this.mouseState.deltaY = data.deltaY || 0;\r\n this.mouseState.wheelDelta = data.wheelDeltaY || 0;\r\n this.mouseState.wheelX = data.wheelDeltaX || 0;\r\n this.mouseState.wheelY = data.wheelDeltaY || 0;\r\n \r\n // Update velocity (smoothed in InteractionManager)\r\n this.mouseState.velocity.x = data.deltaX || 0;\r\n this.mouseState.velocity.y = data.deltaY || 0;\r\n \r\n // Frame-based events (calculated in InteractionManager or provided by host)\r\n this.mouseState.wasPressed = data.wasPressed || false;\r\n this.mouseState.wasReleased = data.wasReleased || false;\r\n this.mouseState.wasMoved = (data.deltaX !== 0 || data.deltaY !== 0);\r\n }\r\n\r\n /**\r\n * Handle keyboard update messages from the host\r\n */\r\n public handleKeyboardUpdate(data: {\r\n type: 'keydown' | 'keyup';\r\n key: string;\r\n code: string;\r\n shiftKey: boolean;\r\n ctrlKey: boolean;\r\n altKey: boolean;\r\n metaKey: boolean;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n const key = data.key.toLowerCase();\r\n \r\n if (data.type === 'keydown') {\r\n if (!this.keyboardState.activeKeys.has(key)) {\r\n this.keyboardState.activeKeys.add(key);\r\n this.keyboardState.pressedThisFrame.add(key);\r\n this.keyboardState.lastKeyPressed = data.key;\r\n }\r\n } else if (data.type === 'keyup') {\r\n this.keyboardState.activeKeys.delete(key);\r\n this.keyboardState.releasedThisFrame.add(key);\r\n this.keyboardState.lastKeyReleased = data.key;\r\n }\r\n \r\n // Update modifier keys\r\n this.keyboardState.shift = data.shiftKey;\r\n this.keyboardState.ctrl = data.ctrlKey;\r\n this.keyboardState.alt = data.altKey;\r\n this.keyboardState.meta = data.metaKey;\r\n }\r\n\r\n /**\r\n * Handle touch update messages from the host\r\n */\r\n public handleTouchUpdate(data: {\r\n type: 'touchstart' | 'touchmove' | 'touchend' | 'touchcancel';\r\n touches: Array<{\r\n identifier: number;\r\n clientX: number;\r\n clientY: number;\r\n pressure: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n }>;\r\n timestamp: number;\r\n }): void {\r\n // Skip processing if interactions are disabled\r\n if (!this.isEnabled) return;\r\n // Clear frame-based touch events\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n \r\n // Convert touch data to our TouchPoint format\r\n const touches: TouchPoint[] = data.touches.map((touch) => ({\r\n id: touch.identifier,\r\n x: touch.clientX,\r\n y: touch.clientY,\r\n pressure: touch.pressure || 0,\r\n radius: Math.max(touch.radiusX || 0, touch.radiusY || 0),\r\n radiusX: touch.radiusX || 0,\r\n radiusY: touch.radiusY || 0,\r\n rotationAngle: touch.rotationAngle || 0,\r\n force: touch.force || touch.pressure || 0,\r\n deltaX: 0, // Could be calculated if we track previous positions\r\n deltaY: 0,\r\n velocity: { x: 0, y: 0 }, // Could be calculated if we track movement\r\n isNew: data.type === 'touchstart',\r\n isActive: true,\r\n isEnding: data.type === 'touchend' || data.type === 'touchcancel'\r\n }));\r\n \r\n // Update touch state\r\n this.touchState.points = touches;\r\n this.touchState.count = touches.length;\r\n this.touchState.primary = touches[0] || null;\r\n \r\n // Set frame-based events based on message type\r\n if (data.type === 'touchstart') {\r\n this.touchState.started = touches;\r\n } else if (data.type === 'touchmove') {\r\n this.touchState.moved = touches;\r\n } else if (data.type === 'touchend' || data.type === 'touchcancel') {\r\n this.touchState.ended = touches;\r\n }\r\n \r\n // Note: Advanced gesture recognition is handled in the InteractionManager\r\n // on the host side. For now, we provide basic gesture state structure.\r\n // In the future, we could move gesture recognition here or receive \r\n // gesture data from the host.\r\n this.touchState.gestures = {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all interaction state (called when loading new scene)\r\n */\r\n public resetInteractionState(): void {\r\n // Reset mouse state\r\n Object.assign(this.mouseState, {\r\n x: 0, y: 0,\r\n isInCanvas: false,\r\n isPressed: false,\r\n leftButton: false,\r\n rightButton: false,\r\n middleButton: false,\r\n velocity: { x: 0, y: 0 },\r\n deltaX: 0,\r\n deltaY: 0,\r\n wheelDelta: 0,\r\n wheelX: 0,\r\n wheelY: 0,\r\n wasPressed: false,\r\n wasReleased: false,\r\n wasMoved: false\r\n });\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n Object.assign(this.touchState.gestures, {\r\n isPinching: false,\r\n isRotating: false,\r\n isPanning: false,\r\n isTapping: false,\r\n pinchScale: 1,\r\n pinchDelta: 0,\r\n rotationAngle: 0,\r\n rotationDelta: 0,\r\n panDelta: { x: 0, y: 0 },\r\n tapCount: 0,\r\n lastTapTime: 0,\r\n tapPosition: null\r\n });\r\n }\r\n\r\n /**\r\n * Enable or disable interaction processing\r\n */\r\n public setInteractionEnabled(enabled: boolean): void {\r\n this.isEnabled = enabled;\r\n \r\n // If disabled, reset all interaction states to prevent stale data\r\n if (!enabled) {\r\n this.resetInteractionStates();\r\n }\r\n }\r\n\r\n /**\r\n * Get current interaction enabled state\r\n */\r\n public getInteractionEnabled(): boolean {\r\n return this.isEnabled;\r\n }\r\n\r\n /**\r\n * Reset all interaction states to default values\r\n */\r\n private resetInteractionStates(): void {\r\n // Reset mouse state\r\n this.mouseState.x = 0;\r\n this.mouseState.y = 0;\r\n this.mouseState.isInCanvas = false;\r\n this.mouseState.isPressed = false;\r\n this.mouseState.leftButton = false;\r\n this.mouseState.rightButton = false;\r\n this.mouseState.middleButton = false;\r\n this.mouseState.velocity.x = 0;\r\n this.mouseState.velocity.y = 0;\r\n this.mouseState.deltaX = 0;\r\n this.mouseState.deltaY = 0;\r\n this.mouseState.wheelDelta = 0;\r\n this.mouseState.wheelX = 0;\r\n this.mouseState.wheelY = 0;\r\n this.mouseState.wasPressed = false;\r\n this.mouseState.wasReleased = false;\r\n this.mouseState.wasMoved = false;\r\n\r\n // Reset keyboard state\r\n this.keyboardState.activeKeys.clear();\r\n this.keyboardState.pressedThisFrame.clear();\r\n this.keyboardState.releasedThisFrame.clear();\r\n this.keyboardState.lastKeyPressed = '';\r\n this.keyboardState.lastKeyReleased = '';\r\n this.keyboardState.shift = false;\r\n this.keyboardState.ctrl = false;\r\n this.keyboardState.alt = false;\r\n this.keyboardState.meta = false;\r\n\r\n // Reset touch state\r\n this.touchState.points = [];\r\n this.touchState.count = 0;\r\n this.touchState.started = [];\r\n this.touchState.moved = [];\r\n this.touchState.ended = [];\r\n this.touchState.primary = null;\r\n this.touchState.gestures.isPinching = false;\r\n this.touchState.gestures.isRotating = false;\r\n this.touchState.gestures.isPanning = false;\r\n this.touchState.gestures.isTapping = false;\r\n this.touchState.gestures.pinchScale = 1;\r\n this.touchState.gestures.pinchDelta = 0;\r\n this.touchState.gestures.rotationAngle = 0;\r\n this.touchState.gestures.rotationDelta = 0;\r\n this.touchState.gestures.panDelta = { x: 0, y: 0 };\r\n this.touchState.gestures.tapCount = 0;\r\n this.touchState.gestures.lastTapTime = 0;\r\n this.touchState.gestures.tapPosition = null;\r\n }\r\n} ","/**\r\n * Worker-side Video System for Phase 10 - CORRECT OffscreenCanvas Implementation\r\n * \r\n * CORRECT Approach:\r\n * 1. Host creates OffscreenCanvas (no context!)\r\n * 2. Host transfers OffscreenCanvas to worker\r\n * 3. Worker receives OffscreenCanvas and gets context\r\n * 4. Host sends ImageBitmap frames to worker\r\n * 5. Worker draws ImageBitmap frames to its OffscreenCanvas\r\n * 6. Worker performs all analysis and effects on OffscreenCanvas\r\n * \r\n * This provides:\r\n * - True worker-side processing with full GPU access\r\n * - Zero-copy OffscreenCanvas ownership transfer\r\n * - Optimal performance for CV and artist effects\r\n * - Proper separation: host = coordination, worker = processing\r\n */\r\nexport class VideoSystem {\r\n // ✅ CORRECT: Worker-owned OffscreenCanvas (transferred from host)\r\n private offscreenCanvas: OffscreenCanvas | null = null;\r\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\r\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\r\n \r\n // Debug logging control\r\n private debugMode = false;\r\n\r\n /**\r\n * Enable or disable debug logging\r\n */\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n\r\n /**\r\n * Debug logging helper\r\n */\r\n private debugLog(message: string, ...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log(message, ...args);\r\n }\r\n }\r\n \r\n // Frame processing configuration\r\n private targetFrameRate = 30; // Default target FPS for video processing\r\n private lastFrameTime = 0;\r\n private frameInterval = 1000 / this.targetFrameRate; // ms between frames\r\n \r\n // Processing state\r\n private hasLoggedFirstFrame = false;\r\n private frameCount = 0;\r\n \r\n // Video state for artist API\r\n private videoState = {\r\n isConnected: false,\r\n currentFrame: null as OffscreenCanvas | null,\r\n frameWidth: 0,\r\n frameHeight: 0,\r\n frameRate: 0,\r\n frameData: null as ImageData | null\r\n };\r\n \r\n // Phase 11 preparation - CV processing placeholder\r\n private cvFeatures = {\r\n faceDetection: false,\r\n handTracking: false,\r\n bodySegmentation: false\r\n };\r\n \r\n private cvResults = {\r\n faces: [] as any[],\r\n hands: [] as any[],\r\n bodySegmentation: null as any\r\n };\r\n\r\n constructor() {\r\n // VideoSystem ready for OffscreenCanvas processing\r\n }\r\n\r\n /**\r\n * Get the video API for inclusion in the viji object\r\n */\r\n public getVideoAPI() {\r\n return {\r\n isConnected: this.videoState.isConnected,\r\n currentFrame: this.videoState.currentFrame,\r\n frameWidth: this.videoState.frameWidth,\r\n frameHeight: this.videoState.frameHeight,\r\n frameRate: this.videoState.frameRate,\r\n getFrameData: () => this.videoState.frameData,\r\n faces: this.cvResults.faces,\r\n hands: this.cvResults.hands\r\n };\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive OffscreenCanvas transfer from host\r\n */\r\n public handleCanvasSetup(data: {\r\n offscreenCanvas: OffscreenCanvas;\r\n width: number;\r\n height: number;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Clean up existing canvas\r\n this.disconnectVideo();\r\n \r\n // ✅ CORRECT: Receive transferred OffscreenCanvas\r\n this.offscreenCanvas = data.offscreenCanvas;\r\n \r\n // ✅ CORRECT: Get context on WORKER side (not host!)\r\n this.ctx = this.offscreenCanvas.getContext('2d', {\r\n willReadFrequently: true // Optimize for frequent getImageData calls\r\n });\r\n \r\n if (!this.ctx) {\r\n throw new Error('Failed to get 2D context from transferred OffscreenCanvas');\r\n }\r\n \r\n // Optional: Get WebGL context for advanced effects\r\n // Note: We can have multiple contexts on the same canvas\r\n try {\r\n this.gl = this.offscreenCanvas.getContext('webgl2') || this.offscreenCanvas.getContext('webgl');\r\n } catch (e) {\r\n // WebGL not available, continue with 2D\r\n this.debugLog('WebGL not available, using 2D context only');\r\n }\r\n \r\n // Update state\r\n this.videoState.isConnected = true;\r\n this.videoState.currentFrame = this.offscreenCanvas;\r\n this.videoState.frameWidth = data.width;\r\n this.videoState.frameHeight = data.height;\r\n this.frameCount = 0;\r\n this.hasLoggedFirstFrame = false;\r\n \r\n this.debugLog('✅ OffscreenCanvas received and setup completed (worker-side)', {\r\n width: data.width,\r\n height: data.height,\r\n hasWebGL: !!this.gl,\r\n targetFrameRate: this.targetFrameRate\r\n });\r\n \r\n this.debugLog('🎬 CORRECT OffscreenCanvas approach - Worker has full GPU access!');\r\n \r\n } catch (error) {\r\n console.error('Failed to setup OffscreenCanvas in worker:', error);\r\n this.disconnectVideo();\r\n }\r\n }\r\n\r\n /**\r\n * ✅ CORRECT: Receive ImageBitmap frame and draw to worker's OffscreenCanvas\r\n */\r\n public handleFrameUpdate(data: {\r\n imageBitmap: ImageBitmap;\r\n timestamp: number;\r\n }): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n console.warn('🔴 Received frame but OffscreenCanvas not setup');\r\n return;\r\n }\r\n \r\n try {\r\n // Log occasionally to avoid spam (very rarely now that it's working)\r\n if (this.frameCount % 150 === 0) { // Log every 150th frame (~5 seconds at 30fps)\r\n this.debugLog('✅ Worker received ImageBitmap frame:', {\r\n bitmapSize: `${data.imageBitmap.width}x${data.imageBitmap.height}`,\r\n canvasSize: `${this.offscreenCanvas.width}x${this.offscreenCanvas.height}`,\r\n frameCount: this.frameCount,\r\n timestamp: data.timestamp\r\n });\r\n }\r\n \r\n // ✅ CORRECT: Worker draws ImageBitmap to its OffscreenCanvas\r\n this.ctx.drawImage(data.imageBitmap, 0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n \r\n // Update frame processing\r\n this.processCurrentFrame(data.timestamp);\r\n \r\n // Close the transferred ImageBitmap to free memory\r\n data.imageBitmap.close();\r\n \r\n this.frameCount++;\r\n \r\n } catch (error) {\r\n console.error('🔴 Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Process current frame (called when new frame is drawn)\r\n */\r\n private processCurrentFrame(timestamp: number): void {\r\n if (!this.offscreenCanvas || !this.ctx) {\r\n return;\r\n }\r\n \r\n try {\r\n // Get current frame data for analysis\r\n this.videoState.frameData = this.ctx.getImageData(\r\n 0, 0, \r\n this.offscreenCanvas.width, \r\n this.offscreenCanvas.height\r\n );\r\n \r\n // Calculate frame rate based on frame arrival\r\n const deltaTime = timestamp - this.lastFrameTime;\r\n this.videoState.frameRate = deltaTime > 0 ? 1000 / deltaTime : 0;\r\n \r\n // Log first successful frame processing (once)\r\n if (!this.hasLoggedFirstFrame) {\r\n this.debugLog(`🎯 Worker-side OffscreenCanvas processing active: ${this.videoState.frameRate.toFixed(1)} FPS (${this.offscreenCanvas.width}x${this.offscreenCanvas.height})`);\r\n this.debugLog('✅ Full GPU access available for custom effects and CV analysis');\r\n this.hasLoggedFirstFrame = true;\r\n }\r\n \r\n // Phase 11 preparation - Perform CV analysis (placeholder)\r\n this.performCVAnalysis();\r\n \r\n this.lastFrameTime = timestamp;\r\n } catch (error) {\r\n console.error('Error processing video frame (worker-side):', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle video configuration updates (including disconnection and resize)\r\n */\r\n public handleVideoConfigUpdate(data: {\r\n targetFrameRate?: number;\r\n cvConfig?: any;\r\n width?: number;\r\n height?: number;\r\n disconnect?: boolean;\r\n timestamp: number;\r\n }): void {\r\n try {\r\n // Handle disconnection\r\n if (data.disconnect) {\r\n this.disconnectVideo();\r\n return;\r\n }\r\n \r\n // Handle resize\r\n if (data.width && data.height && this.offscreenCanvas) {\r\n this.resizeCanvas(data.width, data.height);\r\n }\r\n \r\n // Update processing configuration if provided\r\n if (data.targetFrameRate) {\r\n this.updateProcessingConfig(data.targetFrameRate);\r\n }\r\n \r\n // Phase 11 preparation - CV config\r\n if (data.cvConfig) {\r\n this.updateCVConfig(data.cvConfig);\r\n }\r\n } catch (error) {\r\n console.error('Error handling video config update:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Resize the OffscreenCanvas (when video dimensions change)\r\n */\r\n private resizeCanvas(width: number, height: number): void {\r\n if (!this.offscreenCanvas) return;\r\n \r\n try {\r\n // Resize the OffscreenCanvas\r\n this.offscreenCanvas.width = width;\r\n this.offscreenCanvas.height = height;\r\n \r\n // Update state\r\n this.videoState.frameWidth = width;\r\n this.videoState.frameHeight = height;\r\n \r\n // Reset WebGL viewport if available\r\n if (this.gl) {\r\n this.gl.viewport(0, 0, width, height);\r\n }\r\n \r\n this.debugLog(`📐 OffscreenCanvas resized to ${width}x${height} (worker-side)`);\r\n \r\n } catch (error) {\r\n console.error('Error resizing OffscreenCanvas:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect video and clean up resources\r\n */\r\n private disconnectVideo(): void {\r\n // ✅ Clear the OffscreenCanvas before disconnecting\r\n if (this.offscreenCanvas && this.ctx) {\r\n this.ctx.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);\r\n this.debugLog('🧹 Cleared OffscreenCanvas on disconnect');\r\n }\r\n \r\n // Clear canvas references\r\n this.offscreenCanvas = null;\r\n this.ctx = null;\r\n this.gl = null;\r\n \r\n // Update state\r\n this.videoState.isConnected = false;\r\n this.videoState.currentFrame = null;\r\n this.videoState.frameWidth = 0;\r\n this.videoState.frameHeight = 0;\r\n this.videoState.frameRate = 0;\r\n this.videoState.frameData = null;\r\n this.resetCVResults();\r\n this.hasLoggedFirstFrame = false;\r\n this.frameCount = 0;\r\n \r\n this.debugLog('Video disconnected (worker-side)');\r\n }\r\n\r\n /**\r\n * Update video processing configuration\r\n */\r\n private updateProcessingConfig(targetFrameRate: number): void {\r\n this.targetFrameRate = Math.max(1, Math.min(60, targetFrameRate)); // Clamp between 1-60 FPS\r\n this.frameInterval = 1000 / this.targetFrameRate;\r\n \r\n this.debugLog(`Video processing frame rate updated to ${this.targetFrameRate} FPS (worker-side)`);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Update CV configuration\r\n */\r\n private updateCVConfig(cvConfig: any): void {\r\n // Placeholder for Phase 11 - Computer vision configuration\r\n this.cvFeatures = {\r\n faceDetection: cvConfig.faceDetection || false,\r\n handTracking: cvConfig.handTracking || false,\r\n bodySegmentation: cvConfig.bodySegmentation || false\r\n };\r\n \r\n this.debugLog('CV configuration updated (Phase 11 preparation, worker-side):', this.cvFeatures);\r\n }\r\n\r\n /**\r\n * Phase 11 preparation - Perform computer vision analysis\r\n */\r\n private performCVAnalysis(): void {\r\n // Placeholder for Phase 11 - Computer vision processing\r\n // This will include face detection, hand tracking, body segmentation\r\n \r\n if (this.cvFeatures.faceDetection) {\r\n // TODO Phase 11: Face detection using MediaPipe or TensorFlow.js\r\n // this.cvResults.faces = await detectFaces(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.handTracking) {\r\n // TODO Phase 11: Hand tracking using MediaPipe\r\n // this.cvResults.hands = await detectHands(this.videoState.frameData);\r\n }\r\n \r\n if (this.cvFeatures.bodySegmentation) {\r\n // TODO Phase 11: Body segmentation using TensorFlow.js\r\n // this.cvResults.bodySegmentation = await segmentBody(this.videoState.frameData);\r\n }\r\n }\r\n\r\n /**\r\n * Reset CV results\r\n */\r\n private resetCVResults(): void {\r\n this.cvResults = {\r\n faces: [],\r\n hands: [],\r\n bodySegmentation: null\r\n };\r\n }\r\n\r\n /**\r\n * Reset all video state (called when loading new scene)\r\n */\r\n public resetVideoState(): void {\r\n this.disconnectVideo();\r\n this.resetCVResults();\r\n }\r\n\r\n /**\r\n * Get current processing configuration\r\n */\r\n public getProcessingConfig(): { targetFrameRate: number; frameInterval: number; frameCount: number } {\r\n return {\r\n targetFrameRate: this.targetFrameRate,\r\n frameInterval: this.frameInterval,\r\n frameCount: this.frameCount\r\n };\r\n }\r\n\r\n /**\r\n * Get WebGL context for advanced effects (if available)\r\n */\r\n public getWebGLContext(): WebGLRenderingContext | WebGL2RenderingContext | null {\r\n return this.gl;\r\n }\r\n\r\n /**\r\n * ✅ WORKER API: Artists can access the OffscreenCanvas directly for custom effects\r\n */\r\n public getCanvasForArtistEffects(): OffscreenCanvas | null {\r\n return this.offscreenCanvas;\r\n }\r\n} ","import { \n WorkerMessage, \n WorkerInitMessage, \n WorkerFrameRateMessage, \n WorkerRefreshRateMessage, \n WorkerResolutionMessage, \n WorkerParameterMessage, \n WorkerParameterBatchMessage, \n WorkerStreamMessage, \n WorkerAudioAnalysisMessage,\n WorkerVideoCanvasSetupMessage,\n WorkerVideoFrameUpdateMessage,\n WorkerVideoConfigUpdateMessage,\n WorkerPerformanceMessage, \n WorkerSetSceneCodeMessage \n} from './types.js';\nimport { ParameterSystem } from './ParameterSystem.js';\nimport { InteractionSystem } from './InteractionSystem.js';\nimport { VideoSystem } from './VideoSystem.js';\n\n// Viji Worker Runtime Implementation\nexport class VijiWorkerRuntime {\n private canvas: OffscreenCanvas | null = null;\n private ctx: OffscreenCanvasRenderingContext2D | null = null;\n private gl: WebGLRenderingContext | WebGL2RenderingContext | null = null;\n private isRunning = false;\n private frameCount = 0;\n private lastTime = 0;\n private startTime = 0;\n private frameRateMode: 'full' | 'half' = 'full';\n private skipNextFrame = false;\n private screenRefreshRate = 60; // Will be detected\n \n // Debug logging control\n private debugMode = false;\n\n /**\n * Enable or disable debug logging\n */\n setDebugMode(enabled: boolean): void {\n this.debugMode = enabled;\n // Propagate to child systems\n if (this.videoSystem) this.videoSystem.setDebugMode(enabled);\n if (this.parameterSystem && 'setDebugMode' in this.parameterSystem) {\n (this.parameterSystem as any).setDebugMode(enabled);\n }\n if (this.interactionSystem && 'setDebugMode' in this.interactionSystem) {\n (this.interactionSystem as any).setDebugMode(enabled);\n }\n }\n\n /**\n * Debug logging helper\n */\n private debugLog(message: string, ...args: any[]): void {\n if (this.debugMode) {\n console.log(message, ...args);\n }\n }\n \n // Effective refresh rate tracking\n private effectiveFrameTimes: number[] = [];\n private lastEffectiveRateReport = 0;\n private effectiveRateReportInterval = 1000; // Report every 1 second\n\n // Parameter system\n private parameterSystem: ParameterSystem;\n \n // Interaction system (Phase 7)\n private interactionSystem: InteractionSystem;\n \n // Video system (Phase 10) - worker-side video processing\n private videoSystem: VideoSystem;\n \n // Audio state (Phase 5) - receives analysis results from host\n private audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n\n // Video state is now managed by the worker-side VideoSystem\n \n // Artist API object\n public viji = {\n // Canvas (will be set during init)\n canvas: null as OffscreenCanvas | null,\n ctx: null as OffscreenCanvasRenderingContext2D | null,\n gl: null as WebGLRenderingContext | WebGL2RenderingContext | null,\n width: 0,\n height: 0,\n pixelRatio: 1,\n \n // Timing\n time: 0,\n deltaTime: 0,\n frameCount: 0,\n fps: 60,\n \n // Audio API (Phase 5) - will be set in constructor\n audio: {} as any,\n \n video: {\n isConnected: false,\n currentFrame: null as OffscreenCanvas | null,\n frameWidth: 0,\n frameHeight: 0,\n frameRate: 0,\n getFrameData: () => null,\n faces: [] as any[],\n hands: [] as any[]\n },\n \n // Interaction APIs will be added during construction\n mouse: {} as any,\n keyboard: {} as any,\n touches: {} as any,\n \n // Parameter helper functions (return parameter objects) - delegate to parameter system\n slider: (defaultValue: number, config: any) => {\n return this.parameterSystem.createSliderParameter(defaultValue, config);\n },\n \n color: (defaultValue: string, config: any) => {\n return this.parameterSystem.createColorParameter(defaultValue, config);\n },\n \n toggle: (defaultValue: boolean, config: any) => {\n return this.parameterSystem.createToggleParameter(defaultValue, config);\n },\n \n select: (defaultValue: string | number, config: any) => {\n return this.parameterSystem.createSelectParameter(defaultValue, config);\n },\n \n text: (defaultValue: string, config: any) => {\n return this.parameterSystem.createTextParameter(defaultValue, config);\n },\n \n number: (defaultValue: number, config: any) => {\n return this.parameterSystem.createNumberParameter(defaultValue, config);\n },\n \n // Context selection\n useContext: (type: '2d' | 'webgl') => {\n if (type === '2d') {\n if (!this.ctx && this.canvas) {\n this.ctx = this.canvas.getContext('2d');\n this.viji.ctx = this.ctx;\n }\n return this.ctx;\n } else if (type === 'webgl') {\n if (!this.gl && this.canvas) {\n this.gl = this.canvas.getContext('webgl2') || this.canvas.getContext('webgl');\n this.viji.gl = this.gl;\n \n // Set initial WebGL viewport\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n }\n return this.gl;\n }\n return null;\n }\n };\n \n constructor() {\n // Initialize parameter system with post message callback\n this.parameterSystem = new ParameterSystem((type: string, data?: any) => {\n this.postMessage(type, data);\n });\n \n // Initialize interaction system\n this.interactionSystem = new InteractionSystem();\n \n // Initialize video system (Phase 10)\n this.videoSystem = new VideoSystem();\n \n // Integrate APIs into viji object\n Object.assign(this.viji, this.interactionSystem.getInteractionAPIs());\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n \n // Initialize audio API with getFrequencyData function\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n this.setupMessageHandling();\n }\n\n // Reset parameter state (called when loading new scene)\n public resetParameterState(): void {\n this.parameterSystem.resetParameterState();\n this.interactionSystem.resetInteractionState();\n \n // Reset audio state\n this.audioState = {\n isConnected: false,\n volume: { rms: 0, peak: 0 },\n bands: {\n bass: 0, mid: 0, treble: 0, subBass: 0, \n lowMid: 0, highMid: 0, presence: 0, brilliance: 0\n },\n frequencyData: new Uint8Array(0)\n };\n // Update viji.audio reference\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n \n // Reset video system\n this.videoSystem.resetVideoState();\n // Update viji.video reference\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n // Send all parameters (from helper functions) to host\n public sendAllParametersToHost(): void {\n this.parameterSystem.sendAllParametersToHost();\n }\n \n private setupMessageHandling(): void {\n self.onmessage = (event: MessageEvent<WorkerMessage>) => {\n const message = event.data;\n \n switch (message.type) {\n case 'init':\n this.handleInit(message);\n break;\n case 'frame-rate-update':\n this.handleFrameRateUpdate(message);\n break;\n case 'refresh-rate-update':\n this.handleRefreshRateUpdate(message);\n break;\n case 'resolution-update':\n this.handleResolutionUpdate(message);\n break;\n case 'set-scene-code':\n this.handleSetSceneCode(message);\n break;\n case 'debug-mode':\n this.setDebugMode(message.data.enabled);\n break;\n case 'parameter-update':\n this.handleParameterUpdate(message);\n break;\n case 'parameter-batch-update':\n this.handleParameterBatchUpdate(message);\n break;\n case 'stream-update':\n this.handleStreamUpdate(message);\n break;\n case 'audio-analysis-update':\n this.handleAudioAnalysisUpdate(message);\n break;\n case 'video-canvas-setup':\n this.handleVideoCanvasSetup(message);\n break;\n case 'video-frame-update':\n this.handleVideoFrameUpdate(message);\n break;\n case 'video-config-update':\n this.handleVideoConfigUpdate(message);\n break;\n case 'mouse-update':\n this.handleMouseUpdate(message);\n break;\n case 'keyboard-update':\n this.handleKeyboardUpdate(message);\n break;\n case 'touch-update':\n this.handleTouchUpdate(message);\n break;\n case 'interaction-enabled':\n this.handleInteractionEnabled(message);\n break;\n case 'performance-update':\n this.handlePerformanceUpdate(message);\n break;\n }\n };\n }\n \n private handleInit(message: WorkerInitMessage): void {\n try {\n this.canvas = message.data.canvas;\n this.viji.canvas = this.canvas;\n \n // Set initial effective resolution (same as canvas size initially)\n this.viji.width = this.canvas.width;\n this.viji.height = this.canvas.height;\n \n // Start render loop\n this.startRenderLoop();\n \n // Send ready response\n this.postMessage('ready', { \n id: message.id,\n canvasSize: { width: this.canvas.width, height: this.canvas.height }\n });\n } catch (error) {\n this.postMessage('error', {\n id: message.id,\n message: (error as Error).message,\n code: 'INIT_ERROR'\n });\n }\n }\n \n private handleFrameRateUpdate(message: WorkerFrameRateMessage): void {\n if (message.data && message.data.mode) {\n this.frameRateMode = message.data.mode;\n this.debugLog('Frame rate mode updated to:', message.data.mode);\n }\n }\n \n private handleRefreshRateUpdate(message: WorkerRefreshRateMessage): void {\n if (message.data && message.data.screenRefreshRate) {\n this.screenRefreshRate = message.data.screenRefreshRate;\n this.debugLog('Screen refresh rate updated to:', message.data.screenRefreshRate + 'Hz');\n }\n }\n \n private trackEffectiveFrameTime(currentTime: number): void {\n // Keep track of actual render frame times\n this.effectiveFrameTimes.push(currentTime);\n \n // Keep only the last 60 frames for calculation (1 second at 60fps)\n if (this.effectiveFrameTimes.length > 60) {\n this.effectiveFrameTimes.shift();\n }\n }\n \n private reportEffectiveRefreshRate(currentTime: number): void {\n // Report effective refresh rate every second\n if (currentTime - this.lastEffectiveRateReport >= this.effectiveRateReportInterval) {\n if (this.effectiveFrameTimes.length >= 2) {\n // Calculate effective refresh rate from actual frame times\n const totalTime = this.effectiveFrameTimes[this.effectiveFrameTimes.length - 1] - this.effectiveFrameTimes[0];\n const frameCount = this.effectiveFrameTimes.length - 1;\n const effectiveRefreshRate = Math.round((frameCount / totalTime) * 1000);\n \n // Send performance update to core\n this.postMessage('performance-update', {\n effectiveRefreshRate,\n frameRateMode: this.frameRateMode,\n screenRefreshRate: this.screenRefreshRate,\n parameterCount: this.parameterSystem.getParameterCount()\n });\n }\n \n this.lastEffectiveRateReport = currentTime;\n }\n }\n \n private handleResolutionUpdate(message: WorkerResolutionMessage): void {\n if (message.data) {\n // Update canvas resolution directly (effective dimensions * scale)\n if (this.canvas) {\n this.canvas.width = Math.round(message.data.effectiveWidth);\n this.canvas.height = Math.round(message.data.effectiveHeight);\n }\n \n // Update viji dimensions to match actual canvas\n this.viji.width = Math.round(message.data.effectiveWidth);\n this.viji.height = Math.round(message.data.effectiveHeight);\n \n // Update WebGL viewport if context exists\n if (this.gl) {\n this.gl.viewport(0, 0, this.viji.width, this.viji.height);\n }\n \n this.debugLog('Canvas resolution updated to:', this.viji.width + 'x' + this.viji.height);\n }\n }\n \n private handleParameterUpdate(message: WorkerParameterMessage): void {\n if (message.data && message.data.name !== undefined && message.data.value !== undefined) {\n this.parameterSystem.updateParameterValue(message.data.name, message.data.value);\n }\n }\n\n private handleParameterBatchUpdate(message: WorkerParameterBatchMessage): void {\n if (message.data && message.data.updates) {\n for (const update of message.data.updates) {\n this.parameterSystem.updateParameterValue(update.name, update.value);\n }\n \n // Mark initial values as synced after first batch update\n this.parameterSystem.markInitialValuesSynced();\n this.debugLog('Parameter system initialized successfully');\n }\n }\n \n private handleStreamUpdate(message: WorkerStreamMessage): void {\n // TODO: Handle general stream updates (non-audio)\n this.debugLog('Stream update:', message.data);\n }\n \n private handleAudioAnalysisUpdate(message: WorkerAudioAnalysisMessage): void {\n // Phase 5: Handle audio analysis results from host\n this.audioState = {\n isConnected: message.data.isConnected,\n volume: message.data.volume,\n bands: message.data.bands,\n frequencyData: message.data.frequencyData\n };\n \n // Update viji.audio API\n this.viji.audio = {\n ...this.audioState,\n getFrequencyData: () => this.audioState.frequencyData\n };\n }\n\n private handleVideoCanvasSetup(message: WorkerVideoCanvasSetupMessage): void {\n // Phase 10: Handle OffscreenCanvas transfer from host to worker-side VideoSystem\n this.videoSystem.handleCanvasSetup({\n offscreenCanvas: message.data.offscreenCanvas,\n width: message.data.width,\n height: message.data.height,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoFrameUpdate(message: WorkerVideoFrameUpdateMessage): void {\n // Phase 10: Handle ImageBitmap frame from host to worker-side VideoSystem\n this.videoSystem.handleFrameUpdate({\n imageBitmap: message.data.imageBitmap,\n timestamp: message.data.timestamp\n });\n \n // Update viji.video API with current VideoSystem state\n Object.assign(this.viji.video, this.videoSystem.getVideoAPI());\n }\n\n private handleVideoConfigUpdate(message: WorkerVideoConfigUpdateMessage): void {\n // Phase 10: Handle video configuration updates\n this.videoSystem.handleVideoConfigUpdate({\n ...(message.data.targetFrameRate && { targetFrameRate: message.data.targetFrameRate }),\n ...(message.data.cvConfig && { cvConfig: message.data.cvConfig }),\n ...(message.data.width && { width: message.data.width }),\n ...(message.data.height && { height: message.data.height }),\n ...(message.data.disconnect && { disconnect: message.data.disconnect }),\n timestamp: message.data.timestamp\n });\n }\n \n private handlePerformanceUpdate(message: WorkerPerformanceMessage): void {\n // TODO: Handle performance updates in Phase 3\n this.debugLog('Performance update:', message.data);\n }\n \n private handleSetSceneCode(message: WorkerSetSceneCodeMessage): void {\n if (message.data && message.data.sceneCode) {\n // Delegate to global scene code function\n (self as any).setSceneCode(message.data.sceneCode);\n }\n }\n \n private startRenderLoop(): void {\n this.isRunning = true;\n this.startTime = performance.now();\n this.lastTime = this.startTime;\n this.renderFrame();\n }\n \n public renderFrame(): void {\n if (!this.isRunning) return;\n \n const currentTime = performance.now();\n \n // Phase 7: Reset frame-based interaction events at start of frame\n this.interactionSystem.frameStart();\n \n // Update frame rate info\n this.viji.fps = this.frameRateMode === 'full' ? this.screenRefreshRate : this.screenRefreshRate / 2;\n \n // Check if we should render this frame\n let shouldRender = true;\n if (this.frameRateMode === 'half') {\n shouldRender = !this.skipNextFrame;\n this.skipNextFrame = !this.skipNextFrame;\n }\n \n if (shouldRender) {\n this.viji.deltaTime = (currentTime - this.lastTime) / 1000;\n this.viji.time = (currentTime - this.startTime) / 1000;\n this.viji.frameCount = ++this.frameCount;\n \n // Track effective frame times for performance calculation\n this.trackEffectiveFrameTime(currentTime);\n \n this.lastTime = currentTime;\n \n try {\n // Call artist render function\n const renderFunction = (self as any).renderFunction;\n if (renderFunction && typeof renderFunction === 'function') {\n renderFunction(this.viji);\n }\n } catch (error) {\n console.error('Render error:', error);\n this.postMessage('error', {\n message: (error as Error).message,\n code: 'RENDER_ERROR',\n stack: (error as Error).stack\n });\n }\n }\n \n // Report effective refresh rate periodically\n this.reportEffectiveRefreshRate(currentTime);\n \n // Schedule next frame check\n requestAnimationFrame(() => this.renderFrame());\n }\n \n private postMessage(type: string, data?: any): void {\n self.postMessage({\n type,\n id: data?.id || `${type}_${Date.now()}`,\n timestamp: Date.now(),\n data\n });\n }\n\n // Phase 7: Interaction Message Handlers (delegated to InteractionSystem)\n\n private handleMouseUpdate(message: any): void {\n this.interactionSystem.handleMouseUpdate(message.data);\n }\n\n private handleKeyboardUpdate(message: any): void {\n this.interactionSystem.handleKeyboardUpdate(message.data);\n }\n\n private handleTouchUpdate(message: any): void {\n this.interactionSystem.handleTouchUpdate(message.data);\n }\n\n private handleInteractionEnabled(message: any): void {\n this.interactionSystem.setInteractionEnabled(message.data.enabled);\n }\n} ","/**\n * Viji Worker Runtime - Secure WebWorker for artist scene execution\n * This worker provides the complete artist API and handles scene rendering\n */\n\nimport { VijiWorkerRuntime } from './VijiWorkerRuntime.js';\n\n// Initialize runtime\nconst runtime = new VijiWorkerRuntime();\n\n// Dynamic scene code execution\nlet renderFunction: ((viji: typeof runtime.viji) => void) | null = null;\n\n// Function to set the scene code dynamically\nfunction setSceneCode(sceneCode: string): void {\n try {\n // Reset parameter state for new scene\n runtime.resetParameterState();\n \n // Create a function from the scene code string\n // The scene code should define a render function\n const functionBody = sceneCode + '\\n' +\n 'if (typeof render === \"function\") {\\n' +\n ' return render;\\n' +\n '}\\n' +\n 'throw new Error(\"Scene code must define a render function\");';\n \n const sceneFunction = new Function('viji', functionBody);\n \n renderFunction = sceneFunction(runtime.viji);\n // Update global reference for the runtime to access\n (self as any).renderFunction = renderFunction;\n // Debug logging is controlled by VijiWorkerRuntime\n \n // After scene code execution, automatically send all parameters to host\n runtime.sendAllParametersToHost();\n } catch (error) {\n console.error('Failed to load scene code:', error);\n self.postMessage({\n type: 'error',\n id: `scene_error_${Date.now()}`,\n timestamp: Date.now(),\n data: {\n message: `Scene code error: ${(error as Error).message}`,\n code: 'SCENE_CODE_ERROR'\n }\n });\n }\n}\n\n// Expose functions to global scope for the runtime to access\n(self as any).setSceneCode = setSceneCode; "],"names":["renderFunction"],"mappings":";;EAkBO,MAAM,gBAAgB;AAAA;AAAA,IAEnB,2CAA2B,IAAA;AAAA,IAC3B,sCAAsB,IAAA;AAAA,IACtB,sCAAsB,IAAA;AAAA,IACtB,uCAAuB,IAAA;AAAA;AAAA,IACvB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA;AAAA;AAAA,IAGtB,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ;AAAA,IAER,YAAY,qBAAyD;AACnE,WAAK,sBAAsB;AAAA,IAC7B;AAAA;AAAA,IAGO,sBAAsB,cAAsB,QAAuC;AACxF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,KAAK,OAAO,OAAO;AAAA,QACnB,KAAK,OAAO,OAAO;AAAA,QACnB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,KAAK,aAAa;AAAA,UAClB,MAAM,aAAa;AAAA,QAAA;AAAA,MACrB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,qBAAqB,cAAsB,QAAqC;AACrF,YAAM,YAAY,OAAO;AACzB,YAAM,cAAc;AAAA,QAClB,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,YAAY;AAAA,QACnB,aAAa,YAAY;AAAA,QACzB,OAAO,YAAY;AAAA,QACnB,UAAU,YAAY;AAAA,MAAA;AAGxB,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,WAAW;AAChD,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAAuB,QAAuC;AACzF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,MAAA;AAGzB,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAA+B,QAAuC;AACjG,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,SAAS,aAAa;AAAA,QAAA;AAAA,MACxB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEO,oBAAoB,cAAsB,QAAmC;AAClF,YAAM,YAAY,OAAO;AACzB,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QACP,WAAW,OAAO,aAAa;AAAA,QAC/B,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,WAAW;AAAA,QAClB,aAAa,WAAW;AAAA,QACxB,OAAO,WAAW;AAAA,QAClB,UAAU,WAAW;AAAA,QACrB,QAAQ;AAAA,UACN,WAAW,WAAW;AAAA,QAAA;AAAA,MACxB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,UAAU;AAC/C,aAAO;AAAA,IACT;AAAA,IAEO,sBAAsB,cAAsB,QAAuC;AACxF,YAAM,YAAY,OAAO;AACzB,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,KAAK,OAAO,OAAO;AAAA,QACnB,KAAK,OAAO,OAAO;AAAA,QACnB,MAAM,OAAO,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,OAAO,OAAO,SAAS;AAAA,QACvB,UAAU,OAAO,YAAY;AAAA,MAAA;AAG/B,YAAM,aAAkC;AAAA,QACtC,MAAM;AAAA,QACN;AAAA,QACA,OAAO,aAAa;AAAA,QACpB,aAAa,aAAa;AAAA,QAC1B,OAAO,aAAa;AAAA,QACpB,UAAU,aAAa;AAAA,QACvB,QAAQ;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,KAAK,aAAa;AAAA,UAClB,MAAM,aAAa;AAAA,QAAA;AAAA,MACrB;AAGF,WAAK,yBAAyB,WAAW,UAAU;AACnD,WAAK,iBAAiB,IAAI,WAAW,YAAY;AACjD,aAAO;AAAA,IACT;AAAA,IAEQ,yBAAyB,MAAc,YAAuC;AAGpF,WAAK,qBAAqB,IAAI,MAAM,UAAU;AAC9C,WAAK,gBAAgB,IAAI,MAAM,WAAW,YAAY;AAAA,IACxD;AAAA,IAEO,qBAAqB,MAAc,OAAgC;AACxE,YAAM,aAAa,KAAK,qBAAqB,IAAI,IAAI;AACrD,UAAI,CAAC,YAAY;AACf,gBAAQ,KAAK,sBAAsB,IAAI,2BAA2B,MAAM,KAAK,KAAK,qBAAqB,KAAA,CAAM,CAAC;AAC9G,eAAO;AAAA,MACT;AAGA,UAAI,CAAC,KAAK,uBAAuB,MAAM,OAAO,UAAU,GAAG;AACzD,gBAAQ,KAAK,mCAAmC,IAAI,MAAM,KAAK,EAAE;AACjE,eAAO;AAAA,MACT;AAGA,YAAM,eAAe,KAAK,gBAAgB,IAAI,IAAI;AAClD,YAAM,gBAAgB,CAAC,KAAK;AAE5B,UAAI,iBAAiB,SAAS,CAAC,eAAe;AAC5C,eAAO;AAAA,MACT;AAGA,WAAK,gBAAgB,IAAI,MAAM,KAAK;AAGpC,YAAM,kBAAkB,KAAK,iBAAiB,IAAI,IAAI;AACtD,UAAI,iBAAiB;AACnB,wBAAgB,QAAQ;AAAA,MAC1B;AAEA,aAAO;AAAA,IACT;AAAA,IAEQ,uBAAuB,MAAc,OAAuB,YAA0C;AAE5G,UAAI,WAAW,YAAY,CAAC,WAAW,SAAS,KAAK,GAAG;AACtD,gBAAQ,MAAM,2CAA2C,IAAI,MAAM,KAAK,EAAE;AAC1E,eAAO;AAAA,MACT;AAGA,cAAQ,WAAW,MAAA;AAAA,QACjB,KAAK;AAAA,QACL,KAAK;AACH,cAAI,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AAC7C,oBAAQ,MAAM,cAAc,IAAI,4BAA4B,KAAK,EAAE;AACnE,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,QAAQ,UAAa,QAAQ,WAAW,OAAO,KAAK;AACzE,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,qBAAqB,WAAW,OAAO,GAAG,EAAE;AAC5F,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,QAAQ,UAAa,QAAQ,WAAW,OAAO,KAAK;AACzE,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,qBAAqB,WAAW,OAAO,GAAG,EAAE;AAC5F,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,YAAY,CAAC,oBAAoB,KAAK,KAAK,GAAG;AACjE,oBAAQ,MAAM,cAAc,IAAI,qCAAqC,KAAK,EAAE;AAC5E,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,WAAW;AAC9B,oBAAQ,MAAM,cAAc,IAAI,6BAA6B,KAAK,EAAE;AACpE,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,CAAC,WAAW,QAAQ,WAAW,CAAC,WAAW,OAAO,QAAQ,SAAS,KAAwB,GAAG;AAChG,oBAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,uBAAuB,WAAW,QAAQ,OAAO,EAAE;AACnG,mBAAO;AAAA,UACT;AACA;AAAA,QACF,KAAK;AACH,cAAI,OAAO,UAAU,UAAU;AAC7B,oBAAQ,MAAM,cAAc,IAAI,4BAA4B,KAAK,EAAE;AACnE,mBAAO;AAAA,UACT;AACA,cAAI,WAAW,QAAQ,aAAa,MAAM,SAAS,WAAW,OAAO,WAAW;AAC9E,oBAAQ,MAAM,cAAc,IAAI,oBAAoB,MAAM,MAAM,MAAM,WAAW,OAAO,SAAS,EAAE;AACnG,mBAAO;AAAA,UACT;AACA;AAAA,MAAA;AAGJ,aAAO;AAAA,IACT;AAAA;AAAA,IAGO,sBAA4B;AACjC,WAAK,oBAAoB;AACzB,WAAK,sBAAsB;AAC3B,WAAK,qBAAqB,MAAA;AAC1B,WAAK,gBAAgB,MAAA;AACrB,WAAK,gBAAgB,MAAA;AACrB,WAAK,iBAAiB,MAAA;AAAA,IACxB;AAAA;AAAA,IAGO,0BAAgC;AAErC,UAAI,KAAK,qBAAqB,KAAK,qBAAqB,SAAS,GAAG;AAClE;AAAA,MACF;AAEA,UAAI;AAEF,cAAM,6BAAa,IAAA;AAEnB,mBAAW,CAAC,WAAW,QAAQ,KAAK,KAAK,sBAAsB;AAC7D,gBAAM,YAAY,SAAS,SAAS;AAEpC,cAAI,CAAC,OAAO,IAAI,SAAS,GAAG;AAE1B,kBAAM,WAAW,SAAS,YAAY;AACtC,mBAAO,IAAI,WAAW;AAAA,cACpB;AAAA,cACA;AAAA,cACA,YAAY,CAAA;AAAA,YAAC,CACd;AAAA,UACH;AAEA,gBAAM,QAAQ,OAAO,IAAI,SAAS;AAClC,gBAAM,WAAW,SAAS,IAAI;AAAA,QAChC;AAEA,aAAK,oBAAoB;AAGzB,aAAK,oBAAoB,sBAAsB;AAAA,UAC7C,QAAQ,MAAM,KAAK,OAAO,QAAQ;AAAA,UAClC,WAAW,YAAY,IAAA;AAAA,QAAI,CAC5B;AAED,aAAK,SAAS,gCAAgC,KAAK,qBAAqB,IAAI,kBAAkB,OAAO,IAAI,SAAS;AAAA,MACpH,SAAS,OAAO;AACd,aAAK,oBAAoB,8BAA8B;AAAA,UACrD,SAAS,sCAAuC,MAAgB,OAAO;AAAA,UACvE,MAAM;AAAA,QAAA,CACP;AAAA,MACH;AAAA,IACF;AAAA;AAAA,IAGO,0BAAgC;AACrC,WAAK,sBAAsB;AAAA,IAC7B;AAAA;AAAA,IAGO,oBAA4B;AACjC,aAAO,KAAK,qBAAqB;AAAA,IACnC;AAAA,EACF;AAAA,ECnXO,MAAM,kBAAkB;AAAA;AAAA,IAErB,YAAqB;AAAA;AAAA,IAGrB,aAAuB;AAAA,MAC7B,GAAG;AAAA,MAAG,GAAG;AAAA,MACT,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,cAAc;AAAA,MACd,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,MACrB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,UAAU;AAAA,IAAA;AAAA;AAAA,IAIJ,gBAA6B;AAAA,MACnC,WAAW,CAAC,QAAgB,KAAK,cAAc,WAAW,IAAI,IAAI,aAAa;AAAA,MAC/E,YAAY,CAAC,QAAgB,KAAK,cAAc,iBAAiB,IAAI,IAAI,aAAa;AAAA,MACtF,aAAa,CAAC,QAAgB,KAAK,cAAc,kBAAkB,IAAI,IAAI,aAAa;AAAA,MACxF,gCAAgB,IAAA;AAAA,MAChB,sCAAsB,IAAA;AAAA,MACtB,uCAAuB,IAAA;AAAA,MACvB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,MAAM;AAAA,IAAA;AAAA;AAAA,IAIA,aAAuB;AAAA,MAC7B,QAAQ,CAAA;AAAA,MACR,OAAO;AAAA,MACP,SAAS,CAAA;AAAA,MACT,OAAO,CAAA;AAAA,MACP,OAAO,CAAA;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA;AAAA,IACf;AAAA,IAGF,cAAc;AAEZ,WAAK,oBAAoB,KAAK,kBAAkB,KAAK,IAAI;AACzD,WAAK,uBAAuB,KAAK,qBAAqB,KAAK,IAAI;AAC/D,WAAK,oBAAoB,KAAK,kBAAkB,KAAK,IAAI;AACzD,WAAK,aAAa,KAAK,WAAW,KAAK,IAAI;AAAA,IAC7C;AAAA;AAAA;AAAA;AAAA,IAKO,qBAAqB;AAC1B,aAAO;AAAA,QACL,OAAO,KAAK;AAAA,QACZ,UAAU,KAAK;AAAA,QACf,SAAS,KAAK;AAAA,MAAA;AAAA,IAElB;AAAA;AAAA;AAAA;AAAA,IAKO,aAAmB;AAExB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,WAAW;AAC3B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AAGzB,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AAGrC,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,gBAAgB;AAAA,IAC3C;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAYhB;AAEP,UAAI,CAAC,KAAK,UAAW;AAErB,WAAK,WAAW,IAAI,KAAK;AACzB,WAAK,WAAW,IAAI,KAAK;AACzB,WAAK,WAAW,aAAa,KAAK,eAAe,SAAY,KAAK,aAAa;AAC/E,WAAK,WAAW,cAAc,KAAK,UAAU,OAAO;AACpD,WAAK,WAAW,eAAe,KAAK,UAAU,OAAO;AACrD,WAAK,WAAW,gBAAgB,KAAK,UAAU,OAAO;AACtD,WAAK,WAAW,YAAY,KAAK,UAAU;AAG3C,WAAK,WAAW,SAAS,KAAK,UAAU;AACxC,WAAK,WAAW,SAAS,KAAK,UAAU;AACxC,WAAK,WAAW,aAAa,KAAK,eAAe;AACjD,WAAK,WAAW,SAAS,KAAK,eAAe;AAC7C,WAAK,WAAW,SAAS,KAAK,eAAe;AAG7C,WAAK,WAAW,SAAS,IAAI,KAAK,UAAU;AAC5C,WAAK,WAAW,SAAS,IAAI,KAAK,UAAU;AAG5C,WAAK,WAAW,aAAa,KAAK,cAAc;AAChD,WAAK,WAAW,cAAc,KAAK,eAAe;AAClD,WAAK,WAAW,WAAY,KAAK,WAAW,KAAK,KAAK,WAAW;AAAA,IACnE;AAAA;AAAA;AAAA;AAAA,IAKO,qBAAqB,MASnB;AAEP,UAAI,CAAC,KAAK,UAAW;AACrB,YAAM,MAAM,KAAK,IAAI,YAAA;AAErB,UAAI,KAAK,SAAS,WAAW;AAC3B,YAAI,CAAC,KAAK,cAAc,WAAW,IAAI,GAAG,GAAG;AAC3C,eAAK,cAAc,WAAW,IAAI,GAAG;AACrC,eAAK,cAAc,iBAAiB,IAAI,GAAG;AAC3C,eAAK,cAAc,iBAAiB,KAAK;AAAA,QAC3C;AAAA,MACF,WAAW,KAAK,SAAS,SAAS;AAChC,aAAK,cAAc,WAAW,OAAO,GAAG;AACxC,aAAK,cAAc,kBAAkB,IAAI,GAAG;AAC5C,aAAK,cAAc,kBAAkB,KAAK;AAAA,MAC5C;AAGA,WAAK,cAAc,QAAQ,KAAK;AAChC,WAAK,cAAc,OAAO,KAAK;AAC/B,WAAK,cAAc,MAAM,KAAK;AAC9B,WAAK,cAAc,OAAO,KAAK;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAahB;AAEP,UAAI,CAAC,KAAK,UAAW;AAErB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AAGxB,YAAM,UAAwB,KAAK,QAAQ,IAAI,CAAC,WAAW;AAAA,QACzD,IAAI,MAAM;AAAA,QACV,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,QACT,UAAU,MAAM,YAAY;AAAA,QAC5B,QAAQ,KAAK,IAAI,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC;AAAA,QACvD,SAAS,MAAM,WAAW;AAAA,QAC1B,SAAS,MAAM,WAAW;AAAA,QAC1B,eAAe,MAAM,iBAAiB;AAAA,QACtC,OAAO,MAAM,SAAS,MAAM,YAAY;AAAA,QACxC,QAAQ;AAAA;AAAA,QACR,QAAQ;AAAA,QACR,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA;AAAA,QACrB,OAAO,KAAK,SAAS;AAAA,QACrB,UAAU;AAAA,QACV,UAAU,KAAK,SAAS,cAAc,KAAK,SAAS;AAAA,MAAA,EACpD;AAGF,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,QAAQ,QAAQ;AAChC,WAAK,WAAW,UAAU,QAAQ,CAAC,KAAK;AAGxC,UAAI,KAAK,SAAS,cAAc;AAC9B,aAAK,WAAW,UAAU;AAAA,MAC5B,WAAW,KAAK,SAAS,aAAa;AACpC,aAAK,WAAW,QAAQ;AAAA,MAC1B,WAAW,KAAK,SAAS,cAAc,KAAK,SAAS,eAAe;AAClE,aAAK,WAAW,QAAQ;AAAA,MAC1B;AAMA,WAAK,WAAW,WAAW;AAAA,QACzB,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA;AAAA,IAEjB;AAAA;AAAA;AAAA;AAAA,IAKO,wBAA8B;AAEnC,aAAO,OAAO,KAAK,YAAY;AAAA,QAC7B,GAAG;AAAA,QAAG,GAAG;AAAA,QACT,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,cAAc;AAAA,QACd,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,UAAU;AAAA,MAAA,CACX;AAGD,WAAK,cAAc,WAAW,MAAA;AAC9B,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AACrC,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,kBAAkB;AACrC,WAAK,cAAc,QAAQ;AAC3B,WAAK,cAAc,OAAO;AAC1B,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,OAAO;AAG1B,WAAK,WAAW,SAAS,CAAA;AACzB,WAAK,WAAW,QAAQ;AACxB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,UAAU;AAC1B,aAAO,OAAO,KAAK,WAAW,UAAU;AAAA,QACtC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QACrB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,aAAa;AAAA,MAAA,CACd;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKO,sBAAsB,SAAwB;AACnD,WAAK,YAAY;AAGjB,UAAI,CAAC,SAAS;AACZ,aAAK,uBAAA;AAAA,MACP;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,wBAAiC;AACtC,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKQ,yBAA+B;AAErC,WAAK,WAAW,IAAI;AACpB,WAAK,WAAW,IAAI;AACpB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,YAAY;AAC5B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,eAAe;AAC/B,WAAK,WAAW,SAAS,IAAI;AAC7B,WAAK,WAAW,SAAS,IAAI;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,SAAS;AACzB,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,WAAW;AAG3B,WAAK,cAAc,WAAW,MAAA;AAC9B,WAAK,cAAc,iBAAiB,MAAA;AACpC,WAAK,cAAc,kBAAkB,MAAA;AACrC,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,kBAAkB;AACrC,WAAK,cAAc,QAAQ;AAC3B,WAAK,cAAc,OAAO;AAC1B,WAAK,cAAc,MAAM;AACzB,WAAK,cAAc,OAAO;AAG1B,WAAK,WAAW,SAAS,CAAA;AACzB,WAAK,WAAW,QAAQ;AACxB,WAAK,WAAW,UAAU,CAAA;AAC1B,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,QAAQ,CAAA;AACxB,WAAK,WAAW,UAAU;AAC1B,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,YAAY;AACrC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,aAAa;AACtC,WAAK,WAAW,SAAS,gBAAgB;AACzC,WAAK,WAAW,SAAS,gBAAgB;AACzC,WAAK,WAAW,SAAS,WAAW,EAAE,GAAG,GAAG,GAAG,EAAA;AAC/C,WAAK,WAAW,SAAS,WAAW;AACpC,WAAK,WAAW,SAAS,cAAc;AACvC,WAAK,WAAW,SAAS,cAAc;AAAA,IACzC;AAAA,EACF;AAAA,ECrYO,MAAM,YAAY;AAAA;AAAA,IAEf,kBAA0C;AAAA,IAC1C,MAAgD;AAAA,IAChD,KAA4D;AAAA;AAAA,IAG5D,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAAA,IACnB;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ,kBAAkB;AAAA;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB,MAAO,KAAK;AAAA;AAAA;AAAA,IAG5B,sBAAsB;AAAA,IACtB,aAAa;AAAA;AAAA,IAGb,aAAa;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,MACX,WAAW;AAAA,IAAA;AAAA;AAAA,IAIL,aAAa;AAAA,MACnB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,kBAAkB;AAAA,IAAA;AAAA,IAGZ,YAAY;AAAA,MAClB,OAAO,CAAA;AAAA,MACP,OAAO,CAAA;AAAA,MACP,kBAAkB;AAAA,IAAA;AAAA,IAGpB,cAAc;AAAA,IAEd;AAAA;AAAA;AAAA;AAAA,IAKO,cAAc;AACnB,aAAO;AAAA,QACL,aAAa,KAAK,WAAW;AAAA,QAC7B,cAAc,KAAK,WAAW;AAAA,QAC9B,YAAY,KAAK,WAAW;AAAA,QAC5B,aAAa,KAAK,WAAW;AAAA,QAC7B,WAAW,KAAK,WAAW;AAAA,QAC3B,cAAc,MAAM,KAAK,WAAW;AAAA,QACpC,OAAO,KAAK,UAAU;AAAA,QACtB,OAAO,KAAK,UAAU;AAAA,MAAA;AAAA,IAE1B;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAKhB;AACP,UAAI;AAEF,aAAK,gBAAA;AAGL,aAAK,kBAAkB,KAAK;AAG5B,aAAK,MAAM,KAAK,gBAAgB,WAAW,MAAM;AAAA,UAC/C,oBAAoB;AAAA;AAAA,QAAA,CACrB;AAED,YAAI,CAAC,KAAK,KAAK;AACb,gBAAM,IAAI,MAAM,2DAA2D;AAAA,QAC7E;AAIA,YAAI;AACF,eAAK,KAAK,KAAK,gBAAgB,WAAW,QAAQ,KAAK,KAAK,gBAAgB,WAAW,OAAO;AAAA,QAChG,SAAS,GAAG;AAEV,eAAK,SAAS,4CAA4C;AAAA,QAC5D;AAGA,aAAK,WAAW,cAAc;AAC9B,aAAK,WAAW,eAAe,KAAK;AACpC,aAAK,WAAW,aAAa,KAAK;AAClC,aAAK,WAAW,cAAc,KAAK;AACnC,aAAK,aAAa;AAClB,aAAK,sBAAsB;AAE3B,aAAK,SAAS,gEAAgE;AAAA,UAC5E,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,UAAU,CAAC,CAAC,KAAK;AAAA,UACjB,iBAAiB,KAAK;AAAA,QAAA,CACvB;AAED,aAAK,SAAS,mEAAmE;AAAA,MAEnF,SAAS,OAAO;AACd,gBAAQ,MAAM,8CAA8C,KAAK;AACjE,aAAK,gBAAA;AAAA,MACP;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAkB,MAGhB;AACP,UAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,KAAK;AACtC,gBAAQ,KAAK,iDAAiD;AAC9D;AAAA,MACF;AAEA,UAAI;AAEF,YAAI,KAAK,aAAa,QAAQ,GAAG;AAC/B,eAAK,SAAS,wCAAwC;AAAA,YACpD,YAAY,GAAG,KAAK,YAAY,KAAK,IAAI,KAAK,YAAY,MAAM;AAAA,YAChE,YAAY,GAAG,KAAK,gBAAgB,KAAK,IAAI,KAAK,gBAAgB,MAAM;AAAA,YACxE,YAAY,KAAK;AAAA,YACjB,WAAW,KAAK;AAAA,UAAA,CACjB;AAAA,QACH;AAGA,aAAK,IAAI,UAAU,KAAK,aAAa,GAAG,GAAG,KAAK,gBAAgB,OAAO,KAAK,gBAAgB,MAAM;AAGlG,aAAK,oBAAoB,KAAK,SAAS;AAGvC,aAAK,YAAY,MAAA;AAEjB,aAAK;AAAA,MAEP,SAAS,OAAO;AACd,gBAAQ,MAAM,kDAAkD,KAAK;AAAA,MACvE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,oBAAoB,WAAyB;AACnD,UAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,KAAK;AACtC;AAAA,MACF;AAEA,UAAI;AAEF,aAAK,WAAW,YAAY,KAAK,IAAI;AAAA,UACnC;AAAA,UAAG;AAAA,UACH,KAAK,gBAAgB;AAAA,UACrB,KAAK,gBAAgB;AAAA,QAAA;AAIvB,cAAM,YAAY,YAAY,KAAK;AACnC,aAAK,WAAW,YAAY,YAAY,IAAI,MAAO,YAAY;AAG/D,YAAI,CAAC,KAAK,qBAAqB;AACvB,eAAK,SAAS,qDAAqD,KAAK,WAAW,UAAU,QAAQ,CAAC,CAAC,SAAS,KAAK,gBAAgB,KAAK,IAAI,KAAK,gBAAgB,MAAM,GAAG;AACpL,eAAK,SAAS,gEAAgE;AAC5E,eAAK,sBAAsB;AAAA,QAC7B;AAGA,aAAK,kBAAA;AAEL,aAAK,gBAAgB;AAAA,MACvB,SAAS,OAAO;AACd,gBAAQ,MAAM,+CAA+C,KAAK;AAAA,MACpE;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKO,wBAAwB,MAOtB;AACP,UAAI;AAEF,YAAI,KAAK,YAAY;AACnB,eAAK,gBAAA;AACL;AAAA,QACF;AAGA,YAAI,KAAK,SAAS,KAAK,UAAU,KAAK,iBAAiB;AACrD,eAAK,aAAa,KAAK,OAAO,KAAK,MAAM;AAAA,QAC3C;AAGA,YAAI,KAAK,iBAAiB;AACxB,eAAK,uBAAuB,KAAK,eAAe;AAAA,QAClD;AAGA,YAAI,KAAK,UAAU;AACjB,eAAK,eAAe,KAAK,QAAQ;AAAA,QACnC;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,uCAAuC,KAAK;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,aAAa,OAAe,QAAsB;AACxD,UAAI,CAAC,KAAK,gBAAiB;AAE3B,UAAI;AAEF,aAAK,gBAAgB,QAAQ;AAC7B,aAAK,gBAAgB,SAAS;AAG9B,aAAK,WAAW,aAAa;AAC7B,aAAK,WAAW,cAAc;AAG9B,YAAI,KAAK,IAAI;AACX,eAAK,GAAG,SAAS,GAAG,GAAG,OAAO,MAAM;AAAA,QACtC;AAEA,aAAK,SAAS,iCAAiC,KAAK,IAAI,MAAM,gBAAgB;AAAA,MAEhF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AAAA,MACxD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,kBAAwB;AAE9B,UAAI,KAAK,mBAAmB,KAAK,KAAK;AACpC,aAAK,IAAI,UAAU,GAAG,GAAG,KAAK,gBAAgB,OAAO,KAAK,gBAAgB,MAAM;AAChF,aAAK,SAAS,0CAA0C;AAAA,MAC1D;AAGA,WAAK,kBAAkB;AACvB,WAAK,MAAM;AACX,WAAK,KAAK;AAGV,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,eAAe;AAC/B,WAAK,WAAW,aAAa;AAC7B,WAAK,WAAW,cAAc;AAC9B,WAAK,WAAW,YAAY;AAC5B,WAAK,WAAW,YAAY;AAC5B,WAAK,eAAA;AACL,WAAK,sBAAsB;AAC3B,WAAK,aAAa;AAElB,WAAK,SAAS,kCAAkC;AAAA,IAClD;AAAA;AAAA;AAAA;AAAA,IAKQ,uBAAuB,iBAA+B;AAC5D,WAAK,kBAAkB,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,eAAe,CAAC;AAChE,WAAK,gBAAgB,MAAO,KAAK;AAEjC,WAAK,SAAS,0CAA0C,KAAK,eAAe,oBAAoB;AAAA,IAClG;AAAA;AAAA;AAAA;AAAA,IAKQ,eAAe,UAAqB;AAE1C,WAAK,aAAa;AAAA,QAChB,eAAe,SAAS,iBAAiB;AAAA,QACzC,cAAc,SAAS,gBAAgB;AAAA,QACvC,kBAAkB,SAAS,oBAAoB;AAAA,MAAA;AAGjD,WAAK,SAAS,iEAAiE,KAAK,UAAU;AAAA,IAChG;AAAA;AAAA;AAAA;AAAA,IAKQ,oBAA0B;AAIhC,UAAI,KAAK,WAAW,cAAe;AAKnC,UAAI,KAAK,WAAW,aAAc;AAKlC,UAAI,KAAK,WAAW,iBAAkB;AAAA,IAIxC;AAAA;AAAA;AAAA;AAAA,IAKQ,iBAAuB;AAC7B,WAAK,YAAY;AAAA,QACf,OAAO,CAAA;AAAA,QACP,OAAO,CAAA;AAAA,QACP,kBAAkB;AAAA,MAAA;AAAA,IAEtB;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAwB;AAC7B,WAAK,gBAAA;AACL,WAAK,eAAA;AAAA,IACP;AAAA;AAAA;AAAA;AAAA,IAKO,sBAA8F;AACnG,aAAO;AAAA,QACL,iBAAiB,KAAK;AAAA,QACtB,eAAe,KAAK;AAAA,QACpB,YAAY,KAAK;AAAA,MAAA;AAAA,IAErB;AAAA;AAAA;AAAA;AAAA,IAKO,kBAAyE;AAC9E,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKO,4BAAoD;AACzD,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,ECpYO,MAAM,kBAAkB;AAAA,IACrB,SAAiC;AAAA,IACjC,MAAgD;AAAA,IAChD,KAA4D;AAAA,IAC5D,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,gBAAiC;AAAA,IACjC,gBAAgB;AAAA,IAChB,oBAAoB;AAAA;AAAA;AAAA,IAGpB,YAAY;AAAA;AAAA;AAAA;AAAA,IAKpB,aAAa,SAAwB;AACnC,WAAK,YAAY;AAEjB,UAAI,KAAK,YAAa,MAAK,YAAY,aAAa,OAAO;AAC3D,UAAI,KAAK,mBAAmB,kBAAkB,KAAK,iBAAiB;AACjE,aAAK,gBAAwB,aAAa,OAAO;AAAA,MACpD;AACA,UAAI,KAAK,qBAAqB,kBAAkB,KAAK,mBAAmB;AACrE,aAAK,kBAA0B,aAAa,OAAO;AAAA,MACtD;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKQ,SAAS,YAAoB,MAAmB;AACtD,UAAI,KAAK,WAAW;AAClB,gBAAQ,IAAI,SAAS,GAAG,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA,IAGQ,sBAAgC,CAAA;AAAA,IAChC,0BAA0B;AAAA,IAC1B,8BAA8B;AAAA;AAAA;AAAA,IAG9B;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA;AAAA;AAAA,IAGA,aAAa;AAAA,MACnB,aAAa;AAAA,MACb,QAAQ,EAAE,KAAK,GAAG,MAAM,EAAA;AAAA,MACxB,OAAO;AAAA,QACL,MAAM;AAAA,QAAG,KAAK;AAAA,QAAG,QAAQ;AAAA,QAAG,SAAS;AAAA,QACrC,QAAQ;AAAA,QAAG,SAAS;AAAA,QAAG,UAAU;AAAA,QAAG,YAAY;AAAA,MAAA;AAAA,MAElD,eAAe,IAAI,WAAW,CAAC;AAAA,IAAA;AAAA;AAAA;AAAA,IAM1B,OAAO;AAAA;AAAA,MAEZ,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA;AAAA,MAGZ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,KAAK;AAAA;AAAA,MAGL,OAAO,CAAA;AAAA,MAEP,OAAO;AAAA,QACL,aAAa;AAAA,QACb,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,WAAW;AAAA,QACX,cAAc,MAAM;AAAA,QACpB,OAAO,CAAA;AAAA,QACP,OAAO,CAAA;AAAA,MAAC;AAAA;AAAA,MAIV,OAAO,CAAA;AAAA,MACP,UAAU,CAAA;AAAA,MACV,SAAS,CAAA;AAAA;AAAA,MAGT,QAAQ,CAAC,cAAsB,WAAgB;AAC7C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,OAAO,CAAC,cAAsB,WAAgB;AAC5C,eAAO,KAAK,gBAAgB,qBAAqB,cAAc,MAAM;AAAA,MACvE;AAAA,MAEA,QAAQ,CAAC,cAAuB,WAAgB;AAC9C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,QAAQ,CAAC,cAA+B,WAAgB;AACtD,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA,MAEA,MAAM,CAAC,cAAsB,WAAgB;AAC3C,eAAO,KAAK,gBAAgB,oBAAoB,cAAc,MAAM;AAAA,MACtE;AAAA,MAEA,QAAQ,CAAC,cAAsB,WAAgB;AAC7C,eAAO,KAAK,gBAAgB,sBAAsB,cAAc,MAAM;AAAA,MACxE;AAAA;AAAA,MAGA,YAAY,CAAC,SAAyB;AACpC,YAAI,SAAS,MAAM;AACjB,cAAI,CAAC,KAAK,OAAO,KAAK,QAAQ;AAC5B,iBAAK,MAAM,KAAK,OAAO,WAAW,IAAI;AACtC,iBAAK,KAAK,MAAM,KAAK;AAAA,UACvB;AACA,iBAAO,KAAK;AAAA,QACd,WAAW,SAAS,SAAS;AAC3B,cAAI,CAAC,KAAK,MAAM,KAAK,QAAQ;AAC3B,iBAAK,KAAK,KAAK,OAAO,WAAW,QAAQ,KAAK,KAAK,OAAO,WAAW,OAAO;AAC5E,iBAAK,KAAK,KAAK,KAAK;AAGpB,gBAAI,KAAK,IAAI;AACX,mBAAK,GAAG,SAAS,GAAG,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM;AAAA,YAC1D;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,QACd;AACA,eAAO;AAAA,MACT;AAAA,IAAA;AAAA,IAGF,cAAc;AAEZ,WAAK,kBAAkB,IAAI,gBAAgB,CAAC,MAAc,SAAe;AACvE,aAAK,YAAY,MAAM,IAAI;AAAA,MAC7B,CAAC;AAGD,WAAK,oBAAoB,IAAI,kBAAA;AAG7B,WAAK,cAAc,IAAI,YAAA;AAGvB,aAAO,OAAO,KAAK,MAAM,KAAK,kBAAkB,oBAAoB;AACpE,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAG7D,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAG1C,WAAK,qBAAA;AAAA,IACP;AAAA;AAAA,IAGO,sBAA4B;AACjC,WAAK,gBAAgB,oBAAA;AACrB,WAAK,kBAAkB,sBAAA;AAGvB,WAAK,aAAa;AAAA,QAChB,aAAa;AAAA,QACb,QAAQ,EAAE,KAAK,GAAG,MAAM,EAAA;AAAA,QACxB,OAAO;AAAA,UACL,MAAM;AAAA,UAAG,KAAK;AAAA,UAAG,QAAQ;AAAA,UAAG,SAAS;AAAA,UACrC,QAAQ;AAAA,UAAG,SAAS;AAAA,UAAG,UAAU;AAAA,UAAG,YAAY;AAAA,QAAA;AAAA,QAElD,eAAe,IAAI,WAAW,CAAC;AAAA,MAAA;AAGjC,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAI1C,WAAK,YAAY,gBAAA;AAEjB,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA;AAAA,IAGO,0BAAgC;AACrC,WAAK,gBAAgB,wBAAA;AAAA,IACvB;AAAA,IAEQ,uBAA6B;AACnC,WAAK,YAAY,CAAC,UAAuC;AACvD,cAAM,UAAU,MAAM;AAEtB,gBAAQ,QAAQ,MAAA;AAAA,UACd,KAAK;AACH,iBAAK,WAAW,OAAO;AACvB;AAAA,UACF,KAAK;AACH,iBAAK,sBAAsB,OAAO;AAClC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACI,KAAK;AACX,iBAAK,mBAAmB,OAAO;AAC/B;AAAA,UACF,KAAK;AACH,iBAAK,aAAa,QAAQ,KAAK,OAAO;AACtC;AAAA,UACA,KAAK;AACH,iBAAK,sBAAsB,OAAO;AAClC;AAAA,UACF,KAAK;AACH,iBAAK,2BAA2B,OAAO;AACvC;AAAA,UACF,KAAK;AACH,iBAAK,mBAAmB,OAAO;AAC/B;AAAA,UACF,KAAK;AACH,iBAAK,0BAA0B,OAAO;AACtC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,uBAAuB,OAAO;AACnC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,UACF,KAAK;AACH,iBAAK,kBAAkB,OAAO;AAC9B;AAAA,UACF,KAAK;AACH,iBAAK,qBAAqB,OAAO;AACjC;AAAA,UACF,KAAK;AACH,iBAAK,kBAAkB,OAAO;AAC9B;AAAA,UACF,KAAK;AACH,iBAAK,yBAAyB,OAAO;AACrC;AAAA,UACF,KAAK;AACH,iBAAK,wBAAwB,OAAO;AACpC;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAAA,IAEQ,WAAW,SAAkC;AACnD,UAAI;AACF,aAAK,SAAS,QAAQ,KAAK;AAC3B,aAAK,KAAK,SAAS,KAAK;AAGxB,aAAK,KAAK,QAAQ,KAAK,OAAO;AAC9B,aAAK,KAAK,SAAS,KAAK,OAAO;AAG/B,aAAK,gBAAA;AAGL,aAAK,YAAY,SAAS;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ,YAAY,EAAE,OAAO,KAAK,OAAO,OAAO,QAAQ,KAAK,OAAO,OAAA;AAAA,QAAO,CACpE;AAAA,MACH,SAAS,OAAO;AACd,aAAK,YAAY,SAAS;AAAA,UACxB,IAAI,QAAQ;AAAA,UACZ,SAAU,MAAgB;AAAA,UAC1B,MAAM;AAAA,QAAA,CACP;AAAA,MACH;AAAA,IACF;AAAA,IAEQ,sBAAsB,SAAuC;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,MAAM;AACrC,aAAK,gBAAgB,QAAQ,KAAK;AAClC,aAAK,SAAS,+BAA+B,QAAQ,KAAK,IAAI;AAAA,MAChE;AAAA,IACF;AAAA,IAEQ,wBAAwB,SAAyC;AACvE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,mBAAmB;AAClD,aAAK,oBAAoB,QAAQ,KAAK;AACtC,aAAK,SAAS,mCAAmC,QAAQ,KAAK,oBAAoB,IAAI;AAAA,MACxF;AAAA,IACF;AAAA,IAEQ,wBAAwB,aAA2B;AAEzD,WAAK,oBAAoB,KAAK,WAAW;AAGzC,UAAI,KAAK,oBAAoB,SAAS,IAAI;AACxC,aAAK,oBAAoB,MAAA;AAAA,MAC3B;AAAA,IACF;AAAA,IAEQ,2BAA2B,aAA2B;AAE5D,UAAI,cAAc,KAAK,2BAA2B,KAAK,6BAA6B;AAClF,YAAI,KAAK,oBAAoB,UAAU,GAAG;AAExC,gBAAM,YAAY,KAAK,oBAAoB,KAAK,oBAAoB,SAAS,CAAC,IAAI,KAAK,oBAAoB,CAAC;AAC5G,gBAAM,aAAa,KAAK,oBAAoB,SAAS;AACrD,gBAAM,uBAAuB,KAAK,MAAO,aAAa,YAAa,GAAI;AAGvE,eAAK,YAAY,sBAAsB;AAAA,YACrC;AAAA,YACA,eAAe,KAAK;AAAA,YACpB,mBAAmB,KAAK;AAAA,YACxB,gBAAgB,KAAK,gBAAgB,kBAAA;AAAA,UAAkB,CACxD;AAAA,QACH;AAEA,aAAK,0BAA0B;AAAA,MACjC;AAAA,IACF;AAAA,IAEQ,uBAAuB,SAAwC;AACrE,UAAI,QAAQ,MAAM;AAEhB,YAAI,KAAK,QAAQ;AACf,eAAK,OAAO,QAAQ,KAAK,MAAM,QAAQ,KAAK,cAAc;AAC1D,eAAK,OAAO,SAAS,KAAK,MAAM,QAAQ,KAAK,eAAe;AAAA,QAC9D;AAGA,aAAK,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,cAAc;AACxD,aAAK,KAAK,SAAS,KAAK,MAAM,QAAQ,KAAK,eAAe;AAG1D,YAAI,KAAK,IAAI;AACX,eAAK,GAAG,SAAS,GAAG,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM;AAAA,QAC1D;AAEA,aAAK,SAAS,iCAAiC,KAAK,KAAK,QAAQ,MAAM,KAAK,KAAK,MAAM;AAAA,MACzF;AAAA,IACF;AAAA,IAEQ,sBAAsB,SAAuC;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS,UAAa,QAAQ,KAAK,UAAU,QAAW;AACvF,aAAK,gBAAgB,qBAAqB,QAAQ,KAAK,MAAM,QAAQ,KAAK,KAAK;AAAA,MACjF;AAAA,IACF;AAAA,IAEQ,2BAA2B,SAA4C;AAC7E,UAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS;AACxC,mBAAW,UAAU,QAAQ,KAAK,SAAS;AACzC,eAAK,gBAAgB,qBAAqB,OAAO,MAAM,OAAO,KAAK;AAAA,QACrE;AAGA,aAAK,gBAAgB,wBAAA;AACrB,aAAK,SAAS,2CAA2C;AAAA,MAC3D;AAAA,IACF;AAAA,IAEQ,mBAAmB,SAAoC;AAE7D,WAAK,SAAS,kBAAkB,QAAQ,IAAI;AAAA,IAC9C;AAAA,IAEQ,0BAA0B,SAA2C;AAE3E,WAAK,aAAa;AAAA,QAChB,aAAa,QAAQ,KAAK;AAAA,QAC1B,QAAQ,QAAQ,KAAK;AAAA,QACrB,OAAO,QAAQ,KAAK;AAAA,QACpB,eAAe,QAAQ,KAAK;AAAA,MAAA;AAI9B,WAAK,KAAK,QAAQ;AAAA,QAChB,GAAG,KAAK;AAAA,QACR,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAAA;AAAA,IAE5C;AAAA,IAEQ,uBAAuB,SAA8C;AAE3E,WAAK,YAAY,kBAAkB;AAAA,QACjC,iBAAiB,QAAQ,KAAK;AAAA,QAC9B,OAAO,QAAQ,KAAK;AAAA,QACpB,QAAQ,QAAQ,KAAK;AAAA,QACrB,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAGD,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA,IAEQ,uBAAuB,SAA8C;AAE3E,WAAK,YAAY,kBAAkB;AAAA,QACjC,aAAa,QAAQ,KAAK;AAAA,QAC1B,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAGD,aAAO,OAAO,KAAK,KAAK,OAAO,KAAK,YAAY,aAAa;AAAA,IAC/D;AAAA,IAEQ,wBAAwB,SAA+C;AAE7E,WAAK,YAAY,wBAAwB;AAAA,QACvC,GAAI,QAAQ,KAAK,mBAAmB,EAAE,iBAAiB,QAAQ,KAAK,gBAAA;AAAA,QACpE,GAAI,QAAQ,KAAK,YAAY,EAAE,UAAU,QAAQ,KAAK,SAAA;AAAA,QACtD,GAAI,QAAQ,KAAK,SAAS,EAAE,OAAO,QAAQ,KAAK,MAAA;AAAA,QAChD,GAAI,QAAQ,KAAK,UAAU,EAAE,QAAQ,QAAQ,KAAK,OAAA;AAAA,QAClD,GAAI,QAAQ,KAAK,cAAc,EAAE,YAAY,QAAQ,KAAK,WAAA;AAAA,QAC1D,WAAW,QAAQ,KAAK;AAAA,MAAA,CACzB;AAAA,IACH;AAAA,IAEQ,wBAAwB,SAAyC;AAEvE,WAAK,SAAS,uBAAuB,QAAQ,IAAI;AAAA,IACnD;AAAA,IAEQ,mBAAmB,SAA0C;AACnE,UAAI,QAAQ,QAAQ,QAAQ,KAAK,WAAW;AAEzC,aAAa,aAAa,QAAQ,KAAK,SAAS;AAAA,MACnD;AAAA,IACF;AAAA,IAEQ,kBAAwB;AAC9B,WAAK,YAAY;AACjB,WAAK,YAAY,YAAY,IAAA;AAC7B,WAAK,WAAW,KAAK;AACrB,WAAK,YAAA;AAAA,IACP;AAAA,IAEO,cAAoB;AACzB,UAAI,CAAC,KAAK,UAAW;AAErB,YAAM,cAAc,YAAY,IAAA;AAGhC,WAAK,kBAAkB,WAAA;AAGvB,WAAK,KAAK,MAAM,KAAK,kBAAkB,SAAS,KAAK,oBAAoB,KAAK,oBAAoB;AAGlG,UAAI,eAAe;AACnB,UAAI,KAAK,kBAAkB,QAAQ;AACjC,uBAAe,CAAC,KAAK;AACrB,aAAK,gBAAgB,CAAC,KAAK;AAAA,MAC7B;AAEA,UAAI,cAAc;AAChB,aAAK,KAAK,aAAa,cAAc,KAAK,YAAY;AACtD,aAAK,KAAK,QAAQ,cAAc,KAAK,aAAa;AAClD,aAAK,KAAK,aAAa,EAAE,KAAK;AAG9B,aAAK,wBAAwB,WAAW;AAExC,aAAK,WAAW;AAEhB,YAAI;AAEF,gBAAMA,kBAAkB,KAAa;AACrC,cAAIA,mBAAkB,OAAOA,oBAAmB,YAAY;AAC1D,YAAAA,gBAAe,KAAK,IAAI;AAAA,UAC1B;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,MAAM,iBAAiB,KAAK;AACpC,eAAK,YAAY,SAAS;AAAA,YACxB,SAAU,MAAgB;AAAA,YAC1B,MAAM;AAAA,YACN,OAAQ,MAAgB;AAAA,UAAA,CACzB;AAAA,QACH;AAAA,MACF;AAGA,WAAK,2BAA2B,WAAW;AAG3C,4BAAsB,MAAM,KAAK,aAAa;AAAA,IAChD;AAAA,IAEQ,YAAY,MAAc,MAAkB;AAClD,WAAK,YAAY;AAAA,QACf;AAAA,QACA,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,KAAK,KAAK;AAAA,QACrC,WAAW,KAAK,IAAA;AAAA,QAChB;AAAA,MAAA,CACD;AAAA,IACH;AAAA;AAAA,IAIQ,kBAAkB,SAAoB;AAC5C,WAAK,kBAAkB,kBAAkB,QAAQ,IAAI;AAAA,IACvD;AAAA,IAEQ,qBAAqB,SAAoB;AAC/C,WAAK,kBAAkB,qBAAqB,QAAQ,IAAI;AAAA,IAC1D;AAAA,IAEQ,kBAAkB,SAAoB;AAC5C,WAAK,kBAAkB,kBAAkB,QAAQ,IAAI;AAAA,IACvD;AAAA,IAEQ,yBAAyB,SAAoB;AACnD,WAAK,kBAAkB,sBAAsB,QAAQ,KAAK,OAAO;AAAA,IACnE;AAAA,EACF;ACniBA,QAAM,UAAU,IAAI,kBAAA;AAGpB,MAAI,iBAA+D;AAGnE,WAAS,aAAa,WAAyB;AAC7C,QAAI;AAEF,cAAQ,oBAAA;AAIR,YAAM,eAAe,YAAY;AAMjC,YAAM,gBAAgB,IAAI,SAAS,QAAQ,YAAY;AAEvD,uBAAiB,cAAc,QAAQ,IAAI;AAE1C,WAAa,iBAAiB;AAI/B,cAAQ,wBAAA;AAAA,IACV,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AACjD,WAAK,YAAY;AAAA,QACf,MAAM;AAAA,QACN,IAAI,eAAe,KAAK,IAAA,CAAK;AAAA,QAC7B,WAAW,KAAK,IAAA;AAAA,QAChB,MAAM;AAAA,UACJ,SAAS,qBAAsB,MAAgB,OAAO;AAAA,UACtD,MAAM;AAAA,QAAA;AAAA,MACR,CACD;AAAA,IACH;AAAA,EACF;AAGC,OAAa,eAAe;;"}
package/dist/index.d.ts CHANGED
@@ -336,6 +336,7 @@ export declare class VijiCore {
336
336
  private config;
337
337
  private currentAudioStream;
338
338
  private currentVideoStream;
339
+ private currentInteractionEnabled;
339
340
  private parameterGroups;
340
341
  private parameterValues;
341
342
  private parametersInitialized;
@@ -487,6 +488,18 @@ export declare class VijiCore {
487
488
  * Gets the current audio stream
488
489
  */
489
490
  getAudioStream(): MediaStream | null;
491
+ /**
492
+ * Gets the current video stream
493
+ */
494
+ getVideoStream(): MediaStream | null;
495
+ /**
496
+ * Enables or disables user interactions (mouse, keyboard, touch) at runtime
497
+ */
498
+ setInteractionEnabled(enabled: boolean): Promise<void>;
499
+ /**
500
+ * Gets the current interaction enabled state
501
+ */
502
+ getInteractionEnabled(): boolean;
490
503
  /**
491
504
  * Updates audio analysis configuration
492
505
  */
package/dist/index.js CHANGED
@@ -434,7 +434,7 @@ class IFrameManager {
434
434
  }
435
435
  function WorkerWrapper(options) {
436
436
  return new Worker(
437
- "" + new URL("assets/viji.worker-Cozsmke0.js", import.meta.url).href,
437
+ "" + new URL("assets/viji.worker-BWGhBqAc.js", import.meta.url).href,
438
438
  {
439
439
  name: options?.name
440
440
  }
@@ -1674,6 +1674,8 @@ class VijiCore {
1674
1674
  currentAudioStream = null;
1675
1675
  // Video stream management
1676
1676
  currentVideoStream = null;
1677
+ // Interaction state management
1678
+ currentInteractionEnabled;
1677
1679
  // Parameter system for Phase 2
1678
1680
  parameterGroups = /* @__PURE__ */ new Map();
1679
1681
  parameterValues = /* @__PURE__ */ new Map();
@@ -1706,6 +1708,7 @@ class VijiCore {
1706
1708
  noInputs: config.noInputs ?? false,
1707
1709
  allowUserInteraction: config.allowUserInteraction ?? true
1708
1710
  };
1711
+ this.currentInteractionEnabled = this.config.allowUserInteraction;
1709
1712
  this.debugLog(`VijiCore instance created: ${this.instanceId}`);
1710
1713
  }
1711
1714
  /**
@@ -1760,10 +1763,8 @@ class VijiCore {
1760
1763
  );
1761
1764
  await this.iframeManager.createSecureIFrame();
1762
1765
  const offscreenCanvas = await this.createCanvasWithRetry();
1763
- if (this.config.allowUserInteraction) {
1764
- this.interactionManager = new InteractionManager();
1765
- this.setupInteractionSystem();
1766
- }
1766
+ this.interactionManager = new InteractionManager();
1767
+ this.setupInteractionSystem();
1767
1768
  this.workerManager = new WorkerManager(
1768
1769
  this.config.sceneCode,
1769
1770
  offscreenCanvas
@@ -1868,7 +1869,7 @@ class VijiCore {
1868
1869
  this.workerManager.postMessage("touch-update", data);
1869
1870
  }
1870
1871
  });
1871
- this.iframeManager.setInteractionEnabled(true);
1872
+ this.iframeManager.setInteractionEnabled(this.currentInteractionEnabled);
1872
1873
  }
1873
1874
  /**
1874
1875
  * Sets up communication between components
@@ -2034,7 +2035,7 @@ class VijiCore {
2034
2035
  return {
2035
2036
  hasAudio: this.currentAudioStream !== null,
2036
2037
  hasVideo: this.currentVideoStream !== null,
2037
- hasInteraction: this.config.allowUserInteraction,
2038
+ hasInteraction: this.currentInteractionEnabled,
2038
2039
  hasGeneral: true
2039
2040
  // General parameters are always available
2040
2041
  };
@@ -2298,6 +2299,38 @@ class VijiCore {
2298
2299
  getAudioStream() {
2299
2300
  return this.currentAudioStream;
2300
2301
  }
2302
+ /**
2303
+ * Gets the current video stream
2304
+ */
2305
+ getVideoStream() {
2306
+ return this.currentVideoStream;
2307
+ }
2308
+ /**
2309
+ * Enables or disables user interactions (mouse, keyboard, touch) at runtime
2310
+ */
2311
+ async setInteractionEnabled(enabled) {
2312
+ if (this.isInitialized && !this.isInitializing) {
2313
+ this.validateReady();
2314
+ }
2315
+ const previouslyHadInteraction = this.currentInteractionEnabled;
2316
+ this.currentInteractionEnabled = enabled;
2317
+ if (this.iframeManager) {
2318
+ this.iframeManager.setInteractionEnabled(enabled);
2319
+ }
2320
+ if (this.workerManager) {
2321
+ this.workerManager.postMessage("interaction-enabled", { enabled });
2322
+ }
2323
+ if (previouslyHadInteraction !== enabled) {
2324
+ this.notifyCapabilitiesChange();
2325
+ }
2326
+ this.debugLog(`Interaction ${enabled ? "enabled" : "disabled"} (${this.instanceId})`);
2327
+ }
2328
+ /**
2329
+ * Gets the current interaction enabled state
2330
+ */
2331
+ getInteractionEnabled() {
2332
+ return this.currentInteractionEnabled;
2333
+ }
2301
2334
  /**
2302
2335
  * Updates audio analysis configuration
2303
2336
  */