{"version":3,"file":"index.mjs","names":[],"sources":["../src/utils/math.ts","../src/io/canvas.ts","../src/runtime/ort.ts","../src/runtime/provider.ts","../src/pipeline/detect.ts","../src/pipeline/preprocess.ts","../src/pipeline/recognize.ts","../src/paddle-ocr.ts","../src/manifests/official.ts","../src/presets/ppocrv5.ts"],"sourcesContent":["import type { OcrBox } from \"../types\";\n\nexport function clamp(value: number, min: number, max: number): number {\n  return Math.min(max, Math.max(min, value));\n}\n\nexport function roundUpToMultiple(value: number, multiple: number): number {\n  return Math.max(multiple, Math.ceil(value / multiple) * multiple);\n}\n\nexport function sortBoxes(boxes: readonly OcrBox[]): OcrBox[] {\n  return [...boxes].sort((left, right) => {\n    const ly = left.points[0].y;\n    const ry = right.points[0].y;\n    if (Math.abs(ly - ry) > 12) {\n      return ly - ry;\n    }\n\n    return left.points[0].x - right.points[0].x;\n  });\n}\n\nexport function axisAlignedBounds(box: OcrBox): {\n  left: number;\n  top: number;\n  width: number;\n  height: number;\n} {\n  const xs = box.points.map((point) => point.x);\n  const ys = box.points.map((point) => point.y);\n  const left = Math.min(...xs);\n  const right = Math.max(...xs);\n  const top = Math.min(...ys);\n  const bottom = Math.max(...ys);\n\n  return {\n    left,\n    top,\n    width: right - left,\n    height: bottom - top\n  };\n}\n\nexport function maxIndex(values: ArrayLike<number>): { index: number; value: number } {\n  let index = 0;\n  let value = values[0] ?? Number.NEGATIVE_INFINITY;\n\n  for (let cursor = 1; cursor < values.length; cursor += 1) {\n    if (values[cursor] > value) {\n      index = cursor;\n      value = values[cursor];\n    }\n  }\n\n  return { index, value };\n}\n\nexport function maxProbability(values: ArrayLike<number>): number {\n  let min = Number.POSITIVE_INFINITY;\n  let max = Number.NEGATIVE_INFINITY;\n\n  for (let cursor = 0; cursor < values.length; cursor += 1) {\n    const value = values[cursor];\n    if (value < min) {\n      min = value;\n    }\n    if (value > max) {\n      max = value;\n    }\n  }\n\n  if (min >= 0 && max <= 1) {\n    return max;\n  }\n\n  let total = 0;\n  for (let cursor = 0; cursor < values.length; cursor += 1) {\n    total += Math.exp(values[cursor] - max);\n  }\n\n  return 1 / total;\n}\n","import type { OcrImageSource } from \"../types\";\nimport { clamp } from \"../utils/math\";\n\ntype AnyCanvas = HTMLCanvasElement | OffscreenCanvas;\ntype AnyRenderingContext = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\nfunction hasOffscreenCanvas(): boolean {\n  return typeof OffscreenCanvas !== \"undefined\";\n}\n\nfunction isImageData(value: unknown): value is ImageData {\n  return typeof ImageData !== \"undefined\" && value instanceof ImageData;\n}\n\nfunction isImageBitmap(value: unknown): value is ImageBitmap {\n  return typeof ImageBitmap !== \"undefined\" && value instanceof ImageBitmap;\n}\n\nfunction isHtmlImageElement(value: unknown): value is HTMLImageElement {\n  return typeof HTMLImageElement !== \"undefined\" && value instanceof HTMLImageElement;\n}\n\nfunction isHtmlCanvasElement(value: unknown): value is HTMLCanvasElement {\n  return typeof HTMLCanvasElement !== \"undefined\" && value instanceof HTMLCanvasElement;\n}\n\nfunction isOffscreenCanvas(value: unknown): value is OffscreenCanvas {\n  return hasOffscreenCanvas() && value instanceof OffscreenCanvas;\n}\n\nfunction createCanvas(width: number, height: number): AnyCanvas {\n  if (hasOffscreenCanvas()) {\n    return new OffscreenCanvas(width, height);\n  }\n\n  if (typeof document !== \"undefined\") {\n    const canvas = document.createElement(\"canvas\");\n    canvas.width = width;\n    canvas.height = height;\n    return canvas;\n  }\n\n  throw new Error(\"A canvas implementation is required in this runtime.\");\n}\n\nfunction getContext(canvas: AnyCanvas): AnyRenderingContext {\n  const context = canvas.getContext(\"2d\", { willReadFrequently: true });\n  if (!context) {\n    throw new Error(\"Unable to create a 2D canvas context.\");\n  }\n\n  return context;\n}\n\nasync function loadImageFromUrl(url: string): Promise<ImageBitmap | HTMLImageElement> {\n  if (typeof createImageBitmap !== \"undefined\") {\n    const response = await fetch(url);\n    if (!response.ok) {\n      throw new Error(`Failed to fetch image from ${url}`);\n    }\n    const blob = await response.blob();\n    return createImageBitmap(blob);\n  }\n\n  if (typeof Image === \"undefined\") {\n    throw new Error(\"This runtime cannot load URL inputs.\");\n  }\n\n  return await new Promise<HTMLImageElement>((resolve, reject) => {\n    const image = new Image();\n    image.crossOrigin = \"anonymous\";\n    image.onload = () => resolve(image);\n    image.onerror = () => reject(new Error(`Failed to load image from ${url}`));\n    image.src = url;\n  });\n}\n\nasync function blobToImage(blob: Blob): Promise<ImageBitmap | HTMLImageElement> {\n  if (typeof createImageBitmap !== \"undefined\") {\n    return createImageBitmap(blob);\n  }\n\n  const url = URL.createObjectURL(blob);\n  try {\n    return await loadImageFromUrl(url);\n  } finally {\n    URL.revokeObjectURL(url);\n  }\n}\n\nfunction drawIntoImageData(source: ImageBitmap | HTMLImageElement): ImageData {\n  const width = isHtmlImageElement(source) ? source.naturalWidth || source.width : source.width;\n  const height = isHtmlImageElement(source) ? source.naturalHeight || source.height : source.height;\n  const canvas = createCanvas(width, height);\n  const context = getContext(canvas);\n  context.drawImage(source, 0, 0, width, height);\n  return context.getImageData(0, 0, width, height);\n}\n\nexport async function ensureImageData(source: OcrImageSource): Promise<ImageData> {\n  if (isImageData(source)) {\n    return source;\n  }\n\n  if (isHtmlCanvasElement(source) || isOffscreenCanvas(source)) {\n    const context = getContext(source);\n    return context.getImageData(0, 0, source.width, source.height);\n  }\n\n  if (isImageBitmap(source) || isHtmlImageElement(source)) {\n    return drawIntoImageData(source);\n  }\n\n  if (typeof source === \"string\") {\n    return drawIntoImageData(await loadImageFromUrl(source));\n  }\n\n  if (source instanceof Blob) {\n    return drawIntoImageData(await blobToImage(source));\n  }\n\n  throw new Error(\"Unsupported image source.\");\n}\n\nexport function resizeImageData(source: ImageData, width: number, height: number): ImageData {\n  const inputCanvas = createCanvas(source.width, source.height);\n  const inputContext = getContext(inputCanvas);\n  inputContext.putImageData(source, 0, 0);\n\n  const outputCanvas = createCanvas(width, height);\n  const outputContext = getContext(outputCanvas);\n  outputContext.drawImage(inputCanvas, 0, 0, width, height);\n\n  return outputContext.getImageData(0, 0, width, height);\n}\n\nexport function cropImageData(\n  source: ImageData,\n  left: number,\n  top: number,\n  width: number,\n  height: number\n): ImageData {\n  const x = clamp(Math.floor(left), 0, source.width - 1);\n  const y = clamp(Math.floor(top), 0, source.height - 1);\n  const w = clamp(Math.ceil(width), 1, source.width - x);\n  const h = clamp(Math.ceil(height), 1, source.height - y);\n\n  const pixels = new Uint8ClampedArray(w * h * 4);\n\n  for (let row = 0; row < h; row += 1) {\n    const sourceOffset = ((y + row) * source.width + x) * 4;\n    const targetOffset = row * w * 4;\n    pixels.set(source.data.subarray(sourceOffset, sourceOffset + w * 4), targetOffset);\n  }\n\n  return new ImageData(pixels, w, h);\n}\n","import * as ort from \"onnxruntime-web\";\nimport type { ExecutionProvider, OrtRuntimeOptions } from \"../types\";\n\nexport type OrtSession = ort.InferenceSession;\n\nexport type DownloadProgressCallback = (loaded: number, total: number | undefined) => void;\n\nlet configured = false;\n\nexport function configureOrt(options?: OrtRuntimeOptions): void {\n  if (configured || !options) {\n    return;\n  }\n\n  if (options.wasmPaths) {\n    ort.env.wasm.wasmPaths = options.wasmPaths;\n  }\n\n  if (options.wasmThreads) {\n    ort.env.wasm.numThreads = options.wasmThreads;\n  }\n\n  configured = true;\n}\n\nconst MODEL_CACHE_NAME = \"ffocr-models\";\n\nasync function readResponseWithProgress(\n  response: Response,\n  onProgress?: DownloadProgressCallback\n): Promise<ArrayBuffer> {\n  if (!onProgress || !response.body) {\n    return response.arrayBuffer();\n  }\n\n  const contentLength = response.headers.get(\"content-length\");\n  const total = contentLength ? parseInt(contentLength, 10) : undefined;\n  const reader = response.body.getReader();\n  const chunks: Uint8Array[] = [];\n  let loaded = 0;\n\n  for (;;) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    chunks.push(value);\n    loaded += value.byteLength;\n    onProgress(loaded, total);\n  }\n\n  const result = new Uint8Array(loaded);\n  let offset = 0;\n  for (const chunk of chunks) {\n    result.set(chunk, offset);\n    offset += chunk.byteLength;\n  }\n  return result.buffer;\n}\n\nasync function fetchWithProgress(\n  url: string,\n  onProgress?: DownloadProgressCallback,\n  useCache?: boolean\n): Promise<ArrayBuffer> {\n  if (useCache && typeof caches !== \"undefined\") {\n    const cache = await caches.open(MODEL_CACHE_NAME);\n    const cached = await cache.match(url);\n    if (cached) {\n      return readResponseWithProgress(cached, onProgress);\n    }\n\n    const response = await fetch(url);\n    if (!response.ok) {\n      throw new Error(`Failed to fetch ${url}: ${response.status}`);\n    }\n\n    const cloned = response.clone();\n    cache.put(url, cloned);\n    return readResponseWithProgress(response, onProgress);\n  }\n\n  const response = await fetch(url);\n  if (!response.ok) {\n    throw new Error(`Failed to fetch ${url}: ${response.status}`);\n  }\n  return readResponseWithProgress(response, onProgress);\n}\n\nexport async function createSession(\n  url: string,\n  provider: ExecutionProvider,\n  onDownloadProgress?: DownloadProgressCallback,\n  useCache?: boolean\n): Promise<OrtSession> {\n  const data = await fetchWithProgress(url, onDownloadProgress, useCache);\n  return ort.InferenceSession.create(data, {\n    executionProviders: [provider],\n    graphOptimizationLevel: \"all\"\n  });\n}\n\nexport async function runSession(\n  session: OrtSession,\n  data: Float32Array,\n  dims: readonly number[],\n  inputName?: string,\n  outputName?: string\n): Promise<ort.Tensor> {\n  const feeds: Record<string, ort.Tensor> = {\n    [inputName ?? session.inputNames[0]]: new ort.Tensor(\"float32\", data, dims)\n  };\n\n  const outputs = await session.run(feeds);\n  const output = outputs[outputName ?? session.outputNames[0]];\n  if (!output) {\n    throw new Error(\"ONNX Runtime returned no matching output tensor.\");\n  }\n\n  return output;\n}\n","import type {\n  ExecutionProvider,\n  ExecutionProviderSupport,\n  PaddleOcrModelManifest,\n  ProviderPreference,\n  RuntimeBenchmark\n} from \"../types\";\n\nconst STORAGE_PREFIX = \"ffocr:provider:\";\nconst EXECUTION_PROVIDER_PRIORITY: readonly ExecutionProvider[] = [\n  \"webgpu\",\n  \"webnn\",\n  \"webgl\",\n  \"wasm\"\n];\n\nfunction normalizePreference(preference: ProviderPreference | undefined): ExecutionProvider[] {\n  if (!preference || preference === \"auto\") {\n    const available = getAvailableExecutionProviders();\n    return available.length > 0 ? available : [\"wasm\"];\n  }\n\n  if (typeof preference === \"string\") {\n    return [preference];\n  }\n\n  return [...preference];\n}\n\nexport function getProviderCandidates(\n  preference: ProviderPreference | undefined\n): ExecutionProvider[] {\n  return normalizePreference(preference).filter(\n    (value, index, array) => array.indexOf(value) === index\n  );\n}\n\nexport function getKnownExecutionProviders(): readonly ExecutionProvider[] {\n  return EXECUTION_PROVIDER_PRIORITY;\n}\n\nexport function getExecutionProviderSupport(): readonly ExecutionProviderSupport[] {\n  return EXECUTION_PROVIDER_PRIORITY.map((provider) => ({\n    provider,\n    available: isExecutionProviderAvailable(provider)\n  }));\n}\n\nexport function getAvailableExecutionProviders(): ExecutionProvider[] {\n  return getExecutionProviderSupport()\n    .filter((item) => item.available)\n    .map((item) => item.provider);\n}\n\nexport function isExecutionProviderAvailable(provider: ExecutionProvider): boolean {\n  switch (provider) {\n    case \"webgpu\":\n      return supportsWebGpu();\n    case \"webnn\":\n      return supportsWebNN();\n    case \"webgl\":\n      return supportsWebGl();\n    case \"wasm\":\n      return supportsWasm();\n    default:\n      return false;\n  }\n}\n\nexport function supportsWebGpu(): boolean {\n  return typeof navigator !== \"undefined\" && \"gpu\" in navigator;\n}\n\nexport function supportsWebNN(): boolean {\n  return typeof navigator !== \"undefined\" && \"ml\" in navigator;\n}\n\nexport function supportsWebGl(): boolean {\n  const canvas = createProbeCanvas();\n  if (!canvas) {\n    return false;\n  }\n\n  try {\n    const standardContext = canvas.getContext(\"webgl2\") || canvas.getContext(\"webgl\");\n    if (standardContext) {\n      return true;\n    }\n\n    return typeof HTMLCanvasElement !== \"undefined\" && canvas instanceof HTMLCanvasElement\n      ? Boolean(canvas.getContext(\"experimental-webgl\"))\n      : false;\n  } catch {\n    return false;\n  }\n}\n\nexport function supportsWasm(): boolean {\n  return typeof WebAssembly !== \"undefined\";\n}\n\nexport function buildProviderCacheKey(manifest: PaddleOcrModelManifest): string {\n  const userAgent = typeof navigator === \"undefined\" ? \"unknown\" : navigator.userAgent;\n  return `${STORAGE_PREFIX}${manifest.id}:${userAgent}`;\n}\n\nexport function readCachedProvider(cacheKey: string): ExecutionProvider | null {\n  if (typeof localStorage === \"undefined\") {\n    return null;\n  }\n\n  const cached = localStorage.getItem(cacheKey);\n  if (isExecutionProvider(cached)) {\n    return cached;\n  }\n\n  return null;\n}\n\nfunction isExecutionProvider(value: string | null): value is ExecutionProvider {\n  return value !== null && getKnownExecutionProviders().includes(value as ExecutionProvider);\n}\n\nexport function writeCachedProvider(\n  cacheKey: string,\n  provider: ExecutionProvider,\n  benchmarks: readonly RuntimeBenchmark[]\n): void {\n  if (typeof localStorage === \"undefined\") {\n    return;\n  }\n\n  localStorage.setItem(cacheKey, provider);\n  localStorage.setItem(`${cacheKey}:benchmarks`, JSON.stringify(benchmarks));\n}\n\nfunction createProbeCanvas():\n  | HTMLCanvasElement\n  | OffscreenCanvas\n  | null {\n  if (typeof OffscreenCanvas !== \"undefined\") {\n    return new OffscreenCanvas(1, 1);\n  }\n\n  if (typeof document !== \"undefined\") {\n    return document.createElement(\"canvas\");\n  }\n\n  return null;\n}\n","import type { OcrBox } from \"../types\";\nimport { clamp } from \"../utils/math\";\n\nexport interface DetectionPostprocessOptions {\n  sourceWidth: number;\n  sourceHeight: number;\n  resizedWidth: number;\n  resizedHeight: number;\n  threshold: number;\n  boxThreshold: number;\n  unclipRatio: number;\n  minSize: number;\n}\n\ninterface ComponentBox {\n  minX: number;\n  minY: number;\n  maxX: number;\n  maxY: number;\n  pixels: number;\n  scoreSum: number;\n}\n\nfunction createAxisAlignedBox(\n  component: ComponentBox,\n  options: DetectionPostprocessOptions\n): OcrBox | null {\n  const width = component.maxX - component.minX + 1;\n  const height = component.maxY - component.minY + 1;\n  const score = component.scoreSum / component.pixels;\n\n  if (width < options.minSize || height < options.minSize || score < options.boxThreshold) {\n    return null;\n  }\n\n  const distance =\n    ((width * height) * options.unclipRatio) / Math.max(2 * (width + height), 1);\n  const left = clamp(component.minX - distance, 0, options.resizedWidth - 1);\n  const top = clamp(component.minY - distance, 0, options.resizedHeight - 1);\n  const right = clamp(component.maxX + distance, 0, options.resizedWidth - 1);\n  const bottom = clamp(component.maxY + distance, 0, options.resizedHeight - 1);\n  const scaleX = options.sourceWidth / options.resizedWidth;\n  const scaleY = options.sourceHeight / options.resizedHeight;\n\n  return {\n    score,\n    points: [\n      { x: left * scaleX, y: top * scaleY },\n      { x: right * scaleX, y: top * scaleY },\n      { x: right * scaleX, y: bottom * scaleY },\n      { x: left * scaleX, y: bottom * scaleY }\n    ]\n  };\n}\n\nfunction normalizeProbabilityMap(\n  raw: Float32Array,\n  dims: readonly number[]\n): { map: Float32Array; height: number; width: number } {\n  if (dims.length === 4) {\n    return {\n      map: raw,\n      height: dims[2] ?? 0,\n      width: dims[3] ?? 0\n    };\n  }\n\n  if (dims.length === 3) {\n    return {\n      map: raw,\n      height: dims[1] ?? 0,\n      width: dims[2] ?? 0\n    };\n  }\n\n  throw new Error(`Unsupported detection output shape: ${dims.join(\"x\")}`);\n}\n\nexport function postprocessDetection(\n  raw: Float32Array,\n  dims: readonly number[],\n  options: DetectionPostprocessOptions\n): OcrBox[] {\n  const { map, height, width } = normalizeProbabilityMap(raw, dims);\n  const visited = new Uint8Array(width * height);\n  const queue = new Uint32Array(width * height);\n  const results: OcrBox[] = [];\n\n  for (let y = 0; y < height; y += 1) {\n    for (let x = 0; x < width; x += 1) {\n      const root = y * width + x;\n      if (visited[root] || map[root] < options.threshold) {\n        continue;\n      }\n\n      let head = 0;\n      let tail = 0;\n      let component: ComponentBox = {\n        minX: x,\n        minY: y,\n        maxX: x,\n        maxY: y,\n        pixels: 0,\n        scoreSum: 0\n      };\n\n      visited[root] = 1;\n      queue[tail] = root;\n      tail += 1;\n\n      while (head < tail) {\n        const current = queue[head];\n        head += 1;\n        const cx = current % width;\n        const cy = Math.floor(current / width);\n\n        component.minX = Math.min(component.minX, cx);\n        component.minY = Math.min(component.minY, cy);\n        component.maxX = Math.max(component.maxX, cx);\n        component.maxY = Math.max(component.maxY, cy);\n        component.pixels += 1;\n        component.scoreSum += map[current];\n\n        for (let ny = cy - 1; ny <= cy + 1; ny += 1) {\n          if (ny < 0 || ny >= height) {\n            continue;\n          }\n\n          for (let nx = cx - 1; nx <= cx + 1; nx += 1) {\n            if (nx < 0 || nx >= width) {\n              continue;\n            }\n\n            const next = ny * width + nx;\n            if (visited[next] || map[next] < options.threshold) {\n              continue;\n            }\n\n            visited[next] = 1;\n            queue[tail] = next;\n            tail += 1;\n          }\n        }\n      }\n\n      const box = createAxisAlignedBox(component, options);\n      if (box) {\n        results.push(box);\n      }\n    }\n  }\n\n  return results;\n}\n","import { resizeImageData } from \"../io/canvas\";\nimport { roundUpToMultiple } from \"../utils/math\";\n\n// PaddleOCR normalizes in BGR channel order with ImageNet values\nconst DET_MEAN_BGR = [0.485, 0.456, 0.406] as const;\nconst DET_STD_BGR = [0.229, 0.224, 0.225] as const;\n\nexport interface DetectionPreprocessResult {\n  data: Float32Array;\n  dims: [1, 3, number, number];\n  resizedWidth: number;\n  resizedHeight: number;\n}\n\nexport interface RecognitionPreprocessResult {\n  data: Float32Array;\n  dims: [1, number, number, number];\n}\n\nexport function preprocessDetection(\n  source: ImageData,\n  limitSideLen: number\n): DetectionPreprocessResult {\n  const maxSide = Math.max(source.width, source.height);\n  const scale = maxSide > limitSideLen ? limitSideLen / maxSide : 1;\n  const resizedWidth = roundUpToMultiple(Math.max(32, Math.round(source.width * scale)), 32);\n  const resizedHeight = roundUpToMultiple(Math.max(32, Math.round(source.height * scale)), 32);\n  const resized = resizeImageData(source, resizedWidth, resizedHeight);\n  const tensor = new Float32Array(3 * resizedWidth * resizedHeight);\n\n  for (let y = 0; y < resizedHeight; y += 1) {\n    for (let x = 0; x < resizedWidth; x += 1) {\n      const pixelOffset = (y * resizedWidth + x) * 4;\n      const red = resized.data[pixelOffset] / 255;\n      const green = resized.data[pixelOffset + 1] / 255;\n      const blue = resized.data[pixelOffset + 2] / 255;\n      const spatialOffset = y * resizedWidth + x;\n      tensor[spatialOffset] = (blue - DET_MEAN_BGR[0]) / DET_STD_BGR[0];\n      tensor[resizedWidth * resizedHeight + spatialOffset] =\n        (green - DET_MEAN_BGR[1]) / DET_STD_BGR[1];\n      tensor[2 * resizedWidth * resizedHeight + spatialOffset] =\n        (red - DET_MEAN_BGR[2]) / DET_STD_BGR[2];\n    }\n  }\n\n  return {\n    data: tensor,\n    dims: [1, 3, resizedHeight, resizedWidth],\n    resizedWidth,\n    resizedHeight\n  };\n}\n\nexport function preprocessRecognition(\n  source: ImageData,\n  imageShape: readonly [number, number, number]\n): RecognitionPreprocessResult {\n  const [, targetHeight, targetWidth] = imageShape;\n  const ratio = source.width / Math.max(source.height, 1);\n  const resizedWidth = Math.min(targetWidth, Math.max(1, Math.round(targetHeight * ratio)));\n  const resized = resizeImageData(source, resizedWidth, targetHeight);\n  const tensor = new Float32Array(3 * targetHeight * targetWidth);\n\n  for (let y = 0; y < targetHeight; y += 1) {\n    for (let x = 0; x < targetWidth; x += 1) {\n      const spatialOffset = y * targetWidth + x;\n      const channelOffset = spatialOffset;\n\n      if (x < resizedWidth) {\n        const pixelOffset = (y * resizedWidth + x) * 4;\n        tensor[channelOffset] = resized.data[pixelOffset + 2] / 127.5 - 1;\n        tensor[targetHeight * targetWidth + spatialOffset] =\n          resized.data[pixelOffset + 1] / 127.5 - 1;\n        tensor[2 * targetHeight * targetWidth + spatialOffset] =\n          resized.data[pixelOffset] / 127.5 - 1;\n      } else {\n        tensor[channelOffset] = 0;\n        tensor[targetHeight * targetWidth + spatialOffset] = 0;\n        tensor[2 * targetHeight * targetWidth + spatialOffset] = 0;\n      }\n    }\n  }\n\n  return {\n    data: tensor,\n    dims: [1, 3, targetHeight, targetWidth]\n  };\n}\n","import type { OcrLine } from \"../types\";\nimport { maxIndex, maxProbability } from \"../utils/math\";\n\ninterface DecodeOptions {\n  blankIndex?: number;\n}\n\nexport function decodeRecognitionOutput(\n  output: Float32Array,\n  dims: readonly number[],\n  dictionary: readonly string[],\n  options: DecodeOptions = {}\n): Array<Pick<OcrLine, \"text\" | \"score\">> {\n  if (dims.length !== 3) {\n    throw new Error(`Unsupported recognition output shape: ${dims.join(\"x\")}`);\n  }\n\n  const [batch, second, third] = dims;\n  const blankIndex = options.blankIndex ?? 0;\n  const isBatchTimeClass = second < third;\n  const timeSteps = isBatchTimeClass ? second : third;\n  const classes = isBatchTimeClass ? third : second;\n  const results: Array<Pick<OcrLine, \"text\" | \"score\">> = [];\n\n  for (let batchIndex = 0; batchIndex < batch; batchIndex += 1) {\n    let lastIndex = -1;\n    const pieces: string[] = [];\n    const confidences: number[] = [];\n\n    for (let step = 0; step < timeSteps; step += 1) {\n      const logits = new Float32Array(classes);\n\n      for (let classIndex = 0; classIndex < classes; classIndex += 1) {\n        const offset = isBatchTimeClass\n          ? (batchIndex * timeSteps + step) * classes + classIndex\n          : (batchIndex * classes + classIndex) * timeSteps + step;\n        logits[classIndex] = output[offset];\n      }\n\n      const prediction = maxIndex(logits);\n      if (prediction.index === blankIndex || prediction.index === lastIndex) {\n        lastIndex = prediction.index;\n        continue;\n      }\n\n      const token = dictionary[prediction.index - 1];\n      if (token) {\n        pieces.push(token);\n        confidences.push(maxProbability(logits));\n      }\n\n      lastIndex = prediction.index;\n    }\n\n    const score =\n      confidences.length === 0\n        ? 0\n        : confidences.reduce((total, value) => total + value, 0) / confidences.length;\n\n    results.push({\n      text: pieces.join(\"\"),\n      score\n    });\n  }\n\n  return results;\n}\n","import type {\n  CreatePaddleOcrOptions,\n  DictionarySource,\n  ExecutionProvider,\n  OcrBox,\n  OcrImageSource,\n  OcrLine,\n  OcrOptions,\n  OcrProgressCallback,\n  OcrResult,\n  RuntimeSelection\n} from \"./types\";\nimport { cropImageData, ensureImageData } from \"./io/canvas\";\nimport { createSession, configureOrt, runSession, type OrtSession } from \"./runtime/ort\";\nimport { getProviderCandidates } from \"./runtime/provider\";\nimport { postprocessDetection } from \"./pipeline/detect\";\nimport { preprocessDetection, preprocessRecognition } from \"./pipeline/preprocess\";\nimport { decodeRecognitionOutput } from \"./pipeline/recognize\";\nimport { axisAlignedBounds, sortBoxes } from \"./utils/math\";\n\nconst DEFAULT_RECOGNITION_SHAPE = [3, 48, 320] as const;\n\nfunction now(): number {\n  return typeof performance !== \"undefined\" ? performance.now() : Date.now();\n}\n\nfunction isDictionaryUrlSource(source: DictionarySource): source is { url: string } {\n  return !Array.isArray(source);\n}\n\nasync function loadDictionary(source: DictionarySource): Promise<string[]> {\n  if (!isDictionaryUrlSource(source)) {\n    return [...source];\n  }\n\n  const response = await fetch(source.url);\n  if (!response.ok) {\n    throw new Error(`Unable to fetch dictionary from ${source.url}`);\n  }\n\n  const text = await response.text();\n  const lines = text.split(/\\r?\\n/u);\n  if (lines.at(-1) === \"\") {\n    lines.pop();\n  }\n  return lines;\n}\n\nfunction createBlankTensor(width: number, height: number): Float32Array {\n  return new Float32Array(3 * width * height);\n}\n\nfunction combineRecognitionBatch(\n  batch: readonly Float32Array[],\n  shape: readonly [number, number, number]\n): Float32Array {\n  const [channels, height, width] = shape;\n  const itemSize = channels * height * width;\n  const merged = new Float32Array(batch.length * itemSize);\n\n  batch.forEach((tensor, index) => {\n    merged.set(tensor, index * itemSize);\n  });\n\n  return merged;\n}\n\nexport class PaddleOcrWeb {\n  private readonly options: CreatePaddleOcrOptions;\n\n  private detectorSession: OrtSession | null = null;\n\n  private recognizerSession: OrtSession | null = null;\n\n  private dictionary: string[] = [];\n\n  private runtimeSelection: RuntimeSelection | null = null;\n\n  private initPromise: Promise<void> | null = null;\n\n  constructor(options: CreatePaddleOcrOptions) {\n    this.options = options;\n  }\n\n  async init(onProgress?: OcrProgressCallback): Promise<void> {\n    if (!this.initPromise) {\n      this.initPromise = this.doInit(onProgress);\n    }\n\n    return this.initPromise;\n  }\n\n  private async doInit(onProgress?: OcrProgressCallback): Promise<void> {\n    configureOrt(this.options.ort);\n\n    onProgress?.({ phase: \"loading_dictionary\" });\n    this.dictionary = await loadDictionary(this.options.manifest.dictionary);\n\n    const provider = await this.selectProvider();\n\n    const useCache = this.options.cacheModels;\n\n    onProgress?.({ phase: \"loading_detection_model\" });\n    this.detectorSession = await createSession(\n      this.options.manifest.detection.url,\n      provider,\n      onProgress\n        ? (loaded, totalBytes) =>\n            onProgress({ phase: \"loading_detection_model\", loaded, totalBytes: totalBytes ?? undefined })\n        : undefined,\n      useCache\n    );\n\n    onProgress?.({ phase: \"loading_recognition_model\" });\n    this.recognizerSession = await createSession(\n      this.options.manifest.recognition.url,\n      provider,\n      onProgress\n        ? (loaded, totalBytes) =>\n            onProgress({ phase: \"loading_recognition_model\", loaded, totalBytes: totalBytes ?? undefined })\n        : undefined,\n      useCache\n    );\n\n    if (this.options.warmup) {\n      onProgress?.({ phase: \"warmup\" });\n      await this.warmupSessions();\n    }\n  }\n\n  private async selectProvider(): Promise<ExecutionProvider> {\n    const candidates = getProviderCandidates(this.options.providerPreference);\n    const firstCandidate = candidates[0];\n    if (!firstCandidate) {\n      throw new Error(\"No ONNX Runtime execution providers are available.\");\n    }\n\n    this.runtimeSelection = {\n      provider: firstCandidate,\n      candidates,\n      benchmarked: false,\n      benchmarks: []\n    };\n\n    return firstCandidate;\n  }\n\n  async warmup(): Promise<void> {\n    await this.init();\n    await this.warmupSessions();\n  }\n\n  private async warmupSessions(): Promise<void> {\n    if (!this.detectorSession || !this.recognizerSession) {\n      return;\n    }\n\n    await runSession(\n      this.detectorSession,\n      createBlankTensor(640, 640),\n      [1, 3, 640, 640],\n      this.options.manifest.detection.inputName,\n      this.options.manifest.detection.outputName\n    );\n\n    const recognitionShape =\n      this.options.manifest.recognitionImageShape ?? DEFAULT_RECOGNITION_SHAPE;\n    const [channels, height, width] = recognitionShape;\n    await runSession(\n      this.recognizerSession,\n      new Float32Array(channels * height * width),\n      [1, channels, height, width],\n      this.options.manifest.recognition.inputName,\n      this.options.manifest.recognition.outputName\n    );\n  }\n\n  getRuntimeSelection(): RuntimeSelection | null {\n    return this.runtimeSelection;\n  }\n\n  async ocr(source: OcrImageSource, options: OcrOptions = {}): Promise<OcrResult> {\n    const onProgress = options.onProgress;\n    await this.init(onProgress);\n\n    if (!this.detectorSession || !this.recognizerSession || !this.runtimeSelection) {\n      throw new Error(\"The OCR runtime was not initialized.\");\n    }\n\n    onProgress?.({ phase: \"preprocessing\" });\n    const image = await ensureImageData(source);\n    const detectionInput = preprocessDetection(\n      image,\n      this.options.manifest.detectionLimitSideLen ?? 960\n    );\n\n    onProgress?.({ phase: \"detecting\" });\n    const detectionOutput = await runSession(\n      this.detectorSession,\n      detectionInput.data,\n      detectionInput.dims,\n      this.options.manifest.detection.inputName,\n      this.options.manifest.detection.outputName\n    );\n\n    const rawDetection = detectionOutput.data as Float32Array;\n    const boxes = sortBoxes(\n      postprocessDetection(rawDetection, detectionOutput.dims, {\n        sourceWidth: image.width,\n        sourceHeight: image.height,\n        resizedWidth: detectionInput.resizedWidth,\n        resizedHeight: detectionInput.resizedHeight,\n        threshold: this.options.manifest.detectionThreshold ?? 0.3,\n        boxThreshold: this.options.manifest.detectionBoxThreshold ?? 0.6,\n        unclipRatio: this.options.manifest.detectionUnclipRatio ?? 1.5,\n        minSize: this.options.manifest.detectionMinSize ?? 3\n      })\n    );\n    const lines = await this.recognizeBoxes(image, boxes, options.maxRecognitionBatchSize ?? 8, onProgress);\n\n    return {\n      text: lines.map((line) => line.text).join(\"\\n\"),\n      lines,\n      image: {\n        width: image.width,\n        height: image.height\n      },\n      runtime: this.runtimeSelection\n    };\n  }\n\n  private async recognizeBoxes(\n    image: ImageData,\n    boxes: readonly OcrBox[],\n    batchSize: number,\n    onProgress?: OcrProgressCallback\n  ): Promise<OcrLine[]> {\n    if (!this.recognizerSession) {\n      throw new Error(\"Recognizer session is not available.\");\n    }\n\n    const recognitionShape =\n      this.options.manifest.recognitionImageShape ?? DEFAULT_RECOGNITION_SHAPE;\n    const lines: OcrLine[] = [];\n    const totalBatches = Math.ceil(boxes.length / batchSize);\n    let batchIndex = 0;\n\n    for (let cursor = 0; cursor < boxes.length; cursor += batchSize) {\n      onProgress?.({ phase: \"recognizing\", current: batchIndex + 1, total: totalBatches });\n      const batchBoxes = boxes.slice(cursor, cursor + batchSize);\n      const tensors: Float32Array[] = [];\n\n      for (const box of batchBoxes) {\n        const bounds = axisAlignedBounds(box);\n        const crop = cropImageData(image, bounds.left, bounds.top, bounds.width, bounds.height);\n        tensors.push(preprocessRecognition(crop, recognitionShape).data);\n      }\n\n      const merged = combineRecognitionBatch(tensors, recognitionShape);\n      const [channels, height, width] = recognitionShape;\n      const recognitionOutput = await runSession(\n        this.recognizerSession,\n        merged,\n        [batchBoxes.length, channels, height, width],\n        this.options.manifest.recognition.inputName,\n        this.options.manifest.recognition.outputName\n      );\n      const decoded = decodeRecognitionOutput(\n        recognitionOutput.data as Float32Array,\n        recognitionOutput.dims,\n        this.dictionary\n      );\n\n      decoded.forEach((item, index) => {\n        const box = batchBoxes[index];\n        lines.push({\n          text: item.text,\n          score: (item.score + box.score) / 2,\n          box\n        });\n      });\n\n      batchIndex++;\n    }\n\n    return lines.filter((line) => line.text.length > 0);\n  }\n\n  dispose(): void {\n    this.detectorSession = null;\n    this.recognizerSession = null;\n  }\n}\n\nexport function createPaddleOcr(options: CreatePaddleOcrOptions): PaddleOcrWeb {\n  return new PaddleOcrWeb(options);\n}\n","import type { PaddleOcrModelManifest, PPOcrV5ModelVariant } from \"../types\";\n\nexport interface OfficialManifestOptions {\n  baseUrl: string;\n  dictionaryUrl?: string;\n  modelVariant?: PPOcrV5ModelVariant;\n  detectionModelPath?: string;\n  recognitionModelPath?: string;\n}\n\nexport const DEFAULT_DICTIONARY_URL =\n  \"https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/main/ppocr/utils/dict/ppocrv5_dict.txt\";\n\nexport const PPOCRV5_MODEL_PATHS = {\n  detection: {\n    server: \"det_server.onnx\",\n    mobile: \"det_mobile.onnx\"\n  },\n  recognition: {\n    server: \"rec_server.onnx\",\n    mobile: \"rec_mobile.onnx\"\n  }\n} as const;\n\nfunction resolveDetectionPath(options: OfficialManifestOptions): string {\n  if (options.detectionModelPath) {\n    return options.detectionModelPath;\n  }\n  return PPOCRV5_MODEL_PATHS.detection[options.modelVariant ?? \"mobile\"];\n}\n\nfunction resolveRecognitionPath(options: OfficialManifestOptions): string {\n  if (options.recognitionModelPath) {\n    return options.recognitionModelPath;\n  }\n  return PPOCRV5_MODEL_PATHS.recognition[options.modelVariant ?? \"mobile\"];\n}\n\nexport function createPPOcrV5BrowserManifest(\n  options: OfficialManifestOptions\n): PaddleOcrModelManifest {\n  const normalizedBase = options.baseUrl.replace(/\\/$/, \"\");\n  const variant = options.modelVariant ?? \"mobile\";\n\n  return {\n    id: variant === \"server\" ? \"pp-ocrv5-browser\" : `pp-ocrv5-${variant}-browser`,\n    detection: {\n      url: `${normalizedBase}/${resolveDetectionPath(options)}`\n    },\n    recognition: {\n      url: `${normalizedBase}/${resolveRecognitionPath(options)}`\n    },\n    dictionary: {\n      url: options.dictionaryUrl ?? DEFAULT_DICTIONARY_URL\n    },\n    detectionLimitSideLen: 960,\n    detectionThreshold: 0.3,\n    detectionBoxThreshold: 0.6,\n    detectionUnclipRatio: 1.5,\n    detectionMinSize: 3,\n    recognitionImageShape: [3, 48, 320]\n  };\n}\n","import { createPPOcrV5BrowserManifest } from \"../manifests/official\";\nimport { createPaddleOcr, type PaddleOcrWeb } from \"../paddle-ocr\";\nimport type {\n  CreatePPOcrV5Options,\n  OcrImageSource,\n  OcrOptions,\n  OcrResult,\n  OrtRuntimeOptions\n} from \"../types\";\n\nexport const DEFAULT_ORT_WASM_PATHS = \"https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/\";\nexport const DEFAULT_MODEL_RELEASE_TAG = \"models-ppocrv5-v4\";\nexport const DEFAULT_MODEL_BASE_URL =\n  \"https://zxc88645.github.io/ffocr/models/pp-ocrv5\";\n\nfunction createRecommendedOrtOptions(options?: OrtRuntimeOptions): OrtRuntimeOptions {\n  return {\n    wasmPaths: options?.wasmPaths ?? DEFAULT_ORT_WASM_PATHS,\n    wasmThreads: options?.wasmThreads\n  };\n}\n\nexport function createPPOcrV5(options: CreatePPOcrV5Options): PaddleOcrWeb {\n  const {\n    baseUrl,\n    dictionaryUrl,\n    modelVariant,\n    detectionModelPath,\n    recognitionModelPath,\n    ort,\n    ...rest\n  } = options;\n\n  return createPaddleOcr({\n    ...rest,\n    manifest: createPPOcrV5BrowserManifest({\n      baseUrl,\n      dictionaryUrl,\n      modelVariant,\n      detectionModelPath,\n      recognitionModelPath\n    }),\n    ort: createRecommendedOrtOptions(ort)\n  });\n}\n\nexport function createDefaultPPOcrV5(\n  options: Omit<CreatePPOcrV5Options, \"baseUrl\"> = {}\n): PaddleOcrWeb {\n  return createPPOcrV5({\n    ...options,\n    baseUrl: DEFAULT_MODEL_BASE_URL\n  });\n}\n\nexport async function ocrWithPPOcrV5(\n  source: OcrImageSource,\n  options: CreatePPOcrV5Options,\n  ocrOptions?: OcrOptions\n): Promise<OcrResult> {\n  const runtime = createPPOcrV5(options);\n\n  try {\n    return await runtime.ocr(source, ocrOptions);\n  } finally {\n    runtime.dispose();\n  }\n}\n\nexport async function ocrWithDefaultPPOcrV5(\n  source: OcrImageSource,\n  options: Omit<CreatePPOcrV5Options, \"baseUrl\"> = {},\n  ocrOptions?: OcrOptions\n): Promise<OcrResult> {\n  return ocrWithPPOcrV5(\n    source,\n    {\n      ...options,\n      baseUrl: DEFAULT_MODEL_BASE_URL\n    },\n    ocrOptions\n  );\n}\n"],"mappings":"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"}