{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/utils/config-parser.ts","../src/worker/worker-communicator.ts","../src/utils/video-frame-converter.ts","../src/core/encode.ts","../src/stream/encode-stream.ts","../src/utils/can-encode.ts","../src/factory/encoder.ts"],"sourcesContent":["// メイン関数ファーストAPI\nexport { encode } from \"./core/encode\";\nexport { encodeStream } from \"./stream/encode-stream\";\nexport { canEncode } from \"./utils/can-encode\";\n\n// 高度な使用向け：カスタムエンコーダーファクトリ\nexport { createEncoder, encoders, examples } from \"./factory/encoder\";\nexport type { EncoderFactory } from \"./factory/encoder\";\n\n// Legacy class-based API removed in v0.2.4 - use encodeStream() for MediaStream encoding\n\n// 型定義\nexport type {\n  VideoSource,\n  Frame,\n  EncodeOptions,\n  QualityPreset,\n  VideoConfig,\n  AudioConfig,\n  ProgressInfo,\n  EncodeErrorType,\n  VideoFile,\n} from \"./types\";\n\nexport { EncodeError } from './types';\n\n// 内部実装用（高度な使用のみ）\nexport type {\n  EncoderConfig,\n  ProcessingStage,\n  EncoderErrorType,\n  WorkerMessage,\n  MainThreadMessage,\n  VideoEncoderGetter,\n  AudioEncoderGetter,\n  AudioDataGetter,\n} from './types';\n","// Type definitions for new function-first API\n\n// Basic frame type\nexport type Frame = VideoFrame | HTMLCanvasElement | OffscreenCanvas | ImageBitmap | ImageData;\n\n// Video file type\nexport interface VideoFile {\n  file: File | Blob;\n  type: string;\n}\n\n// Video source type (all input formats)\nexport type VideoSource = \n  | Frame[]                    // Static frame array\n  | AsyncIterable<Frame>       // Streaming frames\n  | MediaStream               // Camera/screen sharing\n  | VideoFile;                // Existing video file\n\n// Quality presets\nexport type QualityPreset = 'low' | 'medium' | 'high' | 'lossless';\n\n// Video configuration\nexport interface VideoConfig {\n  codec?: 'avc' | 'hevc' | 'vp9' | 'vp8' | 'av1';\n  bitrate?: number;\n  hardwareAcceleration?: 'no-preference' | 'prefer-hardware' | 'prefer-software';\n  latencyMode?: 'quality' | 'realtime';\n  keyFrameInterval?: number;\n}\n\n// Audio configuration\nexport type AudioCodec =\n  | 'aac'\n  | 'opus'\n  | 'flac'\n  | 'mp3'\n  | 'vorbis'\n  | 'pcm'\n  | 'ulaw'\n  | 'alaw';\n\nexport interface AudioConfig {\n  codec?: AudioCodec;\n  bitrate?: number;\n  sampleRate?: number;\n  channels?: number;\n  bitrateMode?: 'constant' | 'variable';\n}\n\n// Progress information\nexport interface ProgressInfo {\n  percent: number;\n  processedFrames: number;\n  totalFrames?: number;\n  fps: number;\n  stage: string;\n  estimatedRemainingMs?: number;\n}\n\n// Encode options\nexport interface EncodeOptions {\n  // Basic settings (auto-detectable)\n  width?: number;\n  height?: number;\n  frameRate?: number;\n\n  // Quality preset\n  quality?: QualityPreset;\n\n  // Detailed settings (optional)\n  video?: VideoConfig | false; // false to disable video\n  audio?: AudioConfig | false; // false to disable audio\n  container?: 'mp4' | 'webm';\n\n  // Timestamp handling\n  firstTimestampBehavior?: \"offset\" | \"strict\";\n\n  // Latency mode (top level)\n  latencyMode?: \"quality\" | \"realtime\";\n\n  // Backpressure control\n  maxVideoQueueSize?: number; // Default: 30 frames\n  maxAudioQueueSize?: number; // Default: 30 chunks\n  backpressureStrategy?: \"drop\" | \"wait\"; // Default: \"drop\"\n\n  // Callbacks\n  onProgress?: (progress: ProgressInfo) => void;\n  onError?: (error: EncodeError) => void;\n}\n\n// Error types\nexport type EncodeErrorType =\n  | 'not-supported'\n  | 'initialization-failed'\n  | 'configuration-error'\n  | 'invalid-input' // Input source or frame data is invalid\n  | 'encoding-failed'\n  | 'video-encoding-error'\n  | 'audio-encoding-error'\n  | 'muxing-failed'\n  | 'cancelled'\n  | 'timeout'\n  | 'worker-error'\n  | 'filesystem-error' // VideoFile access errors\n  | 'unknown';\n\n// Custom error class\nexport class EncodeError extends Error {\n  type: EncodeErrorType;\n  cause?: unknown;\n\n  constructor(type: EncodeErrorType, message: string, cause?: unknown) {\n    super(message);\n    this.name = 'EncodeError';\n    this.type = type;\n    this.cause = cause;\n    Object.setPrototypeOf(this, EncodeError.prototype);\n  }\n}\n\n// --- Internal implementation type definitions (worker communication, etc.) ---\n\n// Basic configuration type for worker communication (internal implementation)\nexport interface EncoderConfig {\n  width: number;\n  height: number;\n  frameRate: number;\n  videoBitrate: number; // bps\n  audioBitrate: number; // bps\n  /**\n   * Controls bitrate distribution for AAC. \"constant\" produces constant\n   * bitrate (CBR) output while \"variable\" enables variable bitrate (VBR).\n   * Not all browsers respect this setting. Chrome 119+ improves CBR support.\n   */\n  audioBitrateMode?: \"constant\" | \"variable\";\n  sampleRate: number; // Hz\n  channels: number; // e.g., 1 for mono, 2 for stereo\n  container?: \"mp4\" | \"webm\"; // Default: 'mp4'. Set 'webm' for WebM output.\n  codec?: {\n    video?: \"avc\" | \"hevc\" | \"vp9\" | \"vp8\" | \"av1\"; // Default: 'avc' (H.264)\n    audio?: AudioCodec; // Default: 'aac'\n  };\n  /**\n   * Optional codec string overrides passed directly to the encoders.\n   * For example: `{ video: 'avc1.640028', audio: 'mp4a.40.2' }`.\n   */\n  codecString?: {\n    video?: string;\n    audio?: string;\n  };\n  latencyMode?: \"quality\" | \"realtime\"; // Default: 'quality'\n  /** Preference for hardware or software encoding. */\n  hardwareAcceleration?:\n    | \"prefer-hardware\"\n    | \"prefer-software\"\n    | \"no-preference\";\n  /** Drop new video frames when the number of queued frames exceeds `maxQueueDepth`. */\n  dropFrames?: boolean;\n  /** Maximum number of queued video frames before dropping. Defaults to `Infinity`. */\n  maxQueueDepth?: number;\n  /** Total frames for progress calculation if known in advance. */\n  totalFrames?: number;\n  /** Force a key frame every N video frames. */\n  keyFrameInterval?: number;\n  /**\n   * How to handle the first timestamp of a track.\n   * 'offset': Offsets all timestamps so the first one is 0.\n   * 'strict': Requires the first timestamp to be 0 (default).\n   */\n  firstTimestampBehavior?: \"offset\" | \"strict\";\n  /** Backpressure control for video queue */\n  maxVideoQueueSize?: number;\n  /** Backpressure control for audio queue */\n  maxAudioQueueSize?: number;\n  /** Backpressure strategy: drop frames or wait */\n  backpressureStrategy?: \"drop\" | \"wait\";\n  /** Additional VideoEncoder configuration overrides. */\n  videoEncoderConfig?: Partial<VideoEncoderConfig>;\n  /** Additional AudioEncoder configuration overrides. */\n  audioEncoderConfig?: Partial<AudioEncoderConfig>;\n}\n\n// Processing stage definitions\nexport enum ProcessingStage {\n  Initializing = \"initializing\",\n  VideoEncoding = \"video-encoding\",\n  AudioEncoding = \"audio-encoding\",\n  Muxing = \"muxing\",\n  Finalizing = \"finalizing\",\n}\n\n// Encoder error types (internal implementation)\nexport enum EncoderErrorType {\n  NotSupported = \"not-supported\",\n  InitializationFailed = \"initialization-failed\",\n  ConfigurationError = \"configuration-error\",\n  InvalidInput = \"invalid-input\", // Input source or frame data is invalid\n  EncodingFailed = \"encoding-failed\", // Generic encoding error\n  VideoEncodingError = \"video-encoding-error\", // Specific video encoding error\n  AudioEncodingError = \"audio-encoding-error\", // Specific audio encoding error\n  MuxingFailed = \"muxing-failed\",\n  Cancelled = \"cancelled\",\n  Timeout = \"timeout\",\n  WorkerError = \"worker-error\",\n  FilesystemError = \"filesystem-error\", // VideoFile access errors\n  Unknown = \"unknown\",\n}\n\n// --- Worker communication message types ---\n\n// Messages TO the Worker\nexport interface InitializeWorkerMessage {\n  type: \"initialize\";\n  config: EncoderConfig;\n  totalFrames?: number; // For progress calculation\n}\n\nexport interface AddVideoFrameMessage {\n  type: \"addVideoFrame\";\n  frame: VideoFrame;\n  timestamp: number; // microseconds\n}\n\nexport interface AddAudioDataMessage {\n  type: \"addAudioData\";\n  // Array of Float32Array for each channel (non-interleaved).\n  // The ArrayBuffer of each Float32Array should be transferred.\n  audioData?: Float32Array[];\n  /** Optional AudioData object to be encoded directly. */\n  audio?: AudioData;\n  timestamp: number; // microseconds\n  format: AudioSampleFormat; // e.g., \"f32-planar\" or \"s16\" etc. (AudioSampleFormat from WebCodecs)\n  sampleRate: number;\n  numberOfFrames: number;\n  numberOfChannels: number;\n}\n\nexport interface FinalizeWorkerMessage {\n  type: \"finalize\";\n}\n\nexport interface CancelWorkerMessage {\n  type: \"cancel\";\n}\n\nexport type WorkerMessage =\n  | InitializeWorkerMessage\n  | AddVideoFrameMessage\n  | AddAudioDataMessage\n  | FinalizeWorkerMessage\n  | CancelWorkerMessage;\n\n// Messages FROM the Worker\nexport interface WorkerInitializedMessage {\n  type: \"initialized\";\n  actualVideoCodec?: string;\n  actualAudioCodec?: string;\n}\n\nexport interface ProgressMessage {\n  type: \"progress\";\n  processedFrames: number;\n  totalFrames?: number;\n}\n\nexport interface WorkerFinalizedMessage {\n  type: \"finalized\";\n  output: Uint8Array | null; // MP4 file data or null when streaming\n}\n\nexport interface QueueSizeMessage {\n  type: \"queueSize\";\n  videoQueueSize: number;\n  audioQueueSize: number;\n}\n\nexport interface WorkerDataChunkMessage {\n  type: \"dataChunk\";\n  chunk: Uint8Array;\n  isHeader?: boolean; // Indicates if this chunk is a header (e.g., moov for MP4, EBML for WebM)\n  offset?: number; // For MP4 fragmented streaming\n  container: \"mp4\" | \"webm\"; // To inform the main thread which muxer this chunk belongs to\n}\n\nexport interface WorkerErrorMessage {\n  type: \"error\";\n  errorDetail: {\n    message: string;\n    type: EncoderErrorType;\n    stack?: string;\n  };\n}\n\nexport interface WorkerCancelledMessage {\n  type: \"cancelled\";\n}\n\nexport type MainThreadMessage =\n  | WorkerInitializedMessage\n  | ProgressMessage\n  | WorkerFinalizedMessage\n  | QueueSizeMessage\n  | WorkerDataChunkMessage\n  | WorkerErrorMessage\n  | WorkerCancelledMessage;\n\n// --- Helper Types for environment-dependent constructors ---\nexport type VideoEncoderConstructor = typeof VideoEncoder;\nexport type AudioEncoderConstructor = typeof AudioEncoder;\nexport type AudioDataConstructor = typeof AudioData;\n\nexport type VideoEncoderGetter = () => VideoEncoderConstructor | undefined;\nexport type AudioEncoderGetter = () => AudioEncoderConstructor | undefined;\nexport type AudioDataGetter = () => AudioDataConstructor | undefined;\n","/**\n * 設定の推定・変換・マージ処理のユーティリティ\n */\n\nimport {\n  EncodeOptions,\n  VideoSource,\n  Frame,\n  QualityPreset,\n  EncoderConfig,\n  VideoFile,\n} from \"../types\";\n\n/**\n * VideoSourceから設定を推定し、EncodeOptionsとマージして最終的なEncoderConfigを生成\n */\nexport async function inferAndBuildConfig(\n  source: VideoSource,\n  options?: EncodeOptions,\n): Promise<EncoderConfig> {\n  // ソースから基本的な設定を推定\n  const inferredConfig = await inferConfigFromSource(source);\n\n  // ユーザー指定のオプションをマージ\n  const mergedOptions = mergeWithUserOptions(inferredConfig, options);\n\n  // 品質プリセットを適用\n  const configWithPreset = applyQualityPreset(mergedOptions, options?.quality);\n\n  // 最終的なEncoderConfigに変換\n  return convertToEncoderConfig(configWithPreset);\n}\n\n/**\n * VideoSourceから基本設定を推定\n */\nasync function inferConfigFromSource(\n  source: VideoSource,\n): Promise<Partial<EncodeOptions>> {\n  const config: Partial<EncodeOptions> = {\n    frameRate: 30, // デフォルト値\n    container: \"mp4\", // デフォルト値\n  };\n\n  try {\n    // 最初のフレームを取得して解像度を推定\n    const firstFrame = await getFirstFrame(source);\n    if (firstFrame) {\n      const dimensions = getFrameDimensions(firstFrame);\n      config.width = dimensions.width;\n      config.height = dimensions.height;\n    }\n\n    if (isVideoFileSource(source)) {\n      await enrichConfigFromVideoFile(config, source);\n    }\n\n    // MediaStreamの場合はビデオ・オーディオトラックの有無も確認\n    if (source instanceof MediaStream) {\n      const videoTracks = source.getVideoTracks();\n      const audioTracks = source.getAudioTracks();\n\n      // ビデオトラックがない場合\n      if (videoTracks.length === 0) {\n        config.video = false; // ビデオなし\n      }\n\n      if (audioTracks.length === 0) {\n        config.audio = false; // オーディオなし\n      } else {\n        // MediaStreamTrackからオーディオ設定を推定\n        const audioTrack = audioTracks[0];\n        const settings = audioTrack.getSettings();\n        config.audio = {\n          sampleRate: settings.sampleRate || 48000,\n          channels: settings.channelCount || 2,\n        };\n      }\n    }\n  } catch (error) {\n    // 推定に失敗した場合はデフォルト値を使用\n    config.width = 640;\n    config.height = 480;\n  }\n\n  return config;\n}\n\n/**\n * ユーザー指定のオプションをマージ\n */\nfunction mergeWithUserOptions(\n  inferredConfig: Partial<EncodeOptions>,\n  userOptions?: EncodeOptions,\n): EncodeOptions {\n  const mergeNestedConfig = <T extends Record<string, any>>(\n    inferredValue: T | false | undefined,\n    userValue: T | false | undefined,\n  ): T | false | undefined => {\n    if (userValue === false) {\n      return false;\n    }\n\n    if (userValue === undefined) {\n      if (inferredValue === false) {\n        return false;\n      }\n      if (inferredValue && typeof inferredValue === \"object\") {\n        return { ...inferredValue };\n      }\n      return inferredValue;\n    }\n\n    if (inferredValue === false || inferredValue == null) {\n      return { ...userValue } as T;\n    }\n\n    return {\n      ...(inferredValue as T),\n      ...(userValue as T),\n    };\n  };\n\n  return {\n    // 推定された設定をベースに\n    ...inferredConfig,\n    // ユーザー指定の設定で上書き\n    ...userOptions,\n    // ネストしたオブジェクトは個別にマージ\n    video: mergeNestedConfig(\n      inferredConfig.video as any,\n      userOptions?.video as any,\n    ) as any,\n    audio: mergeNestedConfig(\n      inferredConfig.audio as any,\n      userOptions?.audio as any,\n    ) as any,\n  };\n}\n\n/**\n * 品質プリセットを適用\n */\nfunction applyQualityPreset(\n  config: EncodeOptions,\n  quality?: QualityPreset,\n): EncodeOptions {\n  if (!quality) return config;\n\n  const width = config.width || 640;\n  const height = config.height || 480;\n  const pixels = width * height;\n\n  // 解像度とフレームレートに基づいてビットレートを計算\n  const basePixelsPerSecond = pixels * (config.frameRate || 30);\n\n  let videoBitrate: number;\n  let audioBitrate: number;\n\n  switch (quality) {\n    case \"low\":\n      videoBitrate = Math.max(500_000, basePixelsPerSecond * 0.1);\n      audioBitrate = 64_000;\n      break;\n    case \"medium\":\n      videoBitrate = Math.max(1_000_000, basePixelsPerSecond * 0.2);\n      audioBitrate = 128_000;\n      break;\n    case \"high\":\n      videoBitrate = Math.max(2_000_000, basePixelsPerSecond * 0.4);\n      audioBitrate = 192_000;\n      break;\n    case \"lossless\":\n      videoBitrate = Math.max(10_000_000, basePixelsPerSecond * 1.0);\n      audioBitrate = 320_000;\n      break;\n    default:\n      return config;\n  }\n\n  const mergedAudio =\n    config.audio === false\n      ? false\n      : {\n          ...(config.audio as any),\n        };\n\n  if (mergedAudio && typeof mergedAudio === \"object\") {\n    const codec = (mergedAudio.codec || \"aac\") as any;\n    if (\n      codec !== \"pcm\" &&\n      codec !== \"ulaw\" &&\n      codec !== \"alaw\" &&\n      mergedAudio.bitrate == null\n    ) {\n      mergedAudio.bitrate = audioBitrate;\n    }\n  }\n\n  return {\n    ...config,\n    video:\n      config.video === false\n        ? false\n        : {\n            ...(config.video as any),\n            bitrate: (config.video as any)?.bitrate || videoBitrate,\n          },\n    audio: mergedAudio,\n  };\n}\n\n/**\n * EncodeOptionsから内部のEncoderConfigに変換\n */\nfunction convertToEncoderConfig(options: EncodeOptions): EncoderConfig {\n  const config: EncoderConfig = {\n    width: options.video === false ? 0 : options.width || 640,\n    height: options.video === false ? 0 : options.height || 480,\n    frameRate: options.frameRate || 30,\n    videoBitrate:\n      options.video === false\n        ? 0\n        : (options.video as any)?.bitrate || 1_000_000,\n    audioBitrate: 0,\n    sampleRate: 0,\n    channels: 0,\n    container: options.container || \"mp4\",\n    codec: {\n      video:\n        options.video === false\n          ? undefined\n          : (options.video as any)?.codec || \"avc\",\n      audio: undefined,\n    },\n    latencyMode:\n      options.video === false\n        ? \"quality\"\n        : options.latencyMode ||\n          (options.video as any)?.latencyMode ||\n          \"quality\",\n    hardwareAcceleration:\n      options.video === false\n        ? \"no-preference\"\n        : (options.video as any)?.hardwareAcceleration || \"no-preference\",\n    keyFrameInterval:\n      options.video === false\n        ? undefined\n        : (options.video as any)?.keyFrameInterval,\n    audioBitrateMode: undefined,\n    firstTimestampBehavior: options.firstTimestampBehavior || \"offset\",\n    maxVideoQueueSize: options.maxVideoQueueSize || 30,\n    maxAudioQueueSize: options.maxAudioQueueSize || 30,\n    backpressureStrategy: options.backpressureStrategy || \"drop\",\n  };\n\n  if (options.audio !== false) {\n    const audioOptions = (options.audio as any) || {};\n    const requestedCodec = (audioOptions.codec || \"aac\") as any;\n    const isTelephonyCodec =\n      requestedCodec === \"ulaw\" || requestedCodec === \"alaw\";\n    const isPcmCodec = requestedCodec === \"pcm\";\n\n    const defaultSampleRate =\n      audioOptions.sampleRate || (isTelephonyCodec ? 8000 : 48000);\n    const defaultChannels = audioOptions.channels || (isTelephonyCodec ? 1 : 2);\n\n    let defaultBitrate: number | undefined = audioOptions.bitrate;\n    if (defaultBitrate == null) {\n      if (isPcmCodec) {\n        defaultBitrate = defaultSampleRate * defaultChannels * 16; // Approximate bits per second\n      } else if (isTelephonyCodec) {\n        defaultBitrate = 64_000;\n      } else if (requestedCodec === \"mp3\") {\n        defaultBitrate = 128_000;\n      } else if (requestedCodec === \"flac\") {\n        defaultBitrate = 512_000;\n      } else if (requestedCodec === \"vorbis\") {\n        defaultBitrate = 128_000;\n      } else {\n        defaultBitrate = 128_000;\n      }\n    }\n\n    config.sampleRate = defaultSampleRate;\n    config.channels = defaultChannels;\n    config.audioBitrate = defaultBitrate;\n    config.codec = {\n      ...config.codec,\n      audio: requestedCodec,\n    };\n    config.audioBitrateMode =\n      audioOptions.bitrateMode ||\n      (requestedCodec === \"aac\" ? \"variable\" : \"constant\");\n  }\n\n  if (options.audio === false) {\n    config.codec = {\n      ...config.codec,\n      audio: undefined,\n    };\n  }\n\n  return config;\n}\n\n/**\n * VideoSourceから最初のフレームを取得（AsyncIterableの場合、元のイテレータを消費しない）\n */\nasync function getFirstFrame(source: VideoSource): Promise<Frame | null> {\n  if (Array.isArray(source)) {\n    return source.length > 0 ? source[0] : null;\n  }\n\n  if (source instanceof MediaStream) {\n    // MediaStreamから最初のフレームを取得するのは複雑なので、\n    // VideoTrackの設定から解像度を推定\n    const videoTracks = source.getVideoTracks();\n    if (videoTracks.length > 0) {\n      const settings = videoTracks[0].getSettings();\n      if (settings.width && settings.height) {\n        // 仮想的なフレームサイズ情報として返す\n        return {\n          displayWidth: settings.width,\n          displayHeight: settings.height,\n        } as any;\n      }\n    }\n    return null;\n  }\n\n  if (source && typeof (source as any)[Symbol.asyncIterator] === \"function\") {\n    // AsyncIterableは先頭フレームを安全にプレビューする手段がないため\n    // ここでは推定を行わず、後続処理でデフォルト値にフォールバックする\n    return null;\n  }\n\n  // VideoFileの場合は実装が必要（今回は簡略化）\n  return null;\n}\n\nasync function enrichConfigFromVideoFile(\n  config: Partial<EncodeOptions>,\n  videoFile: VideoFile,\n): Promise<void> {\n  if (typeof document === \"undefined\" || typeof URL === \"undefined\") {\n    return;\n  }\n\n  const file = videoFile.file;\n  if (!(typeof Blob !== \"undefined\" && file instanceof Blob)) {\n    return;\n  }\n\n  const video = document.createElement(\"video\");\n  video.preload = \"metadata\";\n\n  let objectUrl: string | null = null;\n  try {\n    objectUrl = URL.createObjectURL(file);\n    video.src = objectUrl;\n\n    await new Promise<void>((resolve, reject) => {\n      const cleanup = () => {\n        video.onloadedmetadata = null;\n        video.onerror = null;\n      };\n      video.onloadedmetadata = () => {\n        cleanup();\n        resolve();\n      };\n      video.onerror = () => {\n        cleanup();\n        reject(new Error(\"Failed to load video metadata\"));\n      };\n    });\n\n    if (video.videoWidth && video.videoHeight) {\n      config.width = video.videoWidth;\n      config.height = video.videoHeight;\n    }\n\n    if (!config.container && typeof videoFile.type === \"string\") {\n      if (videoFile.type.includes(\"webm\")) {\n        config.container = \"webm\";\n      } else if (videoFile.type.includes(\"mp4\")) {\n        config.container = \"mp4\";\n      }\n    }\n  } catch (error) {\n    console.warn(\"Failed to infer metadata from VideoFile\", error);\n  } finally {\n    if (objectUrl) {\n      URL.revokeObjectURL(objectUrl);\n    }\n    video.src = \"\";\n    video.remove?.();\n  }\n}\n\nfunction isVideoFileSource(source: VideoSource): source is VideoFile {\n  if (!source || typeof source !== \"object\") {\n    return false;\n  }\n\n  const maybeVideoFile = source as Partial<VideoFile> & { file?: unknown };\n  if (!(\"file\" in maybeVideoFile)) {\n    return false;\n  }\n\n  const file = maybeVideoFile.file;\n  if (typeof Blob !== \"undefined\" && file instanceof Blob) {\n    return true;\n  }\n  return false;\n}\n\n/**\n * フレームから解像度を取得\n */\nfunction getFrameDimensions(frame: Frame | null): {\n  width: number;\n  height: number;\n} {\n  if (!frame) {\n    return { width: 640, height: 480 };\n  }\n\n  if (frame instanceof VideoFrame) {\n    return {\n      width: frame.displayWidth || frame.codedWidth,\n      height: frame.displayHeight || frame.codedHeight,\n    };\n  }\n\n  if (frame instanceof HTMLCanvasElement || frame instanceof OffscreenCanvas) {\n    return { width: frame.width, height: frame.height };\n  }\n\n  if (frame instanceof ImageBitmap) {\n    return { width: frame.width, height: frame.height };\n  }\n\n  if (frame instanceof ImageData) {\n    return { width: frame.width, height: frame.height };\n  }\n\n  // 仮想的なフレーム情報の場合\n  if (\"displayWidth\" in frame && \"displayHeight\" in frame) {\n    return {\n      width: (frame as any).displayWidth,\n      height: (frame as any).displayHeight,\n    };\n  }\n\n  return { width: 640, height: 480 };\n}\n","/**\n * Worker creation and management\n */\n\nimport { EncodeError } from \"../types\";\n\n/**\n * Create external worker\n */\nfunction createExternalWorker(): Worker {\n  try {\n    // Use external worker file\n    const worker = new Worker(\"/webcodecs-worker.js\", { type: \"module\" });\n\n    // Worker error handling\n    worker.onerror = (event) => {\n      console.error(\"Worker error:\", event);\n      throw new EncodeError(\"worker-error\", `Worker error: ${event.message}`);\n    };\n\n    return worker;\n  } catch (error) {\n    throw new EncodeError(\n      \"initialization-failed\",\n      \"Failed to create external worker. Make sure webcodecs-worker.js is available in your public directory.\",\n      error,\n    );\n  }\n}\n\n/**\n * Create inline worker (for test environments)\n */\nfunction createInlineWorker(): { worker: Worker; blobUrl: string } {\n  try {\n    const workerSource = getWorkerSource();\n    const blob = new Blob([workerSource], { type: \"application/javascript\" });\n    const blobUrl = URL.createObjectURL(blob);\n\n    const worker = new Worker(blobUrl, { type: \"module\" });\n\n    worker.onerror = (event) => {\n      console.error(\"Inline worker error:\", event);\n      throw new EncodeError(\n        \"worker-error\",\n        `Inline worker error: ${event.message}`,\n      );\n    };\n\n    return { worker, blobUrl };\n  } catch (error) {\n    throw new EncodeError(\n      \"initialization-failed\",\n      \"Failed to create inline worker\",\n      error,\n    );\n  }\n}\n\n/**\n * Create appropriate worker\n */\nexport function createWorker(): Worker | { worker: Worker; blobUrl: string } {\n  const isTestEnvironment = detectTestEnvironment();\n  const isProductionEnvironment = detectProductionEnvironment();\n  const inlineOverride = hasInlineWorkerOverride();\n  const inlineDisabled = isInlineWorkerDisabled();\n\n  if (inlineOverride) {\n    if (isProductionEnvironment && !allowInlineOverrideInProduction()) {\n      throw new Error(\n        \"[WorkerCommunicator] Inline worker override is disabled in production environments.\",\n      );\n    }\n    console.warn(\"[WorkerCommunicator] Using inline worker (override).\");\n    return createInlineWorker();\n  }\n\n  if (isTestEnvironment && !inlineDisabled) {\n    console.warn(\n      \"[WorkerCommunicator] Using inline worker (test environment).\",\n    );\n    return createInlineWorker();\n  }\n\n  try {\n    return createExternalWorker();\n  } catch (error) {\n    if (!inlineDisabled && !isProductionEnvironment) {\n      console.warn(\n        \"[WorkerCommunicator] Failed to create external worker. Falling back to inline worker.\",\n        error,\n      );\n      return createInlineWorker();\n    }\n\n    if (!inlineDisabled) {\n      console.error(\n        \"[WorkerCommunicator] Failed to create external worker in a production-like environment.\",\n        error,\n      );\n    }\n\n    throw error;\n  }\n}\n\nfunction detectTestEnvironment(): boolean {\n  if (typeof process !== \"undefined\") {\n    if (process.env?.VITEST === \"true\") return true;\n    if (process.env?.JEST_WORKER_ID !== undefined) return true;\n    if (process.env?.NODE_ENV === \"test\") return true;\n    if (process.env?.npm_lifecycle_event?.includes(\"test\")) return true;\n  }\n\n  if (typeof globalThis !== \"undefined\" && (globalThis as any).vi) return true;\n\n  if (typeof global !== \"undefined\") {\n    const nodeEnv = (global as any).process?.env?.NODE_ENV;\n    if (nodeEnv === \"test\") return true;\n  }\n\n  if (typeof window !== \"undefined\") {\n    if (window.navigator?.userAgent?.includes(\"jsdom\")) return true;\n  }\n\n  return false;\n}\n\nfunction detectProductionEnvironment(): boolean {\n  if (typeof process !== \"undefined\") {\n    const nodeEnv = process.env?.NODE_ENV;\n    if (!nodeEnv) {\n      const lifecycle = process.env?.npm_lifecycle_event ?? \"\";\n      return /build|start|serve|preview/i.test(lifecycle);\n    }\n    return [\"production\", \"prod\", \"staging\", \"preview\"].includes(nodeEnv);\n  }\n\n  if (typeof window !== \"undefined\") {\n    const protocol = window.location?.protocol;\n    const hostname = window.location?.hostname ?? \"\";\n    const isLocalHost =\n      hostname === \"\" ||\n      hostname === \"localhost\" ||\n      hostname === \"127.0.0.1\" ||\n      hostname.endsWith(\".localhost\");\n\n    return protocol === \"https:\" && !isLocalHost;\n  }\n\n  return false;\n}\n\nfunction hasInlineWorkerOverride(): boolean {\n  return (\n    (typeof process !== \"undefined\" &&\n      process.env?.WEBCODECS_USE_INLINE_WORKER === \"true\") ||\n    (typeof window !== \"undefined\" &&\n      (window as any).__WEBCODECS_USE_INLINE_WORKER__ === true)\n  );\n}\n\nfunction allowInlineOverrideInProduction(): boolean {\n  return (\n    (typeof process !== \"undefined\" &&\n      process.env?.WEBCODECS_ALLOW_INLINE_IN_PROD === \"true\") ||\n    (typeof window !== \"undefined\" &&\n      (window as any).__WEBCODECS_ALLOW_INLINE_IN_PROD__ === true)\n  );\n}\n\nfunction isInlineWorkerDisabled(): boolean {\n  return (\n    (typeof process !== \"undefined\" &&\n      process.env?.WEBCODECS_DISABLE_INLINE_WORKER === \"true\") ||\n    (typeof window !== \"undefined\" &&\n      (window as any).__WEBCODECS_DISABLE_INLINE_WORKER__ === true)\n  );\n}\n\n/**\n * Generate inline worker source code (testing only)\n */\nfunction getWorkerSource(): string {\n  return `\n    // ⚠️  TESTING ONLY - DO NOT USE IN PRODUCTION ⚠️\n    // WebCodecs Encoder Worker (Inline Mock Implementation)\n    // This is a minimal mock for testing purposes only.\n    // Real encoding should use the external webcodecs-worker.js file.\n    \n    console.warn('⚠️  Using inline mock worker - FOR TESTING ONLY');\n    \n    let config = null;\n    let processedFrames = 0;\n    \n    self.onmessage = async function(event) {\n      const { type, ...data } = event.data;\n      \n      try {\n        switch (type) {\n          case 'initialize':\n            config = data.config;\n            processedFrames = 0;\n            // Wait a bit before sending success response\n            setTimeout(() => {\n              self.postMessage({ type: 'initialized' });\n            }, 50);\n            break;\n            \n          case 'addVideoFrame':\n            processedFrames++;\n            // Progress update\n            self.postMessage({ \n              type: 'progress', \n              processedFrames,\n              totalFrames: data.totalFrames \n            });\n            break;\n            \n          case 'addAudioData':\n            // Audio data processing (placeholder)\n            break;\n            \n          case 'finalize':\n            // Wait a bit before returning result\n            setTimeout(() => {\n              const result = new Uint8Array([0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70]); // MP4 magic number\n              self.postMessage({ type: 'finalized', output: result });\n            }, 100);\n            break;\n            \n          case 'cancel':\n            self.postMessage({ type: 'cancelled' });\n            break;\n            \n          default:\n            console.warn('Unknown message type:', type);\n        }\n      } catch (error) {\n        self.postMessage({ \n          type: 'error', \n          errorDetail: {\n            message: error.message,\n            type: 'encoding-failed',\n            stack: error.stack\n          }\n        });\n      }\n    };\n  `;\n}\n\n/**\n * Worker communication helper\n */\nexport class WorkerCommunicator {\n  private worker: Worker;\n  private messageHandlers: Map<string, (data: any) => void> = new Map();\n  private workerBlobUrl: string | null = null;\n\n  constructor() {\n    const workerResult = createWorker();\n    if (typeof workerResult === \"object\" && \"worker\" in workerResult) {\n      // Inline worker case\n      this.worker = workerResult.worker;\n      this.workerBlobUrl = workerResult.blobUrl;\n    } else {\n      // External worker case\n      this.worker = workerResult;\n    }\n    this.worker.onmessage = this.handleMessage.bind(this);\n  }\n\n  private handleMessage(event: MessageEvent): void {\n    const { type, ...data } = event.data;\n    const handler = this.messageHandlers.get(type);\n    if (handler) {\n      handler(data);\n    }\n  }\n\n  /**\n   * Register message handler\n   */\n  on(type: string, handler: (data: any) => void): void {\n    this.messageHandlers.set(type, handler);\n  }\n\n  /**\n   * Unregister message handler\n   */\n  off(type: string): void {\n    this.messageHandlers.delete(type);\n  }\n\n  /**\n   * Send message to worker\n   */\n  send(type: string, data: any = {}): void {\n    // Detect transferable objects for optimization\n    const transferables: Transferable[] = [];\n\n    // Safari compatibility: VideoFrame and AudioData should NOT be transferred\n    // as they cause issues in Safari when used as transferable objects\n    const isSafari =\n      typeof navigator !== \"undefined\" &&\n      /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n\n    // Optimize transfer only if ArrayBuffer is included\n    if (data.buffer instanceof ArrayBuffer) {\n      transferables.push(data.buffer);\n    }\n\n    // Deep scan for nested ArrayBuffers, but skip VideoFrame/AudioData\n    this.collectTransferables(data, transferables, isSafari);\n\n    // Use optimized transfer if transferable objects exist\n    if (transferables.length > 0) {\n      try {\n        this.worker.postMessage({ type, ...data }, transferables);\n      } catch (error) {\n        // Safari fallback: if transferable fails, send without transferables\n        console.warn(\n          \"Transferable object transfer failed, falling back to clone:\",\n          error,\n        );\n        this.worker.postMessage({ type, ...data });\n      }\n    } else {\n      this.worker.postMessage({ type, ...data });\n    }\n  }\n\n  /**\n   * Recursively collect transferable objects while avoiding problematic types\n   */\n  private collectTransferables(\n    obj: any,\n    transferables: Transferable[],\n    isSafari: boolean,\n  ): void {\n    if (!obj || typeof obj !== \"object\") return;\n\n    // Skip VideoFrame and AudioData objects as they cause Safari issues\n    if (typeof VideoFrame !== \"undefined\" && obj instanceof VideoFrame) return;\n    if (typeof AudioData !== \"undefined\" && obj instanceof AudioData) return;\n\n    // Safari-specific: avoid transferring certain objects\n    if (isSafari) {\n      // Be more conservative with Safari - only transfer obvious ArrayBuffers\n      if (obj instanceof ArrayBuffer && !transferables.includes(obj)) {\n        transferables.push(obj);\n      }\n      return;\n    }\n\n    // For other browsers, collect more transferable types\n    if (obj instanceof ArrayBuffer && !transferables.includes(obj)) {\n      transferables.push(obj);\n    } else if (obj instanceof MessagePort && !transferables.includes(obj)) {\n      transferables.push(obj);\n    } else if (\n      typeof ImageBitmap !== \"undefined\" &&\n      obj instanceof ImageBitmap &&\n      !transferables.includes(obj)\n    ) {\n      transferables.push(obj);\n    }\n\n    // Recursively check object properties\n    for (const key in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, key)) {\n        this.collectTransferables(obj[key], transferables, isSafari);\n      }\n    }\n  }\n\n  /**\n   * Terminate communication\n   */\n  terminate(): void {\n    this.messageHandlers.clear();\n    if (this.worker) {\n      this.worker.terminate();\n    }\n    if (this.workerBlobUrl) {\n      URL.revokeObjectURL(this.workerBlobUrl);\n      this.workerBlobUrl = null;\n    }\n  }\n}\n","/**\n * VideoFrame変換ユーティリティ\n */\n\nimport { EncodeError, Frame } from \"../types\";\n\n/**\n * FrameをVideoFrameに変換\n */\nexport async function convertToVideoFrame(\n  frame: Frame,\n  timestamp: number,\n): Promise<VideoFrame> {\n  if (frame instanceof VideoFrame) {\n    // Always create a new VideoFrame to ensure clear ownership\n    // The caller owns the returned VideoFrame and must close it\n    return new VideoFrame(frame, { timestamp });\n  }\n\n  // 他のFrame型をVideoFrameに変換\n  if (frame instanceof HTMLCanvasElement) {\n    return new VideoFrame(frame, { timestamp });\n  }\n\n  if (frame instanceof OffscreenCanvas) {\n    return new VideoFrame(frame, { timestamp });\n  }\n\n  if (frame instanceof ImageBitmap) {\n    return new VideoFrame(frame, { timestamp });\n  }\n\n  if (frame instanceof ImageData) {\n    // ImageDataの場合、BufferInitを使用\n    return new VideoFrame(frame.data, {\n      format: \"RGBA\",\n      codedWidth: frame.width,\n      codedHeight: frame.height,\n      timestamp,\n    });\n  }\n\n  // テスト環境でのモックオブジェクトの場合、プロパティベースで判定\n  if (frame && typeof frame === \"object\") {\n    // ImageDataに似たオブジェクト\n    if (\"width\" in frame && \"height\" in frame && \"data\" in frame) {\n      const imageDataLike = frame as {\n        width: number;\n        height: number;\n        data: Uint8ClampedArray;\n      };\n      return new VideoFrame(imageDataLike.data, {\n        format: \"RGBA\",\n        codedWidth: imageDataLike.width,\n        codedHeight: imageDataLike.height,\n        timestamp,\n      });\n    }\n\n    // Canvasに似たオブジェクト\n    if (\n      \"width\" in frame &&\n      \"height\" in frame &&\n      (\"getContext\" in frame || \"transferToImageBitmap\" in frame)\n    ) {\n      return new VideoFrame(frame as any, { timestamp });\n    }\n\n    // ImageBitmapに似たオブジェクト\n    if (\n      \"width\" in frame &&\n      \"height\" in frame &&\n      \"close\" in frame &&\n      typeof (frame as any).close === \"function\"\n    ) {\n      return new VideoFrame(frame as any, { timestamp });\n    }\n  }\n\n  throw new EncodeError(\n    \"invalid-input\",\n    `Unsupported frame type: ${typeof frame}. Frame must be VideoFrame, HTMLCanvasElement, OffscreenCanvas, ImageBitmap, or ImageData.`,\n  );\n}\n","/**\n * Core encode function implementation\n */\n\nimport {\n  VideoSource,\n  EncodeOptions,\n  EncodeError,\n  Frame,\n  ProgressInfo,\n  VideoFile,\n} from \"../types\";\nimport { inferAndBuildConfig } from \"../utils/config-parser\";\nimport { WorkerCommunicator } from \"../worker/worker-communicator\";\nimport { convertToVideoFrame } from \"../utils/video-frame-converter\";\n\n/**\n * Main video encoding function\n *\n * @param source Video source to encode\n * @param options Encoding options\n * @returns Encoded binary data\n */\nexport async function encode(\n  source: VideoSource,\n  options?: EncodeOptions,\n): Promise<Uint8Array> {\n  let communicator: WorkerCommunicator | null = null;\n\n  try {\n    // Configuration inference and normalization\n    const config = await inferAndBuildConfig(source, options);\n\n    // Start communication with worker\n    communicator = new WorkerCommunicator();\n\n    // Execute encoding process\n    const result = await performEncoding(communicator, source, config, options);\n\n    return result;\n  } catch (error) {\n    // Unified error handling\n    const encodeError =\n      error instanceof EncodeError\n        ? error\n        : new EncodeError(\n            \"encoding-failed\",\n            `Encoding failed: ${error instanceof Error ? error.message : String(error)}`,\n            error,\n          );\n\n    if (options?.onError) {\n      options.onError(encodeError);\n    }\n\n    throw encodeError;\n  } finally {\n    // Resource cleanup\n    if (communicator) {\n      communicator.terminate();\n    }\n  }\n}\n\n/**\n * Execute the actual encoding process\n */\nasync function performEncoding(\n  communicator: WorkerCommunicator,\n  source: VideoSource,\n  config: any,\n  options?: EncodeOptions,\n): Promise<Uint8Array> {\n  return new Promise<Uint8Array>((resolve, reject) => {\n    let processedFrames = 0;\n    let totalFrames: number | undefined;\n    const startTime = Date.now();\n\n    // Calculate totalFrames upfront for progress tracking\n    calculateTotalFrames(source, config)\n      .then((frames) => {\n        totalFrames = frames;\n      })\n      .catch((error) => {\n        console.warn(\"Failed to calculate total frames:\", error);\n      });\n\n    // Update progress information\n    const updateProgress = (stage: string) => {\n      if (options?.onProgress) {\n        const elapsed = Date.now() - startTime;\n        const fps =\n          processedFrames > 0 ? (processedFrames / elapsed) * 1000 : 0;\n        const percent = totalFrames ? (processedFrames / totalFrames) * 100 : 0;\n        const estimatedRemainingMs =\n          totalFrames && fps > 0\n            ? ((totalFrames - processedFrames) / fps) * 1000\n            : undefined;\n\n        const progressInfo: ProgressInfo = {\n          percent,\n          processedFrames,\n          totalFrames,\n          fps,\n          stage,\n          estimatedRemainingMs,\n        };\n\n        options.onProgress(progressInfo);\n      }\n    };\n\n    // Handle messages from worker\n    communicator.on(\"initialized\", () => {\n      updateProgress(\"encoding\");\n      // Start frame processing\n      processVideoSource(communicator, source, config)\n        .then(() => {\n          updateProgress(\"finalizing\");\n          communicator.send(\"finalize\");\n        })\n        .catch(reject);\n    });\n\n    communicator.on(\n      \"progress\",\n      (data: { processedFrames: number; totalFrames?: number }) => {\n        processedFrames = data.processedFrames;\n        if (data.totalFrames !== undefined) {\n          totalFrames = data.totalFrames;\n        }\n        updateProgress(\"encoding\");\n      },\n    );\n\n    communicator.on(\"finalized\", (data: { output: Uint8Array | null }) => {\n      if (data.output) {\n        updateProgress(\"finalizing\");\n        resolve(data.output);\n      } else {\n        reject(new EncodeError(\"encoding-failed\", \"No output produced\"));\n      }\n    });\n\n    communicator.on(\"error\", (data: { errorDetail: any }) => {\n      const error = new EncodeError(\n        data.errorDetail.type || \"encoding-failed\",\n        data.errorDetail.message || \"Worker error\",\n        data.errorDetail,\n      );\n      reject(error);\n    });\n\n    // Start encoding\n    communicator.send(\"initialize\", { config, totalFrames });\n  });\n}\n\n/**\n * Process VideoSource and send to worker\n */\nasync function processVideoSource(\n  communicator: WorkerCommunicator,\n  source: VideoSource,\n  config: any,\n): Promise<void> {\n  if (Array.isArray(source)) {\n    // Process static frame array\n    await processFrameArray(communicator, source, config);\n  } else if (source instanceof MediaStream) {\n    // Process MediaStream\n    await processMediaStream(communicator, source, config);\n  } else if (Symbol.asyncIterator in source) {\n    // Process AsyncIterable\n    await processAsyncIterable(communicator, source, config);\n  } else {\n    // Process VideoFile\n    await processVideoFile(communicator, source as VideoFile, config);\n  }\n}\n\n/**\n * Process frame array\n */\nasync function processFrameArray(\n  communicator: WorkerCommunicator,\n  frames: Frame[],\n  config?: any,\n): Promise<void> {\n  const frameRate = config?.frameRate || 30;\n  for (let i = 0; i < frames.length; i++) {\n    const frame = frames[i];\n    const timestamp = (i * 1000000) / frameRate; // Use frameRate from config\n\n    await addFrameToWorker(communicator, frame, timestamp);\n  }\n}\n\n/**\n * Process AsyncIterable\n */\nasync function processAsyncIterable(\n  communicator: WorkerCommunicator,\n  source: AsyncIterable<Frame>,\n  config?: any,\n): Promise<void> {\n  let frameIndex = 0;\n  const frameRate = config?.frameRate || 30;\n\n  for await (const frame of source) {\n    const timestamp = (frameIndex * 1000000) / frameRate; // Use frameRate from config\n    await addFrameToWorker(communicator, frame, timestamp);\n    frameIndex++;\n  }\n}\n\n/**\n * Process MediaStream\n */\nasync function processMediaStream(\n  communicator: WorkerCommunicator,\n  stream: MediaStream,\n  _config: any,\n): Promise<void> {\n  // MediaStream processing is complex, so use MediaStreamTrackProcessor\n  const videoTracks = stream.getVideoTracks();\n  const audioTracks = stream.getAudioTracks();\n\n  const readers: ReadableStreamDefaultReader<any>[] = [];\n  const processingPromises: Promise<void>[] = [];\n\n  try {\n    // Process video tracks\n    if (videoTracks.length > 0) {\n      const videoTrack = videoTracks[0];\n      const processor = new MediaStreamTrackProcessor({ track: videoTrack });\n      const reader =\n        processor.readable.getReader() as ReadableStreamDefaultReader<VideoFrame>;\n      readers.push(reader);\n\n      processingPromises.push(processVideoReader(communicator, reader));\n    }\n\n    // Process audio tracks\n    if (audioTracks.length > 0) {\n      const audioTrack = audioTracks[0];\n      const processor = new MediaStreamTrackProcessor({ track: audioTrack });\n      const reader =\n        processor.readable.getReader() as ReadableStreamDefaultReader<AudioData>;\n      readers.push(reader);\n\n      processingPromises.push(processAudioReader(communicator, reader));\n    }\n\n    // Wait for all processing to complete\n    await Promise.all(processingPromises);\n  } finally {\n    // Clean up readers\n    for (const reader of readers) {\n      try {\n        reader.cancel();\n      } catch (e) {\n        // Ignore errors (may already be cancelled)\n      }\n    }\n  }\n}\n\n/**\n * Process VideoFrame reader\n */\nasync function processVideoReader(\n  communicator: WorkerCommunicator,\n  reader: ReadableStreamDefaultReader<VideoFrame>,\n): Promise<void> {\n  try {\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      const { value, done } = await reader.read();\n      if (done || !value) break;\n\n      try {\n        await addFrameToWorker(communicator, value, value.timestamp || 0);\n      } finally {\n        value.close();\n      }\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"video-encoding-error\",\n      `Video stream processing error: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  }\n}\n\n/**\n * Process AudioData reader\n */\nasync function processAudioReader(\n  communicator: WorkerCommunicator,\n  reader: ReadableStreamDefaultReader<AudioData>,\n): Promise<void> {\n  try {\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      const { value, done } = await reader.read();\n      if (done || !value) break;\n\n      try {\n        communicator.send(\"addAudioData\", {\n          audio: value,\n          timestamp: value.timestamp || 0,\n          format: \"f32\",\n          sampleRate: value.sampleRate,\n          numberOfFrames: value.numberOfFrames,\n          numberOfChannels: value.numberOfChannels,\n        });\n      } finally {\n        value.close();\n      }\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"audio-encoding-error\",\n      `Audio stream processing error: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  }\n}\n\n/**\n * Send frame to worker\n */\nasync function addFrameToWorker(\n  communicator: WorkerCommunicator,\n  frame: Frame,\n  timestamp: number,\n): Promise<void> {\n  // Convert frame to VideoFrame\n  const videoFrame = await convertToVideoFrame(frame, timestamp);\n\n  try {\n    communicator.send(\"addVideoFrame\", {\n      frame: videoFrame,\n      timestamp,\n    });\n  } finally {\n    // convertToVideoFrame always returns a new VideoFrame that we own\n    videoFrame.close();\n  }\n}\n\n/**\n * Process VideoFile and extract frames\n */\nasync function processVideoFile(\n  communicator: WorkerCommunicator,\n  videoFile: VideoFile,\n  config: any,\n): Promise<void> {\n  const video = document.createElement(\"video\");\n  video.muted = true;\n  video.preload = \"metadata\";\n\n  let objectUrl: string | null = null;\n  let audioContext: AudioContext | null = null;\n\n  try {\n    objectUrl = URL.createObjectURL(videoFile.file);\n    video.src = objectUrl;\n\n    await new Promise<void>((resolve, reject) => {\n      const handleLoaded = () => {\n        cleanup();\n        resolve();\n      };\n      const handleError = () => {\n        cleanup();\n        reject(new Error(\"Failed to load video file\"));\n      };\n      const cleanup = () => {\n        video.onloadedmetadata = null;\n        video.onerror = null;\n      };\n      video.onloadedmetadata = handleLoaded;\n      video.onerror = handleError;\n    });\n\n    const { duration, videoWidth, videoHeight } = video;\n    const frameRate =\n      config.frameRate && config.frameRate > 0 ? config.frameRate : 30;\n    const totalFrames = Math.max(1, Math.floor(duration * frameRate) || 1);\n\n    if (config.audioBitrate > 0 && typeof AudioContext !== \"undefined\") {\n      try {\n        audioContext = new AudioContext();\n        const arrayBuffer = await videoFile.file.arrayBuffer();\n        const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n        await processAudioFromFile(\n          communicator,\n          audioBuffer,\n          duration,\n          frameRate,\n        );\n      } catch (audioError) {\n        console.warn(\"Failed to process audio from VideoFile:\", audioError);\n      }\n    }\n\n    const targetWidth =\n      config.width && config.width > 0 ? config.width : videoWidth || 640;\n    const targetHeight =\n      config.height && config.height > 0 ? config.height : videoHeight || 480;\n\n    const canvas = document.createElement(\"canvas\");\n    canvas.width = targetWidth;\n    canvas.height = targetHeight;\n    const ctx = canvas.getContext(\"2d\");\n\n    if (!ctx) {\n      throw new EncodeError(\n        \"initialization-failed\",\n        \"Failed to get canvas context\",\n      );\n    }\n\n    for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {\n      try {\n        const timestampSeconds = Math.min(\n          duration || 0,\n          frameIndex / frameRate,\n        );\n        video.currentTime = Number.isFinite(timestampSeconds)\n          ? timestampSeconds\n          : 0;\n\n        await new Promise<void>((resolve, reject) => {\n          const handleSeeked = () => {\n            cleanup();\n            resolve();\n          };\n          const handleError = () => {\n            cleanup();\n            reject(new Error(\"Video seek failed\"));\n          };\n          const cleanup = () => {\n            video.removeEventListener(\"seeked\", handleSeeked);\n            video.removeEventListener(\"error\", handleError);\n          };\n          video.addEventListener(\"seeked\", handleSeeked, { once: true });\n          video.addEventListener(\"error\", handleError, { once: true });\n        });\n\n        ctx.drawImage(\n          video,\n          0,\n          0,\n          videoWidth || canvas.width,\n          videoHeight || canvas.height,\n          0,\n          0,\n          canvas.width,\n          canvas.height,\n        );\n\n        const chunkTimestamp = Math.round(frameIndex * (1_000_000 / frameRate));\n        await addFrameToWorker(communicator, canvas, chunkTimestamp);\n      } catch (frameError) {\n        throw new EncodeError(\n          \"video-encoding-error\",\n          `Failed to process frame ${frameIndex}: ${frameError instanceof Error ? frameError.message : String(frameError)}`,\n          frameError,\n        );\n      }\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"invalid-input\",\n      `VideoFile processing failed: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  } finally {\n    if (audioContext) {\n      try {\n        await audioContext.close();\n      } catch (closeError) {\n        console.warn(\"Failed to close AudioContext\", closeError);\n      }\n    }\n\n    if (objectUrl) {\n      URL.revokeObjectURL(objectUrl);\n    }\n    video.src = \"\";\n    video.remove();\n  }\n}\n\n/**\n * Process audio data from AudioBuffer and send to worker\n */\nasync function processAudioFromFile(\n  communicator: WorkerCommunicator,\n  audioBuffer: AudioBuffer,\n  duration: number,\n  frameRate: number,\n): Promise<void> {\n  const sampleRate = audioBuffer.sampleRate;\n  const numberOfChannels = audioBuffer.numberOfChannels;\n  const totalSamples = audioBuffer.length;\n\n  // Split audio data into appropriate chunk sizes\n  // Use smaller chunk sizes for better memory efficiency\n  const chunkDurationMs = Math.min(20, 1000 / frameRate); // 20ms or frame duration, whichever is smaller\n  const samplesPerChunk = Math.floor((sampleRate * chunkDurationMs) / 1000);\n\n  for (let offset = 0; offset < totalSamples; offset += samplesPerChunk) {\n    const remainingSamples = Math.min(samplesPerChunk, totalSamples - offset);\n    const timestamp = (offset / sampleRate) * 1000000; // microseconds\n\n    // Get channel data\n    const channelData: Float32Array[] = [];\n    for (let channel = 0; channel < numberOfChannels; channel++) {\n      const sourceData = audioBuffer.getChannelData(channel);\n      const chunkData = new Float32Array(remainingSamples);\n      chunkData.set(sourceData.subarray(offset, offset + remainingSamples));\n      channelData.push(chunkData);\n    }\n\n    try {\n      // Create AudioData and send to worker\n      // Convert to interleaved format\n      const interleavedData = new Float32Array(\n        remainingSamples * numberOfChannels,\n      );\n      for (let frame = 0; frame < remainingSamples; frame++) {\n        for (let channel = 0; channel < numberOfChannels; channel++) {\n          interleavedData[frame * numberOfChannels + channel] =\n            channelData[channel][frame];\n        }\n      }\n\n      const audioData = new AudioData({\n        format: \"f32\",\n        sampleRate,\n        numberOfFrames: remainingSamples,\n        numberOfChannels,\n        timestamp,\n        data: interleavedData,\n      });\n\n      communicator.send(\"addAudioData\", {\n        audio: audioData,\n        timestamp,\n        format: \"f32\",\n        sampleRate,\n        numberOfFrames: remainingSamples,\n        numberOfChannels,\n      });\n\n      audioData.close();\n\n      // Release channel data for memory efficiency\n      channelData.length = 0;\n    } catch (error) {\n      console.warn(\"Failed to create AudioData chunk:\", error);\n    }\n  }\n}\n\n/**\n * Calculate total frames for different video sources\n */\nasync function calculateTotalFrames(\n  source: VideoSource,\n  config: any,\n): Promise<number | undefined> {\n  try {\n    if (Array.isArray(source)) {\n      // Static frame array\n      return source.length;\n    } else if (source instanceof MediaStream) {\n      // MediaStream - cannot predict total frames\n      return undefined;\n    } else if (Symbol.asyncIterator in source) {\n      // AsyncIterable - cannot predict total frames\n      return undefined;\n    } else {\n      // VideoFile - calculate from duration and frame rate\n      const videoFile = source as VideoFile;\n      const video = document.createElement(\"video\");\n      video.muted = true;\n      video.preload = \"metadata\";\n\n      const objectUrl = URL.createObjectURL(videoFile.file);\n      video.src = objectUrl;\n\n      try {\n        await new Promise<void>((resolve, reject) => {\n          video.onloadedmetadata = () => resolve();\n          video.onerror = () =>\n            reject(new Error(\"Failed to load video metadata\"));\n        });\n\n        const frameRate = config.frameRate || 30;\n        const totalFrames = Math.floor(video.duration * frameRate);\n\n        URL.revokeObjectURL(objectUrl);\n        return totalFrames;\n      } catch (error) {\n        URL.revokeObjectURL(objectUrl);\n        throw error;\n      }\n    }\n  } catch (error) {\n    console.warn(\"Failed to calculate total frames:\", error);\n    return undefined;\n  }\n}\n","/**\n * Streaming encode function implementation\n */\n\nimport {\n  VideoSource,\n  EncodeOptions,\n  EncodeError,\n  ProgressInfo,\n  VideoFile,\n} from \"../types\";\nimport { inferAndBuildConfig } from \"../utils/config-parser\";\nimport { WorkerCommunicator } from \"../worker/worker-communicator\";\nimport { convertToVideoFrame } from \"../utils/video-frame-converter\";\n\n/**\n * Streaming encode function\n *\n * @param source Video source to encode\n * @param options Encoding options\n * @returns AsyncGenerator of encoded chunks\n */\nexport async function* encodeStream(\n  source: VideoSource,\n  options?: EncodeOptions,\n): AsyncGenerator<Uint8Array> {\n  let communicator: WorkerCommunicator | null = null;\n  const chunks: Uint8Array[] = [];\n  let isFinalized = false;\n  let streamError: EncodeError | null = null;\n  let processedFrames = 0;\n  let totalFrames: number | undefined;\n  const startTime = Date.now();\n\n  try {\n    // Configuration inference and normalization (prioritize realtime mode)\n    const baseConfig = await inferAndBuildConfig(source, options);\n    const config = { ...baseConfig, latencyMode: \"realtime\" as const }; // Force setting for streaming\n\n    // Calculate totalFrames upfront for progress tracking\n    try {\n      totalFrames = await calculateTotalFrames(source, config);\n    } catch (error) {\n      console.warn(\"Failed to calculate total frames for streaming:\", error);\n    }\n\n    // Start communication with worker\n    communicator = new WorkerCommunicator();\n\n    // Update progress information\n    const updateProgress = (stage: string) => {\n      if (options?.onProgress) {\n        const elapsed = Date.now() - startTime;\n        const fps =\n          processedFrames > 0 ? (processedFrames / elapsed) * 1000 : 0;\n        const percent = totalFrames ? (processedFrames / totalFrames) * 100 : 0;\n        const estimatedRemainingMs =\n          totalFrames && fps > 0\n            ? ((totalFrames - processedFrames) / fps) * 1000\n            : undefined;\n\n        const progressInfo: ProgressInfo = {\n          percent,\n          processedFrames,\n          totalFrames,\n          fps,\n          stage,\n          estimatedRemainingMs,\n        };\n\n        options.onProgress(progressInfo);\n      }\n    };\n\n    // Manage encoding process start with Promise\n    const encodingPromise = new Promise<void>((resolve, reject) => {\n      // Handle messages from worker\n      communicator!.on(\"initialized\", () => {\n        updateProgress(\"streaming\");\n        // Start frame processing\n        processVideoSource(communicator!, source, config)\n          .then(() => {\n            updateProgress(\"finalizing\");\n            communicator!.send(\"finalize\");\n          })\n          .catch(reject);\n      });\n\n      communicator!.on(\n        \"progress\",\n        (data: { processedFrames: number; totalFrames?: number }) => {\n          processedFrames = data.processedFrames;\n          if (data.totalFrames !== undefined) {\n            totalFrames = data.totalFrames;\n          }\n          updateProgress(\"streaming\");\n        },\n      );\n\n      communicator!.on(\"dataChunk\", (data: { chunk: Uint8Array }) => {\n        chunks.push(data.chunk);\n      });\n\n      communicator!.on(\"finalized\", () => {\n        isFinalized = true;\n        updateProgress(\"finalizing\");\n        resolve();\n      });\n\n      communicator!.on(\"error\", (data: { errorDetail: any }) => {\n        streamError = new EncodeError(\n          data.errorDetail.type || \"encoding-failed\",\n          data.errorDetail.message || \"Worker error\",\n          data.errorDetail,\n        );\n        reject(streamError);\n      });\n\n      // Start encoding\n      communicator!.send(\"initialize\", { config, totalFrames });\n    });\n\n    // Error handling for encoding process\n    // Note: Don't use .catch() here as it would swallow the error\n    // Instead, let errors propagate and handle them later\n\n    // Yield chunks sequentially\n    while (!isFinalized && !streamError) {\n      if (chunks.length > 0) {\n        const chunk = chunks.shift()!;\n        yield chunk;\n      } else {\n        // Wait a bit before checking again\n        await new Promise((resolve) => setTimeout(resolve, 10));\n      }\n    }\n\n    // Yield remaining chunks\n    while (chunks.length > 0) {\n      const chunk = chunks.shift()!;\n      yield chunk;\n    }\n\n    // Throw exception if error occurred\n    if (streamError) {\n      throw streamError;\n    }\n\n    // Wait for encoding process completion\n    try {\n      await encodingPromise;\n    } catch (error) {\n      // If error occurred during encoding process\n      const encodeError =\n        error instanceof EncodeError\n          ? error\n          : new EncodeError(\n              \"encoding-failed\",\n              `Streaming failed: ${error instanceof Error ? error.message : String(error)}`,\n              error,\n            );\n\n      if (options?.onError) {\n        options.onError(encodeError);\n      }\n\n      throw encodeError;\n    }\n  } catch (error) {\n    // Unified error handling\n    const encodeError =\n      error instanceof EncodeError\n        ? error\n        : new EncodeError(\n            \"encoding-failed\",\n            `Stream encoding failed: ${error instanceof Error ? error.message : String(error)}`,\n            error,\n          );\n\n    if (options?.onError) {\n      options.onError(encodeError);\n    }\n\n    throw encodeError;\n  } finally {\n    // Resource cleanup\n    if (communicator) {\n      communicator.terminate();\n    }\n  }\n}\n\n/**\n * Process VideoSource and send to worker (for streaming)\n */\nasync function processVideoSource(\n  communicator: WorkerCommunicator,\n  source: VideoSource,\n  config: any,\n): Promise<void> {\n  if (Array.isArray(source)) {\n    // Process static frame array\n    await processFrameArray(communicator, source, config);\n  } else if (source instanceof MediaStream) {\n    // Process MediaStream (realtime)\n    await processMediaStreamRealtime(communicator, source, config);\n  } else if (Symbol.asyncIterator in source) {\n    // Process AsyncIterable\n    await processAsyncIterable(communicator, source, config);\n  } else {\n    // Process VideoFile\n    await processVideoFile(communicator, source as VideoFile, config);\n  }\n}\n\n/**\n * Process frame array (for streaming)\n */\nasync function processFrameArray(\n  communicator: WorkerCommunicator,\n  frames: import(\"../types\").Frame[],\n  config?: any,\n): Promise<void> {\n  const frameRate = config?.frameRate || 30;\n  const frameDelay = 1000 / frameRate;\n\n  let lastFrameTime = performance.now();\n\n  for (let i = 0; i < frames.length; i++) {\n    const frame = frames[i];\n    const timestamp = (i * 1000000) / frameRate;\n\n    await addFrameToWorker(communicator, frame, timestamp);\n\n    const now = performance.now();\n    const elapsedTime = now - lastFrameTime;\n    const delay = Math.max(0, frameDelay - elapsedTime);\n\n    await new Promise((resolve) => setTimeout(resolve, delay));\n    lastFrameTime = performance.now();\n  }\n}\n\n/**\n * Process AsyncIterable (for streaming)\n */\nasync function processAsyncIterable(\n  communicator: WorkerCommunicator,\n  source: AsyncIterable<import(\"../types\").Frame>,\n  config?: any,\n): Promise<void> {\n  let frameIndex = 0;\n  const frameRate = config?.frameRate || 30;\n\n  for await (const frame of source) {\n    const timestamp = (frameIndex * 1000000) / frameRate; // Use frameRate from config\n    await addFrameToWorker(communicator, frame, timestamp);\n    frameIndex++;\n  }\n}\n\n/**\n * Process MediaStream in realtime\n */\nasync function processMediaStreamRealtime(\n  communicator: WorkerCommunicator,\n  stream: MediaStream,\n  config: any,\n): Promise<void> {\n  const videoTracks = stream.getVideoTracks();\n  const audioTracks = stream.getAudioTracks();\n\n  const readers: ReadableStreamDefaultReader<any>[] = [];\n  const processingPromises: Promise<void>[] = [];\n\n  try {\n    // Process video tracks\n    if (videoTracks.length > 0) {\n      const videoTrack = videoTracks[0];\n      const processor = new MediaStreamTrackProcessor({ track: videoTrack });\n      const reader =\n        processor.readable.getReader() as ReadableStreamDefaultReader<VideoFrame>;\n      readers.push(reader);\n\n      processingPromises.push(\n        processVideoTrackRealtime(communicator, reader, config),\n      );\n    }\n\n    // Process audio tracks\n    if (audioTracks.length > 0) {\n      const audioTrack = audioTracks[0];\n      const processor = new MediaStreamTrackProcessor({ track: audioTrack });\n      const reader =\n        processor.readable.getReader() as ReadableStreamDefaultReader<AudioData>;\n      readers.push(reader);\n\n      processingPromises.push(processAudioTrackRealtime(communicator, reader));\n    }\n\n    // Wait for all processing to complete\n    await Promise.all(processingPromises);\n  } finally {\n    // Clean up readers\n    for (const reader of readers) {\n      try {\n        reader.cancel();\n      } catch (e) {\n        // Ignore errors (may already be cancelled)\n      }\n    }\n  }\n}\n\n/**\n * Process VideoTrack in realtime\n */\nasync function processVideoTrackRealtime(\n  communicator: WorkerCommunicator,\n  reader: ReadableStreamDefaultReader<VideoFrame>,\n  _config: any,\n): Promise<void> {\n  // Frame drop functionality planned for future implementation\n  // const maxQueueDepth = config.maxQueueDepth || 10;\n\n  try {\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      const { value, done } = await reader.read();\n      if (done || !value) break;\n\n      try {\n        await addFrameToWorker(communicator, value, value.timestamp || 0);\n      } finally {\n        value.close();\n      }\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"video-encoding-error\",\n      `Real-time video stream processing error: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  }\n}\n\n/**\n * Process AudioTrack in realtime\n */\nasync function processAudioTrackRealtime(\n  communicator: WorkerCommunicator,\n  reader: ReadableStreamDefaultReader<AudioData>,\n): Promise<void> {\n  try {\n    // eslint-disable-next-line no-constant-condition\n    while (true) {\n      const { value, done } = await reader.read();\n      if (done || !value) break;\n\n      try {\n        communicator.send(\"addAudioData\", {\n          audio: value,\n          timestamp: value.timestamp || 0,\n          format: \"f32\",\n          sampleRate: value.sampleRate,\n          numberOfFrames: value.numberOfFrames,\n          numberOfChannels: value.numberOfChannels,\n        });\n      } finally {\n        value.close();\n      }\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"audio-encoding-error\",\n      `Real-time audio stream processing error: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  }\n}\n\n/**\n * Send frame to worker\n */\nasync function addFrameToWorker(\n  communicator: WorkerCommunicator,\n  frame: import(\"../types\").Frame,\n  timestamp: number,\n): Promise<void> {\n  // Convert frame to VideoFrame\n  const videoFrame = await convertToVideoFrame(frame, timestamp);\n\n  try {\n    communicator.send(\"addVideoFrame\", {\n      frame: videoFrame,\n      timestamp,\n    });\n  } finally {\n    // convertToVideoFrame always returns a new VideoFrame that we own\n    videoFrame.close();\n  }\n}\n\n/**\n * Process VideoFile and extract frames (for streaming)\n */\nasync function processVideoFile(\n  communicator: WorkerCommunicator,\n  videoFile: VideoFile,\n  config: any,\n): Promise<void> {\n  const video = document.createElement(\"video\");\n  video.muted = true;\n  video.preload = \"metadata\";\n\n  let objectUrl: string | null = null;\n  let audioContext: AudioContext | null = null;\n\n  try {\n    objectUrl = URL.createObjectURL(videoFile.file);\n    video.src = objectUrl;\n\n    await new Promise<void>((resolve, reject) => {\n      const handleLoaded = () => {\n        cleanup();\n        resolve();\n      };\n      const handleError = () => {\n        cleanup();\n        reject(new Error(\"Failed to load video file\"));\n      };\n      const cleanup = () => {\n        video.onloadedmetadata = null;\n        video.onerror = null;\n      };\n      video.onloadedmetadata = handleLoaded;\n      video.onerror = handleError;\n    });\n\n    const { duration, videoWidth, videoHeight } = video;\n    const frameRate =\n      config.frameRate && config.frameRate > 0 ? config.frameRate : 30;\n    const totalFrames = Math.max(1, Math.floor(duration * frameRate) || 1);\n\n    if (config.audioBitrate > 0 && typeof AudioContext !== \"undefined\") {\n      try {\n        audioContext = new AudioContext();\n        const arrayBuffer = await videoFile.file.arrayBuffer();\n        const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n        await processAudioFromFile(\n          communicator,\n          audioBuffer,\n          duration,\n          frameRate,\n        );\n      } catch (audioError) {\n        console.warn(\"Failed to process audio from VideoFile:\", audioError);\n      }\n    }\n\n    const targetWidth =\n      config.width && config.width > 0 ? config.width : videoWidth || 640;\n    const targetHeight =\n      config.height && config.height > 0 ? config.height : videoHeight || 480;\n\n    const canvas = document.createElement(\"canvas\");\n    canvas.width = targetWidth;\n    canvas.height = targetHeight;\n    const ctx = canvas.getContext(\"2d\");\n\n    if (!ctx) {\n      throw new EncodeError(\n        \"initialization-failed\",\n        \"Failed to get canvas context\",\n      );\n    }\n\n    for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {\n      const timestampSeconds = Math.min(duration || 0, frameIndex / frameRate);\n      video.currentTime = Number.isFinite(timestampSeconds)\n        ? timestampSeconds\n        : 0;\n\n      await new Promise<void>((resolve, reject) => {\n        const handleSeeked = () => {\n          cleanup();\n          resolve();\n        };\n        const handleError = () => {\n          cleanup();\n          reject(new Error(\"Video seek failed\"));\n        };\n        const cleanup = () => {\n          video.removeEventListener(\"seeked\", handleSeeked);\n          video.removeEventListener(\"error\", handleError);\n        };\n        video.addEventListener(\"seeked\", handleSeeked, { once: true });\n        video.addEventListener(\"error\", handleError, { once: true });\n      });\n\n      ctx.drawImage(\n        video,\n        0,\n        0,\n        videoWidth || canvas.width,\n        videoHeight || canvas.height,\n        0,\n        0,\n        canvas.width,\n        canvas.height,\n      );\n\n      const chunkTimestamp = Math.round(frameIndex * (1_000_000 / frameRate));\n      await addFrameToWorker(communicator, canvas, chunkTimestamp);\n\n      await new Promise((resolve) => requestAnimationFrame(resolve));\n    }\n  } catch (error) {\n    throw new EncodeError(\n      \"invalid-input\",\n      `VideoFile processing failed: ${error instanceof Error ? error.message : String(error)}`,\n      error,\n    );\n  } finally {\n    if (audioContext) {\n      try {\n        await audioContext.close();\n      } catch (closeError) {\n        console.warn(\"Failed to close AudioContext\", closeError);\n      }\n    }\n\n    if (objectUrl) {\n      URL.revokeObjectURL(objectUrl);\n    }\n    video.src = \"\";\n    video.remove();\n  }\n}\n\n/**\n * Process audio data from AudioBuffer and send to worker (for streaming)\n */\nasync function processAudioFromFile(\n  communicator: WorkerCommunicator,\n  audioBuffer: AudioBuffer,\n  duration: number,\n  frameRate: number,\n): Promise<void> {\n  const sampleRate = audioBuffer.sampleRate;\n  const numberOfChannels = audioBuffer.numberOfChannels;\n  const totalSamples = audioBuffer.length;\n\n  const chunkDurationMs = Math.min(20, 1000 / frameRate);\n  const samplesPerChunk = Math.floor((sampleRate * chunkDurationMs) / 1000);\n\n  for (let offset = 0; offset < totalSamples; offset += samplesPerChunk) {\n    const remainingSamples = Math.min(samplesPerChunk, totalSamples - offset);\n    const timestamp = (offset / sampleRate) * 1000000;\n\n    const channelData: Float32Array[] = [];\n    for (let channel = 0; channel < numberOfChannels; channel++) {\n      const sourceData = audioBuffer.getChannelData(channel);\n      const chunkData = new Float32Array(remainingSamples);\n      chunkData.set(sourceData.subarray(offset, offset + remainingSamples));\n      channelData.push(chunkData);\n    }\n\n    try {\n      const interleavedData = new Float32Array(\n        remainingSamples * numberOfChannels,\n      );\n      for (let frame = 0; frame < remainingSamples; frame++) {\n        for (let channel = 0; channel < numberOfChannels; channel++) {\n          interleavedData[frame * numberOfChannels + channel] =\n            channelData[channel][frame];\n        }\n      }\n\n      const audioData = new AudioData({\n        format: \"f32\",\n        sampleRate,\n        numberOfFrames: remainingSamples,\n        numberOfChannels,\n        timestamp,\n        data: interleavedData,\n      });\n\n      communicator.send(\"addAudioData\", {\n        audio: audioData,\n        timestamp,\n        format: \"f32\",\n        sampleRate,\n        numberOfFrames: remainingSamples,\n        numberOfChannels,\n      });\n\n      audioData.close();\n      channelData.length = 0;\n    } catch (error) {\n      console.warn(\"Failed to create AudioData chunk:\", error);\n    }\n\n    // Don't block main thread\n    await new Promise((resolve) => setTimeout(resolve, 0));\n  }\n}\n\n/**\n * Calculate total frames for different video sources (streaming)\n */\nasync function calculateTotalFrames(\n  source: VideoSource,\n  config: any,\n): Promise<number | undefined> {\n  try {\n    if (Array.isArray(source)) {\n      // Static frame array\n      return source.length;\n    } else if (source instanceof MediaStream) {\n      // MediaStream - cannot predict total frames\n      return undefined;\n    } else if (Symbol.asyncIterator in source) {\n      // AsyncIterable - cannot predict total frames\n      return undefined;\n    } else {\n      // VideoFile - calculate from duration and frame rate\n      const videoFile = source as VideoFile;\n      const video = document.createElement(\"video\");\n      video.muted = true;\n      video.preload = \"metadata\";\n\n      const objectUrl = URL.createObjectURL(videoFile.file);\n      video.src = objectUrl;\n\n      try {\n        await new Promise<void>((resolve, reject) => {\n          video.onloadedmetadata = () => resolve();\n          video.onerror = () =>\n            reject(new Error(\"Failed to load video metadata\"));\n        });\n\n        const frameRate = config.frameRate || 30;\n        const totalFrames = Math.floor(video.duration * frameRate);\n\n        URL.revokeObjectURL(objectUrl);\n        return totalFrames;\n      } catch (error) {\n        URL.revokeObjectURL(objectUrl);\n        throw error;\n      }\n    }\n  } catch (error) {\n    console.warn(\"Failed to calculate total frames for streaming:\", error);\n    return undefined;\n  }\n}\n","/**\n * Encode capability verification\n */\n\nimport { EncodeOptions, VideoConfig, AudioConfig } from \"../types\";\n\n/**\n * Verify encode capability\n *\n * @param options Encode options\n * @returns Whether encoding is possible\n */\nexport async function canEncode(options?: EncodeOptions): Promise<boolean> {\n  try {\n    // Check basic WebCodecs support\n    if (!isWebCodecsSupported()) {\n      return false;\n    }\n\n    // Test with default configuration\n    if (!options) {\n      return await testDefaultConfiguration();\n    }\n\n    // Check video configuration unless explicitly disabled\n    const hasVideoConfig = options.video && typeof options.video === \"object\";\n    const videoEnabled = options.video !== false;\n    if (videoEnabled) {\n      const videoConfig = hasVideoConfig\n        ? (options.video as VideoConfig)\n        : undefined;\n      const videoCodec = videoConfig?.codec ?? \"avc\";\n      const videoSupported = await testVideoCodecSupport(videoCodec, options);\n      if (!videoSupported) {\n        return false;\n      }\n    }\n\n    // Check audio configuration (only if audio is explicitly specified)\n    const hasAudioConfig = options.audio && typeof options.audio === \"object\";\n    if (hasAudioConfig) {\n      const audioCodec = (options.audio as AudioConfig).codec || \"aac\";\n      const audioSupported = await testAudioCodecSupport(audioCodec, options);\n      if (!audioSupported) {\n        return false;\n      }\n    } else if (options.audio === undefined && !hasVideoConfig) {\n      // Only check audio for default configuration\n      const audioSupported = await testAudioCodecSupport(\"aac\", options);\n      if (!audioSupported) {\n        return false;\n      }\n    }\n\n    return true;\n  } catch (error) {\n    // If error occurs, assume not supported\n    console.warn(\"canEncode error:\", error);\n    return false;\n  }\n}\n\n/**\n * Check basic WebCodecs support\n */\nfunction isWebCodecsSupported(): boolean {\n  try {\n    return (\n      typeof VideoEncoder !== \"undefined\" &&\n      typeof AudioEncoder !== \"undefined\" &&\n      typeof VideoFrame !== \"undefined\" &&\n      typeof AudioData !== \"undefined\"\n    );\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Check encode capability with default configuration\n */\nasync function testDefaultConfiguration(): Promise<boolean> {\n  try {\n    const defaultWidth = 640;\n    const defaultHeight = 480;\n    const defaultFrameRate = 30;\n\n    // Test H.264 (AVC)\n    const videoConfig: VideoEncoderConfig = {\n      codec: generateAvcCodecString(\n        defaultWidth,\n        defaultHeight,\n        defaultFrameRate,\n      ),\n      width: defaultWidth,\n      height: defaultHeight,\n      bitrate: 1_000_000,\n      framerate: defaultFrameRate,\n    };\n\n    const videoSupport = await VideoEncoder.isConfigSupported(videoConfig);\n    if (!videoSupport.supported) {\n      return false;\n    }\n\n    // Test AAC\n    const audioConfig: AudioEncoderConfig = {\n      codec: \"mp4a.40.2\", // AAC-LC\n      sampleRate: 48000,\n      numberOfChannels: 2,\n      bitrate: 128_000,\n    };\n\n    const audioSupport = await AudioEncoder.isConfigSupported(audioConfig);\n    return audioSupport.supported || false;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Check video codec support\n */\nasync function testVideoCodecSupport(\n  codec: string,\n  options?: EncodeOptions,\n): Promise<boolean> {\n  try {\n    const videoOptions =\n      options?.video && typeof options.video === \"object\" ? options.video : {};\n    const codecString = getVideoCodecString(\n      codec,\n      options?.width || 640,\n      options?.height || 480,\n      options?.frameRate || 30,\n    );\n    const config: VideoEncoderConfig = {\n      codec: codecString,\n      width: options?.width || 640,\n      height: options?.height || 480,\n      bitrate: videoOptions.bitrate || 1_000_000,\n      framerate: options?.frameRate || 30,\n    };\n\n    // Add optional detailed settings\n    if (videoOptions.hardwareAcceleration) {\n      config.hardwareAcceleration = videoOptions.hardwareAcceleration;\n    }\n\n    if (videoOptions.latencyMode) {\n      config.latencyMode = videoOptions.latencyMode;\n    }\n\n    const support = await VideoEncoder.isConfigSupported(config);\n    return support.supported || false;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Check audio codec support\n */\nasync function testAudioCodecSupport(\n  codec: string,\n  options?: EncodeOptions,\n): Promise<boolean> {\n  try {\n    const codecString = getAudioCodecString(codec);\n    const audioOptions =\n      typeof options?.audio === \"object\" ? options.audio : {};\n\n    const isTelephonyCodec = codec === \"ulaw\" || codec === \"alaw\";\n    const isPcmCodec = codec === \"pcm\";\n    const defaultSampleRate =\n      audioOptions.sampleRate || (isTelephonyCodec ? 8000 : 48000);\n    const defaultChannels = audioOptions.channels || (isTelephonyCodec ? 1 : 2);\n\n    let defaultBitrate = audioOptions.bitrate;\n    if (defaultBitrate == null) {\n      if (codec === \"flac\") {\n        defaultBitrate = 512_000;\n      } else if (codec === \"mp3\") {\n        defaultBitrate = 128_000;\n      } else if (codec === \"vorbis\") {\n        defaultBitrate = 128_000;\n      } else if (isTelephonyCodec) {\n        defaultBitrate = 64_000;\n      } else if (isPcmCodec) {\n        defaultBitrate = defaultSampleRate * defaultChannels * 16;\n      } else {\n        defaultBitrate = 128_000;\n      }\n    }\n\n    const config: AudioEncoderConfig = {\n      codec: codecString,\n      sampleRate: defaultSampleRate,\n      numberOfChannels: defaultChannels,\n      bitrate: defaultBitrate,\n    };\n\n    // Add bitrateMode setting for AAC\n    if (codec === \"aac\" && audioOptions.bitrateMode) {\n      (config as any).bitrateMode = audioOptions.bitrateMode;\n    }\n\n    const support = await AudioEncoder.isConfigSupported(config);\n    return support.supported || false;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Convert video codec name to WebCodecs string\n */\nfunction getVideoCodecString(\n  codec: string,\n  width = 640,\n  height = 480,\n  frameRate = 30,\n): string {\n  switch (codec) {\n    case \"avc\":\n      return generateAvcCodecString(width, height, frameRate);\n    case \"hevc\":\n      return \"hvc1\"; // Align with worker default\n    case \"vp9\":\n      return \"vp09.00.50.08\"; // Align with worker fallback string\n    case \"vp8\":\n      return \"vp8\"; // VP8\n    case \"av1\":\n      return \"av01.0.04M.08\"; // AV1 Main Profile Level 4.0\n    default:\n      return codec; // Return as is (for custom codec strings)\n  }\n}\n\n/**\n * Dynamically generate AVC (H.264) codec string\n * Uses same logic as encoder-worker.ts\n */\nexport function generateAvcCodecString(\n  width: number,\n  height: number,\n  frameRate: number,\n  profile?: \"high\" | \"main\" | \"baseline\",\n): string {\n  const mbPerSec = Math.ceil(width / 16) * Math.ceil(height / 16) * frameRate;\n  let level: number;\n  if (mbPerSec <= 108000) level = 31;\n  else if (mbPerSec <= 216000) level = 32;\n  else if (mbPerSec <= 245760) level = 40;\n  else if (mbPerSec <= 589824) level = 50;\n  else if (mbPerSec <= 983040) level = 51;\n  else level = 52;\n\n  const chosenProfile =\n    profile ?? (width >= 1280 || height >= 720 ? \"high\" : \"baseline\");\n  const profileHex =\n    chosenProfile === \"high\" ? \"64\" : chosenProfile === \"main\" ? \"4d\" : \"42\";\n  const levelHex = level.toString(16).padStart(2, \"0\");\n\n  return `avc1.${profileHex}00${levelHex}`;\n}\n\n/**\n * Try multiple AVC profiles and return the first supported one\n */\nexport async function generateSupportedAvcCodecString(\n  width: number,\n  height: number,\n  frameRate: number,\n  bitrate: number,\n  preferredProfile?: \"high\" | \"main\" | \"baseline\",\n): Promise<string | null> {\n  // Define profile order based on preference\n  const profiles: (\"high\" | \"main\" | \"baseline\")[] = preferredProfile\n    ? (([preferredProfile, \"main\", \"baseline\", \"high\"] as const).filter(\n        (p, i, arr) => arr.indexOf(p) === i, // remove duplicates\n      ) as (\"high\" | \"main\" | \"baseline\")[])\n    : [\"high\", \"main\", \"baseline\"];\n\n  // Try each profile in order\n  for (const profile of profiles) {\n    const codecString = generateAvcCodecString(\n      width,\n      height,\n      frameRate,\n      profile,\n    );\n\n    try {\n      const config: VideoEncoderConfig = {\n        codec: codecString,\n        width,\n        height,\n        bitrate,\n        framerate: frameRate,\n      };\n\n      const support = await VideoEncoder.isConfigSupported(config);\n      if (support.supported) {\n        return codecString;\n      }\n    } catch (error) {\n      console.warn(\n        `Failed to check support for AVC profile ${profile}:`,\n        error,\n      );\n    }\n  }\n\n  return null;\n}\n\n/**\n * Convert audio codec name to WebCodecs string\n */\nfunction getAudioCodecString(codec: string): string {\n  switch (codec) {\n    case \"aac\":\n      return \"mp4a.40.2\"; // AAC-LC\n    case \"opus\":\n      return \"opus\"; // Opus\n    case \"flac\":\n      return \"flac\";\n    case \"mp3\":\n      return \"mp3\";\n    case \"vorbis\":\n      return \"vorbis\";\n    case \"pcm\":\n      return \"pcm\";\n    case \"ulaw\":\n      return \"ulaw\";\n    case \"alaw\":\n      return \"alaw\";\n    default:\n      return codec; // Return as is (for custom codec strings)\n  }\n}\n\n/**\n * Check support for specific codec and profile (for advanced users)\n */\nexport async function canEncodeWithProfile(\n  videoCodec: string,\n  audioCodec?: string,\n  profile?: {\n    width: number;\n    height: number;\n    framerate: number;\n    videoBitrate: number;\n    audioBitrate?: number;\n  },\n): Promise<{ video: boolean; audio: boolean; overall: boolean }> {\n  const result = { video: false, audio: false, overall: false };\n\n  try {\n    // Check video\n    if (videoCodec) {\n      const videoConfig: VideoEncoderConfig = {\n        codec: getVideoCodecString(videoCodec),\n        width: profile?.width || 1920,\n        height: profile?.height || 1080,\n        bitrate: profile?.videoBitrate || 2_000_000,\n        framerate: profile?.framerate || 30,\n      };\n\n      const videoSupport = await VideoEncoder.isConfigSupported(videoConfig);\n      result.video = videoSupport.supported || false;\n    }\n\n    // Check audio\n    if (audioCodec) {\n      const audioConfig: AudioEncoderConfig = {\n        codec: getAudioCodecString(audioCodec),\n        sampleRate: 48000,\n        numberOfChannels: 2,\n        bitrate: profile?.audioBitrate || 128_000,\n      };\n\n      const audioSupport = await AudioEncoder.isConfigSupported(audioConfig);\n      result.audio = audioSupport.supported || false;\n    } else {\n      result.audio = true; // Consider supported if no audio\n    }\n\n    result.overall = result.video && result.audio;\n    return result;\n  } catch (error) {\n    console.warn(\"canEncodeWithProfile error:\", error);\n    return result;\n  }\n}\n","/**\n * カスタムエンコーダーファクトリ\n */\n\nimport { encode } from \"../core/encode\";\nimport { encodeStream } from \"../stream/encode-stream\";\nimport { EncodeOptions, VideoSource } from \"../types\";\n\n/**\n * エンコーダー関数のファクトリ\n * 設定を事前に部分適用した専用エンコーダー関数を作成\n */\nexport interface EncoderFactory {\n  /**\n   * ワンショットエンコード\n   */\n  encode(\n    source: VideoSource,\n    additionalOptions?: Partial<EncodeOptions>,\n  ): Promise<Uint8Array>;\n\n  /**\n   * ストリーミングエンコード\n   */\n  encodeStream(\n    source: VideoSource,\n    additionalOptions?: Partial<EncodeOptions>,\n  ): AsyncGenerator<Uint8Array>;\n\n  /**\n   * 設定された設定を取得\n   */\n  getConfig(): EncodeOptions;\n\n  /**\n   * 新しい設定でファクトリを拡張\n   */\n  extend(newOptions: Partial<EncodeOptions>): EncoderFactory;\n}\n\n/**\n * カスタムエンコーダーファクトリを作成\n *\n * @param baseOptions 基本エンコードオプション\n * @returns 設定済みエンコーダーファクトリ\n */\nexport function createEncoder(baseOptions: EncodeOptions = {}): EncoderFactory {\n  const factory: EncoderFactory = {\n    async encode(\n      source: VideoSource,\n      additionalOptions?: Partial<EncodeOptions>,\n    ): Promise<Uint8Array> {\n      const mergedOptions = mergeOptions(baseOptions, additionalOptions);\n      return encode(source, mergedOptions);\n    },\n\n    async *encodeStream(\n      source: VideoSource,\n      additionalOptions?: Partial<EncodeOptions>,\n    ): AsyncGenerator<Uint8Array> {\n      const mergedOptions = mergeOptions(baseOptions, additionalOptions);\n      yield* encodeStream(source, mergedOptions);\n    },\n\n    getConfig(): EncodeOptions {\n      return { ...baseOptions };\n    },\n\n    extend(newOptions: Partial<EncodeOptions>): EncoderFactory {\n      const extendedOptions = mergeOptions(baseOptions, newOptions);\n      return createEncoder(extendedOptions);\n    },\n  };\n\n  return factory;\n}\n\n/**\n * オプションをマージ\n */\nfunction mergeOptions(\n  base: EncodeOptions,\n  additional?: Partial<EncodeOptions>,\n): EncodeOptions {\n  if (!additional) {\n    return { ...base };\n  }\n\n  const mergeNestedConfig = <T extends Record<string, any>>(\n    baseValue: T | false | undefined,\n    additionalValue: Partial<T> | false | undefined,\n  ): T | false | undefined => {\n    if (additionalValue === false) {\n      return false;\n    }\n\n    if (additionalValue === undefined) {\n      if (baseValue === false) {\n        return false;\n      }\n      if (baseValue && typeof baseValue === \"object\") {\n        return { ...baseValue };\n      }\n      return baseValue;\n    }\n\n    if (baseValue === false || baseValue == null) {\n      return { ...(additionalValue as T) };\n    }\n\n    return {\n      ...(baseValue as T),\n      ...(additionalValue as T),\n    };\n  };\n\n  return {\n    ...base,\n    ...additional,\n    // ネストしたオブジェクトは個別にマージ\n    video: mergeNestedConfig(base.video as any, additional.video as any) as any,\n    audio: mergeNestedConfig(base.audio as any, additional.audio as any) as any,\n  };\n}\n\n/**\n * 事前定義されたエンコーダーファクトリ\n */\nexport const encoders = {\n  /**\n   * YouTube向け高品質エンコーダー\n   */\n  youtube: createEncoder({\n    quality: \"high\",\n    frameRate: 60,\n    video: { codec: \"avc\" },\n    audio: { codec: \"aac\", bitrate: 192_000 },\n    container: \"mp4\",\n  }),\n\n  /**\n   * Twitter向け最適化エンコーダー\n   */\n  twitter: createEncoder({\n    quality: \"medium\",\n    width: 1280,\n    height: 720,\n    video: { bitrate: 2_000_000 },\n    audio: { bitrate: 128_000 },\n    container: \"mp4\",\n  }),\n\n  /**\n   * Discord向け最適化エンコーダー\n   */\n  discord: createEncoder({\n    quality: \"medium\",\n    video: { bitrate: 2_000_000 },\n    audio: { bitrate: 128_000 },\n    container: \"mp4\",\n  }),\n\n  /**\n   * Web再生向けバランス型エンコーダー\n   */\n  web: createEncoder({\n    quality: \"medium\",\n    container: \"mp4\",\n    video: { codec: \"avc\" },\n    audio: { codec: \"aac\" },\n  }),\n\n  /**\n   * 軽量・高速エンコーダー\n   */\n  fast: createEncoder({\n    quality: \"low\",\n    video: {\n      codec: \"avc\",\n      hardwareAcceleration: \"prefer-hardware\",\n      latencyMode: \"realtime\",\n    },\n    audio: {\n      codec: \"aac\",\n      bitrate: 64_000,\n    },\n  }),\n\n  /**\n   * 高品質・低圧縮エンコーダー\n   */\n  lossless: createEncoder({\n    quality: \"lossless\",\n    video: {\n      codec: \"hevc\",\n      latencyMode: \"quality\",\n    },\n    audio: {\n      codec: \"aac\",\n      bitrate: 320_000,\n    },\n  }),\n\n  /**\n   * VP9ストリーミング用エンコーダー\n   */\n  vp9Stream: createEncoder({\n    quality: \"medium\",\n    container: \"webm\",\n    video: {\n      codec: \"vp9\",\n      latencyMode: \"realtime\",\n    },\n    audio: { codec: \"opus\" },\n  }),\n};\n\n/**\n * 使用例とヘルパー関数\n */\nexport const examples = {\n  /**\n   * プラットフォーム別のエンコーダーを取得\n   */\n  getEncoderForPlatform(\n    platform: \"youtube\" | \"twitter\" | \"discord\" | \"web\",\n  ): EncoderFactory {\n    return encoders[platform];\n  },\n\n  /**\n   * 解像度ベースのエンコーダーを作成\n   */\n  createByResolution(width: number, height: number): EncoderFactory {\n    // 解像度に基づいて品質を自動選択\n    const pixels = width * height;\n    let quality: \"low\" | \"medium\" | \"high\";\n\n    if (pixels <= 640 * 480) {\n      quality = \"low\";\n    } else if (pixels <= 1920 * 1080) {\n      quality = \"medium\";\n    } else {\n      quality = \"high\";\n    }\n\n    return createEncoder({\n      width,\n      height,\n      quality,\n    });\n  },\n\n  /**\n   * ファイルサイズ制約ベースのエンコーダーを作成\n   */\n  createForFileSize(\n    targetSizeMB: number,\n    durationSeconds: number,\n  ): EncoderFactory {\n    // ファイルサイズからビットレートを逆算\n    const targetBits = targetSizeMB * 8 * 1024 * 1024;\n    const totalBitrate = Math.floor(targetBits / durationSeconds);\n    const videoBitrate = Math.floor(totalBitrate * 0.8); // 80%をビデオに\n    const audioBitrate = Math.floor(totalBitrate * 0.2); // 20%をオーディオに\n\n    return createEncoder({\n      video: { bitrate: videoBitrate },\n      audio: { bitrate: Math.min(audioBitrate, 320_000) }, // 上限320kbps\n    });\n  },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC2GO,IAAM,cAAN,MAAM,qBAAoB,MAAM;AAAA,EAIrC,YAAY,MAAuB,SAAiB,OAAiB;AACnE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,WAAO,eAAe,MAAM,aAAY,SAAS;AAAA,EACnD;AACF;;;ACtGA,eAAsB,oBACpB,QACA,SACwB;AAExB,QAAM,iBAAiB,MAAM,sBAAsB,MAAM;AAGzD,QAAM,gBAAgB,qBAAqB,gBAAgB,OAAO;AAGlE,QAAM,mBAAmB,mBAAmB,eAAe,SAAS,OAAO;AAG3E,SAAO,uBAAuB,gBAAgB;AAChD;AAKA,eAAe,sBACb,QACiC;AACjC,QAAM,SAAiC;AAAA,IACrC,WAAW;AAAA;AAAA,IACX,WAAW;AAAA;AAAA,EACb;AAEA,MAAI;AAEF,UAAM,aAAa,MAAM,cAAc,MAAM;AAC7C,QAAI,YAAY;AACd,YAAM,aAAa,mBAAmB,UAAU;AAChD,aAAO,QAAQ,WAAW;AAC1B,aAAO,SAAS,WAAW;AAAA,IAC7B;AAEA,QAAI,kBAAkB,MAAM,GAAG;AAC7B,YAAM,0BAA0B,QAAQ,MAAM;AAAA,IAChD;AAGA,QAAI,kBAAkB,aAAa;AACjC,YAAM,cAAc,OAAO,eAAe;AAC1C,YAAM,cAAc,OAAO,eAAe;AAG1C,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,QAAQ;AAAA,MACjB,OAAO;AAEL,cAAM,aAAa,YAAY,CAAC;AAChC,cAAM,WAAW,WAAW,YAAY;AACxC,eAAO,QAAQ;AAAA,UACb,YAAY,SAAS,cAAc;AAAA,UACnC,UAAU,SAAS,gBAAgB;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAEd,WAAO,QAAQ;AACf,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO;AACT;AAKA,SAAS,qBACP,gBACA,aACe;AACf,QAAM,oBAAoB,CACxB,eACA,cAC0B;AAC1B,QAAI,cAAc,OAAO;AACvB,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,QAAW;AAC3B,UAAI,kBAAkB,OAAO;AAC3B,eAAO;AAAA,MACT;AACA,UAAI,iBAAiB,OAAO,kBAAkB,UAAU;AACtD,eAAO,EAAE,GAAG,cAAc;AAAA,MAC5B;AACA,aAAO;AAAA,IACT;AAEA,QAAI,kBAAkB,SAAS,iBAAiB,MAAM;AACpD,aAAO,EAAE,GAAG,UAAU;AAAA,IACxB;AAEA,WAAO;AAAA,MACL,GAAI;AAAA,MACJ,GAAI;AAAA,IACN;AAAA,EACF;AAEA,SAAO;AAAA;AAAA,IAEL,GAAG;AAAA;AAAA,IAEH,GAAG;AAAA;AAAA,IAEH,OAAO;AAAA,MACL,eAAe;AAAA,MACf,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,eAAe;AAAA,MACf,aAAa;AAAA,IACf;AAAA,EACF;AACF;AAKA,SAAS,mBACP,QACA,SACe;AACf,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,QAAQ,OAAO,SAAS;AAC9B,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,QAAQ;AAGvB,QAAM,sBAAsB,UAAU,OAAO,aAAa;AAE1D,MAAI;AACJ,MAAI;AAEJ,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,qBAAe,KAAK,IAAI,KAAS,sBAAsB,GAAG;AAC1D,qBAAe;AACf;AAAA,IACF,KAAK;AACH,qBAAe,KAAK,IAAI,KAAW,sBAAsB,GAAG;AAC5D,qBAAe;AACf;AAAA,IACF,KAAK;AACH,qBAAe,KAAK,IAAI,KAAW,sBAAsB,GAAG;AAC5D,qBAAe;AACf;AAAA,IACF,KAAK;AACH,qBAAe,KAAK,IAAI,KAAY,sBAAsB,CAAG;AAC7D,qBAAe;AACf;AAAA,IACF;AACE,aAAO;AAAA,EACX;AAEA,QAAM,cACJ,OAAO,UAAU,QACb,QACA;AAAA,IACE,GAAI,OAAO;AAAA,EACb;AAEN,MAAI,eAAe,OAAO,gBAAgB,UAAU;AAClD,UAAM,QAAS,YAAY,SAAS;AACpC,QACE,UAAU,SACV,UAAU,UACV,UAAU,UACV,YAAY,WAAW,MACvB;AACA,kBAAY,UAAU;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OACE,OAAO,UAAU,QACb,QACA;AAAA,MACE,GAAI,OAAO;AAAA,MACX,SAAU,OAAO,OAAe,WAAW;AAAA,IAC7C;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAKA,SAAS,uBAAuB,SAAuC;AACrE,QAAM,SAAwB;AAAA,IAC5B,OAAO,QAAQ,UAAU,QAAQ,IAAI,QAAQ,SAAS;AAAA,IACtD,QAAQ,QAAQ,UAAU,QAAQ,IAAI,QAAQ,UAAU;AAAA,IACxD,WAAW,QAAQ,aAAa;AAAA,IAChC,cACE,QAAQ,UAAU,QACd,IACC,QAAQ,OAAe,WAAW;AAAA,IACzC,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,WAAW,QAAQ,aAAa;AAAA,IAChC,OAAO;AAAA,MACL,OACE,QAAQ,UAAU,QACd,SACC,QAAQ,OAAe,SAAS;AAAA,MACvC,OAAO;AAAA,IACT;AAAA,IACA,aACE,QAAQ,UAAU,QACd,YACA,QAAQ,eACP,QAAQ,OAAe,eACxB;AAAA,IACN,sBACE,QAAQ,UAAU,QACd,kBACC,QAAQ,OAAe,wBAAwB;AAAA,IACtD,kBACE,QAAQ,UAAU,QACd,SACC,QAAQ,OAAe;AAAA,IAC9B,kBAAkB;AAAA,IAClB,wBAAwB,QAAQ,0BAA0B;AAAA,IAC1D,mBAAmB,QAAQ,qBAAqB;AAAA,IAChD,mBAAmB,QAAQ,qBAAqB;AAAA,IAChD,sBAAsB,QAAQ,wBAAwB;AAAA,EACxD;AAEA,MAAI,QAAQ,UAAU,OAAO;AAC3B,UAAM,eAAgB,QAAQ,SAAiB,CAAC;AAChD,UAAM,iBAAkB,aAAa,SAAS;AAC9C,UAAM,mBACJ,mBAAmB,UAAU,mBAAmB;AAClD,UAAM,aAAa,mBAAmB;AAEtC,UAAM,oBACJ,aAAa,eAAe,mBAAmB,MAAO;AACxD,UAAM,kBAAkB,aAAa,aAAa,mBAAmB,IAAI;AAEzE,QAAI,iBAAqC,aAAa;AACtD,QAAI,kBAAkB,MAAM;AAC1B,UAAI,YAAY;AACd,yBAAiB,oBAAoB,kBAAkB;AAAA,MACzD,WAAW,kBAAkB;AAC3B,yBAAiB;AAAA,MACnB,WAAW,mBAAmB,OAAO;AACnC,yBAAiB;AAAA,MACnB,WAAW,mBAAmB,QAAQ;AACpC,yBAAiB;AAAA,MACnB,WAAW,mBAAmB,UAAU;AACtC,yBAAiB;AAAA,MACnB,OAAO;AACL,yBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,WAAO,aAAa;AACpB,WAAO,WAAW;AAClB,WAAO,eAAe;AACtB,WAAO,QAAQ;AAAA,MACb,GAAG,OAAO;AAAA,MACV,OAAO;AAAA,IACT;AACA,WAAO,mBACL,aAAa,gBACZ,mBAAmB,QAAQ,aAAa;AAAA,EAC7C;AAEA,MAAI,QAAQ,UAAU,OAAO;AAC3B,WAAO,QAAQ;AAAA,MACb,GAAG,OAAO;AAAA,MACV,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAe,cAAc,QAA4C;AACvE,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,OAAO,SAAS,IAAI,OAAO,CAAC,IAAI;AAAA,EACzC;AAEA,MAAI,kBAAkB,aAAa;AAGjC,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,WAAW,YAAY,CAAC,EAAE,YAAY;AAC5C,UAAI,SAAS,SAAS,SAAS,QAAQ;AAErC,eAAO;AAAA,UACL,cAAc,SAAS;AAAA,UACvB,eAAe,SAAS;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,OAAQ,OAAe,OAAO,aAAa,MAAM,YAAY;AAGzE,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAEA,eAAe,0BACb,QACA,WACe;AACf,MAAI,OAAO,aAAa,eAAe,OAAO,QAAQ,aAAa;AACjE;AAAA,EACF;AAEA,QAAM,OAAO,UAAU;AACvB,MAAI,EAAE,OAAO,SAAS,eAAe,gBAAgB,OAAO;AAC1D;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,UAAU;AAEhB,MAAI,YAA2B;AAC/B,MAAI;AACF,gBAAY,IAAI,gBAAgB,IAAI;AACpC,UAAM,MAAM;AAEZ,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,UAAU,MAAM;AACpB,cAAM,mBAAmB;AACzB,cAAM,UAAU;AAAA,MAClB;AACA,YAAM,mBAAmB,MAAM;AAC7B,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,YAAM,UAAU,MAAM;AACpB,gBAAQ;AACR,eAAO,IAAI,MAAM,+BAA+B,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAED,QAAI,MAAM,cAAc,MAAM,aAAa;AACzC,aAAO,QAAQ,MAAM;AACrB,aAAO,SAAS,MAAM;AAAA,IACxB;AAEA,QAAI,CAAC,OAAO,aAAa,OAAO,UAAU,SAAS,UAAU;AAC3D,UAAI,UAAU,KAAK,SAAS,MAAM,GAAG;AACnC,eAAO,YAAY;AAAA,MACrB,WAAW,UAAU,KAAK,SAAS,KAAK,GAAG;AACzC,eAAO,YAAY;AAAA,MACrB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,2CAA2C,KAAK;AAAA,EAC/D,UAAE;AACA,QAAI,WAAW;AACb,UAAI,gBAAgB,SAAS;AAAA,IAC/B;AACA,UAAM,MAAM;AACZ,UAAM,SAAS;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,QAA0C;AACnE,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB;AACvB,MAAI,EAAE,UAAU,iBAAiB;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,eAAe;AAC5B,MAAI,OAAO,SAAS,eAAe,gBAAgB,MAAM;AACvD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,SAAS,mBAAmB,OAG1B;AACA,MAAI,CAAC,OAAO;AACV,WAAO,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,EACnC;AAEA,MAAI,iBAAiB,YAAY;AAC/B,WAAO;AAAA,MACL,OAAO,MAAM,gBAAgB,MAAM;AAAA,MACnC,QAAQ,MAAM,iBAAiB,MAAM;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,iBAAiB,qBAAqB,iBAAiB,iBAAiB;AAC1E,WAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,EACpD;AAEA,MAAI,iBAAiB,aAAa;AAChC,WAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,EACpD;AAEA,MAAI,iBAAiB,WAAW;AAC9B,WAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,EACpD;AAGA,MAAI,kBAAkB,SAAS,mBAAmB,OAAO;AACvD,WAAO;AAAA,MACL,OAAQ,MAAc;AAAA,MACtB,QAAS,MAAc;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,KAAK,QAAQ,IAAI;AACnC;;;AC/bA,SAAS,uBAA+B;AACtC,MAAI;AAEF,UAAM,SAAS,IAAI,OAAO,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAGpE,WAAO,UAAU,CAAC,UAAU;AAC1B,cAAQ,MAAM,iBAAiB,KAAK;AACpC,YAAM,IAAI,YAAY,gBAAgB,iBAAiB,MAAM,OAAO,EAAE;AAAA,IACxE;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,qBAA0D;AACjE,MAAI;AACF,UAAM,eAAe,gBAAgB;AACrC,UAAM,OAAO,IAAI,KAAK,CAAC,YAAY,GAAG,EAAE,MAAM,yBAAyB,CAAC;AACxE,UAAM,UAAU,IAAI,gBAAgB,IAAI;AAExC,UAAM,SAAS,IAAI,OAAO,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,WAAO,UAAU,CAAC,UAAU;AAC1B,cAAQ,MAAM,wBAAwB,KAAK;AAC3C,YAAM,IAAI;AAAA,QACR;AAAA,QACA,wBAAwB,MAAM,OAAO;AAAA,MACvC;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,QAAQ;AAAA,EAC3B,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,eAA6D;AAC3E,QAAM,oBAAoB,sBAAsB;AAChD,QAAM,0BAA0B,4BAA4B;AAC5D,QAAM,iBAAiB,wBAAwB;AAC/C,QAAM,iBAAiB,uBAAuB;AAE9C,MAAI,gBAAgB;AAClB,QAAI,2BAA2B,CAAC,gCAAgC,GAAG;AACjE,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,YAAQ,KAAK,sDAAsD;AACnE,WAAO,mBAAmB;AAAA,EAC5B;AAEA,MAAI,qBAAqB,CAAC,gBAAgB;AACxC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,mBAAmB;AAAA,EAC5B;AAEA,MAAI;AACF,WAAO,qBAAqB;AAAA,EAC9B,SAAS,OAAO;AACd,QAAI,CAAC,kBAAkB,CAAC,yBAAyB;AAC/C,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AACA,aAAO,mBAAmB;AAAA,IAC5B;AAEA,QAAI,CAAC,gBAAgB;AACnB,cAAQ;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAEA,SAAS,wBAAiC;AACxC,MAAI,OAAO,YAAY,aAAa;AAClC,QAAI,QAAQ,KAAK,WAAW,OAAQ,QAAO;AAC3C,QAAI,QAAQ,KAAK,mBAAmB,OAAW,QAAO;AACtD,QAAI,QAAQ,KAAK,aAAa,OAAQ,QAAO;AAC7C,QAAI,QAAQ,KAAK,qBAAqB,SAAS,MAAM,EAAG,QAAO;AAAA,EACjE;AAEA,MAAI,OAAO,eAAe,eAAgB,WAAmB,GAAI,QAAO;AAExE,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,UAAW,OAAe,SAAS,KAAK;AAC9C,QAAI,YAAY,OAAQ,QAAO;AAAA,EACjC;AAEA,MAAI,OAAO,WAAW,aAAa;AACjC,QAAI,OAAO,WAAW,WAAW,SAAS,OAAO,EAAG,QAAO;AAAA,EAC7D;AAEA,SAAO;AACT;AAEA,SAAS,8BAAuC;AAC9C,MAAI,OAAO,YAAY,aAAa;AAClC,UAAM,UAAU,QAAQ,KAAK;AAC7B,QAAI,CAAC,SAAS;AACZ,YAAM,YAAY,QAAQ,KAAK,uBAAuB;AACtD,aAAO,6BAA6B,KAAK,SAAS;AAAA,IACpD;AACA,WAAO,CAAC,cAAc,QAAQ,WAAW,SAAS,EAAE,SAAS,OAAO;AAAA,EACtE;AAEA,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,WAAW,OAAO,UAAU;AAClC,UAAM,WAAW,OAAO,UAAU,YAAY;AAC9C,UAAM,cACJ,aAAa,MACb,aAAa,eACb,aAAa,eACb,SAAS,SAAS,YAAY;AAEhC,WAAO,aAAa,YAAY,CAAC;AAAA,EACnC;AAEA,SAAO;AACT;AAEA,SAAS,0BAAmC;AAC1C,SACG,OAAO,YAAY,eAClB,QAAQ,KAAK,gCAAgC,UAC9C,OAAO,WAAW,eAChB,OAAe,oCAAoC;AAE1D;AAEA,SAAS,kCAA2C;AAClD,SACG,OAAO,YAAY,eAClB,QAAQ,KAAK,mCAAmC,UACjD,OAAO,WAAW,eAChB,OAAe,uCAAuC;AAE7D;AAEA,SAAS,yBAAkC;AACzC,SACG,OAAO,YAAY,eAClB,QAAQ,KAAK,oCAAoC,UAClD,OAAO,WAAW,eAChB,OAAe,wCAAwC;AAE9D;AAKA,SAAS,kBAA0B;AACjC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkET;AAKO,IAAM,qBAAN,MAAyB;AAAA,EAK9B,cAAc;AAHd,SAAQ,kBAAoD,oBAAI,IAAI;AACpE,SAAQ,gBAA+B;AAGrC,UAAM,eAAe,aAAa;AAClC,QAAI,OAAO,iBAAiB,YAAY,YAAY,cAAc;AAEhE,WAAK,SAAS,aAAa;AAC3B,WAAK,gBAAgB,aAAa;AAAA,IACpC,OAAO;AAEL,WAAK,SAAS;AAAA,IAChB;AACA,SAAK,OAAO,YAAY,KAAK,cAAc,KAAK,IAAI;AAAA,EACtD;AAAA,EAEQ,cAAc,OAA2B;AAC/C,UAAM,EAAE,MAAM,GAAG,KAAK,IAAI,MAAM;AAChC,UAAM,UAAU,KAAK,gBAAgB,IAAI,IAAI;AAC7C,QAAI,SAAS;AACX,cAAQ,IAAI;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,GAAG,MAAc,SAAoC;AACnD,SAAK,gBAAgB,IAAI,MAAM,OAAO;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAoB;AACtB,SAAK,gBAAgB,OAAO,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,MAAc,OAAY,CAAC,GAAS;AAEvC,UAAM,gBAAgC,CAAC;AAIvC,UAAM,WACJ,OAAO,cAAc,eACrB,iCAAiC,KAAK,UAAU,SAAS;AAG3D,QAAI,KAAK,kBAAkB,aAAa;AACtC,oBAAc,KAAK,KAAK,MAAM;AAAA,IAChC;AAGA,SAAK,qBAAqB,MAAM,eAAe,QAAQ;AAGvD,QAAI,cAAc,SAAS,GAAG;AAC5B,UAAI;AACF,aAAK,OAAO,YAAY,EAAE,MAAM,GAAG,KAAK,GAAG,aAAa;AAAA,MAC1D,SAAS,OAAO;AAEd,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AACA,aAAK,OAAO,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,MAC3C;AAAA,IACF,OAAO;AACL,WAAK,OAAO,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,qBACN,KACA,eACA,UACM;AACN,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU;AAGrC,QAAI,OAAO,eAAe,eAAe,eAAe,WAAY;AACpE,QAAI,OAAO,cAAc,eAAe,eAAe,UAAW;AAGlE,QAAI,UAAU;AAEZ,UAAI,eAAe,eAAe,CAAC,cAAc,SAAS,GAAG,GAAG;AAC9D,sBAAc,KAAK,GAAG;AAAA,MACxB;AACA;AAAA,IACF;AAGA,QAAI,eAAe,eAAe,CAAC,cAAc,SAAS,GAAG,GAAG;AAC9D,oBAAc,KAAK,GAAG;AAAA,IACxB,WAAW,eAAe,eAAe,CAAC,cAAc,SAAS,GAAG,GAAG;AACrE,oBAAc,KAAK,GAAG;AAAA,IACxB,WACE,OAAO,gBAAgB,eACvB,eAAe,eACf,CAAC,cAAc,SAAS,GAAG,GAC3B;AACA,oBAAc,KAAK,GAAG;AAAA,IACxB;AAGA,eAAW,OAAO,KAAK;AACrB,UAAI,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG,GAAG;AAClD,aAAK,qBAAqB,IAAI,GAAG,GAAG,eAAe,QAAQ;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkB;AAChB,SAAK,gBAAgB,MAAM;AAC3B,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,UAAU;AAAA,IACxB;AACA,QAAI,KAAK,eAAe;AACtB,UAAI,gBAAgB,KAAK,aAAa;AACtC,WAAK,gBAAgB;AAAA,IACvB;AAAA,EACF;AACF;;;AC9XA,eAAsB,oBACpB,OACA,WACqB;AACrB,MAAI,iBAAiB,YAAY;AAG/B,WAAO,IAAI,WAAW,OAAO,EAAE,UAAU,CAAC;AAAA,EAC5C;AAGA,MAAI,iBAAiB,mBAAmB;AACtC,WAAO,IAAI,WAAW,OAAO,EAAE,UAAU,CAAC;AAAA,EAC5C;AAEA,MAAI,iBAAiB,iBAAiB;AACpC,WAAO,IAAI,WAAW,OAAO,EAAE,UAAU,CAAC;AAAA,EAC5C;AAEA,MAAI,iBAAiB,aAAa;AAChC,WAAO,IAAI,WAAW,OAAO,EAAE,UAAU,CAAC;AAAA,EAC5C;AAEA,MAAI,iBAAiB,WAAW;AAE9B,WAAO,IAAI,WAAW,MAAM,MAAM;AAAA,MAChC,QAAQ;AAAA,MACR,YAAY,MAAM;AAAA,MAClB,aAAa,MAAM;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,OAAO,UAAU,UAAU;AAEtC,QAAI,WAAW,SAAS,YAAY,SAAS,UAAU,OAAO;AAC5D,YAAM,gBAAgB;AAKtB,aAAO,IAAI,WAAW,cAAc,MAAM;AAAA,QACxC,QAAQ;AAAA,QACR,YAAY,cAAc;AAAA,QAC1B,aAAa,cAAc;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH;AAGA,QACE,WAAW,SACX,YAAY,UACX,gBAAgB,SAAS,2BAA2B,QACrD;AACA,aAAO,IAAI,WAAW,OAAc,EAAE,UAAU,CAAC;AAAA,IACnD;AAGA,QACE,WAAW,SACX,YAAY,SACZ,WAAW,SACX,OAAQ,MAAc,UAAU,YAChC;AACA,aAAO,IAAI,WAAW,OAAc,EAAE,UAAU,CAAC;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,IACA,2BAA2B,OAAO,KAAK;AAAA,EACzC;AACF;;;AC5DA,eAAsB,OACpB,QACA,SACqB;AACrB,MAAI,eAA0C;AAE9C,MAAI;AAEF,UAAM,SAAS,MAAM,oBAAoB,QAAQ,OAAO;AAGxD,mBAAe,IAAI,mBAAmB;AAGtC,UAAM,SAAS,MAAM,gBAAgB,cAAc,QAAQ,QAAQ,OAAO;AAE1E,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,UAAM,cACJ,iBAAiB,cACb,QACA,IAAI;AAAA,MACF;AAAA,MACA,oBAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAC1E;AAAA,IACF;AAEN,QAAI,SAAS,SAAS;AACpB,cAAQ,QAAQ,WAAW;AAAA,IAC7B;AAEA,UAAM;AAAA,EACR,UAAE;AAEA,QAAI,cAAc;AAChB,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF;AACF;AAKA,eAAe,gBACb,cACA,QACA,QACA,SACqB;AACrB,SAAO,IAAI,QAAoB,CAAC,SAAS,WAAW;AAClD,QAAI,kBAAkB;AACtB,QAAI;AACJ,UAAM,YAAY,KAAK,IAAI;AAG3B,yBAAqB,QAAQ,MAAM,EAChC,KAAK,CAAC,WAAW;AAChB,oBAAc;AAAA,IAChB,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,KAAK,qCAAqC,KAAK;AAAA,IACzD,CAAC;AAGH,UAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAI,SAAS,YAAY;AACvB,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,MACJ,kBAAkB,IAAK,kBAAkB,UAAW,MAAO;AAC7D,cAAM,UAAU,cAAe,kBAAkB,cAAe,MAAM;AACtE,cAAM,uBACJ,eAAe,MAAM,KACf,cAAc,mBAAmB,MAAO,MAC1C;AAEN,cAAM,eAA6B;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,gBAAQ,WAAW,YAAY;AAAA,MACjC;AAAA,IACF;AAGA,iBAAa,GAAG,eAAe,MAAM;AACnC,qBAAe,UAAU;AAEzB,yBAAmB,cAAc,QAAQ,MAAM,EAC5C,KAAK,MAAM;AACV,uBAAe,YAAY;AAC3B,qBAAa,KAAK,UAAU;AAAA,MAC9B,CAAC,EACA,MAAM,MAAM;AAAA,IACjB,CAAC;AAED,iBAAa;AAAA,MACX;AAAA,MACA,CAAC,SAA4D;AAC3D,0BAAkB,KAAK;AACvB,YAAI,KAAK,gBAAgB,QAAW;AAClC,wBAAc,KAAK;AAAA,QACrB;AACA,uBAAe,UAAU;AAAA,MAC3B;AAAA,IACF;AAEA,iBAAa,GAAG,aAAa,CAAC,SAAwC;AACpE,UAAI,KAAK,QAAQ;AACf,uBAAe,YAAY;AAC3B,gBAAQ,KAAK,MAAM;AAAA,MACrB,OAAO;AACL,eAAO,IAAI,YAAY,mBAAmB,oBAAoB,CAAC;AAAA,MACjE;AAAA,IACF,CAAC;AAED,iBAAa,GAAG,SAAS,CAAC,SAA+B;AACvD,YAAM,QAAQ,IAAI;AAAA,QAChB,KAAK,YAAY,QAAQ;AAAA,QACzB,KAAK,YAAY,WAAW;AAAA,QAC5B,KAAK;AAAA,MACP;AACA,aAAO,KAAK;AAAA,IACd,CAAC;AAGD,iBAAa,KAAK,cAAc,EAAE,QAAQ,YAAY,CAAC;AAAA,EACzD,CAAC;AACH;AAKA,eAAe,mBACb,cACA,QACA,QACe;AACf,MAAI,MAAM,QAAQ,MAAM,GAAG;AAEzB,UAAM,kBAAkB,cAAc,QAAQ,MAAM;AAAA,EACtD,WAAW,kBAAkB,aAAa;AAExC,UAAM,mBAAmB,cAAc,QAAQ,MAAM;AAAA,EACvD,WAAW,OAAO,iBAAiB,QAAQ;AAEzC,UAAM,qBAAqB,cAAc,QAAQ,MAAM;AAAA,EACzD,OAAO;AAEL,UAAM,iBAAiB,cAAc,QAAqB,MAAM;AAAA,EAClE;AACF;AAKA,eAAe,kBACb,cACA,QACA,QACe;AACf,QAAM,YAAY,QAAQ,aAAa;AACvC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,QAAQ,OAAO,CAAC;AACtB,UAAM,YAAa,IAAI,MAAW;AAElC,UAAM,iBAAiB,cAAc,OAAO,SAAS;AAAA,EACvD;AACF;AAKA,eAAe,qBACb,cACA,QACA,QACe;AACf,MAAI,aAAa;AACjB,QAAM,YAAY,QAAQ,aAAa;AAEvC,mBAAiB,SAAS,QAAQ;AAChC,UAAM,YAAa,aAAa,MAAW;AAC3C,UAAM,iBAAiB,cAAc,OAAO,SAAS;AACrD;AAAA,EACF;AACF;AAKA,eAAe,mBACb,cACA,QACA,SACe;AAEf,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,cAAc,OAAO,eAAe;AAE1C,QAAM,UAA8C,CAAC;AACrD,QAAM,qBAAsC,CAAC;AAE7C,MAAI;AAEF,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,aAAa,YAAY,CAAC;AAChC,YAAM,YAAY,IAAI,0BAA0B,EAAE,OAAO,WAAW,CAAC;AACrE,YAAM,SACJ,UAAU,SAAS,UAAU;AAC/B,cAAQ,KAAK,MAAM;AAEnB,yBAAmB,KAAK,mBAAmB,cAAc,MAAM,CAAC;AAAA,IAClE;AAGA,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,aAAa,YAAY,CAAC;AAChC,YAAM,YAAY,IAAI,0BAA0B,EAAE,OAAO,WAAW,CAAC;AACrE,YAAM,SACJ,UAAU,SAAS,UAAU;AAC/B,cAAQ,KAAK,MAAM;AAEnB,yBAAmB,KAAK,mBAAmB,cAAc,MAAM,CAAC;AAAA,IAClE;AAGA,UAAM,QAAQ,IAAI,kBAAkB;AAAA,EACtC,UAAE;AAEA,eAAW,UAAU,SAAS;AAC5B,UAAI;AACF,eAAO,OAAO;AAAA,MAChB,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,mBACb,cACA,QACe;AACf,MAAI;AAEF,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,CAAC,MAAO;AAEpB,UAAI;AACF,cAAM,iBAAiB,cAAc,OAAO,MAAM,aAAa,CAAC;AAAA,MAClE,UAAE;AACA,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,mBACb,cACA,QACe;AACf,MAAI;AAEF,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,CAAC,MAAO;AAEpB,UAAI;AACF,qBAAa,KAAK,gBAAgB;AAAA,UAChC,OAAO;AAAA,UACP,WAAW,MAAM,aAAa;AAAA,UAC9B,QAAQ;AAAA,UACR,YAAY,MAAM;AAAA,UAClB,gBAAgB,MAAM;AAAA,UACtB,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,MACH,UAAE;AACA,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,kCAAkC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,iBACb,cACA,OACA,WACe;AAEf,QAAM,aAAa,MAAM,oBAAoB,OAAO,SAAS;AAE7D,MAAI;AACF,iBAAa,KAAK,iBAAiB;AAAA,MACjC,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH,UAAE;AAEA,eAAW,MAAM;AAAA,EACnB;AACF;AAKA,eAAe,iBACb,cACA,WACA,QACe;AACf,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,QAAQ;AACd,QAAM,UAAU;AAEhB,MAAI,YAA2B;AAC/B,MAAI,eAAoC;AAExC,MAAI;AACF,gBAAY,IAAI,gBAAgB,UAAU,IAAI;AAC9C,UAAM,MAAM;AAEZ,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,eAAe,MAAM;AACzB,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,YAAM,cAAc,MAAM;AACxB,gBAAQ;AACR,eAAO,IAAI,MAAM,2BAA2B,CAAC;AAAA,MAC/C;AACA,YAAM,UAAU,MAAM;AACpB,cAAM,mBAAmB;AACzB,cAAM,UAAU;AAAA,MAClB;AACA,YAAM,mBAAmB;AACzB,YAAM,UAAU;AAAA,IAClB,CAAC;AAED,UAAM,EAAE,UAAU,YAAY,YAAY,IAAI;AAC9C,UAAM,YACJ,OAAO,aAAa,OAAO,YAAY,IAAI,OAAO,YAAY;AAChE,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,SAAS,KAAK,CAAC;AAErE,QAAI,OAAO,eAAe,KAAK,OAAO,iBAAiB,aAAa;AAClE,UAAI;AACF,uBAAe,IAAI,aAAa;AAChC,cAAM,cAAc,MAAM,UAAU,KAAK,YAAY;AACrD,cAAM,cAAc,MAAM,aAAa,gBAAgB,WAAW;AAElE,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,SAAS,YAAY;AACnB,gBAAQ,KAAK,2CAA2C,UAAU;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,cACJ,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,QAAQ,cAAc;AAClE,UAAM,eACJ,OAAO,UAAU,OAAO,SAAS,IAAI,OAAO,SAAS,eAAe;AAEtE,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,MAAM,OAAO,WAAW,IAAI;AAElC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,aAAS,aAAa,GAAG,aAAa,aAAa,cAAc;AAC/D,UAAI;AACF,cAAM,mBAAmB,KAAK;AAAA,UAC5B,YAAY;AAAA,UACZ,aAAa;AAAA,QACf;AACA,cAAM,cAAc,OAAO,SAAS,gBAAgB,IAChD,mBACA;AAEJ,cAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,gBAAM,eAAe,MAAM;AACzB,oBAAQ;AACR,oBAAQ;AAAA,UACV;AACA,gBAAM,cAAc,MAAM;AACxB,oBAAQ;AACR,mBAAO,IAAI,MAAM,mBAAmB,CAAC;AAAA,UACvC;AACA,gBAAM,UAAU,MAAM;AACpB,kBAAM,oBAAoB,UAAU,YAAY;AAChD,kBAAM,oBAAoB,SAAS,WAAW;AAAA,UAChD;AACA,gBAAM,iBAAiB,UAAU,cAAc,EAAE,MAAM,KAAK,CAAC;AAC7D,gBAAM,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,QAC7D,CAAC;AAED,YAAI;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,cAAc,OAAO;AAAA,UACrB,eAAe,OAAO;AAAA,UACtB;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAEA,cAAM,iBAAiB,KAAK,MAAM,cAAc,MAAY,UAAU;AACtE,cAAM,iBAAiB,cAAc,QAAQ,cAAc;AAAA,MAC7D,SAAS,YAAY;AACnB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,2BAA2B,UAAU,KAAK,sBAAsB,QAAQ,WAAW,UAAU,OAAO,UAAU,CAAC;AAAA,UAC/G;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF,UAAE;AACA,QAAI,cAAc;AAChB,UAAI;AACF,cAAM,aAAa,MAAM;AAAA,MAC3B,SAAS,YAAY;AACnB,gBAAQ,KAAK,gCAAgC,UAAU;AAAA,MACzD;AAAA,IACF;AAEA,QAAI,WAAW;AACb,UAAI,gBAAgB,SAAS;AAAA,IAC/B;AACA,UAAM,MAAM;AACZ,UAAM,OAAO;AAAA,EACf;AACF;AAKA,eAAe,qBACb,cACA,aACA,UACA,WACe;AACf,QAAM,aAAa,YAAY;AAC/B,QAAM,mBAAmB,YAAY;AACrC,QAAM,eAAe,YAAY;AAIjC,QAAM,kBAAkB,KAAK,IAAI,IAAI,MAAO,SAAS;AACrD,QAAM,kBAAkB,KAAK,MAAO,aAAa,kBAAmB,GAAI;AAExE,WAAS,SAAS,GAAG,SAAS,cAAc,UAAU,iBAAiB;AACrE,UAAM,mBAAmB,KAAK,IAAI,iBAAiB,eAAe,MAAM;AACxE,UAAM,YAAa,SAAS,aAAc;AAG1C,UAAM,cAA8B,CAAC;AACrC,aAAS,UAAU,GAAG,UAAU,kBAAkB,WAAW;AAC3D,YAAM,aAAa,YAAY,eAAe,OAAO;AACrD,YAAM,YAAY,IAAI,aAAa,gBAAgB;AACnD,gBAAU,IAAI,WAAW,SAAS,QAAQ,SAAS,gBAAgB,CAAC;AACpE,kBAAY,KAAK,SAAS;AAAA,IAC5B;AAEA,QAAI;AAGF,YAAM,kBAAkB,IAAI;AAAA,QAC1B,mBAAmB;AAAA,MACrB;AACA,eAAS,QAAQ,GAAG,QAAQ,kBAAkB,SAAS;AACrD,iBAAS,UAAU,GAAG,UAAU,kBAAkB,WAAW;AAC3D,0BAAgB,QAAQ,mBAAmB,OAAO,IAChD,YAAY,OAAO,EAAE,KAAK;AAAA,QAC9B;AAAA,MACF;AAEA,YAAM,YAAY,IAAI,UAAU;AAAA,QAC9B,QAAQ;AAAA,QACR;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR,CAAC;AAED,mBAAa,KAAK,gBAAgB;AAAA,QAChC,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,MACF,CAAC;AAED,gBAAU,MAAM;AAGhB,kBAAY,SAAS;AAAA,IACvB,SAAS,OAAO;AACd,cAAQ,KAAK,qCAAqC,KAAK;AAAA,IACzD;AAAA,EACF;AACF;AAKA,eAAe,qBACb,QACA,QAC6B;AAC7B,MAAI;AACF,QAAI,MAAM,QAAQ,MAAM,GAAG;AAEzB,aAAO,OAAO;AAAA,IAChB,WAAW,kBAAkB,aAAa;AAExC,aAAO;AAAA,IACT,WAAW,OAAO,iBAAiB,QAAQ;AAEzC,aAAO;AAAA,IACT,OAAO;AAEL,YAAM,YAAY;AAClB,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,QAAQ;AACd,YAAM,UAAU;AAEhB,YAAM,YAAY,IAAI,gBAAgB,UAAU,IAAI;AACpD,YAAM,MAAM;AAEZ,UAAI;AACF,cAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,gBAAM,mBAAmB,MAAM,QAAQ;AACvC,gBAAM,UAAU,MACd,OAAO,IAAI,MAAM,+BAA+B,CAAC;AAAA,QACrD,CAAC;AAED,cAAM,YAAY,OAAO,aAAa;AACtC,cAAM,cAAc,KAAK,MAAM,MAAM,WAAW,SAAS;AAEzD,YAAI,gBAAgB,SAAS;AAC7B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,YAAI,gBAAgB,SAAS;AAC7B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,qCAAqC,KAAK;AACvD,WAAO;AAAA,EACT;AACF;;;ACtlBA,gBAAuB,aACrB,QACA,SAC4B;AAC5B,MAAI,eAA0C;AAC9C,QAAM,SAAuB,CAAC;AAC9B,MAAI,cAAc;AAClB,MAAI,cAAkC;AACtC,MAAI,kBAAkB;AACtB,MAAI;AACJ,QAAM,YAAY,KAAK,IAAI;AAE3B,MAAI;AAEF,UAAM,aAAa,MAAM,oBAAoB,QAAQ,OAAO;AAC5D,UAAM,SAAS,EAAE,GAAG,YAAY,aAAa,WAAoB;AAGjE,QAAI;AACF,oBAAc,MAAMA,sBAAqB,QAAQ,MAAM;AAAA,IACzD,SAAS,OAAO;AACd,cAAQ,KAAK,mDAAmD,KAAK;AAAA,IACvE;AAGA,mBAAe,IAAI,mBAAmB;AAGtC,UAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAI,SAAS,YAAY;AACvB,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,MACJ,kBAAkB,IAAK,kBAAkB,UAAW,MAAO;AAC7D,cAAM,UAAU,cAAe,kBAAkB,cAAe,MAAM;AACtE,cAAM,uBACJ,eAAe,MAAM,KACf,cAAc,mBAAmB,MAAO,MAC1C;AAEN,cAAM,eAA6B;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,gBAAQ,WAAW,YAAY;AAAA,MACjC;AAAA,IACF;AAGA,UAAM,kBAAkB,IAAI,QAAc,CAAC,SAAS,WAAW;AAE7D,mBAAc,GAAG,eAAe,MAAM;AACpC,uBAAe,WAAW;AAE1B,QAAAC,oBAAmB,cAAe,QAAQ,MAAM,EAC7C,KAAK,MAAM;AACV,yBAAe,YAAY;AAC3B,uBAAc,KAAK,UAAU;AAAA,QAC/B,CAAC,EACA,MAAM,MAAM;AAAA,MACjB,CAAC;AAED,mBAAc;AAAA,QACZ;AAAA,QACA,CAAC,SAA4D;AAC3D,4BAAkB,KAAK;AACvB,cAAI,KAAK,gBAAgB,QAAW;AAClC,0BAAc,KAAK;AAAA,UACrB;AACA,yBAAe,WAAW;AAAA,QAC5B;AAAA,MACF;AAEA,mBAAc,GAAG,aAAa,CAAC,SAAgC;AAC7D,eAAO,KAAK,KAAK,KAAK;AAAA,MACxB,CAAC;AAED,mBAAc,GAAG,aAAa,MAAM;AAClC,sBAAc;AACd,uBAAe,YAAY;AAC3B,gBAAQ;AAAA,MACV,CAAC;AAED,mBAAc,GAAG,SAAS,CAAC,SAA+B;AACxD,sBAAc,IAAI;AAAA,UAChB,KAAK,YAAY,QAAQ;AAAA,UACzB,KAAK,YAAY,WAAW;AAAA,UAC5B,KAAK;AAAA,QACP;AACA,eAAO,WAAW;AAAA,MACpB,CAAC;AAGD,mBAAc,KAAK,cAAc,EAAE,QAAQ,YAAY,CAAC;AAAA,IAC1D,CAAC;AAOD,WAAO,CAAC,eAAe,CAAC,aAAa;AACnC,UAAI,OAAO,SAAS,GAAG;AACrB,cAAM,QAAQ,OAAO,MAAM;AAC3B,cAAM;AAAA,MACR,OAAO;AAEL,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,WAAO,OAAO,SAAS,GAAG;AACxB,YAAM,QAAQ,OAAO,MAAM;AAC3B,YAAM;AAAA,IACR;AAGA,QAAI,aAAa;AACf,YAAM;AAAA,IACR;AAGA,QAAI;AACF,YAAM;AAAA,IACR,SAAS,OAAO;AAEd,YAAM,cACJ,iBAAiB,cACb,QACA,IAAI;AAAA,QACF;AAAA,QACA,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC3E;AAAA,MACF;AAEN,UAAI,SAAS,SAAS;AACpB,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAEA,YAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AAEd,UAAM,cACJ,iBAAiB,cACb,QACA,IAAI;AAAA,MACF;AAAA,MACA,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACjF;AAAA,IACF;AAEN,QAAI,SAAS,SAAS;AACpB,cAAQ,QAAQ,WAAW;AAAA,IAC7B;AAEA,UAAM;AAAA,EACR,UAAE;AAEA,QAAI,cAAc;AAChB,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF;AACF;AAKA,eAAeA,oBACb,cACA,QACA,QACe;AACf,MAAI,MAAM,QAAQ,MAAM,GAAG;AAEzB,UAAMC,mBAAkB,cAAc,QAAQ,MAAM;AAAA,EACtD,WAAW,kBAAkB,aAAa;AAExC,UAAM,2BAA2B,cAAc,QAAQ,MAAM;AAAA,EAC/D,WAAW,OAAO,iBAAiB,QAAQ;AAEzC,UAAMC,sBAAqB,cAAc,QAAQ,MAAM;AAAA,EACzD,OAAO;AAEL,UAAMC,kBAAiB,cAAc,QAAqB,MAAM;AAAA,EAClE;AACF;AAKA,eAAeF,mBACb,cACA,QACA,QACe;AACf,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,aAAa,MAAO;AAE1B,MAAI,gBAAgB,YAAY,IAAI;AAEpC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,QAAQ,OAAO,CAAC;AACtB,UAAM,YAAa,IAAI,MAAW;AAElC,UAAMG,kBAAiB,cAAc,OAAO,SAAS;AAErD,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,cAAc,MAAM;AAC1B,UAAM,QAAQ,KAAK,IAAI,GAAG,aAAa,WAAW;AAElD,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AACzD,oBAAgB,YAAY,IAAI;AAAA,EAClC;AACF;AAKA,eAAeF,sBACb,cACA,QACA,QACe;AACf,MAAI,aAAa;AACjB,QAAM,YAAY,QAAQ,aAAa;AAEvC,mBAAiB,SAAS,QAAQ;AAChC,UAAM,YAAa,aAAa,MAAW;AAC3C,UAAME,kBAAiB,cAAc,OAAO,SAAS;AACrD;AAAA,EACF;AACF;AAKA,eAAe,2BACb,cACA,QACA,QACe;AACf,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,cAAc,OAAO,eAAe;AAE1C,QAAM,UAA8C,CAAC;AACrD,QAAM,qBAAsC,CAAC;AAE7C,MAAI;AAEF,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,aAAa,YAAY,CAAC;AAChC,YAAM,YAAY,IAAI,0BAA0B,EAAE,OAAO,WAAW,CAAC;AACrE,YAAM,SACJ,UAAU,SAAS,UAAU;AAC/B,cAAQ,KAAK,MAAM;AAEnB,yBAAmB;AAAA,QACjB,0BAA0B,cAAc,QAAQ,MAAM;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,aAAa,YAAY,CAAC;AAChC,YAAM,YAAY,IAAI,0BAA0B,EAAE,OAAO,WAAW,CAAC;AACrE,YAAM,SACJ,UAAU,SAAS,UAAU;AAC/B,cAAQ,KAAK,MAAM;AAEnB,yBAAmB,KAAK,0BAA0B,cAAc,MAAM,CAAC;AAAA,IACzE;AAGA,UAAM,QAAQ,IAAI,kBAAkB;AAAA,EACtC,UAAE;AAEA,eAAW,UAAU,SAAS;AAC5B,UAAI;AACF,eAAO,OAAO;AAAA,MAChB,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,0BACb,cACA,QACA,SACe;AAIf,MAAI;AAEF,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,CAAC,MAAO;AAEpB,UAAI;AACF,cAAMA,kBAAiB,cAAc,OAAO,MAAM,aAAa,CAAC;AAAA,MAClE,UAAE;AACA,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,4CAA4C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAe,0BACb,cACA,QACe;AACf,MAAI;AAEF,WAAO,MAAM;AACX,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,QAAQ,CAAC,MAAO;AAEpB,UAAI;AACF,qBAAa,KAAK,gBAAgB;AAAA,UAChC,OAAO;AAAA,UACP,WAAW,MAAM,aAAa;AAAA,UAC9B,QAAQ;AAAA,UACR,YAAY,MAAM;AAAA,UAClB,gBAAgB,MAAM;AAAA,UACtB,kBAAkB,MAAM;AAAA,QAC1B,CAAC;AAAA,MACH,UAAE;AACA,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,4CAA4C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAeA,kBACb,cACA,OACA,WACe;AAEf,QAAM,aAAa,MAAM,oBAAoB,OAAO,SAAS;AAE7D,MAAI;AACF,iBAAa,KAAK,iBAAiB;AAAA,MACjC,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH,UAAE;AAEA,eAAW,MAAM;AAAA,EACnB;AACF;AAKA,eAAeD,kBACb,cACA,WACA,QACe;AACf,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,QAAQ;AACd,QAAM,UAAU;AAEhB,MAAI,YAA2B;AAC/B,MAAI,eAAoC;AAExC,MAAI;AACF,gBAAY,IAAI,gBAAgB,UAAU,IAAI;AAC9C,UAAM,MAAM;AAEZ,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,eAAe,MAAM;AACzB,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,YAAM,cAAc,MAAM;AACxB,gBAAQ;AACR,eAAO,IAAI,MAAM,2BAA2B,CAAC;AAAA,MAC/C;AACA,YAAM,UAAU,MAAM;AACpB,cAAM,mBAAmB;AACzB,cAAM,UAAU;AAAA,MAClB;AACA,YAAM,mBAAmB;AACzB,YAAM,UAAU;AAAA,IAClB,CAAC;AAED,UAAM,EAAE,UAAU,YAAY,YAAY,IAAI;AAC9C,UAAM,YACJ,OAAO,aAAa,OAAO,YAAY,IAAI,OAAO,YAAY;AAChE,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,SAAS,KAAK,CAAC;AAErE,QAAI,OAAO,eAAe,KAAK,OAAO,iBAAiB,aAAa;AAClE,UAAI;AACF,uBAAe,IAAI,aAAa;AAChC,cAAM,cAAc,MAAM,UAAU,KAAK,YAAY;AACrD,cAAM,cAAc,MAAM,aAAa,gBAAgB,WAAW;AAClE,cAAME;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,SAAS,YAAY;AACnB,gBAAQ,KAAK,2CAA2C,UAAU;AAAA,MACpE;AAAA,IACF;AAEA,UAAM,cACJ,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,QAAQ,cAAc;AAClE,UAAM,eACJ,OAAO,UAAU,OAAO,SAAS,IAAI,OAAO,SAAS,eAAe;AAEtE,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,MAAM,OAAO,WAAW,IAAI;AAElC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,aAAS,aAAa,GAAG,aAAa,aAAa,cAAc;AAC/D,YAAM,mBAAmB,KAAK,IAAI,YAAY,GAAG,aAAa,SAAS;AACvE,YAAM,cAAc,OAAO,SAAS,gBAAgB,IAChD,mBACA;AAEJ,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,cAAM,eAAe,MAAM;AACzB,kBAAQ;AACR,kBAAQ;AAAA,QACV;AACA,cAAM,cAAc,MAAM;AACxB,kBAAQ;AACR,iBAAO,IAAI,MAAM,mBAAmB,CAAC;AAAA,QACvC;AACA,cAAM,UAAU,MAAM;AACpB,gBAAM,oBAAoB,UAAU,YAAY;AAChD,gBAAM,oBAAoB,SAAS,WAAW;AAAA,QAChD;AACA,cAAM,iBAAiB,UAAU,cAAc,EAAE,MAAM,KAAK,CAAC;AAC7D,cAAM,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,MAC7D,CAAC;AAED,UAAI;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AAEA,YAAM,iBAAiB,KAAK,MAAM,cAAc,MAAY,UAAU;AACtE,YAAMD,kBAAiB,cAAc,QAAQ,cAAc;AAE3D,YAAM,IAAI,QAAQ,CAAC,YAAY,sBAAsB,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF,UAAE;AACA,QAAI,cAAc;AAChB,UAAI;AACF,cAAM,aAAa,MAAM;AAAA,MAC3B,SAAS,YAAY;AACnB,gBAAQ,KAAK,gCAAgC,UAAU;AAAA,MACzD;AAAA,IACF;AAEA,QAAI,WAAW;AACb,UAAI,gBAAgB,SAAS;AAAA,IAC/B;AACA,UAAM,MAAM;AACZ,UAAM,OAAO;AAAA,EACf;AACF;AAKA,eAAeC,sBACb,cACA,aACA,UACA,WACe;AACf,QAAM,aAAa,YAAY;AAC/B,QAAM,mBAAmB,YAAY;AACrC,QAAM,eAAe,YAAY;AAEjC,QAAM,kBAAkB,KAAK,IAAI,IAAI,MAAO,SAAS;AACrD,QAAM,kBAAkB,KAAK,MAAO,aAAa,kBAAmB,GAAI;AAExE,WAAS,SAAS,GAAG,SAAS,cAAc,UAAU,iBAAiB;AACrE,UAAM,mBAAmB,KAAK,IAAI,iBAAiB,eAAe,MAAM;AACxE,UAAM,YAAa,SAAS,aAAc;AAE1C,UAAM,cAA8B,CAAC;AACrC,aAAS,UAAU,GAAG,UAAU,kBAAkB,WAAW;AAC3D,YAAM,aAAa,YAAY,eAAe,OAAO;AACrD,YAAM,YAAY,IAAI,aAAa,gBAAgB;AACnD,gBAAU,IAAI,WAAW,SAAS,QAAQ,SAAS,gBAAgB,CAAC;AACpE,kBAAY,KAAK,SAAS;AAAA,IAC5B;AAEA,QAAI;AACF,YAAM,kBAAkB,IAAI;AAAA,QAC1B,mBAAmB;AAAA,MACrB;AACA,eAAS,QAAQ,GAAG,QAAQ,kBAAkB,SAAS;AACrD,iBAAS,UAAU,GAAG,UAAU,kBAAkB,WAAW;AAC3D,0BAAgB,QAAQ,mBAAmB,OAAO,IAChD,YAAY,OAAO,EAAE,KAAK;AAAA,QAC9B;AAAA,MACF;AAEA,YAAM,YAAY,IAAI,UAAU;AAAA,QAC9B,QAAQ;AAAA,QACR;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR,CAAC;AAED,mBAAa,KAAK,gBAAgB;AAAA,QAChC,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,MACF,CAAC;AAED,gBAAU,MAAM;AAChB,kBAAY,SAAS;AAAA,IACvB,SAAS,OAAO;AACd,cAAQ,KAAK,qCAAqC,KAAK;AAAA,IACzD;AAGA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA,EACvD;AACF;AAKA,eAAeN,sBACb,QACA,QAC6B;AAC7B,MAAI;AACF,QAAI,MAAM,QAAQ,MAAM,GAAG;AAEzB,aAAO,OAAO;AAAA,IAChB,WAAW,kBAAkB,aAAa;AAExC,aAAO;AAAA,IACT,WAAW,OAAO,iBAAiB,QAAQ;AAEzC,aAAO;AAAA,IACT,OAAO;AAEL,YAAM,YAAY;AAClB,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,QAAQ;AACd,YAAM,UAAU;AAEhB,YAAM,YAAY,IAAI,gBAAgB,UAAU,IAAI;AACpD,YAAM,MAAM;AAEZ,UAAI;AACF,cAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,gBAAM,mBAAmB,MAAM,QAAQ;AACvC,gBAAM,UAAU,MACd,OAAO,IAAI,MAAM,+BAA+B,CAAC;AAAA,QACrD,CAAC;AAED,cAAM,YAAY,OAAO,aAAa;AACtC,cAAM,cAAc,KAAK,MAAM,MAAM,WAAW,SAAS;AAEzD,YAAI,gBAAgB,SAAS;AAC7B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,YAAI,gBAAgB,SAAS;AAC7B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,mDAAmD,KAAK;AACrE,WAAO;AAAA,EACT;AACF;;;ACpoBA,eAAsB,UAAU,SAA2C;AACzE,MAAI;AAEF,QAAI,CAAC,qBAAqB,GAAG;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,SAAS;AACZ,aAAO,MAAM,yBAAyB;AAAA,IACxC;AAGA,UAAM,iBAAiB,QAAQ,SAAS,OAAO,QAAQ,UAAU;AACjE,UAAM,eAAe,QAAQ,UAAU;AACvC,QAAI,cAAc;AAChB,YAAM,cAAc,iBACf,QAAQ,QACT;AACJ,YAAM,aAAa,aAAa,SAAS;AACzC,YAAM,iBAAiB,MAAM,sBAAsB,YAAY,OAAO;AACtE,UAAI,CAAC,gBAAgB;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,iBAAiB,QAAQ,SAAS,OAAO,QAAQ,UAAU;AACjE,QAAI,gBAAgB;AAClB,YAAM,aAAc,QAAQ,MAAsB,SAAS;AAC3D,YAAM,iBAAiB,MAAM,sBAAsB,YAAY,OAAO;AACtE,UAAI,CAAC,gBAAgB;AACnB,eAAO;AAAA,MACT;AAAA,IACF,WAAW,QAAQ,UAAU,UAAa,CAAC,gBAAgB;AAEzD,YAAM,iBAAiB,MAAM,sBAAsB,OAAO,OAAO;AACjE,UAAI,CAAC,gBAAgB;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,YAAQ,KAAK,oBAAoB,KAAK;AACtC,WAAO;AAAA,EACT;AACF;AAKA,SAAS,uBAAgC;AACvC,MAAI;AACF,WACE,OAAO,iBAAiB,eACxB,OAAO,iBAAiB,eACxB,OAAO,eAAe,eACtB,OAAO,cAAc;AAAA,EAEzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAe,2BAA6C;AAC1D,MAAI;AACF,UAAM,eAAe;AACrB,UAAM,gBAAgB;AACtB,UAAM,mBAAmB;AAGzB,UAAM,cAAkC;AAAA,MACtC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAEA,UAAM,eAAe,MAAM,aAAa,kBAAkB,WAAW;AACrE,QAAI,CAAC,aAAa,WAAW;AAC3B,aAAO;AAAA,IACT;AAGA,UAAM,cAAkC;AAAA,MACtC,OAAO;AAAA;AAAA,MACP,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,SAAS;AAAA,IACX;AAEA,UAAM,eAAe,MAAM,aAAa,kBAAkB,WAAW;AACrE,WAAO,aAAa,aAAa;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAe,sBACb,OACA,SACkB;AAClB,MAAI;AACF,UAAM,eACJ,SAAS,SAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,CAAC;AACzE,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,SAAS,UAAU;AAAA,MACnB,SAAS,aAAa;AAAA,IACxB;AACA,UAAM,SAA6B;AAAA,MACjC,OAAO;AAAA,MACP,OAAO,SAAS,SAAS;AAAA,MACzB,QAAQ,SAAS,UAAU;AAAA,MAC3B,SAAS,aAAa,WAAW;AAAA,MACjC,WAAW,SAAS,aAAa;AAAA,IACnC;AAGA,QAAI,aAAa,sBAAsB;AACrC,aAAO,uBAAuB,aAAa;AAAA,IAC7C;AAEA,QAAI,aAAa,aAAa;AAC5B,aAAO,cAAc,aAAa;AAAA,IACpC;AAEA,UAAM,UAAU,MAAM,aAAa,kBAAkB,MAAM;AAC3D,WAAO,QAAQ,aAAa;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAe,sBACb,OACA,SACkB;AAClB,MAAI;AACF,UAAM,cAAc,oBAAoB,KAAK;AAC7C,UAAM,eACJ,OAAO,SAAS,UAAU,WAAW,QAAQ,QAAQ,CAAC;AAExD,UAAM,mBAAmB,UAAU,UAAU,UAAU;AACvD,UAAM,aAAa,UAAU;AAC7B,UAAM,oBACJ,aAAa,eAAe,mBAAmB,MAAO;AACxD,UAAM,kBAAkB,aAAa,aAAa,mBAAmB,IAAI;AAEzE,QAAI,iBAAiB,aAAa;AAClC,QAAI,kBAAkB,MAAM;AAC1B,UAAI,UAAU,QAAQ;AACpB,yBAAiB;AAAA,MACnB,WAAW,UAAU,OAAO;AAC1B,yBAAiB;AAAA,MACnB,WAAW,UAAU,UAAU;AAC7B,yBAAiB;AAAA,MACnB,WAAW,kBAAkB;AAC3B,yBAAiB;AAAA,MACnB,WAAW,YAAY;AACrB,yBAAiB,oBAAoB,kBAAkB;AAAA,MACzD,OAAO;AACL,yBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,SAA6B;AAAA,MACjC,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,SAAS;AAAA,IACX;AAGA,QAAI,UAAU,SAAS,aAAa,aAAa;AAC/C,MAAC,OAAe,cAAc,aAAa;AAAA,IAC7C;AAEA,UAAM,UAAU,MAAM,aAAa,kBAAkB,MAAM;AAC3D,WAAO,QAAQ,aAAa;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,oBACP,OACA,QAAQ,KACR,SAAS,KACT,YAAY,IACJ;AACR,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,uBAAuB,OAAO,QAAQ,SAAS;AAAA,IACxD,KAAK;AACH,aAAO;AAAA;AAAA,IACT,KAAK;AACH,aAAO;AAAA;AAAA,IACT,KAAK;AACH,aAAO;AAAA;AAAA,IACT,KAAK;AACH,aAAO;AAAA;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAMO,SAAS,uBACd,OACA,QACA,WACA,SACQ;AACR,QAAM,WAAW,KAAK,KAAK,QAAQ,EAAE,IAAI,KAAK,KAAK,SAAS,EAAE,IAAI;AAClE,MAAI;AACJ,MAAI,YAAY,MAAQ,SAAQ;AAAA,WACvB,YAAY,MAAQ,SAAQ;AAAA,WAC5B,YAAY,OAAQ,SAAQ;AAAA,WAC5B,YAAY,OAAQ,SAAQ;AAAA,WAC5B,YAAY,OAAQ,SAAQ;AAAA,MAChC,SAAQ;AAEb,QAAM,gBACJ,YAAY,SAAS,QAAQ,UAAU,MAAM,SAAS;AACxD,QAAM,aACJ,kBAAkB,SAAS,OAAO,kBAAkB,SAAS,OAAO;AACtE,QAAM,WAAW,MAAM,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAEnD,SAAO,QAAQ,UAAU,KAAK,QAAQ;AACxC;AAuDA,SAAS,oBAAoB,OAAuB;AAClD,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA;AAAA,IACT,KAAK;AACH,aAAO;AAAA;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;;;ACvSO,SAAS,cAAc,cAA6B,CAAC,GAAmB;AAC7E,QAAM,UAA0B;AAAA,IAC9B,MAAM,OACJ,QACA,mBACqB;AACrB,YAAM,gBAAgB,aAAa,aAAa,iBAAiB;AACjE,aAAO,OAAO,QAAQ,aAAa;AAAA,IACrC;AAAA,IAEA,OAAO,aACL,QACA,mBAC4B;AAC5B,YAAM,gBAAgB,aAAa,aAAa,iBAAiB;AACjE,aAAO,aAAa,QAAQ,aAAa;AAAA,IAC3C;AAAA,IAEA,YAA2B;AACzB,aAAO,EAAE,GAAG,YAAY;AAAA,IAC1B;AAAA,IAEA,OAAO,YAAoD;AACzD,YAAM,kBAAkB,aAAa,aAAa,UAAU;AAC5D,aAAO,cAAc,eAAe;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,aACP,MACA,YACe;AACf,MAAI,CAAC,YAAY;AACf,WAAO,EAAE,GAAG,KAAK;AAAA,EACnB;AAEA,QAAM,oBAAoB,CACxB,WACA,oBAC0B;AAC1B,QAAI,oBAAoB,OAAO;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,oBAAoB,QAAW;AACjC,UAAI,cAAc,OAAO;AACvB,eAAO;AAAA,MACT;AACA,UAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,eAAO,EAAE,GAAG,UAAU;AAAA,MACxB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,cAAc,SAAS,aAAa,MAAM;AAC5C,aAAO,EAAE,GAAI,gBAAsB;AAAA,IACrC;AAEA,WAAO;AAAA,MACL,GAAI;AAAA,MACJ,GAAI;AAAA,IACN;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA;AAAA,IAEH,OAAO,kBAAkB,KAAK,OAAc,WAAW,KAAY;AAAA,IACnE,OAAO,kBAAkB,KAAK,OAAc,WAAW,KAAY;AAAA,EACrE;AACF;AAKO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAItB,SAAS,cAAc;AAAA,IACrB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO,EAAE,OAAO,MAAM;AAAA,IACtB,OAAO,EAAE,OAAO,OAAO,SAAS,MAAQ;AAAA,IACxC,WAAW;AAAA,EACb,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,SAAS,cAAc;AAAA,IACrB,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO,EAAE,SAAS,IAAU;AAAA,IAC5B,OAAO,EAAE,SAAS,MAAQ;AAAA,IAC1B,WAAW;AAAA,EACb,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,SAAS,cAAc;AAAA,IACrB,SAAS;AAAA,IACT,OAAO,EAAE,SAAS,IAAU;AAAA,IAC5B,OAAO,EAAE,SAAS,MAAQ;AAAA,IAC1B,WAAW;AAAA,EACb,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,KAAK,cAAc;AAAA,IACjB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO,EAAE,OAAO,MAAM;AAAA,IACtB,OAAO,EAAE,OAAO,MAAM;AAAA,EACxB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,MAAM,cAAc;AAAA,IAClB,SAAS;AAAA,IACT,OAAO;AAAA,MACL,OAAO;AAAA,MACP,sBAAsB;AAAA,MACtB,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,UAAU,cAAc;AAAA,IACtB,SAAS;AAAA,IACT,OAAO;AAAA,MACL,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,WAAW,cAAc;AAAA,IACvB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO;AAAA,MACL,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,IACA,OAAO,EAAE,OAAO,OAAO;AAAA,EACzB,CAAC;AACH;AAKO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAItB,sBACE,UACgB;AAChB,WAAO,SAAS,QAAQ;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,OAAe,QAAgC;AAEhE,UAAM,SAAS,QAAQ;AACvB,QAAI;AAEJ,QAAI,UAAU,MAAM,KAAK;AACvB,gBAAU;AAAA,IACZ,WAAW,UAAU,OAAO,MAAM;AAChC,gBAAU;AAAA,IACZ,OAAO;AACL,gBAAU;AAAA,IACZ;AAEA,WAAO,cAAc;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,kBACE,cACA,iBACgB;AAEhB,UAAM,aAAa,eAAe,IAAI,OAAO;AAC7C,UAAM,eAAe,KAAK,MAAM,aAAa,eAAe;AAC5D,UAAM,eAAe,KAAK,MAAM,eAAe,GAAG;AAClD,UAAM,eAAe,KAAK,MAAM,eAAe,GAAG;AAElD,WAAO,cAAc;AAAA,MACnB,OAAO,EAAE,SAAS,aAAa;AAAA,MAC/B,OAAO,EAAE,SAAS,KAAK,IAAI,cAAc,IAAO,EAAE;AAAA;AAAA,IACpD,CAAC;AAAA,EACH;AACF;","names":["calculateTotalFrames","processVideoSource","processFrameArray","processAsyncIterable","processVideoFile","addFrameToWorker","processAudioFromFile"]}