@viji-dev/core 0.3.20 → 0.3.21

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
@@ -133,19 +133,8 @@ interface VijiCoreConfig {
133
133
 
134
134
  // Input streams
135
135
  audioStream?: MediaStream; // Audio input for analysis
136
- videoStream?: MediaStream; // Video input for analysis
137
-
138
- // Audio analysis configuration
139
- analysisConfig?: {
140
- fftSize?: number; // FFT size for frequency analysis (default: 2048)
141
- smoothing?: number; // Smoothing factor 0-1 (default: 0.8)
142
- frequencyBands?: FrequencyBand[]; // Custom frequency bands
143
- beatDetection?: boolean; // Enable beat detection
144
- onsetDetection?: boolean; // Enable onset detection
145
- };
146
-
147
- // Parameter system
148
- parameters?: ParameterGroup[]; // Initial parameter values
136
+ videoStream?: MediaStream; // Video input (main, CV enabled)
137
+ videoStreams?: MediaStream[]; // Additional video streams (no CV)
149
138
 
150
139
  // Feature toggles
151
140
  noInputs?: boolean; // Disable all input processing
@@ -1 +1 @@
1
- export const artistDtsP5 = "// Viji Artist API - Global Type Definitions\n// All types are placed inside declare global {} because this file uses export {}\n// for top-level await support, which makes it a module (where top-level declarations\n// would otherwise be module-scoped, not global).\n\ndeclare global {\n interface AudioAPI {\r\n isConnected: boolean;\r\n volume: {\r\n current: number;\r\n peak: number;\r\n smoothed: number;\r\n };\r\n bands: {\r\n low: number;\r\n lowMid: number;\r\n mid: number;\r\n highMid: number;\r\n high: number;\r\n lowSmoothed: number;\r\n lowMidSmoothed: number;\r\n midSmoothed: number;\r\n highMidSmoothed: number;\r\n highSmoothed: number;\r\n };\r\n beat: {\r\n kick: number;\r\n snare: number;\r\n hat: number;\r\n any: number;\r\n kickSmoothed: number;\r\n snareSmoothed: number;\r\n anySmoothed: number;\r\n triggers: {\r\n any: boolean;\r\n kick: boolean;\r\n snare: boolean;\r\n hat: boolean;\r\n };\r\n events: Array<{\r\n type: 'kick' | 'snare' | 'hat';\r\n time: number;\r\n strength: number;\r\n }>;\r\n bpm: number;\r\n phase: number;\r\n bar: number;\r\n confidence: number;\r\n isLocked: boolean;\r\n };\r\n spectral: {\r\n brightness: number;\r\n flatness: number;\r\n flux: number;\r\n };\r\n getFrequencyData: () => Uint8Array;\r\n getWaveform?: (samples?: number) => Float32Array;\r\n getFFT?: (bins?: number, scale?: 'linear' | 'log') => Float32Array;\r\n }\r\n\n interface CaptureFrameOptions {\r\n /** Output format: 'blob' for encoded image, 'bitmap' for GPU-friendly ImageBitmap */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for blob output (ignored for bitmap), e.g., 'image/png', 'image/jpeg', 'image/webp' */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - number: scale factor relative to current canvas size (e.g., 0.5 = 50%)\r\n * - { width, height }: exact output size; if aspect ratio differs from canvas,\r\n * the source is center-cropped to match the target aspect ratio before scaling\r\n */\r\n resolution?: number | {\r\n width: number;\r\n height: number;\r\n };\r\n }\r\n\n interface ColorConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ColorParameter {\r\n value: string;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation';\r\n\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²) */\r\n acceleration: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²) */\r\n accelerationIncludingGravity: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Rotation rate (degrees/second) */\r\n rotationRate: {\r\n alpha: number | null;\r\n beta: number | null;\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between updates (milliseconds) */\r\n interval: number;\r\n }\r\n\n interface DeviceOrientationData {\r\n /** Rotation around Z-axis (0-360 degrees, compass heading) */\r\n alpha: number | null;\r\n /** Rotation around X-axis (-180 to 180 degrees, front-to-back tilt) */\r\n beta: number | null;\r\n /** Rotation around Y-axis (-90 to 90 degrees, left-to-right tilt) */\r\n gamma: number | null;\r\n /** True if using magnetometer (compass) for absolute orientation */\r\n absolute: boolean;\r\n }\r\n\n interface DeviceSensorState {\r\n motion: DeviceMotionData | null;\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n interface DeviceState extends DeviceSensorState {\r\n /** Unique device identifier */\r\n id: string;\r\n /** User-friendly device name */\r\n name: string;\r\n /** Device camera video (null if not available) */\r\n video: VideoAPI | null;\r\n }\r\n\n interface FaceData {\r\n id: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n confidence: number;\r\n landmarks?: {\r\n x: number;\r\n y: number;\r\n z?: number;\r\n }[];\r\n expressions: {\r\n neutral: number;\r\n happy: number;\r\n sad: number;\r\n angry: number;\r\n surprised: number;\r\n disgusted: number;\r\n fearful: number;\r\n };\r\n headPose: {\r\n pitch: number;\r\n yaw: number;\r\n roll: number;\r\n };\r\n }\r\n\n type FrameRateMode = 'full' | 'half';\r\n\n interface FrequencyBand {\r\n name: string;\r\n min: number;\r\n max: number;\r\n }\r\n\n interface HandData {\r\n id: number;\r\n handedness: 'left' | 'right';\r\n confidence: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n }[];\r\n palm: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n fingers: {\r\n thumb: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n index: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n middle: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n ring: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n pinky: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n };\r\n gestures: {\r\n fist: number;\r\n openPalm: number;\r\n peace: number;\r\n thumbsUp: number;\r\n pointing: number;\r\n };\r\n }\r\n\n interface ImageConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ImageParameter {\r\n value: ImageBitmap | OffscreenCanvas | null;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface KeyboardAPI {\r\n isPressed(key: string): boolean;\r\n wasPressed(key: string): boolean;\r\n wasReleased(key: string): boolean;\r\n activeKeys: Set<string>;\r\n pressedThisFrame: Set<string>;\r\n releasedThisFrame: Set<string>;\r\n lastKeyPressed: string;\r\n lastKeyReleased: string;\r\n shift: boolean;\r\n ctrl: boolean;\r\n alt: boolean;\r\n meta: boolean;\r\n }\r\n\n interface MouseAPI {\r\n x: number;\r\n y: number;\r\n isInCanvas: boolean;\r\n isPressed: boolean;\r\n leftButton: boolean;\r\n rightButton: boolean;\r\n middleButton: boolean;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n /**\n * P5-compatible image object (lazy-loaded, auto-converted from .value)\n * Only available in P5 renderer mode. Use with p5.image() function.\n * Example: p5.image(myImage.p5, x, y)\n */\n p5?: {\n canvas: OffscreenCanvas; // P5.js looks for img.canvas || img.elt\n elt: OffscreenCanvas; // Fallback for compatibility\n width: number; // Logical width\n height: number; // Logical height\n };\n };\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDelta: number;\r\n wheelX: number;\r\n wheelY: number;\r\n wasPressed: boolean;\r\n wasReleased: boolean;\r\n wasMoved: boolean;\r\n }\r\n\n interface NumberConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface NumberParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n interface PoseData {\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n visibility: number;\r\n }[];\r\n face: {\r\n x: number;\r\n y: number;\r\n }[];\r\n torso: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n }\r\n\n type Resolution = {\r\n width: number;\r\n height: number;\r\n };\r\n\n interface SegmentationData {\r\n mask: Uint8Array;\r\n width: number;\r\n height: number;\r\n }\r\n\n interface SelectConfig {\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SelectParameter {\r\n value: string | number;\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface SliderConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SliderParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TextConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n maxLength?: number;\r\n }\r\n\n interface TextParameter {\r\n value: string;\r\n maxLength?: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface ToggleConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ToggleParameter {\r\n value: boolean;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TouchAPI {\r\n points: TouchPoint[];\r\n count: number;\r\n started: TouchPoint[];\r\n moved: TouchPoint[];\r\n ended: TouchPoint[];\r\n primary: TouchPoint | null;\r\n gestures: TouchGestureAPI;\r\n }\r\n\n interface TouchGestureAPI {\r\n isPinching: boolean;\r\n isRotating: boolean;\r\n isPanning: boolean;\r\n isTapping: boolean;\r\n pinchScale: number;\r\n pinchDelta: number;\r\n rotationAngle: number;\r\n rotationDelta: number;\r\n panDelta: {\r\n x: number;\r\n y: number;\r\n };\r\n tapCount: number;\r\n lastTapTime: number;\r\n tapPosition: {\r\n x: number;\r\n y: number;\r\n } | null;\r\n }\r\n\n interface TouchPoint {\r\n id: number;\r\n x: number;\r\n y: number;\r\n pressure: number;\r\n radius: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n deltaX: number;\r\n deltaY: number;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n isNew: boolean;\r\n isActive: boolean;\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.2.20\";\r\n\n interface VideoAPI {\r\n isConnected: boolean;\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n frameWidth: number;\r\n frameHeight: number;\r\n frameRate: number;\r\n getFrameData: () => ImageData | null;\r\n faces: FaceData[];\r\n hands: HandData[];\r\n pose: PoseData | null;\r\n segmentation: SegmentationData | null;\r\n cv: {\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n getActiveFeatures(): CVFeature[];\r\n isProcessing(): boolean;\r\n };\r\n }\r\n\n interface VijiAPI {\r\n canvas: OffscreenCanvas;\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n gl?: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n time: number;\r\n deltaTime: number;\r\n frameCount: number;\r\n fps: number;\r\n audio: AudioAPI;\r\n video: VideoAPI;\r\n streams: VideoAPI[];\r\n mouse: MouseAPI;\r\n keyboard: KeyboardAPI;\r\n touches: TouchAPI;\r\n device: DeviceSensorState;\r\n devices: DeviceState[];\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n color: (defaultValue: string, config: ColorConfig) => ColorParameter;\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\n useContext(type: 'webgl'): WebGLRenderingContext | WebGL2RenderingContext;\r\n }\r\n\n // Runtime global - the main viji object\n const viji: VijiAPI;\n \n // Function type aliases (artists define their own render/setup functions)\n type Render = (viji: VijiAPI) => void;\n type Setup = (viji: VijiAPI) => void;\n}\n\n// Module marker (enables top-level await in artist code)\nexport {};\n\n\n// ============================================================\n// VIJI + P5.JS HYBRID MODE\n// ============================================================\n// In Viji's P5 renderer, you don't use standard P5 patterns.\n// Instead, you define these Viji-specific functions:\n\n// P5-specific globals (augments the base declare global block)\ndeclare global {\n // P5 instance type for annotations\n type p5 = p5;\n \n // Type aliases for P5 function signatures (artists define their own functions)\n /**\n * P5 render function signature - called every frame\n * @param viji - Viji API (canvas, audio, video, parameters, etc.)\n * @param p5 - P5.js instance with all P5 methods\n */\n type P5Render = (viji: VijiAPI, p5: p5) => void;\n \n /**\n * P5 setup function signature - called once at initialization\n * @param viji - Viji API (canvas, audio, video, parameters, etc.)\n * @param p5 - P5.js instance with all P5 methods\n */\n type P5Setup = (viji: VijiAPI, p5: p5) => void;\n}\n\n// ============================================================\n// IMPORTANT NOTES\n// ============================================================\n// - Don't use: new p5(), preload(), draw(), or P5's setup()\n// - Viji manages the P5 instance lifecycle\n// - Access P5 methods through the 'p5' parameter: p5.rect(), p5.fill(), etc.\n// - Access Viji features through the 'viji' parameter: viji.audio, viji.mouse, etc.\n// - Define parameters at the top level (before setup/render functions)\n\n// ============================================================\n// P5.JS TYPES (namespace and instance methods)\n// ============================================================\n// This file was auto-generated. Please do not edit it.\n/// <reference path=\"./src/accessibility/describe.d.ts\" />\n/// <reference path=\"./src/accessibility/outputs.d.ts\" />\n/// <reference path=\"./src/color/creating_reading.d.ts\" />\n/// <reference path=\"./src/color/setting.d.ts\" />\n/// <reference path=\"./src/core/shape/2d_primitives.d.ts\" />\n/// <reference path=\"./src/core/shape/attributes.d.ts\" />\n/// <reference path=\"./src/core/shape/curves.d.ts\" />\n/// <reference path=\"./src/core/shape/vertex.d.ts\" />\n/// <reference path=\"./src/core/constants.d.ts\" />\n/// <reference path=\"./src/core/environment.d.ts\" />\n/// <reference path=\"./src/core/rendering.d.ts\" />\n/// <reference path=\"./src/core/structure.d.ts\" />\n/// <reference path=\"./src/core/transform.d.ts\" />\n/// <reference path=\"./src/data/local_storage.d.ts\" />\n/// <reference path=\"./src/data/p5.TypedDict.d.ts\" />\n/// <reference path=\"./src/dom/dom.d.ts\" />\n/// <reference path=\"./src/events/acceleration.d.ts\" />\n/// <reference path=\"./src/events/keyboard.d.ts\" />\n/// <reference path=\"./src/events/mouse.d.ts\" />\n/// <reference path=\"./src/events/touch.d.ts\" />\n/// <reference path=\"./src/image/image.d.ts\" />\n/// <reference path=\"./src/image/loading_displaying.d.ts\" />\n/// <reference path=\"./src/image/pixels.d.ts\" />\n/// <reference path=\"./src/io/files.d.ts\" />\n/// <reference path=\"./src/math/calculation.d.ts\" />\n/// <reference path=\"./src/math/math.d.ts\" />\n/// <reference path=\"./src/math/noise.d.ts\" />\n/// <reference path=\"./src/math/random.d.ts\" />\n/// <reference path=\"./src/math/trigonometry.d.ts\" />\n/// <reference path=\"./src/typography/attributes.d.ts\" />\n/// <reference path=\"./src/typography/loading_displaying.d.ts\" />\n/// <reference path=\"./src/utilities/array_functions.d.ts\" />\n/// <reference path=\"./src/utilities/conversion.d.ts\" />\n/// <reference path=\"./src/utilities/string_functions.d.ts\" />\n/// <reference path=\"./src/utilities/time_date.d.ts\" />\n/// <reference path=\"./src/webgl/3d_primitives.d.ts\" />\n/// <reference path=\"./src/webgl/interaction.d.ts\" />\n/// <reference path=\"./src/webgl/light.d.ts\" />\n/// <reference path=\"./src/webgl/loading.d.ts\" />\n/// <reference path=\"./src/webgl/material.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Camera.d.ts\" />\n/// <reference path=\"./src/webgl/p5.RendererGL.Immediate.d.ts\" />\n/// <reference path=\"./src/webgl/p5.RendererGL.d.ts\" />\n/// <reference path=\"./src/color/p5.Color.d.ts\" />\n/// <reference path=\"./src/core/p5.Element.d.ts\" />\n/// <reference path=\"./src/core/p5.Graphics.d.ts\" />\n/// <reference path=\"./src/image/p5.Image.d.ts\" />\n/// <reference path=\"./src/io/p5.Table.d.ts\" />\n/// <reference path=\"./src/io/p5.TableRow.d.ts\" />\n/// <reference path=\"./src/io/p5.XML.d.ts\" />\n/// <reference path=\"./src/math/p5.Vector.d.ts\" />\n/// <reference path=\"./src/typography/p5.Font.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Framebuffer.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Geometry.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Shader.d.ts\" />\n/// <reference path=\"./src/core/p5.Renderer.d.ts\" />\n/// <reference path=\"./literals.d.ts\" />\n/// <reference path=\"./constants.d.ts\" />\n= p5;\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface p5 extends p5.p5InstanceExtensions {}\n\ndeclare namespace p5 {\n type UNKNOWN_P5_CONSTANT = any;\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n interface p5InstanceExtensions {}\n}\n\n";
1
+ export const artistDtsP5 = "// Viji Artist API - Global Type Definitions\n// All types are placed inside declare global {} because this file uses export {}\n// for top-level await support, which makes it a module (where top-level declarations\n// would otherwise be module-scoped, not global).\n\ndeclare global {\n interface AudioAPI {\r\n isConnected: boolean;\r\n volume: {\r\n current: number;\r\n peak: number;\r\n smoothed: number;\r\n };\r\n bands: {\r\n low: number;\r\n lowMid: number;\r\n mid: number;\r\n highMid: number;\r\n high: number;\r\n lowSmoothed: number;\r\n lowMidSmoothed: number;\r\n midSmoothed: number;\r\n highMidSmoothed: number;\r\n highSmoothed: number;\r\n };\r\n beat: {\r\n kick: number;\r\n snare: number;\r\n hat: number;\r\n any: number;\r\n kickSmoothed: number;\r\n snareSmoothed: number;\r\n hatSmoothed: number;\r\n anySmoothed: number;\r\n triggers: {\r\n any: boolean;\r\n kick: boolean;\r\n snare: boolean;\r\n hat: boolean;\r\n };\r\n events: Array<{\r\n type: 'kick' | 'snare' | 'hat';\r\n time: number;\r\n strength: number;\r\n }>;\r\n bpm: number;\r\n confidence: number;\r\n isLocked: boolean;\r\n };\r\n spectral: {\r\n brightness: number;\r\n flatness: number;\r\n };\r\n getFrequencyData: () => Uint8Array;\r\n getWaveform: () => Float32Array;\r\n }\r\n\n interface CaptureFrameOptions {\r\n /** Output format: 'blob' for encoded image, 'bitmap' for GPU-friendly ImageBitmap */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for blob output (ignored for bitmap), e.g., 'image/png', 'image/jpeg', 'image/webp' */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - number: scale factor relative to current canvas size (e.g., 0.5 = 50%)\r\n * - { width, height }: exact output size; if aspect ratio differs from canvas,\r\n * the source is center-cropped to match the target aspect ratio before scaling\r\n */\r\n resolution?: number | {\r\n width: number;\r\n height: number;\r\n };\r\n }\r\n\n interface ColorConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ColorParameter {\r\n value: string;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation' | 'emotionDetection';\r\n\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²) */\r\n acceleration: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²) */\r\n accelerationIncludingGravity: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Rotation rate (degrees/second) */\r\n rotationRate: {\r\n alpha: number | null;\r\n beta: number | null;\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between updates (milliseconds) */\r\n interval: number;\r\n }\r\n\n interface DeviceOrientationData {\r\n /** Rotation around Z-axis (0-360 degrees, compass heading) */\r\n alpha: number | null;\r\n /** Rotation around X-axis (-180 to 180 degrees, front-to-back tilt) */\r\n beta: number | null;\r\n /** Rotation around Y-axis (-90 to 90 degrees, left-to-right tilt) */\r\n gamma: number | null;\r\n /** True if using magnetometer (compass) for absolute orientation */\r\n absolute: boolean;\r\n }\r\n\n interface DeviceSensorState {\r\n motion: DeviceMotionData | null;\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n interface DeviceState extends DeviceSensorState {\r\n /** Unique device identifier */\r\n id: string;\r\n /** User-friendly device name */\r\n name: string;\r\n /** Device camera video (null if not available) */\r\n video: VideoAPI | null;\r\n }\r\n\n interface FaceBlendshapes {\r\n browDownLeft: number;\r\n browDownRight: number;\r\n browInnerUp: number;\r\n browOuterUpLeft: number;\r\n browOuterUpRight: number;\r\n cheekPuff: number;\r\n cheekSquintLeft: number;\r\n cheekSquintRight: number;\r\n eyeBlinkLeft: number;\r\n eyeBlinkRight: number;\r\n eyeLookDownLeft: number;\r\n eyeLookDownRight: number;\r\n eyeLookInLeft: number;\r\n eyeLookInRight: number;\r\n eyeLookOutLeft: number;\r\n eyeLookOutRight: number;\r\n eyeLookUpLeft: number;\r\n eyeLookUpRight: number;\r\n eyeSquintLeft: number;\r\n eyeSquintRight: number;\r\n eyeWideLeft: number;\r\n eyeWideRight: number;\r\n jawForward: number;\r\n jawLeft: number;\r\n jawOpen: number;\r\n jawRight: number;\r\n mouthClose: number;\r\n mouthDimpleLeft: number;\r\n mouthDimpleRight: number;\r\n mouthFrownLeft: number;\r\n mouthFrownRight: number;\r\n mouthFunnel: number;\r\n mouthLeft: number;\r\n mouthLowerDownLeft: number;\r\n mouthLowerDownRight: number;\r\n mouthPressLeft: number;\r\n mouthPressRight: number;\r\n mouthPucker: number;\r\n mouthRight: number;\r\n mouthRollLower: number;\r\n mouthRollUpper: number;\r\n mouthShrugLower: number;\r\n mouthShrugUpper: number;\r\n mouthSmileLeft: number;\r\n mouthSmileRight: number;\r\n mouthStretchLeft: number;\r\n mouthStretchRight: number;\r\n mouthUpperUpLeft: number;\r\n mouthUpperUpRight: number;\r\n noseSneerLeft: number;\r\n noseSneerRight: number;\r\n tongueOut: number;\r\n }\r\n\n interface FaceData {\r\n id: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n center: {\r\n x: number;\r\n y: number;\r\n };\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z?: number;\r\n }[];\r\n expressions: {\r\n neutral: number;\r\n happy: number;\r\n sad: number;\r\n angry: number;\r\n surprised: number;\r\n disgusted: number;\r\n fearful: number;\r\n };\r\n headPose: {\r\n pitch: number;\r\n yaw: number;\r\n roll: number;\r\n };\r\n blendshapes: FaceBlendshapes;\r\n }\r\n\n type FrameRateMode = 'full' | 'half';\r\n\n interface FrequencyBand {\r\n name: string;\r\n min: number;\r\n max: number;\r\n }\r\n\n interface HandData {\r\n id: number;\r\n handedness: 'left' | 'right';\r\n confidence: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n }[];\r\n palm: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n fingers: {\r\n thumb: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n index: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n middle: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n ring: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n pinky: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n };\r\n gestures: {\r\n fist: number;\r\n openPalm: number;\r\n peace: number;\r\n thumbsUp: number;\r\n pointing: number;\r\n };\r\n }\r\n\n interface ImageConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ImageParameter {\r\n value: ImageBitmap | OffscreenCanvas | null;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface KeyboardAPI {\r\n isPressed(key: string): boolean;\r\n wasPressed(key: string): boolean;\r\n wasReleased(key: string): boolean;\r\n activeKeys: Set<string>;\r\n pressedThisFrame: Set<string>;\r\n releasedThisFrame: Set<string>;\r\n lastKeyPressed: string;\r\n lastKeyReleased: string;\r\n shift: boolean;\r\n ctrl: boolean;\r\n alt: boolean;\r\n meta: boolean;\r\n }\r\n\n interface MouseAPI {\r\n x: number;\r\n y: number;\r\n isInCanvas: boolean;\r\n isPressed: boolean;\r\n leftButton: boolean;\r\n rightButton: boolean;\r\n middleButton: boolean;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n /**\n * P5-compatible image object (lazy-loaded, auto-converted from .value)\n * Only available in P5 renderer mode. Use with p5.image() function.\n * Example: p5.image(myImage.p5, x, y)\n */\n p5?: {\n canvas: OffscreenCanvas; // P5.js looks for img.canvas || img.elt\n elt: OffscreenCanvas; // Fallback for compatibility\n width: number; // Logical width\n height: number; // Logical height\n };\n };\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDelta: number;\r\n wheelX: number;\r\n wheelY: number;\r\n wasPressed: boolean;\r\n wasReleased: boolean;\r\n wasMoved: boolean;\r\n }\r\n\n interface NumberConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface NumberParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n interface PoseData {\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n visibility: number;\r\n }[];\r\n face: {\r\n x: number;\r\n y: number;\r\n }[];\r\n torso: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n }\r\n\n type Resolution = {\r\n width: number;\r\n height: number;\r\n };\r\n\n interface SegmentationData {\r\n mask: Uint8Array;\r\n width: number;\r\n height: number;\r\n }\r\n\n interface SelectConfig {\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SelectParameter {\r\n value: string | number;\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface SliderConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SliderParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TextConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n maxLength?: number;\r\n }\r\n\n interface TextParameter {\r\n value: string;\r\n maxLength?: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface ToggleConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ToggleParameter {\r\n value: boolean;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TouchAPI {\r\n points: TouchPoint[];\r\n count: number;\r\n started: TouchPoint[];\r\n moved: TouchPoint[];\r\n ended: TouchPoint[];\r\n primary: TouchPoint | null;\r\n gestures: TouchGestureAPI;\r\n }\r\n\n interface TouchGestureAPI {\r\n isPinching: boolean;\r\n isRotating: boolean;\r\n isPanning: boolean;\r\n isTapping: boolean;\r\n pinchScale: number;\r\n pinchDelta: number;\r\n rotationAngle: number;\r\n rotationDelta: number;\r\n panDelta: {\r\n x: number;\r\n y: number;\r\n };\r\n tapCount: number;\r\n lastTapTime: number;\r\n tapPosition: {\r\n x: number;\r\n y: number;\r\n } | null;\r\n }\r\n\n interface TouchPoint {\r\n id: number;\r\n x: number;\r\n y: number;\r\n pressure: number;\r\n radius: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n deltaX: number;\r\n deltaY: number;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n isNew: boolean;\r\n isActive: boolean;\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.2.20\";\r\n\n interface VideoAPI {\r\n isConnected: boolean;\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n frameWidth: number;\r\n frameHeight: number;\r\n frameRate: number;\r\n getFrameData: () => ImageData | null;\r\n faces: FaceData[];\r\n hands: HandData[];\r\n pose: PoseData | null;\r\n segmentation: SegmentationData | null;\r\n cv: {\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n enableEmotionDetection(enabled: boolean): Promise<void>;\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n getActiveFeatures(): CVFeature[];\r\n isProcessing(): boolean;\r\n };\r\n }\r\n\n interface VijiAPI {\r\n canvas: OffscreenCanvas;\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n gl?: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n time: number;\r\n deltaTime: number;\r\n frameCount: number;\r\n fps: number;\r\n audio: AudioAPI;\r\n video: VideoAPI;\r\n streams: VideoAPI[];\r\n mouse: MouseAPI;\r\n keyboard: KeyboardAPI;\r\n touches: TouchAPI;\r\n device: DeviceSensorState;\r\n devices: DeviceState[];\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n color: (defaultValue: string, config: ColorConfig) => ColorParameter;\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\n useContext(type: 'webgl'): WebGLRenderingContext | WebGL2RenderingContext;\r\n }\r\n\n // Runtime global - the main viji object\n const viji: VijiAPI;\n \n // Function type aliases (artists define their own render/setup functions)\n type Render = (viji: VijiAPI) => void;\n type Setup = (viji: VijiAPI) => void;\n}\n\n// Module marker (enables top-level await in artist code)\nexport {};\n\n\n// ============================================================\n// VIJI + P5.JS HYBRID MODE\n// ============================================================\n// In Viji's P5 renderer, you don't use standard P5 patterns.\n// Instead, you define these Viji-specific functions:\n\n// P5-specific globals (augments the base declare global block)\ndeclare global {\n // P5 instance type for annotations\n type p5 = p5;\n \n // Type aliases for P5 function signatures (artists define their own functions)\n /**\n * P5 render function signature - called every frame\n * @param viji - Viji API (canvas, audio, video, parameters, etc.)\n * @param p5 - P5.js instance with all P5 methods\n */\n type P5Render = (viji: VijiAPI, p5: p5) => void;\n \n /**\n * P5 setup function signature - called once at initialization\n * @param viji - Viji API (canvas, audio, video, parameters, etc.)\n * @param p5 - P5.js instance with all P5 methods\n */\n type P5Setup = (viji: VijiAPI, p5: p5) => void;\n}\n\n// ============================================================\n// IMPORTANT NOTES\n// ============================================================\n// - Don't use: new p5(), preload(), draw(), or P5's setup()\n// - Viji manages the P5 instance lifecycle\n// - Access P5 methods through the 'p5' parameter: p5.rect(), p5.fill(), etc.\n// - Access Viji features through the 'viji' parameter: viji.audio, viji.mouse, etc.\n// - Define parameters at the top level (before setup/render functions)\n\n// ============================================================\n// P5.JS TYPES (namespace and instance methods)\n// ============================================================\n// This file was auto-generated. Please do not edit it.\n/// <reference path=\"./src/accessibility/describe.d.ts\" />\n/// <reference path=\"./src/accessibility/outputs.d.ts\" />\n/// <reference path=\"./src/color/creating_reading.d.ts\" />\n/// <reference path=\"./src/color/setting.d.ts\" />\n/// <reference path=\"./src/core/shape/2d_primitives.d.ts\" />\n/// <reference path=\"./src/core/shape/attributes.d.ts\" />\n/// <reference path=\"./src/core/shape/curves.d.ts\" />\n/// <reference path=\"./src/core/shape/vertex.d.ts\" />\n/// <reference path=\"./src/core/constants.d.ts\" />\n/// <reference path=\"./src/core/environment.d.ts\" />\n/// <reference path=\"./src/core/rendering.d.ts\" />\n/// <reference path=\"./src/core/structure.d.ts\" />\n/// <reference path=\"./src/core/transform.d.ts\" />\n/// <reference path=\"./src/data/local_storage.d.ts\" />\n/// <reference path=\"./src/data/p5.TypedDict.d.ts\" />\n/// <reference path=\"./src/dom/dom.d.ts\" />\n/// <reference path=\"./src/events/acceleration.d.ts\" />\n/// <reference path=\"./src/events/keyboard.d.ts\" />\n/// <reference path=\"./src/events/mouse.d.ts\" />\n/// <reference path=\"./src/events/touch.d.ts\" />\n/// <reference path=\"./src/image/image.d.ts\" />\n/// <reference path=\"./src/image/loading_displaying.d.ts\" />\n/// <reference path=\"./src/image/pixels.d.ts\" />\n/// <reference path=\"./src/io/files.d.ts\" />\n/// <reference path=\"./src/math/calculation.d.ts\" />\n/// <reference path=\"./src/math/math.d.ts\" />\n/// <reference path=\"./src/math/noise.d.ts\" />\n/// <reference path=\"./src/math/random.d.ts\" />\n/// <reference path=\"./src/math/trigonometry.d.ts\" />\n/// <reference path=\"./src/typography/attributes.d.ts\" />\n/// <reference path=\"./src/typography/loading_displaying.d.ts\" />\n/// <reference path=\"./src/utilities/array_functions.d.ts\" />\n/// <reference path=\"./src/utilities/conversion.d.ts\" />\n/// <reference path=\"./src/utilities/string_functions.d.ts\" />\n/// <reference path=\"./src/utilities/time_date.d.ts\" />\n/// <reference path=\"./src/webgl/3d_primitives.d.ts\" />\n/// <reference path=\"./src/webgl/interaction.d.ts\" />\n/// <reference path=\"./src/webgl/light.d.ts\" />\n/// <reference path=\"./src/webgl/loading.d.ts\" />\n/// <reference path=\"./src/webgl/material.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Camera.d.ts\" />\n/// <reference path=\"./src/webgl/p5.RendererGL.Immediate.d.ts\" />\n/// <reference path=\"./src/webgl/p5.RendererGL.d.ts\" />\n/// <reference path=\"./src/color/p5.Color.d.ts\" />\n/// <reference path=\"./src/core/p5.Element.d.ts\" />\n/// <reference path=\"./src/core/p5.Graphics.d.ts\" />\n/// <reference path=\"./src/image/p5.Image.d.ts\" />\n/// <reference path=\"./src/io/p5.Table.d.ts\" />\n/// <reference path=\"./src/io/p5.TableRow.d.ts\" />\n/// <reference path=\"./src/io/p5.XML.d.ts\" />\n/// <reference path=\"./src/math/p5.Vector.d.ts\" />\n/// <reference path=\"./src/typography/p5.Font.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Framebuffer.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Geometry.d.ts\" />\n/// <reference path=\"./src/webgl/p5.Shader.d.ts\" />\n/// <reference path=\"./src/core/p5.Renderer.d.ts\" />\n/// <reference path=\"./literals.d.ts\" />\n/// <reference path=\"./constants.d.ts\" />\n= p5;\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface p5 extends p5.p5InstanceExtensions {}\n\ndeclare namespace p5 {\n type UNKNOWN_P5_CONSTANT = any;\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n interface p5InstanceExtensions {}\n}\n\n";
@@ -1 +1 @@
1
- export const artistDts = "// Viji Artist API - Global Type Definitions\n// All types are placed inside declare global {} because this file uses export {}\n// for top-level await support, which makes it a module (where top-level declarations\n// would otherwise be module-scoped, not global).\n\ndeclare global {\n interface AudioAPI {\r\n isConnected: boolean;\r\n volume: {\r\n current: number;\r\n peak: number;\r\n smoothed: number;\r\n };\r\n bands: {\r\n low: number;\r\n lowMid: number;\r\n mid: number;\r\n highMid: number;\r\n high: number;\r\n lowSmoothed: number;\r\n lowMidSmoothed: number;\r\n midSmoothed: number;\r\n highMidSmoothed: number;\r\n highSmoothed: number;\r\n };\r\n beat: {\r\n kick: number;\r\n snare: number;\r\n hat: number;\r\n any: number;\r\n kickSmoothed: number;\r\n snareSmoothed: number;\r\n anySmoothed: number;\r\n triggers: {\r\n any: boolean;\r\n kick: boolean;\r\n snare: boolean;\r\n hat: boolean;\r\n };\r\n events: Array<{\r\n type: 'kick' | 'snare' | 'hat';\r\n time: number;\r\n strength: number;\r\n }>;\r\n bpm: number;\r\n phase: number;\r\n bar: number;\r\n confidence: number;\r\n isLocked: boolean;\r\n };\r\n spectral: {\r\n brightness: number;\r\n flatness: number;\r\n flux: number;\r\n };\r\n getFrequencyData: () => Uint8Array;\r\n getWaveform?: (samples?: number) => Float32Array;\r\n getFFT?: (bins?: number, scale?: 'linear' | 'log') => Float32Array;\r\n }\r\n\n interface CaptureFrameOptions {\r\n /** Output format: 'blob' for encoded image, 'bitmap' for GPU-friendly ImageBitmap */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for blob output (ignored for bitmap), e.g., 'image/png', 'image/jpeg', 'image/webp' */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - number: scale factor relative to current canvas size (e.g., 0.5 = 50%)\r\n * - { width, height }: exact output size; if aspect ratio differs from canvas,\r\n * the source is center-cropped to match the target aspect ratio before scaling\r\n */\r\n resolution?: number | {\r\n width: number;\r\n height: number;\r\n };\r\n }\r\n\n interface ColorConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ColorParameter {\r\n value: string;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation';\r\n\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²) */\r\n acceleration: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²) */\r\n accelerationIncludingGravity: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Rotation rate (degrees/second) */\r\n rotationRate: {\r\n alpha: number | null;\r\n beta: number | null;\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between updates (milliseconds) */\r\n interval: number;\r\n }\r\n\n interface DeviceOrientationData {\r\n /** Rotation around Z-axis (0-360 degrees, compass heading) */\r\n alpha: number | null;\r\n /** Rotation around X-axis (-180 to 180 degrees, front-to-back tilt) */\r\n beta: number | null;\r\n /** Rotation around Y-axis (-90 to 90 degrees, left-to-right tilt) */\r\n gamma: number | null;\r\n /** True if using magnetometer (compass) for absolute orientation */\r\n absolute: boolean;\r\n }\r\n\n interface DeviceSensorState {\r\n motion: DeviceMotionData | null;\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n interface DeviceState extends DeviceSensorState {\r\n /** Unique device identifier */\r\n id: string;\r\n /** User-friendly device name */\r\n name: string;\r\n /** Device camera video (null if not available) */\r\n video: VideoAPI | null;\r\n }\r\n\n interface FaceData {\r\n id: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n confidence: number;\r\n landmarks?: {\r\n x: number;\r\n y: number;\r\n z?: number;\r\n }[];\r\n expressions: {\r\n neutral: number;\r\n happy: number;\r\n sad: number;\r\n angry: number;\r\n surprised: number;\r\n disgusted: number;\r\n fearful: number;\r\n };\r\n headPose: {\r\n pitch: number;\r\n yaw: number;\r\n roll: number;\r\n };\r\n }\r\n\n type FrameRateMode = 'full' | 'half';\r\n\n interface FrequencyBand {\r\n name: string;\r\n min: number;\r\n max: number;\r\n }\r\n\n interface HandData {\r\n id: number;\r\n handedness: 'left' | 'right';\r\n confidence: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n }[];\r\n palm: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n fingers: {\r\n thumb: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n index: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n middle: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n ring: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n pinky: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n };\r\n gestures: {\r\n fist: number;\r\n openPalm: number;\r\n peace: number;\r\n thumbsUp: number;\r\n pointing: number;\r\n };\r\n }\r\n\n interface ImageConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ImageParameter {\r\n value: ImageBitmap | OffscreenCanvas | null;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface KeyboardAPI {\r\n isPressed(key: string): boolean;\r\n wasPressed(key: string): boolean;\r\n wasReleased(key: string): boolean;\r\n activeKeys: Set<string>;\r\n pressedThisFrame: Set<string>;\r\n releasedThisFrame: Set<string>;\r\n lastKeyPressed: string;\r\n lastKeyReleased: string;\r\n shift: boolean;\r\n ctrl: boolean;\r\n alt: boolean;\r\n meta: boolean;\r\n }\r\n\n interface MouseAPI {\r\n x: number;\r\n y: number;\r\n isInCanvas: boolean;\r\n isPressed: boolean;\r\n leftButton: boolean;\r\n rightButton: boolean;\r\n middleButton: boolean;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDelta: number;\r\n wheelX: number;\r\n wheelY: number;\r\n wasPressed: boolean;\r\n wasReleased: boolean;\r\n wasMoved: boolean;\r\n }\r\n\n interface NumberConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface NumberParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n interface PoseData {\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n visibility: number;\r\n }[];\r\n face: {\r\n x: number;\r\n y: number;\r\n }[];\r\n torso: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n }\r\n\n type Resolution = {\r\n width: number;\r\n height: number;\r\n };\r\n\n interface SegmentationData {\r\n mask: Uint8Array;\r\n width: number;\r\n height: number;\r\n }\r\n\n interface SelectConfig {\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SelectParameter {\r\n value: string | number;\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface SliderConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SliderParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TextConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n maxLength?: number;\r\n }\r\n\n interface TextParameter {\r\n value: string;\r\n maxLength?: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface ToggleConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ToggleParameter {\r\n value: boolean;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TouchAPI {\r\n points: TouchPoint[];\r\n count: number;\r\n started: TouchPoint[];\r\n moved: TouchPoint[];\r\n ended: TouchPoint[];\r\n primary: TouchPoint | null;\r\n gestures: TouchGestureAPI;\r\n }\r\n\n interface TouchGestureAPI {\r\n isPinching: boolean;\r\n isRotating: boolean;\r\n isPanning: boolean;\r\n isTapping: boolean;\r\n pinchScale: number;\r\n pinchDelta: number;\r\n rotationAngle: number;\r\n rotationDelta: number;\r\n panDelta: {\r\n x: number;\r\n y: number;\r\n };\r\n tapCount: number;\r\n lastTapTime: number;\r\n tapPosition: {\r\n x: number;\r\n y: number;\r\n } | null;\r\n }\r\n\n interface TouchPoint {\r\n id: number;\r\n x: number;\r\n y: number;\r\n pressure: number;\r\n radius: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n deltaX: number;\r\n deltaY: number;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n isNew: boolean;\r\n isActive: boolean;\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.2.20\";\r\n\n interface VideoAPI {\r\n isConnected: boolean;\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n frameWidth: number;\r\n frameHeight: number;\r\n frameRate: number;\r\n getFrameData: () => ImageData | null;\r\n faces: FaceData[];\r\n hands: HandData[];\r\n pose: PoseData | null;\r\n segmentation: SegmentationData | null;\r\n cv: {\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n getActiveFeatures(): CVFeature[];\r\n isProcessing(): boolean;\r\n };\r\n }\r\n\n interface VijiAPI {\r\n canvas: OffscreenCanvas;\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n gl?: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n time: number;\r\n deltaTime: number;\r\n frameCount: number;\r\n fps: number;\r\n audio: AudioAPI;\r\n video: VideoAPI;\r\n streams: VideoAPI[];\r\n mouse: MouseAPI;\r\n keyboard: KeyboardAPI;\r\n touches: TouchAPI;\r\n device: DeviceSensorState;\r\n devices: DeviceState[];\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n color: (defaultValue: string, config: ColorConfig) => ColorParameter;\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\n useContext(type: 'webgl'): WebGLRenderingContext | WebGL2RenderingContext;\r\n }\r\n\n // Runtime global - the main viji object\n const viji: VijiAPI;\n \n // Function type aliases (artists define their own render/setup functions)\n type Render = (viji: VijiAPI) => void;\n type Setup = (viji: VijiAPI) => void;\n}\n\n// Module marker (enables top-level await in artist code)\nexport {};\n";
1
+ export const artistDts = "// Viji Artist API - Global Type Definitions\n// All types are placed inside declare global {} because this file uses export {}\n// for top-level await support, which makes it a module (where top-level declarations\n// would otherwise be module-scoped, not global).\n\ndeclare global {\n interface AudioAPI {\r\n isConnected: boolean;\r\n volume: {\r\n current: number;\r\n peak: number;\r\n smoothed: number;\r\n };\r\n bands: {\r\n low: number;\r\n lowMid: number;\r\n mid: number;\r\n highMid: number;\r\n high: number;\r\n lowSmoothed: number;\r\n lowMidSmoothed: number;\r\n midSmoothed: number;\r\n highMidSmoothed: number;\r\n highSmoothed: number;\r\n };\r\n beat: {\r\n kick: number;\r\n snare: number;\r\n hat: number;\r\n any: number;\r\n kickSmoothed: number;\r\n snareSmoothed: number;\r\n hatSmoothed: number;\r\n anySmoothed: number;\r\n triggers: {\r\n any: boolean;\r\n kick: boolean;\r\n snare: boolean;\r\n hat: boolean;\r\n };\r\n events: Array<{\r\n type: 'kick' | 'snare' | 'hat';\r\n time: number;\r\n strength: number;\r\n }>;\r\n bpm: number;\r\n confidence: number;\r\n isLocked: boolean;\r\n };\r\n spectral: {\r\n brightness: number;\r\n flatness: number;\r\n };\r\n getFrequencyData: () => Uint8Array;\r\n getWaveform: () => Float32Array;\r\n }\r\n\n interface CaptureFrameOptions {\r\n /** Output format: 'blob' for encoded image, 'bitmap' for GPU-friendly ImageBitmap */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for blob output (ignored for bitmap), e.g., 'image/png', 'image/jpeg', 'image/webp' */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - number: scale factor relative to current canvas size (e.g., 0.5 = 50%)\r\n * - { width, height }: exact output size; if aspect ratio differs from canvas,\r\n * the source is center-cropped to match the target aspect ratio before scaling\r\n */\r\n resolution?: number | {\r\n width: number;\r\n height: number;\r\n };\r\n }\r\n\n interface ColorConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ColorParameter {\r\n value: string;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation' | 'emotionDetection';\r\n\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²) */\r\n acceleration: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²) */\r\n accelerationIncludingGravity: {\r\n x: number | null;\r\n y: number | null;\r\n z: number | null;\r\n } | null;\r\n /** Rotation rate (degrees/second) */\r\n rotationRate: {\r\n alpha: number | null;\r\n beta: number | null;\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between updates (milliseconds) */\r\n interval: number;\r\n }\r\n\n interface DeviceOrientationData {\r\n /** Rotation around Z-axis (0-360 degrees, compass heading) */\r\n alpha: number | null;\r\n /** Rotation around X-axis (-180 to 180 degrees, front-to-back tilt) */\r\n beta: number | null;\r\n /** Rotation around Y-axis (-90 to 90 degrees, left-to-right tilt) */\r\n gamma: number | null;\r\n /** True if using magnetometer (compass) for absolute orientation */\r\n absolute: boolean;\r\n }\r\n\n interface DeviceSensorState {\r\n motion: DeviceMotionData | null;\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n interface DeviceState extends DeviceSensorState {\r\n /** Unique device identifier */\r\n id: string;\r\n /** User-friendly device name */\r\n name: string;\r\n /** Device camera video (null if not available) */\r\n video: VideoAPI | null;\r\n }\r\n\n interface FaceBlendshapes {\r\n browDownLeft: number;\r\n browDownRight: number;\r\n browInnerUp: number;\r\n browOuterUpLeft: number;\r\n browOuterUpRight: number;\r\n cheekPuff: number;\r\n cheekSquintLeft: number;\r\n cheekSquintRight: number;\r\n eyeBlinkLeft: number;\r\n eyeBlinkRight: number;\r\n eyeLookDownLeft: number;\r\n eyeLookDownRight: number;\r\n eyeLookInLeft: number;\r\n eyeLookInRight: number;\r\n eyeLookOutLeft: number;\r\n eyeLookOutRight: number;\r\n eyeLookUpLeft: number;\r\n eyeLookUpRight: number;\r\n eyeSquintLeft: number;\r\n eyeSquintRight: number;\r\n eyeWideLeft: number;\r\n eyeWideRight: number;\r\n jawForward: number;\r\n jawLeft: number;\r\n jawOpen: number;\r\n jawRight: number;\r\n mouthClose: number;\r\n mouthDimpleLeft: number;\r\n mouthDimpleRight: number;\r\n mouthFrownLeft: number;\r\n mouthFrownRight: number;\r\n mouthFunnel: number;\r\n mouthLeft: number;\r\n mouthLowerDownLeft: number;\r\n mouthLowerDownRight: number;\r\n mouthPressLeft: number;\r\n mouthPressRight: number;\r\n mouthPucker: number;\r\n mouthRight: number;\r\n mouthRollLower: number;\r\n mouthRollUpper: number;\r\n mouthShrugLower: number;\r\n mouthShrugUpper: number;\r\n mouthSmileLeft: number;\r\n mouthSmileRight: number;\r\n mouthStretchLeft: number;\r\n mouthStretchRight: number;\r\n mouthUpperUpLeft: number;\r\n mouthUpperUpRight: number;\r\n noseSneerLeft: number;\r\n noseSneerRight: number;\r\n tongueOut: number;\r\n }\r\n\n interface FaceData {\r\n id: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n center: {\r\n x: number;\r\n y: number;\r\n };\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z?: number;\r\n }[];\r\n expressions: {\r\n neutral: number;\r\n happy: number;\r\n sad: number;\r\n angry: number;\r\n surprised: number;\r\n disgusted: number;\r\n fearful: number;\r\n };\r\n headPose: {\r\n pitch: number;\r\n yaw: number;\r\n roll: number;\r\n };\r\n blendshapes: FaceBlendshapes;\r\n }\r\n\n type FrameRateMode = 'full' | 'half';\r\n\n interface FrequencyBand {\r\n name: string;\r\n min: number;\r\n max: number;\r\n }\r\n\n interface HandData {\r\n id: number;\r\n handedness: 'left' | 'right';\r\n confidence: number;\r\n bounds: {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n };\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n }[];\r\n palm: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n fingers: {\r\n thumb: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n index: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n middle: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n ring: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n pinky: {\r\n tip: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n };\r\n extended: boolean;\r\n };\r\n };\r\n gestures: {\r\n fist: number;\r\n openPalm: number;\r\n peace: number;\r\n thumbsUp: number;\r\n pointing: number;\r\n };\r\n }\r\n\n interface ImageConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ImageParameter {\r\n value: ImageBitmap | OffscreenCanvas | null;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface KeyboardAPI {\r\n isPressed(key: string): boolean;\r\n wasPressed(key: string): boolean;\r\n wasReleased(key: string): boolean;\r\n activeKeys: Set<string>;\r\n pressedThisFrame: Set<string>;\r\n releasedThisFrame: Set<string>;\r\n lastKeyPressed: string;\r\n lastKeyReleased: string;\r\n shift: boolean;\r\n ctrl: boolean;\r\n alt: boolean;\r\n meta: boolean;\r\n }\r\n\n interface MouseAPI {\r\n x: number;\r\n y: number;\r\n isInCanvas: boolean;\r\n isPressed: boolean;\r\n leftButton: boolean;\r\n rightButton: boolean;\r\n middleButton: boolean;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n deltaX: number;\r\n deltaY: number;\r\n wheelDelta: number;\r\n wheelX: number;\r\n wheelY: number;\r\n wasPressed: boolean;\r\n wasReleased: boolean;\r\n wasMoved: boolean;\r\n }\r\n\n interface NumberConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface NumberParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n interface PoseData {\r\n confidence: number;\r\n landmarks: {\r\n x: number;\r\n y: number;\r\n z: number;\r\n visibility: number;\r\n }[];\r\n face: {\r\n x: number;\r\n y: number;\r\n }[];\r\n torso: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightArm: {\r\n x: number;\r\n y: number;\r\n }[];\r\n leftLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n rightLeg: {\r\n x: number;\r\n y: number;\r\n }[];\r\n }\r\n\n type Resolution = {\r\n width: number;\r\n height: number;\r\n };\r\n\n interface SegmentationData {\r\n mask: Uint8Array;\r\n width: number;\r\n height: number;\r\n }\r\n\n interface SelectConfig {\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SelectParameter {\r\n value: string | number;\r\n options: string[] | number[];\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface SliderConfig {\r\n min?: number;\r\n max?: number;\r\n step?: number;\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface SliderParameter {\r\n value: number;\r\n min: number;\r\n max: number;\r\n step: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TextConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n maxLength?: number;\r\n }\r\n\n interface TextParameter {\r\n value: string;\r\n maxLength?: number;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface ToggleConfig {\r\n label: string;\r\n description?: string;\r\n group?: string;\r\n category?: ParameterCategory;\r\n }\r\n\n interface ToggleParameter {\r\n value: boolean;\r\n label: string;\r\n description?: string;\r\n group: string;\r\n category: ParameterCategory;\r\n }\r\n\n interface TouchAPI {\r\n points: TouchPoint[];\r\n count: number;\r\n started: TouchPoint[];\r\n moved: TouchPoint[];\r\n ended: TouchPoint[];\r\n primary: TouchPoint | null;\r\n gestures: TouchGestureAPI;\r\n }\r\n\n interface TouchGestureAPI {\r\n isPinching: boolean;\r\n isRotating: boolean;\r\n isPanning: boolean;\r\n isTapping: boolean;\r\n pinchScale: number;\r\n pinchDelta: number;\r\n rotationAngle: number;\r\n rotationDelta: number;\r\n panDelta: {\r\n x: number;\r\n y: number;\r\n };\r\n tapCount: number;\r\n lastTapTime: number;\r\n tapPosition: {\r\n x: number;\r\n y: number;\r\n } | null;\r\n }\r\n\n interface TouchPoint {\r\n id: number;\r\n x: number;\r\n y: number;\r\n pressure: number;\r\n radius: number;\r\n radiusX: number;\r\n radiusY: number;\r\n rotationAngle: number;\r\n force: number;\r\n deltaX: number;\r\n deltaY: number;\r\n velocity: {\r\n x: number;\r\n y: number;\r\n };\r\n isNew: boolean;\r\n isActive: boolean;\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.2.20\";\r\n\n interface VideoAPI {\r\n isConnected: boolean;\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n frameWidth: number;\r\n frameHeight: number;\r\n frameRate: number;\r\n getFrameData: () => ImageData | null;\r\n faces: FaceData[];\r\n hands: HandData[];\r\n pose: PoseData | null;\r\n segmentation: SegmentationData | null;\r\n cv: {\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n enableEmotionDetection(enabled: boolean): Promise<void>;\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n getActiveFeatures(): CVFeature[];\r\n isProcessing(): boolean;\r\n };\r\n }\r\n\n interface VijiAPI {\r\n canvas: OffscreenCanvas;\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n gl?: WebGL2RenderingContext;\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n time: number;\r\n deltaTime: number;\r\n frameCount: number;\r\n fps: number;\r\n audio: AudioAPI;\r\n video: VideoAPI;\r\n streams: VideoAPI[];\r\n mouse: MouseAPI;\r\n keyboard: KeyboardAPI;\r\n touches: TouchAPI;\r\n device: DeviceSensorState;\r\n devices: DeviceState[];\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n color: (defaultValue: string, config: ColorConfig) => ColorParameter;\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\n useContext(type: 'webgl'): WebGLRenderingContext | WebGL2RenderingContext;\r\n }\r\n\n // Runtime global - the main viji object\n const viji: VijiAPI;\n \n // Function type aliases (artists define their own render/setup functions)\n type Render = (viji: VijiAPI) => void;\n type Setup = (viji: VijiAPI) => void;\n}\n\n// Module marker (enables top-level await in artist code)\nexport {};\n";
@@ -30,6 +30,7 @@ declare global {
30
30
  any: number;
31
31
  kickSmoothed: number;
32
32
  snareSmoothed: number;
33
+ hatSmoothed: number;
33
34
  anySmoothed: number;
34
35
  triggers: {
35
36
  any: boolean;
@@ -43,19 +44,15 @@ declare global {
43
44
  strength: number;
44
45
  }>;
45
46
  bpm: number;
46
- phase: number;
47
- bar: number;
48
47
  confidence: number;
49
48
  isLocked: boolean;
50
49
  };
51
50
  spectral: {
52
51
  brightness: number;
53
52
  flatness: number;
54
- flux: number;
55
53
  };
56
54
  getFrequencyData: () => Uint8Array;
57
- getWaveform?: (samples?: number) => Float32Array;
58
- getFFT?: (bins?: number, scale?: 'linear' | 'log') => Float32Array;
55
+ getWaveform: () => Float32Array;
59
56
  }
60
57
 
61
58
  interface CaptureFrameOptions {
@@ -90,7 +87,7 @@ declare global {
90
87
  category: ParameterCategory;
91
88
  }
92
89
 
93
- type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation';
90
+ type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation' | 'emotionDetection';
94
91
 
95
92
  type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';
96
93
 
@@ -142,6 +139,61 @@ declare global {
142
139
  video: VideoAPI | null;
143
140
  }
144
141
 
142
+ interface FaceBlendshapes {
143
+ browDownLeft: number;
144
+ browDownRight: number;
145
+ browInnerUp: number;
146
+ browOuterUpLeft: number;
147
+ browOuterUpRight: number;
148
+ cheekPuff: number;
149
+ cheekSquintLeft: number;
150
+ cheekSquintRight: number;
151
+ eyeBlinkLeft: number;
152
+ eyeBlinkRight: number;
153
+ eyeLookDownLeft: number;
154
+ eyeLookDownRight: number;
155
+ eyeLookInLeft: number;
156
+ eyeLookInRight: number;
157
+ eyeLookOutLeft: number;
158
+ eyeLookOutRight: number;
159
+ eyeLookUpLeft: number;
160
+ eyeLookUpRight: number;
161
+ eyeSquintLeft: number;
162
+ eyeSquintRight: number;
163
+ eyeWideLeft: number;
164
+ eyeWideRight: number;
165
+ jawForward: number;
166
+ jawLeft: number;
167
+ jawOpen: number;
168
+ jawRight: number;
169
+ mouthClose: number;
170
+ mouthDimpleLeft: number;
171
+ mouthDimpleRight: number;
172
+ mouthFrownLeft: number;
173
+ mouthFrownRight: number;
174
+ mouthFunnel: number;
175
+ mouthLeft: number;
176
+ mouthLowerDownLeft: number;
177
+ mouthLowerDownRight: number;
178
+ mouthPressLeft: number;
179
+ mouthPressRight: number;
180
+ mouthPucker: number;
181
+ mouthRight: number;
182
+ mouthRollLower: number;
183
+ mouthRollUpper: number;
184
+ mouthShrugLower: number;
185
+ mouthShrugUpper: number;
186
+ mouthSmileLeft: number;
187
+ mouthSmileRight: number;
188
+ mouthStretchLeft: number;
189
+ mouthStretchRight: number;
190
+ mouthUpperUpLeft: number;
191
+ mouthUpperUpRight: number;
192
+ noseSneerLeft: number;
193
+ noseSneerRight: number;
194
+ tongueOut: number;
195
+ }
196
+
145
197
  interface FaceData {
146
198
  id: number;
147
199
  bounds: {
@@ -150,8 +202,12 @@ declare global {
150
202
  width: number;
151
203
  height: number;
152
204
  };
205
+ center: {
206
+ x: number;
207
+ y: number;
208
+ };
153
209
  confidence: number;
154
- landmarks?: {
210
+ landmarks: {
155
211
  x: number;
156
212
  y: number;
157
213
  z?: number;
@@ -170,6 +226,7 @@ declare global {
170
226
  yaw: number;
171
227
  roll: number;
172
228
  };
229
+ blendshapes: FaceBlendshapes;
173
230
  }
174
231
 
175
232
  type FrameRateMode = 'full' | 'half';
@@ -509,6 +566,7 @@ declare global {
509
566
  cv: {
510
567
  enableFaceDetection(enabled: boolean): Promise<void>;
511
568
  enableFaceMesh(enabled: boolean): Promise<void>;
569
+ enableEmotionDetection(enabled: boolean): Promise<void>;
512
570
  enableHandTracking(enabled: boolean): Promise<void>;
513
571
  enablePoseDetection(enabled: boolean): Promise<void>;
514
572
  enableBodySegmentation(enabled: boolean): Promise<void>;