edgeflowjs 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/onnx.d.ts +38 -0
- package/dist/backends/onnx.d.ts.map +1 -1
- package/dist/backends/onnx.js +79 -9
- package/dist/backends/onnx.js.map +1 -1
- package/dist/edgeflow.browser.js +28 -5
- package/dist/edgeflow.browser.js.map +2 -2
- package/dist/edgeflow.browser.min.js +18 -18
- package/dist/edgeflow.browser.min.js.map +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core/types.ts", "../src/core/tensor.ts", "../src/utils/model-loader.ts", "../src/index.ts", "../src/core/scheduler.ts", "../src/core/memory.ts", "../src/core/runtime.ts", "../src/core/plugin.ts", "../src/core/device-profiler.ts", "../src/backends/webgpu.ts", "../src/backends/webnn.ts", "../src/backends/wasm.ts", "../src/backends/onnx.ts", "../src/backends/transformers-adapter.ts", "../src/backends/index.ts", "../src/utils/cache.ts", "../src/pipelines/base.ts", "../src/pipelines/text-classification.ts", "../src/utils/tokenizer.ts", "../src/pipelines/feature-extraction.ts", "../src/pipelines/image-classification.ts", "../src/utils/preprocessor.ts", "../src/pipelines/text-generation.ts", "../src/pipelines/object-detection.ts", "../src/pipelines/automatic-speech-recognition.ts", "../src/pipelines/zero-shot-classification.ts", "../src/pipelines/question-answering.ts", "../src/pipelines/image-segmentation.ts", "../src/pipelines/index.ts", "../src/core/composer.ts", "../src/utils/index.ts", "../src/utils/hub.ts", "../src/tools/benchmark.ts", "../src/core/index.ts", "../src/tools/quantization.ts", "../src/tools/debugger.ts", "../src/tools/monitor.ts", "../src/tools/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * edgeFlow.js - Core Type Definitions\n * \n * This file contains all the core types used throughout the framework.\n */\n\n// ============================================================================\n// Tensor Types\n// ============================================================================\n\n/**\n * Supported data types for tensors\n */\nexport type DataType = \n | 'float32' \n | 'float16' \n | 'int32' \n | 'int64' \n | 'uint8' \n | 'int8' \n | 'bool';\n\n/**\n * TypedArray types used for tensor data\n */\nexport type TypedArray = \n | Float32Array \n | Float64Array \n | Int32Array \n | BigInt64Array \n | Uint8Array \n | Int8Array;\n\n/**\n * Tensor shape definition\n */\nexport type Shape = readonly number[];\n\n/**\n * Tensor interface\n */\nexport interface Tensor {\n /** Unique identifier for the tensor */\n readonly id: string;\n /** Data type of the tensor */\n readonly dtype: DataType;\n /** Shape of the tensor */\n readonly shape: Shape;\n /** Total number of elements */\n readonly size: number;\n /** Underlying data */\n readonly data: TypedArray;\n /** Get data as Float32Array */\n toFloat32Array(): Float32Array;\n /** Get data as array */\n toArray(): number[];\n /** Clone the tensor */\n clone(): Tensor;\n /** Dispose the tensor and free memory */\n dispose(): void;\n /** Check if tensor has been disposed */\n readonly isDisposed: boolean;\n}\n\n// ============================================================================\n// Runtime Types\n// ============================================================================\n\n/**\n * Supported runtime backends\n */\nexport type RuntimeType = 'webgpu' | 'webnn' | 'wasm' | 'auto';\n\n/**\n * Runtime capability flags\n */\nexport interface RuntimeCapabilities {\n /** Supports concurrent execution */\n concurrency: boolean;\n /** Supports quantized models */\n quantization: boolean;\n /** Supports float16 */\n float16: boolean;\n /** Supports dynamic shapes */\n dynamicShapes: boolean;\n /** Maximum batch size */\n maxBatchSize: number;\n /** Available memory in bytes */\n availableMemory: number;\n}\n\n/**\n * Runtime interface that all backends must implement\n */\nexport interface Runtime {\n /** Runtime name */\n readonly name: RuntimeType;\n /** Runtime capabilities */\n readonly capabilities: RuntimeCapabilities;\n /** Initialize the runtime */\n initialize(): Promise<void>;\n /** Check if runtime is available in current environment */\n isAvailable(): Promise<boolean>;\n /** Load a model from ArrayBuffer */\n loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;\n /** Run inference */\n run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;\n /** Run inference with named inputs (optional) */\n runNamed?(model: LoadedModel, namedInputs: Map<string, Tensor>): Promise<Tensor[]>;\n /** Dispose the runtime and free resources */\n dispose(): void;\n}\n\n// ============================================================================\n// Model Types\n// ============================================================================\n\n/**\n * Model format types\n */\nexport type ModelFormat = 'onnx' | 'edgeflow' | 'safetensors';\n\n/**\n * Model quantization types\n */\nexport type QuantizationType = 'float32' | 'float16' | 'int8' | 'uint8' | 'int4';\n\n/**\n * Model metadata\n */\nexport interface ModelMetadata {\n /** Model name/identifier */\n name: string;\n /** Model version */\n version?: string;\n /** Model description */\n description?: string;\n /** Model author */\n author?: string;\n /** Model license */\n license?: string;\n /** Model tags */\n tags?: string[];\n /** Input specifications */\n inputs: ModelIOSpec[];\n /** Output specifications */\n outputs: ModelIOSpec[];\n /** Model size in bytes */\n sizeBytes: number;\n /** Quantization type */\n quantization: QuantizationType;\n /** Model format */\n format: ModelFormat;\n}\n\n/**\n * Model input/output specification\n */\nexport interface ModelIOSpec {\n /** Name of the input/output */\n name: string;\n /** Data type */\n dtype: DataType;\n /** Shape (use -1 for dynamic dimensions) */\n shape: number[];\n /** Optional description */\n description?: string;\n}\n\n/**\n * Options for loading a model\n */\nexport interface ModelLoadOptions {\n /** Target quantization (convert during load) */\n quantization?: QuantizationType;\n /** Custom metadata */\n metadata?: Partial<ModelMetadata>;\n /** Enable caching */\n cache?: boolean;\n /** Progress callback */\n onProgress?: (progress: number) => void;\n}\n\n/**\n * Loaded model instance\n */\nexport interface LoadedModel {\n /** Unique model instance ID */\n readonly id: string;\n /** Model metadata */\n readonly metadata: ModelMetadata;\n /** Check if model is loaded */\n readonly isLoaded: boolean;\n /** Runtime this model is loaded on */\n readonly runtime: RuntimeType;\n /** Dispose the model and free resources */\n dispose(): void;\n}\n\n// ============================================================================\n// Scheduler Types\n// ============================================================================\n\n/**\n * Task priority levels\n */\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical';\n\n/**\n * Task status\n */\nexport type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n\n/**\n * Inference task definition\n */\nexport interface InferenceTask<T = unknown> {\n /** Unique task ID */\n readonly id: string;\n /** Model ID this task is for */\n readonly modelId: string;\n /** Task priority */\n readonly priority: TaskPriority;\n /** Task status */\n readonly status: TaskStatus;\n /** Creation timestamp */\n readonly createdAt: number;\n /** Start timestamp (when running) */\n readonly startedAt?: number;\n /** Completion timestamp */\n readonly completedAt?: number;\n /** Task result (when completed) */\n readonly result?: T;\n /** Task error (when failed) */\n readonly error?: Error;\n /** Cancel the task */\n cancel(): void;\n /** Wait for task completion */\n wait(): Promise<T>;\n}\n\n/**\n * Scheduler options\n */\nexport interface SchedulerOptions {\n /** Maximum concurrent tasks across all models */\n maxConcurrentTasks?: number;\n /** Maximum concurrent tasks per model */\n maxConcurrentPerModel?: number;\n /** Default task timeout in milliseconds */\n defaultTimeout?: number;\n /** Enable task batching */\n enableBatching?: boolean;\n /** Maximum batch size */\n maxBatchSize?: number;\n /** Batch timeout in milliseconds */\n batchTimeout?: number;\n /** Maximum retry attempts for failed tasks (default: 0 = no retry) */\n maxRetries?: number;\n /** Base delay between retries in ms (exponential backoff) */\n retryBaseDelay?: number;\n /** Enable circuit breaker per model (default: false) */\n circuitBreaker?: boolean;\n /** Consecutive failures before the circuit opens (default: 5) */\n circuitBreakerThreshold?: number;\n /** Time in ms before the circuit half-opens to test (default: 30000) */\n circuitBreakerResetTimeout?: number;\n}\n\n// ============================================================================\n// Memory Types\n// ============================================================================\n\n/**\n * Memory statistics\n */\nexport interface MemoryStats {\n /** Total allocated memory in bytes */\n allocated: number;\n /** Currently used memory in bytes */\n used: number;\n /** Peak memory usage in bytes */\n peak: number;\n /** Number of active tensors */\n tensorCount: number;\n /** Number of loaded models */\n modelCount: number;\n}\n\n/**\n * Memory pool configuration\n */\nexport interface MemoryPoolConfig {\n /** Initial pool size in bytes */\n initialSize?: number;\n /** Maximum pool size in bytes */\n maxSize?: number;\n /** Growth factor when expanding */\n growthFactor?: number;\n /** Enable automatic garbage collection */\n autoGC?: boolean;\n /** GC threshold (percentage of max size) */\n gcThreshold?: number;\n}\n\n// ============================================================================\n// Pipeline Types\n// ============================================================================\n\n/**\n * Supported pipeline tasks\n */\nexport type PipelineTask = \n | 'text-classification'\n | 'token-classification'\n | 'question-answering'\n | 'fill-mask'\n | 'text-generation'\n | 'text2text-generation'\n | 'summarization'\n | 'translation'\n | 'feature-extraction'\n | 'sentiment-analysis'\n | 'zero-shot-classification'\n | 'image-classification'\n | 'object-detection'\n | 'image-segmentation'\n | 'depth-estimation'\n | 'image-to-text'\n | 'audio-classification'\n | 'automatic-speech-recognition'\n | 'text-to-speech';\n\n/**\n * Pipeline configuration\n */\nexport interface PipelineConfig {\n /** Task type */\n task: PipelineTask;\n /** Model ID or path */\n model: string;\n /** Runtime to use */\n runtime?: RuntimeType;\n /** Enable caching */\n cache?: boolean;\n /** Quantization type */\n quantization?: QuantizationType;\n /** Device to use */\n device?: 'cpu' | 'gpu';\n /** Custom tokenizer config */\n tokenizer?: TokenizerConfig;\n /** Tokenizer URL (e.g. HuggingFace tokenizer.json); overrides the pipeline's default */\n tokenizerUrl?: string;\n}\n\n/**\n * Pipeline options passed during inference\n */\nexport interface PipelineOptions {\n /** Batch size */\n batchSize?: number;\n /** Top K results */\n topK?: number;\n /** Temperature for generation */\n temperature?: number;\n /** Maximum length for generation */\n maxLength?: number;\n /** Task timeout in milliseconds */\n timeout?: number;\n}\n\n// ============================================================================\n// Tokenizer Types\n// ============================================================================\n\n/**\n * Tokenizer configuration\n */\nexport interface TokenizerConfig {\n /** Vocabulary size */\n vocabSize: number;\n /** Maximum sequence length */\n maxLength: number;\n /** Padding token ID */\n padTokenId: number;\n /** Unknown token ID */\n unkTokenId: number;\n /** Start of sequence token ID */\n bosTokenId?: number;\n /** End of sequence token ID */\n eosTokenId?: number;\n /** Separator token ID */\n sepTokenId?: number;\n /** CLS token ID */\n clsTokenId?: number;\n /** Mask token ID */\n maskTokenId?: number;\n}\n\n/**\n * Tokenized output\n */\nexport interface TokenizedOutput {\n /** Input IDs */\n inputIds: number[];\n /** Attention mask */\n attentionMask: number[];\n /** Token type IDs (for segment embeddings) */\n tokenTypeIds?: number[];\n /** Special tokens mask */\n specialTokensMask?: number[];\n /** Offset mapping (for token-level tasks) */\n offsetMapping?: [number, number][];\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * Base error class for edgeFlow errors\n */\nexport class EdgeFlowError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'EdgeFlowError';\n }\n}\n\n/**\n * Error codes\n */\nexport const ErrorCodes = {\n // Runtime errors\n RUNTIME_NOT_AVAILABLE: 'RUNTIME_NOT_AVAILABLE',\n RUNTIME_INIT_FAILED: 'RUNTIME_INIT_FAILED',\n RUNTIME_NOT_INITIALIZED: 'RUNTIME_NOT_INITIALIZED',\n \n // Model errors\n MODEL_NOT_FOUND: 'MODEL_NOT_FOUND',\n MODEL_LOAD_FAILED: 'MODEL_LOAD_FAILED',\n MODEL_INVALID_FORMAT: 'MODEL_INVALID_FORMAT',\n MODEL_NOT_LOADED: 'MODEL_NOT_LOADED',\n \n // Inference errors\n INFERENCE_FAILED: 'INFERENCE_FAILED',\n INFERENCE_TIMEOUT: 'INFERENCE_TIMEOUT',\n INFERENCE_CANCELLED: 'INFERENCE_CANCELLED',\n \n // Memory errors\n OUT_OF_MEMORY: 'OUT_OF_MEMORY',\n MEMORY_LEAK_DETECTED: 'MEMORY_LEAK_DETECTED',\n \n // Tensor errors\n TENSOR_SHAPE_MISMATCH: 'TENSOR_SHAPE_MISMATCH',\n TENSOR_DTYPE_MISMATCH: 'TENSOR_DTYPE_MISMATCH',\n TENSOR_DISPOSED: 'TENSOR_DISPOSED',\n \n // Pipeline errors\n PIPELINE_NOT_SUPPORTED: 'PIPELINE_NOT_SUPPORTED',\n PIPELINE_INPUT_INVALID: 'PIPELINE_INPUT_INVALID',\n \n // General errors\n INVALID_ARGUMENT: 'INVALID_ARGUMENT',\n NOT_IMPLEMENTED: 'NOT_IMPLEMENTED',\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n} as const;\n\nexport type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];\n\n// ============================================================================\n// Event Types\n// ============================================================================\n\n/**\n * Event types emitted by edgeFlow\n */\nexport type EventType = \n | 'model:loading'\n | 'model:loaded'\n | 'model:unloaded'\n | 'inference:start'\n | 'inference:complete'\n | 'inference:error'\n | 'memory:warning'\n | 'memory:gc'\n | 'runtime:ready'\n | 'runtime:error';\n\n/**\n * Event payload interface\n */\nexport interface EdgeFlowEvent<T = unknown> {\n type: EventType;\n timestamp: number;\n data: T;\n}\n\n/**\n * Event listener function type\n */\nexport type EventListener<T = unknown> = (event: EdgeFlowEvent<T>) => void;\n", "/**\n * edgeFlow.js - Tensor Implementation\n * \n * Lightweight tensor implementation with efficient memory management.\n */\n\nimport { \n Tensor, \n DataType, \n Shape, \n TypedArray,\n EdgeFlowError,\n ErrorCodes \n} from './types.js';\n\n// Counter for generating unique tensor IDs\nlet tensorIdCounter = 0;\n\n/**\n * Generate a unique tensor ID\n */\nfunction generateTensorId(): string {\n return `tensor_${++tensorIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * Get the typed array constructor for a data type\n */\nfunction getTypedArrayConstructor(dtype: DataType): new (length: number) => TypedArray {\n switch (dtype) {\n case 'float32':\n return Float32Array;\n case 'float16':\n // Float16 not natively supported, use Float32Array\n return Float32Array;\n case 'int32':\n return Int32Array;\n case 'int64':\n return BigInt64Array as unknown as new (length: number) => TypedArray;\n case 'uint8':\n case 'bool':\n return Uint8Array;\n case 'int8':\n return Int8Array;\n default:\n throw new EdgeFlowError(\n `Unsupported data type: ${dtype}`,\n ErrorCodes.INVALID_ARGUMENT,\n { dtype }\n );\n }\n}\n\n/**\n * Calculate the total number of elements from shape\n */\nfunction calculateSize(shape: Shape): number {\n if (shape.length === 0) return 1; // Scalar\n return shape.reduce((acc, dim) => acc * dim, 1);\n}\n\n/**\n * Validate tensor shape\n */\nfunction validateShape(shape: Shape): void {\n for (let i = 0; i < shape.length; i++) {\n const dim = shape[i];\n if (dim === undefined || !Number.isInteger(dim) || dim < 0) {\n throw new EdgeFlowError(\n `Invalid shape dimension at index ${i}: ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { shape, index: i, dimension: dim }\n );\n }\n }\n}\n\n/**\n * EdgeFlowTensor - Core tensor implementation\n */\nexport class EdgeFlowTensor implements Tensor {\n readonly id: string;\n readonly dtype: DataType;\n readonly shape: Shape;\n readonly size: number;\n private _data: TypedArray;\n private _isDisposed: boolean = false;\n\n constructor(\n data: TypedArray | number[],\n shape: Shape,\n dtype: DataType = 'float32'\n ) {\n validateShape(shape);\n \n this.id = generateTensorId();\n this.dtype = dtype;\n this.shape = Object.freeze([...shape]) as Shape;\n this.size = calculateSize(this.shape);\n\n // Validate data size matches shape\n const expectedSize = this.size;\n if (data.length !== expectedSize) {\n throw new EdgeFlowError(\n `Data length (${data.length}) does not match shape ${JSON.stringify(shape)} (expected ${expectedSize})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { dataLength: data.length, expectedSize, shape }\n );\n }\n\n // Convert to appropriate typed array\n if (data instanceof Array) {\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n this._data = new TypedArrayCtor(data.length);\n \n if (dtype === 'int64') {\n // BigInt64Array requires BigInt values\n const bigIntData = this._data as unknown as BigInt64Array;\n for (let i = 0; i < data.length; i++) {\n bigIntData[i] = BigInt(Math.round(data[i] ?? 0));\n }\n } else {\n for (let i = 0; i < data.length; i++) {\n (this._data as Float32Array)[i] = data[i] ?? 0;\n }\n }\n } else {\n this._data = data;\n }\n }\n\n get data(): TypedArray {\n this.checkDisposed();\n return this._data;\n }\n\n get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n /**\n * Check if tensor has been disposed\n */\n private checkDisposed(): void {\n if (this._isDisposed) {\n throw new EdgeFlowError(\n 'Cannot access disposed tensor',\n ErrorCodes.TENSOR_DISPOSED,\n { tensorId: this.id }\n );\n }\n }\n\n /**\n * Convert to Float32Array\n */\n toFloat32Array(): Float32Array {\n this.checkDisposed();\n \n if (this._data instanceof Float32Array) {\n return this._data;\n }\n \n const result = new Float32Array(this.size);\n for (let i = 0; i < this.size; i++) {\n result[i] = Number(this._data[i] ?? 0);\n }\n return result;\n }\n\n /**\n * Convert to regular array\n */\n toArray(): number[] {\n this.checkDisposed();\n if (this.dtype === 'int64') {\n // BigInt64Array needs special handling\n const bigIntData = this._data as unknown as BigInt64Array;\n const result: number[] = [];\n for (let i = 0; i < bigIntData.length; i++) {\n result.push(Number(bigIntData[i]));\n }\n return result;\n }\n return Array.from(this._data as Float32Array);\n }\n\n /**\n * Clone the tensor\n */\n clone(): EdgeFlowTensor {\n this.checkDisposed();\n \n const TypedArrayCtor = this._data.constructor as new (data: TypedArray) => TypedArray;\n const clonedData = new TypedArrayCtor(this._data);\n return new EdgeFlowTensor(clonedData, this.shape, this.dtype);\n }\n\n /**\n * Dispose the tensor and free memory\n */\n dispose(): void {\n if (!this._isDisposed) {\n this._isDisposed = true;\n // Help garbage collection - use Object.assign to avoid type issues\n Object.assign(this, { _data: null });\n }\n }\n\n /**\n * Get value at specific indices\n */\n get(...indices: number[]): number {\n this.checkDisposed();\n \n if (indices.length !== this.shape.length) {\n throw new EdgeFlowError(\n `Expected ${this.shape.length} indices, got ${indices.length}`,\n ErrorCodes.INVALID_ARGUMENT,\n { expectedIndices: this.shape.length, gotIndices: indices.length }\n );\n }\n\n let flatIndex = 0;\n let stride = 1;\n \n for (let i = this.shape.length - 1; i >= 0; i--) {\n const idx = indices[i] ?? 0;\n const dim = this.shape[i] ?? 1;\n \n if (idx < 0 || idx >= dim) {\n throw new EdgeFlowError(\n `Index ${idx} out of bounds for dimension ${i} with size ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { index: idx, dimension: i, size: dim }\n );\n }\n \n flatIndex += idx * stride;\n stride *= dim;\n }\n\n return Number(this._data[flatIndex] ?? 0);\n }\n\n /**\n * Set value at specific indices\n */\n set(value: number, ...indices: number[]): void {\n this.checkDisposed();\n \n if (indices.length !== this.shape.length) {\n throw new EdgeFlowError(\n `Expected ${this.shape.length} indices, got ${indices.length}`,\n ErrorCodes.INVALID_ARGUMENT,\n { expectedIndices: this.shape.length, gotIndices: indices.length }\n );\n }\n\n let flatIndex = 0;\n let stride = 1;\n \n for (let i = this.shape.length - 1; i >= 0; i--) {\n const idx = indices[i] ?? 0;\n const dim = this.shape[i] ?? 1;\n \n if (idx < 0 || idx >= dim) {\n throw new EdgeFlowError(\n `Index ${idx} out of bounds for dimension ${i} with size ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { index: idx, dimension: i, size: dim }\n );\n }\n \n flatIndex += idx * stride;\n stride *= dim;\n }\n\n (this._data as Float32Array)[flatIndex] = value;\n }\n\n /**\n * Reshape the tensor (returns new tensor)\n */\n reshape(newShape: Shape): EdgeFlowTensor {\n this.checkDisposed();\n \n const newSize = calculateSize(newShape);\n if (newSize !== this.size) {\n throw new EdgeFlowError(\n `Cannot reshape tensor of size ${this.size} to shape ${JSON.stringify(newShape)} (size ${newSize})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { currentSize: this.size, newSize, newShape }\n );\n }\n\n const TypedArrayCtor = this._data.constructor as new (data: TypedArray) => TypedArray;\n const clonedData = new TypedArrayCtor(this._data);\n return new EdgeFlowTensor(clonedData, newShape, this.dtype);\n }\n\n /**\n * Transpose the tensor (2D only for now)\n */\n transpose(): EdgeFlowTensor {\n this.checkDisposed();\n \n if (this.shape.length !== 2) {\n throw new EdgeFlowError(\n 'Transpose is currently only supported for 2D tensors',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: this.shape }\n );\n }\n\n const [rows, cols] = this.shape as [number, number];\n const result = new Float32Array(this.size);\n \n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n result[j * rows + i] = Number(this._data[i * cols + j] ?? 0);\n }\n }\n\n return new EdgeFlowTensor(result, [cols, rows], this.dtype);\n }\n\n /**\n * Create string representation\n */\n toString(): string {\n return `Tensor(shape=[${this.shape.join(', ')}], dtype=${this.dtype})`;\n }\n}\n\n// ============================================================================\n// Tensor Factory Functions\n// ============================================================================\n\n/**\n * Create a tensor from data\n */\nexport function tensor(\n data: TypedArray | number[] | number[][],\n shape?: Shape,\n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n // Handle nested arrays\n if (Array.isArray(data) && data.length > 0 && Array.isArray(data[0])) {\n const rows = data.length;\n const cols = (data[0] as number[]).length;\n const flatData: number[] = [];\n \n for (const row of data as number[][]) {\n if (row.length !== cols) {\n throw new EdgeFlowError(\n 'Nested arrays must have consistent dimensions',\n ErrorCodes.INVALID_ARGUMENT\n );\n }\n flatData.push(...row);\n }\n \n return new EdgeFlowTensor(flatData, shape ?? [rows, cols], dtype);\n }\n\n // Infer shape if not provided\n const inferredShape = shape ?? [data.length];\n return new EdgeFlowTensor(data as TypedArray | number[], inferredShape, dtype);\n}\n\n/**\n * Create a tensor filled with zeros\n */\nexport function zeros(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor filled with ones\n */\nexport function ones(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n data.fill(1 as never);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor filled with a specific value\n */\nexport function full(\n shape: Shape, \n value: number, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n data.fill(value as never);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor with random values between 0 and 1\n */\nexport function random(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const data = new Float32Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Math.random();\n }\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor with random values from normal distribution\n */\nexport function randn(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const data = new Float32Array(size);\n \n // Box-Muller transform for normal distribution\n for (let i = 0; i < size; i += 2) {\n const u1 = Math.random();\n const u2 = Math.random();\n const r = Math.sqrt(-2 * Math.log(u1));\n const theta = 2 * Math.PI * u2;\n \n data[i] = r * Math.cos(theta);\n if (i + 1 < size) {\n data[i + 1] = r * Math.sin(theta);\n }\n }\n \n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a 1D tensor with evenly spaced values\n */\nexport function arange(\n start: number, \n stop?: number, \n step: number = 1, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n if (stop === undefined) {\n stop = start;\n start = 0;\n }\n \n const size = Math.ceil((stop - start) / step);\n const data = new Float32Array(size);\n \n for (let i = 0; i < size; i++) {\n data[i] = start + i * step;\n }\n \n return new EdgeFlowTensor(data, [size], dtype);\n}\n\n/**\n * Create a 1D tensor with evenly spaced values (specify number of points)\n */\nexport function linspace(\n start: number, \n stop: number, \n num: number = 50, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n const data = new Float32Array(num);\n const step = (stop - start) / (num - 1);\n \n for (let i = 0; i < num; i++) {\n data[i] = start + i * step;\n }\n \n return new EdgeFlowTensor(data, [num], dtype);\n}\n\n/**\n * Create an identity matrix\n */\nexport function eye(n: number, dtype: DataType = 'float32'): EdgeFlowTensor {\n const data = new Float32Array(n * n);\n \n for (let i = 0; i < n; i++) {\n data[i * n + i] = 1;\n }\n \n return new EdgeFlowTensor(data, [n, n], dtype);\n}\n\n// ============================================================================\n// Tensor Operations\n// ============================================================================\n\n/**\n * Element-wise addition\n */\nexport function add(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) + b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) + (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise subtraction\n */\nexport function sub(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) - b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) - (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise multiplication\n */\nexport function mul(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) * b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) * (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise division\n */\nexport function div(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) / b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) / (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Matrix multiplication (2D tensors)\n */\nexport function matmul(a: EdgeFlowTensor, b: EdgeFlowTensor): EdgeFlowTensor {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new EdgeFlowError(\n 'matmul requires 2D tensors',\n ErrorCodes.INVALID_ARGUMENT,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const [m, k1] = a.shape as [number, number];\n const [k2, n] = b.shape as [number, number];\n\n if (k1 !== k2) {\n throw new EdgeFlowError(\n `Matrix dimensions incompatible for multiplication: (${m}x${k1}) @ (${k2}x${n})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(m * n);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n let sum = 0;\n for (let k = 0; k < k1; k++) {\n sum += (aData[i * k1 + k] ?? 0) * (bData[k * n + j] ?? 0);\n }\n result[i * n + j] = sum;\n }\n }\n\n return new EdgeFlowTensor(result, [m, n], a.dtype);\n}\n\n/**\n * Softmax activation\n */\nexport function softmax(t: EdgeFlowTensor, axis: number = -1): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n if (actualAxis < 0 || actualAxis >= t.shape.length) {\n throw new EdgeFlowError(\n `Invalid axis ${axis} for tensor with ${t.shape.length} dimensions`,\n ErrorCodes.INVALID_ARGUMENT,\n { axis, shape: t.shape }\n );\n }\n\n // For 1D tensors\n if (t.shape.length === 1) {\n let max = -Infinity;\n for (let i = 0; i < t.size; i++) {\n if ((data[i] ?? 0) > max) max = data[i] ?? 0;\n }\n \n let sum = 0;\n for (let i = 0; i < t.size; i++) {\n result[i] = Math.exp((data[i] ?? 0) - max);\n sum += result[i] ?? 0;\n }\n \n for (let i = 0; i < t.size; i++) {\n result[i] = (result[i] ?? 0) / sum;\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n }\n\n // For 2D tensors along last axis\n if (t.shape.length === 2 && actualAxis === 1) {\n const [rows, cols] = t.shape as [number, number];\n \n for (let i = 0; i < rows; i++) {\n let max = -Infinity;\n for (let j = 0; j < cols; j++) {\n if ((data[i * cols + j] ?? 0) > max) max = data[i * cols + j] ?? 0;\n }\n \n let sum = 0;\n for (let j = 0; j < cols; j++) {\n result[i * cols + j] = Math.exp((data[i * cols + j] ?? 0) - max);\n sum += result[i * cols + j] ?? 0;\n }\n \n for (let j = 0; j < cols; j++) {\n result[i * cols + j] = (result[i * cols + j] ?? 0) / sum;\n }\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n }\n\n throw new EdgeFlowError(\n 'Softmax currently only supports 1D tensors or 2D tensors along the last axis',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * ReLU activation\n */\nexport function relu(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = Math.max(0, data[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Sigmoid activation\n */\nexport function sigmoid(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = 1 / (1 + Math.exp(-(data[i] ?? 0)));\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Tanh activation\n */\nexport function tanh(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = Math.tanh(data[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Sum all elements or along an axis\n */\nexport function sum(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {\n const data = t.toFloat32Array();\n \n if (axis === undefined) {\n let total = 0;\n for (let i = 0; i < t.size; i++) {\n total += data[i] ?? 0;\n }\n return total;\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n if (actualAxis < 0 || actualAxis >= t.shape.length) {\n throw new EdgeFlowError(\n `Invalid axis ${axis} for tensor with ${t.shape.length} dimensions`,\n ErrorCodes.INVALID_ARGUMENT,\n { axis, shape: t.shape }\n );\n }\n\n // Calculate new shape\n const newShape = [...t.shape];\n newShape.splice(actualAxis, 1);\n \n if (newShape.length === 0) {\n let total = 0;\n for (let i = 0; i < t.size; i++) {\n total += data[i] ?? 0;\n }\n return total;\n }\n\n // For 2D sum along axis\n if (t.shape.length === 2) {\n const [rows, cols] = t.shape as [number, number];\n \n if (actualAxis === 0) {\n const result = new Float32Array(cols);\n for (let j = 0; j < cols; j++) {\n for (let i = 0; i < rows; i++) {\n result[j] = (result[j] ?? 0) + (data[i * cols + j] ?? 0);\n }\n }\n return new EdgeFlowTensor(result, [cols], t.dtype);\n } else {\n const result = new Float32Array(rows);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n result[i] = (result[i] ?? 0) + (data[i * cols + j] ?? 0);\n }\n }\n return new EdgeFlowTensor(result, [rows], t.dtype);\n }\n }\n\n throw new EdgeFlowError(\n 'Sum along axis currently only supports up to 2D tensors',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * Mean of all elements or along an axis\n */\nexport function mean(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {\n if (axis === undefined) {\n return (sum(t) as number) / t.size;\n }\n\n const result = sum(t, axis);\n if (typeof result === 'number') {\n return result / (t.shape[axis] ?? 1);\n }\n\n const axisSize = t.shape[axis] ?? 1;\n return div(result, axisSize);\n}\n\n/**\n * Argmax - return index of maximum value\n */\nexport function argmax(t: EdgeFlowTensor, axis?: number): number | EdgeFlowTensor {\n const data = t.toFloat32Array();\n \n if (axis === undefined) {\n let maxIdx = 0;\n let maxVal = data[0] ?? -Infinity;\n \n for (let i = 1; i < t.size; i++) {\n if ((data[i] ?? -Infinity) > maxVal) {\n maxVal = data[i] ?? -Infinity;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n // For 2D along last axis\n if (t.shape.length === 2 && actualAxis === 1) {\n const [rows, cols] = t.shape as [number, number];\n const result = new Float32Array(rows);\n \n for (let i = 0; i < rows; i++) {\n let maxIdx = 0;\n let maxVal = data[i * cols] ?? -Infinity;\n \n for (let j = 1; j < cols; j++) {\n if ((data[i * cols + j] ?? -Infinity) > maxVal) {\n maxVal = data[i * cols + j] ?? -Infinity;\n maxIdx = j;\n }\n }\n result[i] = maxIdx;\n }\n \n return new EdgeFlowTensor(result, [rows], 'int32');\n }\n\n throw new EdgeFlowError(\n 'Argmax along axis currently only supports 2D tensors along the last axis',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * Concatenate tensors along an axis\n */\nexport function concat(tensors: EdgeFlowTensor[], axis: number = 0): EdgeFlowTensor {\n if (tensors.length === 0) {\n throw new EdgeFlowError(\n 'Cannot concatenate empty array of tensors',\n ErrorCodes.INVALID_ARGUMENT\n );\n }\n\n if (tensors.length === 1) {\n return tensors[0]?.clone() ?? zeros([0]);\n }\n\n const first = tensors[0];\n if (!first) {\n throw new EdgeFlowError('First tensor is undefined', ErrorCodes.INVALID_ARGUMENT);\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? first.shape.length + axis : axis;\n\n // Validate shapes\n for (let i = 1; i < tensors.length; i++) {\n const t = tensors[i];\n if (!t) continue;\n \n if (t.shape.length !== first.shape.length) {\n throw new EdgeFlowError(\n 'All tensors must have the same number of dimensions',\n ErrorCodes.TENSOR_SHAPE_MISMATCH\n );\n }\n \n for (let j = 0; j < first.shape.length; j++) {\n if (j !== actualAxis && first.shape[j] !== t.shape[j]) {\n throw new EdgeFlowError(\n `Shape mismatch at dimension ${j}`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH\n );\n }\n }\n }\n\n // Calculate new shape\n const newShape = [...first.shape];\n let totalAxisSize = 0;\n for (const t of tensors) {\n if (t) totalAxisSize += t.shape[actualAxis] ?? 0;\n }\n newShape[actualAxis] = totalAxisSize;\n\n // For 1D concatenation\n if (first.shape.length === 1) {\n const result = new Float32Array(totalAxisSize);\n let offset = 0;\n \n for (const t of tensors) {\n if (!t) continue;\n result.set(t.toFloat32Array(), offset);\n offset += t.size;\n }\n \n return new EdgeFlowTensor(result, newShape, first.dtype);\n }\n\n throw new EdgeFlowError(\n 'Concatenation currently only supports 1D tensors',\n ErrorCodes.NOT_IMPLEMENTED\n );\n}\n", "/**\n * edgeFlow.js - Advanced Model Loader\n * \n * Features:\n * - Preloading: Background model loading\n * - Sharding: Split large files into chunks for download\n * - Resume Download: Continue download from where it left off\n * - Model Caching: IndexedDB storage for large models\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Download progress information\n */\nexport interface DownloadProgress {\n /** Downloaded bytes */\n loaded: number;\n /** Total bytes (0 if unknown) */\n total: number;\n /** Progress percentage (0-100) */\n percent: number;\n /** Download speed in bytes/sec */\n speed: number;\n /** Estimated time remaining in ms */\n eta: number;\n /** Current chunk index (for sharded downloads) */\n currentChunk?: number;\n /** Total chunks (for sharded downloads) */\n totalChunks?: number;\n}\n\n/**\n * Model loader options\n */\nexport interface ModelLoaderOptions {\n /** Enable caching (default: true) */\n cache?: boolean;\n /** Cache name for IndexedDB (default: 'edgeflow-models') */\n cacheName?: string;\n /** Enable resume download (default: true) */\n resumable?: boolean;\n /** Chunk size for sharded downloads in bytes (default: 5MB) */\n chunkSize?: number;\n /** Progress callback */\n onProgress?: (progress: DownloadProgress) => void;\n /** Number of parallel download connections (default: 4) */\n parallelConnections?: number;\n /** Request timeout in ms (default: 30000) */\n timeout?: number;\n /** Force re-download even if cached */\n forceDownload?: boolean;\n}\n\n/**\n * Preload options\n */\nexport interface PreloadOptions extends ModelLoaderOptions {\n /** Priority (higher = more important, default: 0) */\n priority?: number;\n}\n\n/**\n * Cached model metadata\n */\ninterface CachedModelMeta {\n url: string;\n size: number;\n etag?: string;\n lastModified?: string;\n cachedAt: number;\n chunks?: number;\n complete: boolean;\n}\n\n/**\n * Download state for resume support\n */\ninterface DownloadState {\n url: string;\n totalSize: number;\n downloadedSize: number;\n chunks: ChunkState[];\n startedAt: number;\n}\n\n/**\n * Chunk state\n */\ninterface ChunkState {\n index: number;\n start: number;\n end: number;\n downloaded: boolean;\n}\n\n// ============================================================================\n// IndexedDB Model Cache\n// ============================================================================\n\nconst DB_NAME = 'edgeflow-model-cache';\nconst DB_VERSION = 1;\nconst STORE_META = 'meta';\nconst STORE_CHUNKS = 'chunks';\nconst STORE_STATE = 'download-state';\n\n/**\n * IndexedDB-based model cache for large files\n */\nclass ModelCache {\n private db: IDBDatabase | null = null;\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n /**\n * Open the database\n */\n private async openDB(): Promise<IDBDatabase> {\n if (this.db) return this.db;\n if (this.dbPromise) return this.dbPromise;\n\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n \n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result;\n \n // Model metadata store\n if (!db.objectStoreNames.contains(STORE_META)) {\n db.createObjectStore(STORE_META, { keyPath: 'url' });\n }\n \n // Chunk data store\n if (!db.objectStoreNames.contains(STORE_CHUNKS)) {\n const chunkStore = db.createObjectStore(STORE_CHUNKS, { keyPath: ['url', 'index'] });\n chunkStore.createIndex('url', 'url', { unique: false });\n }\n \n // Download state store (for resume)\n if (!db.objectStoreNames.contains(STORE_STATE)) {\n db.createObjectStore(STORE_STATE, { keyPath: 'url' });\n }\n };\n\n request.onsuccess = () => {\n this.db = request.result;\n resolve(this.db);\n };\n\n request.onerror = () => reject(request.error);\n });\n\n return this.dbPromise;\n }\n\n /**\n * Get cached model metadata\n */\n async getMeta(url: string): Promise<CachedModelMeta | null> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(url);\n request.onsuccess = () => resolve(request.result ?? null);\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Save model metadata (with quota error handling)\n */\n async saveMeta(meta: CachedModelMeta): Promise<void> {\n try {\n await this.putInStore(STORE_META, meta);\n } catch (err) {\n if (this.isQuotaError(err)) {\n await this.evictOldest(meta.size);\n try {\n await this.putInStore(STORE_META, meta);\n } catch {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded even after eviction; skipping cache.');\n }\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Save a chunk (with quota error handling)\n */\n async saveChunk(url: string, index: number, data: ArrayBuffer): Promise<void> {\n try {\n await this.putInStore(STORE_CHUNKS, { url, index, data });\n } catch (err) {\n if (this.isQuotaError(err)) {\n await this.evictOldest(data.byteLength);\n try {\n await this.putInStore(STORE_CHUNKS, { url, index, data });\n } catch {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded even after eviction; skipping cache for chunk.');\n }\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Generic put helper\n */\n private async putInStore(storeName: string, value: unknown): Promise<void> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n store.put(value);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n /**\n * Detect IndexedDB quota exceeded errors\n */\n private isQuotaError(err: unknown): boolean {\n if (err instanceof DOMException) {\n return err.name === 'QuotaExceededError' || err.code === 22;\n }\n return false;\n }\n\n /**\n * Evict oldest cached models to free space.\n * Deletes models by ascending `cachedAt` until at least `bytesNeeded` is freed.\n */\n async evictOldest(bytesNeeded: number): Promise<void> {\n const db = await this.openDB();\n const allMeta: CachedModelMeta[] = await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.getAll();\n request.onsuccess = () => resolve(request.result ?? []);\n request.onerror = () => reject(request.error);\n });\n\n allMeta.sort((a, b) => a.cachedAt - b.cachedAt);\n\n let freed = 0;\n for (const meta of allMeta) {\n if (freed >= bytesNeeded) break;\n await this.deleteModel(meta.url);\n freed += meta.size;\n }\n }\n\n /**\n * Get all chunks for a URL\n */\n async getChunks(url: string): Promise<ArrayBuffer[]> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_CHUNKS, 'readonly');\n const store = tx.objectStore(STORE_CHUNKS);\n const index = store.index('url');\n const request = index.getAll(url);\n \n request.onsuccess = () => {\n const results = request.result as Array<{ url: string; index: number; data: ArrayBuffer }>;\n // Sort by index and extract data\n results.sort((a, b) => a.index - b.index);\n resolve(results.map(r => r.data));\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Get complete model data (merged chunks)\n */\n async getModel(url: string): Promise<ArrayBuffer | null> {\n const meta = await this.getMeta(url);\n if (!meta || !meta.complete) return null;\n\n const chunks = await this.getChunks(url);\n if (chunks.length === 0) return null;\n\n // Merge chunks\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n \n for (const chunk of chunks) {\n result.set(new Uint8Array(chunk), offset);\n offset += chunk.byteLength;\n }\n\n return result.buffer;\n }\n\n /**\n * Save download state (for resume, with quota handling)\n */\n async saveDownloadState(state: DownloadState): Promise<void> {\n try {\n await this.putInStore(STORE_STATE, state);\n } catch (err) {\n if (this.isQuotaError(err)) {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded saving download state; resume may not work.');\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Get download state\n */\n async getDownloadState(url: string): Promise<DownloadState | null> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_STATE, 'readonly');\n const store = tx.objectStore(STORE_STATE);\n const request = store.get(url);\n request.onsuccess = () => resolve(request.result ?? null);\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Delete download state\n */\n async deleteDownloadState(url: string): Promise<void> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_STATE, 'readwrite');\n const store = tx.objectStore(STORE_STATE);\n store.delete(url);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n /**\n * Delete cached model\n */\n async deleteModel(url: string): Promise<void> {\n const db = await this.openDB();\n \n // Delete metadata\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.delete(url);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n\n // Delete chunks\n const chunks = await this.getChunks(url);\n if (chunks.length > 0) {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_CHUNKS, 'readwrite');\n const store = tx.objectStore(STORE_CHUNKS);\n const index = store.index('url');\n const request = index.openCursor(IDBKeyRange.only(url));\n \n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;\n if (cursor) {\n cursor.delete();\n cursor.continue();\n }\n };\n \n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // Delete download state\n await this.deleteDownloadState(url);\n }\n\n /**\n * Clear all cached models\n */\n async clear(): Promise<void> {\n const db = await this.openDB();\n \n const stores = [STORE_META, STORE_CHUNKS, STORE_STATE];\n for (const storeName of stores) {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n store.clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n }\n\n /**\n * Get cache statistics\n */\n async getStats(): Promise<{ models: number; totalSize: number }> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.getAll();\n \n request.onsuccess = () => {\n const metas = request.result as CachedModelMeta[];\n resolve({\n models: metas.filter(m => m.complete).length,\n totalSize: metas.reduce((sum, m) => sum + (m.complete ? m.size : 0), 0),\n });\n };\n request.onerror = () => reject(request.error);\n });\n }\n}\n\n// Global cache instance\nconst modelCache = new ModelCache();\n\n// ============================================================================\n// Advanced Model Loader\n// ============================================================================\n\n/**\n * Check if server supports Range requests\n */\nasync function supportsRangeRequests(url: string): Promise<{ supports: boolean; size: number; etag?: string }> {\n try {\n const response = await fetch(url, { method: 'HEAD' });\n const acceptRanges = response.headers.get('Accept-Ranges');\n const contentLength = response.headers.get('Content-Length');\n const etag = response.headers.get('ETag') ?? undefined;\n \n return {\n supports: acceptRanges === 'bytes',\n size: contentLength ? parseInt(contentLength, 10) : 0,\n etag,\n };\n } catch {\n return { supports: false, size: 0 };\n }\n}\n\n/**\n * Download a single chunk using Range request\n */\nasync function downloadChunk(\n url: string,\n start: number,\n end: number,\n timeout: number\n): Promise<ArrayBuffer> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n headers: { Range: `bytes=${start}-${end}` },\n signal: controller.signal,\n });\n\n if (response.status !== 206 && response.status !== 200) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return await response.arrayBuffer();\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Download model with sharding and resume support\n */\nasync function downloadWithResume(\n url: string,\n options: ModelLoaderOptions\n): Promise<ArrayBuffer> {\n const {\n chunkSize = 5 * 1024 * 1024, // 5MB\n parallelConnections = 4,\n timeout = 30000,\n onProgress,\n } = options;\n\n // Check server capabilities\n const { supports: supportsRange, size: totalSize, etag } = await supportsRangeRequests(url);\n\n // If no Range support or small file, download normally\n if (!supportsRange || totalSize < chunkSize * 2) {\n return downloadSimple(url, timeout, onProgress);\n }\n\n // Check for existing download state\n let state = await modelCache.getDownloadState(url);\n \n // Initialize or reset state if needed\n if (!state || (etag && state.totalSize !== totalSize)) {\n const numChunks = Math.ceil(totalSize / chunkSize);\n const chunks: ChunkState[] = [];\n \n for (let i = 0; i < numChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize - 1, totalSize - 1);\n chunks.push({ index: i, start, end, downloaded: false });\n }\n \n state = {\n url,\n totalSize,\n downloadedSize: 0,\n chunks,\n startedAt: Date.now(),\n };\n \n // Clear any existing chunks\n await modelCache.deleteModel(url);\n }\n\n // Download remaining chunks\n const pendingChunks = state.chunks.filter(c => !c.downloaded);\n let downloadedSize = state.downloadedSize;\n const startTime = Date.now();\n let lastProgressTime = startTime;\n let lastDownloadedSize = downloadedSize;\n\n // Progress tracking\n const reportProgress = () => {\n if (!onProgress) return;\n \n const now = Date.now();\n const elapsed = (now - lastProgressTime) / 1000;\n const bytesDownloaded = downloadedSize - lastDownloadedSize;\n const speed = elapsed > 0 ? bytesDownloaded / elapsed : 0;\n const remaining = totalSize - downloadedSize;\n const eta = speed > 0 ? (remaining / speed) * 1000 : 0;\n\n onProgress({\n loaded: downloadedSize,\n total: totalSize,\n percent: (downloadedSize / totalSize) * 100,\n speed,\n eta,\n currentChunk: state!.chunks.filter(c => c.downloaded).length,\n totalChunks: state!.chunks.length,\n });\n\n lastProgressTime = now;\n lastDownloadedSize = downloadedSize;\n };\n\n // Download chunks in parallel\n const downloadQueue = [...pendingChunks];\n const inProgress = new Map<number, Promise<void>>();\n\n while (downloadQueue.length > 0 || inProgress.size > 0) {\n // Start new downloads up to parallelConnections limit\n while (downloadQueue.length > 0 && inProgress.size < parallelConnections) {\n const chunk = downloadQueue.shift()!;\n \n const downloadPromise = (async () => {\n try {\n const data = await downloadChunk(url, chunk.start, chunk.end, timeout);\n await modelCache.saveChunk(url, chunk.index, data);\n \n chunk.downloaded = true;\n downloadedSize += data.byteLength;\n \n // Update state periodically\n state!.downloadedSize = downloadedSize;\n await modelCache.saveDownloadState(state!);\n \n reportProgress();\n } finally {\n inProgress.delete(chunk.index);\n }\n })();\n \n inProgress.set(chunk.index, downloadPromise);\n }\n\n // Wait for at least one to complete\n if (inProgress.size > 0) {\n await Promise.race(inProgress.values());\n }\n }\n\n // All chunks downloaded, merge them\n const chunks = await modelCache.getChunks(url);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n \n for (const chunk of chunks) {\n result.set(new Uint8Array(chunk), offset);\n offset += chunk.byteLength;\n }\n\n // Save metadata and cleanup state\n await modelCache.saveMeta({\n url,\n size: totalSize,\n etag,\n cachedAt: Date.now(),\n chunks: chunks.length,\n complete: true,\n });\n await modelCache.deleteDownloadState(url);\n\n return result.buffer;\n}\n\n/**\n * Simple download without sharding\n */\nasync function downloadSimple(\n url: string,\n timeout: number,\n onProgress?: (progress: DownloadProgress) => void\n): Promise<ArrayBuffer> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, { signal: controller.signal });\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('Content-Length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body || !onProgress || total === 0) {\n return await response.arrayBuffer();\n }\n\n // Stream with progress\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n const startTime = Date.now();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n chunks.push(value);\n loaded += value.length;\n\n const elapsed = (Date.now() - startTime) / 1000;\n const speed = elapsed > 0 ? loaded / elapsed : 0;\n const remaining = total - loaded;\n const eta = speed > 0 ? (remaining / speed) * 1000 : 0;\n\n onProgress({\n loaded,\n total,\n percent: (loaded / total) * 100,\n speed,\n eta,\n });\n }\n\n // Merge chunks\n const result = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result.buffer;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n// ============================================================================\n// Preload Manager\n// ============================================================================\n\ninterface PreloadTask {\n url: string;\n priority: number;\n options: ModelLoaderOptions;\n promise: Promise<ArrayBuffer>;\n resolve: (data: ArrayBuffer) => void;\n reject: (error: Error) => void;\n status: 'pending' | 'loading' | 'complete' | 'error';\n}\n\n/**\n * Preload manager for background model loading\n */\nclass PreloadManager {\n private tasks: Map<string, PreloadTask> = new Map();\n private queue: string[] = [];\n private maxConcurrent = 2;\n private activeCount = 0;\n\n /**\n * Preload a model in the background\n */\n preload(url: string, options: PreloadOptions = {}): Promise<ArrayBuffer> {\n // Check if already preloading\n const existing = this.tasks.get(url);\n if (existing) {\n return existing.promise;\n }\n\n // Create task\n let resolve!: (data: ArrayBuffer) => void;\n let reject!: (error: Error) => void;\n \n const promise = new Promise<ArrayBuffer>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n const task: PreloadTask = {\n url,\n priority: options.priority ?? 0,\n options,\n promise,\n resolve,\n reject,\n status: 'pending',\n };\n\n this.tasks.set(url, task);\n \n // Insert into queue based on priority\n const insertIndex = this.queue.findIndex(u => {\n const t = this.tasks.get(u);\n return t && t.priority < task.priority;\n });\n \n if (insertIndex === -1) {\n this.queue.push(url);\n } else {\n this.queue.splice(insertIndex, 0, url);\n }\n\n // Process queue\n this.processQueue();\n\n return promise;\n }\n\n /**\n * Process the preload queue\n */\n private async processQueue(): Promise<void> {\n while (this.queue.length > 0 && this.activeCount < this.maxConcurrent) {\n const url = this.queue.shift();\n if (!url) break;\n\n const task = this.tasks.get(url);\n if (!task || task.status !== 'pending') continue;\n\n this.activeCount++;\n task.status = 'loading';\n\n this.downloadTask(task).finally(() => {\n this.activeCount--;\n this.processQueue();\n });\n }\n }\n\n /**\n * Download a preload task\n */\n private async downloadTask(task: PreloadTask): Promise<void> {\n try {\n const data = await loadModelData(task.url, task.options);\n task.status = 'complete';\n task.resolve(data);\n } catch (error) {\n task.status = 'error';\n task.reject(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Check if a model is preloaded\n */\n isPreloaded(url: string): boolean {\n const task = this.tasks.get(url);\n return task?.status === 'complete';\n }\n\n /**\n * Get preload status\n */\n getStatus(url: string): 'pending' | 'loading' | 'complete' | 'error' | 'not_found' {\n const task = this.tasks.get(url);\n return task?.status ?? 'not_found';\n }\n\n /**\n * Get preloaded model data\n */\n async get(url: string): Promise<ArrayBuffer | null> {\n const task = this.tasks.get(url);\n if (!task) return null;\n \n if (task.status === 'complete' || task.status === 'loading') {\n return task.promise;\n }\n \n return null;\n }\n\n /**\n * Cancel preload\n */\n cancel(url: string): void {\n const task = this.tasks.get(url);\n if (task && task.status === 'pending') {\n this.tasks.delete(url);\n this.queue = this.queue.filter(u => u !== url);\n task.reject(new Error('Preload cancelled'));\n }\n }\n\n /**\n * Clear all preloads\n */\n clear(): void {\n for (const [, task] of this.tasks) {\n if (task.status === 'pending') {\n task.reject(new Error('Preload cleared'));\n }\n }\n this.tasks.clear();\n this.queue = [];\n }\n}\n\n// Global preload manager\nconst preloadManager = new PreloadManager();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load model data with caching, sharding, and resume support\n */\nexport async function loadModelData(\n url: string,\n options: ModelLoaderOptions = {}\n): Promise<ArrayBuffer> {\n const {\n cache = true,\n forceDownload = false,\n resumable = true,\n } = options;\n\n // Check cache first\n if (cache && !forceDownload) {\n const cached = await modelCache.getModel(url);\n if (cached) {\n // Validate: reject cached content that is clearly an HTTP error page\n // (HTML starts with '<', JSON error starts with '{'). Valid ONNX\n // protobuf binaries always have high-bit or control bytes first.\n const firstByte = new Uint8Array(cached)[0];\n const isHtmlOrText = firstByte === 0x3c /* '<' */ || firstByte === 0x7b /* '{' */;\n if (isHtmlOrText || cached.byteLength < 1024) {\n console.warn(`[edgeFlow.js] Cached model for ${url} appears corrupt (${cached.byteLength} bytes, first byte 0x${firstByte?.toString(16)}). Evicting and re-downloading.`);\n await modelCache.deleteModel(url);\n } else {\n console.log(`\u2713 Model loaded from cache: ${url}`);\n options.onProgress?.({\n loaded: cached.byteLength,\n total: cached.byteLength,\n percent: 100,\n speed: 0,\n eta: 0,\n });\n return cached;\n }\n }\n }\n\n // Download with resume support\n let data: ArrayBuffer;\n \n if (resumable) {\n data = await downloadWithResume(url, options);\n } else {\n data = await downloadSimple(url, options.timeout ?? 30000, options.onProgress);\n }\n\n // Cache the result\n if (cache) {\n // For simple downloads, save as single chunk\n if (!resumable) {\n await modelCache.saveChunk(url, 0, data);\n await modelCache.saveMeta({\n url,\n size: data.byteLength,\n cachedAt: Date.now(),\n chunks: 1,\n complete: true,\n });\n }\n }\n\n return data;\n}\n\n/**\n * Preload a model in the background\n */\nexport function preloadModel(url: string, options: PreloadOptions = {}): Promise<ArrayBuffer> {\n return preloadManager.preload(url, options);\n}\n\n/**\n * Preload multiple models\n */\nexport function preloadModels(\n urls: Array<{ url: string; priority?: number }>,\n options: Omit<PreloadOptions, 'priority'> = {}\n): Promise<ArrayBuffer[]> {\n return Promise.all(\n urls.map(({ url, priority }) => preloadManager.preload(url, { ...options, priority }))\n );\n}\n\n/**\n * Check if a model is cached\n */\nexport async function isModelCached(url: string): Promise<boolean> {\n const meta = await modelCache.getMeta(url);\n return meta?.complete ?? false;\n}\n\n/**\n * Get cached model data\n */\nexport async function getCachedModel(url: string): Promise<ArrayBuffer | null> {\n return modelCache.getModel(url);\n}\n\n/**\n * Delete a cached model\n */\nexport async function deleteCachedModel(url: string): Promise<void> {\n return modelCache.deleteModel(url);\n}\n\n/**\n * Clear all cached models\n */\nexport async function clearModelCache(): Promise<void> {\n return modelCache.clear();\n}\n\n/**\n * Get model cache statistics\n */\nexport async function getModelCacheStats(): Promise<{ models: number; totalSize: number }> {\n return modelCache.getStats();\n}\n\n/**\n * Get preload status\n */\nexport function getPreloadStatus(url: string): 'pending' | 'loading' | 'complete' | 'error' | 'not_found' {\n return preloadManager.getStatus(url);\n}\n\n/**\n * Cancel a preload\n */\nexport function cancelPreload(url: string): void {\n preloadManager.cancel(url);\n}\n\n/**\n * Get preloaded model (or wait for preload to complete)\n */\nexport async function getPreloadedModel(url: string): Promise<ArrayBuffer | null> {\n return preloadManager.get(url);\n}\n", "/**\n * edgeFlow.js\n * \n * Lightweight, high-performance browser ML inference framework\n * with native concurrency support.\n * \n * @example\n * ```typescript\n * import { pipeline } from 'edgeflow';\n * \n * // Create a sentiment analysis pipeline\n * const sentiment = await pipeline('sentiment-analysis');\n * \n * // Run inference\n * const result = await sentiment.run('I love this product!');\n * console.log(result); // { label: 'positive', score: 0.98 }\n * \n * // Batch processing\n * const results = await sentiment.run([\n * 'This is amazing!',\n * 'This is terrible.'\n * ]);\n * \n * // Concurrent execution with different models\n * const classifier = await pipeline('text-classification');\n * const extractor = await pipeline('feature-extraction');\n * \n * const [classification, features] = await Promise.all([\n * classifier.run('Sample text'),\n * extractor.run('Sample text')\n * ]);\n * ```\n * \n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Exports\n// ============================================================================\n\n// Types\nexport type {\n // Tensor types\n DataType,\n TypedArray,\n Shape,\n Tensor,\n \n // Runtime types\n RuntimeType,\n RuntimeCapabilities,\n Runtime,\n \n // Model types\n ModelFormat,\n QuantizationType,\n ModelMetadata,\n ModelIOSpec,\n ModelLoadOptions,\n LoadedModel,\n \n // Scheduler types\n TaskPriority,\n TaskStatus,\n InferenceTask,\n SchedulerOptions,\n \n // Memory types\n MemoryStats,\n MemoryPoolConfig,\n \n // Pipeline types\n PipelineTask,\n PipelineConfig,\n PipelineOptions,\n \n // Tokenizer types\n TokenizerConfig,\n TokenizedOutput,\n \n // Event types\n EventType,\n EdgeFlowEvent,\n EventListener,\n \n // Error types\n ErrorCode,\n} from './core/types.js';\n\n// Error class\nexport { EdgeFlowError, ErrorCodes } from './core/types.js';\n\n// Tensor operations\nexport {\n EdgeFlowTensor,\n tensor,\n zeros,\n ones,\n full,\n random,\n randn,\n arange,\n linspace,\n eye,\n add,\n sub,\n mul,\n div,\n matmul,\n softmax,\n relu,\n sigmoid,\n tanh,\n sum,\n mean,\n argmax,\n concat,\n} from './core/tensor.js';\n\n// Scheduler\nexport {\n InferenceScheduler,\n getScheduler,\n setScheduler,\n configureScheduler,\n} from './core/scheduler.js';\n\n// Memory management\nexport {\n MemoryManager,\n MemoryScope,\n ModelCache,\n withMemoryScope,\n withMemoryScopeSync,\n getMemoryManager,\n getMemoryStats,\n release,\n gc,\n} from './core/memory.js';\n\n// Plugin system\nexport {\n registerPlugin,\n getPluginPipeline,\n getPluginMiddleware,\n listPlugins,\n unregisterPlugin,\n type EdgeFlowPlugin,\n type PluginPipelineEntry,\n type PluginBackendEntry,\n type PluginMiddleware,\n} from './core/plugin.js';\n\n// Device profiling\nexport {\n getDeviceProfile,\n recommendQuantization,\n recommendModelVariant,\n resetDeviceProfile,\n type DeviceProfile,\n type DeviceTier,\n type ModelRecommendation,\n} from './core/device-profiler.js';\n\n// Pipeline composition\nexport {\n compose,\n parallel,\n type CompositionStage,\n type CompositionResult,\n type ComposedPipeline,\n} from './core/composer.js';\n\n// Runtime management\nexport {\n RuntimeManager,\n LoadedModelImpl,\n loadModel,\n loadModelFromBuffer,\n runInference,\n runBatchInference,\n getRuntimeManager,\n registerRuntime,\n getBestRuntime,\n getAvailableRuntimes,\n} from './core/runtime.js';\n\n// ============================================================================\n// Backend Exports\n// ============================================================================\n\nexport {\n WebGPURuntime,\n createWebGPURuntime,\n WebNNRuntime,\n createWebNNRuntime,\n WASMRuntime,\n createWASMRuntime,\n registerAllBackends,\n \n // transformers.js adapter\n TransformersAdapterRuntime,\n useTransformersBackend,\n getTransformersAdapter,\n type TransformersAdapterOptions,\n type TransformersPipelineFactory,\n} from './backends/index.js';\n\n// ============================================================================\n// Pipeline Exports\n// ============================================================================\n\nexport {\n // Factory function\n pipeline,\n createPipelines,\n \n // Base classes\n BasePipeline,\n registerPipeline,\n getPipelineFactory,\n \n // Labels\n SENTIMENT_LABELS,\n EMOTION_LABELS,\n IMAGENET_LABELS,\n \n // Result types\n type PipelineResult,\n type TextClassificationResult,\n type FeatureExtractionResult,\n type ImageClassificationResult,\n type ObjectDetectionResult,\n \n // Pipelines\n TextClassificationPipeline,\n SentimentAnalysisPipeline,\n FeatureExtractionPipeline,\n ImageClassificationPipeline,\n TextGenerationPipeline,\n ImageSegmentationPipeline,\n \n // Factory functions\n createTextClassificationPipeline,\n createSentimentAnalysisPipeline,\n createFeatureExtractionPipeline,\n createImageClassificationPipeline,\n createTextGenerationPipeline,\n createImageSegmentationPipeline,\n \n // Options types\n type PipelineFactoryOptions,\n type TextClassificationOptions,\n type FeatureExtractionOptions,\n type ImageClassificationOptions,\n type ImageInput,\n \n // Text Generation types\n type TextGenerationOptions,\n type TextGenerationResult,\n type GenerationStreamEvent,\n type ChatMessage,\n type ChatOptions,\n type ChatTemplateType,\n type LLMLoadProgress,\n \n // Image Segmentation types\n type ImageSegmentationOptions,\n type ImageSegmentationResult,\n type PointPrompt,\n type BoxPrompt,\n type ModelLoadProgress,\n} from './pipelines/index.js';\n\n// ============================================================================\n// Utility Exports\n// ============================================================================\n\nexport {\n // Tokenizer\n Tokenizer,\n createBasicTokenizer,\n loadTokenizer,\n loadTokenizerFromHub,\n type TokenizerModel,\n type TokenizerOptions,\n \n // Preprocessor\n ImagePreprocessor,\n AudioPreprocessor,\n preprocessText,\n createImagePreprocessor,\n createAudioPreprocessor,\n type ImagePreprocessorOptions,\n type AudioPreprocessorOptions,\n type TextPreprocessorOptions,\n \n // Cache\n Cache,\n InferenceCache,\n ModelDownloadCache,\n createCache,\n type CacheStrategy,\n type CacheOptions,\n type CacheStats,\n \n // Model Loader (Preloading, Sharding, Resume, Caching)\n loadModelData,\n preloadModel,\n preloadModels,\n isModelCached,\n getCachedModel,\n deleteCachedModel,\n clearModelCache,\n getModelCacheStats,\n getPreloadStatus,\n cancelPreload,\n getPreloadedModel,\n type DownloadProgress,\n type ModelLoaderOptions,\n type PreloadOptions,\n \n // HuggingFace Hub Integration\n fromHub,\n fromTask,\n downloadModel,\n downloadTokenizer,\n downloadConfig,\n modelExists,\n getModelInfo,\n getDefaultModel,\n POPULAR_MODELS,\n type HubOptions,\n type HubDownloadProgress,\n type ModelConfig,\n type ModelBundle,\n type PopularModelTask,\n} from './utils/index.js';\n\n// ============================================================================\n// Tools Exports\n// ============================================================================\n\nexport {\n // Quantization (basic)\n quantize,\n type QuantizationOptions,\n type QuantizationResult,\n \n // Pruning (basic)\n prune,\n type PruningOptions,\n type PruningResult,\n \n // Analysis (basic)\n analyzeModel,\n type ModelAnalysis,\n \n // Benchmarking (basic)\n benchmark,\n type BenchmarkOptions,\n type BenchmarkResult,\n \n // Export\n exportModel,\n \n // Advanced Quantization\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModelDetailed,\n exportModelAdvanced,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n type QuantizationMethod,\n type AdvancedQuantizationOptions,\n type QuantizationProgress,\n type AdvancedQuantizationResult,\n type LayerQuantizationStats,\n type QuantizationStats,\n type AdvancedPruningOptions,\n type AdvancedPruningResult,\n type DetailedModelAnalysis,\n type ExportFormat,\n type ExportOptions,\n \n // Debugging Tools\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n type DebuggerConfig,\n type TensorInspection,\n type TensorStats,\n type HistogramData,\n type InferenceTrace,\n type OperationTrace,\n type DebugEvent,\n type DebugPerformanceMetrics,\n \n // Performance Monitor\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n type MonitorConfig,\n type PerformanceSample,\n type InferenceMetrics,\n type MemoryMetrics,\n type SystemMetrics,\n type AlertConfig,\n type AlertEvent,\n type WidgetData,\n \n // Benchmark utilities\n runBenchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n type DetailedBenchmarkOptions,\n type DetailedBenchmarkResult,\n type CompareBenchmarkResult,\n type MemoryBenchmarkResult,\n} from './tools/index.js';\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Check if edgeFlow is supported in the current environment\n */\nexport async function isSupported(): Promise<boolean> {\n const runtimes = await getAvailableRuntimes();\n return Array.from(runtimes.values()).some(v => v);\n}\n\n/**\n * Get the best available runtime type\n */\nexport async function getBestRuntimeType(): Promise<RuntimeType | null> {\n const runtimes = await getAvailableRuntimes();\n \n if (runtimes.get('webgpu')) return 'webgpu';\n if (runtimes.get('webnn')) return 'webnn';\n if (runtimes.get('wasm')) return 'wasm';\n \n return null;\n}\n\n/**\n * Preload models for faster subsequent loading\n */\nexport async function preload(\n models: string[]\n): Promise<void> {\n const cache = new ModelDownloadCache();\n \n await Promise.all(models.map(async (url) => {\n if (!(await cache.get(url))) {\n const response = await fetch(url);\n if (response.ok) {\n await cache.put(url, response);\n }\n }\n }));\n}\n\n// ============================================================================\n// Version Info\n// ============================================================================\n\n/**\n * edgeFlow.js version\n */\nexport const VERSION = '0.1.0';\n\n/**\n * Get framework info\n */\nexport async function getInfo(): Promise<{\n version: string;\n runtimes: Record<RuntimeType, boolean>;\n features: string[];\n}> {\n const runtimes = await getAvailableRuntimes();\n \n return {\n version: VERSION,\n runtimes: {\n webgpu: runtimes.get('webgpu') ?? false,\n webnn: runtimes.get('webnn') ?? false,\n wasm: runtimes.get('wasm') ?? false,\n auto: true,\n },\n features: [\n 'concurrent-execution',\n 'batch-processing',\n 'memory-management',\n 'model-caching',\n 'quantization',\n ],\n };\n}\n\n// Re-export RuntimeType for convenience\nimport { RuntimeType } from './core/types.js';\nimport { getAvailableRuntimes } from './core/runtime.js';\nimport { ModelDownloadCache } from './utils/cache.js';\n", "/**\n * edgeFlow.js - Inference Scheduler\n * \n * Task scheduler for managing concurrent inference execution.\n * Supports priority queues, model-level isolation, and batch processing.\n */\n\nimport {\n InferenceTask,\n TaskPriority,\n TaskStatus,\n SchedulerOptions,\n EdgeFlowError,\n ErrorCodes,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\n\n// ============================================================================\n// Task Implementation\n// ============================================================================\n\n/**\n * Internal task implementation\n */\nclass Task<T = unknown> implements InferenceTask<T> {\n readonly id: string;\n readonly modelId: string;\n readonly priority: TaskPriority;\n readonly createdAt: number;\n \n private _status: TaskStatus = 'pending';\n private _startedAt?: number;\n private _completedAt?: number;\n private _result?: T;\n private _error?: Error;\n private _executor: () => Promise<T>;\n private _resolvers: Array<{\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n }> = [];\n private _cancelled = false;\n\n constructor(\n id: string,\n modelId: string,\n priority: TaskPriority,\n executor: () => Promise<T>\n ) {\n this.id = id;\n this.modelId = modelId;\n this.priority = priority;\n this.createdAt = Date.now();\n this._executor = executor;\n }\n\n get status(): TaskStatus {\n return this._status;\n }\n\n get startedAt(): number | undefined {\n return this._startedAt;\n }\n\n get completedAt(): number | undefined {\n return this._completedAt;\n }\n\n get result(): T | undefined {\n return this._result;\n }\n\n get error(): Error | undefined {\n return this._error;\n }\n\n /**\n * Cancel the task\n */\n cancel(): void {\n if (this._status === 'pending') {\n this._cancelled = true;\n this._status = 'cancelled';\n this._completedAt = Date.now();\n \n const cancelError = new EdgeFlowError(\n 'Task was cancelled',\n ErrorCodes.INFERENCE_CANCELLED,\n { taskId: this.id }\n );\n \n for (const { reject } of this._resolvers) {\n reject(cancelError);\n }\n this._resolvers = [];\n }\n }\n\n /**\n * Wait for task completion\n */\n wait(): Promise<T> {\n if (this._status === 'completed') {\n return Promise.resolve(this._result as T);\n }\n \n if (this._status === 'failed') {\n return Promise.reject(this._error);\n }\n \n if (this._status === 'cancelled') {\n return Promise.reject(new EdgeFlowError(\n 'Task was cancelled',\n ErrorCodes.INFERENCE_CANCELLED,\n { taskId: this.id }\n ));\n }\n\n return new Promise<T>((resolve, reject) => {\n this._resolvers.push({ resolve, reject });\n });\n }\n\n /**\n * Execute the task\n */\n async execute(): Promise<void> {\n if (this._cancelled) {\n return;\n }\n\n this._status = 'running';\n this._startedAt = Date.now();\n\n try {\n this._result = await this._executor();\n this._status = 'completed';\n this._completedAt = Date.now();\n \n for (const { resolve } of this._resolvers) {\n resolve(this._result);\n }\n } catch (err) {\n this._error = err instanceof Error ? err : new Error(String(err));\n this._status = 'failed';\n this._completedAt = Date.now();\n \n for (const { reject } of this._resolvers) {\n reject(this._error);\n }\n }\n \n this._resolvers = [];\n }\n}\n\n// ============================================================================\n// Priority Queue Implementation\n// ============================================================================\n\n/**\n * Priority mapping for comparison\n */\nconst PRIORITY_ORDER: Record<TaskPriority, number> = {\n critical: 0,\n high: 1,\n normal: 2,\n low: 3,\n};\n\n/**\n * Priority queue for tasks\n */\nclass PriorityQueue<T extends Task> {\n private items: T[] = [];\n\n get length(): number {\n return this.items.length;\n }\n\n isEmpty(): boolean {\n return this.items.length === 0;\n }\n\n /**\n * Add item to queue with priority ordering\n */\n enqueue(item: T): void {\n let inserted = false;\n \n for (let i = 0; i < this.items.length; i++) {\n const currentItem = this.items[i];\n if (currentItem && PRIORITY_ORDER[item.priority] < PRIORITY_ORDER[currentItem.priority]) {\n this.items.splice(i, 0, item);\n inserted = true;\n break;\n }\n }\n \n if (!inserted) {\n this.items.push(item);\n }\n }\n\n /**\n * Remove and return highest priority item\n */\n dequeue(): T | undefined {\n return this.items.shift();\n }\n\n /**\n * Peek at highest priority item without removing\n */\n peek(): T | undefined {\n return this.items[0];\n }\n\n /**\n * Remove a specific item by ID\n */\n remove(id: string): T | undefined {\n const index = this.items.findIndex(item => item.id === id);\n if (index !== -1) {\n const [removed] = this.items.splice(index, 1);\n return removed;\n }\n return undefined;\n }\n\n /**\n * Get all items\n */\n getAll(): T[] {\n return [...this.items];\n }\n\n /**\n * Clear the queue\n */\n clear(): void {\n this.items = [];\n }\n}\n\n// ============================================================================\n// Batch Collector\n// ============================================================================\n\n/**\n * Collects tasks for batch processing\n */\nclass BatchCollector<T> {\n private tasks: Task<T>[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private readonly maxSize: number;\n private readonly timeout: number;\n private readonly onBatch: (tasks: Task<T>[]) => void;\n\n constructor(\n maxSize: number,\n timeout: number,\n onBatch: (tasks: Task<T>[]) => void\n ) {\n this.maxSize = maxSize;\n this.timeout = timeout;\n this.onBatch = onBatch;\n }\n\n add(task: Task<T>): void {\n this.tasks.push(task);\n\n if (this.tasks.length >= this.maxSize) {\n this.flush();\n } else if (!this.timer) {\n this.timer = setTimeout(() => this.flush(), this.timeout);\n }\n }\n\n flush(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.tasks.length > 0) {\n const batch = this.tasks;\n this.tasks = [];\n this.onBatch(batch);\n }\n }\n\n clear(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.tasks = [];\n }\n}\n\n// ============================================================================\n// Inference Scheduler\n// ============================================================================\n\n// Counter for task IDs\nlet taskIdCounter = 0;\n\n/**\n * Generate unique task ID\n */\nfunction generateTaskId(): string {\n return `task_${++taskIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * Circuit breaker state per model\n */\ninterface CircuitState {\n failures: number;\n state: 'closed' | 'open' | 'half-open';\n lastFailure: number;\n}\n\n/**\n * Default scheduler options\n */\nconst DEFAULT_OPTIONS: Required<SchedulerOptions> = {\n maxConcurrentTasks: 4,\n maxConcurrentPerModel: 1,\n defaultTimeout: 30000,\n enableBatching: false,\n maxBatchSize: 32,\n batchTimeout: 50,\n maxRetries: 0,\n retryBaseDelay: 1000,\n circuitBreaker: false,\n circuitBreakerThreshold: 5,\n circuitBreakerResetTimeout: 30000,\n};\n\n/**\n * InferenceScheduler - Manages concurrent task execution\n * \n * Features:\n * - Priority-based task scheduling\n * - Model-level concurrency control\n * - Optional batch processing\n * - Task cancellation\n * - Event emission\n */\nexport class InferenceScheduler {\n private readonly options: Required<SchedulerOptions>;\n private readonly queues: Map<string, PriorityQueue<Task>> = new Map();\n private readonly runningTasks: Map<string, Set<string>> = new Map();\n private readonly allTasks: Map<string, Task> = new Map();\n private readonly batchers: Map<string, BatchCollector<unknown>> = new Map();\n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n private readonly circuits: Map<string, CircuitState> = new Map();\n private globalRunningCount = 0;\n private isProcessing = false;\n private disposed = false;\n\n constructor(options: SchedulerOptions = {}) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n /**\n * Get circuit breaker state for a model, creating default if absent\n */\n private getCircuit(modelId: string): CircuitState {\n let c = this.circuits.get(modelId);\n if (!c) {\n c = { failures: 0, state: 'closed', lastFailure: 0 };\n this.circuits.set(modelId, c);\n }\n return c;\n }\n\n /**\n * Check if the circuit for a model allows new tasks\n */\n private isCircuitOpen(modelId: string): boolean {\n if (!this.options.circuitBreaker) return false;\n const c = this.getCircuit(modelId);\n if (c.state === 'closed') return false;\n if (c.state === 'open') {\n if (Date.now() - c.lastFailure > this.options.circuitBreakerResetTimeout) {\n c.state = 'half-open';\n return false; // allow one probe\n }\n return true;\n }\n return false; // half-open allows one\n }\n\n /**\n * Record a success for circuit breaker\n */\n private circuitSuccess(modelId: string): void {\n if (!this.options.circuitBreaker) return;\n const c = this.getCircuit(modelId);\n c.failures = 0;\n c.state = 'closed';\n }\n\n /**\n * Record a failure for circuit breaker\n */\n private circuitFailure(modelId: string): void {\n if (!this.options.circuitBreaker) return;\n const c = this.getCircuit(modelId);\n c.failures++;\n c.lastFailure = Date.now();\n if (c.failures >= this.options.circuitBreakerThreshold) {\n c.state = 'open';\n this.emit('inference:error', {\n modelId,\n error: new Error(`Circuit breaker opened after ${c.failures} consecutive failures`),\n });\n }\n }\n\n /**\n * Get or create queue for a model\n */\n private getQueue(modelId: string): PriorityQueue<Task> {\n let queue = this.queues.get(modelId);\n if (!queue) {\n queue = new PriorityQueue<Task>();\n this.queues.set(modelId, queue);\n }\n return queue;\n }\n\n /**\n * Get or create running set for a model\n */\n private getRunningSet(modelId: string): Set<string> {\n let running = this.runningTasks.get(modelId);\n if (!running) {\n running = new Set<string>();\n this.runningTasks.set(modelId, running);\n }\n return running;\n }\n\n /**\n * Check if we can start a new task for a model\n */\n private canStartTask(modelId: string): boolean {\n if (this.globalRunningCount >= this.options.maxConcurrentTasks) {\n return false;\n }\n\n const running = this.runningTasks.get(modelId);\n if (running && running.size >= this.options.maxConcurrentPerModel) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Process pending tasks\n */\n private async processQueue(): Promise<void> {\n if (this.isProcessing || this.disposed) {\n return;\n }\n\n this.isProcessing = true;\n\n try {\n // Find tasks that can be started\n const tasksToStart: Task[] = [];\n\n for (const [modelId, queue] of this.queues) {\n while (!queue.isEmpty() && this.canStartTask(modelId)) {\n const task = queue.dequeue();\n if (task && task.status === 'pending') {\n tasksToStart.push(task);\n \n const running = this.getRunningSet(modelId);\n running.add(task.id);\n this.globalRunningCount++;\n }\n }\n }\n\n // Execute tasks concurrently\n await Promise.all(\n tasksToStart.map(async (task) => {\n this.emit('inference:start', { taskId: task.id, modelId: task.modelId });\n\n try {\n await task.execute();\n this.emit('inference:complete', {\n taskId: task.id,\n modelId: task.modelId,\n duration: (task.completedAt ?? 0) - (task.startedAt ?? 0),\n });\n } catch (error) {\n this.emit('inference:error', {\n taskId: task.id,\n modelId: task.modelId,\n error,\n });\n } finally {\n // Clean up\n const running = this.runningTasks.get(task.modelId);\n if (running) {\n running.delete(task.id);\n }\n this.globalRunningCount--;\n }\n })\n );\n } finally {\n this.isProcessing = false;\n }\n\n // Check if there are more tasks to process\n let hasPending = false;\n for (const queue of this.queues.values()) {\n if (!queue.isEmpty()) {\n hasPending = true;\n break;\n }\n }\n\n if (hasPending) {\n // Use setImmediate-like behavior for next tick processing\n setTimeout(() => this.processQueue(), 0);\n }\n }\n\n /**\n * Schedule a task for execution\n */\n schedule<T>(\n modelId: string,\n executor: () => Promise<T>,\n priority: TaskPriority = 'normal'\n ): InferenceTask<T> {\n if (this.disposed) {\n throw new EdgeFlowError(\n 'Scheduler has been disposed',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n\n if (this.isCircuitOpen(modelId)) {\n throw new EdgeFlowError(\n `Circuit breaker is open for model ${modelId} \u2014 too many consecutive failures. ` +\n `Retry after ${this.options.circuitBreakerResetTimeout}ms.`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId },\n );\n }\n\n // Wrap executor with retry logic\n const maxRetries = this.options.maxRetries;\n const baseDelay = this.options.retryBaseDelay;\n const wrappedExecutor = maxRetries > 0\n ? async (): Promise<T> => {\n let lastError: Error | undefined;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const result = await executor();\n this.circuitSuccess(modelId);\n return result;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n this.circuitFailure(modelId);\n if (attempt < maxRetries) {\n const delay = baseDelay * Math.pow(2, attempt);\n await new Promise(r => setTimeout(r, delay));\n }\n }\n }\n throw lastError!;\n }\n : async (): Promise<T> => {\n try {\n const result = await executor();\n this.circuitSuccess(modelId);\n return result;\n } catch (err) {\n this.circuitFailure(modelId);\n throw err;\n }\n };\n\n const task = new Task<T>(\n generateTaskId(),\n modelId,\n priority,\n wrappedExecutor\n );\n\n this.allTasks.set(task.id, task as Task);\n\n const queue = this.getQueue(modelId);\n queue.enqueue(task as Task);\n\n this.processQueue();\n\n return task;\n }\n\n /**\n * Schedule with timeout\n */\n scheduleWithTimeout<T>(\n modelId: string,\n executor: () => Promise<T>,\n timeout: number = this.options.defaultTimeout,\n priority: TaskPriority = 'normal'\n ): InferenceTask<T> {\n const timeoutExecutor = (): Promise<T> => {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new EdgeFlowError(\n `Task timed out after ${timeout}ms`,\n ErrorCodes.INFERENCE_TIMEOUT,\n { timeout }\n ));\n }, timeout);\n\n executor()\n .then(result => {\n clearTimeout(timer);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timer);\n reject(error);\n });\n });\n };\n\n return this.schedule(modelId, timeoutExecutor, priority);\n }\n\n /**\n * Schedule multiple tasks and wait for all\n */\n async scheduleAll<T>(\n tasks: Array<{\n modelId: string;\n executor: () => Promise<T>;\n priority?: TaskPriority;\n }>\n ): Promise<T[]> {\n const scheduledTasks = tasks.map(({ modelId, executor, priority }) =>\n this.schedule<T>(modelId, executor, priority)\n );\n\n return Promise.all(scheduledTasks.map(task => task.wait()));\n }\n\n /**\n * Get task by ID\n */\n getTask(taskId: string): InferenceTask | undefined {\n return this.allTasks.get(taskId);\n }\n\n /**\n * Cancel a task\n */\n cancelTask(taskId: string): boolean {\n const task = this.allTasks.get(taskId);\n if (task && task.status === 'pending') {\n task.cancel();\n \n // Remove from queue\n for (const queue of this.queues.values()) {\n queue.remove(taskId);\n }\n \n return true;\n }\n return false;\n }\n\n /**\n * Cancel all tasks for a model\n */\n cancelAllForModel(modelId: string): number {\n const queue = this.queues.get(modelId);\n if (!queue) return 0;\n\n let cancelled = 0;\n for (const task of queue.getAll()) {\n if (task.status === 'pending') {\n task.cancel();\n cancelled++;\n }\n }\n queue.clear();\n \n return cancelled;\n }\n\n /**\n * Get statistics\n */\n getStats(): {\n totalTasks: number;\n pendingTasks: number;\n runningTasks: number;\n completedTasks: number;\n failedTasks: number;\n cancelledTasks: number;\n queuedByModel: Record<string, number>;\n } {\n const stats = {\n totalTasks: this.allTasks.size,\n pendingTasks: 0,\n runningTasks: 0,\n completedTasks: 0,\n failedTasks: 0,\n cancelledTasks: 0,\n queuedByModel: {} as Record<string, number>,\n };\n\n for (const task of this.allTasks.values()) {\n switch (task.status) {\n case 'pending':\n stats.pendingTasks++;\n break;\n case 'running':\n stats.runningTasks++;\n break;\n case 'completed':\n stats.completedTasks++;\n break;\n case 'failed':\n stats.failedTasks++;\n break;\n case 'cancelled':\n stats.cancelledTasks++;\n break;\n }\n }\n\n for (const [modelId, queue] of this.queues) {\n stats.queuedByModel[modelId] = queue.length;\n }\n\n return stats;\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n\n /**\n * Clear completed/failed/cancelled tasks from history\n */\n clearHistory(): void {\n for (const [taskId, task] of this.allTasks) {\n if (\n task.status === 'completed' ||\n task.status === 'failed' ||\n task.status === 'cancelled'\n ) {\n this.allTasks.delete(taskId);\n }\n }\n }\n\n /**\n * Dispose the scheduler\n */\n dispose(): void {\n this.disposed = true;\n\n // Cancel all pending tasks\n for (const queue of this.queues.values()) {\n for (const task of queue.getAll()) {\n task.cancel();\n }\n queue.clear();\n }\n\n // Clear batchers\n for (const batcher of this.batchers.values()) {\n batcher.clear();\n }\n\n this.queues.clear();\n this.runningTasks.clear();\n this.allTasks.clear();\n this.batchers.clear();\n this.listeners.clear();\n }\n}\n\n// ============================================================================\n// Global Scheduler Instance\n// ============================================================================\n\nlet globalScheduler: InferenceScheduler | null = null;\n\n/**\n * Get the global scheduler instance\n */\nexport function getScheduler(): InferenceScheduler {\n if (!globalScheduler) {\n globalScheduler = new InferenceScheduler();\n }\n return globalScheduler;\n}\n\n/**\n * Set the global scheduler instance\n */\nexport function setScheduler(scheduler: InferenceScheduler): void {\n if (globalScheduler) {\n globalScheduler.dispose();\n }\n globalScheduler = scheduler;\n}\n\n/**\n * Configure the global scheduler\n */\nexport function configureScheduler(options: SchedulerOptions): void {\n setScheduler(new InferenceScheduler(options));\n}\n", "/**\n * edgeFlow.js - Memory Management\n * \n * Efficient memory management for tensors and models.\n * Features:\n * - Memory pooling\n * - Automatic garbage collection\n * - Memory tracking and statistics\n * - Leak detection\n */\n\nimport {\n Tensor,\n LoadedModel,\n MemoryStats,\n MemoryPoolConfig,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\n\n// ============================================================================\n// Memory Tracking\n// ============================================================================\n\n/**\n * Tracked resource info\n */\ninterface TrackedResource {\n id: string;\n type: 'tensor' | 'model';\n size: number;\n createdAt: number;\n stackTrace?: string;\n}\n\n/**\n * Default memory pool configuration\n */\nconst DEFAULT_POOL_CONFIG: Required<MemoryPoolConfig> = {\n initialSize: 64 * 1024 * 1024, // 64MB\n maxSize: 512 * 1024 * 1024, // 512MB\n growthFactor: 1.5,\n autoGC: true,\n gcThreshold: 0.8, // 80%\n};\n\n// ============================================================================\n// Memory Manager\n// ============================================================================\n\n/**\n * MemoryManager - Central memory management\n * \n * Provides:\n * - Resource tracking\n * - Memory statistics\n * - Garbage collection coordination\n * - Memory warning events\n */\nexport class MemoryManager {\n private static instance: MemoryManager | null = null;\n \n private readonly config: Required<MemoryPoolConfig>;\n private readonly resources: Map<string, TrackedResource> = new Map();\n private readonly disposers: Map<string, () => void> = new Map();\n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n \n private allocated = 0;\n private peak = 0;\n private gcScheduled = false;\n private disposed = false;\n\n private constructor(config: MemoryPoolConfig = {}) {\n this.config = { ...DEFAULT_POOL_CONFIG, ...config };\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): MemoryManager {\n if (!MemoryManager.instance) {\n MemoryManager.instance = new MemoryManager();\n }\n return MemoryManager.instance;\n }\n\n /**\n * Configure the memory manager\n */\n static configure(config: MemoryPoolConfig): void {\n if (MemoryManager.instance) {\n console.warn('MemoryManager already initialized, configuration may not apply');\n }\n MemoryManager.instance = new MemoryManager(config);\n }\n\n /**\n * Track a tensor\n */\n track(tensor: Tensor, disposer?: () => void): void {\n if (this.disposed) return;\n\n const size = this.estimateTensorSize(tensor);\n \n this.resources.set(tensor.id, {\n id: tensor.id,\n type: 'tensor',\n size,\n createdAt: Date.now(),\n stackTrace: this.captureStackTrace(),\n });\n\n if (disposer) {\n this.disposers.set(tensor.id, disposer);\n }\n\n this.allocated += size;\n this.peak = Math.max(this.peak, this.allocated);\n\n this.checkMemoryThreshold();\n }\n\n /**\n * Track a model\n */\n trackModel(model: LoadedModel, disposer?: () => void): void {\n if (this.disposed) return;\n\n const size = model.metadata.sizeBytes;\n \n this.resources.set(model.id, {\n id: model.id,\n type: 'model',\n size,\n createdAt: Date.now(),\n stackTrace: this.captureStackTrace(),\n });\n\n if (disposer) {\n this.disposers.set(model.id, disposer);\n }\n\n this.allocated += size;\n this.peak = Math.max(this.peak, this.allocated);\n\n this.checkMemoryThreshold();\n }\n\n /**\n * Untrack a resource\n */\n untrack(id: string): void {\n const resource = this.resources.get(id);\n if (resource) {\n this.allocated -= resource.size;\n this.resources.delete(id);\n this.disposers.delete(id);\n }\n }\n\n /**\n * Release a resource\n */\n release(resourceOrId: Tensor | LoadedModel | string): void {\n const id = typeof resourceOrId === 'string' ? resourceOrId : resourceOrId.id;\n \n const disposer = this.disposers.get(id);\n if (disposer) {\n try {\n disposer();\n } catch (error) {\n console.error('Error disposing resource:', error);\n }\n }\n\n this.untrack(id);\n }\n\n /**\n * Estimate tensor memory size\n */\n private estimateTensorSize(tensor: Tensor): number {\n const bytesPerElement = this.getBytesPerElement(tensor.dtype);\n return tensor.size * bytesPerElement;\n }\n\n /**\n * Get bytes per element for a data type\n */\n private getBytesPerElement(dtype: string): number {\n switch (dtype) {\n case 'float32':\n return 4;\n case 'float16':\n return 2;\n case 'int32':\n return 4;\n case 'int64':\n return 8;\n case 'uint8':\n case 'int8':\n case 'bool':\n return 1;\n default:\n return 4;\n }\n }\n\n /**\n * Capture stack trace for debugging\n */\n private captureStackTrace(): string | undefined {\n if (typeof Error.captureStackTrace === 'function') {\n const obj: { stack?: string } = {};\n Error.captureStackTrace(obj, this.captureStackTrace);\n return obj.stack;\n }\n return new Error().stack;\n }\n\n /**\n * Check if memory threshold is exceeded\n */\n private checkMemoryThreshold(): void {\n if (!this.config.autoGC) return;\n\n const usage = this.allocated / this.config.maxSize;\n \n if (usage >= this.config.gcThreshold && !this.gcScheduled) {\n this.gcScheduled = true;\n this.emit('memory:warning', {\n allocated: this.allocated,\n maxSize: this.config.maxSize,\n usage,\n });\n\n // Schedule GC on next tick\n setTimeout(() => {\n this.gc();\n this.gcScheduled = false;\n }, 0);\n }\n }\n\n /**\n * Garbage collection helper.\n *\n * Identifies stale resources and optionally evicts them.\n * @param evict - If true, actually dispose stale resources (default: false)\n * @param maxAge - Resources older than this (ms) are considered stale (default: 5 min)\n */\n gc(evict = false, maxAge = 5 * 60 * 1000): void {\n this.emit('memory:gc', { before: this.allocated });\n\n const now = Date.now();\n const staleIds: string[] = [];\n\n for (const [id, resource] of this.resources) {\n if (now - resource.createdAt > maxAge) {\n staleIds.push(id);\n }\n }\n\n if (evict) {\n for (const id of staleIds) {\n this.release(id);\n }\n }\n\n this.emit('memory:gc', {\n after: this.allocated,\n evicted: evict ? staleIds.length : 0,\n potentialCleanup: staleIds.length,\n });\n }\n\n /**\n * Query actual browser memory usage via performance.measureUserAgentSpecificMemory()\n * (Chrome 89+, requires cross-origin isolation). Returns null if unavailable.\n */\n async measureBrowserMemory(): Promise<{\n bytes: number;\n breakdown: Array<{ bytes: number; types: string[] }>;\n } | null> {\n try {\n if (\n typeof performance !== 'undefined' &&\n 'measureUserAgentSpecificMemory' in performance\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = await (performance as any).measureUserAgentSpecificMemory();\n return result;\n }\n } catch {\n // Not available or not cross-origin isolated\n }\n return null;\n }\n\n /**\n * Get the device's total memory hint (navigator.deviceMemory).\n * Returns null if unavailable. Value is in GiB, rounded (e.g. 4, 8).\n */\n getDeviceMemory(): number | null {\n try {\n if (typeof navigator !== 'undefined' && 'deviceMemory' in navigator) {\n return (navigator as { deviceMemory?: number }).deviceMemory ?? null;\n }\n } catch {\n // Not available\n }\n return null;\n }\n\n /**\n * Get memory statistics\n */\n getStats(): MemoryStats {\n let tensorCount = 0;\n let modelCount = 0;\n\n for (const resource of this.resources.values()) {\n if (resource.type === 'tensor') {\n tensorCount++;\n } else {\n modelCount++;\n }\n }\n\n return {\n allocated: this.allocated,\n used: this.allocated, // In JS, allocated = used\n peak: this.peak,\n tensorCount,\n modelCount,\n };\n }\n\n /**\n * Get detailed resource list (for debugging)\n */\n getResourceDetails(): TrackedResource[] {\n return Array.from(this.resources.values());\n }\n\n /**\n * Check for potential memory leaks\n */\n detectLeaks(maxAge: number = 10 * 60 * 1000): TrackedResource[] {\n const now = Date.now();\n const potentialLeaks: TrackedResource[] = [];\n\n for (const resource of this.resources.values()) {\n if (now - resource.createdAt > maxAge) {\n potentialLeaks.push(resource);\n }\n }\n\n return potentialLeaks;\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n\n /**\n * Reset statistics\n */\n resetStats(): void {\n this.peak = this.allocated;\n }\n\n /**\n * Dispose all resources\n */\n disposeAll(): void {\n for (const id of this.resources.keys()) {\n this.release(id);\n }\n }\n\n /**\n * Dispose the manager\n */\n dispose(): void {\n this.disposeAll();\n this.disposed = true;\n this.listeners.clear();\n MemoryManager.instance = null;\n }\n}\n\n// ============================================================================\n// Memory Scope (RAII-like pattern)\n// ============================================================================\n\n/**\n * Memory scope for automatic resource cleanup\n * \n * Usage:\n * ```typescript\n * const result = await withMemoryScope(async (scope) => {\n * const tensor1 = scope.track(createTensor(...));\n * const tensor2 = scope.track(createTensor(...));\n * // Process tensors\n * return computeResult(tensor1, tensor2);\n * });\n * // tensor1 and tensor2 are automatically disposed\n * ```\n */\nexport class MemoryScope {\n private resources: Array<{ dispose: () => void }> = [];\n private children: MemoryScope[] = [];\n private parent: MemoryScope | null = null;\n\n constructor(parent?: MemoryScope) {\n if (parent) {\n this.parent = parent;\n parent.children.push(this);\n }\n }\n\n /**\n * Track a resource in this scope\n */\n track<T extends { dispose: () => void }>(resource: T): T {\n this.resources.push(resource);\n return resource;\n }\n\n /**\n * Create a child scope\n */\n createChild(): MemoryScope {\n return new MemoryScope(this);\n }\n\n /**\n * Keep a resource (don't dispose it when scope ends)\n */\n keep<T extends { dispose: () => void }>(resource: T): T {\n const index = this.resources.indexOf(resource);\n if (index !== -1) {\n this.resources.splice(index, 1);\n }\n return resource;\n }\n\n /**\n * Dispose all resources in this scope\n */\n dispose(): void {\n // Dispose children first\n for (const child of this.children) {\n child.dispose();\n }\n this.children = [];\n\n // Dispose resources in reverse order\n for (let i = this.resources.length - 1; i >= 0; i--) {\n try {\n this.resources[i]?.dispose();\n } catch (error) {\n console.error('Error disposing resource in scope:', error);\n }\n }\n this.resources = [];\n\n // Remove from parent\n if (this.parent) {\n const index = this.parent.children.indexOf(this);\n if (index !== -1) {\n this.parent.children.splice(index, 1);\n }\n this.parent = null;\n }\n }\n}\n\n/**\n * Execute a function with automatic memory cleanup\n */\nexport async function withMemoryScope<T>(\n fn: (scope: MemoryScope) => Promise<T>\n): Promise<T> {\n const scope = new MemoryScope();\n try {\n return await fn(scope);\n } finally {\n scope.dispose();\n }\n}\n\n/**\n * Synchronous version of withMemoryScope\n */\nexport function withMemoryScopeSync<T>(\n fn: (scope: MemoryScope) => T\n): T {\n const scope = new MemoryScope();\n try {\n return fn(scope);\n } finally {\n scope.dispose();\n }\n}\n\n// ============================================================================\n// LRU Cache for Models\n// ============================================================================\n\n/**\n * LRU Cache for loaded models\n */\nexport class ModelCache {\n private readonly maxSize: number;\n private readonly maxModels: number;\n private readonly cache: Map<string, { model: LoadedModel; size: number; lastAccess: number }> = new Map();\n private currentSize = 0;\n\n constructor(options: { maxSize?: number; maxModels?: number } = {}) {\n this.maxSize = options.maxSize ?? 256 * 1024 * 1024; // 256MB default\n this.maxModels = options.maxModels ?? 5;\n }\n\n /**\n * Get a model from cache\n */\n get(key: string): LoadedModel | undefined {\n const entry = this.cache.get(key);\n if (entry) {\n entry.lastAccess = Date.now();\n return entry.model;\n }\n return undefined;\n }\n\n /**\n * Add a model to cache\n */\n set(key: string, model: LoadedModel): void {\n const size = model.metadata.sizeBytes;\n\n // Check if we need to evict\n while (\n (this.currentSize + size > this.maxSize || this.cache.size >= this.maxModels) &&\n this.cache.size > 0\n ) {\n this.evictLRU();\n }\n\n // Add to cache\n this.cache.set(key, {\n model,\n size,\n lastAccess: Date.now(),\n });\n this.currentSize += size;\n }\n\n /**\n * Remove a model from cache\n */\n delete(key: string): boolean {\n const entry = this.cache.get(key);\n if (entry) {\n entry.model.dispose();\n this.currentSize -= entry.size;\n this.cache.delete(key);\n return true;\n }\n return false;\n }\n\n /**\n * Check if model is in cache\n */\n has(key: string): boolean {\n return this.cache.has(key);\n }\n\n /**\n * Evict least recently used model\n */\n private evictLRU(): void {\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.delete(oldestKey);\n }\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n for (const entry of this.cache.values()) {\n entry.model.dispose();\n }\n this.cache.clear();\n this.currentSize = 0;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): { size: number; count: number; maxSize: number; maxModels: number } {\n return {\n size: this.currentSize,\n count: this.cache.size,\n maxSize: this.maxSize,\n maxModels: this.maxModels,\n };\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get memory manager instance\n */\nexport function getMemoryManager(): MemoryManager {\n return MemoryManager.getInstance();\n}\n\n/**\n * Get memory statistics\n */\nexport function getMemoryStats(): MemoryStats {\n return MemoryManager.getInstance().getStats();\n}\n\n/**\n * Release a resource\n */\nexport function release(resource: Tensor | LoadedModel): void {\n MemoryManager.getInstance().release(resource);\n}\n\n/**\n * Force garbage collection hint\n */\nexport function gc(): void {\n MemoryManager.getInstance().gc();\n}\n", "/**\n * edgeFlow.js - Runtime Management\n * \n * Manages runtime backends and automatic selection.\n * Provides unified interface for different compute backends.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\nimport { getScheduler } from './scheduler.js';\nimport { getMemoryManager } from './memory.js';\n\n// ============================================================================\n// Runtime Registry\n// ============================================================================\n\n/**\n * Registered runtime factories\n */\nconst runtimeFactories: Map<RuntimeType, () => Runtime> = new Map();\n\n/**\n * Cached runtime instances\n */\nconst runtimeInstances: Map<RuntimeType, Runtime> = new Map();\n\n/**\n * Runtime priority order (higher priority first)\n */\nconst RUNTIME_PRIORITY: RuntimeType[] = ['webgpu', 'webnn', 'wasm'];\n\n// ============================================================================\n// Runtime Manager\n// ============================================================================\n\n/**\n * RuntimeManager - Manages runtime selection and lifecycle\n * \n * Features:\n * - Automatic best runtime selection\n * - Runtime registration\n * - Capability detection\n * - Fallback handling\n */\nexport class RuntimeManager {\n private static instance: RuntimeManager | null = null;\n \n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n private defaultRuntime: RuntimeType = 'auto';\n\n private constructor() {}\n\n /**\n * Get singleton instance\n */\n static getInstance(): RuntimeManager {\n if (!RuntimeManager.instance) {\n RuntimeManager.instance = new RuntimeManager();\n }\n return RuntimeManager.instance;\n }\n\n /**\n * Register a runtime factory\n */\n register(type: RuntimeType, factory: () => Runtime): void {\n runtimeFactories.set(type, factory);\n }\n\n /**\n * Get a runtime instance\n */\n async getRuntime(type: RuntimeType = 'auto'): Promise<Runtime> {\n if (type === 'auto') {\n return this.getBestRuntime();\n }\n\n // Check if already instantiated\n let runtime = runtimeInstances.get(type);\n if (runtime) {\n return runtime;\n }\n\n // Create new instance\n const factory = runtimeFactories.get(type);\n if (!factory) {\n throw new EdgeFlowError(\n `Runtime '${type}' is not registered`,\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { runtime: type }\n );\n }\n\n runtime = factory();\n \n // Check availability\n const available = await runtime.isAvailable();\n if (!available) {\n throw new EdgeFlowError(\n `Runtime '${type}' is not available in this environment`,\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { runtime: type }\n );\n }\n\n // Initialize\n try {\n await runtime.initialize();\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to initialize runtime '${type}': ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.RUNTIME_INIT_FAILED,\n { runtime: type, error }\n );\n }\n\n runtimeInstances.set(type, runtime);\n this.emit('runtime:ready', { runtime: type });\n\n return runtime;\n }\n\n /**\n * Get the best available runtime\n */\n async getBestRuntime(): Promise<Runtime> {\n for (const type of RUNTIME_PRIORITY) {\n try {\n // Check if already available\n const existing = runtimeInstances.get(type);\n if (existing) {\n return existing;\n }\n\n // Try to create and initialize\n const factory = runtimeFactories.get(type);\n if (!factory) continue;\n\n const runtime = factory();\n const available = await runtime.isAvailable();\n \n if (available) {\n await runtime.initialize();\n runtimeInstances.set(type, runtime);\n this.emit('runtime:ready', { runtime: type });\n return runtime;\n }\n } catch {\n // Try next runtime\n continue;\n }\n }\n\n throw new EdgeFlowError(\n 'No runtime available. Please ensure WebGPU, WebNN, or WASM is supported.',\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { triedRuntimes: RUNTIME_PRIORITY }\n );\n }\n\n /**\n * Check which runtimes are available\n */\n async detectAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {\n const results = new Map<RuntimeType, boolean>();\n\n for (const type of RUNTIME_PRIORITY) {\n const factory = runtimeFactories.get(type);\n if (!factory) {\n results.set(type, false);\n continue;\n }\n\n try {\n const runtime = factory();\n results.set(type, await runtime.isAvailable());\n } catch {\n results.set(type, false);\n }\n }\n\n return results;\n }\n\n /**\n * Get capabilities of a runtime\n */\n async getCapabilities(type: RuntimeType): Promise<RuntimeCapabilities> {\n const runtime = await this.getRuntime(type);\n return runtime.capabilities;\n }\n\n /**\n * Set default runtime\n */\n setDefaultRuntime(type: RuntimeType): void {\n this.defaultRuntime = type;\n }\n\n /**\n * Get default runtime type\n */\n getDefaultRuntimeType(): RuntimeType {\n return this.defaultRuntime;\n }\n\n /**\n * Dispose a specific runtime\n */\n disposeRuntime(type: RuntimeType): void {\n const runtime = runtimeInstances.get(type);\n if (runtime) {\n runtime.dispose();\n runtimeInstances.delete(type);\n }\n }\n\n /**\n * Dispose all runtimes\n */\n disposeAll(): void {\n for (const [type, runtime] of runtimeInstances) {\n runtime.dispose();\n runtimeInstances.delete(type);\n }\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n}\n\n// ============================================================================\n// Model Loader\n// ============================================================================\n\n/**\n * Model instance counter\n */\nlet modelIdCounter = 0;\n\n/**\n * Generate unique model ID\n */\nfunction generateModelId(): string {\n return `model_${++modelIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * LoadedModelImpl - Implementation of LoadedModel interface\n */\nexport class LoadedModelImpl implements LoadedModel {\n readonly id: string;\n readonly metadata: ModelMetadata;\n readonly runtime: RuntimeType;\n \n private _isLoaded = true;\n private readonly _dispose: () => void;\n\n constructor(\n metadata: ModelMetadata,\n runtime: RuntimeType,\n dispose: () => void\n ) {\n this.id = generateModelId();\n this.metadata = metadata;\n this.runtime = runtime;\n this._dispose = dispose;\n }\n\n get isLoaded(): boolean {\n return this._isLoaded;\n }\n\n dispose(): void {\n if (this._isLoaded) {\n this._isLoaded = false;\n this._dispose();\n getMemoryManager().untrack(this.id);\n }\n }\n}\n\n// ============================================================================\n// Model Loading Functions\n// ============================================================================\n\n/**\n * Load model from URL with advanced loading support\n * (caching, sharding, resume download)\n */\nexport async function loadModel(\n url: string,\n options: ModelLoadOptions & { \n runtime?: RuntimeType;\n cache?: boolean;\n resumable?: boolean;\n chunkSize?: number;\n forceDownload?: boolean;\n } = {}\n): Promise<LoadedModel> {\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(options.runtime ?? 'auto');\n\n // Import model loader dynamically to avoid circular dependencies\n const { loadModelData } = await import('../utils/model-loader.js');\n\n // Use advanced model loader with caching and resume support\n const modelData = await loadModelData(url, {\n cache: options.cache ?? true,\n resumable: options.resumable ?? true,\n chunkSize: options.chunkSize,\n forceDownload: options.forceDownload,\n onProgress: options.onProgress ? (progress) => {\n options.onProgress!(progress.percent / 100);\n } : undefined,\n });\n\n // Load into runtime\n const model = await runtime.loadModel(modelData, options);\n\n return model;\n}\n\n/**\n * Load model from ArrayBuffer\n */\nexport async function loadModelFromBuffer(\n data: ArrayBuffer,\n options: ModelLoadOptions & { runtime?: RuntimeType } = {}\n): Promise<LoadedModel> {\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(options.runtime ?? 'auto');\n return runtime.loadModel(data, options);\n}\n\n// ============================================================================\n// Inference Functions\n// ============================================================================\n\n/**\n * Run inference on a model\n */\nexport async function runInference(\n model: LoadedModel,\n inputs: Tensor[]\n): Promise<Tensor[]> {\n if (!model.isLoaded) {\n throw new EdgeFlowError(\n 'Model has been disposed',\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n \n // Use scheduler for execution\n const scheduler = getScheduler();\n const task = scheduler.schedule(model.id, () => runtime.run(model, inputs));\n \n return task.wait();\n}\n\n/**\n * Run inference with named inputs\n */\nexport async function runInferenceNamed(\n model: LoadedModel,\n namedInputs: Map<string, Tensor>\n): Promise<Tensor[]> {\n if (!model.isLoaded) {\n throw new EdgeFlowError(\n 'Model has been disposed',\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n \n // Check if runtime supports named inputs\n if (!('runNamed' in runtime)) {\n throw new EdgeFlowError(\n 'Runtime does not support named inputs',\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id }\n );\n }\n \n // Use scheduler for execution\n const scheduler = getScheduler();\n const task = scheduler.schedule(model.id, () => \n (runtime as any).runNamed(model, namedInputs)\n );\n \n return task.wait() as Promise<Tensor[]>;\n}\n\n/**\n * Run inference with batch processing\n */\nexport async function runBatchInference(\n model: LoadedModel,\n batches: Tensor[][]\n): Promise<Tensor[][]> {\n const scheduler = getScheduler();\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n\n // Schedule all batches\n const tasks = batches.map(inputs =>\n scheduler.schedule(model.id, () => runtime.run(model, inputs))\n );\n\n // Wait for all to complete\n return Promise.all(tasks.map(task => task.wait()));\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get runtime manager instance\n */\nexport function getRuntimeManager(): RuntimeManager {\n return RuntimeManager.getInstance();\n}\n\n/**\n * Register a runtime\n */\nexport function registerRuntime(type: RuntimeType, factory: () => Runtime): void {\n RuntimeManager.getInstance().register(type, factory);\n}\n\n/**\n * Get the best available runtime\n */\nexport async function getBestRuntime(): Promise<Runtime> {\n return RuntimeManager.getInstance().getBestRuntime();\n}\n\n/**\n * Check available runtimes\n */\nexport async function getAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {\n return RuntimeManager.getInstance().detectAvailableRuntimes();\n}\n", "/**\n * edgeFlow.js - Plugin System\n *\n * Register custom pipelines, backends, and middleware via plugins.\n *\n * @example\n * ```typescript\n * import { registerPlugin } from 'edgeflowjs';\n *\n * registerPlugin({\n * name: 'edgeflow-plugin-whisper',\n * version: '1.0.0',\n * pipelines: {\n * 'whisper-transcribe': {\n * factory: (config) => new WhisperPipeline(config),\n * },\n * },\n * });\n *\n * // Now available via pipeline('whisper-transcribe')\n * ```\n */\n\nimport type { PipelineConfig, Runtime, RuntimeType } from './types.js';\nimport { registerRuntime } from './runtime.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A pipeline factory registered by a plugin.\n */\nexport interface PluginPipelineEntry {\n /** Factory that creates a pipeline instance */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory: (config: PipelineConfig) => any;\n /** Optional description */\n description?: string;\n}\n\n/**\n * A backend registered by a plugin.\n */\nexport interface PluginBackendEntry {\n /** Factory that creates a runtime instance */\n factory: () => Runtime;\n /** Optional description */\n description?: string;\n}\n\n/**\n * Middleware that runs before/after inference.\n */\nexport interface PluginMiddleware {\n /** Unique name */\n name: string;\n /** Called before inference with (model, inputs). Return modified inputs. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n before?: (ctx: { modelId: string; inputs: any }) => any | Promise<any>;\n /** Called after inference with (model, outputs). Return modified outputs. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n after?: (ctx: { modelId: string; outputs: any }) => any | Promise<any>;\n}\n\n/**\n * Plugin definition.\n */\nexport interface EdgeFlowPlugin {\n /** Unique plugin name (e.g. 'edgeflow-plugin-whisper') */\n name: string;\n /** Plugin version (semver) */\n version: string;\n /** Pipelines contributed by this plugin */\n pipelines?: Record<string, PluginPipelineEntry>;\n /** Backends contributed by this plugin */\n backends?: Record<string, PluginBackendEntry>;\n /** Middleware contributed by this plugin */\n middleware?: PluginMiddleware[];\n /** Called once when the plugin is registered */\n setup?: () => void | Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nconst registeredPlugins = new Map<string, EdgeFlowPlugin>();\nconst pluginPipelines = new Map<string, PluginPipelineEntry>();\nconst pluginMiddleware: PluginMiddleware[] = [];\n\n/**\n * Register a plugin. Pipelines and backends are made available immediately.\n */\nexport async function registerPlugin(plugin: EdgeFlowPlugin): Promise<void> {\n if (registeredPlugins.has(plugin.name)) {\n console.warn(`[edgeFlow.js] Plugin \"${plugin.name}\" is already registered \u2014 skipping.`);\n return;\n }\n\n // Run setup hook\n if (plugin.setup) {\n await plugin.setup();\n }\n\n // Register pipelines\n if (plugin.pipelines) {\n for (const [task, entry] of Object.entries(plugin.pipelines)) {\n pluginPipelines.set(task, entry);\n }\n }\n\n // Register backends\n if (plugin.backends) {\n for (const [name, entry] of Object.entries(plugin.backends)) {\n registerRuntime(name as RuntimeType, entry.factory);\n }\n }\n\n // Register middleware\n if (plugin.middleware) {\n pluginMiddleware.push(...plugin.middleware);\n }\n\n registeredPlugins.set(plugin.name, plugin);\n}\n\n/**\n * Look up a pipeline factory registered by any plugin.\n * Returns undefined if no plugin provides this task.\n */\nexport function getPluginPipeline(task: string): PluginPipelineEntry | undefined {\n return pluginPipelines.get(task);\n}\n\n/**\n * Get all registered middleware.\n */\nexport function getPluginMiddleware(): ReadonlyArray<PluginMiddleware> {\n return pluginMiddleware;\n}\n\n/**\n * List all registered plugins.\n */\nexport function listPlugins(): Array<{ name: string; version: string }> {\n return Array.from(registeredPlugins.values()).map(p => ({\n name: p.name,\n version: p.version,\n }));\n}\n\n/**\n * Unregister a plugin by name.\n */\nexport function unregisterPlugin(name: string): boolean {\n const plugin = registeredPlugins.get(name);\n if (!plugin) return false;\n\n // Remove pipelines\n if (plugin.pipelines) {\n for (const task of Object.keys(plugin.pipelines)) {\n pluginPipelines.delete(task);\n }\n }\n\n // Remove middleware\n if (plugin.middleware) {\n for (const mw of plugin.middleware) {\n const idx = pluginMiddleware.indexOf(mw);\n if (idx !== -1) pluginMiddleware.splice(idx, 1);\n }\n }\n\n registeredPlugins.delete(name);\n return true;\n}\n", "/**\n * edgeFlow.js - Device Profiler\n *\n * Automatically profiles the current device and recommends optimal model\n * variants (quantization level, batch size, execution provider).\n *\n * @example\n * ```typescript\n * import { getDeviceProfile, recommendQuantization } from 'edgeflowjs';\n *\n * const profile = await getDeviceProfile();\n * console.log(profile.tier); // 'high' | 'medium' | 'low'\n *\n * const quant = recommendQuantization(profile);\n * console.log(quant); // 'fp16' | 'int8' | 'int4'\n * ```\n */\n\nimport type { QuantizationType } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Device capability tier.\n */\nexport type DeviceTier = 'high' | 'medium' | 'low';\n\n/**\n * Profiled device information.\n */\nexport interface DeviceProfile {\n /** Capability tier */\n tier: DeviceTier;\n /** Number of logical CPU cores */\n cores: number;\n /** Device memory in GiB (navigator.deviceMemory, may be null) */\n memoryGiB: number | null;\n /** Whether WebGPU is available */\n webgpu: boolean;\n /** Whether WebNN is available */\n webnn: boolean;\n /** Recommended max batch size */\n recommendedBatchSize: number;\n /** Recommended concurrency limit */\n recommendedConcurrency: number;\n /** Whether the device is mobile */\n mobile: boolean;\n /** Raw GPU adapter info (if WebGPU available) */\n gpuInfo?: string;\n}\n\n/**\n * Model variant recommendation.\n */\nexport interface ModelRecommendation {\n /** Recommended quantization */\n quantization: QuantizationType;\n /** Recommended execution provider */\n executionProvider: 'webgpu' | 'wasm';\n /** Recommended batch size */\n batchSize: number;\n /** Whether to enable worker-based inference */\n useWorker: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Profiling\n// ---------------------------------------------------------------------------\n\nlet cachedProfile: DeviceProfile | null = null;\n\n/**\n * Profile the current device. Results are cached after the first call.\n */\nexport async function getDeviceProfile(): Promise<DeviceProfile> {\n if (cachedProfile) return cachedProfile;\n\n const cores = typeof navigator !== 'undefined'\n ? navigator.hardwareConcurrency ?? 2\n : 2;\n\n const memoryGiB = typeof navigator !== 'undefined' && 'deviceMemory' in navigator\n ? (navigator as { deviceMemory?: number }).deviceMemory ?? null\n : null;\n\n const mobile = typeof navigator !== 'undefined'\n ? /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)\n : false;\n\n let webgpu = false;\n let gpuInfo: string | undefined;\n if (typeof navigator !== 'undefined' && 'gpu' in navigator) {\n try {\n const adapter = await (navigator as Navigator & { gpu: { requestAdapter: () => Promise<unknown> } }).gpu.requestAdapter();\n webgpu = adapter != null;\n if (adapter && typeof adapter === 'object') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const info = (adapter as any)['info'];\n if (info) {\n gpuInfo = `${info['vendor'] ?? ''} ${info['architecture'] ?? ''}`.trim() || undefined;\n }\n } catch {\n // info not available\n }\n }\n } catch {\n // WebGPU not available\n }\n }\n\n let webnn = false;\n if (typeof navigator !== 'undefined' && 'ml' in navigator) {\n try {\n const ml = (navigator as Navigator & { ml?: { createContext: () => Promise<unknown> } }).ml;\n if (ml) {\n const ctx = await ml.createContext();\n webnn = ctx != null;\n }\n } catch {\n // WebNN not available\n }\n }\n\n // Determine tier\n let tier: DeviceTier;\n if (webgpu && cores >= 8 && (memoryGiB === null || memoryGiB >= 8)) {\n tier = 'high';\n } else if (cores >= 4 && (memoryGiB === null || memoryGiB >= 4)) {\n tier = 'medium';\n } else {\n tier = 'low';\n }\n\n // Mobile devices get capped even if specs look good\n if (mobile && tier === 'high') {\n tier = 'medium';\n }\n\n const recommendedBatchSize = tier === 'high' ? 32 : tier === 'medium' ? 8 : 1;\n const recommendedConcurrency = tier === 'high' ? 4 : tier === 'medium' ? 2 : 1;\n\n cachedProfile = {\n tier,\n cores,\n memoryGiB,\n webgpu,\n webnn,\n recommendedBatchSize,\n recommendedConcurrency,\n mobile,\n gpuInfo,\n };\n\n return cachedProfile;\n}\n\n/**\n * Recommend the best quantization level for the current device.\n */\nexport function recommendQuantization(profile: DeviceProfile): QuantizationType {\n if (profile.tier === 'high' && profile.webgpu) return 'float16';\n if (profile.tier === 'medium') return 'int8';\n return 'int8'; // low-tier: most aggressive\n}\n\n/**\n * Get full model variant recommendations for the current device.\n */\nexport async function recommendModelVariant(): Promise<ModelRecommendation> {\n const profile = await getDeviceProfile();\n\n return {\n quantization: recommendQuantization(profile),\n executionProvider: profile.webgpu ? 'webgpu' : 'wasm',\n batchSize: profile.recommendedBatchSize,\n useWorker: profile.cores >= 4,\n };\n}\n\n/**\n * Reset the cached profile (useful for testing).\n */\nexport function resetDeviceProfile(): void {\n cachedProfile = null;\n}\n", "/**\n * edgeFlow.js - WebGPU Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * WebGPU and creates compute pipelines but does not perform real model\n * inference. For GPU-accelerated inference, use the ONNX Runtime backend\n * which supports WebGPU via its execution providers.\n * \n * This backend is intended for future custom WebGPU compute shader\n * implementations that bypass ONNX Runtime for specialized ops.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WebGPU Type Declarations\n// ============================================================================\n\n// Declare WebGPU types for environments without @webgpu/types\ndeclare global {\n interface Navigator {\n gpu?: GPU;\n }\n \n interface GPU {\n requestAdapter(options?: GPURequestAdapterOptions): Promise<GPUAdapter | null>;\n }\n \n interface GPURequestAdapterOptions {\n powerPreference?: 'low-power' | 'high-performance';\n }\n \n interface GPUAdapter {\n requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>;\n }\n \n interface GPUDeviceDescriptor {\n requiredFeatures?: string[];\n requiredLimits?: Record<string, number>;\n }\n \n interface GPUDevice {\n limits: GPULimits;\n lost: Promise<GPUDeviceLostInfo>;\n createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer;\n createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule;\n createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor): GPUBindGroupLayout;\n createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor): GPUPipelineLayout;\n createComputePipeline(descriptor: GPUComputePipelineDescriptor): GPUComputePipeline;\n destroy(): void;\n }\n \n interface GPULimits {\n maxBufferSize: number;\n }\n \n interface GPUDeviceLostInfo {\n message: string;\n reason: string;\n }\n \n interface GPUBuffer {\n destroy(): void;\n }\n \n interface GPUShaderModule {}\n interface GPUBindGroupLayout {}\n interface GPUPipelineLayout {}\n interface GPUComputePipeline {}\n \n interface GPUBufferDescriptor {\n size: number;\n usage: number;\n }\n \n interface GPUShaderModuleDescriptor {\n code: string;\n }\n \n interface GPUBindGroupLayoutDescriptor {\n entries: GPUBindGroupLayoutEntry[];\n }\n \n interface GPUBindGroupLayoutEntry {\n binding: number;\n visibility: number;\n buffer?: { type: string };\n }\n \n interface GPUPipelineLayoutDescriptor {\n bindGroupLayouts: GPUBindGroupLayout[];\n }\n \n interface GPUComputePipelineDescriptor {\n layout: GPUPipelineLayout;\n compute: {\n module: GPUShaderModule;\n entryPoint: string;\n };\n }\n}\n\n// WebGPU constants\nconst GPUBufferUsage = {\n STORAGE: 0x0080,\n COPY_SRC: 0x0004,\n COPY_DST: 0x0008,\n MAP_READ: 0x0001,\n};\n\nconst GPUShaderStage = {\n COMPUTE: 0x0004,\n};\n\n// ============================================================================\n// WebGPU Types\n// ============================================================================\n\n/**\n * WebGPU model data structure\n */\ninterface WebGPUModelData {\n /** Shader modules */\n shaders: Map<string, GPUShaderModule>;\n /** Compute pipelines */\n pipelines: Map<string, GPUComputePipeline>;\n /** Weight buffers */\n weights: Map<string, GPUBuffer>;\n /** Bind group layouts */\n bindGroupLayouts: GPUBindGroupLayout[];\n /** Model configuration */\n config: ModelConfig;\n}\n\n/**\n * Model configuration from model file\n */\ninterface ModelConfig {\n name: string;\n version: string;\n layers: LayerConfig[];\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n/**\n * Layer configuration\n */\ninterface LayerConfig {\n name: string;\n type: string;\n inputs: string[];\n outputs: string[];\n params: Record<string, unknown>;\n}\n\n// ============================================================================\n// WebGPU Runtime Implementation\n// ============================================================================\n\n/**\n * WebGPURuntime - GPU-accelerated inference runtime\n */\nexport class WebGPURuntime implements Runtime {\n readonly name: RuntimeType = 'webgpu';\n \n private adapter: GPUAdapter | null = null;\n private device: GPUDevice | null = null;\n private models: Map<string, WebGPUModelData> = new Map();\n private initialized = false;\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: false,\n maxBatchSize: 64,\n availableMemory: this.device?.limits.maxBufferSize ?? 256 * 1024 * 1024,\n };\n }\n\n /**\n * Check if WebGPU is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof navigator === 'undefined') return false;\n if (!navigator.gpu) return false;\n\n try {\n const adapter = await navigator.gpu.requestAdapter();\n return adapter !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WebGPU runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n if (!navigator.gpu) {\n throw new EdgeFlowError(\n 'WebGPU is not supported in this browser',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // Request adapter\n this.adapter = await navigator.gpu.requestAdapter({\n powerPreference: 'high-performance',\n });\n\n if (!this.adapter) {\n throw new EdgeFlowError(\n 'Failed to get WebGPU adapter',\n ErrorCodes.RUNTIME_INIT_FAILED\n );\n }\n\n // Request device\n this.device = await this.adapter.requestDevice({\n requiredFeatures: [],\n requiredLimits: {},\n });\n\n // Handle device loss\n this.device.lost.then((info: GPUDeviceLostInfo) => {\n console.error('WebGPU device was lost:', info.message);\n this.initialized = false;\n this.device = null;\n });\n\n this.initialized = true;\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model data\n const config = this.parseModelData(modelData);\n\n // Create shader modules and pipelines\n const webgpuData: WebGPUModelData = {\n shaders: new Map(),\n pipelines: new Map(),\n weights: new Map(),\n bindGroupLayouts: [],\n config,\n };\n\n // Extract and upload weights\n await this.uploadWeights(modelData, webgpuData);\n\n // Create compute pipelines for each layer\n await this.createPipelines(webgpuData);\n\n // Generate model ID\n const modelId = `webgpu_${Date.now().toString(36)}`;\n this.models.set(modelId, webgpuData);\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version,\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'webgpu',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n\n // For now, use a simple fallback implementation\n // In a full implementation, this would execute the compute pipelines\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model (simplified implementation)\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n // This is a simplified implementation\n // A full implementation would:\n // 1. Upload input tensors to GPU buffers\n // 2. Execute compute pipelines in topological order\n // 3. Read back output tensors\n\n const device = this.device!;\n const outputs: Tensor[] = [];\n\n for (const outputSpec of metadata.outputs) {\n // Create output buffer\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n const outputBuffer = device.createBuffer({\n size: outputSize * 4, // float32\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n\n // Create staging buffer for readback\n const stagingBuffer = device.createBuffer({\n size: outputSize * 4,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n\n // For now, return zeros (placeholder)\n // In production, execute actual compute pipelines\n const outputData = new Float32Array(outputSize);\n \n // Simulate some computation based on inputs\n if (inputs.length > 0 && inputs[0]) {\n const inputData = inputs[0].toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = (inputData[i] ?? 0);\n }\n }\n\n outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));\n\n // Cleanup\n outputBuffer.destroy();\n stagingBuffer.destroy();\n }\n\n return outputs;\n }\n\n /**\n * Parse model data\n */\n private parseModelData(data: ArrayBuffer): ModelConfig {\n // Try to parse as JSON first (for our custom format)\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));\n \n // Check if it starts with JSON\n if (text.trim().startsWith('{')) {\n // Find the JSON header end\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) jsonEnd = data.byteLength;\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as ModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n // Return default config for unknown formats\n return {\n name: 'unknown',\n version: '1.0.0',\n layers: [],\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Upload weights to GPU\n */\n private async uploadWeights(\n _data: ArrayBuffer,\n modelData: WebGPUModelData\n ): Promise<void> {\n const device = this.device!;\n\n // In a full implementation, parse weight data from the model file\n // and upload to GPU buffers\n \n // Placeholder: create empty weight buffer\n const weightsBuffer = device.createBuffer({\n size: 1024,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n\n modelData.weights.set('default', weightsBuffer);\n }\n\n /**\n * Create compute pipelines\n */\n private async createPipelines(modelData: WebGPUModelData): Promise<void> {\n const device = this.device!;\n\n // Create a general-purpose compute shader\n const shaderCode = /* wgsl */ `\n @group(0) @binding(0) var<storage, read> input: array<f32>;\n @group(0) @binding(1) var<storage, read_write> output: array<f32>;\n \n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx < arrayLength(&input)) {\n output[idx] = input[idx];\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({\n code: shaderCode,\n });\n\n modelData.shaders.set('default', shaderModule);\n\n // Create bind group layout\n const bindGroupLayout = device.createBindGroupLayout({\n entries: [\n {\n binding: 0,\n visibility: GPUShaderStage.COMPUTE,\n buffer: { type: 'read-only-storage' },\n },\n {\n binding: 1,\n visibility: GPUShaderStage.COMPUTE,\n buffer: { type: 'storage' },\n },\n ],\n });\n\n modelData.bindGroupLayouts.push(bindGroupLayout);\n\n // Create pipeline layout\n const pipelineLayout = device.createPipelineLayout({\n bindGroupLayouts: [bindGroupLayout],\n });\n\n // Create compute pipeline\n const pipeline = device.createComputePipeline({\n layout: pipelineLayout,\n compute: {\n module: shaderModule,\n entryPoint: 'main',\n },\n });\n\n modelData.pipelines.set('default', pipeline);\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n const modelData = this.models.get(modelId);\n if (modelData) {\n // Destroy GPU buffers\n for (const buffer of modelData.weights.values()) {\n buffer.destroy();\n }\n this.models.delete(modelId);\n }\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.device) {\n throw new EdgeFlowError(\n 'WebGPU runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Unload all models\n for (const modelId of this.models.keys()) {\n this.unloadModel(modelId);\n }\n\n // Destroy device\n if (this.device) {\n this.device.destroy();\n this.device = null;\n }\n\n this.adapter = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WebGPU runtime factory\n */\nexport function createWebGPURuntime(): Runtime {\n return new WebGPURuntime();\n}\n", "/**\n * edgeFlow.js - WebNN Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * a WebNN context but does not perform real model inference or graph building.\n * For hardware-accelerated inference, use the ONNX Runtime backend which\n * supports WebNN via its execution providers when available.\n * \n * This backend is intended for future native WebNN graph building support.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WebNN Type Definitions (since WebNN types may not be globally available)\n// ============================================================================\n\n/**\n * WebNN context type\n */\ntype MLContextType = 'default' | 'gpu' | 'cpu' | 'npu';\n\n/**\n * WebNN operand descriptor\n */\ninterface MLOperandDescriptor {\n dataType: 'float32' | 'float16' | 'int32' | 'uint32' | 'int8' | 'uint8';\n dimensions: number[];\n}\n\n/**\n * WebNN context options\n */\ninterface MLContextOptions {\n deviceType?: MLContextType;\n powerPreference?: 'default' | 'high-performance' | 'low-power';\n}\n\n// Extend Navigator for WebNN\ndeclare global {\n interface Navigator {\n ml?: {\n createContext(options?: MLContextOptions): Promise<MLContext>;\n };\n }\n \n interface MLContext {\n compute(\n graph: MLGraph,\n inputs: Record<string, ArrayBufferView>,\n outputs: Record<string, ArrayBufferView>\n ): Promise<Record<string, ArrayBufferView>>;\n }\n \n interface MLGraph {\n // Graph interface\n }\n \n interface MLGraphBuilder {\n input(name: string, desc: MLOperandDescriptor): MLOperand;\n constant(desc: MLOperandDescriptor, data: ArrayBufferView): MLOperand;\n build(outputs: Record<string, MLOperand>): Promise<MLGraph>;\n \n // Operations\n add(a: MLOperand, b: MLOperand): MLOperand;\n sub(a: MLOperand, b: MLOperand): MLOperand;\n mul(a: MLOperand, b: MLOperand): MLOperand;\n div(a: MLOperand, b: MLOperand): MLOperand;\n matmul(a: MLOperand, b: MLOperand): MLOperand;\n relu(x: MLOperand): MLOperand;\n sigmoid(x: MLOperand): MLOperand;\n tanh(x: MLOperand): MLOperand;\n softmax(x: MLOperand): MLOperand;\n reshape(x: MLOperand, newShape: number[]): MLOperand;\n transpose(x: MLOperand, permutation?: number[]): MLOperand;\n }\n \n interface MLOperand {\n // Operand interface\n }\n}\n\n// ============================================================================\n// WebNN Model Data\n// ============================================================================\n\n/**\n * WebNN model data structure\n */\ninterface WebNNModelData {\n /** Compiled graph */\n graph: MLGraph;\n /** Graph builder (for potential graph modifications) */\n builder: MLGraphBuilder;\n /** Input names and shapes */\n inputNames: string[];\n /** Output names and shapes */\n outputNames: string[];\n /** Model configuration */\n config: WebNNModelConfig;\n}\n\n/**\n * Model configuration\n */\ninterface WebNNModelConfig {\n name: string;\n version: string;\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n// ============================================================================\n// WebNN Runtime Implementation\n// ============================================================================\n\n/**\n * WebNNRuntime - Browser-native neural network runtime\n */\nexport class WebNNRuntime implements Runtime {\n readonly name: RuntimeType = 'webnn';\n \n private context: MLContext | null = null;\n private models: Map<string, WebNNModelData> = new Map();\n private initialized = false;\n private deviceType: MLContextType = 'default';\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: false,\n maxBatchSize: 32,\n availableMemory: 256 * 1024 * 1024, // Estimated\n };\n }\n\n /**\n * Check if WebNN is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof navigator === 'undefined') return false;\n if (!navigator.ml) return false;\n\n try {\n const context = await navigator.ml.createContext({ deviceType: 'default' });\n return context !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WebNN runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n if (!navigator.ml) {\n throw new EdgeFlowError(\n 'WebNN is not supported in this browser',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // Try to get GPU context first, fallback to CPU\n try {\n this.context = await navigator.ml.createContext({ \n deviceType: 'gpu',\n powerPreference: 'high-performance',\n });\n this.deviceType = 'gpu';\n } catch {\n try {\n this.context = await navigator.ml.createContext({ deviceType: 'cpu' });\n this.deviceType = 'cpu';\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to create WebNN context: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.RUNTIME_INIT_FAILED\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model configuration\n const config = this.parseModelConfig(modelData);\n\n // Note: Full WebNN implementation would build the graph here\n // This is a placeholder that creates minimal metadata\n \n const modelId = `webnn_${Date.now().toString(36)}`;\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version || '1.0.0',\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'webnn',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n\n // Simplified implementation - in production, would use compiled graph\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model (simplified implementation)\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n const outputs: Tensor[] = [];\n\n // For each expected output\n for (const outputSpec of metadata.outputs) {\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n const outputData = new Float32Array(outputSize);\n\n // Simple passthrough for demo (real impl would use WebNN compute)\n if (inputs.length > 0 && inputs[0]) {\n const inputData = inputs[0].toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = inputData[i] ?? 0;\n }\n }\n\n outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));\n }\n\n return outputs;\n }\n\n /**\n * Parse model configuration\n */\n private parseModelConfig(data: ArrayBuffer): WebNNModelConfig {\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));\n \n if (text.trim().startsWith('{')) {\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) jsonEnd = data.byteLength;\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as WebNNModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n return {\n name: 'unknown',\n version: '1.0.0',\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n this.models.delete(modelId);\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.context) {\n throw new EdgeFlowError(\n 'WebNN runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Get device type\n */\n getDeviceType(): MLContextType {\n return this.deviceType;\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n this.models.clear();\n this.context = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WebNN runtime factory\n */\nexport function createWebNNRuntime(): Runtime {\n return new WebNNRuntime();\n}\n", "/**\n * edgeFlow.js - WebAssembly Backend\n * \n * Pure WASM runtime for universal browser support.\n * Features:\n * - Universal compatibility\n * - SIMD acceleration when available\n * - Memory-efficient execution\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor, softmax as tensorSoftmax, relu as tensorRelu, sigmoid as tensorSigmoid } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WASM Types\n// ============================================================================\n\n/**\n * WASM module instance\n */\ninterface WASMModule {\n memory: WebAssembly.Memory;\n exports: WASMExports;\n}\n\n/**\n * WASM exported functions\n */\ninterface WASMExports {\n // Memory management\n malloc(size: number): number;\n free(ptr: number): void;\n \n // Tensor operations\n matmul_f32(\n a: number, aRows: number, aCols: number,\n b: number, bRows: number, bCols: number,\n out: number\n ): void;\n \n add_f32(a: number, b: number, out: number, size: number): void;\n mul_f32(a: number, b: number, out: number, size: number): void;\n relu_f32(input: number, output: number, size: number): void;\n sigmoid_f32(input: number, output: number, size: number): void;\n softmax_f32(input: number, output: number, size: number): void;\n \n // SIMD variants (when available)\n matmul_f32_simd?(\n a: number, aRows: number, aCols: number,\n b: number, bRows: number, bCols: number,\n out: number\n ): void;\n}\n\n/**\n * WASM model data structure\n */\ninterface WASMModelData {\n /** Weight buffers */\n weights: Map<string, { ptr: number; size: number; data: Float32Array }>;\n /** Model configuration */\n config: WASMModelConfig;\n /** Layer execution order */\n executionOrder: string[];\n}\n\n/**\n * Model configuration\n */\ninterface WASMModelConfig {\n name: string;\n version: string;\n layers: WASMLayerConfig[];\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n/**\n * Layer configuration\n */\ninterface WASMLayerConfig {\n name: string;\n type: string;\n inputShape: number[];\n outputShape: number[];\n weights?: string[];\n params?: Record<string, unknown>;\n}\n\n// ============================================================================\n// WASM Runtime Implementation\n// ============================================================================\n\n/**\n * WASMRuntime - Pure WebAssembly inference runtime\n */\nexport class WASMRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm';\n \n private module: WASMModule | null = null;\n private simdSupported = false;\n private models: Map<string, WASMModelData> = new Map();\n private initialized = false;\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: false, // WASM is single-threaded by default\n quantization: true,\n float16: false,\n dynamicShapes: true,\n maxBatchSize: 16,\n availableMemory: 128 * 1024 * 1024, // 128MB default\n };\n }\n\n /**\n * Check if WASM is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof WebAssembly === 'undefined') return false;\n\n try {\n // Check if we can instantiate a minimal WASM module\n const bytes = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, // Magic number\n 0x01, 0x00, 0x00, 0x00, // Version\n ]);\n await WebAssembly.instantiate(bytes);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WASM runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Check SIMD support\n this.simdSupported = await this.checkSIMDSupport();\n\n // Create memory pool\n const memory = new WebAssembly.Memory({\n initial: 256, // 16MB initial\n maximum: 2048, // 128MB maximum\n });\n\n // Compile and instantiate the WASM module\n // In production, this would load an actual WASM binary\n // For now, we use a pure JS fallback\n this.module = {\n memory,\n exports: this.createJSFallback(memory),\n };\n\n this.initialized = true;\n }\n\n /**\n * Check SIMD support\n */\n private async checkSIMDSupport(): Promise<boolean> {\n try {\n // SIMD detection via feature detection\n const simdTest = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,\n 0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,\n 0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,\n 0xfd, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0b\n ]);\n await WebAssembly.instantiate(simdTest);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Create JavaScript fallback for WASM operations\n */\n private createJSFallback(memory: WebAssembly.Memory): WASMExports {\n let nextPtr = 0;\n const allocations: Map<number, number> = new Map();\n\n return {\n malloc: (size: number): number => {\n const ptr = nextPtr;\n nextPtr += size;\n allocations.set(ptr, size);\n return ptr;\n },\n\n free: (ptr: number): void => {\n allocations.delete(ptr);\n },\n\n matmul_f32: (\n aPtr: number, aRows: number, aCols: number,\n bPtr: number, _bRows: number, bCols: number,\n outPtr: number\n ): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < aRows; i++) {\n for (let j = 0; j < bCols; j++) {\n let sum = 0;\n for (let k = 0; k < aCols; k++) {\n sum += (view[aOffset + i * aCols + k] ?? 0) * (view[bOffset + k * bCols + j] ?? 0);\n }\n view[outOffset + i * bCols + j] = sum;\n }\n }\n },\n\n add_f32: (aPtr: number, bPtr: number, outPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[aOffset + i] ?? 0) + (view[bOffset + i] ?? 0);\n }\n },\n\n mul_f32: (aPtr: number, bPtr: number, outPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[aOffset + i] ?? 0) * (view[bOffset + i] ?? 0);\n }\n },\n\n relu_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = Math.max(0, view[inOffset + i] ?? 0);\n }\n },\n\n sigmoid_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = 1 / (1 + Math.exp(-(view[inOffset + i] ?? 0)));\n }\n },\n\n softmax_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n // Find max for numerical stability\n let max = -Infinity;\n for (let i = 0; i < size; i++) {\n if ((view[inOffset + i] ?? 0) > max) max = view[inOffset + i] ?? 0;\n }\n\n // Compute exp and sum\n let sum = 0;\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = Math.exp((view[inOffset + i] ?? 0) - max);\n sum += view[outOffset + i] ?? 0;\n }\n\n // Normalize\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[outOffset + i] ?? 0) / sum;\n }\n },\n };\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model configuration\n const config = this.parseModelConfig(modelData);\n\n // Extract and store weights\n const wasmData: WASMModelData = {\n weights: new Map(),\n config,\n executionOrder: config.layers.map(l => l.name),\n };\n\n // Load weights into memory\n await this.loadWeights(modelData, wasmData);\n\n const modelId = `wasm_${Date.now().toString(36)}`;\n this.models.set(modelId, wasmData);\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version || '1.0.0',\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'wasm',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n \n // Execute model layers\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n const outputs: Tensor[] = [];\n\n for (const outputSpec of metadata.outputs) {\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n \n // Process based on output requirements\n // This is a simplified implementation\n let outputTensor: EdgeFlowTensor;\n\n if (inputs.length > 0 && inputs[0]) {\n const inputTensor = inputs[0] as EdgeFlowTensor;\n \n // Apply transformations based on layer types\n // For demo, apply softmax to classification outputs\n if (outputSpec.name.includes('logits') || outputSpec.name.includes('class')) {\n outputTensor = tensorSoftmax(inputTensor) as EdgeFlowTensor;\n } else if (outputSpec.name.includes('relu')) {\n outputTensor = tensorRelu(inputTensor);\n } else if (outputSpec.name.includes('sigmoid')) {\n outputTensor = tensorSigmoid(inputTensor);\n } else {\n // Identity or feature extraction\n const outputData = new Float32Array(outputSize);\n const inputData = inputTensor.toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = inputData[i] ?? 0;\n }\n outputTensor = new EdgeFlowTensor(outputData, outputSpec.shape, 'float32');\n }\n } else {\n outputTensor = new EdgeFlowTensor(new Float32Array(outputSize), outputSpec.shape, 'float32');\n }\n\n outputs.push(outputTensor);\n }\n\n return outputs;\n }\n\n /**\n * Parse model configuration\n */\n private parseModelConfig(data: ArrayBuffer): WASMModelConfig {\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(2048, data.byteLength)));\n \n if (text.trim().startsWith('{')) {\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) {\n // Try to parse as pure JSON\n try {\n return JSON.parse(text) as WASMModelConfig;\n } catch {\n jsonEnd = data.byteLength;\n }\n }\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as WASMModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n return {\n name: 'unknown',\n version: '1.0.0',\n layers: [],\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Load weights into WASM memory\n */\n private async loadWeights(\n _modelData: ArrayBuffer,\n _wasmData: WASMModelData\n ): Promise<void> {\n // In a full implementation, extract and load weights\n // This is a placeholder\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n const modelData = this.models.get(modelId);\n if (modelData && this.module) {\n // Free weight buffers\n for (const weight of modelData.weights.values()) {\n this.module.exports.free(weight.ptr);\n }\n }\n this.models.delete(modelId);\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.module) {\n throw new EdgeFlowError(\n 'WASM runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Check if SIMD is supported\n */\n hasSIMDSupport(): boolean {\n return this.simdSupported;\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Free all model weights\n for (const modelId of this.models.keys()) {\n this.unloadModel(modelId);\n }\n\n this.module = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WASM runtime factory\n */\nexport function createWASMRuntime(): Runtime {\n return new WASMRuntime();\n}\n", "/**\n * edgeFlow.js - ONNX Runtime Backend\n * \n * Uses onnxruntime-web for real ONNX model inference.\n * onnxruntime-web is an optional peer dependency loaded dynamically.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n DataType,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// Lazy-loaded onnxruntime-web module\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet ort: any = null;\n\nasync function getOrt(): Promise<any> {\n if (ort) return ort;\n try {\n // Import the WASM-only sub-path so Vite rewrites the bare specifier\n // to ort.wasm.bundle.min.mjs. This avoids loading the JSEP/WebGPU\n // worker module (jsep.mjs) that ort.bundle.min.mjs eagerly fetches\n // whenever navigator.gpu exists \u2014 which causes a 404 in dev servers\n // that restrict ES module imports from /public.\n ort = await import('onnxruntime-web/wasm');\n return ort;\n } catch {\n return null;\n }\n}\n\n/**\n * Check whether onnxruntime-web is importable.\n */\nexport async function isOnnxAvailable(): Promise<boolean> {\n return (await getOrt()) != null;\n}\n\n// ============================================================================\n// ONNX Session Storage\n// ============================================================================\n\ninterface ONNXSessionData {\n session: any; // ort.InferenceSession\n inputNames: string[];\n outputNames: string[];\n}\n\nconst sessionStore: Map<string, ONNXSessionData> = new Map();\n\n// ============================================================================\n// ONNX Runtime Implementation\n// ============================================================================\n\n/**\n * ONNXRuntime - Real ONNX model inference using onnxruntime-web\n */\nexport class ONNXRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm'; // Register as wasm since it's the fallback\n \n private initialized = false;\n private executionProvider: 'webgpu' | 'wasm' = 'wasm';\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: this.executionProvider === 'webgpu',\n dynamicShapes: true,\n maxBatchSize: 32,\n availableMemory: 512 * 1024 * 1024, // 512MB\n };\n }\n\n /**\n * Check if ONNX Runtime is available (peer dependency installed)\n */\n async isAvailable(): Promise<boolean> {\n return isOnnxAvailable();\n }\n\n /**\n * Initialize the ONNX runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n const ortModule = await getOrt();\n if (!ortModule) {\n throw new EdgeFlowError(\n 'onnxruntime-web is not installed. Install it with: npm install onnxruntime-web',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // Configure WASM backend for browser use.\n // numThreads=1 disables multi-threading so ort only needs the plain\n // .wasm binary \u2014 the worker .mjs file is never requested, which avoids\n // Vite's restriction on importing files from /public as ES modules.\n // Consumers should copy onnxruntime-web/dist/*.wasm to public/ort/.\n if (typeof window !== 'undefined' && ortModule.env?.wasm) {\n (ortModule.env.wasm as any).wasmPaths = '/ort/';\n (ortModule.env.wasm as any).numThreads = 1;\n }\n\n this.initialized = true;\n }\n\n /**\n * Load a model from ArrayBuffer\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n try {\n const ortModule = await getOrt();\n if (!ortModule) {\n throw new Error('onnxruntime-web is not installed');\n }\n\n // WASM-only execution provider \u2014 WebGPU acceleration can be added\n // later via the dedicated WebGPURuntime backend.\n const sessionOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n };\n\n const modelBytes = new Uint8Array(modelData);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const session: any = await ortModule.InferenceSession.create(modelBytes, sessionOptions);\n \n // Get input/output names\n const inputNames = session.inputNames;\n const outputNames = session.outputNames;\n\n // Generate model ID\n const modelId = `onnx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n\n // Store session\n sessionStore.set(modelId, {\n session,\n inputNames: [...inputNames],\n outputNames: [...outputNames],\n });\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: options.metadata?.name ?? 'onnx-model',\n version: '1.0.0',\n inputs: inputNames.map((name: string) => ({\n name,\n dtype: 'float32' as DataType,\n shape: [-1], // Dynamic shape\n })),\n outputs: outputNames.map((name: string) => ({\n name,\n dtype: 'float32' as DataType,\n shape: [-1],\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'onnx',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'wasm',\n () => this.unloadModel(modelId)\n );\n\n // Override the ID to match our stored session\n Object.defineProperty(model, 'id', { value: modelId, writable: false });\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to load ONNX model: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.MODEL_LOAD_FAILED,\n { error }\n );\n }\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n const sessionData = sessionStore.get(model.id);\n if (!sessionData) {\n throw new EdgeFlowError(\n `ONNX session not found for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const { session, inputNames, outputNames } = sessionData;\n\n try {\n const ortModule = await getOrt();\n const feeds: Record<string, any> = {};\n \n for (let i = 0; i < Math.min(inputs.length, inputNames.length); i++) {\n const inputName = inputNames[i];\n const inputTensor = inputs[i] as EdgeFlowTensor;\n \n if (inputName && inputTensor) {\n const dtype = inputTensor.dtype;\n let ortTensor: any;\n \n if (dtype === 'int64') {\n const data = inputTensor.data as unknown as BigInt64Array;\n ortTensor = new ortModule.Tensor('int64', data, inputTensor.shape as number[]);\n } else if (dtype === 'int32') {\n const data = inputTensor.data as Int32Array;\n ortTensor = new ortModule.Tensor('int32', data, inputTensor.shape as number[]);\n } else {\n const data = inputTensor.toFloat32Array();\n ortTensor = new ortModule.Tensor('float32', data, inputTensor.shape as number[]);\n }\n \n feeds[inputName] = ortTensor;\n }\n }\n\n const results = await session.run(feeds);\n\n // Convert outputs to EdgeFlowTensor\n const outputs: Tensor[] = [];\n \n for (const outputName of outputNames) {\n const ortTensor = results[outputName];\n if (ortTensor) {\n const data = ortTensor.data as Float32Array;\n const shape = Array.from(ortTensor.dims).map(d => Number(d));\n outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));\n }\n }\n\n return outputs;\n } catch (error) {\n throw new EdgeFlowError(\n `ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id, error }\n );\n }\n }\n\n /**\n * Run inference with named inputs\n */\n async runNamed(model: LoadedModel, namedInputs: Map<string, Tensor>): Promise<Tensor[]> {\n const sessionData = sessionStore.get(model.id);\n if (!sessionData) {\n throw new EdgeFlowError(\n `ONNX session not found for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const { session, inputNames, outputNames } = sessionData;\n\n try {\n const ortModule = await getOrt();\n const feeds: Record<string, any> = {};\n \n for (const [inputName, inputTensor] of namedInputs) {\n const tensor = inputTensor as EdgeFlowTensor;\n const dtype = tensor.dtype;\n let ortTensor: any;\n \n if (dtype === 'int64') {\n const data = tensor.data as unknown as BigInt64Array;\n ortTensor = new ortModule.Tensor('int64', data, tensor.shape as number[]);\n } else if (dtype === 'int32') {\n const data = tensor.data as Int32Array;\n ortTensor = new ortModule.Tensor('int32', data, tensor.shape as number[]);\n } else {\n const data = tensor.toFloat32Array();\n ortTensor = new ortModule.Tensor('float32', data, tensor.shape as number[]);\n }\n \n feeds[inputName] = ortTensor;\n }\n\n const results = await session.run(feeds);\n\n // Convert outputs to EdgeFlowTensor\n const outputs: Tensor[] = [];\n \n for (const outputName of outputNames) {\n const ortTensor = results[outputName];\n if (ortTensor) {\n const data = ortTensor.data as Float32Array;\n const shape = Array.from(ortTensor.dims).map(d => Number(d));\n outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));\n }\n }\n\n return outputs;\n } catch (error) {\n throw new EdgeFlowError(\n `ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id, expectedInputs: inputNames, providedInputs: Array.from(namedInputs.keys()), error }\n );\n }\n }\n\n /**\n * Unload a model\n */\n private async unloadModel(modelId: string): Promise<void> {\n const sessionData = sessionStore.get(modelId);\n if (sessionData) {\n // Release session will be handled by GC\n sessionStore.delete(modelId);\n }\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Clear all sessions\n sessionStore.clear();\n this.initialized = false;\n }\n}\n\n/**\n * Create ONNX runtime factory\n */\nexport function createONNXRuntime(): Runtime {\n return new ONNXRuntime();\n}\n", "/**\n * edgeFlow.js - transformers.js Adapter Backend\n *\n * Wraps transformers.js (by Hugging Face) as an inference backend, giving\n * users access to 1000+ HuggingFace models while adding edgeFlow.js's\n * orchestration layer (scheduling, caching, memory management, workers).\n *\n * @example\n * ```typescript\n * import { useTransformersBackend } from 'edgeflowjs';\n * import { pipeline as tfPipeline } from '@xenova/transformers';\n *\n * // Register the adapter\n * useTransformersBackend();\n *\n * // Now use edgeFlow.js pipeline API \u2014 inference delegates to transformers.js\n * const classifier = await pipeline('text-classification', {\n * model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n * });\n *\n * // edgeFlow.js handles scheduling, batching, memory, caching\n * const results = await classifier.runBatch(thousandsOfTexts);\n * ```\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\nimport { registerRuntime } from '../core/runtime.js';\n\n// ---------------------------------------------------------------------------\n// Types for the transformers.js interop\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal interface for a transformers.js pipeline instance.\n * We avoid importing @xenova/transformers directly so edgeFlow.js\n * does not add it as a hard dependency.\n */\ninterface TransformersPipelineInstance {\n (input: unknown, options?: unknown): Promise<unknown>;\n dispose?: () => Promise<void> | void;\n}\n\n/**\n * A factory that creates a transformers.js pipeline.\n * Users pass this so we don't hard-depend on the library.\n */\nexport type TransformersPipelineFactory = (\n task: string,\n model?: string,\n options?: Record<string, unknown>,\n) => Promise<TransformersPipelineInstance>;\n\n/**\n * Options for configuring the transformers.js adapter.\n */\nexport interface TransformersAdapterOptions {\n /** The pipeline factory from transformers.js (e.g. the `pipeline` function) */\n pipelineFactory: TransformersPipelineFactory;\n /** Default device ('webgpu' | 'wasm' | 'cpu') \u2014 passed to transformers.js */\n device?: string;\n /** Default dtype ('fp32' | 'fp16' | 'q8' | 'q4') */\n dtype?: string;\n /** Cache directory (browser IndexedDB path) */\n cacheDir?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Session store: maps model IDs to transformers.js pipeline instances\n// ---------------------------------------------------------------------------\n\nconst sessionStore = new Map<string, {\n instance: TransformersPipelineInstance;\n task: string;\n model: string;\n}>();\n\nlet adapterOptions: TransformersAdapterOptions | null = null;\n\n// ---------------------------------------------------------------------------\n// Runtime implementation\n// ---------------------------------------------------------------------------\n\nexport class TransformersAdapterRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm'; // registers under the wasm slot\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: true,\n maxBatchSize: 128,\n availableMemory: 1024 * 1024 * 1024,\n };\n }\n\n async isAvailable(): Promise<boolean> {\n return adapterOptions?.pipelineFactory != null;\n }\n\n async initialize(): Promise<void> {\n if (!adapterOptions?.pipelineFactory) {\n throw new EdgeFlowError(\n 'TransformersAdapterRuntime requires a pipelineFactory. ' +\n 'Call useTransformersBackend({ pipelineFactory }) first.',\n ErrorCodes.RUNTIME_INIT_FAILED,\n );\n }\n }\n\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {},\n ): Promise<LoadedModel> {\n // modelData is unused \u2014 transformers.js downloads its own models.\n // Instead the model identifier comes via metadata.name or the URL.\n const modelName = options.metadata?.name ?? 'default';\n\n const metadata: ModelMetadata = {\n name: modelName,\n version: '1.0.0',\n inputs: [{ name: 'input', dtype: 'float32', shape: [-1] }],\n outputs: [{ name: 'output', dtype: 'float32', shape: [-1] }],\n sizeBytes: modelData.byteLength || 0,\n quantization: options.quantization ?? 'float32',\n format: 'onnx',\n };\n\n const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n\n const model = new LoadedModelImpl(metadata, this.name, () => {\n const session = sessionStore.get(modelId);\n if (session?.instance.dispose) {\n session.instance.dispose();\n }\n sessionStore.delete(modelId);\n });\n\n getMemoryManager().trackModel(model, () => model.dispose());\n return model;\n }\n\n /**\n * Load a transformers.js pipeline by task + model name\n * (called by the higher-level adapter pipeline, not via the\n * standard loadModel path).\n */\n async loadPipeline(\n task: string,\n model: string,\n pipelineOptions?: Record<string, unknown>,\n ): Promise<string> {\n if (!adapterOptions?.pipelineFactory) {\n throw new EdgeFlowError(\n 'Adapter not initialised',\n ErrorCodes.RUNTIME_NOT_INITIALIZED,\n );\n }\n\n const opts: Record<string, unknown> = { ...pipelineOptions };\n if (adapterOptions.device) opts['device'] = adapterOptions.device;\n if (adapterOptions.dtype) opts['dtype'] = adapterOptions.dtype;\n\n const instance = await adapterOptions.pipelineFactory(task, model, opts);\n const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n sessionStore.set(modelId, { instance, task, model });\n\n return modelId;\n }\n\n /**\n * Run inference by passing the raw input to the transformers.js pipeline.\n * The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output\n * (since transformers.js returns task-specific objects, not raw tensors).\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n const session = sessionStore.get(model.id);\n if (!session) {\n throw new EdgeFlowError(\n `No transformers.js session for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n );\n }\n\n // Reconstruct input from tensor (simple: use the float data as-is)\n const inputData = inputs[0]?.toFloat32Array() ?? new Float32Array(0);\n const result = await session.instance(inputData);\n\n // Wrap the result in a tensor \u2014 downstream pipelines can interpret it\n const resultArray = Array.isArray(result)\n ? new Float32Array(result.flat(Infinity) as number[])\n : new Float32Array([0]);\n\n return [new EdgeFlowTensor(resultArray, [resultArray.length], 'float32')];\n }\n\n /**\n * High-level: run the transformers.js pipeline directly with arbitrary input.\n * Returns the raw result object (not a tensor).\n */\n async runDirect(\n modelId: string,\n input: unknown,\n options?: Record<string, unknown>,\n ): Promise<unknown> {\n const session = sessionStore.get(modelId);\n if (!session) {\n throw new EdgeFlowError(\n `No transformers.js session for model ${modelId}`,\n ErrorCodes.MODEL_NOT_LOADED,\n );\n }\n return session.instance(input, options);\n }\n\n dispose(): void {\n for (const [id, session] of sessionStore) {\n if (session.instance.dispose) {\n session.instance.dispose();\n }\n sessionStore.delete(id);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nlet adapterRuntime: TransformersAdapterRuntime | null = null;\n\n/**\n * Register the transformers.js adapter as the default inference backend.\n *\n * @example\n * ```typescript\n * import { pipeline } from '@xenova/transformers';\n * import { useTransformersBackend } from 'edgeflowjs';\n *\n * useTransformersBackend({\n * pipelineFactory: pipeline,\n * device: 'webgpu',\n * dtype: 'fp16',\n * });\n * ```\n */\nexport function useTransformersBackend(options: TransformersAdapterOptions): void {\n adapterOptions = options;\n adapterRuntime = new TransformersAdapterRuntime();\n registerRuntime('wasm', () => adapterRuntime!);\n}\n\n/**\n * Get the adapter runtime instance (for advanced use).\n */\nexport function getTransformersAdapter(): TransformersAdapterRuntime | null {\n return adapterRuntime;\n}\n", "/**\n * edgeFlow.js - Backend Exports\n */\n\n// WebGPU Backend (planned - skeleton only)\nexport { WebGPURuntime, createWebGPURuntime } from './webgpu.js';\n\n// WebNN Backend (planned - skeleton only)\nexport { WebNNRuntime, createWebNNRuntime } from './webnn.js';\n\n// WASM Backend (basic tensor ops)\nexport { WASMRuntime, createWASMRuntime } from './wasm.js';\n\n// ONNX Runtime Backend (real model inference)\nexport { ONNXRuntime, createONNXRuntime, isOnnxAvailable } from './onnx.js';\n\n// transformers.js Adapter Backend\nexport {\n TransformersAdapterRuntime,\n useTransformersBackend,\n getTransformersAdapter,\n type TransformersAdapterOptions,\n type TransformersPipelineFactory,\n} from './transformers-adapter.js';\n\n// Re-export types\nexport type { Runtime, RuntimeType, RuntimeCapabilities } from '../core/types.js';\n\nimport { registerRuntime } from '../core/runtime.js';\nimport { createONNXRuntime } from './onnx.js';\n\n/**\n * Register all available backends.\n *\n * Always registers the ONNX Runtime factory synchronously so there is no\n * async race between registration and the first pipeline() call.\n * `ONNXRuntime.isAvailable()` is called lazily by RuntimeManager when it\n * selects a backend, so if onnxruntime-web is not installed the runtime is\n * simply skipped at that point.\n */\nexport function registerAllBackends(): void {\n registerRuntime('wasm', createONNXRuntime);\n}\n\n/**\n * Auto-register backends on module load (synchronous \u2014 no race condition).\n */\nregisterAllBackends();\n", "/**\n * edgeFlow.js - Caching Utilities\n * \n * Smart caching for models, tensors, and inference results.\n */\n\n// ============================================================================\n// Cache Types\n// ============================================================================\n\n/**\n * Cache strategy types\n */\nexport type CacheStrategy = 'lru' | 'lfu' | 'fifo' | 'ttl';\n\n/**\n * Cache entry\n */\ninterface CacheEntry<T> {\n value: T;\n size: number;\n createdAt: number;\n accessedAt: number;\n accessCount: number;\n ttl?: number;\n}\n\n/**\n * Cache options\n */\nexport interface CacheOptions {\n /** Cache strategy */\n strategy?: CacheStrategy;\n /** Maximum cache size in bytes */\n maxSize?: number;\n /** Maximum number of entries */\n maxEntries?: number;\n /** Default TTL in milliseconds */\n ttl?: number;\n /** Enable persistence to IndexedDB */\n persistent?: boolean;\n /** Cache name for persistence */\n name?: string;\n}\n\n/**\n * Cache statistics\n */\nexport interface CacheStats {\n /** Number of entries */\n entries: number;\n /** Total size in bytes */\n size: number;\n /** Cache hits */\n hits: number;\n /** Cache misses */\n misses: number;\n /** Hit rate (0-1) */\n hitRate: number;\n}\n\n// ============================================================================\n// Cache Implementation\n// ============================================================================\n\n/**\n * Cache - Generic cache implementation\n */\nexport class Cache<T> {\n private readonly options: Required<CacheOptions>;\n private readonly cache: Map<string, CacheEntry<T>> = new Map();\n private currentSize = 0;\n private hits = 0;\n private misses = 0;\n\n constructor(options: CacheOptions = {}) {\n this.options = {\n strategy: options.strategy ?? 'lru',\n maxSize: options.maxSize ?? 100 * 1024 * 1024, // 100MB\n maxEntries: options.maxEntries ?? 1000,\n ttl: options.ttl ?? 0, // 0 = no TTL\n persistent: options.persistent ?? false,\n name: options.name ?? 'edgeflow-cache',\n };\n\n // Load from persistent storage if enabled\n if (this.options.persistent) {\n this.loadFromStorage();\n }\n }\n\n /**\n * Get value from cache\n */\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n \n if (!entry) {\n this.misses++;\n return undefined;\n }\n\n // Check TTL\n if (entry.ttl && Date.now() - entry.createdAt > entry.ttl) {\n this.delete(key);\n this.misses++;\n return undefined;\n }\n\n // Update access stats\n entry.accessedAt = Date.now();\n entry.accessCount++;\n this.hits++;\n\n return entry.value;\n }\n\n /**\n * Set value in cache\n */\n set(key: string, value: T, size: number, ttl?: number): void {\n // Remove existing entry if present\n if (this.cache.has(key)) {\n this.delete(key);\n }\n\n // Evict entries if necessary\n while (\n (this.currentSize + size > this.options.maxSize ||\n this.cache.size >= this.options.maxEntries) &&\n this.cache.size > 0\n ) {\n this.evict();\n }\n\n // Determine TTL value\n const entryTtl = ttl !== undefined ? ttl : (this.options.ttl > 0 ? this.options.ttl : undefined);\n\n // Add new entry\n const entry: CacheEntry<T> = {\n value,\n size,\n createdAt: Date.now(),\n accessedAt: Date.now(),\n accessCount: 1,\n ttl: entryTtl,\n };\n\n this.cache.set(key, entry);\n this.currentSize += size;\n\n // Persist if enabled\n if (this.options.persistent) {\n this.saveToStorage();\n }\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n\n // Check TTL\n if (entry.ttl && Date.now() - entry.createdAt > entry.ttl) {\n this.delete(key);\n return false;\n }\n\n return true;\n }\n\n /**\n * Delete entry\n */\n delete(key: string): boolean {\n const entry = this.cache.get(key);\n if (entry) {\n this.currentSize -= entry.size;\n this.cache.delete(key);\n \n if (this.options.persistent) {\n this.saveToStorage();\n }\n \n return true;\n }\n return false;\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n this.cache.clear();\n this.currentSize = 0;\n this.hits = 0;\n this.misses = 0;\n\n if (this.options.persistent) {\n this.clearStorage();\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): CacheStats {\n const total = this.hits + this.misses;\n return {\n entries: this.cache.size,\n size: this.currentSize,\n hits: this.hits,\n misses: this.misses,\n hitRate: total > 0 ? this.hits / total : 0,\n };\n }\n\n /**\n * Evict an entry based on strategy\n */\n private evict(): void {\n let keyToEvict: string | null = null;\n\n switch (this.options.strategy) {\n case 'lru':\n keyToEvict = this.findLRU();\n break;\n case 'lfu':\n keyToEvict = this.findLFU();\n break;\n case 'fifo':\n keyToEvict = this.findOldest();\n break;\n case 'ttl':\n keyToEvict = this.findExpired() ?? this.findOldest();\n break;\n }\n\n if (keyToEvict) {\n this.delete(keyToEvict);\n }\n }\n\n /**\n * Find least recently used entry\n */\n private findLRU(): string | null {\n let oldest: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.accessedAt < oldestTime) {\n oldestTime = entry.accessedAt;\n oldest = key;\n }\n }\n\n return oldest;\n }\n\n /**\n * Find least frequently used entry\n */\n private findLFU(): string | null {\n let lfu: string | null = null;\n let minCount = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.accessCount < minCount) {\n minCount = entry.accessCount;\n lfu = key;\n }\n }\n\n return lfu;\n }\n\n /**\n * Find oldest entry (FIFO)\n */\n private findOldest(): string | null {\n let oldest: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.createdAt < oldestTime) {\n oldestTime = entry.createdAt;\n oldest = key;\n }\n }\n\n return oldest;\n }\n\n /**\n * Find expired entry\n */\n private findExpired(): string | null {\n const now = Date.now();\n\n for (const [key, entry] of this.cache) {\n if (entry.ttl && now - entry.createdAt > entry.ttl) {\n return key;\n }\n }\n\n return null;\n }\n\n /**\n * Load cache from IndexedDB\n */\n private async loadFromStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readonly');\n const store = tx.objectStore('cache');\n const request = store.getAll();\n\n return new Promise((resolve, reject) => {\n request.onsuccess = () => {\n const entries = request.result as Array<{ key: string; entry: CacheEntry<T> }>;\n for (const { key, entry } of entries) {\n this.cache.set(key, entry);\n this.currentSize += entry.size;\n }\n resolve();\n };\n request.onerror = () => reject(request.error);\n });\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Save cache to IndexedDB\n */\n private async saveToStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readwrite');\n const store = tx.objectStore('cache');\n\n // Clear existing entries\n store.clear();\n\n // Add current entries\n for (const [key, entry] of this.cache) {\n store.put({ key, entry });\n }\n\n return new Promise((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Clear IndexedDB storage\n */\n private async clearStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readwrite');\n const store = tx.objectStore('cache');\n store.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Open IndexedDB database\n */\n private openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.options.name, 1);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains('cache')) {\n db.createObjectStore('cache', { keyPath: 'key' });\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n}\n\n// ============================================================================\n// Inference Result Cache\n// ============================================================================\n\n/**\n * InferenceCache - Cache for inference results\n */\nexport class InferenceCache extends Cache<Float32Array> {\n /**\n * Generate cache key from input\n */\n generateKey(modelId: string, input: Float32Array | number[]): string {\n // Create hash from input data\n const inputArray = Array.isArray(input) ? input : Array.from(input);\n const hash = this.hashArray(inputArray);\n return `${modelId}:${hash}`;\n }\n\n /**\n * Simple hash function for arrays\n */\n private hashArray(arr: number[]): string {\n let hash = 0;\n const sample = arr.length > 100 \n ? arr.filter((_, i) => i % Math.floor(arr.length / 100) === 0)\n : arr;\n \n for (let i = 0; i < sample.length; i++) {\n const value = sample[i] ?? 0;\n hash = ((hash << 5) - hash) + (value * 1000 | 0);\n hash |= 0;\n }\n \n return hash.toString(36);\n }\n}\n\n// ============================================================================\n// Model Cache\n// ============================================================================\n\n/**\n * Model download cache using Cache API\n */\nexport class ModelDownloadCache {\n private readonly cacheName: string;\n private cache: globalThis.Cache | null = null;\n\n constructor(cacheName: string = 'edgeflow-models') {\n this.cacheName = cacheName;\n }\n\n /**\n * Initialize cache\n */\n private async ensureCache(): Promise<globalThis.Cache> {\n if (!this.cache) {\n if (typeof caches === 'undefined') {\n throw new Error('Cache API is not available');\n }\n this.cache = await caches.open(this.cacheName);\n }\n return this.cache;\n }\n\n /**\n * Get cached response\n */\n async get(url: string): Promise<Response | undefined> {\n try {\n const cache = await this.ensureCache();\n return await cache.match(url) ?? undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Store response in cache\n */\n async put(url: string, response: Response): Promise<void> {\n try {\n const cache = await this.ensureCache();\n await cache.put(url, response.clone());\n } catch {\n // Ignore cache errors\n }\n }\n\n /**\n * Delete cached response\n */\n async delete(url: string): Promise<boolean> {\n try {\n const cache = await this.ensureCache();\n return await cache.delete(url);\n } catch {\n return false;\n }\n }\n\n /**\n * Clear all cached models\n */\n async clear(): Promise<void> {\n try {\n await caches.delete(this.cacheName);\n this.cache = null;\n } catch {\n // Ignore cache errors\n }\n }\n\n /**\n * Get all cached URLs\n */\n async keys(): Promise<string[]> {\n try {\n const cache = await this.ensureCache();\n const requests = await cache.keys();\n return requests.map(r => r.url);\n } catch {\n return [];\n }\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a cache with common presets\n */\nexport function createCache<T>(\n preset: 'small' | 'medium' | 'large' | 'custom' = 'medium',\n options: CacheOptions = {}\n): Cache<T> {\n const presets: Record<string, CacheOptions> = {\n small: {\n maxSize: 10 * 1024 * 1024, // 10MB\n maxEntries: 100,\n },\n medium: {\n maxSize: 100 * 1024 * 1024, // 100MB\n maxEntries: 500,\n },\n large: {\n maxSize: 500 * 1024 * 1024, // 500MB\n maxEntries: 2000,\n },\n custom: {},\n };\n\n return new Cache<T>({ ...presets[preset], ...options });\n}\n", "/**\n * edgeFlow.js - Base Pipeline\n * \n * Base class and utilities for all pipeline implementations.\n */\n\nimport {\n LoadedModel,\n PipelineConfig,\n PipelineOptions,\n PipelineTask,\n} from '../core/types.js';\nimport { loadModel, runInference } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { ModelCache } from '../core/memory.js';\nimport { ModelDownloadCache } from '../utils/cache.js';\n\n// ============================================================================\n// Pipeline Types\n// ============================================================================\n\n/**\n * Pipeline result base interface\n */\nexport interface PipelineResult {\n /** Processing time in milliseconds */\n processingTime?: number;\n}\n\n/**\n * Text classification result\n */\nexport interface TextClassificationResult extends PipelineResult {\n label: string;\n score: number;\n}\n\n/**\n * Feature extraction result\n */\nexport interface FeatureExtractionResult extends PipelineResult {\n embeddings: number[];\n}\n\n/**\n * Image classification result\n */\nexport interface ImageClassificationResult extends PipelineResult {\n label: string;\n score: number;\n}\n\n/**\n * Object detection result\n */\nexport interface ObjectDetectionResult extends PipelineResult {\n label: string;\n score: number;\n box: { x: number; y: number; width: number; height: number };\n}\n\n// ============================================================================\n// Base Pipeline Class\n// ============================================================================\n\n/**\n * BasePipeline - Abstract base class for all pipelines\n */\nexport abstract class BasePipeline<TInput, TOutput extends PipelineResult | PipelineResult[]> {\n protected model: LoadedModel | null = null;\n protected readonly config: PipelineConfig;\n protected readonly modelCache: ModelCache;\n protected readonly downloadCache: ModelDownloadCache;\n protected isReady = false;\n\n constructor(config: PipelineConfig) {\n this.config = config;\n this.modelCache = new ModelCache();\n this.downloadCache = new ModelDownloadCache();\n }\n\n /**\n * Initialize the pipeline (load model).\n *\n * Skips model loading when `config.model === 'default'` \u2014 concrete\n * subclasses that define their own DEFAULT_MODELS handle all model\n * loading in their overridden `initialize()` methods, so the base\n * should not attempt to fetch a URL called \"default\".\n */\n async initialize(): Promise<void> {\n if (this.isReady && this.model) return;\n\n // Skip generic model loading for subclasses that manage their own models.\n if (this.config.model === 'default') {\n this.isReady = true;\n return;\n }\n\n // Check model cache first\n const cachedModel = this.modelCache.get(this.config.model);\n if (cachedModel) {\n this.model = cachedModel;\n this.isReady = true;\n return;\n }\n\n // Load model using the explicit URL from config\n this.model = await this.loadModelWithCache(this.config.model);\n this.isReady = true;\n }\n\n /**\n * Load model with caching\n */\n protected async loadModelWithCache(modelPath: string): Promise<LoadedModel> {\n // Try download cache first\n const cachedResponse = await this.downloadCache.get(modelPath);\n if (cachedResponse) {\n // Use cached data\n }\n\n // Download and cache (or use mock for now)\n try {\n const response = await fetch(modelPath);\n if (response.ok) {\n // Cache the response\n await this.downloadCache.put(modelPath, response.clone());\n }\n } catch {\n // Ignore fetch errors for demo\n }\n\n // Load into runtime\n return loadModel(modelPath, {\n runtime: this.config.runtime,\n quantization: this.config.quantization,\n cache: this.config.cache,\n });\n }\n\n /**\n * Run inference (single input)\n */\n async run(input: TInput, options?: PipelineOptions): Promise<TOutput> {\n await this.initialize();\n \n const startTime = performance.now();\n \n // Preprocess\n const preprocessed = await this.preprocess(input);\n \n // Run inference\n const outputs = await runInference(this.model!, preprocessed);\n \n // Postprocess\n const result = await this.postprocess(outputs as EdgeFlowTensor[], options);\n \n if (result && typeof result === 'object' && 'processingTime' in result) {\n (result as PipelineResult).processingTime = performance.now() - startTime;\n }\n \n return result;\n }\n\n /**\n * Run batch inference\n */\n async runBatch(inputs: TInput[], options?: PipelineOptions): Promise<TOutput[]> {\n await this.initialize();\n \n // Process all inputs\n const results = await Promise.all(\n inputs.map(input => this.run(input, options))\n );\n \n return results;\n }\n\n /**\n * Preprocess input - must be implemented by subclasses\n */\n protected abstract preprocess(input: TInput): Promise<EdgeFlowTensor[]>;\n\n /**\n * Postprocess output - must be implemented by subclasses\n */\n protected abstract postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<TOutput>;\n\n /**\n * Get the task type\n */\n get task(): PipelineTask {\n return this.config.task;\n }\n\n /**\n * Check if pipeline is ready\n */\n get ready(): boolean {\n return this.isReady;\n }\n\n /**\n * Dispose the pipeline\n */\n dispose(): void {\n if (this.model) {\n this.model.dispose();\n this.model = null;\n }\n this.isReady = false;\n }\n}\n\n// ============================================================================\n// Pipeline Registry\n// ============================================================================\n\n/**\n * Pipeline factory function type\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype PipelineFactory = (config: PipelineConfig) => BasePipeline<any, any>;\n\n/**\n * Registered pipeline factories\n */\nconst pipelineFactories: Map<PipelineTask, PipelineFactory> = new Map();\n\n/**\n * Register a pipeline factory\n */\nexport function registerPipeline(task: PipelineTask, factory: PipelineFactory): void {\n pipelineFactories.set(task, factory);\n}\n\n/**\n * Get a pipeline factory\n */\nexport function getPipelineFactory(task: PipelineTask): PipelineFactory | undefined {\n return pipelineFactories.get(task);\n}\n\n// ============================================================================\n// Default Label Maps\n// ============================================================================\n\n/**\n * Common sentiment labels\n */\nexport const SENTIMENT_LABELS = ['negative', 'positive'];\n\n/**\n * Common emotion labels\n */\nexport const EMOTION_LABELS = [\n 'anger', 'disgust', 'fear', 'joy', 'sadness', 'surprise', 'neutral'\n];\n\n/**\n * ImageNet top-10 labels (for demo)\n */\nexport const IMAGENET_LABELS = [\n 'tench', 'goldfish', 'great white shark', 'tiger shark', 'hammerhead',\n 'electric ray', 'stingray', 'cock', 'hen', 'ostrich'\n];\n", "/**\n * edgeFlow.js - Text Classification Pipeline\n * \n * High-level API for text classification tasks including\n * sentiment analysis, topic classification, etc.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\nimport {\n BasePipeline,\n TextClassificationResult,\n registerPipeline,\n SENTIMENT_LABELS,\n} from './base.js';\n\n// ============================================================================\n// Default Model (DistilBERT fine-tuned on SST-2)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/tokenizer.json',\n};\n\nconst DEFAULT_SST2_LABELS = ['NEGATIVE', 'POSITIVE'];\n\n// ============================================================================\n// Text Classification Pipeline\n// ============================================================================\n\nexport interface TextClassificationOptions extends PipelineOptions {\n returnAllScores?: boolean;\n labels?: string[];\n topK?: number;\n}\n\nexport class TextClassificationPipeline extends BasePipeline<\n string | string[],\n TextClassificationResult | TextClassificationResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config: PipelineConfig, labels?: string[]) {\n super(config);\n this.labels = labels ?? DEFAULT_SST2_LABELS;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: string | string[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult | TextClassificationResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n \n await this.initialize();\n \n const startTime = performance.now();\n const results: TextClassificationResult[] = [];\n\n for (const text of inputs) {\n const tensorInputs = await this.preprocess(text);\n const outputs = await this.runInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n const text = Array.isArray(input) ? input[0]! : input;\n \n const encoded = this.tokenizer!.encode(text, {\n maxLength: 128,\n padding: 'max_length',\n truncation: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n return [inputIds, attentionMask];\n }\n\n private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputs[0]!);\n namedInputs.set('attention_mask', inputs[1]!);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult> {\n const logits = outputs[0];\n if (!logits) {\n return { label: 'unknown', score: 0 };\n }\n\n const probs = softmax(logits, -1) as EdgeFlowTensor;\n const probsArray = probs.toFloat32Array();\n\n let maxIdx = 0;\n let maxScore = probsArray[0] ?? 0;\n \n for (let i = 1; i < probsArray.length; i++) {\n if ((probsArray[i] ?? 0) > maxScore) {\n maxScore = probsArray[i] ?? 0;\n maxIdx = i;\n }\n }\n\n const label = options?.labels?.[maxIdx] ?? this.labels[maxIdx] ?? `class_${maxIdx}`;\n\n return {\n label,\n score: maxScore,\n };\n }\n}\n\n// ============================================================================\n// Sentiment Analysis Pipeline\n// ============================================================================\n\nexport class SentimentAnalysisPipeline extends TextClassificationPipeline {\n constructor(config: PipelineConfig) {\n super(config, SENTIMENT_LABELS);\n }\n\n async analyze(\n text: string | string[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult | TextClassificationResult[]> {\n return this.run(text, options);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\nexport function createTextClassificationPipeline(\n config: Partial<PipelineConfig> = {}\n): TextClassificationPipeline {\n return new TextClassificationPipeline({\n task: 'text-classification',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\nexport function createSentimentAnalysisPipeline(\n config: Partial<PipelineConfig> = {}\n): SentimentAnalysisPipeline {\n return new SentimentAnalysisPipeline({\n task: 'sentiment-analysis',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\nregisterPipeline('text-classification', (config) => new TextClassificationPipeline(config));\nregisterPipeline('sentiment-analysis', (config) => new SentimentAnalysisPipeline(config));\n", "/**\n * edgeFlow.js - Tokenizer\n * \n * Full-featured tokenizer supporting HuggingFace tokenizer.json format.\n * Supports BPE, WordPiece, and Unigram tokenization.\n */\n\nimport {\n TokenizerConfig,\n TokenizedOutput,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type TokenizerModel = 'BPE' | 'WordPiece' | 'Unigram' | 'basic';\n\nexport interface TokenizerOptions {\n addSpecialTokens?: boolean;\n maxLength?: number;\n padding?: 'max_length' | 'longest' | 'do_not_pad';\n truncation?: boolean;\n returnAttentionMask?: boolean;\n returnTokenTypeIds?: boolean;\n textPair?: string;\n}\n\n/**\n * HuggingFace tokenizer.json format\n */\ninterface HFTokenizerJSON {\n version?: string;\n truncation?: {\n max_length: number;\n strategy: string;\n };\n padding?: {\n strategy: string;\n pad_id: number;\n pad_token: string;\n };\n added_tokens?: Array<{\n id: number;\n content: string;\n single_word: boolean;\n lstrip: boolean;\n rstrip: boolean;\n normalized: boolean;\n special: boolean;\n }>;\n normalizer?: {\n type: string;\n lowercase?: boolean;\n strip_accents?: boolean;\n [key: string]: unknown;\n };\n pre_tokenizer?: {\n type: string;\n [key: string]: unknown;\n };\n post_processor?: {\n type: string;\n single?: Array<{ id: string; type_id: number } | { SpecialToken: { id: string; type_id: number } } | { Sequence: { id: string; type_id: number } }>;\n pair?: Array<{ id: string; type_id: number } | { SpecialToken: { id: string; type_id: number } } | { Sequence: { id: string; type_id: number } }>;\n special_tokens?: Record<string, { id: string; ids: number[]; tokens: string[] }>;\n [key: string]: unknown;\n };\n decoder?: {\n type: string;\n [key: string]: unknown;\n };\n model: {\n type: string;\n vocab?: Record<string, number>;\n merges?: string[];\n unk_token?: string;\n continuing_subword_prefix?: string;\n end_of_word_suffix?: string;\n fuse_unk?: boolean;\n byte_fallback?: boolean;\n [key: string]: unknown;\n };\n}\n\n\n// ============================================================================\n// Tokenizer Implementation\n// ============================================================================\n\n/**\n * Tokenizer - Full-featured tokenizer supporting HuggingFace format\n */\nexport class Tokenizer {\n private vocab: Map<string, number> = new Map();\n private reverseVocab: Map<number, string> = new Map();\n private merges: Map<string, number> = new Map();\n private addedTokens: Map<string, number> = new Map();\n private specialTokens: Set<string> = new Set();\n \n private modelType: TokenizerModel = 'BPE';\n private unkToken: string = '[UNK]';\n private continuingSubwordPrefix: string = '##';\n \n // Special token IDs\n private padTokenId: number = 0;\n private unkTokenId: number = 0;\n private clsTokenId?: number;\n private sepTokenId?: number;\n private maskTokenId?: number;\n private bosTokenId?: number;\n private eosTokenId?: number;\n \n // Config\n private maxLength: number = 512;\n private doLowerCase: boolean = false;\n private stripAccents: boolean = false;\n \n // Post-processor config\n private postProcessor?: HFTokenizerJSON['post_processor'];\n \n // Byte encoder for BPE\n private byteEncoder: Map<number, string> = new Map();\n private byteDecoder: Map<string, number> = new Map();\n\n constructor() {\n this.initByteEncoder();\n }\n\n /**\n * Initialize byte encoder/decoder for BPE\n */\n private initByteEncoder(): void {\n const bytes: number[] = [];\n \n // Printable ASCII\n for (let i = 33; i <= 126; i++) bytes.push(i);\n for (let i = 161; i <= 172; i++) bytes.push(i);\n for (let i = 174; i <= 255; i++) bytes.push(i);\n \n const chars = [...bytes];\n let n = 0;\n \n for (let i = 0; i < 256; i++) {\n if (!bytes.includes(i)) {\n bytes.push(i);\n chars.push(256 + n);\n n++;\n }\n }\n \n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i]!;\n const char = String.fromCharCode(chars[i]!);\n this.byteEncoder.set(byte, char);\n this.byteDecoder.set(char, byte);\n }\n }\n\n /**\n * Load from HuggingFace tokenizer.json\n */\n static async fromJSON(json: HFTokenizerJSON | string): Promise<Tokenizer> {\n const tokenizer = new Tokenizer();\n const data = typeof json === 'string' ? JSON.parse(json) as HFTokenizerJSON : json;\n \n // Load model config\n if (data.model) {\n tokenizer.modelType = data.model.type as TokenizerModel;\n \n // Load vocabulary.\n // BPE/WordPiece: vocab is an object { token: id }.\n // Unigram (SentencePiece): vocab is an array of [token, score] pairs\n // where the array *index* is the token ID.\n if (data.model.vocab) {\n if (Array.isArray(data.model.vocab)) {\n // Unigram format\n const unigramVocab = data.model.vocab as Array<[string, number]>;\n for (let i = 0; i < unigramVocab.length; i++) {\n const entry = unigramVocab[i]!;\n const token = Array.isArray(entry) ? entry[0] : (entry as unknown as string);\n tokenizer.vocab.set(token, i);\n tokenizer.reverseVocab.set(i, token);\n }\n } else {\n for (const [token, id] of Object.entries(data.model.vocab)) {\n tokenizer.vocab.set(token, id as number);\n tokenizer.reverseVocab.set(id as number, token);\n }\n }\n }\n \n // Load merges for BPE\n if (data.model.merges) {\n for (let i = 0; i < data.model.merges.length; i++) {\n tokenizer.merges.set(data.model.merges[i]!, i);\n }\n }\n \n // Model-specific config\n tokenizer.unkToken = data.model.unk_token ?? '[UNK]';\n tokenizer.continuingSubwordPrefix = data.model.continuing_subword_prefix ?? '##';\n }\n \n // Load added tokens\n if (data.added_tokens) {\n for (const token of data.added_tokens) {\n tokenizer.addedTokens.set(token.content, token.id);\n tokenizer.reverseVocab.set(token.id, token.content);\n if (token.special) {\n tokenizer.specialTokens.add(token.content);\n }\n \n // Detect special token types\n const content = token.content.toLowerCase();\n if (content.includes('pad')) tokenizer.padTokenId = token.id;\n if (content.includes('unk')) tokenizer.unkTokenId = token.id;\n if (content.includes('cls') || content === '[cls]') tokenizer.clsTokenId = token.id;\n if (content.includes('sep') || content === '[sep]') tokenizer.sepTokenId = token.id;\n if (content.includes('mask')) tokenizer.maskTokenId = token.id;\n if (content.includes('bos') || content === '<s>') tokenizer.bosTokenId = token.id;\n if (content.includes('eos') || content === '</s>') tokenizer.eosTokenId = token.id;\n }\n }\n \n // Load normalizer config\n if (data.normalizer) {\n tokenizer.doLowerCase = data.normalizer.lowercase ?? false;\n tokenizer.stripAccents = data.normalizer.strip_accents ?? false;\n }\n \n // Load truncation config\n if (data.truncation) {\n tokenizer.maxLength = data.truncation.max_length;\n }\n \n // Load post-processor\n if (data.post_processor) {\n tokenizer.postProcessor = data.post_processor;\n }\n \n return tokenizer;\n }\n\n /**\n * Load from URL (tokenizer.json)\n */\n static async fromUrl(url: string): Promise<Tokenizer> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new EdgeFlowError(\n `Failed to load tokenizer from ${url}: ${response.status}`,\n ErrorCodes.MODEL_NOT_FOUND\n );\n }\n const json = await response.json() as HFTokenizerJSON;\n return Tokenizer.fromJSON(json);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromHuggingFace(modelId: string, options?: { revision?: string }): Promise<Tokenizer> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/tokenizer.json`;\n return Tokenizer.fromUrl(url);\n }\n\n /**\n * Normalize text\n */\n private normalize(text: string): string {\n let result = text;\n \n if (this.doLowerCase) {\n result = result.toLowerCase();\n }\n \n if (this.stripAccents) {\n result = result.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n }\n \n // Normalize whitespace\n result = result.replace(/\\s+/g, ' ').trim();\n \n return result;\n }\n\n /**\n * Pre-tokenize text (split into words)\n */\n private preTokenize(text: string): string[] {\n // GPT-2 style: split on whitespace and punctuation, keeping them\n const pattern = /'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)|\\s+/gu;\n const matches = text.match(pattern);\n return matches ?? [text];\n }\n\n /**\n * Encode text to bytes (for BPE)\n */\n private textToBytes(text: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(text);\n return Array.from(bytes).map(b => this.byteEncoder.get(b) ?? '').join('');\n }\n\n /**\n * Decode bytes to text (for BPE)\n */\n private bytesToText(text: string): string {\n const bytes = new Uint8Array(\n text.split('').map(c => this.byteDecoder.get(c) ?? 0)\n );\n const decoder = new TextDecoder('utf-8', { fatal: false });\n return decoder.decode(bytes);\n }\n\n /**\n * Get BPE pairs from word\n */\n private getPairs(word: string[]): Set<string> {\n const pairs = new Set<string>();\n for (let i = 0; i < word.length - 1; i++) {\n pairs.add(`${word[i]} ${word[i + 1]}`);\n }\n return pairs;\n }\n\n /**\n * Apply BPE to a word\n */\n private bpe(token: string): string[] {\n if (this.vocab.has(token)) {\n return [token];\n }\n \n let word = token.split('');\n let pairs = this.getPairs(word);\n \n if (pairs.size === 0) {\n return [token];\n }\n \n while (true) {\n // Find the pair with lowest merge rank\n let minPair: string | null = null;\n let minRank = Infinity;\n \n for (const pair of pairs) {\n const rank = this.merges.get(pair);\n if (rank !== undefined && rank < minRank) {\n minRank = rank;\n minPair = pair;\n }\n }\n \n if (minPair === null) break;\n \n const parts = minPair.split(' ');\n const first = parts[0];\n const second = parts[1];\n if (!first || !second) break;\n \n const newWord: string[] = [];\n let i = 0;\n \n while (i < word.length) {\n const j = word.indexOf(first, i);\n if (j === -1) {\n newWord.push(...word.slice(i));\n break;\n }\n \n newWord.push(...word.slice(i, j));\n \n if (word[j] === first && j < word.length - 1 && word[j + 1] === second) {\n newWord.push(first + second);\n i = j + 2;\n } else {\n newWord.push(word[j]!);\n i = j + 1;\n }\n }\n \n word = newWord;\n \n if (word.length === 1) break;\n \n pairs = this.getPairs(word);\n }\n \n return word;\n }\n\n /**\n * WordPiece tokenization\n */\n private wordPiece(word: string): string[] {\n if (this.vocab.has(word)) {\n return [word];\n }\n \n const tokens: string[] = [];\n let start = 0;\n \n while (start < word.length) {\n let end = word.length;\n let curSubstr: string | null = null;\n \n while (start < end) {\n let substr = word.slice(start, end);\n if (start > 0) {\n substr = this.continuingSubwordPrefix + substr;\n }\n \n if (this.vocab.has(substr)) {\n curSubstr = substr;\n break;\n }\n end--;\n }\n \n if (curSubstr === null) {\n tokens.push(this.unkToken);\n start++;\n } else {\n tokens.push(curSubstr);\n start = end;\n }\n }\n \n return tokens;\n }\n\n /**\n * Tokenize a single word\n */\n private tokenizeWord(word: string): string[] {\n // Check added tokens first\n if (this.addedTokens.has(word)) {\n return [word];\n }\n \n switch (this.modelType) {\n case 'BPE': {\n // Convert to byte representation\n const byteStr = this.textToBytes(word);\n return this.bpe(byteStr);\n }\n case 'WordPiece':\n return this.wordPiece(word);\n case 'Unigram':\n return this.unigramTokenize(word);\n default:\n return this.vocab.has(word) ? [word] : [this.unkToken];\n }\n }\n\n /**\n * Greedy longest-match tokenizer for SentencePiece Unigram models.\n * Adds the U+2581 (\u2581) word-start prefix expected by SPM-based models.\n */\n private unigramTokenize(word: string): string[] {\n // SentencePiece prepends \u2581 to words that follow a space (i.e. the\n // tokenizer receives individual words, so all of them get the prefix).\n const prefixedWord = '\\u2581' + word;\n const tokens: string[] = [];\n let start = 0;\n const text = prefixedWord;\n\n while (start < text.length) {\n let end = text.length;\n let found = false;\n // Greedy longest-match scan\n while (end > start) {\n const sub = text.slice(start, end);\n if (this.vocab.has(sub)) {\n tokens.push(sub);\n start = end;\n found = true;\n break;\n }\n end--;\n }\n if (!found) {\n // Emit the single character (or unk if it's not in vocab either)\n const ch = text[start]!;\n tokens.push(this.vocab.has(ch) ? ch : this.unkToken);\n start++;\n }\n }\n\n return tokens.length > 0 ? tokens : [this.unkToken];\n }\n\n /**\n * Main tokenization\n */\n private tokenize(text: string): string[] {\n // Normalize\n const normalized = this.normalize(text);\n \n // Check for added tokens (special tokens)\n const tokens: string[] = [];\n let remaining = normalized;\n \n // Sort added tokens by length (longest first) for greedy matching\n const sortedAddedTokens = Array.from(this.addedTokens.keys())\n .sort((a, b) => b.length - a.length);\n \n // Split by added tokens\n for (const addedToken of sortedAddedTokens) {\n if (remaining.includes(addedToken)) {\n const parts = remaining.split(addedToken);\n const newRemaining: string[] = [];\n \n for (let i = 0; i < parts.length; i++) {\n if (parts[i]) {\n newRemaining.push(parts[i]!);\n }\n if (i < parts.length - 1) {\n tokens.push(addedToken);\n }\n }\n \n remaining = newRemaining.join(' ');\n }\n }\n \n // Pre-tokenize remaining text\n if (remaining.trim()) {\n const words = this.preTokenize(remaining);\n \n for (const word of words) {\n if (!word) continue;\n const wordTokens = this.tokenizeWord(word);\n tokens.push(...wordTokens);\n }\n }\n \n return tokens;\n }\n\n /**\n * Convert tokens to IDs\n */\n private convertTokensToIds(tokens: string[]): number[] {\n return tokens.map(token => {\n // Check added tokens first\n const addedId = this.addedTokens.get(token);\n if (addedId !== undefined) return addedId;\n \n // Check vocabulary\n const vocabId = this.vocab.get(token);\n if (vocabId !== undefined) return vocabId;\n \n // Return UNK\n return this.unkTokenId;\n });\n }\n\n /**\n * Convert IDs to tokens\n */\n private convertIdsToTokens(ids: number[]): string[] {\n return ids.map(id => this.reverseVocab.get(id) ?? this.unkToken);\n }\n\n /**\n * Apply post-processing (add special tokens)\n */\n private postProcess(\n ids: number[],\n pairIds?: number[]\n ): { ids: number[]; typeIds: number[] } {\n if (!this.postProcessor) {\n // Default: [CLS] tokens [SEP] or [CLS] tokens [SEP] pair [SEP]\n const result: number[] = [];\n const typeIds: number[] = [];\n \n if (this.clsTokenId !== undefined) {\n result.push(this.clsTokenId);\n typeIds.push(0);\n }\n \n result.push(...ids);\n typeIds.push(...ids.map(() => 0));\n \n if (this.sepTokenId !== undefined) {\n result.push(this.sepTokenId);\n typeIds.push(0);\n }\n \n if (pairIds) {\n result.push(...pairIds);\n typeIds.push(...pairIds.map(() => 1));\n \n if (this.sepTokenId !== undefined) {\n result.push(this.sepTokenId);\n typeIds.push(1);\n }\n }\n \n return { ids: result, typeIds };\n }\n \n // Use post-processor config\n const template = pairIds ? this.postProcessor.pair : this.postProcessor.single;\n if (!template) {\n return { ids, typeIds: ids.map(() => 0) };\n }\n \n const result: number[] = [];\n const typeIds: number[] = [];\n \n for (const item of template) {\n if ('SpecialToken' in item) {\n const specialToken = this.postProcessor.special_tokens?.[item.SpecialToken.id];\n if (specialToken) {\n result.push(...specialToken.ids);\n typeIds.push(...specialToken.ids.map(() => item.SpecialToken.type_id));\n }\n } else if ('Sequence' in item) {\n const seqIds = item.Sequence.id === 'A' ? ids : pairIds ?? [];\n result.push(...seqIds);\n typeIds.push(...seqIds.map(() => item.Sequence.type_id));\n }\n }\n \n return { ids: result, typeIds };\n }\n\n /**\n * Encode text\n */\n encode(text: string, options: TokenizerOptions = {}): TokenizedOutput {\n const {\n addSpecialTokens = true,\n maxLength = this.maxLength,\n padding = 'max_length',\n truncation = true,\n returnAttentionMask = true,\n returnTokenTypeIds = false,\n textPair,\n } = options;\n \n // Tokenize\n const tokens = this.tokenize(text);\n let inputIds = this.convertTokensToIds(tokens);\n \n // Tokenize pair if provided\n let pairIds: number[] | undefined;\n if (textPair) {\n const pairTokens = this.tokenize(textPair);\n pairIds = this.convertTokensToIds(pairTokens);\n }\n \n // Post-process (add special tokens)\n let tokenTypeIds: number[] | undefined;\n if (addSpecialTokens) {\n const processed = this.postProcess(inputIds, pairIds);\n inputIds = processed.ids;\n if (returnTokenTypeIds) {\n tokenTypeIds = processed.typeIds;\n }\n } else if (pairIds) {\n inputIds = [...inputIds, ...pairIds];\n if (returnTokenTypeIds) {\n tokenTypeIds = [...inputIds.map(() => 0), ...pairIds.map(() => 1)];\n }\n }\n \n // Truncate\n if (truncation && inputIds.length > maxLength) {\n inputIds = inputIds.slice(0, maxLength);\n if (tokenTypeIds) {\n tokenTypeIds = tokenTypeIds.slice(0, maxLength);\n }\n }\n \n // Create attention mask\n let attentionMask: number[] = [];\n if (returnAttentionMask) {\n attentionMask = inputIds.map(() => 1);\n }\n \n // Padding\n if (padding === 'max_length' && inputIds.length < maxLength) {\n const padLength = maxLength - inputIds.length;\n inputIds = [...inputIds, ...new Array(padLength).fill(this.padTokenId) as number[]];\n if (returnAttentionMask) {\n attentionMask = [...attentionMask, ...new Array(padLength).fill(0) as number[]];\n }\n if (tokenTypeIds) {\n tokenTypeIds = [...tokenTypeIds, ...new Array(padLength).fill(0) as number[]];\n }\n }\n \n const result: TokenizedOutput = {\n inputIds,\n attentionMask,\n };\n \n if (returnTokenTypeIds && tokenTypeIds) {\n result.tokenTypeIds = tokenTypeIds;\n }\n \n return result;\n }\n\n /**\n * Batch encode\n */\n encodeBatch(texts: string[], options: TokenizerOptions = {}): TokenizedOutput[] {\n // For 'longest' padding, first encode all without padding\n if (options.padding === 'longest') {\n const encodings = texts.map(t => this.encode(t, { ...options, padding: 'do_not_pad' }));\n const maxLen = Math.max(...encodings.map(e => e.inputIds.length));\n return texts.map(t => this.encode(t, { ...options, maxLength: maxLen, padding: 'max_length' }));\n }\n \n return texts.map(t => this.encode(t, options));\n }\n\n /**\n * Decode IDs to text\n */\n decode(ids: number[], skipSpecialTokens = true): string {\n let tokens = this.convertIdsToTokens(ids);\n\n if (skipSpecialTokens) {\n tokens = tokens.filter(t => !this.specialTokens.has(t));\n }\n\n if (this.modelType === 'BPE') {\n // BPE: byte-level encoding, join raw and decode bytes\n return this.bytesToText(tokens.join('')).replace(/\\s+/g, ' ').trim();\n }\n\n if (this.modelType === 'WordPiece') {\n // WordPiece: tokens starting with continuingSubwordPrefix (##) are\n // subword continuations and must be appended to the previous word\n // WITHOUT a space. All other tokens are word-starts and get a space.\n const prefix = this.continuingSubwordPrefix; // '##'\n const words: string[] = [];\n for (const token of tokens) {\n if (token.startsWith(prefix)) {\n if (words.length > 0) {\n words[words.length - 1] += token.slice(prefix.length);\n } else {\n words.push(token.slice(prefix.length));\n }\n } else {\n words.push(token);\n }\n }\n return words.join(' ').replace(/\\s+/g, ' ').trim();\n }\n\n if (this.modelType === 'Unigram') {\n // SentencePiece: \u2581 marks word boundaries (replaces the leading space)\n return tokens\n .join('')\n .replace(/\\u2581/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n }\n\n // Default: space-join\n return tokens.join(' ').replace(/\\s+/g, ' ').trim();\n }\n\n /**\n * Decode batch\n */\n decodeBatch(batchIds: number[][], skipSpecialTokens = true): string[] {\n return batchIds.map(ids => this.decode(ids, skipSpecialTokens));\n }\n\n /**\n * Get vocabulary size\n */\n get vocabSize(): number {\n return this.vocab.size + this.addedTokens.size;\n }\n\n /**\n * Get special token IDs\n */\n getSpecialTokenIds(): {\n padTokenId: number;\n unkTokenId: number;\n clsTokenId?: number;\n sepTokenId?: number;\n maskTokenId?: number;\n bosTokenId?: number;\n eosTokenId?: number;\n } {\n return {\n padTokenId: this.padTokenId,\n unkTokenId: this.unkTokenId,\n clsTokenId: this.clsTokenId,\n sepTokenId: this.sepTokenId,\n maskTokenId: this.maskTokenId,\n bosTokenId: this.bosTokenId,\n eosTokenId: this.eosTokenId,\n };\n }\n\n /**\n * Get config\n */\n getConfig(): TokenizerConfig {\n return {\n vocabSize: this.vocabSize,\n maxLength: this.maxLength,\n padTokenId: this.padTokenId,\n unkTokenId: this.unkTokenId,\n clsTokenId: this.clsTokenId,\n sepTokenId: this.sepTokenId,\n maskTokenId: this.maskTokenId,\n bosTokenId: this.bosTokenId,\n eosTokenId: this.eosTokenId,\n };\n }\n\n /**\n * Check if token is special\n */\n isSpecialToken(token: string): boolean {\n return this.specialTokens.has(token);\n }\n\n /**\n * Get token ID\n */\n getTokenId(token: string): number | undefined {\n return this.addedTokens.get(token) ?? this.vocab.get(token);\n }\n\n /**\n * Get token from ID\n */\n getToken(id: number): string | undefined {\n return this.reverseVocab.get(id);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a basic English tokenizer (for testing)\n */\nexport function createBasicTokenizer(): Tokenizer {\n const tokenizer = new Tokenizer();\n return tokenizer;\n}\n\n/**\n * Load tokenizer from URL\n */\nexport async function loadTokenizer(url: string): Promise<Tokenizer> {\n return Tokenizer.fromUrl(url);\n}\n\n/**\n * Load tokenizer from HuggingFace Hub\n */\nexport async function loadTokenizerFromHub(\n modelId: string,\n options?: { revision?: string }\n): Promise<Tokenizer> {\n return Tokenizer.fromHuggingFace(modelId, options);\n}\n\n", "/**\n * edgeFlow.js - Feature Extraction Pipeline\n * \n * Extract embeddings/features from text using sentence-transformer models.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\nimport {\n BasePipeline,\n FeatureExtractionResult,\n registerPipeline,\n} from './base.js';\n\n// ============================================================================\n// Default Model (all-MiniLM-L6-v2, 384-dim sentence embeddings)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/all-MiniLM-L6-v2/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/all-MiniLM-L6-v2/resolve/main/tokenizer.json',\n};\n\nconst DEFAULT_EMBEDDING_DIM = 384;\n\n// ============================================================================\n// Feature Extraction Pipeline\n// ============================================================================\n\nexport interface FeatureExtractionOptions extends PipelineOptions {\n pooling?: 'mean' | 'max' | 'cls' | 'none';\n normalize?: boolean;\n outputDim?: number;\n}\n\nexport class FeatureExtractionPipeline extends BasePipeline<\n string | string[],\n FeatureExtractionResult | FeatureExtractionResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private embeddingDim: number;\n private modelUrl: string;\n private tokenizerUrl: string;\n private modelInputNames: Set<string> = new Set();\n\n constructor(config: PipelineConfig, embeddingDim: number = DEFAULT_EMBEDDING_DIM) {\n super(config);\n this.embeddingDim = embeddingDim;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = config.tokenizerUrl ?? DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n this.modelInputNames = new Set(this.onnxModel.metadata.inputs.map(i => i.name));\n }\n }\n\n override async run(\n input: string | string[],\n options?: FeatureExtractionOptions\n ): Promise<FeatureExtractionResult | FeatureExtractionResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n \n await this.initialize();\n \n const startTime = performance.now();\n const results: FeatureExtractionResult[] = [];\n\n for (const text of inputs) {\n const tensorInputs = await this.preprocess(text);\n const outputs = await this.runInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n const text = Array.isArray(input) ? input[0]! : input;\n \n const encoded = this.tokenizer!.encode(text, {\n maxLength: 128,\n padding: 'max_length',\n truncation: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n const tensors: EdgeFlowTensor[] = [inputIds, attentionMask];\n\n // Only emit token_type_ids when the loaded model declares it as an input.\n // XLM-R / RoBERTa / multilingual MiniLM omit this input; feeding it would\n // trip onnxruntime-web's session.run with \"invalid input\" errors.\n if (this.modelInputNames.has('token_type_ids')) {\n const tokenTypeIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(() => BigInt(0))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n tensors.push(tokenTypeIds);\n }\n\n return tensors;\n }\n\n private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputs[0]!);\n namedInputs.set('attention_mask', inputs[1]!);\n if (this.modelInputNames.has('token_type_ids') && inputs[2]) {\n namedInputs.set('token_type_ids', inputs[2]);\n }\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: FeatureExtractionOptions\n ): Promise<FeatureExtractionResult> {\n const hiddenStates = outputs[0];\n if (!hiddenStates) {\n return { embeddings: [] };\n }\n\n const pooling = options?.pooling ?? 'mean';\n const normalize = options?.normalize ?? true;\n\n let embeddings: number[];\n\n switch (pooling) {\n case 'cls':\n embeddings = this.extractCLSEmbedding(hiddenStates);\n break;\n case 'max':\n embeddings = this.maxPooling(hiddenStates);\n break;\n case 'none':\n embeddings = hiddenStates.toArray();\n break;\n case 'mean':\n default:\n embeddings = this.meanPooling(hiddenStates);\n break;\n }\n\n if (normalize) {\n embeddings = this.normalizeVector(embeddings);\n }\n\n if (options?.outputDim && options.outputDim < embeddings.length) {\n embeddings = embeddings.slice(0, options.outputDim);\n }\n\n return { embeddings };\n }\n\n private extractCLSEmbedding(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n return Array.from(data.slice(0, embeddingDim));\n }\n\n private meanPooling(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const seqLen = hiddenStates.shape[1] ?? 1;\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n \n const result = new Float32Array(embeddingDim);\n for (let i = 0; i < seqLen; i++) {\n for (let j = 0; j < embeddingDim; j++) {\n result[j] = (result[j] ?? 0) + (data[i * embeddingDim + j] ?? 0) / seqLen;\n }\n }\n return Array.from(result);\n }\n\n private maxPooling(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const seqLen = hiddenStates.shape[1] ?? 1;\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n \n const result = new Array(embeddingDim).fill(-Infinity) as number[];\n for (let i = 0; i < seqLen; i++) {\n for (let j = 0; j < embeddingDim; j++) {\n const val = data[i * embeddingDim + j] ?? 0;\n if (val > (result[j] ?? -Infinity)) {\n result[j] = val;\n }\n }\n }\n return result;\n }\n\n private normalizeVector(vec: number[]): number[] {\n let norm = 0;\n for (const v of vec) {\n norm += v * v;\n }\n norm = Math.sqrt(norm);\n if (norm === 0) return vec;\n return vec.map(v => v / norm);\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\nexport function createFeatureExtractionPipeline(\n config: Partial<PipelineConfig> = {}\n): FeatureExtractionPipeline {\n return new FeatureExtractionPipeline({\n task: 'feature-extraction',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n tokenizerUrl: config.tokenizerUrl,\n });\n}\n\nregisterPipeline('feature-extraction', (config) => new FeatureExtractionPipeline(config));\n", "/**\n * edgeFlow.js - Image Classification Pipeline\n * \n * Classify images into categories using vision models.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { ImagePreprocessor, createImagePreprocessor } from '../utils/preprocessor.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference } from '../core/runtime.js';\nimport {\n BasePipeline,\n ImageClassificationResult,\n registerPipeline,\n IMAGENET_LABELS,\n} from './base.js';\n\n// ============================================================================\n// Default Model (MobileViT-small, quantized)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/mobilevit-small/resolve/main/onnx/model_quantized.onnx',\n};\n\n\n// ============================================================================\n// Image Classification Pipeline\n// ============================================================================\n\nexport interface ImageClassificationOptions extends PipelineOptions {\n returnAllScores?: boolean;\n labels?: string[];\n topK?: number;\n}\n\nexport type ImageInput =\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | ImageData\n | string;\n\nexport class ImageClassificationPipeline extends BasePipeline<\n ImageInput | ImageInput[],\n ImageClassificationResult | ImageClassificationResult[]\n> {\n private preprocessor: ImagePreprocessor | null = null;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n\n constructor(\n config: PipelineConfig,\n labels?: string[],\n _numClasses: number = 1000\n ) {\n super(config);\n this.labels = labels ?? IMAGENET_LABELS;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.preprocessor) {\n this.preprocessor = createImagePreprocessor('imagenet');\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: ImageInput | ImageInput[],\n options?: ImageClassificationOptions\n ): Promise<ImageClassificationResult | ImageClassificationResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n\n await this.initialize();\n\n const startTime = performance.now();\n const results: ImageClassificationResult[] = [];\n\n for (const image of inputs) {\n const tensorInputs = await this.preprocess(image);\n const outputs = await this.runModelInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: ImageInput | ImageInput[]): Promise<EdgeFlowTensor[]> {\n const image = Array.isArray(input) ? input[0]! : input;\n const tensor = await this.preprocessor!.process(image);\n\n if (tensor.shape.length === 3) {\n return [tensor.reshape([1, ...tensor.shape])];\n }\n return [tensor];\n }\n\n private async runModelInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const outputs = await runInference(this.onnxModel!, inputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: ImageClassificationOptions\n ): Promise<ImageClassificationResult> {\n const logits = outputs[0];\n if (!logits) {\n return { label: 'unknown', score: 0 };\n }\n\n const probs = softmax(logits, -1) as EdgeFlowTensor;\n const probsArray = probs.toFloat32Array();\n\n let maxIdx = 0;\n let maxScore = probsArray[0] ?? 0;\n\n for (let i = 1; i < probsArray.length; i++) {\n if ((probsArray[i] ?? 0) > maxScore) {\n maxScore = probsArray[i] ?? 0;\n maxIdx = i;\n }\n }\n\n const label = options?.labels?.[maxIdx] ?? this.labels[maxIdx] ?? `class_${maxIdx}`;\n\n return { label, score: maxScore };\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\nexport function createImageClassificationPipeline(\n config: Partial<PipelineConfig> = {},\n labels?: string[]\n): ImageClassificationPipeline {\n return new ImageClassificationPipeline(\n {\n task: 'image-classification',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n },\n labels\n );\n}\n\nregisterPipeline('image-classification', (config) => new ImageClassificationPipeline(config));\n", "/**\n * edgeFlow.js - Preprocessor\n * \n * Data preprocessing utilities for images, audio, and other data types.\n * Supports HuggingFace preprocessor_config.json format.\n */\n\nimport { EdgeFlowTensor } from '../core/tensor.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Image input types\n */\nexport type ImageInput = \n | HTMLImageElement \n | HTMLCanvasElement \n | ImageBitmap \n | ImageData \n | Blob \n | File \n | string;\n\n/**\n * Audio input types\n */\nexport type AudioInput = \n | AudioBuffer \n | Float32Array \n | ArrayBuffer \n | Blob \n | File \n | string;\n\n// ============================================================================\n// Image Preprocessing\n// ============================================================================\n\n/**\n * Image preprocessing options\n */\nexport interface ImagePreprocessorOptions {\n /** Target width (or size for square) */\n width?: number;\n /** Target height */\n height?: number;\n /** Single size for square output (sets both width and height) */\n size?: number;\n /** Resize mode */\n resizeMode?: 'stretch' | 'contain' | 'cover' | 'pad' | 'shortest_edge' | 'longest_edge';\n /** Normalization mean */\n mean?: [number, number, number];\n /** Normalization std */\n std?: [number, number, number];\n /** Rescale factor (applied before normalization) */\n rescaleFactor?: number;\n /** Convert to grayscale */\n grayscale?: boolean;\n /** Channel format */\n channelFormat?: 'CHW' | 'HWC';\n /** Output data type */\n dtype?: 'float32' | 'uint8';\n /** Do resize */\n doResize?: boolean;\n /** Do rescale */\n doRescale?: boolean;\n /** Do normalize */\n doNormalize?: boolean;\n /** Do center crop */\n doCenterCrop?: boolean;\n /** Center crop size */\n cropSize?: number | { width: number; height: number };\n /** Padding color for 'pad' mode (RGB 0-255) */\n paddingColor?: [number, number, number];\n}\n\n/**\n * Default image preprocessing options (ImageNet style)\n */\nconst DEFAULT_IMAGE_OPTIONS: ImagePreprocessorOptions = {\n width: 224,\n height: 224,\n resizeMode: 'cover',\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n rescaleFactor: 1 / 255,\n grayscale: false,\n channelFormat: 'CHW',\n dtype: 'float32',\n doResize: true,\n doRescale: true,\n doNormalize: true,\n doCenterCrop: false,\n paddingColor: [0, 0, 0],\n};\n\n/**\n * ImagePreprocessor - Process images for model input\n * \n * Supports HuggingFace preprocessor_config.json format.\n */\nexport class ImagePreprocessor {\n private readonly options: Required<ImagePreprocessorOptions>;\n private canvas: HTMLCanvasElement | null = null;\n private ctx: CanvasRenderingContext2D | null = null;\n\n constructor(options: ImagePreprocessorOptions = {}) {\n // Handle size option\n const size = options.size;\n const width = options.width ?? size ?? DEFAULT_IMAGE_OPTIONS.width!;\n const height = options.height ?? size ?? DEFAULT_IMAGE_OPTIONS.height!;\n \n this.options = {\n ...DEFAULT_IMAGE_OPTIONS,\n ...options,\n width,\n height,\n size: size ?? width,\n cropSize: options.cropSize ?? options.size ?? width,\n } as Required<ImagePreprocessorOptions>;\n }\n\n /**\n * Load from HuggingFace preprocessor_config.json\n */\n static fromConfig(config: Record<string, unknown>): ImagePreprocessor {\n const options: ImagePreprocessorOptions = {};\n \n // Map HuggingFace config to our options\n const size = config['size'];\n if (size !== undefined) {\n if (typeof size === 'number') {\n options.size = size;\n } else if (typeof size === 'object' && size !== null) {\n const sizeObj = size as { width?: number; height?: number; shortest_edge?: number };\n options.width = sizeObj.width ?? sizeObj.shortest_edge;\n options.height = sizeObj.height ?? sizeObj.shortest_edge;\n }\n }\n \n const cropSize = config['crop_size'];\n if (cropSize !== undefined) {\n if (typeof cropSize === 'number') {\n options.cropSize = cropSize;\n } else if (typeof cropSize === 'object' && cropSize !== null) {\n const cropObj = cropSize as { width?: number; height?: number };\n options.cropSize = { width: cropObj.width ?? 224, height: cropObj.height ?? 224 };\n }\n }\n \n const imageMean = config['image_mean'];\n if (Array.isArray(imageMean)) {\n options.mean = imageMean as [number, number, number];\n }\n \n const imageStd = config['image_std'];\n if (Array.isArray(imageStd)) {\n options.std = imageStd as [number, number, number];\n }\n \n const rescaleFactor = config['rescale_factor'];\n if (typeof rescaleFactor === 'number') {\n options.rescaleFactor = rescaleFactor;\n }\n \n const doResize = config['do_resize'];\n if (typeof doResize === 'boolean') {\n options.doResize = doResize;\n }\n \n const doRescale = config['do_rescale'];\n if (typeof doRescale === 'boolean') {\n options.doRescale = doRescale;\n }\n \n const doNormalize = config['do_normalize'];\n if (typeof doNormalize === 'boolean') {\n options.doNormalize = doNormalize;\n }\n \n const doCenterCrop = config['do_center_crop'];\n if (typeof doCenterCrop === 'boolean') {\n options.doCenterCrop = doCenterCrop;\n }\n \n if (config['resample'] !== undefined) {\n // Map HuggingFace resample to our resize mode\n options.resizeMode = 'cover';\n }\n \n return new ImagePreprocessor(options);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromUrl(url: string): Promise<ImagePreprocessor> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load preprocessor config from ${url}`);\n }\n const config = await response.json() as Record<string, unknown>;\n return ImagePreprocessor.fromConfig(config);\n }\n\n /**\n * Load from HuggingFace Hub by model ID\n */\n static async fromHuggingFace(\n modelId: string,\n options?: { revision?: string }\n ): Promise<ImagePreprocessor> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/preprocessor_config.json`;\n return ImagePreprocessor.fromUrl(url);\n }\n\n /**\n * Initialize canvas (lazy)\n */\n private ensureCanvas(): void {\n if (!this.canvas) {\n if (typeof document !== 'undefined') {\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d');\n } else {\n throw new Error('ImagePreprocessor requires a browser environment');\n }\n }\n }\n\n /**\n * Process an image\n */\n async process(input: ImageInput): Promise<EdgeFlowTensor> {\n let imageData: ImageData;\n\n if (typeof input === 'string') {\n // Load from URL or base64\n imageData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n imageData = await this.loadFromBlob(input);\n } else if (input instanceof ImageData) {\n imageData = input;\n } else {\n // HTMLImageElement, HTMLCanvasElement, ImageBitmap\n imageData = this.toImageData(input);\n }\n\n // Apply preprocessing pipeline\n let processed = imageData;\n\n // 1. Resize\n if (this.options.doResize) {\n processed = this.resize(processed);\n }\n\n // 2. Center crop\n if (this.options.doCenterCrop) {\n processed = this.centerCrop(processed);\n }\n\n // 3. Convert to tensor (with rescale and normalize)\n return this.toTensor(processed);\n }\n\n /**\n * Process multiple images (batch)\n */\n async processBatch(inputs: ImageInput[]): Promise<EdgeFlowTensor> {\n const tensors = await Promise.all(inputs.map(input => this.process(input)));\n \n // Stack tensors into batch\n const batchSize = tensors.length;\n const firstTensor = tensors[0];\n if (!firstTensor) {\n return new EdgeFlowTensor(new Float32Array(0), [0], 'float32');\n }\n \n const channels = firstTensor.shape[0] ?? 3;\n const height = firstTensor.shape[1] ?? this.options.height;\n const width = firstTensor.shape[2] ?? this.options.width;\n \n const batchData = new Float32Array(batchSize * channels * height * width);\n \n for (let i = 0; i < tensors.length; i++) {\n const t = tensors[i];\n if (t) {\n batchData.set(t.toFloat32Array(), i * channels * height * width);\n }\n }\n\n return new EdgeFlowTensor(\n batchData,\n [batchSize, channels, height, width],\n 'float32'\n );\n }\n\n /**\n * Load image from URL or base64\n */\n private async loadFromUrl(url: string): Promise<ImageData> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n \n img.onload = () => {\n resolve(this.toImageData(img));\n };\n \n img.onerror = () => {\n reject(new Error(`Failed to load image from ${url}`));\n };\n \n img.src = url;\n });\n }\n\n /**\n * Load image from Blob/File\n */\n private async loadFromBlob(blob: Blob): Promise<ImageData> {\n const url = URL.createObjectURL(blob);\n try {\n return await this.loadFromUrl(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n\n /**\n * Center crop image\n */\n private centerCrop(imageData: ImageData): ImageData {\n const cropSize = this.options.cropSize;\n let cropWidth: number;\n let cropHeight: number;\n \n if (typeof cropSize === 'number') {\n cropWidth = cropSize;\n cropHeight = cropSize;\n } else {\n cropWidth = cropSize.width;\n cropHeight = cropSize.height;\n }\n \n const srcX = Math.max(0, Math.floor((imageData.width - cropWidth) / 2));\n const srcY = Math.max(0, Math.floor((imageData.height - cropHeight) / 2));\n \n this.ensureCanvas();\n \n // Draw source image\n const srcCanvas = document.createElement('canvas');\n srcCanvas.width = imageData.width;\n srcCanvas.height = imageData.height;\n const srcCtx = srcCanvas.getContext('2d')!;\n srcCtx.putImageData(imageData, 0, 0);\n \n // Crop\n this.canvas!.width = cropWidth;\n this.canvas!.height = cropHeight;\n this.ctx!.drawImage(srcCanvas, srcX, srcY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);\n \n return this.ctx!.getImageData(0, 0, cropWidth, cropHeight);\n }\n\n /**\n * Convert image element to ImageData\n */\n private toImageData(\n source: HTMLImageElement | HTMLCanvasElement | ImageBitmap\n ): ImageData {\n this.ensureCanvas();\n \n const { width, height } = source;\n this.canvas!.width = width;\n this.canvas!.height = height;\n \n this.ctx!.drawImage(source, 0, 0);\n return this.ctx!.getImageData(0, 0, width, height);\n }\n\n /**\n * Resize image data\n */\n private resize(imageData: ImageData): ImageData {\n const { width, height, resizeMode } = this.options;\n \n this.ensureCanvas();\n \n // Calculate resize dimensions\n let srcX = 0, srcY = 0, srcW = imageData.width, srcH = imageData.height;\n let dstX = 0, dstY = 0, dstW = width, dstH = height;\n\n if (resizeMode === 'contain') {\n const scale = Math.min(width / imageData.width, height / imageData.height);\n dstW = Math.round(imageData.width * scale);\n dstH = Math.round(imageData.height * scale);\n dstX = Math.round((width - dstW) / 2);\n dstY = Math.round((height - dstH) / 2);\n } else if (resizeMode === 'cover') {\n const scale = Math.max(width / imageData.width, height / imageData.height);\n srcW = Math.round(width / scale);\n srcH = Math.round(height / scale);\n srcX = Math.round((imageData.width - srcW) / 2);\n srcY = Math.round((imageData.height - srcH) / 2);\n }\n\n // Create temp canvas for source\n const srcCanvas = document.createElement('canvas');\n srcCanvas.width = imageData.width;\n srcCanvas.height = imageData.height;\n const srcCtx = srcCanvas.getContext('2d')!;\n srcCtx.putImageData(imageData, 0, 0);\n\n // Draw to output canvas\n this.canvas!.width = width;\n this.canvas!.height = height;\n \n // Fill with black for padding modes\n if (resizeMode === 'contain' || resizeMode === 'pad') {\n this.ctx!.fillStyle = 'black';\n this.ctx!.fillRect(0, 0, width, height);\n }\n \n this.ctx!.drawImage(srcCanvas, srcX, srcY, srcW, srcH, dstX, dstY, dstW, dstH);\n \n return this.ctx!.getImageData(0, 0, width, height);\n }\n\n /**\n * Convert ImageData to tensor\n */\n private toTensor(imageData: ImageData): EdgeFlowTensor {\n const { \n mean, std, grayscale, channelFormat, dtype,\n doRescale, rescaleFactor, doNormalize\n } = this.options;\n \n const height = imageData.height;\n const width = imageData.width;\n const channels = grayscale ? 1 : 3;\n \n const data = new Float32Array(channels * height * width);\n const pixels = imageData.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const pixelIdx = (y * width + x) * 4;\n \n if (grayscale) {\n // Convert to grayscale\n let gray = (\n 0.299 * (pixels[pixelIdx] ?? 0) +\n 0.587 * (pixels[pixelIdx + 1] ?? 0) +\n 0.114 * (pixels[pixelIdx + 2] ?? 0)\n );\n \n if (doRescale) {\n gray *= rescaleFactor;\n }\n \n if (doNormalize) {\n gray = (gray - (mean[0] ?? 0)) / (std[0] ?? 1);\n }\n \n const idx = y * width + x;\n data[idx] = gray;\n } else if (channelFormat === 'CHW') {\n // Channel-first format (used by most PyTorch models)\n for (let c = 0; c < 3; c++) {\n let value = pixels[pixelIdx + c] ?? 0;\n \n if (doRescale) {\n value *= rescaleFactor;\n }\n \n if (doNormalize) {\n value = (value - (mean[c] ?? 0)) / (std[c] ?? 1);\n }\n \n const idx = c * height * width + y * width + x;\n data[idx] = value;\n }\n } else {\n // HWC format (used by TensorFlow models)\n for (let c = 0; c < 3; c++) {\n let value = pixels[pixelIdx + c] ?? 0;\n \n if (doRescale) {\n value *= rescaleFactor;\n }\n \n if (doNormalize) {\n value = (value - (mean[c] ?? 0)) / (std[c] ?? 1);\n }\n \n const idx = y * width * 3 + x * 3 + c;\n data[idx] = value;\n }\n }\n }\n }\n\n const shape = channelFormat === 'CHW'\n ? [channels, height, width]\n : [height, width, channels];\n\n return new EdgeFlowTensor(data, shape, dtype);\n }\n\n /**\n * Get current options\n */\n getOptions(): ImagePreprocessorOptions {\n return { ...this.options };\n }\n}\n\n// ============================================================================\n// Audio Preprocessing\n// ============================================================================\n\n/**\n * Audio preprocessing options\n */\nexport interface AudioPreprocessorOptions {\n /** Target sample rate */\n sampleRate?: number;\n /** Number of mel bins */\n nMels?: number;\n /** FFT size */\n nFft?: number;\n /** Hop length */\n hopLength?: number;\n /** Whether to normalize */\n normalize?: boolean;\n /** Maximum duration in seconds */\n maxDuration?: number;\n}\n\n/**\n * Default audio options\n */\nconst DEFAULT_AUDIO_OPTIONS: Required<AudioPreprocessorOptions> = {\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n normalize: true,\n maxDuration: 30,\n};\n\n/**\n * AudioPreprocessor - Process audio for model input\n * \n * Supports Whisper and other audio model preprocessing.\n */\nexport class AudioPreprocessor {\n private readonly options: Required<AudioPreprocessorOptions>;\n private audioContext: AudioContext | null = null;\n\n constructor(options: AudioPreprocessorOptions = {}) {\n this.options = { ...DEFAULT_AUDIO_OPTIONS, ...options };\n }\n\n /**\n * Load from HuggingFace feature_extractor config\n */\n static fromConfig(config: Record<string, unknown>): AudioPreprocessor {\n const options: AudioPreprocessorOptions = {};\n \n const samplingRate = config['sampling_rate'];\n if (typeof samplingRate === 'number') {\n options.sampleRate = samplingRate;\n }\n \n const featureSize = config['feature_size'];\n if (typeof featureSize === 'number') {\n options.nMels = featureSize;\n }\n \n const nFft = config['n_fft'];\n if (typeof nFft === 'number') {\n options.nFft = nFft;\n }\n \n const hopLength = config['hop_length'];\n if (typeof hopLength === 'number') {\n options.hopLength = hopLength;\n }\n \n return new AudioPreprocessor(options);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromHuggingFace(\n modelId: string,\n options?: { revision?: string }\n ): Promise<AudioPreprocessor> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/preprocessor_config.json`;\n \n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load audio config from ${url}`);\n }\n const config = await response.json() as Record<string, unknown>;\n return AudioPreprocessor.fromConfig(config);\n }\n\n /**\n * Initialize audio context (lazy)\n */\n private ensureAudioContext(): void {\n if (!this.audioContext) {\n if (typeof AudioContext !== 'undefined') {\n this.audioContext = new AudioContext({ sampleRate: this.options.sampleRate });\n } else {\n throw new Error('AudioPreprocessor requires Web Audio API support');\n }\n }\n }\n\n /**\n * Process audio data\n */\n async process(input: AudioInput): Promise<EdgeFlowTensor> {\n let audioData: Float32Array;\n\n if (typeof input === 'string') {\n // Load from URL\n audioData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n // Load from Blob/File\n audioData = await this.loadFromBlob(input);\n } else if (input instanceof AudioBuffer) {\n audioData = this.audioBufferToFloat32(input);\n } else if (input instanceof Float32Array) {\n audioData = input;\n } else {\n // ArrayBuffer - decode\n audioData = await this.decodeAudioData(input);\n }\n\n // Resample if needed\n // For now, assume input is at target sample rate\n\n // Normalize\n if (this.options.normalize) {\n audioData = this.normalizeAudio(audioData);\n }\n\n // Truncate if needed\n const maxSamples = this.options.maxDuration * this.options.sampleRate;\n if (audioData.length > maxSamples) {\n audioData = audioData.slice(0, maxSamples);\n }\n\n // Compute mel spectrogram (simplified)\n const melSpec = this.computeMelSpectrogram(audioData);\n\n return melSpec;\n }\n\n /**\n * Process raw waveform (for models that don't need mel spectrogram)\n */\n async processRaw(input: AudioInput): Promise<EdgeFlowTensor> {\n let audioData: Float32Array;\n\n if (typeof input === 'string') {\n audioData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n audioData = await this.loadFromBlob(input);\n } else if (input instanceof AudioBuffer) {\n audioData = this.audioBufferToFloat32(input);\n } else if (input instanceof Float32Array) {\n audioData = input;\n } else {\n audioData = await this.decodeAudioData(input);\n }\n\n // Normalize\n if (this.options.normalize) {\n audioData = this.normalizeAudio(audioData);\n }\n\n // Truncate/pad\n const maxSamples = this.options.maxDuration * this.options.sampleRate;\n if (audioData.length > maxSamples) {\n audioData = audioData.slice(0, maxSamples);\n }\n\n return new EdgeFlowTensor(audioData, [1, audioData.length], 'float32');\n }\n\n /**\n * Load audio from URL\n */\n private async loadFromUrl(url: string): Promise<Float32Array> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load audio from ${url}`);\n }\n \n const arrayBuffer = await response.arrayBuffer();\n return this.decodeAudioData(arrayBuffer);\n }\n\n /**\n * Load audio from Blob/File\n */\n private async loadFromBlob(blob: Blob): Promise<Float32Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return this.decodeAudioData(arrayBuffer);\n }\n\n /**\n * Decode audio data\n */\n private async decodeAudioData(data: ArrayBuffer): Promise<Float32Array> {\n this.ensureAudioContext();\n const audioBuffer = await this.audioContext!.decodeAudioData(data.slice(0)); // Clone to avoid detached buffer\n return this.audioBufferToFloat32(audioBuffer);\n }\n\n /**\n * Convert AudioBuffer to Float32Array\n */\n private audioBufferToFloat32(buffer: AudioBuffer): Float32Array {\n // Get first channel\n const channelData = buffer.getChannelData(0);\n return new Float32Array(channelData);\n }\n\n /**\n * Normalize audio\n */\n private normalizeAudio(data: Float32Array): Float32Array {\n let max = 0;\n for (let i = 0; i < data.length; i++) {\n const abs = Math.abs(data[i] ?? 0);\n if (abs > max) max = abs;\n }\n\n if (max > 0) {\n const result = new Float32Array(data.length);\n for (let i = 0; i < data.length; i++) {\n result[i] = (data[i] ?? 0) / max;\n }\n return result;\n }\n\n return data;\n }\n\n /**\n * Compute mel spectrogram (simplified implementation)\n */\n private computeMelSpectrogram(audio: Float32Array): EdgeFlowTensor {\n const { nMels, nFft, hopLength } = this.options;\n \n // Calculate number of frames\n const numFrames = Math.floor((audio.length - nFft) / hopLength) + 1;\n \n if (numFrames <= 0) {\n // Return empty spectrogram for very short audio\n return new EdgeFlowTensor(new Float32Array(nMels), [1, nMels], 'float32');\n }\n\n const melSpec = new Float32Array(numFrames * nMels);\n\n // Simplified mel spectrogram computation\n // In production, use proper FFT and mel filterbank\n for (let frame = 0; frame < numFrames; frame++) {\n const start = frame * hopLength;\n \n // Compute frame energy (simplified - not real FFT)\n for (let mel = 0; mel < nMels; mel++) {\n let energy = 0;\n const freqStart = Math.floor((mel / nMels) * (nFft / 2));\n const freqEnd = Math.floor(((mel + 1) / nMels) * (nFft / 2));\n \n for (let i = freqStart; i < Math.min(freqEnd, nFft); i++) {\n const sample = audio[start + i] ?? 0;\n energy += sample * sample;\n }\n \n // Convert to log scale\n melSpec[frame * nMels + mel] = Math.log(energy + 1e-10);\n }\n }\n\n return new EdgeFlowTensor(melSpec, [numFrames, nMels], 'float32');\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = null;\n }\n }\n}\n\n// ============================================================================\n// Text Preprocessing\n// ============================================================================\n\n/**\n * Text preprocessing options\n */\nexport interface TextPreprocessorOptions {\n /** Convert to lowercase */\n lowercase?: boolean;\n /** Remove punctuation */\n removePunctuation?: boolean;\n /** Remove extra whitespace */\n normalizeWhitespace?: boolean;\n /** Maximum length in characters */\n maxLength?: number;\n}\n\n/**\n * Preprocess text\n */\nexport function preprocessText(\n text: string,\n options: TextPreprocessorOptions = {}\n): string {\n const {\n lowercase = true,\n removePunctuation = false,\n normalizeWhitespace = true,\n maxLength,\n } = options;\n\n let result = text;\n\n if (lowercase) {\n result = result.toLowerCase();\n }\n\n if (removePunctuation) {\n result = result.replace(/[^\\w\\s]/g, '');\n }\n\n if (normalizeWhitespace) {\n result = result.replace(/\\s+/g, ' ').trim();\n }\n\n if (maxLength && result.length > maxLength) {\n result = result.slice(0, maxLength);\n }\n\n return result;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create image preprocessor with common presets\n */\nexport function createImagePreprocessor(\n preset: 'imagenet' | 'clip' | 'vit' | 'custom' = 'imagenet',\n options: ImagePreprocessorOptions = {}\n): ImagePreprocessor {\n const presets: Record<string, ImagePreprocessorOptions> = {\n imagenet: {\n width: 224,\n height: 224,\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n },\n clip: {\n width: 224,\n height: 224,\n mean: [0.48145466, 0.4578275, 0.40821073],\n std: [0.26862954, 0.26130258, 0.27577711],\n },\n vit: {\n width: 224,\n height: 224,\n mean: [0.5, 0.5, 0.5],\n std: [0.5, 0.5, 0.5],\n },\n custom: {},\n };\n\n return new ImagePreprocessor({ ...presets[preset], ...options });\n}\n\n/**\n * Create audio preprocessor with common presets\n */\nexport function createAudioPreprocessor(\n preset: 'whisper' | 'wav2vec' | 'custom' = 'whisper',\n options: AudioPreprocessorOptions = {}\n): AudioPreprocessor {\n const presets: Record<string, AudioPreprocessorOptions> = {\n whisper: {\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n },\n wav2vec: {\n sampleRate: 16000,\n normalize: true,\n },\n custom: {},\n };\n\n return new AudioPreprocessor({ ...presets[preset], ...options });\n}\n", "/**\n * edgeFlow.js - Text Generation Pipeline\n * \n * Autoregressive text generation with streaming support.\n * Supports GPT-2, LLaMA, Mistral, and other causal LM models.\n * Includes chat/conversation support with message history.\n */\n\nimport { BasePipeline, PipelineResult } from './base.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { runInferenceNamed, loadModelFromBuffer } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model URLs (TinyLlama - quantized for browser)\n// ============================================================================\n\nconst DEFAULT_LLM_MODELS = {\n model: 'https://huggingface.co/Xenova/TinyLlama-1.1B-Chat-v1.0/resolve/main/onnx/model_q4f16.onnx',\n tokenizer: 'https://huggingface.co/Xenova/TinyLlama-1.1B-Chat-v1.0/resolve/main/tokenizer.json',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * LLM model loading progress callback\n */\nexport interface LLMLoadProgress {\n /** Stage: 'tokenizer' or 'model' */\n stage: 'tokenizer' | 'model';\n /** Bytes loaded */\n loaded: number;\n /** Total bytes */\n total: number;\n /** Progress percentage (0-100) */\n progress: number;\n}\n\n/**\n * Chat message\n */\nexport interface ChatMessage {\n /** Role: 'system', 'user', or 'assistant' */\n role: 'system' | 'user' | 'assistant';\n /** Message content */\n content: string;\n}\n\n/**\n * Chat template type\n */\nexport type ChatTemplateType = 'chatml' | 'llama2' | 'llama3' | 'mistral' | 'phi3' | 'alpaca' | 'vicuna' | 'custom';\n\n/**\n * Text generation options\n */\nexport interface TextGenerationOptions {\n /** Maximum number of new tokens to generate */\n maxNewTokens?: number;\n /** Maximum total length (prompt + generated) */\n maxLength?: number;\n /** Minimum number of new tokens to generate */\n minNewTokens?: number;\n /** Sampling temperature (higher = more random) */\n temperature?: number;\n /** Top-k sampling (0 = disabled) */\n topK?: number;\n /** Top-p (nucleus) sampling (1.0 = disabled) */\n topP?: number;\n /** Repetition penalty (1.0 = disabled) */\n repetitionPenalty?: number;\n /** Stop sequences */\n stopSequences?: string[];\n /** Whether to do sampling (false = greedy) */\n doSample?: boolean;\n /** Number of sequences to return */\n numReturnSequences?: number;\n /** Return full text (including prompt) */\n returnFullText?: boolean;\n /** Callback for each generated token */\n onToken?: (token: string, tokenId: number) => void;\n}\n\n/**\n * Chat generation options\n */\nexport interface ChatOptions extends TextGenerationOptions {\n /** System prompt */\n systemPrompt?: string;\n /** Chat template type */\n templateType?: ChatTemplateType;\n /** Custom template (if templateType is 'custom') */\n customTemplate?: {\n systemPrefix?: string;\n systemSuffix?: string;\n userPrefix?: string;\n userSuffix?: string;\n assistantPrefix?: string;\n assistantSuffix?: string;\n separator?: string;\n };\n}\n\n/**\n * Text generation result\n */\nexport interface TextGenerationResult extends PipelineResult {\n /** Generated text */\n generatedText: string;\n /** Full text (prompt + generated) if returnFullText is true */\n fullText?: string;\n /** Generated token IDs */\n tokenIds: number[];\n /** Number of tokens generated */\n numTokens: number;\n}\n\n/**\n * Streaming generation event\n */\nexport interface GenerationStreamEvent {\n /** Current token */\n token: string;\n /** Token ID */\n tokenId: number;\n /** Generated text so far */\n generatedText: string;\n /** Whether generation is complete */\n done: boolean;\n}\n\n// ============================================================================\n// Text Generation Pipeline\n// ============================================================================\n\n/**\n * TextGenerationPipeline - Autoregressive text generation\n * \n * @example\n * ```typescript\n * const generator = await pipeline('text-generation', 'Xenova/gpt2');\n * \n * // Simple generation\n * const result = await generator.run('Once upon a time');\n * console.log(result.generatedText);\n * \n * // Streaming generation\n * for await (const event of generator.stream('Hello, ')) {\n * process.stdout.write(event.token);\n * }\n * ```\n */\nexport class TextGenerationPipeline extends BasePipeline<string | string[], TextGenerationResult | TextGenerationResult[]> {\n private tokenizer: Tokenizer | null = null;\n private eosTokenId: number = 50256; // GPT-2 default\n private llmModel: LoadedModel | null = null;\n private modelsLoaded: boolean = false;\n \n // Custom model URLs\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'text-generation',\n model: 'default',\n });\n this.modelUrl = DEFAULT_LLM_MODELS.model;\n this.tokenizerUrl = DEFAULT_LLM_MODELS.tokenizer;\n }\n\n /**\n * Check if model is loaded\n */\n get isModelLoaded(): boolean {\n return this.modelsLoaded;\n }\n\n /**\n * Set custom model URLs\n */\n setModelUrls(model: string, tokenizer: string): void {\n this.modelUrl = model;\n this.tokenizerUrl = tokenizer;\n }\n\n /**\n * Load model and tokenizer with progress callback\n */\n async loadModel(\n onProgress?: (progress: LLMLoadProgress) => void\n ): Promise<void> {\n if (this.modelsLoaded) return;\n\n // Load tokenizer first (small, fast)\n onProgress?.({ stage: 'tokenizer', loaded: 0, total: 100, progress: 0 });\n \n try {\n const tokenizerResponse = await fetch(this.tokenizerUrl);\n if (!tokenizerResponse.ok) {\n throw new Error(`Failed to fetch tokenizer: ${tokenizerResponse.status}`);\n }\n const tokenizerJson = await tokenizerResponse.json();\n this.tokenizer = await Tokenizer.fromJSON(tokenizerJson);\n \n const specialIds = this.tokenizer.getSpecialTokenIds();\n this.eosTokenId = specialIds.eosTokenId ?? specialIds.sepTokenId ?? 2; // TinyLlama uses 2 as EOS\n \n onProgress?.({ stage: 'tokenizer', loaded: 100, total: 100, progress: 100 });\n } catch (error) {\n throw new Error(`Failed to load tokenizer: ${error}`);\n }\n\n // Load model with progress tracking\n onProgress?.({ stage: 'model', loaded: 0, total: 100, progress: 0 });\n \n const modelData = await this.fetchModelWithProgress(\n this.modelUrl,\n (loaded, total) => {\n onProgress?.({\n stage: 'model',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.llmModel = await loadModelFromBuffer(modelData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n this.model = this.llmModel;\n\n this.modelsLoaded = true;\n }\n\n /**\n * Fetch model with progress tracking\n */\n private async fetchModelWithProgress(\n url: string,\n onProgress: (loaded: number, total: number) => void\n ): Promise<ArrayBuffer> {\n const response = await fetch(url);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch model: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body) {\n // Fallback if no streaming support\n const buffer = await response.arrayBuffer();\n onProgress(buffer.byteLength, buffer.byteLength);\n return buffer;\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n \n if (done) break;\n \n chunks.push(value);\n loaded += value.length;\n onProgress(loaded, total || loaded);\n }\n\n // Combine chunks into ArrayBuffer\n const buffer = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n return buffer.buffer;\n }\n\n /**\n * Initialize pipeline (override to skip default model loading)\n */\n override async initialize(): Promise<void> {\n if (this.isReady) return;\n // Don't call super.initialize() - we handle model loading separately\n this.isReady = true;\n }\n\n /**\n * Set tokenizer\n */\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n const specialIds = tokenizer.getSpecialTokenIds();\n this.eosTokenId = specialIds.eosTokenId ?? specialIds.sepTokenId ?? 50256;\n }\n\n /**\n * Preprocess - not used for text generation (handled in generateSingle)\n */\n protected async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n // For text generation, preprocessing is handled in generateNextToken\n const text = Array.isArray(input) ? input[0] ?? '' : input;\n if (!this.tokenizer) {\n // Return dummy tensor if no tokenizer\n return [new EdgeFlowTensor(new Float32Array([0]), [1], 'float32')];\n }\n const encoded = this.tokenizer.encode(text, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n });\n return [new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n )];\n }\n\n /**\n * Postprocess - not used for text generation (handled in generateSingle)\n */\n protected async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<TextGenerationResult | TextGenerationResult[]> {\n // For text generation, postprocessing is handled in generateSingle\n return {\n generatedText: '',\n tokenIds: [],\n numTokens: 0,\n processingTime: 0,\n };\n }\n\n /**\n * Generate text (non-streaming)\n */\n override async run(\n prompt: string | string[],\n options?: PipelineOptions & TextGenerationOptions\n ): Promise<TextGenerationResult | TextGenerationResult[]> {\n await this.initialize();\n \n const prompts = Array.isArray(prompt) ? prompt : [prompt];\n const results = await Promise.all(\n prompts.map(p => this.generateSingle(p, options ?? {}))\n );\n return Array.isArray(prompt) ? results : results[0]!;\n }\n\n /**\n * Generate text with streaming (async generator)\n */\n async *stream(\n prompt: string,\n options: TextGenerationOptions = {}\n ): AsyncGenerator<GenerationStreamEvent> {\n const startTime = performance.now();\n \n if (!this.tokenizer) {\n throw new Error('Tokenizer not set. Call setTokenizer() first.');\n }\n\n const {\n maxNewTokens = 50,\n maxLength = 512,\n temperature = 1.0,\n topK = 0,\n topP = 1.0,\n repetitionPenalty = 1.0,\n stopSequences = [],\n doSample = true,\n } = options;\n\n // Encode prompt\n const encoded = this.tokenizer.encode(prompt, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n truncation: false,\n });\n\n let inputIds = [...encoded.inputIds];\n const generatedIds: number[] = [];\n let generatedText = '';\n\n // Generation loop\n for (let i = 0; i < maxNewTokens; i++) {\n // Check max length\n if (inputIds.length >= maxLength) break;\n\n // Run model forward pass\n const nextTokenId = await this.generateNextToken(\n inputIds,\n temperature,\n topK,\n topP,\n repetitionPenalty,\n doSample\n );\n\n // Check for EOS\n if (nextTokenId === this.eosTokenId) {\n yield {\n token: '',\n tokenId: nextTokenId,\n generatedText,\n done: true,\n };\n break;\n }\n\n // Decode token\n const token = this.tokenizer.decode([nextTokenId], true);\n generatedIds.push(nextTokenId);\n inputIds.push(nextTokenId);\n generatedText += token;\n\n // Call token callback\n if (options.onToken) {\n options.onToken(token, nextTokenId);\n }\n\n // Check stop sequences\n let shouldStop = false;\n for (const stopSeq of stopSequences) {\n if (generatedText.endsWith(stopSeq)) {\n generatedText = generatedText.slice(0, -stopSeq.length);\n shouldStop = true;\n break;\n }\n }\n\n yield {\n token,\n tokenId: nextTokenId,\n generatedText,\n done: shouldStop,\n };\n\n if (shouldStop) break;\n }\n\n // Final event\n const endTime = performance.now();\n console.log(`Generation completed in ${(endTime - startTime).toFixed(2)}ms`);\n }\n\n /**\n * Generate a single sequence (non-streaming)\n */\n private async generateSingle(\n prompt: string,\n options: TextGenerationOptions\n ): Promise<TextGenerationResult> {\n const startTime = performance.now();\n \n if (!this.tokenizer) {\n throw new Error('Tokenizer not set. Call setTokenizer() first.');\n }\n\n const {\n maxNewTokens = 50,\n maxLength = 512,\n temperature = 1.0,\n topK = 0,\n topP = 1.0,\n repetitionPenalty = 1.0,\n stopSequences = [],\n doSample = true,\n returnFullText = false,\n } = options;\n\n // Encode prompt\n const encoded = this.tokenizer.encode(prompt, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n truncation: false,\n });\n\n let inputIds = [...encoded.inputIds];\n const generatedIds: number[] = [];\n\n // Generation loop\n for (let i = 0; i < maxNewTokens; i++) {\n // Check max length\n if (inputIds.length >= maxLength) break;\n\n // Run model forward pass\n const nextTokenId = await this.generateNextToken(\n inputIds,\n temperature,\n topK,\n topP,\n repetitionPenalty,\n doSample\n );\n\n // Check for EOS\n if (nextTokenId === this.eosTokenId) break;\n\n // Add to sequence\n generatedIds.push(nextTokenId);\n inputIds.push(nextTokenId);\n\n // Call token callback\n if (options.onToken) {\n const token = this.tokenizer.decode([nextTokenId], true);\n options.onToken(token, nextTokenId);\n }\n\n // Check stop sequences\n const currentText = this.tokenizer.decode(generatedIds, true);\n let shouldStop = false;\n for (const stopSeq of stopSequences) {\n if (currentText.endsWith(stopSeq)) {\n shouldStop = true;\n break;\n }\n }\n if (shouldStop) break;\n }\n\n // Decode generated text\n const generatedText = this.tokenizer.decode(generatedIds, true);\n const endTime = performance.now();\n\n return {\n generatedText,\n fullText: returnFullText ? prompt + generatedText : undefined,\n tokenIds: generatedIds,\n numTokens: generatedIds.length,\n processingTime: endTime - startTime,\n };\n }\n\n /**\n * Generate next token using the model\n */\n private async generateNextToken(\n inputIds: number[],\n temperature: number,\n topK: number,\n topP: number,\n repetitionPenalty: number,\n doSample: boolean\n ): Promise<number> {\n if (!this.model) {\n throw new Error('Model not loaded');\n }\n\n const seqLen = inputIds.length;\n\n // Prepare named inputs\n const inputs = new Map<string, EdgeFlowTensor>();\n\n // input_ids: [1, seq_len]\n inputs.set('input_ids', new EdgeFlowTensor(\n BigInt64Array.from(inputIds.map(id => BigInt(id))),\n [1, seqLen],\n 'int64'\n ));\n\n // attention_mask: [1, seq_len]\n inputs.set('attention_mask', new EdgeFlowTensor(\n BigInt64Array.from(inputIds.map(() => BigInt(1))),\n [1, seqLen],\n 'int64'\n ));\n\n // position_ids: [1, seq_len] - sequential positions from 0 to seq_len-1\n inputs.set('position_ids', new EdgeFlowTensor(\n BigInt64Array.from(Array.from({ length: seqLen }, (_, i) => BigInt(i))),\n [1, seqLen],\n 'int64'\n ));\n\n // TinyLlama has 22 layers with GQA (4 KV heads, head_dim=64)\n // For first inference without cache, provide empty past_key_values\n const numLayers = 22;\n const numKVHeads = 4;\n const headDim = 64;\n \n for (let i = 0; i < numLayers; i++) {\n // past_key_values.{i}.key: [batch, num_kv_heads, 0, head_dim]\n inputs.set(`past_key_values.${i}.key`, new EdgeFlowTensor(\n new Float32Array(0),\n [1, numKVHeads, 0, headDim],\n 'float32'\n ));\n // past_key_values.{i}.value: [batch, num_kv_heads, 0, head_dim]\n inputs.set(`past_key_values.${i}.value`, new EdgeFlowTensor(\n new Float32Array(0),\n [1, numKVHeads, 0, headDim],\n 'float32'\n ));\n }\n\n // Run inference with named inputs\n const outputs = await runInferenceNamed(this.model, inputs);\n \n if (!outputs || outputs.length === 0) {\n throw new Error('Model returned no outputs');\n }\n\n // Get logits for last token\n const logits = outputs[0]!;\n const logitsData = logits.toFloat32Array();\n const vocabSize = logits.shape[logits.shape.length - 1] ?? 50257;\n \n // Get logits for the last position\n const lastPositionLogits = new Float32Array(vocabSize);\n const offset = (inputIds.length - 1) * vocabSize;\n \n for (let i = 0; i < vocabSize; i++) {\n lastPositionLogits[i] = logitsData[offset + i] ?? 0;\n }\n\n // Apply repetition penalty\n if (repetitionPenalty !== 1.0) {\n for (const prevId of inputIds) {\n if (prevId < vocabSize) {\n const score = lastPositionLogits[prevId] ?? 0;\n lastPositionLogits[prevId] = score > 0 \n ? score / repetitionPenalty \n : score * repetitionPenalty;\n }\n }\n }\n\n // Apply temperature\n if (temperature !== 1.0) {\n for (let i = 0; i < vocabSize; i++) {\n lastPositionLogits[i] = (lastPositionLogits[i] ?? 0) / temperature;\n }\n }\n\n // Convert to probabilities\n const logitsTensor = new EdgeFlowTensor(lastPositionLogits, [vocabSize], 'float32');\n const probs = softmax(logitsTensor).toFloat32Array();\n\n // Sample or greedy\n if (doSample) {\n return this.sample(probs, topK, topP);\n } else {\n return this.greedy(probs);\n }\n }\n\n /**\n * Greedy decoding (argmax)\n */\n private greedy(probs: Float32Array): number {\n let maxIdx = 0;\n let maxProb = probs[0] ?? 0;\n \n for (let i = 1; i < probs.length; i++) {\n if ((probs[i] ?? 0) > maxProb) {\n maxProb = probs[i] ?? 0;\n maxIdx = i;\n }\n }\n \n return maxIdx;\n }\n\n /**\n * Sample from probability distribution with top-k/top-p filtering\n */\n private sample(probs: Float32Array, topK: number, topP: number): number {\n // Create sorted indices\n const indices = Array.from({ length: probs.length }, (_, i) => i);\n indices.sort((a, b) => (probs[b] ?? 0) - (probs[a] ?? 0));\n\n // Apply top-k filtering\n let candidateIndices = indices;\n if (topK > 0 && topK < probs.length) {\n candidateIndices = indices.slice(0, topK);\n }\n\n // Apply top-p (nucleus) filtering\n if (topP < 1.0) {\n let cumulativeProb = 0;\n const filtered: number[] = [];\n \n for (const idx of candidateIndices) {\n filtered.push(idx);\n cumulativeProb += probs[idx] ?? 0;\n if (cumulativeProb >= topP) break;\n }\n \n candidateIndices = filtered;\n }\n\n // Renormalize probabilities\n let totalProb = 0;\n for (const idx of candidateIndices) {\n totalProb += probs[idx] ?? 0;\n }\n\n // Sample\n const r = Math.random() * totalProb;\n let cumulative = 0;\n \n for (const idx of candidateIndices) {\n cumulative += probs[idx] ?? 0;\n if (cumulative >= r) {\n return idx;\n }\n }\n\n // Fallback\n return candidateIndices[0] ?? 0;\n }\n\n // ==========================================================================\n // Chat / Conversation Support\n // ==========================================================================\n\n private conversationHistory: ChatMessage[] = [];\n private chatTemplateType: ChatTemplateType = 'chatml';\n\n /**\n * Set the chat template type\n */\n setChatTemplate(templateType: ChatTemplateType): void {\n this.chatTemplateType = templateType;\n }\n\n /**\n * Apply chat template to messages\n */\n applyChatTemplate(messages: ChatMessage[], options?: ChatOptions): string {\n const templateType = options?.templateType ?? this.chatTemplateType;\n \n switch (templateType) {\n case 'chatml':\n return this.applyChatMLTemplate(messages);\n case 'llama2':\n return this.applyLlama2Template(messages);\n case 'llama3':\n return this.applyLlama3Template(messages);\n case 'mistral':\n return this.applyMistralTemplate(messages);\n case 'phi3':\n return this.applyPhi3Template(messages);\n case 'alpaca':\n return this.applyAlpacaTemplate(messages);\n case 'vicuna':\n return this.applyVicunaTemplate(messages);\n case 'custom':\n return this.applyCustomTemplate(messages, options?.customTemplate ?? {});\n default:\n return this.applyChatMLTemplate(messages);\n }\n }\n\n /**\n * ChatML template (used by many models including Qwen, Yi)\n */\n private applyChatMLTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n for (const msg of messages) {\n prompt += `<|im_start|>${msg.role}\\n${msg.content}<|im_end|>\\n`;\n }\n prompt += '<|im_start|>assistant\\n';\n return prompt;\n }\n\n /**\n * Llama 2 template\n */\n private applyLlama2Template(messages: ChatMessage[]): string {\n let prompt = '';\n let systemMsg = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n systemMsg = msg.content;\n } else if (msg.role === 'user') {\n if (systemMsg) {\n prompt += `<s>[INST] <<SYS>>\\n${systemMsg}\\n<</SYS>>\\n\\n${msg.content} [/INST]`;\n systemMsg = '';\n } else {\n prompt += `<s>[INST] ${msg.content} [/INST]`;\n }\n } else if (msg.role === 'assistant') {\n prompt += ` ${msg.content} </s>`;\n }\n }\n \n return prompt;\n }\n\n /**\n * Llama 3 template\n */\n private applyLlama3Template(messages: ChatMessage[]): string {\n let prompt = '<|begin_of_text|>';\n \n for (const msg of messages) {\n prompt += `<|start_header_id|>${msg.role}<|end_header_id|>\\n\\n${msg.content}<|eot_id|>`;\n }\n \n prompt += '<|start_header_id|>assistant<|end_header_id|>\\n\\n';\n return prompt;\n }\n\n /**\n * Mistral template\n */\n private applyMistralTemplate(messages: ChatMessage[]): string {\n let prompt = '<s>';\n \n for (const msg of messages) {\n if (msg.role === 'user') {\n prompt += `[INST] ${msg.content} [/INST]`;\n } else if (msg.role === 'assistant') {\n prompt += ` ${msg.content}</s>`;\n } else if (msg.role === 'system') {\n prompt += `[INST] ${msg.content}\\n`;\n }\n }\n \n return prompt;\n }\n\n /**\n * Phi-3 template\n */\n private applyPhi3Template(messages: ChatMessage[]): string {\n let prompt = '';\n \n for (const msg of messages) {\n prompt += `<|${msg.role}|>\\n${msg.content}<|end|>\\n`;\n }\n \n prompt += '<|assistant|>\\n';\n return prompt;\n }\n\n /**\n * Alpaca template\n */\n private applyAlpacaTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n let instruction = '';\n let input = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n instruction = msg.content;\n } else if (msg.role === 'user') {\n input = msg.content;\n }\n }\n \n if (instruction) {\n prompt = `### Instruction:\\n${instruction}\\n\\n`;\n }\n if (input) {\n prompt += `### Input:\\n${input}\\n\\n`;\n }\n prompt += '### Response:\\n';\n \n return prompt;\n }\n\n /**\n * Vicuna template\n */\n private applyVicunaTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n prompt += `${msg.content}\\n\\n`;\n } else if (msg.role === 'user') {\n prompt += `USER: ${msg.content}\\n`;\n } else if (msg.role === 'assistant') {\n prompt += `ASSISTANT: ${msg.content}\\n`;\n }\n }\n \n prompt += 'ASSISTANT:';\n return prompt;\n }\n\n /**\n * Custom template\n */\n private applyCustomTemplate(\n messages: ChatMessage[],\n template: NonNullable<ChatOptions['customTemplate']>\n ): string {\n const {\n systemPrefix = '',\n systemSuffix = '\\n',\n userPrefix = 'User: ',\n userSuffix = '\\n',\n assistantPrefix = 'Assistant: ',\n assistantSuffix = '\\n',\n separator = '',\n } = template;\n \n let prompt = '';\n \n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!;\n if (i > 0) prompt += separator;\n \n switch (msg.role) {\n case 'system':\n prompt += `${systemPrefix}${msg.content}${systemSuffix}`;\n break;\n case 'user':\n prompt += `${userPrefix}${msg.content}${userSuffix}`;\n break;\n case 'assistant':\n prompt += `${assistantPrefix}${msg.content}${assistantSuffix}`;\n break;\n }\n }\n \n prompt += assistantPrefix;\n return prompt;\n }\n\n /**\n * Chat with the model\n * \n * @example\n * ```typescript\n * const generator = await pipeline('text-generation', 'model');\n * \n * // Single turn\n * const response = await generator.chat('Hello, how are you?');\n * \n * // Multi-turn with history\n * const response1 = await generator.chat('What is AI?');\n * const response2 = await generator.chat('Can you give an example?');\n * \n * // With system prompt\n * const response = await generator.chat('Hello', {\n * systemPrompt: 'You are a helpful assistant.',\n * });\n * ```\n */\n async chat(\n userMessage: string,\n options?: ChatOptions\n ): Promise<TextGenerationResult> {\n // Add system message if provided and not already present\n if (options?.systemPrompt && \n (this.conversationHistory.length === 0 || this.conversationHistory[0]?.role !== 'system')) {\n this.conversationHistory.unshift({\n role: 'system',\n content: options.systemPrompt,\n });\n }\n\n // Add user message\n this.conversationHistory.push({\n role: 'user',\n content: userMessage,\n });\n\n // Apply chat template\n const prompt = this.applyChatTemplate(this.conversationHistory, options);\n\n // Generate response\n const result = await this.run(prompt, {\n ...options,\n stopSequences: [\n ...(options?.stopSequences ?? []),\n '<|im_end|>',\n '<|end|>',\n '<|eot_id|>',\n '</s>',\n '\\n\\nUser:',\n '\\n\\nHuman:',\n ],\n });\n\n // Add assistant response to history\n const response = Array.isArray(result) ? result[0]! : result;\n this.conversationHistory.push({\n role: 'assistant',\n content: response.generatedText.trim(),\n });\n\n return response;\n }\n\n /**\n * Stream chat response\n */\n async *chatStream(\n userMessage: string,\n options?: ChatOptions\n ): AsyncGenerator<GenerationStreamEvent> {\n // Add system message if provided\n if (options?.systemPrompt && \n (this.conversationHistory.length === 0 || this.conversationHistory[0]?.role !== 'system')) {\n this.conversationHistory.unshift({\n role: 'system',\n content: options.systemPrompt,\n });\n }\n\n // Add user message\n this.conversationHistory.push({\n role: 'user',\n content: userMessage,\n });\n\n // Apply chat template\n const prompt = this.applyChatTemplate(this.conversationHistory, options);\n\n // Stream response\n let fullResponse = '';\n for await (const event of this.stream(prompt, {\n ...options,\n stopSequences: [\n ...(options?.stopSequences ?? []),\n '<|im_end|>',\n '<|end|>',\n '<|eot_id|>',\n '</s>',\n ],\n })) {\n fullResponse = event.generatedText;\n yield event;\n }\n\n // Add assistant response to history\n this.conversationHistory.push({\n role: 'assistant',\n content: fullResponse.trim(),\n });\n }\n\n /**\n * Get conversation history\n */\n getConversationHistory(): ChatMessage[] {\n return [...this.conversationHistory];\n }\n\n /**\n * Set conversation history\n */\n setConversationHistory(messages: ChatMessage[]): void {\n this.conversationHistory = [...messages];\n }\n\n /**\n * Clear conversation history\n */\n clearConversation(): void {\n this.conversationHistory = [];\n }\n\n /**\n * Remove last exchange (user message + assistant response)\n */\n undoLastExchange(): void {\n // Remove assistant message\n if (this.conversationHistory.length > 0 && \n this.conversationHistory[this.conversationHistory.length - 1]?.role === 'assistant') {\n this.conversationHistory.pop();\n }\n // Remove user message\n if (this.conversationHistory.length > 0 && \n this.conversationHistory[this.conversationHistory.length - 1]?.role === 'user') {\n this.conversationHistory.pop();\n }\n }\n\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create text generation pipeline\n */\nexport function createTextGenerationPipeline(config?: PipelineConfig): TextGenerationPipeline {\n return new TextGenerationPipeline(config);\n}\n", "/**\n * edgeFlow.js - Object Detection Pipeline\n * \n * Detect objects in images with bounding boxes and class labels.\n */\n\nimport { BasePipeline, ObjectDetectionResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { ImagePreprocessor, type ImageInput } from '../utils/preprocessor.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference } from '../core/runtime.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ObjectDetectionOptions extends PipelineOptions {\n threshold?: number;\n topK?: number;\n nms?: boolean;\n iouThreshold?: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface Detection extends ObjectDetectionResult {\n classId: number;\n boxNormalized: BoundingBox;\n}\n\n// ============================================================================\n// Default Model (YOLOS-tiny, quantized)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/yolos-tiny/resolve/main/onnx/model_quantized.onnx',\n};\n\n// ============================================================================\n// COCO Labels\n// ============================================================================\n\nexport const COCO_LABELS = [\n 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck',\n 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench',\n 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra',\n 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',\n 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',\n 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',\n 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange',\n 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',\n 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse',\n 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink',\n 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier',\n 'toothbrush'\n];\n\n// ============================================================================\n// Object Detection Pipeline\n// ============================================================================\n\nexport class ObjectDetectionPipeline extends BasePipeline<ImageInput | ImageInput[], Detection[]> {\n private preprocessor: ImagePreprocessor;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n\n constructor(config?: PipelineConfig, labels?: string[]) {\n super(config ?? {\n task: 'object-detection',\n model: 'default',\n });\n\n this.labels = labels ?? COCO_LABELS;\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.preprocessor = new ImagePreprocessor({\n width: 640,\n height: 640,\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n channelFormat: 'CHW',\n });\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: ImageInput | ImageInput[],\n options?: ObjectDetectionOptions\n ): Promise<Detection[]> {\n await this.initialize();\n const tensorInputs = await this.preprocess(input);\n const outputs = await this.runModelInference(tensorInputs);\n return this.postprocess(outputs, options);\n }\n\n protected async preprocess(input: ImageInput | ImageInput[]): Promise<EdgeFlowTensor[]> {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (inputs.length === 1) {\n const tensor = await this.preprocessor.process(inputs[0]!);\n return [new EdgeFlowTensor(\n tensor.toFloat32Array(),\n [1, ...tensor.shape],\n 'float32'\n )];\n }\n\n return [await this.preprocessor.processBatch(inputs)];\n }\n\n private async runModelInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const outputs = await runInference(this.onnxModel!, inputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<Detection[]> {\n const opts = options as ObjectDetectionOptions ?? {};\n const threshold = opts.threshold ?? 0.5;\n const topK = opts.topK ?? 100;\n const nms = opts.nms ?? true;\n const iouThreshold = opts.iouThreshold ?? 0.5;\n\n if (!outputs[0]) {\n return [];\n }\n\n const outputData = outputs[0].toFloat32Array();\n const shape = [...outputs[0].shape] as number[];\n\n const detections = this.parseDetections(outputData, shape, threshold);\n\n let filtered = nms ? this.nonMaxSuppression(detections, iouThreshold) : detections;\n\n filtered.sort((a, b) => b.score - a.score);\n filtered = filtered.slice(0, topK);\n\n return filtered;\n }\n\n private parseDetections(\n data: Float32Array,\n shape: number[],\n threshold: number\n ): Detection[] {\n const detections: Detection[] = [];\n\n const numBoxes = shape[1] ?? 0;\n const boxSize = shape[2] ?? 0;\n\n if (boxSize >= 5) {\n const numClasses = boxSize - 5;\n\n for (let i = 0; i < numBoxes; i++) {\n const offset = i * boxSize;\n const objectness = data[offset + 4] ?? 0;\n\n if (objectness < threshold) continue;\n\n let maxClassScore = 0;\n let maxClassIdx = 0;\n\n for (let c = 0; c < numClasses; c++) {\n const score = data[offset + 5 + c] ?? 0;\n if (score > maxClassScore) {\n maxClassScore = score;\n maxClassIdx = c;\n }\n }\n\n const confidence = objectness * maxClassScore;\n if (confidence < threshold) continue;\n\n const x = data[offset] ?? 0;\n const y = data[offset + 1] ?? 0;\n const w = data[offset + 2] ?? 0;\n const h = data[offset + 3] ?? 0;\n\n detections.push({\n label: this.labels[maxClassIdx] ?? `class_${maxClassIdx}`,\n score: confidence,\n classId: maxClassIdx,\n box: {\n x: Math.max(0, x - w / 2),\n y: Math.max(0, y - h / 2),\n width: w,\n height: h,\n },\n boxNormalized: {\n x: Math.max(0, x - w / 2),\n y: Math.max(0, y - h / 2),\n width: w,\n height: h,\n },\n });\n }\n } else if (boxSize === 4) {\n for (let i = 0; i < numBoxes; i++) {\n const offset = i * boxSize;\n const x1 = data[offset] ?? 0;\n const y1 = data[offset + 1] ?? 0;\n const x2 = data[offset + 2] ?? 0;\n const y2 = data[offset + 3] ?? 0;\n\n detections.push({\n label: this.labels[0] ?? 'object',\n score: 1.0,\n classId: 0,\n box: {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n },\n boxNormalized: {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n },\n });\n }\n }\n\n return detections;\n }\n\n private nonMaxSuppression(\n detections: Detection[],\n iouThreshold: number\n ): Detection[] {\n if (detections.length === 0) return [];\n\n const sorted = [...detections].sort((a, b) => b.score - a.score);\n const selected: Detection[] = [];\n const active = new Array(sorted.length).fill(true);\n\n for (let i = 0; i < sorted.length; i++) {\n if (!active[i]) continue;\n\n const current = sorted[i]!;\n selected.push(current);\n\n for (let j = i + 1; j < sorted.length; j++) {\n if (!active[j]) continue;\n\n const other = sorted[j]!;\n if (current.classId !== other.classId) continue;\n\n const iou = this.computeIoU(current.box, other.box);\n if (iou > iouThreshold) {\n active[j] = false;\n }\n }\n }\n\n return selected;\n }\n\n private computeIoU(a: BoundingBox, b: BoundingBox): number {\n const xOverlap = Math.max(0,\n Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x)\n );\n const yOverlap = Math.max(0,\n Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y)\n );\n\n const intersection = xOverlap * yOverlap;\n const aArea = a.width * a.height;\n const bArea = b.width * b.height;\n const union = aArea + bArea - intersection;\n\n return union > 0 ? intersection / union : 0;\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createObjectDetectionPipeline(\n config?: PipelineConfig,\n labels?: string[]\n): ObjectDetectionPipeline {\n return new ObjectDetectionPipeline(config, labels);\n}\n\nregisterPipeline('object-detection', (config) => new ObjectDetectionPipeline(config));\n", "/**\n * edgeFlow.js - Automatic Speech Recognition Pipeline\n * \n * Transcribe audio to text using Whisper ONNX models (encoder + decoder).\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { AudioPreprocessor, type AudioInput } from '../utils/preprocessor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (Whisper-tiny, quantized encoder + decoder)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n encoder: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/onnx/encoder_model_quantized.onnx',\n decoder: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/onnx/decoder_model_merged_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/tokenizer.json',\n};\n\n// Whisper special tokens\nconst SOT_TOKEN = 50258; // <|startoftranscript|>\nconst TRANSLATE_TOKEN = 50358; // <|translate|>\nconst TRANSCRIBE_TOKEN = 50359; // <|transcribe|>\nconst EOT_TOKEN = 50257; // <|endoftext|>\nconst NO_TIMESTAMPS_TOKEN = 50363; // <|notimestamps|>\nconst EN_TOKEN = 50259; // <|en|>\n\nconst MAX_DECODER_TOKENS = 448;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ASROptions extends PipelineOptions {\n language?: string;\n task?: 'transcribe' | 'translate';\n returnTimestamps?: boolean | 'word' | 'chunk';\n maxDuration?: number;\n chunkDuration?: number;\n chunkOverlap?: number;\n}\n\nexport interface WordTimestamp {\n word: string;\n start: number;\n end: number;\n confidence?: number;\n}\n\nexport interface ChunkTimestamp {\n text: string;\n start: number;\n end: number;\n}\n\nexport interface ASRResult extends PipelineResult {\n text: string;\n language?: string;\n words?: WordTimestamp[];\n chunks?: ChunkTimestamp[];\n}\n\n// ============================================================================\n// ASR Pipeline\n// ============================================================================\n\nexport class AutomaticSpeechRecognitionPipeline extends BasePipeline<AudioInput | AudioInput[], ASRResult | ASRResult[]> {\n private audioPreprocessor: AudioPreprocessor;\n private tokenizer: Tokenizer | null = null;\n private encoderModel: LoadedModel | null = null;\n private decoderModel: LoadedModel | null = null;\n private encoderUrl: string;\n private decoderUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'automatic-speech-recognition',\n model: 'default',\n });\n\n this.encoderUrl = DEFAULT_MODELS.encoder;\n this.decoderUrl = DEFAULT_MODELS.decoder;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n\n this.audioPreprocessor = new AudioPreprocessor({\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n maxDuration: 30,\n });\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.encoderModel) {\n const data = await loadModelData(this.encoderUrl, { cache: this.config.cache ?? true });\n this.encoderModel = await loadModelFromBuffer(data);\n }\n\n if (!this.decoderModel) {\n const data = await loadModelData(this.decoderUrl, { cache: this.config.cache ?? true });\n this.decoderModel = await loadModelFromBuffer(data);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n override async run(\n input: AudioInput | AudioInput[],\n options?: PipelineOptions\n ): Promise<ASRResult | ASRResult[]> {\n await this.initialize();\n\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n const opts = options as ASROptions ?? {};\n\n const results: ASRResult[] = [];\n for (const audio of inputs) {\n const result = await this.transcribeSingle(audio, opts);\n results.push(result);\n }\n\n return isBatch ? results : results[0]!;\n }\n\n private async transcribeSingle(audio: AudioInput, options: ASROptions): Promise<ASRResult> {\n const startTime = performance.now();\n\n // 1. Preprocess audio \u2192 mel spectrogram\n const melTensor = await this.audioPreprocessor.process(audio);\n const melInput = new EdgeFlowTensor(\n melTensor.toFloat32Array(),\n [1, ...melTensor.shape],\n 'float32'\n );\n\n // 2. Run encoder\n const encoderOutputs = await runInference(this.encoderModel!, [melInput]);\n const encoderHidden = encoderOutputs[0] as EdgeFlowTensor;\n\n // 3. Autoregressive decoder loop\n const task = options.task ?? 'transcribe';\n const initialTokens = this.buildInitialTokens(task, options.language);\n\n const generatedTokens = await this.autoregressiveDecode(\n encoderHidden,\n initialTokens,\n );\n\n // 4. Decode tokens to text\n const text = this.tokenizer!.decode(generatedTokens, true);\n\n const result: ASRResult = {\n text: text.trim(),\n processingTime: performance.now() - startTime,\n };\n\n if (options.returnTimestamps) {\n result.chunks = this.extractTimestamps(generatedTokens, text);\n }\n\n return result;\n }\n\n private buildInitialTokens(task: 'transcribe' | 'translate', language?: string): number[] {\n const tokens = [SOT_TOKEN];\n tokens.push(language ? this.getLanguageToken(language) : EN_TOKEN);\n tokens.push(task === 'translate' ? TRANSLATE_TOKEN : TRANSCRIBE_TOKEN);\n tokens.push(NO_TIMESTAMPS_TOKEN);\n return tokens;\n }\n\n private getLanguageToken(language: string): number {\n // Whisper language tokens start at 50259 for English\n const langMap: Record<string, number> = {\n en: 50259, zh: 50260, de: 50261, es: 50262, ru: 50263,\n ko: 50264, fr: 50265, ja: 50266, pt: 50267, tr: 50268,\n pl: 50269, ca: 50270, nl: 50271, ar: 50272, sv: 50273,\n it: 50274, id: 50275, hi: 50276, fi: 50277, vi: 50278,\n };\n return langMap[language.toLowerCase()] ?? EN_TOKEN;\n }\n\n /**\n * Autoregressive decoder loop similar to text-generation.\n * Feeds encoder hidden states + growing token sequence to decoder.\n */\n private async autoregressiveDecode(\n encoderHidden: EdgeFlowTensor,\n initialTokens: number[],\n ): Promise<number[]> {\n const tokens = [...initialTokens];\n\n for (let step = 0; step < MAX_DECODER_TOKENS; step++) {\n const decoderInputIds = new EdgeFlowTensor(\n BigInt64Array.from(tokens.map(t => BigInt(t))),\n [1, tokens.length],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', decoderInputIds);\n namedInputs.set('encoder_hidden_states', encoderHidden);\n\n const decoderOutputs = await runInferenceNamed(this.decoderModel!, namedInputs);\n const logits = (decoderOutputs[0] as EdgeFlowTensor).toFloat32Array();\n\n // Get logits for the last token position\n const vocabSize = logits.length / tokens.length;\n const lastTokenLogits = logits.slice((tokens.length - 1) * vocabSize);\n\n // Greedy: argmax\n let bestId = 0;\n let bestVal = lastTokenLogits[0] ?? -Infinity;\n for (let i = 1; i < lastTokenLogits.length; i++) {\n if ((lastTokenLogits[i] ?? -Infinity) > bestVal) {\n bestVal = lastTokenLogits[i] ?? -Infinity;\n bestId = i;\n }\n }\n\n if (bestId === EOT_TOKEN) break;\n\n tokens.push(bestId);\n }\n\n // Strip initial tokens to return only generated tokens\n return tokens.slice(initialTokens.length);\n }\n\n private extractTimestamps(\n _tokenIds: number[],\n text: string\n ): ChunkTimestamp[] {\n // Simplified timestamp extraction: split by punctuation\n const words = text.split(/\\s+/).filter(w => w.length > 0);\n const chunks: ChunkTimestamp[] = [];\n\n const wordsPerSecond = 2.5;\n let chunkText = '';\n let chunkStart = 0;\n\n for (let i = 0; i < words.length; i++) {\n chunkText += (chunkText ? ' ' : '') + words[i];\n\n if ((i + 1) % 5 === 0 || i === words.length - 1) {\n const duration = chunkText.split(/\\s+/).length / wordsPerSecond;\n chunks.push({\n text: chunkText,\n start: chunkStart,\n end: chunkStart + duration,\n });\n chunkStart = chunkStart + duration;\n chunkText = '';\n }\n }\n\n return chunks;\n }\n\n async processLongAudio(\n audio: AudioInput,\n options: ASROptions = {}\n ): Promise<ASRResult> {\n const chunkDuration = options.chunkDuration ?? 30;\n const chunkOverlap = options.chunkOverlap ?? 5;\n\n const rawTensor = await this.audioPreprocessor.processRaw(audio);\n const audioData = rawTensor.toFloat32Array();\n const sampleRate = 16000;\n\n const chunkSamples = chunkDuration * sampleRate;\n const overlapSamples = chunkOverlap * sampleRate;\n const stepSamples = chunkSamples - overlapSamples;\n\n const chunks: ASRResult[] = [];\n\n for (let start = 0; start < audioData.length; start += stepSamples) {\n const end = Math.min(start + chunkSamples, audioData.length);\n const chunkAudio = audioData.slice(start, end);\n\n const chunkResult = await this.run(\n new Float32Array(chunkAudio),\n options\n ) as ASRResult;\n\n if (chunkResult.chunks) {\n const timeOffset = start / sampleRate;\n chunkResult.chunks = chunkResult.chunks.map(c => ({\n ...c,\n start: c.start + timeOffset,\n end: c.end + timeOffset,\n }));\n }\n\n chunks.push(chunkResult);\n }\n\n const mergedText = chunks.map(c => c.text).join(' ');\n const mergedChunks = chunks.flatMap(c => c.chunks ?? []);\n\n return {\n text: mergedText,\n chunks: mergedChunks,\n };\n }\n\n protected async preprocess(input: AudioInput | AudioInput[]): Promise<EdgeFlowTensor[]> {\n const inputs = Array.isArray(input) ? input : [input];\n\n const tensors = await Promise.all(\n inputs.map(audio => this.audioPreprocessor.process(audio))\n );\n\n if (tensors.length === 1) {\n const t = tensors[0]!;\n return [new EdgeFlowTensor(\n t.toFloat32Array(),\n [1, ...t.shape],\n 'float32'\n )];\n }\n\n return tensors;\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<ASRResult | ASRResult[]> {\n const opts = options as ASROptions ?? {};\n const returnTimestamps = opts.returnTimestamps ?? false;\n\n if (!outputs[0]) {\n return { text: '' };\n }\n\n const outputData = outputs[0].toFloat32Array();\n const shape = outputs[0].shape;\n\n const text = this.decodeOutput(outputData, shape);\n\n const result: ASRResult = { text };\n\n if (returnTimestamps) {\n result.chunks = this.extractTimestamps([], text);\n }\n\n return result;\n }\n\n private decodeOutput(data: Float32Array, shape: readonly number[]): string {\n const seqLen = shape[1] ?? data.length;\n const vocabSize = shape[2] ?? 1;\n\n const tokenIds: number[] = [];\n\n if (vocabSize > 1) {\n for (let i = 0; i < seqLen; i++) {\n const offset = i * vocabSize;\n let maxIdx = 0;\n let maxVal = data[offset] ?? -Infinity;\n\n for (let j = 1; j < vocabSize; j++) {\n if ((data[offset + j] ?? -Infinity) > maxVal) {\n maxVal = data[offset + j] ?? -Infinity;\n maxIdx = j;\n }\n }\n tokenIds.push(maxIdx);\n }\n } else {\n for (let i = 0; i < data.length; i++) {\n tokenIds.push(Math.round(data[i] ?? 0));\n }\n }\n\n if (this.tokenizer) {\n return this.tokenizer.decode(tokenIds, true);\n }\n\n return tokenIds.join(' ');\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createASRPipeline(config?: PipelineConfig): AutomaticSpeechRecognitionPipeline {\n return new AutomaticSpeechRecognitionPipeline(config);\n}\n\nregisterPipeline('automatic-speech-recognition', (config) => new AutomaticSpeechRecognitionPipeline(config));\n", "/**\n * edgeFlow.js - Zero-shot Classification Pipeline\n * \n * Classify text into any set of labels without fine-tuning,\n * using a real NLI (Natural Language Inference) model.\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (DistilBART fine-tuned on MNLI)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/nli-deberta-v3-small/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/nli-deberta-v3-small/resolve/main/tokenizer.json',\n};\n\n// NLI output indices: [contradiction, neutral, entailment]\nconst ENTAILMENT_IDX = 2;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ZeroShotClassificationOptions extends PipelineOptions {\n multiLabel?: boolean;\n hypothesisTemplate?: string;\n}\n\nexport interface ZeroShotClassificationResult extends PipelineResult {\n sequence: string;\n labels: string[];\n scores: number[];\n}\n\nexport interface ZeroShotInput {\n text: string | string[];\n candidateLabels: string[];\n}\n\n// ============================================================================\n// Zero-shot Classification Pipeline\n// ============================================================================\n\nexport class ZeroShotClassificationPipeline extends BasePipeline<\n ZeroShotInput,\n ZeroShotClassificationResult | ZeroShotClassificationResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private hypothesisTemplate: string = 'This text is about {label}.';\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'zero-shot-classification',\n model: 'default',\n });\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n async classify(\n text: string | string[],\n candidateLabels: string[],\n options?: ZeroShotClassificationOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n return this.run({ text, candidateLabels }, options);\n }\n\n override async run(\n input: ZeroShotInput,\n options?: PipelineOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n await this.initialize();\n\n const { text, candidateLabels } = input;\n const opts = options as ZeroShotClassificationOptions ?? {};\n const texts = Array.isArray(text) ? text : [text];\n const template = opts.hypothesisTemplate ?? this.hypothesisTemplate;\n const multiLabel = opts.multiLabel ?? false;\n\n const results = await Promise.all(\n texts.map(t => this.classifySingle(t, candidateLabels, template, multiLabel))\n );\n\n return Array.isArray(text) ? results : results[0]!;\n }\n\n private async classifySingle(\n text: string,\n candidateLabels: string[],\n template: string,\n multiLabel: boolean\n ): Promise<ZeroShotClassificationResult> {\n const startTime = performance.now();\n\n const hypotheses = candidateLabels.map(label =>\n template.replace('{label}', label)\n );\n\n const scores: number[] = [];\n\n for (const hypothesis of hypotheses) {\n const score = await this.scoreHypothesis(text, hypothesis);\n scores.push(score);\n }\n\n let normalizedScores: number[];\n\n if (multiLabel) {\n normalizedScores = scores.map(s => 1 / (1 + Math.exp(-s)));\n } else {\n const tensor = new EdgeFlowTensor(new Float32Array(scores), [scores.length], 'float32');\n normalizedScores = Array.from(softmax(tensor).toFloat32Array());\n }\n\n const indexed = candidateLabels.map((label, i) => ({\n label,\n score: normalizedScores[i] ?? 0,\n }));\n indexed.sort((a, b) => b.score - a.score);\n\n return {\n sequence: text,\n labels: indexed.map(i => i.label),\n scores: indexed.map(i => i.score),\n processingTime: performance.now() - startTime,\n };\n }\n\n /**\n * Score a single hypothesis using the real NLI ONNX model.\n * Returns the entailment logit.\n */\n private async scoreHypothesis(premise: string, hypothesis: string): Promise<number> {\n const encoded = this.tokenizer!.encode(premise, {\n textPair: hypothesis,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n returnAttentionMask: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputIds);\n namedInputs.set('attention_mask', attentionMask);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n const logits = (outputs[0] as EdgeFlowTensor).toFloat32Array();\n\n // Return entailment logit (index 2 in [contradiction, neutral, entailment])\n return logits[ENTAILMENT_IDX] ?? 0;\n }\n\n protected async preprocess(\n input: ZeroShotInput\n ): Promise<EdgeFlowTensor[]> {\n const { text, candidateLabels } = input;\n const firstText = Array.isArray(text) ? text[0] ?? '' : text;\n const firstLabel = candidateLabels[0] ?? '';\n\n const encoded = this.tokenizer!.encode(firstText, {\n textPair: this.hypothesisTemplate.replace('{label}', firstLabel),\n addSpecialTokens: true,\n maxLength: 512,\n });\n\n return [new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n )];\n }\n\n protected async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n return {\n sequence: '',\n labels: [],\n scores: [],\n };\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createZeroShotClassificationPipeline(\n config?: PipelineConfig\n): ZeroShotClassificationPipeline {\n return new ZeroShotClassificationPipeline(config);\n}\n\nregisterPipeline('zero-shot-classification', (config) => new ZeroShotClassificationPipeline(config));\n", "/**\n * edgeFlow.js - Question Answering Pipeline\n * \n * Extract answers from context given a question using real ONNX QA models.\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (DistilBERT fine-tuned on SQuAD)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/distilbert-base-cased-distilled-squad/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/distilbert-base-cased-distilled-squad/resolve/main/tokenizer.json',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface QAInput {\n question: string;\n context: string;\n}\n\nexport interface QuestionAnsweringOptions extends PipelineOptions {\n maxAnswerLength?: number;\n maxQuestionLength?: number;\n topK?: number;\n threshold?: number;\n handleImpossible?: boolean;\n}\n\nexport interface QuestionAnsweringResult extends PipelineResult {\n answer: string;\n score: number;\n start: number;\n end: number;\n}\n\n// ============================================================================\n// Question Answering Pipeline\n// ============================================================================\n\nexport class QuestionAnsweringPipeline extends BasePipeline<\n QAInput | QAInput[],\n QuestionAnsweringResult | QuestionAnsweringResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'question-answering',\n model: 'default',\n });\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n override async run(\n input: QAInput | QAInput[],\n options?: QuestionAnsweringOptions\n ): Promise<QuestionAnsweringResult | QuestionAnsweringResult[]> {\n await this.initialize();\n\n const inputs = Array.isArray(input) ? input : [input];\n const results = await Promise.all(\n inputs.map(i => this.answerQuestion(i, options ?? {}))\n );\n\n return Array.isArray(input) ? results : results[0]!;\n }\n\n private async answerQuestion(\n input: QAInput,\n options: QuestionAnsweringOptions\n ): Promise<QuestionAnsweringResult> {\n const startTime = performance.now();\n const { question, context } = input;\n const maxAnswerLength = options.maxAnswerLength ?? 30;\n\n // No padding \u2014 QA runs one example at a time and padding wastes compute\n const encoded = this.tokenizer!.encode(question, {\n textPair: context,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n padding: 'do_not_pad',\n returnAttentionMask: true,\n returnTokenTypeIds: true,\n });\n\n const seqLen = encoded.inputIds.length;\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, seqLen],\n 'int64'\n );\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, seqLen],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputIds);\n namedInputs.set('attention_mask', attentionMask);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n\n if (outputs.length < 2) {\n return { answer: '', score: 0, start: 0, end: 0, processingTime: performance.now() - startTime };\n }\n\n const startLogits = (outputs[0] as EdgeFlowTensor).toFloat32Array();\n const endLogits = (outputs[1] as EdgeFlowTensor).toFloat32Array();\n\n const startProbs = softmax(new EdgeFlowTensor(new Float32Array(startLogits), [seqLen], 'float32')).toFloat32Array();\n const endProbs = softmax(new EdgeFlowTensor(new Float32Array(endLogits), [seqLen], 'float32')).toFloat32Array();\n\n // Constrain answer span to the context portion only (tokenTypeIds === 1).\n // tokenTypeIds: 0 = question tokens ([CLS], question, [SEP]), 1 = context tokens.\n const typeIds = encoded.tokenTypeIds ?? new Array(seqLen).fill(1);\n // Find where context starts (first index with typeId === 1)\n const contextStart = typeIds.findIndex(t => t === 1);\n const spanStart = contextStart >= 0 ? contextStart : 0;\n const spanEnd = seqLen - 1; // last non-padding position\n\n let bestStartIdx = spanStart;\n let bestEndIdx = spanStart;\n let bestScore = -Infinity;\n\n for (let s = spanStart; s <= spanEnd; s++) {\n for (let e = s; e < Math.min(s + maxAnswerLength, spanEnd + 1); e++) {\n const score = (startProbs[s] ?? 0) * (endProbs[e] ?? 0);\n if (score > bestScore) {\n bestScore = score;\n bestStartIdx = s;\n bestEndIdx = e;\n }\n }\n }\n\n // Decode the answer span directly from token IDs in the context portion\n const answerTokenIds = encoded.inputIds.slice(bestStartIdx, bestEndIdx + 1);\n const answer = this.tokenizer!.decode(answerTokenIds, true);\n\n return {\n answer: answer || '',\n score: Math.max(0, bestScore),\n start: bestStartIdx,\n end: bestEndIdx,\n processingTime: performance.now() - startTime,\n };\n }\n\n\n protected async preprocess(input: QAInput | QAInput[]): Promise<EdgeFlowTensor[]> {\n const qaInput = Array.isArray(input) ? input[0]! : input;\n const encoded = this.tokenizer!.encode(qaInput.question, {\n textPair: qaInput.context,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n returnAttentionMask: true,\n returnTokenTypeIds: true,\n });\n\n return [\n new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n ),\n new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n ),\n ];\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<QuestionAnsweringResult | QuestionAnsweringResult[]> {\n if (outputs.length < 2) {\n return { answer: '', score: 0, start: 0, end: 0 };\n }\n\n const startLogits = outputs[0]!.toFloat32Array();\n const endLogits = outputs[1]!.toFloat32Array();\n const seqLen = startLogits.length;\n\n const startProbs = softmax(new EdgeFlowTensor(startLogits, [seqLen], 'float32')).toFloat32Array();\n const endProbs = softmax(new EdgeFlowTensor(endLogits, [seqLen], 'float32')).toFloat32Array();\n\n let bestStart = 0;\n let bestEnd = 0;\n let bestScore = 0;\n\n for (let start = 0; start < seqLen; start++) {\n for (let end = start; end < Math.min(start + 30, seqLen); end++) {\n const score = (startProbs[start] ?? 0) * (endProbs[end] ?? 0);\n if (score > bestScore) {\n bestScore = score;\n bestStart = start;\n bestEnd = end;\n }\n }\n }\n\n return {\n answer: '',\n score: bestScore,\n start: bestStart,\n end: bestEnd,\n };\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createQuestionAnsweringPipeline(\n config?: PipelineConfig\n): QuestionAnsweringPipeline {\n return new QuestionAnsweringPipeline(config);\n}\n\nregisterPipeline('question-answering', (config) => new QuestionAnsweringPipeline(config));\n", "/**\n * edgeFlow.js - Image Segmentation Pipeline\n * \n * Interactive image segmentation using SAM (Segment Anything Model).\n * Supports point prompts and bounding box prompts.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { loadModel, loadModelFromBuffer, runInference, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model URLs (SlimSAM - quantized for browser)\n// ============================================================================\n\nconst DEFAULT_SAM_MODELS = {\n encoder: 'https://huggingface.co/Xenova/slimsam-77-uniform/resolve/main/onnx/vision_encoder_quantized.onnx',\n decoder: 'https://huggingface.co/Xenova/slimsam-77-uniform/resolve/main/onnx/prompt_encoder_mask_decoder_quantized.onnx',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Point prompt for segmentation\n */\nexport interface PointPrompt {\n /** X coordinate (0-1 normalized) */\n x: number;\n /** Y coordinate (0-1 normalized) */\n y: number;\n /** 1 for foreground (include), 0 for background (exclude) */\n label: 0 | 1;\n}\n\n/**\n * Box prompt for segmentation\n */\nexport interface BoxPrompt {\n /** Top-left X (0-1 normalized) */\n x1: number;\n /** Top-left Y (0-1 normalized) */\n y1: number;\n /** Bottom-right X (0-1 normalized) */\n x2: number;\n /** Bottom-right Y (0-1 normalized) */\n y2: number;\n}\n\n/**\n * Model loading progress callback\n */\nexport interface ModelLoadProgress {\n /** Model name (encoder or decoder) */\n model: 'encoder' | 'decoder';\n /** Bytes loaded */\n loaded: number;\n /** Total bytes */\n total: number;\n /** Progress percentage (0-100) */\n progress: number;\n}\n\n/**\n * Segmentation options\n */\nexport interface ImageSegmentationOptions extends PipelineOptions {\n /** Point prompts */\n points?: PointPrompt[];\n /** Box prompts */\n boxes?: BoxPrompt[];\n /** Return all masks or just the best one */\n returnAllMasks?: boolean;\n /** Mask threshold (0-1) */\n maskThreshold?: number;\n}\n\n/**\n * Segmentation result\n */\nexport interface ImageSegmentationResult extends PipelineResult {\n /** Segmentation mask (Uint8Array, 0 or 255) */\n mask: Uint8Array;\n /** Mask width */\n width: number;\n /** Mask height */\n height: number;\n /** Confidence score */\n score: number;\n /** All masks if returnAllMasks is true */\n allMasks?: Array<{ mask: Uint8Array; score: number }>;\n}\n\n/**\n * Image input types\n */\nexport type ImageInput =\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | ImageData\n | string; // URL or base64\n\n// ============================================================================\n// Image Segmentation Pipeline\n// ============================================================================\n\n/**\n * ImageSegmentationPipeline - Interactive image segmentation\n * \n * Uses SAM-style models for point/box prompted segmentation.\n * \n * @example\n * ```typescript\n * const segmenter = createImageSegmentationPipeline();\n * \n * // Load models with progress callback\n * await segmenter.loadModels((progress) => {\n * console.log(`Loading ${progress.model}: ${progress.progress}%`);\n * });\n * \n * // Set image and segment\n * await segmenter.setImage(imageElement);\n * const result = await segmenter.segment({\n * points: [{ x: 0.5, y: 0.5, label: 1 }]\n * });\n * ```\n */\nexport class ImageSegmentationPipeline extends BasePipeline<\n ImageInput,\n ImageSegmentationResult\n> {\n private encoderModel: LoadedModel | null = null;\n private decoderModel: LoadedModel | null = null;\n private imageEmbedding: EdgeFlowTensor | null = null;\n private imagePositionalEmbedding: EdgeFlowTensor | null = null;\n private currentImageSize: { width: number; height: number } | null = null;\n private resizedImageSize: { width: number; height: number } | null = null;\n private inputSize: number = 1024; // SAM default input size\n private modelsLoaded: boolean = false;\n \n // Custom model URLs\n private encoderUrl: string;\n private decoderUrl: string;\n\n constructor(config: PipelineConfig) {\n super(config);\n this.encoderUrl = DEFAULT_SAM_MODELS.encoder;\n this.decoderUrl = DEFAULT_SAM_MODELS.decoder;\n }\n\n /**\n * Check if models are loaded\n */\n get isModelsLoaded(): boolean {\n return this.modelsLoaded;\n }\n\n /**\n * Set custom model URLs\n */\n setModelUrls(encoder: string, decoder: string): void {\n this.encoderUrl = encoder;\n this.decoderUrl = decoder;\n }\n\n /**\n * Load both encoder and decoder models with progress callback\n */\n async loadModels(\n onProgress?: (progress: ModelLoadProgress) => void\n ): Promise<void> {\n if (this.modelsLoaded) return;\n\n // Load encoder\n onProgress?.({ model: 'encoder', loaded: 0, total: 100, progress: 0 });\n \n const encoderData = await this.fetchModelWithProgress(\n this.encoderUrl,\n (loaded, total) => {\n onProgress?.({\n model: 'encoder',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.encoderModel = await loadModelFromBuffer(encoderData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n\n // Load decoder\n onProgress?.({ model: 'decoder', loaded: 0, total: 100, progress: 0 });\n \n const decoderData = await this.fetchModelWithProgress(\n this.decoderUrl,\n (loaded, total) => {\n onProgress?.({\n model: 'decoder',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.decoderModel = await loadModelFromBuffer(decoderData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n\n this.modelsLoaded = true;\n }\n\n /**\n * Fetch model with progress tracking\n */\n private async fetchModelWithProgress(\n url: string,\n onProgress: (loaded: number, total: number) => void\n ): Promise<ArrayBuffer> {\n const response = await fetch(url);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch model: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body) {\n // Fallback if no streaming support\n const buffer = await response.arrayBuffer();\n onProgress(buffer.byteLength, buffer.byteLength);\n return buffer;\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n \n if (done) break;\n \n chunks.push(value);\n loaded += value.length;\n onProgress(loaded, total || loaded);\n }\n\n // Combine chunks into ArrayBuffer\n const buffer = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n return buffer.buffer;\n }\n\n /**\n * Initialize pipeline (override to skip default model loading)\n */\n override async initialize(): Promise<void> {\n if (this.isReady) return;\n // Don't call super.initialize() - we handle model loading separately\n this.isReady = true;\n }\n\n /**\n * Load encoder model (processes the image once)\n */\n async loadEncoder(modelUrl: string): Promise<void> {\n this.encoderModel = await loadModel(modelUrl, {\n runtime: 'wasm',\n });\n }\n\n /**\n * Load decoder model (processes prompts to generate masks)\n */\n async loadDecoder(modelUrl: string): Promise<void> {\n this.decoderModel = await loadModel(modelUrl, {\n runtime: 'wasm',\n });\n }\n\n /**\n * Set and encode the image (call once per image)\n */\n async setImage(image: ImageInput): Promise<void> {\n if (!this.modelsLoaded) {\n throw new Error('Models not loaded. Call loadModels() first.');\n }\n\n // Get image data\n const imageData = await this.loadImage(image);\n this.currentImageSize = {\n width: imageData.width,\n height: imageData.height,\n };\n\n // Preprocess image for SAM\n const { tensor: inputTensor, resizedSize } = this.preprocessImage(imageData);\n this.resizedImageSize = resizedSize;\n\n // Run encoder\n if (this.encoderModel) {\n const outputs = await runInference(this.encoderModel, [inputTensor]);\n // SlimSAM encoder outputs: [image_embeddings, image_positional_embeddings]\n this.imageEmbedding = outputs[0] as EdgeFlowTensor;\n this.imagePositionalEmbedding = outputs[1] as EdgeFlowTensor;\n console.log('[SAM] Encoder outputs:', outputs.length);\n console.log('[SAM] image_embeddings shape:', this.imageEmbedding.shape);\n if (this.imagePositionalEmbedding) {\n console.log('[SAM] image_positional_embeddings shape:', this.imagePositionalEmbedding.shape);\n }\n } else {\n throw new Error('Encoder model not loaded');\n }\n }\n\n /**\n * Segment the image with given prompts\n */\n async segment(options: ImageSegmentationOptions = {}): Promise<ImageSegmentationResult> {\n if (!this.imageEmbedding || !this.currentImageSize || !this.resizedImageSize) {\n throw new Error('No image set. Call setImage() first.');\n }\n\n if (!this.decoderModel) {\n throw new Error('Decoder model not loaded');\n }\n\n const startTime = performance.now();\n const { points = [], boxes = [], maskThreshold = 0.0, returnAllMasks = false } = options;\n\n // Prepare inputs for decoder\n const decoderInputs = this.prepareDecoderInputs(points, boxes);\n \n // Add image embeddings to inputs\n decoderInputs.set('image_embeddings', this.imageEmbedding!);\n \n // Add positional embeddings (required by SlimSAM)\n if (this.imagePositionalEmbedding) {\n decoderInputs.set('image_positional_embeddings', this.imagePositionalEmbedding);\n } else {\n throw new Error('image_positional_embeddings not available from encoder');\n }\n\n // Run decoder model with named inputs\n const outputs = await runInferenceNamed(this.decoderModel, decoderInputs);\n\n // SAM decoder outputs: [masks, iou_predictions]\n const masks = outputs[0] as EdgeFlowTensor;\n const scores = outputs[1] as EdgeFlowTensor;\n\n // Post-process masks\n const result = this.postprocessMasks(masks, scores, maskThreshold, returnAllMasks);\n result.processingTime = performance.now() - startTime;\n\n return result;\n }\n\n /**\n * Run segmentation (implements BasePipeline interface)\n */\n override async run(\n input: ImageInput,\n options?: ImageSegmentationOptions\n ): Promise<ImageSegmentationResult> {\n await this.setImage(input);\n return this.segment(options);\n }\n\n /**\n * Load image from various sources\n */\n private async loadImage(input: ImageInput): Promise<ImageData> {\n // Handle different input types\n if (typeof input === 'string') {\n // URL or base64\n return this.loadImageFromUrl(input);\n } else if (input instanceof HTMLImageElement) {\n return this.imageElementToImageData(input);\n } else if (input instanceof HTMLCanvasElement) {\n return this.canvasToImageData(input);\n } else if (input instanceof ImageData) {\n return input;\n } else if (typeof ImageBitmap !== 'undefined' && input instanceof ImageBitmap) {\n return this.imageBitmapToImageData(input);\n }\n throw new Error('Unsupported image input type');\n }\n\n /**\n * Load image from URL\n */\n private async loadImageFromUrl(url: string): Promise<ImageData> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = img.width;\n canvas.height = img.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0);\n resolve(ctx.getImageData(0, 0, img.width, img.height));\n };\n img.onerror = reject;\n img.src = url;\n });\n }\n\n /**\n * Convert HTMLImageElement to ImageData\n */\n private imageElementToImageData(img: HTMLImageElement): ImageData {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth || img.width;\n canvas.height = img.naturalHeight || img.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0);\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Convert canvas to ImageData\n */\n private canvasToImageData(canvas: HTMLCanvasElement): ImageData {\n const ctx = canvas.getContext('2d')!;\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Convert ImageBitmap to ImageData\n */\n private imageBitmapToImageData(bitmap: ImageBitmap): ImageData {\n const canvas = document.createElement('canvas');\n canvas.width = bitmap.width;\n canvas.height = bitmap.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(bitmap, 0, 0);\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Preprocess image for SAM\n */\n private preprocessImage(imageData: ImageData): { \n tensor: EdgeFlowTensor; \n resizedSize: { width: number; height: number };\n } {\n const { width, height } = imageData;\n\n // Calculate resize dimensions (longest side = inputSize)\n const scale = this.inputSize / Math.max(width, height);\n const newWidth = Math.round(width * scale);\n const newHeight = Math.round(height * scale);\n\n // Create resized canvas with padding\n const canvas = document.createElement('canvas');\n canvas.width = this.inputSize;\n canvas.height = this.inputSize;\n const ctx = canvas.getContext('2d')!;\n\n // Fill with padding color (SAM uses pixel mean)\n ctx.fillStyle = `rgb(123.675, 116.28, 103.53)`;\n ctx.fillRect(0, 0, this.inputSize, this.inputSize);\n\n // Draw resized image (top-left aligned)\n const tempCanvas = document.createElement('canvas');\n tempCanvas.width = width;\n tempCanvas.height = height;\n const tempCtx = tempCanvas.getContext('2d')!;\n tempCtx.putImageData(imageData, 0, 0);\n ctx.drawImage(tempCanvas, 0, 0, newWidth, newHeight);\n\n // Get pixel data\n const resizedData = ctx.getImageData(0, 0, this.inputSize, this.inputSize);\n\n // Convert to tensor (NCHW format, normalized with ImageNet mean/std)\n const tensorData = new Float32Array(3 * this.inputSize * this.inputSize);\n const mean = [123.675, 116.28, 103.53];\n const std = [58.395, 57.12, 57.375];\n\n for (let i = 0; i < this.inputSize * this.inputSize; i++) {\n const pixelIdx = i * 4;\n tensorData[i] = (resizedData.data[pixelIdx]! - mean[0]!) / std[0]!; // R\n tensorData[this.inputSize * this.inputSize + i] =\n (resizedData.data[pixelIdx + 1]! - mean[1]!) / std[1]!; // G\n tensorData[2 * this.inputSize * this.inputSize + i] =\n (resizedData.data[pixelIdx + 2]! - mean[2]!) / std[2]!; // B\n }\n\n return {\n tensor: new EdgeFlowTensor(tensorData, [1, 3, this.inputSize, this.inputSize], 'float32'),\n resizedSize: { width: newWidth, height: newHeight },\n };\n }\n\n /**\n * Prepare decoder inputs (prompts) for SlimSAM\n * \n * SlimSAM prompt_encoder_mask_decoder expects these named inputs:\n * - image_embeddings: [1, 256, 64, 64]\n * - point_coords: [batch, num_points, 2]\n * - point_labels: [batch, num_points]\n * - mask_input: [batch, 1, 256, 256]\n * - has_mask_input: [batch, 1]\n * - orig_im_size: [2]\n * - position_ids: [batch, num_points]\n */\n private prepareDecoderInputs(\n points: PointPrompt[],\n boxes: BoxPrompt[]\n ): Map<string, EdgeFlowTensor> {\n const { width: resizedW, height: resizedH } = this.resizedImageSize!;\n\n // Scale factors for converting normalized coords to resized image coords\n const scaleX = resizedW;\n const scaleY = resizedH;\n\n const allPoints: number[] = [];\n const allLabels: number[] = [];\n\n // Add point prompts\n for (const point of points) {\n allPoints.push(\n point.x * scaleX,\n point.y * scaleY\n );\n allLabels.push(point.label);\n }\n\n // Add box prompts (as two corner points)\n for (const box of boxes) {\n // Top-left corner (label 2)\n allPoints.push(box.x1 * scaleX, box.y1 * scaleY);\n allLabels.push(2);\n // Bottom-right corner (label 3)\n allPoints.push(box.x2 * scaleX, box.y2 * scaleY);\n allLabels.push(3);\n }\n\n // Default point if no prompts (center of image)\n if (allPoints.length === 0) {\n allPoints.push(resizedW / 2, resizedH / 2);\n allLabels.push(1);\n }\n\n const numPoints = allLabels.length;\n\n const inputs = new Map<string, EdgeFlowTensor>();\n\n // input_points: [1, 1, num_points, 2] - SlimSAM format (float32)\n inputs.set('input_points', new EdgeFlowTensor(\n new Float32Array(allPoints),\n [1, 1, numPoints, 2],\n 'float32'\n ));\n\n // input_labels: [1, 1, num_points] - SlimSAM format (int64)\n inputs.set('input_labels', new EdgeFlowTensor(\n BigInt64Array.from(allLabels.map(l => BigInt(l))),\n [1, 1, numPoints],\n 'int64'\n ));\n\n // Note: image_embeddings and image_positional_embeddings are added in segment()\n // SlimSAM decoder only needs: image_embeddings, image_positional_embeddings, input_points, input_labels\n\n return inputs;\n }\n\n /**\n * Post-process masks from decoder output\n */\n private postprocessMasks(\n masks: EdgeFlowTensor,\n scores: EdgeFlowTensor,\n threshold: number,\n returnAllMasks: boolean\n ): ImageSegmentationResult {\n const { width, height } = this.currentImageSize!;\n const scoresData = scores.toFloat32Array();\n const masksData = masks.toFloat32Array();\n\n // SAM outputs multiple masks (usually 3)\n const numMasks = scoresData.length;\n const maskShape = masks.shape; // [1, num_masks, H, W]\n const maskH = maskShape[2] ?? height;\n const maskW = maskShape[3] ?? width;\n\n // Find best mask by score\n let bestIdx = 0;\n let bestScore = scoresData[0] ?? 0;\n\n for (let i = 1; i < numMasks; i++) {\n if ((scoresData[i] ?? 0) > bestScore) {\n bestScore = scoresData[i] ?? 0;\n bestIdx = i;\n }\n }\n\n // Extract and resize the best mask to original image size\n const outputMask = this.resizeMask(\n masksData, \n bestIdx, \n maskW, \n maskH, \n width, \n height, \n threshold\n );\n\n const result: ImageSegmentationResult = {\n mask: outputMask,\n width,\n height,\n score: bestScore,\n };\n\n if (returnAllMasks && numMasks > 1) {\n result.allMasks = [];\n for (let m = 0; m < numMasks; m++) {\n const mask = this.resizeMask(\n masksData, \n m, \n maskW, \n maskH, \n width, \n height, \n threshold\n );\n result.allMasks.push({\n mask,\n score: scoresData[m] ?? 0,\n });\n }\n }\n\n return result;\n }\n\n /**\n * Resize mask from model output size to original image size\n */\n private resizeMask(\n masksData: Float32Array,\n maskIdx: number,\n srcW: number,\n srcH: number,\n dstW: number,\n dstH: number,\n threshold: number\n ): Uint8Array {\n const outputMask = new Uint8Array(dstW * dstH);\n const maskOffset = maskIdx * srcW * srcH;\n\n // Bilinear interpolation for resizing\n for (let y = 0; y < dstH; y++) {\n for (let x = 0; x < dstW; x++) {\n // Map to source coordinates\n const srcX = (x / dstW) * srcW;\n const srcY = (y / dstH) * srcH;\n\n // Bilinear interpolation\n const x0 = Math.floor(srcX);\n const x1 = Math.min(x0 + 1, srcW - 1);\n const y0 = Math.floor(srcY);\n const y1 = Math.min(y0 + 1, srcH - 1);\n\n const xFrac = srcX - x0;\n const yFrac = srcY - y0;\n\n const v00 = masksData[maskOffset + y0 * srcW + x0] ?? 0;\n const v01 = masksData[maskOffset + y0 * srcW + x1] ?? 0;\n const v10 = masksData[maskOffset + y1 * srcW + x0] ?? 0;\n const v11 = masksData[maskOffset + y1 * srcW + x1] ?? 0;\n\n const value = \n v00 * (1 - xFrac) * (1 - yFrac) +\n v01 * xFrac * (1 - yFrac) +\n v10 * (1 - xFrac) * yFrac +\n v11 * xFrac * yFrac;\n\n // Apply sigmoid and threshold\n const sigmoid = 1 / (1 + Math.exp(-value));\n outputMask[y * dstW + x] = sigmoid > threshold ? 255 : 0;\n }\n }\n\n return outputMask;\n }\n\n /**\n * Clear the current image embedding\n */\n clearImage(): void {\n this.imageEmbedding = null;\n this.imagePositionalEmbedding = null;\n this.currentImageSize = null;\n this.resizedImageSize = null;\n }\n\n /**\n * Preprocess (required by BasePipeline)\n */\n protected override async preprocess(input: ImageInput): Promise<EdgeFlowTensor[]> {\n const imageData = await this.loadImage(input);\n const { tensor } = this.preprocessImage(imageData);\n return [tensor];\n }\n\n /**\n * Postprocess (required by BasePipeline)\n */\n protected override async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<ImageSegmentationResult> {\n // This is handled in segment() method\n return {\n mask: new Uint8Array(0),\n width: 0,\n height: 0,\n score: 0,\n };\n }\n\n /**\n * Dispose resources\n */\n override dispose(): void {\n super.dispose();\n this.encoderModel?.dispose();\n this.decoderModel?.dispose();\n this.imageEmbedding = null;\n this.imagePositionalEmbedding = null;\n this.currentImageSize = null;\n this.resizedImageSize = null;\n this.modelsLoaded = false;\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create image segmentation pipeline\n */\nexport function createImageSegmentationPipeline(\n config: Partial<PipelineConfig> = {}\n): ImageSegmentationPipeline {\n return new ImageSegmentationPipeline({\n task: 'image-segmentation',\n model: config.model ?? 'slimsam',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\n// Register pipeline\nregisterPipeline('image-segmentation', (config) => new ImageSegmentationPipeline(config));\n", "/**\n * edgeFlow.js - Pipeline Exports\n */\n\nimport {\n PipelineConfig,\n PipelineTask,\n RuntimeType,\n QuantizationType,\n} from '../core/types.js';\n\nimport { getPluginPipeline } from '../core/plugin.js';\nimport { registerAllBackends } from '../backends/index.js';\n\n// Base\nexport {\n BasePipeline,\n registerPipeline,\n getPipelineFactory,\n SENTIMENT_LABELS,\n EMOTION_LABELS,\n IMAGENET_LABELS,\n type PipelineResult,\n type TextClassificationResult,\n type FeatureExtractionResult,\n type ImageClassificationResult,\n type ObjectDetectionResult,\n} from './base.js';\n\n// Text Classification\nexport {\n TextClassificationPipeline,\n SentimentAnalysisPipeline,\n createTextClassificationPipeline,\n createSentimentAnalysisPipeline,\n type TextClassificationOptions,\n} from './text-classification.js';\n\n// Feature Extraction\nexport {\n FeatureExtractionPipeline,\n createFeatureExtractionPipeline,\n type FeatureExtractionOptions,\n} from './feature-extraction.js';\n\n// Image Classification\nexport {\n ImageClassificationPipeline,\n createImageClassificationPipeline,\n type ImageClassificationOptions,\n type ImageInput,\n} from './image-classification.js';\n\n// Text Generation\nexport {\n TextGenerationPipeline,\n createTextGenerationPipeline,\n type TextGenerationOptions,\n type TextGenerationResult,\n type GenerationStreamEvent,\n type ChatMessage,\n type ChatOptions,\n type ChatTemplateType,\n type LLMLoadProgress,\n} from './text-generation.js';\n\n// Object Detection\nexport {\n ObjectDetectionPipeline,\n createObjectDetectionPipeline,\n COCO_LABELS,\n type ObjectDetectionOptions,\n type Detection,\n type BoundingBox,\n} from './object-detection.js';\n\n// Automatic Speech Recognition\nexport {\n AutomaticSpeechRecognitionPipeline,\n createASRPipeline,\n type ASROptions,\n type ASRResult,\n type WordTimestamp,\n type ChunkTimestamp,\n} from './automatic-speech-recognition.js';\n\n// Zero-shot Classification\nexport {\n ZeroShotClassificationPipeline,\n createZeroShotClassificationPipeline,\n type ZeroShotClassificationOptions,\n type ZeroShotClassificationResult,\n} from './zero-shot-classification.js';\n\n// Question Answering\nexport {\n QuestionAnsweringPipeline,\n createQuestionAnsweringPipeline,\n type QuestionAnsweringOptions,\n type QuestionAnsweringResult,\n type QAInput,\n} from './question-answering.js';\n\n// Image Segmentation\nexport {\n ImageSegmentationPipeline,\n createImageSegmentationPipeline,\n type ImageSegmentationOptions,\n type ImageSegmentationResult,\n type PointPrompt,\n type BoxPrompt,\n type ModelLoadProgress,\n} from './image-segmentation.js';\n\n// ============================================================================\n// High-Level Pipeline Factory\n// ============================================================================\n\n/**\n * Pipeline options for the factory function\n */\nexport interface PipelineFactoryOptions {\n /** Model ID or URL */\n model?: string;\n /** Runtime to use */\n runtime?: RuntimeType;\n /** Enable caching */\n cache?: boolean;\n /** Quantization type */\n quantization?: QuantizationType;\n /** Custom labels for classification */\n labels?: string[];\n}\n\n/**\n * Supported pipeline task mapping\n */\ntype PipelineTaskMap = {\n 'text-classification': TextClassificationPipeline;\n 'sentiment-analysis': SentimentAnalysisPipeline;\n 'feature-extraction': FeatureExtractionPipeline;\n 'image-classification': ImageClassificationPipeline;\n 'text-generation': TextGenerationPipeline;\n 'object-detection': ObjectDetectionPipeline;\n 'automatic-speech-recognition': AutomaticSpeechRecognitionPipeline;\n 'zero-shot-classification': ZeroShotClassificationPipeline;\n 'question-answering': QuestionAnsweringPipeline;\n 'image-segmentation': ImageSegmentationPipeline;\n};\n\n// Import pipeline classes\nimport { TextClassificationPipeline, SentimentAnalysisPipeline } from './text-classification.js';\nimport { FeatureExtractionPipeline } from './feature-extraction.js';\nimport { ImageClassificationPipeline } from './image-classification.js';\nimport { TextGenerationPipeline } from './text-generation.js';\nimport { ObjectDetectionPipeline } from './object-detection.js';\nimport { AutomaticSpeechRecognitionPipeline } from './automatic-speech-recognition.js';\nimport { ZeroShotClassificationPipeline } from './zero-shot-classification.js';\nimport { QuestionAnsweringPipeline } from './question-answering.js';\nimport { ImageSegmentationPipeline } from './image-segmentation.js';\n\n/**\n * Create a pipeline for a specific task\n * \n * @example\n * ```typescript\n * // Create a sentiment analysis pipeline\n * const sentiment = await pipeline('sentiment-analysis');\n * const result = await sentiment.run('I love this product!');\n * \n * // Create an image classifier with custom model\n * const classifier = await pipeline('image-classification', {\n * model: 'https://example.com/model.bin',\n * });\n * ```\n */\nexport async function pipeline<T extends keyof PipelineTaskMap>(\n task: T,\n options?: PipelineFactoryOptions\n): Promise<PipelineTaskMap[T]> {\n // Guarantee backends are registered before any model loads.\n // registerAllBackends() is synchronous and idempotent (safe to call repeatedly).\n registerAllBackends();\n\n const config: PipelineConfig = {\n task: task as PipelineTask,\n model: options?.model ?? 'default',\n runtime: options?.runtime,\n cache: options?.cache ?? true,\n quantization: options?.quantization,\n };\n\n type AllPipelines = TextClassificationPipeline | SentimentAnalysisPipeline | FeatureExtractionPipeline | ImageClassificationPipeline | TextGenerationPipeline | ObjectDetectionPipeline | AutomaticSpeechRecognitionPipeline | ZeroShotClassificationPipeline | QuestionAnsweringPipeline | ImageSegmentationPipeline;\n \n let pipelineInstance: AllPipelines;\n\n switch (task) {\n case 'text-classification':\n pipelineInstance = new TextClassificationPipeline(config, options?.labels);\n break;\n case 'sentiment-analysis':\n pipelineInstance = new SentimentAnalysisPipeline(config);\n break;\n case 'feature-extraction':\n pipelineInstance = new FeatureExtractionPipeline(config);\n break;\n case 'image-classification':\n pipelineInstance = new ImageClassificationPipeline(config, options?.labels);\n break;\n case 'text-generation':\n pipelineInstance = new TextGenerationPipeline(config);\n break;\n case 'object-detection':\n pipelineInstance = new ObjectDetectionPipeline(config, options?.labels);\n break;\n case 'automatic-speech-recognition':\n pipelineInstance = new AutomaticSpeechRecognitionPipeline(config);\n break;\n case 'zero-shot-classification':\n pipelineInstance = new ZeroShotClassificationPipeline(config);\n break;\n case 'question-answering':\n pipelineInstance = new QuestionAnsweringPipeline(config);\n break;\n case 'image-segmentation':\n pipelineInstance = new ImageSegmentationPipeline(config);\n break;\n default: {\n // Check if a plugin provides this pipeline task\n const pluginEntry = getPluginPipeline(task);\n if (pluginEntry) {\n pipelineInstance = pluginEntry.factory(config);\n break;\n }\n throw new Error(\n `Unknown pipeline task: \"${task}\". ` +\n `Register a plugin with registerPlugin() to add custom pipeline tasks.`\n );\n }\n }\n\n // Initialize the pipeline\n await pipelineInstance.initialize();\n\n return pipelineInstance as PipelineTaskMap[T];\n}\n\n/**\n * Create multiple pipelines at once\n */\nexport async function createPipelines<T extends (keyof PipelineTaskMap)[]>(\n tasks: T,\n options?: PipelineFactoryOptions\n): Promise<{ [K in T[number]]: PipelineTaskMap[K] }> {\n const pipelines = await Promise.all(\n tasks.map(task => pipeline(task, options))\n );\n\n const result: Partial<{ [K in T[number]]: PipelineTaskMap[K] }> = {};\n \n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i]!;\n result[task as T[number]] = pipelines[i] as PipelineTaskMap[T[number]];\n }\n\n return result as { [K in T[number]]: PipelineTaskMap[K] };\n}\n", "/**\n * edgeFlow.js - Pipeline Composer\n *\n * Chain multiple pipelines together to build complex multi-model workflows.\n * Each stage's output is transformed and fed as input to the next stage.\n *\n * @example\n * ```typescript\n * import { compose } from 'edgeflowjs';\n *\n * const speechTranslator = compose([\n * { task: 'automatic-speech-recognition' },\n * { task: 'translation', options: { srcLang: 'en', tgtLang: 'zh' } },\n * ]);\n *\n * const result = await speechTranslator.run(audioBlob);\n * // result.stages = [asrResult, translationResult]\n * // result.output = final translation text\n * ```\n */\n\nimport { pipeline, type PipelineFactoryOptions } from '../pipelines/index.js';\nimport type { PipelineTask } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single stage in a composed pipeline.\n */\nexport interface CompositionStage {\n /** The pipeline task to run */\n task: PipelineTask | (string & {});\n /** Model override for this stage */\n model?: string;\n /** Extra options forwarded to `pipeline()` */\n options?: PipelineFactoryOptions;\n /**\n * Optional transform applied to the previous stage's output before it is\n * passed as input to this stage. If omitted, the raw output is forwarded.\n */\n transform?: (previousOutput: unknown) => unknown;\n /**\n * Options forwarded to the pipeline's `run()` call.\n */\n runOptions?: Record<string, unknown>;\n}\n\n/**\n * Result from running a composed pipeline.\n */\nexport interface CompositionResult {\n /** The final output from the last stage */\n output: unknown;\n /** Intermediate results for every stage (index-aligned with stages) */\n stages: unknown[];\n /** Total wall-clock time in milliseconds */\n totalTime: number;\n /** Per-stage timing */\n stageTimes: number[];\n}\n\n/**\n * A composed (chained) pipeline.\n */\nexport interface ComposedPipeline {\n /** Execute the full chain with the given initial input */\n run(input: unknown): Promise<CompositionResult>;\n /** Dispose all underlying pipeline instances */\n dispose(): void;\n /** Number of stages */\n readonly length: number;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Compose multiple pipeline stages into a single sequential chain.\n *\n * The output of each stage is fed as the input to the next stage. Use the\n * optional `transform` hook in a stage to reshape data between stages.\n *\n * All pipelines are lazily initialised on the first `run()` call and cached\n * for subsequent calls.\n *\n * @param stages - Ordered list of pipeline stages\n * @returns A composed pipeline that can be run end-to-end\n *\n * @example\n * ```typescript\n * const ocrPipeline = compose([\n * { task: 'image-to-text' },\n * {\n * task: 'text-classification',\n * transform: (ocrResult: any) => ocrResult.text,\n * },\n * ]);\n *\n * const { output, stages, totalTime } = await ocrPipeline.run(imageElement);\n * ```\n */\nexport function compose(stages: CompositionStage[]): ComposedPipeline {\n if (stages.length === 0) {\n throw new Error('[edgeFlow.js] compose() requires at least one stage');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let pipelineInstances: any[] | null = null;\n\n async function ensureInitialised() {\n if (pipelineInstances) return pipelineInstances;\n\n pipelineInstances = await Promise.all(\n stages.map((stage) =>\n pipeline(stage.task as Parameters<typeof pipeline>[0], {\n model: stage.model,\n ...stage.options,\n }),\n ),\n );\n return pipelineInstances;\n }\n\n return {\n get length() {\n return stages.length;\n },\n\n async run(input: unknown): Promise<CompositionResult> {\n const instances = await ensureInitialised();\n const stageResults: unknown[] = [];\n const stageTimes: number[] = [];\n let current = input;\n const wallStart = performance.now();\n\n for (let i = 0; i < stages.length; i++) {\n const stage = stages[i]!;\n const inst = instances[i]!;\n\n // Apply transform from previous stage output if provided\n if (stage.transform) {\n current = stage.transform(current);\n }\n\n const t0 = performance.now();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n current = await (inst as any).run(current, stage.runOptions);\n stageTimes.push(performance.now() - t0);\n stageResults.push(current);\n }\n\n return {\n output: current,\n stages: stageResults,\n totalTime: performance.now() - wallStart,\n stageTimes,\n };\n },\n\n dispose() {\n if (pipelineInstances) {\n for (const inst of pipelineInstances) {\n if (inst && typeof inst.dispose === 'function') {\n inst.dispose();\n }\n }\n pipelineInstances = null;\n }\n },\n };\n}\n\n/**\n * Run stages in parallel (fan-out) and collect all results.\n *\n * Unlike `compose` (which is sequential), `parallel` runs every stage\n * independently with the same input and returns an array of results.\n *\n * @example\n * ```typescript\n * const analyzer = parallel([\n * { task: 'text-classification' },\n * { task: 'feature-extraction' },\n * { task: 'zero-shot-classification',\n * transform: (text) => ({ text, candidateLabels: ['news', 'sports'] }) },\n * ]);\n *\n * const results = await analyzer.run('Breaking: team wins championship');\n * ```\n */\nexport function parallel(\n stages: CompositionStage[],\n): {\n run(input: unknown): Promise<{ outputs: unknown[]; totalTime: number }>;\n dispose(): void;\n} {\n if (stages.length === 0) {\n throw new Error('[edgeFlow.js] parallel() requires at least one stage');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let pipelineInstances: any[] | null = null;\n\n async function ensureInitialised() {\n if (pipelineInstances) return pipelineInstances;\n pipelineInstances = await Promise.all(\n stages.map((s) =>\n pipeline(s.task as Parameters<typeof pipeline>[0], {\n model: s.model,\n ...s.options,\n }),\n ),\n );\n return pipelineInstances;\n }\n\n return {\n async run(input: unknown) {\n const instances = await ensureInitialised();\n const t0 = performance.now();\n\n const outputs = await Promise.all(\n stages.map((stage, i) => {\n const stageInput = stage.transform ? stage.transform(input) : input;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (instances[i] as any).run(stageInput, stage.runOptions);\n }),\n );\n\n return { outputs, totalTime: performance.now() - t0 };\n },\n\n dispose() {\n if (pipelineInstances) {\n for (const inst of pipelineInstances) {\n if (inst && typeof inst.dispose === 'function') {\n inst.dispose();\n }\n }\n pipelineInstances = null;\n }\n },\n };\n}\n", "/**\n * edgeFlow.js - Utilities Exports\n */\n\n// Tokenizer\nexport {\n Tokenizer,\n createBasicTokenizer,\n loadTokenizer,\n loadTokenizerFromHub,\n type TokenizerModel,\n type TokenizerOptions,\n} from './tokenizer.js';\n\n// Preprocessor\nexport {\n ImagePreprocessor,\n AudioPreprocessor,\n preprocessText,\n createImagePreprocessor,\n createAudioPreprocessor,\n type ImagePreprocessorOptions,\n type AudioPreprocessorOptions,\n type TextPreprocessorOptions,\n} from './preprocessor.js';\n\n// Cache\nexport {\n Cache,\n InferenceCache,\n ModelDownloadCache,\n createCache,\n type CacheStrategy,\n type CacheOptions,\n type CacheStats,\n} from './cache.js';\n\n// Model Loader (Preloading, Sharding, Resume, Caching)\nexport {\n loadModelData,\n preloadModel,\n preloadModels,\n isModelCached,\n getCachedModel,\n deleteCachedModel,\n clearModelCache,\n getModelCacheStats,\n getPreloadStatus,\n cancelPreload,\n getPreloadedModel,\n type DownloadProgress,\n type ModelLoaderOptions,\n type PreloadOptions,\n} from './model-loader.js';\n\n// HuggingFace Hub Integration\nexport {\n fromHub,\n fromTask,\n downloadModel,\n downloadFile,\n downloadTokenizer,\n downloadConfig,\n modelExists,\n getModelInfo,\n getDefaultModel,\n POPULAR_MODELS,\n type HubOptions,\n type HubDownloadProgress,\n type ModelConfig,\n type ModelBundle,\n type PopularModelTask,\n} from './hub.js';\n\n// Offline/PWA Support\nexport {\n OfflineManager,\n getOfflineManager,\n initOffline,\n isOffline,\n isPWASupported,\n generateServiceWorker,\n generateManifest,\n type OfflineConfig,\n type OfflineStatus,\n type CachedModelInfo,\n} from './offline.js';\n", "/**\n * edgeFlow.js - Hugging Face Hub Integration\n * \n * Automatically download models, tokenizers, and configs from Hugging Face Hub.\n */\n\nimport { loadModelData, isModelCached, type DownloadProgress } from './model-loader.js';\nimport { Tokenizer } from './tokenizer.js';\nimport { EdgeFlowError, ErrorCodes } from '../core/types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Hub options\n */\nexport interface HubOptions {\n /** HuggingFace API endpoint (default: https://huggingface.co) */\n endpoint?: string;\n /** Model revision/branch (default: main) */\n revision?: string;\n /** Subfolder within the repo */\n subfolder?: string;\n /** Enable caching */\n cache?: boolean;\n /** Force re-download */\n forceDownload?: boolean;\n /** Progress callback */\n onProgress?: (progress: HubDownloadProgress) => void;\n /** HuggingFace API token (for private repos) */\n token?: string;\n}\n\n/**\n * Download progress for hub\n */\nexport interface HubDownloadProgress {\n /** Current file being downloaded */\n file: string;\n /** File index (1-based) */\n fileIndex: number;\n /** Total files */\n totalFiles: number;\n /** File download progress */\n fileProgress: DownloadProgress;\n /** Overall progress (0-100) */\n overallProgress: number;\n}\n\n/**\n * Model info from config.json\n */\nexport interface ModelConfig {\n model_type?: string;\n architectures?: string[];\n hidden_size?: number;\n num_attention_heads?: number;\n num_hidden_layers?: number;\n vocab_size?: number;\n max_position_embeddings?: number;\n type_vocab_size?: number;\n id2label?: Record<string, string>;\n label2id?: Record<string, number>;\n [key: string]: unknown;\n}\n\n/**\n * Downloaded model bundle\n */\nexport interface ModelBundle {\n /** Model ID */\n modelId: string;\n /** Model data (ArrayBuffer) */\n modelData: ArrayBuffer;\n /** Tokenizer instance */\n tokenizer?: Tokenizer;\n /** Model config */\n config?: ModelConfig;\n /** Model files info */\n files: {\n model?: string;\n tokenizer?: string;\n config?: string;\n };\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_ENDPOINT = 'https://huggingface.co';\nconst DEFAULT_REVISION = 'main';\n\n/**\n * Common ONNX model file patterns (in order of preference)\n */\nconst ONNX_MODEL_FILES = [\n 'model.onnx',\n 'model_quantized.onnx',\n 'model_int8.onnx',\n 'model_uint8.onnx',\n 'model_fp16.onnx',\n 'onnx/model.onnx',\n 'onnx/model_quantized.onnx',\n];\n\n// ============================================================================\n// Hub API\n// ============================================================================\n\n/**\n * Build URL for a file in a HuggingFace repo\n */\nfunction buildFileUrl(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): string {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const revision = options.revision ?? DEFAULT_REVISION;\n const subfolder = options.subfolder ? `${options.subfolder}/` : '';\n \n return `${endpoint}/${modelId}/resolve/${revision}/${subfolder}${filename}`;\n}\n\n/**\n * Fetch with optional auth token\n */\nasync function fetchWithAuth(url: string, token?: string): Promise<Response> {\n const headers: HeadersInit = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n \n const response = await fetch(url, { headers });\n return response;\n}\n\n/**\n * Check if a file exists in a repo\n */\nasync function fileExists(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<boolean> {\n const url = buildFileUrl(modelId, filename, options);\n \n try {\n const response = await fetchWithAuth(url, options.token);\n // HuggingFace returns 302 redirect for existing files\n return response.ok || response.status === 302;\n } catch {\n return false;\n }\n}\n\n/**\n * Find the best ONNX model file in a repo\n */\nasync function findOnnxModel(\n modelId: string,\n options: HubOptions = {}\n): Promise<string | null> {\n // Try common file patterns\n for (const filename of ONNX_MODEL_FILES) {\n if (await fileExists(modelId, filename, options)) {\n return filename;\n }\n }\n \n return null;\n}\n\n/**\n * Download a file from HuggingFace Hub\n */\nexport async function downloadFile(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<ArrayBuffer> {\n const url = buildFileUrl(modelId, filename, options);\n \n // Use model loader for caching and resume support\n return loadModelData(url, {\n cache: options.cache ?? true,\n forceDownload: options.forceDownload ?? false,\n onProgress: options.onProgress ? (progress) => {\n options.onProgress!({\n file: filename,\n fileIndex: 1,\n totalFiles: 1,\n fileProgress: progress,\n overallProgress: progress.percent,\n });\n } : undefined,\n });\n}\n\n/**\n * Download JSON file from HuggingFace Hub\n */\nexport async function downloadJson<T = unknown>(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<T> {\n const url = buildFileUrl(modelId, filename, options);\n \n // Check cache first\n if (options.cache !== false && !options.forceDownload) {\n const cached = await isModelCached(url);\n if (cached) {\n const data = await loadModelData(url, { cache: true });\n const text = new TextDecoder().decode(data);\n return JSON.parse(text) as T;\n }\n }\n \n // Fetch directly for small JSON files\n const response = await fetchWithAuth(url, options.token);\n \n if (!response.ok) {\n throw new EdgeFlowError(\n `Failed to download ${filename} from ${modelId}: ${response.status}`,\n ErrorCodes.MODEL_NOT_FOUND\n );\n }\n \n return response.json() as Promise<T>;\n}\n\n/**\n * Download tokenizer from HuggingFace Hub\n */\nexport async function downloadTokenizer(\n modelId: string,\n options: HubOptions = {}\n): Promise<Tokenizer> {\n const url = buildFileUrl(modelId, 'tokenizer.json', options);\n return Tokenizer.fromUrl(url);\n}\n\n/**\n * Download model config from HuggingFace Hub\n */\nexport async function downloadConfig(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelConfig> {\n return downloadJson<ModelConfig>(modelId, 'config.json', options);\n}\n\n/**\n * Download complete model bundle (model + tokenizer + config)\n */\nexport async function downloadModel(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n const files: ModelBundle['files'] = {};\n const totalSteps = 3; // model, tokenizer, config\n let currentStep = 0;\n \n const reportProgress = (\n file: string,\n progress: DownloadProgress\n ) => {\n if (options.onProgress) {\n const baseProgress = (currentStep / totalSteps) * 100;\n const stepProgress = (progress.percent / totalSteps);\n \n options.onProgress({\n file,\n fileIndex: currentStep + 1,\n totalFiles: totalSteps,\n fileProgress: progress,\n overallProgress: baseProgress + stepProgress,\n });\n }\n };\n \n // 1. Find and download ONNX model\n console.log(`\uD83D\uDD0D Finding ONNX model in ${modelId}...`);\n const modelFile = await findOnnxModel(modelId, options);\n \n if (!modelFile) {\n throw new EdgeFlowError(\n `No ONNX model found in ${modelId}. Please ensure the model has an ONNX file.`,\n ErrorCodes.MODEL_NOT_FOUND,\n { modelId, triedFiles: ONNX_MODEL_FILES }\n );\n }\n \n files.model = modelFile;\n console.log(`\uD83D\uDCE6 Downloading model: ${modelFile}`);\n \n const modelData = await downloadFile(modelId, modelFile, {\n ...options,\n onProgress: (p) => reportProgress(modelFile, p.fileProgress),\n });\n \n currentStep = 1;\n \n // 2. Download tokenizer (optional)\n let tokenizer: Tokenizer | undefined;\n try {\n console.log(`\uD83D\uDCDD Downloading tokenizer...`);\n files.tokenizer = 'tokenizer.json';\n tokenizer = await downloadTokenizer(modelId, options);\n console.log(`\u2713 Tokenizer loaded`);\n } catch (error) {\n console.warn(`\u26A0\uFE0F No tokenizer found for ${modelId}`);\n }\n \n currentStep = 2;\n \n // 3. Download config (optional)\n let config: ModelConfig | undefined;\n try {\n console.log(`\u2699\uFE0F Downloading config...`);\n files.config = 'config.json';\n config = await downloadConfig(modelId, options);\n console.log(`\u2713 Config loaded`);\n } catch (error) {\n console.warn(`\u26A0\uFE0F No config found for ${modelId}`);\n }\n \n currentStep = 3;\n \n if (options.onProgress) {\n options.onProgress({\n file: 'complete',\n fileIndex: totalSteps,\n totalFiles: totalSteps,\n fileProgress: { loaded: 1, total: 1, percent: 100, speed: 0, eta: 0 },\n overallProgress: 100,\n });\n }\n \n console.log(`\u2705 Model bundle downloaded: ${modelId}`);\n \n return {\n modelId,\n modelData,\n tokenizer,\n config,\n files,\n };\n}\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\n/**\n * Load a model from HuggingFace Hub\n * \n * @example\n * ```typescript\n * // Load a sentiment analysis model\n * const bundle = await fromHub('Xenova/distilbert-base-uncased-finetuned-sst-2-english');\n * \n * // Use with edgeFlow\n * const model = await loadModelFromBuffer(bundle.modelData);\n * const tokens = bundle.tokenizer.encode('I love this!');\n * ```\n */\nexport async function fromHub(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n return downloadModel(modelId, options);\n}\n\n/**\n * Check if a model exists on HuggingFace Hub\n */\nexport async function modelExists(\n modelId: string,\n options: HubOptions = {}\n): Promise<boolean> {\n try {\n // Try to find an ONNX model\n const modelFile = await findOnnxModel(modelId, options);\n return modelFile !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Get model info from HuggingFace Hub\n */\nexport async function getModelInfo(\n modelId: string,\n options: HubOptions = {}\n): Promise<{\n hasOnnx: boolean;\n onnxFile?: string;\n hasTokenizer: boolean;\n hasConfig: boolean;\n config?: ModelConfig;\n}> {\n const [onnxFile, hasTokenizer, config] = await Promise.all([\n findOnnxModel(modelId, options),\n fileExists(modelId, 'tokenizer.json', options),\n downloadConfig(modelId, options).catch(() => undefined),\n ]);\n \n return {\n hasOnnx: onnxFile !== null,\n onnxFile: onnxFile ?? undefined,\n hasTokenizer,\n hasConfig: config !== undefined,\n config,\n };\n}\n\n// ============================================================================\n// Popular Models Registry\n// ============================================================================\n\n/**\n * Pre-configured popular models\n */\nexport const POPULAR_MODELS = {\n // Text Classification / Sentiment\n 'sentiment-analysis': 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n 'text-classification': 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n \n // Feature Extraction\n 'feature-extraction': 'Xenova/all-MiniLM-L6-v2',\n 'sentence-similarity': 'Xenova/all-MiniLM-L6-v2',\n \n // Question Answering\n 'question-answering': 'Xenova/distilbert-base-cased-distilled-squad',\n \n // Token Classification\n 'ner': 'Xenova/bert-base-NER',\n 'token-classification': 'Xenova/bert-base-NER',\n \n // Text Generation\n 'text-generation': 'Xenova/gpt2',\n \n // Translation\n 'translation-en-fr': 'Xenova/t5-small',\n 'translation-en-de': 'Xenova/t5-small',\n \n // Summarization\n 'summarization': 'Xenova/distilbart-cnn-6-6',\n \n // Fill Mask\n 'fill-mask': 'Xenova/bert-base-uncased',\n \n // Image Classification\n 'image-classification': 'Xenova/vit-base-patch16-224',\n \n // Object Detection\n 'object-detection': 'Xenova/detr-resnet-50',\n \n // Image Segmentation\n 'image-segmentation': 'Xenova/segformer-b0-finetuned-ade-512-512',\n \n // Zero-shot Classification\n 'zero-shot-classification': 'Xenova/mobilebert-uncased-mnli',\n \n // Speech Recognition\n 'automatic-speech-recognition': 'Xenova/whisper-tiny.en',\n \n // Text-to-Speech\n 'text-to-speech': 'Xenova/speecht5_tts',\n} as const;\n\nexport type PopularModelTask = keyof typeof POPULAR_MODELS;\n\n/**\n * Get the default model ID for a task\n */\nexport function getDefaultModel(task: PopularModelTask): string {\n return POPULAR_MODELS[task];\n}\n\n/**\n * Load a model by task name\n * \n * @example\n * ```typescript\n * const bundle = await fromTask('sentiment-analysis');\n * ```\n */\nexport async function fromTask(\n task: PopularModelTask,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n const modelId = getDefaultModel(task);\n return downloadModel(modelId, options);\n}\n", "/**\n * edgeFlow.js - Benchmark Utilities\n * \n * Performance testing and comparison tools.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BenchmarkOptions {\n /** Number of warmup runs (default: 3) */\n warmupRuns?: number;\n \n /** Number of measured runs (default: 10) */\n runs?: number;\n \n /** Whether to log progress (default: true) */\n verbose?: boolean;\n \n /** Timeout per run in ms (default: 30000) */\n timeout?: number;\n \n /** Name for this benchmark */\n name?: string;\n}\n\nexport interface BenchmarkResult {\n name: string;\n \n /** Average time in ms */\n avgTime: number;\n \n /** Median time in ms */\n medianTime: number;\n \n /** Minimum time in ms */\n minTime: number;\n \n /** Maximum time in ms */\n maxTime: number;\n \n /** Standard deviation in ms */\n stdDev: number;\n \n /** 95th percentile in ms */\n p95: number;\n \n /** 99th percentile in ms */\n p99: number;\n \n /** Throughput (ops/sec) */\n throughput: number;\n \n /** All individual run times */\n times: number[];\n \n /** Number of runs */\n totalRuns: number;\n \n /** Number of failed runs */\n failedRuns: number;\n}\n\nexport interface CompareBenchmarkResult {\n baseline: BenchmarkResult;\n comparison: BenchmarkResult;\n speedup: number;\n percentFaster: number;\n winner: 'baseline' | 'comparison' | 'tie';\n}\n\n// ============================================================================\n// Benchmark Functions\n// ============================================================================\n\n/**\n * Run a benchmark on an async function\n */\nexport async function benchmark(\n fn: () => Promise<unknown> | unknown,\n options: BenchmarkOptions = {}\n): Promise<BenchmarkResult> {\n const {\n warmupRuns = 3,\n runs = 10,\n verbose = false,\n timeout = 30000,\n name = 'benchmark',\n } = options;\n\n const times: number[] = [];\n let failedRuns = 0;\n\n // Warmup\n if (verbose) console.log(`[${name}] Running ${warmupRuns} warmup iterations...`);\n for (let i = 0; i < warmupRuns; i++) {\n try {\n await Promise.race([\n Promise.resolve(fn()),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Timeout')), timeout)\n ),\n ]);\n } catch {\n // Warmup failures are ignored\n }\n }\n\n // Measured runs\n if (verbose) console.log(`[${name}] Running ${runs} measured iterations...`);\n for (let i = 0; i < runs; i++) {\n try {\n const start = performance.now();\n await Promise.race([\n Promise.resolve(fn()),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Timeout')), timeout)\n ),\n ]);\n const end = performance.now();\n times.push(end - start);\n \n if (verbose) console.log(` Run ${i + 1}: ${(end - start).toFixed(2)}ms`);\n } catch (error) {\n failedRuns++;\n if (verbose) console.log(` Run ${i + 1}: FAILED - ${error}`);\n }\n }\n\n if (times.length === 0) {\n throw new Error(`All ${runs} runs failed`);\n }\n\n // Calculate statistics\n const sorted = [...times].sort((a, b) => a - b);\n const sum = times.reduce((a, b) => a + b, 0);\n const avg = sum / times.length;\n const variance = times.reduce((sum, t) => sum + Math.pow(t - avg, 2), 0) / times.length;\n const stdDev = Math.sqrt(variance);\n\n const result: BenchmarkResult = {\n name,\n avgTime: avg,\n medianTime: sorted[Math.floor(sorted.length / 2)] ?? 0,\n minTime: sorted[0] ?? 0,\n maxTime: sorted[sorted.length - 1] ?? 0,\n stdDev,\n p95: sorted[Math.floor(sorted.length * 0.95)] ?? sorted[sorted.length - 1] ?? 0,\n p99: sorted[Math.floor(sorted.length * 0.99)] ?? sorted[sorted.length - 1] ?? 0,\n throughput: 1000 / avg,\n times,\n totalRuns: runs,\n failedRuns,\n };\n\n if (verbose) {\n console.log(`\\n[${name}] Results:`);\n console.log(` Avg: ${result.avgTime.toFixed(2)}ms`);\n console.log(` Median: ${result.medianTime.toFixed(2)}ms`);\n console.log(` Min: ${result.minTime.toFixed(2)}ms`);\n console.log(` Max: ${result.maxTime.toFixed(2)}ms`);\n console.log(` Std Dev: ${result.stdDev.toFixed(2)}ms`);\n console.log(` P95: ${result.p95.toFixed(2)}ms`);\n console.log(` Throughput: ${result.throughput.toFixed(2)} ops/sec`);\n }\n\n return result;\n}\n\n/**\n * Compare two benchmarks\n */\nexport async function compareBenchmarks(\n baseline: () => Promise<unknown> | unknown,\n comparison: () => Promise<unknown> | unknown,\n options: BenchmarkOptions = {}\n): Promise<CompareBenchmarkResult> {\n const baselineResult = await benchmark(baseline, { \n ...options, \n name: options.name ? `${options.name} (baseline)` : 'baseline' \n });\n \n const comparisonResult = await benchmark(comparison, { \n ...options, \n name: options.name ? `${options.name} (comparison)` : 'comparison' \n });\n\n const speedup = baselineResult.avgTime / comparisonResult.avgTime;\n const percentFaster = ((baselineResult.avgTime - comparisonResult.avgTime) / baselineResult.avgTime) * 100;\n\n let winner: 'baseline' | 'comparison' | 'tie';\n if (Math.abs(percentFaster) < 5) {\n winner = 'tie';\n } else if (percentFaster > 0) {\n winner = 'comparison';\n } else {\n winner = 'baseline';\n }\n\n return {\n baseline: baselineResult,\n comparison: comparisonResult,\n speedup,\n percentFaster,\n winner,\n };\n}\n\n/**\n * Run multiple benchmarks in a suite\n */\nexport async function benchmarkSuite(\n suite: Record<string, () => Promise<unknown> | unknown>,\n options: BenchmarkOptions = {}\n): Promise<Record<string, BenchmarkResult>> {\n const results: Record<string, BenchmarkResult> = {};\n\n for (const [name, fn] of Object.entries(suite)) {\n console.log(`\\n=== ${name} ===`);\n results[name] = await benchmark(fn, { ...options, name, verbose: true });\n }\n\n return results;\n}\n\n/**\n * Format benchmark result as a table string\n */\nexport function formatBenchmarkResult(result: BenchmarkResult): string {\n return `\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ${result.name.padEnd(39)} \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Avg Time: ${result.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Median: ${result.medianTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Min Time: ${result.minTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Max Time: ${result.maxTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Std Dev: ${result.stdDev.toFixed(2).padStart(10)}ms \u2502\n\u2502 P95: ${result.p95.toFixed(2).padStart(10)}ms \u2502\n\u2502 P99: ${result.p99.toFixed(2).padStart(10)}ms \u2502\n\u2502 Throughput: ${result.throughput.toFixed(2).padStart(10)} ops/sec \u2502\n\u2502 Runs: ${result.totalRuns.toString().padStart(10)} (${result.failedRuns} failed) \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n `.trim();\n}\n\n/**\n * Format comparison result\n */\nexport function formatComparisonResult(result: CompareBenchmarkResult): string {\n const arrow = result.percentFaster > 0 ? '\u2191' : result.percentFaster < 0 ? '\u2193' : '=';\n const winnerText = result.winner === 'comparison' \n ? 'Comparison is faster!'\n : result.winner === 'baseline'\n ? 'Baseline is faster!'\n : 'Results are similar';\n\n return `\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 BENCHMARK COMPARISON \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Baseline: ${result.baseline.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Comparison: ${result.comparison.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Speedup: ${result.speedup.toFixed(2).padStart(10)}x \u2502\n\u2502 Difference: ${arrow} ${Math.abs(result.percentFaster).toFixed(1).padStart(8)}% \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Winner: ${winnerText.padEnd(42)} \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n `.trim();\n}\n\n// ============================================================================\n// Memory Benchmark\n// ============================================================================\n\nexport interface MemoryBenchmarkResult {\n name: string;\n peakMemory: number;\n avgMemory: number;\n memoryDelta: number;\n}\n\n/**\n * Benchmark memory usage\n */\nexport async function benchmarkMemory(\n fn: () => Promise<unknown> | unknown,\n options: { name?: string; runs?: number } = {}\n): Promise<MemoryBenchmarkResult> {\n const { name = 'memory-benchmark', runs = 5 } = options;\n\n // Note: Memory APIs are limited in browsers\n // This is a simplified version that works when performance.memory is available\n const getMemory = (): number => {\n if (typeof performance !== 'undefined' && 'memory' in performance) {\n return (performance as { memory: { usedJSHeapSize: number } }).memory.usedJSHeapSize;\n }\n return 0;\n };\n\n const memoryReadings: number[] = [];\n const initialMemory = getMemory();\n\n for (let i = 0; i < runs; i++) {\n await fn();\n memoryReadings.push(getMemory());\n }\n\n const peakMemory = Math.max(...memoryReadings);\n const avgMemory = memoryReadings.reduce((a, b) => a + b, 0) / memoryReadings.length;\n const memoryDelta = avgMemory - initialMemory;\n\n return {\n name,\n peakMemory,\n avgMemory,\n memoryDelta,\n };\n}\n\n// ============================================================================\n// Export\n// ============================================================================\n\nexport default {\n benchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n};\n", "/**\n * edgeFlow.js - Core Module Exports\n */\n\n// Types\nexport * from './types.js';\n\n// Tensor\nexport {\n EdgeFlowTensor,\n tensor,\n zeros,\n ones,\n full,\n random,\n randn,\n arange,\n linspace,\n eye,\n add,\n sub,\n mul,\n div,\n matmul,\n softmax,\n relu,\n sigmoid,\n tanh,\n sum,\n mean,\n argmax,\n concat,\n} from './tensor.js';\n\n// Scheduler\nexport {\n InferenceScheduler,\n getScheduler,\n setScheduler,\n configureScheduler,\n} from './scheduler.js';\n\n// Memory\nexport {\n MemoryManager,\n MemoryScope,\n ModelCache,\n withMemoryScope,\n withMemoryScopeSync,\n getMemoryManager,\n getMemoryStats,\n release,\n gc,\n} from './memory.js';\n\n// Runtime\nexport {\n RuntimeManager,\n LoadedModelImpl,\n loadModel,\n loadModelFromBuffer,\n runInference,\n runBatchInference,\n getRuntimeManager,\n registerRuntime,\n getBestRuntime,\n getAvailableRuntimes,\n} from './runtime.js';\n\n// Plugin System\nexport {\n registerPlugin,\n getPluginPipeline,\n getPluginMiddleware,\n listPlugins,\n unregisterPlugin,\n type EdgeFlowPlugin,\n type PluginPipelineEntry,\n type PluginBackendEntry,\n type PluginMiddleware,\n} from './plugin.js';\n\n// Device Profiler\nexport {\n getDeviceProfile,\n recommendQuantization,\n recommendModelVariant,\n resetDeviceProfile,\n type DeviceProfile,\n type DeviceTier,\n type ModelRecommendation,\n} from './device-profiler.js';\n\n// Composer\nexport {\n compose,\n parallel,\n type CompositionStage,\n type CompositionResult,\n type ComposedPipeline,\n} from './composer.js';\n\n// Worker\nexport {\n InferenceWorker,\n WorkerPool,\n getWorkerPool,\n runInWorker,\n isWorkerSupported,\n serializeTensor,\n deserializeTensor,\n type WorkerMessage,\n type WorkerMessageType,\n type LoadModelRequest,\n type InferenceRequest,\n type SerializedTensor,\n type WorkerPoolOptions,\n} from './worker.js';\n", "/**\n * edgeFlow.js - Model Compression & Quantization Tools\n * \n * In-browser model quantization and compression utilities.\n * Supports dynamic quantization (no calibration data needed).\n */\n\nimport { EdgeFlowTensor, DataType } from '../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Quantization type\n */\nexport type QuantizationType = 'int8' | 'uint8' | 'int4' | 'float16' | 'dynamic';\n\n/**\n * Quantization options\n */\nexport interface QuantizationOptions {\n /** Quantization type */\n type: QuantizationType;\n \n /** Layers/ops to skip quantization (by name pattern) */\n skipPatterns?: (string | RegExp)[];\n \n /** Per-channel quantization (more accurate, larger model) */\n perChannel?: boolean;\n \n /** Symmetric quantization (simpler, slightly less accurate) */\n symmetric?: boolean;\n \n /** Progress callback */\n onProgress?: (progress: QuantizationProgress) => void;\n \n /** Minimum tensor size to quantize (in elements) */\n minTensorSize?: number;\n \n /** Keep original weights for comparison */\n keepOriginal?: boolean;\n}\n\n/**\n * Quantization progress\n */\nexport interface QuantizationProgress {\n stage: 'analyzing' | 'quantizing' | 'packing' | 'complete';\n current: number;\n total: number;\n percent: number;\n layerName?: string;\n}\n\n/**\n * Quantization result\n */\nexport interface QuantizationResult {\n /** Quantized model data */\n data: ArrayBuffer;\n \n /** Original model size in bytes */\n originalSize: number;\n \n /** Quantized model size in bytes */\n quantizedSize: number;\n \n /** Compression ratio */\n compressionRatio: number;\n \n /** Number of tensors quantized */\n tensorsQuantized: number;\n \n /** Number of tensors skipped */\n tensorsSkipped: number;\n \n /** Quantization statistics per layer */\n layerStats: LayerQuantizationStats[];\n \n /** Overall statistics */\n stats: QuantizationStats;\n}\n\n/**\n * Layer quantization statistics\n */\nexport interface LayerQuantizationStats {\n name: string;\n originalDtype: string;\n quantizedDtype: string;\n originalSize: number;\n quantizedSize: number;\n scale: number | number[];\n zeroPoint: number | number[];\n minValue: number;\n maxValue: number;\n skipped: boolean;\n skipReason?: string;\n}\n\n/**\n * Overall quantization statistics\n */\nexport interface QuantizationStats {\n totalParameters: number;\n quantizedParameters: number;\n averageScale: number;\n minScale: number;\n maxScale: number;\n errorEstimate: number;\n}\n\n/**\n * Quantization parameters for a tensor\n */\ninterface QuantizationParams {\n scale: number | Float32Array;\n zeroPoint: number | Int32Array;\n min: number;\n max: number;\n}\n\n// ============================================================================\n// Quantization Core\n// ============================================================================\n\n/**\n * Calculate quantization parameters for a tensor\n */\nfunction calculateQuantParams(\n data: Float32Array,\n bits: number,\n symmetric: boolean,\n perChannel: boolean,\n channelAxis: number = 0,\n shape: number[] = []\n): QuantizationParams {\n const qmin = symmetric ? -(1 << (bits - 1)) : 0;\n const qmax = symmetric ? (1 << (bits - 1)) - 1 : (1 << bits) - 1;\n \n if (perChannel && shape.length > 1) {\n // Per-channel quantization\n const numChannels = shape[channelAxis] ?? 1;\n const scales = new Float32Array(numChannels);\n const zeroPoints = new Int32Array(numChannels);\n \n const channelSize = data.length / numChannels;\n let globalMin = Infinity;\n let globalMax = -Infinity;\n \n for (let c = 0; c < numChannels; c++) {\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n \n globalMin = Math.min(globalMin, min);\n globalMax = Math.max(globalMax, max);\n \n if (symmetric) {\n const absMax = Math.max(Math.abs(min), Math.abs(max));\n scales[c] = absMax / qmax;\n zeroPoints[c] = 0;\n } else {\n scales[c] = (max - min) / (qmax - qmin);\n zeroPoints[c] = Math.round(qmin - min / (scales[c] || 1));\n }\n \n // Avoid division by zero\n if (scales[c] === 0) scales[c] = 1;\n }\n \n return { scale: scales, zeroPoint: zeroPoints, min: globalMin, max: globalMax };\n } else {\n // Per-tensor quantization\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n \n let scale: number;\n let zeroPoint: number;\n \n if (symmetric) {\n const absMax = Math.max(Math.abs(min), Math.abs(max));\n scale = absMax / qmax;\n zeroPoint = 0;\n } else {\n scale = (max - min) / (qmax - qmin);\n zeroPoint = Math.round(qmin - min / (scale || 1));\n }\n \n // Avoid division by zero\n if (scale === 0) scale = 1;\n \n return { scale, zeroPoint, min, max };\n }\n}\n\n/**\n * Quantize float32 data to int8\n */\nfunction quantizeToInt8(\n data: Float32Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean,\n channelSize: number = data.length\n): Int8Array {\n const result = new Int8Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n result[idx] = Math.max(-128, Math.min(127, Math.round(val / s + zp)));\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n result[i] = Math.max(-128, Math.min(127, Math.round(val / s + zp)));\n }\n }\n \n return result;\n}\n\n/**\n * Quantize float32 data to uint8\n */\nfunction quantizeToUint8(\n data: Float32Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean,\n channelSize: number = data.length\n): Uint8Array {\n const result = new Uint8Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n result[idx] = Math.max(0, Math.min(255, Math.round(val / s + zp)));\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n result[i] = Math.max(0, Math.min(255, Math.round(val / s + zp)));\n }\n }\n \n return result;\n}\n\n/**\n * Quantize float32 data to int4 (packed as uint8, 2 values per byte)\n */\nfunction quantizeToInt4(\n data: Float32Array,\n scale: number,\n zeroPoint: number\n): Uint8Array {\n const packedLength = Math.ceil(data.length / 2);\n const result = new Uint8Array(packedLength);\n \n for (let i = 0; i < data.length; i += 2) {\n const val1 = data[i] ?? 0;\n const val2 = data[i + 1] ?? 0;\n \n // Quantize to range [-8, 7] then shift to [0, 15]\n const q1 = Math.max(0, Math.min(15, Math.round(val1 / scale + zeroPoint + 8)));\n const q2 = Math.max(0, Math.min(15, Math.round(val2 / scale + zeroPoint + 8)));\n \n // Pack two 4-bit values into one byte\n result[i >> 1] = (q1 << 4) | q2;\n }\n \n return result;\n}\n\n/**\n * Convert float32 to float16 (stored in Uint16Array)\n */\nfunction quantizeToFloat16(data: Float32Array): Uint16Array {\n const result = new Uint16Array(data.length);\n \n for (let i = 0; i < data.length; i++) {\n result[i] = float32ToFloat16(data[i] ?? 0);\n }\n \n return result;\n}\n\n/**\n * Convert a single float32 value to float16 bits\n */\nfunction float32ToFloat16(value: number): number {\n const float32View = new Float32Array(1);\n const int32View = new Int32Array(float32View.buffer);\n \n float32View[0] = value;\n const f = int32View[0]!;\n \n const sign = (f >> 16) & 0x8000;\n const exponent = ((f >> 23) & 0xff) - 127 + 15;\n const mantissa = f & 0x7fffff;\n \n if (exponent <= 0) {\n // Denormalized or zero\n if (exponent < -10) {\n return sign;\n }\n const m = (mantissa | 0x800000) >> (1 - exponent);\n return sign | (m >> 13);\n } else if (exponent >= 31) {\n // Overflow to infinity\n return sign | 0x7c00;\n }\n \n return sign | (exponent << 10) | (mantissa >> 13);\n}\n\n/**\n * Dequantize int8 data back to float32\n */\nexport function dequantizeInt8(\n data: Int8Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean = false,\n channelSize: number = data.length\n): Float32Array {\n const result = new Float32Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n result[idx] = ((data[idx] ?? 0) - zp) * s;\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n result[i] = ((data[i] ?? 0) - zp) * s;\n }\n }\n \n return result;\n}\n\n/**\n * Dequantize uint8 data back to float32\n */\nexport function dequantizeUint8(\n data: Uint8Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean = false,\n channelSize: number = data.length\n): Float32Array {\n const result = new Float32Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n result[idx] = ((data[idx] ?? 0) - zp) * s;\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n result[i] = ((data[i] ?? 0) - zp) * s;\n }\n }\n \n return result;\n}\n\n/**\n * Convert float16 bits back to float32\n */\nexport function float16ToFloat32(value: number): number {\n const sign = (value & 0x8000) >> 15;\n const exponent = (value & 0x7c00) >> 10;\n const mantissa = value & 0x03ff;\n \n if (exponent === 0) {\n if (mantissa === 0) {\n return sign === 0 ? 0 : -0;\n }\n // Denormalized\n return (sign === 0 ? 1 : -1) * Math.pow(2, -14) * (mantissa / 1024);\n } else if (exponent === 31) {\n if (mantissa === 0) {\n return sign === 0 ? Infinity : -Infinity;\n }\n return NaN;\n }\n \n return (sign === 0 ? 1 : -1) * Math.pow(2, exponent - 15) * (1 + mantissa / 1024);\n}\n\n/**\n * Dequantize float16 data back to float32\n */\nexport function dequantizeFloat16(data: Uint16Array): Float32Array {\n const result = new Float32Array(data.length);\n for (let i = 0; i < data.length; i++) {\n result[i] = float16ToFloat32(data[i] ?? 0);\n }\n return result;\n}\n\n// ============================================================================\n// Model Quantization\n// ============================================================================\n\n/**\n * Simple ONNX-like model representation for quantization\n */\ninterface ModelWeights {\n name: string;\n data: Float32Array;\n shape: number[];\n dtype: string;\n}\n\n/**\n * Quantized model format\n */\ninterface QuantizedModel {\n version: number;\n quantizationType: QuantizationType;\n originalSize: number;\n weights: Array<{\n name: string;\n data: ArrayBuffer;\n shape: number[];\n dtype: string;\n originalDtype: string;\n scale?: number | number[];\n zeroPoint?: number | number[];\n }>;\n}\n\n/**\n * Parse ONNX model to extract weights\n * Note: This is a simplified parser for demonstration\n */\nfunction parseModelWeights(modelData: ArrayBuffer): ModelWeights[] {\n // Check if it's an ONNX model by magic number\n // const view = new DataView(modelData); // Reserved for future ONNX header parsing\n const weights: ModelWeights[] = [];\n \n // Simple heuristic: look for float32 arrays in the buffer\n // In a real implementation, we'd use proper ONNX parsing\n const float32Array = new Float32Array(modelData);\n \n // Create a single weight tensor from the model data\n // This is a placeholder - real implementation would parse ONNX properly\n weights.push({\n name: 'model_weights',\n data: float32Array,\n shape: [float32Array.length],\n dtype: 'float32',\n });\n \n return weights;\n}\n\n/**\n * Serialize quantized model to ArrayBuffer\n */\nfunction serializeQuantizedModel(model: QuantizedModel): ArrayBuffer {\n // Create a simple binary format:\n // Header: version (4 bytes) + type (4 bytes) + originalSize (8 bytes) + numWeights (4 bytes)\n // For each weight: nameLen (4) + name + shapeLen (4) + shape + dtypeLen (4) + dtype + \n // origDtypeLen (4) + origDtype + hasScale (1) + scale + hasZP (1) + zp + dataLen (8) + data\n \n const encoder = new TextEncoder();\n \n // Calculate total size\n let totalSize = 20; // Header\n \n for (const weight of model.weights) {\n const nameBytes = encoder.encode(weight.name);\n const dtypeBytes = encoder.encode(weight.dtype);\n const origDtypeBytes = encoder.encode(weight.originalDtype);\n \n totalSize += 4 + nameBytes.length; // name\n totalSize += 4 + weight.shape.length * 4; // shape\n totalSize += 4 + dtypeBytes.length; // dtype\n totalSize += 4 + origDtypeBytes.length; // originalDtype\n totalSize += 1; // hasScale\n if (weight.scale !== undefined) {\n totalSize += Array.isArray(weight.scale) ? 4 + weight.scale.length * 4 : 4;\n }\n totalSize += 1; // hasZeroPoint\n if (weight.zeroPoint !== undefined) {\n totalSize += Array.isArray(weight.zeroPoint) ? 4 + weight.zeroPoint.length * 4 : 4;\n }\n totalSize += 8 + weight.data.byteLength; // data\n }\n \n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const uint8 = new Uint8Array(buffer);\n let offset = 0;\n \n // Write header\n view.setUint32(offset, model.version, true); offset += 4;\n view.setUint32(offset, ['int8', 'uint8', 'int4', 'float16', 'dynamic'].indexOf(model.quantizationType), true); offset += 4;\n // Write originalSize as two 32-bit integers (for 64-bit compatibility)\n view.setUint32(offset, model.originalSize & 0xFFFFFFFF, true); offset += 4;\n view.setUint32(offset, (model.originalSize / 0x100000000) >>> 0, true); offset += 4;\n view.setUint32(offset, model.weights.length, true); offset += 4;\n \n // Write weights\n for (const weight of model.weights) {\n const nameBytes = encoder.encode(weight.name);\n const dtypeBytes = encoder.encode(weight.dtype);\n const origDtypeBytes = encoder.encode(weight.originalDtype);\n \n // Name\n view.setUint32(offset, nameBytes.length, true); offset += 4;\n uint8.set(nameBytes, offset); offset += nameBytes.length;\n \n // Shape\n view.setUint32(offset, weight.shape.length, true); offset += 4;\n for (const dim of weight.shape) {\n view.setInt32(offset, dim, true); offset += 4;\n }\n \n // Dtype\n view.setUint32(offset, dtypeBytes.length, true); offset += 4;\n uint8.set(dtypeBytes, offset); offset += dtypeBytes.length;\n \n // Original dtype\n view.setUint32(offset, origDtypeBytes.length, true); offset += 4;\n uint8.set(origDtypeBytes, offset); offset += origDtypeBytes.length;\n \n // Scale\n if (weight.scale !== undefined) {\n view.setUint8(offset, 1); offset += 1;\n if (Array.isArray(weight.scale)) {\n view.setUint32(offset, weight.scale.length, true); offset += 4;\n for (const s of weight.scale) {\n view.setFloat32(offset, s, true); offset += 4;\n }\n } else {\n view.setUint32(offset, 1, true); offset += 4;\n view.setFloat32(offset, weight.scale, true); offset += 4;\n }\n } else {\n view.setUint8(offset, 0); offset += 1;\n }\n \n // Zero point\n if (weight.zeroPoint !== undefined) {\n view.setUint8(offset, 1); offset += 1;\n if (Array.isArray(weight.zeroPoint)) {\n view.setUint32(offset, weight.zeroPoint.length, true); offset += 4;\n for (const zp of weight.zeroPoint) {\n view.setInt32(offset, zp, true); offset += 4;\n }\n } else {\n view.setUint32(offset, 1, true); offset += 4;\n view.setInt32(offset, weight.zeroPoint, true); offset += 4;\n }\n } else {\n view.setUint8(offset, 0); offset += 1;\n }\n \n // Data\n const dataLow = weight.data.byteLength & 0xFFFFFFFF;\n const dataHigh = (weight.data.byteLength / 0x100000000) >>> 0;\n view.setUint32(offset, dataLow, true); offset += 4;\n view.setUint32(offset, dataHigh, true); offset += 4;\n uint8.set(new Uint8Array(weight.data), offset); offset += weight.data.byteLength;\n }\n \n return buffer;\n}\n\n/**\n * Quantize a model\n */\nexport async function quantizeModel(\n modelData: ArrayBuffer,\n options: QuantizationOptions\n): Promise<QuantizationResult> {\n const {\n type,\n skipPatterns = [],\n perChannel = false,\n symmetric = true,\n onProgress,\n minTensorSize = 100,\n } = options;\n \n const originalSize = modelData.byteLength;\n const layerStats: LayerQuantizationStats[] = [];\n let tensorsQuantized = 0;\n let tensorsSkipped = 0;\n \n // Parse model weights\n onProgress?.({ stage: 'analyzing', current: 0, total: 1, percent: 0 });\n const weights = parseModelWeights(modelData);\n \n const quantizedWeights: QuantizedModel['weights'] = [];\n let totalParams = 0;\n let quantizedParams = 0;\n const scales: number[] = [];\n \n // Quantize each weight tensor\n for (let i = 0; i < weights.length; i++) {\n const weight = weights[i]!;\n const percent = ((i + 1) / weights.length) * 100;\n \n onProgress?.({\n stage: 'quantizing',\n current: i + 1,\n total: weights.length,\n percent,\n layerName: weight.name,\n });\n \n totalParams += weight.data.length;\n \n // Check if should skip\n const shouldSkip = \n weight.data.length < minTensorSize ||\n skipPatterns.some(pattern => {\n if (typeof pattern === 'string') {\n return weight.name.includes(pattern);\n }\n return pattern.test(weight.name);\n });\n \n if (shouldSkip) {\n tensorsSkipped++;\n layerStats.push({\n name: weight.name,\n originalDtype: weight.dtype,\n quantizedDtype: weight.dtype,\n originalSize: weight.data.byteLength,\n quantizedSize: weight.data.byteLength,\n scale: 1,\n zeroPoint: 0,\n minValue: Math.min(...weight.data),\n maxValue: Math.max(...weight.data),\n skipped: true,\n skipReason: weight.data.length < minTensorSize \n ? 'Tensor too small' \n : 'Matched skip pattern',\n });\n \n quantizedWeights.push({\n name: weight.name,\n data: weight.data.buffer.slice(0) as ArrayBuffer,\n shape: weight.shape,\n dtype: weight.dtype,\n originalDtype: weight.dtype,\n });\n continue;\n }\n \n // Calculate quantization parameters\n const bits = type === 'int4' ? 4 : 8;\n const params = calculateQuantParams(\n weight.data,\n bits,\n symmetric,\n perChannel,\n 0,\n weight.shape\n );\n \n // Quantize data\n let quantizedData: ArrayBuffer;\n let quantizedDtype: string;\n \n switch (type) {\n case 'int8':\n const int8Data = quantizeToInt8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = int8Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int8';\n break;\n \n case 'uint8':\n const uint8Data = quantizeToUint8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = uint8Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'uint8';\n break;\n \n case 'int4':\n const int4Data = quantizeToInt4(\n weight.data,\n params.scale as number,\n params.zeroPoint as number\n );\n quantizedData = int4Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int4';\n break;\n \n case 'float16':\n const fp16Data = quantizeToFloat16(weight.data);\n quantizedData = fp16Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'float16';\n break;\n \n case 'dynamic':\n default:\n // Dynamic quantization: use int8 for weights\n const dynData = quantizeToInt8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = dynData.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int8';\n break;\n }\n \n tensorsQuantized++;\n quantizedParams += weight.data.length;\n \n const scaleValue = params.scale instanceof Float32Array \n ? Array.from(params.scale)\n : params.scale;\n const zpValue = params.zeroPoint instanceof Int32Array\n ? Array.from(params.zeroPoint)\n : params.zeroPoint;\n \n if (typeof scaleValue === 'number') {\n scales.push(scaleValue);\n } else {\n scales.push(...scaleValue);\n }\n \n layerStats.push({\n name: weight.name,\n originalDtype: weight.dtype,\n quantizedDtype,\n originalSize: weight.data.byteLength,\n quantizedSize: quantizedData.byteLength,\n scale: scaleValue,\n zeroPoint: zpValue,\n minValue: params.min,\n maxValue: params.max,\n skipped: false,\n });\n \n quantizedWeights.push({\n name: weight.name,\n data: quantizedData,\n shape: weight.shape,\n dtype: quantizedDtype,\n originalDtype: weight.dtype,\n scale: scaleValue,\n zeroPoint: zpValue,\n });\n }\n \n // Pack into final format\n onProgress?.({ stage: 'packing', current: 0, total: 1, percent: 0 });\n \n const quantizedModel: QuantizedModel = {\n version: 1,\n quantizationType: type,\n originalSize,\n weights: quantizedWeights,\n };\n \n const quantizedData = serializeQuantizedModel(quantizedModel);\n \n onProgress?.({ stage: 'complete', current: 1, total: 1, percent: 100 });\n \n // Calculate statistics\n const avgScale = scales.length > 0 \n ? scales.reduce((a, b) => a + b, 0) / scales.length \n : 1;\n const minScale = scales.length > 0 ? Math.min(...scales) : 1;\n const maxScale = scales.length > 0 ? Math.max(...scales) : 1;\n \n // Estimate quantization error (very rough approximation)\n const bitsReduction = type === 'int4' ? 8 : type === 'float16' ? 2 : 4;\n const errorEstimate = avgScale / bitsReduction;\n \n return {\n data: quantizedData,\n originalSize,\n quantizedSize: quantizedData.byteLength,\n compressionRatio: originalSize / quantizedData.byteLength,\n tensorsQuantized,\n tensorsSkipped,\n layerStats,\n stats: {\n totalParameters: totalParams,\n quantizedParameters: quantizedParams,\n averageScale: avgScale,\n minScale,\n maxScale,\n errorEstimate,\n },\n };\n}\n\n// ============================================================================\n// Tensor Quantization (for individual tensors)\n// ============================================================================\n\n/**\n * Quantize a single EdgeFlowTensor\n */\nexport function quantizeTensor(\n tensor: EdgeFlowTensor,\n type: QuantizationType,\n options: { symmetric?: boolean; perChannel?: boolean } = {}\n): {\n tensor: EdgeFlowTensor;\n scale: number | number[];\n zeroPoint: number | number[];\n} {\n const { symmetric = true, perChannel = false } = options;\n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n \n const bits = type === 'int4' ? 4 : 8;\n const params = calculateQuantParams(\n data,\n bits,\n symmetric,\n perChannel,\n 0,\n shape\n );\n \n let quantizedData: Int8Array | Uint8Array | Uint16Array;\n let dtype: DataType;\n \n switch (type) {\n case 'int8':\n quantizedData = quantizeToInt8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32'; // Store as int32 since we don't have int8 dtype\n break;\n \n case 'uint8':\n quantizedData = quantizeToUint8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32';\n break;\n \n case 'float16':\n quantizedData = quantizeToFloat16(data);\n dtype = 'float32'; // Will be stored differently\n break;\n \n default:\n quantizedData = quantizeToInt8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32';\n }\n \n const scaleValue = params.scale instanceof Float32Array\n ? Array.from(params.scale)\n : params.scale;\n const zpValue = params.zeroPoint instanceof Int32Array\n ? Array.from(params.zeroPoint)\n : params.zeroPoint;\n \n return {\n tensor: new EdgeFlowTensor(Array.from(quantizedData), shape, dtype),\n scale: scaleValue,\n zeroPoint: zpValue,\n };\n}\n\n/**\n * Dequantize a tensor back to float32\n */\nexport function dequantizeTensor(\n tensor: EdgeFlowTensor,\n scale: number | number[],\n zeroPoint: number | number[],\n type: QuantizationType\n): EdgeFlowTensor {\n const data = tensor.toArray();\n const shape = tensor.shape as number[];\n \n let dequantizedData: Float32Array;\n \n const scaleArr = Array.isArray(scale) ? new Float32Array(scale) : scale;\n const zpArr = Array.isArray(zeroPoint) ? new Int32Array(zeroPoint) : zeroPoint;\n const perChannel = Array.isArray(scale);\n \n switch (type) {\n case 'int8':\n dequantizedData = dequantizeInt8(\n new Int8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n break;\n \n case 'uint8':\n dequantizedData = dequantizeUint8(\n new Uint8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n break;\n \n case 'float16':\n dequantizedData = dequantizeFloat16(new Uint16Array(data.map(Number)));\n break;\n \n default:\n dequantizedData = dequantizeInt8(\n new Int8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n }\n \n return new EdgeFlowTensor(Array.from(dequantizedData), shape, 'float32');\n}\n\n// ============================================================================\n// Pruning\n// ============================================================================\n\n/**\n * Pruning options\n */\nexport interface PruningOptions {\n /** Pruning ratio (0-1, default: 0.5 = 50% sparsity) */\n ratio?: number;\n \n /** Pruning method */\n method?: 'magnitude' | 'random' | 'structured';\n \n /** For structured pruning: dimension to prune along */\n dim?: number;\n \n /** Minimum absolute value to keep */\n threshold?: number;\n \n /** Progress callback */\n onProgress?: (progress: { current: number; total: number; percent: number }) => void;\n}\n\n/**\n * Pruning result\n */\nexport interface PruningResult {\n /** Pruned model data */\n data: ArrayBuffer;\n \n /** Original size */\n originalSize: number;\n \n /** Pruned size (sparse representation) */\n prunedSize: number;\n \n /** Sparsity ratio achieved */\n sparsity: number;\n \n /** Number of parameters pruned */\n parametersPruned: number;\n \n /** Total parameters */\n totalParameters: number;\n}\n\n/**\n * Prune a tensor using magnitude-based pruning\n */\nexport function pruneTensor(\n tensor: EdgeFlowTensor,\n options: PruningOptions = {}\n): {\n tensor: EdgeFlowTensor;\n mask: EdgeFlowTensor;\n sparsity: number;\n} {\n const { ratio = 0.5, method = 'magnitude', threshold } = options;\n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n \n const mask = new Float32Array(data.length);\n const prunedData = new Float32Array(data.length);\n let prunedCount = 0;\n \n if (method === 'magnitude') {\n // Get threshold based on ratio\n const absValues = Array.from(data).map(Math.abs).sort((a, b) => a - b);\n const thresholdIndex = Math.floor(absValues.length * ratio);\n const computedThreshold = threshold ?? (absValues[thresholdIndex] ?? 0);\n \n for (let i = 0; i < data.length; i++) {\n if (Math.abs(data[i] ?? 0) > computedThreshold) {\n mask[i] = 1;\n prunedData[i] = data[i] ?? 0;\n } else {\n mask[i] = 0;\n prunedData[i] = 0;\n prunedCount++;\n }\n }\n } else if (method === 'random') {\n for (let i = 0; i < data.length; i++) {\n if (Math.random() > ratio) {\n mask[i] = 1;\n prunedData[i] = data[i] ?? 0;\n } else {\n mask[i] = 0;\n prunedData[i] = 0;\n prunedCount++;\n }\n }\n }\n \n return {\n tensor: new EdgeFlowTensor(Array.from(prunedData), shape, 'float32'),\n mask: new EdgeFlowTensor(Array.from(mask), shape, 'float32'),\n sparsity: prunedCount / data.length,\n };\n}\n\n/**\n * Prune a model\n */\nexport async function pruneModel(\n modelData: ArrayBuffer,\n options: PruningOptions = {}\n): Promise<PruningResult> {\n const { onProgress } = options;\n \n onProgress?.({ current: 0, total: 1, percent: 0 });\n \n // This is a simplified implementation\n // Real implementation would parse the model properly\n const weights = parseModelWeights(modelData);\n let totalParams = 0;\n let prunedParams = 0;\n \n for (const weight of weights) {\n totalParams += weight.data.length;\n \n const tensor = new EdgeFlowTensor(\n Array.from(weight.data),\n weight.shape,\n 'float32'\n );\n \n const { sparsity } = pruneTensor(tensor, options);\n prunedParams += Math.floor(weight.data.length * sparsity);\n }\n \n onProgress?.({ current: 1, total: 1, percent: 100 });\n \n return {\n data: modelData, // In a real implementation, we'd create a sparse format\n originalSize: modelData.byteLength,\n prunedSize: modelData.byteLength, // Would be smaller with sparse format\n sparsity: prunedParams / totalParams,\n parametersPruned: prunedParams,\n totalParameters: totalParams,\n };\n}\n\n// ============================================================================\n// Model Analysis\n// ============================================================================\n\n/**\n * Model analysis result\n */\nexport interface ModelAnalysis {\n /** Total model size in bytes */\n totalSize: number;\n \n /** Number of tensors */\n tensorCount: number;\n \n /** Total number of parameters */\n totalParameters: number;\n \n /** Parameter breakdown by dtype */\n dtypeBreakdown: Record<string, { count: number; size: number }>;\n \n /** Largest tensors */\n largestTensors: Array<{ name: string; size: number; shape: number[] }>;\n \n /** Estimated memory usage at runtime */\n estimatedMemory: number;\n \n /** Recommended quantization type */\n recommendedQuantization: QuantizationType;\n \n /** Estimated size after quantization */\n estimatedQuantizedSizes: Record<QuantizationType, number>;\n}\n\n/**\n * Analyze a model\n */\nexport async function analyzeModel(modelData: ArrayBuffer): Promise<ModelAnalysis> {\n const weights = parseModelWeights(modelData);\n const totalSize = modelData.byteLength;\n \n const dtypeBreakdown: Record<string, { count: number; size: number }> = {};\n let totalParams = 0;\n \n const tensorInfos: Array<{ name: string; size: number; shape: number[] }> = [];\n \n for (const weight of weights) {\n totalParams += weight.data.length;\n \n const bytesPerElement = weight.dtype === 'float32' ? 4 \n : weight.dtype === 'float16' ? 2 \n : weight.dtype === 'int8' ? 1 \n : 4;\n const size = weight.data.length * bytesPerElement;\n \n if (!dtypeBreakdown[weight.dtype]) {\n dtypeBreakdown[weight.dtype] = { count: 0, size: 0 };\n }\n dtypeBreakdown[weight.dtype]!.count++;\n dtypeBreakdown[weight.dtype]!.size += size;\n \n tensorInfos.push({\n name: weight.name,\n size,\n shape: weight.shape,\n });\n }\n \n // Sort by size and get top 10\n tensorInfos.sort((a, b) => b.size - a.size);\n const largestTensors = tensorInfos.slice(0, 10);\n \n // Estimate quantized sizes\n const estimatedQuantizedSizes: Record<QuantizationType, number> = {\n int8: Math.ceil(totalSize / 4),\n uint8: Math.ceil(totalSize / 4),\n int4: Math.ceil(totalSize / 8),\n float16: Math.ceil(totalSize / 2),\n dynamic: Math.ceil(totalSize / 4),\n };\n \n // Recommend quantization based on model size\n let recommendedQuantization: QuantizationType = 'dynamic';\n if (totalSize > 500 * 1024 * 1024) {\n recommendedQuantization = 'int4';\n } else if (totalSize > 100 * 1024 * 1024) {\n recommendedQuantization = 'int8';\n } else if (totalSize > 50 * 1024 * 1024) {\n recommendedQuantization = 'float16';\n }\n \n return {\n totalSize,\n tensorCount: weights.length,\n totalParameters: totalParams,\n dtypeBreakdown,\n largestTensors,\n estimatedMemory: totalParams * 4, // Assuming float32 at runtime\n recommendedQuantization,\n estimatedQuantizedSizes,\n };\n}\n\n// ============================================================================\n// Export Model\n// ============================================================================\n\n/**\n * Export format\n */\nexport type ExportFormat = 'onnx' | 'tflite' | 'edgeflow';\n\n/**\n * Export options\n */\nexport interface ExportOptions {\n format: ExportFormat;\n optimize?: boolean;\n quantize?: QuantizationType;\n}\n\n/**\n * Export a model to different formats\n * Note: This is a placeholder - real implementation would require proper format conversion\n */\nexport async function exportModel(\n modelData: ArrayBuffer,\n options: ExportOptions\n): Promise<ArrayBuffer> {\n const { format, quantize } = options;\n \n // Apply quantization if requested\n let data = modelData;\n if (quantize) {\n const result = await quantizeModel(modelData, { type: quantize });\n data = result.data;\n }\n \n // Format conversion would happen here\n // For now, we just return the (possibly quantized) data\n switch (format) {\n case 'edgeflow':\n return data;\n case 'onnx':\n // Would convert to ONNX format\n return data;\n case 'tflite':\n // Would convert to TFLite format\n return data;\n default:\n return data;\n }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModel,\n exportModel,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n};\n", "/**\n * edgeFlow.js - Visual Debugging Tools\n * \n * In-browser debugging and visualization utilities for ML models.\n */\n\nimport { EdgeFlowTensor } from '../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Debugger configuration\n */\nexport interface DebuggerConfig {\n /** Enable logging */\n logging?: boolean;\n \n /** Log level */\n logLevel?: 'debug' | 'info' | 'warn' | 'error';\n \n /** Enable tensor inspection */\n inspectTensors?: boolean;\n \n /** Maximum values to display per tensor */\n maxDisplayValues?: number;\n \n /** Enable performance tracking */\n trackPerformance?: boolean;\n \n /** Custom logger function */\n logger?: (level: string, message: string, data?: unknown) => void;\n}\n\n/**\n * Tensor inspection result\n */\nexport interface TensorInspection {\n name: string;\n shape: number[];\n dtype: string;\n size: number;\n memoryBytes: number;\n stats: TensorStats;\n sample: number[];\n histogram?: HistogramData;\n}\n\n/**\n * Tensor statistics\n */\nexport interface TensorStats {\n min: number;\n max: number;\n mean: number;\n std: number;\n zeros: number;\n nans: number;\n infinities: number;\n sparsity: number;\n}\n\n/**\n * Histogram data\n */\nexport interface HistogramData {\n bins: number[];\n counts: number[];\n binEdges: number[];\n}\n\n/**\n * Inference trace\n */\nexport interface InferenceTrace {\n id: string;\n modelId: string;\n timestamp: number;\n inputs: TensorInspection[];\n outputs: TensorInspection[];\n duration: number;\n memoryUsed: number;\n operations: OperationTrace[];\n}\n\n/**\n * Operation trace\n */\nexport interface OperationTrace {\n name: string;\n type: string;\n duration: number;\n inputShapes: number[][];\n outputShapes: number[][];\n attributes?: Record<string, unknown>;\n}\n\n/**\n * Debug event\n */\nexport interface DebugEvent {\n type: 'tensor' | 'inference' | 'error' | 'warning' | 'info' | 'performance';\n timestamp: number;\n data: unknown;\n message: string;\n}\n\n/**\n * Performance metrics\n */\nexport interface PerformanceMetrics {\n inferenceCount: number;\n totalInferenceTime: number;\n averageInferenceTime: number;\n minInferenceTime: number;\n maxInferenceTime: number;\n peakMemoryUsage: number;\n currentMemoryUsage: number;\n tensorAllocations: number;\n tensorDeallocations: number;\n}\n\n// ============================================================================\n// Tensor Inspection\n// ============================================================================\n\n/**\n * Calculate tensor statistics\n */\nfunction calculateTensorStats(data: Float32Array | number[]): TensorStats {\n const arr = data instanceof Float32Array ? data : new Float32Array(data);\n \n let min = Infinity;\n let max = -Infinity;\n let sum = 0;\n let zeros = 0;\n let nans = 0;\n let infinities = 0;\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n \n if (isNaN(val)) {\n nans++;\n continue;\n }\n \n if (!isFinite(val)) {\n infinities++;\n continue;\n }\n \n min = Math.min(min, val);\n max = Math.max(max, val);\n sum += val;\n \n if (val === 0) zeros++;\n }\n \n const validCount = arr.length - nans - infinities;\n const mean = validCount > 0 ? sum / validCount : 0;\n \n // Calculate std\n let varianceSum = 0;\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n varianceSum += Math.pow(val - mean, 2);\n }\n }\n const std = validCount > 0 ? Math.sqrt(varianceSum / validCount) : 0;\n \n return {\n min: min === Infinity ? 0 : min,\n max: max === -Infinity ? 0 : max,\n mean,\n std,\n zeros,\n nans,\n infinities,\n sparsity: zeros / arr.length,\n };\n}\n\n/**\n * Create histogram from data\n */\nfunction createHistogram(data: Float32Array | number[], bins: number = 50): HistogramData {\n const arr = data instanceof Float32Array ? data : new Float32Array(data);\n \n // Find min/max (excluding NaN/Inf)\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n \n if (min === Infinity || max === -Infinity || min === max) {\n return { bins: [min || 0], counts: [arr.length], binEdges: [min || 0, max || 0] };\n }\n \n const binWidth = (max - min) / bins;\n const counts = new Array(bins).fill(0);\n const binEdges = new Array(bins + 1);\n \n for (let i = 0; i <= bins; i++) {\n binEdges[i] = min + i * binWidth;\n }\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n const binIndex = Math.min(Math.floor((val - min) / binWidth), bins - 1);\n counts[binIndex]++;\n }\n }\n \n return {\n bins: binEdges.slice(0, -1).map((e, i) => (e + binEdges[i + 1]!) / 2),\n counts,\n binEdges,\n };\n}\n\n/**\n * Inspect a tensor\n */\nexport function inspectTensor(\n tensor: EdgeFlowTensor,\n name: string = 'tensor',\n options: { histogram?: boolean; maxSample?: number } = {}\n): TensorInspection {\n const { histogram = true, maxSample = 10 } = options;\n \n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n const size = tensor.size;\n \n // Get sample of values\n const sampleIndices = [];\n const step = Math.max(1, Math.floor(size / maxSample));\n for (let i = 0; i < size && sampleIndices.length < maxSample; i += step) {\n sampleIndices.push(i);\n }\n const sample = sampleIndices.map(i => data[i] ?? 0);\n \n // Calculate memory (assuming float32)\n const bytesPerElement = tensor.dtype === 'float32' ? 4 \n : tensor.dtype === 'int32' ? 4 \n : tensor.dtype === 'int64' ? 8 \n : 4;\n const memoryBytes = size * bytesPerElement;\n \n return {\n name,\n shape,\n dtype: tensor.dtype,\n size,\n memoryBytes,\n stats: calculateTensorStats(data),\n sample,\n histogram: histogram ? createHistogram(data) : undefined,\n };\n}\n\n/**\n * Format tensor inspection for display\n */\nexport function formatTensorInspection(inspection: TensorInspection): string {\n const { name, shape, dtype, size, memoryBytes, stats, sample } = inspection;\n \n const lines = [\n `\u250C\u2500 Tensor: ${name} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,\n `\u2502 Shape: [${shape.join(', ')}]`,\n `\u2502 Dtype: ${dtype}`,\n `\u2502 Size: ${size.toLocaleString()} elements`,\n `\u2502 Memory: ${formatBytes(memoryBytes)}`,\n `\u251C\u2500 Statistics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,\n `\u2502 Min: ${stats.min.toFixed(6)}`,\n `\u2502 Max: ${stats.max.toFixed(6)}`,\n `\u2502 Mean: ${stats.mean.toFixed(6)}`,\n `\u2502 Std: ${stats.std.toFixed(6)}`,\n `\u2502 Sparsity: ${(stats.sparsity * 100).toFixed(2)}%`,\n ];\n \n if (stats.nans > 0) {\n lines.push(`\u2502 \u26A0\uFE0F NaN values: ${stats.nans}`);\n }\n if (stats.infinities > 0) {\n lines.push(`\u2502 \u26A0\uFE0F Infinity values: ${stats.infinities}`);\n }\n \n lines.push(`\u251C\u2500 Sample Values \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);\n lines.push(`\u2502 [${sample.map(v => v.toFixed(4)).join(', ')}]`);\n lines.push(`\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);\n \n return lines.join('\\n');\n}\n\n/**\n * Format bytes to human readable\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n// ============================================================================\n// Visual Debugger Class\n// ============================================================================\n\n/**\n * Visual debugger for edgeFlow.js\n */\nexport class EdgeFlowDebugger {\n private config: Required<DebuggerConfig>;\n private events: DebugEvent[] = [];\n private traces: InferenceTrace[] = [];\n private performanceMetrics: PerformanceMetrics;\n private listeners: Map<string, Array<(event: DebugEvent) => void>> = new Map();\n private isEnabled: boolean = true;\n \n constructor(config: DebuggerConfig = {}) {\n this.config = {\n logging: config.logging ?? true,\n logLevel: config.logLevel ?? 'info',\n inspectTensors: config.inspectTensors ?? true,\n maxDisplayValues: config.maxDisplayValues ?? 10,\n trackPerformance: config.trackPerformance ?? true,\n logger: config.logger ?? this.defaultLogger.bind(this),\n };\n \n this.performanceMetrics = {\n inferenceCount: 0,\n totalInferenceTime: 0,\n averageInferenceTime: 0,\n minInferenceTime: Infinity,\n maxInferenceTime: 0,\n peakMemoryUsage: 0,\n currentMemoryUsage: 0,\n tensorAllocations: 0,\n tensorDeallocations: 0,\n };\n }\n \n /**\n * Default logger\n */\n private defaultLogger(level: string, message: string, data?: unknown): void {\n const timestamp = new Date().toISOString();\n const prefix = `[edgeFlow.js ${timestamp}] [${level.toUpperCase()}]`;\n \n switch (level) {\n case 'debug':\n console.debug(prefix, message, data ?? '');\n break;\n case 'info':\n console.info(prefix, message, data ?? '');\n break;\n case 'warn':\n console.warn(prefix, message, data ?? '');\n break;\n case 'error':\n console.error(prefix, message, data ?? '');\n break;\n default:\n console.log(prefix, message, data ?? '');\n }\n }\n \n /**\n * Log a message\n */\n log(level: string, message: string, data?: unknown): void {\n if (!this.isEnabled || !this.config.logging) return;\n \n const levels = ['debug', 'info', 'warn', 'error'];\n const configLevel = levels.indexOf(this.config.logLevel);\n const msgLevel = levels.indexOf(level);\n \n if (msgLevel >= configLevel) {\n this.config.logger(level, message, data);\n }\n }\n \n /**\n * Add debug event\n */\n private addEvent(event: DebugEvent): void {\n this.events.push(event);\n \n // Notify listeners\n const listeners = this.listeners.get(event.type) ?? [];\n for (const listener of listeners) {\n listener(event);\n }\n \n // Keep only last 1000 events\n if (this.events.length > 1000) {\n this.events = this.events.slice(-1000);\n }\n }\n \n /**\n * Enable debugger\n */\n enable(): void {\n this.isEnabled = true;\n this.log('info', 'Debugger enabled');\n }\n \n /**\n * Disable debugger\n */\n disable(): void {\n this.isEnabled = false;\n }\n \n /**\n * Subscribe to events\n */\n on(type: string, callback: (event: DebugEvent) => void): () => void {\n const listeners = this.listeners.get(type) ?? [];\n listeners.push(callback);\n this.listeners.set(type, listeners);\n \n return () => {\n const idx = listeners.indexOf(callback);\n if (idx !== -1) listeners.splice(idx, 1);\n };\n }\n \n /**\n * Inspect and log a tensor\n */\n inspectTensor(tensor: EdgeFlowTensor, name: string = 'tensor'): TensorInspection {\n const inspection = inspectTensor(tensor, name, {\n histogram: true,\n maxSample: this.config.maxDisplayValues,\n });\n \n if (this.config.inspectTensors) {\n this.log('debug', `Tensor: ${name}`, inspection);\n \n this.addEvent({\n type: 'tensor',\n timestamp: Date.now(),\n message: `Inspected tensor: ${name}`,\n data: inspection,\n });\n \n // Check for issues\n if (inspection.stats.nans > 0) {\n this.log('warn', `Tensor \"${name}\" contains ${inspection.stats.nans} NaN values`);\n }\n if (inspection.stats.infinities > 0) {\n this.log('warn', `Tensor \"${name}\" contains ${inspection.stats.infinities} Infinity values`);\n }\n }\n \n return inspection;\n }\n \n /**\n * Start tracing an inference\n */\n startTrace(modelId: string): string {\n const id = `trace_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n \n const trace: InferenceTrace = {\n id,\n modelId,\n timestamp: Date.now(),\n inputs: [],\n outputs: [],\n duration: 0,\n memoryUsed: 0,\n operations: [],\n };\n \n this.traces.push(trace);\n \n this.log('debug', `Started trace: ${id} for model: ${modelId}`);\n \n return id;\n }\n \n /**\n * Add input to trace\n */\n traceInput(traceId: string, tensor: EdgeFlowTensor, name: string): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.inputs.push(inspectTensor(tensor, name));\n }\n \n /**\n * Add output to trace\n */\n traceOutput(traceId: string, tensor: EdgeFlowTensor, name: string): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.outputs.push(inspectTensor(tensor, name));\n }\n \n /**\n * Add operation to trace\n */\n traceOperation(traceId: string, operation: OperationTrace): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.operations.push(operation);\n }\n \n /**\n * End trace\n */\n endTrace(traceId: string): InferenceTrace | undefined {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.duration = Date.now() - trace.timestamp;\n \n // Update performance metrics\n this.performanceMetrics.inferenceCount++;\n this.performanceMetrics.totalInferenceTime += trace.duration;\n this.performanceMetrics.averageInferenceTime = \n this.performanceMetrics.totalInferenceTime / this.performanceMetrics.inferenceCount;\n this.performanceMetrics.minInferenceTime = \n Math.min(this.performanceMetrics.minInferenceTime, trace.duration);\n this.performanceMetrics.maxInferenceTime = \n Math.max(this.performanceMetrics.maxInferenceTime, trace.duration);\n \n this.log('info', `Trace completed: ${traceId}`, {\n duration: `${trace.duration}ms`,\n inputs: trace.inputs.length,\n outputs: trace.outputs.length,\n operations: trace.operations.length,\n });\n \n this.addEvent({\n type: 'inference',\n timestamp: Date.now(),\n message: `Inference completed in ${trace.duration}ms`,\n data: trace,\n });\n \n return trace;\n }\n \n /**\n * Record tensor allocation\n */\n recordAllocation(tensor: EdgeFlowTensor): void {\n if (!this.config.trackPerformance) return;\n \n this.performanceMetrics.tensorAllocations++;\n const memory = tensor.size * 4; // Assume float32\n this.performanceMetrics.currentMemoryUsage += memory;\n this.performanceMetrics.peakMemoryUsage = Math.max(\n this.performanceMetrics.peakMemoryUsage,\n this.performanceMetrics.currentMemoryUsage\n );\n }\n \n /**\n * Record tensor deallocation\n */\n recordDeallocation(tensor: EdgeFlowTensor): void {\n if (!this.config.trackPerformance) return;\n \n this.performanceMetrics.tensorDeallocations++;\n const memory = tensor.size * 4;\n this.performanceMetrics.currentMemoryUsage -= memory;\n }\n \n /**\n * Get performance metrics\n */\n getPerformanceMetrics(): PerformanceMetrics {\n return { ...this.performanceMetrics };\n }\n \n /**\n * Get all events\n */\n getEvents(): DebugEvent[] {\n return [...this.events];\n }\n \n /**\n * Get all traces\n */\n getTraces(): InferenceTrace[] {\n return [...this.traces];\n }\n \n /**\n * Get trace by ID\n */\n getTrace(traceId: string): InferenceTrace | undefined {\n return this.traces.find(t => t.id === traceId);\n }\n \n /**\n * Clear all data\n */\n clear(): void {\n this.events = [];\n this.traces = [];\n this.performanceMetrics = {\n inferenceCount: 0,\n totalInferenceTime: 0,\n averageInferenceTime: 0,\n minInferenceTime: Infinity,\n maxInferenceTime: 0,\n peakMemoryUsage: 0,\n currentMemoryUsage: 0,\n tensorAllocations: 0,\n tensorDeallocations: 0,\n };\n }\n \n /**\n * Export debug data\n */\n export(): {\n events: DebugEvent[];\n traces: InferenceTrace[];\n metrics: PerformanceMetrics;\n timestamp: number;\n } {\n return {\n events: this.getEvents(),\n traces: this.getTraces(),\n metrics: this.getPerformanceMetrics(),\n timestamp: Date.now(),\n };\n }\n \n /**\n * Generate summary report\n */\n generateReport(): string {\n const metrics = this.getPerformanceMetrics();\n const traces = this.getTraces();\n \n const lines = [\n '\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557',\n '\u2551 edgeFlow.js Debug Report \u2551',\n '\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563',\n '\u2551 Performance Metrics \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n `\u2551 Total Inferences: ${metrics.inferenceCount.toString().padStart(10)} \u2551`,\n `\u2551 Average Time: ${metrics.averageInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Min Time: ${(metrics.minInferenceTime === Infinity ? 0 : metrics.minInferenceTime).toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Max Time: ${metrics.maxInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Peak Memory: ${formatBytes(metrics.peakMemoryUsage).padStart(10)} \u2551`,\n `\u2551 Current Memory: ${formatBytes(metrics.currentMemoryUsage).padStart(10)} \u2551`,\n `\u2551 Tensor Allocations: ${metrics.tensorAllocations.toString().padStart(10)} \u2551`,\n `\u2551 Tensor Deallocations: ${metrics.tensorDeallocations.toString().padStart(10)} \u2551`,\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Recent Traces \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n ];\n \n const recentTraces = traces.slice(-5);\n for (const trace of recentTraces) {\n lines.push(`\u2551 ${trace.id.slice(0, 20).padEnd(20)} | ${trace.duration.toFixed(2).padStart(8)}ms | ${trace.modelId.slice(0, 20).padEnd(20)} \u2551`);\n }\n \n if (recentTraces.length === 0) {\n lines.push('\u2551 No traces recorded \u2551');\n }\n \n lines.push('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D');\n \n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// Global Debugger Instance\n// ============================================================================\n\nlet globalDebugger: EdgeFlowDebugger | null = null;\n\n/**\n * Get or create the global debugger instance\n */\nexport function getDebugger(config?: DebuggerConfig): EdgeFlowDebugger {\n if (!globalDebugger || config) {\n globalDebugger = new EdgeFlowDebugger(config);\n }\n return globalDebugger;\n}\n\n/**\n * Enable debugging\n */\nexport function enableDebugging(config?: DebuggerConfig): EdgeFlowDebugger {\n const debugger_ = getDebugger(config);\n debugger_.enable();\n return debugger_;\n}\n\n/**\n * Disable debugging\n */\nexport function disableDebugging(): void {\n globalDebugger?.disable();\n}\n\n// ============================================================================\n// Visualization Helpers\n// ============================================================================\n\n/**\n * Create ASCII histogram\n */\nexport function createAsciiHistogram(histogram: HistogramData, width: number = 50, height: number = 10): string {\n const { counts, binEdges } = histogram;\n const maxCount = Math.max(...counts);\n \n if (maxCount === 0) return 'No data to display';\n \n const lines: string[] = [];\n \n // Scale counts to height\n const scaled = counts.map(c => Math.round((c / maxCount) * height));\n \n // Create rows\n for (let row = height; row > 0; row--) {\n let line = row === height ? `${maxCount.toString().padStart(6)} \u2502` : ' \u2502';\n \n for (let col = 0; col < width && col < scaled.length; col++) {\n line += (scaled[col] ?? 0) >= row ? '\u2588' : ' ';\n }\n \n lines.push(line);\n }\n \n // X axis\n lines.push(' \u2514' + '\u2500'.repeat(Math.min(width, scaled.length)));\n \n // Labels\n const minLabel = (binEdges[0] ?? 0).toFixed(2);\n const maxLabel = (binEdges[binEdges.length - 1] ?? 0).toFixed(2);\n lines.push(` ${minLabel}${' '.repeat(Math.max(0, Math.min(width, scaled.length) - minLabel.length - maxLabel.length))}${maxLabel}`);\n \n return lines.join('\\n');\n}\n\n/**\n * Create tensor heatmap (for 2D tensors)\n */\nexport function createTensorHeatmap(tensor: EdgeFlowTensor, width: number = 40): string {\n const shape = tensor.shape as number[];\n \n if (shape.length !== 2) {\n return 'Heatmap only supports 2D tensors';\n }\n \n const [rows, cols] = shape;\n if (rows === undefined || cols === undefined) {\n return 'Invalid tensor shape';\n }\n \n const data = tensor.toFloat32Array();\n \n // Find min/max\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n \n const range = max - min;\n const chars = [' ', '\u2591', '\u2592', '\u2593', '\u2588'];\n \n const lines: string[] = [];\n const scaleX = Math.max(1, Math.ceil(cols / width));\n const displayCols = Math.min(cols, width);\n \n for (let r = 0; r < rows; r++) {\n let line = '';\n for (let c = 0; c < displayCols; c++) {\n const idx = r * cols + c * scaleX;\n const val = data[idx] ?? 0;\n const normalized = range > 0 ? (val - min) / range : 0;\n const charIdx = Math.floor(normalized * (chars.length - 1));\n line += chars[charIdx];\n }\n lines.push(line);\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Create model architecture visualization\n */\nexport function visualizeModelArchitecture(\n layers: Array<{ name: string; type: string; inputShape: number[]; outputShape: number[] }>\n): string {\n const lines: string[] = [];\n \n lines.push('\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510');\n lines.push('\u2502 Model Architecture \u2502');\n lines.push('\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524');\n \n for (let i = 0; i < layers.length; i++) {\n const layer = layers[i]!;\n const inputStr = `[${layer.inputShape.join('\u00D7')}]`;\n const outputStr = `[${layer.outputShape.join('\u00D7')}]`;\n \n lines.push(`\u2502 ${(i + 1).toString().padStart(2)}. ${layer.name.padEnd(20)} \u2502 ${layer.type.padEnd(15)} \u2502`);\n lines.push(`\u2502 ${inputStr.padEnd(15)} \u2192 ${outputStr.padEnd(15)} \u2502`);\n \n if (i < layers.length - 1) {\n lines.push('\u2502 \u2193 \u2502');\n }\n }\n \n lines.push('\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518');\n \n return lines.join('\\n');\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n};\n", "/**\n * edgeFlow.js - Performance Monitoring Dashboard\n * \n * Real-time performance monitoring and metrics visualization.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Monitor configuration\n */\nexport interface MonitorConfig {\n /** Enable monitoring (default: true) */\n enabled?: boolean;\n \n /** Sampling interval in ms (default: 1000) */\n sampleInterval?: number;\n \n /** History size (number of samples to keep) */\n historySize?: number;\n \n /** Enable memory monitoring (default: true) */\n monitorMemory?: boolean;\n \n /** Enable FPS monitoring (default: true) */\n monitorFPS?: boolean;\n \n /** Custom metric collectors */\n collectors?: Array<() => Record<string, number>>;\n}\n\n/**\n * Performance sample\n */\nexport interface PerformanceSample {\n timestamp: number;\n inference: InferenceMetrics;\n memory: MemoryMetrics;\n system: SystemMetrics;\n custom: Record<string, number>;\n}\n\n/**\n * Inference metrics\n */\nexport interface InferenceMetrics {\n /** Inferences in the last interval */\n count: number;\n \n /** Average inference time (ms) */\n avgTime: number;\n \n /** Min inference time (ms) */\n minTime: number;\n \n /** Max inference time (ms) */\n maxTime: number;\n \n /** Throughput (inferences per second) */\n throughput: number;\n \n /** Queue length */\n queueLength: number;\n \n /** Active inferences */\n activeCount: number;\n}\n\n/**\n * Memory metrics\n */\nexport interface MemoryMetrics {\n /** Used JS heap size (bytes) */\n usedHeap: number;\n \n /** Total JS heap size (bytes) */\n totalHeap: number;\n \n /** Heap limit (bytes) */\n heapLimit: number;\n \n /** Heap usage percentage */\n heapUsage: number;\n \n /** Tensor memory (bytes) */\n tensorMemory: number;\n \n /** Cache memory (bytes) */\n cacheMemory: number;\n}\n\n/**\n * System metrics\n */\nexport interface SystemMetrics {\n /** Frames per second */\n fps: number;\n \n /** CPU usage estimate (0-1) */\n cpuUsage: number;\n \n /** Time since last sample (ms) */\n deltaTime: number;\n \n /** Browser info */\n userAgent: string;\n \n /** WebGPU available */\n webgpuAvailable: boolean;\n \n /** WebNN available */\n webnnAvailable: boolean;\n}\n\n/**\n * Alert configuration\n */\nexport interface AlertConfig {\n /** Metric name */\n metric: string;\n \n /** Threshold value */\n threshold: number;\n \n /** Comparison operator */\n operator: '>' | '<' | '>=' | '<=' | '==' | '!=';\n \n /** Alert message */\n message: string;\n \n /** Alert level */\n level: 'info' | 'warn' | 'error';\n}\n\n/**\n * Alert event\n */\nexport interface AlertEvent {\n config: AlertConfig;\n value: number;\n timestamp: number;\n}\n\n/**\n * Dashboard widget data\n */\nexport interface WidgetData {\n type: 'chart' | 'gauge' | 'counter' | 'text';\n title: string;\n data: unknown;\n}\n\n// ============================================================================\n// Performance Monitor\n// ============================================================================\n\n/**\n * Performance monitor for edgeFlow.js\n */\nexport class PerformanceMonitor {\n private config: Required<MonitorConfig>;\n private samples: PerformanceSample[] = [];\n private isRunning: boolean = false;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private alerts: AlertConfig[] = [];\n private alertListeners: Array<(alert: AlertEvent) => void> = [];\n private sampleListeners: Array<(sample: PerformanceSample) => void> = [];\n \n // Inference tracking\n private inferenceCount: number = 0;\n private inferenceTimes: number[] = [];\n private queueLength: number = 0;\n private activeCount: number = 0;\n \n // FPS tracking\n private frameCount: number = 0;\n private lastFrameTime: number = 0;\n private fps: number = 0;\n private rafId: number | null = null;\n \n // Memory tracking\n private tensorMemory: number = 0;\n private cacheMemory: number = 0;\n \n constructor(config: MonitorConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n sampleInterval: config.sampleInterval ?? 1000,\n historySize: config.historySize ?? 60,\n monitorMemory: config.monitorMemory ?? true,\n monitorFPS: config.monitorFPS ?? true,\n collectors: config.collectors ?? [],\n };\n }\n \n /**\n * Start monitoring\n */\n start(): void {\n if (this.isRunning) return;\n \n this.isRunning = true;\n \n // Start sampling\n this.intervalId = setInterval(() => {\n this.collectSample();\n }, this.config.sampleInterval);\n \n // Start FPS monitoring\n if (this.config.monitorFPS && typeof requestAnimationFrame !== 'undefined') {\n this.lastFrameTime = performance.now();\n this.frameCount = 0;\n this.monitorFPS();\n }\n }\n \n /**\n * Stop monitoring\n */\n stop(): void {\n this.isRunning = false;\n \n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n \n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n \n /**\n * Monitor FPS\n */\n private monitorFPS(): void {\n if (!this.isRunning) return;\n \n this.frameCount++;\n const now = performance.now();\n const elapsed = now - this.lastFrameTime;\n \n if (elapsed >= 1000) {\n this.fps = Math.round((this.frameCount * 1000) / elapsed);\n this.frameCount = 0;\n this.lastFrameTime = now;\n }\n \n this.rafId = requestAnimationFrame(() => this.monitorFPS());\n }\n \n /**\n * Collect a performance sample\n */\n private collectSample(): void {\n const now = Date.now();\n \n // Calculate inference metrics\n const avgTime = this.inferenceTimes.length > 0\n ? this.inferenceTimes.reduce((a, b) => a + b, 0) / this.inferenceTimes.length\n : 0;\n const minTime = this.inferenceTimes.length > 0\n ? Math.min(...this.inferenceTimes)\n : 0;\n const maxTime = this.inferenceTimes.length > 0\n ? Math.max(...this.inferenceTimes)\n : 0;\n const throughput = this.inferenceCount / (this.config.sampleInterval / 1000);\n \n const inference: InferenceMetrics = {\n count: this.inferenceCount,\n avgTime,\n minTime,\n maxTime,\n throughput,\n queueLength: this.queueLength,\n activeCount: this.activeCount,\n };\n \n // Collect memory metrics\n const memory = this.collectMemoryMetrics();\n \n // Collect system metrics\n const system = this.collectSystemMetrics();\n \n // Collect custom metrics\n const custom: Record<string, number> = {};\n for (const collector of this.config.collectors) {\n try {\n Object.assign(custom, collector());\n } catch {\n // Ignore collector errors\n }\n }\n \n const sample: PerformanceSample = {\n timestamp: now,\n inference,\n memory,\n system,\n custom,\n };\n \n // Add to history\n this.samples.push(sample);\n if (this.samples.length > this.config.historySize) {\n this.samples.shift();\n }\n \n // Check alerts\n this.checkAlerts(sample);\n \n // Notify listeners\n for (const listener of this.sampleListeners) {\n listener(sample);\n }\n \n // Reset counters\n this.inferenceCount = 0;\n this.inferenceTimes = [];\n }\n \n /**\n * Collect memory metrics\n */\n private collectMemoryMetrics(): MemoryMetrics {\n let usedHeap = 0;\n let totalHeap = 0;\n let heapLimit = 0;\n \n if (typeof performance !== 'undefined' && 'memory' in performance) {\n const memory = (performance as { memory: { usedJSHeapSize: number; totalJSHeapSize: number; jsHeapSizeLimit: number } }).memory;\n usedHeap = memory.usedJSHeapSize;\n totalHeap = memory.totalJSHeapSize;\n heapLimit = memory.jsHeapSizeLimit;\n }\n \n return {\n usedHeap,\n totalHeap,\n heapLimit,\n heapUsage: heapLimit > 0 ? usedHeap / heapLimit : 0,\n tensorMemory: this.tensorMemory,\n cacheMemory: this.cacheMemory,\n };\n }\n \n /**\n * Collect system metrics\n */\n private collectSystemMetrics(): SystemMetrics {\n const lastSample = this.samples[this.samples.length - 1];\n const deltaTime = lastSample \n ? Date.now() - lastSample.timestamp \n : this.config.sampleInterval;\n \n // Check WebGPU availability\n let webgpuAvailable = false;\n if (typeof navigator !== 'undefined' && 'gpu' in navigator) {\n webgpuAvailable = true;\n }\n \n // Check WebNN availability\n let webnnAvailable = false;\n if (typeof navigator !== 'undefined' && 'ml' in navigator) {\n webnnAvailable = true;\n }\n \n return {\n fps: this.fps,\n cpuUsage: this.estimateCPUUsage(),\n deltaTime,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown',\n webgpuAvailable,\n webnnAvailable,\n };\n }\n \n /**\n * Estimate CPU usage based on inference times\n */\n private estimateCPUUsage(): number {\n if (this.inferenceTimes.length === 0) return 0;\n \n const totalTime = this.inferenceTimes.reduce((a, b) => a + b, 0);\n return Math.min(1, totalTime / this.config.sampleInterval);\n }\n \n /**\n * Check alerts\n */\n private checkAlerts(sample: PerformanceSample): void {\n for (const alert of this.alerts) {\n const value = this.getMetricValue(sample, alert.metric);\n if (value === undefined) continue;\n \n let triggered = false;\n switch (alert.operator) {\n case '>': triggered = value > alert.threshold; break;\n case '<': triggered = value < alert.threshold; break;\n case '>=': triggered = value >= alert.threshold; break;\n case '<=': triggered = value <= alert.threshold; break;\n case '==': triggered = value === alert.threshold; break;\n case '!=': triggered = value !== alert.threshold; break;\n }\n \n if (triggered) {\n const event: AlertEvent = {\n config: alert,\n value,\n timestamp: sample.timestamp,\n };\n \n for (const listener of this.alertListeners) {\n listener(event);\n }\n }\n }\n }\n \n /**\n * Get metric value from sample\n */\n private getMetricValue(sample: PerformanceSample, metric: string): number | undefined {\n const parts = metric.split('.');\n let value: unknown = sample;\n \n for (const part of parts) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n \n return typeof value === 'number' ? value : undefined;\n }\n \n /**\n * Record an inference\n */\n recordInference(duration: number): void {\n this.inferenceCount++;\n this.inferenceTimes.push(duration);\n }\n \n /**\n * Update queue length\n */\n updateQueueLength(length: number): void {\n this.queueLength = length;\n }\n \n /**\n * Update active count\n */\n updateActiveCount(count: number): void {\n this.activeCount = count;\n }\n \n /**\n * Update tensor memory\n */\n updateTensorMemory(bytes: number): void {\n this.tensorMemory = bytes;\n }\n \n /**\n * Update cache memory\n */\n updateCacheMemory(bytes: number): void {\n this.cacheMemory = bytes;\n }\n \n /**\n * Add an alert\n */\n addAlert(config: AlertConfig): void {\n this.alerts.push(config);\n }\n \n /**\n * Remove an alert\n */\n removeAlert(metric: string): void {\n this.alerts = this.alerts.filter(a => a.metric !== metric);\n }\n \n /**\n * Subscribe to alerts\n */\n onAlert(callback: (alert: AlertEvent) => void): () => void {\n this.alertListeners.push(callback);\n return () => {\n const idx = this.alertListeners.indexOf(callback);\n if (idx !== -1) this.alertListeners.splice(idx, 1);\n };\n }\n \n /**\n * Subscribe to samples\n */\n onSample(callback: (sample: PerformanceSample) => void): () => void {\n this.sampleListeners.push(callback);\n return () => {\n const idx = this.sampleListeners.indexOf(callback);\n if (idx !== -1) this.sampleListeners.splice(idx, 1);\n };\n }\n \n /**\n * Get current sample\n */\n getCurrentSample(): PerformanceSample | undefined {\n return this.samples[this.samples.length - 1];\n }\n \n /**\n * Get all samples\n */\n getSamples(): PerformanceSample[] {\n return [...this.samples];\n }\n \n /**\n * Get samples in time range\n */\n getSamplesInRange(startTime: number, endTime: number): PerformanceSample[] {\n return this.samples.filter(s => s.timestamp >= startTime && s.timestamp <= endTime);\n }\n \n /**\n * Get summary statistics\n */\n getSummary(): {\n avgInferenceTime: number;\n avgThroughput: number;\n avgMemoryUsage: number;\n avgFPS: number;\n totalInferences: number;\n uptime: number;\n } {\n if (this.samples.length === 0) {\n return {\n avgInferenceTime: 0,\n avgThroughput: 0,\n avgMemoryUsage: 0,\n avgFPS: 0,\n totalInferences: 0,\n uptime: 0,\n };\n }\n \n const avgInferenceTime = this.samples.reduce((sum, s) => sum + s.inference.avgTime, 0) / this.samples.length;\n const avgThroughput = this.samples.reduce((sum, s) => sum + s.inference.throughput, 0) / this.samples.length;\n const avgMemoryUsage = this.samples.reduce((sum, s) => sum + s.memory.heapUsage, 0) / this.samples.length;\n const avgFPS = this.samples.reduce((sum, s) => sum + s.system.fps, 0) / this.samples.length;\n const totalInferences = this.samples.reduce((sum, s) => sum + s.inference.count, 0);\n \n const firstSample = this.samples[0]!;\n const lastSample = this.samples[this.samples.length - 1]!;\n const uptime = lastSample.timestamp - firstSample.timestamp;\n \n return {\n avgInferenceTime,\n avgThroughput,\n avgMemoryUsage,\n avgFPS,\n totalInferences,\n uptime,\n };\n }\n \n /**\n * Clear all data\n */\n clear(): void {\n this.samples = [];\n this.inferenceCount = 0;\n this.inferenceTimes = [];\n this.queueLength = 0;\n this.activeCount = 0;\n this.tensorMemory = 0;\n this.cacheMemory = 0;\n }\n \n /**\n * Export data\n */\n export(): {\n samples: PerformanceSample[];\n summary: {\n avgInferenceTime: number;\n avgThroughput: number;\n avgMemoryUsage: number;\n avgFPS: number;\n totalInferences: number;\n uptime: number;\n };\n config: MonitorConfig;\n timestamp: number;\n } {\n return {\n samples: this.getSamples(),\n summary: this.getSummary(),\n config: this.config,\n timestamp: Date.now(),\n };\n }\n}\n\n// ============================================================================\n// Dashboard Generator\n// ============================================================================\n\n/**\n * Generate HTML dashboard\n */\nexport function generateDashboardHTML(monitor: PerformanceMonitor): string {\n const summary = monitor.getSummary();\n const samples = monitor.getSamples();\n const lastSample = samples[samples.length - 1];\n \n const formatBytes = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n };\n \n const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n };\n \n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>edgeFlow.js Performance Dashboard</title>\n <style>\n :root {\n --bg-primary: #0d1117;\n --bg-secondary: #161b22;\n --bg-tertiary: #21262d;\n --text-primary: #f0f6fc;\n --text-secondary: #8b949e;\n --accent: #58a6ff;\n --success: #3fb950;\n --warning: #d29922;\n --error: #f85149;\n }\n \n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n \n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n background: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n }\n \n .dashboard {\n max-width: 1400px;\n margin: 0 auto;\n padding: 24px;\n }\n \n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 32px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--bg-tertiary);\n }\n \n h1 {\n font-size: 24px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n \n .status {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n color: var(--text-secondary);\n }\n \n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--success);\n }\n \n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 20px;\n margin-bottom: 32px;\n }\n \n .card {\n background: var(--bg-secondary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 12px;\n padding: 20px;\n }\n \n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n }\n \n .card-title {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .card-value {\n font-size: 36px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n }\n \n .card-value.small {\n font-size: 24px;\n }\n \n .card-unit {\n font-size: 14px;\n color: var(--text-secondary);\n margin-left: 4px;\n }\n \n .card-change {\n font-size: 12px;\n padding: 4px 8px;\n border-radius: 4px;\n }\n \n .card-change.up {\n background: rgba(63, 185, 80, 0.2);\n color: var(--success);\n }\n \n .card-change.down {\n background: rgba(248, 81, 73, 0.2);\n color: var(--error);\n }\n \n .progress-bar {\n height: 8px;\n background: var(--bg-tertiary);\n border-radius: 4px;\n overflow: hidden;\n margin-top: 12px;\n }\n \n .progress-fill {\n height: 100%;\n border-radius: 4px;\n transition: width 0.3s ease;\n }\n \n .progress-fill.blue { background: var(--accent); }\n .progress-fill.green { background: var(--success); }\n .progress-fill.yellow { background: var(--warning); }\n .progress-fill.red { background: var(--error); }\n \n .chart-container {\n background: var(--bg-secondary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 20px;\n }\n \n .chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n }\n \n .chart-title {\n font-size: 16px;\n font-weight: 600;\n }\n \n .chart {\n height: 200px;\n position: relative;\n }\n \n .chart-line {\n stroke: var(--accent);\n stroke-width: 2;\n fill: none;\n }\n \n .chart-area {\n fill: url(#chartGradient);\n opacity: 0.3;\n }\n \n .chart-grid {\n stroke: var(--bg-tertiary);\n stroke-width: 1;\n }\n \n .table {\n width: 100%;\n border-collapse: collapse;\n }\n \n .table th,\n .table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--bg-tertiary);\n }\n \n .table th {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .table td {\n font-variant-numeric: tabular-nums;\n }\n \n footer {\n text-align: center;\n padding: 24px;\n color: var(--text-secondary);\n font-size: 14px;\n }\n </style>\n</head>\n<body>\n <div class=\"dashboard\">\n <header>\n <h1>\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\">\n <rect width=\"32\" height=\"32\" rx=\"8\" fill=\"var(--accent)\"/>\n <path d=\"M8 16L14 10L20 16L26 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8 22L14 16L20 22L26 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" opacity=\"0.5\"/>\n </svg>\n edgeFlow.js Performance Dashboard\n </h1>\n <div class=\"status\">\n <div class=\"status-dot\"></div>\n Running for ${formatDuration(summary.uptime)}\n </div>\n </header>\n \n <div class=\"grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Total Inferences</span>\n </div>\n <div class=\"card-value\">${summary.totalInferences.toLocaleString()}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Avg Inference Time</span>\n </div>\n <div class=\"card-value\">${summary.avgInferenceTime.toFixed(1)}<span class=\"card-unit\">ms</span></div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Throughput</span>\n </div>\n <div class=\"card-value\">${summary.avgThroughput.toFixed(1)}<span class=\"card-unit\">ops/s</span></div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Avg FPS</span>\n </div>\n <div class=\"card-value\">${Math.round(summary.avgFPS)}</div>\n </div>\n </div>\n \n <div class=\"grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Memory Usage</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.usedHeap ?? 0)}</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${summary.avgMemoryUsage > 0.8 ? 'red' : summary.avgMemoryUsage > 0.6 ? 'yellow' : 'green'}\" \n style=\"width: ${(summary.avgMemoryUsage * 100).toFixed(0)}%\"></div>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Tensor Memory</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.tensorMemory ?? 0)}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Cache Memory</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.cacheMemory ?? 0)}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Queue Length</span>\n </div>\n <div class=\"card-value small\">${lastSample?.inference.queueLength ?? 0}</div>\n </div>\n </div>\n \n <div class=\"chart-container\">\n <div class=\"chart-header\">\n <span class=\"chart-title\">Inference Time History</span>\n </div>\n <div class=\"chart\">\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 600 200\" preserveAspectRatio=\"none\">\n <defs>\n <linearGradient id=\"chartGradient\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"var(--accent)\" stop-opacity=\"0.5\"/>\n <stop offset=\"100%\" stop-color=\"var(--accent)\" stop-opacity=\"0\"/>\n </linearGradient>\n </defs>\n ${generateChartPath(samples)}\n </svg>\n </div>\n </div>\n \n <div class=\"chart-container\">\n <div class=\"chart-header\">\n <span class=\"chart-title\">Recent Samples</span>\n </div>\n <table class=\"table\">\n <thead>\n <tr>\n <th>Time</th>\n <th>Inferences</th>\n <th>Avg Time</th>\n <th>Throughput</th>\n <th>Memory</th>\n <th>FPS</th>\n </tr>\n </thead>\n <tbody>\n ${samples.slice(-10).reverse().map(s => `\n <tr>\n <td>${new Date(s.timestamp).toLocaleTimeString()}</td>\n <td>${s.inference.count}</td>\n <td>${s.inference.avgTime.toFixed(2)}ms</td>\n <td>${s.inference.throughput.toFixed(1)}/s</td>\n <td>${formatBytes(s.memory.usedHeap)}</td>\n <td>${s.system.fps}</td>\n </tr>\n `).join('')}\n </tbody>\n </table>\n </div>\n \n <footer>\n Generated at ${new Date().toLocaleString()} | edgeFlow.js Performance Monitor\n </footer>\n </div>\n</body>\n</html>\n `.trim();\n}\n\n/**\n * Generate SVG chart path\n */\nfunction generateChartPath(samples: PerformanceSample[]): string {\n if (samples.length < 2) return '';\n \n const width = 600;\n const height = 180;\n const padding = 10;\n \n const times = samples.map(s => s.inference.avgTime);\n const maxTime = Math.max(...times, 1);\n \n const points = samples.map((s, i) => {\n const x = padding + (i / (samples.length - 1)) * (width - 2 * padding);\n const y = height - padding - (s.inference.avgTime / maxTime) * (height - 2 * padding);\n return `${x},${y}`;\n });\n \n const linePath = `M ${points.join(' L ')}`;\n const areaPath = `M ${padding},${height - padding} L ${points.join(' L ')} L ${width - padding},${height - padding} Z`;\n \n // Grid lines\n const gridLines = [];\n for (let i = 0; i <= 4; i++) {\n const y = padding + (i / 4) * (height - 2 * padding);\n gridLines.push(`<line class=\"chart-grid\" x1=\"${padding}\" y1=\"${y}\" x2=\"${width - padding}\" y2=\"${y}\"/>`);\n }\n \n return `\n ${gridLines.join('\\n')}\n <path class=\"chart-area\" d=\"${areaPath}\"/>\n <path class=\"chart-line\" d=\"${linePath}\"/>\n `;\n}\n\n/**\n * Generate ASCII dashboard\n */\nexport function generateAsciiDashboard(monitor: PerformanceMonitor): string {\n const summary = monitor.getSummary();\n const samples = monitor.getSamples();\n const lastSample = samples[samples.length - 1];\n \n const formatBytes = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n };\n \n const bar = (value: number, max: number, width: number = 20): string => {\n const filled = Math.round((value / max) * width);\n return '\u2588'.repeat(filled) + '\u2591'.repeat(width - filled);\n };\n \n const lines = [\n '\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557',\n '\u2551 edgeFlow.js Performance Monitor Dashboard \u2551',\n '\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563',\n '\u2551 \u2551',\n `\u2551 Total Inferences: ${summary.totalInferences.toString().padStart(10)} \u2551`,\n `\u2551 Avg Inference: ${summary.avgInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Throughput: ${summary.avgThroughput.toFixed(2).padStart(10)} ops/s \u2551`,\n `\u2551 Avg FPS: ${Math.round(summary.avgFPS).toString().padStart(10)} \u2551`,\n '\u2551 \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Memory Usage \u2551',\n `\u2551 Heap: ${bar(summary.avgMemoryUsage, 1)} ${(summary.avgMemoryUsage * 100).toFixed(0).padStart(3)}% \u2551`,\n `\u2551 Used: ${formatBytes(lastSample?.memory.usedHeap ?? 0).padStart(10)} \u2551`,\n `\u2551 Tensor: ${formatBytes(lastSample?.memory.tensorMemory ?? 0).padStart(10)} \u2551`,\n `\u2551 Cache: ${formatBytes(lastSample?.memory.cacheMemory ?? 0).padStart(10)} \u2551`,\n '\u2551 \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Inference Time History (last 30 samples) \u2551',\n '\u2551 \u2551',\n ];\n \n // Add mini chart\n const recentSamples = samples.slice(-30);\n if (recentSamples.length > 0) {\n const times = recentSamples.map(s => s.inference.avgTime);\n const maxTime = Math.max(...times, 1);\n const chartHeight = 5;\n \n for (let row = chartHeight; row > 0; row--) {\n let line = '\u2551 ';\n for (const time of times) {\n const height = Math.ceil((time / maxTime) * chartHeight);\n line += height >= row ? '\u2593' : ' ';\n }\n lines.push(line.padEnd(76) + '\u2551');\n }\n lines.push('\u2551 ' + '\u2500'.repeat(30) + ' \u2551');\n }\n \n lines.push('\u2551 \u2551');\n lines.push(`\u2551 Last updated: ${new Date().toLocaleString().padEnd(40)} \u2551`);\n lines.push('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D');\n \n return lines.join('\\n');\n}\n\n// ============================================================================\n// Global Instance\n// ============================================================================\n\nlet globalMonitor: PerformanceMonitor | null = null;\n\n/**\n * Get or create global monitor\n */\nexport function getMonitor(config?: MonitorConfig): PerformanceMonitor {\n if (!globalMonitor || config) {\n globalMonitor = new PerformanceMonitor(config);\n }\n return globalMonitor;\n}\n\n/**\n * Start monitoring\n */\nexport function startMonitoring(config?: MonitorConfig): PerformanceMonitor {\n const monitor = getMonitor(config);\n monitor.start();\n return monitor;\n}\n\n/**\n * Stop monitoring\n */\nexport function stopMonitoring(): void {\n globalMonitor?.stop();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n};\n", "/**\n * edgeFlow.js - Tools and Utilities\n * \n * Model optimization, quantization, and analysis tools.\n */\n\nimport { \n LoadedModel,\n QuantizationType,\n} from '../core/types.js';\n\n// ============================================================================\n// Quantization Tools\n// ============================================================================\n\n/**\n * Quantization options\n */\nexport interface QuantizationOptions {\n /** Quantization method */\n method: QuantizationType;\n /** Calibration data for calibrated quantization */\n calibrationData?: Float32Array[];\n /** Whether to quantize weights only */\n weightsOnly?: boolean;\n /** Layers to exclude from quantization */\n excludeLayers?: string[];\n}\n\n/**\n * Quantization result\n */\nexport interface QuantizationResult {\n /** Quantized model data */\n modelData: ArrayBuffer;\n /** Original size in bytes */\n originalSize: number;\n /** Quantized size in bytes */\n quantizedSize: number;\n /** Compression ratio */\n compressionRatio: number;\n /** Quantization statistics */\n stats: {\n layersQuantized: number;\n layersSkipped: number;\n };\n}\n\n/**\n * Quantize a model\n * \n * @example\n * ```typescript\n * const quantized = await quantize(model, {\n * method: 'int8',\n * calibrationData: samples,\n * });\n * ```\n */\nexport async function quantize(\n model: LoadedModel | ArrayBuffer,\n options: QuantizationOptions\n): Promise<QuantizationResult> {\n // Get model data\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n const originalSize = modelData.byteLength;\n\n // Apply quantization based on method\n let quantizedData: ArrayBuffer;\n let layersQuantized = 0;\n let layersSkipped = 0;\n\n switch (options.method) {\n case 'int8':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeInt8(modelData, options));\n break;\n case 'uint8':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeUint8(modelData, options));\n break;\n case 'float16':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeFloat16(modelData, options));\n break;\n case 'int4':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeInt4(modelData, options));\n break;\n default:\n quantizedData = modelData;\n }\n\n return {\n modelData: quantizedData,\n originalSize,\n quantizedSize: quantizedData.byteLength,\n compressionRatio: originalSize / quantizedData.byteLength,\n stats: {\n layersQuantized,\n layersSkipped,\n },\n };\n}\n\n/**\n * Placeholder for getting model data\n */\nasync function getModelData(_model: LoadedModel): Promise<ArrayBuffer> {\n // In production, this would extract the model weights\n return new ArrayBuffer(0);\n}\n\n/**\n * INT8 quantization\n */\nfunction quantizeInt8(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n // Simplified INT8 quantization\n const input = new Float32Array(data);\n const output = new Int8Array(input.length);\n \n // Find scale\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n const abs = Math.abs(input[i] ?? 0);\n if (abs > max) max = abs;\n }\n const scale = max / 127;\n \n // Quantize\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.round((input[i] ?? 0) / scale);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * UINT8 quantization\n */\nfunction quantizeUint8(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n const output = new Uint8Array(input.length);\n \n // Find min/max\n let min = Infinity, max = -Infinity;\n for (let i = 0; i < input.length; i++) {\n const val = input[i] ?? 0;\n if (val < min) min = val;\n if (val > max) max = val;\n }\n const scale = (max - min) / 255;\n \n // Quantize\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.round(((input[i] ?? 0) - min) / scale);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * Float16 quantization\n */\nfunction quantizeFloat16(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n const output = new Uint16Array(input.length);\n \n // Convert float32 to float16\n for (let i = 0; i < input.length; i++) {\n output[i] = float32ToFloat16(input[i] ?? 0);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * INT4 quantization\n */\nfunction quantizeInt4(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n // Pack two INT4 values per byte\n const output = new Uint8Array(Math.ceil(input.length / 2));\n \n // Find scale\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n const abs = Math.abs(input[i] ?? 0);\n if (abs > max) max = abs;\n }\n const scale = max / 7; // INT4 range: -8 to 7\n \n // Quantize and pack\n for (let i = 0; i < input.length; i += 2) {\n const val1 = Math.round((input[i] ?? 0) / scale) + 8;\n const val2 = Math.round((input[i + 1] ?? 0) / scale) + 8;\n output[i / 2] = ((val1 & 0xF) << 4) | (val2 & 0xF);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * Convert float32 to float16\n */\nfunction float32ToFloat16(value: number): number {\n const floatView = new Float32Array(1);\n const int32View = new Int32Array(floatView.buffer);\n \n floatView[0] = value;\n const x = int32View[0] ?? 0;\n \n let bits = (x >> 16) & 0x8000; // sign\n let m = (x >> 12) & 0x07ff; // mantissa\n const e = (x >> 23) & 0xff; // exponent\n \n if (e < 103) {\n // Too small, return zero\n return bits;\n }\n \n if (e > 142) {\n // Too large, return infinity\n bits |= 0x7c00;\n bits |= ((e === 255) ? 0 : 1) && (x & 0x007fffff);\n return bits;\n }\n \n if (e < 113) {\n // Denormalized\n m |= 0x0800;\n bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);\n return bits;\n }\n \n bits |= ((e - 112) << 10) | (m >> 1);\n bits += m & 1;\n return bits;\n}\n\n// ============================================================================\n// Model Pruning\n// ============================================================================\n\n/**\n * Pruning options\n */\nexport interface PruningOptions {\n /** Target sparsity (0-1) */\n sparsity: number;\n /** Pruning method */\n method?: 'magnitude' | 'random' | 'structured';\n /** Layers to exclude */\n excludeLayers?: string[];\n}\n\n/**\n * Pruning result\n */\nexport interface PruningResult {\n /** Pruned model data */\n modelData: ArrayBuffer;\n /** Achieved sparsity */\n actualSparsity: number;\n /** Number of parameters pruned */\n parametersPruned: number;\n /** Total parameters */\n totalParameters: number;\n}\n\n/**\n * Prune model weights\n */\nexport async function prune(\n model: LoadedModel | ArrayBuffer,\n options: PruningOptions\n): Promise<PruningResult> {\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n const weights = new Float32Array(modelData);\n const total = weights.length;\n \n // Calculate threshold for magnitude pruning\n const magnitudes = weights.map(Math.abs);\n const sorted = [...magnitudes].sort((a, b) => a - b);\n const thresholdIdx = Math.floor(options.sparsity * sorted.length);\n const threshold = sorted[thresholdIdx] ?? 0;\n \n // Prune weights\n let pruned = 0;\n for (let i = 0; i < weights.length; i++) {\n if (Math.abs(weights[i] ?? 0) < threshold) {\n weights[i] = 0;\n pruned++;\n }\n }\n\n return {\n modelData: weights.buffer,\n actualSparsity: pruned / total,\n parametersPruned: pruned,\n totalParameters: total,\n };\n}\n\n// ============================================================================\n// Model Analysis\n// ============================================================================\n\n/**\n * Model analysis result\n */\nexport interface ModelAnalysis {\n /** Total number of parameters */\n totalParameters: number;\n /** Model size in bytes */\n sizeBytes: number;\n /** Layer information */\n layers: Array<{\n name: string;\n type: string;\n parameters: number;\n inputShape: number[];\n outputShape: number[];\n }>;\n /** Estimated FLOPs */\n estimatedFlops: number;\n /** Memory requirements */\n memoryRequirements: {\n weights: number;\n activations: number;\n total: number;\n };\n}\n\n/**\n * Analyze a model\n */\nexport async function analyzeModel(\n model: LoadedModel | ArrayBuffer\n): Promise<ModelAnalysis> {\n // Simplified analysis\n const size = model instanceof ArrayBuffer \n ? model.byteLength \n : model.metadata.sizeBytes;\n\n const estimatedParams = Math.floor(size / 4); // Assume float32\n\n return {\n totalParameters: estimatedParams,\n sizeBytes: size,\n layers: [],\n estimatedFlops: estimatedParams * 2, // Rough estimate\n memoryRequirements: {\n weights: size,\n activations: size * 0.1, // Rough estimate\n total: size * 1.1,\n },\n };\n}\n\n// ============================================================================\n// Benchmarking\n// ============================================================================\n\n/**\n * Benchmark options\n */\nexport interface BenchmarkOptions {\n /** Number of warmup runs */\n warmupRuns?: number;\n /** Number of benchmark runs */\n runs?: number;\n /** Input shape */\n inputShape?: number[];\n}\n\n/**\n * Benchmark result\n */\nexport interface BenchmarkResult {\n /** Average inference time in ms */\n avgTime: number;\n /** Minimum inference time in ms */\n minTime: number;\n /** Maximum inference time in ms */\n maxTime: number;\n /** Standard deviation */\n stdDev: number;\n /** Throughput (inferences per second) */\n throughput: number;\n /** All run times */\n times: number[];\n}\n\n/**\n * Benchmark model inference\n */\nexport async function benchmark(\n runFn: () => Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<BenchmarkResult> {\n const {\n warmupRuns = 3,\n runs = 10,\n } = options;\n\n // Warmup\n for (let i = 0; i < warmupRuns; i++) {\n await runFn();\n }\n\n // Benchmark\n const times: number[] = [];\n for (let i = 0; i < runs; i++) {\n const start = performance.now();\n await runFn();\n times.push(performance.now() - start);\n }\n\n // Calculate statistics\n const sum = times.reduce((a, b) => a + b, 0);\n const avgTime = sum / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n \n const squaredDiffs = times.map(t => Math.pow(t - avgTime, 2));\n const avgSquaredDiff = squaredDiffs.reduce((a, b) => a + b, 0) / times.length;\n const stdDev = Math.sqrt(avgSquaredDiff);\n\n return {\n avgTime,\n minTime,\n maxTime,\n stdDev,\n throughput: 1000 / avgTime,\n times,\n };\n}\n\n// ============================================================================\n// Re-export benchmark utilities\n// ============================================================================\n\nexport {\n benchmark as runBenchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n} from './benchmark.js';\n\nexport type {\n BenchmarkOptions as DetailedBenchmarkOptions,\n BenchmarkResult as DetailedBenchmarkResult,\n CompareBenchmarkResult,\n MemoryBenchmarkResult,\n} from './benchmark.js';\n\n// ============================================================================\n// Re-export advanced quantization tools\n// ============================================================================\n\nexport {\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModel as analyzeModelDetailed,\n exportModel as exportModelAdvanced,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n} from './quantization.js';\n\nexport type {\n QuantizationType as QuantizationMethod,\n QuantizationOptions as AdvancedQuantizationOptions,\n QuantizationProgress,\n QuantizationResult as AdvancedQuantizationResult,\n LayerQuantizationStats,\n QuantizationStats,\n PruningOptions as AdvancedPruningOptions,\n PruningResult as AdvancedPruningResult,\n ModelAnalysis as DetailedModelAnalysis,\n ExportFormat,\n ExportOptions,\n} from './quantization.js';\n\n// ============================================================================\n// Re-export debugging tools\n// ============================================================================\n\nexport {\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n} from './debugger.js';\n\nexport type {\n DebuggerConfig,\n TensorInspection,\n TensorStats,\n HistogramData,\n InferenceTrace,\n OperationTrace,\n DebugEvent,\n PerformanceMetrics as DebugPerformanceMetrics,\n} from './debugger.js';\n\n// ============================================================================\n// Re-export monitoring tools\n// ============================================================================\n\nexport {\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n} from './monitor.js';\n\nexport type {\n MonitorConfig,\n PerformanceSample,\n InferenceMetrics,\n MemoryMetrics,\n SystemMetrics,\n AlertConfig,\n AlertEvent,\n WidgetData,\n} from './monitor.js';\n\n// ============================================================================\n// Export Utilities\n// ============================================================================\n\n/**\n * Export model to different formats\n */\nexport async function exportModel(\n model: LoadedModel | ArrayBuffer,\n format: 'onnx' | 'json' | 'binary'\n): Promise<ArrayBuffer | string> {\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n switch (format) {\n case 'json':\n // Export as JSON (for small models)\n const array = new Float32Array(modelData);\n return JSON.stringify(Array.from(array));\n case 'binary':\n case 'onnx':\n default:\n return modelData;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["EdgeFlowError", "ErrorCodes", "init_types", "__esmMin", "message", "code", "details", "__publicField", "generateTensorId", "tensorIdCounter", "getTypedArrayConstructor", "dtype", "EdgeFlowError", "ErrorCodes", "calculateSize", "shape", "acc", "dim", "validateShape", "i", "tensor", "data", "rows", "cols", "flatData", "row", "EdgeFlowTensor", "inferredShape", "zeros", "size", "TypedArrayCtor", "ones", "full", "value", "random", "randn", "u1", "u2", "r", "theta", "arange", "start", "stop", "step", "linspace", "num", "eye", "n", "add", "a", "b", "result", "aData", "bData", "sub", "mul", "div", "matmul", "m", "k1", "k2", "j", "sum", "k", "softmax", "t", "axis", "actualAxis", "max", "relu", "sigmoid", "tanh", "total", "newShape", "mean", "axisSize", "argmax", "maxIdx", "maxVal", "concat", "tensors", "first", "totalAxisSize", "offset", "init_tensor", "__esmMin", "init_types", "_EdgeFlowTensor", "__publicField", "expectedSize", "bigIntData", "clonedData", "indices", "flatIndex", "stride", "idx", "newSize", "model_loader_exports", "__export", "cancelPreload", "clearModelCache", "deleteCachedModel", "getCachedModel", "getModelCacheStats", "getPreloadStatus", "getPreloadedModel", "isModelCached", "loadModelData", "preloadModel", "preloadModels", "supportsRangeRequests", "url", "response", "acceptRanges", "contentLength", "etag", "downloadChunk", "start", "end", "timeout", "controller", "timeoutId", "downloadWithResume", "options", "chunkSize", "parallelConnections", "onProgress", "supportsRange", "totalSize", "downloadSimple", "state", "modelCache", "numChunks", "chunks", "i", "pendingChunks", "c", "downloadedSize", "lastProgressTime", "lastDownloadedSize", "reportProgress", "now", "elapsed", "bytesDownloaded", "speed", "remaining", "eta", "downloadQueue", "inProgress", "chunk", "downloadPromise", "data", "result", "offset", "total", "reader", "loaded", "startTime", "done", "value", "cache", "forceDownload", "resumable", "cached", "firstByte", "preloadManager", "urls", "priority", "DB_NAME", "STORE_META", "STORE_CHUNKS", "STORE_STATE", "ModelCache", "PreloadManager", "init_model_loader", "__esmMin", "__publicField", "resolve", "reject", "request", "event", "db", "meta", "err", "index", "storeName", "tx", "bytesNeeded", "allMeta", "a", "b", "freed", "results", "r", "sum", "cursor", "stores", "metas", "m", "existing", "promise", "res", "rej", "task", "insertIndex", "u", "t", "error", "init_types", "init_tensor", "init_types", "Task", "id", "modelId", "priority", "executor", "__publicField", "cancelError", "EdgeFlowError", "ErrorCodes", "reject", "resolve", "err", "PRIORITY_ORDER", "PriorityQueue", "item", "inserted", "i", "currentItem", "index", "removed", "taskIdCounter", "generateTaskId", "DEFAULT_OPTIONS", "InferenceScheduler", "options", "__publicField", "modelId", "c", "queue", "PriorityQueue", "running", "tasksToStart", "task", "error", "hasPending", "executor", "priority", "EdgeFlowError", "ErrorCodes", "maxRetries", "baseDelay", "wrappedExecutor", "lastError", "attempt", "result", "err", "delay", "r", "Task", "timeout", "timeoutExecutor", "resolve", "reject", "timer", "tasks", "scheduledTasks", "taskId", "cancelled", "stats", "event", "listener", "listeners", "type", "data", "batcher", "globalScheduler", "getScheduler", "setScheduler", "scheduler", "configureScheduler", "DEFAULT_POOL_CONFIG", "_MemoryManager", "config", "__publicField", "tensor", "disposer", "size", "model", "id", "resource", "resourceOrId", "error", "bytesPerElement", "dtype", "obj", "usage", "evict", "maxAge", "now", "staleIds", "tensorCount", "modelCount", "potentialLeaks", "event", "listener", "listeners", "type", "data", "MemoryManager", "MemoryScope", "_MemoryScope", "parent", "index", "child", "i", "withMemoryScope", "fn", "scope", "withMemoryScopeSync", "ModelCache", "options", "key", "entry", "oldestKey", "oldestTime", "getMemoryManager", "getMemoryStats", "release", "gc", "init_types", "runtimeFactories", "runtimeInstances", "RUNTIME_PRIORITY", "_RuntimeManager", "__publicField", "type", "factory", "runtime", "EdgeFlowError", "ErrorCodes", "error", "existing", "results", "event", "listener", "listeners", "data", "RuntimeManager", "modelIdCounter", "generateModelId", "LoadedModelImpl", "metadata", "dispose", "getMemoryManager", "loadModel", "url", "options", "loadModelData", "modelData", "progress", "loadModelFromBuffer", "runInference", "model", "inputs", "getScheduler", "runInferenceNamed", "namedInputs", "runBatchInference", "batches", "scheduler", "tasks", "task", "getRuntimeManager", "registerRuntime", "getBestRuntime", "getAvailableRuntimes", "registeredPlugins", "pluginPipelines", "pluginMiddleware", "registerPlugin", "plugin", "task", "entry", "name", "registerRuntime", "getPluginPipeline", "getPluginMiddleware", "listPlugins", "p", "unregisterPlugin", "mw", "idx", "cachedProfile", "getDeviceProfile", "cores", "memoryGiB", "mobile", "webgpu", "gpuInfo", "adapter", "info", "webnn", "ml", "tier", "recommendQuantization", "profile", "recommendModelVariant", "resetDeviceProfile", "init_types", "init_tensor", "GPUBufferUsage", "GPUShaderStage", "WebGPURuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "info", "modelData", "options", "config", "webgpuData", "modelId", "metadata", "i", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "device", "outputs", "outputSpec", "outputSize", "a", "b", "outputBuffer", "stagingBuffer", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "_data", "weightsBuffer", "shaderModule", "bindGroupLayout", "pipelineLayout", "pipeline", "buffer", "createWebGPURuntime", "init_types", "init_tensor", "WebNNRuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "error", "modelData", "options", "config", "modelId", "metadata", "i", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "outputs", "outputSpec", "outputSize", "b", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "createWebNNRuntime", "init_types", "init_tensor", "WASMRuntime", "__publicField", "bytes", "memory", "simdTest", "nextPtr", "allocations", "size", "ptr", "aPtr", "aRows", "aCols", "bPtr", "_bRows", "bCols", "outPtr", "view", "aOffset", "bOffset", "outOffset", "i", "j", "sum", "inputPtr", "outputPtr", "inOffset", "max", "modelData", "options", "config", "wasmData", "l", "modelId", "metadata", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "outputs", "outputSpec", "outputSize", "b", "outputTensor", "inputTensor", "softmax", "relu", "sigmoid", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "_modelData", "_wasmData", "weight", "EdgeFlowError", "ErrorCodes", "createWASMRuntime", "init_types", "init_tensor", "ort", "getOrt", "isOnnxAvailable", "sessionStore", "ONNXRuntime", "__publicField", "ortModule", "EdgeFlowError", "ErrorCodes", "modelData", "options", "sessionOptions", "modelBytes", "session", "inputNames", "outputNames", "modelId", "metadata", "name", "model", "LoadedModelImpl", "getMemoryManager", "error", "inputs", "sessionData", "feeds", "i", "inputName", "inputTensor", "dtype", "ortTensor", "data", "results", "outputs", "outputName", "shape", "d", "EdgeFlowTensor", "namedInputs", "tensor", "createONNXRuntime", "init_types", "init_tensor", "sessionStore", "adapterOptions", "TransformersAdapterRuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "modelData", "options", "metadata", "modelId", "model", "LoadedModelImpl", "session", "getMemoryManager", "task", "pipelineOptions", "opts", "instance", "inputs", "inputData", "result", "resultArray", "EdgeFlowTensor", "input", "id", "adapterRuntime", "useTransformersBackend", "registerRuntime", "getTransformersAdapter", "registerAllBackends", "registerRuntime", "createONNXRuntime", "Cache", "options", "__publicField", "key", "entry", "value", "size", "ttl", "entryTtl", "total", "keyToEvict", "oldest", "oldestTime", "lfu", "minCount", "now", "request", "resolve", "reject", "entries", "tx", "store", "db", "InferenceCache", "modelId", "input", "inputArray", "hash", "arr", "sample", "_", "i", "ModelDownloadCache", "cacheName", "url", "response", "r", "createCache", "preset", "presets", "BasePipeline", "config", "__publicField", "ModelCache", "ModelDownloadCache", "cachedModel", "modelPath", "cachedResponse", "response", "loadModel", "input", "options", "startTime", "preprocessed", "outputs", "runInference", "result", "inputs", "pipelineFactories", "registerPipeline", "task", "factory", "getPipelineFactory", "SENTIMENT_LABELS", "EMOTION_LABELS", "IMAGENET_LABELS", "init_tensor", "init_types", "Tokenizer", "_Tokenizer", "__publicField", "bytes", "i", "chars", "byte", "char", "json", "tokenizer", "data", "unigramVocab", "entry", "token", "id", "content", "url", "response", "EdgeFlowError", "ErrorCodes", "modelId", "options", "revision", "text", "result", "pattern", "b", "c", "word", "pairs", "minPair", "minRank", "pair", "rank", "parts", "first", "second", "newWord", "j", "tokens", "start", "end", "curSubstr", "substr", "byteStr", "prefixedWord", "found", "sub", "ch", "normalized", "remaining", "sortedAddedTokens", "a", "addedToken", "newRemaining", "words", "wordTokens", "addedId", "vocabId", "ids", "pairIds", "typeIds", "template", "item", "specialToken", "seqIds", "addSpecialTokens", "maxLength", "padding", "truncation", "returnAttentionMask", "returnTokenTypeIds", "textPair", "inputIds", "pairTokens", "tokenTypeIds", "processed", "attentionMask", "padLength", "texts", "encodings", "t", "maxLen", "e", "skipSpecialTokens", "prefix", "batchIds", "createBasicTokenizer", "loadTokenizer", "loadTokenizerFromHub", "init_model_loader", "DEFAULT_MODELS", "DEFAULT_SST2_LABELS", "TextClassificationPipeline", "BasePipeline", "config", "labels", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "isBatch", "inputs", "startTime", "results", "text", "tensorInputs", "outputs", "result", "processingTime", "encoded", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "namedInputs", "runInferenceNamed", "logits", "probsArray", "softmax", "maxIdx", "maxScore", "i", "SentimentAnalysisPipeline", "SENTIMENT_LABELS", "createTextClassificationPipeline", "createSentimentAnalysisPipeline", "registerPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "DEFAULT_EMBEDDING_DIM", "FeatureExtractionPipeline", "BasePipeline", "config", "embeddingDim", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "i", "input", "options", "isBatch", "inputs", "startTime", "results", "text", "tensorInputs", "outputs", "result", "processingTime", "encoded", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "tensors", "tokenTypeIds", "namedInputs", "runInferenceNamed", "hiddenStates", "pooling", "normalize", "embeddings", "data", "seqLen", "j", "val", "vec", "norm", "v", "createFeatureExtractionPipeline", "registerPipeline", "init_tensor", "init_tensor", "DEFAULT_IMAGE_OPTIONS", "ImagePreprocessor", "_ImagePreprocessor", "options", "__publicField", "size", "width", "height", "config", "sizeObj", "cropSize", "cropObj", "imageMean", "imageStd", "rescaleFactor", "doResize", "doRescale", "doNormalize", "doCenterCrop", "url", "response", "modelId", "revision", "input", "imageData", "processed", "inputs", "tensors", "batchSize", "firstTensor", "EdgeFlowTensor", "channels", "batchData", "i", "t", "resolve", "reject", "img", "blob", "cropWidth", "cropHeight", "srcX", "srcY", "srcCanvas", "source", "resizeMode", "srcW", "srcH", "dstX", "dstY", "dstW", "dstH", "scale", "mean", "std", "grayscale", "channelFormat", "dtype", "data", "pixels", "y", "x", "pixelIdx", "gray", "idx", "c", "value", "shape", "DEFAULT_AUDIO_OPTIONS", "AudioPreprocessor", "_AudioPreprocessor", "samplingRate", "featureSize", "nFft", "hopLength", "audioData", "maxSamples", "arrayBuffer", "audioBuffer", "buffer", "channelData", "max", "abs", "result", "audio", "nMels", "numFrames", "melSpec", "frame", "start", "mel", "energy", "freqStart", "freqEnd", "sample", "preprocessText", "text", "lowercase", "removePunctuation", "normalizeWhitespace", "maxLength", "createImagePreprocessor", "preset", "presets", "createAudioPreprocessor", "init_model_loader", "DEFAULT_MODELS", "ImageClassificationPipeline", "BasePipeline", "config", "labels", "_numClasses", "__publicField", "IMAGENET_LABELS", "createImagePreprocessor", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "isBatch", "inputs", "startTime", "results", "image", "tensorInputs", "outputs", "result", "processingTime", "tensor", "runInference", "logits", "probsArray", "softmax", "maxIdx", "maxScore", "i", "createImageClassificationPipeline", "registerPipeline", "init_tensor", "DEFAULT_LLM_MODELS", "TextGenerationPipeline", "BasePipeline", "config", "__publicField", "model", "tokenizer", "onProgress", "tokenizerResponse", "tokenizerJson", "Tokenizer", "specialIds", "error", "modelData", "loaded", "total", "loadModelFromBuffer", "url", "response", "contentLength", "buffer", "reader", "chunks", "done", "value", "offset", "chunk", "input", "text", "EdgeFlowTensor", "encoded", "id", "_outputs", "_options", "prompt", "options", "prompts", "results", "p", "startTime", "maxNewTokens", "maxLength", "temperature", "topK", "topP", "repetitionPenalty", "stopSequences", "doSample", "inputIds", "generatedIds", "generatedText", "i", "nextTokenId", "token", "shouldStop", "stopSeq", "endTime", "returnFullText", "currentText", "seqLen", "inputs", "_", "numLayers", "numKVHeads", "headDim", "outputs", "runInferenceNamed", "logits", "logitsData", "vocabSize", "lastPositionLogits", "prevId", "score", "logitsTensor", "probs", "softmax", "maxIdx", "maxProb", "indices", "a", "b", "candidateIndices", "cumulativeProb", "filtered", "idx", "totalProb", "r", "cumulative", "templateType", "messages", "msg", "systemMsg", "instruction", "template", "systemPrefix", "systemSuffix", "userPrefix", "userSuffix", "assistantPrefix", "assistantSuffix", "separator", "userMessage", "result", "fullResponse", "event", "createTextGenerationPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "COCO_LABELS", "ObjectDetectionPipeline", "BasePipeline", "config", "labels", "__publicField", "ImagePreprocessor", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "tensorInputs", "outputs", "inputs", "tensor", "EdgeFlowTensor", "runInference", "opts", "threshold", "topK", "nms", "iouThreshold", "outputData", "shape", "detections", "filtered", "a", "b", "data", "numBoxes", "boxSize", "numClasses", "i", "offset", "objectness", "maxClassScore", "maxClassIdx", "c", "score", "confidence", "x", "y", "w", "h", "x1", "y1", "x2", "y2", "sorted", "selected", "active", "current", "j", "other", "xOverlap", "yOverlap", "intersection", "aArea", "bArea", "union", "registerPipeline", "config", "ObjectDetectionPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "SOT_TOKEN", "TRANSLATE_TOKEN", "TRANSCRIBE_TOKEN", "EOT_TOKEN", "NO_TIMESTAMPS_TOKEN", "EN_TOKEN", "MAX_DECODER_TOKENS", "AutomaticSpeechRecognitionPipeline", "BasePipeline", "config", "__publicField", "AudioPreprocessor", "Tokenizer", "data", "loadModelData", "loadModelFromBuffer", "tokenizer", "input", "options", "isBatch", "inputs", "opts", "results", "audio", "result", "startTime", "melTensor", "melInput", "EdgeFlowTensor", "encoderHidden", "runInference", "task", "initialTokens", "generatedTokens", "text", "language", "tokens", "step", "decoderInputIds", "t", "namedInputs", "logits", "runInferenceNamed", "vocabSize", "lastTokenLogits", "bestId", "bestVal", "i", "_tokenIds", "words", "w", "chunks", "wordsPerSecond", "chunkText", "chunkStart", "duration", "chunkDuration", "chunkOverlap", "audioData", "sampleRate", "chunkSamples", "overlapSamples", "stepSamples", "start", "end", "chunkAudio", "chunkResult", "timeOffset", "c", "mergedText", "mergedChunks", "tensors", "outputs", "returnTimestamps", "outputData", "shape", "seqLen", "tokenIds", "offset", "maxIdx", "maxVal", "j", "registerPipeline", "config", "AutomaticSpeechRecognitionPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "ENTAILMENT_IDX", "ZeroShotClassificationPipeline", "BasePipeline", "config", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "tokenizer", "text", "candidateLabels", "options", "input", "opts", "texts", "template", "multiLabel", "results", "t", "startTime", "hypotheses", "label", "scores", "hypothesis", "score", "normalizedScores", "s", "tensor", "EdgeFlowTensor", "softmax", "indexed", "i", "a", "b", "premise", "encoded", "inputIds", "id", "attentionMask", "m", "namedInputs", "runInferenceNamed", "firstText", "firstLabel", "_outputs", "_options", "registerPipeline", "config", "ZeroShotClassificationPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "QuestionAnsweringPipeline", "BasePipeline", "config", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "tokenizer", "input", "options", "inputs", "results", "i", "startTime", "question", "context", "maxAnswerLength", "encoded", "seqLen", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "namedInputs", "outputs", "runInferenceNamed", "startLogits", "endLogits", "startProbs", "softmax", "endProbs", "contextStart", "t", "spanStart", "spanEnd", "bestStartIdx", "bestEndIdx", "bestScore", "s", "e", "score", "answerTokenIds", "qaInput", "_options", "bestStart", "bestEnd", "start", "end", "registerPipeline", "config", "QuestionAnsweringPipeline", "init_tensor", "DEFAULT_SAM_MODELS", "ImageSegmentationPipeline", "BasePipeline", "config", "__publicField", "encoder", "decoder", "onProgress", "encoderData", "loaded", "total", "loadModelFromBuffer", "decoderData", "url", "response", "contentLength", "buffer", "reader", "chunks", "done", "value", "offset", "chunk", "modelUrl", "loadModel", "image", "imageData", "inputTensor", "resizedSize", "outputs", "runInference", "options", "startTime", "points", "boxes", "maskThreshold", "returnAllMasks", "decoderInputs", "runInferenceNamed", "masks", "scores", "result", "input", "resolve", "reject", "img", "canvas", "ctx", "bitmap", "width", "height", "scale", "newWidth", "newHeight", "tempCanvas", "resizedData", "tensorData", "mean", "std", "i", "pixelIdx", "EdgeFlowTensor", "resizedW", "resizedH", "scaleX", "scaleY", "allPoints", "allLabels", "point", "box", "numPoints", "inputs", "l", "threshold", "scoresData", "masksData", "numMasks", "maskShape", "maskH", "maskW", "bestIdx", "bestScore", "m", "mask", "maskIdx", "srcW", "srcH", "dstW", "dstH", "outputMask", "maskOffset", "y", "x", "srcX", "srcY", "x0", "x1", "y0", "y1", "xFrac", "yFrac", "v00", "v01", "v10", "v11", "sigmoid", "tensor", "_outputs", "_options", "createImageSegmentationPipeline", "registerPipeline", "pipeline", "task", "options", "registerAllBackends", "config", "pipelineInstance", "TextClassificationPipeline", "SentimentAnalysisPipeline", "FeatureExtractionPipeline", "ImageClassificationPipeline", "TextGenerationPipeline", "ObjectDetectionPipeline", "AutomaticSpeechRecognitionPipeline", "ZeroShotClassificationPipeline", "QuestionAnsweringPipeline", "ImageSegmentationPipeline", "pluginEntry", "getPluginPipeline", "createPipelines", "tasks", "pipelines", "result", "i", "compose", "stages", "pipelineInstances", "ensureInitialised", "stage", "pipeline", "input", "instances", "stageResults", "stageTimes", "current", "wallStart", "i", "inst", "t0", "parallel", "s", "stageInput", "init_model_loader", "init_model_loader", "init_types", "DEFAULT_ENDPOINT", "DEFAULT_REVISION", "ONNX_MODEL_FILES", "buildFileUrl", "modelId", "filename", "options", "endpoint", "revision", "subfolder", "fetchWithAuth", "url", "token", "headers", "fileExists", "response", "findOnnxModel", "downloadFile", "loadModelData", "progress", "downloadJson", "isModelCached", "data", "text", "EdgeFlowError", "ErrorCodes", "downloadTokenizer", "Tokenizer", "downloadConfig", "downloadModel", "files", "currentStep", "reportProgress", "file", "baseProgress", "stepProgress", "modelFile", "modelData", "p", "tokenizer", "config", "fromHub", "modelExists", "getModelInfo", "onnxFile", "hasTokenizer", "POPULAR_MODELS", "getDefaultModel", "task", "fromTask", "benchmark", "fn", "options", "warmupRuns", "runs", "verbose", "timeout", "name", "times", "failedRuns", "i", "_", "reject", "start", "end", "error", "sorted", "a", "b", "avg", "variance", "sum", "t", "stdDev", "result", "compareBenchmarks", "baseline", "comparison", "baselineResult", "comparisonResult", "speedup", "percentFaster", "winner", "benchmarkSuite", "suite", "results", "formatBenchmarkResult", "formatComparisonResult", "arrow", "winnerText", "benchmarkMemory", "getMemory", "memoryReadings", "initialMemory", "peakMemory", "avgMemory", "memoryDelta", "init_types", "init_tensor", "calculateQuantParams", "data", "bits", "symmetric", "perChannel", "channelAxis", "shape", "qmin", "qmax", "numChannels", "scales", "zeroPoints", "channelSize", "globalMin", "globalMax", "c", "min", "max", "i", "idx", "val", "absMax", "scale", "zeroPoint", "quantizeToInt8", "result", "s", "zp", "quantizeToUint8", "quantizeToInt4", "packedLength", "val1", "val2", "q1", "q2", "quantizeToFloat16", "float32ToFloat16", "value", "float32View", "int32View", "f", "sign", "exponent", "mantissa", "m", "dequantizeInt8", "dequantizeUint8", "float16ToFloat32", "dequantizeFloat16", "parseModelWeights", "modelData", "weights", "float32Array", "serializeQuantizedModel", "model", "encoder", "totalSize", "weight", "nameBytes", "dtypeBytes", "origDtypeBytes", "buffer", "view", "uint8", "offset", "dim", "dataLow", "dataHigh", "quantizeModel", "options", "type", "skipPatterns", "onProgress", "minTensorSize", "originalSize", "layerStats", "tensorsQuantized", "tensorsSkipped", "quantizedWeights", "totalParams", "quantizedParams", "percent", "pattern", "params", "quantizedData", "quantizedDtype", "scaleValue", "zpValue", "avgScale", "a", "b", "minScale", "maxScale", "errorEstimate", "quantizeTensor", "tensor", "dtype", "EdgeFlowTensor", "dequantizeTensor", "dequantizedData", "scaleArr", "zpArr", "pruneTensor", "ratio", "method", "threshold", "mask", "prunedData", "prunedCount", "absValues", "thresholdIndex", "computedThreshold", "pruneModel", "prunedParams", "sparsity", "analyzeModel", "dtypeBreakdown", "tensorInfos", "bytesPerElement", "size", "largestTensors", "estimatedQuantizedSizes", "recommendedQuantization", "exportModel", "format", "quantize", "calculateTensorStats", "data", "arr", "min", "max", "sum", "zeros", "nans", "infinities", "i", "val", "validCount", "mean", "varianceSum", "std", "createHistogram", "bins", "binWidth", "counts", "binEdges", "binIndex", "e", "inspectTensor", "tensor", "name", "options", "histogram", "maxSample", "shape", "size", "sampleIndices", "step", "sample", "bytesPerElement", "memoryBytes", "formatTensorInspection", "inspection", "dtype", "stats", "lines", "formatBytes", "v", "bytes", "EdgeFlowDebugger", "config", "__publicField", "level", "message", "prefix", "levels", "configLevel", "event", "listeners", "listener", "type", "callback", "idx", "modelId", "id", "trace", "traceId", "t", "operation", "memory", "metrics", "traces", "recentTraces", "globalDebugger", "getDebugger", "enableDebugging", "debugger_", "disableDebugging", "createAsciiHistogram", "width", "height", "maxCount", "scaled", "c", "row", "line", "col", "minLabel", "maxLabel", "createTensorHeatmap", "rows", "cols", "range", "chars", "scaleX", "displayCols", "r", "normalized", "charIdx", "visualizeModelArchitecture", "layers", "layer", "inputStr", "outputStr", "PerformanceMonitor", "config", "__publicField", "now", "elapsed", "avgTime", "a", "b", "minTime", "maxTime", "throughput", "inference", "memory", "system", "custom", "collector", "sample", "listener", "usedHeap", "totalHeap", "heapLimit", "lastSample", "deltaTime", "webgpuAvailable", "webnnAvailable", "totalTime", "alert", "value", "triggered", "event", "metric", "parts", "part", "duration", "length", "count", "bytes", "callback", "idx", "startTime", "endTime", "s", "avgInferenceTime", "sum", "avgThroughput", "avgMemoryUsage", "avgFPS", "totalInferences", "firstSample", "uptime", "generateDashboardHTML", "monitor", "summary", "samples", "formatBytes", "ms", "generateChartPath", "width", "height", "padding", "times", "points", "i", "x", "y", "linePath", "areaPath", "gridLines", "generateAsciiDashboard", "bar", "max", "filled", "lines", "recentSamples", "chartHeight", "row", "line", "time", "globalMonitor", "getMonitor", "startMonitoring", "stopMonitoring", "quantize", "model", "options", "modelData", "getModelData", "originalSize", "quantizedData", "layersQuantized", "layersSkipped", "quantizeInt8", "quantizeUint8", "quantizeFloat16", "quantizeInt4", "_model", "data", "_options", "input", "output", "max", "i", "abs", "scale", "min", "val", "float32ToFloat16", "val1", "val2", "value", "floatView", "int32View", "x", "bits", "m", "e", "prune", "weights", "total", "sorted", "a", "b", "thresholdIdx", "threshold", "pruned", "analyzeModel", "size", "estimatedParams", "benchmark", "runFn", "warmupRuns", "runs", "times", "start", "avgTime", "minTime", "maxTime", "avgSquaredDiff", "t", "stdDev", "exportModel", "format", "array", "isSupported", "runtimes", "getAvailableRuntimes", "v", "getBestRuntimeType", "preload", "models", "cache", "ModelDownloadCache", "url", "response", "VERSION", "getInfo"]
|
|
4
|
+
"sourcesContent": ["/**\n * edgeFlow.js - Core Type Definitions\n * \n * This file contains all the core types used throughout the framework.\n */\n\n// ============================================================================\n// Tensor Types\n// ============================================================================\n\n/**\n * Supported data types for tensors\n */\nexport type DataType = \n | 'float32' \n | 'float16' \n | 'int32' \n | 'int64' \n | 'uint8' \n | 'int8' \n | 'bool';\n\n/**\n * TypedArray types used for tensor data\n */\nexport type TypedArray = \n | Float32Array \n | Float64Array \n | Int32Array \n | BigInt64Array \n | Uint8Array \n | Int8Array;\n\n/**\n * Tensor shape definition\n */\nexport type Shape = readonly number[];\n\n/**\n * Tensor interface\n */\nexport interface Tensor {\n /** Unique identifier for the tensor */\n readonly id: string;\n /** Data type of the tensor */\n readonly dtype: DataType;\n /** Shape of the tensor */\n readonly shape: Shape;\n /** Total number of elements */\n readonly size: number;\n /** Underlying data */\n readonly data: TypedArray;\n /** Get data as Float32Array */\n toFloat32Array(): Float32Array;\n /** Get data as array */\n toArray(): number[];\n /** Clone the tensor */\n clone(): Tensor;\n /** Dispose the tensor and free memory */\n dispose(): void;\n /** Check if tensor has been disposed */\n readonly isDisposed: boolean;\n}\n\n// ============================================================================\n// Runtime Types\n// ============================================================================\n\n/**\n * Supported runtime backends\n */\nexport type RuntimeType = 'webgpu' | 'webnn' | 'wasm' | 'auto';\n\n/**\n * Runtime capability flags\n */\nexport interface RuntimeCapabilities {\n /** Supports concurrent execution */\n concurrency: boolean;\n /** Supports quantized models */\n quantization: boolean;\n /** Supports float16 */\n float16: boolean;\n /** Supports dynamic shapes */\n dynamicShapes: boolean;\n /** Maximum batch size */\n maxBatchSize: number;\n /** Available memory in bytes */\n availableMemory: number;\n}\n\n/**\n * Runtime interface that all backends must implement\n */\nexport interface Runtime {\n /** Runtime name */\n readonly name: RuntimeType;\n /** Runtime capabilities */\n readonly capabilities: RuntimeCapabilities;\n /** Initialize the runtime */\n initialize(): Promise<void>;\n /** Check if runtime is available in current environment */\n isAvailable(): Promise<boolean>;\n /** Load a model from ArrayBuffer */\n loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;\n /** Run inference */\n run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;\n /** Run inference with named inputs (optional) */\n runNamed?(model: LoadedModel, namedInputs: Map<string, Tensor>): Promise<Tensor[]>;\n /** Dispose the runtime and free resources */\n dispose(): void;\n}\n\n// ============================================================================\n// Model Types\n// ============================================================================\n\n/**\n * Model format types\n */\nexport type ModelFormat = 'onnx' | 'edgeflow' | 'safetensors';\n\n/**\n * Model quantization types\n */\nexport type QuantizationType = 'float32' | 'float16' | 'int8' | 'uint8' | 'int4';\n\n/**\n * Model metadata\n */\nexport interface ModelMetadata {\n /** Model name/identifier */\n name: string;\n /** Model version */\n version?: string;\n /** Model description */\n description?: string;\n /** Model author */\n author?: string;\n /** Model license */\n license?: string;\n /** Model tags */\n tags?: string[];\n /** Input specifications */\n inputs: ModelIOSpec[];\n /** Output specifications */\n outputs: ModelIOSpec[];\n /** Model size in bytes */\n sizeBytes: number;\n /** Quantization type */\n quantization: QuantizationType;\n /** Model format */\n format: ModelFormat;\n}\n\n/**\n * Model input/output specification\n */\nexport interface ModelIOSpec {\n /** Name of the input/output */\n name: string;\n /** Data type */\n dtype: DataType;\n /** Shape (use -1 for dynamic dimensions) */\n shape: number[];\n /** Optional description */\n description?: string;\n}\n\n/**\n * Options for loading a model\n */\nexport interface ModelLoadOptions {\n /** Target quantization (convert during load) */\n quantization?: QuantizationType;\n /** Custom metadata */\n metadata?: Partial<ModelMetadata>;\n /** Enable caching */\n cache?: boolean;\n /** Progress callback */\n onProgress?: (progress: number) => void;\n}\n\n/**\n * Loaded model instance\n */\nexport interface LoadedModel {\n /** Unique model instance ID */\n readonly id: string;\n /** Model metadata */\n readonly metadata: ModelMetadata;\n /** Check if model is loaded */\n readonly isLoaded: boolean;\n /** Runtime this model is loaded on */\n readonly runtime: RuntimeType;\n /** Dispose the model and free resources */\n dispose(): void;\n}\n\n// ============================================================================\n// Scheduler Types\n// ============================================================================\n\n/**\n * Task priority levels\n */\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'critical';\n\n/**\n * Task status\n */\nexport type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n\n/**\n * Inference task definition\n */\nexport interface InferenceTask<T = unknown> {\n /** Unique task ID */\n readonly id: string;\n /** Model ID this task is for */\n readonly modelId: string;\n /** Task priority */\n readonly priority: TaskPriority;\n /** Task status */\n readonly status: TaskStatus;\n /** Creation timestamp */\n readonly createdAt: number;\n /** Start timestamp (when running) */\n readonly startedAt?: number;\n /** Completion timestamp */\n readonly completedAt?: number;\n /** Task result (when completed) */\n readonly result?: T;\n /** Task error (when failed) */\n readonly error?: Error;\n /** Cancel the task */\n cancel(): void;\n /** Wait for task completion */\n wait(): Promise<T>;\n}\n\n/**\n * Scheduler options\n */\nexport interface SchedulerOptions {\n /** Maximum concurrent tasks across all models */\n maxConcurrentTasks?: number;\n /** Maximum concurrent tasks per model */\n maxConcurrentPerModel?: number;\n /** Default task timeout in milliseconds */\n defaultTimeout?: number;\n /** Enable task batching */\n enableBatching?: boolean;\n /** Maximum batch size */\n maxBatchSize?: number;\n /** Batch timeout in milliseconds */\n batchTimeout?: number;\n /** Maximum retry attempts for failed tasks (default: 0 = no retry) */\n maxRetries?: number;\n /** Base delay between retries in ms (exponential backoff) */\n retryBaseDelay?: number;\n /** Enable circuit breaker per model (default: false) */\n circuitBreaker?: boolean;\n /** Consecutive failures before the circuit opens (default: 5) */\n circuitBreakerThreshold?: number;\n /** Time in ms before the circuit half-opens to test (default: 30000) */\n circuitBreakerResetTimeout?: number;\n}\n\n// ============================================================================\n// Memory Types\n// ============================================================================\n\n/**\n * Memory statistics\n */\nexport interface MemoryStats {\n /** Total allocated memory in bytes */\n allocated: number;\n /** Currently used memory in bytes */\n used: number;\n /** Peak memory usage in bytes */\n peak: number;\n /** Number of active tensors */\n tensorCount: number;\n /** Number of loaded models */\n modelCount: number;\n}\n\n/**\n * Memory pool configuration\n */\nexport interface MemoryPoolConfig {\n /** Initial pool size in bytes */\n initialSize?: number;\n /** Maximum pool size in bytes */\n maxSize?: number;\n /** Growth factor when expanding */\n growthFactor?: number;\n /** Enable automatic garbage collection */\n autoGC?: boolean;\n /** GC threshold (percentage of max size) */\n gcThreshold?: number;\n}\n\n// ============================================================================\n// Pipeline Types\n// ============================================================================\n\n/**\n * Supported pipeline tasks\n */\nexport type PipelineTask = \n | 'text-classification'\n | 'token-classification'\n | 'question-answering'\n | 'fill-mask'\n | 'text-generation'\n | 'text2text-generation'\n | 'summarization'\n | 'translation'\n | 'feature-extraction'\n | 'sentiment-analysis'\n | 'zero-shot-classification'\n | 'image-classification'\n | 'object-detection'\n | 'image-segmentation'\n | 'depth-estimation'\n | 'image-to-text'\n | 'audio-classification'\n | 'automatic-speech-recognition'\n | 'text-to-speech';\n\n/**\n * Pipeline configuration\n */\nexport interface PipelineConfig {\n /** Task type */\n task: PipelineTask;\n /** Model ID or path */\n model: string;\n /** Runtime to use */\n runtime?: RuntimeType;\n /** Enable caching */\n cache?: boolean;\n /** Quantization type */\n quantization?: QuantizationType;\n /** Device to use */\n device?: 'cpu' | 'gpu';\n /** Custom tokenizer config */\n tokenizer?: TokenizerConfig;\n /** Tokenizer URL (e.g. HuggingFace tokenizer.json); overrides the pipeline's default */\n tokenizerUrl?: string;\n}\n\n/**\n * Pipeline options passed during inference\n */\nexport interface PipelineOptions {\n /** Batch size */\n batchSize?: number;\n /** Top K results */\n topK?: number;\n /** Temperature for generation */\n temperature?: number;\n /** Maximum length for generation */\n maxLength?: number;\n /** Task timeout in milliseconds */\n timeout?: number;\n}\n\n// ============================================================================\n// Tokenizer Types\n// ============================================================================\n\n/**\n * Tokenizer configuration\n */\nexport interface TokenizerConfig {\n /** Vocabulary size */\n vocabSize: number;\n /** Maximum sequence length */\n maxLength: number;\n /** Padding token ID */\n padTokenId: number;\n /** Unknown token ID */\n unkTokenId: number;\n /** Start of sequence token ID */\n bosTokenId?: number;\n /** End of sequence token ID */\n eosTokenId?: number;\n /** Separator token ID */\n sepTokenId?: number;\n /** CLS token ID */\n clsTokenId?: number;\n /** Mask token ID */\n maskTokenId?: number;\n}\n\n/**\n * Tokenized output\n */\nexport interface TokenizedOutput {\n /** Input IDs */\n inputIds: number[];\n /** Attention mask */\n attentionMask: number[];\n /** Token type IDs (for segment embeddings) */\n tokenTypeIds?: number[];\n /** Special tokens mask */\n specialTokensMask?: number[];\n /** Offset mapping (for token-level tasks) */\n offsetMapping?: [number, number][];\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * Base error class for edgeFlow errors\n */\nexport class EdgeFlowError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'EdgeFlowError';\n }\n}\n\n/**\n * Error codes\n */\nexport const ErrorCodes = {\n // Runtime errors\n RUNTIME_NOT_AVAILABLE: 'RUNTIME_NOT_AVAILABLE',\n RUNTIME_INIT_FAILED: 'RUNTIME_INIT_FAILED',\n RUNTIME_NOT_INITIALIZED: 'RUNTIME_NOT_INITIALIZED',\n \n // Model errors\n MODEL_NOT_FOUND: 'MODEL_NOT_FOUND',\n MODEL_LOAD_FAILED: 'MODEL_LOAD_FAILED',\n MODEL_INVALID_FORMAT: 'MODEL_INVALID_FORMAT',\n MODEL_NOT_LOADED: 'MODEL_NOT_LOADED',\n \n // Inference errors\n INFERENCE_FAILED: 'INFERENCE_FAILED',\n INFERENCE_TIMEOUT: 'INFERENCE_TIMEOUT',\n INFERENCE_CANCELLED: 'INFERENCE_CANCELLED',\n \n // Memory errors\n OUT_OF_MEMORY: 'OUT_OF_MEMORY',\n MEMORY_LEAK_DETECTED: 'MEMORY_LEAK_DETECTED',\n \n // Tensor errors\n TENSOR_SHAPE_MISMATCH: 'TENSOR_SHAPE_MISMATCH',\n TENSOR_DTYPE_MISMATCH: 'TENSOR_DTYPE_MISMATCH',\n TENSOR_DISPOSED: 'TENSOR_DISPOSED',\n \n // Pipeline errors\n PIPELINE_NOT_SUPPORTED: 'PIPELINE_NOT_SUPPORTED',\n PIPELINE_INPUT_INVALID: 'PIPELINE_INPUT_INVALID',\n \n // General errors\n INVALID_ARGUMENT: 'INVALID_ARGUMENT',\n NOT_IMPLEMENTED: 'NOT_IMPLEMENTED',\n UNKNOWN_ERROR: 'UNKNOWN_ERROR',\n} as const;\n\nexport type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];\n\n// ============================================================================\n// Event Types\n// ============================================================================\n\n/**\n * Event types emitted by edgeFlow\n */\nexport type EventType = \n | 'model:loading'\n | 'model:loaded'\n | 'model:unloaded'\n | 'inference:start'\n | 'inference:complete'\n | 'inference:error'\n | 'memory:warning'\n | 'memory:gc'\n | 'runtime:ready'\n | 'runtime:error';\n\n/**\n * Event payload interface\n */\nexport interface EdgeFlowEvent<T = unknown> {\n type: EventType;\n timestamp: number;\n data: T;\n}\n\n/**\n * Event listener function type\n */\nexport type EventListener<T = unknown> = (event: EdgeFlowEvent<T>) => void;\n", "/**\n * edgeFlow.js - Tensor Implementation\n * \n * Lightweight tensor implementation with efficient memory management.\n */\n\nimport { \n Tensor, \n DataType, \n Shape, \n TypedArray,\n EdgeFlowError,\n ErrorCodes \n} from './types.js';\n\n// Counter for generating unique tensor IDs\nlet tensorIdCounter = 0;\n\n/**\n * Generate a unique tensor ID\n */\nfunction generateTensorId(): string {\n return `tensor_${++tensorIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * Get the typed array constructor for a data type\n */\nfunction getTypedArrayConstructor(dtype: DataType): new (length: number) => TypedArray {\n switch (dtype) {\n case 'float32':\n return Float32Array;\n case 'float16':\n // Float16 not natively supported, use Float32Array\n return Float32Array;\n case 'int32':\n return Int32Array;\n case 'int64':\n return BigInt64Array as unknown as new (length: number) => TypedArray;\n case 'uint8':\n case 'bool':\n return Uint8Array;\n case 'int8':\n return Int8Array;\n default:\n throw new EdgeFlowError(\n `Unsupported data type: ${dtype}`,\n ErrorCodes.INVALID_ARGUMENT,\n { dtype }\n );\n }\n}\n\n/**\n * Calculate the total number of elements from shape\n */\nfunction calculateSize(shape: Shape): number {\n if (shape.length === 0) return 1; // Scalar\n return shape.reduce((acc, dim) => acc * dim, 1);\n}\n\n/**\n * Validate tensor shape\n */\nfunction validateShape(shape: Shape): void {\n for (let i = 0; i < shape.length; i++) {\n const dim = shape[i];\n if (dim === undefined || !Number.isInteger(dim) || dim < 0) {\n throw new EdgeFlowError(\n `Invalid shape dimension at index ${i}: ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { shape, index: i, dimension: dim }\n );\n }\n }\n}\n\n/**\n * EdgeFlowTensor - Core tensor implementation\n */\nexport class EdgeFlowTensor implements Tensor {\n readonly id: string;\n readonly dtype: DataType;\n readonly shape: Shape;\n readonly size: number;\n private _data: TypedArray;\n private _isDisposed: boolean = false;\n\n constructor(\n data: TypedArray | number[],\n shape: Shape,\n dtype: DataType = 'float32'\n ) {\n validateShape(shape);\n \n this.id = generateTensorId();\n this.dtype = dtype;\n this.shape = Object.freeze([...shape]) as Shape;\n this.size = calculateSize(this.shape);\n\n // Validate data size matches shape\n const expectedSize = this.size;\n if (data.length !== expectedSize) {\n throw new EdgeFlowError(\n `Data length (${data.length}) does not match shape ${JSON.stringify(shape)} (expected ${expectedSize})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { dataLength: data.length, expectedSize, shape }\n );\n }\n\n // Convert to appropriate typed array\n if (data instanceof Array) {\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n this._data = new TypedArrayCtor(data.length);\n \n if (dtype === 'int64') {\n // BigInt64Array requires BigInt values\n const bigIntData = this._data as unknown as BigInt64Array;\n for (let i = 0; i < data.length; i++) {\n bigIntData[i] = BigInt(Math.round(data[i] ?? 0));\n }\n } else {\n for (let i = 0; i < data.length; i++) {\n (this._data as Float32Array)[i] = data[i] ?? 0;\n }\n }\n } else {\n this._data = data;\n }\n }\n\n get data(): TypedArray {\n this.checkDisposed();\n return this._data;\n }\n\n get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n /**\n * Check if tensor has been disposed\n */\n private checkDisposed(): void {\n if (this._isDisposed) {\n throw new EdgeFlowError(\n 'Cannot access disposed tensor',\n ErrorCodes.TENSOR_DISPOSED,\n { tensorId: this.id }\n );\n }\n }\n\n /**\n * Convert to Float32Array\n */\n toFloat32Array(): Float32Array {\n this.checkDisposed();\n \n if (this._data instanceof Float32Array) {\n return this._data;\n }\n \n const result = new Float32Array(this.size);\n for (let i = 0; i < this.size; i++) {\n result[i] = Number(this._data[i] ?? 0);\n }\n return result;\n }\n\n /**\n * Convert to regular array\n */\n toArray(): number[] {\n this.checkDisposed();\n if (this.dtype === 'int64') {\n // BigInt64Array needs special handling\n const bigIntData = this._data as unknown as BigInt64Array;\n const result: number[] = [];\n for (let i = 0; i < bigIntData.length; i++) {\n result.push(Number(bigIntData[i]));\n }\n return result;\n }\n return Array.from(this._data as Float32Array);\n }\n\n /**\n * Clone the tensor\n */\n clone(): EdgeFlowTensor {\n this.checkDisposed();\n \n const TypedArrayCtor = this._data.constructor as new (data: TypedArray) => TypedArray;\n const clonedData = new TypedArrayCtor(this._data);\n return new EdgeFlowTensor(clonedData, this.shape, this.dtype);\n }\n\n /**\n * Dispose the tensor and free memory\n */\n dispose(): void {\n if (!this._isDisposed) {\n this._isDisposed = true;\n // Help garbage collection - use Object.assign to avoid type issues\n Object.assign(this, { _data: null });\n }\n }\n\n /**\n * Get value at specific indices\n */\n get(...indices: number[]): number {\n this.checkDisposed();\n \n if (indices.length !== this.shape.length) {\n throw new EdgeFlowError(\n `Expected ${this.shape.length} indices, got ${indices.length}`,\n ErrorCodes.INVALID_ARGUMENT,\n { expectedIndices: this.shape.length, gotIndices: indices.length }\n );\n }\n\n let flatIndex = 0;\n let stride = 1;\n \n for (let i = this.shape.length - 1; i >= 0; i--) {\n const idx = indices[i] ?? 0;\n const dim = this.shape[i] ?? 1;\n \n if (idx < 0 || idx >= dim) {\n throw new EdgeFlowError(\n `Index ${idx} out of bounds for dimension ${i} with size ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { index: idx, dimension: i, size: dim }\n );\n }\n \n flatIndex += idx * stride;\n stride *= dim;\n }\n\n return Number(this._data[flatIndex] ?? 0);\n }\n\n /**\n * Set value at specific indices\n */\n set(value: number, ...indices: number[]): void {\n this.checkDisposed();\n \n if (indices.length !== this.shape.length) {\n throw new EdgeFlowError(\n `Expected ${this.shape.length} indices, got ${indices.length}`,\n ErrorCodes.INVALID_ARGUMENT,\n { expectedIndices: this.shape.length, gotIndices: indices.length }\n );\n }\n\n let flatIndex = 0;\n let stride = 1;\n \n for (let i = this.shape.length - 1; i >= 0; i--) {\n const idx = indices[i] ?? 0;\n const dim = this.shape[i] ?? 1;\n \n if (idx < 0 || idx >= dim) {\n throw new EdgeFlowError(\n `Index ${idx} out of bounds for dimension ${i} with size ${dim}`,\n ErrorCodes.INVALID_ARGUMENT,\n { index: idx, dimension: i, size: dim }\n );\n }\n \n flatIndex += idx * stride;\n stride *= dim;\n }\n\n (this._data as Float32Array)[flatIndex] = value;\n }\n\n /**\n * Reshape the tensor (returns new tensor)\n */\n reshape(newShape: Shape): EdgeFlowTensor {\n this.checkDisposed();\n \n const newSize = calculateSize(newShape);\n if (newSize !== this.size) {\n throw new EdgeFlowError(\n `Cannot reshape tensor of size ${this.size} to shape ${JSON.stringify(newShape)} (size ${newSize})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { currentSize: this.size, newSize, newShape }\n );\n }\n\n const TypedArrayCtor = this._data.constructor as new (data: TypedArray) => TypedArray;\n const clonedData = new TypedArrayCtor(this._data);\n return new EdgeFlowTensor(clonedData, newShape, this.dtype);\n }\n\n /**\n * Transpose the tensor (2D only for now)\n */\n transpose(): EdgeFlowTensor {\n this.checkDisposed();\n \n if (this.shape.length !== 2) {\n throw new EdgeFlowError(\n 'Transpose is currently only supported for 2D tensors',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: this.shape }\n );\n }\n\n const [rows, cols] = this.shape as [number, number];\n const result = new Float32Array(this.size);\n \n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n result[j * rows + i] = Number(this._data[i * cols + j] ?? 0);\n }\n }\n\n return new EdgeFlowTensor(result, [cols, rows], this.dtype);\n }\n\n /**\n * Create string representation\n */\n toString(): string {\n return `Tensor(shape=[${this.shape.join(', ')}], dtype=${this.dtype})`;\n }\n}\n\n// ============================================================================\n// Tensor Factory Functions\n// ============================================================================\n\n/**\n * Create a tensor from data\n */\nexport function tensor(\n data: TypedArray | number[] | number[][],\n shape?: Shape,\n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n // Handle nested arrays\n if (Array.isArray(data) && data.length > 0 && Array.isArray(data[0])) {\n const rows = data.length;\n const cols = (data[0] as number[]).length;\n const flatData: number[] = [];\n \n for (const row of data as number[][]) {\n if (row.length !== cols) {\n throw new EdgeFlowError(\n 'Nested arrays must have consistent dimensions',\n ErrorCodes.INVALID_ARGUMENT\n );\n }\n flatData.push(...row);\n }\n \n return new EdgeFlowTensor(flatData, shape ?? [rows, cols], dtype);\n }\n\n // Infer shape if not provided\n const inferredShape = shape ?? [data.length];\n return new EdgeFlowTensor(data as TypedArray | number[], inferredShape, dtype);\n}\n\n/**\n * Create a tensor filled with zeros\n */\nexport function zeros(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor filled with ones\n */\nexport function ones(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n data.fill(1 as never);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor filled with a specific value\n */\nexport function full(\n shape: Shape, \n value: number, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n const size = calculateSize(shape);\n const TypedArrayCtor = getTypedArrayConstructor(dtype);\n const data = new TypedArrayCtor(size);\n data.fill(value as never);\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor with random values between 0 and 1\n */\nexport function random(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const data = new Float32Array(size);\n for (let i = 0; i < size; i++) {\n data[i] = Math.random();\n }\n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a tensor with random values from normal distribution\n */\nexport function randn(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {\n const size = calculateSize(shape);\n const data = new Float32Array(size);\n \n // Box-Muller transform for normal distribution\n for (let i = 0; i < size; i += 2) {\n const u1 = Math.random();\n const u2 = Math.random();\n const r = Math.sqrt(-2 * Math.log(u1));\n const theta = 2 * Math.PI * u2;\n \n data[i] = r * Math.cos(theta);\n if (i + 1 < size) {\n data[i + 1] = r * Math.sin(theta);\n }\n }\n \n return new EdgeFlowTensor(data, shape, dtype);\n}\n\n/**\n * Create a 1D tensor with evenly spaced values\n */\nexport function arange(\n start: number, \n stop?: number, \n step: number = 1, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n if (stop === undefined) {\n stop = start;\n start = 0;\n }\n \n const size = Math.ceil((stop - start) / step);\n const data = new Float32Array(size);\n \n for (let i = 0; i < size; i++) {\n data[i] = start + i * step;\n }\n \n return new EdgeFlowTensor(data, [size], dtype);\n}\n\n/**\n * Create a 1D tensor with evenly spaced values (specify number of points)\n */\nexport function linspace(\n start: number, \n stop: number, \n num: number = 50, \n dtype: DataType = 'float32'\n): EdgeFlowTensor {\n const data = new Float32Array(num);\n const step = (stop - start) / (num - 1);\n \n for (let i = 0; i < num; i++) {\n data[i] = start + i * step;\n }\n \n return new EdgeFlowTensor(data, [num], dtype);\n}\n\n/**\n * Create an identity matrix\n */\nexport function eye(n: number, dtype: DataType = 'float32'): EdgeFlowTensor {\n const data = new Float32Array(n * n);\n \n for (let i = 0; i < n; i++) {\n data[i * n + i] = 1;\n }\n \n return new EdgeFlowTensor(data, [n, n], dtype);\n}\n\n// ============================================================================\n// Tensor Operations\n// ============================================================================\n\n/**\n * Element-wise addition\n */\nexport function add(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) + b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) + (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise subtraction\n */\nexport function sub(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) - b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) - (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise multiplication\n */\nexport function mul(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) * b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) * (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Element-wise division\n */\nexport function div(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTensor {\n if (typeof b === 'number') {\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) / b;\n }\n return new EdgeFlowTensor(result, a.shape, a.dtype);\n }\n\n if (a.size !== b.size) {\n throw new EdgeFlowError(\n 'Tensor sizes must match for element-wise operations',\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(a.size);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n \n for (let i = 0; i < a.size; i++) {\n result[i] = (aData[i] ?? 0) / (bData[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, a.shape, a.dtype);\n}\n\n/**\n * Matrix multiplication (2D tensors)\n */\nexport function matmul(a: EdgeFlowTensor, b: EdgeFlowTensor): EdgeFlowTensor {\n if (a.shape.length !== 2 || b.shape.length !== 2) {\n throw new EdgeFlowError(\n 'matmul requires 2D tensors',\n ErrorCodes.INVALID_ARGUMENT,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const [m, k1] = a.shape as [number, number];\n const [k2, n] = b.shape as [number, number];\n\n if (k1 !== k2) {\n throw new EdgeFlowError(\n `Matrix dimensions incompatible for multiplication: (${m}x${k1}) @ (${k2}x${n})`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH,\n { aShape: a.shape, bShape: b.shape }\n );\n }\n\n const result = new Float32Array(m * n);\n const aData = a.toFloat32Array();\n const bData = b.toFloat32Array();\n\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n let sum = 0;\n for (let k = 0; k < k1; k++) {\n sum += (aData[i * k1 + k] ?? 0) * (bData[k * n + j] ?? 0);\n }\n result[i * n + j] = sum;\n }\n }\n\n return new EdgeFlowTensor(result, [m, n], a.dtype);\n}\n\n/**\n * Softmax activation\n */\nexport function softmax(t: EdgeFlowTensor, axis: number = -1): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n if (actualAxis < 0 || actualAxis >= t.shape.length) {\n throw new EdgeFlowError(\n `Invalid axis ${axis} for tensor with ${t.shape.length} dimensions`,\n ErrorCodes.INVALID_ARGUMENT,\n { axis, shape: t.shape }\n );\n }\n\n // For 1D tensors\n if (t.shape.length === 1) {\n let max = -Infinity;\n for (let i = 0; i < t.size; i++) {\n if ((data[i] ?? 0) > max) max = data[i] ?? 0;\n }\n \n let sum = 0;\n for (let i = 0; i < t.size; i++) {\n result[i] = Math.exp((data[i] ?? 0) - max);\n sum += result[i] ?? 0;\n }\n \n for (let i = 0; i < t.size; i++) {\n result[i] = (result[i] ?? 0) / sum;\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n }\n\n // For 2D tensors along last axis\n if (t.shape.length === 2 && actualAxis === 1) {\n const [rows, cols] = t.shape as [number, number];\n \n for (let i = 0; i < rows; i++) {\n let max = -Infinity;\n for (let j = 0; j < cols; j++) {\n if ((data[i * cols + j] ?? 0) > max) max = data[i * cols + j] ?? 0;\n }\n \n let sum = 0;\n for (let j = 0; j < cols; j++) {\n result[i * cols + j] = Math.exp((data[i * cols + j] ?? 0) - max);\n sum += result[i * cols + j] ?? 0;\n }\n \n for (let j = 0; j < cols; j++) {\n result[i * cols + j] = (result[i * cols + j] ?? 0) / sum;\n }\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n }\n\n throw new EdgeFlowError(\n 'Softmax currently only supports 1D tensors or 2D tensors along the last axis',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * ReLU activation\n */\nexport function relu(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = Math.max(0, data[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Sigmoid activation\n */\nexport function sigmoid(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = 1 / (1 + Math.exp(-(data[i] ?? 0)));\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Tanh activation\n */\nexport function tanh(t: EdgeFlowTensor): EdgeFlowTensor {\n const data = t.toFloat32Array();\n const result = new Float32Array(t.size);\n \n for (let i = 0; i < t.size; i++) {\n result[i] = Math.tanh(data[i] ?? 0);\n }\n \n return new EdgeFlowTensor(result, t.shape, t.dtype);\n}\n\n/**\n * Sum all elements or along an axis\n */\nexport function sum(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {\n const data = t.toFloat32Array();\n \n if (axis === undefined) {\n let total = 0;\n for (let i = 0; i < t.size; i++) {\n total += data[i] ?? 0;\n }\n return total;\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n if (actualAxis < 0 || actualAxis >= t.shape.length) {\n throw new EdgeFlowError(\n `Invalid axis ${axis} for tensor with ${t.shape.length} dimensions`,\n ErrorCodes.INVALID_ARGUMENT,\n { axis, shape: t.shape }\n );\n }\n\n // Calculate new shape\n const newShape = [...t.shape];\n newShape.splice(actualAxis, 1);\n \n if (newShape.length === 0) {\n let total = 0;\n for (let i = 0; i < t.size; i++) {\n total += data[i] ?? 0;\n }\n return total;\n }\n\n // For 2D sum along axis\n if (t.shape.length === 2) {\n const [rows, cols] = t.shape as [number, number];\n \n if (actualAxis === 0) {\n const result = new Float32Array(cols);\n for (let j = 0; j < cols; j++) {\n for (let i = 0; i < rows; i++) {\n result[j] = (result[j] ?? 0) + (data[i * cols + j] ?? 0);\n }\n }\n return new EdgeFlowTensor(result, [cols], t.dtype);\n } else {\n const result = new Float32Array(rows);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n result[i] = (result[i] ?? 0) + (data[i * cols + j] ?? 0);\n }\n }\n return new EdgeFlowTensor(result, [rows], t.dtype);\n }\n }\n\n throw new EdgeFlowError(\n 'Sum along axis currently only supports up to 2D tensors',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * Mean of all elements or along an axis\n */\nexport function mean(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {\n if (axis === undefined) {\n return (sum(t) as number) / t.size;\n }\n\n const result = sum(t, axis);\n if (typeof result === 'number') {\n return result / (t.shape[axis] ?? 1);\n }\n\n const axisSize = t.shape[axis] ?? 1;\n return div(result, axisSize);\n}\n\n/**\n * Argmax - return index of maximum value\n */\nexport function argmax(t: EdgeFlowTensor, axis?: number): number | EdgeFlowTensor {\n const data = t.toFloat32Array();\n \n if (axis === undefined) {\n let maxIdx = 0;\n let maxVal = data[0] ?? -Infinity;\n \n for (let i = 1; i < t.size; i++) {\n if ((data[i] ?? -Infinity) > maxVal) {\n maxVal = data[i] ?? -Infinity;\n maxIdx = i;\n }\n }\n return maxIdx;\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? t.shape.length + axis : axis;\n \n // For 2D along last axis\n if (t.shape.length === 2 && actualAxis === 1) {\n const [rows, cols] = t.shape as [number, number];\n const result = new Float32Array(rows);\n \n for (let i = 0; i < rows; i++) {\n let maxIdx = 0;\n let maxVal = data[i * cols] ?? -Infinity;\n \n for (let j = 1; j < cols; j++) {\n if ((data[i * cols + j] ?? -Infinity) > maxVal) {\n maxVal = data[i * cols + j] ?? -Infinity;\n maxIdx = j;\n }\n }\n result[i] = maxIdx;\n }\n \n return new EdgeFlowTensor(result, [rows], 'int32');\n }\n\n throw new EdgeFlowError(\n 'Argmax along axis currently only supports 2D tensors along the last axis',\n ErrorCodes.NOT_IMPLEMENTED,\n { shape: t.shape, axis }\n );\n}\n\n/**\n * Concatenate tensors along an axis\n */\nexport function concat(tensors: EdgeFlowTensor[], axis: number = 0): EdgeFlowTensor {\n if (tensors.length === 0) {\n throw new EdgeFlowError(\n 'Cannot concatenate empty array of tensors',\n ErrorCodes.INVALID_ARGUMENT\n );\n }\n\n if (tensors.length === 1) {\n return tensors[0]?.clone() ?? zeros([0]);\n }\n\n const first = tensors[0];\n if (!first) {\n throw new EdgeFlowError('First tensor is undefined', ErrorCodes.INVALID_ARGUMENT);\n }\n\n // Handle negative axis\n const actualAxis = axis < 0 ? first.shape.length + axis : axis;\n\n // Validate shapes\n for (let i = 1; i < tensors.length; i++) {\n const t = tensors[i];\n if (!t) continue;\n \n if (t.shape.length !== first.shape.length) {\n throw new EdgeFlowError(\n 'All tensors must have the same number of dimensions',\n ErrorCodes.TENSOR_SHAPE_MISMATCH\n );\n }\n \n for (let j = 0; j < first.shape.length; j++) {\n if (j !== actualAxis && first.shape[j] !== t.shape[j]) {\n throw new EdgeFlowError(\n `Shape mismatch at dimension ${j}`,\n ErrorCodes.TENSOR_SHAPE_MISMATCH\n );\n }\n }\n }\n\n // Calculate new shape\n const newShape = [...first.shape];\n let totalAxisSize = 0;\n for (const t of tensors) {\n if (t) totalAxisSize += t.shape[actualAxis] ?? 0;\n }\n newShape[actualAxis] = totalAxisSize;\n\n // For 1D concatenation\n if (first.shape.length === 1) {\n const result = new Float32Array(totalAxisSize);\n let offset = 0;\n \n for (const t of tensors) {\n if (!t) continue;\n result.set(t.toFloat32Array(), offset);\n offset += t.size;\n }\n \n return new EdgeFlowTensor(result, newShape, first.dtype);\n }\n\n throw new EdgeFlowError(\n 'Concatenation currently only supports 1D tensors',\n ErrorCodes.NOT_IMPLEMENTED\n );\n}\n", "/**\n * edgeFlow.js - Advanced Model Loader\n * \n * Features:\n * - Preloading: Background model loading\n * - Sharding: Split large files into chunks for download\n * - Resume Download: Continue download from where it left off\n * - Model Caching: IndexedDB storage for large models\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Download progress information\n */\nexport interface DownloadProgress {\n /** Downloaded bytes */\n loaded: number;\n /** Total bytes (0 if unknown) */\n total: number;\n /** Progress percentage (0-100) */\n percent: number;\n /** Download speed in bytes/sec */\n speed: number;\n /** Estimated time remaining in ms */\n eta: number;\n /** Current chunk index (for sharded downloads) */\n currentChunk?: number;\n /** Total chunks (for sharded downloads) */\n totalChunks?: number;\n}\n\n/**\n * Model loader options\n */\nexport interface ModelLoaderOptions {\n /** Enable caching (default: true) */\n cache?: boolean;\n /** Cache name for IndexedDB (default: 'edgeflow-models') */\n cacheName?: string;\n /** Enable resume download (default: true) */\n resumable?: boolean;\n /** Chunk size for sharded downloads in bytes (default: 5MB) */\n chunkSize?: number;\n /** Progress callback */\n onProgress?: (progress: DownloadProgress) => void;\n /** Number of parallel download connections (default: 4) */\n parallelConnections?: number;\n /** Request timeout in ms (default: 30000) */\n timeout?: number;\n /** Force re-download even if cached */\n forceDownload?: boolean;\n}\n\n/**\n * Preload options\n */\nexport interface PreloadOptions extends ModelLoaderOptions {\n /** Priority (higher = more important, default: 0) */\n priority?: number;\n}\n\n/**\n * Cached model metadata\n */\ninterface CachedModelMeta {\n url: string;\n size: number;\n etag?: string;\n lastModified?: string;\n cachedAt: number;\n chunks?: number;\n complete: boolean;\n}\n\n/**\n * Download state for resume support\n */\ninterface DownloadState {\n url: string;\n totalSize: number;\n downloadedSize: number;\n chunks: ChunkState[];\n startedAt: number;\n}\n\n/**\n * Chunk state\n */\ninterface ChunkState {\n index: number;\n start: number;\n end: number;\n downloaded: boolean;\n}\n\n// ============================================================================\n// IndexedDB Model Cache\n// ============================================================================\n\nconst DB_NAME = 'edgeflow-model-cache';\nconst DB_VERSION = 1;\nconst STORE_META = 'meta';\nconst STORE_CHUNKS = 'chunks';\nconst STORE_STATE = 'download-state';\n\n/**\n * IndexedDB-based model cache for large files\n */\nclass ModelCache {\n private db: IDBDatabase | null = null;\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n /**\n * Open the database\n */\n private async openDB(): Promise<IDBDatabase> {\n if (this.db) return this.db;\n if (this.dbPromise) return this.dbPromise;\n\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n \n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result;\n \n // Model metadata store\n if (!db.objectStoreNames.contains(STORE_META)) {\n db.createObjectStore(STORE_META, { keyPath: 'url' });\n }\n \n // Chunk data store\n if (!db.objectStoreNames.contains(STORE_CHUNKS)) {\n const chunkStore = db.createObjectStore(STORE_CHUNKS, { keyPath: ['url', 'index'] });\n chunkStore.createIndex('url', 'url', { unique: false });\n }\n \n // Download state store (for resume)\n if (!db.objectStoreNames.contains(STORE_STATE)) {\n db.createObjectStore(STORE_STATE, { keyPath: 'url' });\n }\n };\n\n request.onsuccess = () => {\n this.db = request.result;\n resolve(this.db);\n };\n\n request.onerror = () => reject(request.error);\n });\n\n return this.dbPromise;\n }\n\n /**\n * Get cached model metadata\n */\n async getMeta(url: string): Promise<CachedModelMeta | null> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(url);\n request.onsuccess = () => resolve(request.result ?? null);\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Save model metadata (with quota error handling)\n */\n async saveMeta(meta: CachedModelMeta): Promise<void> {\n try {\n await this.putInStore(STORE_META, meta);\n } catch (err) {\n if (this.isQuotaError(err)) {\n await this.evictOldest(meta.size);\n try {\n await this.putInStore(STORE_META, meta);\n } catch {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded even after eviction; skipping cache.');\n }\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Save a chunk (with quota error handling)\n */\n async saveChunk(url: string, index: number, data: ArrayBuffer): Promise<void> {\n try {\n await this.putInStore(STORE_CHUNKS, { url, index, data });\n } catch (err) {\n if (this.isQuotaError(err)) {\n await this.evictOldest(data.byteLength);\n try {\n await this.putInStore(STORE_CHUNKS, { url, index, data });\n } catch {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded even after eviction; skipping cache for chunk.');\n }\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Generic put helper\n */\n private async putInStore(storeName: string, value: unknown): Promise<void> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n store.put(value);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n /**\n * Detect IndexedDB quota exceeded errors\n */\n private isQuotaError(err: unknown): boolean {\n if (err instanceof DOMException) {\n return err.name === 'QuotaExceededError' || err.code === 22;\n }\n return false;\n }\n\n /**\n * Evict oldest cached models to free space.\n * Deletes models by ascending `cachedAt` until at least `bytesNeeded` is freed.\n */\n async evictOldest(bytesNeeded: number): Promise<void> {\n const db = await this.openDB();\n const allMeta: CachedModelMeta[] = await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.getAll();\n request.onsuccess = () => resolve(request.result ?? []);\n request.onerror = () => reject(request.error);\n });\n\n allMeta.sort((a, b) => a.cachedAt - b.cachedAt);\n\n let freed = 0;\n for (const meta of allMeta) {\n if (freed >= bytesNeeded) break;\n await this.deleteModel(meta.url);\n freed += meta.size;\n }\n }\n\n /**\n * Get all chunks for a URL\n */\n async getChunks(url: string): Promise<ArrayBuffer[]> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_CHUNKS, 'readonly');\n const store = tx.objectStore(STORE_CHUNKS);\n const index = store.index('url');\n const request = index.getAll(url);\n \n request.onsuccess = () => {\n const results = request.result as Array<{ url: string; index: number; data: ArrayBuffer }>;\n // Sort by index and extract data\n results.sort((a, b) => a.index - b.index);\n resolve(results.map(r => r.data));\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Get complete model data (merged chunks)\n */\n async getModel(url: string): Promise<ArrayBuffer | null> {\n const meta = await this.getMeta(url);\n if (!meta || !meta.complete) return null;\n\n const chunks = await this.getChunks(url);\n if (chunks.length === 0) return null;\n\n // Merge chunks\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n \n for (const chunk of chunks) {\n result.set(new Uint8Array(chunk), offset);\n offset += chunk.byteLength;\n }\n\n return result.buffer;\n }\n\n /**\n * Save download state (for resume, with quota handling)\n */\n async saveDownloadState(state: DownloadState): Promise<void> {\n try {\n await this.putInStore(STORE_STATE, state);\n } catch (err) {\n if (this.isQuotaError(err)) {\n console.warn('[edgeFlow.js] IndexedDB quota exceeded saving download state; resume may not work.');\n } else {\n throw err;\n }\n }\n }\n\n /**\n * Get download state\n */\n async getDownloadState(url: string): Promise<DownloadState | null> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_STATE, 'readonly');\n const store = tx.objectStore(STORE_STATE);\n const request = store.get(url);\n request.onsuccess = () => resolve(request.result ?? null);\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Delete download state\n */\n async deleteDownloadState(url: string): Promise<void> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_STATE, 'readwrite');\n const store = tx.objectStore(STORE_STATE);\n store.delete(url);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n /**\n * Delete cached model\n */\n async deleteModel(url: string): Promise<void> {\n const db = await this.openDB();\n \n // Delete metadata\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.delete(url);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n\n // Delete chunks\n const chunks = await this.getChunks(url);\n if (chunks.length > 0) {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_CHUNKS, 'readwrite');\n const store = tx.objectStore(STORE_CHUNKS);\n const index = store.index('url');\n const request = index.openCursor(IDBKeyRange.only(url));\n \n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;\n if (cursor) {\n cursor.delete();\n cursor.continue();\n }\n };\n \n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // Delete download state\n await this.deleteDownloadState(url);\n }\n\n /**\n * Clear all cached models\n */\n async clear(): Promise<void> {\n const db = await this.openDB();\n \n const stores = [STORE_META, STORE_CHUNKS, STORE_STATE];\n for (const storeName of stores) {\n await new Promise<void>((resolve, reject) => {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n store.clear();\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n }\n\n /**\n * Get cache statistics\n */\n async getStats(): Promise<{ models: number; totalSize: number }> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.getAll();\n \n request.onsuccess = () => {\n const metas = request.result as CachedModelMeta[];\n resolve({\n models: metas.filter(m => m.complete).length,\n totalSize: metas.reduce((sum, m) => sum + (m.complete ? m.size : 0), 0),\n });\n };\n request.onerror = () => reject(request.error);\n });\n }\n}\n\n// Global cache instance\nconst modelCache = new ModelCache();\n\n// ============================================================================\n// Advanced Model Loader\n// ============================================================================\n\n/**\n * Check if server supports Range requests\n */\nasync function supportsRangeRequests(url: string): Promise<{ supports: boolean; size: number; etag?: string }> {\n try {\n const response = await fetch(url, { method: 'HEAD' });\n const acceptRanges = response.headers.get('Accept-Ranges');\n const contentLength = response.headers.get('Content-Length');\n const etag = response.headers.get('ETag') ?? undefined;\n \n return {\n supports: acceptRanges === 'bytes',\n size: contentLength ? parseInt(contentLength, 10) : 0,\n etag,\n };\n } catch {\n return { supports: false, size: 0 };\n }\n}\n\n/**\n * Download a single chunk using Range request\n */\nasync function downloadChunk(\n url: string,\n start: number,\n end: number,\n timeout: number\n): Promise<ArrayBuffer> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n headers: { Range: `bytes=${start}-${end}` },\n signal: controller.signal,\n });\n\n if (response.status !== 206 && response.status !== 200) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return await response.arrayBuffer();\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n/**\n * Download model with sharding and resume support\n */\nasync function downloadWithResume(\n url: string,\n options: ModelLoaderOptions\n): Promise<ArrayBuffer> {\n const {\n chunkSize = 5 * 1024 * 1024, // 5MB\n parallelConnections = 4,\n timeout = 30000,\n onProgress,\n } = options;\n\n // Check server capabilities\n const { supports: supportsRange, size: totalSize, etag } = await supportsRangeRequests(url);\n\n // If no Range support or small file, download normally\n if (!supportsRange || totalSize < chunkSize * 2) {\n return downloadSimple(url, timeout, onProgress);\n }\n\n // Check for existing download state\n let state = await modelCache.getDownloadState(url);\n \n // Initialize or reset state if needed\n if (!state || (etag && state.totalSize !== totalSize)) {\n const numChunks = Math.ceil(totalSize / chunkSize);\n const chunks: ChunkState[] = [];\n \n for (let i = 0; i < numChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize - 1, totalSize - 1);\n chunks.push({ index: i, start, end, downloaded: false });\n }\n \n state = {\n url,\n totalSize,\n downloadedSize: 0,\n chunks,\n startedAt: Date.now(),\n };\n \n // Clear any existing chunks\n await modelCache.deleteModel(url);\n }\n\n // Download remaining chunks\n const pendingChunks = state.chunks.filter(c => !c.downloaded);\n let downloadedSize = state.downloadedSize;\n const startTime = Date.now();\n let lastProgressTime = startTime;\n let lastDownloadedSize = downloadedSize;\n\n // Progress tracking\n const reportProgress = () => {\n if (!onProgress) return;\n \n const now = Date.now();\n const elapsed = (now - lastProgressTime) / 1000;\n const bytesDownloaded = downloadedSize - lastDownloadedSize;\n const speed = elapsed > 0 ? bytesDownloaded / elapsed : 0;\n const remaining = totalSize - downloadedSize;\n const eta = speed > 0 ? (remaining / speed) * 1000 : 0;\n\n onProgress({\n loaded: downloadedSize,\n total: totalSize,\n percent: (downloadedSize / totalSize) * 100,\n speed,\n eta,\n currentChunk: state!.chunks.filter(c => c.downloaded).length,\n totalChunks: state!.chunks.length,\n });\n\n lastProgressTime = now;\n lastDownloadedSize = downloadedSize;\n };\n\n // Download chunks in parallel\n const downloadQueue = [...pendingChunks];\n const inProgress = new Map<number, Promise<void>>();\n\n while (downloadQueue.length > 0 || inProgress.size > 0) {\n // Start new downloads up to parallelConnections limit\n while (downloadQueue.length > 0 && inProgress.size < parallelConnections) {\n const chunk = downloadQueue.shift()!;\n \n const downloadPromise = (async () => {\n try {\n const data = await downloadChunk(url, chunk.start, chunk.end, timeout);\n await modelCache.saveChunk(url, chunk.index, data);\n \n chunk.downloaded = true;\n downloadedSize += data.byteLength;\n \n // Update state periodically\n state!.downloadedSize = downloadedSize;\n await modelCache.saveDownloadState(state!);\n \n reportProgress();\n } finally {\n inProgress.delete(chunk.index);\n }\n })();\n \n inProgress.set(chunk.index, downloadPromise);\n }\n\n // Wait for at least one to complete\n if (inProgress.size > 0) {\n await Promise.race(inProgress.values());\n }\n }\n\n // All chunks downloaded, merge them\n const chunks = await modelCache.getChunks(url);\n const result = new Uint8Array(totalSize);\n let offset = 0;\n \n for (const chunk of chunks) {\n result.set(new Uint8Array(chunk), offset);\n offset += chunk.byteLength;\n }\n\n // Save metadata and cleanup state\n await modelCache.saveMeta({\n url,\n size: totalSize,\n etag,\n cachedAt: Date.now(),\n chunks: chunks.length,\n complete: true,\n });\n await modelCache.deleteDownloadState(url);\n\n return result.buffer;\n}\n\n/**\n * Simple download without sharding\n */\nasync function downloadSimple(\n url: string,\n timeout: number,\n onProgress?: (progress: DownloadProgress) => void\n): Promise<ArrayBuffer> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, { signal: controller.signal });\n \n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('Content-Length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body || !onProgress || total === 0) {\n return await response.arrayBuffer();\n }\n\n // Stream with progress\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n const startTime = Date.now();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n chunks.push(value);\n loaded += value.length;\n\n const elapsed = (Date.now() - startTime) / 1000;\n const speed = elapsed > 0 ? loaded / elapsed : 0;\n const remaining = total - loaded;\n const eta = speed > 0 ? (remaining / speed) * 1000 : 0;\n\n onProgress({\n loaded,\n total,\n percent: (loaded / total) * 100,\n speed,\n eta,\n });\n }\n\n // Merge chunks\n const result = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result.buffer;\n } finally {\n clearTimeout(timeoutId);\n }\n}\n\n// ============================================================================\n// Preload Manager\n// ============================================================================\n\ninterface PreloadTask {\n url: string;\n priority: number;\n options: ModelLoaderOptions;\n promise: Promise<ArrayBuffer>;\n resolve: (data: ArrayBuffer) => void;\n reject: (error: Error) => void;\n status: 'pending' | 'loading' | 'complete' | 'error';\n}\n\n/**\n * Preload manager for background model loading\n */\nclass PreloadManager {\n private tasks: Map<string, PreloadTask> = new Map();\n private queue: string[] = [];\n private maxConcurrent = 2;\n private activeCount = 0;\n\n /**\n * Preload a model in the background\n */\n preload(url: string, options: PreloadOptions = {}): Promise<ArrayBuffer> {\n // Check if already preloading\n const existing = this.tasks.get(url);\n if (existing) {\n return existing.promise;\n }\n\n // Create task\n let resolve!: (data: ArrayBuffer) => void;\n let reject!: (error: Error) => void;\n \n const promise = new Promise<ArrayBuffer>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n const task: PreloadTask = {\n url,\n priority: options.priority ?? 0,\n options,\n promise,\n resolve,\n reject,\n status: 'pending',\n };\n\n this.tasks.set(url, task);\n \n // Insert into queue based on priority\n const insertIndex = this.queue.findIndex(u => {\n const t = this.tasks.get(u);\n return t && t.priority < task.priority;\n });\n \n if (insertIndex === -1) {\n this.queue.push(url);\n } else {\n this.queue.splice(insertIndex, 0, url);\n }\n\n // Process queue\n this.processQueue();\n\n return promise;\n }\n\n /**\n * Process the preload queue\n */\n private async processQueue(): Promise<void> {\n while (this.queue.length > 0 && this.activeCount < this.maxConcurrent) {\n const url = this.queue.shift();\n if (!url) break;\n\n const task = this.tasks.get(url);\n if (!task || task.status !== 'pending') continue;\n\n this.activeCount++;\n task.status = 'loading';\n\n this.downloadTask(task).finally(() => {\n this.activeCount--;\n this.processQueue();\n });\n }\n }\n\n /**\n * Download a preload task\n */\n private async downloadTask(task: PreloadTask): Promise<void> {\n try {\n const data = await loadModelData(task.url, task.options);\n task.status = 'complete';\n task.resolve(data);\n } catch (error) {\n task.status = 'error';\n task.reject(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n /**\n * Check if a model is preloaded\n */\n isPreloaded(url: string): boolean {\n const task = this.tasks.get(url);\n return task?.status === 'complete';\n }\n\n /**\n * Get preload status\n */\n getStatus(url: string): 'pending' | 'loading' | 'complete' | 'error' | 'not_found' {\n const task = this.tasks.get(url);\n return task?.status ?? 'not_found';\n }\n\n /**\n * Get preloaded model data\n */\n async get(url: string): Promise<ArrayBuffer | null> {\n const task = this.tasks.get(url);\n if (!task) return null;\n \n if (task.status === 'complete' || task.status === 'loading') {\n return task.promise;\n }\n \n return null;\n }\n\n /**\n * Cancel preload\n */\n cancel(url: string): void {\n const task = this.tasks.get(url);\n if (task && task.status === 'pending') {\n this.tasks.delete(url);\n this.queue = this.queue.filter(u => u !== url);\n task.reject(new Error('Preload cancelled'));\n }\n }\n\n /**\n * Clear all preloads\n */\n clear(): void {\n for (const [, task] of this.tasks) {\n if (task.status === 'pending') {\n task.reject(new Error('Preload cleared'));\n }\n }\n this.tasks.clear();\n this.queue = [];\n }\n}\n\n// Global preload manager\nconst preloadManager = new PreloadManager();\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load model data with caching, sharding, and resume support\n */\nexport async function loadModelData(\n url: string,\n options: ModelLoaderOptions = {}\n): Promise<ArrayBuffer> {\n const {\n cache = true,\n forceDownload = false,\n resumable = true,\n } = options;\n\n // Check cache first\n if (cache && !forceDownload) {\n const cached = await modelCache.getModel(url);\n if (cached) {\n // Validate: reject cached content that is clearly an HTTP error page\n // (HTML starts with '<', JSON error starts with '{'). Valid ONNX\n // protobuf binaries always have high-bit or control bytes first.\n const firstByte = new Uint8Array(cached)[0];\n const isHtmlOrText = firstByte === 0x3c /* '<' */ || firstByte === 0x7b /* '{' */;\n if (isHtmlOrText || cached.byteLength < 1024) {\n console.warn(`[edgeFlow.js] Cached model for ${url} appears corrupt (${cached.byteLength} bytes, first byte 0x${firstByte?.toString(16)}). Evicting and re-downloading.`);\n await modelCache.deleteModel(url);\n } else {\n console.log(`\u2713 Model loaded from cache: ${url}`);\n options.onProgress?.({\n loaded: cached.byteLength,\n total: cached.byteLength,\n percent: 100,\n speed: 0,\n eta: 0,\n });\n return cached;\n }\n }\n }\n\n // Download with resume support\n let data: ArrayBuffer;\n \n if (resumable) {\n data = await downloadWithResume(url, options);\n } else {\n data = await downloadSimple(url, options.timeout ?? 30000, options.onProgress);\n }\n\n // Cache the result\n if (cache) {\n // For simple downloads, save as single chunk\n if (!resumable) {\n await modelCache.saveChunk(url, 0, data);\n await modelCache.saveMeta({\n url,\n size: data.byteLength,\n cachedAt: Date.now(),\n chunks: 1,\n complete: true,\n });\n }\n }\n\n return data;\n}\n\n/**\n * Preload a model in the background\n */\nexport function preloadModel(url: string, options: PreloadOptions = {}): Promise<ArrayBuffer> {\n return preloadManager.preload(url, options);\n}\n\n/**\n * Preload multiple models\n */\nexport function preloadModels(\n urls: Array<{ url: string; priority?: number }>,\n options: Omit<PreloadOptions, 'priority'> = {}\n): Promise<ArrayBuffer[]> {\n return Promise.all(\n urls.map(({ url, priority }) => preloadManager.preload(url, { ...options, priority }))\n );\n}\n\n/**\n * Check if a model is cached\n */\nexport async function isModelCached(url: string): Promise<boolean> {\n const meta = await modelCache.getMeta(url);\n return meta?.complete ?? false;\n}\n\n/**\n * Get cached model data\n */\nexport async function getCachedModel(url: string): Promise<ArrayBuffer | null> {\n return modelCache.getModel(url);\n}\n\n/**\n * Delete a cached model\n */\nexport async function deleteCachedModel(url: string): Promise<void> {\n return modelCache.deleteModel(url);\n}\n\n/**\n * Clear all cached models\n */\nexport async function clearModelCache(): Promise<void> {\n return modelCache.clear();\n}\n\n/**\n * Get model cache statistics\n */\nexport async function getModelCacheStats(): Promise<{ models: number; totalSize: number }> {\n return modelCache.getStats();\n}\n\n/**\n * Get preload status\n */\nexport function getPreloadStatus(url: string): 'pending' | 'loading' | 'complete' | 'error' | 'not_found' {\n return preloadManager.getStatus(url);\n}\n\n/**\n * Cancel a preload\n */\nexport function cancelPreload(url: string): void {\n preloadManager.cancel(url);\n}\n\n/**\n * Get preloaded model (or wait for preload to complete)\n */\nexport async function getPreloadedModel(url: string): Promise<ArrayBuffer | null> {\n return preloadManager.get(url);\n}\n", "/**\n * edgeFlow.js\n * \n * Lightweight, high-performance browser ML inference framework\n * with native concurrency support.\n * \n * @example\n * ```typescript\n * import { pipeline } from 'edgeflow';\n * \n * // Create a sentiment analysis pipeline\n * const sentiment = await pipeline('sentiment-analysis');\n * \n * // Run inference\n * const result = await sentiment.run('I love this product!');\n * console.log(result); // { label: 'positive', score: 0.98 }\n * \n * // Batch processing\n * const results = await sentiment.run([\n * 'This is amazing!',\n * 'This is terrible.'\n * ]);\n * \n * // Concurrent execution with different models\n * const classifier = await pipeline('text-classification');\n * const extractor = await pipeline('feature-extraction');\n * \n * const [classification, features] = await Promise.all([\n * classifier.run('Sample text'),\n * extractor.run('Sample text')\n * ]);\n * ```\n * \n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Exports\n// ============================================================================\n\n// Types\nexport type {\n // Tensor types\n DataType,\n TypedArray,\n Shape,\n Tensor,\n \n // Runtime types\n RuntimeType,\n RuntimeCapabilities,\n Runtime,\n \n // Model types\n ModelFormat,\n QuantizationType,\n ModelMetadata,\n ModelIOSpec,\n ModelLoadOptions,\n LoadedModel,\n \n // Scheduler types\n TaskPriority,\n TaskStatus,\n InferenceTask,\n SchedulerOptions,\n \n // Memory types\n MemoryStats,\n MemoryPoolConfig,\n \n // Pipeline types\n PipelineTask,\n PipelineConfig,\n PipelineOptions,\n \n // Tokenizer types\n TokenizerConfig,\n TokenizedOutput,\n \n // Event types\n EventType,\n EdgeFlowEvent,\n EventListener,\n \n // Error types\n ErrorCode,\n} from './core/types.js';\n\n// Error class\nexport { EdgeFlowError, ErrorCodes } from './core/types.js';\n\n// Tensor operations\nexport {\n EdgeFlowTensor,\n tensor,\n zeros,\n ones,\n full,\n random,\n randn,\n arange,\n linspace,\n eye,\n add,\n sub,\n mul,\n div,\n matmul,\n softmax,\n relu,\n sigmoid,\n tanh,\n sum,\n mean,\n argmax,\n concat,\n} from './core/tensor.js';\n\n// Scheduler\nexport {\n InferenceScheduler,\n getScheduler,\n setScheduler,\n configureScheduler,\n} from './core/scheduler.js';\n\n// Memory management\nexport {\n MemoryManager,\n MemoryScope,\n ModelCache,\n withMemoryScope,\n withMemoryScopeSync,\n getMemoryManager,\n getMemoryStats,\n release,\n gc,\n} from './core/memory.js';\n\n// Plugin system\nexport {\n registerPlugin,\n getPluginPipeline,\n getPluginMiddleware,\n listPlugins,\n unregisterPlugin,\n type EdgeFlowPlugin,\n type PluginPipelineEntry,\n type PluginBackendEntry,\n type PluginMiddleware,\n} from './core/plugin.js';\n\n// Device profiling\nexport {\n getDeviceProfile,\n recommendQuantization,\n recommendModelVariant,\n resetDeviceProfile,\n type DeviceProfile,\n type DeviceTier,\n type ModelRecommendation,\n} from './core/device-profiler.js';\n\n// Pipeline composition\nexport {\n compose,\n parallel,\n type CompositionStage,\n type CompositionResult,\n type ComposedPipeline,\n} from './core/composer.js';\n\n// Runtime management\nexport {\n RuntimeManager,\n LoadedModelImpl,\n loadModel,\n loadModelFromBuffer,\n runInference,\n runInferenceNamed,\n runBatchInference,\n getRuntimeManager,\n registerRuntime,\n getBestRuntime,\n getAvailableRuntimes,\n} from './core/runtime.js';\n\n// ============================================================================\n// Backend Exports\n// ============================================================================\n\nexport {\n WebGPURuntime,\n createWebGPURuntime,\n WebNNRuntime,\n createWebNNRuntime,\n WASMRuntime,\n createWASMRuntime,\n registerAllBackends,\n\n // ONNX backend + asset/module injection (for Web Worker consumers)\n ONNXRuntime,\n createONNXRuntime,\n isOnnxAvailable,\n setOnnxModule,\n configureOnnxAssets,\n type OnnxAssetPaths,\n\n // transformers.js adapter\n TransformersAdapterRuntime,\n useTransformersBackend,\n getTransformersAdapter,\n type TransformersAdapterOptions,\n type TransformersPipelineFactory,\n} from './backends/index.js';\n\n// ============================================================================\n// Pipeline Exports\n// ============================================================================\n\nexport {\n // Factory function\n pipeline,\n createPipelines,\n \n // Base classes\n BasePipeline,\n registerPipeline,\n getPipelineFactory,\n \n // Labels\n SENTIMENT_LABELS,\n EMOTION_LABELS,\n IMAGENET_LABELS,\n \n // Result types\n type PipelineResult,\n type TextClassificationResult,\n type FeatureExtractionResult,\n type ImageClassificationResult,\n type ObjectDetectionResult,\n \n // Pipelines\n TextClassificationPipeline,\n SentimentAnalysisPipeline,\n FeatureExtractionPipeline,\n ImageClassificationPipeline,\n TextGenerationPipeline,\n ImageSegmentationPipeline,\n \n // Factory functions\n createTextClassificationPipeline,\n createSentimentAnalysisPipeline,\n createFeatureExtractionPipeline,\n createImageClassificationPipeline,\n createTextGenerationPipeline,\n createImageSegmentationPipeline,\n \n // Options types\n type PipelineFactoryOptions,\n type TextClassificationOptions,\n type FeatureExtractionOptions,\n type ImageClassificationOptions,\n type ImageInput,\n \n // Text Generation types\n type TextGenerationOptions,\n type TextGenerationResult,\n type GenerationStreamEvent,\n type ChatMessage,\n type ChatOptions,\n type ChatTemplateType,\n type LLMLoadProgress,\n \n // Image Segmentation types\n type ImageSegmentationOptions,\n type ImageSegmentationResult,\n type PointPrompt,\n type BoxPrompt,\n type ModelLoadProgress,\n} from './pipelines/index.js';\n\n// ============================================================================\n// Utility Exports\n// ============================================================================\n\nexport {\n // Tokenizer\n Tokenizer,\n createBasicTokenizer,\n loadTokenizer,\n loadTokenizerFromHub,\n type TokenizerModel,\n type TokenizerOptions,\n \n // Preprocessor\n ImagePreprocessor,\n AudioPreprocessor,\n preprocessText,\n createImagePreprocessor,\n createAudioPreprocessor,\n type ImagePreprocessorOptions,\n type AudioPreprocessorOptions,\n type TextPreprocessorOptions,\n \n // Cache\n Cache,\n InferenceCache,\n ModelDownloadCache,\n createCache,\n type CacheStrategy,\n type CacheOptions,\n type CacheStats,\n \n // Model Loader (Preloading, Sharding, Resume, Caching)\n loadModelData,\n preloadModel,\n preloadModels,\n isModelCached,\n getCachedModel,\n deleteCachedModel,\n clearModelCache,\n getModelCacheStats,\n getPreloadStatus,\n cancelPreload,\n getPreloadedModel,\n type DownloadProgress,\n type ModelLoaderOptions,\n type PreloadOptions,\n \n // HuggingFace Hub Integration\n fromHub,\n fromTask,\n downloadModel,\n downloadTokenizer,\n downloadConfig,\n modelExists,\n getModelInfo,\n getDefaultModel,\n POPULAR_MODELS,\n type HubOptions,\n type HubDownloadProgress,\n type ModelConfig,\n type ModelBundle,\n type PopularModelTask,\n} from './utils/index.js';\n\n// ============================================================================\n// Tools Exports\n// ============================================================================\n\nexport {\n // Quantization (basic)\n quantize,\n type QuantizationOptions,\n type QuantizationResult,\n \n // Pruning (basic)\n prune,\n type PruningOptions,\n type PruningResult,\n \n // Analysis (basic)\n analyzeModel,\n type ModelAnalysis,\n \n // Benchmarking (basic)\n benchmark,\n type BenchmarkOptions,\n type BenchmarkResult,\n \n // Export\n exportModel,\n \n // Advanced Quantization\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModelDetailed,\n exportModelAdvanced,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n type QuantizationMethod,\n type AdvancedQuantizationOptions,\n type QuantizationProgress,\n type AdvancedQuantizationResult,\n type LayerQuantizationStats,\n type QuantizationStats,\n type AdvancedPruningOptions,\n type AdvancedPruningResult,\n type DetailedModelAnalysis,\n type ExportFormat,\n type ExportOptions,\n \n // Debugging Tools\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n type DebuggerConfig,\n type TensorInspection,\n type TensorStats,\n type HistogramData,\n type InferenceTrace,\n type OperationTrace,\n type DebugEvent,\n type DebugPerformanceMetrics,\n \n // Performance Monitor\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n type MonitorConfig,\n type PerformanceSample,\n type InferenceMetrics,\n type MemoryMetrics,\n type SystemMetrics,\n type AlertConfig,\n type AlertEvent,\n type WidgetData,\n \n // Benchmark utilities\n runBenchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n type DetailedBenchmarkOptions,\n type DetailedBenchmarkResult,\n type CompareBenchmarkResult,\n type MemoryBenchmarkResult,\n} from './tools/index.js';\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Check if edgeFlow is supported in the current environment\n */\nexport async function isSupported(): Promise<boolean> {\n const runtimes = await getAvailableRuntimes();\n return Array.from(runtimes.values()).some(v => v);\n}\n\n/**\n * Get the best available runtime type\n */\nexport async function getBestRuntimeType(): Promise<RuntimeType | null> {\n const runtimes = await getAvailableRuntimes();\n \n if (runtimes.get('webgpu')) return 'webgpu';\n if (runtimes.get('webnn')) return 'webnn';\n if (runtimes.get('wasm')) return 'wasm';\n \n return null;\n}\n\n/**\n * Preload models for faster subsequent loading\n */\nexport async function preload(\n models: string[]\n): Promise<void> {\n const cache = new ModelDownloadCache();\n \n await Promise.all(models.map(async (url) => {\n if (!(await cache.get(url))) {\n const response = await fetch(url);\n if (response.ok) {\n await cache.put(url, response);\n }\n }\n }));\n}\n\n// ============================================================================\n// Version Info\n// ============================================================================\n\n/**\n * edgeFlow.js version\n */\nexport const VERSION = '0.3.0';\n\n/**\n * Get framework info\n */\nexport async function getInfo(): Promise<{\n version: string;\n runtimes: Record<RuntimeType, boolean>;\n features: string[];\n}> {\n const runtimes = await getAvailableRuntimes();\n \n return {\n version: VERSION,\n runtimes: {\n webgpu: runtimes.get('webgpu') ?? false,\n webnn: runtimes.get('webnn') ?? false,\n wasm: runtimes.get('wasm') ?? false,\n auto: true,\n },\n features: [\n 'concurrent-execution',\n 'batch-processing',\n 'memory-management',\n 'model-caching',\n 'quantization',\n ],\n };\n}\n\n// Re-export RuntimeType for convenience\nimport { RuntimeType } from './core/types.js';\nimport { getAvailableRuntimes } from './core/runtime.js';\nimport { ModelDownloadCache } from './utils/cache.js';\n", "/**\n * edgeFlow.js - Inference Scheduler\n * \n * Task scheduler for managing concurrent inference execution.\n * Supports priority queues, model-level isolation, and batch processing.\n */\n\nimport {\n InferenceTask,\n TaskPriority,\n TaskStatus,\n SchedulerOptions,\n EdgeFlowError,\n ErrorCodes,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\n\n// ============================================================================\n// Task Implementation\n// ============================================================================\n\n/**\n * Internal task implementation\n */\nclass Task<T = unknown> implements InferenceTask<T> {\n readonly id: string;\n readonly modelId: string;\n readonly priority: TaskPriority;\n readonly createdAt: number;\n \n private _status: TaskStatus = 'pending';\n private _startedAt?: number;\n private _completedAt?: number;\n private _result?: T;\n private _error?: Error;\n private _executor: () => Promise<T>;\n private _resolvers: Array<{\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n }> = [];\n private _cancelled = false;\n\n constructor(\n id: string,\n modelId: string,\n priority: TaskPriority,\n executor: () => Promise<T>\n ) {\n this.id = id;\n this.modelId = modelId;\n this.priority = priority;\n this.createdAt = Date.now();\n this._executor = executor;\n }\n\n get status(): TaskStatus {\n return this._status;\n }\n\n get startedAt(): number | undefined {\n return this._startedAt;\n }\n\n get completedAt(): number | undefined {\n return this._completedAt;\n }\n\n get result(): T | undefined {\n return this._result;\n }\n\n get error(): Error | undefined {\n return this._error;\n }\n\n /**\n * Cancel the task\n */\n cancel(): void {\n if (this._status === 'pending') {\n this._cancelled = true;\n this._status = 'cancelled';\n this._completedAt = Date.now();\n \n const cancelError = new EdgeFlowError(\n 'Task was cancelled',\n ErrorCodes.INFERENCE_CANCELLED,\n { taskId: this.id }\n );\n \n for (const { reject } of this._resolvers) {\n reject(cancelError);\n }\n this._resolvers = [];\n }\n }\n\n /**\n * Wait for task completion\n */\n wait(): Promise<T> {\n if (this._status === 'completed') {\n return Promise.resolve(this._result as T);\n }\n \n if (this._status === 'failed') {\n return Promise.reject(this._error);\n }\n \n if (this._status === 'cancelled') {\n return Promise.reject(new EdgeFlowError(\n 'Task was cancelled',\n ErrorCodes.INFERENCE_CANCELLED,\n { taskId: this.id }\n ));\n }\n\n return new Promise<T>((resolve, reject) => {\n this._resolvers.push({ resolve, reject });\n });\n }\n\n /**\n * Execute the task\n */\n async execute(): Promise<void> {\n if (this._cancelled) {\n return;\n }\n\n this._status = 'running';\n this._startedAt = Date.now();\n\n try {\n this._result = await this._executor();\n this._status = 'completed';\n this._completedAt = Date.now();\n \n for (const { resolve } of this._resolvers) {\n resolve(this._result);\n }\n } catch (err) {\n this._error = err instanceof Error ? err : new Error(String(err));\n this._status = 'failed';\n this._completedAt = Date.now();\n \n for (const { reject } of this._resolvers) {\n reject(this._error);\n }\n }\n \n this._resolvers = [];\n }\n}\n\n// ============================================================================\n// Priority Queue Implementation\n// ============================================================================\n\n/**\n * Priority mapping for comparison\n */\nconst PRIORITY_ORDER: Record<TaskPriority, number> = {\n critical: 0,\n high: 1,\n normal: 2,\n low: 3,\n};\n\n/**\n * Priority queue for tasks\n */\nclass PriorityQueue<T extends Task> {\n private items: T[] = [];\n\n get length(): number {\n return this.items.length;\n }\n\n isEmpty(): boolean {\n return this.items.length === 0;\n }\n\n /**\n * Add item to queue with priority ordering\n */\n enqueue(item: T): void {\n let inserted = false;\n \n for (let i = 0; i < this.items.length; i++) {\n const currentItem = this.items[i];\n if (currentItem && PRIORITY_ORDER[item.priority] < PRIORITY_ORDER[currentItem.priority]) {\n this.items.splice(i, 0, item);\n inserted = true;\n break;\n }\n }\n \n if (!inserted) {\n this.items.push(item);\n }\n }\n\n /**\n * Remove and return highest priority item\n */\n dequeue(): T | undefined {\n return this.items.shift();\n }\n\n /**\n * Peek at highest priority item without removing\n */\n peek(): T | undefined {\n return this.items[0];\n }\n\n /**\n * Remove a specific item by ID\n */\n remove(id: string): T | undefined {\n const index = this.items.findIndex(item => item.id === id);\n if (index !== -1) {\n const [removed] = this.items.splice(index, 1);\n return removed;\n }\n return undefined;\n }\n\n /**\n * Get all items\n */\n getAll(): T[] {\n return [...this.items];\n }\n\n /**\n * Clear the queue\n */\n clear(): void {\n this.items = [];\n }\n}\n\n// ============================================================================\n// Batch Collector\n// ============================================================================\n\n/**\n * Collects tasks for batch processing\n */\nclass BatchCollector<T> {\n private tasks: Task<T>[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private readonly maxSize: number;\n private readonly timeout: number;\n private readonly onBatch: (tasks: Task<T>[]) => void;\n\n constructor(\n maxSize: number,\n timeout: number,\n onBatch: (tasks: Task<T>[]) => void\n ) {\n this.maxSize = maxSize;\n this.timeout = timeout;\n this.onBatch = onBatch;\n }\n\n add(task: Task<T>): void {\n this.tasks.push(task);\n\n if (this.tasks.length >= this.maxSize) {\n this.flush();\n } else if (!this.timer) {\n this.timer = setTimeout(() => this.flush(), this.timeout);\n }\n }\n\n flush(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.tasks.length > 0) {\n const batch = this.tasks;\n this.tasks = [];\n this.onBatch(batch);\n }\n }\n\n clear(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.tasks = [];\n }\n}\n\n// ============================================================================\n// Inference Scheduler\n// ============================================================================\n\n// Counter for task IDs\nlet taskIdCounter = 0;\n\n/**\n * Generate unique task ID\n */\nfunction generateTaskId(): string {\n return `task_${++taskIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * Circuit breaker state per model\n */\ninterface CircuitState {\n failures: number;\n state: 'closed' | 'open' | 'half-open';\n lastFailure: number;\n}\n\n/**\n * Default scheduler options\n */\nconst DEFAULT_OPTIONS: Required<SchedulerOptions> = {\n maxConcurrentTasks: 4,\n maxConcurrentPerModel: 1,\n defaultTimeout: 30000,\n enableBatching: false,\n maxBatchSize: 32,\n batchTimeout: 50,\n maxRetries: 0,\n retryBaseDelay: 1000,\n circuitBreaker: false,\n circuitBreakerThreshold: 5,\n circuitBreakerResetTimeout: 30000,\n};\n\n/**\n * InferenceScheduler - Manages concurrent task execution\n * \n * Features:\n * - Priority-based task scheduling\n * - Model-level concurrency control\n * - Optional batch processing\n * - Task cancellation\n * - Event emission\n */\nexport class InferenceScheduler {\n private readonly options: Required<SchedulerOptions>;\n private readonly queues: Map<string, PriorityQueue<Task>> = new Map();\n private readonly runningTasks: Map<string, Set<string>> = new Map();\n private readonly allTasks: Map<string, Task> = new Map();\n private readonly batchers: Map<string, BatchCollector<unknown>> = new Map();\n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n private readonly circuits: Map<string, CircuitState> = new Map();\n private globalRunningCount = 0;\n private isProcessing = false;\n private disposed = false;\n\n constructor(options: SchedulerOptions = {}) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n }\n\n /**\n * Get circuit breaker state for a model, creating default if absent\n */\n private getCircuit(modelId: string): CircuitState {\n let c = this.circuits.get(modelId);\n if (!c) {\n c = { failures: 0, state: 'closed', lastFailure: 0 };\n this.circuits.set(modelId, c);\n }\n return c;\n }\n\n /**\n * Check if the circuit for a model allows new tasks\n */\n private isCircuitOpen(modelId: string): boolean {\n if (!this.options.circuitBreaker) return false;\n const c = this.getCircuit(modelId);\n if (c.state === 'closed') return false;\n if (c.state === 'open') {\n if (Date.now() - c.lastFailure > this.options.circuitBreakerResetTimeout) {\n c.state = 'half-open';\n return false; // allow one probe\n }\n return true;\n }\n return false; // half-open allows one\n }\n\n /**\n * Record a success for circuit breaker\n */\n private circuitSuccess(modelId: string): void {\n if (!this.options.circuitBreaker) return;\n const c = this.getCircuit(modelId);\n c.failures = 0;\n c.state = 'closed';\n }\n\n /**\n * Record a failure for circuit breaker\n */\n private circuitFailure(modelId: string): void {\n if (!this.options.circuitBreaker) return;\n const c = this.getCircuit(modelId);\n c.failures++;\n c.lastFailure = Date.now();\n if (c.failures >= this.options.circuitBreakerThreshold) {\n c.state = 'open';\n this.emit('inference:error', {\n modelId,\n error: new Error(`Circuit breaker opened after ${c.failures} consecutive failures`),\n });\n }\n }\n\n /**\n * Get or create queue for a model\n */\n private getQueue(modelId: string): PriorityQueue<Task> {\n let queue = this.queues.get(modelId);\n if (!queue) {\n queue = new PriorityQueue<Task>();\n this.queues.set(modelId, queue);\n }\n return queue;\n }\n\n /**\n * Get or create running set for a model\n */\n private getRunningSet(modelId: string): Set<string> {\n let running = this.runningTasks.get(modelId);\n if (!running) {\n running = new Set<string>();\n this.runningTasks.set(modelId, running);\n }\n return running;\n }\n\n /**\n * Check if we can start a new task for a model\n */\n private canStartTask(modelId: string): boolean {\n if (this.globalRunningCount >= this.options.maxConcurrentTasks) {\n return false;\n }\n\n const running = this.runningTasks.get(modelId);\n if (running && running.size >= this.options.maxConcurrentPerModel) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Process pending tasks\n */\n private async processQueue(): Promise<void> {\n if (this.isProcessing || this.disposed) {\n return;\n }\n\n this.isProcessing = true;\n\n try {\n // Find tasks that can be started\n const tasksToStart: Task[] = [];\n\n for (const [modelId, queue] of this.queues) {\n while (!queue.isEmpty() && this.canStartTask(modelId)) {\n const task = queue.dequeue();\n if (task && task.status === 'pending') {\n tasksToStart.push(task);\n \n const running = this.getRunningSet(modelId);\n running.add(task.id);\n this.globalRunningCount++;\n }\n }\n }\n\n // Execute tasks concurrently\n await Promise.all(\n tasksToStart.map(async (task) => {\n this.emit('inference:start', { taskId: task.id, modelId: task.modelId });\n\n try {\n await task.execute();\n this.emit('inference:complete', {\n taskId: task.id,\n modelId: task.modelId,\n duration: (task.completedAt ?? 0) - (task.startedAt ?? 0),\n });\n } catch (error) {\n this.emit('inference:error', {\n taskId: task.id,\n modelId: task.modelId,\n error,\n });\n } finally {\n // Clean up\n const running = this.runningTasks.get(task.modelId);\n if (running) {\n running.delete(task.id);\n }\n this.globalRunningCount--;\n }\n })\n );\n } finally {\n this.isProcessing = false;\n }\n\n // Check if there are more tasks to process\n let hasPending = false;\n for (const queue of this.queues.values()) {\n if (!queue.isEmpty()) {\n hasPending = true;\n break;\n }\n }\n\n if (hasPending) {\n // Use setImmediate-like behavior for next tick processing\n setTimeout(() => this.processQueue(), 0);\n }\n }\n\n /**\n * Schedule a task for execution\n */\n schedule<T>(\n modelId: string,\n executor: () => Promise<T>,\n priority: TaskPriority = 'normal'\n ): InferenceTask<T> {\n if (this.disposed) {\n throw new EdgeFlowError(\n 'Scheduler has been disposed',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n\n if (this.isCircuitOpen(modelId)) {\n throw new EdgeFlowError(\n `Circuit breaker is open for model ${modelId} \u2014 too many consecutive failures. ` +\n `Retry after ${this.options.circuitBreakerResetTimeout}ms.`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId },\n );\n }\n\n // Wrap executor with retry logic\n const maxRetries = this.options.maxRetries;\n const baseDelay = this.options.retryBaseDelay;\n const wrappedExecutor = maxRetries > 0\n ? async (): Promise<T> => {\n let lastError: Error | undefined;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const result = await executor();\n this.circuitSuccess(modelId);\n return result;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n this.circuitFailure(modelId);\n if (attempt < maxRetries) {\n const delay = baseDelay * Math.pow(2, attempt);\n await new Promise(r => setTimeout(r, delay));\n }\n }\n }\n throw lastError!;\n }\n : async (): Promise<T> => {\n try {\n const result = await executor();\n this.circuitSuccess(modelId);\n return result;\n } catch (err) {\n this.circuitFailure(modelId);\n throw err;\n }\n };\n\n const task = new Task<T>(\n generateTaskId(),\n modelId,\n priority,\n wrappedExecutor\n );\n\n this.allTasks.set(task.id, task as Task);\n\n const queue = this.getQueue(modelId);\n queue.enqueue(task as Task);\n\n this.processQueue();\n\n return task;\n }\n\n /**\n * Schedule with timeout\n */\n scheduleWithTimeout<T>(\n modelId: string,\n executor: () => Promise<T>,\n timeout: number = this.options.defaultTimeout,\n priority: TaskPriority = 'normal'\n ): InferenceTask<T> {\n const timeoutExecutor = (): Promise<T> => {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new EdgeFlowError(\n `Task timed out after ${timeout}ms`,\n ErrorCodes.INFERENCE_TIMEOUT,\n { timeout }\n ));\n }, timeout);\n\n executor()\n .then(result => {\n clearTimeout(timer);\n resolve(result);\n })\n .catch(error => {\n clearTimeout(timer);\n reject(error);\n });\n });\n };\n\n return this.schedule(modelId, timeoutExecutor, priority);\n }\n\n /**\n * Schedule multiple tasks and wait for all\n */\n async scheduleAll<T>(\n tasks: Array<{\n modelId: string;\n executor: () => Promise<T>;\n priority?: TaskPriority;\n }>\n ): Promise<T[]> {\n const scheduledTasks = tasks.map(({ modelId, executor, priority }) =>\n this.schedule<T>(modelId, executor, priority)\n );\n\n return Promise.all(scheduledTasks.map(task => task.wait()));\n }\n\n /**\n * Get task by ID\n */\n getTask(taskId: string): InferenceTask | undefined {\n return this.allTasks.get(taskId);\n }\n\n /**\n * Cancel a task\n */\n cancelTask(taskId: string): boolean {\n const task = this.allTasks.get(taskId);\n if (task && task.status === 'pending') {\n task.cancel();\n \n // Remove from queue\n for (const queue of this.queues.values()) {\n queue.remove(taskId);\n }\n \n return true;\n }\n return false;\n }\n\n /**\n * Cancel all tasks for a model\n */\n cancelAllForModel(modelId: string): number {\n const queue = this.queues.get(modelId);\n if (!queue) return 0;\n\n let cancelled = 0;\n for (const task of queue.getAll()) {\n if (task.status === 'pending') {\n task.cancel();\n cancelled++;\n }\n }\n queue.clear();\n \n return cancelled;\n }\n\n /**\n * Get statistics\n */\n getStats(): {\n totalTasks: number;\n pendingTasks: number;\n runningTasks: number;\n completedTasks: number;\n failedTasks: number;\n cancelledTasks: number;\n queuedByModel: Record<string, number>;\n } {\n const stats = {\n totalTasks: this.allTasks.size,\n pendingTasks: 0,\n runningTasks: 0,\n completedTasks: 0,\n failedTasks: 0,\n cancelledTasks: 0,\n queuedByModel: {} as Record<string, number>,\n };\n\n for (const task of this.allTasks.values()) {\n switch (task.status) {\n case 'pending':\n stats.pendingTasks++;\n break;\n case 'running':\n stats.runningTasks++;\n break;\n case 'completed':\n stats.completedTasks++;\n break;\n case 'failed':\n stats.failedTasks++;\n break;\n case 'cancelled':\n stats.cancelledTasks++;\n break;\n }\n }\n\n for (const [modelId, queue] of this.queues) {\n stats.queuedByModel[modelId] = queue.length;\n }\n\n return stats;\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n\n /**\n * Clear completed/failed/cancelled tasks from history\n */\n clearHistory(): void {\n for (const [taskId, task] of this.allTasks) {\n if (\n task.status === 'completed' ||\n task.status === 'failed' ||\n task.status === 'cancelled'\n ) {\n this.allTasks.delete(taskId);\n }\n }\n }\n\n /**\n * Dispose the scheduler\n */\n dispose(): void {\n this.disposed = true;\n\n // Cancel all pending tasks\n for (const queue of this.queues.values()) {\n for (const task of queue.getAll()) {\n task.cancel();\n }\n queue.clear();\n }\n\n // Clear batchers\n for (const batcher of this.batchers.values()) {\n batcher.clear();\n }\n\n this.queues.clear();\n this.runningTasks.clear();\n this.allTasks.clear();\n this.batchers.clear();\n this.listeners.clear();\n }\n}\n\n// ============================================================================\n// Global Scheduler Instance\n// ============================================================================\n\nlet globalScheduler: InferenceScheduler | null = null;\n\n/**\n * Get the global scheduler instance\n */\nexport function getScheduler(): InferenceScheduler {\n if (!globalScheduler) {\n globalScheduler = new InferenceScheduler();\n }\n return globalScheduler;\n}\n\n/**\n * Set the global scheduler instance\n */\nexport function setScheduler(scheduler: InferenceScheduler): void {\n if (globalScheduler) {\n globalScheduler.dispose();\n }\n globalScheduler = scheduler;\n}\n\n/**\n * Configure the global scheduler\n */\nexport function configureScheduler(options: SchedulerOptions): void {\n setScheduler(new InferenceScheduler(options));\n}\n", "/**\n * edgeFlow.js - Memory Management\n * \n * Efficient memory management for tensors and models.\n * Features:\n * - Memory pooling\n * - Automatic garbage collection\n * - Memory tracking and statistics\n * - Leak detection\n */\n\nimport {\n Tensor,\n LoadedModel,\n MemoryStats,\n MemoryPoolConfig,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\n\n// ============================================================================\n// Memory Tracking\n// ============================================================================\n\n/**\n * Tracked resource info\n */\ninterface TrackedResource {\n id: string;\n type: 'tensor' | 'model';\n size: number;\n createdAt: number;\n stackTrace?: string;\n}\n\n/**\n * Default memory pool configuration\n */\nconst DEFAULT_POOL_CONFIG: Required<MemoryPoolConfig> = {\n initialSize: 64 * 1024 * 1024, // 64MB\n maxSize: 512 * 1024 * 1024, // 512MB\n growthFactor: 1.5,\n autoGC: true,\n gcThreshold: 0.8, // 80%\n};\n\n// ============================================================================\n// Memory Manager\n// ============================================================================\n\n/**\n * MemoryManager - Central memory management\n * \n * Provides:\n * - Resource tracking\n * - Memory statistics\n * - Garbage collection coordination\n * - Memory warning events\n */\nexport class MemoryManager {\n private static instance: MemoryManager | null = null;\n \n private readonly config: Required<MemoryPoolConfig>;\n private readonly resources: Map<string, TrackedResource> = new Map();\n private readonly disposers: Map<string, () => void> = new Map();\n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n \n private allocated = 0;\n private peak = 0;\n private gcScheduled = false;\n private disposed = false;\n\n private constructor(config: MemoryPoolConfig = {}) {\n this.config = { ...DEFAULT_POOL_CONFIG, ...config };\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): MemoryManager {\n if (!MemoryManager.instance) {\n MemoryManager.instance = new MemoryManager();\n }\n return MemoryManager.instance;\n }\n\n /**\n * Configure the memory manager\n */\n static configure(config: MemoryPoolConfig): void {\n if (MemoryManager.instance) {\n console.warn('MemoryManager already initialized, configuration may not apply');\n }\n MemoryManager.instance = new MemoryManager(config);\n }\n\n /**\n * Track a tensor\n */\n track(tensor: Tensor, disposer?: () => void): void {\n if (this.disposed) return;\n\n const size = this.estimateTensorSize(tensor);\n \n this.resources.set(tensor.id, {\n id: tensor.id,\n type: 'tensor',\n size,\n createdAt: Date.now(),\n stackTrace: this.captureStackTrace(),\n });\n\n if (disposer) {\n this.disposers.set(tensor.id, disposer);\n }\n\n this.allocated += size;\n this.peak = Math.max(this.peak, this.allocated);\n\n this.checkMemoryThreshold();\n }\n\n /**\n * Track a model\n */\n trackModel(model: LoadedModel, disposer?: () => void): void {\n if (this.disposed) return;\n\n const size = model.metadata.sizeBytes;\n \n this.resources.set(model.id, {\n id: model.id,\n type: 'model',\n size,\n createdAt: Date.now(),\n stackTrace: this.captureStackTrace(),\n });\n\n if (disposer) {\n this.disposers.set(model.id, disposer);\n }\n\n this.allocated += size;\n this.peak = Math.max(this.peak, this.allocated);\n\n this.checkMemoryThreshold();\n }\n\n /**\n * Untrack a resource\n */\n untrack(id: string): void {\n const resource = this.resources.get(id);\n if (resource) {\n this.allocated -= resource.size;\n this.resources.delete(id);\n this.disposers.delete(id);\n }\n }\n\n /**\n * Release a resource\n */\n release(resourceOrId: Tensor | LoadedModel | string): void {\n const id = typeof resourceOrId === 'string' ? resourceOrId : resourceOrId.id;\n \n const disposer = this.disposers.get(id);\n if (disposer) {\n try {\n disposer();\n } catch (error) {\n console.error('Error disposing resource:', error);\n }\n }\n\n this.untrack(id);\n }\n\n /**\n * Estimate tensor memory size\n */\n private estimateTensorSize(tensor: Tensor): number {\n const bytesPerElement = this.getBytesPerElement(tensor.dtype);\n return tensor.size * bytesPerElement;\n }\n\n /**\n * Get bytes per element for a data type\n */\n private getBytesPerElement(dtype: string): number {\n switch (dtype) {\n case 'float32':\n return 4;\n case 'float16':\n return 2;\n case 'int32':\n return 4;\n case 'int64':\n return 8;\n case 'uint8':\n case 'int8':\n case 'bool':\n return 1;\n default:\n return 4;\n }\n }\n\n /**\n * Capture stack trace for debugging\n */\n private captureStackTrace(): string | undefined {\n if (typeof Error.captureStackTrace === 'function') {\n const obj: { stack?: string } = {};\n Error.captureStackTrace(obj, this.captureStackTrace);\n return obj.stack;\n }\n return new Error().stack;\n }\n\n /**\n * Check if memory threshold is exceeded\n */\n private checkMemoryThreshold(): void {\n if (!this.config.autoGC) return;\n\n const usage = this.allocated / this.config.maxSize;\n \n if (usage >= this.config.gcThreshold && !this.gcScheduled) {\n this.gcScheduled = true;\n this.emit('memory:warning', {\n allocated: this.allocated,\n maxSize: this.config.maxSize,\n usage,\n });\n\n // Schedule GC on next tick\n setTimeout(() => {\n this.gc();\n this.gcScheduled = false;\n }, 0);\n }\n }\n\n /**\n * Garbage collection helper.\n *\n * Identifies stale resources and optionally evicts them.\n * @param evict - If true, actually dispose stale resources (default: false)\n * @param maxAge - Resources older than this (ms) are considered stale (default: 5 min)\n */\n gc(evict = false, maxAge = 5 * 60 * 1000): void {\n this.emit('memory:gc', { before: this.allocated });\n\n const now = Date.now();\n const staleIds: string[] = [];\n\n for (const [id, resource] of this.resources) {\n if (now - resource.createdAt > maxAge) {\n staleIds.push(id);\n }\n }\n\n if (evict) {\n for (const id of staleIds) {\n this.release(id);\n }\n }\n\n this.emit('memory:gc', {\n after: this.allocated,\n evicted: evict ? staleIds.length : 0,\n potentialCleanup: staleIds.length,\n });\n }\n\n /**\n * Query actual browser memory usage via performance.measureUserAgentSpecificMemory()\n * (Chrome 89+, requires cross-origin isolation). Returns null if unavailable.\n */\n async measureBrowserMemory(): Promise<{\n bytes: number;\n breakdown: Array<{ bytes: number; types: string[] }>;\n } | null> {\n try {\n if (\n typeof performance !== 'undefined' &&\n 'measureUserAgentSpecificMemory' in performance\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = await (performance as any).measureUserAgentSpecificMemory();\n return result;\n }\n } catch {\n // Not available or not cross-origin isolated\n }\n return null;\n }\n\n /**\n * Get the device's total memory hint (navigator.deviceMemory).\n * Returns null if unavailable. Value is in GiB, rounded (e.g. 4, 8).\n */\n getDeviceMemory(): number | null {\n try {\n if (typeof navigator !== 'undefined' && 'deviceMemory' in navigator) {\n return (navigator as { deviceMemory?: number }).deviceMemory ?? null;\n }\n } catch {\n // Not available\n }\n return null;\n }\n\n /**\n * Get memory statistics\n */\n getStats(): MemoryStats {\n let tensorCount = 0;\n let modelCount = 0;\n\n for (const resource of this.resources.values()) {\n if (resource.type === 'tensor') {\n tensorCount++;\n } else {\n modelCount++;\n }\n }\n\n return {\n allocated: this.allocated,\n used: this.allocated, // In JS, allocated = used\n peak: this.peak,\n tensorCount,\n modelCount,\n };\n }\n\n /**\n * Get detailed resource list (for debugging)\n */\n getResourceDetails(): TrackedResource[] {\n return Array.from(this.resources.values());\n }\n\n /**\n * Check for potential memory leaks\n */\n detectLeaks(maxAge: number = 10 * 60 * 1000): TrackedResource[] {\n const now = Date.now();\n const potentialLeaks: TrackedResource[] = [];\n\n for (const resource of this.resources.values()) {\n if (now - resource.createdAt > maxAge) {\n potentialLeaks.push(resource);\n }\n }\n\n return potentialLeaks;\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n\n /**\n * Reset statistics\n */\n resetStats(): void {\n this.peak = this.allocated;\n }\n\n /**\n * Dispose all resources\n */\n disposeAll(): void {\n for (const id of this.resources.keys()) {\n this.release(id);\n }\n }\n\n /**\n * Dispose the manager\n */\n dispose(): void {\n this.disposeAll();\n this.disposed = true;\n this.listeners.clear();\n MemoryManager.instance = null;\n }\n}\n\n// ============================================================================\n// Memory Scope (RAII-like pattern)\n// ============================================================================\n\n/**\n * Memory scope for automatic resource cleanup\n * \n * Usage:\n * ```typescript\n * const result = await withMemoryScope(async (scope) => {\n * const tensor1 = scope.track(createTensor(...));\n * const tensor2 = scope.track(createTensor(...));\n * // Process tensors\n * return computeResult(tensor1, tensor2);\n * });\n * // tensor1 and tensor2 are automatically disposed\n * ```\n */\nexport class MemoryScope {\n private resources: Array<{ dispose: () => void }> = [];\n private children: MemoryScope[] = [];\n private parent: MemoryScope | null = null;\n\n constructor(parent?: MemoryScope) {\n if (parent) {\n this.parent = parent;\n parent.children.push(this);\n }\n }\n\n /**\n * Track a resource in this scope\n */\n track<T extends { dispose: () => void }>(resource: T): T {\n this.resources.push(resource);\n return resource;\n }\n\n /**\n * Create a child scope\n */\n createChild(): MemoryScope {\n return new MemoryScope(this);\n }\n\n /**\n * Keep a resource (don't dispose it when scope ends)\n */\n keep<T extends { dispose: () => void }>(resource: T): T {\n const index = this.resources.indexOf(resource);\n if (index !== -1) {\n this.resources.splice(index, 1);\n }\n return resource;\n }\n\n /**\n * Dispose all resources in this scope\n */\n dispose(): void {\n // Dispose children first\n for (const child of this.children) {\n child.dispose();\n }\n this.children = [];\n\n // Dispose resources in reverse order\n for (let i = this.resources.length - 1; i >= 0; i--) {\n try {\n this.resources[i]?.dispose();\n } catch (error) {\n console.error('Error disposing resource in scope:', error);\n }\n }\n this.resources = [];\n\n // Remove from parent\n if (this.parent) {\n const index = this.parent.children.indexOf(this);\n if (index !== -1) {\n this.parent.children.splice(index, 1);\n }\n this.parent = null;\n }\n }\n}\n\n/**\n * Execute a function with automatic memory cleanup\n */\nexport async function withMemoryScope<T>(\n fn: (scope: MemoryScope) => Promise<T>\n): Promise<T> {\n const scope = new MemoryScope();\n try {\n return await fn(scope);\n } finally {\n scope.dispose();\n }\n}\n\n/**\n * Synchronous version of withMemoryScope\n */\nexport function withMemoryScopeSync<T>(\n fn: (scope: MemoryScope) => T\n): T {\n const scope = new MemoryScope();\n try {\n return fn(scope);\n } finally {\n scope.dispose();\n }\n}\n\n// ============================================================================\n// LRU Cache for Models\n// ============================================================================\n\n/**\n * LRU Cache for loaded models\n */\nexport class ModelCache {\n private readonly maxSize: number;\n private readonly maxModels: number;\n private readonly cache: Map<string, { model: LoadedModel; size: number; lastAccess: number }> = new Map();\n private currentSize = 0;\n\n constructor(options: { maxSize?: number; maxModels?: number } = {}) {\n this.maxSize = options.maxSize ?? 256 * 1024 * 1024; // 256MB default\n this.maxModels = options.maxModels ?? 5;\n }\n\n /**\n * Get a model from cache\n */\n get(key: string): LoadedModel | undefined {\n const entry = this.cache.get(key);\n if (entry) {\n entry.lastAccess = Date.now();\n return entry.model;\n }\n return undefined;\n }\n\n /**\n * Add a model to cache\n */\n set(key: string, model: LoadedModel): void {\n const size = model.metadata.sizeBytes;\n\n // Check if we need to evict\n while (\n (this.currentSize + size > this.maxSize || this.cache.size >= this.maxModels) &&\n this.cache.size > 0\n ) {\n this.evictLRU();\n }\n\n // Add to cache\n this.cache.set(key, {\n model,\n size,\n lastAccess: Date.now(),\n });\n this.currentSize += size;\n }\n\n /**\n * Remove a model from cache\n */\n delete(key: string): boolean {\n const entry = this.cache.get(key);\n if (entry) {\n entry.model.dispose();\n this.currentSize -= entry.size;\n this.cache.delete(key);\n return true;\n }\n return false;\n }\n\n /**\n * Check if model is in cache\n */\n has(key: string): boolean {\n return this.cache.has(key);\n }\n\n /**\n * Evict least recently used model\n */\n private evictLRU(): void {\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n this.delete(oldestKey);\n }\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n for (const entry of this.cache.values()) {\n entry.model.dispose();\n }\n this.cache.clear();\n this.currentSize = 0;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): { size: number; count: number; maxSize: number; maxModels: number } {\n return {\n size: this.currentSize,\n count: this.cache.size,\n maxSize: this.maxSize,\n maxModels: this.maxModels,\n };\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get memory manager instance\n */\nexport function getMemoryManager(): MemoryManager {\n return MemoryManager.getInstance();\n}\n\n/**\n * Get memory statistics\n */\nexport function getMemoryStats(): MemoryStats {\n return MemoryManager.getInstance().getStats();\n}\n\n/**\n * Release a resource\n */\nexport function release(resource: Tensor | LoadedModel): void {\n MemoryManager.getInstance().release(resource);\n}\n\n/**\n * Force garbage collection hint\n */\nexport function gc(): void {\n MemoryManager.getInstance().gc();\n}\n", "/**\n * edgeFlow.js - Runtime Management\n * \n * Manages runtime backends and automatic selection.\n * Provides unified interface for different compute backends.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n EventType,\n EventListener,\n EdgeFlowEvent,\n} from './types.js';\nimport { getScheduler } from './scheduler.js';\nimport { getMemoryManager } from './memory.js';\n\n// ============================================================================\n// Runtime Registry\n// ============================================================================\n\n/**\n * Registered runtime factories\n */\nconst runtimeFactories: Map<RuntimeType, () => Runtime> = new Map();\n\n/**\n * Cached runtime instances\n */\nconst runtimeInstances: Map<RuntimeType, Runtime> = new Map();\n\n/**\n * Runtime priority order (higher priority first)\n */\nconst RUNTIME_PRIORITY: RuntimeType[] = ['webgpu', 'webnn', 'wasm'];\n\n// ============================================================================\n// Runtime Manager\n// ============================================================================\n\n/**\n * RuntimeManager - Manages runtime selection and lifecycle\n * \n * Features:\n * - Automatic best runtime selection\n * - Runtime registration\n * - Capability detection\n * - Fallback handling\n */\nexport class RuntimeManager {\n private static instance: RuntimeManager | null = null;\n \n private readonly listeners: Map<EventType, Set<EventListener>> = new Map();\n private defaultRuntime: RuntimeType = 'auto';\n\n private constructor() {}\n\n /**\n * Get singleton instance\n */\n static getInstance(): RuntimeManager {\n if (!RuntimeManager.instance) {\n RuntimeManager.instance = new RuntimeManager();\n }\n return RuntimeManager.instance;\n }\n\n /**\n * Register a runtime factory\n */\n register(type: RuntimeType, factory: () => Runtime): void {\n runtimeFactories.set(type, factory);\n }\n\n /**\n * Get a runtime instance\n */\n async getRuntime(type: RuntimeType = 'auto'): Promise<Runtime> {\n if (type === 'auto') {\n return this.getBestRuntime();\n }\n\n // Check if already instantiated\n let runtime = runtimeInstances.get(type);\n if (runtime) {\n return runtime;\n }\n\n // Create new instance\n const factory = runtimeFactories.get(type);\n if (!factory) {\n throw new EdgeFlowError(\n `Runtime '${type}' is not registered`,\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { runtime: type }\n );\n }\n\n runtime = factory();\n \n // Check availability\n const available = await runtime.isAvailable();\n if (!available) {\n throw new EdgeFlowError(\n `Runtime '${type}' is not available in this environment`,\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { runtime: type }\n );\n }\n\n // Initialize\n try {\n await runtime.initialize();\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to initialize runtime '${type}': ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.RUNTIME_INIT_FAILED,\n { runtime: type, error }\n );\n }\n\n runtimeInstances.set(type, runtime);\n this.emit('runtime:ready', { runtime: type });\n\n return runtime;\n }\n\n /**\n * Get the best available runtime\n */\n async getBestRuntime(): Promise<Runtime> {\n for (const type of RUNTIME_PRIORITY) {\n try {\n // Check if already available\n const existing = runtimeInstances.get(type);\n if (existing) {\n return existing;\n }\n\n // Try to create and initialize\n const factory = runtimeFactories.get(type);\n if (!factory) continue;\n\n const runtime = factory();\n const available = await runtime.isAvailable();\n \n if (available) {\n await runtime.initialize();\n runtimeInstances.set(type, runtime);\n this.emit('runtime:ready', { runtime: type });\n return runtime;\n }\n } catch {\n // Try next runtime\n continue;\n }\n }\n\n throw new EdgeFlowError(\n 'No runtime available. Please ensure WebGPU, WebNN, or WASM is supported.',\n ErrorCodes.RUNTIME_NOT_AVAILABLE,\n { triedRuntimes: RUNTIME_PRIORITY }\n );\n }\n\n /**\n * Check which runtimes are available\n */\n async detectAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {\n const results = new Map<RuntimeType, boolean>();\n\n for (const type of RUNTIME_PRIORITY) {\n const factory = runtimeFactories.get(type);\n if (!factory) {\n results.set(type, false);\n continue;\n }\n\n try {\n const runtime = factory();\n results.set(type, await runtime.isAvailable());\n } catch {\n results.set(type, false);\n }\n }\n\n return results;\n }\n\n /**\n * Get capabilities of a runtime\n */\n async getCapabilities(type: RuntimeType): Promise<RuntimeCapabilities> {\n const runtime = await this.getRuntime(type);\n return runtime.capabilities;\n }\n\n /**\n * Set default runtime\n */\n setDefaultRuntime(type: RuntimeType): void {\n this.defaultRuntime = type;\n }\n\n /**\n * Get default runtime type\n */\n getDefaultRuntimeType(): RuntimeType {\n return this.defaultRuntime;\n }\n\n /**\n * Dispose a specific runtime\n */\n disposeRuntime(type: RuntimeType): void {\n const runtime = runtimeInstances.get(type);\n if (runtime) {\n runtime.dispose();\n runtimeInstances.delete(type);\n }\n }\n\n /**\n * Dispose all runtimes\n */\n disposeAll(): void {\n for (const [type, runtime] of runtimeInstances) {\n runtime.dispose();\n runtimeInstances.delete(type);\n }\n }\n\n /**\n * Add event listener\n */\n on<T = unknown>(event: EventType, listener: EventListener<T>): void {\n let listeners = this.listeners.get(event);\n if (!listeners) {\n listeners = new Set();\n this.listeners.set(event, listeners);\n }\n listeners.add(listener as EventListener);\n }\n\n /**\n * Remove event listener\n */\n off<T = unknown>(event: EventType, listener: EventListener<T>): void {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.delete(listener as EventListener);\n }\n }\n\n /**\n * Emit event\n */\n private emit<T>(type: EventType, data: T): void {\n const event: EdgeFlowEvent<T> = {\n type,\n timestamp: Date.now(),\n data,\n };\n\n const listeners = this.listeners.get(type);\n if (listeners) {\n for (const listener of listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('Error in event listener:', error);\n }\n }\n }\n }\n}\n\n// ============================================================================\n// Model Loader\n// ============================================================================\n\n/**\n * Model instance counter\n */\nlet modelIdCounter = 0;\n\n/**\n * Generate unique model ID\n */\nfunction generateModelId(): string {\n return `model_${++modelIdCounter}_${Date.now().toString(36)}`;\n}\n\n/**\n * LoadedModelImpl - Implementation of LoadedModel interface\n */\nexport class LoadedModelImpl implements LoadedModel {\n readonly id: string;\n readonly metadata: ModelMetadata;\n readonly runtime: RuntimeType;\n \n private _isLoaded = true;\n private readonly _dispose: () => void;\n\n constructor(\n metadata: ModelMetadata,\n runtime: RuntimeType,\n dispose: () => void\n ) {\n this.id = generateModelId();\n this.metadata = metadata;\n this.runtime = runtime;\n this._dispose = dispose;\n }\n\n get isLoaded(): boolean {\n return this._isLoaded;\n }\n\n dispose(): void {\n if (this._isLoaded) {\n this._isLoaded = false;\n this._dispose();\n getMemoryManager().untrack(this.id);\n }\n }\n}\n\n// ============================================================================\n// Model Loading Functions\n// ============================================================================\n\n/**\n * Load model from URL with advanced loading support\n * (caching, sharding, resume download)\n */\nexport async function loadModel(\n url: string,\n options: ModelLoadOptions & { \n runtime?: RuntimeType;\n cache?: boolean;\n resumable?: boolean;\n chunkSize?: number;\n forceDownload?: boolean;\n } = {}\n): Promise<LoadedModel> {\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(options.runtime ?? 'auto');\n\n // Import model loader dynamically to avoid circular dependencies\n const { loadModelData } = await import('../utils/model-loader.js');\n\n // Use advanced model loader with caching and resume support\n const modelData = await loadModelData(url, {\n cache: options.cache ?? true,\n resumable: options.resumable ?? true,\n chunkSize: options.chunkSize,\n forceDownload: options.forceDownload,\n onProgress: options.onProgress ? (progress) => {\n options.onProgress!(progress.percent / 100);\n } : undefined,\n });\n\n // Load into runtime\n const model = await runtime.loadModel(modelData, options);\n\n return model;\n}\n\n/**\n * Load model from ArrayBuffer\n */\nexport async function loadModelFromBuffer(\n data: ArrayBuffer,\n options: ModelLoadOptions & { runtime?: RuntimeType } = {}\n): Promise<LoadedModel> {\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(options.runtime ?? 'auto');\n return runtime.loadModel(data, options);\n}\n\n// ============================================================================\n// Inference Functions\n// ============================================================================\n\n/**\n * Run inference on a model\n */\nexport async function runInference(\n model: LoadedModel,\n inputs: Tensor[]\n): Promise<Tensor[]> {\n if (!model.isLoaded) {\n throw new EdgeFlowError(\n 'Model has been disposed',\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n \n // Use scheduler for execution\n const scheduler = getScheduler();\n const task = scheduler.schedule(model.id, () => runtime.run(model, inputs));\n \n return task.wait();\n}\n\n/**\n * Run inference with named inputs\n */\nexport async function runInferenceNamed(\n model: LoadedModel,\n namedInputs: Map<string, Tensor>\n): Promise<Tensor[]> {\n if (!model.isLoaded) {\n throw new EdgeFlowError(\n 'Model has been disposed',\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n \n // Check if runtime supports named inputs\n if (!('runNamed' in runtime)) {\n throw new EdgeFlowError(\n 'Runtime does not support named inputs',\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id }\n );\n }\n \n // Use scheduler for execution\n const scheduler = getScheduler();\n const task = scheduler.schedule(model.id, () => \n (runtime as any).runNamed(model, namedInputs)\n );\n \n return task.wait() as Promise<Tensor[]>;\n}\n\n/**\n * Run inference with batch processing\n */\nexport async function runBatchInference(\n model: LoadedModel,\n batches: Tensor[][]\n): Promise<Tensor[][]> {\n const scheduler = getScheduler();\n const manager = RuntimeManager.getInstance();\n const runtime = await manager.getRuntime(model.runtime);\n\n // Schedule all batches\n const tasks = batches.map(inputs =>\n scheduler.schedule(model.id, () => runtime.run(model, inputs))\n );\n\n // Wait for all to complete\n return Promise.all(tasks.map(task => task.wait()));\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get runtime manager instance\n */\nexport function getRuntimeManager(): RuntimeManager {\n return RuntimeManager.getInstance();\n}\n\n/**\n * Register a runtime\n */\nexport function registerRuntime(type: RuntimeType, factory: () => Runtime): void {\n RuntimeManager.getInstance().register(type, factory);\n}\n\n/**\n * Get the best available runtime\n */\nexport async function getBestRuntime(): Promise<Runtime> {\n return RuntimeManager.getInstance().getBestRuntime();\n}\n\n/**\n * Check available runtimes\n */\nexport async function getAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {\n return RuntimeManager.getInstance().detectAvailableRuntimes();\n}\n", "/**\n * edgeFlow.js - Plugin System\n *\n * Register custom pipelines, backends, and middleware via plugins.\n *\n * @example\n * ```typescript\n * import { registerPlugin } from 'edgeflowjs';\n *\n * registerPlugin({\n * name: 'edgeflow-plugin-whisper',\n * version: '1.0.0',\n * pipelines: {\n * 'whisper-transcribe': {\n * factory: (config) => new WhisperPipeline(config),\n * },\n * },\n * });\n *\n * // Now available via pipeline('whisper-transcribe')\n * ```\n */\n\nimport type { PipelineConfig, Runtime, RuntimeType } from './types.js';\nimport { registerRuntime } from './runtime.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A pipeline factory registered by a plugin.\n */\nexport interface PluginPipelineEntry {\n /** Factory that creates a pipeline instance */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory: (config: PipelineConfig) => any;\n /** Optional description */\n description?: string;\n}\n\n/**\n * A backend registered by a plugin.\n */\nexport interface PluginBackendEntry {\n /** Factory that creates a runtime instance */\n factory: () => Runtime;\n /** Optional description */\n description?: string;\n}\n\n/**\n * Middleware that runs before/after inference.\n */\nexport interface PluginMiddleware {\n /** Unique name */\n name: string;\n /** Called before inference with (model, inputs). Return modified inputs. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n before?: (ctx: { modelId: string; inputs: any }) => any | Promise<any>;\n /** Called after inference with (model, outputs). Return modified outputs. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n after?: (ctx: { modelId: string; outputs: any }) => any | Promise<any>;\n}\n\n/**\n * Plugin definition.\n */\nexport interface EdgeFlowPlugin {\n /** Unique plugin name (e.g. 'edgeflow-plugin-whisper') */\n name: string;\n /** Plugin version (semver) */\n version: string;\n /** Pipelines contributed by this plugin */\n pipelines?: Record<string, PluginPipelineEntry>;\n /** Backends contributed by this plugin */\n backends?: Record<string, PluginBackendEntry>;\n /** Middleware contributed by this plugin */\n middleware?: PluginMiddleware[];\n /** Called once when the plugin is registered */\n setup?: () => void | Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nconst registeredPlugins = new Map<string, EdgeFlowPlugin>();\nconst pluginPipelines = new Map<string, PluginPipelineEntry>();\nconst pluginMiddleware: PluginMiddleware[] = [];\n\n/**\n * Register a plugin. Pipelines and backends are made available immediately.\n */\nexport async function registerPlugin(plugin: EdgeFlowPlugin): Promise<void> {\n if (registeredPlugins.has(plugin.name)) {\n console.warn(`[edgeFlow.js] Plugin \"${plugin.name}\" is already registered \u2014 skipping.`);\n return;\n }\n\n // Run setup hook\n if (plugin.setup) {\n await plugin.setup();\n }\n\n // Register pipelines\n if (plugin.pipelines) {\n for (const [task, entry] of Object.entries(plugin.pipelines)) {\n pluginPipelines.set(task, entry);\n }\n }\n\n // Register backends\n if (plugin.backends) {\n for (const [name, entry] of Object.entries(plugin.backends)) {\n registerRuntime(name as RuntimeType, entry.factory);\n }\n }\n\n // Register middleware\n if (plugin.middleware) {\n pluginMiddleware.push(...plugin.middleware);\n }\n\n registeredPlugins.set(plugin.name, plugin);\n}\n\n/**\n * Look up a pipeline factory registered by any plugin.\n * Returns undefined if no plugin provides this task.\n */\nexport function getPluginPipeline(task: string): PluginPipelineEntry | undefined {\n return pluginPipelines.get(task);\n}\n\n/**\n * Get all registered middleware.\n */\nexport function getPluginMiddleware(): ReadonlyArray<PluginMiddleware> {\n return pluginMiddleware;\n}\n\n/**\n * List all registered plugins.\n */\nexport function listPlugins(): Array<{ name: string; version: string }> {\n return Array.from(registeredPlugins.values()).map(p => ({\n name: p.name,\n version: p.version,\n }));\n}\n\n/**\n * Unregister a plugin by name.\n */\nexport function unregisterPlugin(name: string): boolean {\n const plugin = registeredPlugins.get(name);\n if (!plugin) return false;\n\n // Remove pipelines\n if (plugin.pipelines) {\n for (const task of Object.keys(plugin.pipelines)) {\n pluginPipelines.delete(task);\n }\n }\n\n // Remove middleware\n if (plugin.middleware) {\n for (const mw of plugin.middleware) {\n const idx = pluginMiddleware.indexOf(mw);\n if (idx !== -1) pluginMiddleware.splice(idx, 1);\n }\n }\n\n registeredPlugins.delete(name);\n return true;\n}\n", "/**\n * edgeFlow.js - Device Profiler\n *\n * Automatically profiles the current device and recommends optimal model\n * variants (quantization level, batch size, execution provider).\n *\n * @example\n * ```typescript\n * import { getDeviceProfile, recommendQuantization } from 'edgeflowjs';\n *\n * const profile = await getDeviceProfile();\n * console.log(profile.tier); // 'high' | 'medium' | 'low'\n *\n * const quant = recommendQuantization(profile);\n * console.log(quant); // 'fp16' | 'int8' | 'int4'\n * ```\n */\n\nimport type { QuantizationType } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Device capability tier.\n */\nexport type DeviceTier = 'high' | 'medium' | 'low';\n\n/**\n * Profiled device information.\n */\nexport interface DeviceProfile {\n /** Capability tier */\n tier: DeviceTier;\n /** Number of logical CPU cores */\n cores: number;\n /** Device memory in GiB (navigator.deviceMemory, may be null) */\n memoryGiB: number | null;\n /** Whether WebGPU is available */\n webgpu: boolean;\n /** Whether WebNN is available */\n webnn: boolean;\n /** Recommended max batch size */\n recommendedBatchSize: number;\n /** Recommended concurrency limit */\n recommendedConcurrency: number;\n /** Whether the device is mobile */\n mobile: boolean;\n /** Raw GPU adapter info (if WebGPU available) */\n gpuInfo?: string;\n}\n\n/**\n * Model variant recommendation.\n */\nexport interface ModelRecommendation {\n /** Recommended quantization */\n quantization: QuantizationType;\n /** Recommended execution provider */\n executionProvider: 'webgpu' | 'wasm';\n /** Recommended batch size */\n batchSize: number;\n /** Whether to enable worker-based inference */\n useWorker: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Profiling\n// ---------------------------------------------------------------------------\n\nlet cachedProfile: DeviceProfile | null = null;\n\n/**\n * Profile the current device. Results are cached after the first call.\n */\nexport async function getDeviceProfile(): Promise<DeviceProfile> {\n if (cachedProfile) return cachedProfile;\n\n const cores = typeof navigator !== 'undefined'\n ? navigator.hardwareConcurrency ?? 2\n : 2;\n\n const memoryGiB = typeof navigator !== 'undefined' && 'deviceMemory' in navigator\n ? (navigator as { deviceMemory?: number }).deviceMemory ?? null\n : null;\n\n const mobile = typeof navigator !== 'undefined'\n ? /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)\n : false;\n\n let webgpu = false;\n let gpuInfo: string | undefined;\n if (typeof navigator !== 'undefined' && 'gpu' in navigator) {\n try {\n const adapter = await (navigator as Navigator & { gpu: { requestAdapter: () => Promise<unknown> } }).gpu.requestAdapter();\n webgpu = adapter != null;\n if (adapter && typeof adapter === 'object') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const info = (adapter as any)['info'];\n if (info) {\n gpuInfo = `${info['vendor'] ?? ''} ${info['architecture'] ?? ''}`.trim() || undefined;\n }\n } catch {\n // info not available\n }\n }\n } catch {\n // WebGPU not available\n }\n }\n\n let webnn = false;\n if (typeof navigator !== 'undefined' && 'ml' in navigator) {\n try {\n const ml = (navigator as Navigator & { ml?: { createContext: () => Promise<unknown> } }).ml;\n if (ml) {\n const ctx = await ml.createContext();\n webnn = ctx != null;\n }\n } catch {\n // WebNN not available\n }\n }\n\n // Determine tier\n let tier: DeviceTier;\n if (webgpu && cores >= 8 && (memoryGiB === null || memoryGiB >= 8)) {\n tier = 'high';\n } else if (cores >= 4 && (memoryGiB === null || memoryGiB >= 4)) {\n tier = 'medium';\n } else {\n tier = 'low';\n }\n\n // Mobile devices get capped even if specs look good\n if (mobile && tier === 'high') {\n tier = 'medium';\n }\n\n const recommendedBatchSize = tier === 'high' ? 32 : tier === 'medium' ? 8 : 1;\n const recommendedConcurrency = tier === 'high' ? 4 : tier === 'medium' ? 2 : 1;\n\n cachedProfile = {\n tier,\n cores,\n memoryGiB,\n webgpu,\n webnn,\n recommendedBatchSize,\n recommendedConcurrency,\n mobile,\n gpuInfo,\n };\n\n return cachedProfile;\n}\n\n/**\n * Recommend the best quantization level for the current device.\n */\nexport function recommendQuantization(profile: DeviceProfile): QuantizationType {\n if (profile.tier === 'high' && profile.webgpu) return 'float16';\n if (profile.tier === 'medium') return 'int8';\n return 'int8'; // low-tier: most aggressive\n}\n\n/**\n * Get full model variant recommendations for the current device.\n */\nexport async function recommendModelVariant(): Promise<ModelRecommendation> {\n const profile = await getDeviceProfile();\n\n return {\n quantization: recommendQuantization(profile),\n executionProvider: profile.webgpu ? 'webgpu' : 'wasm',\n batchSize: profile.recommendedBatchSize,\n useWorker: profile.cores >= 4,\n };\n}\n\n/**\n * Reset the cached profile (useful for testing).\n */\nexport function resetDeviceProfile(): void {\n cachedProfile = null;\n}\n", "/**\n * edgeFlow.js - WebGPU Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * WebGPU and creates compute pipelines but does not perform real model\n * inference. For GPU-accelerated inference, use the ONNX Runtime backend\n * which supports WebGPU via its execution providers.\n * \n * This backend is intended for future custom WebGPU compute shader\n * implementations that bypass ONNX Runtime for specialized ops.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WebGPU Type Declarations\n// ============================================================================\n\n// Declare WebGPU types for environments without @webgpu/types\ndeclare global {\n interface Navigator {\n gpu?: GPU;\n }\n \n interface GPU {\n requestAdapter(options?: GPURequestAdapterOptions): Promise<GPUAdapter | null>;\n }\n \n interface GPURequestAdapterOptions {\n powerPreference?: 'low-power' | 'high-performance';\n }\n \n interface GPUAdapter {\n requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>;\n }\n \n interface GPUDeviceDescriptor {\n requiredFeatures?: string[];\n requiredLimits?: Record<string, number>;\n }\n \n interface GPUDevice {\n limits: GPULimits;\n lost: Promise<GPUDeviceLostInfo>;\n createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer;\n createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule;\n createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor): GPUBindGroupLayout;\n createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor): GPUPipelineLayout;\n createComputePipeline(descriptor: GPUComputePipelineDescriptor): GPUComputePipeline;\n destroy(): void;\n }\n \n interface GPULimits {\n maxBufferSize: number;\n }\n \n interface GPUDeviceLostInfo {\n message: string;\n reason: string;\n }\n \n interface GPUBuffer {\n destroy(): void;\n }\n \n interface GPUShaderModule {}\n interface GPUBindGroupLayout {}\n interface GPUPipelineLayout {}\n interface GPUComputePipeline {}\n \n interface GPUBufferDescriptor {\n size: number;\n usage: number;\n }\n \n interface GPUShaderModuleDescriptor {\n code: string;\n }\n \n interface GPUBindGroupLayoutDescriptor {\n entries: GPUBindGroupLayoutEntry[];\n }\n \n interface GPUBindGroupLayoutEntry {\n binding: number;\n visibility: number;\n buffer?: { type: string };\n }\n \n interface GPUPipelineLayoutDescriptor {\n bindGroupLayouts: GPUBindGroupLayout[];\n }\n \n interface GPUComputePipelineDescriptor {\n layout: GPUPipelineLayout;\n compute: {\n module: GPUShaderModule;\n entryPoint: string;\n };\n }\n}\n\n// WebGPU constants\nconst GPUBufferUsage = {\n STORAGE: 0x0080,\n COPY_SRC: 0x0004,\n COPY_DST: 0x0008,\n MAP_READ: 0x0001,\n};\n\nconst GPUShaderStage = {\n COMPUTE: 0x0004,\n};\n\n// ============================================================================\n// WebGPU Types\n// ============================================================================\n\n/**\n * WebGPU model data structure\n */\ninterface WebGPUModelData {\n /** Shader modules */\n shaders: Map<string, GPUShaderModule>;\n /** Compute pipelines */\n pipelines: Map<string, GPUComputePipeline>;\n /** Weight buffers */\n weights: Map<string, GPUBuffer>;\n /** Bind group layouts */\n bindGroupLayouts: GPUBindGroupLayout[];\n /** Model configuration */\n config: ModelConfig;\n}\n\n/**\n * Model configuration from model file\n */\ninterface ModelConfig {\n name: string;\n version: string;\n layers: LayerConfig[];\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n/**\n * Layer configuration\n */\ninterface LayerConfig {\n name: string;\n type: string;\n inputs: string[];\n outputs: string[];\n params: Record<string, unknown>;\n}\n\n// ============================================================================\n// WebGPU Runtime Implementation\n// ============================================================================\n\n/**\n * WebGPURuntime - GPU-accelerated inference runtime\n */\nexport class WebGPURuntime implements Runtime {\n readonly name: RuntimeType = 'webgpu';\n \n private adapter: GPUAdapter | null = null;\n private device: GPUDevice | null = null;\n private models: Map<string, WebGPUModelData> = new Map();\n private initialized = false;\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: false,\n maxBatchSize: 64,\n availableMemory: this.device?.limits.maxBufferSize ?? 256 * 1024 * 1024,\n };\n }\n\n /**\n * Check if WebGPU is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof navigator === 'undefined') return false;\n if (!navigator.gpu) return false;\n\n try {\n const adapter = await navigator.gpu.requestAdapter();\n return adapter !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WebGPU runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n if (!navigator.gpu) {\n throw new EdgeFlowError(\n 'WebGPU is not supported in this browser',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // Request adapter\n this.adapter = await navigator.gpu.requestAdapter({\n powerPreference: 'high-performance',\n });\n\n if (!this.adapter) {\n throw new EdgeFlowError(\n 'Failed to get WebGPU adapter',\n ErrorCodes.RUNTIME_INIT_FAILED\n );\n }\n\n // Request device\n this.device = await this.adapter.requestDevice({\n requiredFeatures: [],\n requiredLimits: {},\n });\n\n // Handle device loss\n this.device.lost.then((info: GPUDeviceLostInfo) => {\n console.error('WebGPU device was lost:', info.message);\n this.initialized = false;\n this.device = null;\n });\n\n this.initialized = true;\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model data\n const config = this.parseModelData(modelData);\n\n // Create shader modules and pipelines\n const webgpuData: WebGPUModelData = {\n shaders: new Map(),\n pipelines: new Map(),\n weights: new Map(),\n bindGroupLayouts: [],\n config,\n };\n\n // Extract and upload weights\n await this.uploadWeights(modelData, webgpuData);\n\n // Create compute pipelines for each layer\n await this.createPipelines(webgpuData);\n\n // Generate model ID\n const modelId = `webgpu_${Date.now().toString(36)}`;\n this.models.set(modelId, webgpuData);\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version,\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'webgpu',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n\n // For now, use a simple fallback implementation\n // In a full implementation, this would execute the compute pipelines\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model (simplified implementation)\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n // This is a simplified implementation\n // A full implementation would:\n // 1. Upload input tensors to GPU buffers\n // 2. Execute compute pipelines in topological order\n // 3. Read back output tensors\n\n const device = this.device!;\n const outputs: Tensor[] = [];\n\n for (const outputSpec of metadata.outputs) {\n // Create output buffer\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n const outputBuffer = device.createBuffer({\n size: outputSize * 4, // float32\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n\n // Create staging buffer for readback\n const stagingBuffer = device.createBuffer({\n size: outputSize * 4,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n\n // For now, return zeros (placeholder)\n // In production, execute actual compute pipelines\n const outputData = new Float32Array(outputSize);\n \n // Simulate some computation based on inputs\n if (inputs.length > 0 && inputs[0]) {\n const inputData = inputs[0].toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = (inputData[i] ?? 0);\n }\n }\n\n outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));\n\n // Cleanup\n outputBuffer.destroy();\n stagingBuffer.destroy();\n }\n\n return outputs;\n }\n\n /**\n * Parse model data\n */\n private parseModelData(data: ArrayBuffer): ModelConfig {\n // Try to parse as JSON first (for our custom format)\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));\n \n // Check if it starts with JSON\n if (text.trim().startsWith('{')) {\n // Find the JSON header end\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) jsonEnd = data.byteLength;\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as ModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n // Return default config for unknown formats\n return {\n name: 'unknown',\n version: '1.0.0',\n layers: [],\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Upload weights to GPU\n */\n private async uploadWeights(\n _data: ArrayBuffer,\n modelData: WebGPUModelData\n ): Promise<void> {\n const device = this.device!;\n\n // In a full implementation, parse weight data from the model file\n // and upload to GPU buffers\n \n // Placeholder: create empty weight buffer\n const weightsBuffer = device.createBuffer({\n size: 1024,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n\n modelData.weights.set('default', weightsBuffer);\n }\n\n /**\n * Create compute pipelines\n */\n private async createPipelines(modelData: WebGPUModelData): Promise<void> {\n const device = this.device!;\n\n // Create a general-purpose compute shader\n const shaderCode = /* wgsl */ `\n @group(0) @binding(0) var<storage, read> input: array<f32>;\n @group(0) @binding(1) var<storage, read_write> output: array<f32>;\n \n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx < arrayLength(&input)) {\n output[idx] = input[idx];\n }\n }\n `;\n\n const shaderModule = device.createShaderModule({\n code: shaderCode,\n });\n\n modelData.shaders.set('default', shaderModule);\n\n // Create bind group layout\n const bindGroupLayout = device.createBindGroupLayout({\n entries: [\n {\n binding: 0,\n visibility: GPUShaderStage.COMPUTE,\n buffer: { type: 'read-only-storage' },\n },\n {\n binding: 1,\n visibility: GPUShaderStage.COMPUTE,\n buffer: { type: 'storage' },\n },\n ],\n });\n\n modelData.bindGroupLayouts.push(bindGroupLayout);\n\n // Create pipeline layout\n const pipelineLayout = device.createPipelineLayout({\n bindGroupLayouts: [bindGroupLayout],\n });\n\n // Create compute pipeline\n const pipeline = device.createComputePipeline({\n layout: pipelineLayout,\n compute: {\n module: shaderModule,\n entryPoint: 'main',\n },\n });\n\n modelData.pipelines.set('default', pipeline);\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n const modelData = this.models.get(modelId);\n if (modelData) {\n // Destroy GPU buffers\n for (const buffer of modelData.weights.values()) {\n buffer.destroy();\n }\n this.models.delete(modelId);\n }\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.device) {\n throw new EdgeFlowError(\n 'WebGPU runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Unload all models\n for (const modelId of this.models.keys()) {\n this.unloadModel(modelId);\n }\n\n // Destroy device\n if (this.device) {\n this.device.destroy();\n this.device = null;\n }\n\n this.adapter = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WebGPU runtime factory\n */\nexport function createWebGPURuntime(): Runtime {\n return new WebGPURuntime();\n}\n", "/**\n * edgeFlow.js - WebNN Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * a WebNN context but does not perform real model inference or graph building.\n * For hardware-accelerated inference, use the ONNX Runtime backend which\n * supports WebNN via its execution providers when available.\n * \n * This backend is intended for future native WebNN graph building support.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WebNN Type Definitions (since WebNN types may not be globally available)\n// ============================================================================\n\n/**\n * WebNN context type\n */\ntype MLContextType = 'default' | 'gpu' | 'cpu' | 'npu';\n\n/**\n * WebNN operand descriptor\n */\ninterface MLOperandDescriptor {\n dataType: 'float32' | 'float16' | 'int32' | 'uint32' | 'int8' | 'uint8';\n dimensions: number[];\n}\n\n/**\n * WebNN context options\n */\ninterface MLContextOptions {\n deviceType?: MLContextType;\n powerPreference?: 'default' | 'high-performance' | 'low-power';\n}\n\n// Extend Navigator for WebNN\ndeclare global {\n interface Navigator {\n ml?: {\n createContext(options?: MLContextOptions): Promise<MLContext>;\n };\n }\n \n interface MLContext {\n compute(\n graph: MLGraph,\n inputs: Record<string, ArrayBufferView>,\n outputs: Record<string, ArrayBufferView>\n ): Promise<Record<string, ArrayBufferView>>;\n }\n \n interface MLGraph {\n // Graph interface\n }\n \n interface MLGraphBuilder {\n input(name: string, desc: MLOperandDescriptor): MLOperand;\n constant(desc: MLOperandDescriptor, data: ArrayBufferView): MLOperand;\n build(outputs: Record<string, MLOperand>): Promise<MLGraph>;\n \n // Operations\n add(a: MLOperand, b: MLOperand): MLOperand;\n sub(a: MLOperand, b: MLOperand): MLOperand;\n mul(a: MLOperand, b: MLOperand): MLOperand;\n div(a: MLOperand, b: MLOperand): MLOperand;\n matmul(a: MLOperand, b: MLOperand): MLOperand;\n relu(x: MLOperand): MLOperand;\n sigmoid(x: MLOperand): MLOperand;\n tanh(x: MLOperand): MLOperand;\n softmax(x: MLOperand): MLOperand;\n reshape(x: MLOperand, newShape: number[]): MLOperand;\n transpose(x: MLOperand, permutation?: number[]): MLOperand;\n }\n \n interface MLOperand {\n // Operand interface\n }\n}\n\n// ============================================================================\n// WebNN Model Data\n// ============================================================================\n\n/**\n * WebNN model data structure\n */\ninterface WebNNModelData {\n /** Compiled graph */\n graph: MLGraph;\n /** Graph builder (for potential graph modifications) */\n builder: MLGraphBuilder;\n /** Input names and shapes */\n inputNames: string[];\n /** Output names and shapes */\n outputNames: string[];\n /** Model configuration */\n config: WebNNModelConfig;\n}\n\n/**\n * Model configuration\n */\ninterface WebNNModelConfig {\n name: string;\n version: string;\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n// ============================================================================\n// WebNN Runtime Implementation\n// ============================================================================\n\n/**\n * WebNNRuntime - Browser-native neural network runtime\n */\nexport class WebNNRuntime implements Runtime {\n readonly name: RuntimeType = 'webnn';\n \n private context: MLContext | null = null;\n private models: Map<string, WebNNModelData> = new Map();\n private initialized = false;\n private deviceType: MLContextType = 'default';\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: false,\n maxBatchSize: 32,\n availableMemory: 256 * 1024 * 1024, // Estimated\n };\n }\n\n /**\n * Check if WebNN is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof navigator === 'undefined') return false;\n if (!navigator.ml) return false;\n\n try {\n const context = await navigator.ml.createContext({ deviceType: 'default' });\n return context !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WebNN runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n if (!navigator.ml) {\n throw new EdgeFlowError(\n 'WebNN is not supported in this browser',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // Try to get GPU context first, fallback to CPU\n try {\n this.context = await navigator.ml.createContext({ \n deviceType: 'gpu',\n powerPreference: 'high-performance',\n });\n this.deviceType = 'gpu';\n } catch {\n try {\n this.context = await navigator.ml.createContext({ deviceType: 'cpu' });\n this.deviceType = 'cpu';\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to create WebNN context: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.RUNTIME_INIT_FAILED\n );\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model configuration\n const config = this.parseModelConfig(modelData);\n\n // Note: Full WebNN implementation would build the graph here\n // This is a placeholder that creates minimal metadata\n \n const modelId = `webnn_${Date.now().toString(36)}`;\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version || '1.0.0',\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'webnn',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n\n // Simplified implementation - in production, would use compiled graph\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model (simplified implementation)\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n const outputs: Tensor[] = [];\n\n // For each expected output\n for (const outputSpec of metadata.outputs) {\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n const outputData = new Float32Array(outputSize);\n\n // Simple passthrough for demo (real impl would use WebNN compute)\n if (inputs.length > 0 && inputs[0]) {\n const inputData = inputs[0].toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = inputData[i] ?? 0;\n }\n }\n\n outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));\n }\n\n return outputs;\n }\n\n /**\n * Parse model configuration\n */\n private parseModelConfig(data: ArrayBuffer): WebNNModelConfig {\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));\n \n if (text.trim().startsWith('{')) {\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) jsonEnd = data.byteLength;\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as WebNNModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n return {\n name: 'unknown',\n version: '1.0.0',\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n this.models.delete(modelId);\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.context) {\n throw new EdgeFlowError(\n 'WebNN runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Get device type\n */\n getDeviceType(): MLContextType {\n return this.deviceType;\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n this.models.clear();\n this.context = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WebNN runtime factory\n */\nexport function createWebNNRuntime(): Runtime {\n return new WebNNRuntime();\n}\n", "/**\n * edgeFlow.js - WebAssembly Backend\n * \n * Pure WASM runtime for universal browser support.\n * Features:\n * - Universal compatibility\n * - SIMD acceleration when available\n * - Memory-efficient execution\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor, softmax as tensorSoftmax, relu as tensorRelu, sigmoid as tensorSigmoid } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// ============================================================================\n// WASM Types\n// ============================================================================\n\n/**\n * WASM module instance\n */\ninterface WASMModule {\n memory: WebAssembly.Memory;\n exports: WASMExports;\n}\n\n/**\n * WASM exported functions\n */\ninterface WASMExports {\n // Memory management\n malloc(size: number): number;\n free(ptr: number): void;\n \n // Tensor operations\n matmul_f32(\n a: number, aRows: number, aCols: number,\n b: number, bRows: number, bCols: number,\n out: number\n ): void;\n \n add_f32(a: number, b: number, out: number, size: number): void;\n mul_f32(a: number, b: number, out: number, size: number): void;\n relu_f32(input: number, output: number, size: number): void;\n sigmoid_f32(input: number, output: number, size: number): void;\n softmax_f32(input: number, output: number, size: number): void;\n \n // SIMD variants (when available)\n matmul_f32_simd?(\n a: number, aRows: number, aCols: number,\n b: number, bRows: number, bCols: number,\n out: number\n ): void;\n}\n\n/**\n * WASM model data structure\n */\ninterface WASMModelData {\n /** Weight buffers */\n weights: Map<string, { ptr: number; size: number; data: Float32Array }>;\n /** Model configuration */\n config: WASMModelConfig;\n /** Layer execution order */\n executionOrder: string[];\n}\n\n/**\n * Model configuration\n */\ninterface WASMModelConfig {\n name: string;\n version: string;\n layers: WASMLayerConfig[];\n inputs: { name: string; shape: number[]; dtype: string }[];\n outputs: { name: string; shape: number[]; dtype: string }[];\n}\n\n/**\n * Layer configuration\n */\ninterface WASMLayerConfig {\n name: string;\n type: string;\n inputShape: number[];\n outputShape: number[];\n weights?: string[];\n params?: Record<string, unknown>;\n}\n\n// ============================================================================\n// WASM Runtime Implementation\n// ============================================================================\n\n/**\n * WASMRuntime - Pure WebAssembly inference runtime\n */\nexport class WASMRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm';\n \n private module: WASMModule | null = null;\n private simdSupported = false;\n private models: Map<string, WASMModelData> = new Map();\n private initialized = false;\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: false, // WASM is single-threaded by default\n quantization: true,\n float16: false,\n dynamicShapes: true,\n maxBatchSize: 16,\n availableMemory: 128 * 1024 * 1024, // 128MB default\n };\n }\n\n /**\n * Check if WASM is available\n */\n async isAvailable(): Promise<boolean> {\n if (typeof WebAssembly === 'undefined') return false;\n\n try {\n // Check if we can instantiate a minimal WASM module\n const bytes = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, // Magic number\n 0x01, 0x00, 0x00, 0x00, // Version\n ]);\n await WebAssembly.instantiate(bytes);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Initialize the WASM runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Check SIMD support\n this.simdSupported = await this.checkSIMDSupport();\n\n // Create memory pool\n const memory = new WebAssembly.Memory({\n initial: 256, // 16MB initial\n maximum: 2048, // 128MB maximum\n });\n\n // Compile and instantiate the WASM module\n // In production, this would load an actual WASM binary\n // For now, we use a pure JS fallback\n this.module = {\n memory,\n exports: this.createJSFallback(memory),\n };\n\n this.initialized = true;\n }\n\n /**\n * Check SIMD support\n */\n private async checkSIMDSupport(): Promise<boolean> {\n try {\n // SIMD detection via feature detection\n const simdTest = new Uint8Array([\n 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,\n 0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,\n 0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,\n 0xfd, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0b\n ]);\n await WebAssembly.instantiate(simdTest);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Create JavaScript fallback for WASM operations\n */\n private createJSFallback(memory: WebAssembly.Memory): WASMExports {\n let nextPtr = 0;\n const allocations: Map<number, number> = new Map();\n\n return {\n malloc: (size: number): number => {\n const ptr = nextPtr;\n nextPtr += size;\n allocations.set(ptr, size);\n return ptr;\n },\n\n free: (ptr: number): void => {\n allocations.delete(ptr);\n },\n\n matmul_f32: (\n aPtr: number, aRows: number, aCols: number,\n bPtr: number, _bRows: number, bCols: number,\n outPtr: number\n ): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < aRows; i++) {\n for (let j = 0; j < bCols; j++) {\n let sum = 0;\n for (let k = 0; k < aCols; k++) {\n sum += (view[aOffset + i * aCols + k] ?? 0) * (view[bOffset + k * bCols + j] ?? 0);\n }\n view[outOffset + i * bCols + j] = sum;\n }\n }\n },\n\n add_f32: (aPtr: number, bPtr: number, outPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[aOffset + i] ?? 0) + (view[bOffset + i] ?? 0);\n }\n },\n\n mul_f32: (aPtr: number, bPtr: number, outPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const aOffset = aPtr / 4;\n const bOffset = bPtr / 4;\n const outOffset = outPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[aOffset + i] ?? 0) * (view[bOffset + i] ?? 0);\n }\n },\n\n relu_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = Math.max(0, view[inOffset + i] ?? 0);\n }\n },\n\n sigmoid_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = 1 / (1 + Math.exp(-(view[inOffset + i] ?? 0)));\n }\n },\n\n softmax_f32: (inputPtr: number, outputPtr: number, size: number): void => {\n const view = new Float32Array(memory.buffer);\n const inOffset = inputPtr / 4;\n const outOffset = outputPtr / 4;\n\n // Find max for numerical stability\n let max = -Infinity;\n for (let i = 0; i < size; i++) {\n if ((view[inOffset + i] ?? 0) > max) max = view[inOffset + i] ?? 0;\n }\n\n // Compute exp and sum\n let sum = 0;\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = Math.exp((view[inOffset + i] ?? 0) - max);\n sum += view[outOffset + i] ?? 0;\n }\n\n // Normalize\n for (let i = 0; i < size; i++) {\n view[outOffset + i] = (view[outOffset + i] ?? 0) / sum;\n }\n },\n };\n }\n\n /**\n * Load a model\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n this.ensureInitialized();\n\n // Parse model configuration\n const config = this.parseModelConfig(modelData);\n\n // Extract and store weights\n const wasmData: WASMModelData = {\n weights: new Map(),\n config,\n executionOrder: config.layers.map(l => l.name),\n };\n\n // Load weights into memory\n await this.loadWeights(modelData, wasmData);\n\n const modelId = `wasm_${Date.now().toString(36)}`;\n this.models.set(modelId, wasmData);\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: config.name || options.metadata?.name || 'unknown',\n version: config.version || '1.0.0',\n inputs: config.inputs.map(i => ({\n name: i.name,\n dtype: i.dtype as 'float32',\n shape: i.shape,\n })),\n outputs: config.outputs.map(o => ({\n name: o.name,\n dtype: o.dtype as 'float32',\n shape: o.shape,\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'edgeflow',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'wasm',\n () => this.unloadModel(modelId)\n );\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n this.ensureInitialized();\n \n // Execute model layers\n return this.executeModel(inputs, model.metadata);\n }\n\n /**\n * Execute model\n */\n private async executeModel(inputs: Tensor[], metadata: ModelMetadata): Promise<Tensor[]> {\n const outputs: Tensor[] = [];\n\n for (const outputSpec of metadata.outputs) {\n const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);\n \n // Process based on output requirements\n // This is a simplified implementation\n let outputTensor: EdgeFlowTensor;\n\n if (inputs.length > 0 && inputs[0]) {\n const inputTensor = inputs[0] as EdgeFlowTensor;\n \n // Apply transformations based on layer types\n // For demo, apply softmax to classification outputs\n if (outputSpec.name.includes('logits') || outputSpec.name.includes('class')) {\n outputTensor = tensorSoftmax(inputTensor) as EdgeFlowTensor;\n } else if (outputSpec.name.includes('relu')) {\n outputTensor = tensorRelu(inputTensor);\n } else if (outputSpec.name.includes('sigmoid')) {\n outputTensor = tensorSigmoid(inputTensor);\n } else {\n // Identity or feature extraction\n const outputData = new Float32Array(outputSize);\n const inputData = inputTensor.toFloat32Array();\n for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {\n outputData[i] = inputData[i] ?? 0;\n }\n outputTensor = new EdgeFlowTensor(outputData, outputSpec.shape, 'float32');\n }\n } else {\n outputTensor = new EdgeFlowTensor(new Float32Array(outputSize), outputSpec.shape, 'float32');\n }\n\n outputs.push(outputTensor);\n }\n\n return outputs;\n }\n\n /**\n * Parse model configuration\n */\n private parseModelConfig(data: ArrayBuffer): WASMModelConfig {\n try {\n const decoder = new TextDecoder();\n const text = decoder.decode(new Uint8Array(data, 0, Math.min(2048, data.byteLength)));\n \n if (text.trim().startsWith('{')) {\n let jsonEnd = text.indexOf('\\n---\\n');\n if (jsonEnd === -1) {\n // Try to parse as pure JSON\n try {\n return JSON.parse(text) as WASMModelConfig;\n } catch {\n jsonEnd = data.byteLength;\n }\n }\n \n const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));\n return JSON.parse(jsonStr) as WASMModelConfig;\n }\n } catch {\n // Not JSON format\n }\n\n return {\n name: 'unknown',\n version: '1.0.0',\n layers: [],\n inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],\n outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],\n };\n }\n\n /**\n * Load weights into WASM memory\n */\n private async loadWeights(\n _modelData: ArrayBuffer,\n _wasmData: WASMModelData\n ): Promise<void> {\n // In a full implementation, extract and load weights\n // This is a placeholder\n }\n\n /**\n * Unload a model\n */\n private unloadModel(modelId: string): void {\n const modelData = this.models.get(modelId);\n if (modelData && this.module) {\n // Free weight buffers\n for (const weight of modelData.weights.values()) {\n this.module.exports.free(weight.ptr);\n }\n }\n this.models.delete(modelId);\n }\n\n /**\n * Ensure runtime is initialized\n */\n private ensureInitialized(): void {\n if (!this.initialized || !this.module) {\n throw new EdgeFlowError(\n 'WASM runtime is not initialized',\n ErrorCodes.RUNTIME_NOT_INITIALIZED\n );\n }\n }\n\n /**\n * Check if SIMD is supported\n */\n hasSIMDSupport(): boolean {\n return this.simdSupported;\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Free all model weights\n for (const modelId of this.models.keys()) {\n this.unloadModel(modelId);\n }\n\n this.module = null;\n this.initialized = false;\n }\n}\n\n/**\n * Create WASM runtime factory\n */\nexport function createWASMRuntime(): Runtime {\n return new WASMRuntime();\n}\n", "/**\n * edgeFlow.js - ONNX Runtime Backend\n * \n * Uses onnxruntime-web for real ONNX model inference.\n * onnxruntime-web is an optional peer dependency loaded dynamically.\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n DataType,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\n\n// Lazy-loaded onnxruntime-web module\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet ort: any = null;\n\n// A consumer-injected onnxruntime-web module. Bundlers like Vite don't\n// always preserve the dynamic `import('onnxruntime-web/wasm')` below\n// inside a Web Worker chunk; when that import is dropped the backend\n// silently reports \"no runtime available\". Consumers that statically\n// import ORT in their worker can inject it here so getOrt() never has to\n// rely on the dynamic import.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet injectedOrt: any = null;\n\n/**\n * Override paths for the onnxruntime-web WASM assets, mirroring ORT's\n * `env.wasm.wasmPaths` object form. Set via {@link configureOnnxAssets}\n * when the consumer's bundler emits content-hashed asset URLs (a bare\n * directory prefix can't address those).\n */\nexport interface OnnxAssetPaths {\n /** URL/path for the main `.wasm` binary. */\n wasm?: string;\n /** URL/path for the loader `.mjs` glue. */\n mjs?: string;\n}\n\nlet onnxAssetPaths: OnnxAssetPaths | null = null;\n\n/**\n * Inject a pre-imported onnxruntime-web module \u2014 the recommended\n * integration path for Web Workers and custom bundler setups, where the\n * internal dynamic `import('onnxruntime-web/wasm')` may be dropped.\n *\n * ONNX Runtime is an optional peer dependency that the consumer owns:\n * once you inject a module, **you** own its configuration. Configure it\n * first (`ort.env.wasm.wasmPaths`, `numThreads`, execution providers,\n * ...) and the backend will use it as-is without overriding anything.\n *\n * import * as ort from \"onnxruntime-web/wasm\";\n * ort.env.wasm.wasmPaths = { wasm: wasmUrl, mjs: mjsUrl };\n * ort.env.wasm.numThreads = 1;\n * setOnnxModule(ort);\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function setOnnxModule(module: any): void {\n injectedOrt = module;\n}\n\n/**\n * Configure the onnxruntime-web WASM asset locations (sets\n * `env.wasm.wasmPaths` during init). Primarily for the auto-load path \u2014\n * when you let the backend import ORT itself but your bundler content-\n * hashes the `.wasm` / `.mjs` files (e.g. Vite `?url` imports), so the\n * default `/ort/` prefix can't resolve them. If you inject your own\n * module via {@link setOnnxModule}, prefer configuring it directly.\n * An explicit call here is still honored even for an injected module.\n */\nexport function configureOnnxAssets(paths: OnnxAssetPaths): void {\n onnxAssetPaths = paths;\n}\n\nasync function getOrt(): Promise<any> {\n if (injectedOrt) return injectedOrt;\n if (ort) return ort;\n try {\n // Import the WASM-only sub-path so Vite rewrites the bare specifier\n // to ort.wasm.bundle.min.mjs. This avoids loading the JSEP/WebGPU\n // worker module (jsep.mjs) that ort.bundle.min.mjs eagerly fetches\n // whenever navigator.gpu exists \u2014 which causes a 404 in dev servers\n // that restrict ES module imports from /public.\n ort = await import('onnxruntime-web/wasm');\n return ort;\n } catch {\n return null;\n }\n}\n\n/**\n * Check whether onnxruntime-web is importable.\n */\nexport async function isOnnxAvailable(): Promise<boolean> {\n return (await getOrt()) != null;\n}\n\n// ============================================================================\n// ONNX Session Storage\n// ============================================================================\n\ninterface ONNXSessionData {\n session: any; // ort.InferenceSession\n inputNames: string[];\n outputNames: string[];\n}\n\nconst sessionStore: Map<string, ONNXSessionData> = new Map();\n\n// ============================================================================\n// ONNX Runtime Implementation\n// ============================================================================\n\n/**\n * ONNXRuntime - Real ONNX model inference using onnxruntime-web\n */\nexport class ONNXRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm'; // Register as wasm since it's the fallback\n \n private initialized = false;\n private executionProvider: 'webgpu' | 'wasm' = 'wasm';\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: this.executionProvider === 'webgpu',\n dynamicShapes: true,\n maxBatchSize: 32,\n availableMemory: 512 * 1024 * 1024, // 512MB\n };\n }\n\n /**\n * Check if ONNX Runtime is available (peer dependency installed)\n */\n async isAvailable(): Promise<boolean> {\n return isOnnxAvailable();\n }\n\n /**\n * Initialize the ONNX runtime\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n const ortModule = await getOrt();\n if (!ortModule) {\n // Two distinct causes land here, and the fix differs \u2014 say both so\n // a consumer who DID install ORT isn't sent chasing a phantom\n // missing dependency:\n // 1. onnxruntime-web genuinely isn't installed.\n // 2. It's installed, but the internal dynamic import was dropped /\n // not resolved by the bundler \u2014 common in Web Workers and some\n // Vite setups. The fix there is to inject it, not reinstall.\n throw new EdgeFlowError(\n 'onnxruntime-web could not be loaded.\\n' +\n ' - If it is not installed: `npm install onnxruntime-web`.\\n' +\n ' - If it IS installed (e.g. you see this inside a Web Worker, or ' +\n 'with a bundler that drops the internal dynamic import): import it ' +\n 'yourself and inject it before use \u2014 `import * as ort from ' +\n '\"onnxruntime-web/wasm\"; setOnnxModule(ort);`',\n ErrorCodes.RUNTIME_NOT_AVAILABLE\n );\n }\n\n // onnxruntime-web is an optional peer dependency the CONSUMER owns.\n // When they inject a module via setOnnxModule(), they're responsible\n // for its configuration (wasmPaths, numThreads, execution providers),\n // so we don't touch it \u2014 the library defers entirely. We only apply\n // convenience defaults when WE auto-loaded ORT ourselves, and even\n // then never clobber a value the consumer already set.\n //\n // An explicit configureOnnxAssets() call is honored regardless of how\n // ORT was loaded \u2014 it's an explicit consumer request, not us guessing.\n //\n // Note this is intentionally NOT gated on `typeof window`: Web Workers\n // have no `window`, and the old gate left ORT unconfigured (hence\n // unusable) in exactly that context.\n const wasmEnv = ortModule.env?.wasm as any;\n if (wasmEnv) {\n if (onnxAssetPaths) {\n wasmEnv.wasmPaths = { ...onnxAssetPaths };\n } else if (!injectedOrt && wasmEnv.wasmPaths === undefined) {\n wasmEnv.wasmPaths = '/ort/';\n }\n if (!injectedOrt && wasmEnv.numThreads === undefined) {\n wasmEnv.numThreads = 1;\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Load a model from ArrayBuffer\n */\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {}\n ): Promise<LoadedModel> {\n if (!this.initialized) {\n await this.initialize();\n }\n\n try {\n const ortModule = await getOrt();\n if (!ortModule) {\n throw new Error('onnxruntime-web is not installed');\n }\n\n // WASM-only execution provider \u2014 WebGPU acceleration can be added\n // later via the dedicated WebGPURuntime backend.\n const sessionOptions = {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n };\n\n const modelBytes = new Uint8Array(modelData);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const session: any = await ortModule.InferenceSession.create(modelBytes, sessionOptions);\n \n // Get input/output names\n const inputNames = session.inputNames;\n const outputNames = session.outputNames;\n\n // Generate model ID\n const modelId = `onnx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\n\n // Store session\n sessionStore.set(modelId, {\n session,\n inputNames: [...inputNames],\n outputNames: [...outputNames],\n });\n\n // Create metadata\n const metadata: ModelMetadata = {\n name: options.metadata?.name ?? 'onnx-model',\n version: '1.0.0',\n inputs: inputNames.map((name: string) => ({\n name,\n dtype: 'float32' as DataType,\n shape: [-1], // Dynamic shape\n })),\n outputs: outputNames.map((name: string) => ({\n name,\n dtype: 'float32' as DataType,\n shape: [-1],\n })),\n sizeBytes: modelData.byteLength,\n quantization: options.quantization ?? 'float32',\n format: 'onnx',\n };\n\n // Create model instance\n const model = new LoadedModelImpl(\n metadata,\n 'wasm',\n () => this.unloadModel(modelId)\n );\n\n // Override the ID to match our stored session\n Object.defineProperty(model, 'id', { value: modelId, writable: false });\n\n // Track in memory manager\n getMemoryManager().trackModel(model, () => model.dispose());\n\n return model;\n } catch (error) {\n throw new EdgeFlowError(\n `Failed to load ONNX model: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.MODEL_LOAD_FAILED,\n { error }\n );\n }\n }\n\n /**\n * Run inference\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n const sessionData = sessionStore.get(model.id);\n if (!sessionData) {\n throw new EdgeFlowError(\n `ONNX session not found for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const { session, inputNames, outputNames } = sessionData;\n\n try {\n const ortModule = await getOrt();\n const feeds: Record<string, any> = {};\n \n for (let i = 0; i < Math.min(inputs.length, inputNames.length); i++) {\n const inputName = inputNames[i];\n const inputTensor = inputs[i] as EdgeFlowTensor;\n \n if (inputName && inputTensor) {\n const dtype = inputTensor.dtype;\n let ortTensor: any;\n \n if (dtype === 'int64') {\n const data = inputTensor.data as unknown as BigInt64Array;\n ortTensor = new ortModule.Tensor('int64', data, inputTensor.shape as number[]);\n } else if (dtype === 'int32') {\n const data = inputTensor.data as Int32Array;\n ortTensor = new ortModule.Tensor('int32', data, inputTensor.shape as number[]);\n } else {\n const data = inputTensor.toFloat32Array();\n ortTensor = new ortModule.Tensor('float32', data, inputTensor.shape as number[]);\n }\n \n feeds[inputName] = ortTensor;\n }\n }\n\n const results = await session.run(feeds);\n\n // Convert outputs to EdgeFlowTensor\n const outputs: Tensor[] = [];\n \n for (const outputName of outputNames) {\n const ortTensor = results[outputName];\n if (ortTensor) {\n const data = ortTensor.data as Float32Array;\n const shape = Array.from(ortTensor.dims).map(d => Number(d));\n outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));\n }\n }\n\n return outputs;\n } catch (error) {\n throw new EdgeFlowError(\n `ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id, error }\n );\n }\n }\n\n /**\n * Run inference with named inputs\n */\n async runNamed(model: LoadedModel, namedInputs: Map<string, Tensor>): Promise<Tensor[]> {\n const sessionData = sessionStore.get(model.id);\n if (!sessionData) {\n throw new EdgeFlowError(\n `ONNX session not found for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n { modelId: model.id }\n );\n }\n\n const { session, inputNames, outputNames } = sessionData;\n\n try {\n const ortModule = await getOrt();\n const feeds: Record<string, any> = {};\n \n for (const [inputName, inputTensor] of namedInputs) {\n const tensor = inputTensor as EdgeFlowTensor;\n const dtype = tensor.dtype;\n let ortTensor: any;\n \n if (dtype === 'int64') {\n const data = tensor.data as unknown as BigInt64Array;\n ortTensor = new ortModule.Tensor('int64', data, tensor.shape as number[]);\n } else if (dtype === 'int32') {\n const data = tensor.data as Int32Array;\n ortTensor = new ortModule.Tensor('int32', data, tensor.shape as number[]);\n } else {\n const data = tensor.toFloat32Array();\n ortTensor = new ortModule.Tensor('float32', data, tensor.shape as number[]);\n }\n \n feeds[inputName] = ortTensor;\n }\n\n const results = await session.run(feeds);\n\n // Convert outputs to EdgeFlowTensor\n const outputs: Tensor[] = [];\n \n for (const outputName of outputNames) {\n const ortTensor = results[outputName];\n if (ortTensor) {\n const data = ortTensor.data as Float32Array;\n const shape = Array.from(ortTensor.dims).map(d => Number(d));\n outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));\n }\n }\n\n return outputs;\n } catch (error) {\n throw new EdgeFlowError(\n `ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`,\n ErrorCodes.INFERENCE_FAILED,\n { modelId: model.id, expectedInputs: inputNames, providedInputs: Array.from(namedInputs.keys()), error }\n );\n }\n }\n\n /**\n * Unload a model\n */\n private async unloadModel(modelId: string): Promise<void> {\n const sessionData = sessionStore.get(modelId);\n if (sessionData) {\n // Release session will be handled by GC\n sessionStore.delete(modelId);\n }\n }\n\n /**\n * Dispose the runtime\n */\n dispose(): void {\n // Clear all sessions\n sessionStore.clear();\n this.initialized = false;\n }\n}\n\n/**\n * Create ONNX runtime factory\n */\nexport function createONNXRuntime(): Runtime {\n return new ONNXRuntime();\n}\n", "/**\n * edgeFlow.js - transformers.js Adapter Backend\n *\n * Wraps transformers.js (by Hugging Face) as an inference backend, giving\n * users access to 1000+ HuggingFace models while adding edgeFlow.js's\n * orchestration layer (scheduling, caching, memory management, workers).\n *\n * @example\n * ```typescript\n * import { useTransformersBackend } from 'edgeflowjs';\n * import { pipeline as tfPipeline } from '@xenova/transformers';\n *\n * // Register the adapter\n * useTransformersBackend();\n *\n * // Now use edgeFlow.js pipeline API \u2014 inference delegates to transformers.js\n * const classifier = await pipeline('text-classification', {\n * model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n * });\n *\n * // edgeFlow.js handles scheduling, batching, memory, caching\n * const results = await classifier.runBatch(thousandsOfTexts);\n * ```\n */\n\nimport {\n Runtime,\n RuntimeType,\n RuntimeCapabilities,\n LoadedModel,\n ModelLoadOptions,\n ModelMetadata,\n Tensor,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\nimport { LoadedModelImpl } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { getMemoryManager } from '../core/memory.js';\nimport { registerRuntime } from '../core/runtime.js';\n\n// ---------------------------------------------------------------------------\n// Types for the transformers.js interop\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal interface for a transformers.js pipeline instance.\n * We avoid importing @xenova/transformers directly so edgeFlow.js\n * does not add it as a hard dependency.\n */\ninterface TransformersPipelineInstance {\n (input: unknown, options?: unknown): Promise<unknown>;\n dispose?: () => Promise<void> | void;\n}\n\n/**\n * A factory that creates a transformers.js pipeline.\n * Users pass this so we don't hard-depend on the library.\n */\nexport type TransformersPipelineFactory = (\n task: string,\n model?: string,\n options?: Record<string, unknown>,\n) => Promise<TransformersPipelineInstance>;\n\n/**\n * Options for configuring the transformers.js adapter.\n */\nexport interface TransformersAdapterOptions {\n /** The pipeline factory from transformers.js (e.g. the `pipeline` function) */\n pipelineFactory: TransformersPipelineFactory;\n /** Default device ('webgpu' | 'wasm' | 'cpu') \u2014 passed to transformers.js */\n device?: string;\n /** Default dtype ('fp32' | 'fp16' | 'q8' | 'q4') */\n dtype?: string;\n /** Cache directory (browser IndexedDB path) */\n cacheDir?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Session store: maps model IDs to transformers.js pipeline instances\n// ---------------------------------------------------------------------------\n\nconst sessionStore = new Map<string, {\n instance: TransformersPipelineInstance;\n task: string;\n model: string;\n}>();\n\nlet adapterOptions: TransformersAdapterOptions | null = null;\n\n// ---------------------------------------------------------------------------\n// Runtime implementation\n// ---------------------------------------------------------------------------\n\nexport class TransformersAdapterRuntime implements Runtime {\n readonly name: RuntimeType = 'wasm'; // registers under the wasm slot\n\n get capabilities(): RuntimeCapabilities {\n return {\n concurrency: true,\n quantization: true,\n float16: true,\n dynamicShapes: true,\n maxBatchSize: 128,\n availableMemory: 1024 * 1024 * 1024,\n };\n }\n\n async isAvailable(): Promise<boolean> {\n return adapterOptions?.pipelineFactory != null;\n }\n\n async initialize(): Promise<void> {\n if (!adapterOptions?.pipelineFactory) {\n throw new EdgeFlowError(\n 'TransformersAdapterRuntime requires a pipelineFactory. ' +\n 'Call useTransformersBackend({ pipelineFactory }) first.',\n ErrorCodes.RUNTIME_INIT_FAILED,\n );\n }\n }\n\n async loadModel(\n modelData: ArrayBuffer,\n options: ModelLoadOptions = {},\n ): Promise<LoadedModel> {\n // modelData is unused \u2014 transformers.js downloads its own models.\n // Instead the model identifier comes via metadata.name or the URL.\n const modelName = options.metadata?.name ?? 'default';\n\n const metadata: ModelMetadata = {\n name: modelName,\n version: '1.0.0',\n inputs: [{ name: 'input', dtype: 'float32', shape: [-1] }],\n outputs: [{ name: 'output', dtype: 'float32', shape: [-1] }],\n sizeBytes: modelData.byteLength || 0,\n quantization: options.quantization ?? 'float32',\n format: 'onnx',\n };\n\n const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n\n const model = new LoadedModelImpl(metadata, this.name, () => {\n const session = sessionStore.get(modelId);\n if (session?.instance.dispose) {\n session.instance.dispose();\n }\n sessionStore.delete(modelId);\n });\n\n getMemoryManager().trackModel(model, () => model.dispose());\n return model;\n }\n\n /**\n * Load a transformers.js pipeline by task + model name\n * (called by the higher-level adapter pipeline, not via the\n * standard loadModel path).\n */\n async loadPipeline(\n task: string,\n model: string,\n pipelineOptions?: Record<string, unknown>,\n ): Promise<string> {\n if (!adapterOptions?.pipelineFactory) {\n throw new EdgeFlowError(\n 'Adapter not initialised',\n ErrorCodes.RUNTIME_NOT_INITIALIZED,\n );\n }\n\n const opts: Record<string, unknown> = { ...pipelineOptions };\n if (adapterOptions.device) opts['device'] = adapterOptions.device;\n if (adapterOptions.dtype) opts['dtype'] = adapterOptions.dtype;\n\n const instance = await adapterOptions.pipelineFactory(task, model, opts);\n const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;\n sessionStore.set(modelId, { instance, task, model });\n\n return modelId;\n }\n\n /**\n * Run inference by passing the raw input to the transformers.js pipeline.\n * The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output\n * (since transformers.js returns task-specific objects, not raw tensors).\n */\n async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {\n const session = sessionStore.get(model.id);\n if (!session) {\n throw new EdgeFlowError(\n `No transformers.js session for model ${model.id}`,\n ErrorCodes.MODEL_NOT_LOADED,\n );\n }\n\n // Reconstruct input from tensor (simple: use the float data as-is)\n const inputData = inputs[0]?.toFloat32Array() ?? new Float32Array(0);\n const result = await session.instance(inputData);\n\n // Wrap the result in a tensor \u2014 downstream pipelines can interpret it\n const resultArray = Array.isArray(result)\n ? new Float32Array(result.flat(Infinity) as number[])\n : new Float32Array([0]);\n\n return [new EdgeFlowTensor(resultArray, [resultArray.length], 'float32')];\n }\n\n /**\n * High-level: run the transformers.js pipeline directly with arbitrary input.\n * Returns the raw result object (not a tensor).\n */\n async runDirect(\n modelId: string,\n input: unknown,\n options?: Record<string, unknown>,\n ): Promise<unknown> {\n const session = sessionStore.get(modelId);\n if (!session) {\n throw new EdgeFlowError(\n `No transformers.js session for model ${modelId}`,\n ErrorCodes.MODEL_NOT_LOADED,\n );\n }\n return session.instance(input, options);\n }\n\n dispose(): void {\n for (const [id, session] of sessionStore) {\n if (session.instance.dispose) {\n session.instance.dispose();\n }\n sessionStore.delete(id);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nlet adapterRuntime: TransformersAdapterRuntime | null = null;\n\n/**\n * Register the transformers.js adapter as the default inference backend.\n *\n * @example\n * ```typescript\n * import { pipeline } from '@xenova/transformers';\n * import { useTransformersBackend } from 'edgeflowjs';\n *\n * useTransformersBackend({\n * pipelineFactory: pipeline,\n * device: 'webgpu',\n * dtype: 'fp16',\n * });\n * ```\n */\nexport function useTransformersBackend(options: TransformersAdapterOptions): void {\n adapterOptions = options;\n adapterRuntime = new TransformersAdapterRuntime();\n registerRuntime('wasm', () => adapterRuntime!);\n}\n\n/**\n * Get the adapter runtime instance (for advanced use).\n */\nexport function getTransformersAdapter(): TransformersAdapterRuntime | null {\n return adapterRuntime;\n}\n", "/**\n * edgeFlow.js - Backend Exports\n */\n\n// WebGPU Backend (planned - skeleton only)\nexport { WebGPURuntime, createWebGPURuntime } from './webgpu.js';\n\n// WebNN Backend (planned - skeleton only)\nexport { WebNNRuntime, createWebNNRuntime } from './webnn.js';\n\n// WASM Backend (basic tensor ops)\nexport { WASMRuntime, createWASMRuntime } from './wasm.js';\n\n// ONNX Runtime Backend (real model inference)\nexport {\n ONNXRuntime,\n createONNXRuntime,\n isOnnxAvailable,\n setOnnxModule,\n configureOnnxAssets,\n type OnnxAssetPaths,\n} from './onnx.js';\n\n// transformers.js Adapter Backend\nexport {\n TransformersAdapterRuntime,\n useTransformersBackend,\n getTransformersAdapter,\n type TransformersAdapterOptions,\n type TransformersPipelineFactory,\n} from './transformers-adapter.js';\n\n// Re-export types\nexport type { Runtime, RuntimeType, RuntimeCapabilities } from '../core/types.js';\n\nimport { registerRuntime } from '../core/runtime.js';\nimport { createONNXRuntime } from './onnx.js';\n\n/**\n * Register all available backends.\n *\n * Always registers the ONNX Runtime factory synchronously so there is no\n * async race between registration and the first pipeline() call.\n * `ONNXRuntime.isAvailable()` is called lazily by RuntimeManager when it\n * selects a backend, so if onnxruntime-web is not installed the runtime is\n * simply skipped at that point.\n */\nexport function registerAllBackends(): void {\n registerRuntime('wasm', createONNXRuntime);\n}\n\n/**\n * Auto-register backends on module load (synchronous \u2014 no race condition).\n */\nregisterAllBackends();\n", "/**\n * edgeFlow.js - Caching Utilities\n * \n * Smart caching for models, tensors, and inference results.\n */\n\n// ============================================================================\n// Cache Types\n// ============================================================================\n\n/**\n * Cache strategy types\n */\nexport type CacheStrategy = 'lru' | 'lfu' | 'fifo' | 'ttl';\n\n/**\n * Cache entry\n */\ninterface CacheEntry<T> {\n value: T;\n size: number;\n createdAt: number;\n accessedAt: number;\n accessCount: number;\n ttl?: number;\n}\n\n/**\n * Cache options\n */\nexport interface CacheOptions {\n /** Cache strategy */\n strategy?: CacheStrategy;\n /** Maximum cache size in bytes */\n maxSize?: number;\n /** Maximum number of entries */\n maxEntries?: number;\n /** Default TTL in milliseconds */\n ttl?: number;\n /** Enable persistence to IndexedDB */\n persistent?: boolean;\n /** Cache name for persistence */\n name?: string;\n}\n\n/**\n * Cache statistics\n */\nexport interface CacheStats {\n /** Number of entries */\n entries: number;\n /** Total size in bytes */\n size: number;\n /** Cache hits */\n hits: number;\n /** Cache misses */\n misses: number;\n /** Hit rate (0-1) */\n hitRate: number;\n}\n\n// ============================================================================\n// Cache Implementation\n// ============================================================================\n\n/**\n * Cache - Generic cache implementation\n */\nexport class Cache<T> {\n private readonly options: Required<CacheOptions>;\n private readonly cache: Map<string, CacheEntry<T>> = new Map();\n private currentSize = 0;\n private hits = 0;\n private misses = 0;\n\n constructor(options: CacheOptions = {}) {\n this.options = {\n strategy: options.strategy ?? 'lru',\n maxSize: options.maxSize ?? 100 * 1024 * 1024, // 100MB\n maxEntries: options.maxEntries ?? 1000,\n ttl: options.ttl ?? 0, // 0 = no TTL\n persistent: options.persistent ?? false,\n name: options.name ?? 'edgeflow-cache',\n };\n\n // Load from persistent storage if enabled\n if (this.options.persistent) {\n this.loadFromStorage();\n }\n }\n\n /**\n * Get value from cache\n */\n get(key: string): T | undefined {\n const entry = this.cache.get(key);\n \n if (!entry) {\n this.misses++;\n return undefined;\n }\n\n // Check TTL\n if (entry.ttl && Date.now() - entry.createdAt > entry.ttl) {\n this.delete(key);\n this.misses++;\n return undefined;\n }\n\n // Update access stats\n entry.accessedAt = Date.now();\n entry.accessCount++;\n this.hits++;\n\n return entry.value;\n }\n\n /**\n * Set value in cache\n */\n set(key: string, value: T, size: number, ttl?: number): void {\n // Remove existing entry if present\n if (this.cache.has(key)) {\n this.delete(key);\n }\n\n // Evict entries if necessary\n while (\n (this.currentSize + size > this.options.maxSize ||\n this.cache.size >= this.options.maxEntries) &&\n this.cache.size > 0\n ) {\n this.evict();\n }\n\n // Determine TTL value\n const entryTtl = ttl !== undefined ? ttl : (this.options.ttl > 0 ? this.options.ttl : undefined);\n\n // Add new entry\n const entry: CacheEntry<T> = {\n value,\n size,\n createdAt: Date.now(),\n accessedAt: Date.now(),\n accessCount: 1,\n ttl: entryTtl,\n };\n\n this.cache.set(key, entry);\n this.currentSize += size;\n\n // Persist if enabled\n if (this.options.persistent) {\n this.saveToStorage();\n }\n }\n\n /**\n * Check if key exists\n */\n has(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n\n // Check TTL\n if (entry.ttl && Date.now() - entry.createdAt > entry.ttl) {\n this.delete(key);\n return false;\n }\n\n return true;\n }\n\n /**\n * Delete entry\n */\n delete(key: string): boolean {\n const entry = this.cache.get(key);\n if (entry) {\n this.currentSize -= entry.size;\n this.cache.delete(key);\n \n if (this.options.persistent) {\n this.saveToStorage();\n }\n \n return true;\n }\n return false;\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n this.cache.clear();\n this.currentSize = 0;\n this.hits = 0;\n this.misses = 0;\n\n if (this.options.persistent) {\n this.clearStorage();\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): CacheStats {\n const total = this.hits + this.misses;\n return {\n entries: this.cache.size,\n size: this.currentSize,\n hits: this.hits,\n misses: this.misses,\n hitRate: total > 0 ? this.hits / total : 0,\n };\n }\n\n /**\n * Evict an entry based on strategy\n */\n private evict(): void {\n let keyToEvict: string | null = null;\n\n switch (this.options.strategy) {\n case 'lru':\n keyToEvict = this.findLRU();\n break;\n case 'lfu':\n keyToEvict = this.findLFU();\n break;\n case 'fifo':\n keyToEvict = this.findOldest();\n break;\n case 'ttl':\n keyToEvict = this.findExpired() ?? this.findOldest();\n break;\n }\n\n if (keyToEvict) {\n this.delete(keyToEvict);\n }\n }\n\n /**\n * Find least recently used entry\n */\n private findLRU(): string | null {\n let oldest: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.accessedAt < oldestTime) {\n oldestTime = entry.accessedAt;\n oldest = key;\n }\n }\n\n return oldest;\n }\n\n /**\n * Find least frequently used entry\n */\n private findLFU(): string | null {\n let lfu: string | null = null;\n let minCount = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.accessCount < minCount) {\n minCount = entry.accessCount;\n lfu = key;\n }\n }\n\n return lfu;\n }\n\n /**\n * Find oldest entry (FIFO)\n */\n private findOldest(): string | null {\n let oldest: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of this.cache) {\n if (entry.createdAt < oldestTime) {\n oldestTime = entry.createdAt;\n oldest = key;\n }\n }\n\n return oldest;\n }\n\n /**\n * Find expired entry\n */\n private findExpired(): string | null {\n const now = Date.now();\n\n for (const [key, entry] of this.cache) {\n if (entry.ttl && now - entry.createdAt > entry.ttl) {\n return key;\n }\n }\n\n return null;\n }\n\n /**\n * Load cache from IndexedDB\n */\n private async loadFromStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readonly');\n const store = tx.objectStore('cache');\n const request = store.getAll();\n\n return new Promise((resolve, reject) => {\n request.onsuccess = () => {\n const entries = request.result as Array<{ key: string; entry: CacheEntry<T> }>;\n for (const { key, entry } of entries) {\n this.cache.set(key, entry);\n this.currentSize += entry.size;\n }\n resolve();\n };\n request.onerror = () => reject(request.error);\n });\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Save cache to IndexedDB\n */\n private async saveToStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readwrite');\n const store = tx.objectStore('cache');\n\n // Clear existing entries\n store.clear();\n\n // Add current entries\n for (const [key, entry] of this.cache) {\n store.put({ key, entry });\n }\n\n return new Promise((resolve, reject) => {\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Clear IndexedDB storage\n */\n private async clearStorage(): Promise<void> {\n if (typeof indexedDB === 'undefined') return;\n\n try {\n const db = await this.openDB();\n const tx = db.transaction('cache', 'readwrite');\n const store = tx.objectStore('cache');\n store.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n /**\n * Open IndexedDB database\n */\n private openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.options.name, 1);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains('cache')) {\n db.createObjectStore('cache', { keyPath: 'key' });\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n}\n\n// ============================================================================\n// Inference Result Cache\n// ============================================================================\n\n/**\n * InferenceCache - Cache for inference results\n */\nexport class InferenceCache extends Cache<Float32Array> {\n /**\n * Generate cache key from input\n */\n generateKey(modelId: string, input: Float32Array | number[]): string {\n // Create hash from input data\n const inputArray = Array.isArray(input) ? input : Array.from(input);\n const hash = this.hashArray(inputArray);\n return `${modelId}:${hash}`;\n }\n\n /**\n * Simple hash function for arrays\n */\n private hashArray(arr: number[]): string {\n let hash = 0;\n const sample = arr.length > 100 \n ? arr.filter((_, i) => i % Math.floor(arr.length / 100) === 0)\n : arr;\n \n for (let i = 0; i < sample.length; i++) {\n const value = sample[i] ?? 0;\n hash = ((hash << 5) - hash) + (value * 1000 | 0);\n hash |= 0;\n }\n \n return hash.toString(36);\n }\n}\n\n// ============================================================================\n// Model Cache\n// ============================================================================\n\n/**\n * Model download cache using Cache API\n */\nexport class ModelDownloadCache {\n private readonly cacheName: string;\n private cache: globalThis.Cache | null = null;\n\n constructor(cacheName: string = 'edgeflow-models') {\n this.cacheName = cacheName;\n }\n\n /**\n * Initialize cache\n */\n private async ensureCache(): Promise<globalThis.Cache> {\n if (!this.cache) {\n if (typeof caches === 'undefined') {\n throw new Error('Cache API is not available');\n }\n this.cache = await caches.open(this.cacheName);\n }\n return this.cache;\n }\n\n /**\n * Get cached response\n */\n async get(url: string): Promise<Response | undefined> {\n try {\n const cache = await this.ensureCache();\n return await cache.match(url) ?? undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Store response in cache\n */\n async put(url: string, response: Response): Promise<void> {\n try {\n const cache = await this.ensureCache();\n await cache.put(url, response.clone());\n } catch {\n // Ignore cache errors\n }\n }\n\n /**\n * Delete cached response\n */\n async delete(url: string): Promise<boolean> {\n try {\n const cache = await this.ensureCache();\n return await cache.delete(url);\n } catch {\n return false;\n }\n }\n\n /**\n * Clear all cached models\n */\n async clear(): Promise<void> {\n try {\n await caches.delete(this.cacheName);\n this.cache = null;\n } catch {\n // Ignore cache errors\n }\n }\n\n /**\n * Get all cached URLs\n */\n async keys(): Promise<string[]> {\n try {\n const cache = await this.ensureCache();\n const requests = await cache.keys();\n return requests.map(r => r.url);\n } catch {\n return [];\n }\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a cache with common presets\n */\nexport function createCache<T>(\n preset: 'small' | 'medium' | 'large' | 'custom' = 'medium',\n options: CacheOptions = {}\n): Cache<T> {\n const presets: Record<string, CacheOptions> = {\n small: {\n maxSize: 10 * 1024 * 1024, // 10MB\n maxEntries: 100,\n },\n medium: {\n maxSize: 100 * 1024 * 1024, // 100MB\n maxEntries: 500,\n },\n large: {\n maxSize: 500 * 1024 * 1024, // 500MB\n maxEntries: 2000,\n },\n custom: {},\n };\n\n return new Cache<T>({ ...presets[preset], ...options });\n}\n", "/**\n * edgeFlow.js - Base Pipeline\n * \n * Base class and utilities for all pipeline implementations.\n */\n\nimport {\n LoadedModel,\n PipelineConfig,\n PipelineOptions,\n PipelineTask,\n} from '../core/types.js';\nimport { loadModel, runInference } from '../core/runtime.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { ModelCache } from '../core/memory.js';\nimport { ModelDownloadCache } from '../utils/cache.js';\n\n// ============================================================================\n// Pipeline Types\n// ============================================================================\n\n/**\n * Pipeline result base interface\n */\nexport interface PipelineResult {\n /** Processing time in milliseconds */\n processingTime?: number;\n}\n\n/**\n * Text classification result\n */\nexport interface TextClassificationResult extends PipelineResult {\n label: string;\n score: number;\n}\n\n/**\n * Feature extraction result\n */\nexport interface FeatureExtractionResult extends PipelineResult {\n embeddings: number[];\n}\n\n/**\n * Image classification result\n */\nexport interface ImageClassificationResult extends PipelineResult {\n label: string;\n score: number;\n}\n\n/**\n * Object detection result\n */\nexport interface ObjectDetectionResult extends PipelineResult {\n label: string;\n score: number;\n box: { x: number; y: number; width: number; height: number };\n}\n\n// ============================================================================\n// Base Pipeline Class\n// ============================================================================\n\n/**\n * BasePipeline - Abstract base class for all pipelines\n */\nexport abstract class BasePipeline<TInput, TOutput extends PipelineResult | PipelineResult[]> {\n protected model: LoadedModel | null = null;\n protected readonly config: PipelineConfig;\n protected readonly modelCache: ModelCache;\n protected readonly downloadCache: ModelDownloadCache;\n protected isReady = false;\n\n constructor(config: PipelineConfig) {\n this.config = config;\n this.modelCache = new ModelCache();\n this.downloadCache = new ModelDownloadCache();\n }\n\n /**\n * Initialize the pipeline (load model).\n *\n * Skips model loading when `config.model === 'default'` \u2014 concrete\n * subclasses that define their own DEFAULT_MODELS handle all model\n * loading in their overridden `initialize()` methods, so the base\n * should not attempt to fetch a URL called \"default\".\n */\n async initialize(): Promise<void> {\n if (this.isReady && this.model) return;\n\n // Skip generic model loading for subclasses that manage their own models.\n if (this.config.model === 'default') {\n this.isReady = true;\n return;\n }\n\n // Check model cache first\n const cachedModel = this.modelCache.get(this.config.model);\n if (cachedModel) {\n this.model = cachedModel;\n this.isReady = true;\n return;\n }\n\n // Load model using the explicit URL from config\n this.model = await this.loadModelWithCache(this.config.model);\n this.isReady = true;\n }\n\n /**\n * Load model with caching\n */\n protected async loadModelWithCache(modelPath: string): Promise<LoadedModel> {\n // Try download cache first\n const cachedResponse = await this.downloadCache.get(modelPath);\n if (cachedResponse) {\n // Use cached data\n }\n\n // Download and cache (or use mock for now)\n try {\n const response = await fetch(modelPath);\n if (response.ok) {\n // Cache the response\n await this.downloadCache.put(modelPath, response.clone());\n }\n } catch {\n // Ignore fetch errors for demo\n }\n\n // Load into runtime\n return loadModel(modelPath, {\n runtime: this.config.runtime,\n quantization: this.config.quantization,\n cache: this.config.cache,\n });\n }\n\n /**\n * Run inference (single input)\n */\n async run(input: TInput, options?: PipelineOptions): Promise<TOutput> {\n await this.initialize();\n \n const startTime = performance.now();\n \n // Preprocess\n const preprocessed = await this.preprocess(input);\n \n // Run inference\n const outputs = await runInference(this.model!, preprocessed);\n \n // Postprocess\n const result = await this.postprocess(outputs as EdgeFlowTensor[], options);\n \n if (result && typeof result === 'object' && 'processingTime' in result) {\n (result as PipelineResult).processingTime = performance.now() - startTime;\n }\n \n return result;\n }\n\n /**\n * Run batch inference\n */\n async runBatch(inputs: TInput[], options?: PipelineOptions): Promise<TOutput[]> {\n await this.initialize();\n \n // Process all inputs\n const results = await Promise.all(\n inputs.map(input => this.run(input, options))\n );\n \n return results;\n }\n\n /**\n * Preprocess input - must be implemented by subclasses\n */\n protected abstract preprocess(input: TInput): Promise<EdgeFlowTensor[]>;\n\n /**\n * Postprocess output - must be implemented by subclasses\n */\n protected abstract postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<TOutput>;\n\n /**\n * Get the task type\n */\n get task(): PipelineTask {\n return this.config.task;\n }\n\n /**\n * Check if pipeline is ready\n */\n get ready(): boolean {\n return this.isReady;\n }\n\n /**\n * Dispose the pipeline\n */\n dispose(): void {\n if (this.model) {\n this.model.dispose();\n this.model = null;\n }\n this.isReady = false;\n }\n}\n\n// ============================================================================\n// Pipeline Registry\n// ============================================================================\n\n/**\n * Pipeline factory function type\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype PipelineFactory = (config: PipelineConfig) => BasePipeline<any, any>;\n\n/**\n * Registered pipeline factories\n */\nconst pipelineFactories: Map<PipelineTask, PipelineFactory> = new Map();\n\n/**\n * Register a pipeline factory\n */\nexport function registerPipeline(task: PipelineTask, factory: PipelineFactory): void {\n pipelineFactories.set(task, factory);\n}\n\n/**\n * Get a pipeline factory\n */\nexport function getPipelineFactory(task: PipelineTask): PipelineFactory | undefined {\n return pipelineFactories.get(task);\n}\n\n// ============================================================================\n// Default Label Maps\n// ============================================================================\n\n/**\n * Common sentiment labels\n */\nexport const SENTIMENT_LABELS = ['negative', 'positive'];\n\n/**\n * Common emotion labels\n */\nexport const EMOTION_LABELS = [\n 'anger', 'disgust', 'fear', 'joy', 'sadness', 'surprise', 'neutral'\n];\n\n/**\n * ImageNet top-10 labels (for demo)\n */\nexport const IMAGENET_LABELS = [\n 'tench', 'goldfish', 'great white shark', 'tiger shark', 'hammerhead',\n 'electric ray', 'stingray', 'cock', 'hen', 'ostrich'\n];\n", "/**\n * edgeFlow.js - Text Classification Pipeline\n * \n * High-level API for text classification tasks including\n * sentiment analysis, topic classification, etc.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\nimport {\n BasePipeline,\n TextClassificationResult,\n registerPipeline,\n SENTIMENT_LABELS,\n} from './base.js';\n\n// ============================================================================\n// Default Model (DistilBERT fine-tuned on SST-2)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/tokenizer.json',\n};\n\nconst DEFAULT_SST2_LABELS = ['NEGATIVE', 'POSITIVE'];\n\n// ============================================================================\n// Text Classification Pipeline\n// ============================================================================\n\nexport interface TextClassificationOptions extends PipelineOptions {\n returnAllScores?: boolean;\n labels?: string[];\n topK?: number;\n}\n\nexport class TextClassificationPipeline extends BasePipeline<\n string | string[],\n TextClassificationResult | TextClassificationResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config: PipelineConfig, labels?: string[]) {\n super(config);\n this.labels = labels ?? DEFAULT_SST2_LABELS;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: string | string[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult | TextClassificationResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n \n await this.initialize();\n \n const startTime = performance.now();\n const results: TextClassificationResult[] = [];\n\n for (const text of inputs) {\n const tensorInputs = await this.preprocess(text);\n const outputs = await this.runInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n const text = Array.isArray(input) ? input[0]! : input;\n \n const encoded = this.tokenizer!.encode(text, {\n maxLength: 128,\n padding: 'max_length',\n truncation: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n return [inputIds, attentionMask];\n }\n\n private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputs[0]!);\n namedInputs.set('attention_mask', inputs[1]!);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult> {\n const logits = outputs[0];\n if (!logits) {\n return { label: 'unknown', score: 0 };\n }\n\n const probs = softmax(logits, -1) as EdgeFlowTensor;\n const probsArray = probs.toFloat32Array();\n\n let maxIdx = 0;\n let maxScore = probsArray[0] ?? 0;\n \n for (let i = 1; i < probsArray.length; i++) {\n if ((probsArray[i] ?? 0) > maxScore) {\n maxScore = probsArray[i] ?? 0;\n maxIdx = i;\n }\n }\n\n const label = options?.labels?.[maxIdx] ?? this.labels[maxIdx] ?? `class_${maxIdx}`;\n\n return {\n label,\n score: maxScore,\n };\n }\n}\n\n// ============================================================================\n// Sentiment Analysis Pipeline\n// ============================================================================\n\nexport class SentimentAnalysisPipeline extends TextClassificationPipeline {\n constructor(config: PipelineConfig) {\n super(config, SENTIMENT_LABELS);\n }\n\n async analyze(\n text: string | string[],\n options?: TextClassificationOptions\n ): Promise<TextClassificationResult | TextClassificationResult[]> {\n return this.run(text, options);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\nexport function createTextClassificationPipeline(\n config: Partial<PipelineConfig> = {}\n): TextClassificationPipeline {\n return new TextClassificationPipeline({\n task: 'text-classification',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\nexport function createSentimentAnalysisPipeline(\n config: Partial<PipelineConfig> = {}\n): SentimentAnalysisPipeline {\n return new SentimentAnalysisPipeline({\n task: 'sentiment-analysis',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\nregisterPipeline('text-classification', (config) => new TextClassificationPipeline(config));\nregisterPipeline('sentiment-analysis', (config) => new SentimentAnalysisPipeline(config));\n", "/**\n * edgeFlow.js - Tokenizer\n * \n * Full-featured tokenizer supporting HuggingFace tokenizer.json format.\n * Supports BPE, WordPiece, and Unigram tokenization.\n */\n\nimport {\n TokenizerConfig,\n TokenizedOutput,\n EdgeFlowError,\n ErrorCodes,\n} from '../core/types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type TokenizerModel = 'BPE' | 'WordPiece' | 'Unigram' | 'basic';\n\nexport interface TokenizerOptions {\n addSpecialTokens?: boolean;\n maxLength?: number;\n padding?: 'max_length' | 'longest' | 'do_not_pad';\n truncation?: boolean;\n returnAttentionMask?: boolean;\n returnTokenTypeIds?: boolean;\n textPair?: string;\n}\n\n/**\n * HuggingFace tokenizer.json format\n */\ninterface HFTokenizerJSON {\n version?: string;\n truncation?: {\n max_length: number;\n strategy: string;\n };\n padding?: {\n strategy: string;\n pad_id: number;\n pad_token: string;\n };\n added_tokens?: Array<{\n id: number;\n content: string;\n single_word: boolean;\n lstrip: boolean;\n rstrip: boolean;\n normalized: boolean;\n special: boolean;\n }>;\n normalizer?: {\n type: string;\n lowercase?: boolean;\n strip_accents?: boolean;\n [key: string]: unknown;\n };\n pre_tokenizer?: {\n type: string;\n [key: string]: unknown;\n };\n post_processor?: {\n type: string;\n single?: Array<{ id: string; type_id: number } | { SpecialToken: { id: string; type_id: number } } | { Sequence: { id: string; type_id: number } }>;\n pair?: Array<{ id: string; type_id: number } | { SpecialToken: { id: string; type_id: number } } | { Sequence: { id: string; type_id: number } }>;\n special_tokens?: Record<string, { id: string; ids: number[]; tokens: string[] }>;\n [key: string]: unknown;\n };\n decoder?: {\n type: string;\n [key: string]: unknown;\n };\n model: {\n type: string;\n vocab?: Record<string, number>;\n merges?: string[];\n unk_token?: string;\n continuing_subword_prefix?: string;\n end_of_word_suffix?: string;\n fuse_unk?: boolean;\n byte_fallback?: boolean;\n [key: string]: unknown;\n };\n}\n\n\n// ============================================================================\n// Tokenizer Implementation\n// ============================================================================\n\n/**\n * Tokenizer - Full-featured tokenizer supporting HuggingFace format\n */\nexport class Tokenizer {\n private vocab: Map<string, number> = new Map();\n private reverseVocab: Map<number, string> = new Map();\n private merges: Map<string, number> = new Map();\n private addedTokens: Map<string, number> = new Map();\n private specialTokens: Set<string> = new Set();\n \n private modelType: TokenizerModel = 'BPE';\n private unkToken: string = '[UNK]';\n private continuingSubwordPrefix: string = '##';\n \n // Special token IDs\n private padTokenId: number = 0;\n private unkTokenId: number = 0;\n private clsTokenId?: number;\n private sepTokenId?: number;\n private maskTokenId?: number;\n private bosTokenId?: number;\n private eosTokenId?: number;\n \n // Config\n private maxLength: number = 512;\n private doLowerCase: boolean = false;\n private stripAccents: boolean = false;\n \n // Post-processor config\n private postProcessor?: HFTokenizerJSON['post_processor'];\n \n // Byte encoder for BPE\n private byteEncoder: Map<number, string> = new Map();\n private byteDecoder: Map<string, number> = new Map();\n\n constructor() {\n this.initByteEncoder();\n }\n\n /**\n * Initialize byte encoder/decoder for BPE\n */\n private initByteEncoder(): void {\n const bytes: number[] = [];\n \n // Printable ASCII\n for (let i = 33; i <= 126; i++) bytes.push(i);\n for (let i = 161; i <= 172; i++) bytes.push(i);\n for (let i = 174; i <= 255; i++) bytes.push(i);\n \n const chars = [...bytes];\n let n = 0;\n \n for (let i = 0; i < 256; i++) {\n if (!bytes.includes(i)) {\n bytes.push(i);\n chars.push(256 + n);\n n++;\n }\n }\n \n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i]!;\n const char = String.fromCharCode(chars[i]!);\n this.byteEncoder.set(byte, char);\n this.byteDecoder.set(char, byte);\n }\n }\n\n /**\n * Load from HuggingFace tokenizer.json\n */\n static async fromJSON(json: HFTokenizerJSON | string): Promise<Tokenizer> {\n const tokenizer = new Tokenizer();\n const data = typeof json === 'string' ? JSON.parse(json) as HFTokenizerJSON : json;\n \n // Load model config\n if (data.model) {\n tokenizer.modelType = data.model.type as TokenizerModel;\n \n // Load vocabulary.\n // BPE/WordPiece: vocab is an object { token: id }.\n // Unigram (SentencePiece): vocab is an array of [token, score] pairs\n // where the array *index* is the token ID.\n if (data.model.vocab) {\n if (Array.isArray(data.model.vocab)) {\n // Unigram format\n const unigramVocab = data.model.vocab as Array<[string, number]>;\n for (let i = 0; i < unigramVocab.length; i++) {\n const entry = unigramVocab[i]!;\n const token = Array.isArray(entry) ? entry[0] : (entry as unknown as string);\n tokenizer.vocab.set(token, i);\n tokenizer.reverseVocab.set(i, token);\n }\n } else {\n for (const [token, id] of Object.entries(data.model.vocab)) {\n tokenizer.vocab.set(token, id as number);\n tokenizer.reverseVocab.set(id as number, token);\n }\n }\n }\n \n // Load merges for BPE\n if (data.model.merges) {\n for (let i = 0; i < data.model.merges.length; i++) {\n tokenizer.merges.set(data.model.merges[i]!, i);\n }\n }\n \n // Model-specific config\n tokenizer.unkToken = data.model.unk_token ?? '[UNK]';\n tokenizer.continuingSubwordPrefix = data.model.continuing_subword_prefix ?? '##';\n }\n \n // Load added tokens\n if (data.added_tokens) {\n for (const token of data.added_tokens) {\n tokenizer.addedTokens.set(token.content, token.id);\n tokenizer.reverseVocab.set(token.id, token.content);\n if (token.special) {\n tokenizer.specialTokens.add(token.content);\n }\n \n // Detect special token types\n const content = token.content.toLowerCase();\n if (content.includes('pad')) tokenizer.padTokenId = token.id;\n if (content.includes('unk')) tokenizer.unkTokenId = token.id;\n if (content.includes('cls') || content === '[cls]') tokenizer.clsTokenId = token.id;\n if (content.includes('sep') || content === '[sep]') tokenizer.sepTokenId = token.id;\n if (content.includes('mask')) tokenizer.maskTokenId = token.id;\n if (content.includes('bos') || content === '<s>') tokenizer.bosTokenId = token.id;\n if (content.includes('eos') || content === '</s>') tokenizer.eosTokenId = token.id;\n }\n }\n \n // Load normalizer config\n if (data.normalizer) {\n tokenizer.doLowerCase = data.normalizer.lowercase ?? false;\n tokenizer.stripAccents = data.normalizer.strip_accents ?? false;\n }\n \n // Load truncation config\n if (data.truncation) {\n tokenizer.maxLength = data.truncation.max_length;\n }\n \n // Load post-processor\n if (data.post_processor) {\n tokenizer.postProcessor = data.post_processor;\n }\n \n return tokenizer;\n }\n\n /**\n * Load from URL (tokenizer.json)\n */\n static async fromUrl(url: string): Promise<Tokenizer> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new EdgeFlowError(\n `Failed to load tokenizer from ${url}: ${response.status}`,\n ErrorCodes.MODEL_NOT_FOUND\n );\n }\n const json = await response.json() as HFTokenizerJSON;\n return Tokenizer.fromJSON(json);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromHuggingFace(modelId: string, options?: { revision?: string }): Promise<Tokenizer> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/tokenizer.json`;\n return Tokenizer.fromUrl(url);\n }\n\n /**\n * Normalize text\n */\n private normalize(text: string): string {\n let result = text;\n \n if (this.doLowerCase) {\n result = result.toLowerCase();\n }\n \n if (this.stripAccents) {\n result = result.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n }\n \n // Normalize whitespace\n result = result.replace(/\\s+/g, ' ').trim();\n \n return result;\n }\n\n /**\n * Pre-tokenize text (split into words)\n */\n private preTokenize(text: string): string[] {\n // GPT-2 style: split on whitespace and punctuation, keeping them\n const pattern = /'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)|\\s+/gu;\n const matches = text.match(pattern);\n return matches ?? [text];\n }\n\n /**\n * Encode text to bytes (for BPE)\n */\n private textToBytes(text: string): string {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(text);\n return Array.from(bytes).map(b => this.byteEncoder.get(b) ?? '').join('');\n }\n\n /**\n * Decode bytes to text (for BPE)\n */\n private bytesToText(text: string): string {\n const bytes = new Uint8Array(\n text.split('').map(c => this.byteDecoder.get(c) ?? 0)\n );\n const decoder = new TextDecoder('utf-8', { fatal: false });\n return decoder.decode(bytes);\n }\n\n /**\n * Get BPE pairs from word\n */\n private getPairs(word: string[]): Set<string> {\n const pairs = new Set<string>();\n for (let i = 0; i < word.length - 1; i++) {\n pairs.add(`${word[i]} ${word[i + 1]}`);\n }\n return pairs;\n }\n\n /**\n * Apply BPE to a word\n */\n private bpe(token: string): string[] {\n if (this.vocab.has(token)) {\n return [token];\n }\n \n let word = token.split('');\n let pairs = this.getPairs(word);\n \n if (pairs.size === 0) {\n return [token];\n }\n \n while (true) {\n // Find the pair with lowest merge rank\n let minPair: string | null = null;\n let minRank = Infinity;\n \n for (const pair of pairs) {\n const rank = this.merges.get(pair);\n if (rank !== undefined && rank < minRank) {\n minRank = rank;\n minPair = pair;\n }\n }\n \n if (minPair === null) break;\n \n const parts = minPair.split(' ');\n const first = parts[0];\n const second = parts[1];\n if (!first || !second) break;\n \n const newWord: string[] = [];\n let i = 0;\n \n while (i < word.length) {\n const j = word.indexOf(first, i);\n if (j === -1) {\n newWord.push(...word.slice(i));\n break;\n }\n \n newWord.push(...word.slice(i, j));\n \n if (word[j] === first && j < word.length - 1 && word[j + 1] === second) {\n newWord.push(first + second);\n i = j + 2;\n } else {\n newWord.push(word[j]!);\n i = j + 1;\n }\n }\n \n word = newWord;\n \n if (word.length === 1) break;\n \n pairs = this.getPairs(word);\n }\n \n return word;\n }\n\n /**\n * WordPiece tokenization\n */\n private wordPiece(word: string): string[] {\n if (this.vocab.has(word)) {\n return [word];\n }\n \n const tokens: string[] = [];\n let start = 0;\n \n while (start < word.length) {\n let end = word.length;\n let curSubstr: string | null = null;\n \n while (start < end) {\n let substr = word.slice(start, end);\n if (start > 0) {\n substr = this.continuingSubwordPrefix + substr;\n }\n \n if (this.vocab.has(substr)) {\n curSubstr = substr;\n break;\n }\n end--;\n }\n \n if (curSubstr === null) {\n tokens.push(this.unkToken);\n start++;\n } else {\n tokens.push(curSubstr);\n start = end;\n }\n }\n \n return tokens;\n }\n\n /**\n * Tokenize a single word\n */\n private tokenizeWord(word: string): string[] {\n // Check added tokens first\n if (this.addedTokens.has(word)) {\n return [word];\n }\n \n switch (this.modelType) {\n case 'BPE': {\n // Convert to byte representation\n const byteStr = this.textToBytes(word);\n return this.bpe(byteStr);\n }\n case 'WordPiece':\n return this.wordPiece(word);\n case 'Unigram':\n return this.unigramTokenize(word);\n default:\n return this.vocab.has(word) ? [word] : [this.unkToken];\n }\n }\n\n /**\n * Greedy longest-match tokenizer for SentencePiece Unigram models.\n * Adds the U+2581 (\u2581) word-start prefix expected by SPM-based models.\n */\n private unigramTokenize(word: string): string[] {\n // SentencePiece prepends \u2581 to words that follow a space (i.e. the\n // tokenizer receives individual words, so all of them get the prefix).\n const prefixedWord = '\\u2581' + word;\n const tokens: string[] = [];\n let start = 0;\n const text = prefixedWord;\n\n while (start < text.length) {\n let end = text.length;\n let found = false;\n // Greedy longest-match scan\n while (end > start) {\n const sub = text.slice(start, end);\n if (this.vocab.has(sub)) {\n tokens.push(sub);\n start = end;\n found = true;\n break;\n }\n end--;\n }\n if (!found) {\n // Emit the single character (or unk if it's not in vocab either)\n const ch = text[start]!;\n tokens.push(this.vocab.has(ch) ? ch : this.unkToken);\n start++;\n }\n }\n\n return tokens.length > 0 ? tokens : [this.unkToken];\n }\n\n /**\n * Main tokenization\n */\n private tokenize(text: string): string[] {\n // Normalize\n const normalized = this.normalize(text);\n \n // Check for added tokens (special tokens)\n const tokens: string[] = [];\n let remaining = normalized;\n \n // Sort added tokens by length (longest first) for greedy matching\n const sortedAddedTokens = Array.from(this.addedTokens.keys())\n .sort((a, b) => b.length - a.length);\n \n // Split by added tokens\n for (const addedToken of sortedAddedTokens) {\n if (remaining.includes(addedToken)) {\n const parts = remaining.split(addedToken);\n const newRemaining: string[] = [];\n \n for (let i = 0; i < parts.length; i++) {\n if (parts[i]) {\n newRemaining.push(parts[i]!);\n }\n if (i < parts.length - 1) {\n tokens.push(addedToken);\n }\n }\n \n remaining = newRemaining.join(' ');\n }\n }\n \n // Pre-tokenize remaining text\n if (remaining.trim()) {\n const words = this.preTokenize(remaining);\n \n for (const word of words) {\n if (!word) continue;\n const wordTokens = this.tokenizeWord(word);\n tokens.push(...wordTokens);\n }\n }\n \n return tokens;\n }\n\n /**\n * Convert tokens to IDs\n */\n private convertTokensToIds(tokens: string[]): number[] {\n return tokens.map(token => {\n // Check added tokens first\n const addedId = this.addedTokens.get(token);\n if (addedId !== undefined) return addedId;\n \n // Check vocabulary\n const vocabId = this.vocab.get(token);\n if (vocabId !== undefined) return vocabId;\n \n // Return UNK\n return this.unkTokenId;\n });\n }\n\n /**\n * Convert IDs to tokens\n */\n private convertIdsToTokens(ids: number[]): string[] {\n return ids.map(id => this.reverseVocab.get(id) ?? this.unkToken);\n }\n\n /**\n * Apply post-processing (add special tokens)\n */\n private postProcess(\n ids: number[],\n pairIds?: number[]\n ): { ids: number[]; typeIds: number[] } {\n if (!this.postProcessor) {\n // Default: [CLS] tokens [SEP] or [CLS] tokens [SEP] pair [SEP]\n const result: number[] = [];\n const typeIds: number[] = [];\n \n if (this.clsTokenId !== undefined) {\n result.push(this.clsTokenId);\n typeIds.push(0);\n }\n \n result.push(...ids);\n typeIds.push(...ids.map(() => 0));\n \n if (this.sepTokenId !== undefined) {\n result.push(this.sepTokenId);\n typeIds.push(0);\n }\n \n if (pairIds) {\n result.push(...pairIds);\n typeIds.push(...pairIds.map(() => 1));\n \n if (this.sepTokenId !== undefined) {\n result.push(this.sepTokenId);\n typeIds.push(1);\n }\n }\n \n return { ids: result, typeIds };\n }\n \n // Use post-processor config\n const template = pairIds ? this.postProcessor.pair : this.postProcessor.single;\n if (!template) {\n return { ids, typeIds: ids.map(() => 0) };\n }\n \n const result: number[] = [];\n const typeIds: number[] = [];\n \n for (const item of template) {\n if ('SpecialToken' in item) {\n const specialToken = this.postProcessor.special_tokens?.[item.SpecialToken.id];\n if (specialToken) {\n result.push(...specialToken.ids);\n typeIds.push(...specialToken.ids.map(() => item.SpecialToken.type_id));\n }\n } else if ('Sequence' in item) {\n const seqIds = item.Sequence.id === 'A' ? ids : pairIds ?? [];\n result.push(...seqIds);\n typeIds.push(...seqIds.map(() => item.Sequence.type_id));\n }\n }\n \n return { ids: result, typeIds };\n }\n\n /**\n * Encode text\n */\n encode(text: string, options: TokenizerOptions = {}): TokenizedOutput {\n const {\n addSpecialTokens = true,\n maxLength = this.maxLength,\n padding = 'max_length',\n truncation = true,\n returnAttentionMask = true,\n returnTokenTypeIds = false,\n textPair,\n } = options;\n \n // Tokenize\n const tokens = this.tokenize(text);\n let inputIds = this.convertTokensToIds(tokens);\n \n // Tokenize pair if provided\n let pairIds: number[] | undefined;\n if (textPair) {\n const pairTokens = this.tokenize(textPair);\n pairIds = this.convertTokensToIds(pairTokens);\n }\n \n // Post-process (add special tokens)\n let tokenTypeIds: number[] | undefined;\n if (addSpecialTokens) {\n const processed = this.postProcess(inputIds, pairIds);\n inputIds = processed.ids;\n if (returnTokenTypeIds) {\n tokenTypeIds = processed.typeIds;\n }\n } else if (pairIds) {\n inputIds = [...inputIds, ...pairIds];\n if (returnTokenTypeIds) {\n tokenTypeIds = [...inputIds.map(() => 0), ...pairIds.map(() => 1)];\n }\n }\n \n // Truncate\n if (truncation && inputIds.length > maxLength) {\n inputIds = inputIds.slice(0, maxLength);\n if (tokenTypeIds) {\n tokenTypeIds = tokenTypeIds.slice(0, maxLength);\n }\n }\n \n // Create attention mask\n let attentionMask: number[] = [];\n if (returnAttentionMask) {\n attentionMask = inputIds.map(() => 1);\n }\n \n // Padding\n if (padding === 'max_length' && inputIds.length < maxLength) {\n const padLength = maxLength - inputIds.length;\n inputIds = [...inputIds, ...new Array(padLength).fill(this.padTokenId) as number[]];\n if (returnAttentionMask) {\n attentionMask = [...attentionMask, ...new Array(padLength).fill(0) as number[]];\n }\n if (tokenTypeIds) {\n tokenTypeIds = [...tokenTypeIds, ...new Array(padLength).fill(0) as number[]];\n }\n }\n \n const result: TokenizedOutput = {\n inputIds,\n attentionMask,\n };\n \n if (returnTokenTypeIds && tokenTypeIds) {\n result.tokenTypeIds = tokenTypeIds;\n }\n \n return result;\n }\n\n /**\n * Batch encode\n */\n encodeBatch(texts: string[], options: TokenizerOptions = {}): TokenizedOutput[] {\n // For 'longest' padding, first encode all without padding\n if (options.padding === 'longest') {\n const encodings = texts.map(t => this.encode(t, { ...options, padding: 'do_not_pad' }));\n const maxLen = Math.max(...encodings.map(e => e.inputIds.length));\n return texts.map(t => this.encode(t, { ...options, maxLength: maxLen, padding: 'max_length' }));\n }\n \n return texts.map(t => this.encode(t, options));\n }\n\n /**\n * Decode IDs to text\n */\n decode(ids: number[], skipSpecialTokens = true): string {\n let tokens = this.convertIdsToTokens(ids);\n\n if (skipSpecialTokens) {\n tokens = tokens.filter(t => !this.specialTokens.has(t));\n }\n\n if (this.modelType === 'BPE') {\n // BPE: byte-level encoding, join raw and decode bytes\n return this.bytesToText(tokens.join('')).replace(/\\s+/g, ' ').trim();\n }\n\n if (this.modelType === 'WordPiece') {\n // WordPiece: tokens starting with continuingSubwordPrefix (##) are\n // subword continuations and must be appended to the previous word\n // WITHOUT a space. All other tokens are word-starts and get a space.\n const prefix = this.continuingSubwordPrefix; // '##'\n const words: string[] = [];\n for (const token of tokens) {\n if (token.startsWith(prefix)) {\n if (words.length > 0) {\n words[words.length - 1] += token.slice(prefix.length);\n } else {\n words.push(token.slice(prefix.length));\n }\n } else {\n words.push(token);\n }\n }\n return words.join(' ').replace(/\\s+/g, ' ').trim();\n }\n\n if (this.modelType === 'Unigram') {\n // SentencePiece: \u2581 marks word boundaries (replaces the leading space)\n return tokens\n .join('')\n .replace(/\\u2581/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n }\n\n // Default: space-join\n return tokens.join(' ').replace(/\\s+/g, ' ').trim();\n }\n\n /**\n * Decode batch\n */\n decodeBatch(batchIds: number[][], skipSpecialTokens = true): string[] {\n return batchIds.map(ids => this.decode(ids, skipSpecialTokens));\n }\n\n /**\n * Get vocabulary size\n */\n get vocabSize(): number {\n return this.vocab.size + this.addedTokens.size;\n }\n\n /**\n * Get special token IDs\n */\n getSpecialTokenIds(): {\n padTokenId: number;\n unkTokenId: number;\n clsTokenId?: number;\n sepTokenId?: number;\n maskTokenId?: number;\n bosTokenId?: number;\n eosTokenId?: number;\n } {\n return {\n padTokenId: this.padTokenId,\n unkTokenId: this.unkTokenId,\n clsTokenId: this.clsTokenId,\n sepTokenId: this.sepTokenId,\n maskTokenId: this.maskTokenId,\n bosTokenId: this.bosTokenId,\n eosTokenId: this.eosTokenId,\n };\n }\n\n /**\n * Get config\n */\n getConfig(): TokenizerConfig {\n return {\n vocabSize: this.vocabSize,\n maxLength: this.maxLength,\n padTokenId: this.padTokenId,\n unkTokenId: this.unkTokenId,\n clsTokenId: this.clsTokenId,\n sepTokenId: this.sepTokenId,\n maskTokenId: this.maskTokenId,\n bosTokenId: this.bosTokenId,\n eosTokenId: this.eosTokenId,\n };\n }\n\n /**\n * Check if token is special\n */\n isSpecialToken(token: string): boolean {\n return this.specialTokens.has(token);\n }\n\n /**\n * Get token ID\n */\n getTokenId(token: string): number | undefined {\n return this.addedTokens.get(token) ?? this.vocab.get(token);\n }\n\n /**\n * Get token from ID\n */\n getToken(id: number): string | undefined {\n return this.reverseVocab.get(id);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a basic English tokenizer (for testing)\n */\nexport function createBasicTokenizer(): Tokenizer {\n const tokenizer = new Tokenizer();\n return tokenizer;\n}\n\n/**\n * Load tokenizer from URL\n */\nexport async function loadTokenizer(url: string): Promise<Tokenizer> {\n return Tokenizer.fromUrl(url);\n}\n\n/**\n * Load tokenizer from HuggingFace Hub\n */\nexport async function loadTokenizerFromHub(\n modelId: string,\n options?: { revision?: string }\n): Promise<Tokenizer> {\n return Tokenizer.fromHuggingFace(modelId, options);\n}\n\n", "/**\n * edgeFlow.js - Feature Extraction Pipeline\n * \n * Extract embeddings/features from text using sentence-transformer models.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\nimport {\n BasePipeline,\n FeatureExtractionResult,\n registerPipeline,\n} from './base.js';\n\n// ============================================================================\n// Default Model (all-MiniLM-L6-v2, 384-dim sentence embeddings)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/all-MiniLM-L6-v2/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/all-MiniLM-L6-v2/resolve/main/tokenizer.json',\n};\n\nconst DEFAULT_EMBEDDING_DIM = 384;\n\n// ============================================================================\n// Feature Extraction Pipeline\n// ============================================================================\n\nexport interface FeatureExtractionOptions extends PipelineOptions {\n pooling?: 'mean' | 'max' | 'cls' | 'none';\n normalize?: boolean;\n outputDim?: number;\n}\n\nexport class FeatureExtractionPipeline extends BasePipeline<\n string | string[],\n FeatureExtractionResult | FeatureExtractionResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private embeddingDim: number;\n private modelUrl: string;\n private tokenizerUrl: string;\n private modelInputNames: Set<string> = new Set();\n\n constructor(config: PipelineConfig, embeddingDim: number = DEFAULT_EMBEDDING_DIM) {\n super(config);\n this.embeddingDim = embeddingDim;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = config.tokenizerUrl ?? DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n this.modelInputNames = new Set(this.onnxModel.metadata.inputs.map(i => i.name));\n }\n }\n\n override async run(\n input: string | string[],\n options?: FeatureExtractionOptions\n ): Promise<FeatureExtractionResult | FeatureExtractionResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n \n await this.initialize();\n \n const startTime = performance.now();\n const results: FeatureExtractionResult[] = [];\n\n for (const text of inputs) {\n const tensorInputs = await this.preprocess(text);\n const outputs = await this.runInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n const text = Array.isArray(input) ? input[0]! : input;\n \n const encoded = this.tokenizer!.encode(text, {\n maxLength: 128,\n padding: 'max_length',\n truncation: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n const tensors: EdgeFlowTensor[] = [inputIds, attentionMask];\n\n // Only emit token_type_ids when the loaded model declares it as an input.\n // XLM-R / RoBERTa / multilingual MiniLM omit this input; feeding it would\n // trip onnxruntime-web's session.run with \"invalid input\" errors.\n if (this.modelInputNames.has('token_type_ids')) {\n const tokenTypeIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(() => BigInt(0))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n tensors.push(tokenTypeIds);\n }\n\n return tensors;\n }\n\n private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputs[0]!);\n namedInputs.set('attention_mask', inputs[1]!);\n if (this.modelInputNames.has('token_type_ids') && inputs[2]) {\n namedInputs.set('token_type_ids', inputs[2]);\n }\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: FeatureExtractionOptions\n ): Promise<FeatureExtractionResult> {\n const hiddenStates = outputs[0];\n if (!hiddenStates) {\n return { embeddings: [] };\n }\n\n const pooling = options?.pooling ?? 'mean';\n const normalize = options?.normalize ?? true;\n\n let embeddings: number[];\n\n switch (pooling) {\n case 'cls':\n embeddings = this.extractCLSEmbedding(hiddenStates);\n break;\n case 'max':\n embeddings = this.maxPooling(hiddenStates);\n break;\n case 'none':\n embeddings = hiddenStates.toArray();\n break;\n case 'mean':\n default:\n embeddings = this.meanPooling(hiddenStates);\n break;\n }\n\n if (normalize) {\n embeddings = this.normalizeVector(embeddings);\n }\n\n if (options?.outputDim && options.outputDim < embeddings.length) {\n embeddings = embeddings.slice(0, options.outputDim);\n }\n\n return { embeddings };\n }\n\n private extractCLSEmbedding(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n return Array.from(data.slice(0, embeddingDim));\n }\n\n private meanPooling(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const seqLen = hiddenStates.shape[1] ?? 1;\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n \n const result = new Float32Array(embeddingDim);\n for (let i = 0; i < seqLen; i++) {\n for (let j = 0; j < embeddingDim; j++) {\n result[j] = (result[j] ?? 0) + (data[i * embeddingDim + j] ?? 0) / seqLen;\n }\n }\n return Array.from(result);\n }\n\n private maxPooling(hiddenStates: EdgeFlowTensor): number[] {\n const data = hiddenStates.toFloat32Array();\n const seqLen = hiddenStates.shape[1] ?? 1;\n const embeddingDim = hiddenStates.shape[2] ?? this.embeddingDim;\n \n const result = new Array(embeddingDim).fill(-Infinity) as number[];\n for (let i = 0; i < seqLen; i++) {\n for (let j = 0; j < embeddingDim; j++) {\n const val = data[i * embeddingDim + j] ?? 0;\n if (val > (result[j] ?? -Infinity)) {\n result[j] = val;\n }\n }\n }\n return result;\n }\n\n private normalizeVector(vec: number[]): number[] {\n let norm = 0;\n for (const v of vec) {\n norm += v * v;\n }\n norm = Math.sqrt(norm);\n if (norm === 0) return vec;\n return vec.map(v => v / norm);\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\nexport function createFeatureExtractionPipeline(\n config: Partial<PipelineConfig> = {}\n): FeatureExtractionPipeline {\n return new FeatureExtractionPipeline({\n task: 'feature-extraction',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n tokenizerUrl: config.tokenizerUrl,\n });\n}\n\nregisterPipeline('feature-extraction', (config) => new FeatureExtractionPipeline(config));\n", "/**\n * edgeFlow.js - Image Classification Pipeline\n * \n * Classify images into categories using vision models.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { ImagePreprocessor, createImagePreprocessor } from '../utils/preprocessor.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference } from '../core/runtime.js';\nimport {\n BasePipeline,\n ImageClassificationResult,\n registerPipeline,\n IMAGENET_LABELS,\n} from './base.js';\n\n// ============================================================================\n// Default Model (MobileViT-small, quantized)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/mobilevit-small/resolve/main/onnx/model_quantized.onnx',\n};\n\n\n// ============================================================================\n// Image Classification Pipeline\n// ============================================================================\n\nexport interface ImageClassificationOptions extends PipelineOptions {\n returnAllScores?: boolean;\n labels?: string[];\n topK?: number;\n}\n\nexport type ImageInput =\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | ImageData\n | string;\n\nexport class ImageClassificationPipeline extends BasePipeline<\n ImageInput | ImageInput[],\n ImageClassificationResult | ImageClassificationResult[]\n> {\n private preprocessor: ImagePreprocessor | null = null;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n\n constructor(\n config: PipelineConfig,\n labels?: string[],\n _numClasses: number = 1000\n ) {\n super(config);\n this.labels = labels ?? IMAGENET_LABELS;\n this.modelUrl = config.model !== 'default' ? config.model : DEFAULT_MODELS.model;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.preprocessor) {\n this.preprocessor = createImagePreprocessor('imagenet');\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: ImageInput | ImageInput[],\n options?: ImageClassificationOptions\n ): Promise<ImageClassificationResult | ImageClassificationResult[]> {\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n\n await this.initialize();\n\n const startTime = performance.now();\n const results: ImageClassificationResult[] = [];\n\n for (const image of inputs) {\n const tensorInputs = await this.preprocess(image);\n const outputs = await this.runModelInference(tensorInputs);\n const result = await this.postprocess(outputs, options);\n results.push(result);\n }\n\n const processingTime = performance.now() - startTime;\n for (const result of results) {\n result.processingTime = processingTime / results.length;\n }\n\n return isBatch ? results : results[0]!;\n }\n\n protected override async preprocess(input: ImageInput | ImageInput[]): Promise<EdgeFlowTensor[]> {\n const image = Array.isArray(input) ? input[0]! : input;\n const tensor = await this.preprocessor!.process(image);\n\n if (tensor.shape.length === 3) {\n return [tensor.reshape([1, ...tensor.shape])];\n }\n return [tensor];\n }\n\n private async runModelInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const outputs = await runInference(this.onnxModel!, inputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected override async postprocess(\n outputs: EdgeFlowTensor[],\n options?: ImageClassificationOptions\n ): Promise<ImageClassificationResult> {\n const logits = outputs[0];\n if (!logits) {\n return { label: 'unknown', score: 0 };\n }\n\n const probs = softmax(logits, -1) as EdgeFlowTensor;\n const probsArray = probs.toFloat32Array();\n\n let maxIdx = 0;\n let maxScore = probsArray[0] ?? 0;\n\n for (let i = 1; i < probsArray.length; i++) {\n if ((probsArray[i] ?? 0) > maxScore) {\n maxScore = probsArray[i] ?? 0;\n maxIdx = i;\n }\n }\n\n const label = options?.labels?.[maxIdx] ?? this.labels[maxIdx] ?? `class_${maxIdx}`;\n\n return { label, score: maxScore };\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\nexport function createImageClassificationPipeline(\n config: Partial<PipelineConfig> = {},\n labels?: string[]\n): ImageClassificationPipeline {\n return new ImageClassificationPipeline(\n {\n task: 'image-classification',\n model: config.model ?? 'default',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n },\n labels\n );\n}\n\nregisterPipeline('image-classification', (config) => new ImageClassificationPipeline(config));\n", "/**\n * edgeFlow.js - Preprocessor\n * \n * Data preprocessing utilities for images, audio, and other data types.\n * Supports HuggingFace preprocessor_config.json format.\n */\n\nimport { EdgeFlowTensor } from '../core/tensor.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Image input types\n */\nexport type ImageInput = \n | HTMLImageElement \n | HTMLCanvasElement \n | ImageBitmap \n | ImageData \n | Blob \n | File \n | string;\n\n/**\n * Audio input types\n */\nexport type AudioInput = \n | AudioBuffer \n | Float32Array \n | ArrayBuffer \n | Blob \n | File \n | string;\n\n// ============================================================================\n// Image Preprocessing\n// ============================================================================\n\n/**\n * Image preprocessing options\n */\nexport interface ImagePreprocessorOptions {\n /** Target width (or size for square) */\n width?: number;\n /** Target height */\n height?: number;\n /** Single size for square output (sets both width and height) */\n size?: number;\n /** Resize mode */\n resizeMode?: 'stretch' | 'contain' | 'cover' | 'pad' | 'shortest_edge' | 'longest_edge';\n /** Normalization mean */\n mean?: [number, number, number];\n /** Normalization std */\n std?: [number, number, number];\n /** Rescale factor (applied before normalization) */\n rescaleFactor?: number;\n /** Convert to grayscale */\n grayscale?: boolean;\n /** Channel format */\n channelFormat?: 'CHW' | 'HWC';\n /** Output data type */\n dtype?: 'float32' | 'uint8';\n /** Do resize */\n doResize?: boolean;\n /** Do rescale */\n doRescale?: boolean;\n /** Do normalize */\n doNormalize?: boolean;\n /** Do center crop */\n doCenterCrop?: boolean;\n /** Center crop size */\n cropSize?: number | { width: number; height: number };\n /** Padding color for 'pad' mode (RGB 0-255) */\n paddingColor?: [number, number, number];\n}\n\n/**\n * Default image preprocessing options (ImageNet style)\n */\nconst DEFAULT_IMAGE_OPTIONS: ImagePreprocessorOptions = {\n width: 224,\n height: 224,\n resizeMode: 'cover',\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n rescaleFactor: 1 / 255,\n grayscale: false,\n channelFormat: 'CHW',\n dtype: 'float32',\n doResize: true,\n doRescale: true,\n doNormalize: true,\n doCenterCrop: false,\n paddingColor: [0, 0, 0],\n};\n\n/**\n * ImagePreprocessor - Process images for model input\n * \n * Supports HuggingFace preprocessor_config.json format.\n */\nexport class ImagePreprocessor {\n private readonly options: Required<ImagePreprocessorOptions>;\n private canvas: HTMLCanvasElement | null = null;\n private ctx: CanvasRenderingContext2D | null = null;\n\n constructor(options: ImagePreprocessorOptions = {}) {\n // Handle size option\n const size = options.size;\n const width = options.width ?? size ?? DEFAULT_IMAGE_OPTIONS.width!;\n const height = options.height ?? size ?? DEFAULT_IMAGE_OPTIONS.height!;\n \n this.options = {\n ...DEFAULT_IMAGE_OPTIONS,\n ...options,\n width,\n height,\n size: size ?? width,\n cropSize: options.cropSize ?? options.size ?? width,\n } as Required<ImagePreprocessorOptions>;\n }\n\n /**\n * Load from HuggingFace preprocessor_config.json\n */\n static fromConfig(config: Record<string, unknown>): ImagePreprocessor {\n const options: ImagePreprocessorOptions = {};\n \n // Map HuggingFace config to our options\n const size = config['size'];\n if (size !== undefined) {\n if (typeof size === 'number') {\n options.size = size;\n } else if (typeof size === 'object' && size !== null) {\n const sizeObj = size as { width?: number; height?: number; shortest_edge?: number };\n options.width = sizeObj.width ?? sizeObj.shortest_edge;\n options.height = sizeObj.height ?? sizeObj.shortest_edge;\n }\n }\n \n const cropSize = config['crop_size'];\n if (cropSize !== undefined) {\n if (typeof cropSize === 'number') {\n options.cropSize = cropSize;\n } else if (typeof cropSize === 'object' && cropSize !== null) {\n const cropObj = cropSize as { width?: number; height?: number };\n options.cropSize = { width: cropObj.width ?? 224, height: cropObj.height ?? 224 };\n }\n }\n \n const imageMean = config['image_mean'];\n if (Array.isArray(imageMean)) {\n options.mean = imageMean as [number, number, number];\n }\n \n const imageStd = config['image_std'];\n if (Array.isArray(imageStd)) {\n options.std = imageStd as [number, number, number];\n }\n \n const rescaleFactor = config['rescale_factor'];\n if (typeof rescaleFactor === 'number') {\n options.rescaleFactor = rescaleFactor;\n }\n \n const doResize = config['do_resize'];\n if (typeof doResize === 'boolean') {\n options.doResize = doResize;\n }\n \n const doRescale = config['do_rescale'];\n if (typeof doRescale === 'boolean') {\n options.doRescale = doRescale;\n }\n \n const doNormalize = config['do_normalize'];\n if (typeof doNormalize === 'boolean') {\n options.doNormalize = doNormalize;\n }\n \n const doCenterCrop = config['do_center_crop'];\n if (typeof doCenterCrop === 'boolean') {\n options.doCenterCrop = doCenterCrop;\n }\n \n if (config['resample'] !== undefined) {\n // Map HuggingFace resample to our resize mode\n options.resizeMode = 'cover';\n }\n \n return new ImagePreprocessor(options);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromUrl(url: string): Promise<ImagePreprocessor> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load preprocessor config from ${url}`);\n }\n const config = await response.json() as Record<string, unknown>;\n return ImagePreprocessor.fromConfig(config);\n }\n\n /**\n * Load from HuggingFace Hub by model ID\n */\n static async fromHuggingFace(\n modelId: string,\n options?: { revision?: string }\n ): Promise<ImagePreprocessor> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/preprocessor_config.json`;\n return ImagePreprocessor.fromUrl(url);\n }\n\n /**\n * Initialize canvas (lazy)\n */\n private ensureCanvas(): void {\n if (!this.canvas) {\n if (typeof document !== 'undefined') {\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d');\n } else {\n throw new Error('ImagePreprocessor requires a browser environment');\n }\n }\n }\n\n /**\n * Process an image\n */\n async process(input: ImageInput): Promise<EdgeFlowTensor> {\n let imageData: ImageData;\n\n if (typeof input === 'string') {\n // Load from URL or base64\n imageData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n imageData = await this.loadFromBlob(input);\n } else if (input instanceof ImageData) {\n imageData = input;\n } else {\n // HTMLImageElement, HTMLCanvasElement, ImageBitmap\n imageData = this.toImageData(input);\n }\n\n // Apply preprocessing pipeline\n let processed = imageData;\n\n // 1. Resize\n if (this.options.doResize) {\n processed = this.resize(processed);\n }\n\n // 2. Center crop\n if (this.options.doCenterCrop) {\n processed = this.centerCrop(processed);\n }\n\n // 3. Convert to tensor (with rescale and normalize)\n return this.toTensor(processed);\n }\n\n /**\n * Process multiple images (batch)\n */\n async processBatch(inputs: ImageInput[]): Promise<EdgeFlowTensor> {\n const tensors = await Promise.all(inputs.map(input => this.process(input)));\n \n // Stack tensors into batch\n const batchSize = tensors.length;\n const firstTensor = tensors[0];\n if (!firstTensor) {\n return new EdgeFlowTensor(new Float32Array(0), [0], 'float32');\n }\n \n const channels = firstTensor.shape[0] ?? 3;\n const height = firstTensor.shape[1] ?? this.options.height;\n const width = firstTensor.shape[2] ?? this.options.width;\n \n const batchData = new Float32Array(batchSize * channels * height * width);\n \n for (let i = 0; i < tensors.length; i++) {\n const t = tensors[i];\n if (t) {\n batchData.set(t.toFloat32Array(), i * channels * height * width);\n }\n }\n\n return new EdgeFlowTensor(\n batchData,\n [batchSize, channels, height, width],\n 'float32'\n );\n }\n\n /**\n * Load image from URL or base64\n */\n private async loadFromUrl(url: string): Promise<ImageData> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n \n img.onload = () => {\n resolve(this.toImageData(img));\n };\n \n img.onerror = () => {\n reject(new Error(`Failed to load image from ${url}`));\n };\n \n img.src = url;\n });\n }\n\n /**\n * Load image from Blob/File\n */\n private async loadFromBlob(blob: Blob): Promise<ImageData> {\n const url = URL.createObjectURL(blob);\n try {\n return await this.loadFromUrl(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n }\n\n /**\n * Center crop image\n */\n private centerCrop(imageData: ImageData): ImageData {\n const cropSize = this.options.cropSize;\n let cropWidth: number;\n let cropHeight: number;\n \n if (typeof cropSize === 'number') {\n cropWidth = cropSize;\n cropHeight = cropSize;\n } else {\n cropWidth = cropSize.width;\n cropHeight = cropSize.height;\n }\n \n const srcX = Math.max(0, Math.floor((imageData.width - cropWidth) / 2));\n const srcY = Math.max(0, Math.floor((imageData.height - cropHeight) / 2));\n \n this.ensureCanvas();\n \n // Draw source image\n const srcCanvas = document.createElement('canvas');\n srcCanvas.width = imageData.width;\n srcCanvas.height = imageData.height;\n const srcCtx = srcCanvas.getContext('2d')!;\n srcCtx.putImageData(imageData, 0, 0);\n \n // Crop\n this.canvas!.width = cropWidth;\n this.canvas!.height = cropHeight;\n this.ctx!.drawImage(srcCanvas, srcX, srcY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);\n \n return this.ctx!.getImageData(0, 0, cropWidth, cropHeight);\n }\n\n /**\n * Convert image element to ImageData\n */\n private toImageData(\n source: HTMLImageElement | HTMLCanvasElement | ImageBitmap\n ): ImageData {\n this.ensureCanvas();\n \n const { width, height } = source;\n this.canvas!.width = width;\n this.canvas!.height = height;\n \n this.ctx!.drawImage(source, 0, 0);\n return this.ctx!.getImageData(0, 0, width, height);\n }\n\n /**\n * Resize image data\n */\n private resize(imageData: ImageData): ImageData {\n const { width, height, resizeMode } = this.options;\n \n this.ensureCanvas();\n \n // Calculate resize dimensions\n let srcX = 0, srcY = 0, srcW = imageData.width, srcH = imageData.height;\n let dstX = 0, dstY = 0, dstW = width, dstH = height;\n\n if (resizeMode === 'contain') {\n const scale = Math.min(width / imageData.width, height / imageData.height);\n dstW = Math.round(imageData.width * scale);\n dstH = Math.round(imageData.height * scale);\n dstX = Math.round((width - dstW) / 2);\n dstY = Math.round((height - dstH) / 2);\n } else if (resizeMode === 'cover') {\n const scale = Math.max(width / imageData.width, height / imageData.height);\n srcW = Math.round(width / scale);\n srcH = Math.round(height / scale);\n srcX = Math.round((imageData.width - srcW) / 2);\n srcY = Math.round((imageData.height - srcH) / 2);\n }\n\n // Create temp canvas for source\n const srcCanvas = document.createElement('canvas');\n srcCanvas.width = imageData.width;\n srcCanvas.height = imageData.height;\n const srcCtx = srcCanvas.getContext('2d')!;\n srcCtx.putImageData(imageData, 0, 0);\n\n // Draw to output canvas\n this.canvas!.width = width;\n this.canvas!.height = height;\n \n // Fill with black for padding modes\n if (resizeMode === 'contain' || resizeMode === 'pad') {\n this.ctx!.fillStyle = 'black';\n this.ctx!.fillRect(0, 0, width, height);\n }\n \n this.ctx!.drawImage(srcCanvas, srcX, srcY, srcW, srcH, dstX, dstY, dstW, dstH);\n \n return this.ctx!.getImageData(0, 0, width, height);\n }\n\n /**\n * Convert ImageData to tensor\n */\n private toTensor(imageData: ImageData): EdgeFlowTensor {\n const { \n mean, std, grayscale, channelFormat, dtype,\n doRescale, rescaleFactor, doNormalize\n } = this.options;\n \n const height = imageData.height;\n const width = imageData.width;\n const channels = grayscale ? 1 : 3;\n \n const data = new Float32Array(channels * height * width);\n const pixels = imageData.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const pixelIdx = (y * width + x) * 4;\n \n if (grayscale) {\n // Convert to grayscale\n let gray = (\n 0.299 * (pixels[pixelIdx] ?? 0) +\n 0.587 * (pixels[pixelIdx + 1] ?? 0) +\n 0.114 * (pixels[pixelIdx + 2] ?? 0)\n );\n \n if (doRescale) {\n gray *= rescaleFactor;\n }\n \n if (doNormalize) {\n gray = (gray - (mean[0] ?? 0)) / (std[0] ?? 1);\n }\n \n const idx = y * width + x;\n data[idx] = gray;\n } else if (channelFormat === 'CHW') {\n // Channel-first format (used by most PyTorch models)\n for (let c = 0; c < 3; c++) {\n let value = pixels[pixelIdx + c] ?? 0;\n \n if (doRescale) {\n value *= rescaleFactor;\n }\n \n if (doNormalize) {\n value = (value - (mean[c] ?? 0)) / (std[c] ?? 1);\n }\n \n const idx = c * height * width + y * width + x;\n data[idx] = value;\n }\n } else {\n // HWC format (used by TensorFlow models)\n for (let c = 0; c < 3; c++) {\n let value = pixels[pixelIdx + c] ?? 0;\n \n if (doRescale) {\n value *= rescaleFactor;\n }\n \n if (doNormalize) {\n value = (value - (mean[c] ?? 0)) / (std[c] ?? 1);\n }\n \n const idx = y * width * 3 + x * 3 + c;\n data[idx] = value;\n }\n }\n }\n }\n\n const shape = channelFormat === 'CHW'\n ? [channels, height, width]\n : [height, width, channels];\n\n return new EdgeFlowTensor(data, shape, dtype);\n }\n\n /**\n * Get current options\n */\n getOptions(): ImagePreprocessorOptions {\n return { ...this.options };\n }\n}\n\n// ============================================================================\n// Audio Preprocessing\n// ============================================================================\n\n/**\n * Audio preprocessing options\n */\nexport interface AudioPreprocessorOptions {\n /** Target sample rate */\n sampleRate?: number;\n /** Number of mel bins */\n nMels?: number;\n /** FFT size */\n nFft?: number;\n /** Hop length */\n hopLength?: number;\n /** Whether to normalize */\n normalize?: boolean;\n /** Maximum duration in seconds */\n maxDuration?: number;\n}\n\n/**\n * Default audio options\n */\nconst DEFAULT_AUDIO_OPTIONS: Required<AudioPreprocessorOptions> = {\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n normalize: true,\n maxDuration: 30,\n};\n\n/**\n * AudioPreprocessor - Process audio for model input\n * \n * Supports Whisper and other audio model preprocessing.\n */\nexport class AudioPreprocessor {\n private readonly options: Required<AudioPreprocessorOptions>;\n private audioContext: AudioContext | null = null;\n\n constructor(options: AudioPreprocessorOptions = {}) {\n this.options = { ...DEFAULT_AUDIO_OPTIONS, ...options };\n }\n\n /**\n * Load from HuggingFace feature_extractor config\n */\n static fromConfig(config: Record<string, unknown>): AudioPreprocessor {\n const options: AudioPreprocessorOptions = {};\n \n const samplingRate = config['sampling_rate'];\n if (typeof samplingRate === 'number') {\n options.sampleRate = samplingRate;\n }\n \n const featureSize = config['feature_size'];\n if (typeof featureSize === 'number') {\n options.nMels = featureSize;\n }\n \n const nFft = config['n_fft'];\n if (typeof nFft === 'number') {\n options.nFft = nFft;\n }\n \n const hopLength = config['hop_length'];\n if (typeof hopLength === 'number') {\n options.hopLength = hopLength;\n }\n \n return new AudioPreprocessor(options);\n }\n\n /**\n * Load from HuggingFace Hub\n */\n static async fromHuggingFace(\n modelId: string,\n options?: { revision?: string }\n ): Promise<AudioPreprocessor> {\n const revision = options?.revision ?? 'main';\n const url = `https://huggingface.co/${modelId}/resolve/${revision}/preprocessor_config.json`;\n \n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load audio config from ${url}`);\n }\n const config = await response.json() as Record<string, unknown>;\n return AudioPreprocessor.fromConfig(config);\n }\n\n /**\n * Initialize audio context (lazy)\n */\n private ensureAudioContext(): void {\n if (!this.audioContext) {\n if (typeof AudioContext !== 'undefined') {\n this.audioContext = new AudioContext({ sampleRate: this.options.sampleRate });\n } else {\n throw new Error('AudioPreprocessor requires Web Audio API support');\n }\n }\n }\n\n /**\n * Process audio data\n */\n async process(input: AudioInput): Promise<EdgeFlowTensor> {\n let audioData: Float32Array;\n\n if (typeof input === 'string') {\n // Load from URL\n audioData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n // Load from Blob/File\n audioData = await this.loadFromBlob(input);\n } else if (input instanceof AudioBuffer) {\n audioData = this.audioBufferToFloat32(input);\n } else if (input instanceof Float32Array) {\n audioData = input;\n } else {\n // ArrayBuffer - decode\n audioData = await this.decodeAudioData(input);\n }\n\n // Resample if needed\n // For now, assume input is at target sample rate\n\n // Normalize\n if (this.options.normalize) {\n audioData = this.normalizeAudio(audioData);\n }\n\n // Truncate if needed\n const maxSamples = this.options.maxDuration * this.options.sampleRate;\n if (audioData.length > maxSamples) {\n audioData = audioData.slice(0, maxSamples);\n }\n\n // Compute mel spectrogram (simplified)\n const melSpec = this.computeMelSpectrogram(audioData);\n\n return melSpec;\n }\n\n /**\n * Process raw waveform (for models that don't need mel spectrogram)\n */\n async processRaw(input: AudioInput): Promise<EdgeFlowTensor> {\n let audioData: Float32Array;\n\n if (typeof input === 'string') {\n audioData = await this.loadFromUrl(input);\n } else if (input instanceof Blob || input instanceof File) {\n audioData = await this.loadFromBlob(input);\n } else if (input instanceof AudioBuffer) {\n audioData = this.audioBufferToFloat32(input);\n } else if (input instanceof Float32Array) {\n audioData = input;\n } else {\n audioData = await this.decodeAudioData(input);\n }\n\n // Normalize\n if (this.options.normalize) {\n audioData = this.normalizeAudio(audioData);\n }\n\n // Truncate/pad\n const maxSamples = this.options.maxDuration * this.options.sampleRate;\n if (audioData.length > maxSamples) {\n audioData = audioData.slice(0, maxSamples);\n }\n\n return new EdgeFlowTensor(audioData, [1, audioData.length], 'float32');\n }\n\n /**\n * Load audio from URL\n */\n private async loadFromUrl(url: string): Promise<Float32Array> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load audio from ${url}`);\n }\n \n const arrayBuffer = await response.arrayBuffer();\n return this.decodeAudioData(arrayBuffer);\n }\n\n /**\n * Load audio from Blob/File\n */\n private async loadFromBlob(blob: Blob): Promise<Float32Array> {\n const arrayBuffer = await blob.arrayBuffer();\n return this.decodeAudioData(arrayBuffer);\n }\n\n /**\n * Decode audio data\n */\n private async decodeAudioData(data: ArrayBuffer): Promise<Float32Array> {\n this.ensureAudioContext();\n const audioBuffer = await this.audioContext!.decodeAudioData(data.slice(0)); // Clone to avoid detached buffer\n return this.audioBufferToFloat32(audioBuffer);\n }\n\n /**\n * Convert AudioBuffer to Float32Array\n */\n private audioBufferToFloat32(buffer: AudioBuffer): Float32Array {\n // Get first channel\n const channelData = buffer.getChannelData(0);\n return new Float32Array(channelData);\n }\n\n /**\n * Normalize audio\n */\n private normalizeAudio(data: Float32Array): Float32Array {\n let max = 0;\n for (let i = 0; i < data.length; i++) {\n const abs = Math.abs(data[i] ?? 0);\n if (abs > max) max = abs;\n }\n\n if (max > 0) {\n const result = new Float32Array(data.length);\n for (let i = 0; i < data.length; i++) {\n result[i] = (data[i] ?? 0) / max;\n }\n return result;\n }\n\n return data;\n }\n\n /**\n * Compute mel spectrogram (simplified implementation)\n */\n private computeMelSpectrogram(audio: Float32Array): EdgeFlowTensor {\n const { nMels, nFft, hopLength } = this.options;\n \n // Calculate number of frames\n const numFrames = Math.floor((audio.length - nFft) / hopLength) + 1;\n \n if (numFrames <= 0) {\n // Return empty spectrogram for very short audio\n return new EdgeFlowTensor(new Float32Array(nMels), [1, nMels], 'float32');\n }\n\n const melSpec = new Float32Array(numFrames * nMels);\n\n // Simplified mel spectrogram computation\n // In production, use proper FFT and mel filterbank\n for (let frame = 0; frame < numFrames; frame++) {\n const start = frame * hopLength;\n \n // Compute frame energy (simplified - not real FFT)\n for (let mel = 0; mel < nMels; mel++) {\n let energy = 0;\n const freqStart = Math.floor((mel / nMels) * (nFft / 2));\n const freqEnd = Math.floor(((mel + 1) / nMels) * (nFft / 2));\n \n for (let i = freqStart; i < Math.min(freqEnd, nFft); i++) {\n const sample = audio[start + i] ?? 0;\n energy += sample * sample;\n }\n \n // Convert to log scale\n melSpec[frame * nMels + mel] = Math.log(energy + 1e-10);\n }\n }\n\n return new EdgeFlowTensor(melSpec, [numFrames, nMels], 'float32');\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = null;\n }\n }\n}\n\n// ============================================================================\n// Text Preprocessing\n// ============================================================================\n\n/**\n * Text preprocessing options\n */\nexport interface TextPreprocessorOptions {\n /** Convert to lowercase */\n lowercase?: boolean;\n /** Remove punctuation */\n removePunctuation?: boolean;\n /** Remove extra whitespace */\n normalizeWhitespace?: boolean;\n /** Maximum length in characters */\n maxLength?: number;\n}\n\n/**\n * Preprocess text\n */\nexport function preprocessText(\n text: string,\n options: TextPreprocessorOptions = {}\n): string {\n const {\n lowercase = true,\n removePunctuation = false,\n normalizeWhitespace = true,\n maxLength,\n } = options;\n\n let result = text;\n\n if (lowercase) {\n result = result.toLowerCase();\n }\n\n if (removePunctuation) {\n result = result.replace(/[^\\w\\s]/g, '');\n }\n\n if (normalizeWhitespace) {\n result = result.replace(/\\s+/g, ' ').trim();\n }\n\n if (maxLength && result.length > maxLength) {\n result = result.slice(0, maxLength);\n }\n\n return result;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create image preprocessor with common presets\n */\nexport function createImagePreprocessor(\n preset: 'imagenet' | 'clip' | 'vit' | 'custom' = 'imagenet',\n options: ImagePreprocessorOptions = {}\n): ImagePreprocessor {\n const presets: Record<string, ImagePreprocessorOptions> = {\n imagenet: {\n width: 224,\n height: 224,\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n },\n clip: {\n width: 224,\n height: 224,\n mean: [0.48145466, 0.4578275, 0.40821073],\n std: [0.26862954, 0.26130258, 0.27577711],\n },\n vit: {\n width: 224,\n height: 224,\n mean: [0.5, 0.5, 0.5],\n std: [0.5, 0.5, 0.5],\n },\n custom: {},\n };\n\n return new ImagePreprocessor({ ...presets[preset], ...options });\n}\n\n/**\n * Create audio preprocessor with common presets\n */\nexport function createAudioPreprocessor(\n preset: 'whisper' | 'wav2vec' | 'custom' = 'whisper',\n options: AudioPreprocessorOptions = {}\n): AudioPreprocessor {\n const presets: Record<string, AudioPreprocessorOptions> = {\n whisper: {\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n },\n wav2vec: {\n sampleRate: 16000,\n normalize: true,\n },\n custom: {},\n };\n\n return new AudioPreprocessor({ ...presets[preset], ...options });\n}\n", "/**\n * edgeFlow.js - Text Generation Pipeline\n * \n * Autoregressive text generation with streaming support.\n * Supports GPT-2, LLaMA, Mistral, and other causal LM models.\n * Includes chat/conversation support with message history.\n */\n\nimport { BasePipeline, PipelineResult } from './base.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { runInferenceNamed, loadModelFromBuffer } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model URLs (TinyLlama - quantized for browser)\n// ============================================================================\n\nconst DEFAULT_LLM_MODELS = {\n model: 'https://huggingface.co/Xenova/TinyLlama-1.1B-Chat-v1.0/resolve/main/onnx/model_q4f16.onnx',\n tokenizer: 'https://huggingface.co/Xenova/TinyLlama-1.1B-Chat-v1.0/resolve/main/tokenizer.json',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * LLM model loading progress callback\n */\nexport interface LLMLoadProgress {\n /** Stage: 'tokenizer' or 'model' */\n stage: 'tokenizer' | 'model';\n /** Bytes loaded */\n loaded: number;\n /** Total bytes */\n total: number;\n /** Progress percentage (0-100) */\n progress: number;\n}\n\n/**\n * Chat message\n */\nexport interface ChatMessage {\n /** Role: 'system', 'user', or 'assistant' */\n role: 'system' | 'user' | 'assistant';\n /** Message content */\n content: string;\n}\n\n/**\n * Chat template type\n */\nexport type ChatTemplateType = 'chatml' | 'llama2' | 'llama3' | 'mistral' | 'phi3' | 'alpaca' | 'vicuna' | 'custom';\n\n/**\n * Text generation options\n */\nexport interface TextGenerationOptions {\n /** Maximum number of new tokens to generate */\n maxNewTokens?: number;\n /** Maximum total length (prompt + generated) */\n maxLength?: number;\n /** Minimum number of new tokens to generate */\n minNewTokens?: number;\n /** Sampling temperature (higher = more random) */\n temperature?: number;\n /** Top-k sampling (0 = disabled) */\n topK?: number;\n /** Top-p (nucleus) sampling (1.0 = disabled) */\n topP?: number;\n /** Repetition penalty (1.0 = disabled) */\n repetitionPenalty?: number;\n /** Stop sequences */\n stopSequences?: string[];\n /** Whether to do sampling (false = greedy) */\n doSample?: boolean;\n /** Number of sequences to return */\n numReturnSequences?: number;\n /** Return full text (including prompt) */\n returnFullText?: boolean;\n /** Callback for each generated token */\n onToken?: (token: string, tokenId: number) => void;\n}\n\n/**\n * Chat generation options\n */\nexport interface ChatOptions extends TextGenerationOptions {\n /** System prompt */\n systemPrompt?: string;\n /** Chat template type */\n templateType?: ChatTemplateType;\n /** Custom template (if templateType is 'custom') */\n customTemplate?: {\n systemPrefix?: string;\n systemSuffix?: string;\n userPrefix?: string;\n userSuffix?: string;\n assistantPrefix?: string;\n assistantSuffix?: string;\n separator?: string;\n };\n}\n\n/**\n * Text generation result\n */\nexport interface TextGenerationResult extends PipelineResult {\n /** Generated text */\n generatedText: string;\n /** Full text (prompt + generated) if returnFullText is true */\n fullText?: string;\n /** Generated token IDs */\n tokenIds: number[];\n /** Number of tokens generated */\n numTokens: number;\n}\n\n/**\n * Streaming generation event\n */\nexport interface GenerationStreamEvent {\n /** Current token */\n token: string;\n /** Token ID */\n tokenId: number;\n /** Generated text so far */\n generatedText: string;\n /** Whether generation is complete */\n done: boolean;\n}\n\n// ============================================================================\n// Text Generation Pipeline\n// ============================================================================\n\n/**\n * TextGenerationPipeline - Autoregressive text generation\n * \n * @example\n * ```typescript\n * const generator = await pipeline('text-generation', 'Xenova/gpt2');\n * \n * // Simple generation\n * const result = await generator.run('Once upon a time');\n * console.log(result.generatedText);\n * \n * // Streaming generation\n * for await (const event of generator.stream('Hello, ')) {\n * process.stdout.write(event.token);\n * }\n * ```\n */\nexport class TextGenerationPipeline extends BasePipeline<string | string[], TextGenerationResult | TextGenerationResult[]> {\n private tokenizer: Tokenizer | null = null;\n private eosTokenId: number = 50256; // GPT-2 default\n private llmModel: LoadedModel | null = null;\n private modelsLoaded: boolean = false;\n \n // Custom model URLs\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'text-generation',\n model: 'default',\n });\n this.modelUrl = DEFAULT_LLM_MODELS.model;\n this.tokenizerUrl = DEFAULT_LLM_MODELS.tokenizer;\n }\n\n /**\n * Check if model is loaded\n */\n get isModelLoaded(): boolean {\n return this.modelsLoaded;\n }\n\n /**\n * Set custom model URLs\n */\n setModelUrls(model: string, tokenizer: string): void {\n this.modelUrl = model;\n this.tokenizerUrl = tokenizer;\n }\n\n /**\n * Load model and tokenizer with progress callback\n */\n async loadModel(\n onProgress?: (progress: LLMLoadProgress) => void\n ): Promise<void> {\n if (this.modelsLoaded) return;\n\n // Load tokenizer first (small, fast)\n onProgress?.({ stage: 'tokenizer', loaded: 0, total: 100, progress: 0 });\n \n try {\n const tokenizerResponse = await fetch(this.tokenizerUrl);\n if (!tokenizerResponse.ok) {\n throw new Error(`Failed to fetch tokenizer: ${tokenizerResponse.status}`);\n }\n const tokenizerJson = await tokenizerResponse.json();\n this.tokenizer = await Tokenizer.fromJSON(tokenizerJson);\n \n const specialIds = this.tokenizer.getSpecialTokenIds();\n this.eosTokenId = specialIds.eosTokenId ?? specialIds.sepTokenId ?? 2; // TinyLlama uses 2 as EOS\n \n onProgress?.({ stage: 'tokenizer', loaded: 100, total: 100, progress: 100 });\n } catch (error) {\n throw new Error(`Failed to load tokenizer: ${error}`);\n }\n\n // Load model with progress tracking\n onProgress?.({ stage: 'model', loaded: 0, total: 100, progress: 0 });\n \n const modelData = await this.fetchModelWithProgress(\n this.modelUrl,\n (loaded, total) => {\n onProgress?.({\n stage: 'model',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.llmModel = await loadModelFromBuffer(modelData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n this.model = this.llmModel;\n\n this.modelsLoaded = true;\n }\n\n /**\n * Fetch model with progress tracking\n */\n private async fetchModelWithProgress(\n url: string,\n onProgress: (loaded: number, total: number) => void\n ): Promise<ArrayBuffer> {\n const response = await fetch(url);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch model: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body) {\n // Fallback if no streaming support\n const buffer = await response.arrayBuffer();\n onProgress(buffer.byteLength, buffer.byteLength);\n return buffer;\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n \n if (done) break;\n \n chunks.push(value);\n loaded += value.length;\n onProgress(loaded, total || loaded);\n }\n\n // Combine chunks into ArrayBuffer\n const buffer = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n return buffer.buffer;\n }\n\n /**\n * Initialize pipeline (override to skip default model loading)\n */\n override async initialize(): Promise<void> {\n if (this.isReady) return;\n // Don't call super.initialize() - we handle model loading separately\n this.isReady = true;\n }\n\n /**\n * Set tokenizer\n */\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n const specialIds = tokenizer.getSpecialTokenIds();\n this.eosTokenId = specialIds.eosTokenId ?? specialIds.sepTokenId ?? 50256;\n }\n\n /**\n * Preprocess - not used for text generation (handled in generateSingle)\n */\n protected async preprocess(input: string | string[]): Promise<EdgeFlowTensor[]> {\n // For text generation, preprocessing is handled in generateNextToken\n const text = Array.isArray(input) ? input[0] ?? '' : input;\n if (!this.tokenizer) {\n // Return dummy tensor if no tokenizer\n return [new EdgeFlowTensor(new Float32Array([0]), [1], 'float32')];\n }\n const encoded = this.tokenizer.encode(text, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n });\n return [new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n )];\n }\n\n /**\n * Postprocess - not used for text generation (handled in generateSingle)\n */\n protected async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<TextGenerationResult | TextGenerationResult[]> {\n // For text generation, postprocessing is handled in generateSingle\n return {\n generatedText: '',\n tokenIds: [],\n numTokens: 0,\n processingTime: 0,\n };\n }\n\n /**\n * Generate text (non-streaming)\n */\n override async run(\n prompt: string | string[],\n options?: PipelineOptions & TextGenerationOptions\n ): Promise<TextGenerationResult | TextGenerationResult[]> {\n await this.initialize();\n \n const prompts = Array.isArray(prompt) ? prompt : [prompt];\n const results = await Promise.all(\n prompts.map(p => this.generateSingle(p, options ?? {}))\n );\n return Array.isArray(prompt) ? results : results[0]!;\n }\n\n /**\n * Generate text with streaming (async generator)\n */\n async *stream(\n prompt: string,\n options: TextGenerationOptions = {}\n ): AsyncGenerator<GenerationStreamEvent> {\n const startTime = performance.now();\n \n if (!this.tokenizer) {\n throw new Error('Tokenizer not set. Call setTokenizer() first.');\n }\n\n const {\n maxNewTokens = 50,\n maxLength = 512,\n temperature = 1.0,\n topK = 0,\n topP = 1.0,\n repetitionPenalty = 1.0,\n stopSequences = [],\n doSample = true,\n } = options;\n\n // Encode prompt\n const encoded = this.tokenizer.encode(prompt, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n truncation: false,\n });\n\n let inputIds = [...encoded.inputIds];\n const generatedIds: number[] = [];\n let generatedText = '';\n\n // Generation loop\n for (let i = 0; i < maxNewTokens; i++) {\n // Check max length\n if (inputIds.length >= maxLength) break;\n\n // Run model forward pass\n const nextTokenId = await this.generateNextToken(\n inputIds,\n temperature,\n topK,\n topP,\n repetitionPenalty,\n doSample\n );\n\n // Check for EOS\n if (nextTokenId === this.eosTokenId) {\n yield {\n token: '',\n tokenId: nextTokenId,\n generatedText,\n done: true,\n };\n break;\n }\n\n // Decode token\n const token = this.tokenizer.decode([nextTokenId], true);\n generatedIds.push(nextTokenId);\n inputIds.push(nextTokenId);\n generatedText += token;\n\n // Call token callback\n if (options.onToken) {\n options.onToken(token, nextTokenId);\n }\n\n // Check stop sequences\n let shouldStop = false;\n for (const stopSeq of stopSequences) {\n if (generatedText.endsWith(stopSeq)) {\n generatedText = generatedText.slice(0, -stopSeq.length);\n shouldStop = true;\n break;\n }\n }\n\n yield {\n token,\n tokenId: nextTokenId,\n generatedText,\n done: shouldStop,\n };\n\n if (shouldStop) break;\n }\n\n // Final event\n const endTime = performance.now();\n console.log(`Generation completed in ${(endTime - startTime).toFixed(2)}ms`);\n }\n\n /**\n * Generate a single sequence (non-streaming)\n */\n private async generateSingle(\n prompt: string,\n options: TextGenerationOptions\n ): Promise<TextGenerationResult> {\n const startTime = performance.now();\n \n if (!this.tokenizer) {\n throw new Error('Tokenizer not set. Call setTokenizer() first.');\n }\n\n const {\n maxNewTokens = 50,\n maxLength = 512,\n temperature = 1.0,\n topK = 0,\n topP = 1.0,\n repetitionPenalty = 1.0,\n stopSequences = [],\n doSample = true,\n returnFullText = false,\n } = options;\n\n // Encode prompt\n const encoded = this.tokenizer.encode(prompt, {\n addSpecialTokens: false,\n padding: 'do_not_pad',\n truncation: false,\n });\n\n let inputIds = [...encoded.inputIds];\n const generatedIds: number[] = [];\n\n // Generation loop\n for (let i = 0; i < maxNewTokens; i++) {\n // Check max length\n if (inputIds.length >= maxLength) break;\n\n // Run model forward pass\n const nextTokenId = await this.generateNextToken(\n inputIds,\n temperature,\n topK,\n topP,\n repetitionPenalty,\n doSample\n );\n\n // Check for EOS\n if (nextTokenId === this.eosTokenId) break;\n\n // Add to sequence\n generatedIds.push(nextTokenId);\n inputIds.push(nextTokenId);\n\n // Call token callback\n if (options.onToken) {\n const token = this.tokenizer.decode([nextTokenId], true);\n options.onToken(token, nextTokenId);\n }\n\n // Check stop sequences\n const currentText = this.tokenizer.decode(generatedIds, true);\n let shouldStop = false;\n for (const stopSeq of stopSequences) {\n if (currentText.endsWith(stopSeq)) {\n shouldStop = true;\n break;\n }\n }\n if (shouldStop) break;\n }\n\n // Decode generated text\n const generatedText = this.tokenizer.decode(generatedIds, true);\n const endTime = performance.now();\n\n return {\n generatedText,\n fullText: returnFullText ? prompt + generatedText : undefined,\n tokenIds: generatedIds,\n numTokens: generatedIds.length,\n processingTime: endTime - startTime,\n };\n }\n\n /**\n * Generate next token using the model\n */\n private async generateNextToken(\n inputIds: number[],\n temperature: number,\n topK: number,\n topP: number,\n repetitionPenalty: number,\n doSample: boolean\n ): Promise<number> {\n if (!this.model) {\n throw new Error('Model not loaded');\n }\n\n const seqLen = inputIds.length;\n\n // Prepare named inputs\n const inputs = new Map<string, EdgeFlowTensor>();\n\n // input_ids: [1, seq_len]\n inputs.set('input_ids', new EdgeFlowTensor(\n BigInt64Array.from(inputIds.map(id => BigInt(id))),\n [1, seqLen],\n 'int64'\n ));\n\n // attention_mask: [1, seq_len]\n inputs.set('attention_mask', new EdgeFlowTensor(\n BigInt64Array.from(inputIds.map(() => BigInt(1))),\n [1, seqLen],\n 'int64'\n ));\n\n // position_ids: [1, seq_len] - sequential positions from 0 to seq_len-1\n inputs.set('position_ids', new EdgeFlowTensor(\n BigInt64Array.from(Array.from({ length: seqLen }, (_, i) => BigInt(i))),\n [1, seqLen],\n 'int64'\n ));\n\n // TinyLlama has 22 layers with GQA (4 KV heads, head_dim=64)\n // For first inference without cache, provide empty past_key_values\n const numLayers = 22;\n const numKVHeads = 4;\n const headDim = 64;\n \n for (let i = 0; i < numLayers; i++) {\n // past_key_values.{i}.key: [batch, num_kv_heads, 0, head_dim]\n inputs.set(`past_key_values.${i}.key`, new EdgeFlowTensor(\n new Float32Array(0),\n [1, numKVHeads, 0, headDim],\n 'float32'\n ));\n // past_key_values.{i}.value: [batch, num_kv_heads, 0, head_dim]\n inputs.set(`past_key_values.${i}.value`, new EdgeFlowTensor(\n new Float32Array(0),\n [1, numKVHeads, 0, headDim],\n 'float32'\n ));\n }\n\n // Run inference with named inputs\n const outputs = await runInferenceNamed(this.model, inputs);\n \n if (!outputs || outputs.length === 0) {\n throw new Error('Model returned no outputs');\n }\n\n // Get logits for last token\n const logits = outputs[0]!;\n const logitsData = logits.toFloat32Array();\n const vocabSize = logits.shape[logits.shape.length - 1] ?? 50257;\n \n // Get logits for the last position\n const lastPositionLogits = new Float32Array(vocabSize);\n const offset = (inputIds.length - 1) * vocabSize;\n \n for (let i = 0; i < vocabSize; i++) {\n lastPositionLogits[i] = logitsData[offset + i] ?? 0;\n }\n\n // Apply repetition penalty\n if (repetitionPenalty !== 1.0) {\n for (const prevId of inputIds) {\n if (prevId < vocabSize) {\n const score = lastPositionLogits[prevId] ?? 0;\n lastPositionLogits[prevId] = score > 0 \n ? score / repetitionPenalty \n : score * repetitionPenalty;\n }\n }\n }\n\n // Apply temperature\n if (temperature !== 1.0) {\n for (let i = 0; i < vocabSize; i++) {\n lastPositionLogits[i] = (lastPositionLogits[i] ?? 0) / temperature;\n }\n }\n\n // Convert to probabilities\n const logitsTensor = new EdgeFlowTensor(lastPositionLogits, [vocabSize], 'float32');\n const probs = softmax(logitsTensor).toFloat32Array();\n\n // Sample or greedy\n if (doSample) {\n return this.sample(probs, topK, topP);\n } else {\n return this.greedy(probs);\n }\n }\n\n /**\n * Greedy decoding (argmax)\n */\n private greedy(probs: Float32Array): number {\n let maxIdx = 0;\n let maxProb = probs[0] ?? 0;\n \n for (let i = 1; i < probs.length; i++) {\n if ((probs[i] ?? 0) > maxProb) {\n maxProb = probs[i] ?? 0;\n maxIdx = i;\n }\n }\n \n return maxIdx;\n }\n\n /**\n * Sample from probability distribution with top-k/top-p filtering\n */\n private sample(probs: Float32Array, topK: number, topP: number): number {\n // Create sorted indices\n const indices = Array.from({ length: probs.length }, (_, i) => i);\n indices.sort((a, b) => (probs[b] ?? 0) - (probs[a] ?? 0));\n\n // Apply top-k filtering\n let candidateIndices = indices;\n if (topK > 0 && topK < probs.length) {\n candidateIndices = indices.slice(0, topK);\n }\n\n // Apply top-p (nucleus) filtering\n if (topP < 1.0) {\n let cumulativeProb = 0;\n const filtered: number[] = [];\n \n for (const idx of candidateIndices) {\n filtered.push(idx);\n cumulativeProb += probs[idx] ?? 0;\n if (cumulativeProb >= topP) break;\n }\n \n candidateIndices = filtered;\n }\n\n // Renormalize probabilities\n let totalProb = 0;\n for (const idx of candidateIndices) {\n totalProb += probs[idx] ?? 0;\n }\n\n // Sample\n const r = Math.random() * totalProb;\n let cumulative = 0;\n \n for (const idx of candidateIndices) {\n cumulative += probs[idx] ?? 0;\n if (cumulative >= r) {\n return idx;\n }\n }\n\n // Fallback\n return candidateIndices[0] ?? 0;\n }\n\n // ==========================================================================\n // Chat / Conversation Support\n // ==========================================================================\n\n private conversationHistory: ChatMessage[] = [];\n private chatTemplateType: ChatTemplateType = 'chatml';\n\n /**\n * Set the chat template type\n */\n setChatTemplate(templateType: ChatTemplateType): void {\n this.chatTemplateType = templateType;\n }\n\n /**\n * Apply chat template to messages\n */\n applyChatTemplate(messages: ChatMessage[], options?: ChatOptions): string {\n const templateType = options?.templateType ?? this.chatTemplateType;\n \n switch (templateType) {\n case 'chatml':\n return this.applyChatMLTemplate(messages);\n case 'llama2':\n return this.applyLlama2Template(messages);\n case 'llama3':\n return this.applyLlama3Template(messages);\n case 'mistral':\n return this.applyMistralTemplate(messages);\n case 'phi3':\n return this.applyPhi3Template(messages);\n case 'alpaca':\n return this.applyAlpacaTemplate(messages);\n case 'vicuna':\n return this.applyVicunaTemplate(messages);\n case 'custom':\n return this.applyCustomTemplate(messages, options?.customTemplate ?? {});\n default:\n return this.applyChatMLTemplate(messages);\n }\n }\n\n /**\n * ChatML template (used by many models including Qwen, Yi)\n */\n private applyChatMLTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n for (const msg of messages) {\n prompt += `<|im_start|>${msg.role}\\n${msg.content}<|im_end|>\\n`;\n }\n prompt += '<|im_start|>assistant\\n';\n return prompt;\n }\n\n /**\n * Llama 2 template\n */\n private applyLlama2Template(messages: ChatMessage[]): string {\n let prompt = '';\n let systemMsg = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n systemMsg = msg.content;\n } else if (msg.role === 'user') {\n if (systemMsg) {\n prompt += `<s>[INST] <<SYS>>\\n${systemMsg}\\n<</SYS>>\\n\\n${msg.content} [/INST]`;\n systemMsg = '';\n } else {\n prompt += `<s>[INST] ${msg.content} [/INST]`;\n }\n } else if (msg.role === 'assistant') {\n prompt += ` ${msg.content} </s>`;\n }\n }\n \n return prompt;\n }\n\n /**\n * Llama 3 template\n */\n private applyLlama3Template(messages: ChatMessage[]): string {\n let prompt = '<|begin_of_text|>';\n \n for (const msg of messages) {\n prompt += `<|start_header_id|>${msg.role}<|end_header_id|>\\n\\n${msg.content}<|eot_id|>`;\n }\n \n prompt += '<|start_header_id|>assistant<|end_header_id|>\\n\\n';\n return prompt;\n }\n\n /**\n * Mistral template\n */\n private applyMistralTemplate(messages: ChatMessage[]): string {\n let prompt = '<s>';\n \n for (const msg of messages) {\n if (msg.role === 'user') {\n prompt += `[INST] ${msg.content} [/INST]`;\n } else if (msg.role === 'assistant') {\n prompt += ` ${msg.content}</s>`;\n } else if (msg.role === 'system') {\n prompt += `[INST] ${msg.content}\\n`;\n }\n }\n \n return prompt;\n }\n\n /**\n * Phi-3 template\n */\n private applyPhi3Template(messages: ChatMessage[]): string {\n let prompt = '';\n \n for (const msg of messages) {\n prompt += `<|${msg.role}|>\\n${msg.content}<|end|>\\n`;\n }\n \n prompt += '<|assistant|>\\n';\n return prompt;\n }\n\n /**\n * Alpaca template\n */\n private applyAlpacaTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n let instruction = '';\n let input = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n instruction = msg.content;\n } else if (msg.role === 'user') {\n input = msg.content;\n }\n }\n \n if (instruction) {\n prompt = `### Instruction:\\n${instruction}\\n\\n`;\n }\n if (input) {\n prompt += `### Input:\\n${input}\\n\\n`;\n }\n prompt += '### Response:\\n';\n \n return prompt;\n }\n\n /**\n * Vicuna template\n */\n private applyVicunaTemplate(messages: ChatMessage[]): string {\n let prompt = '';\n \n for (const msg of messages) {\n if (msg.role === 'system') {\n prompt += `${msg.content}\\n\\n`;\n } else if (msg.role === 'user') {\n prompt += `USER: ${msg.content}\\n`;\n } else if (msg.role === 'assistant') {\n prompt += `ASSISTANT: ${msg.content}\\n`;\n }\n }\n \n prompt += 'ASSISTANT:';\n return prompt;\n }\n\n /**\n * Custom template\n */\n private applyCustomTemplate(\n messages: ChatMessage[],\n template: NonNullable<ChatOptions['customTemplate']>\n ): string {\n const {\n systemPrefix = '',\n systemSuffix = '\\n',\n userPrefix = 'User: ',\n userSuffix = '\\n',\n assistantPrefix = 'Assistant: ',\n assistantSuffix = '\\n',\n separator = '',\n } = template;\n \n let prompt = '';\n \n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!;\n if (i > 0) prompt += separator;\n \n switch (msg.role) {\n case 'system':\n prompt += `${systemPrefix}${msg.content}${systemSuffix}`;\n break;\n case 'user':\n prompt += `${userPrefix}${msg.content}${userSuffix}`;\n break;\n case 'assistant':\n prompt += `${assistantPrefix}${msg.content}${assistantSuffix}`;\n break;\n }\n }\n \n prompt += assistantPrefix;\n return prompt;\n }\n\n /**\n * Chat with the model\n * \n * @example\n * ```typescript\n * const generator = await pipeline('text-generation', 'model');\n * \n * // Single turn\n * const response = await generator.chat('Hello, how are you?');\n * \n * // Multi-turn with history\n * const response1 = await generator.chat('What is AI?');\n * const response2 = await generator.chat('Can you give an example?');\n * \n * // With system prompt\n * const response = await generator.chat('Hello', {\n * systemPrompt: 'You are a helpful assistant.',\n * });\n * ```\n */\n async chat(\n userMessage: string,\n options?: ChatOptions\n ): Promise<TextGenerationResult> {\n // Add system message if provided and not already present\n if (options?.systemPrompt && \n (this.conversationHistory.length === 0 || this.conversationHistory[0]?.role !== 'system')) {\n this.conversationHistory.unshift({\n role: 'system',\n content: options.systemPrompt,\n });\n }\n\n // Add user message\n this.conversationHistory.push({\n role: 'user',\n content: userMessage,\n });\n\n // Apply chat template\n const prompt = this.applyChatTemplate(this.conversationHistory, options);\n\n // Generate response\n const result = await this.run(prompt, {\n ...options,\n stopSequences: [\n ...(options?.stopSequences ?? []),\n '<|im_end|>',\n '<|end|>',\n '<|eot_id|>',\n '</s>',\n '\\n\\nUser:',\n '\\n\\nHuman:',\n ],\n });\n\n // Add assistant response to history\n const response = Array.isArray(result) ? result[0]! : result;\n this.conversationHistory.push({\n role: 'assistant',\n content: response.generatedText.trim(),\n });\n\n return response;\n }\n\n /**\n * Stream chat response\n */\n async *chatStream(\n userMessage: string,\n options?: ChatOptions\n ): AsyncGenerator<GenerationStreamEvent> {\n // Add system message if provided\n if (options?.systemPrompt && \n (this.conversationHistory.length === 0 || this.conversationHistory[0]?.role !== 'system')) {\n this.conversationHistory.unshift({\n role: 'system',\n content: options.systemPrompt,\n });\n }\n\n // Add user message\n this.conversationHistory.push({\n role: 'user',\n content: userMessage,\n });\n\n // Apply chat template\n const prompt = this.applyChatTemplate(this.conversationHistory, options);\n\n // Stream response\n let fullResponse = '';\n for await (const event of this.stream(prompt, {\n ...options,\n stopSequences: [\n ...(options?.stopSequences ?? []),\n '<|im_end|>',\n '<|end|>',\n '<|eot_id|>',\n '</s>',\n ],\n })) {\n fullResponse = event.generatedText;\n yield event;\n }\n\n // Add assistant response to history\n this.conversationHistory.push({\n role: 'assistant',\n content: fullResponse.trim(),\n });\n }\n\n /**\n * Get conversation history\n */\n getConversationHistory(): ChatMessage[] {\n return [...this.conversationHistory];\n }\n\n /**\n * Set conversation history\n */\n setConversationHistory(messages: ChatMessage[]): void {\n this.conversationHistory = [...messages];\n }\n\n /**\n * Clear conversation history\n */\n clearConversation(): void {\n this.conversationHistory = [];\n }\n\n /**\n * Remove last exchange (user message + assistant response)\n */\n undoLastExchange(): void {\n // Remove assistant message\n if (this.conversationHistory.length > 0 && \n this.conversationHistory[this.conversationHistory.length - 1]?.role === 'assistant') {\n this.conversationHistory.pop();\n }\n // Remove user message\n if (this.conversationHistory.length > 0 && \n this.conversationHistory[this.conversationHistory.length - 1]?.role === 'user') {\n this.conversationHistory.pop();\n }\n }\n\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create text generation pipeline\n */\nexport function createTextGenerationPipeline(config?: PipelineConfig): TextGenerationPipeline {\n return new TextGenerationPipeline(config);\n}\n", "/**\n * edgeFlow.js - Object Detection Pipeline\n * \n * Detect objects in images with bounding boxes and class labels.\n */\n\nimport { BasePipeline, ObjectDetectionResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { ImagePreprocessor, type ImageInput } from '../utils/preprocessor.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference } from '../core/runtime.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ObjectDetectionOptions extends PipelineOptions {\n threshold?: number;\n topK?: number;\n nms?: boolean;\n iouThreshold?: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface Detection extends ObjectDetectionResult {\n classId: number;\n boxNormalized: BoundingBox;\n}\n\n// ============================================================================\n// Default Model (YOLOS-tiny, quantized)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/yolos-tiny/resolve/main/onnx/model_quantized.onnx',\n};\n\n// ============================================================================\n// COCO Labels\n// ============================================================================\n\nexport const COCO_LABELS = [\n 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck',\n 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench',\n 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra',\n 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',\n 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',\n 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',\n 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange',\n 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',\n 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse',\n 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink',\n 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier',\n 'toothbrush'\n];\n\n// ============================================================================\n// Object Detection Pipeline\n// ============================================================================\n\nexport class ObjectDetectionPipeline extends BasePipeline<ImageInput | ImageInput[], Detection[]> {\n private preprocessor: ImagePreprocessor;\n private onnxModel: LoadedModel | null = null;\n private labels: string[];\n private modelUrl: string;\n\n constructor(config?: PipelineConfig, labels?: string[]) {\n super(config ?? {\n task: 'object-detection',\n model: 'default',\n });\n\n this.labels = labels ?? COCO_LABELS;\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.preprocessor = new ImagePreprocessor({\n width: 640,\n height: 640,\n mean: [0.485, 0.456, 0.406],\n std: [0.229, 0.224, 0.225],\n channelFormat: 'CHW',\n });\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setLabels(labels: string[]): void {\n this.labels = labels;\n }\n\n override async run(\n input: ImageInput | ImageInput[],\n options?: ObjectDetectionOptions\n ): Promise<Detection[]> {\n await this.initialize();\n const tensorInputs = await this.preprocess(input);\n const outputs = await this.runModelInference(tensorInputs);\n return this.postprocess(outputs, options);\n }\n\n protected async preprocess(input: ImageInput | ImageInput[]): Promise<EdgeFlowTensor[]> {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (inputs.length === 1) {\n const tensor = await this.preprocessor.process(inputs[0]!);\n return [new EdgeFlowTensor(\n tensor.toFloat32Array(),\n [1, ...tensor.shape],\n 'float32'\n )];\n }\n\n return [await this.preprocessor.processBatch(inputs)];\n }\n\n private async runModelInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlowTensor[]> {\n const outputs = await runInference(this.onnxModel!, inputs);\n return outputs as EdgeFlowTensor[];\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<Detection[]> {\n const opts = options as ObjectDetectionOptions ?? {};\n const threshold = opts.threshold ?? 0.5;\n const topK = opts.topK ?? 100;\n const nms = opts.nms ?? true;\n const iouThreshold = opts.iouThreshold ?? 0.5;\n\n if (!outputs[0]) {\n return [];\n }\n\n const outputData = outputs[0].toFloat32Array();\n const shape = [...outputs[0].shape] as number[];\n\n const detections = this.parseDetections(outputData, shape, threshold);\n\n let filtered = nms ? this.nonMaxSuppression(detections, iouThreshold) : detections;\n\n filtered.sort((a, b) => b.score - a.score);\n filtered = filtered.slice(0, topK);\n\n return filtered;\n }\n\n private parseDetections(\n data: Float32Array,\n shape: number[],\n threshold: number\n ): Detection[] {\n const detections: Detection[] = [];\n\n const numBoxes = shape[1] ?? 0;\n const boxSize = shape[2] ?? 0;\n\n if (boxSize >= 5) {\n const numClasses = boxSize - 5;\n\n for (let i = 0; i < numBoxes; i++) {\n const offset = i * boxSize;\n const objectness = data[offset + 4] ?? 0;\n\n if (objectness < threshold) continue;\n\n let maxClassScore = 0;\n let maxClassIdx = 0;\n\n for (let c = 0; c < numClasses; c++) {\n const score = data[offset + 5 + c] ?? 0;\n if (score > maxClassScore) {\n maxClassScore = score;\n maxClassIdx = c;\n }\n }\n\n const confidence = objectness * maxClassScore;\n if (confidence < threshold) continue;\n\n const x = data[offset] ?? 0;\n const y = data[offset + 1] ?? 0;\n const w = data[offset + 2] ?? 0;\n const h = data[offset + 3] ?? 0;\n\n detections.push({\n label: this.labels[maxClassIdx] ?? `class_${maxClassIdx}`,\n score: confidence,\n classId: maxClassIdx,\n box: {\n x: Math.max(0, x - w / 2),\n y: Math.max(0, y - h / 2),\n width: w,\n height: h,\n },\n boxNormalized: {\n x: Math.max(0, x - w / 2),\n y: Math.max(0, y - h / 2),\n width: w,\n height: h,\n },\n });\n }\n } else if (boxSize === 4) {\n for (let i = 0; i < numBoxes; i++) {\n const offset = i * boxSize;\n const x1 = data[offset] ?? 0;\n const y1 = data[offset + 1] ?? 0;\n const x2 = data[offset + 2] ?? 0;\n const y2 = data[offset + 3] ?? 0;\n\n detections.push({\n label: this.labels[0] ?? 'object',\n score: 1.0,\n classId: 0,\n box: {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n },\n boxNormalized: {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n },\n });\n }\n }\n\n return detections;\n }\n\n private nonMaxSuppression(\n detections: Detection[],\n iouThreshold: number\n ): Detection[] {\n if (detections.length === 0) return [];\n\n const sorted = [...detections].sort((a, b) => b.score - a.score);\n const selected: Detection[] = [];\n const active = new Array(sorted.length).fill(true);\n\n for (let i = 0; i < sorted.length; i++) {\n if (!active[i]) continue;\n\n const current = sorted[i]!;\n selected.push(current);\n\n for (let j = i + 1; j < sorted.length; j++) {\n if (!active[j]) continue;\n\n const other = sorted[j]!;\n if (current.classId !== other.classId) continue;\n\n const iou = this.computeIoU(current.box, other.box);\n if (iou > iouThreshold) {\n active[j] = false;\n }\n }\n }\n\n return selected;\n }\n\n private computeIoU(a: BoundingBox, b: BoundingBox): number {\n const xOverlap = Math.max(0,\n Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x)\n );\n const yOverlap = Math.max(0,\n Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y)\n );\n\n const intersection = xOverlap * yOverlap;\n const aArea = a.width * a.height;\n const bArea = b.width * b.height;\n const union = aArea + bArea - intersection;\n\n return union > 0 ? intersection / union : 0;\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createObjectDetectionPipeline(\n config?: PipelineConfig,\n labels?: string[]\n): ObjectDetectionPipeline {\n return new ObjectDetectionPipeline(config, labels);\n}\n\nregisterPipeline('object-detection', (config) => new ObjectDetectionPipeline(config));\n", "/**\n * edgeFlow.js - Automatic Speech Recognition Pipeline\n * \n * Transcribe audio to text using Whisper ONNX models (encoder + decoder).\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { AudioPreprocessor, type AudioInput } from '../utils/preprocessor.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInference, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (Whisper-tiny, quantized encoder + decoder)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n encoder: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/onnx/encoder_model_quantized.onnx',\n decoder: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/onnx/decoder_model_merged_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/whisper-tiny/resolve/main/tokenizer.json',\n};\n\n// Whisper special tokens\nconst SOT_TOKEN = 50258; // <|startoftranscript|>\nconst TRANSLATE_TOKEN = 50358; // <|translate|>\nconst TRANSCRIBE_TOKEN = 50359; // <|transcribe|>\nconst EOT_TOKEN = 50257; // <|endoftext|>\nconst NO_TIMESTAMPS_TOKEN = 50363; // <|notimestamps|>\nconst EN_TOKEN = 50259; // <|en|>\n\nconst MAX_DECODER_TOKENS = 448;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ASROptions extends PipelineOptions {\n language?: string;\n task?: 'transcribe' | 'translate';\n returnTimestamps?: boolean | 'word' | 'chunk';\n maxDuration?: number;\n chunkDuration?: number;\n chunkOverlap?: number;\n}\n\nexport interface WordTimestamp {\n word: string;\n start: number;\n end: number;\n confidence?: number;\n}\n\nexport interface ChunkTimestamp {\n text: string;\n start: number;\n end: number;\n}\n\nexport interface ASRResult extends PipelineResult {\n text: string;\n language?: string;\n words?: WordTimestamp[];\n chunks?: ChunkTimestamp[];\n}\n\n// ============================================================================\n// ASR Pipeline\n// ============================================================================\n\nexport class AutomaticSpeechRecognitionPipeline extends BasePipeline<AudioInput | AudioInput[], ASRResult | ASRResult[]> {\n private audioPreprocessor: AudioPreprocessor;\n private tokenizer: Tokenizer | null = null;\n private encoderModel: LoadedModel | null = null;\n private decoderModel: LoadedModel | null = null;\n private encoderUrl: string;\n private decoderUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'automatic-speech-recognition',\n model: 'default',\n });\n\n this.encoderUrl = DEFAULT_MODELS.encoder;\n this.decoderUrl = DEFAULT_MODELS.decoder;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n\n this.audioPreprocessor = new AudioPreprocessor({\n sampleRate: 16000,\n nMels: 80,\n nFft: 400,\n hopLength: 160,\n maxDuration: 30,\n });\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.encoderModel) {\n const data = await loadModelData(this.encoderUrl, { cache: this.config.cache ?? true });\n this.encoderModel = await loadModelFromBuffer(data);\n }\n\n if (!this.decoderModel) {\n const data = await loadModelData(this.decoderUrl, { cache: this.config.cache ?? true });\n this.decoderModel = await loadModelFromBuffer(data);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n override async run(\n input: AudioInput | AudioInput[],\n options?: PipelineOptions\n ): Promise<ASRResult | ASRResult[]> {\n await this.initialize();\n\n const isBatch = Array.isArray(input);\n const inputs = isBatch ? input : [input];\n const opts = options as ASROptions ?? {};\n\n const results: ASRResult[] = [];\n for (const audio of inputs) {\n const result = await this.transcribeSingle(audio, opts);\n results.push(result);\n }\n\n return isBatch ? results : results[0]!;\n }\n\n private async transcribeSingle(audio: AudioInput, options: ASROptions): Promise<ASRResult> {\n const startTime = performance.now();\n\n // 1. Preprocess audio \u2192 mel spectrogram\n const melTensor = await this.audioPreprocessor.process(audio);\n const melInput = new EdgeFlowTensor(\n melTensor.toFloat32Array(),\n [1, ...melTensor.shape],\n 'float32'\n );\n\n // 2. Run encoder\n const encoderOutputs = await runInference(this.encoderModel!, [melInput]);\n const encoderHidden = encoderOutputs[0] as EdgeFlowTensor;\n\n // 3. Autoregressive decoder loop\n const task = options.task ?? 'transcribe';\n const initialTokens = this.buildInitialTokens(task, options.language);\n\n const generatedTokens = await this.autoregressiveDecode(\n encoderHidden,\n initialTokens,\n );\n\n // 4. Decode tokens to text\n const text = this.tokenizer!.decode(generatedTokens, true);\n\n const result: ASRResult = {\n text: text.trim(),\n processingTime: performance.now() - startTime,\n };\n\n if (options.returnTimestamps) {\n result.chunks = this.extractTimestamps(generatedTokens, text);\n }\n\n return result;\n }\n\n private buildInitialTokens(task: 'transcribe' | 'translate', language?: string): number[] {\n const tokens = [SOT_TOKEN];\n tokens.push(language ? this.getLanguageToken(language) : EN_TOKEN);\n tokens.push(task === 'translate' ? TRANSLATE_TOKEN : TRANSCRIBE_TOKEN);\n tokens.push(NO_TIMESTAMPS_TOKEN);\n return tokens;\n }\n\n private getLanguageToken(language: string): number {\n // Whisper language tokens start at 50259 for English\n const langMap: Record<string, number> = {\n en: 50259, zh: 50260, de: 50261, es: 50262, ru: 50263,\n ko: 50264, fr: 50265, ja: 50266, pt: 50267, tr: 50268,\n pl: 50269, ca: 50270, nl: 50271, ar: 50272, sv: 50273,\n it: 50274, id: 50275, hi: 50276, fi: 50277, vi: 50278,\n };\n return langMap[language.toLowerCase()] ?? EN_TOKEN;\n }\n\n /**\n * Autoregressive decoder loop similar to text-generation.\n * Feeds encoder hidden states + growing token sequence to decoder.\n */\n private async autoregressiveDecode(\n encoderHidden: EdgeFlowTensor,\n initialTokens: number[],\n ): Promise<number[]> {\n const tokens = [...initialTokens];\n\n for (let step = 0; step < MAX_DECODER_TOKENS; step++) {\n const decoderInputIds = new EdgeFlowTensor(\n BigInt64Array.from(tokens.map(t => BigInt(t))),\n [1, tokens.length],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', decoderInputIds);\n namedInputs.set('encoder_hidden_states', encoderHidden);\n\n const decoderOutputs = await runInferenceNamed(this.decoderModel!, namedInputs);\n const logits = (decoderOutputs[0] as EdgeFlowTensor).toFloat32Array();\n\n // Get logits for the last token position\n const vocabSize = logits.length / tokens.length;\n const lastTokenLogits = logits.slice((tokens.length - 1) * vocabSize);\n\n // Greedy: argmax\n let bestId = 0;\n let bestVal = lastTokenLogits[0] ?? -Infinity;\n for (let i = 1; i < lastTokenLogits.length; i++) {\n if ((lastTokenLogits[i] ?? -Infinity) > bestVal) {\n bestVal = lastTokenLogits[i] ?? -Infinity;\n bestId = i;\n }\n }\n\n if (bestId === EOT_TOKEN) break;\n\n tokens.push(bestId);\n }\n\n // Strip initial tokens to return only generated tokens\n return tokens.slice(initialTokens.length);\n }\n\n private extractTimestamps(\n _tokenIds: number[],\n text: string\n ): ChunkTimestamp[] {\n // Simplified timestamp extraction: split by punctuation\n const words = text.split(/\\s+/).filter(w => w.length > 0);\n const chunks: ChunkTimestamp[] = [];\n\n const wordsPerSecond = 2.5;\n let chunkText = '';\n let chunkStart = 0;\n\n for (let i = 0; i < words.length; i++) {\n chunkText += (chunkText ? ' ' : '') + words[i];\n\n if ((i + 1) % 5 === 0 || i === words.length - 1) {\n const duration = chunkText.split(/\\s+/).length / wordsPerSecond;\n chunks.push({\n text: chunkText,\n start: chunkStart,\n end: chunkStart + duration,\n });\n chunkStart = chunkStart + duration;\n chunkText = '';\n }\n }\n\n return chunks;\n }\n\n async processLongAudio(\n audio: AudioInput,\n options: ASROptions = {}\n ): Promise<ASRResult> {\n const chunkDuration = options.chunkDuration ?? 30;\n const chunkOverlap = options.chunkOverlap ?? 5;\n\n const rawTensor = await this.audioPreprocessor.processRaw(audio);\n const audioData = rawTensor.toFloat32Array();\n const sampleRate = 16000;\n\n const chunkSamples = chunkDuration * sampleRate;\n const overlapSamples = chunkOverlap * sampleRate;\n const stepSamples = chunkSamples - overlapSamples;\n\n const chunks: ASRResult[] = [];\n\n for (let start = 0; start < audioData.length; start += stepSamples) {\n const end = Math.min(start + chunkSamples, audioData.length);\n const chunkAudio = audioData.slice(start, end);\n\n const chunkResult = await this.run(\n new Float32Array(chunkAudio),\n options\n ) as ASRResult;\n\n if (chunkResult.chunks) {\n const timeOffset = start / sampleRate;\n chunkResult.chunks = chunkResult.chunks.map(c => ({\n ...c,\n start: c.start + timeOffset,\n end: c.end + timeOffset,\n }));\n }\n\n chunks.push(chunkResult);\n }\n\n const mergedText = chunks.map(c => c.text).join(' ');\n const mergedChunks = chunks.flatMap(c => c.chunks ?? []);\n\n return {\n text: mergedText,\n chunks: mergedChunks,\n };\n }\n\n protected async preprocess(input: AudioInput | AudioInput[]): Promise<EdgeFlowTensor[]> {\n const inputs = Array.isArray(input) ? input : [input];\n\n const tensors = await Promise.all(\n inputs.map(audio => this.audioPreprocessor.process(audio))\n );\n\n if (tensors.length === 1) {\n const t = tensors[0]!;\n return [new EdgeFlowTensor(\n t.toFloat32Array(),\n [1, ...t.shape],\n 'float32'\n )];\n }\n\n return tensors;\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n options?: PipelineOptions\n ): Promise<ASRResult | ASRResult[]> {\n const opts = options as ASROptions ?? {};\n const returnTimestamps = opts.returnTimestamps ?? false;\n\n if (!outputs[0]) {\n return { text: '' };\n }\n\n const outputData = outputs[0].toFloat32Array();\n const shape = outputs[0].shape;\n\n const text = this.decodeOutput(outputData, shape);\n\n const result: ASRResult = { text };\n\n if (returnTimestamps) {\n result.chunks = this.extractTimestamps([], text);\n }\n\n return result;\n }\n\n private decodeOutput(data: Float32Array, shape: readonly number[]): string {\n const seqLen = shape[1] ?? data.length;\n const vocabSize = shape[2] ?? 1;\n\n const tokenIds: number[] = [];\n\n if (vocabSize > 1) {\n for (let i = 0; i < seqLen; i++) {\n const offset = i * vocabSize;\n let maxIdx = 0;\n let maxVal = data[offset] ?? -Infinity;\n\n for (let j = 1; j < vocabSize; j++) {\n if ((data[offset + j] ?? -Infinity) > maxVal) {\n maxVal = data[offset + j] ?? -Infinity;\n maxIdx = j;\n }\n }\n tokenIds.push(maxIdx);\n }\n } else {\n for (let i = 0; i < data.length; i++) {\n tokenIds.push(Math.round(data[i] ?? 0));\n }\n }\n\n if (this.tokenizer) {\n return this.tokenizer.decode(tokenIds, true);\n }\n\n return tokenIds.join(' ');\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createASRPipeline(config?: PipelineConfig): AutomaticSpeechRecognitionPipeline {\n return new AutomaticSpeechRecognitionPipeline(config);\n}\n\nregisterPipeline('automatic-speech-recognition', (config) => new AutomaticSpeechRecognitionPipeline(config));\n", "/**\n * edgeFlow.js - Zero-shot Classification Pipeline\n * \n * Classify text into any set of labels without fine-tuning,\n * using a real NLI (Natural Language Inference) model.\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (DistilBART fine-tuned on MNLI)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/nli-deberta-v3-small/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/nli-deberta-v3-small/resolve/main/tokenizer.json',\n};\n\n// NLI output indices: [contradiction, neutral, entailment]\nconst ENTAILMENT_IDX = 2;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ZeroShotClassificationOptions extends PipelineOptions {\n multiLabel?: boolean;\n hypothesisTemplate?: string;\n}\n\nexport interface ZeroShotClassificationResult extends PipelineResult {\n sequence: string;\n labels: string[];\n scores: number[];\n}\n\nexport interface ZeroShotInput {\n text: string | string[];\n candidateLabels: string[];\n}\n\n// ============================================================================\n// Zero-shot Classification Pipeline\n// ============================================================================\n\nexport class ZeroShotClassificationPipeline extends BasePipeline<\n ZeroShotInput,\n ZeroShotClassificationResult | ZeroShotClassificationResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private hypothesisTemplate: string = 'This text is about {label}.';\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'zero-shot-classification',\n model: 'default',\n });\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n async classify(\n text: string | string[],\n candidateLabels: string[],\n options?: ZeroShotClassificationOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n return this.run({ text, candidateLabels }, options);\n }\n\n override async run(\n input: ZeroShotInput,\n options?: PipelineOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n await this.initialize();\n\n const { text, candidateLabels } = input;\n const opts = options as ZeroShotClassificationOptions ?? {};\n const texts = Array.isArray(text) ? text : [text];\n const template = opts.hypothesisTemplate ?? this.hypothesisTemplate;\n const multiLabel = opts.multiLabel ?? false;\n\n const results = await Promise.all(\n texts.map(t => this.classifySingle(t, candidateLabels, template, multiLabel))\n );\n\n return Array.isArray(text) ? results : results[0]!;\n }\n\n private async classifySingle(\n text: string,\n candidateLabels: string[],\n template: string,\n multiLabel: boolean\n ): Promise<ZeroShotClassificationResult> {\n const startTime = performance.now();\n\n const hypotheses = candidateLabels.map(label =>\n template.replace('{label}', label)\n );\n\n const scores: number[] = [];\n\n for (const hypothesis of hypotheses) {\n const score = await this.scoreHypothesis(text, hypothesis);\n scores.push(score);\n }\n\n let normalizedScores: number[];\n\n if (multiLabel) {\n normalizedScores = scores.map(s => 1 / (1 + Math.exp(-s)));\n } else {\n const tensor = new EdgeFlowTensor(new Float32Array(scores), [scores.length], 'float32');\n normalizedScores = Array.from(softmax(tensor).toFloat32Array());\n }\n\n const indexed = candidateLabels.map((label, i) => ({\n label,\n score: normalizedScores[i] ?? 0,\n }));\n indexed.sort((a, b) => b.score - a.score);\n\n return {\n sequence: text,\n labels: indexed.map(i => i.label),\n scores: indexed.map(i => i.score),\n processingTime: performance.now() - startTime,\n };\n }\n\n /**\n * Score a single hypothesis using the real NLI ONNX model.\n * Returns the entailment logit.\n */\n private async scoreHypothesis(premise: string, hypothesis: string): Promise<number> {\n const encoded = this.tokenizer!.encode(premise, {\n textPair: hypothesis,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n returnAttentionMask: true,\n });\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n );\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputIds);\n namedInputs.set('attention_mask', attentionMask);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n const logits = (outputs[0] as EdgeFlowTensor).toFloat32Array();\n\n // Return entailment logit (index 2 in [contradiction, neutral, entailment])\n return logits[ENTAILMENT_IDX] ?? 0;\n }\n\n protected async preprocess(\n input: ZeroShotInput\n ): Promise<EdgeFlowTensor[]> {\n const { text, candidateLabels } = input;\n const firstText = Array.isArray(text) ? text[0] ?? '' : text;\n const firstLabel = candidateLabels[0] ?? '';\n\n const encoded = this.tokenizer!.encode(firstText, {\n textPair: this.hypothesisTemplate.replace('{label}', firstLabel),\n addSpecialTokens: true,\n maxLength: 512,\n });\n\n return [new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n )];\n }\n\n protected async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<ZeroShotClassificationResult | ZeroShotClassificationResult[]> {\n return {\n sequence: '',\n labels: [],\n scores: [],\n };\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createZeroShotClassificationPipeline(\n config?: PipelineConfig\n): ZeroShotClassificationPipeline {\n return new ZeroShotClassificationPipeline(config);\n}\n\nregisterPipeline('zero-shot-classification', (config) => new ZeroShotClassificationPipeline(config));\n", "/**\n * edgeFlow.js - Question Answering Pipeline\n * \n * Extract answers from context given a question using real ONNX QA models.\n */\n\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { EdgeFlowTensor, softmax } from '../core/tensor.js';\nimport { PipelineConfig, PipelineOptions, LoadedModel } from '../core/types.js';\nimport { Tokenizer } from '../utils/tokenizer.js';\nimport { loadModelData } from '../utils/model-loader.js';\nimport { loadModelFromBuffer, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model (DistilBERT fine-tuned on SQuAD)\n// ============================================================================\n\nconst DEFAULT_MODELS = {\n model: 'https://huggingface.co/Xenova/distilbert-base-cased-distilled-squad/resolve/main/onnx/model_quantized.onnx',\n tokenizer: 'https://huggingface.co/Xenova/distilbert-base-cased-distilled-squad/resolve/main/tokenizer.json',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface QAInput {\n question: string;\n context: string;\n}\n\nexport interface QuestionAnsweringOptions extends PipelineOptions {\n maxAnswerLength?: number;\n maxQuestionLength?: number;\n topK?: number;\n threshold?: number;\n handleImpossible?: boolean;\n}\n\nexport interface QuestionAnsweringResult extends PipelineResult {\n answer: string;\n score: number;\n start: number;\n end: number;\n}\n\n// ============================================================================\n// Question Answering Pipeline\n// ============================================================================\n\nexport class QuestionAnsweringPipeline extends BasePipeline<\n QAInput | QAInput[],\n QuestionAnsweringResult | QuestionAnsweringResult[]\n> {\n private tokenizer: Tokenizer | null = null;\n private onnxModel: LoadedModel | null = null;\n private modelUrl: string;\n private tokenizerUrl: string;\n\n constructor(config?: PipelineConfig) {\n super(config ?? {\n task: 'question-answering',\n model: 'default',\n });\n this.modelUrl = (config?.model && config.model !== 'default') ? config.model : DEFAULT_MODELS.model;\n this.tokenizerUrl = DEFAULT_MODELS.tokenizer;\n }\n\n override async initialize(): Promise<void> {\n await super.initialize();\n\n if (!this.tokenizer) {\n this.tokenizer = await Tokenizer.fromUrl(this.tokenizerUrl);\n }\n\n if (!this.onnxModel) {\n const modelData = await loadModelData(this.modelUrl, { cache: this.config.cache ?? true });\n this.onnxModel = await loadModelFromBuffer(modelData);\n }\n }\n\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n override async run(\n input: QAInput | QAInput[],\n options?: QuestionAnsweringOptions\n ): Promise<QuestionAnsweringResult | QuestionAnsweringResult[]> {\n await this.initialize();\n\n const inputs = Array.isArray(input) ? input : [input];\n const results = await Promise.all(\n inputs.map(i => this.answerQuestion(i, options ?? {}))\n );\n\n return Array.isArray(input) ? results : results[0]!;\n }\n\n private async answerQuestion(\n input: QAInput,\n options: QuestionAnsweringOptions\n ): Promise<QuestionAnsweringResult> {\n const startTime = performance.now();\n const { question, context } = input;\n const maxAnswerLength = options.maxAnswerLength ?? 30;\n\n // No padding \u2014 QA runs one example at a time and padding wastes compute\n const encoded = this.tokenizer!.encode(question, {\n textPair: context,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n padding: 'do_not_pad',\n returnAttentionMask: true,\n returnTokenTypeIds: true,\n });\n\n const seqLen = encoded.inputIds.length;\n\n const inputIds = new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, seqLen],\n 'int64'\n );\n const attentionMask = new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, seqLen],\n 'int64'\n );\n\n const namedInputs = new Map<string, EdgeFlowTensor>();\n namedInputs.set('input_ids', inputIds);\n namedInputs.set('attention_mask', attentionMask);\n\n const outputs = await runInferenceNamed(this.onnxModel!, namedInputs);\n\n if (outputs.length < 2) {\n return { answer: '', score: 0, start: 0, end: 0, processingTime: performance.now() - startTime };\n }\n\n const startLogits = (outputs[0] as EdgeFlowTensor).toFloat32Array();\n const endLogits = (outputs[1] as EdgeFlowTensor).toFloat32Array();\n\n const startProbs = softmax(new EdgeFlowTensor(new Float32Array(startLogits), [seqLen], 'float32')).toFloat32Array();\n const endProbs = softmax(new EdgeFlowTensor(new Float32Array(endLogits), [seqLen], 'float32')).toFloat32Array();\n\n // Constrain answer span to the context portion only (tokenTypeIds === 1).\n // tokenTypeIds: 0 = question tokens ([CLS], question, [SEP]), 1 = context tokens.\n const typeIds = encoded.tokenTypeIds ?? new Array(seqLen).fill(1);\n // Find where context starts (first index with typeId === 1)\n const contextStart = typeIds.findIndex(t => t === 1);\n const spanStart = contextStart >= 0 ? contextStart : 0;\n const spanEnd = seqLen - 1; // last non-padding position\n\n let bestStartIdx = spanStart;\n let bestEndIdx = spanStart;\n let bestScore = -Infinity;\n\n for (let s = spanStart; s <= spanEnd; s++) {\n for (let e = s; e < Math.min(s + maxAnswerLength, spanEnd + 1); e++) {\n const score = (startProbs[s] ?? 0) * (endProbs[e] ?? 0);\n if (score > bestScore) {\n bestScore = score;\n bestStartIdx = s;\n bestEndIdx = e;\n }\n }\n }\n\n // Decode the answer span directly from token IDs in the context portion\n const answerTokenIds = encoded.inputIds.slice(bestStartIdx, bestEndIdx + 1);\n const answer = this.tokenizer!.decode(answerTokenIds, true);\n\n return {\n answer: answer || '',\n score: Math.max(0, bestScore),\n start: bestStartIdx,\n end: bestEndIdx,\n processingTime: performance.now() - startTime,\n };\n }\n\n\n protected async preprocess(input: QAInput | QAInput[]): Promise<EdgeFlowTensor[]> {\n const qaInput = Array.isArray(input) ? input[0]! : input;\n const encoded = this.tokenizer!.encode(qaInput.question, {\n textPair: qaInput.context,\n addSpecialTokens: true,\n maxLength: 512,\n truncation: true,\n returnAttentionMask: true,\n returnTokenTypeIds: true,\n });\n\n return [\n new EdgeFlowTensor(\n BigInt64Array.from(encoded.inputIds.map(id => BigInt(id))),\n [1, encoded.inputIds.length],\n 'int64'\n ),\n new EdgeFlowTensor(\n BigInt64Array.from(encoded.attentionMask.map(m => BigInt(m))),\n [1, encoded.attentionMask.length],\n 'int64'\n ),\n ];\n }\n\n protected async postprocess(\n outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<QuestionAnsweringResult | QuestionAnsweringResult[]> {\n if (outputs.length < 2) {\n return { answer: '', score: 0, start: 0, end: 0 };\n }\n\n const startLogits = outputs[0]!.toFloat32Array();\n const endLogits = outputs[1]!.toFloat32Array();\n const seqLen = startLogits.length;\n\n const startProbs = softmax(new EdgeFlowTensor(startLogits, [seqLen], 'float32')).toFloat32Array();\n const endProbs = softmax(new EdgeFlowTensor(endLogits, [seqLen], 'float32')).toFloat32Array();\n\n let bestStart = 0;\n let bestEnd = 0;\n let bestScore = 0;\n\n for (let start = 0; start < seqLen; start++) {\n for (let end = start; end < Math.min(start + 30, seqLen); end++) {\n const score = (startProbs[start] ?? 0) * (endProbs[end] ?? 0);\n if (score > bestScore) {\n bestScore = score;\n bestStart = start;\n bestEnd = end;\n }\n }\n }\n\n return {\n answer: '',\n score: bestScore,\n start: bestStart,\n end: bestEnd,\n };\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createQuestionAnsweringPipeline(\n config?: PipelineConfig\n): QuestionAnsweringPipeline {\n return new QuestionAnsweringPipeline(config);\n}\n\nregisterPipeline('question-answering', (config) => new QuestionAnsweringPipeline(config));\n", "/**\n * edgeFlow.js - Image Segmentation Pipeline\n * \n * Interactive image segmentation using SAM (Segment Anything Model).\n * Supports point prompts and bounding box prompts.\n */\n\nimport {\n PipelineConfig,\n PipelineOptions,\n LoadedModel,\n} from '../core/types.js';\nimport { EdgeFlowTensor } from '../core/tensor.js';\nimport { BasePipeline, PipelineResult, registerPipeline } from './base.js';\nimport { loadModel, loadModelFromBuffer, runInference, runInferenceNamed } from '../core/runtime.js';\n\n// ============================================================================\n// Default Model URLs (SlimSAM - quantized for browser)\n// ============================================================================\n\nconst DEFAULT_SAM_MODELS = {\n encoder: 'https://huggingface.co/Xenova/slimsam-77-uniform/resolve/main/onnx/vision_encoder_quantized.onnx',\n decoder: 'https://huggingface.co/Xenova/slimsam-77-uniform/resolve/main/onnx/prompt_encoder_mask_decoder_quantized.onnx',\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Point prompt for segmentation\n */\nexport interface PointPrompt {\n /** X coordinate (0-1 normalized) */\n x: number;\n /** Y coordinate (0-1 normalized) */\n y: number;\n /** 1 for foreground (include), 0 for background (exclude) */\n label: 0 | 1;\n}\n\n/**\n * Box prompt for segmentation\n */\nexport interface BoxPrompt {\n /** Top-left X (0-1 normalized) */\n x1: number;\n /** Top-left Y (0-1 normalized) */\n y1: number;\n /** Bottom-right X (0-1 normalized) */\n x2: number;\n /** Bottom-right Y (0-1 normalized) */\n y2: number;\n}\n\n/**\n * Model loading progress callback\n */\nexport interface ModelLoadProgress {\n /** Model name (encoder or decoder) */\n model: 'encoder' | 'decoder';\n /** Bytes loaded */\n loaded: number;\n /** Total bytes */\n total: number;\n /** Progress percentage (0-100) */\n progress: number;\n}\n\n/**\n * Segmentation options\n */\nexport interface ImageSegmentationOptions extends PipelineOptions {\n /** Point prompts */\n points?: PointPrompt[];\n /** Box prompts */\n boxes?: BoxPrompt[];\n /** Return all masks or just the best one */\n returnAllMasks?: boolean;\n /** Mask threshold (0-1) */\n maskThreshold?: number;\n}\n\n/**\n * Segmentation result\n */\nexport interface ImageSegmentationResult extends PipelineResult {\n /** Segmentation mask (Uint8Array, 0 or 255) */\n mask: Uint8Array;\n /** Mask width */\n width: number;\n /** Mask height */\n height: number;\n /** Confidence score */\n score: number;\n /** All masks if returnAllMasks is true */\n allMasks?: Array<{ mask: Uint8Array; score: number }>;\n}\n\n/**\n * Image input types\n */\nexport type ImageInput =\n | HTMLImageElement\n | HTMLCanvasElement\n | ImageBitmap\n | ImageData\n | string; // URL or base64\n\n// ============================================================================\n// Image Segmentation Pipeline\n// ============================================================================\n\n/**\n * ImageSegmentationPipeline - Interactive image segmentation\n * \n * Uses SAM-style models for point/box prompted segmentation.\n * \n * @example\n * ```typescript\n * const segmenter = createImageSegmentationPipeline();\n * \n * // Load models with progress callback\n * await segmenter.loadModels((progress) => {\n * console.log(`Loading ${progress.model}: ${progress.progress}%`);\n * });\n * \n * // Set image and segment\n * await segmenter.setImage(imageElement);\n * const result = await segmenter.segment({\n * points: [{ x: 0.5, y: 0.5, label: 1 }]\n * });\n * ```\n */\nexport class ImageSegmentationPipeline extends BasePipeline<\n ImageInput,\n ImageSegmentationResult\n> {\n private encoderModel: LoadedModel | null = null;\n private decoderModel: LoadedModel | null = null;\n private imageEmbedding: EdgeFlowTensor | null = null;\n private imagePositionalEmbedding: EdgeFlowTensor | null = null;\n private currentImageSize: { width: number; height: number } | null = null;\n private resizedImageSize: { width: number; height: number } | null = null;\n private inputSize: number = 1024; // SAM default input size\n private modelsLoaded: boolean = false;\n \n // Custom model URLs\n private encoderUrl: string;\n private decoderUrl: string;\n\n constructor(config: PipelineConfig) {\n super(config);\n this.encoderUrl = DEFAULT_SAM_MODELS.encoder;\n this.decoderUrl = DEFAULT_SAM_MODELS.decoder;\n }\n\n /**\n * Check if models are loaded\n */\n get isModelsLoaded(): boolean {\n return this.modelsLoaded;\n }\n\n /**\n * Set custom model URLs\n */\n setModelUrls(encoder: string, decoder: string): void {\n this.encoderUrl = encoder;\n this.decoderUrl = decoder;\n }\n\n /**\n * Load both encoder and decoder models with progress callback\n */\n async loadModels(\n onProgress?: (progress: ModelLoadProgress) => void\n ): Promise<void> {\n if (this.modelsLoaded) return;\n\n // Load encoder\n onProgress?.({ model: 'encoder', loaded: 0, total: 100, progress: 0 });\n \n const encoderData = await this.fetchModelWithProgress(\n this.encoderUrl,\n (loaded, total) => {\n onProgress?.({\n model: 'encoder',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.encoderModel = await loadModelFromBuffer(encoderData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n\n // Load decoder\n onProgress?.({ model: 'decoder', loaded: 0, total: 100, progress: 0 });\n \n const decoderData = await this.fetchModelWithProgress(\n this.decoderUrl,\n (loaded, total) => {\n onProgress?.({\n model: 'decoder',\n loaded,\n total,\n progress: Math.round((loaded / total) * 100),\n });\n }\n );\n \n this.decoderModel = await loadModelFromBuffer(decoderData, {\n runtime: 'wasm', // Uses ONNXRuntime which auto-detects WebGPU internally\n });\n\n this.modelsLoaded = true;\n }\n\n /**\n * Fetch model with progress tracking\n */\n private async fetchModelWithProgress(\n url: string,\n onProgress: (loaded: number, total: number) => void\n ): Promise<ArrayBuffer> {\n const response = await fetch(url);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch model: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n if (!response.body) {\n // Fallback if no streaming support\n const buffer = await response.arrayBuffer();\n onProgress(buffer.byteLength, buffer.byteLength);\n return buffer;\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let loaded = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n \n if (done) break;\n \n chunks.push(value);\n loaded += value.length;\n onProgress(loaded, total || loaded);\n }\n\n // Combine chunks into ArrayBuffer\n const buffer = new Uint8Array(loaded);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.length;\n }\n\n return buffer.buffer;\n }\n\n /**\n * Initialize pipeline (override to skip default model loading)\n */\n override async initialize(): Promise<void> {\n if (this.isReady) return;\n // Don't call super.initialize() - we handle model loading separately\n this.isReady = true;\n }\n\n /**\n * Load encoder model (processes the image once)\n */\n async loadEncoder(modelUrl: string): Promise<void> {\n this.encoderModel = await loadModel(modelUrl, {\n runtime: 'wasm',\n });\n }\n\n /**\n * Load decoder model (processes prompts to generate masks)\n */\n async loadDecoder(modelUrl: string): Promise<void> {\n this.decoderModel = await loadModel(modelUrl, {\n runtime: 'wasm',\n });\n }\n\n /**\n * Set and encode the image (call once per image)\n */\n async setImage(image: ImageInput): Promise<void> {\n if (!this.modelsLoaded) {\n throw new Error('Models not loaded. Call loadModels() first.');\n }\n\n // Get image data\n const imageData = await this.loadImage(image);\n this.currentImageSize = {\n width: imageData.width,\n height: imageData.height,\n };\n\n // Preprocess image for SAM\n const { tensor: inputTensor, resizedSize } = this.preprocessImage(imageData);\n this.resizedImageSize = resizedSize;\n\n // Run encoder\n if (this.encoderModel) {\n const outputs = await runInference(this.encoderModel, [inputTensor]);\n // SlimSAM encoder outputs: [image_embeddings, image_positional_embeddings]\n this.imageEmbedding = outputs[0] as EdgeFlowTensor;\n this.imagePositionalEmbedding = outputs[1] as EdgeFlowTensor;\n console.log('[SAM] Encoder outputs:', outputs.length);\n console.log('[SAM] image_embeddings shape:', this.imageEmbedding.shape);\n if (this.imagePositionalEmbedding) {\n console.log('[SAM] image_positional_embeddings shape:', this.imagePositionalEmbedding.shape);\n }\n } else {\n throw new Error('Encoder model not loaded');\n }\n }\n\n /**\n * Segment the image with given prompts\n */\n async segment(options: ImageSegmentationOptions = {}): Promise<ImageSegmentationResult> {\n if (!this.imageEmbedding || !this.currentImageSize || !this.resizedImageSize) {\n throw new Error('No image set. Call setImage() first.');\n }\n\n if (!this.decoderModel) {\n throw new Error('Decoder model not loaded');\n }\n\n const startTime = performance.now();\n const { points = [], boxes = [], maskThreshold = 0.0, returnAllMasks = false } = options;\n\n // Prepare inputs for decoder\n const decoderInputs = this.prepareDecoderInputs(points, boxes);\n \n // Add image embeddings to inputs\n decoderInputs.set('image_embeddings', this.imageEmbedding!);\n \n // Add positional embeddings (required by SlimSAM)\n if (this.imagePositionalEmbedding) {\n decoderInputs.set('image_positional_embeddings', this.imagePositionalEmbedding);\n } else {\n throw new Error('image_positional_embeddings not available from encoder');\n }\n\n // Run decoder model with named inputs\n const outputs = await runInferenceNamed(this.decoderModel, decoderInputs);\n\n // SAM decoder outputs: [masks, iou_predictions]\n const masks = outputs[0] as EdgeFlowTensor;\n const scores = outputs[1] as EdgeFlowTensor;\n\n // Post-process masks\n const result = this.postprocessMasks(masks, scores, maskThreshold, returnAllMasks);\n result.processingTime = performance.now() - startTime;\n\n return result;\n }\n\n /**\n * Run segmentation (implements BasePipeline interface)\n */\n override async run(\n input: ImageInput,\n options?: ImageSegmentationOptions\n ): Promise<ImageSegmentationResult> {\n await this.setImage(input);\n return this.segment(options);\n }\n\n /**\n * Load image from various sources\n */\n private async loadImage(input: ImageInput): Promise<ImageData> {\n // Handle different input types\n if (typeof input === 'string') {\n // URL or base64\n return this.loadImageFromUrl(input);\n } else if (input instanceof HTMLImageElement) {\n return this.imageElementToImageData(input);\n } else if (input instanceof HTMLCanvasElement) {\n return this.canvasToImageData(input);\n } else if (input instanceof ImageData) {\n return input;\n } else if (typeof ImageBitmap !== 'undefined' && input instanceof ImageBitmap) {\n return this.imageBitmapToImageData(input);\n }\n throw new Error('Unsupported image input type');\n }\n\n /**\n * Load image from URL\n */\n private async loadImageFromUrl(url: string): Promise<ImageData> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = img.width;\n canvas.height = img.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0);\n resolve(ctx.getImageData(0, 0, img.width, img.height));\n };\n img.onerror = reject;\n img.src = url;\n });\n }\n\n /**\n * Convert HTMLImageElement to ImageData\n */\n private imageElementToImageData(img: HTMLImageElement): ImageData {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth || img.width;\n canvas.height = img.naturalHeight || img.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0);\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Convert canvas to ImageData\n */\n private canvasToImageData(canvas: HTMLCanvasElement): ImageData {\n const ctx = canvas.getContext('2d')!;\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Convert ImageBitmap to ImageData\n */\n private imageBitmapToImageData(bitmap: ImageBitmap): ImageData {\n const canvas = document.createElement('canvas');\n canvas.width = bitmap.width;\n canvas.height = bitmap.height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(bitmap, 0, 0);\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n }\n\n /**\n * Preprocess image for SAM\n */\n private preprocessImage(imageData: ImageData): { \n tensor: EdgeFlowTensor; \n resizedSize: { width: number; height: number };\n } {\n const { width, height } = imageData;\n\n // Calculate resize dimensions (longest side = inputSize)\n const scale = this.inputSize / Math.max(width, height);\n const newWidth = Math.round(width * scale);\n const newHeight = Math.round(height * scale);\n\n // Create resized canvas with padding\n const canvas = document.createElement('canvas');\n canvas.width = this.inputSize;\n canvas.height = this.inputSize;\n const ctx = canvas.getContext('2d')!;\n\n // Fill with padding color (SAM uses pixel mean)\n ctx.fillStyle = `rgb(123.675, 116.28, 103.53)`;\n ctx.fillRect(0, 0, this.inputSize, this.inputSize);\n\n // Draw resized image (top-left aligned)\n const tempCanvas = document.createElement('canvas');\n tempCanvas.width = width;\n tempCanvas.height = height;\n const tempCtx = tempCanvas.getContext('2d')!;\n tempCtx.putImageData(imageData, 0, 0);\n ctx.drawImage(tempCanvas, 0, 0, newWidth, newHeight);\n\n // Get pixel data\n const resizedData = ctx.getImageData(0, 0, this.inputSize, this.inputSize);\n\n // Convert to tensor (NCHW format, normalized with ImageNet mean/std)\n const tensorData = new Float32Array(3 * this.inputSize * this.inputSize);\n const mean = [123.675, 116.28, 103.53];\n const std = [58.395, 57.12, 57.375];\n\n for (let i = 0; i < this.inputSize * this.inputSize; i++) {\n const pixelIdx = i * 4;\n tensorData[i] = (resizedData.data[pixelIdx]! - mean[0]!) / std[0]!; // R\n tensorData[this.inputSize * this.inputSize + i] =\n (resizedData.data[pixelIdx + 1]! - mean[1]!) / std[1]!; // G\n tensorData[2 * this.inputSize * this.inputSize + i] =\n (resizedData.data[pixelIdx + 2]! - mean[2]!) / std[2]!; // B\n }\n\n return {\n tensor: new EdgeFlowTensor(tensorData, [1, 3, this.inputSize, this.inputSize], 'float32'),\n resizedSize: { width: newWidth, height: newHeight },\n };\n }\n\n /**\n * Prepare decoder inputs (prompts) for SlimSAM\n * \n * SlimSAM prompt_encoder_mask_decoder expects these named inputs:\n * - image_embeddings: [1, 256, 64, 64]\n * - point_coords: [batch, num_points, 2]\n * - point_labels: [batch, num_points]\n * - mask_input: [batch, 1, 256, 256]\n * - has_mask_input: [batch, 1]\n * - orig_im_size: [2]\n * - position_ids: [batch, num_points]\n */\n private prepareDecoderInputs(\n points: PointPrompt[],\n boxes: BoxPrompt[]\n ): Map<string, EdgeFlowTensor> {\n const { width: resizedW, height: resizedH } = this.resizedImageSize!;\n\n // Scale factors for converting normalized coords to resized image coords\n const scaleX = resizedW;\n const scaleY = resizedH;\n\n const allPoints: number[] = [];\n const allLabels: number[] = [];\n\n // Add point prompts\n for (const point of points) {\n allPoints.push(\n point.x * scaleX,\n point.y * scaleY\n );\n allLabels.push(point.label);\n }\n\n // Add box prompts (as two corner points)\n for (const box of boxes) {\n // Top-left corner (label 2)\n allPoints.push(box.x1 * scaleX, box.y1 * scaleY);\n allLabels.push(2);\n // Bottom-right corner (label 3)\n allPoints.push(box.x2 * scaleX, box.y2 * scaleY);\n allLabels.push(3);\n }\n\n // Default point if no prompts (center of image)\n if (allPoints.length === 0) {\n allPoints.push(resizedW / 2, resizedH / 2);\n allLabels.push(1);\n }\n\n const numPoints = allLabels.length;\n\n const inputs = new Map<string, EdgeFlowTensor>();\n\n // input_points: [1, 1, num_points, 2] - SlimSAM format (float32)\n inputs.set('input_points', new EdgeFlowTensor(\n new Float32Array(allPoints),\n [1, 1, numPoints, 2],\n 'float32'\n ));\n\n // input_labels: [1, 1, num_points] - SlimSAM format (int64)\n inputs.set('input_labels', new EdgeFlowTensor(\n BigInt64Array.from(allLabels.map(l => BigInt(l))),\n [1, 1, numPoints],\n 'int64'\n ));\n\n // Note: image_embeddings and image_positional_embeddings are added in segment()\n // SlimSAM decoder only needs: image_embeddings, image_positional_embeddings, input_points, input_labels\n\n return inputs;\n }\n\n /**\n * Post-process masks from decoder output\n */\n private postprocessMasks(\n masks: EdgeFlowTensor,\n scores: EdgeFlowTensor,\n threshold: number,\n returnAllMasks: boolean\n ): ImageSegmentationResult {\n const { width, height } = this.currentImageSize!;\n const scoresData = scores.toFloat32Array();\n const masksData = masks.toFloat32Array();\n\n // SAM outputs multiple masks (usually 3)\n const numMasks = scoresData.length;\n const maskShape = masks.shape; // [1, num_masks, H, W]\n const maskH = maskShape[2] ?? height;\n const maskW = maskShape[3] ?? width;\n\n // Find best mask by score\n let bestIdx = 0;\n let bestScore = scoresData[0] ?? 0;\n\n for (let i = 1; i < numMasks; i++) {\n if ((scoresData[i] ?? 0) > bestScore) {\n bestScore = scoresData[i] ?? 0;\n bestIdx = i;\n }\n }\n\n // Extract and resize the best mask to original image size\n const outputMask = this.resizeMask(\n masksData, \n bestIdx, \n maskW, \n maskH, \n width, \n height, \n threshold\n );\n\n const result: ImageSegmentationResult = {\n mask: outputMask,\n width,\n height,\n score: bestScore,\n };\n\n if (returnAllMasks && numMasks > 1) {\n result.allMasks = [];\n for (let m = 0; m < numMasks; m++) {\n const mask = this.resizeMask(\n masksData, \n m, \n maskW, \n maskH, \n width, \n height, \n threshold\n );\n result.allMasks.push({\n mask,\n score: scoresData[m] ?? 0,\n });\n }\n }\n\n return result;\n }\n\n /**\n * Resize mask from model output size to original image size\n */\n private resizeMask(\n masksData: Float32Array,\n maskIdx: number,\n srcW: number,\n srcH: number,\n dstW: number,\n dstH: number,\n threshold: number\n ): Uint8Array {\n const outputMask = new Uint8Array(dstW * dstH);\n const maskOffset = maskIdx * srcW * srcH;\n\n // Bilinear interpolation for resizing\n for (let y = 0; y < dstH; y++) {\n for (let x = 0; x < dstW; x++) {\n // Map to source coordinates\n const srcX = (x / dstW) * srcW;\n const srcY = (y / dstH) * srcH;\n\n // Bilinear interpolation\n const x0 = Math.floor(srcX);\n const x1 = Math.min(x0 + 1, srcW - 1);\n const y0 = Math.floor(srcY);\n const y1 = Math.min(y0 + 1, srcH - 1);\n\n const xFrac = srcX - x0;\n const yFrac = srcY - y0;\n\n const v00 = masksData[maskOffset + y0 * srcW + x0] ?? 0;\n const v01 = masksData[maskOffset + y0 * srcW + x1] ?? 0;\n const v10 = masksData[maskOffset + y1 * srcW + x0] ?? 0;\n const v11 = masksData[maskOffset + y1 * srcW + x1] ?? 0;\n\n const value = \n v00 * (1 - xFrac) * (1 - yFrac) +\n v01 * xFrac * (1 - yFrac) +\n v10 * (1 - xFrac) * yFrac +\n v11 * xFrac * yFrac;\n\n // Apply sigmoid and threshold\n const sigmoid = 1 / (1 + Math.exp(-value));\n outputMask[y * dstW + x] = sigmoid > threshold ? 255 : 0;\n }\n }\n\n return outputMask;\n }\n\n /**\n * Clear the current image embedding\n */\n clearImage(): void {\n this.imageEmbedding = null;\n this.imagePositionalEmbedding = null;\n this.currentImageSize = null;\n this.resizedImageSize = null;\n }\n\n /**\n * Preprocess (required by BasePipeline)\n */\n protected override async preprocess(input: ImageInput): Promise<EdgeFlowTensor[]> {\n const imageData = await this.loadImage(input);\n const { tensor } = this.preprocessImage(imageData);\n return [tensor];\n }\n\n /**\n * Postprocess (required by BasePipeline)\n */\n protected override async postprocess(\n _outputs: EdgeFlowTensor[],\n _options?: PipelineOptions\n ): Promise<ImageSegmentationResult> {\n // This is handled in segment() method\n return {\n mask: new Uint8Array(0),\n width: 0,\n height: 0,\n score: 0,\n };\n }\n\n /**\n * Dispose resources\n */\n override dispose(): void {\n super.dispose();\n this.encoderModel?.dispose();\n this.decoderModel?.dispose();\n this.imageEmbedding = null;\n this.imagePositionalEmbedding = null;\n this.currentImageSize = null;\n this.resizedImageSize = null;\n this.modelsLoaded = false;\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create image segmentation pipeline\n */\nexport function createImageSegmentationPipeline(\n config: Partial<PipelineConfig> = {}\n): ImageSegmentationPipeline {\n return new ImageSegmentationPipeline({\n task: 'image-segmentation',\n model: config.model ?? 'slimsam',\n runtime: config.runtime,\n cache: config.cache ?? true,\n quantization: config.quantization,\n });\n}\n\n// Register pipeline\nregisterPipeline('image-segmentation', (config) => new ImageSegmentationPipeline(config));\n", "/**\n * edgeFlow.js - Pipeline Exports\n */\n\nimport {\n PipelineConfig,\n PipelineTask,\n RuntimeType,\n QuantizationType,\n} from '../core/types.js';\n\nimport { getPluginPipeline } from '../core/plugin.js';\nimport { registerAllBackends } from '../backends/index.js';\n\n// Base\nexport {\n BasePipeline,\n registerPipeline,\n getPipelineFactory,\n SENTIMENT_LABELS,\n EMOTION_LABELS,\n IMAGENET_LABELS,\n type PipelineResult,\n type TextClassificationResult,\n type FeatureExtractionResult,\n type ImageClassificationResult,\n type ObjectDetectionResult,\n} from './base.js';\n\n// Text Classification\nexport {\n TextClassificationPipeline,\n SentimentAnalysisPipeline,\n createTextClassificationPipeline,\n createSentimentAnalysisPipeline,\n type TextClassificationOptions,\n} from './text-classification.js';\n\n// Feature Extraction\nexport {\n FeatureExtractionPipeline,\n createFeatureExtractionPipeline,\n type FeatureExtractionOptions,\n} from './feature-extraction.js';\n\n// Image Classification\nexport {\n ImageClassificationPipeline,\n createImageClassificationPipeline,\n type ImageClassificationOptions,\n type ImageInput,\n} from './image-classification.js';\n\n// Text Generation\nexport {\n TextGenerationPipeline,\n createTextGenerationPipeline,\n type TextGenerationOptions,\n type TextGenerationResult,\n type GenerationStreamEvent,\n type ChatMessage,\n type ChatOptions,\n type ChatTemplateType,\n type LLMLoadProgress,\n} from './text-generation.js';\n\n// Object Detection\nexport {\n ObjectDetectionPipeline,\n createObjectDetectionPipeline,\n COCO_LABELS,\n type ObjectDetectionOptions,\n type Detection,\n type BoundingBox,\n} from './object-detection.js';\n\n// Automatic Speech Recognition\nexport {\n AutomaticSpeechRecognitionPipeline,\n createASRPipeline,\n type ASROptions,\n type ASRResult,\n type WordTimestamp,\n type ChunkTimestamp,\n} from './automatic-speech-recognition.js';\n\n// Zero-shot Classification\nexport {\n ZeroShotClassificationPipeline,\n createZeroShotClassificationPipeline,\n type ZeroShotClassificationOptions,\n type ZeroShotClassificationResult,\n} from './zero-shot-classification.js';\n\n// Question Answering\nexport {\n QuestionAnsweringPipeline,\n createQuestionAnsweringPipeline,\n type QuestionAnsweringOptions,\n type QuestionAnsweringResult,\n type QAInput,\n} from './question-answering.js';\n\n// Image Segmentation\nexport {\n ImageSegmentationPipeline,\n createImageSegmentationPipeline,\n type ImageSegmentationOptions,\n type ImageSegmentationResult,\n type PointPrompt,\n type BoxPrompt,\n type ModelLoadProgress,\n} from './image-segmentation.js';\n\n// ============================================================================\n// High-Level Pipeline Factory\n// ============================================================================\n\n/**\n * Pipeline options for the factory function\n */\nexport interface PipelineFactoryOptions {\n /** Model ID or URL */\n model?: string;\n /** Runtime to use */\n runtime?: RuntimeType;\n /** Enable caching */\n cache?: boolean;\n /** Quantization type */\n quantization?: QuantizationType;\n /** Custom labels for classification */\n labels?: string[];\n}\n\n/**\n * Supported pipeline task mapping\n */\ntype PipelineTaskMap = {\n 'text-classification': TextClassificationPipeline;\n 'sentiment-analysis': SentimentAnalysisPipeline;\n 'feature-extraction': FeatureExtractionPipeline;\n 'image-classification': ImageClassificationPipeline;\n 'text-generation': TextGenerationPipeline;\n 'object-detection': ObjectDetectionPipeline;\n 'automatic-speech-recognition': AutomaticSpeechRecognitionPipeline;\n 'zero-shot-classification': ZeroShotClassificationPipeline;\n 'question-answering': QuestionAnsweringPipeline;\n 'image-segmentation': ImageSegmentationPipeline;\n};\n\n// Import pipeline classes\nimport { TextClassificationPipeline, SentimentAnalysisPipeline } from './text-classification.js';\nimport { FeatureExtractionPipeline } from './feature-extraction.js';\nimport { ImageClassificationPipeline } from './image-classification.js';\nimport { TextGenerationPipeline } from './text-generation.js';\nimport { ObjectDetectionPipeline } from './object-detection.js';\nimport { AutomaticSpeechRecognitionPipeline } from './automatic-speech-recognition.js';\nimport { ZeroShotClassificationPipeline } from './zero-shot-classification.js';\nimport { QuestionAnsweringPipeline } from './question-answering.js';\nimport { ImageSegmentationPipeline } from './image-segmentation.js';\n\n/**\n * Create a pipeline for a specific task\n * \n * @example\n * ```typescript\n * // Create a sentiment analysis pipeline\n * const sentiment = await pipeline('sentiment-analysis');\n * const result = await sentiment.run('I love this product!');\n * \n * // Create an image classifier with custom model\n * const classifier = await pipeline('image-classification', {\n * model: 'https://example.com/model.bin',\n * });\n * ```\n */\nexport async function pipeline<T extends keyof PipelineTaskMap>(\n task: T,\n options?: PipelineFactoryOptions\n): Promise<PipelineTaskMap[T]> {\n // Guarantee backends are registered before any model loads.\n // registerAllBackends() is synchronous and idempotent (safe to call repeatedly).\n registerAllBackends();\n\n const config: PipelineConfig = {\n task: task as PipelineTask,\n model: options?.model ?? 'default',\n runtime: options?.runtime,\n cache: options?.cache ?? true,\n quantization: options?.quantization,\n };\n\n type AllPipelines = TextClassificationPipeline | SentimentAnalysisPipeline | FeatureExtractionPipeline | ImageClassificationPipeline | TextGenerationPipeline | ObjectDetectionPipeline | AutomaticSpeechRecognitionPipeline | ZeroShotClassificationPipeline | QuestionAnsweringPipeline | ImageSegmentationPipeline;\n \n let pipelineInstance: AllPipelines;\n\n switch (task) {\n case 'text-classification':\n pipelineInstance = new TextClassificationPipeline(config, options?.labels);\n break;\n case 'sentiment-analysis':\n pipelineInstance = new SentimentAnalysisPipeline(config);\n break;\n case 'feature-extraction':\n pipelineInstance = new FeatureExtractionPipeline(config);\n break;\n case 'image-classification':\n pipelineInstance = new ImageClassificationPipeline(config, options?.labels);\n break;\n case 'text-generation':\n pipelineInstance = new TextGenerationPipeline(config);\n break;\n case 'object-detection':\n pipelineInstance = new ObjectDetectionPipeline(config, options?.labels);\n break;\n case 'automatic-speech-recognition':\n pipelineInstance = new AutomaticSpeechRecognitionPipeline(config);\n break;\n case 'zero-shot-classification':\n pipelineInstance = new ZeroShotClassificationPipeline(config);\n break;\n case 'question-answering':\n pipelineInstance = new QuestionAnsweringPipeline(config);\n break;\n case 'image-segmentation':\n pipelineInstance = new ImageSegmentationPipeline(config);\n break;\n default: {\n // Check if a plugin provides this pipeline task\n const pluginEntry = getPluginPipeline(task);\n if (pluginEntry) {\n pipelineInstance = pluginEntry.factory(config);\n break;\n }\n throw new Error(\n `Unknown pipeline task: \"${task}\". ` +\n `Register a plugin with registerPlugin() to add custom pipeline tasks.`\n );\n }\n }\n\n // Initialize the pipeline\n await pipelineInstance.initialize();\n\n return pipelineInstance as PipelineTaskMap[T];\n}\n\n/**\n * Create multiple pipelines at once\n */\nexport async function createPipelines<T extends (keyof PipelineTaskMap)[]>(\n tasks: T,\n options?: PipelineFactoryOptions\n): Promise<{ [K in T[number]]: PipelineTaskMap[K] }> {\n const pipelines = await Promise.all(\n tasks.map(task => pipeline(task, options))\n );\n\n const result: Partial<{ [K in T[number]]: PipelineTaskMap[K] }> = {};\n \n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i]!;\n result[task as T[number]] = pipelines[i] as PipelineTaskMap[T[number]];\n }\n\n return result as { [K in T[number]]: PipelineTaskMap[K] };\n}\n", "/**\n * edgeFlow.js - Pipeline Composer\n *\n * Chain multiple pipelines together to build complex multi-model workflows.\n * Each stage's output is transformed and fed as input to the next stage.\n *\n * @example\n * ```typescript\n * import { compose } from 'edgeflowjs';\n *\n * const speechTranslator = compose([\n * { task: 'automatic-speech-recognition' },\n * { task: 'translation', options: { srcLang: 'en', tgtLang: 'zh' } },\n * ]);\n *\n * const result = await speechTranslator.run(audioBlob);\n * // result.stages = [asrResult, translationResult]\n * // result.output = final translation text\n * ```\n */\n\nimport { pipeline, type PipelineFactoryOptions } from '../pipelines/index.js';\nimport type { PipelineTask } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single stage in a composed pipeline.\n */\nexport interface CompositionStage {\n /** The pipeline task to run */\n task: PipelineTask | (string & {});\n /** Model override for this stage */\n model?: string;\n /** Extra options forwarded to `pipeline()` */\n options?: PipelineFactoryOptions;\n /**\n * Optional transform applied to the previous stage's output before it is\n * passed as input to this stage. If omitted, the raw output is forwarded.\n */\n transform?: (previousOutput: unknown) => unknown;\n /**\n * Options forwarded to the pipeline's `run()` call.\n */\n runOptions?: Record<string, unknown>;\n}\n\n/**\n * Result from running a composed pipeline.\n */\nexport interface CompositionResult {\n /** The final output from the last stage */\n output: unknown;\n /** Intermediate results for every stage (index-aligned with stages) */\n stages: unknown[];\n /** Total wall-clock time in milliseconds */\n totalTime: number;\n /** Per-stage timing */\n stageTimes: number[];\n}\n\n/**\n * A composed (chained) pipeline.\n */\nexport interface ComposedPipeline {\n /** Execute the full chain with the given initial input */\n run(input: unknown): Promise<CompositionResult>;\n /** Dispose all underlying pipeline instances */\n dispose(): void;\n /** Number of stages */\n readonly length: number;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Compose multiple pipeline stages into a single sequential chain.\n *\n * The output of each stage is fed as the input to the next stage. Use the\n * optional `transform` hook in a stage to reshape data between stages.\n *\n * All pipelines are lazily initialised on the first `run()` call and cached\n * for subsequent calls.\n *\n * @param stages - Ordered list of pipeline stages\n * @returns A composed pipeline that can be run end-to-end\n *\n * @example\n * ```typescript\n * const ocrPipeline = compose([\n * { task: 'image-to-text' },\n * {\n * task: 'text-classification',\n * transform: (ocrResult: any) => ocrResult.text,\n * },\n * ]);\n *\n * const { output, stages, totalTime } = await ocrPipeline.run(imageElement);\n * ```\n */\nexport function compose(stages: CompositionStage[]): ComposedPipeline {\n if (stages.length === 0) {\n throw new Error('[edgeFlow.js] compose() requires at least one stage');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let pipelineInstances: any[] | null = null;\n\n async function ensureInitialised() {\n if (pipelineInstances) return pipelineInstances;\n\n pipelineInstances = await Promise.all(\n stages.map((stage) =>\n pipeline(stage.task as Parameters<typeof pipeline>[0], {\n model: stage.model,\n ...stage.options,\n }),\n ),\n );\n return pipelineInstances;\n }\n\n return {\n get length() {\n return stages.length;\n },\n\n async run(input: unknown): Promise<CompositionResult> {\n const instances = await ensureInitialised();\n const stageResults: unknown[] = [];\n const stageTimes: number[] = [];\n let current = input;\n const wallStart = performance.now();\n\n for (let i = 0; i < stages.length; i++) {\n const stage = stages[i]!;\n const inst = instances[i]!;\n\n // Apply transform from previous stage output if provided\n if (stage.transform) {\n current = stage.transform(current);\n }\n\n const t0 = performance.now();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n current = await (inst as any).run(current, stage.runOptions);\n stageTimes.push(performance.now() - t0);\n stageResults.push(current);\n }\n\n return {\n output: current,\n stages: stageResults,\n totalTime: performance.now() - wallStart,\n stageTimes,\n };\n },\n\n dispose() {\n if (pipelineInstances) {\n for (const inst of pipelineInstances) {\n if (inst && typeof inst.dispose === 'function') {\n inst.dispose();\n }\n }\n pipelineInstances = null;\n }\n },\n };\n}\n\n/**\n * Run stages in parallel (fan-out) and collect all results.\n *\n * Unlike `compose` (which is sequential), `parallel` runs every stage\n * independently with the same input and returns an array of results.\n *\n * @example\n * ```typescript\n * const analyzer = parallel([\n * { task: 'text-classification' },\n * { task: 'feature-extraction' },\n * { task: 'zero-shot-classification',\n * transform: (text) => ({ text, candidateLabels: ['news', 'sports'] }) },\n * ]);\n *\n * const results = await analyzer.run('Breaking: team wins championship');\n * ```\n */\nexport function parallel(\n stages: CompositionStage[],\n): {\n run(input: unknown): Promise<{ outputs: unknown[]; totalTime: number }>;\n dispose(): void;\n} {\n if (stages.length === 0) {\n throw new Error('[edgeFlow.js] parallel() requires at least one stage');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let pipelineInstances: any[] | null = null;\n\n async function ensureInitialised() {\n if (pipelineInstances) return pipelineInstances;\n pipelineInstances = await Promise.all(\n stages.map((s) =>\n pipeline(s.task as Parameters<typeof pipeline>[0], {\n model: s.model,\n ...s.options,\n }),\n ),\n );\n return pipelineInstances;\n }\n\n return {\n async run(input: unknown) {\n const instances = await ensureInitialised();\n const t0 = performance.now();\n\n const outputs = await Promise.all(\n stages.map((stage, i) => {\n const stageInput = stage.transform ? stage.transform(input) : input;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (instances[i] as any).run(stageInput, stage.runOptions);\n }),\n );\n\n return { outputs, totalTime: performance.now() - t0 };\n },\n\n dispose() {\n if (pipelineInstances) {\n for (const inst of pipelineInstances) {\n if (inst && typeof inst.dispose === 'function') {\n inst.dispose();\n }\n }\n pipelineInstances = null;\n }\n },\n };\n}\n", "/**\n * edgeFlow.js - Utilities Exports\n */\n\n// Tokenizer\nexport {\n Tokenizer,\n createBasicTokenizer,\n loadTokenizer,\n loadTokenizerFromHub,\n type TokenizerModel,\n type TokenizerOptions,\n} from './tokenizer.js';\n\n// Preprocessor\nexport {\n ImagePreprocessor,\n AudioPreprocessor,\n preprocessText,\n createImagePreprocessor,\n createAudioPreprocessor,\n type ImagePreprocessorOptions,\n type AudioPreprocessorOptions,\n type TextPreprocessorOptions,\n} from './preprocessor.js';\n\n// Cache\nexport {\n Cache,\n InferenceCache,\n ModelDownloadCache,\n createCache,\n type CacheStrategy,\n type CacheOptions,\n type CacheStats,\n} from './cache.js';\n\n// Model Loader (Preloading, Sharding, Resume, Caching)\nexport {\n loadModelData,\n preloadModel,\n preloadModels,\n isModelCached,\n getCachedModel,\n deleteCachedModel,\n clearModelCache,\n getModelCacheStats,\n getPreloadStatus,\n cancelPreload,\n getPreloadedModel,\n type DownloadProgress,\n type ModelLoaderOptions,\n type PreloadOptions,\n} from './model-loader.js';\n\n// HuggingFace Hub Integration\nexport {\n fromHub,\n fromTask,\n downloadModel,\n downloadFile,\n downloadTokenizer,\n downloadConfig,\n modelExists,\n getModelInfo,\n getDefaultModel,\n POPULAR_MODELS,\n type HubOptions,\n type HubDownloadProgress,\n type ModelConfig,\n type ModelBundle,\n type PopularModelTask,\n} from './hub.js';\n\n// Offline/PWA Support\nexport {\n OfflineManager,\n getOfflineManager,\n initOffline,\n isOffline,\n isPWASupported,\n generateServiceWorker,\n generateManifest,\n type OfflineConfig,\n type OfflineStatus,\n type CachedModelInfo,\n} from './offline.js';\n", "/**\n * edgeFlow.js - Hugging Face Hub Integration\n * \n * Automatically download models, tokenizers, and configs from Hugging Face Hub.\n */\n\nimport { loadModelData, isModelCached, type DownloadProgress } from './model-loader.js';\nimport { Tokenizer } from './tokenizer.js';\nimport { EdgeFlowError, ErrorCodes } from '../core/types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Hub options\n */\nexport interface HubOptions {\n /** HuggingFace API endpoint (default: https://huggingface.co) */\n endpoint?: string;\n /** Model revision/branch (default: main) */\n revision?: string;\n /** Subfolder within the repo */\n subfolder?: string;\n /** Enable caching */\n cache?: boolean;\n /** Force re-download */\n forceDownload?: boolean;\n /** Progress callback */\n onProgress?: (progress: HubDownloadProgress) => void;\n /** HuggingFace API token (for private repos) */\n token?: string;\n}\n\n/**\n * Download progress for hub\n */\nexport interface HubDownloadProgress {\n /** Current file being downloaded */\n file: string;\n /** File index (1-based) */\n fileIndex: number;\n /** Total files */\n totalFiles: number;\n /** File download progress */\n fileProgress: DownloadProgress;\n /** Overall progress (0-100) */\n overallProgress: number;\n}\n\n/**\n * Model info from config.json\n */\nexport interface ModelConfig {\n model_type?: string;\n architectures?: string[];\n hidden_size?: number;\n num_attention_heads?: number;\n num_hidden_layers?: number;\n vocab_size?: number;\n max_position_embeddings?: number;\n type_vocab_size?: number;\n id2label?: Record<string, string>;\n label2id?: Record<string, number>;\n [key: string]: unknown;\n}\n\n/**\n * Downloaded model bundle\n */\nexport interface ModelBundle {\n /** Model ID */\n modelId: string;\n /** Model data (ArrayBuffer) */\n modelData: ArrayBuffer;\n /** Tokenizer instance */\n tokenizer?: Tokenizer;\n /** Model config */\n config?: ModelConfig;\n /** Model files info */\n files: {\n model?: string;\n tokenizer?: string;\n config?: string;\n };\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_ENDPOINT = 'https://huggingface.co';\nconst DEFAULT_REVISION = 'main';\n\n/**\n * Common ONNX model file patterns (in order of preference)\n */\nconst ONNX_MODEL_FILES = [\n 'model.onnx',\n 'model_quantized.onnx',\n 'model_int8.onnx',\n 'model_uint8.onnx',\n 'model_fp16.onnx',\n 'onnx/model.onnx',\n 'onnx/model_quantized.onnx',\n];\n\n// ============================================================================\n// Hub API\n// ============================================================================\n\n/**\n * Build URL for a file in a HuggingFace repo\n */\nfunction buildFileUrl(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): string {\n const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;\n const revision = options.revision ?? DEFAULT_REVISION;\n const subfolder = options.subfolder ? `${options.subfolder}/` : '';\n \n return `${endpoint}/${modelId}/resolve/${revision}/${subfolder}${filename}`;\n}\n\n/**\n * Fetch with optional auth token\n */\nasync function fetchWithAuth(url: string, token?: string): Promise<Response> {\n const headers: HeadersInit = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n \n const response = await fetch(url, { headers });\n return response;\n}\n\n/**\n * Check if a file exists in a repo\n */\nasync function fileExists(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<boolean> {\n const url = buildFileUrl(modelId, filename, options);\n \n try {\n const response = await fetchWithAuth(url, options.token);\n // HuggingFace returns 302 redirect for existing files\n return response.ok || response.status === 302;\n } catch {\n return false;\n }\n}\n\n/**\n * Find the best ONNX model file in a repo\n */\nasync function findOnnxModel(\n modelId: string,\n options: HubOptions = {}\n): Promise<string | null> {\n // Try common file patterns\n for (const filename of ONNX_MODEL_FILES) {\n if (await fileExists(modelId, filename, options)) {\n return filename;\n }\n }\n \n return null;\n}\n\n/**\n * Download a file from HuggingFace Hub\n */\nexport async function downloadFile(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<ArrayBuffer> {\n const url = buildFileUrl(modelId, filename, options);\n \n // Use model loader for caching and resume support\n return loadModelData(url, {\n cache: options.cache ?? true,\n forceDownload: options.forceDownload ?? false,\n onProgress: options.onProgress ? (progress) => {\n options.onProgress!({\n file: filename,\n fileIndex: 1,\n totalFiles: 1,\n fileProgress: progress,\n overallProgress: progress.percent,\n });\n } : undefined,\n });\n}\n\n/**\n * Download JSON file from HuggingFace Hub\n */\nexport async function downloadJson<T = unknown>(\n modelId: string,\n filename: string,\n options: HubOptions = {}\n): Promise<T> {\n const url = buildFileUrl(modelId, filename, options);\n \n // Check cache first\n if (options.cache !== false && !options.forceDownload) {\n const cached = await isModelCached(url);\n if (cached) {\n const data = await loadModelData(url, { cache: true });\n const text = new TextDecoder().decode(data);\n return JSON.parse(text) as T;\n }\n }\n \n // Fetch directly for small JSON files\n const response = await fetchWithAuth(url, options.token);\n \n if (!response.ok) {\n throw new EdgeFlowError(\n `Failed to download ${filename} from ${modelId}: ${response.status}`,\n ErrorCodes.MODEL_NOT_FOUND\n );\n }\n \n return response.json() as Promise<T>;\n}\n\n/**\n * Download tokenizer from HuggingFace Hub\n */\nexport async function downloadTokenizer(\n modelId: string,\n options: HubOptions = {}\n): Promise<Tokenizer> {\n const url = buildFileUrl(modelId, 'tokenizer.json', options);\n return Tokenizer.fromUrl(url);\n}\n\n/**\n * Download model config from HuggingFace Hub\n */\nexport async function downloadConfig(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelConfig> {\n return downloadJson<ModelConfig>(modelId, 'config.json', options);\n}\n\n/**\n * Download complete model bundle (model + tokenizer + config)\n */\nexport async function downloadModel(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n const files: ModelBundle['files'] = {};\n const totalSteps = 3; // model, tokenizer, config\n let currentStep = 0;\n \n const reportProgress = (\n file: string,\n progress: DownloadProgress\n ) => {\n if (options.onProgress) {\n const baseProgress = (currentStep / totalSteps) * 100;\n const stepProgress = (progress.percent / totalSteps);\n \n options.onProgress({\n file,\n fileIndex: currentStep + 1,\n totalFiles: totalSteps,\n fileProgress: progress,\n overallProgress: baseProgress + stepProgress,\n });\n }\n };\n \n // 1. Find and download ONNX model\n console.log(`\uD83D\uDD0D Finding ONNX model in ${modelId}...`);\n const modelFile = await findOnnxModel(modelId, options);\n \n if (!modelFile) {\n throw new EdgeFlowError(\n `No ONNX model found in ${modelId}. Please ensure the model has an ONNX file.`,\n ErrorCodes.MODEL_NOT_FOUND,\n { modelId, triedFiles: ONNX_MODEL_FILES }\n );\n }\n \n files.model = modelFile;\n console.log(`\uD83D\uDCE6 Downloading model: ${modelFile}`);\n \n const modelData = await downloadFile(modelId, modelFile, {\n ...options,\n onProgress: (p) => reportProgress(modelFile, p.fileProgress),\n });\n \n currentStep = 1;\n \n // 2. Download tokenizer (optional)\n let tokenizer: Tokenizer | undefined;\n try {\n console.log(`\uD83D\uDCDD Downloading tokenizer...`);\n files.tokenizer = 'tokenizer.json';\n tokenizer = await downloadTokenizer(modelId, options);\n console.log(`\u2713 Tokenizer loaded`);\n } catch (error) {\n console.warn(`\u26A0\uFE0F No tokenizer found for ${modelId}`);\n }\n \n currentStep = 2;\n \n // 3. Download config (optional)\n let config: ModelConfig | undefined;\n try {\n console.log(`\u2699\uFE0F Downloading config...`);\n files.config = 'config.json';\n config = await downloadConfig(modelId, options);\n console.log(`\u2713 Config loaded`);\n } catch (error) {\n console.warn(`\u26A0\uFE0F No config found for ${modelId}`);\n }\n \n currentStep = 3;\n \n if (options.onProgress) {\n options.onProgress({\n file: 'complete',\n fileIndex: totalSteps,\n totalFiles: totalSteps,\n fileProgress: { loaded: 1, total: 1, percent: 100, speed: 0, eta: 0 },\n overallProgress: 100,\n });\n }\n \n console.log(`\u2705 Model bundle downloaded: ${modelId}`);\n \n return {\n modelId,\n modelData,\n tokenizer,\n config,\n files,\n };\n}\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\n/**\n * Load a model from HuggingFace Hub\n * \n * @example\n * ```typescript\n * // Load a sentiment analysis model\n * const bundle = await fromHub('Xenova/distilbert-base-uncased-finetuned-sst-2-english');\n * \n * // Use with edgeFlow\n * const model = await loadModelFromBuffer(bundle.modelData);\n * const tokens = bundle.tokenizer.encode('I love this!');\n * ```\n */\nexport async function fromHub(\n modelId: string,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n return downloadModel(modelId, options);\n}\n\n/**\n * Check if a model exists on HuggingFace Hub\n */\nexport async function modelExists(\n modelId: string,\n options: HubOptions = {}\n): Promise<boolean> {\n try {\n // Try to find an ONNX model\n const modelFile = await findOnnxModel(modelId, options);\n return modelFile !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Get model info from HuggingFace Hub\n */\nexport async function getModelInfo(\n modelId: string,\n options: HubOptions = {}\n): Promise<{\n hasOnnx: boolean;\n onnxFile?: string;\n hasTokenizer: boolean;\n hasConfig: boolean;\n config?: ModelConfig;\n}> {\n const [onnxFile, hasTokenizer, config] = await Promise.all([\n findOnnxModel(modelId, options),\n fileExists(modelId, 'tokenizer.json', options),\n downloadConfig(modelId, options).catch(() => undefined),\n ]);\n \n return {\n hasOnnx: onnxFile !== null,\n onnxFile: onnxFile ?? undefined,\n hasTokenizer,\n hasConfig: config !== undefined,\n config,\n };\n}\n\n// ============================================================================\n// Popular Models Registry\n// ============================================================================\n\n/**\n * Pre-configured popular models\n */\nexport const POPULAR_MODELS = {\n // Text Classification / Sentiment\n 'sentiment-analysis': 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n 'text-classification': 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',\n \n // Feature Extraction\n 'feature-extraction': 'Xenova/all-MiniLM-L6-v2',\n 'sentence-similarity': 'Xenova/all-MiniLM-L6-v2',\n \n // Question Answering\n 'question-answering': 'Xenova/distilbert-base-cased-distilled-squad',\n \n // Token Classification\n 'ner': 'Xenova/bert-base-NER',\n 'token-classification': 'Xenova/bert-base-NER',\n \n // Text Generation\n 'text-generation': 'Xenova/gpt2',\n \n // Translation\n 'translation-en-fr': 'Xenova/t5-small',\n 'translation-en-de': 'Xenova/t5-small',\n \n // Summarization\n 'summarization': 'Xenova/distilbart-cnn-6-6',\n \n // Fill Mask\n 'fill-mask': 'Xenova/bert-base-uncased',\n \n // Image Classification\n 'image-classification': 'Xenova/vit-base-patch16-224',\n \n // Object Detection\n 'object-detection': 'Xenova/detr-resnet-50',\n \n // Image Segmentation\n 'image-segmentation': 'Xenova/segformer-b0-finetuned-ade-512-512',\n \n // Zero-shot Classification\n 'zero-shot-classification': 'Xenova/mobilebert-uncased-mnli',\n \n // Speech Recognition\n 'automatic-speech-recognition': 'Xenova/whisper-tiny.en',\n \n // Text-to-Speech\n 'text-to-speech': 'Xenova/speecht5_tts',\n} as const;\n\nexport type PopularModelTask = keyof typeof POPULAR_MODELS;\n\n/**\n * Get the default model ID for a task\n */\nexport function getDefaultModel(task: PopularModelTask): string {\n return POPULAR_MODELS[task];\n}\n\n/**\n * Load a model by task name\n * \n * @example\n * ```typescript\n * const bundle = await fromTask('sentiment-analysis');\n * ```\n */\nexport async function fromTask(\n task: PopularModelTask,\n options: HubOptions = {}\n): Promise<ModelBundle> {\n const modelId = getDefaultModel(task);\n return downloadModel(modelId, options);\n}\n", "/**\n * edgeFlow.js - Benchmark Utilities\n * \n * Performance testing and comparison tools.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BenchmarkOptions {\n /** Number of warmup runs (default: 3) */\n warmupRuns?: number;\n \n /** Number of measured runs (default: 10) */\n runs?: number;\n \n /** Whether to log progress (default: true) */\n verbose?: boolean;\n \n /** Timeout per run in ms (default: 30000) */\n timeout?: number;\n \n /** Name for this benchmark */\n name?: string;\n}\n\nexport interface BenchmarkResult {\n name: string;\n \n /** Average time in ms */\n avgTime: number;\n \n /** Median time in ms */\n medianTime: number;\n \n /** Minimum time in ms */\n minTime: number;\n \n /** Maximum time in ms */\n maxTime: number;\n \n /** Standard deviation in ms */\n stdDev: number;\n \n /** 95th percentile in ms */\n p95: number;\n \n /** 99th percentile in ms */\n p99: number;\n \n /** Throughput (ops/sec) */\n throughput: number;\n \n /** All individual run times */\n times: number[];\n \n /** Number of runs */\n totalRuns: number;\n \n /** Number of failed runs */\n failedRuns: number;\n}\n\nexport interface CompareBenchmarkResult {\n baseline: BenchmarkResult;\n comparison: BenchmarkResult;\n speedup: number;\n percentFaster: number;\n winner: 'baseline' | 'comparison' | 'tie';\n}\n\n// ============================================================================\n// Benchmark Functions\n// ============================================================================\n\n/**\n * Run a benchmark on an async function\n */\nexport async function benchmark(\n fn: () => Promise<unknown> | unknown,\n options: BenchmarkOptions = {}\n): Promise<BenchmarkResult> {\n const {\n warmupRuns = 3,\n runs = 10,\n verbose = false,\n timeout = 30000,\n name = 'benchmark',\n } = options;\n\n const times: number[] = [];\n let failedRuns = 0;\n\n // Warmup\n if (verbose) console.log(`[${name}] Running ${warmupRuns} warmup iterations...`);\n for (let i = 0; i < warmupRuns; i++) {\n try {\n await Promise.race([\n Promise.resolve(fn()),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Timeout')), timeout)\n ),\n ]);\n } catch {\n // Warmup failures are ignored\n }\n }\n\n // Measured runs\n if (verbose) console.log(`[${name}] Running ${runs} measured iterations...`);\n for (let i = 0; i < runs; i++) {\n try {\n const start = performance.now();\n await Promise.race([\n Promise.resolve(fn()),\n new Promise((_, reject) => \n setTimeout(() => reject(new Error('Timeout')), timeout)\n ),\n ]);\n const end = performance.now();\n times.push(end - start);\n \n if (verbose) console.log(` Run ${i + 1}: ${(end - start).toFixed(2)}ms`);\n } catch (error) {\n failedRuns++;\n if (verbose) console.log(` Run ${i + 1}: FAILED - ${error}`);\n }\n }\n\n if (times.length === 0) {\n throw new Error(`All ${runs} runs failed`);\n }\n\n // Calculate statistics\n const sorted = [...times].sort((a, b) => a - b);\n const sum = times.reduce((a, b) => a + b, 0);\n const avg = sum / times.length;\n const variance = times.reduce((sum, t) => sum + Math.pow(t - avg, 2), 0) / times.length;\n const stdDev = Math.sqrt(variance);\n\n const result: BenchmarkResult = {\n name,\n avgTime: avg,\n medianTime: sorted[Math.floor(sorted.length / 2)] ?? 0,\n minTime: sorted[0] ?? 0,\n maxTime: sorted[sorted.length - 1] ?? 0,\n stdDev,\n p95: sorted[Math.floor(sorted.length * 0.95)] ?? sorted[sorted.length - 1] ?? 0,\n p99: sorted[Math.floor(sorted.length * 0.99)] ?? sorted[sorted.length - 1] ?? 0,\n throughput: 1000 / avg,\n times,\n totalRuns: runs,\n failedRuns,\n };\n\n if (verbose) {\n console.log(`\\n[${name}] Results:`);\n console.log(` Avg: ${result.avgTime.toFixed(2)}ms`);\n console.log(` Median: ${result.medianTime.toFixed(2)}ms`);\n console.log(` Min: ${result.minTime.toFixed(2)}ms`);\n console.log(` Max: ${result.maxTime.toFixed(2)}ms`);\n console.log(` Std Dev: ${result.stdDev.toFixed(2)}ms`);\n console.log(` P95: ${result.p95.toFixed(2)}ms`);\n console.log(` Throughput: ${result.throughput.toFixed(2)} ops/sec`);\n }\n\n return result;\n}\n\n/**\n * Compare two benchmarks\n */\nexport async function compareBenchmarks(\n baseline: () => Promise<unknown> | unknown,\n comparison: () => Promise<unknown> | unknown,\n options: BenchmarkOptions = {}\n): Promise<CompareBenchmarkResult> {\n const baselineResult = await benchmark(baseline, { \n ...options, \n name: options.name ? `${options.name} (baseline)` : 'baseline' \n });\n \n const comparisonResult = await benchmark(comparison, { \n ...options, \n name: options.name ? `${options.name} (comparison)` : 'comparison' \n });\n\n const speedup = baselineResult.avgTime / comparisonResult.avgTime;\n const percentFaster = ((baselineResult.avgTime - comparisonResult.avgTime) / baselineResult.avgTime) * 100;\n\n let winner: 'baseline' | 'comparison' | 'tie';\n if (Math.abs(percentFaster) < 5) {\n winner = 'tie';\n } else if (percentFaster > 0) {\n winner = 'comparison';\n } else {\n winner = 'baseline';\n }\n\n return {\n baseline: baselineResult,\n comparison: comparisonResult,\n speedup,\n percentFaster,\n winner,\n };\n}\n\n/**\n * Run multiple benchmarks in a suite\n */\nexport async function benchmarkSuite(\n suite: Record<string, () => Promise<unknown> | unknown>,\n options: BenchmarkOptions = {}\n): Promise<Record<string, BenchmarkResult>> {\n const results: Record<string, BenchmarkResult> = {};\n\n for (const [name, fn] of Object.entries(suite)) {\n console.log(`\\n=== ${name} ===`);\n results[name] = await benchmark(fn, { ...options, name, verbose: true });\n }\n\n return results;\n}\n\n/**\n * Format benchmark result as a table string\n */\nexport function formatBenchmarkResult(result: BenchmarkResult): string {\n return `\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 ${result.name.padEnd(39)} \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Avg Time: ${result.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Median: ${result.medianTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Min Time: ${result.minTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Max Time: ${result.maxTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Std Dev: ${result.stdDev.toFixed(2).padStart(10)}ms \u2502\n\u2502 P95: ${result.p95.toFixed(2).padStart(10)}ms \u2502\n\u2502 P99: ${result.p99.toFixed(2).padStart(10)}ms \u2502\n\u2502 Throughput: ${result.throughput.toFixed(2).padStart(10)} ops/sec \u2502\n\u2502 Runs: ${result.totalRuns.toString().padStart(10)} (${result.failedRuns} failed) \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n `.trim();\n}\n\n/**\n * Format comparison result\n */\nexport function formatComparisonResult(result: CompareBenchmarkResult): string {\n const arrow = result.percentFaster > 0 ? '\u2191' : result.percentFaster < 0 ? '\u2193' : '=';\n const winnerText = result.winner === 'comparison' \n ? 'Comparison is faster!'\n : result.winner === 'baseline'\n ? 'Baseline is faster!'\n : 'Results are similar';\n\n return `\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 BENCHMARK COMPARISON \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Baseline: ${result.baseline.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u2502 Comparison: ${result.comparison.avgTime.toFixed(2).padStart(10)}ms \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Speedup: ${result.speedup.toFixed(2).padStart(10)}x \u2502\n\u2502 Difference: ${arrow} ${Math.abs(result.percentFaster).toFixed(1).padStart(8)}% \u2502\n\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Winner: ${winnerText.padEnd(42)} \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n `.trim();\n}\n\n// ============================================================================\n// Memory Benchmark\n// ============================================================================\n\nexport interface MemoryBenchmarkResult {\n name: string;\n peakMemory: number;\n avgMemory: number;\n memoryDelta: number;\n}\n\n/**\n * Benchmark memory usage\n */\nexport async function benchmarkMemory(\n fn: () => Promise<unknown> | unknown,\n options: { name?: string; runs?: number } = {}\n): Promise<MemoryBenchmarkResult> {\n const { name = 'memory-benchmark', runs = 5 } = options;\n\n // Note: Memory APIs are limited in browsers\n // This is a simplified version that works when performance.memory is available\n const getMemory = (): number => {\n if (typeof performance !== 'undefined' && 'memory' in performance) {\n return (performance as { memory: { usedJSHeapSize: number } }).memory.usedJSHeapSize;\n }\n return 0;\n };\n\n const memoryReadings: number[] = [];\n const initialMemory = getMemory();\n\n for (let i = 0; i < runs; i++) {\n await fn();\n memoryReadings.push(getMemory());\n }\n\n const peakMemory = Math.max(...memoryReadings);\n const avgMemory = memoryReadings.reduce((a, b) => a + b, 0) / memoryReadings.length;\n const memoryDelta = avgMemory - initialMemory;\n\n return {\n name,\n peakMemory,\n avgMemory,\n memoryDelta,\n };\n}\n\n// ============================================================================\n// Export\n// ============================================================================\n\nexport default {\n benchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n};\n", "/**\n * edgeFlow.js - Core Module Exports\n */\n\n// Types\nexport * from './types.js';\n\n// Tensor\nexport {\n EdgeFlowTensor,\n tensor,\n zeros,\n ones,\n full,\n random,\n randn,\n arange,\n linspace,\n eye,\n add,\n sub,\n mul,\n div,\n matmul,\n softmax,\n relu,\n sigmoid,\n tanh,\n sum,\n mean,\n argmax,\n concat,\n} from './tensor.js';\n\n// Scheduler\nexport {\n InferenceScheduler,\n getScheduler,\n setScheduler,\n configureScheduler,\n} from './scheduler.js';\n\n// Memory\nexport {\n MemoryManager,\n MemoryScope,\n ModelCache,\n withMemoryScope,\n withMemoryScopeSync,\n getMemoryManager,\n getMemoryStats,\n release,\n gc,\n} from './memory.js';\n\n// Runtime\nexport {\n RuntimeManager,\n LoadedModelImpl,\n loadModel,\n loadModelFromBuffer,\n runInference,\n runBatchInference,\n getRuntimeManager,\n registerRuntime,\n getBestRuntime,\n getAvailableRuntimes,\n} from './runtime.js';\n\n// Plugin System\nexport {\n registerPlugin,\n getPluginPipeline,\n getPluginMiddleware,\n listPlugins,\n unregisterPlugin,\n type EdgeFlowPlugin,\n type PluginPipelineEntry,\n type PluginBackendEntry,\n type PluginMiddleware,\n} from './plugin.js';\n\n// Device Profiler\nexport {\n getDeviceProfile,\n recommendQuantization,\n recommendModelVariant,\n resetDeviceProfile,\n type DeviceProfile,\n type DeviceTier,\n type ModelRecommendation,\n} from './device-profiler.js';\n\n// Composer\nexport {\n compose,\n parallel,\n type CompositionStage,\n type CompositionResult,\n type ComposedPipeline,\n} from './composer.js';\n\n// Worker\nexport {\n InferenceWorker,\n WorkerPool,\n getWorkerPool,\n runInWorker,\n isWorkerSupported,\n serializeTensor,\n deserializeTensor,\n type WorkerMessage,\n type WorkerMessageType,\n type LoadModelRequest,\n type InferenceRequest,\n type SerializedTensor,\n type WorkerPoolOptions,\n} from './worker.js';\n", "/**\n * edgeFlow.js - Model Compression & Quantization Tools\n * \n * In-browser model quantization and compression utilities.\n * Supports dynamic quantization (no calibration data needed).\n */\n\nimport { EdgeFlowTensor, DataType } from '../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Quantization type\n */\nexport type QuantizationType = 'int8' | 'uint8' | 'int4' | 'float16' | 'dynamic';\n\n/**\n * Quantization options\n */\nexport interface QuantizationOptions {\n /** Quantization type */\n type: QuantizationType;\n \n /** Layers/ops to skip quantization (by name pattern) */\n skipPatterns?: (string | RegExp)[];\n \n /** Per-channel quantization (more accurate, larger model) */\n perChannel?: boolean;\n \n /** Symmetric quantization (simpler, slightly less accurate) */\n symmetric?: boolean;\n \n /** Progress callback */\n onProgress?: (progress: QuantizationProgress) => void;\n \n /** Minimum tensor size to quantize (in elements) */\n minTensorSize?: number;\n \n /** Keep original weights for comparison */\n keepOriginal?: boolean;\n}\n\n/**\n * Quantization progress\n */\nexport interface QuantizationProgress {\n stage: 'analyzing' | 'quantizing' | 'packing' | 'complete';\n current: number;\n total: number;\n percent: number;\n layerName?: string;\n}\n\n/**\n * Quantization result\n */\nexport interface QuantizationResult {\n /** Quantized model data */\n data: ArrayBuffer;\n \n /** Original model size in bytes */\n originalSize: number;\n \n /** Quantized model size in bytes */\n quantizedSize: number;\n \n /** Compression ratio */\n compressionRatio: number;\n \n /** Number of tensors quantized */\n tensorsQuantized: number;\n \n /** Number of tensors skipped */\n tensorsSkipped: number;\n \n /** Quantization statistics per layer */\n layerStats: LayerQuantizationStats[];\n \n /** Overall statistics */\n stats: QuantizationStats;\n}\n\n/**\n * Layer quantization statistics\n */\nexport interface LayerQuantizationStats {\n name: string;\n originalDtype: string;\n quantizedDtype: string;\n originalSize: number;\n quantizedSize: number;\n scale: number | number[];\n zeroPoint: number | number[];\n minValue: number;\n maxValue: number;\n skipped: boolean;\n skipReason?: string;\n}\n\n/**\n * Overall quantization statistics\n */\nexport interface QuantizationStats {\n totalParameters: number;\n quantizedParameters: number;\n averageScale: number;\n minScale: number;\n maxScale: number;\n errorEstimate: number;\n}\n\n/**\n * Quantization parameters for a tensor\n */\ninterface QuantizationParams {\n scale: number | Float32Array;\n zeroPoint: number | Int32Array;\n min: number;\n max: number;\n}\n\n// ============================================================================\n// Quantization Core\n// ============================================================================\n\n/**\n * Calculate quantization parameters for a tensor\n */\nfunction calculateQuantParams(\n data: Float32Array,\n bits: number,\n symmetric: boolean,\n perChannel: boolean,\n channelAxis: number = 0,\n shape: number[] = []\n): QuantizationParams {\n const qmin = symmetric ? -(1 << (bits - 1)) : 0;\n const qmax = symmetric ? (1 << (bits - 1)) - 1 : (1 << bits) - 1;\n \n if (perChannel && shape.length > 1) {\n // Per-channel quantization\n const numChannels = shape[channelAxis] ?? 1;\n const scales = new Float32Array(numChannels);\n const zeroPoints = new Int32Array(numChannels);\n \n const channelSize = data.length / numChannels;\n let globalMin = Infinity;\n let globalMax = -Infinity;\n \n for (let c = 0; c < numChannels; c++) {\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n \n globalMin = Math.min(globalMin, min);\n globalMax = Math.max(globalMax, max);\n \n if (symmetric) {\n const absMax = Math.max(Math.abs(min), Math.abs(max));\n scales[c] = absMax / qmax;\n zeroPoints[c] = 0;\n } else {\n scales[c] = (max - min) / (qmax - qmin);\n zeroPoints[c] = Math.round(qmin - min / (scales[c] || 1));\n }\n \n // Avoid division by zero\n if (scales[c] === 0) scales[c] = 1;\n }\n \n return { scale: scales, zeroPoint: zeroPoints, min: globalMin, max: globalMax };\n } else {\n // Per-tensor quantization\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n \n let scale: number;\n let zeroPoint: number;\n \n if (symmetric) {\n const absMax = Math.max(Math.abs(min), Math.abs(max));\n scale = absMax / qmax;\n zeroPoint = 0;\n } else {\n scale = (max - min) / (qmax - qmin);\n zeroPoint = Math.round(qmin - min / (scale || 1));\n }\n \n // Avoid division by zero\n if (scale === 0) scale = 1;\n \n return { scale, zeroPoint, min, max };\n }\n}\n\n/**\n * Quantize float32 data to int8\n */\nfunction quantizeToInt8(\n data: Float32Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean,\n channelSize: number = data.length\n): Int8Array {\n const result = new Int8Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n result[idx] = Math.max(-128, Math.min(127, Math.round(val / s + zp)));\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n result[i] = Math.max(-128, Math.min(127, Math.round(val / s + zp)));\n }\n }\n \n return result;\n}\n\n/**\n * Quantize float32 data to uint8\n */\nfunction quantizeToUint8(\n data: Float32Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean,\n channelSize: number = data.length\n): Uint8Array {\n const result = new Uint8Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n const val = data[idx] ?? 0;\n result[idx] = Math.max(0, Math.min(255, Math.round(val / s + zp)));\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n result[i] = Math.max(0, Math.min(255, Math.round(val / s + zp)));\n }\n }\n \n return result;\n}\n\n/**\n * Quantize float32 data to int4 (packed as uint8, 2 values per byte)\n */\nfunction quantizeToInt4(\n data: Float32Array,\n scale: number,\n zeroPoint: number\n): Uint8Array {\n const packedLength = Math.ceil(data.length / 2);\n const result = new Uint8Array(packedLength);\n \n for (let i = 0; i < data.length; i += 2) {\n const val1 = data[i] ?? 0;\n const val2 = data[i + 1] ?? 0;\n \n // Quantize to range [-8, 7] then shift to [0, 15]\n const q1 = Math.max(0, Math.min(15, Math.round(val1 / scale + zeroPoint + 8)));\n const q2 = Math.max(0, Math.min(15, Math.round(val2 / scale + zeroPoint + 8)));\n \n // Pack two 4-bit values into one byte\n result[i >> 1] = (q1 << 4) | q2;\n }\n \n return result;\n}\n\n/**\n * Convert float32 to float16 (stored in Uint16Array)\n */\nfunction quantizeToFloat16(data: Float32Array): Uint16Array {\n const result = new Uint16Array(data.length);\n \n for (let i = 0; i < data.length; i++) {\n result[i] = float32ToFloat16(data[i] ?? 0);\n }\n \n return result;\n}\n\n/**\n * Convert a single float32 value to float16 bits\n */\nfunction float32ToFloat16(value: number): number {\n const float32View = new Float32Array(1);\n const int32View = new Int32Array(float32View.buffer);\n \n float32View[0] = value;\n const f = int32View[0]!;\n \n const sign = (f >> 16) & 0x8000;\n const exponent = ((f >> 23) & 0xff) - 127 + 15;\n const mantissa = f & 0x7fffff;\n \n if (exponent <= 0) {\n // Denormalized or zero\n if (exponent < -10) {\n return sign;\n }\n const m = (mantissa | 0x800000) >> (1 - exponent);\n return sign | (m >> 13);\n } else if (exponent >= 31) {\n // Overflow to infinity\n return sign | 0x7c00;\n }\n \n return sign | (exponent << 10) | (mantissa >> 13);\n}\n\n/**\n * Dequantize int8 data back to float32\n */\nexport function dequantizeInt8(\n data: Int8Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean = false,\n channelSize: number = data.length\n): Float32Array {\n const result = new Float32Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n result[idx] = ((data[idx] ?? 0) - zp) * s;\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n result[i] = ((data[i] ?? 0) - zp) * s;\n }\n }\n \n return result;\n}\n\n/**\n * Dequantize uint8 data back to float32\n */\nexport function dequantizeUint8(\n data: Uint8Array,\n scale: number | Float32Array,\n zeroPoint: number | Int32Array,\n perChannel: boolean = false,\n channelSize: number = data.length\n): Float32Array {\n const result = new Float32Array(data.length);\n \n if (perChannel && scale instanceof Float32Array) {\n const numChannels = scale.length;\n for (let c = 0; c < numChannels; c++) {\n const s = scale[c] ?? 1;\n const zp = (zeroPoint as Int32Array)[c] ?? 0;\n for (let i = 0; i < channelSize; i++) {\n const idx = c * channelSize + i;\n result[idx] = ((data[idx] ?? 0) - zp) * s;\n }\n }\n } else {\n const s = scale as number;\n const zp = zeroPoint as number;\n for (let i = 0; i < data.length; i++) {\n result[i] = ((data[i] ?? 0) - zp) * s;\n }\n }\n \n return result;\n}\n\n/**\n * Convert float16 bits back to float32\n */\nexport function float16ToFloat32(value: number): number {\n const sign = (value & 0x8000) >> 15;\n const exponent = (value & 0x7c00) >> 10;\n const mantissa = value & 0x03ff;\n \n if (exponent === 0) {\n if (mantissa === 0) {\n return sign === 0 ? 0 : -0;\n }\n // Denormalized\n return (sign === 0 ? 1 : -1) * Math.pow(2, -14) * (mantissa / 1024);\n } else if (exponent === 31) {\n if (mantissa === 0) {\n return sign === 0 ? Infinity : -Infinity;\n }\n return NaN;\n }\n \n return (sign === 0 ? 1 : -1) * Math.pow(2, exponent - 15) * (1 + mantissa / 1024);\n}\n\n/**\n * Dequantize float16 data back to float32\n */\nexport function dequantizeFloat16(data: Uint16Array): Float32Array {\n const result = new Float32Array(data.length);\n for (let i = 0; i < data.length; i++) {\n result[i] = float16ToFloat32(data[i] ?? 0);\n }\n return result;\n}\n\n// ============================================================================\n// Model Quantization\n// ============================================================================\n\n/**\n * Simple ONNX-like model representation for quantization\n */\ninterface ModelWeights {\n name: string;\n data: Float32Array;\n shape: number[];\n dtype: string;\n}\n\n/**\n * Quantized model format\n */\ninterface QuantizedModel {\n version: number;\n quantizationType: QuantizationType;\n originalSize: number;\n weights: Array<{\n name: string;\n data: ArrayBuffer;\n shape: number[];\n dtype: string;\n originalDtype: string;\n scale?: number | number[];\n zeroPoint?: number | number[];\n }>;\n}\n\n/**\n * Parse ONNX model to extract weights\n * Note: This is a simplified parser for demonstration\n */\nfunction parseModelWeights(modelData: ArrayBuffer): ModelWeights[] {\n // Check if it's an ONNX model by magic number\n // const view = new DataView(modelData); // Reserved for future ONNX header parsing\n const weights: ModelWeights[] = [];\n \n // Simple heuristic: look for float32 arrays in the buffer\n // In a real implementation, we'd use proper ONNX parsing\n const float32Array = new Float32Array(modelData);\n \n // Create a single weight tensor from the model data\n // This is a placeholder - real implementation would parse ONNX properly\n weights.push({\n name: 'model_weights',\n data: float32Array,\n shape: [float32Array.length],\n dtype: 'float32',\n });\n \n return weights;\n}\n\n/**\n * Serialize quantized model to ArrayBuffer\n */\nfunction serializeQuantizedModel(model: QuantizedModel): ArrayBuffer {\n // Create a simple binary format:\n // Header: version (4 bytes) + type (4 bytes) + originalSize (8 bytes) + numWeights (4 bytes)\n // For each weight: nameLen (4) + name + shapeLen (4) + shape + dtypeLen (4) + dtype + \n // origDtypeLen (4) + origDtype + hasScale (1) + scale + hasZP (1) + zp + dataLen (8) + data\n \n const encoder = new TextEncoder();\n \n // Calculate total size\n let totalSize = 20; // Header\n \n for (const weight of model.weights) {\n const nameBytes = encoder.encode(weight.name);\n const dtypeBytes = encoder.encode(weight.dtype);\n const origDtypeBytes = encoder.encode(weight.originalDtype);\n \n totalSize += 4 + nameBytes.length; // name\n totalSize += 4 + weight.shape.length * 4; // shape\n totalSize += 4 + dtypeBytes.length; // dtype\n totalSize += 4 + origDtypeBytes.length; // originalDtype\n totalSize += 1; // hasScale\n if (weight.scale !== undefined) {\n totalSize += Array.isArray(weight.scale) ? 4 + weight.scale.length * 4 : 4;\n }\n totalSize += 1; // hasZeroPoint\n if (weight.zeroPoint !== undefined) {\n totalSize += Array.isArray(weight.zeroPoint) ? 4 + weight.zeroPoint.length * 4 : 4;\n }\n totalSize += 8 + weight.data.byteLength; // data\n }\n \n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const uint8 = new Uint8Array(buffer);\n let offset = 0;\n \n // Write header\n view.setUint32(offset, model.version, true); offset += 4;\n view.setUint32(offset, ['int8', 'uint8', 'int4', 'float16', 'dynamic'].indexOf(model.quantizationType), true); offset += 4;\n // Write originalSize as two 32-bit integers (for 64-bit compatibility)\n view.setUint32(offset, model.originalSize & 0xFFFFFFFF, true); offset += 4;\n view.setUint32(offset, (model.originalSize / 0x100000000) >>> 0, true); offset += 4;\n view.setUint32(offset, model.weights.length, true); offset += 4;\n \n // Write weights\n for (const weight of model.weights) {\n const nameBytes = encoder.encode(weight.name);\n const dtypeBytes = encoder.encode(weight.dtype);\n const origDtypeBytes = encoder.encode(weight.originalDtype);\n \n // Name\n view.setUint32(offset, nameBytes.length, true); offset += 4;\n uint8.set(nameBytes, offset); offset += nameBytes.length;\n \n // Shape\n view.setUint32(offset, weight.shape.length, true); offset += 4;\n for (const dim of weight.shape) {\n view.setInt32(offset, dim, true); offset += 4;\n }\n \n // Dtype\n view.setUint32(offset, dtypeBytes.length, true); offset += 4;\n uint8.set(dtypeBytes, offset); offset += dtypeBytes.length;\n \n // Original dtype\n view.setUint32(offset, origDtypeBytes.length, true); offset += 4;\n uint8.set(origDtypeBytes, offset); offset += origDtypeBytes.length;\n \n // Scale\n if (weight.scale !== undefined) {\n view.setUint8(offset, 1); offset += 1;\n if (Array.isArray(weight.scale)) {\n view.setUint32(offset, weight.scale.length, true); offset += 4;\n for (const s of weight.scale) {\n view.setFloat32(offset, s, true); offset += 4;\n }\n } else {\n view.setUint32(offset, 1, true); offset += 4;\n view.setFloat32(offset, weight.scale, true); offset += 4;\n }\n } else {\n view.setUint8(offset, 0); offset += 1;\n }\n \n // Zero point\n if (weight.zeroPoint !== undefined) {\n view.setUint8(offset, 1); offset += 1;\n if (Array.isArray(weight.zeroPoint)) {\n view.setUint32(offset, weight.zeroPoint.length, true); offset += 4;\n for (const zp of weight.zeroPoint) {\n view.setInt32(offset, zp, true); offset += 4;\n }\n } else {\n view.setUint32(offset, 1, true); offset += 4;\n view.setInt32(offset, weight.zeroPoint, true); offset += 4;\n }\n } else {\n view.setUint8(offset, 0); offset += 1;\n }\n \n // Data\n const dataLow = weight.data.byteLength & 0xFFFFFFFF;\n const dataHigh = (weight.data.byteLength / 0x100000000) >>> 0;\n view.setUint32(offset, dataLow, true); offset += 4;\n view.setUint32(offset, dataHigh, true); offset += 4;\n uint8.set(new Uint8Array(weight.data), offset); offset += weight.data.byteLength;\n }\n \n return buffer;\n}\n\n/**\n * Quantize a model\n */\nexport async function quantizeModel(\n modelData: ArrayBuffer,\n options: QuantizationOptions\n): Promise<QuantizationResult> {\n const {\n type,\n skipPatterns = [],\n perChannel = false,\n symmetric = true,\n onProgress,\n minTensorSize = 100,\n } = options;\n \n const originalSize = modelData.byteLength;\n const layerStats: LayerQuantizationStats[] = [];\n let tensorsQuantized = 0;\n let tensorsSkipped = 0;\n \n // Parse model weights\n onProgress?.({ stage: 'analyzing', current: 0, total: 1, percent: 0 });\n const weights = parseModelWeights(modelData);\n \n const quantizedWeights: QuantizedModel['weights'] = [];\n let totalParams = 0;\n let quantizedParams = 0;\n const scales: number[] = [];\n \n // Quantize each weight tensor\n for (let i = 0; i < weights.length; i++) {\n const weight = weights[i]!;\n const percent = ((i + 1) / weights.length) * 100;\n \n onProgress?.({\n stage: 'quantizing',\n current: i + 1,\n total: weights.length,\n percent,\n layerName: weight.name,\n });\n \n totalParams += weight.data.length;\n \n // Check if should skip\n const shouldSkip = \n weight.data.length < minTensorSize ||\n skipPatterns.some(pattern => {\n if (typeof pattern === 'string') {\n return weight.name.includes(pattern);\n }\n return pattern.test(weight.name);\n });\n \n if (shouldSkip) {\n tensorsSkipped++;\n layerStats.push({\n name: weight.name,\n originalDtype: weight.dtype,\n quantizedDtype: weight.dtype,\n originalSize: weight.data.byteLength,\n quantizedSize: weight.data.byteLength,\n scale: 1,\n zeroPoint: 0,\n minValue: Math.min(...weight.data),\n maxValue: Math.max(...weight.data),\n skipped: true,\n skipReason: weight.data.length < minTensorSize \n ? 'Tensor too small' \n : 'Matched skip pattern',\n });\n \n quantizedWeights.push({\n name: weight.name,\n data: weight.data.buffer.slice(0) as ArrayBuffer,\n shape: weight.shape,\n dtype: weight.dtype,\n originalDtype: weight.dtype,\n });\n continue;\n }\n \n // Calculate quantization parameters\n const bits = type === 'int4' ? 4 : 8;\n const params = calculateQuantParams(\n weight.data,\n bits,\n symmetric,\n perChannel,\n 0,\n weight.shape\n );\n \n // Quantize data\n let quantizedData: ArrayBuffer;\n let quantizedDtype: string;\n \n switch (type) {\n case 'int8':\n const int8Data = quantizeToInt8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = int8Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int8';\n break;\n \n case 'uint8':\n const uint8Data = quantizeToUint8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = uint8Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'uint8';\n break;\n \n case 'int4':\n const int4Data = quantizeToInt4(\n weight.data,\n params.scale as number,\n params.zeroPoint as number\n );\n quantizedData = int4Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int4';\n break;\n \n case 'float16':\n const fp16Data = quantizeToFloat16(weight.data);\n quantizedData = fp16Data.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'float16';\n break;\n \n case 'dynamic':\n default:\n // Dynamic quantization: use int8 for weights\n const dynData = quantizeToInt8(\n weight.data,\n params.scale,\n params.zeroPoint,\n perChannel,\n perChannel ? weight.data.length / (weight.shape[0] ?? 1) : weight.data.length\n );\n quantizedData = dynData.buffer.slice(0) as ArrayBuffer;\n quantizedDtype = 'int8';\n break;\n }\n \n tensorsQuantized++;\n quantizedParams += weight.data.length;\n \n const scaleValue = params.scale instanceof Float32Array \n ? Array.from(params.scale)\n : params.scale;\n const zpValue = params.zeroPoint instanceof Int32Array\n ? Array.from(params.zeroPoint)\n : params.zeroPoint;\n \n if (typeof scaleValue === 'number') {\n scales.push(scaleValue);\n } else {\n scales.push(...scaleValue);\n }\n \n layerStats.push({\n name: weight.name,\n originalDtype: weight.dtype,\n quantizedDtype,\n originalSize: weight.data.byteLength,\n quantizedSize: quantizedData.byteLength,\n scale: scaleValue,\n zeroPoint: zpValue,\n minValue: params.min,\n maxValue: params.max,\n skipped: false,\n });\n \n quantizedWeights.push({\n name: weight.name,\n data: quantizedData,\n shape: weight.shape,\n dtype: quantizedDtype,\n originalDtype: weight.dtype,\n scale: scaleValue,\n zeroPoint: zpValue,\n });\n }\n \n // Pack into final format\n onProgress?.({ stage: 'packing', current: 0, total: 1, percent: 0 });\n \n const quantizedModel: QuantizedModel = {\n version: 1,\n quantizationType: type,\n originalSize,\n weights: quantizedWeights,\n };\n \n const quantizedData = serializeQuantizedModel(quantizedModel);\n \n onProgress?.({ stage: 'complete', current: 1, total: 1, percent: 100 });\n \n // Calculate statistics\n const avgScale = scales.length > 0 \n ? scales.reduce((a, b) => a + b, 0) / scales.length \n : 1;\n const minScale = scales.length > 0 ? Math.min(...scales) : 1;\n const maxScale = scales.length > 0 ? Math.max(...scales) : 1;\n \n // Estimate quantization error (very rough approximation)\n const bitsReduction = type === 'int4' ? 8 : type === 'float16' ? 2 : 4;\n const errorEstimate = avgScale / bitsReduction;\n \n return {\n data: quantizedData,\n originalSize,\n quantizedSize: quantizedData.byteLength,\n compressionRatio: originalSize / quantizedData.byteLength,\n tensorsQuantized,\n tensorsSkipped,\n layerStats,\n stats: {\n totalParameters: totalParams,\n quantizedParameters: quantizedParams,\n averageScale: avgScale,\n minScale,\n maxScale,\n errorEstimate,\n },\n };\n}\n\n// ============================================================================\n// Tensor Quantization (for individual tensors)\n// ============================================================================\n\n/**\n * Quantize a single EdgeFlowTensor\n */\nexport function quantizeTensor(\n tensor: EdgeFlowTensor,\n type: QuantizationType,\n options: { symmetric?: boolean; perChannel?: boolean } = {}\n): {\n tensor: EdgeFlowTensor;\n scale: number | number[];\n zeroPoint: number | number[];\n} {\n const { symmetric = true, perChannel = false } = options;\n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n \n const bits = type === 'int4' ? 4 : 8;\n const params = calculateQuantParams(\n data,\n bits,\n symmetric,\n perChannel,\n 0,\n shape\n );\n \n let quantizedData: Int8Array | Uint8Array | Uint16Array;\n let dtype: DataType;\n \n switch (type) {\n case 'int8':\n quantizedData = quantizeToInt8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32'; // Store as int32 since we don't have int8 dtype\n break;\n \n case 'uint8':\n quantizedData = quantizeToUint8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32';\n break;\n \n case 'float16':\n quantizedData = quantizeToFloat16(data);\n dtype = 'float32'; // Will be stored differently\n break;\n \n default:\n quantizedData = quantizeToInt8(\n data,\n params.scale,\n params.zeroPoint,\n perChannel\n );\n dtype = 'int32';\n }\n \n const scaleValue = params.scale instanceof Float32Array\n ? Array.from(params.scale)\n : params.scale;\n const zpValue = params.zeroPoint instanceof Int32Array\n ? Array.from(params.zeroPoint)\n : params.zeroPoint;\n \n return {\n tensor: new EdgeFlowTensor(Array.from(quantizedData), shape, dtype),\n scale: scaleValue,\n zeroPoint: zpValue,\n };\n}\n\n/**\n * Dequantize a tensor back to float32\n */\nexport function dequantizeTensor(\n tensor: EdgeFlowTensor,\n scale: number | number[],\n zeroPoint: number | number[],\n type: QuantizationType\n): EdgeFlowTensor {\n const data = tensor.toArray();\n const shape = tensor.shape as number[];\n \n let dequantizedData: Float32Array;\n \n const scaleArr = Array.isArray(scale) ? new Float32Array(scale) : scale;\n const zpArr = Array.isArray(zeroPoint) ? new Int32Array(zeroPoint) : zeroPoint;\n const perChannel = Array.isArray(scale);\n \n switch (type) {\n case 'int8':\n dequantizedData = dequantizeInt8(\n new Int8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n break;\n \n case 'uint8':\n dequantizedData = dequantizeUint8(\n new Uint8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n break;\n \n case 'float16':\n dequantizedData = dequantizeFloat16(new Uint16Array(data.map(Number)));\n break;\n \n default:\n dequantizedData = dequantizeInt8(\n new Int8Array(data.map(Number)),\n scaleArr,\n zpArr,\n perChannel\n );\n }\n \n return new EdgeFlowTensor(Array.from(dequantizedData), shape, 'float32');\n}\n\n// ============================================================================\n// Pruning\n// ============================================================================\n\n/**\n * Pruning options\n */\nexport interface PruningOptions {\n /** Pruning ratio (0-1, default: 0.5 = 50% sparsity) */\n ratio?: number;\n \n /** Pruning method */\n method?: 'magnitude' | 'random' | 'structured';\n \n /** For structured pruning: dimension to prune along */\n dim?: number;\n \n /** Minimum absolute value to keep */\n threshold?: number;\n \n /** Progress callback */\n onProgress?: (progress: { current: number; total: number; percent: number }) => void;\n}\n\n/**\n * Pruning result\n */\nexport interface PruningResult {\n /** Pruned model data */\n data: ArrayBuffer;\n \n /** Original size */\n originalSize: number;\n \n /** Pruned size (sparse representation) */\n prunedSize: number;\n \n /** Sparsity ratio achieved */\n sparsity: number;\n \n /** Number of parameters pruned */\n parametersPruned: number;\n \n /** Total parameters */\n totalParameters: number;\n}\n\n/**\n * Prune a tensor using magnitude-based pruning\n */\nexport function pruneTensor(\n tensor: EdgeFlowTensor,\n options: PruningOptions = {}\n): {\n tensor: EdgeFlowTensor;\n mask: EdgeFlowTensor;\n sparsity: number;\n} {\n const { ratio = 0.5, method = 'magnitude', threshold } = options;\n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n \n const mask = new Float32Array(data.length);\n const prunedData = new Float32Array(data.length);\n let prunedCount = 0;\n \n if (method === 'magnitude') {\n // Get threshold based on ratio\n const absValues = Array.from(data).map(Math.abs).sort((a, b) => a - b);\n const thresholdIndex = Math.floor(absValues.length * ratio);\n const computedThreshold = threshold ?? (absValues[thresholdIndex] ?? 0);\n \n for (let i = 0; i < data.length; i++) {\n if (Math.abs(data[i] ?? 0) > computedThreshold) {\n mask[i] = 1;\n prunedData[i] = data[i] ?? 0;\n } else {\n mask[i] = 0;\n prunedData[i] = 0;\n prunedCount++;\n }\n }\n } else if (method === 'random') {\n for (let i = 0; i < data.length; i++) {\n if (Math.random() > ratio) {\n mask[i] = 1;\n prunedData[i] = data[i] ?? 0;\n } else {\n mask[i] = 0;\n prunedData[i] = 0;\n prunedCount++;\n }\n }\n }\n \n return {\n tensor: new EdgeFlowTensor(Array.from(prunedData), shape, 'float32'),\n mask: new EdgeFlowTensor(Array.from(mask), shape, 'float32'),\n sparsity: prunedCount / data.length,\n };\n}\n\n/**\n * Prune a model\n */\nexport async function pruneModel(\n modelData: ArrayBuffer,\n options: PruningOptions = {}\n): Promise<PruningResult> {\n const { onProgress } = options;\n \n onProgress?.({ current: 0, total: 1, percent: 0 });\n \n // This is a simplified implementation\n // Real implementation would parse the model properly\n const weights = parseModelWeights(modelData);\n let totalParams = 0;\n let prunedParams = 0;\n \n for (const weight of weights) {\n totalParams += weight.data.length;\n \n const tensor = new EdgeFlowTensor(\n Array.from(weight.data),\n weight.shape,\n 'float32'\n );\n \n const { sparsity } = pruneTensor(tensor, options);\n prunedParams += Math.floor(weight.data.length * sparsity);\n }\n \n onProgress?.({ current: 1, total: 1, percent: 100 });\n \n return {\n data: modelData, // In a real implementation, we'd create a sparse format\n originalSize: modelData.byteLength,\n prunedSize: modelData.byteLength, // Would be smaller with sparse format\n sparsity: prunedParams / totalParams,\n parametersPruned: prunedParams,\n totalParameters: totalParams,\n };\n}\n\n// ============================================================================\n// Model Analysis\n// ============================================================================\n\n/**\n * Model analysis result\n */\nexport interface ModelAnalysis {\n /** Total model size in bytes */\n totalSize: number;\n \n /** Number of tensors */\n tensorCount: number;\n \n /** Total number of parameters */\n totalParameters: number;\n \n /** Parameter breakdown by dtype */\n dtypeBreakdown: Record<string, { count: number; size: number }>;\n \n /** Largest tensors */\n largestTensors: Array<{ name: string; size: number; shape: number[] }>;\n \n /** Estimated memory usage at runtime */\n estimatedMemory: number;\n \n /** Recommended quantization type */\n recommendedQuantization: QuantizationType;\n \n /** Estimated size after quantization */\n estimatedQuantizedSizes: Record<QuantizationType, number>;\n}\n\n/**\n * Analyze a model\n */\nexport async function analyzeModel(modelData: ArrayBuffer): Promise<ModelAnalysis> {\n const weights = parseModelWeights(modelData);\n const totalSize = modelData.byteLength;\n \n const dtypeBreakdown: Record<string, { count: number; size: number }> = {};\n let totalParams = 0;\n \n const tensorInfos: Array<{ name: string; size: number; shape: number[] }> = [];\n \n for (const weight of weights) {\n totalParams += weight.data.length;\n \n const bytesPerElement = weight.dtype === 'float32' ? 4 \n : weight.dtype === 'float16' ? 2 \n : weight.dtype === 'int8' ? 1 \n : 4;\n const size = weight.data.length * bytesPerElement;\n \n if (!dtypeBreakdown[weight.dtype]) {\n dtypeBreakdown[weight.dtype] = { count: 0, size: 0 };\n }\n dtypeBreakdown[weight.dtype]!.count++;\n dtypeBreakdown[weight.dtype]!.size += size;\n \n tensorInfos.push({\n name: weight.name,\n size,\n shape: weight.shape,\n });\n }\n \n // Sort by size and get top 10\n tensorInfos.sort((a, b) => b.size - a.size);\n const largestTensors = tensorInfos.slice(0, 10);\n \n // Estimate quantized sizes\n const estimatedQuantizedSizes: Record<QuantizationType, number> = {\n int8: Math.ceil(totalSize / 4),\n uint8: Math.ceil(totalSize / 4),\n int4: Math.ceil(totalSize / 8),\n float16: Math.ceil(totalSize / 2),\n dynamic: Math.ceil(totalSize / 4),\n };\n \n // Recommend quantization based on model size\n let recommendedQuantization: QuantizationType = 'dynamic';\n if (totalSize > 500 * 1024 * 1024) {\n recommendedQuantization = 'int4';\n } else if (totalSize > 100 * 1024 * 1024) {\n recommendedQuantization = 'int8';\n } else if (totalSize > 50 * 1024 * 1024) {\n recommendedQuantization = 'float16';\n }\n \n return {\n totalSize,\n tensorCount: weights.length,\n totalParameters: totalParams,\n dtypeBreakdown,\n largestTensors,\n estimatedMemory: totalParams * 4, // Assuming float32 at runtime\n recommendedQuantization,\n estimatedQuantizedSizes,\n };\n}\n\n// ============================================================================\n// Export Model\n// ============================================================================\n\n/**\n * Export format\n */\nexport type ExportFormat = 'onnx' | 'tflite' | 'edgeflow';\n\n/**\n * Export options\n */\nexport interface ExportOptions {\n format: ExportFormat;\n optimize?: boolean;\n quantize?: QuantizationType;\n}\n\n/**\n * Export a model to different formats\n * Note: This is a placeholder - real implementation would require proper format conversion\n */\nexport async function exportModel(\n modelData: ArrayBuffer,\n options: ExportOptions\n): Promise<ArrayBuffer> {\n const { format, quantize } = options;\n \n // Apply quantization if requested\n let data = modelData;\n if (quantize) {\n const result = await quantizeModel(modelData, { type: quantize });\n data = result.data;\n }\n \n // Format conversion would happen here\n // For now, we just return the (possibly quantized) data\n switch (format) {\n case 'edgeflow':\n return data;\n case 'onnx':\n // Would convert to ONNX format\n return data;\n case 'tflite':\n // Would convert to TFLite format\n return data;\n default:\n return data;\n }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModel,\n exportModel,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n};\n", "/**\n * edgeFlow.js - Visual Debugging Tools\n * \n * In-browser debugging and visualization utilities for ML models.\n */\n\nimport { EdgeFlowTensor } from '../core/index.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Debugger configuration\n */\nexport interface DebuggerConfig {\n /** Enable logging */\n logging?: boolean;\n \n /** Log level */\n logLevel?: 'debug' | 'info' | 'warn' | 'error';\n \n /** Enable tensor inspection */\n inspectTensors?: boolean;\n \n /** Maximum values to display per tensor */\n maxDisplayValues?: number;\n \n /** Enable performance tracking */\n trackPerformance?: boolean;\n \n /** Custom logger function */\n logger?: (level: string, message: string, data?: unknown) => void;\n}\n\n/**\n * Tensor inspection result\n */\nexport interface TensorInspection {\n name: string;\n shape: number[];\n dtype: string;\n size: number;\n memoryBytes: number;\n stats: TensorStats;\n sample: number[];\n histogram?: HistogramData;\n}\n\n/**\n * Tensor statistics\n */\nexport interface TensorStats {\n min: number;\n max: number;\n mean: number;\n std: number;\n zeros: number;\n nans: number;\n infinities: number;\n sparsity: number;\n}\n\n/**\n * Histogram data\n */\nexport interface HistogramData {\n bins: number[];\n counts: number[];\n binEdges: number[];\n}\n\n/**\n * Inference trace\n */\nexport interface InferenceTrace {\n id: string;\n modelId: string;\n timestamp: number;\n inputs: TensorInspection[];\n outputs: TensorInspection[];\n duration: number;\n memoryUsed: number;\n operations: OperationTrace[];\n}\n\n/**\n * Operation trace\n */\nexport interface OperationTrace {\n name: string;\n type: string;\n duration: number;\n inputShapes: number[][];\n outputShapes: number[][];\n attributes?: Record<string, unknown>;\n}\n\n/**\n * Debug event\n */\nexport interface DebugEvent {\n type: 'tensor' | 'inference' | 'error' | 'warning' | 'info' | 'performance';\n timestamp: number;\n data: unknown;\n message: string;\n}\n\n/**\n * Performance metrics\n */\nexport interface PerformanceMetrics {\n inferenceCount: number;\n totalInferenceTime: number;\n averageInferenceTime: number;\n minInferenceTime: number;\n maxInferenceTime: number;\n peakMemoryUsage: number;\n currentMemoryUsage: number;\n tensorAllocations: number;\n tensorDeallocations: number;\n}\n\n// ============================================================================\n// Tensor Inspection\n// ============================================================================\n\n/**\n * Calculate tensor statistics\n */\nfunction calculateTensorStats(data: Float32Array | number[]): TensorStats {\n const arr = data instanceof Float32Array ? data : new Float32Array(data);\n \n let min = Infinity;\n let max = -Infinity;\n let sum = 0;\n let zeros = 0;\n let nans = 0;\n let infinities = 0;\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n \n if (isNaN(val)) {\n nans++;\n continue;\n }\n \n if (!isFinite(val)) {\n infinities++;\n continue;\n }\n \n min = Math.min(min, val);\n max = Math.max(max, val);\n sum += val;\n \n if (val === 0) zeros++;\n }\n \n const validCount = arr.length - nans - infinities;\n const mean = validCount > 0 ? sum / validCount : 0;\n \n // Calculate std\n let varianceSum = 0;\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n varianceSum += Math.pow(val - mean, 2);\n }\n }\n const std = validCount > 0 ? Math.sqrt(varianceSum / validCount) : 0;\n \n return {\n min: min === Infinity ? 0 : min,\n max: max === -Infinity ? 0 : max,\n mean,\n std,\n zeros,\n nans,\n infinities,\n sparsity: zeros / arr.length,\n };\n}\n\n/**\n * Create histogram from data\n */\nfunction createHistogram(data: Float32Array | number[], bins: number = 50): HistogramData {\n const arr = data instanceof Float32Array ? data : new Float32Array(data);\n \n // Find min/max (excluding NaN/Inf)\n let min = Infinity;\n let max = -Infinity;\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n \n if (min === Infinity || max === -Infinity || min === max) {\n return { bins: [min || 0], counts: [arr.length], binEdges: [min || 0, max || 0] };\n }\n \n const binWidth = (max - min) / bins;\n const counts = new Array(bins).fill(0);\n const binEdges = new Array(bins + 1);\n \n for (let i = 0; i <= bins; i++) {\n binEdges[i] = min + i * binWidth;\n }\n \n for (let i = 0; i < arr.length; i++) {\n const val = arr[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n const binIndex = Math.min(Math.floor((val - min) / binWidth), bins - 1);\n counts[binIndex]++;\n }\n }\n \n return {\n bins: binEdges.slice(0, -1).map((e, i) => (e + binEdges[i + 1]!) / 2),\n counts,\n binEdges,\n };\n}\n\n/**\n * Inspect a tensor\n */\nexport function inspectTensor(\n tensor: EdgeFlowTensor,\n name: string = 'tensor',\n options: { histogram?: boolean; maxSample?: number } = {}\n): TensorInspection {\n const { histogram = true, maxSample = 10 } = options;\n \n const data = tensor.toFloat32Array();\n const shape = tensor.shape as number[];\n const size = tensor.size;\n \n // Get sample of values\n const sampleIndices = [];\n const step = Math.max(1, Math.floor(size / maxSample));\n for (let i = 0; i < size && sampleIndices.length < maxSample; i += step) {\n sampleIndices.push(i);\n }\n const sample = sampleIndices.map(i => data[i] ?? 0);\n \n // Calculate memory (assuming float32)\n const bytesPerElement = tensor.dtype === 'float32' ? 4 \n : tensor.dtype === 'int32' ? 4 \n : tensor.dtype === 'int64' ? 8 \n : 4;\n const memoryBytes = size * bytesPerElement;\n \n return {\n name,\n shape,\n dtype: tensor.dtype,\n size,\n memoryBytes,\n stats: calculateTensorStats(data),\n sample,\n histogram: histogram ? createHistogram(data) : undefined,\n };\n}\n\n/**\n * Format tensor inspection for display\n */\nexport function formatTensorInspection(inspection: TensorInspection): string {\n const { name, shape, dtype, size, memoryBytes, stats, sample } = inspection;\n \n const lines = [\n `\u250C\u2500 Tensor: ${name} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,\n `\u2502 Shape: [${shape.join(', ')}]`,\n `\u2502 Dtype: ${dtype}`,\n `\u2502 Size: ${size.toLocaleString()} elements`,\n `\u2502 Memory: ${formatBytes(memoryBytes)}`,\n `\u251C\u2500 Statistics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`,\n `\u2502 Min: ${stats.min.toFixed(6)}`,\n `\u2502 Max: ${stats.max.toFixed(6)}`,\n `\u2502 Mean: ${stats.mean.toFixed(6)}`,\n `\u2502 Std: ${stats.std.toFixed(6)}`,\n `\u2502 Sparsity: ${(stats.sparsity * 100).toFixed(2)}%`,\n ];\n \n if (stats.nans > 0) {\n lines.push(`\u2502 \u26A0\uFE0F NaN values: ${stats.nans}`);\n }\n if (stats.infinities > 0) {\n lines.push(`\u2502 \u26A0\uFE0F Infinity values: ${stats.infinities}`);\n }\n \n lines.push(`\u251C\u2500 Sample Values \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);\n lines.push(`\u2502 [${sample.map(v => v.toFixed(4)).join(', ')}]`);\n lines.push(`\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);\n \n return lines.join('\\n');\n}\n\n/**\n * Format bytes to human readable\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n// ============================================================================\n// Visual Debugger Class\n// ============================================================================\n\n/**\n * Visual debugger for edgeFlow.js\n */\nexport class EdgeFlowDebugger {\n private config: Required<DebuggerConfig>;\n private events: DebugEvent[] = [];\n private traces: InferenceTrace[] = [];\n private performanceMetrics: PerformanceMetrics;\n private listeners: Map<string, Array<(event: DebugEvent) => void>> = new Map();\n private isEnabled: boolean = true;\n \n constructor(config: DebuggerConfig = {}) {\n this.config = {\n logging: config.logging ?? true,\n logLevel: config.logLevel ?? 'info',\n inspectTensors: config.inspectTensors ?? true,\n maxDisplayValues: config.maxDisplayValues ?? 10,\n trackPerformance: config.trackPerformance ?? true,\n logger: config.logger ?? this.defaultLogger.bind(this),\n };\n \n this.performanceMetrics = {\n inferenceCount: 0,\n totalInferenceTime: 0,\n averageInferenceTime: 0,\n minInferenceTime: Infinity,\n maxInferenceTime: 0,\n peakMemoryUsage: 0,\n currentMemoryUsage: 0,\n tensorAllocations: 0,\n tensorDeallocations: 0,\n };\n }\n \n /**\n * Default logger\n */\n private defaultLogger(level: string, message: string, data?: unknown): void {\n const timestamp = new Date().toISOString();\n const prefix = `[edgeFlow.js ${timestamp}] [${level.toUpperCase()}]`;\n \n switch (level) {\n case 'debug':\n console.debug(prefix, message, data ?? '');\n break;\n case 'info':\n console.info(prefix, message, data ?? '');\n break;\n case 'warn':\n console.warn(prefix, message, data ?? '');\n break;\n case 'error':\n console.error(prefix, message, data ?? '');\n break;\n default:\n console.log(prefix, message, data ?? '');\n }\n }\n \n /**\n * Log a message\n */\n log(level: string, message: string, data?: unknown): void {\n if (!this.isEnabled || !this.config.logging) return;\n \n const levels = ['debug', 'info', 'warn', 'error'];\n const configLevel = levels.indexOf(this.config.logLevel);\n const msgLevel = levels.indexOf(level);\n \n if (msgLevel >= configLevel) {\n this.config.logger(level, message, data);\n }\n }\n \n /**\n * Add debug event\n */\n private addEvent(event: DebugEvent): void {\n this.events.push(event);\n \n // Notify listeners\n const listeners = this.listeners.get(event.type) ?? [];\n for (const listener of listeners) {\n listener(event);\n }\n \n // Keep only last 1000 events\n if (this.events.length > 1000) {\n this.events = this.events.slice(-1000);\n }\n }\n \n /**\n * Enable debugger\n */\n enable(): void {\n this.isEnabled = true;\n this.log('info', 'Debugger enabled');\n }\n \n /**\n * Disable debugger\n */\n disable(): void {\n this.isEnabled = false;\n }\n \n /**\n * Subscribe to events\n */\n on(type: string, callback: (event: DebugEvent) => void): () => void {\n const listeners = this.listeners.get(type) ?? [];\n listeners.push(callback);\n this.listeners.set(type, listeners);\n \n return () => {\n const idx = listeners.indexOf(callback);\n if (idx !== -1) listeners.splice(idx, 1);\n };\n }\n \n /**\n * Inspect and log a tensor\n */\n inspectTensor(tensor: EdgeFlowTensor, name: string = 'tensor'): TensorInspection {\n const inspection = inspectTensor(tensor, name, {\n histogram: true,\n maxSample: this.config.maxDisplayValues,\n });\n \n if (this.config.inspectTensors) {\n this.log('debug', `Tensor: ${name}`, inspection);\n \n this.addEvent({\n type: 'tensor',\n timestamp: Date.now(),\n message: `Inspected tensor: ${name}`,\n data: inspection,\n });\n \n // Check for issues\n if (inspection.stats.nans > 0) {\n this.log('warn', `Tensor \"${name}\" contains ${inspection.stats.nans} NaN values`);\n }\n if (inspection.stats.infinities > 0) {\n this.log('warn', `Tensor \"${name}\" contains ${inspection.stats.infinities} Infinity values`);\n }\n }\n \n return inspection;\n }\n \n /**\n * Start tracing an inference\n */\n startTrace(modelId: string): string {\n const id = `trace_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n \n const trace: InferenceTrace = {\n id,\n modelId,\n timestamp: Date.now(),\n inputs: [],\n outputs: [],\n duration: 0,\n memoryUsed: 0,\n operations: [],\n };\n \n this.traces.push(trace);\n \n this.log('debug', `Started trace: ${id} for model: ${modelId}`);\n \n return id;\n }\n \n /**\n * Add input to trace\n */\n traceInput(traceId: string, tensor: EdgeFlowTensor, name: string): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.inputs.push(inspectTensor(tensor, name));\n }\n \n /**\n * Add output to trace\n */\n traceOutput(traceId: string, tensor: EdgeFlowTensor, name: string): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.outputs.push(inspectTensor(tensor, name));\n }\n \n /**\n * Add operation to trace\n */\n traceOperation(traceId: string, operation: OperationTrace): void {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.operations.push(operation);\n }\n \n /**\n * End trace\n */\n endTrace(traceId: string): InferenceTrace | undefined {\n const trace = this.traces.find(t => t.id === traceId);\n if (!trace) return;\n \n trace.duration = Date.now() - trace.timestamp;\n \n // Update performance metrics\n this.performanceMetrics.inferenceCount++;\n this.performanceMetrics.totalInferenceTime += trace.duration;\n this.performanceMetrics.averageInferenceTime = \n this.performanceMetrics.totalInferenceTime / this.performanceMetrics.inferenceCount;\n this.performanceMetrics.minInferenceTime = \n Math.min(this.performanceMetrics.minInferenceTime, trace.duration);\n this.performanceMetrics.maxInferenceTime = \n Math.max(this.performanceMetrics.maxInferenceTime, trace.duration);\n \n this.log('info', `Trace completed: ${traceId}`, {\n duration: `${trace.duration}ms`,\n inputs: trace.inputs.length,\n outputs: trace.outputs.length,\n operations: trace.operations.length,\n });\n \n this.addEvent({\n type: 'inference',\n timestamp: Date.now(),\n message: `Inference completed in ${trace.duration}ms`,\n data: trace,\n });\n \n return trace;\n }\n \n /**\n * Record tensor allocation\n */\n recordAllocation(tensor: EdgeFlowTensor): void {\n if (!this.config.trackPerformance) return;\n \n this.performanceMetrics.tensorAllocations++;\n const memory = tensor.size * 4; // Assume float32\n this.performanceMetrics.currentMemoryUsage += memory;\n this.performanceMetrics.peakMemoryUsage = Math.max(\n this.performanceMetrics.peakMemoryUsage,\n this.performanceMetrics.currentMemoryUsage\n );\n }\n \n /**\n * Record tensor deallocation\n */\n recordDeallocation(tensor: EdgeFlowTensor): void {\n if (!this.config.trackPerformance) return;\n \n this.performanceMetrics.tensorDeallocations++;\n const memory = tensor.size * 4;\n this.performanceMetrics.currentMemoryUsage -= memory;\n }\n \n /**\n * Get performance metrics\n */\n getPerformanceMetrics(): PerformanceMetrics {\n return { ...this.performanceMetrics };\n }\n \n /**\n * Get all events\n */\n getEvents(): DebugEvent[] {\n return [...this.events];\n }\n \n /**\n * Get all traces\n */\n getTraces(): InferenceTrace[] {\n return [...this.traces];\n }\n \n /**\n * Get trace by ID\n */\n getTrace(traceId: string): InferenceTrace | undefined {\n return this.traces.find(t => t.id === traceId);\n }\n \n /**\n * Clear all data\n */\n clear(): void {\n this.events = [];\n this.traces = [];\n this.performanceMetrics = {\n inferenceCount: 0,\n totalInferenceTime: 0,\n averageInferenceTime: 0,\n minInferenceTime: Infinity,\n maxInferenceTime: 0,\n peakMemoryUsage: 0,\n currentMemoryUsage: 0,\n tensorAllocations: 0,\n tensorDeallocations: 0,\n };\n }\n \n /**\n * Export debug data\n */\n export(): {\n events: DebugEvent[];\n traces: InferenceTrace[];\n metrics: PerformanceMetrics;\n timestamp: number;\n } {\n return {\n events: this.getEvents(),\n traces: this.getTraces(),\n metrics: this.getPerformanceMetrics(),\n timestamp: Date.now(),\n };\n }\n \n /**\n * Generate summary report\n */\n generateReport(): string {\n const metrics = this.getPerformanceMetrics();\n const traces = this.getTraces();\n \n const lines = [\n '\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557',\n '\u2551 edgeFlow.js Debug Report \u2551',\n '\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563',\n '\u2551 Performance Metrics \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n `\u2551 Total Inferences: ${metrics.inferenceCount.toString().padStart(10)} \u2551`,\n `\u2551 Average Time: ${metrics.averageInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Min Time: ${(metrics.minInferenceTime === Infinity ? 0 : metrics.minInferenceTime).toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Max Time: ${metrics.maxInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Peak Memory: ${formatBytes(metrics.peakMemoryUsage).padStart(10)} \u2551`,\n `\u2551 Current Memory: ${formatBytes(metrics.currentMemoryUsage).padStart(10)} \u2551`,\n `\u2551 Tensor Allocations: ${metrics.tensorAllocations.toString().padStart(10)} \u2551`,\n `\u2551 Tensor Deallocations: ${metrics.tensorDeallocations.toString().padStart(10)} \u2551`,\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Recent Traces \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n ];\n \n const recentTraces = traces.slice(-5);\n for (const trace of recentTraces) {\n lines.push(`\u2551 ${trace.id.slice(0, 20).padEnd(20)} | ${trace.duration.toFixed(2).padStart(8)}ms | ${trace.modelId.slice(0, 20).padEnd(20)} \u2551`);\n }\n \n if (recentTraces.length === 0) {\n lines.push('\u2551 No traces recorded \u2551');\n }\n \n lines.push('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D');\n \n return lines.join('\\n');\n }\n}\n\n// ============================================================================\n// Global Debugger Instance\n// ============================================================================\n\nlet globalDebugger: EdgeFlowDebugger | null = null;\n\n/**\n * Get or create the global debugger instance\n */\nexport function getDebugger(config?: DebuggerConfig): EdgeFlowDebugger {\n if (!globalDebugger || config) {\n globalDebugger = new EdgeFlowDebugger(config);\n }\n return globalDebugger;\n}\n\n/**\n * Enable debugging\n */\nexport function enableDebugging(config?: DebuggerConfig): EdgeFlowDebugger {\n const debugger_ = getDebugger(config);\n debugger_.enable();\n return debugger_;\n}\n\n/**\n * Disable debugging\n */\nexport function disableDebugging(): void {\n globalDebugger?.disable();\n}\n\n// ============================================================================\n// Visualization Helpers\n// ============================================================================\n\n/**\n * Create ASCII histogram\n */\nexport function createAsciiHistogram(histogram: HistogramData, width: number = 50, height: number = 10): string {\n const { counts, binEdges } = histogram;\n const maxCount = Math.max(...counts);\n \n if (maxCount === 0) return 'No data to display';\n \n const lines: string[] = [];\n \n // Scale counts to height\n const scaled = counts.map(c => Math.round((c / maxCount) * height));\n \n // Create rows\n for (let row = height; row > 0; row--) {\n let line = row === height ? `${maxCount.toString().padStart(6)} \u2502` : ' \u2502';\n \n for (let col = 0; col < width && col < scaled.length; col++) {\n line += (scaled[col] ?? 0) >= row ? '\u2588' : ' ';\n }\n \n lines.push(line);\n }\n \n // X axis\n lines.push(' \u2514' + '\u2500'.repeat(Math.min(width, scaled.length)));\n \n // Labels\n const minLabel = (binEdges[0] ?? 0).toFixed(2);\n const maxLabel = (binEdges[binEdges.length - 1] ?? 0).toFixed(2);\n lines.push(` ${minLabel}${' '.repeat(Math.max(0, Math.min(width, scaled.length) - minLabel.length - maxLabel.length))}${maxLabel}`);\n \n return lines.join('\\n');\n}\n\n/**\n * Create tensor heatmap (for 2D tensors)\n */\nexport function createTensorHeatmap(tensor: EdgeFlowTensor, width: number = 40): string {\n const shape = tensor.shape as number[];\n \n if (shape.length !== 2) {\n return 'Heatmap only supports 2D tensors';\n }\n \n const [rows, cols] = shape;\n if (rows === undefined || cols === undefined) {\n return 'Invalid tensor shape';\n }\n \n const data = tensor.toFloat32Array();\n \n // Find min/max\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < data.length; i++) {\n const val = data[i] ?? 0;\n if (!isNaN(val) && isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n \n const range = max - min;\n const chars = [' ', '\u2591', '\u2592', '\u2593', '\u2588'];\n \n const lines: string[] = [];\n const scaleX = Math.max(1, Math.ceil(cols / width));\n const displayCols = Math.min(cols, width);\n \n for (let r = 0; r < rows; r++) {\n let line = '';\n for (let c = 0; c < displayCols; c++) {\n const idx = r * cols + c * scaleX;\n const val = data[idx] ?? 0;\n const normalized = range > 0 ? (val - min) / range : 0;\n const charIdx = Math.floor(normalized * (chars.length - 1));\n line += chars[charIdx];\n }\n lines.push(line);\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Create model architecture visualization\n */\nexport function visualizeModelArchitecture(\n layers: Array<{ name: string; type: string; inputShape: number[]; outputShape: number[] }>\n): string {\n const lines: string[] = [];\n \n lines.push('\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510');\n lines.push('\u2502 Model Architecture \u2502');\n lines.push('\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524');\n \n for (let i = 0; i < layers.length; i++) {\n const layer = layers[i]!;\n const inputStr = `[${layer.inputShape.join('\u00D7')}]`;\n const outputStr = `[${layer.outputShape.join('\u00D7')}]`;\n \n lines.push(`\u2502 ${(i + 1).toString().padStart(2)}. ${layer.name.padEnd(20)} \u2502 ${layer.type.padEnd(15)} \u2502`);\n lines.push(`\u2502 ${inputStr.padEnd(15)} \u2192 ${outputStr.padEnd(15)} \u2502`);\n \n if (i < layers.length - 1) {\n lines.push('\u2502 \u2193 \u2502');\n }\n }\n \n lines.push('\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518');\n \n return lines.join('\\n');\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n};\n", "/**\n * edgeFlow.js - Performance Monitoring Dashboard\n * \n * Real-time performance monitoring and metrics visualization.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Monitor configuration\n */\nexport interface MonitorConfig {\n /** Enable monitoring (default: true) */\n enabled?: boolean;\n \n /** Sampling interval in ms (default: 1000) */\n sampleInterval?: number;\n \n /** History size (number of samples to keep) */\n historySize?: number;\n \n /** Enable memory monitoring (default: true) */\n monitorMemory?: boolean;\n \n /** Enable FPS monitoring (default: true) */\n monitorFPS?: boolean;\n \n /** Custom metric collectors */\n collectors?: Array<() => Record<string, number>>;\n}\n\n/**\n * Performance sample\n */\nexport interface PerformanceSample {\n timestamp: number;\n inference: InferenceMetrics;\n memory: MemoryMetrics;\n system: SystemMetrics;\n custom: Record<string, number>;\n}\n\n/**\n * Inference metrics\n */\nexport interface InferenceMetrics {\n /** Inferences in the last interval */\n count: number;\n \n /** Average inference time (ms) */\n avgTime: number;\n \n /** Min inference time (ms) */\n minTime: number;\n \n /** Max inference time (ms) */\n maxTime: number;\n \n /** Throughput (inferences per second) */\n throughput: number;\n \n /** Queue length */\n queueLength: number;\n \n /** Active inferences */\n activeCount: number;\n}\n\n/**\n * Memory metrics\n */\nexport interface MemoryMetrics {\n /** Used JS heap size (bytes) */\n usedHeap: number;\n \n /** Total JS heap size (bytes) */\n totalHeap: number;\n \n /** Heap limit (bytes) */\n heapLimit: number;\n \n /** Heap usage percentage */\n heapUsage: number;\n \n /** Tensor memory (bytes) */\n tensorMemory: number;\n \n /** Cache memory (bytes) */\n cacheMemory: number;\n}\n\n/**\n * System metrics\n */\nexport interface SystemMetrics {\n /** Frames per second */\n fps: number;\n \n /** CPU usage estimate (0-1) */\n cpuUsage: number;\n \n /** Time since last sample (ms) */\n deltaTime: number;\n \n /** Browser info */\n userAgent: string;\n \n /** WebGPU available */\n webgpuAvailable: boolean;\n \n /** WebNN available */\n webnnAvailable: boolean;\n}\n\n/**\n * Alert configuration\n */\nexport interface AlertConfig {\n /** Metric name */\n metric: string;\n \n /** Threshold value */\n threshold: number;\n \n /** Comparison operator */\n operator: '>' | '<' | '>=' | '<=' | '==' | '!=';\n \n /** Alert message */\n message: string;\n \n /** Alert level */\n level: 'info' | 'warn' | 'error';\n}\n\n/**\n * Alert event\n */\nexport interface AlertEvent {\n config: AlertConfig;\n value: number;\n timestamp: number;\n}\n\n/**\n * Dashboard widget data\n */\nexport interface WidgetData {\n type: 'chart' | 'gauge' | 'counter' | 'text';\n title: string;\n data: unknown;\n}\n\n// ============================================================================\n// Performance Monitor\n// ============================================================================\n\n/**\n * Performance monitor for edgeFlow.js\n */\nexport class PerformanceMonitor {\n private config: Required<MonitorConfig>;\n private samples: PerformanceSample[] = [];\n private isRunning: boolean = false;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private alerts: AlertConfig[] = [];\n private alertListeners: Array<(alert: AlertEvent) => void> = [];\n private sampleListeners: Array<(sample: PerformanceSample) => void> = [];\n \n // Inference tracking\n private inferenceCount: number = 0;\n private inferenceTimes: number[] = [];\n private queueLength: number = 0;\n private activeCount: number = 0;\n \n // FPS tracking\n private frameCount: number = 0;\n private lastFrameTime: number = 0;\n private fps: number = 0;\n private rafId: number | null = null;\n \n // Memory tracking\n private tensorMemory: number = 0;\n private cacheMemory: number = 0;\n \n constructor(config: MonitorConfig = {}) {\n this.config = {\n enabled: config.enabled ?? true,\n sampleInterval: config.sampleInterval ?? 1000,\n historySize: config.historySize ?? 60,\n monitorMemory: config.monitorMemory ?? true,\n monitorFPS: config.monitorFPS ?? true,\n collectors: config.collectors ?? [],\n };\n }\n \n /**\n * Start monitoring\n */\n start(): void {\n if (this.isRunning) return;\n \n this.isRunning = true;\n \n // Start sampling\n this.intervalId = setInterval(() => {\n this.collectSample();\n }, this.config.sampleInterval);\n \n // Start FPS monitoring\n if (this.config.monitorFPS && typeof requestAnimationFrame !== 'undefined') {\n this.lastFrameTime = performance.now();\n this.frameCount = 0;\n this.monitorFPS();\n }\n }\n \n /**\n * Stop monitoring\n */\n stop(): void {\n this.isRunning = false;\n \n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n \n if (this.rafId) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n \n /**\n * Monitor FPS\n */\n private monitorFPS(): void {\n if (!this.isRunning) return;\n \n this.frameCount++;\n const now = performance.now();\n const elapsed = now - this.lastFrameTime;\n \n if (elapsed >= 1000) {\n this.fps = Math.round((this.frameCount * 1000) / elapsed);\n this.frameCount = 0;\n this.lastFrameTime = now;\n }\n \n this.rafId = requestAnimationFrame(() => this.monitorFPS());\n }\n \n /**\n * Collect a performance sample\n */\n private collectSample(): void {\n const now = Date.now();\n \n // Calculate inference metrics\n const avgTime = this.inferenceTimes.length > 0\n ? this.inferenceTimes.reduce((a, b) => a + b, 0) / this.inferenceTimes.length\n : 0;\n const minTime = this.inferenceTimes.length > 0\n ? Math.min(...this.inferenceTimes)\n : 0;\n const maxTime = this.inferenceTimes.length > 0\n ? Math.max(...this.inferenceTimes)\n : 0;\n const throughput = this.inferenceCount / (this.config.sampleInterval / 1000);\n \n const inference: InferenceMetrics = {\n count: this.inferenceCount,\n avgTime,\n minTime,\n maxTime,\n throughput,\n queueLength: this.queueLength,\n activeCount: this.activeCount,\n };\n \n // Collect memory metrics\n const memory = this.collectMemoryMetrics();\n \n // Collect system metrics\n const system = this.collectSystemMetrics();\n \n // Collect custom metrics\n const custom: Record<string, number> = {};\n for (const collector of this.config.collectors) {\n try {\n Object.assign(custom, collector());\n } catch {\n // Ignore collector errors\n }\n }\n \n const sample: PerformanceSample = {\n timestamp: now,\n inference,\n memory,\n system,\n custom,\n };\n \n // Add to history\n this.samples.push(sample);\n if (this.samples.length > this.config.historySize) {\n this.samples.shift();\n }\n \n // Check alerts\n this.checkAlerts(sample);\n \n // Notify listeners\n for (const listener of this.sampleListeners) {\n listener(sample);\n }\n \n // Reset counters\n this.inferenceCount = 0;\n this.inferenceTimes = [];\n }\n \n /**\n * Collect memory metrics\n */\n private collectMemoryMetrics(): MemoryMetrics {\n let usedHeap = 0;\n let totalHeap = 0;\n let heapLimit = 0;\n \n if (typeof performance !== 'undefined' && 'memory' in performance) {\n const memory = (performance as { memory: { usedJSHeapSize: number; totalJSHeapSize: number; jsHeapSizeLimit: number } }).memory;\n usedHeap = memory.usedJSHeapSize;\n totalHeap = memory.totalJSHeapSize;\n heapLimit = memory.jsHeapSizeLimit;\n }\n \n return {\n usedHeap,\n totalHeap,\n heapLimit,\n heapUsage: heapLimit > 0 ? usedHeap / heapLimit : 0,\n tensorMemory: this.tensorMemory,\n cacheMemory: this.cacheMemory,\n };\n }\n \n /**\n * Collect system metrics\n */\n private collectSystemMetrics(): SystemMetrics {\n const lastSample = this.samples[this.samples.length - 1];\n const deltaTime = lastSample \n ? Date.now() - lastSample.timestamp \n : this.config.sampleInterval;\n \n // Check WebGPU availability\n let webgpuAvailable = false;\n if (typeof navigator !== 'undefined' && 'gpu' in navigator) {\n webgpuAvailable = true;\n }\n \n // Check WebNN availability\n let webnnAvailable = false;\n if (typeof navigator !== 'undefined' && 'ml' in navigator) {\n webnnAvailable = true;\n }\n \n return {\n fps: this.fps,\n cpuUsage: this.estimateCPUUsage(),\n deltaTime,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown',\n webgpuAvailable,\n webnnAvailable,\n };\n }\n \n /**\n * Estimate CPU usage based on inference times\n */\n private estimateCPUUsage(): number {\n if (this.inferenceTimes.length === 0) return 0;\n \n const totalTime = this.inferenceTimes.reduce((a, b) => a + b, 0);\n return Math.min(1, totalTime / this.config.sampleInterval);\n }\n \n /**\n * Check alerts\n */\n private checkAlerts(sample: PerformanceSample): void {\n for (const alert of this.alerts) {\n const value = this.getMetricValue(sample, alert.metric);\n if (value === undefined) continue;\n \n let triggered = false;\n switch (alert.operator) {\n case '>': triggered = value > alert.threshold; break;\n case '<': triggered = value < alert.threshold; break;\n case '>=': triggered = value >= alert.threshold; break;\n case '<=': triggered = value <= alert.threshold; break;\n case '==': triggered = value === alert.threshold; break;\n case '!=': triggered = value !== alert.threshold; break;\n }\n \n if (triggered) {\n const event: AlertEvent = {\n config: alert,\n value,\n timestamp: sample.timestamp,\n };\n \n for (const listener of this.alertListeners) {\n listener(event);\n }\n }\n }\n }\n \n /**\n * Get metric value from sample\n */\n private getMetricValue(sample: PerformanceSample, metric: string): number | undefined {\n const parts = metric.split('.');\n let value: unknown = sample;\n \n for (const part of parts) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n \n return typeof value === 'number' ? value : undefined;\n }\n \n /**\n * Record an inference\n */\n recordInference(duration: number): void {\n this.inferenceCount++;\n this.inferenceTimes.push(duration);\n }\n \n /**\n * Update queue length\n */\n updateQueueLength(length: number): void {\n this.queueLength = length;\n }\n \n /**\n * Update active count\n */\n updateActiveCount(count: number): void {\n this.activeCount = count;\n }\n \n /**\n * Update tensor memory\n */\n updateTensorMemory(bytes: number): void {\n this.tensorMemory = bytes;\n }\n \n /**\n * Update cache memory\n */\n updateCacheMemory(bytes: number): void {\n this.cacheMemory = bytes;\n }\n \n /**\n * Add an alert\n */\n addAlert(config: AlertConfig): void {\n this.alerts.push(config);\n }\n \n /**\n * Remove an alert\n */\n removeAlert(metric: string): void {\n this.alerts = this.alerts.filter(a => a.metric !== metric);\n }\n \n /**\n * Subscribe to alerts\n */\n onAlert(callback: (alert: AlertEvent) => void): () => void {\n this.alertListeners.push(callback);\n return () => {\n const idx = this.alertListeners.indexOf(callback);\n if (idx !== -1) this.alertListeners.splice(idx, 1);\n };\n }\n \n /**\n * Subscribe to samples\n */\n onSample(callback: (sample: PerformanceSample) => void): () => void {\n this.sampleListeners.push(callback);\n return () => {\n const idx = this.sampleListeners.indexOf(callback);\n if (idx !== -1) this.sampleListeners.splice(idx, 1);\n };\n }\n \n /**\n * Get current sample\n */\n getCurrentSample(): PerformanceSample | undefined {\n return this.samples[this.samples.length - 1];\n }\n \n /**\n * Get all samples\n */\n getSamples(): PerformanceSample[] {\n return [...this.samples];\n }\n \n /**\n * Get samples in time range\n */\n getSamplesInRange(startTime: number, endTime: number): PerformanceSample[] {\n return this.samples.filter(s => s.timestamp >= startTime && s.timestamp <= endTime);\n }\n \n /**\n * Get summary statistics\n */\n getSummary(): {\n avgInferenceTime: number;\n avgThroughput: number;\n avgMemoryUsage: number;\n avgFPS: number;\n totalInferences: number;\n uptime: number;\n } {\n if (this.samples.length === 0) {\n return {\n avgInferenceTime: 0,\n avgThroughput: 0,\n avgMemoryUsage: 0,\n avgFPS: 0,\n totalInferences: 0,\n uptime: 0,\n };\n }\n \n const avgInferenceTime = this.samples.reduce((sum, s) => sum + s.inference.avgTime, 0) / this.samples.length;\n const avgThroughput = this.samples.reduce((sum, s) => sum + s.inference.throughput, 0) / this.samples.length;\n const avgMemoryUsage = this.samples.reduce((sum, s) => sum + s.memory.heapUsage, 0) / this.samples.length;\n const avgFPS = this.samples.reduce((sum, s) => sum + s.system.fps, 0) / this.samples.length;\n const totalInferences = this.samples.reduce((sum, s) => sum + s.inference.count, 0);\n \n const firstSample = this.samples[0]!;\n const lastSample = this.samples[this.samples.length - 1]!;\n const uptime = lastSample.timestamp - firstSample.timestamp;\n \n return {\n avgInferenceTime,\n avgThroughput,\n avgMemoryUsage,\n avgFPS,\n totalInferences,\n uptime,\n };\n }\n \n /**\n * Clear all data\n */\n clear(): void {\n this.samples = [];\n this.inferenceCount = 0;\n this.inferenceTimes = [];\n this.queueLength = 0;\n this.activeCount = 0;\n this.tensorMemory = 0;\n this.cacheMemory = 0;\n }\n \n /**\n * Export data\n */\n export(): {\n samples: PerformanceSample[];\n summary: {\n avgInferenceTime: number;\n avgThroughput: number;\n avgMemoryUsage: number;\n avgFPS: number;\n totalInferences: number;\n uptime: number;\n };\n config: MonitorConfig;\n timestamp: number;\n } {\n return {\n samples: this.getSamples(),\n summary: this.getSummary(),\n config: this.config,\n timestamp: Date.now(),\n };\n }\n}\n\n// ============================================================================\n// Dashboard Generator\n// ============================================================================\n\n/**\n * Generate HTML dashboard\n */\nexport function generateDashboardHTML(monitor: PerformanceMonitor): string {\n const summary = monitor.getSummary();\n const samples = monitor.getSamples();\n const lastSample = samples[samples.length - 1];\n \n const formatBytes = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n };\n \n const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n };\n \n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>edgeFlow.js Performance Dashboard</title>\n <style>\n :root {\n --bg-primary: #0d1117;\n --bg-secondary: #161b22;\n --bg-tertiary: #21262d;\n --text-primary: #f0f6fc;\n --text-secondary: #8b949e;\n --accent: #58a6ff;\n --success: #3fb950;\n --warning: #d29922;\n --error: #f85149;\n }\n \n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n \n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n background: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n }\n \n .dashboard {\n max-width: 1400px;\n margin: 0 auto;\n padding: 24px;\n }\n \n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 32px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--bg-tertiary);\n }\n \n h1 {\n font-size: 24px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n \n .status {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n color: var(--text-secondary);\n }\n \n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--success);\n }\n \n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 20px;\n margin-bottom: 32px;\n }\n \n .card {\n background: var(--bg-secondary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 12px;\n padding: 20px;\n }\n \n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n }\n \n .card-title {\n font-size: 14px;\n font-weight: 500;\n color: var(--text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .card-value {\n font-size: 36px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n }\n \n .card-value.small {\n font-size: 24px;\n }\n \n .card-unit {\n font-size: 14px;\n color: var(--text-secondary);\n margin-left: 4px;\n }\n \n .card-change {\n font-size: 12px;\n padding: 4px 8px;\n border-radius: 4px;\n }\n \n .card-change.up {\n background: rgba(63, 185, 80, 0.2);\n color: var(--success);\n }\n \n .card-change.down {\n background: rgba(248, 81, 73, 0.2);\n color: var(--error);\n }\n \n .progress-bar {\n height: 8px;\n background: var(--bg-tertiary);\n border-radius: 4px;\n overflow: hidden;\n margin-top: 12px;\n }\n \n .progress-fill {\n height: 100%;\n border-radius: 4px;\n transition: width 0.3s ease;\n }\n \n .progress-fill.blue { background: var(--accent); }\n .progress-fill.green { background: var(--success); }\n .progress-fill.yellow { background: var(--warning); }\n .progress-fill.red { background: var(--error); }\n \n .chart-container {\n background: var(--bg-secondary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 20px;\n }\n \n .chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n }\n \n .chart-title {\n font-size: 16px;\n font-weight: 600;\n }\n \n .chart {\n height: 200px;\n position: relative;\n }\n \n .chart-line {\n stroke: var(--accent);\n stroke-width: 2;\n fill: none;\n }\n \n .chart-area {\n fill: url(#chartGradient);\n opacity: 0.3;\n }\n \n .chart-grid {\n stroke: var(--bg-tertiary);\n stroke-width: 1;\n }\n \n .table {\n width: 100%;\n border-collapse: collapse;\n }\n \n .table th,\n .table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--bg-tertiary);\n }\n \n .table th {\n font-size: 12px;\n font-weight: 500;\n color: var(--text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .table td {\n font-variant-numeric: tabular-nums;\n }\n \n footer {\n text-align: center;\n padding: 24px;\n color: var(--text-secondary);\n font-size: 14px;\n }\n </style>\n</head>\n<body>\n <div class=\"dashboard\">\n <header>\n <h1>\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\">\n <rect width=\"32\" height=\"32\" rx=\"8\" fill=\"var(--accent)\"/>\n <path d=\"M8 16L14 10L20 16L26 10\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M8 22L14 16L20 22L26 16\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" opacity=\"0.5\"/>\n </svg>\n edgeFlow.js Performance Dashboard\n </h1>\n <div class=\"status\">\n <div class=\"status-dot\"></div>\n Running for ${formatDuration(summary.uptime)}\n </div>\n </header>\n \n <div class=\"grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Total Inferences</span>\n </div>\n <div class=\"card-value\">${summary.totalInferences.toLocaleString()}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Avg Inference Time</span>\n </div>\n <div class=\"card-value\">${summary.avgInferenceTime.toFixed(1)}<span class=\"card-unit\">ms</span></div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Throughput</span>\n </div>\n <div class=\"card-value\">${summary.avgThroughput.toFixed(1)}<span class=\"card-unit\">ops/s</span></div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Avg FPS</span>\n </div>\n <div class=\"card-value\">${Math.round(summary.avgFPS)}</div>\n </div>\n </div>\n \n <div class=\"grid\">\n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Memory Usage</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.usedHeap ?? 0)}</div>\n <div class=\"progress-bar\">\n <div class=\"progress-fill ${summary.avgMemoryUsage > 0.8 ? 'red' : summary.avgMemoryUsage > 0.6 ? 'yellow' : 'green'}\" \n style=\"width: ${(summary.avgMemoryUsage * 100).toFixed(0)}%\"></div>\n </div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Tensor Memory</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.tensorMemory ?? 0)}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Cache Memory</span>\n </div>\n <div class=\"card-value small\">${formatBytes(lastSample?.memory.cacheMemory ?? 0)}</div>\n </div>\n \n <div class=\"card\">\n <div class=\"card-header\">\n <span class=\"card-title\">Queue Length</span>\n </div>\n <div class=\"card-value small\">${lastSample?.inference.queueLength ?? 0}</div>\n </div>\n </div>\n \n <div class=\"chart-container\">\n <div class=\"chart-header\">\n <span class=\"chart-title\">Inference Time History</span>\n </div>\n <div class=\"chart\">\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 600 200\" preserveAspectRatio=\"none\">\n <defs>\n <linearGradient id=\"chartGradient\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"var(--accent)\" stop-opacity=\"0.5\"/>\n <stop offset=\"100%\" stop-color=\"var(--accent)\" stop-opacity=\"0\"/>\n </linearGradient>\n </defs>\n ${generateChartPath(samples)}\n </svg>\n </div>\n </div>\n \n <div class=\"chart-container\">\n <div class=\"chart-header\">\n <span class=\"chart-title\">Recent Samples</span>\n </div>\n <table class=\"table\">\n <thead>\n <tr>\n <th>Time</th>\n <th>Inferences</th>\n <th>Avg Time</th>\n <th>Throughput</th>\n <th>Memory</th>\n <th>FPS</th>\n </tr>\n </thead>\n <tbody>\n ${samples.slice(-10).reverse().map(s => `\n <tr>\n <td>${new Date(s.timestamp).toLocaleTimeString()}</td>\n <td>${s.inference.count}</td>\n <td>${s.inference.avgTime.toFixed(2)}ms</td>\n <td>${s.inference.throughput.toFixed(1)}/s</td>\n <td>${formatBytes(s.memory.usedHeap)}</td>\n <td>${s.system.fps}</td>\n </tr>\n `).join('')}\n </tbody>\n </table>\n </div>\n \n <footer>\n Generated at ${new Date().toLocaleString()} | edgeFlow.js Performance Monitor\n </footer>\n </div>\n</body>\n</html>\n `.trim();\n}\n\n/**\n * Generate SVG chart path\n */\nfunction generateChartPath(samples: PerformanceSample[]): string {\n if (samples.length < 2) return '';\n \n const width = 600;\n const height = 180;\n const padding = 10;\n \n const times = samples.map(s => s.inference.avgTime);\n const maxTime = Math.max(...times, 1);\n \n const points = samples.map((s, i) => {\n const x = padding + (i / (samples.length - 1)) * (width - 2 * padding);\n const y = height - padding - (s.inference.avgTime / maxTime) * (height - 2 * padding);\n return `${x},${y}`;\n });\n \n const linePath = `M ${points.join(' L ')}`;\n const areaPath = `M ${padding},${height - padding} L ${points.join(' L ')} L ${width - padding},${height - padding} Z`;\n \n // Grid lines\n const gridLines = [];\n for (let i = 0; i <= 4; i++) {\n const y = padding + (i / 4) * (height - 2 * padding);\n gridLines.push(`<line class=\"chart-grid\" x1=\"${padding}\" y1=\"${y}\" x2=\"${width - padding}\" y2=\"${y}\"/>`);\n }\n \n return `\n ${gridLines.join('\\n')}\n <path class=\"chart-area\" d=\"${areaPath}\"/>\n <path class=\"chart-line\" d=\"${linePath}\"/>\n `;\n}\n\n/**\n * Generate ASCII dashboard\n */\nexport function generateAsciiDashboard(monitor: PerformanceMonitor): string {\n const summary = monitor.getSummary();\n const samples = monitor.getSamples();\n const lastSample = samples[samples.length - 1];\n \n const formatBytes = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n };\n \n const bar = (value: number, max: number, width: number = 20): string => {\n const filled = Math.round((value / max) * width);\n return '\u2588'.repeat(filled) + '\u2591'.repeat(width - filled);\n };\n \n const lines = [\n '\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557',\n '\u2551 edgeFlow.js Performance Monitor Dashboard \u2551',\n '\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563',\n '\u2551 \u2551',\n `\u2551 Total Inferences: ${summary.totalInferences.toString().padStart(10)} \u2551`,\n `\u2551 Avg Inference: ${summary.avgInferenceTime.toFixed(2).padStart(10)}ms \u2551`,\n `\u2551 Throughput: ${summary.avgThroughput.toFixed(2).padStart(10)} ops/s \u2551`,\n `\u2551 Avg FPS: ${Math.round(summary.avgFPS).toString().padStart(10)} \u2551`,\n '\u2551 \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Memory Usage \u2551',\n `\u2551 Heap: ${bar(summary.avgMemoryUsage, 1)} ${(summary.avgMemoryUsage * 100).toFixed(0).padStart(3)}% \u2551`,\n `\u2551 Used: ${formatBytes(lastSample?.memory.usedHeap ?? 0).padStart(10)} \u2551`,\n `\u2551 Tensor: ${formatBytes(lastSample?.memory.tensorMemory ?? 0).padStart(10)} \u2551`,\n `\u2551 Cache: ${formatBytes(lastSample?.memory.cacheMemory ?? 0).padStart(10)} \u2551`,\n '\u2551 \u2551',\n '\u255F\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2562',\n '\u2551 Inference Time History (last 30 samples) \u2551',\n '\u2551 \u2551',\n ];\n \n // Add mini chart\n const recentSamples = samples.slice(-30);\n if (recentSamples.length > 0) {\n const times = recentSamples.map(s => s.inference.avgTime);\n const maxTime = Math.max(...times, 1);\n const chartHeight = 5;\n \n for (let row = chartHeight; row > 0; row--) {\n let line = '\u2551 ';\n for (const time of times) {\n const height = Math.ceil((time / maxTime) * chartHeight);\n line += height >= row ? '\u2593' : ' ';\n }\n lines.push(line.padEnd(76) + '\u2551');\n }\n lines.push('\u2551 ' + '\u2500'.repeat(30) + ' \u2551');\n }\n \n lines.push('\u2551 \u2551');\n lines.push(`\u2551 Last updated: ${new Date().toLocaleString().padEnd(40)} \u2551`);\n lines.push('\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D');\n \n return lines.join('\\n');\n}\n\n// ============================================================================\n// Global Instance\n// ============================================================================\n\nlet globalMonitor: PerformanceMonitor | null = null;\n\n/**\n * Get or create global monitor\n */\nexport function getMonitor(config?: MonitorConfig): PerformanceMonitor {\n if (!globalMonitor || config) {\n globalMonitor = new PerformanceMonitor(config);\n }\n return globalMonitor;\n}\n\n/**\n * Start monitoring\n */\nexport function startMonitoring(config?: MonitorConfig): PerformanceMonitor {\n const monitor = getMonitor(config);\n monitor.start();\n return monitor;\n}\n\n/**\n * Stop monitoring\n */\nexport function stopMonitoring(): void {\n globalMonitor?.stop();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n};\n", "/**\n * edgeFlow.js - Tools and Utilities\n * \n * Model optimization, quantization, and analysis tools.\n */\n\nimport { \n LoadedModel,\n QuantizationType,\n} from '../core/types.js';\n\n// ============================================================================\n// Quantization Tools\n// ============================================================================\n\n/**\n * Quantization options\n */\nexport interface QuantizationOptions {\n /** Quantization method */\n method: QuantizationType;\n /** Calibration data for calibrated quantization */\n calibrationData?: Float32Array[];\n /** Whether to quantize weights only */\n weightsOnly?: boolean;\n /** Layers to exclude from quantization */\n excludeLayers?: string[];\n}\n\n/**\n * Quantization result\n */\nexport interface QuantizationResult {\n /** Quantized model data */\n modelData: ArrayBuffer;\n /** Original size in bytes */\n originalSize: number;\n /** Quantized size in bytes */\n quantizedSize: number;\n /** Compression ratio */\n compressionRatio: number;\n /** Quantization statistics */\n stats: {\n layersQuantized: number;\n layersSkipped: number;\n };\n}\n\n/**\n * Quantize a model\n * \n * @example\n * ```typescript\n * const quantized = await quantize(model, {\n * method: 'int8',\n * calibrationData: samples,\n * });\n * ```\n */\nexport async function quantize(\n model: LoadedModel | ArrayBuffer,\n options: QuantizationOptions\n): Promise<QuantizationResult> {\n // Get model data\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n const originalSize = modelData.byteLength;\n\n // Apply quantization based on method\n let quantizedData: ArrayBuffer;\n let layersQuantized = 0;\n let layersSkipped = 0;\n\n switch (options.method) {\n case 'int8':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeInt8(modelData, options));\n break;\n case 'uint8':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeUint8(modelData, options));\n break;\n case 'float16':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeFloat16(modelData, options));\n break;\n case 'int4':\n ({ data: quantizedData, layersQuantized, layersSkipped } = \n quantizeInt4(modelData, options));\n break;\n default:\n quantizedData = modelData;\n }\n\n return {\n modelData: quantizedData,\n originalSize,\n quantizedSize: quantizedData.byteLength,\n compressionRatio: originalSize / quantizedData.byteLength,\n stats: {\n layersQuantized,\n layersSkipped,\n },\n };\n}\n\n/**\n * Placeholder for getting model data\n */\nasync function getModelData(_model: LoadedModel): Promise<ArrayBuffer> {\n // In production, this would extract the model weights\n return new ArrayBuffer(0);\n}\n\n/**\n * INT8 quantization\n */\nfunction quantizeInt8(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n // Simplified INT8 quantization\n const input = new Float32Array(data);\n const output = new Int8Array(input.length);\n \n // Find scale\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n const abs = Math.abs(input[i] ?? 0);\n if (abs > max) max = abs;\n }\n const scale = max / 127;\n \n // Quantize\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.round((input[i] ?? 0) / scale);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * UINT8 quantization\n */\nfunction quantizeUint8(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n const output = new Uint8Array(input.length);\n \n // Find min/max\n let min = Infinity, max = -Infinity;\n for (let i = 0; i < input.length; i++) {\n const val = input[i] ?? 0;\n if (val < min) min = val;\n if (val > max) max = val;\n }\n const scale = (max - min) / 255;\n \n // Quantize\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.round(((input[i] ?? 0) - min) / scale);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * Float16 quantization\n */\nfunction quantizeFloat16(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n const output = new Uint16Array(input.length);\n \n // Convert float32 to float16\n for (let i = 0; i < input.length; i++) {\n output[i] = float32ToFloat16(input[i] ?? 0);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * INT4 quantization\n */\nfunction quantizeInt4(\n data: ArrayBuffer,\n _options: QuantizationOptions\n): { data: ArrayBuffer; layersQuantized: number; layersSkipped: number } {\n const input = new Float32Array(data);\n // Pack two INT4 values per byte\n const output = new Uint8Array(Math.ceil(input.length / 2));\n \n // Find scale\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n const abs = Math.abs(input[i] ?? 0);\n if (abs > max) max = abs;\n }\n const scale = max / 7; // INT4 range: -8 to 7\n \n // Quantize and pack\n for (let i = 0; i < input.length; i += 2) {\n const val1 = Math.round((input[i] ?? 0) / scale) + 8;\n const val2 = Math.round((input[i + 1] ?? 0) / scale) + 8;\n output[i / 2] = ((val1 & 0xF) << 4) | (val2 & 0xF);\n }\n \n return {\n data: output.buffer,\n layersQuantized: 1,\n layersSkipped: 0,\n };\n}\n\n/**\n * Convert float32 to float16\n */\nfunction float32ToFloat16(value: number): number {\n const floatView = new Float32Array(1);\n const int32View = new Int32Array(floatView.buffer);\n \n floatView[0] = value;\n const x = int32View[0] ?? 0;\n \n let bits = (x >> 16) & 0x8000; // sign\n let m = (x >> 12) & 0x07ff; // mantissa\n const e = (x >> 23) & 0xff; // exponent\n \n if (e < 103) {\n // Too small, return zero\n return bits;\n }\n \n if (e > 142) {\n // Too large, return infinity\n bits |= 0x7c00;\n bits |= ((e === 255) ? 0 : 1) && (x & 0x007fffff);\n return bits;\n }\n \n if (e < 113) {\n // Denormalized\n m |= 0x0800;\n bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);\n return bits;\n }\n \n bits |= ((e - 112) << 10) | (m >> 1);\n bits += m & 1;\n return bits;\n}\n\n// ============================================================================\n// Model Pruning\n// ============================================================================\n\n/**\n * Pruning options\n */\nexport interface PruningOptions {\n /** Target sparsity (0-1) */\n sparsity: number;\n /** Pruning method */\n method?: 'magnitude' | 'random' | 'structured';\n /** Layers to exclude */\n excludeLayers?: string[];\n}\n\n/**\n * Pruning result\n */\nexport interface PruningResult {\n /** Pruned model data */\n modelData: ArrayBuffer;\n /** Achieved sparsity */\n actualSparsity: number;\n /** Number of parameters pruned */\n parametersPruned: number;\n /** Total parameters */\n totalParameters: number;\n}\n\n/**\n * Prune model weights\n */\nexport async function prune(\n model: LoadedModel | ArrayBuffer,\n options: PruningOptions\n): Promise<PruningResult> {\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n const weights = new Float32Array(modelData);\n const total = weights.length;\n \n // Calculate threshold for magnitude pruning\n const magnitudes = weights.map(Math.abs);\n const sorted = [...magnitudes].sort((a, b) => a - b);\n const thresholdIdx = Math.floor(options.sparsity * sorted.length);\n const threshold = sorted[thresholdIdx] ?? 0;\n \n // Prune weights\n let pruned = 0;\n for (let i = 0; i < weights.length; i++) {\n if (Math.abs(weights[i] ?? 0) < threshold) {\n weights[i] = 0;\n pruned++;\n }\n }\n\n return {\n modelData: weights.buffer,\n actualSparsity: pruned / total,\n parametersPruned: pruned,\n totalParameters: total,\n };\n}\n\n// ============================================================================\n// Model Analysis\n// ============================================================================\n\n/**\n * Model analysis result\n */\nexport interface ModelAnalysis {\n /** Total number of parameters */\n totalParameters: number;\n /** Model size in bytes */\n sizeBytes: number;\n /** Layer information */\n layers: Array<{\n name: string;\n type: string;\n parameters: number;\n inputShape: number[];\n outputShape: number[];\n }>;\n /** Estimated FLOPs */\n estimatedFlops: number;\n /** Memory requirements */\n memoryRequirements: {\n weights: number;\n activations: number;\n total: number;\n };\n}\n\n/**\n * Analyze a model\n */\nexport async function analyzeModel(\n model: LoadedModel | ArrayBuffer\n): Promise<ModelAnalysis> {\n // Simplified analysis\n const size = model instanceof ArrayBuffer \n ? model.byteLength \n : model.metadata.sizeBytes;\n\n const estimatedParams = Math.floor(size / 4); // Assume float32\n\n return {\n totalParameters: estimatedParams,\n sizeBytes: size,\n layers: [],\n estimatedFlops: estimatedParams * 2, // Rough estimate\n memoryRequirements: {\n weights: size,\n activations: size * 0.1, // Rough estimate\n total: size * 1.1,\n },\n };\n}\n\n// ============================================================================\n// Benchmarking\n// ============================================================================\n\n/**\n * Benchmark options\n */\nexport interface BenchmarkOptions {\n /** Number of warmup runs */\n warmupRuns?: number;\n /** Number of benchmark runs */\n runs?: number;\n /** Input shape */\n inputShape?: number[];\n}\n\n/**\n * Benchmark result\n */\nexport interface BenchmarkResult {\n /** Average inference time in ms */\n avgTime: number;\n /** Minimum inference time in ms */\n minTime: number;\n /** Maximum inference time in ms */\n maxTime: number;\n /** Standard deviation */\n stdDev: number;\n /** Throughput (inferences per second) */\n throughput: number;\n /** All run times */\n times: number[];\n}\n\n/**\n * Benchmark model inference\n */\nexport async function benchmark(\n runFn: () => Promise<void>,\n options: BenchmarkOptions = {}\n): Promise<BenchmarkResult> {\n const {\n warmupRuns = 3,\n runs = 10,\n } = options;\n\n // Warmup\n for (let i = 0; i < warmupRuns; i++) {\n await runFn();\n }\n\n // Benchmark\n const times: number[] = [];\n for (let i = 0; i < runs; i++) {\n const start = performance.now();\n await runFn();\n times.push(performance.now() - start);\n }\n\n // Calculate statistics\n const sum = times.reduce((a, b) => a + b, 0);\n const avgTime = sum / times.length;\n const minTime = Math.min(...times);\n const maxTime = Math.max(...times);\n \n const squaredDiffs = times.map(t => Math.pow(t - avgTime, 2));\n const avgSquaredDiff = squaredDiffs.reduce((a, b) => a + b, 0) / times.length;\n const stdDev = Math.sqrt(avgSquaredDiff);\n\n return {\n avgTime,\n minTime,\n maxTime,\n stdDev,\n throughput: 1000 / avgTime,\n times,\n };\n}\n\n// ============================================================================\n// Re-export benchmark utilities\n// ============================================================================\n\nexport {\n benchmark as runBenchmark,\n compareBenchmarks,\n benchmarkSuite,\n benchmarkMemory,\n formatBenchmarkResult,\n formatComparisonResult,\n} from './benchmark.js';\n\nexport type {\n BenchmarkOptions as DetailedBenchmarkOptions,\n BenchmarkResult as DetailedBenchmarkResult,\n CompareBenchmarkResult,\n MemoryBenchmarkResult,\n} from './benchmark.js';\n\n// ============================================================================\n// Re-export advanced quantization tools\n// ============================================================================\n\nexport {\n quantizeModel,\n quantizeTensor,\n dequantizeTensor,\n pruneModel,\n pruneTensor,\n analyzeModel as analyzeModelDetailed,\n exportModel as exportModelAdvanced,\n dequantizeInt8,\n dequantizeUint8,\n dequantizeFloat16,\n float16ToFloat32,\n} from './quantization.js';\n\nexport type {\n QuantizationType as QuantizationMethod,\n QuantizationOptions as AdvancedQuantizationOptions,\n QuantizationProgress,\n QuantizationResult as AdvancedQuantizationResult,\n LayerQuantizationStats,\n QuantizationStats,\n PruningOptions as AdvancedPruningOptions,\n PruningResult as AdvancedPruningResult,\n ModelAnalysis as DetailedModelAnalysis,\n ExportFormat,\n ExportOptions,\n} from './quantization.js';\n\n// ============================================================================\n// Re-export debugging tools\n// ============================================================================\n\nexport {\n EdgeFlowDebugger,\n getDebugger,\n enableDebugging,\n disableDebugging,\n inspectTensor,\n formatTensorInspection,\n createAsciiHistogram,\n createTensorHeatmap,\n visualizeModelArchitecture,\n} from './debugger.js';\n\nexport type {\n DebuggerConfig,\n TensorInspection,\n TensorStats,\n HistogramData,\n InferenceTrace,\n OperationTrace,\n DebugEvent,\n PerformanceMetrics as DebugPerformanceMetrics,\n} from './debugger.js';\n\n// ============================================================================\n// Re-export monitoring tools\n// ============================================================================\n\nexport {\n PerformanceMonitor,\n getMonitor,\n startMonitoring,\n stopMonitoring,\n generateDashboardHTML,\n generateAsciiDashboard,\n} from './monitor.js';\n\nexport type {\n MonitorConfig,\n PerformanceSample,\n InferenceMetrics,\n MemoryMetrics,\n SystemMetrics,\n AlertConfig,\n AlertEvent,\n WidgetData,\n} from './monitor.js';\n\n// ============================================================================\n// Export Utilities\n// ============================================================================\n\n/**\n * Export model to different formats\n */\nexport async function exportModel(\n model: LoadedModel | ArrayBuffer,\n format: 'onnx' | 'json' | 'binary'\n): Promise<ArrayBuffer | string> {\n const modelData = model instanceof ArrayBuffer \n ? model \n : await getModelData(model);\n\n switch (format) {\n case 'json':\n // Export as JSON (for small models)\n const array = new Float32Array(modelData);\n return JSON.stringify(Array.from(array));\n case 'binary':\n case 'onnx':\n default:\n return modelData;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EdgeFlowError", "ErrorCodes", "init_types", "__esmMin", "message", "code", "details", "__publicField", "generateTensorId", "tensorIdCounter", "getTypedArrayConstructor", "dtype", "EdgeFlowError", "ErrorCodes", "calculateSize", "shape", "acc", "dim", "validateShape", "i", "tensor", "data", "rows", "cols", "flatData", "row", "EdgeFlowTensor", "inferredShape", "zeros", "size", "TypedArrayCtor", "ones", "full", "value", "random", "randn", "u1", "u2", "r", "theta", "arange", "start", "stop", "step", "linspace", "num", "eye", "n", "add", "a", "b", "result", "aData", "bData", "sub", "mul", "div", "matmul", "m", "k1", "k2", "j", "sum", "k", "softmax", "t", "axis", "actualAxis", "max", "relu", "sigmoid", "tanh", "total", "newShape", "mean", "axisSize", "argmax", "maxIdx", "maxVal", "concat", "tensors", "first", "totalAxisSize", "offset", "init_tensor", "__esmMin", "init_types", "_EdgeFlowTensor", "__publicField", "expectedSize", "bigIntData", "clonedData", "indices", "flatIndex", "stride", "idx", "newSize", "model_loader_exports", "__export", "cancelPreload", "clearModelCache", "deleteCachedModel", "getCachedModel", "getModelCacheStats", "getPreloadStatus", "getPreloadedModel", "isModelCached", "loadModelData", "preloadModel", "preloadModels", "supportsRangeRequests", "url", "response", "acceptRanges", "contentLength", "etag", "downloadChunk", "start", "end", "timeout", "controller", "timeoutId", "downloadWithResume", "options", "chunkSize", "parallelConnections", "onProgress", "supportsRange", "totalSize", "downloadSimple", "state", "modelCache", "numChunks", "chunks", "i", "pendingChunks", "c", "downloadedSize", "lastProgressTime", "lastDownloadedSize", "reportProgress", "now", "elapsed", "bytesDownloaded", "speed", "remaining", "eta", "downloadQueue", "inProgress", "chunk", "downloadPromise", "data", "result", "offset", "total", "reader", "loaded", "startTime", "done", "value", "cache", "forceDownload", "resumable", "cached", "firstByte", "preloadManager", "urls", "priority", "DB_NAME", "STORE_META", "STORE_CHUNKS", "STORE_STATE", "ModelCache", "PreloadManager", "init_model_loader", "__esmMin", "__publicField", "resolve", "reject", "request", "event", "db", "meta", "err", "index", "storeName", "tx", "bytesNeeded", "allMeta", "a", "b", "freed", "results", "r", "sum", "cursor", "stores", "metas", "m", "existing", "promise", "res", "rej", "task", "insertIndex", "u", "t", "error", "init_types", "init_tensor", "init_types", "Task", "id", "modelId", "priority", "executor", "__publicField", "cancelError", "EdgeFlowError", "ErrorCodes", "reject", "resolve", "err", "PRIORITY_ORDER", "PriorityQueue", "item", "inserted", "i", "currentItem", "index", "removed", "taskIdCounter", "generateTaskId", "DEFAULT_OPTIONS", "InferenceScheduler", "options", "__publicField", "modelId", "c", "queue", "PriorityQueue", "running", "tasksToStart", "task", "error", "hasPending", "executor", "priority", "EdgeFlowError", "ErrorCodes", "maxRetries", "baseDelay", "wrappedExecutor", "lastError", "attempt", "result", "err", "delay", "r", "Task", "timeout", "timeoutExecutor", "resolve", "reject", "timer", "tasks", "scheduledTasks", "taskId", "cancelled", "stats", "event", "listener", "listeners", "type", "data", "batcher", "globalScheduler", "getScheduler", "setScheduler", "scheduler", "configureScheduler", "DEFAULT_POOL_CONFIG", "_MemoryManager", "config", "__publicField", "tensor", "disposer", "size", "model", "id", "resource", "resourceOrId", "error", "bytesPerElement", "dtype", "obj", "usage", "evict", "maxAge", "now", "staleIds", "tensorCount", "modelCount", "potentialLeaks", "event", "listener", "listeners", "type", "data", "MemoryManager", "MemoryScope", "_MemoryScope", "parent", "index", "child", "i", "withMemoryScope", "fn", "scope", "withMemoryScopeSync", "ModelCache", "options", "key", "entry", "oldestKey", "oldestTime", "getMemoryManager", "getMemoryStats", "release", "gc", "init_types", "runtimeFactories", "runtimeInstances", "RUNTIME_PRIORITY", "_RuntimeManager", "__publicField", "type", "factory", "runtime", "EdgeFlowError", "ErrorCodes", "error", "existing", "results", "event", "listener", "listeners", "data", "RuntimeManager", "modelIdCounter", "generateModelId", "LoadedModelImpl", "metadata", "dispose", "getMemoryManager", "loadModel", "url", "options", "loadModelData", "modelData", "progress", "loadModelFromBuffer", "runInference", "model", "inputs", "getScheduler", "runInferenceNamed", "namedInputs", "runBatchInference", "batches", "scheduler", "tasks", "task", "getRuntimeManager", "registerRuntime", "getBestRuntime", "getAvailableRuntimes", "registeredPlugins", "pluginPipelines", "pluginMiddleware", "registerPlugin", "plugin", "task", "entry", "name", "registerRuntime", "getPluginPipeline", "getPluginMiddleware", "listPlugins", "p", "unregisterPlugin", "mw", "idx", "cachedProfile", "getDeviceProfile", "cores", "memoryGiB", "mobile", "webgpu", "gpuInfo", "adapter", "info", "webnn", "ml", "tier", "recommendQuantization", "profile", "recommendModelVariant", "resetDeviceProfile", "init_types", "init_tensor", "GPUBufferUsage", "GPUShaderStage", "WebGPURuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "info", "modelData", "options", "config", "webgpuData", "modelId", "metadata", "i", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "device", "outputs", "outputSpec", "outputSize", "a", "b", "outputBuffer", "stagingBuffer", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "_data", "weightsBuffer", "shaderModule", "bindGroupLayout", "pipelineLayout", "pipeline", "buffer", "createWebGPURuntime", "init_types", "init_tensor", "WebNNRuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "error", "modelData", "options", "config", "modelId", "metadata", "i", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "outputs", "outputSpec", "outputSize", "b", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "createWebNNRuntime", "init_types", "init_tensor", "WASMRuntime", "__publicField", "bytes", "memory", "simdTest", "nextPtr", "allocations", "size", "ptr", "aPtr", "aRows", "aCols", "bPtr", "_bRows", "bCols", "outPtr", "view", "aOffset", "bOffset", "outOffset", "i", "j", "sum", "inputPtr", "outputPtr", "inOffset", "max", "modelData", "options", "config", "wasmData", "l", "modelId", "metadata", "o", "model", "LoadedModelImpl", "getMemoryManager", "inputs", "outputs", "outputSpec", "outputSize", "b", "outputTensor", "inputTensor", "softmax", "relu", "sigmoid", "outputData", "inputData", "EdgeFlowTensor", "data", "decoder", "text", "jsonEnd", "jsonStr", "_modelData", "_wasmData", "weight", "EdgeFlowError", "ErrorCodes", "createWASMRuntime", "init_types", "init_tensor", "ort", "injectedOrt", "onnxAssetPaths", "setOnnxModule", "module", "configureOnnxAssets", "paths", "getOrt", "isOnnxAvailable", "sessionStore", "ONNXRuntime", "__publicField", "ortModule", "EdgeFlowError", "ErrorCodes", "wasmEnv", "modelData", "options", "sessionOptions", "modelBytes", "session", "inputNames", "outputNames", "modelId", "metadata", "name", "model", "LoadedModelImpl", "getMemoryManager", "error", "inputs", "sessionData", "feeds", "i", "inputName", "inputTensor", "dtype", "ortTensor", "data", "results", "outputs", "outputName", "shape", "d", "EdgeFlowTensor", "namedInputs", "tensor", "createONNXRuntime", "init_types", "init_tensor", "sessionStore", "adapterOptions", "TransformersAdapterRuntime", "__publicField", "EdgeFlowError", "ErrorCodes", "modelData", "options", "metadata", "modelId", "model", "LoadedModelImpl", "session", "getMemoryManager", "task", "pipelineOptions", "opts", "instance", "inputs", "inputData", "result", "resultArray", "EdgeFlowTensor", "input", "id", "adapterRuntime", "useTransformersBackend", "registerRuntime", "getTransformersAdapter", "registerAllBackends", "registerRuntime", "createONNXRuntime", "Cache", "options", "__publicField", "key", "entry", "value", "size", "ttl", "entryTtl", "total", "keyToEvict", "oldest", "oldestTime", "lfu", "minCount", "now", "request", "resolve", "reject", "entries", "tx", "store", "db", "InferenceCache", "modelId", "input", "inputArray", "hash", "arr", "sample", "_", "i", "ModelDownloadCache", "cacheName", "url", "response", "r", "createCache", "preset", "presets", "BasePipeline", "config", "__publicField", "ModelCache", "ModelDownloadCache", "cachedModel", "modelPath", "cachedResponse", "response", "loadModel", "input", "options", "startTime", "preprocessed", "outputs", "runInference", "result", "inputs", "pipelineFactories", "registerPipeline", "task", "factory", "getPipelineFactory", "SENTIMENT_LABELS", "EMOTION_LABELS", "IMAGENET_LABELS", "init_tensor", "init_types", "Tokenizer", "_Tokenizer", "__publicField", "bytes", "i", "chars", "byte", "char", "json", "tokenizer", "data", "unigramVocab", "entry", "token", "id", "content", "url", "response", "EdgeFlowError", "ErrorCodes", "modelId", "options", "revision", "text", "result", "pattern", "b", "c", "word", "pairs", "minPair", "minRank", "pair", "rank", "parts", "first", "second", "newWord", "j", "tokens", "start", "end", "curSubstr", "substr", "byteStr", "prefixedWord", "found", "sub", "ch", "normalized", "remaining", "sortedAddedTokens", "a", "addedToken", "newRemaining", "words", "wordTokens", "addedId", "vocabId", "ids", "pairIds", "typeIds", "template", "item", "specialToken", "seqIds", "addSpecialTokens", "maxLength", "padding", "truncation", "returnAttentionMask", "returnTokenTypeIds", "textPair", "inputIds", "pairTokens", "tokenTypeIds", "processed", "attentionMask", "padLength", "texts", "encodings", "t", "maxLen", "e", "skipSpecialTokens", "prefix", "batchIds", "createBasicTokenizer", "loadTokenizer", "loadTokenizerFromHub", "init_model_loader", "DEFAULT_MODELS", "DEFAULT_SST2_LABELS", "TextClassificationPipeline", "BasePipeline", "config", "labels", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "isBatch", "inputs", "startTime", "results", "text", "tensorInputs", "outputs", "result", "processingTime", "encoded", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "namedInputs", "runInferenceNamed", "logits", "probsArray", "softmax", "maxIdx", "maxScore", "i", "SentimentAnalysisPipeline", "SENTIMENT_LABELS", "createTextClassificationPipeline", "createSentimentAnalysisPipeline", "registerPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "DEFAULT_EMBEDDING_DIM", "FeatureExtractionPipeline", "BasePipeline", "config", "embeddingDim", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "i", "input", "options", "isBatch", "inputs", "startTime", "results", "text", "tensorInputs", "outputs", "result", "processingTime", "encoded", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "tensors", "tokenTypeIds", "namedInputs", "runInferenceNamed", "hiddenStates", "pooling", "normalize", "embeddings", "data", "seqLen", "j", "val", "vec", "norm", "v", "createFeatureExtractionPipeline", "registerPipeline", "init_tensor", "init_tensor", "DEFAULT_IMAGE_OPTIONS", "ImagePreprocessor", "_ImagePreprocessor", "options", "__publicField", "size", "width", "height", "config", "sizeObj", "cropSize", "cropObj", "imageMean", "imageStd", "rescaleFactor", "doResize", "doRescale", "doNormalize", "doCenterCrop", "url", "response", "modelId", "revision", "input", "imageData", "processed", "inputs", "tensors", "batchSize", "firstTensor", "EdgeFlowTensor", "channels", "batchData", "i", "t", "resolve", "reject", "img", "blob", "cropWidth", "cropHeight", "srcX", "srcY", "srcCanvas", "source", "resizeMode", "srcW", "srcH", "dstX", "dstY", "dstW", "dstH", "scale", "mean", "std", "grayscale", "channelFormat", "dtype", "data", "pixels", "y", "x", "pixelIdx", "gray", "idx", "c", "value", "shape", "DEFAULT_AUDIO_OPTIONS", "AudioPreprocessor", "_AudioPreprocessor", "samplingRate", "featureSize", "nFft", "hopLength", "audioData", "maxSamples", "arrayBuffer", "audioBuffer", "buffer", "channelData", "max", "abs", "result", "audio", "nMels", "numFrames", "melSpec", "frame", "start", "mel", "energy", "freqStart", "freqEnd", "sample", "preprocessText", "text", "lowercase", "removePunctuation", "normalizeWhitespace", "maxLength", "createImagePreprocessor", "preset", "presets", "createAudioPreprocessor", "init_model_loader", "DEFAULT_MODELS", "ImageClassificationPipeline", "BasePipeline", "config", "labels", "_numClasses", "__publicField", "IMAGENET_LABELS", "createImagePreprocessor", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "isBatch", "inputs", "startTime", "results", "image", "tensorInputs", "outputs", "result", "processingTime", "tensor", "runInference", "logits", "probsArray", "softmax", "maxIdx", "maxScore", "i", "createImageClassificationPipeline", "registerPipeline", "init_tensor", "DEFAULT_LLM_MODELS", "TextGenerationPipeline", "BasePipeline", "config", "__publicField", "model", "tokenizer", "onProgress", "tokenizerResponse", "tokenizerJson", "Tokenizer", "specialIds", "error", "modelData", "loaded", "total", "loadModelFromBuffer", "url", "response", "contentLength", "buffer", "reader", "chunks", "done", "value", "offset", "chunk", "input", "text", "EdgeFlowTensor", "encoded", "id", "_outputs", "_options", "prompt", "options", "prompts", "results", "p", "startTime", "maxNewTokens", "maxLength", "temperature", "topK", "topP", "repetitionPenalty", "stopSequences", "doSample", "inputIds", "generatedIds", "generatedText", "i", "nextTokenId", "token", "shouldStop", "stopSeq", "endTime", "returnFullText", "currentText", "seqLen", "inputs", "_", "numLayers", "numKVHeads", "headDim", "outputs", "runInferenceNamed", "logits", "logitsData", "vocabSize", "lastPositionLogits", "prevId", "score", "logitsTensor", "probs", "softmax", "maxIdx", "maxProb", "indices", "a", "b", "candidateIndices", "cumulativeProb", "filtered", "idx", "totalProb", "r", "cumulative", "templateType", "messages", "msg", "systemMsg", "instruction", "template", "systemPrefix", "systemSuffix", "userPrefix", "userSuffix", "assistantPrefix", "assistantSuffix", "separator", "userMessage", "result", "fullResponse", "event", "createTextGenerationPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "COCO_LABELS", "ObjectDetectionPipeline", "BasePipeline", "config", "labels", "__publicField", "ImagePreprocessor", "modelData", "loadModelData", "loadModelFromBuffer", "input", "options", "tensorInputs", "outputs", "inputs", "tensor", "EdgeFlowTensor", "runInference", "opts", "threshold", "topK", "nms", "iouThreshold", "outputData", "shape", "detections", "filtered", "a", "b", "data", "numBoxes", "boxSize", "numClasses", "i", "offset", "objectness", "maxClassScore", "maxClassIdx", "c", "score", "confidence", "x", "y", "w", "h", "x1", "y1", "x2", "y2", "sorted", "selected", "active", "current", "j", "other", "xOverlap", "yOverlap", "intersection", "aArea", "bArea", "union", "registerPipeline", "config", "ObjectDetectionPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "SOT_TOKEN", "TRANSLATE_TOKEN", "TRANSCRIBE_TOKEN", "EOT_TOKEN", "NO_TIMESTAMPS_TOKEN", "EN_TOKEN", "MAX_DECODER_TOKENS", "AutomaticSpeechRecognitionPipeline", "BasePipeline", "config", "__publicField", "AudioPreprocessor", "Tokenizer", "data", "loadModelData", "loadModelFromBuffer", "tokenizer", "input", "options", "isBatch", "inputs", "opts", "results", "audio", "result", "startTime", "melTensor", "melInput", "EdgeFlowTensor", "encoderHidden", "runInference", "task", "initialTokens", "generatedTokens", "text", "language", "tokens", "step", "decoderInputIds", "t", "namedInputs", "logits", "runInferenceNamed", "vocabSize", "lastTokenLogits", "bestId", "bestVal", "i", "_tokenIds", "words", "w", "chunks", "wordsPerSecond", "chunkText", "chunkStart", "duration", "chunkDuration", "chunkOverlap", "audioData", "sampleRate", "chunkSamples", "overlapSamples", "stepSamples", "start", "end", "chunkAudio", "chunkResult", "timeOffset", "c", "mergedText", "mergedChunks", "tensors", "outputs", "returnTimestamps", "outputData", "shape", "seqLen", "tokenIds", "offset", "maxIdx", "maxVal", "j", "registerPipeline", "config", "AutomaticSpeechRecognitionPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "ENTAILMENT_IDX", "ZeroShotClassificationPipeline", "BasePipeline", "config", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "tokenizer", "text", "candidateLabels", "options", "input", "opts", "texts", "template", "multiLabel", "results", "t", "startTime", "hypotheses", "label", "scores", "hypothesis", "score", "normalizedScores", "s", "tensor", "EdgeFlowTensor", "softmax", "indexed", "i", "a", "b", "premise", "encoded", "inputIds", "id", "attentionMask", "m", "namedInputs", "runInferenceNamed", "firstText", "firstLabel", "_outputs", "_options", "registerPipeline", "config", "ZeroShotClassificationPipeline", "init_tensor", "init_model_loader", "DEFAULT_MODELS", "QuestionAnsweringPipeline", "BasePipeline", "config", "__publicField", "Tokenizer", "modelData", "loadModelData", "loadModelFromBuffer", "tokenizer", "input", "options", "inputs", "results", "i", "startTime", "question", "context", "maxAnswerLength", "encoded", "seqLen", "inputIds", "EdgeFlowTensor", "id", "attentionMask", "m", "namedInputs", "outputs", "runInferenceNamed", "startLogits", "endLogits", "startProbs", "softmax", "endProbs", "contextStart", "t", "spanStart", "spanEnd", "bestStartIdx", "bestEndIdx", "bestScore", "s", "e", "score", "answerTokenIds", "qaInput", "_options", "bestStart", "bestEnd", "start", "end", "registerPipeline", "config", "QuestionAnsweringPipeline", "init_tensor", "DEFAULT_SAM_MODELS", "ImageSegmentationPipeline", "BasePipeline", "config", "__publicField", "encoder", "decoder", "onProgress", "encoderData", "loaded", "total", "loadModelFromBuffer", "decoderData", "url", "response", "contentLength", "buffer", "reader", "chunks", "done", "value", "offset", "chunk", "modelUrl", "loadModel", "image", "imageData", "inputTensor", "resizedSize", "outputs", "runInference", "options", "startTime", "points", "boxes", "maskThreshold", "returnAllMasks", "decoderInputs", "runInferenceNamed", "masks", "scores", "result", "input", "resolve", "reject", "img", "canvas", "ctx", "bitmap", "width", "height", "scale", "newWidth", "newHeight", "tempCanvas", "resizedData", "tensorData", "mean", "std", "i", "pixelIdx", "EdgeFlowTensor", "resizedW", "resizedH", "scaleX", "scaleY", "allPoints", "allLabels", "point", "box", "numPoints", "inputs", "l", "threshold", "scoresData", "masksData", "numMasks", "maskShape", "maskH", "maskW", "bestIdx", "bestScore", "m", "mask", "maskIdx", "srcW", "srcH", "dstW", "dstH", "outputMask", "maskOffset", "y", "x", "srcX", "srcY", "x0", "x1", "y0", "y1", "xFrac", "yFrac", "v00", "v01", "v10", "v11", "sigmoid", "tensor", "_outputs", "_options", "createImageSegmentationPipeline", "registerPipeline", "pipeline", "task", "options", "registerAllBackends", "config", "pipelineInstance", "TextClassificationPipeline", "SentimentAnalysisPipeline", "FeatureExtractionPipeline", "ImageClassificationPipeline", "TextGenerationPipeline", "ObjectDetectionPipeline", "AutomaticSpeechRecognitionPipeline", "ZeroShotClassificationPipeline", "QuestionAnsweringPipeline", "ImageSegmentationPipeline", "pluginEntry", "getPluginPipeline", "createPipelines", "tasks", "pipelines", "result", "i", "compose", "stages", "pipelineInstances", "ensureInitialised", "stage", "pipeline", "input", "instances", "stageResults", "stageTimes", "current", "wallStart", "i", "inst", "t0", "parallel", "s", "stageInput", "init_model_loader", "init_model_loader", "init_types", "DEFAULT_ENDPOINT", "DEFAULT_REVISION", "ONNX_MODEL_FILES", "buildFileUrl", "modelId", "filename", "options", "endpoint", "revision", "subfolder", "fetchWithAuth", "url", "token", "headers", "fileExists", "response", "findOnnxModel", "downloadFile", "loadModelData", "progress", "downloadJson", "isModelCached", "data", "text", "EdgeFlowError", "ErrorCodes", "downloadTokenizer", "Tokenizer", "downloadConfig", "downloadModel", "files", "currentStep", "reportProgress", "file", "baseProgress", "stepProgress", "modelFile", "modelData", "p", "tokenizer", "config", "fromHub", "modelExists", "getModelInfo", "onnxFile", "hasTokenizer", "POPULAR_MODELS", "getDefaultModel", "task", "fromTask", "benchmark", "fn", "options", "warmupRuns", "runs", "verbose", "timeout", "name", "times", "failedRuns", "i", "_", "reject", "start", "end", "error", "sorted", "a", "b", "avg", "variance", "sum", "t", "stdDev", "result", "compareBenchmarks", "baseline", "comparison", "baselineResult", "comparisonResult", "speedup", "percentFaster", "winner", "benchmarkSuite", "suite", "results", "formatBenchmarkResult", "formatComparisonResult", "arrow", "winnerText", "benchmarkMemory", "getMemory", "memoryReadings", "initialMemory", "peakMemory", "avgMemory", "memoryDelta", "init_types", "init_tensor", "calculateQuantParams", "data", "bits", "symmetric", "perChannel", "channelAxis", "shape", "qmin", "qmax", "numChannels", "scales", "zeroPoints", "channelSize", "globalMin", "globalMax", "c", "min", "max", "i", "idx", "val", "absMax", "scale", "zeroPoint", "quantizeToInt8", "result", "s", "zp", "quantizeToUint8", "quantizeToInt4", "packedLength", "val1", "val2", "q1", "q2", "quantizeToFloat16", "float32ToFloat16", "value", "float32View", "int32View", "f", "sign", "exponent", "mantissa", "m", "dequantizeInt8", "dequantizeUint8", "float16ToFloat32", "dequantizeFloat16", "parseModelWeights", "modelData", "weights", "float32Array", "serializeQuantizedModel", "model", "encoder", "totalSize", "weight", "nameBytes", "dtypeBytes", "origDtypeBytes", "buffer", "view", "uint8", "offset", "dim", "dataLow", "dataHigh", "quantizeModel", "options", "type", "skipPatterns", "onProgress", "minTensorSize", "originalSize", "layerStats", "tensorsQuantized", "tensorsSkipped", "quantizedWeights", "totalParams", "quantizedParams", "percent", "pattern", "params", "quantizedData", "quantizedDtype", "scaleValue", "zpValue", "avgScale", "a", "b", "minScale", "maxScale", "errorEstimate", "quantizeTensor", "tensor", "dtype", "EdgeFlowTensor", "dequantizeTensor", "dequantizedData", "scaleArr", "zpArr", "pruneTensor", "ratio", "method", "threshold", "mask", "prunedData", "prunedCount", "absValues", "thresholdIndex", "computedThreshold", "pruneModel", "prunedParams", "sparsity", "analyzeModel", "dtypeBreakdown", "tensorInfos", "bytesPerElement", "size", "largestTensors", "estimatedQuantizedSizes", "recommendedQuantization", "exportModel", "format", "quantize", "calculateTensorStats", "data", "arr", "min", "max", "sum", "zeros", "nans", "infinities", "i", "val", "validCount", "mean", "varianceSum", "std", "createHistogram", "bins", "binWidth", "counts", "binEdges", "binIndex", "e", "inspectTensor", "tensor", "name", "options", "histogram", "maxSample", "shape", "size", "sampleIndices", "step", "sample", "bytesPerElement", "memoryBytes", "formatTensorInspection", "inspection", "dtype", "stats", "lines", "formatBytes", "v", "bytes", "EdgeFlowDebugger", "config", "__publicField", "level", "message", "prefix", "levels", "configLevel", "event", "listeners", "listener", "type", "callback", "idx", "modelId", "id", "trace", "traceId", "t", "operation", "memory", "metrics", "traces", "recentTraces", "globalDebugger", "getDebugger", "enableDebugging", "debugger_", "disableDebugging", "createAsciiHistogram", "width", "height", "maxCount", "scaled", "c", "row", "line", "col", "minLabel", "maxLabel", "createTensorHeatmap", "rows", "cols", "range", "chars", "scaleX", "displayCols", "r", "normalized", "charIdx", "visualizeModelArchitecture", "layers", "layer", "inputStr", "outputStr", "PerformanceMonitor", "config", "__publicField", "now", "elapsed", "avgTime", "a", "b", "minTime", "maxTime", "throughput", "inference", "memory", "system", "custom", "collector", "sample", "listener", "usedHeap", "totalHeap", "heapLimit", "lastSample", "deltaTime", "webgpuAvailable", "webnnAvailable", "totalTime", "alert", "value", "triggered", "event", "metric", "parts", "part", "duration", "length", "count", "bytes", "callback", "idx", "startTime", "endTime", "s", "avgInferenceTime", "sum", "avgThroughput", "avgMemoryUsage", "avgFPS", "totalInferences", "firstSample", "uptime", "generateDashboardHTML", "monitor", "summary", "samples", "formatBytes", "ms", "generateChartPath", "width", "height", "padding", "times", "points", "i", "x", "y", "linePath", "areaPath", "gridLines", "generateAsciiDashboard", "bar", "max", "filled", "lines", "recentSamples", "chartHeight", "row", "line", "time", "globalMonitor", "getMonitor", "startMonitoring", "stopMonitoring", "quantize", "model", "options", "modelData", "getModelData", "originalSize", "quantizedData", "layersQuantized", "layersSkipped", "quantizeInt8", "quantizeUint8", "quantizeFloat16", "quantizeInt4", "_model", "data", "_options", "input", "output", "max", "i", "abs", "scale", "min", "val", "float32ToFloat16", "val1", "val2", "value", "floatView", "int32View", "x", "bits", "m", "e", "prune", "weights", "total", "sorted", "a", "b", "thresholdIdx", "threshold", "pruned", "analyzeModel", "size", "estimatedParams", "benchmark", "runFn", "warmupRuns", "runs", "times", "start", "avgTime", "minTime", "maxTime", "avgSquaredDiff", "t", "stdDev", "exportModel", "format", "array", "isSupported", "runtimes", "getAvailableRuntimes", "v", "getBestRuntimeType", "preload", "models", "cache", "ModelDownloadCache", "url", "response", "VERSION", "getInfo"]
|
|
7
7
|
}
|