@viji-dev/core 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artist-dts-p5.js +1 -1
- package/dist/artist-dts.js +1 -1
- package/dist/artist-global-p5.d.ts +1 -1
- package/dist/artist-global.d.ts +1 -1
- package/dist/docs-api.js +2 -2
- package/dist/{essentia-wasm.web-C58CPq4U.js → essentia-wasm.web-B2bIxnGE.js} +2 -2
- package/dist/{essentia-wasm.web-C58CPq4U.js.map → essentia-wasm.web-B2bIxnGE.js.map} +1 -1
- package/dist/{index-DsJxKERc.js → index-Yg6_UX8C.js} +38 -8
- package/dist/{index-DsJxKERc.js.map → index-Yg6_UX8C.js.map} +1 -1
- package/dist/index.d.ts +15 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/artist-dts.js
CHANGED
|
@@ -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 /**\r\n * Real-time audio analysis for the main audio stream (`viji.audio`).\r\n * Provides volume, frequency bands, beat detection (with triggers, events, BPM),\r\n * spectral features, and access to raw FFT / waveform data.\r\n *\r\n * All numeric outputs are zeroed when `isConnected` is `false`.\r\n */\r\n interface AudioAPI {\r\n /** `true` when an audio source is connected; otherwise all numeric fields read as `0` and helper methods return empty data. */\r\n isConnected: boolean;\r\n /** Overall loudness across the stream. */\r\n volume: {\r\n /** Instantaneous RMS volume in 0..1. */\r\n current: number;\r\n /** Instantaneous peak amplitude in 0..1. */\r\n peak: number;\r\n /** Volume with a 200ms decay envelope; rises fast, falls smoothly. Use for flicker-free animations. */\r\n smoothed: number;\r\n };\r\n /** Energy in five fixed frequency bands, plus a smoothed companion (~150ms decay) for each. All in 0..1. */\r\n bands: {\r\n /** Instant low-band energy (20-120 Hz, bass/kick range). 0..1. */\r\n low: number;\r\n /** Instant low-mid energy (120-400 Hz). 0..1. */\r\n lowMid: number;\r\n /** Instant mid energy (400-1600 Hz, vocals/instruments). 0..1. */\r\n mid: number;\r\n /** Instant high-mid energy (1600-6000 Hz, cymbals/hi-hats). 0..1. */\r\n highMid: number;\r\n /** Instant high-band energy (6000-16000 Hz, air/brilliance). 0..1. */\r\n high: number;\r\n /** Smoothed `low` (~150ms decay). 0..1. */\r\n lowSmoothed: number;\r\n /** Smoothed `lowMid` (~150ms decay). 0..1. */\r\n lowMidSmoothed: number;\r\n /** Smoothed `mid` (~150ms decay). 0..1. */\r\n midSmoothed: number;\r\n /** Smoothed `highMid` (~150ms decay). 0..1. */\r\n highMidSmoothed: number;\r\n /** Smoothed `high` (~150ms decay). 0..1. */\r\n highSmoothed: number;\r\n };\r\n /** Beat detection: fast/smoothed energy curves, single-frame boolean triggers, raw event list, and BPM tracking. */\r\n beat: {\r\n /** Kick energy curve in 0..1 with a 300ms decay. Peaks on each detected kick. */\r\n kick: number;\r\n /** Snare energy curve in 0..1 with a 300ms decay. */\r\n snare: number;\r\n /** Hi-hat energy curve in 0..1 with a 300ms decay. */\r\n hat: number;\r\n /** Energy curve for any beat type in 0..1 with a 300ms decay. */\r\n any: number;\r\n /** Smoothed `kick` curve in 0..1 with a 500ms decay. Use for ambient pulses. */\r\n kickSmoothed: number;\r\n /** Smoothed `snare` curve in 0..1 with a 500ms decay. */\r\n snareSmoothed: number;\r\n /** Smoothed `hat` curve in 0..1 with a 500ms decay. */\r\n hatSmoothed: number;\r\n /** Smoothed `any` curve in 0..1 with a 500ms decay. */\r\n anySmoothed: number;\r\n /** Single-frame boolean triggers OR-accumulated between frames, so no detected beat is lost. */\r\n triggers: {\r\n /** `true` for one frame when any beat is detected. */\r\n any: boolean;\r\n /** `true` for one frame when a kick is detected. */\r\n kick: boolean;\r\n /** `true` for one frame when a snare is detected. */\r\n snare: boolean;\r\n /** `true` for one frame when a hi-hat is detected. */\r\n hat: boolean;\r\n };\r\n /** All beats detected since the last render frame (zero or more). Cleared each frame. */\r\n events: Array<{\r\n /** Which drum was detected. */\r\n type: 'kick' | 'snare' | 'hat';\r\n /** Timestamp of the detection in milliseconds. */\r\n time: number;\r\n /** Strength of the beat in 0..1. */\r\n strength: number;\r\n }>;\r\n /** Currently detected tempo in beats per minute. Defaults to `120` when no audio. */\r\n bpm: number;\r\n /** Confidence of the BPM tracker in 0..1. */\r\n confidence: number;\r\n /** `true` when the BPM tracker has a stable lock on the current tempo. */\r\n isLocked: boolean;\r\n };\r\n /** High-level spectral features derived from the FFT. */\r\n spectral: {\r\n /** Normalized spectral centroid in 0..1. Higher values mean brighter, more treble-heavy sound. */\r\n brightness: number;\r\n /** Normalized spectral flatness in 0..1. Higher values mean noisier (white-noise-like) sound; lower values mean tonal. */\r\n flatness: number;\r\n };\r\n /**\r\n * Returns the raw FFT magnitude spectrum as a `Uint8Array` (1024 bins, each 0..255).\r\n * Bin `i` covers frequency `i × (sampleRate / fftSize)`. The returned array is a\r\n * snapshot from the latest analysis tick; repeated calls in the same frame return the same data.\r\n *\r\n * @example\r\n * const fft = viji.audio.getFrequencyData();\r\n * for (let i = 0; i < fft.length; i++) drawBar(i, fft[i] / 255);\r\n */\r\n getFrequencyData: () => Uint8Array;\r\n /**\r\n * Returns the raw time-domain waveform as a `Float32Array` (2048 PCM samples in -1..1).\r\n * The returned array is a snapshot; repeated calls in the same frame return the same data.\r\n *\r\n * @example\r\n * const wave = viji.audio.getWaveform();\r\n * for (let i = 0; i < wave.length; i++) drawSample(i, wave[i]);\r\n */\r\n getWaveform: () => Float32Array;\r\n }\r\n\n /**\r\n * Lightweight audio analysis for additional or device audio streams. A strict\r\n * subset of `AudioAPI` that exposes volume, frequency bands, spectral features,\r\n * and raw FFT/waveform access, but **no beat detection** (no `beat`, no BPM,\r\n * no triggers, no events).\r\n */\r\n interface AudioStreamAPI {\r\n /** `true` when this audio stream is connected; otherwise all numeric fields read as `0`. */\r\n isConnected: boolean;\r\n /** Overall loudness across the stream. */\r\n volume: {\r\n /** Instantaneous RMS volume in 0..1. */\r\n current: number;\r\n /** Instantaneous peak amplitude in 0..1. */\r\n peak: number;\r\n /** Volume with a 200ms decay envelope. */\r\n smoothed: number;\r\n };\r\n /** Energy in five fixed frequency bands, plus a smoothed companion (~150ms decay) for each. All in 0..1. */\r\n bands: {\r\n /** Instant low-band energy (20-120 Hz). 0..1. */\r\n low: number;\r\n /** Instant low-mid energy (120-400 Hz). 0..1. */\r\n lowMid: number;\r\n /** Instant mid energy (400-1600 Hz). 0..1. */\r\n mid: number;\r\n /** Instant high-mid energy (1600-6000 Hz). 0..1. */\r\n highMid: number;\r\n /** Instant high-band energy (6000-16000 Hz). 0..1. */\r\n high: number;\r\n /** Smoothed `low` (~150ms decay). 0..1. */\r\n lowSmoothed: number;\r\n /** Smoothed `lowMid` (~150ms decay). 0..1. */\r\n lowMidSmoothed: number;\r\n /** Smoothed `mid` (~150ms decay). 0..1. */\r\n midSmoothed: number;\r\n /** Smoothed `highMid` (~150ms decay). 0..1. */\r\n highMidSmoothed: number;\r\n /** Smoothed `high` (~150ms decay). 0..1. */\r\n highSmoothed: number;\r\n };\r\n /** High-level spectral features derived from the FFT. */\r\n spectral: {\r\n /** Normalized spectral centroid in 0..1. */\r\n brightness: number;\r\n /** Normalized spectral flatness in 0..1. */\r\n flatness: number;\r\n };\r\n /**\r\n * Returns the raw FFT magnitude spectrum for this stream as a `Uint8Array`\r\n * (1024 bins, each 0..255). Snapshot semantics; see `AudioAPI.getFrequencyData`.\r\n */\r\n getFrequencyData: () => Uint8Array;\r\n /**\r\n * Returns the raw time-domain waveform for this stream as a `Float32Array`\r\n * (2048 samples, each -1..1). Snapshot semantics; see `AudioAPI.getWaveform`.\r\n */\r\n getWaveform: () => Float32Array;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.button()`. The host renders a clickable\r\n * momentary button. The resulting `value` is `true` for one frame after press,\r\n * then auto-resets to `false`.\r\n */\r\n interface ButtonConfig {\r\n /** Display name shown on the button in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.button()`. `value` is a momentary flag:\r\n * `true` for exactly one frame after the user clicks, then auto-resets to\r\n * `false`. Use it to trigger discrete events from `render()`.\r\n */\r\n interface ButtonParameter {\r\n /** `true` for the single frame after the user clicks the button, `false` otherwise. */\r\n value: boolean;\r\n /** Display name shown on the button in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Options accepted by `VijiCore.captureFrame()` for snapshotting the current\r\n * scene. Controls output format, encoding, and target resolution / aspect.\r\n */\r\n interface CaptureFrameOptions {\r\n /** Output format: `'blob'` for an encoded image, `'bitmap'` for a GPU-friendly `ImageBitmap`. Default: `'blob'`. */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for `'blob'` output (ignored for `'bitmap'`). Examples: `'image/png'`, `'image/jpeg'`, `'image/webp'`. */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - `number`: scale factor relative to the current canvas size (e.g., `0.5` = 50%).\r\n * - `Resolution`: exact output size. If the aspect ratio differs from the\r\n * canvas, the source is center-cropped before scaling.\r\n */\r\n resolution?: number | Resolution;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.color()`. Defines the color picker's\r\n * label and UI grouping/visibility.\r\n */\r\n interface ColorConfig {\r\n /** Display name shown next to the color swatch in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Accepted input forms for color parameters. Internally normalized to canonical\r\n * lowercase 6-digit hex `#rrggbb`. See `viji.color()` for full documentation.\r\n *\r\n * - `string`: hex (`#rrggbb`, `#rgb`), CSS `rgb(r, g, b)`, CSS `hsl(h, s%, l%)`,\r\n * GLSL-style `vec3(r, g, b)` (0..1), or P5-style `hsb(h, s, b)` (0..360 / 0..100 / 0..100)\r\n * - `{ r, g, b }`: RGB object with components in 0..255\r\n * - `{ h, s, b }`: HSB object with `h` in 0..360, `s` and `b` in 0..100\r\n */\r\n type ColorInput = string | {\r\n /** Red component in 0..255. */\r\n r: number;\r\n /** Green component in 0..255. */\r\n g: number;\r\n /** Blue component in 0..255. */\r\n b: number;\r\n } | {\r\n /** Hue in 0..360. */\r\n h: number;\r\n /** Saturation in 0..100. */\r\n s: number;\r\n /** Brightness in 0..100. */\r\n b: number;\r\n };\r\n\n /**\r\n * Reactive object returned by `viji.color()`. `value` is always a canonical\r\n * lowercase 6-digit hex string; `rgb` and `hsb` are derived accessors that are\r\n * recomputed (and frozen) every time the user changes the color.\r\n */\r\n interface ColorParameter {\r\n /** Canonical hex color string `#rrggbb` (lowercase). Updates in real-time. */\r\n value: string;\r\n /** RGB components as integers in 0..255 (frozen, recomputed when value changes). */\r\n rgb: {\r\n /** Red component, integer in 0..255. */\r\n r: number;\r\n /** Green component, integer in 0..255. */\r\n g: number;\r\n /** Blue component, integer in 0..255. */\r\n b: number;\r\n };\r\n /** HSB components: `h` in 0..360, `s` and `b` in 0..100 (frozen, recomputed when value changes). */\r\n hsb: {\r\n /** Hue in 0..360. */\r\n h: number;\r\n /** Saturation in 0..100. */\r\n s: number;\r\n /** Brightness in 0..100. */\r\n b: number;\r\n };\r\n /** Display name shown next to the swatch in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.coordinate()`. The host renders a 2D\r\n * draggable pad; both `x` and `y` are clamped to `-1..1`.\r\n */\r\n interface CoordinateConfig {\r\n /** Snap increment for both `x` and `y` components. Default: `0.01`. */\r\n step?: number;\r\n /** Display name shown next to the pad in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.coordinate()`. `value.x` and `value.y` are\r\n * always in `-1..1`; the host UI renders a draggable 2D pad.\r\n */\r\n interface CoordinateParameter {\r\n /** Current `{ x, y }` position. Both components are in `-1..1`. Updates in real-time. */\r\n value: CoordinateValue;\r\n /** Snap increment for both `x` and `y` components. */\r\n step: number;\r\n /** Display name shown next to the pad in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Two-component coordinate, both axes in `-1..1` (centered on the canvas).\r\n * Returned and consumed by `viji.coordinate()`.\r\n */\r\n type CoordinateValue = {\r\n /** Horizontal axis in `-1..1` (left to right, `0` = canvas center). */\r\n x: number;\r\n /** Vertical axis in `-1..1` (bottom to top, `0` = canvas center). */\r\n y: number;\r\n };\r\n\n /**\r\n * Identifier for an individual computer-vision feature pipeline. Returned by\r\n * `VideoAPI.cv.getActiveFeatures()` and used internally to track state.\r\n */\r\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation' | 'emotionDetection';\r\n\n /**\r\n * Computer-vision processing rate relative to the scene's render rate.\r\n * `'full'` runs CV every frame, `'half'` every other frame, `'quarter'` every\r\n * fourth, `'eighth'` every eighth. Lower rates reduce CPU/GPU cost.\r\n */\r\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n /**\r\n * Device motion data sourced from the platform's `DeviceMotionEvent`. All\r\n * accelerations are in metres per second squared (m/s²); rotation rates are\r\n * in degrees per second. Inner objects may be `null` when the underlying\r\n * sensor is unavailable, and individual axes may be `null` on platforms that\r\n * report only some components.\r\n */\r\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²). `null` when no accelerometer is available. */\r\n acceleration: {\r\n /** Acceleration along the device's X axis in m/s². `null` if unsupported. */\r\n x: number | null;\r\n /** Acceleration along the device's Y axis in m/s². `null` if unsupported. */\r\n y: number | null;\r\n /** Acceleration along the device's Z axis in m/s². `null` if unsupported. */\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²). `null` when no accelerometer is available. */\r\n accelerationIncludingGravity: {\r\n /** Acceleration including gravity along the device's X axis in m/s². `null` if unsupported. */\r\n x: number | null;\r\n /** Acceleration including gravity along the device's Y axis in m/s². `null` if unsupported. */\r\n y: number | null;\r\n /** Acceleration including gravity along the device's Z axis in m/s². `null` if unsupported. */\r\n z: number | null;\r\n } | null;\r\n /** Angular rotation rate (degrees per second). `null` when no gyroscope is available. */\r\n rotationRate: {\r\n /** Rotation rate around the device's Z axis in deg/s. `null` if unsupported. */\r\n alpha: number | null;\r\n /** Rotation rate around the device's X axis in deg/s. `null` if unsupported. */\r\n beta: number | null;\r\n /** Rotation rate around the device's Y axis in deg/s. `null` if unsupported. */\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between sensor updates in milliseconds. */\r\n interval: number;\r\n }\r\n\n /**\r\n * DeviceOrientationEvent data\r\n * Matches native DeviceOrientationEvent structure\r\n */\r\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 /**\r\n * Sensor snapshot for the device running the scene. Both fields read `null`\r\n * when the corresponding sensor is unavailable or has not delivered a sample yet.\r\n */\r\n interface DeviceSensorState {\r\n /** Motion data (acceleration, rotation rate, sampling interval). `null` if no motion sensor is available. */\r\n motion: DeviceMotionData | null;\r\n /** Orientation data (alpha/beta/gamma in degrees). `null` if no orientation sensor is available. */\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n /**\r\n * External device state (includes id and name)\r\n */\r\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 /** Device audio stream (null if not available) */\r\n audio: AudioStreamAPI | null;\r\n }\r\n\n /**\r\n * 52 ARKit-compatible face blendshape coefficients (each in 0..1) derived from\r\n * MediaPipe FaceLandmarker. All fields are `0` unless emotion detection is\r\n * enabled. Available on each `FaceData.blendshapes`.\r\n */\r\n interface FaceBlendshapes {\r\n /** Coefficient (0..1) for the inner brow of the left eye pulling down. */\r\n browDownLeft: number;\r\n /** Coefficient (0..1) for the inner brow of the right eye pulling down. */\r\n browDownRight: number;\r\n /** Coefficient (0..1) for both inner brows pulling up. */\r\n browInnerUp: number;\r\n /** Coefficient (0..1) for the outer left brow pulling up. */\r\n browOuterUpLeft: number;\r\n /** Coefficient (0..1) for the outer right brow pulling up. */\r\n browOuterUpRight: number;\r\n /** Coefficient (0..1) for puffed cheeks. */\r\n cheekPuff: number;\r\n /** Coefficient (0..1) for the left cheek squinting. */\r\n cheekSquintLeft: number;\r\n /** Coefficient (0..1) for the right cheek squinting. */\r\n cheekSquintRight: number;\r\n /** Coefficient (0..1) for the left eyelid closing. */\r\n eyeBlinkLeft: number;\r\n /** Coefficient (0..1) for the right eyelid closing. */\r\n eyeBlinkRight: number;\r\n /** Coefficient (0..1) for the left eye looking down. */\r\n eyeLookDownLeft: number;\r\n /** Coefficient (0..1) for the right eye looking down. */\r\n eyeLookDownRight: number;\r\n /** Coefficient (0..1) for the left eye looking inward (toward the nose). */\r\n eyeLookInLeft: number;\r\n /** Coefficient (0..1) for the right eye looking inward. */\r\n eyeLookInRight: number;\r\n /** Coefficient (0..1) for the left eye looking outward (away from the nose). */\r\n eyeLookOutLeft: number;\r\n /** Coefficient (0..1) for the right eye looking outward. */\r\n eyeLookOutRight: number;\r\n /** Coefficient (0..1) for the left eye looking up. */\r\n eyeLookUpLeft: number;\r\n /** Coefficient (0..1) for the right eye looking up. */\r\n eyeLookUpRight: number;\r\n /** Coefficient (0..1) for the left eye squinting. */\r\n eyeSquintLeft: number;\r\n /** Coefficient (0..1) for the right eye squinting. */\r\n eyeSquintRight: number;\r\n /** Coefficient (0..1) for the left eye opening wide. */\r\n eyeWideLeft: number;\r\n /** Coefficient (0..1) for the right eye opening wide. */\r\n eyeWideRight: number;\r\n /** Coefficient (0..1) for the jaw moving forward. */\r\n jawForward: number;\r\n /** Coefficient (0..1) for the jaw moving left. */\r\n jawLeft: number;\r\n /** Coefficient (0..1) for the jaw opening (mouth open). */\r\n jawOpen: number;\r\n /** Coefficient (0..1) for the jaw moving right. */\r\n jawRight: number;\r\n /** Coefficient (0..1) for the mouth closing tightly. */\r\n mouthClose: number;\r\n /** Coefficient (0..1) for a dimple appearing on the left side. */\r\n mouthDimpleLeft: number;\r\n /** Coefficient (0..1) for a dimple appearing on the right side. */\r\n mouthDimpleRight: number;\r\n /** Coefficient (0..1) for the left mouth corner pulling down (frown). */\r\n mouthFrownLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner pulling down (frown). */\r\n mouthFrownRight: number;\r\n /** Coefficient (0..1) for funneling the lips outward. */\r\n mouthFunnel: number;\r\n /** Coefficient (0..1) for the mouth shifting left. */\r\n mouthLeft: number;\r\n /** Coefficient (0..1) for the lower lip on the left pulling down. */\r\n mouthLowerDownLeft: number;\r\n /** Coefficient (0..1) for the lower lip on the right pulling down. */\r\n mouthLowerDownRight: number;\r\n /** Coefficient (0..1) for the left lip pressing inward. */\r\n mouthPressLeft: number;\r\n /** Coefficient (0..1) for the right lip pressing inward. */\r\n mouthPressRight: number;\r\n /** Coefficient (0..1) for puckered lips. */\r\n mouthPucker: number;\r\n /** Coefficient (0..1) for the mouth shifting right. */\r\n mouthRight: number;\r\n /** Coefficient (0..1) for the lower lip rolling inward. */\r\n mouthRollLower: number;\r\n /** Coefficient (0..1) for the upper lip rolling inward. */\r\n mouthRollUpper: number;\r\n /** Coefficient (0..1) for the lower lip shrugging. */\r\n mouthShrugLower: number;\r\n /** Coefficient (0..1) for the upper lip shrugging. */\r\n mouthShrugUpper: number;\r\n /** Coefficient (0..1) for the left mouth corner pulling up (smile). */\r\n mouthSmileLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner pulling up (smile). */\r\n mouthSmileRight: number;\r\n /** Coefficient (0..1) for the left mouth corner stretching outward. */\r\n mouthStretchLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner stretching outward. */\r\n mouthStretchRight: number;\r\n /** Coefficient (0..1) for the upper lip on the left raising. */\r\n mouthUpperUpLeft: number;\r\n /** Coefficient (0..1) for the upper lip on the right raising. */\r\n mouthUpperUpRight: number;\r\n /** Coefficient (0..1) for the left side of the nose sneering. */\r\n noseSneerLeft: number;\r\n /** Coefficient (0..1) for the right side of the nose sneering. */\r\n noseSneerRight: number;\r\n /** Coefficient (0..1) for the tongue protruding. */\r\n tongueOut: number;\r\n }\r\n\n /**\r\n * One detected face produced by the video CV pipeline. Always carries `id`,\r\n * `bounds`, `center`, and `confidence`; the rest is populated only when the\r\n * matching CV feature is enabled (face mesh for `landmarks` and `headPose`,\r\n * emotion detection for `expressions` and `blendshapes`).\r\n */\r\n interface FaceData {\r\n /** Index-based face identifier (`0`, `1`, …). Stable within a single frame, may change between frames. */\r\n id: number;\r\n /** Bounding box, all components normalized to 0..1 of the source frame. */\r\n bounds: {\r\n /** Left edge of the face bounding box, normalized 0..1. */\r\n x: number;\r\n /** Top edge of the face bounding box, normalized 0..1. */\r\n y: number;\r\n /** Width of the face bounding box, normalized 0..1. */\r\n width: number;\r\n /** Height of the face bounding box, normalized 0..1. */\r\n height: number;\r\n };\r\n /** Center of the bounding box, normalized 0..1. */\r\n center: {\r\n /** Horizontal center of the face, normalized 0..1. */\r\n x: number;\r\n /** Vertical center of the face, normalized 0..1. */\r\n y: number;\r\n };\r\n /** Detection confidence in 0..1. */\r\n confidence: number;\r\n /** 468 normalized face mesh landmarks when face mesh is enabled; empty array otherwise. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Optional depth (relative). */\r\n z?: number;\r\n }[];\r\n /** Seven expression confidence scores in 0..1. All zero unless emotion detection is enabled. */\r\n expressions: {\r\n /** Confidence (0..1) of a neutral expression. */\r\n neutral: number;\r\n /** Confidence (0..1) of a happy / smiling expression. */\r\n happy: number;\r\n /** Confidence (0..1) of a sad expression. */\r\n sad: number;\r\n /** Confidence (0..1) of an angry expression. */\r\n angry: number;\r\n /** Confidence (0..1) of a surprised expression. */\r\n surprised: number;\r\n /** Confidence (0..1) of a disgusted expression. */\r\n disgusted: number;\r\n /** Confidence (0..1) of a fearful expression. */\r\n fearful: number;\r\n };\r\n /** Estimated head rotation. All zero unless face mesh is enabled. */\r\n headPose: {\r\n /** Up/down rotation in degrees (-90..90). */\r\n pitch: number;\r\n /** Left/right rotation in degrees (-90..90). */\r\n yaw: number;\r\n /** Tilt rotation in degrees (-180..180). */\r\n roll: number;\r\n };\r\n /** 52 ARKit-compatible facial muscle coefficients. All zero unless emotion detection is enabled. */\r\n blendshapes: FaceBlendshapes;\r\n }\r\n\n /**\r\n * Render-loop pacing mode. `'full'` runs `render()` on every animation frame\r\n * (~60 FPS). `'half'` runs every second frame (~30 FPS), saving CPU/GPU on\r\n * lower-cost scenes.\r\n */\r\n type FrameRateMode = 'full' | 'half';\r\n\n /**\r\n * One named frequency band reported by the audio analyzer\r\n * (e.g., `{ name: 'low', min: 20, max: 120 }`). Frequencies are in Hertz.\r\n */\r\n interface FrequencyBand {\r\n /** Human-readable band name (e.g., `'low'`, `'mid'`, `'high'`). */\r\n name: string;\r\n /** Lower edge of the band in Hertz (inclusive). */\r\n min: number;\r\n /** Upper edge of the band in Hertz (exclusive). */\r\n max: number;\r\n }\r\n\n /**\r\n * One detected hand produced by the video CV pipeline. Carries 21 landmarks,\r\n * a palm shortcut, and ML-classified gesture confidence scores. Up to two\r\n * hands appear in `VideoAPI.hands` simultaneously.\r\n */\r\n interface HandData {\r\n /** Index-based hand identifier (`0` or `1`). */\r\n id: number;\r\n /** Which hand. Always lowercase. */\r\n handedness: 'left' | 'right';\r\n /** Detection confidence in 0..1. */\r\n confidence: number;\r\n /** Bounding box, all components normalized to 0..1 of the source frame. */\r\n bounds: {\r\n /** Left edge of the hand bounding box, normalized 0..1. */\r\n x: number;\r\n /** Top edge of the hand bounding box, normalized 0..1. */\r\n y: number;\r\n /** Width of the hand bounding box, normalized 0..1. */\r\n width: number;\r\n /** Height of the hand bounding box, normalized 0..1. */\r\n height: number;\r\n };\r\n /** 21 MediaPipe hand landmarks, normalized 0..1. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Depth (relative). */\r\n z: number;\r\n }[];\r\n /** Palm center, equivalent to `landmarks[9]` (middle-finger MCP). */\r\n palm: {\r\n /** Palm horizontal coordinate, normalized 0..1. */\r\n x: number;\r\n /** Palm vertical coordinate, normalized 0..1. */\r\n y: number;\r\n /** Palm depth (relative). */\r\n z: number;\r\n };\r\n /**\r\n * ML-classified gesture confidences from MediaPipe GestureRecognizer.\r\n * Each value is in 0..1; multiple gestures can fire simultaneously.\r\n */\r\n gestures: {\r\n /** Confidence (0..1) of a closed-fist gesture. */\r\n fist: number;\r\n /** Confidence (0..1) of an open-palm gesture. */\r\n openPalm: number;\r\n /** Confidence (0..1) of a peace / victory sign. */\r\n peace: number;\r\n /** Confidence (0..1) of a thumbs-up gesture. */\r\n thumbsUp: number;\r\n /** Confidence (0..1) of a thumbs-down gesture. */\r\n thumbsDown: number;\r\n /** Confidence (0..1) of a pointing-up gesture. */\r\n pointing: number;\r\n /** Confidence (0..1) of the ASL \"I love you\" sign. */\r\n iLoveYou: number;\r\n };\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.image()`. The host renders an upload\r\n * field; the user-supplied image becomes available as an `ImageBitmap` (Native)\r\n * or a P5 image wrapper (P5 renderer).\r\n */\r\n interface ImageConfig {\r\n /** Display name shown next to the upload field in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.image()`. `value` is `null` until the user\r\n * uploads an image; in P5 scenes a `.p5` accessor is also added at runtime so\r\n * the image works directly with `image()`, `texture()`, etc.\r\n */\r\n interface ImageParameter {\r\n /** Uploaded image as an `ImageBitmap`, or `null` until the user provides one. */\r\n value: ImageBitmap | null;\r\n /** P5-compatible image wrapper. Only available in the P5 renderer; added at runtime by the P5 adapter. */\r\n readonly p5?: any;\r\n /** Display name shown next to the upload field in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Keyboard input state for the current frame: per-key press / hold / release\r\n * queries (case-insensitive), the live set of held keys, modifier flags, and\r\n * a Shadertoy-compatible texture buffer for shader-side keyboard reads.\r\n *\r\n * Key names follow the browser's `event.key` standard\r\n * (`'a'`, `'arrowup'`, `' '` for Space, `'enter'`, `'escape'`, etc.).\r\n */\r\n interface KeyboardAPI {\r\n /** Returns `true` while the named key is held. Case-insensitive. */\r\n isPressed(key: string): boolean;\r\n /** Returns `true` for exactly one frame on the rising edge of the named key (no key-repeat). Case-insensitive. */\r\n wasPressed(key: string): boolean;\r\n /** Returns `true` for exactly one frame on the falling edge of the named key. Case-insensitive. */\r\n wasReleased(key: string): boolean;\r\n /** Set of all currently held keys, lowercased. Persists across frames. */\r\n activeKeys: Set<string>;\r\n /** Set of keys whose key-down fired this frame, lowercased. Cleared each frame. */\r\n pressedThisFrame: Set<string>;\r\n /** Set of keys whose key-up fired this frame, lowercased. Cleared each frame. */\r\n releasedThisFrame: Set<string>;\r\n /** Most recently pressed key in its original case (e.g., `'A'` when Shift is held). */\r\n lastKeyPressed: string;\r\n /** Most recently released key in its original case. */\r\n lastKeyReleased: string;\r\n /** `true` while the Shift key is held. */\r\n shift: boolean;\r\n /** `true` while the Ctrl key is held. */\r\n ctrl: boolean;\r\n /** `true` while the Alt (or Option) key is held. */\r\n alt: boolean;\r\n /** `true` while the Meta (Windows / Cmd) key is held. */\r\n meta: boolean;\r\n /**\r\n * Shadertoy-compatible 256×3 keyboard texture (256 keycodes × 3 rows).\r\n * Row 0: held state (1 / 0). Row 1: pressed-this-frame (1 / 0). Row 2: per-key toggle.\r\n * Bound to a uniform sampler in shader scenes; rarely needed in JS.\r\n */\r\n textureData: Uint8Array;\r\n }\r\n\n /**\r\n * Mouse input state for the current frame: position, individual button states,\r\n * per-frame movement, scroll wheel, and frame-based press / release events.\r\n * Coordinates are in canvas-space pixels with `(0, 0)` at the top-left corner.\r\n *\r\n * For interactions that should also work on touch devices, prefer `viji.pointer`.\r\n */\r\n interface MouseAPI {\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** `true` when the cursor is currently over the canvas. */\r\n isInCanvas: boolean;\r\n /** `true` if any mouse button is currently held. */\r\n isPressed: boolean;\r\n /** `true` while the left mouse button is held. */\r\n leftButton: boolean;\r\n /** `true` while the right mouse button is held. The browser context menu is suppressed on the canvas. */\r\n rightButton: boolean;\r\n /** `true` while the middle (wheel) mouse button is held. */\r\n middleButton: boolean;\r\n /** Horizontal movement this frame in pixels. Resets to `0` each frame. */\r\n deltaX: number;\r\n /** Vertical movement this frame in pixels. Resets to `0` each frame. */\r\n deltaY: number;\r\n /** Vertical scroll accumulated this frame (alias of `wheelY`). Resets to `0` each frame. */\r\n wheelDelta: number;\r\n /** Horizontal scroll accumulated this frame (e.g., trackpad gestures, tilt-wheel mice). Resets to `0` each frame. */\r\n wheelX: number;\r\n /** Vertical scroll accumulated this frame. Resets to `0` each frame. */\r\n wheelY: number;\r\n /** `true` for exactly one frame when any button is first pressed, then auto-resets. */\r\n wasPressed: boolean;\r\n /** `true` for exactly one frame when any button is released, then auto-resets. */\r\n wasReleased: boolean;\r\n /** `true` if the mouse moved this frame (any non-zero `deltaX` / `deltaY`). Resets each frame. */\r\n wasMoved: boolean;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.number()`. Defines the bounds, step,\r\n * label, and UI grouping/visibility for a precise numeric input.\r\n */\r\n interface NumberConfig {\r\n /** Inclusive minimum value. Default: `0`. */\r\n min?: number;\r\n /** Inclusive maximum value. Default: `100`. */\r\n max?: number;\r\n /** Increment between values. Default: `1`. */\r\n step?: number;\r\n /** Display name shown next to the input in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.number()`. Like `SliderParameter` but the\r\n * host UI renders a precise numeric input rather than a draggable slider.\r\n */\r\n interface NumberParameter {\r\n /** Current numeric value in the configured `min..max` range. Updates in real-time. */\r\n value: number;\r\n /** Inclusive minimum value. */\r\n min: number;\r\n /** Inclusive maximum value. */\r\n max: number;\r\n /** Increment between values. */\r\n step: number;\r\n /** Display name shown next to the input in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Visibility category for a parameter. The host hides parameters whose category\r\n * is not currently available (e.g., `'audio'` controls hide when no audio\r\n * source is connected). `'general'` parameters are always visible.\r\n */\r\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n /**\r\n * Unified pointer that abstracts mouse and primary touch into a single input\r\n * stream. Recommended for click / drag / position-tracking interactions that\r\n * should work identically on desktop and mobile.\r\n *\r\n * Use `viji.mouse` for mouse-specific features (right click, middle click,\r\n * scroll wheel); use `viji.touches` for multi-touch, pressure, or radius.\r\n */\r\n interface PointerAPI {\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** Horizontal movement since the last frame in pixels. */\r\n deltaX: number;\r\n /** Vertical movement since the last frame in pixels. */\r\n deltaY: number;\r\n /** `true` while the pointer is \"down\": left mouse button held, or a touch active. */\r\n isDown: boolean;\r\n /** `true` for exactly one frame when the pointer becomes down, then auto-resets. */\r\n wasPressed: boolean;\r\n /** `true` for exactly one frame when the pointer is released, then auto-resets. */\r\n wasReleased: boolean;\r\n /** `true` while the pointer is within the canvas bounds. */\r\n isInCanvas: boolean;\r\n /** Currently active input source: `'touch'` when at least one touch is active, otherwise `'mouse'` (or `'none'` when the cursor is off-canvas). */\r\n type: 'mouse' | 'touch' | 'none';\r\n }\r\n\n /**\r\n * Detected body pose from MediaPipe BlazePose. `landmarks` contains 33 points;\r\n * the `face` / `torso` / `leftArm` / `rightArm` / `leftLeg` / `rightLeg` arrays\r\n * are pre-grouped slices for convenience.\r\n */\r\n interface PoseData {\r\n /** Average landmark visibility in 0..1. */\r\n confidence: number;\r\n /** 33 BlazePose landmarks, normalized 0..1. Each carries a per-point `visibility` score. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Depth (relative). */\r\n z: number;\r\n /** Visibility / confidence of this individual landmark in 0..1. */\r\n visibility: number;\r\n }[];\r\n /** Face landmarks (BlazePose indices 0..10). Coordinates normalized 0..1. */\r\n face: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Torso landmarks (BlazePose indices 11, 12, 23, 24). Coordinates normalized 0..1. */\r\n torso: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Left-arm landmarks (BlazePose indices 11, 13, 15). Coordinates normalized 0..1. */\r\n leftArm: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Right-arm landmarks (BlazePose indices 12, 14, 16). Coordinates normalized 0..1. */\r\n rightArm: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Left-leg landmarks (BlazePose indices 23, 25, 27, 29, 31). Coordinates normalized 0..1. */\r\n leftLeg: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Right-leg landmarks (BlazePose indices 24, 26, 28, 30, 32). Coordinates normalized 0..1. */\r\n rightLeg: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n }\r\n\n /**\r\n * Discrete pixel dimensions for a canvas, frame capture, or render target.\r\n */\r\n type Resolution = {\r\n /** Width in pixels (positive integer). */\r\n width: number;\r\n /** Height in pixels (positive integer). */\r\n height: number;\r\n };\r\n\n /**\r\n * Per-pixel person/background segmentation mask. Mask dimensions reflect the\r\n * ML model's output and may differ from the source video frame.\r\n */\r\n interface SegmentationData {\r\n /** Flat per-pixel mask: each byte is `0` (background) or `1` (person). Length = `width * height`. */\r\n mask: Uint8Array;\r\n /** Mask width in pixels. */\r\n width: number;\r\n /** Mask height in pixels. */\r\n height: number;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.select()`. The host renders the choices\r\n * as a dropdown or segmented control.\r\n */\r\n interface SelectConfig {\r\n /** Available choices. The element type (`string` or `number`) becomes the parameter's value type. Required. */\r\n options: string[] | number[];\r\n /** Display name shown next to the dropdown in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.select()`. `value` matches the element type\r\n * of the configured `options` array (`string` or `number`).\r\n */\r\n interface SelectParameter {\r\n /** Currently selected option. Updates in real-time when the user changes the selection. */\r\n value: string | number;\r\n /** The full list of choices originally configured. */\r\n options: string[] | number[];\r\n /** Display name shown next to the dropdown in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.slider()`. Defines the slider's bounds,\r\n * increment, label, and UI grouping/visibility.\r\n */\r\n interface SliderConfig {\r\n /** Inclusive minimum value of the slider. Default: `0`. */\r\n min?: number;\r\n /** Inclusive maximum value of the slider. Default: `100`. */\r\n max?: number;\r\n /** Increment between values. Default: `1`. */\r\n step?: number;\r\n /** Display name shown next to the control in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.slider()`. `value` updates in real-time as\r\n * the user drags the control; the remaining fields mirror the configuration.\r\n */\r\n interface SliderParameter {\r\n /** Current slider value in the configured `min..max` range. Updates in real-time. */\r\n value: number;\r\n /** Inclusive minimum value of the slider. */\r\n min: number;\r\n /** Inclusive maximum value of the slider. */\r\n max: number;\r\n /** Increment between values. */\r\n step: number;\r\n /** Display name shown next to the control in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.text()`. The host renders a single-line\r\n * text input field.\r\n */\r\n interface TextConfig {\r\n /** Display name shown next to the text field in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n /** Maximum character count enforced by the host UI. Default: `1000`. */\r\n maxLength?: number;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.text()`. `value` updates as the user types\r\n * and is enforced to be no longer than `maxLength` by the host UI.\r\n */\r\n interface TextParameter {\r\n /** Current text content. Updates in real-time as the user types. */\r\n value: string;\r\n /** Maximum character count enforced by the host UI. */\r\n maxLength?: number;\r\n /** Display name shown next to the input in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.toggle()`. Defines the on/off switch's\r\n * label and UI grouping/visibility.\r\n */\r\n interface ToggleConfig {\r\n /** Display name shown next to the switch in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.toggle()`. `value` flips between `true`\r\n * and `false` as the user interacts with the switch.\r\n */\r\n interface ToggleParameter {\r\n /** Current state of the switch. Updates in real-time when the user toggles it. */\r\n value: boolean;\r\n /** Display name shown next to the switch in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Multi-touch input state. Lists all active touches, plus per-frame\r\n * `started` / `moved` / `ended` arrays for frame-based gesture handling.\r\n *\r\n * For single-point interactions that should also work with a mouse, prefer\r\n * `viji.pointer`. It switches automatically between mouse and primary touch.\r\n */\r\n interface TouchAPI {\r\n /** All currently active touch points. Order is stable but not ordered by id. */\r\n points: TouchPoint[];\r\n /** Number of currently active touches (equivalent to `points.length`). */\r\n count: number;\r\n /** Touches that started this frame (also visible in `points`). Cleared each frame. */\r\n started: TouchPoint[];\r\n /** Touches that moved this frame. Cleared each frame. */\r\n moved: TouchPoint[];\r\n /** Touches that ended this frame. Each entry has `isEnding === true`. Cleared each frame. */\r\n ended: TouchPoint[];\r\n /** Convenience shortcut to `points[0]`, or `null` when no touches are active. */\r\n primary: TouchPoint | null;\r\n }\r\n\n /**\r\n * One active touch contact reported by `TouchAPI`. Position, pressure, radius,\r\n * rotation, per-frame movement, velocity, and lifecycle flags. Coordinates are\r\n * in canvas-space pixels.\r\n *\r\n * Some fields (notably `pressure` / `force`, `radiusX` / `radiusY`,\r\n * `rotationAngle`) are passed through from the device; values vary by\r\n * platform; many devices report `0` when unsupported.\r\n */\r\n interface TouchPoint {\r\n /** Stable touch identifier across frames for the duration of this contact. */\r\n id: number;\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** Touch pressure in 0..1 (device-dependent; often `0` on devices without force support). */\r\n pressure: number;\r\n /** Contact radius, `Math.max(radiusX, radiusY)` in pixels. */\r\n radius: number;\r\n /** Horizontal contact radius in pixels (raw device value). */\r\n radiusX: number;\r\n /** Vertical contact radius in pixels (raw device value). */\r\n radiusY: number;\r\n /** Contact area rotation in radians (raw device value). */\r\n rotationAngle: number;\r\n /** Touch force in 0..1; alias of `pressure`. */\r\n force: number;\r\n /** `true` while the touch position is within the canvas bounds. */\r\n isInCanvas: boolean;\r\n /** Horizontal movement since the last frame in pixels. */\r\n deltaX: number;\r\n /** Vertical movement since the last frame in pixels. */\r\n deltaY: number;\r\n /** Movement velocity in pixels per second, computed by Viji. */\r\n velocity: {\r\n /** Horizontal velocity component in pixels per second. */\r\n x: number;\r\n /** Vertical velocity component in pixels per second. */\r\n y: number;\r\n };\r\n /** `true` for exactly one frame when this touch starts, then auto-resets. */\r\n isNew: boolean;\r\n /** `true` while the touch is ongoing. */\r\n isActive: boolean;\r\n /** `true` for exactly one frame when this touch ends, then auto-resets. */\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.5.5\";\r\n\n /**\r\n * Real-time video API: drawable frame, dimensions, and the source-side\r\n * properties of the connected stream. All computer-vision data and controls\r\n * (faces, hands, pose, segmentation, the analysed frame, and feature\r\n * enable/disable verbs) live on `viji.video.cv`.\r\n *\r\n * When `isConnected` is `false`, `currentFrame` is `null`, all dimensions are\r\n * `0`, and every member of `cv` holds its empty default.\r\n */\r\n interface VideoAPI {\r\n /** `true` when a video stream is connected. When `false`, all other fields hold their default empty values. */\r\n isConnected: boolean;\r\n /** Latest video frame, drawable directly with `ctx.drawImage()`. `null` when disconnected. */\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n /** Source video frame width in pixels. `0` when disconnected. */\r\n frameWidth: number;\r\n /** Source video frame height in pixels. `0` when disconnected. */\r\n frameHeight: number;\r\n /** Source video frame rate in Hz (frames per second). `0` when disconnected. */\r\n frameRate: number;\r\n /**\r\n * Returns the latest frame as raw RGBA `ImageData` for per-pixel CPU analysis,\r\n * or `null` when disconnected. Slow compared to drawing `currentFrame` directly;\r\n * use only when you need to read individual pixel values.\r\n */\r\n getFrameData: () => ImageData | null;\r\n /**\r\n * Computer-vision surface for this video stream. Holds both the data\r\n * outputs (`faces`, `hands`, `pose`, `segmentation`, `analysedFrame`,\r\n * `getAnalysedFrameData`) and the verbs that activate them\r\n * (`enable*`/`disable*`/`getActiveFeatures`/`isProcessing`).\r\n *\r\n * Multiple features can be active simultaneously, but each adds CPU/GPU\r\n * and WebGL-context cost; toggle only what you need.\r\n *\r\n * `analysedFrame` and the result fields refresh together once per host\r\n * frame as an atomic snapshot: within a single `render()` call they are\r\n * always paired.\r\n */\r\n cv: VideoCVAPI;\r\n }\r\n\n /**\r\n * Computer-vision surface attached to a `VideoAPI`. Combines paired CV data\r\n * outputs (the analysed frame and its detection / segmentation results) with\r\n * the verbs that activate the underlying MediaPipe pipelines.\r\n *\r\n * Available only on the main video stream (`viji.video.cv`). Additional\r\n * streams (`viji.videoStreams[i].cv`) and device videos\r\n * (`viji.devices[i].video.cv`) do not run CV; their `cv` surface exists for\r\n * API consistency but the data fields stay at their empty defaults and the\r\n * `enable*` verbs are no-ops.\r\n */\r\n interface VideoCVAPI {\r\n /**\r\n * The exact video frame that produced the current `faces` / `hands` /\r\n * `pose` / `segmentation` results: the frame MediaPipe actually analysed.\r\n *\r\n * Choose between `analysedFrame` and `viji.video.currentFrame` by asking\r\n * whether the effect reads pixels from the displayed frame at CV-derived\r\n * positions. Reach for `analysedFrame` when the answer is yes\r\n * (compositing the segmentation mask onto the body, sampling skin tone\r\n * under a face landmark, warping the face along its mesh, texture-mapped\r\n * face filters): pairing the displayed frame with the CV results is\r\n * required for those effects. Stay on `currentFrame` when the answer is\r\n * no (drawing landmark dots, particles, debug overlays, geometry driven\r\n * by CV positions): `analysedFrame` only refreshes when MediaPipe\r\n * completes an inference, which is not every frame, so reaching for it\r\n * without a reason makes the displayed video stutter or hold between\r\n * inferences.\r\n *\r\n * Pairing guarantee: within a single `render()` call, `analysedFrame`\r\n * is paired with the values of `faces`, `hands`, `pose`, `segmentation`\r\n * read in the same call.\r\n *\r\n * `null` until the first CV inference completes after a feature is\r\n * enabled, after the video disconnects, or after a CV-feature toggle\r\n * clears state. A common pattern is\r\n * `viji.video.cv.analysedFrame ?? viji.video.currentFrame` to fall back\r\n * to the live feed during the brief startup window; expect a small\r\n * visual hitch when the source switches as the first inference lands.\r\n *\r\n * Read-only: this `OffscreenCanvas` is owned by the engine. Do not\r\n * mutate it (no `getContext`-and-paint, no `transferToImageBitmap`).\r\n * Drawing it as a source (`ctx.drawImage`, `gl.texImage2D`,\r\n * `p5.image(...)`) is the only supported usage.\r\n */\r\n analysedFrame: OffscreenCanvas | null;\r\n /**\r\n * Returns `analysedFrame` as raw RGBA `ImageData` for per-pixel CPU\r\n * analysis, or `null` when no CV result has landed yet (or the stream is\r\n * disconnected). Cached: re-extracted only when a new CV result arrives,\r\n * so multiple readers within a render share one allocation. Slow\r\n * compared to drawing `analysedFrame` directly. Use only when you need\r\n * pixel values aligned with CV landmark positions (e.g. sampling skin\r\n * colour at a face landmark).\r\n */\r\n getAnalysedFrameData: () => ImageData | null;\r\n /** Detected faces (empty array when face detection is off or no faces are visible). */\r\n faces: FaceData[];\r\n /** Detected hands (up to 2; empty array when hand tracking is off or no hands are visible). */\r\n hands: HandData[];\r\n /** Detected body pose, or `null` when pose detection is off or no pose is visible. */\r\n pose: PoseData | null;\r\n /** Body segmentation mask, or `null` when segmentation is off. */\r\n segmentation: SegmentationData | null;\r\n /**\r\n * Toggle face detection (bounding box, center, confidence, id).\r\n * @returns Resolves once the underlying pipeline has finished switching.\r\n */\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 468-point face mesh + head pose (`pitch`, `yaw`, `roll`). Implies\r\n * face detection.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 7 expressions + 52 ARKit blendshape coefficients on each face.\r\n * Implies face mesh.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableEmotionDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 21-point hand landmarks + ML-classified gesture confidences for up\r\n * to two hands.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 33-point BlazePose body landmarks (face / torso / arms / legs).\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle per-pixel person/background segmentation mask.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n /** Returns the list of CV features currently enabled on this stream. */\r\n getActiveFeatures(): CVFeature[];\r\n /** Returns `true` if the CV worker is actively processing frames. */\r\n isProcessing(): boolean;\r\n }\r\n\n /**\r\n * The Viji API surface available to artist code as the global `viji` object.\r\n * Groups canvas access, timing, connected media APIs, user interaction, device\r\n * sensors, parameter helpers, and the `useContext()` selector.\r\n */\r\n interface VijiAPI {\r\n /** The `OffscreenCanvas` driving the scene. The host owns its lifecycle and dimensions; prefer `useContext()` over touching this directly. */\r\n canvas: OffscreenCanvas;\r\n /** 2D rendering context. `undefined` until `viji.useContext('2d')` is called; afterwards equals the cached context. */\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n /** WebGL rendering context. `undefined` until `viji.useContext('webgl')` or `'webgl2'` is called; afterwards equals the cached context. */\r\n gl?: WebGLRenderingContext | WebGL2RenderingContext;\r\n /** Current canvas width in pixels. Updates automatically when the host resizes the canvas; read every frame. */\r\n width: number;\r\n /** Current canvas height in pixels. Updates automatically when the host resizes the canvas; read every frame. */\r\n height: number;\r\n /** Seconds elapsed since the scene started (monotonically increasing float). Use for oscillations and absolute-time effects. */\r\n time: number;\r\n /** Seconds since the previous frame. Use for accumulation: movement, physics, fades, anything that should progress per second regardless of FPS. */\r\n deltaTime: number;\r\n /** Integer frame counter starting at `0` and incrementing by `1` each frame. */\r\n frameCount: number;\r\n /** Target frames-per-second for the host's current frame-rate mode (`60` for `'full'`, `30` for `'half'`). */\r\n fps: number;\r\n /** Real-time analysis of the main audio stream: volume, frequency bands, beat detection, spectral features. Fields are zeroed when no audio source is connected. */\r\n audio: AudioAPI;\r\n /** Main video stream API: pixel access, frame metadata, and computer-vision results (face, hands, pose, segmentation). */\r\n video: VideoAPI;\r\n /** Additional video streams provided by the host. These do not run CV processing; use them for raw pixel access only. */\r\n videoStreams: VideoAPI[];\r\n /** Additional audio streams (lightweight analysis: volume, bands, spectral). No beat detection; use the main `audio` for that. */\r\n audioStreams: AudioStreamAPI[];\r\n /** Mouse position, buttons, wheel, and per-frame movement state. Coordinates are in canvas pixels. */\r\n mouse: MouseAPI;\r\n /** Keyboard state: per-frame press/release queries, currently held keys, and modifier flags. */\r\n keyboard: KeyboardAPI;\r\n /** Multi-touch state: count, primary touch shortcut, and the per-frame `started` / `moved` / `ended` arrays. */\r\n touches: TouchAPI;\r\n /** Unified pointer (mouse + primary touch). Convenient single-point input that works on both desktop and mobile. */\r\n pointer: PointerAPI;\r\n /** Internal device sensors (motion + orientation) reported by the device running the scene. */\r\n device: DeviceSensorState;\r\n /** External connected devices reporting sensor / camera / audio. Each entry has its own `id`, `name`, and per-device API surface. */\r\n devices: DeviceState[];\r\n /**\r\n * Declares a numeric slider parameter. The host UI renders a draggable slider.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const radius = viji.slider(50, { min: 10, max: 200, step: 1, label: 'Radius' });\r\n * // ...\r\n * function render(viji) { drawCircle(radius.value); }\r\n */\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n /**\r\n * Declares a color parameter. Accepts hex strings, CSS color functions, or RGB / HSB objects;\r\n * the value is always normalized to a canonical lowercase hex string and exposes derived `.rgb` / `.hsb` accessors.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const tint = viji.color('#ff6600', { label: 'Tint' });\r\n * // tint.value -> '#ff6600', tint.rgb -> { r: 255, g: 102, b: 0 }, tint.hsb -> { h: 24, s: 100, b: 100 }\r\n */\r\n color: (defaultValue: ColorInput, config: ColorConfig) => ColorParameter;\r\n /**\r\n * Declares a boolean toggle parameter. The host UI renders an on/off switch.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const showTrail = viji.toggle(true, { label: 'Show Trail' });\r\n */\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n /**\r\n * Declares a dropdown selection parameter. The element type of `options`\r\n * (`string` or `number`) determines the parameter's value type.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const shape = viji.select('circle', { options: ['circle', 'square', 'triangle'], label: 'Shape' });\r\n */\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n /**\r\n * Declares a text input parameter. The host UI renders a single-line text field.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const caption = viji.text('Hello', { label: 'Caption', maxLength: 64 });\r\n */\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n /**\r\n * Declares a precise numeric input parameter. Like `slider()` but the host UI\r\n * shows a number field instead of a draggable handle.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const count = viji.number(12, { min: 1, max: 64, step: 1, label: 'Count' });\r\n */\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n /**\r\n * Declares an image upload parameter. The user-supplied image becomes available\r\n * as `value` (an `ImageBitmap`); in P5 scenes a `.p5` accessor is also added at runtime.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const tex = viji.image(null, { label: 'Texture' });\r\n * if (tex.value) ctx.drawImage(tex.value, 0, 0, viji.width, viji.height);\r\n */\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n /**\r\n * Declares a momentary button parameter. `value` is `true` for one frame after\r\n * the user clicks, then auto-resets. Perfect for triggering discrete events.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const reset = viji.button({ label: 'Reset' });\r\n * function render(viji) { if (reset.value) state = initialState; }\r\n */\r\n button: (config: ButtonConfig) => ButtonParameter;\r\n /**\r\n * Declares a 2D coordinate parameter. Both `value.x` and `value.y` are in `-1..1`.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const origin = viji.coordinate({ x: 0, y: 0 }, { label: 'Origin' });\r\n * const cx = viji.width / 2 + origin.value.x * viji.width * 0.4;\r\n */\r\n coordinate: (defaultValue: CoordinateValue, config: CoordinateConfig) => CoordinateParameter;\r\n /**\r\n * Selects the 2D canvas rendering context. Returns the same instance on\r\n * subsequent calls and also stores it on `viji.ctx`. A canvas only supports\r\n * one context type. If a different context type was already requested,\r\n * the call returns `null`. Choose ONE type and use it for the entire scene.\r\n *\r\n * @example\r\n * const ctx = viji.useContext('2d');\r\n * ctx.fillRect(0, 0, viji.width, viji.height);\r\n */\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\r\n /**\r\n * Selects a WebGL 1 rendering context. Returns the same instance on subsequent\r\n * calls and also stores it on `viji.gl`. A canvas only supports one context\r\n * type. If a different context type was already requested, the call returns\r\n * `null`. Choose ONE type and use it for the entire scene.\r\n */\r\n useContext(type: 'webgl'): WebGLRenderingContext;\r\n /**\r\n * Selects a WebGL 2 rendering context. Returns the same instance on subsequent\r\n * calls and also stores it on `viji.gl`. A canvas only supports one context\r\n * type. If a different context type was already requested, the call returns\r\n * `null`. Choose ONE type and use it for the entire scene.\r\n */\r\n useContext(type: 'webgl2'): 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 /**\r\n * Real-time audio analysis for the main audio stream (`viji.audio`).\r\n * Provides volume, frequency bands, beat detection (with triggers, events, BPM),\r\n * spectral features, and access to raw FFT / waveform data.\r\n *\r\n * All numeric outputs are zeroed when `isConnected` is `false`.\r\n */\r\n interface AudioAPI {\r\n /** `true` when an audio source is connected; otherwise all numeric fields read as `0` and helper methods return empty data. */\r\n isConnected: boolean;\r\n /** Overall loudness across the stream. */\r\n volume: {\r\n /** Instantaneous RMS volume in 0..1. */\r\n current: number;\r\n /** Instantaneous peak amplitude in 0..1. */\r\n peak: number;\r\n /** Volume with a 200ms decay envelope; rises fast, falls smoothly. Use for flicker-free animations. */\r\n smoothed: number;\r\n };\r\n /** Energy in five fixed frequency bands, plus a smoothed companion (~150ms decay) for each. All in 0..1. */\r\n bands: {\r\n /** Instant low-band energy (20-120 Hz, bass/kick range). 0..1. */\r\n low: number;\r\n /** Instant low-mid energy (120-400 Hz). 0..1. */\r\n lowMid: number;\r\n /** Instant mid energy (400-1600 Hz, vocals/instruments). 0..1. */\r\n mid: number;\r\n /** Instant high-mid energy (1600-6000 Hz, cymbals/hi-hats). 0..1. */\r\n highMid: number;\r\n /** Instant high-band energy (6000-16000 Hz, air/brilliance). 0..1. */\r\n high: number;\r\n /** Smoothed `low` (~150ms decay). 0..1. */\r\n lowSmoothed: number;\r\n /** Smoothed `lowMid` (~150ms decay). 0..1. */\r\n lowMidSmoothed: number;\r\n /** Smoothed `mid` (~150ms decay). 0..1. */\r\n midSmoothed: number;\r\n /** Smoothed `highMid` (~150ms decay). 0..1. */\r\n highMidSmoothed: number;\r\n /** Smoothed `high` (~150ms decay). 0..1. */\r\n highSmoothed: number;\r\n };\r\n /** Beat detection: fast/smoothed energy curves, single-frame boolean triggers, raw event list, and BPM tracking. */\r\n beat: {\r\n /** Kick energy curve in 0..1 with a 300ms decay. Peaks on each detected kick. */\r\n kick: number;\r\n /** Snare energy curve in 0..1 with a 300ms decay. */\r\n snare: number;\r\n /** Hi-hat energy curve in 0..1 with a 300ms decay. */\r\n hat: number;\r\n /** Energy curve for any beat type in 0..1 with a 300ms decay. */\r\n any: number;\r\n /** Smoothed `kick` curve in 0..1 with a 500ms decay. Use for ambient pulses. */\r\n kickSmoothed: number;\r\n /** Smoothed `snare` curve in 0..1 with a 500ms decay. */\r\n snareSmoothed: number;\r\n /** Smoothed `hat` curve in 0..1 with a 500ms decay. */\r\n hatSmoothed: number;\r\n /** Smoothed `any` curve in 0..1 with a 500ms decay. */\r\n anySmoothed: number;\r\n /** Single-frame boolean triggers OR-accumulated between frames, so no detected beat is lost. */\r\n triggers: {\r\n /** `true` for one frame when any beat is detected. */\r\n any: boolean;\r\n /** `true` for one frame when a kick is detected. */\r\n kick: boolean;\r\n /** `true` for one frame when a snare is detected. */\r\n snare: boolean;\r\n /** `true` for one frame when a hi-hat is detected. */\r\n hat: boolean;\r\n };\r\n /** All beats detected since the last render frame (zero or more). Cleared each frame. */\r\n events: Array<{\r\n /** Which drum was detected. */\r\n type: 'kick' | 'snare' | 'hat';\r\n /** Timestamp of the detection in milliseconds. */\r\n time: number;\r\n /** Strength of the beat in 0..1. */\r\n strength: number;\r\n }>;\r\n /** Currently detected tempo in beats per minute. Defaults to `120` when no audio. */\r\n bpm: number;\r\n /** Confidence of the BPM tracker in 0..1. */\r\n confidence: number;\r\n /** `true` when the BPM tracker has a stable lock on the current tempo. */\r\n isLocked: boolean;\r\n };\r\n /** High-level spectral features derived from the FFT. */\r\n spectral: {\r\n /** Normalized spectral centroid in 0..1. Higher values mean brighter, more treble-heavy sound. */\r\n brightness: number;\r\n /** Normalized spectral flatness in 0..1. Higher values mean noisier (white-noise-like) sound; lower values mean tonal. */\r\n flatness: number;\r\n };\r\n /**\r\n * Returns the raw FFT magnitude spectrum as a `Uint8Array` (1024 bins, each 0..255).\r\n * Bin `i` covers frequency `i × (sampleRate / fftSize)`. The returned array is a\r\n * snapshot from the latest analysis tick; repeated calls in the same frame return the same data.\r\n *\r\n * @example\r\n * const fft = viji.audio.getFrequencyData();\r\n * for (let i = 0; i < fft.length; i++) drawBar(i, fft[i] / 255);\r\n */\r\n getFrequencyData: () => Uint8Array;\r\n /**\r\n * Returns the raw time-domain waveform as a `Float32Array` (2048 PCM samples in -1..1).\r\n * The returned array is a snapshot; repeated calls in the same frame return the same data.\r\n *\r\n * @example\r\n * const wave = viji.audio.getWaveform();\r\n * for (let i = 0; i < wave.length; i++) drawSample(i, wave[i]);\r\n */\r\n getWaveform: () => Float32Array;\r\n }\r\n\n /**\r\n * Lightweight audio analysis for additional or device audio streams. A strict\r\n * subset of `AudioAPI` that exposes volume, frequency bands, spectral features,\r\n * and raw FFT/waveform access, but **no beat detection** (no `beat`, no BPM,\r\n * no triggers, no events).\r\n */\r\n interface AudioStreamAPI {\r\n /** `true` when this audio stream is connected; otherwise all numeric fields read as `0`. */\r\n isConnected: boolean;\r\n /** Overall loudness across the stream. */\r\n volume: {\r\n /** Instantaneous RMS volume in 0..1. */\r\n current: number;\r\n /** Instantaneous peak amplitude in 0..1. */\r\n peak: number;\r\n /** Volume with a 200ms decay envelope. */\r\n smoothed: number;\r\n };\r\n /** Energy in five fixed frequency bands, plus a smoothed companion (~150ms decay) for each. All in 0..1. */\r\n bands: {\r\n /** Instant low-band energy (20-120 Hz). 0..1. */\r\n low: number;\r\n /** Instant low-mid energy (120-400 Hz). 0..1. */\r\n lowMid: number;\r\n /** Instant mid energy (400-1600 Hz). 0..1. */\r\n mid: number;\r\n /** Instant high-mid energy (1600-6000 Hz). 0..1. */\r\n highMid: number;\r\n /** Instant high-band energy (6000-16000 Hz). 0..1. */\r\n high: number;\r\n /** Smoothed `low` (~150ms decay). 0..1. */\r\n lowSmoothed: number;\r\n /** Smoothed `lowMid` (~150ms decay). 0..1. */\r\n lowMidSmoothed: number;\r\n /** Smoothed `mid` (~150ms decay). 0..1. */\r\n midSmoothed: number;\r\n /** Smoothed `highMid` (~150ms decay). 0..1. */\r\n highMidSmoothed: number;\r\n /** Smoothed `high` (~150ms decay). 0..1. */\r\n highSmoothed: number;\r\n };\r\n /** High-level spectral features derived from the FFT. */\r\n spectral: {\r\n /** Normalized spectral centroid in 0..1. */\r\n brightness: number;\r\n /** Normalized spectral flatness in 0..1. */\r\n flatness: number;\r\n };\r\n /**\r\n * Returns the raw FFT magnitude spectrum for this stream as a `Uint8Array`\r\n * (1024 bins, each 0..255). Snapshot semantics; see `AudioAPI.getFrequencyData`.\r\n */\r\n getFrequencyData: () => Uint8Array;\r\n /**\r\n * Returns the raw time-domain waveform for this stream as a `Float32Array`\r\n * (2048 samples, each -1..1). Snapshot semantics; see `AudioAPI.getWaveform`.\r\n */\r\n getWaveform: () => Float32Array;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.button()`. The host renders a clickable\r\n * momentary button. The resulting `value` is `true` for one frame after press,\r\n * then auto-resets to `false`.\r\n */\r\n interface ButtonConfig {\r\n /** Display name shown on the button in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.button()`. `value` is a momentary flag:\r\n * `true` for exactly one frame after the user clicks, then auto-resets to\r\n * `false`. Use it to trigger discrete events from `render()`.\r\n */\r\n interface ButtonParameter {\r\n /** `true` for the single frame after the user clicks the button, `false` otherwise. */\r\n value: boolean;\r\n /** Display name shown on the button in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Options accepted by `VijiCore.captureFrame()` for snapshotting the current\r\n * scene. Controls output format, encoding, and target resolution / aspect.\r\n */\r\n interface CaptureFrameOptions {\r\n /** Output format: `'blob'` for an encoded image, `'bitmap'` for a GPU-friendly `ImageBitmap`. Default: `'blob'`. */\r\n format?: 'blob' | 'bitmap';\r\n /** MIME type for `'blob'` output (ignored for `'bitmap'`). Examples: `'image/png'`, `'image/jpeg'`, `'image/webp'`. */\r\n type?: string;\r\n /**\r\n * Target resolution.\r\n * - `number`: scale factor relative to the current canvas size (e.g., `0.5` = 50%).\r\n * - `Resolution`: exact output size. If the aspect ratio differs from the\r\n * canvas, the source is center-cropped before scaling.\r\n */\r\n resolution?: number | Resolution;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.color()`. Defines the color picker's\r\n * label and UI grouping/visibility.\r\n */\r\n interface ColorConfig {\r\n /** Display name shown next to the color swatch in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Accepted input forms for color parameters. Internally normalized to canonical\r\n * lowercase 6-digit hex `#rrggbb`. See `viji.color()` for full documentation.\r\n *\r\n * - `string`: hex (`#rrggbb`, `#rgb`), CSS `rgb(r, g, b)`, CSS `hsl(h, s%, l%)`,\r\n * GLSL-style `vec3(r, g, b)` (0..1), or P5-style `hsb(h, s, b)` (0..360 / 0..100 / 0..100)\r\n * - `{ r, g, b }`: RGB object with components in 0..255\r\n * - `{ h, s, b }`: HSB object with `h` in 0..360, `s` and `b` in 0..100\r\n */\r\n type ColorInput = string | {\r\n /** Red component in 0..255. */\r\n r: number;\r\n /** Green component in 0..255. */\r\n g: number;\r\n /** Blue component in 0..255. */\r\n b: number;\r\n } | {\r\n /** Hue in 0..360. */\r\n h: number;\r\n /** Saturation in 0..100. */\r\n s: number;\r\n /** Brightness in 0..100. */\r\n b: number;\r\n };\r\n\n /**\r\n * Reactive object returned by `viji.color()`. `value` is always a canonical\r\n * lowercase 6-digit hex string; `rgb` and `hsb` are derived accessors that are\r\n * recomputed (and frozen) every time the user changes the color.\r\n */\r\n interface ColorParameter {\r\n /** Canonical hex color string `#rrggbb` (lowercase). Updates in real-time. */\r\n value: string;\r\n /** RGB components as integers in 0..255 (frozen, recomputed when value changes). */\r\n rgb: {\r\n /** Red component, integer in 0..255. */\r\n r: number;\r\n /** Green component, integer in 0..255. */\r\n g: number;\r\n /** Blue component, integer in 0..255. */\r\n b: number;\r\n };\r\n /** HSB components: `h` in 0..360, `s` and `b` in 0..100 (frozen, recomputed when value changes). */\r\n hsb: {\r\n /** Hue in 0..360. */\r\n h: number;\r\n /** Saturation in 0..100. */\r\n s: number;\r\n /** Brightness in 0..100. */\r\n b: number;\r\n };\r\n /** Display name shown next to the swatch in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.coordinate()`. The host renders a 2D\r\n * draggable pad; both `x` and `y` are clamped to `-1..1`.\r\n */\r\n interface CoordinateConfig {\r\n /** Snap increment for both `x` and `y` components. Default: `0.01`. */\r\n step?: number;\r\n /** Display name shown next to the pad in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.coordinate()`. `value.x` and `value.y` are\r\n * always in `-1..1`; the host UI renders a draggable 2D pad.\r\n */\r\n interface CoordinateParameter {\r\n /** Current `{ x, y }` position. Both components are in `-1..1`. Updates in real-time. */\r\n value: CoordinateValue;\r\n /** Snap increment for both `x` and `y` components. */\r\n step: number;\r\n /** Display name shown next to the pad in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Two-component coordinate, both axes in `-1..1` (centered on the canvas).\r\n * Returned and consumed by `viji.coordinate()`.\r\n */\r\n type CoordinateValue = {\r\n /** Horizontal axis in `-1..1` (left to right, `0` = canvas center). */\r\n x: number;\r\n /** Vertical axis in `-1..1` (bottom to top, `0` = canvas center). */\r\n y: number;\r\n };\r\n\n /**\r\n * Identifier for an individual computer-vision feature pipeline. Returned by\r\n * `VideoAPI.cv.getActiveFeatures()` and used internally to track state.\r\n */\r\n type CVFeature = 'faceDetection' | 'faceMesh' | 'handTracking' | 'poseDetection' | 'bodySegmentation' | 'emotionDetection';\r\n\n /**\r\n * Computer-vision processing rate relative to the scene's render rate.\r\n * `'full'` runs CV every frame, `'half'` every other frame, `'quarter'` every\r\n * fourth, `'eighth'` every eighth. Lower rates reduce CPU/GPU cost.\r\n */\r\n type CVFrameRateMode = 'full' | 'half' | 'quarter' | 'eighth';\r\n\n /**\r\n * Device motion data sourced from the platform's `DeviceMotionEvent`. All\r\n * accelerations are in metres per second squared (m/s²); rotation rates are\r\n * in degrees per second. Inner objects may be `null` when the underlying\r\n * sensor is unavailable, and individual axes may be `null` on platforms that\r\n * report only some components.\r\n */\r\n interface DeviceMotionData {\r\n /** Acceleration without gravity (m/s²). `null` when no accelerometer is available. */\r\n acceleration: {\r\n /** Acceleration along the device's X axis in m/s². `null` if unsupported. */\r\n x: number | null;\r\n /** Acceleration along the device's Y axis in m/s². `null` if unsupported. */\r\n y: number | null;\r\n /** Acceleration along the device's Z axis in m/s². `null` if unsupported. */\r\n z: number | null;\r\n } | null;\r\n /** Acceleration including gravity (m/s²). `null` when no accelerometer is available. */\r\n accelerationIncludingGravity: {\r\n /** Acceleration including gravity along the device's X axis in m/s². `null` if unsupported. */\r\n x: number | null;\r\n /** Acceleration including gravity along the device's Y axis in m/s². `null` if unsupported. */\r\n y: number | null;\r\n /** Acceleration including gravity along the device's Z axis in m/s². `null` if unsupported. */\r\n z: number | null;\r\n } | null;\r\n /** Angular rotation rate (degrees per second). `null` when no gyroscope is available. */\r\n rotationRate: {\r\n /** Rotation rate around the device's Z axis in deg/s. `null` if unsupported. */\r\n alpha: number | null;\r\n /** Rotation rate around the device's X axis in deg/s. `null` if unsupported. */\r\n beta: number | null;\r\n /** Rotation rate around the device's Y axis in deg/s. `null` if unsupported. */\r\n gamma: number | null;\r\n } | null;\r\n /** Interval between sensor updates in milliseconds. */\r\n interval: number;\r\n }\r\n\n /**\r\n * DeviceOrientationEvent data\r\n * Matches native DeviceOrientationEvent structure\r\n */\r\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 /**\r\n * Sensor snapshot for the device running the scene. Both fields read `null`\r\n * when the corresponding sensor is unavailable or has not delivered a sample yet.\r\n */\r\n interface DeviceSensorState {\r\n /** Motion data (acceleration, rotation rate, sampling interval). `null` if no motion sensor is available. */\r\n motion: DeviceMotionData | null;\r\n /** Orientation data (alpha/beta/gamma in degrees). `null` if no orientation sensor is available. */\r\n orientation: DeviceOrientationData | null;\r\n }\r\n\n /**\r\n * External device state (includes id and name)\r\n */\r\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 /** Device audio stream (null if not available) */\r\n audio: AudioStreamAPI | null;\r\n }\r\n\n /**\r\n * 52 ARKit-compatible face blendshape coefficients (each in 0..1) derived from\r\n * MediaPipe FaceLandmarker. All fields are `0` unless emotion detection is\r\n * enabled. Available on each `FaceData.blendshapes`.\r\n */\r\n interface FaceBlendshapes {\r\n /** Coefficient (0..1) for the inner brow of the left eye pulling down. */\r\n browDownLeft: number;\r\n /** Coefficient (0..1) for the inner brow of the right eye pulling down. */\r\n browDownRight: number;\r\n /** Coefficient (0..1) for both inner brows pulling up. */\r\n browInnerUp: number;\r\n /** Coefficient (0..1) for the outer left brow pulling up. */\r\n browOuterUpLeft: number;\r\n /** Coefficient (0..1) for the outer right brow pulling up. */\r\n browOuterUpRight: number;\r\n /** Coefficient (0..1) for puffed cheeks. */\r\n cheekPuff: number;\r\n /** Coefficient (0..1) for the left cheek squinting. */\r\n cheekSquintLeft: number;\r\n /** Coefficient (0..1) for the right cheek squinting. */\r\n cheekSquintRight: number;\r\n /** Coefficient (0..1) for the left eyelid closing. */\r\n eyeBlinkLeft: number;\r\n /** Coefficient (0..1) for the right eyelid closing. */\r\n eyeBlinkRight: number;\r\n /** Coefficient (0..1) for the left eye looking down. */\r\n eyeLookDownLeft: number;\r\n /** Coefficient (0..1) for the right eye looking down. */\r\n eyeLookDownRight: number;\r\n /** Coefficient (0..1) for the left eye looking inward (toward the nose). */\r\n eyeLookInLeft: number;\r\n /** Coefficient (0..1) for the right eye looking inward. */\r\n eyeLookInRight: number;\r\n /** Coefficient (0..1) for the left eye looking outward (away from the nose). */\r\n eyeLookOutLeft: number;\r\n /** Coefficient (0..1) for the right eye looking outward. */\r\n eyeLookOutRight: number;\r\n /** Coefficient (0..1) for the left eye looking up. */\r\n eyeLookUpLeft: number;\r\n /** Coefficient (0..1) for the right eye looking up. */\r\n eyeLookUpRight: number;\r\n /** Coefficient (0..1) for the left eye squinting. */\r\n eyeSquintLeft: number;\r\n /** Coefficient (0..1) for the right eye squinting. */\r\n eyeSquintRight: number;\r\n /** Coefficient (0..1) for the left eye opening wide. */\r\n eyeWideLeft: number;\r\n /** Coefficient (0..1) for the right eye opening wide. */\r\n eyeWideRight: number;\r\n /** Coefficient (0..1) for the jaw moving forward. */\r\n jawForward: number;\r\n /** Coefficient (0..1) for the jaw moving left. */\r\n jawLeft: number;\r\n /** Coefficient (0..1) for the jaw opening (mouth open). */\r\n jawOpen: number;\r\n /** Coefficient (0..1) for the jaw moving right. */\r\n jawRight: number;\r\n /** Coefficient (0..1) for the mouth closing tightly. */\r\n mouthClose: number;\r\n /** Coefficient (0..1) for a dimple appearing on the left side. */\r\n mouthDimpleLeft: number;\r\n /** Coefficient (0..1) for a dimple appearing on the right side. */\r\n mouthDimpleRight: number;\r\n /** Coefficient (0..1) for the left mouth corner pulling down (frown). */\r\n mouthFrownLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner pulling down (frown). */\r\n mouthFrownRight: number;\r\n /** Coefficient (0..1) for funneling the lips outward. */\r\n mouthFunnel: number;\r\n /** Coefficient (0..1) for the mouth shifting left. */\r\n mouthLeft: number;\r\n /** Coefficient (0..1) for the lower lip on the left pulling down. */\r\n mouthLowerDownLeft: number;\r\n /** Coefficient (0..1) for the lower lip on the right pulling down. */\r\n mouthLowerDownRight: number;\r\n /** Coefficient (0..1) for the left lip pressing inward. */\r\n mouthPressLeft: number;\r\n /** Coefficient (0..1) for the right lip pressing inward. */\r\n mouthPressRight: number;\r\n /** Coefficient (0..1) for puckered lips. */\r\n mouthPucker: number;\r\n /** Coefficient (0..1) for the mouth shifting right. */\r\n mouthRight: number;\r\n /** Coefficient (0..1) for the lower lip rolling inward. */\r\n mouthRollLower: number;\r\n /** Coefficient (0..1) for the upper lip rolling inward. */\r\n mouthRollUpper: number;\r\n /** Coefficient (0..1) for the lower lip shrugging. */\r\n mouthShrugLower: number;\r\n /** Coefficient (0..1) for the upper lip shrugging. */\r\n mouthShrugUpper: number;\r\n /** Coefficient (0..1) for the left mouth corner pulling up (smile). */\r\n mouthSmileLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner pulling up (smile). */\r\n mouthSmileRight: number;\r\n /** Coefficient (0..1) for the left mouth corner stretching outward. */\r\n mouthStretchLeft: number;\r\n /** Coefficient (0..1) for the right mouth corner stretching outward. */\r\n mouthStretchRight: number;\r\n /** Coefficient (0..1) for the upper lip on the left raising. */\r\n mouthUpperUpLeft: number;\r\n /** Coefficient (0..1) for the upper lip on the right raising. */\r\n mouthUpperUpRight: number;\r\n /** Coefficient (0..1) for the left side of the nose sneering. */\r\n noseSneerLeft: number;\r\n /** Coefficient (0..1) for the right side of the nose sneering. */\r\n noseSneerRight: number;\r\n /** Coefficient (0..1) for the tongue protruding. */\r\n tongueOut: number;\r\n }\r\n\n /**\r\n * One detected face produced by the video CV pipeline. Always carries `id`,\r\n * `bounds`, `center`, and `confidence`; the rest is populated only when the\r\n * matching CV feature is enabled (face mesh for `landmarks` and `headPose`,\r\n * emotion detection for `expressions` and `blendshapes`).\r\n */\r\n interface FaceData {\r\n /** Index-based face identifier (`0`, `1`, …). Stable within a single frame, may change between frames. */\r\n id: number;\r\n /** Bounding box, all components normalized to 0..1 of the source frame. */\r\n bounds: {\r\n /** Left edge of the face bounding box, normalized 0..1. */\r\n x: number;\r\n /** Top edge of the face bounding box, normalized 0..1. */\r\n y: number;\r\n /** Width of the face bounding box, normalized 0..1. */\r\n width: number;\r\n /** Height of the face bounding box, normalized 0..1. */\r\n height: number;\r\n };\r\n /** Center of the bounding box, normalized 0..1. */\r\n center: {\r\n /** Horizontal center of the face, normalized 0..1. */\r\n x: number;\r\n /** Vertical center of the face, normalized 0..1. */\r\n y: number;\r\n };\r\n /** Detection confidence in 0..1. */\r\n confidence: number;\r\n /** 468 normalized face mesh landmarks when face mesh is enabled; empty array otherwise. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Optional depth (relative). */\r\n z?: number;\r\n }[];\r\n /** Seven expression confidence scores in 0..1. All zero unless emotion detection is enabled. */\r\n expressions: {\r\n /** Confidence (0..1) of a neutral expression. */\r\n neutral: number;\r\n /** Confidence (0..1) of a happy / smiling expression. */\r\n happy: number;\r\n /** Confidence (0..1) of a sad expression. */\r\n sad: number;\r\n /** Confidence (0..1) of an angry expression. */\r\n angry: number;\r\n /** Confidence (0..1) of a surprised expression. */\r\n surprised: number;\r\n /** Confidence (0..1) of a disgusted expression. */\r\n disgusted: number;\r\n /** Confidence (0..1) of a fearful expression. */\r\n fearful: number;\r\n };\r\n /** Estimated head rotation. All zero unless face mesh is enabled. */\r\n headPose: {\r\n /** Up/down rotation in degrees (-90..90). */\r\n pitch: number;\r\n /** Left/right rotation in degrees (-90..90). */\r\n yaw: number;\r\n /** Tilt rotation in degrees (-180..180). */\r\n roll: number;\r\n };\r\n /** 52 ARKit-compatible facial muscle coefficients. All zero unless emotion detection is enabled. */\r\n blendshapes: FaceBlendshapes;\r\n }\r\n\n /**\r\n * Render-loop pacing mode. `'full'` runs `render()` on every animation frame\r\n * (~60 FPS). `'half'` runs every second frame (~30 FPS), saving CPU/GPU on\r\n * lower-cost scenes.\r\n */\r\n type FrameRateMode = 'full' | 'half';\r\n\n /**\r\n * One named frequency band reported by the audio analyzer\r\n * (e.g., `{ name: 'low', min: 20, max: 120 }`). Frequencies are in Hertz.\r\n */\r\n interface FrequencyBand {\r\n /** Human-readable band name (e.g., `'low'`, `'mid'`, `'high'`). */\r\n name: string;\r\n /** Lower edge of the band in Hertz (inclusive). */\r\n min: number;\r\n /** Upper edge of the band in Hertz (exclusive). */\r\n max: number;\r\n }\r\n\n /**\r\n * One detected hand produced by the video CV pipeline. Carries 21 landmarks,\r\n * a palm shortcut, and ML-classified gesture confidence scores. Up to two\r\n * hands appear in `VideoAPI.hands` simultaneously.\r\n */\r\n interface HandData {\r\n /** Index-based hand identifier (`0` or `1`). */\r\n id: number;\r\n /** Which hand. Always lowercase. */\r\n handedness: 'left' | 'right';\r\n /** Detection confidence in 0..1. */\r\n confidence: number;\r\n /** Bounding box, all components normalized to 0..1 of the source frame. */\r\n bounds: {\r\n /** Left edge of the hand bounding box, normalized 0..1. */\r\n x: number;\r\n /** Top edge of the hand bounding box, normalized 0..1. */\r\n y: number;\r\n /** Width of the hand bounding box, normalized 0..1. */\r\n width: number;\r\n /** Height of the hand bounding box, normalized 0..1. */\r\n height: number;\r\n };\r\n /** 21 MediaPipe hand landmarks, normalized 0..1. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Depth (relative). */\r\n z: number;\r\n }[];\r\n /** Palm center, equivalent to `landmarks[9]` (middle-finger MCP). */\r\n palm: {\r\n /** Palm horizontal coordinate, normalized 0..1. */\r\n x: number;\r\n /** Palm vertical coordinate, normalized 0..1. */\r\n y: number;\r\n /** Palm depth (relative). */\r\n z: number;\r\n };\r\n /**\r\n * ML-classified gesture confidences from MediaPipe GestureRecognizer.\r\n * Each value is in 0..1; multiple gestures can fire simultaneously.\r\n */\r\n gestures: {\r\n /** Confidence (0..1) of a closed-fist gesture. */\r\n fist: number;\r\n /** Confidence (0..1) of an open-palm gesture. */\r\n openPalm: number;\r\n /** Confidence (0..1) of a peace / victory sign. */\r\n peace: number;\r\n /** Confidence (0..1) of a thumbs-up gesture. */\r\n thumbsUp: number;\r\n /** Confidence (0..1) of a thumbs-down gesture. */\r\n thumbsDown: number;\r\n /** Confidence (0..1) of a pointing-up gesture. */\r\n pointing: number;\r\n /** Confidence (0..1) of the ASL \"I love you\" sign. */\r\n iLoveYou: number;\r\n };\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.image()`. The host renders an upload\r\n * field; the user-supplied image becomes available as an `ImageBitmap` (Native)\r\n * or a P5 image wrapper (P5 renderer).\r\n */\r\n interface ImageConfig {\r\n /** Display name shown next to the upload field in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.image()`. `value` is `null` until the user\r\n * uploads an image; in P5 scenes a `.p5` accessor is also added at runtime so\r\n * the image works directly with `image()`, `texture()`, etc.\r\n */\r\n interface ImageParameter {\r\n /** Uploaded image as an `ImageBitmap`, or `null` until the user provides one. */\r\n value: ImageBitmap | null;\r\n /** P5-compatible image wrapper. Only available in the P5 renderer; added at runtime by the P5 adapter. */\r\n readonly p5?: any;\r\n /** Display name shown next to the upload field in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Keyboard input state for the current frame: per-key press / hold / release\r\n * queries (case-insensitive), the live set of held keys, modifier flags, and\r\n * a Shadertoy-compatible texture buffer for shader-side keyboard reads.\r\n *\r\n * Key names follow the browser's `event.key` standard\r\n * (`'a'`, `'arrowup'`, `' '` for Space, `'enter'`, `'escape'`, etc.).\r\n */\r\n interface KeyboardAPI {\r\n /** Returns `true` while the named key is held. Case-insensitive. */\r\n isPressed(key: string): boolean;\r\n /** Returns `true` for exactly one frame on the rising edge of the named key (no key-repeat). Case-insensitive. */\r\n wasPressed(key: string): boolean;\r\n /** Returns `true` for exactly one frame on the falling edge of the named key. Case-insensitive. */\r\n wasReleased(key: string): boolean;\r\n /** Set of all currently held keys, lowercased. Persists across frames. */\r\n activeKeys: Set<string>;\r\n /** Set of keys whose key-down fired this frame, lowercased. Cleared each frame. */\r\n pressedThisFrame: Set<string>;\r\n /** Set of keys whose key-up fired this frame, lowercased. Cleared each frame. */\r\n releasedThisFrame: Set<string>;\r\n /** Most recently pressed key in its original case (e.g., `'A'` when Shift is held). */\r\n lastKeyPressed: string;\r\n /** Most recently released key in its original case. */\r\n lastKeyReleased: string;\r\n /** `true` while the Shift key is held. */\r\n shift: boolean;\r\n /** `true` while the Ctrl key is held. */\r\n ctrl: boolean;\r\n /** `true` while the Alt (or Option) key is held. */\r\n alt: boolean;\r\n /** `true` while the Meta (Windows / Cmd) key is held. */\r\n meta: boolean;\r\n /**\r\n * Shadertoy-compatible 256×3 keyboard texture (256 keycodes × 3 rows).\r\n * Row 0: held state (1 / 0). Row 1: pressed-this-frame (1 / 0). Row 2: per-key toggle.\r\n * Bound to a uniform sampler in shader scenes; rarely needed in JS.\r\n */\r\n textureData: Uint8Array;\r\n }\r\n\n /**\r\n * Mouse input state for the current frame: position, individual button states,\r\n * per-frame movement, scroll wheel, and frame-based press / release events.\r\n * Coordinates are in canvas-space pixels with `(0, 0)` at the top-left corner.\r\n *\r\n * For interactions that should also work on touch devices, prefer `viji.pointer`.\r\n */\r\n interface MouseAPI {\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** `true` when the cursor is currently over the canvas. */\r\n isInCanvas: boolean;\r\n /** `true` if any mouse button is currently held. */\r\n isPressed: boolean;\r\n /** `true` while the left mouse button is held. */\r\n leftButton: boolean;\r\n /** `true` while the right mouse button is held. The browser context menu is suppressed on the canvas. */\r\n rightButton: boolean;\r\n /** `true` while the middle (wheel) mouse button is held. */\r\n middleButton: boolean;\r\n /** Horizontal movement this frame in pixels. Resets to `0` each frame. */\r\n deltaX: number;\r\n /** Vertical movement this frame in pixels. Resets to `0` each frame. */\r\n deltaY: number;\r\n /** Vertical scroll accumulated this frame (alias of `wheelY`). Resets to `0` each frame. */\r\n wheelDelta: number;\r\n /** Horizontal scroll accumulated this frame (e.g., trackpad gestures, tilt-wheel mice). Resets to `0` each frame. */\r\n wheelX: number;\r\n /** Vertical scroll accumulated this frame. Resets to `0` each frame. */\r\n wheelY: number;\r\n /** `true` for exactly one frame when any button is first pressed, then auto-resets. */\r\n wasPressed: boolean;\r\n /** `true` for exactly one frame when any button is released, then auto-resets. */\r\n wasReleased: boolean;\r\n /** `true` if the mouse moved this frame (any non-zero `deltaX` / `deltaY`). Resets each frame. */\r\n wasMoved: boolean;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.number()`. Defines the bounds, step,\r\n * label, and UI grouping/visibility for a precise numeric input.\r\n */\r\n interface NumberConfig {\r\n /** Inclusive minimum value. Default: `0`. */\r\n min?: number;\r\n /** Inclusive maximum value. Default: `100`. */\r\n max?: number;\r\n /** Increment between values. Default: `1`. */\r\n step?: number;\r\n /** Display name shown next to the input in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.number()`. Like `SliderParameter` but the\r\n * host UI renders a precise numeric input rather than a draggable slider.\r\n */\r\n interface NumberParameter {\r\n /** Current numeric value in the configured `min..max` range. Updates in real-time. */\r\n value: number;\r\n /** Inclusive minimum value. */\r\n min: number;\r\n /** Inclusive maximum value. */\r\n max: number;\r\n /** Increment between values. */\r\n step: number;\r\n /** Display name shown next to the input in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Visibility category for a parameter. The host hides parameters whose category\r\n * is not currently available (e.g., `'audio'` controls hide when no audio\r\n * source is connected). `'general'` parameters are always visible.\r\n */\r\n type ParameterCategory = 'audio' | 'video' | 'interaction' | 'general';\r\n\n /**\r\n * Unified pointer that abstracts mouse and primary touch into a single input\r\n * stream. Recommended for click / drag / position-tracking interactions that\r\n * should work identically on desktop and mobile.\r\n *\r\n * Use `viji.mouse` for mouse-specific features (right click, middle click,\r\n * scroll wheel); use `viji.touches` for multi-touch, pressure, or radius.\r\n */\r\n interface PointerAPI {\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** Horizontal movement since the last frame in pixels. */\r\n deltaX: number;\r\n /** Vertical movement since the last frame in pixels. */\r\n deltaY: number;\r\n /** `true` while the pointer is \"down\": left mouse button held, or a touch active. */\r\n isDown: boolean;\r\n /** `true` for exactly one frame when the pointer becomes down, then auto-resets. */\r\n wasPressed: boolean;\r\n /** `true` for exactly one frame when the pointer is released, then auto-resets. */\r\n wasReleased: boolean;\r\n /** `true` while the pointer is within the canvas bounds. */\r\n isInCanvas: boolean;\r\n /** Currently active input source: `'touch'` when at least one touch is active, otherwise `'mouse'` (or `'none'` when the cursor is off-canvas). */\r\n type: 'mouse' | 'touch' | 'none';\r\n }\r\n\n /**\r\n * Detected body pose from MediaPipe BlazePose. `landmarks` contains 33 points;\r\n * the `face` / `torso` / `leftArm` / `rightArm` / `leftLeg` / `rightLeg` arrays\r\n * are pre-grouped slices for convenience.\r\n */\r\n interface PoseData {\r\n /** Average landmark visibility in 0..1. */\r\n confidence: number;\r\n /** 33 BlazePose landmarks, normalized 0..1. Each carries a per-point `visibility` score. */\r\n landmarks: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n /** Depth (relative). */\r\n z: number;\r\n /** Visibility / confidence of this individual landmark in 0..1. */\r\n visibility: number;\r\n }[];\r\n /** Face landmarks (BlazePose indices 0..10). Coordinates normalized 0..1. */\r\n face: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Torso landmarks (BlazePose indices 11, 12, 23, 24). Coordinates normalized 0..1. */\r\n torso: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Left-arm landmarks (BlazePose indices 11, 13, 15). Coordinates normalized 0..1. */\r\n leftArm: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Right-arm landmarks (BlazePose indices 12, 14, 16). Coordinates normalized 0..1. */\r\n rightArm: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Left-leg landmarks (BlazePose indices 23, 25, 27, 29, 31). Coordinates normalized 0..1. */\r\n leftLeg: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n /** Right-leg landmarks (BlazePose indices 24, 26, 28, 30, 32). Coordinates normalized 0..1. */\r\n rightLeg: {\r\n /** Horizontal landmark coordinate, normalized 0..1. */\r\n x: number;\r\n /** Vertical landmark coordinate, normalized 0..1. */\r\n y: number;\r\n }[];\r\n }\r\n\n /**\r\n * Discrete pixel dimensions for a canvas, frame capture, or render target.\r\n */\r\n type Resolution = {\r\n /** Width in pixels (positive integer). */\r\n width: number;\r\n /** Height in pixels (positive integer). */\r\n height: number;\r\n };\r\n\n /**\r\n * Per-pixel person/background segmentation mask. Mask dimensions reflect the\r\n * ML model's output and may differ from the source video frame.\r\n */\r\n interface SegmentationData {\r\n /** Flat per-pixel mask: each byte is `0` (background) or `1` (person). Length = `width * height`. */\r\n mask: Uint8Array;\r\n /** Mask width in pixels. */\r\n width: number;\r\n /** Mask height in pixels. */\r\n height: number;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.select()`. The host renders the choices\r\n * as a dropdown or segmented control.\r\n */\r\n interface SelectConfig {\r\n /** Available choices. The element type (`string` or `number`) becomes the parameter's value type. Required. */\r\n options: string[] | number[];\r\n /** Display name shown next to the dropdown in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.select()`. `value` matches the element type\r\n * of the configured `options` array (`string` or `number`).\r\n */\r\n interface SelectParameter {\r\n /** Currently selected option. Updates in real-time when the user changes the selection. */\r\n value: string | number;\r\n /** The full list of choices originally configured. */\r\n options: string[] | number[];\r\n /** Display name shown next to the dropdown in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.slider()`. Defines the slider's bounds,\r\n * increment, label, and UI grouping/visibility.\r\n */\r\n interface SliderConfig {\r\n /** Inclusive minimum value of the slider. Default: `0`. */\r\n min?: number;\r\n /** Inclusive maximum value of the slider. Default: `100`. */\r\n max?: number;\r\n /** Increment between values. Default: `1`. */\r\n step?: number;\r\n /** Display name shown next to the control in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.slider()`. `value` updates in real-time as\r\n * the user drags the control; the remaining fields mirror the configuration.\r\n */\r\n interface SliderParameter {\r\n /** Current slider value in the configured `min..max` range. Updates in real-time. */\r\n value: number;\r\n /** Inclusive minimum value of the slider. */\r\n min: number;\r\n /** Inclusive maximum value of the slider. */\r\n max: number;\r\n /** Increment between values. */\r\n step: number;\r\n /** Display name shown next to the control in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.text()`. The host renders a single-line\r\n * text input field.\r\n */\r\n interface TextConfig {\r\n /** Display name shown next to the text field in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n /** Maximum character count enforced by the host UI. Default: `1000`. */\r\n maxLength?: number;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.text()`. `value` updates as the user types\r\n * and is enforced to be no longer than `maxLength` by the host UI.\r\n */\r\n interface TextParameter {\r\n /** Current text content. Updates in real-time as the user types. */\r\n value: string;\r\n /** Maximum character count enforced by the host UI. */\r\n maxLength?: number;\r\n /** Display name shown next to the input in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Configuration object passed to `viji.toggle()`. Defines the on/off switch's\r\n * label and UI grouping/visibility.\r\n */\r\n interface ToggleConfig {\r\n /** Display name shown next to the switch in the parameter UI. Required. */\r\n label: string;\r\n /** Optional tooltip / help text shown next to the control. */\r\n description?: string;\r\n /** Group name for organizing related parameters under a shared heading. Default: `'general'`. */\r\n group?: string;\r\n /** Visibility category. The control hides when its capability is unavailable. Default: `'general'`. */\r\n category?: ParameterCategory;\r\n }\r\n\n /**\r\n * Reactive object returned by `viji.toggle()`. `value` flips between `true`\r\n * and `false` as the user interacts with the switch.\r\n */\r\n interface ToggleParameter {\r\n /** Current state of the switch. Updates in real-time when the user toggles it. */\r\n value: boolean;\r\n /** Display name shown next to the switch in the parameter UI. */\r\n label: string;\r\n /** Tooltip / help text for the control (empty string when not configured). */\r\n description?: string;\r\n /** Group name under which the control appears in the UI. */\r\n group: string;\r\n /** Visibility category that controls when the parameter is shown. */\r\n category: ParameterCategory;\r\n }\r\n\n /**\r\n * Multi-touch input state. Lists all active touches, plus per-frame\r\n * `started` / `moved` / `ended` arrays for frame-based gesture handling.\r\n *\r\n * For single-point interactions that should also work with a mouse, prefer\r\n * `viji.pointer`. It switches automatically between mouse and primary touch.\r\n */\r\n interface TouchAPI {\r\n /** All currently active touch points. Order is stable but not ordered by id. */\r\n points: TouchPoint[];\r\n /** Number of currently active touches (equivalent to `points.length`). */\r\n count: number;\r\n /** Touches that started this frame (also visible in `points`). Cleared each frame. */\r\n started: TouchPoint[];\r\n /** Touches that moved this frame. Cleared each frame. */\r\n moved: TouchPoint[];\r\n /** Touches that ended this frame. Each entry has `isEnding === true`. Cleared each frame. */\r\n ended: TouchPoint[];\r\n /** Convenience shortcut to `points[0]`, or `null` when no touches are active. */\r\n primary: TouchPoint | null;\r\n }\r\n\n /**\r\n * One active touch contact reported by `TouchAPI`. Position, pressure, radius,\r\n * rotation, per-frame movement, velocity, and lifecycle flags. Coordinates are\r\n * in canvas-space pixels.\r\n *\r\n * Some fields (notably `pressure` / `force`, `radiusX` / `radiusY`,\r\n * `rotationAngle`) are passed through from the device; values vary by\r\n * platform; many devices report `0` when unsupported.\r\n */\r\n interface TouchPoint {\r\n /** Stable touch identifier across frames for the duration of this contact. */\r\n id: number;\r\n /** Canvas-space X position in pixels. */\r\n x: number;\r\n /** Canvas-space Y position in pixels. */\r\n y: number;\r\n /** Touch pressure in 0..1 (device-dependent; often `0` on devices without force support). */\r\n pressure: number;\r\n /** Contact radius, `Math.max(radiusX, radiusY)` in pixels. */\r\n radius: number;\r\n /** Horizontal contact radius in pixels (raw device value). */\r\n radiusX: number;\r\n /** Vertical contact radius in pixels (raw device value). */\r\n radiusY: number;\r\n /** Contact area rotation in radians (raw device value). */\r\n rotationAngle: number;\r\n /** Touch force in 0..1; alias of `pressure`. */\r\n force: number;\r\n /** `true` while the touch position is within the canvas bounds. */\r\n isInCanvas: boolean;\r\n /** Horizontal movement since the last frame in pixels. */\r\n deltaX: number;\r\n /** Vertical movement since the last frame in pixels. */\r\n deltaY: number;\r\n /** Movement velocity in pixels per second, computed by Viji. */\r\n velocity: {\r\n /** Horizontal velocity component in pixels per second. */\r\n x: number;\r\n /** Vertical velocity component in pixels per second. */\r\n y: number;\r\n };\r\n /** `true` for exactly one frame when this touch starts, then auto-resets. */\r\n isNew: boolean;\r\n /** `true` while the touch is ongoing. */\r\n isActive: boolean;\r\n /** `true` for exactly one frame when this touch ends, then auto-resets. */\r\n isEnding: boolean;\r\n }\r\n\n const VERSION = \"0.5.6\";\r\n\n /**\r\n * Real-time video API: drawable frame, dimensions, and the source-side\r\n * properties of the connected stream. All computer-vision data and controls\r\n * (faces, hands, pose, segmentation, the analysed frame, and feature\r\n * enable/disable verbs) live on `viji.video.cv`.\r\n *\r\n * When `isConnected` is `false`, `currentFrame` is `null`, all dimensions are\r\n * `0`, and every member of `cv` holds its empty default.\r\n */\r\n interface VideoAPI {\r\n /** `true` when a video stream is connected. When `false`, all other fields hold their default empty values. */\r\n isConnected: boolean;\r\n /** Latest video frame, drawable directly with `ctx.drawImage()`. `null` when disconnected. */\r\n currentFrame: OffscreenCanvas | ImageBitmap | null;\r\n /** Source video frame width in pixels. `0` when disconnected. */\r\n frameWidth: number;\r\n /** Source video frame height in pixels. `0` when disconnected. */\r\n frameHeight: number;\r\n /** Source video frame rate in Hz (frames per second). `0` when disconnected. */\r\n frameRate: number;\r\n /**\r\n * Returns the latest frame as raw RGBA `ImageData` for per-pixel CPU analysis,\r\n * or `null` when disconnected. Slow compared to drawing `currentFrame` directly;\r\n * use only when you need to read individual pixel values.\r\n */\r\n getFrameData: () => ImageData | null;\r\n /**\r\n * Computer-vision surface for this video stream. Holds both the data\r\n * outputs (`faces`, `hands`, `pose`, `segmentation`, `analysedFrame`,\r\n * `getAnalysedFrameData`) and the verbs that activate them\r\n * (`enable*`/`disable*`/`getActiveFeatures`/`isProcessing`).\r\n *\r\n * Multiple features can be active simultaneously, but each adds CPU/GPU\r\n * and WebGL-context cost; toggle only what you need.\r\n *\r\n * `analysedFrame` and the result fields refresh together once per host\r\n * frame as an atomic snapshot: within a single `render()` call they are\r\n * always paired.\r\n */\r\n cv: VideoCVAPI;\r\n }\r\n\n /**\r\n * Computer-vision surface attached to a `VideoAPI`. Combines paired CV data\r\n * outputs (the analysed frame and its detection / segmentation results) with\r\n * the verbs that activate the underlying MediaPipe pipelines.\r\n *\r\n * Available only on the main video stream (`viji.video.cv`). Additional\r\n * streams (`viji.videoStreams[i].cv`) and device videos\r\n * (`viji.devices[i].video.cv`) do not run CV; their `cv` surface exists for\r\n * API consistency but the data fields stay at their empty defaults and the\r\n * `enable*` verbs are no-ops.\r\n */\r\n interface VideoCVAPI {\r\n /**\r\n * The exact video frame that produced the current `faces` / `hands` /\r\n * `pose` / `segmentation` results: the frame MediaPipe actually analysed.\r\n *\r\n * Choose between `analysedFrame` and `viji.video.currentFrame` by asking\r\n * whether the effect reads pixels from the displayed frame at CV-derived\r\n * positions. Reach for `analysedFrame` when the answer is yes\r\n * (compositing the segmentation mask onto the body, sampling skin tone\r\n * under a face landmark, warping the face along its mesh, texture-mapped\r\n * face filters): pairing the displayed frame with the CV results is\r\n * required for those effects. Stay on `currentFrame` when the answer is\r\n * no (drawing landmark dots, particles, debug overlays, geometry driven\r\n * by CV positions): `analysedFrame` only refreshes when MediaPipe\r\n * completes an inference, which is not every frame, so reaching for it\r\n * without a reason makes the displayed video stutter or hold between\r\n * inferences.\r\n *\r\n * Pairing guarantee: within a single `render()` call, `analysedFrame`\r\n * is paired with the values of `faces`, `hands`, `pose`, `segmentation`\r\n * read in the same call.\r\n *\r\n * `null` until the first CV inference completes after a feature is\r\n * enabled, after the video disconnects, or after a CV-feature toggle\r\n * clears state. A common pattern is\r\n * `viji.video.cv.analysedFrame ?? viji.video.currentFrame` to fall back\r\n * to the live feed during the brief startup window; expect a small\r\n * visual hitch when the source switches as the first inference lands.\r\n *\r\n * Read-only: this `OffscreenCanvas` is owned by the engine. Do not\r\n * mutate it (no `getContext`-and-paint, no `transferToImageBitmap`).\r\n * Drawing it as a source (`ctx.drawImage`, `gl.texImage2D`,\r\n * `p5.image(...)`) is the only supported usage.\r\n */\r\n analysedFrame: OffscreenCanvas | null;\r\n /**\r\n * Returns `analysedFrame` as raw RGBA `ImageData` for per-pixel CPU\r\n * analysis, or `null` when no CV result has landed yet (or the stream is\r\n * disconnected). Cached: re-extracted only when a new CV result arrives,\r\n * so multiple readers within a render share one allocation. Slow\r\n * compared to drawing `analysedFrame` directly. Use only when you need\r\n * pixel values aligned with CV landmark positions (e.g. sampling skin\r\n * colour at a face landmark).\r\n */\r\n getAnalysedFrameData: () => ImageData | null;\r\n /** Detected faces (empty array when face detection is off or no faces are visible). */\r\n faces: FaceData[];\r\n /** Detected hands (up to 2; empty array when hand tracking is off or no hands are visible). */\r\n hands: HandData[];\r\n /** Detected body pose, or `null` when pose detection is off or no pose is visible. */\r\n pose: PoseData | null;\r\n /** Body segmentation mask, or `null` when segmentation is off. */\r\n segmentation: SegmentationData | null;\r\n /**\r\n * Toggle face detection (bounding box, center, confidence, id).\r\n * @returns Resolves once the underlying pipeline has finished switching.\r\n */\r\n enableFaceDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 468-point face mesh + head pose (`pitch`, `yaw`, `roll`). Implies\r\n * face detection.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableFaceMesh(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 7 expressions + 52 ARKit blendshape coefficients on each face.\r\n * Implies face mesh.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableEmotionDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 21-point hand landmarks + ML-classified gesture confidences for up\r\n * to two hands.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableHandTracking(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle 33-point BlazePose body landmarks (face / torso / arms / legs).\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enablePoseDetection(enabled: boolean): Promise<void>;\r\n /**\r\n * Toggle per-pixel person/background segmentation mask.\r\n * @returns Resolves once the pipeline has finished switching.\r\n */\r\n enableBodySegmentation(enabled: boolean): Promise<void>;\r\n /** Returns the list of CV features currently enabled on this stream. */\r\n getActiveFeatures(): CVFeature[];\r\n /** Returns `true` if the CV worker is actively processing frames. */\r\n isProcessing(): boolean;\r\n }\r\n\n /**\r\n * The Viji API surface available to artist code as the global `viji` object.\r\n * Groups canvas access, timing, connected media APIs, user interaction, device\r\n * sensors, parameter helpers, and the `useContext()` selector.\r\n */\r\n interface VijiAPI {\r\n /** The `OffscreenCanvas` driving the scene. The host owns its lifecycle and dimensions; prefer `useContext()` over touching this directly. */\r\n canvas: OffscreenCanvas;\r\n /** 2D rendering context. `undefined` until `viji.useContext('2d')` is called; afterwards equals the cached context. */\r\n ctx?: OffscreenCanvasRenderingContext2D;\r\n /** WebGL rendering context. `undefined` until `viji.useContext('webgl')` or `'webgl2'` is called; afterwards equals the cached context. */\r\n gl?: WebGLRenderingContext | WebGL2RenderingContext;\r\n /** Current canvas width in pixels. Updates automatically when the host resizes the canvas; read every frame. */\r\n width: number;\r\n /** Current canvas height in pixels. Updates automatically when the host resizes the canvas; read every frame. */\r\n height: number;\r\n /** Seconds elapsed since the scene started (monotonically increasing float). Use for oscillations and absolute-time effects. */\r\n time: number;\r\n /** Seconds since the previous frame. Use for accumulation: movement, physics, fades, anything that should progress per second regardless of FPS. */\r\n deltaTime: number;\r\n /** Integer frame counter starting at `0` and incrementing by `1` each frame. */\r\n frameCount: number;\r\n /** Target frames-per-second for the host's current frame-rate mode (`60` for `'full'`, `30` for `'half'`). */\r\n fps: number;\r\n /** Real-time analysis of the main audio stream: volume, frequency bands, beat detection, spectral features. Fields are zeroed when no audio source is connected. */\r\n audio: AudioAPI;\r\n /** Main video stream API: pixel access, frame metadata, and computer-vision results (face, hands, pose, segmentation). */\r\n video: VideoAPI;\r\n /** Additional video streams provided by the host. These do not run CV processing; use them for raw pixel access only. */\r\n videoStreams: VideoAPI[];\r\n /** Additional audio streams (lightweight analysis: volume, bands, spectral). No beat detection; use the main `audio` for that. */\r\n audioStreams: AudioStreamAPI[];\r\n /** Mouse position, buttons, wheel, and per-frame movement state. Coordinates are in canvas pixels. */\r\n mouse: MouseAPI;\r\n /** Keyboard state: per-frame press/release queries, currently held keys, and modifier flags. */\r\n keyboard: KeyboardAPI;\r\n /** Multi-touch state: count, primary touch shortcut, and the per-frame `started` / `moved` / `ended` arrays. */\r\n touches: TouchAPI;\r\n /** Unified pointer (mouse + primary touch). Convenient single-point input that works on both desktop and mobile. */\r\n pointer: PointerAPI;\r\n /** Internal device sensors (motion + orientation) reported by the device running the scene. */\r\n device: DeviceSensorState;\r\n /** External connected devices reporting sensor / camera / audio. Each entry has its own `id`, `name`, and per-device API surface. */\r\n devices: DeviceState[];\r\n /**\r\n * Declares a numeric slider parameter. The host UI renders a draggable slider.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const radius = viji.slider(50, { min: 10, max: 200, step: 1, label: 'Radius' });\r\n * // ...\r\n * function render(viji) { drawCircle(radius.value); }\r\n */\r\n slider: (defaultValue: number, config: SliderConfig) => SliderParameter;\r\n /**\r\n * Declares a color parameter. Accepts hex strings, CSS color functions, or RGB / HSB objects;\r\n * the value is always normalized to a canonical lowercase hex string and exposes derived `.rgb` / `.hsb` accessors.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const tint = viji.color('#ff6600', { label: 'Tint' });\r\n * // tint.value -> '#ff6600', tint.rgb -> { r: 255, g: 102, b: 0 }, tint.hsb -> { h: 24, s: 100, b: 100 }\r\n */\r\n color: (defaultValue: ColorInput, config: ColorConfig) => ColorParameter;\r\n /**\r\n * Declares a boolean toggle parameter. The host UI renders an on/off switch.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const showTrail = viji.toggle(true, { label: 'Show Trail' });\r\n */\r\n toggle: (defaultValue: boolean, config: ToggleConfig) => ToggleParameter;\r\n /**\r\n * Declares a dropdown selection parameter. The element type of `options`\r\n * (`string` or `number`) determines the parameter's value type.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const shape = viji.select('circle', { options: ['circle', 'square', 'triangle'], label: 'Shape' });\r\n */\r\n select: (defaultValue: string | number, config: SelectConfig) => SelectParameter;\r\n /**\r\n * Declares a text input parameter. The host UI renders a single-line text field.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const caption = viji.text('Hello', { label: 'Caption', maxLength: 64 });\r\n */\r\n text: (defaultValue: string, config: TextConfig) => TextParameter;\r\n /**\r\n * Declares a precise numeric input parameter. Like `slider()` but the host UI\r\n * shows a number field instead of a draggable handle.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const count = viji.number(12, { min: 1, max: 64, step: 1, label: 'Count' });\r\n */\r\n number: (defaultValue: number, config: NumberConfig) => NumberParameter;\r\n /**\r\n * Declares an image upload parameter. The user-supplied image becomes available\r\n * as `value` (an `ImageBitmap`); in P5 scenes a `.p5` accessor is also added at runtime.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const tex = viji.image(null, { label: 'Texture' });\r\n * if (tex.value) ctx.drawImage(tex.value, 0, 0, viji.width, viji.height);\r\n */\r\n image: (defaultValue: null, config: ImageConfig) => ImageParameter;\r\n /**\r\n * Declares a momentary button parameter. `value` is `true` for one frame after\r\n * the user clicks, then auto-resets. Perfect for triggering discrete events.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const reset = viji.button({ label: 'Reset' });\r\n * function render(viji) { if (reset.value) state = initialState; }\r\n */\r\n button: (config: ButtonConfig) => ButtonParameter;\r\n /**\r\n * Declares a 2D coordinate parameter. Both `value.x` and `value.y` are in `-1..1`.\r\n * Must be called at the top level of the scene, never inside `render()`.\r\n *\r\n * @example\r\n * const origin = viji.coordinate({ x: 0, y: 0 }, { label: 'Origin' });\r\n * const cx = viji.width / 2 + origin.value.x * viji.width * 0.4;\r\n */\r\n coordinate: (defaultValue: CoordinateValue, config: CoordinateConfig) => CoordinateParameter;\r\n /**\r\n * Selects the 2D canvas rendering context. Returns the same instance on\r\n * subsequent calls and also stores it on `viji.ctx`. A canvas only supports\r\n * one context type. If a different context type was already requested,\r\n * the call returns `null`. Choose ONE type and use it for the entire scene.\r\n *\r\n * @example\r\n * const ctx = viji.useContext('2d');\r\n * ctx.fillRect(0, 0, viji.width, viji.height);\r\n */\r\n useContext(type: '2d'): OffscreenCanvasRenderingContext2D;\r\n /**\r\n * Selects a WebGL 1 rendering context. Returns the same instance on subsequent\r\n * calls and also stores it on `viji.gl`. A canvas only supports one context\r\n * type. If a different context type was already requested, the call returns\r\n * `null`. Choose ONE type and use it for the entire scene.\r\n */\r\n useContext(type: 'webgl'): WebGLRenderingContext;\r\n /**\r\n * Selects a WebGL 2 rendering context. Returns the same instance on subsequent\r\n * calls and also stores it on `viji.gl`. A canvas only supports one context\r\n * type. If a different context type was already requested, the call returns\r\n * `null`. Choose ONE type and use it for the entire scene.\r\n */\r\n useContext(type: 'webgl2'): 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";
|
package/dist/artist-global.d.ts
CHANGED
package/dist/docs-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as getDefaultExportFromCjs } from "./index-
|
|
1
|
+
import { g as getDefaultExportFromCjs } from "./index-Yg6_UX8C.js";
|
|
2
2
|
function _mergeNamespaces(n, m) {
|
|
3
3
|
for (var i = 0; i < m.length; i++) {
|
|
4
4
|
const e = m[i];
|
|
@@ -5693,4 +5693,4 @@ const essentiaWasm_web$1 = /* @__PURE__ */ _mergeNamespaces({
|
|
|
5693
5693
|
export {
|
|
5694
5694
|
essentiaWasm_web$1 as e
|
|
5695
5695
|
};
|
|
5696
|
-
//# sourceMappingURL=essentia-wasm.web-
|
|
5696
|
+
//# sourceMappingURL=essentia-wasm.web-B2bIxnGE.js.map
|