tempest-react-sdk 0.72.0 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +6 -4
  2. package/dist/br/MapMarkers.cjs +1 -1
  3. package/dist/br/MapMarkers.cjs.map +1 -1
  4. package/dist/br/MapMarkers.js +19 -22
  5. package/dist/br/MapMarkers.js.map +1 -1
  6. package/dist/components/AIChat/AIChatTurn.cjs +1 -1
  7. package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
  8. package/dist/components/AIChat/AIChatTurn.js +1 -1
  9. package/dist/components/AIChat/AIChatTurn.js.map +1 -1
  10. package/dist/components/AppShell/AppShell.module.cjs.map +1 -1
  11. package/dist/components/AppShell/AppShell.module.js.map +1 -1
  12. package/dist/components/Button/Button.cjs +1 -1
  13. package/dist/components/Button/Button.cjs.map +1 -1
  14. package/dist/components/Button/Button.js +41 -36
  15. package/dist/components/Button/Button.js.map +1 -1
  16. package/dist/components/Button/Button.module.cjs.map +1 -1
  17. package/dist/components/Button/Button.module.js.map +1 -1
  18. package/dist/components/Button/ButtonContent.cjs +2 -0
  19. package/dist/components/Button/ButtonContent.cjs.map +1 -0
  20. package/dist/components/Button/ButtonContent.js +34 -0
  21. package/dist/components/Button/ButtonContent.js.map +1 -0
  22. package/dist/components/Button/ButtonSlot.cjs +2 -0
  23. package/dist/components/Button/ButtonSlot.cjs.map +1 -0
  24. package/dist/components/Button/ButtonSlot.js +36 -0
  25. package/dist/components/Button/ButtonSlot.js.map +1 -0
  26. package/dist/components/Button/button-class.cjs +2 -0
  27. package/dist/components/Button/button-class.cjs.map +1 -0
  28. package/dist/components/Button/button-class.js +13 -0
  29. package/dist/components/Button/button-class.js.map +1 -0
  30. package/dist/components/Button/link-rel.cjs +2 -0
  31. package/dist/components/Button/link-rel.cjs.map +1 -0
  32. package/dist/components/Button/link-rel.js +11 -0
  33. package/dist/components/Button/link-rel.js.map +1 -0
  34. package/dist/components/Button/slot.cjs +2 -0
  35. package/dist/components/Button/slot.cjs.map +1 -0
  36. package/dist/components/Button/slot.js +41 -0
  37. package/dist/components/Button/slot.js.map +1 -0
  38. package/dist/components/Collapsible/Collapsible.cjs +1 -1
  39. package/dist/components/Collapsible/Collapsible.cjs.map +1 -1
  40. package/dist/components/Collapsible/Collapsible.js +1 -1
  41. package/dist/components/Collapsible/Collapsible.js.map +1 -1
  42. package/dist/components/Form/Form.cjs.map +1 -1
  43. package/dist/components/Form/Form.js.map +1 -1
  44. package/dist/components/InstallButton/InstallButton.cjs.map +1 -1
  45. package/dist/components/InstallButton/InstallButton.js.map +1 -1
  46. package/dist/components/Modal/Modal.cjs +1 -1
  47. package/dist/components/Modal/Modal.cjs.map +1 -1
  48. package/dist/components/Modal/Modal.js +1 -1
  49. package/dist/components/Modal/Modal.js.map +1 -1
  50. package/dist/components/Modal/Modal.module.cjs +1 -1
  51. package/dist/components/Modal/Modal.module.cjs.map +1 -1
  52. package/dist/components/Modal/Modal.module.js +1 -1
  53. package/dist/components/Modal/Modal.module.js.map +1 -1
  54. package/dist/components/Page/Page.cjs +1 -1
  55. package/dist/components/Page/Page.cjs.map +1 -1
  56. package/dist/components/Page/Page.js +23 -39
  57. package/dist/components/Page/Page.js.map +1 -1
  58. package/dist/components/Page/Page.module.cjs +1 -1
  59. package/dist/components/Page/Page.module.cjs.map +1 -1
  60. package/dist/components/Page/Page.module.js +5 -11
  61. package/dist/components/Page/Page.module.js.map +1 -1
  62. package/dist/components/Reveal/Reveal.cjs +2 -0
  63. package/dist/components/Reveal/Reveal.cjs.map +1 -0
  64. package/dist/components/Reveal/Reveal.js +56 -0
  65. package/dist/components/Reveal/Reveal.js.map +1 -0
  66. package/dist/components/Reveal/Reveal.module.cjs +3 -0
  67. package/dist/components/Reveal/Reveal.module.cjs.map +1 -0
  68. package/dist/components/Reveal/Reveal.module.js +7 -0
  69. package/dist/components/Reveal/Reveal.module.js.map +1 -0
  70. package/dist/components/Reveal/reveal-threshold.cjs +2 -0
  71. package/dist/components/Reveal/reveal-threshold.cjs.map +1 -0
  72. package/dist/components/Reveal/reveal-threshold.js +13 -0
  73. package/dist/components/Reveal/reveal-threshold.js.map +1 -0
  74. package/dist/components/SectionHeader/SectionHeader.cjs +2 -0
  75. package/dist/components/SectionHeader/SectionHeader.cjs.map +1 -0
  76. package/dist/components/SectionHeader/SectionHeader.js +58 -0
  77. package/dist/components/SectionHeader/SectionHeader.js.map +1 -0
  78. package/dist/components/SectionHeader/SectionHeader.module.cjs +3 -0
  79. package/dist/components/SectionHeader/SectionHeader.module.cjs.map +1 -0
  80. package/dist/components/SectionHeader/SectionHeader.module.js +15 -0
  81. package/dist/components/SectionHeader/SectionHeader.module.js.map +1 -0
  82. package/dist/components/Timeline/Timeline.cjs +1 -1
  83. package/dist/components/Timeline/Timeline.cjs.map +1 -1
  84. package/dist/components/Timeline/Timeline.js +22 -15
  85. package/dist/components/Timeline/Timeline.js.map +1 -1
  86. package/dist/components/Timeline/Timeline.module.cjs +1 -1
  87. package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
  88. package/dist/components/Timeline/Timeline.module.js +1 -1
  89. package/dist/components/Timeline/Timeline.module.js.map +1 -1
  90. package/dist/styles/Reveal.css +2 -0
  91. package/dist/styles/SectionHeader.css +2 -0
  92. package/dist/styles/actions.css +24 -22
  93. package/dist/styles/base.css +3 -1
  94. package/dist/styles/component/AppShell.css +1 -1
  95. package/dist/styles/component/Button.css +24 -22
  96. package/dist/styles/component/Modal.css +2 -2
  97. package/dist/styles/component/Page.css +0 -6
  98. package/dist/styles/component/Reveal.css +9 -0
  99. package/dist/styles/component/SectionHeader.css +9 -0
  100. package/dist/styles/component/Timeline.css +5 -5
  101. package/dist/styles/core.css +3 -1
  102. package/dist/styles/data.css +5 -5
  103. package/dist/styles/inverse.css +147 -0
  104. package/dist/styles/layout.css +9 -7
  105. package/dist/styles/manifest.json +14 -1
  106. package/dist/styles/overlay.css +2 -2
  107. package/dist/styles/utility.css +8 -0
  108. package/dist/styles.css +1 -1
  109. package/dist/tempest-react-sdk.cjs +1 -1
  110. package/dist/tempest-react-sdk.d.ts +353 -4
  111. package/dist/tempest-react-sdk.js +350 -346
  112. package/dist/theme/create-theme.cjs +3 -3
  113. package/dist/theme/create-theme.cjs.map +1 -1
  114. package/dist/theme/create-theme.js +67 -55
  115. package/dist/theme/create-theme.js.map +1 -1
  116. package/dist/theme/inverse-render.cjs +3 -0
  117. package/dist/theme/inverse-render.cjs.map +1 -0
  118. package/dist/theme/inverse-render.js +10 -0
  119. package/dist/theme/inverse-render.js.map +1 -0
  120. package/dist/theme/inverse-surface.cjs +2 -0
  121. package/dist/theme/inverse-surface.cjs.map +1 -0
  122. package/dist/theme/inverse-surface.js +258 -0
  123. package/dist/theme/inverse-surface.js.map +1 -0
  124. package/dist/theme/status-tokens.cjs +2 -0
  125. package/dist/theme/status-tokens.cjs.map +1 -0
  126. package/dist/theme/status-tokens.js +15 -0
  127. package/dist/theme/status-tokens.js.map +1 -0
  128. package/dist/vision/core/graph.cjs.map +1 -1
  129. package/dist/vision/core/graph.js.map +1 -1
  130. package/dist/vision/core/metadata.cjs +2 -2
  131. package/dist/vision/core/metadata.cjs.map +1 -1
  132. package/dist/vision/core/metadata.js +101 -29
  133. package/dist/vision/core/metadata.js.map +1 -1
  134. package/dist/vision/core/session.cjs +1 -1
  135. package/dist/vision/core/session.cjs.map +1 -1
  136. package/dist/vision/core/session.js +59 -48
  137. package/dist/vision/core/session.js.map +1 -1
  138. package/dist/vision/index.cjs +1 -1
  139. package/dist/vision/index.cjs.map +1 -1
  140. package/dist/vision/index.js +1 -1
  141. package/dist/vision/index.js.map +1 -1
  142. package/dist/vision.d.ts +25 -21
  143. package/dist/vite/create-vite-config.cjs +1 -1
  144. package/dist/vite/create-vite-config.cjs.map +1 -1
  145. package/dist/vite/create-vite-config.js +6 -4
  146. package/dist/vite/create-vite-config.js.map +1 -1
  147. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.cjs","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field number of `graph` in `ModelProto` (GraphProto). */\nconst MODEL_GRAPH_FIELD = 7;\n\n/** Field number of `input` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_INPUT_FIELD = 11;\n\n/** Field numbers of `name` and `type` in `ValueInfoProto`. */\nconst VALUE_INFO_NAME_FIELD = 1;\nconst VALUE_INFO_TYPE_FIELD = 2;\n\n/** Field number of `tensor_type` in `TypeProto` (TypeProto.Tensor). */\nconst TYPE_TENSOR_FIELD = 1;\n\n/** Field number of `elem_type` in `TypeProto.Tensor` (a `TensorProto.DataType`). */\nconst TENSOR_ELEM_TYPE_FIELD = 1;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n *\n * It applies to leaf fields being read *out* of the file, not to the messages\n * walked *through* to reach them. The `graph` of a real export is the file: 21.79\n * MB on a reported YOLO detector. Applying this ceiling there made the reader\n * give up on every model anyone would actually load, and give up silently.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @param maxBytes Largest payload to accept, defaulting to\n * {@link MAX_FIELD_BYTES}. Pass the buffer length when descending into a\n * message whose size is the file's size rather than a leaf value's.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds `maxBytes`.\n */\nfunction readLengthDelimited(\n cursor: Cursor,\n maxBytes: number = MAX_FIELD_BYTES,\n): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > maxBytes) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/**\n * Read the element type of a `TypeProto.Tensor` message.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` when the message\n * carries none or cannot be walked.\n */\nfunction readTensorElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n return readVarint(cursor);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read the element type out of a `TypeProto`, which wraps the tensor type.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` for a non-tensor type\n * (sequence, map, optional) or an unreadable message.\n */\nfunction readTypeElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TYPE_TENSOR_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n return readTensorElemType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read one `ValueInfoProto` into a name/element-type pair.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The pair, or `null` when either half is missing or unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, number] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let elemType: number | null = null;\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n if (field === VALUE_INFO_NAME_FIELD) {\n name = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n bytes.subarray(range.start, range.end),\n );\n } else if (field === VALUE_INFO_TYPE_FIELD) {\n elemType = readTypeElemType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null || elemType === null) return null;\n return [name, elemType];\n}\n\n/**\n * Read the element type each graph input declares.\n *\n * `onnxruntime-web` does not expose this. `session.inputMetadata` is\n * `undefined` on 1.20.1 — the same version where `declaredShapesFrom` comes\n * back empty — so the declared types have to come from the file, which the SDK\n * already downloads and walks for {@link readModelMetadata}. Same bytes, one\n * more pass, no extra request.\n *\n * @param model The `.onnx` file contents.\n * @returns Input name → `TensorProto.DataType` value. An empty object when the\n * file carries no readable graph, which every caller treats as \"assume\n * float32\" — the behaviour before any of this existed.\n */\nexport function readModelInputTypes(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, number>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const types: Record<string, number> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_GRAPH_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const graph = readLengthDelimited(cursor, bytes.length);\n if (graph === null) break;\n const inner: Cursor = { bytes, end: graph.end, pos: graph.start };\n while (inner.pos < inner.end) {\n const innerTag = readVarint(inner);\n if (innerTag === null) break;\n const innerField = innerTag >>> 3;\n const innerWire = innerTag & 0x07;\n if (innerField === GRAPH_INPUT_FIELD && innerWire === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) types[info[0]] = info[1];\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return types;\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"metadata.cjs","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\nimport type { DeclaredDim, DeclaredShape } from \"./graph\";\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field number of `graph` in `ModelProto` (GraphProto). */\nconst MODEL_GRAPH_FIELD = 7;\n\n/** Field number of `input` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_INPUT_FIELD = 11;\n\n/** Field number of `output` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_OUTPUT_FIELD = 12;\n\n/** Field numbers of `name` and `type` in `ValueInfoProto`. */\nconst VALUE_INFO_NAME_FIELD = 1;\nconst VALUE_INFO_TYPE_FIELD = 2;\n\n/** Field number of `tensor_type` in `TypeProto` (TypeProto.Tensor). */\nconst TYPE_TENSOR_FIELD = 1;\n\n/** Field number of `elem_type` in `TypeProto.Tensor` (a `TensorProto.DataType`). */\nconst TENSOR_ELEM_TYPE_FIELD = 1;\n\n/** Field number of `shape` in `TypeProto.Tensor` (TensorShapeProto). */\nconst TENSOR_SHAPE_FIELD = 2;\n\n/** Field number of `dim` in `TensorShapeProto` (repeated Dimension). */\nconst SHAPE_DIM_FIELD = 1;\n\n/** Field number of `dim_value` in `TensorShapeProto.Dimension` (int64). */\nconst DIM_VALUE_FIELD = 1;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n *\n * It applies to leaf fields being read *out* of the file, not to the messages\n * walked *through* to reach them. The `graph` of a real export is the file: 21.79\n * MB on a reported YOLO detector. Applying this ceiling there made the reader\n * give up on every model anyone would actually load, and give up silently.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @param maxBytes Largest payload to accept, defaulting to\n * {@link MAX_FIELD_BYTES}. Pass the buffer length when descending into a\n * message whose size is the file's size rather than a leaf value's.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds `maxBytes`.\n */\nfunction readLengthDelimited(\n cursor: Cursor,\n maxBytes: number = MAX_FIELD_BYTES,\n): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > maxBytes) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/** What a graph value declares about itself: its element type and its shape. */\ninterface DeclaredTensor {\n readonly elemType: number | null;\n readonly shape: DeclaredShape;\n}\n\n/** A graph value with nothing readable declared. */\nconst UNDECLARED: DeclaredTensor = { elemType: null, shape: [] };\n\n/**\n * Read one `TensorShapeProto.Dimension`.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The size when the graph pins it to a positive integer, `null` for a\n * symbolic (`dim_param`) or absent one — the same convention as\n * `declaredShapesFrom`, so both sources read alike downstream.\n */\nfunction readDimension(bytes: Uint8Array, start: number, end: number): DeclaredDim {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === DIM_VALUE_FIELD && wireType === WIRE_VARINT) {\n const value = readVarint(cursor);\n return value !== null && Number.isSafeInteger(value) && value > 0 ? value : null;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read a `TensorShapeProto` into a declared shape.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns One entry per dimension, or an empty shape when the message cannot\n * be walked — a half-read shape would claim the wrong rank.\n */\nfunction readShape(bytes: Uint8Array, start: number, end: number): DeclaredShape {\n const cursor: Cursor = { bytes, end, pos: start };\n const dims: DeclaredDim[] = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return [];\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === SHAPE_DIM_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return [];\n dims.push(readDimension(bytes, range.start, range.end));\n continue;\n }\n if (!skipField(cursor, wireType)) return [];\n }\n return dims;\n}\n\n/**\n * Read a `TypeProto.Tensor` message.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns Its element type and shape; either is left undeclared when the\n * message carries none or cannot be walked.\n */\nfunction readTensorType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n let elemType: number | null = null;\n let shape: DeclaredShape = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n elemType = readVarint(cursor);\n continue;\n }\n if (field === TENSOR_SHAPE_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n shape = readShape(bytes, range.start, range.end);\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n return { elemType, shape };\n}\n\n/**\n * Read a `TypeProto`, which wraps the tensor type.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The tensor's declarations, or {@link UNDECLARED} for a non-tensor\n * type (sequence, map, optional) or an unreadable message.\n */\nfunction readType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return UNDECLARED;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TYPE_TENSOR_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return UNDECLARED;\n return readTensorType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return UNDECLARED;\n }\n return UNDECLARED;\n}\n\n/**\n * Read one `ValueInfoProto`.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The value's name and declarations, or `null` when the name is\n * missing or the message is unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): (DeclaredTensor & { readonly name: string }) | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let declared: DeclaredTensor = UNDECLARED;\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n if (field === VALUE_INFO_NAME_FIELD) {\n name = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n bytes.subarray(range.start, range.end),\n );\n } else if (field === VALUE_INFO_TYPE_FIELD) {\n declared = readType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null) return null;\n return { name, ...declared };\n}\n\n/** The graph's declared inputs and outputs, each in declaration order. */\ninterface GraphValues {\n readonly inputs: readonly (DeclaredTensor & { readonly name: string })[];\n readonly outputs: readonly (DeclaredTensor & { readonly name: string })[];\n}\n\n/**\n * Walk the `GraphProto` and collect what its inputs and outputs declare.\n *\n * @param model The `.onnx` file contents.\n * @returns Both lists, empty when the file carries no readable graph.\n */\nfunction readGraphValues(model: Uint8Array | ArrayBufferLike): GraphValues {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const inputs: (DeclaredTensor & { readonly name: string })[] = [];\n const outputs: (DeclaredTensor & { readonly name: string })[] = [];\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_GRAPH_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const graph = readLengthDelimited(cursor, bytes.length);\n if (graph === null) break;\n const inner: Cursor = { bytes, end: graph.end, pos: graph.start };\n while (inner.pos < inner.end) {\n const innerTag = readVarint(inner);\n if (innerTag === null) break;\n const innerField = innerTag >>> 3;\n const innerWire = innerTag & 0x07;\n if (\n (innerField === GRAPH_INPUT_FIELD || innerField === GRAPH_OUTPUT_FIELD) &&\n innerWire === WIRE_LENGTH_DELIMITED\n ) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) (innerField === GRAPH_INPUT_FIELD ? inputs : outputs).push(info);\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return { inputs, outputs };\n}\n\n/**\n * Read the element type each graph input declares.\n *\n * `onnxruntime-web` does not expose this. `session.inputMetadata` is\n * `undefined` on 1.20.1 — the same version where `declaredShapesFrom` comes\n * back empty — so the declared types have to come from the file, which the SDK\n * already downloads and walks for {@link readModelMetadata}. Same bytes, one\n * more pass, no extra request.\n *\n * @param model The `.onnx` file contents.\n * @returns Input name → `TensorProto.DataType` value. An empty object when the\n * file carries no readable graph, which every caller treats as \"assume\n * float32\" — the behaviour before any of this existed.\n */\nexport function readModelInputTypes(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, number>> {\n const types: Record<string, number> = {};\n for (const input of readGraphValues(model).inputs) {\n if (input.elemType !== null) types[input.name] = input.elemType;\n }\n return types;\n}\n\n/**\n * Read the shape each graph input and output declares, straight from the file.\n *\n * `onnxruntime-web` reports these through `inputMetadata` / `outputMetadata`\n * only from 1.22 on. Below that the session answers nothing, and a task that\n * reads its input size or class count off the session silently fell back to\n * its defaults: a 64x64 detector was fed 640x640 and ORT aborted with\n * `Got invalid dimensions for input` (measured on 1.17.3, 1.18.0, 1.19.2,\n * 1.20.1 and 1.21.0). The\n * file carries the same declarations, in the same `ValueInfoProto` the element\n * types are read from.\n *\n * Keyed by name rather than position: in an older IR the graph's `input` list\n * also carries the initializers, so its order does not line up with the\n * session's `inputNames`.\n *\n * @param model The `.onnx` file contents.\n * @returns Input and output name → shape, dynamic axes as `null`. Both maps\n * are empty when the file carries no readable graph.\n */\nexport function readModelShapes(model: Uint8Array | ArrayBufferLike): {\n readonly inputs: Readonly<Record<string, DeclaredShape>>;\n readonly outputs: Readonly<Record<string, DeclaredShape>>;\n} {\n const { inputs, outputs } = readGraphValues(model);\n return {\n inputs: Object.fromEntries(inputs.map((value) => [value.name, value.shape])),\n outputs: Object.fromEntries(outputs.map((value) => [value.name, value.shape])),\n };\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"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"}
@@ -70,7 +70,11 @@ function i(i) {
70
70
  }
71
71
  return s;
72
72
  }
73
- function a(n, r, i) {
73
+ var a = {
74
+ elemType: null,
75
+ shape: []
76
+ };
77
+ function o(n, r, i) {
74
78
  let a = {
75
79
  bytes: n,
76
80
  end: i,
@@ -80,12 +84,62 @@ function a(n, r, i) {
80
84
  let n = e(a);
81
85
  if (n === null) return null;
82
86
  let r = n >>> 3, i = n & 7;
83
- if (r === 1 && i === 0) return e(a);
87
+ if (r === 1 && i === 0) {
88
+ let t = e(a);
89
+ return t !== null && Number.isSafeInteger(t) && t > 0 ? t : null;
90
+ }
84
91
  if (!t(a, i)) return null;
85
92
  }
86
93
  return null;
87
94
  }
88
- function o(r, i, o) {
95
+ function s(r, i, a) {
96
+ let s = {
97
+ bytes: r,
98
+ end: a,
99
+ pos: i
100
+ }, c = [];
101
+ for (; s.pos < s.end;) {
102
+ let i = e(s);
103
+ if (i === null) return [];
104
+ let a = i >>> 3, l = i & 7;
105
+ if (a === 1 && l === 2) {
106
+ let e = n(s);
107
+ if (e === null) return [];
108
+ c.push(o(r, e.start, e.end));
109
+ continue;
110
+ }
111
+ if (!t(s, l)) return [];
112
+ }
113
+ return c;
114
+ }
115
+ function c(r, i, a) {
116
+ let o = {
117
+ bytes: r,
118
+ end: a,
119
+ pos: i
120
+ }, c = null, l = [];
121
+ for (; o.pos < o.end;) {
122
+ let i = e(o);
123
+ if (i === null) break;
124
+ let a = i >>> 3, u = i & 7;
125
+ if (a === 1 && u === 0) {
126
+ c = e(o);
127
+ continue;
128
+ }
129
+ if (a === 2 && u === 2) {
130
+ let e = n(o);
131
+ if (e === null) break;
132
+ l = s(r, e.start, e.end);
133
+ continue;
134
+ }
135
+ if (!t(o, u)) break;
136
+ }
137
+ return {
138
+ elemType: c,
139
+ shape: l
140
+ };
141
+ }
142
+ function l(r, i, o) {
89
143
  let s = {
90
144
  bytes: r,
91
145
  end: o,
@@ -93,42 +147,45 @@ function o(r, i, o) {
93
147
  };
94
148
  for (; s.pos < s.end;) {
95
149
  let i = e(s);
96
- if (i === null) return null;
97
- let o = i >>> 3, c = i & 7;
98
- if (o === 1 && c === 2) {
150
+ if (i === null) return a;
151
+ let o = i >>> 3, l = i & 7;
152
+ if (o === 1 && l === 2) {
99
153
  let e = n(s);
100
- return e === null ? null : a(r, e.start, e.end);
154
+ return e === null ? a : c(r, e.start, e.end);
101
155
  }
102
- if (!t(s, c)) return null;
156
+ if (!t(s, l)) return a;
103
157
  }
104
- return null;
158
+ return a;
105
159
  }
106
- function s(r, i, a) {
160
+ function u(r, i, o) {
107
161
  let s = {
108
162
  bytes: r,
109
- end: a,
163
+ end: o,
110
164
  pos: i
111
- }, c = null, l = null;
165
+ }, c = null, u = a;
112
166
  for (; s.pos < s.end;) {
113
167
  let i = e(s);
114
168
  if (i === null) return null;
115
- let a = i >>> 3, u = i & 7;
116
- if (u === 2) {
169
+ let a = i >>> 3, o = i & 7;
170
+ if (o === 2) {
117
171
  let e = n(s);
118
172
  if (e === null) return null;
119
- a === 1 ? c = new TextDecoder("utf-8", { fatal: !1 }).decode(r.subarray(e.start, e.end)) : a === 2 && (l = o(r, e.start, e.end));
173
+ a === 1 ? c = new TextDecoder("utf-8", { fatal: !1 }).decode(r.subarray(e.start, e.end)) : a === 2 && (u = l(r, e.start, e.end));
120
174
  continue;
121
175
  }
122
- if (!t(s, u)) return null;
176
+ if (!t(s, o)) return null;
123
177
  }
124
- return c === null || l === null ? null : [c, l];
178
+ return c === null ? null : {
179
+ name: c,
180
+ ...u
181
+ };
125
182
  }
126
- function c(r) {
183
+ function d(r) {
127
184
  let i = r instanceof Uint8Array ? r : new Uint8Array(r), a = {
128
185
  bytes: i,
129
186
  end: i.length,
130
187
  pos: 0
131
- }, o = {};
188
+ }, o = [], s = [];
132
189
  for (; a.pos < a.end;) {
133
190
  let r = e(a);
134
191
  if (r === null) break;
@@ -145,11 +202,11 @@ function c(r) {
145
202
  let r = e(c);
146
203
  if (r === null) break;
147
204
  let a = r >>> 3, l = r & 7;
148
- if (a === 11 && l === 2) {
205
+ if ((a === 11 || a === 12) && l === 2) {
149
206
  let e = n(c);
150
207
  if (e === null) break;
151
- let t = s(i, e.start, e.end);
152
- t && (o[t[0]] = t[1]);
208
+ let t = u(i, e.start, e.end);
209
+ t && (a === 11 ? o : s).push(t);
153
210
  continue;
154
211
  }
155
212
  if (!t(c, l)) break;
@@ -158,12 +215,27 @@ function c(r) {
158
215
  }
159
216
  if (!t(a, l)) break;
160
217
  }
161
- return o;
218
+ return {
219
+ inputs: o,
220
+ outputs: s
221
+ };
222
+ }
223
+ function f(e) {
224
+ let t = {};
225
+ for (let n of d(e).inputs) n.elemType !== null && (t[n.name] = n.elemType);
226
+ return t;
227
+ }
228
+ function p(e) {
229
+ let { inputs: t, outputs: n } = d(e);
230
+ return {
231
+ inputs: Object.fromEntries(t.map((e) => [e.name, e.shape])),
232
+ outputs: Object.fromEntries(n.map((e) => [e.name, e.shape]))
233
+ };
162
234
  }
163
- function l(e) {
164
- return u(e?.names);
235
+ function m(e) {
236
+ return h(e?.names);
165
237
  }
166
- function u(e) {
238
+ function h(e) {
167
239
  let t = e?.trim();
168
240
  if (!t || !t.startsWith("{") || !t.endsWith("}")) return null;
169
241
  let n = t.slice(1, -1).trim();
@@ -172,7 +244,7 @@ function u(e) {
172
244
  for (let e of n.matchAll(i)) {
173
245
  let t = Number(e[1]), n = e[2] ?? e[3];
174
246
  if (!Number.isInteger(t) || n === void 0) return null;
175
- r.set(t, d(n)), a += e[0].length;
247
+ r.set(t, g(n)), a += e[0].length;
176
248
  }
177
249
  if (r.size === 0 || n.length - a > r.size * 3) return null;
178
250
  let o = [];
@@ -183,10 +255,10 @@ function u(e) {
183
255
  }
184
256
  return o;
185
257
  }
186
- function d(e) {
258
+ function g(e) {
187
259
  return e.replace(/\\(.)/g, (e, t) => t === "n" ? "\n" : t === "r" ? "\r" : t === "t" ? " " : t);
188
260
  }
189
261
  //#endregion
190
- export { l as modelNames, u as parseNames, c as readModelInputTypes, i as readModelMetadata };
262
+ export { m as modelNames, h as parseNames, f as readModelInputTypes, i as readModelMetadata, p as readModelShapes };
191
263
 
192
264
  //# sourceMappingURL=metadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.js","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field number of `graph` in `ModelProto` (GraphProto). */\nconst MODEL_GRAPH_FIELD = 7;\n\n/** Field number of `input` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_INPUT_FIELD = 11;\n\n/** Field numbers of `name` and `type` in `ValueInfoProto`. */\nconst VALUE_INFO_NAME_FIELD = 1;\nconst VALUE_INFO_TYPE_FIELD = 2;\n\n/** Field number of `tensor_type` in `TypeProto` (TypeProto.Tensor). */\nconst TYPE_TENSOR_FIELD = 1;\n\n/** Field number of `elem_type` in `TypeProto.Tensor` (a `TensorProto.DataType`). */\nconst TENSOR_ELEM_TYPE_FIELD = 1;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n *\n * It applies to leaf fields being read *out* of the file, not to the messages\n * walked *through* to reach them. The `graph` of a real export is the file: 21.79\n * MB on a reported YOLO detector. Applying this ceiling there made the reader\n * give up on every model anyone would actually load, and give up silently.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @param maxBytes Largest payload to accept, defaulting to\n * {@link MAX_FIELD_BYTES}. Pass the buffer length when descending into a\n * message whose size is the file's size rather than a leaf value's.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds `maxBytes`.\n */\nfunction readLengthDelimited(\n cursor: Cursor,\n maxBytes: number = MAX_FIELD_BYTES,\n): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > maxBytes) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/**\n * Read the element type of a `TypeProto.Tensor` message.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` when the message\n * carries none or cannot be walked.\n */\nfunction readTensorElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n return readVarint(cursor);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read the element type out of a `TypeProto`, which wraps the tensor type.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The `TensorProto.DataType` value, or `null` for a non-tensor type\n * (sequence, map, optional) or an unreadable message.\n */\nfunction readTypeElemType(bytes: Uint8Array, start: number, end: number): number | null {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TYPE_TENSOR_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n return readTensorElemType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read one `ValueInfoProto` into a name/element-type pair.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The pair, or `null` when either half is missing or unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, number] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let elemType: number | null = null;\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n if (field === VALUE_INFO_NAME_FIELD) {\n name = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n bytes.subarray(range.start, range.end),\n );\n } else if (field === VALUE_INFO_TYPE_FIELD) {\n elemType = readTypeElemType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null || elemType === null) return null;\n return [name, elemType];\n}\n\n/**\n * Read the element type each graph input declares.\n *\n * `onnxruntime-web` does not expose this. `session.inputMetadata` is\n * `undefined` on 1.20.1 — the same version where `declaredShapesFrom` comes\n * back empty — so the declared types have to come from the file, which the SDK\n * already downloads and walks for {@link readModelMetadata}. Same bytes, one\n * more pass, no extra request.\n *\n * @param model The `.onnx` file contents.\n * @returns Input name → `TensorProto.DataType` value. An empty object when the\n * file carries no readable graph, which every caller treats as \"assume\n * float32\" — the behaviour before any of this existed.\n */\nexport function readModelInputTypes(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, number>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const types: Record<string, number> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_GRAPH_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const graph = readLengthDelimited(cursor, bytes.length);\n if (graph === null) break;\n const inner: Cursor = { bytes, end: graph.end, pos: graph.start };\n while (inner.pos < inner.end) {\n const innerTag = readVarint(inner);\n if (innerTag === null) break;\n const innerField = innerTag >>> 3;\n const innerWire = innerTag & 0x07;\n if (innerField === GRAPH_INPUT_FIELD && innerWire === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) types[info[0]] = info[1];\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return types;\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"metadata.js","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Read the metadata an exporter baked into a `.onnx` file.\n *\n * `onnxruntime-web` exposes input/output metadata but **not** the model's\n * custom metadata map, which is where Ultralytics writes `names`, `task` and\n * `imgsz`. The Python SDK gets it for free from\n * `InferenceSession.get_modelmeta().custom_metadata_map`; in the browser the\n * only way to the same information is to read it out of the file, so this\n * module walks just enough of the ModelProto wire format to collect\n * `metadata_props`.\n *\n * It never throws and never allocates unbounded: a truncated, hostile or\n * simply unexpected file yields an empty map, and every caller treats that as\n * \"the model says nothing\", falling back to what it was given.\n */\n\nimport type { DeclaredDim, DeclaredShape } from \"./graph\";\n\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\n\n/** Field number of `graph` in `ModelProto` (GraphProto). */\nconst MODEL_GRAPH_FIELD = 7;\n\n/** Field number of `input` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_INPUT_FIELD = 11;\n\n/** Field number of `output` in `GraphProto` (repeated ValueInfoProto). */\nconst GRAPH_OUTPUT_FIELD = 12;\n\n/** Field numbers of `name` and `type` in `ValueInfoProto`. */\nconst VALUE_INFO_NAME_FIELD = 1;\nconst VALUE_INFO_TYPE_FIELD = 2;\n\n/** Field number of `tensor_type` in `TypeProto` (TypeProto.Tensor). */\nconst TYPE_TENSOR_FIELD = 1;\n\n/** Field number of `elem_type` in `TypeProto.Tensor` (a `TensorProto.DataType`). */\nconst TENSOR_ELEM_TYPE_FIELD = 1;\n\n/** Field number of `shape` in `TypeProto.Tensor` (TensorShapeProto). */\nconst TENSOR_SHAPE_FIELD = 2;\n\n/** Field number of `dim` in `TensorShapeProto` (repeated Dimension). */\nconst SHAPE_DIM_FIELD = 1;\n\n/** Field number of `dim_value` in `TensorShapeProto.Dimension` (int64). */\nconst DIM_VALUE_FIELD = 1;\n\n/** Field numbers of `key` and `value` in `StringStringEntryProto`. */\nconst ENTRY_KEY_FIELD = 1;\nconst ENTRY_VALUE_FIELD = 2;\n\n/** Protobuf wire types this reader understands. */\nconst WIRE_VARINT = 0;\nconst WIRE_FIXED64 = 1;\nconst WIRE_LENGTH_DELIMITED = 2;\nconst WIRE_FIXED32 = 5;\n\n/**\n * Hard ceiling on a single length-delimited field, as a guard against a corrupt\n * length turning into a huge slice. Model metadata values are strings — a class\n * name map for thousands of classes still fits well inside this.\n *\n * It applies to leaf fields being read *out* of the file, not to the messages\n * walked *through* to reach them. The `graph` of a real export is the file: 21.79\n * MB on a reported YOLO detector. Applying this ceiling there made the reader\n * give up on every model anyone would actually load, and give up silently.\n */\nconst MAX_FIELD_BYTES = 1 << 20;\n\n/** A cursor over a byte range, tracking its own position. */\ninterface Cursor {\n readonly bytes: Uint8Array;\n readonly end: number;\n pos: number;\n}\n\n/**\n * Read a base-128 varint.\n *\n * @param cursor Cursor to advance.\n * @returns The value, or `null` when the varint is truncated or overlong\n * (beyond the 64-bit range protobuf allows).\n */\nfunction readVarint(cursor: Cursor): number | null {\n let result = 0;\n let shift = 0;\n while (cursor.pos < cursor.end) {\n const byte = cursor.bytes[cursor.pos]!;\n cursor.pos += 1;\n result += (byte & 0x7f) * 2 ** shift;\n if ((byte & 0x80) === 0) return result;\n shift += 7;\n if (shift > 63) return null;\n }\n return null;\n}\n\n/**\n * Skip a field whose contents are not needed.\n *\n * @param cursor Cursor to advance past the field's payload.\n * @param wireType Wire type read from the field's tag.\n * @returns `true` when the field was skipped, `false` when the stream is\n * unreadable from here (unknown wire type or truncated payload).\n */\nfunction skipField(cursor: Cursor, wireType: number): boolean {\n switch (wireType) {\n case WIRE_VARINT:\n return readVarint(cursor) !== null;\n case WIRE_FIXED64:\n cursor.pos += 8;\n return cursor.pos <= cursor.end;\n case WIRE_LENGTH_DELIMITED: {\n const length = readVarint(cursor);\n if (length === null) return false;\n cursor.pos += length;\n return cursor.pos <= cursor.end;\n }\n case WIRE_FIXED32:\n cursor.pos += 4;\n return cursor.pos <= cursor.end;\n default:\n return false;\n }\n}\n\n/**\n * Read a length-delimited payload as a byte range.\n *\n * @param cursor Cursor to advance past the payload.\n * @param maxBytes Largest payload to accept, defaulting to\n * {@link MAX_FIELD_BYTES}. Pass the buffer length when descending into a\n * message whose size is the file's size rather than a leaf value's.\n * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds `maxBytes`.\n */\nfunction readLengthDelimited(\n cursor: Cursor,\n maxBytes: number = MAX_FIELD_BYTES,\n): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > maxBytes) return null;\n const start = cursor.pos;\n const end = start + length;\n if (end > cursor.end) return null;\n cursor.pos = end;\n return { start, end };\n}\n\n/**\n * Decode one `StringStringEntryProto` into a key/value pair.\n *\n * @param bytes The model buffer.\n * @param start Offset the entry's payload starts at.\n * @param end Offset the entry's payload ends at.\n * @returns The pair, or `null` when either half is missing or undecodable.\n */\nfunction readEntry(\n bytes: Uint8Array,\n start: number,\n end: number,\n): readonly [string, string] | null {\n const cursor: Cursor = { bytes, end, pos: start };\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let key: string | null = null;\n let value: string | null = null;\n\n while (cursor.pos < end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (\n wireType === WIRE_LENGTH_DELIMITED &&\n (field === ENTRY_KEY_FIELD || field === ENTRY_VALUE_FIELD)\n ) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n const text = decoder.decode(bytes.subarray(range.start, range.end));\n if (field === ENTRY_KEY_FIELD) key = text;\n else value = text;\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n\n if (key === null || value === null) return null;\n return [key, value];\n}\n\n/**\n * Collect a model's custom metadata map straight out of its bytes.\n *\n * @param model The `.onnx` file contents.\n * @returns Key/value metadata — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export — or an empty object when the file carries none or\n * cannot be walked.\n */\nexport function readModelMetadata(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, string>> {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const metadata: Record<string, string> = {};\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_METADATA_PROPS_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n const entry = readEntry(bytes, range.start, range.end);\n if (entry) metadata[entry[0]] = entry[1];\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return metadata;\n}\n\n/** What a graph value declares about itself: its element type and its shape. */\ninterface DeclaredTensor {\n readonly elemType: number | null;\n readonly shape: DeclaredShape;\n}\n\n/** A graph value with nothing readable declared. */\nconst UNDECLARED: DeclaredTensor = { elemType: null, shape: [] };\n\n/**\n * Read one `TensorShapeProto.Dimension`.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The size when the graph pins it to a positive integer, `null` for a\n * symbolic (`dim_param`) or absent one — the same convention as\n * `declaredShapesFrom`, so both sources read alike downstream.\n */\nfunction readDimension(bytes: Uint8Array, start: number, end: number): DeclaredDim {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === DIM_VALUE_FIELD && wireType === WIRE_VARINT) {\n const value = readVarint(cursor);\n return value !== null && Number.isSafeInteger(value) && value > 0 ? value : null;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n return null;\n}\n\n/**\n * Read a `TensorShapeProto` into a declared shape.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns One entry per dimension, or an empty shape when the message cannot\n * be walked — a half-read shape would claim the wrong rank.\n */\nfunction readShape(bytes: Uint8Array, start: number, end: number): DeclaredShape {\n const cursor: Cursor = { bytes, end, pos: start };\n const dims: DeclaredDim[] = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return [];\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === SHAPE_DIM_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return [];\n dims.push(readDimension(bytes, range.start, range.end));\n continue;\n }\n if (!skipField(cursor, wireType)) return [];\n }\n return dims;\n}\n\n/**\n * Read a `TypeProto.Tensor` message.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns Its element type and shape; either is left undeclared when the\n * message carries none or cannot be walked.\n */\nfunction readTensorType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n let elemType: number | null = null;\n let shape: DeclaredShape = [];\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TENSOR_ELEM_TYPE_FIELD && wireType === WIRE_VARINT) {\n elemType = readVarint(cursor);\n continue;\n }\n if (field === TENSOR_SHAPE_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) break;\n shape = readShape(bytes, range.start, range.end);\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n return { elemType, shape };\n}\n\n/**\n * Read a `TypeProto`, which wraps the tensor type.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The tensor's declarations, or {@link UNDECLARED} for a non-tensor\n * type (sequence, map, optional) or an unreadable message.\n */\nfunction readType(bytes: Uint8Array, start: number, end: number): DeclaredTensor {\n const cursor: Cursor = { bytes, end, pos: start };\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return UNDECLARED;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === TYPE_TENSOR_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return UNDECLARED;\n return readTensorType(bytes, range.start, range.end);\n }\n if (!skipField(cursor, wireType)) return UNDECLARED;\n }\n return UNDECLARED;\n}\n\n/**\n * Read one `ValueInfoProto`.\n *\n * @param bytes The whole model buffer.\n * @param start Offset of the message's first byte.\n * @param end Offset one past its last byte.\n * @returns The value's name and declarations, or `null` when the name is\n * missing or the message is unreadable.\n */\nfunction readValueInfo(\n bytes: Uint8Array,\n start: number,\n end: number,\n): (DeclaredTensor & { readonly name: string }) | null {\n const cursor: Cursor = { bytes, end, pos: start };\n let name: string | null = null;\n let declared: DeclaredTensor = UNDECLARED;\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) return null;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (wireType === WIRE_LENGTH_DELIMITED) {\n const range = readLengthDelimited(cursor);\n if (range === null) return null;\n if (field === VALUE_INFO_NAME_FIELD) {\n name = new TextDecoder(\"utf-8\", { fatal: false }).decode(\n bytes.subarray(range.start, range.end),\n );\n } else if (field === VALUE_INFO_TYPE_FIELD) {\n declared = readType(bytes, range.start, range.end);\n }\n continue;\n }\n if (!skipField(cursor, wireType)) return null;\n }\n if (name === null) return null;\n return { name, ...declared };\n}\n\n/** The graph's declared inputs and outputs, each in declaration order. */\ninterface GraphValues {\n readonly inputs: readonly (DeclaredTensor & { readonly name: string })[];\n readonly outputs: readonly (DeclaredTensor & { readonly name: string })[];\n}\n\n/**\n * Walk the `GraphProto` and collect what its inputs and outputs declare.\n *\n * @param model The `.onnx` file contents.\n * @returns Both lists, empty when the file carries no readable graph.\n */\nfunction readGraphValues(model: Uint8Array | ArrayBufferLike): GraphValues {\n const bytes = model instanceof Uint8Array ? model : new Uint8Array(model);\n const cursor: Cursor = { bytes, end: bytes.length, pos: 0 };\n const inputs: (DeclaredTensor & { readonly name: string })[] = [];\n const outputs: (DeclaredTensor & { readonly name: string })[] = [];\n\n while (cursor.pos < cursor.end) {\n const tag = readVarint(cursor);\n if (tag === null) break;\n const field = tag >>> 3;\n const wireType = tag & 0x07;\n if (field === MODEL_GRAPH_FIELD && wireType === WIRE_LENGTH_DELIMITED) {\n const graph = readLengthDelimited(cursor, bytes.length);\n if (graph === null) break;\n const inner: Cursor = { bytes, end: graph.end, pos: graph.start };\n while (inner.pos < inner.end) {\n const innerTag = readVarint(inner);\n if (innerTag === null) break;\n const innerField = innerTag >>> 3;\n const innerWire = innerTag & 0x07;\n if (\n (innerField === GRAPH_INPUT_FIELD || innerField === GRAPH_OUTPUT_FIELD) &&\n innerWire === WIRE_LENGTH_DELIMITED\n ) {\n const range = readLengthDelimited(inner);\n if (range === null) break;\n const info = readValueInfo(bytes, range.start, range.end);\n if (info) (innerField === GRAPH_INPUT_FIELD ? inputs : outputs).push(info);\n continue;\n }\n if (!skipField(inner, innerWire)) break;\n }\n continue;\n }\n if (!skipField(cursor, wireType)) break;\n }\n\n return { inputs, outputs };\n}\n\n/**\n * Read the element type each graph input declares.\n *\n * `onnxruntime-web` does not expose this. `session.inputMetadata` is\n * `undefined` on 1.20.1 — the same version where `declaredShapesFrom` comes\n * back empty — so the declared types have to come from the file, which the SDK\n * already downloads and walks for {@link readModelMetadata}. Same bytes, one\n * more pass, no extra request.\n *\n * @param model The `.onnx` file contents.\n * @returns Input name → `TensorProto.DataType` value. An empty object when the\n * file carries no readable graph, which every caller treats as \"assume\n * float32\" — the behaviour before any of this existed.\n */\nexport function readModelInputTypes(\n model: Uint8Array | ArrayBufferLike,\n): Readonly<Record<string, number>> {\n const types: Record<string, number> = {};\n for (const input of readGraphValues(model).inputs) {\n if (input.elemType !== null) types[input.name] = input.elemType;\n }\n return types;\n}\n\n/**\n * Read the shape each graph input and output declares, straight from the file.\n *\n * `onnxruntime-web` reports these through `inputMetadata` / `outputMetadata`\n * only from 1.22 on. Below that the session answers nothing, and a task that\n * reads its input size or class count off the session silently fell back to\n * its defaults: a 64x64 detector was fed 640x640 and ORT aborted with\n * `Got invalid dimensions for input` (measured on 1.17.3, 1.18.0, 1.19.2,\n * 1.20.1 and 1.21.0). The\n * file carries the same declarations, in the same `ValueInfoProto` the element\n * types are read from.\n *\n * Keyed by name rather than position: in an older IR the graph's `input` list\n * also carries the initializers, so its order does not line up with the\n * session's `inputNames`.\n *\n * @param model The `.onnx` file contents.\n * @returns Input and output name → shape, dynamic axes as `null`. Both maps\n * are empty when the file carries no readable graph.\n */\nexport function readModelShapes(model: Uint8Array | ArrayBufferLike): {\n readonly inputs: Readonly<Record<string, DeclaredShape>>;\n readonly outputs: Readonly<Record<string, DeclaredShape>>;\n} {\n const { inputs, outputs } = readGraphValues(model);\n return {\n inputs: Object.fromEntries(inputs.map((value) => [value.name, value.shape])),\n outputs: Object.fromEntries(outputs.map((value) => [value.name, value.shape])),\n };\n}\n\n/**\n * Read the class names an export baked into the model metadata.\n *\n * Ultralytics writes `names` as the Python `repr` of a `dict[int, str]` — e.g.\n * `\"{0: 'deworm', 1: 'not_deworm'}\"`. The value is parsed structurally (never\n * evaluated), and anything unparseable, non-`dict`, or not keyed by contiguous\n * integers from zero is rejected whole rather than half-applied: a partial name\n * map would silently mislabel predictions.\n *\n * @param metadata A model's custom metadata map.\n * @returns Class names in class-id order, or `null` when the model carries no\n * usable `names` entry.\n */\nexport function modelNames(\n metadata: Readonly<Record<string, string>> | undefined,\n): readonly string[] | null {\n return parseNames(metadata?.names);\n}\n\n/**\n * Parse a `repr`-encoded `dict[int, str]` class map.\n *\n * Split out of {@link modelNames} because the same encoding is reused by a\n * fused pipeline, which carries one class map per stage and therefore cannot\n * store both under the single `names` key Ultralytics uses.\n *\n * @param encoded The encoded map — e.g. `\"{0: 'deworm', 1: 'not_deworm'}\"`.\n * @returns Class names in class-id order, or `null` when the value is missing,\n * unparseable, not a `dict`, or not keyed by contiguous integers from zero.\n */\nexport function parseNames(encoded: string | undefined): readonly string[] | null {\n const raw = encoded?.trim();\n if (!raw || !raw.startsWith(\"{\") || !raw.endsWith(\"}\")) return null;\n\n const body = raw.slice(1, -1).trim();\n if (!body) return null;\n\n const names = new Map<number, string>();\n const entryPattern = /(-?\\d+)\\s*:\\s*(?:'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\")/g;\n let consumed = 0;\n for (const match of body.matchAll(entryPattern)) {\n const id = Number(match[1]);\n const text = match[2] ?? match[3];\n if (!Number.isInteger(id) || text === undefined) return null;\n names.set(id, unescapeQuoted(text));\n consumed += match[0].length;\n }\n if (names.size === 0) return null;\n\n const separators = body.length - consumed;\n if (separators > names.size * 3) return null;\n\n const ordered: string[] = [];\n for (let id = 0; id < names.size; id += 1) {\n const name = names.get(id);\n if (name === undefined) return null;\n ordered.push(name);\n }\n return ordered;\n}\n\n/**\n * Resolve the backslash escapes Python's `repr` emits inside a quoted string.\n *\n * @param text The quoted string's contents, escapes intact.\n * @returns The same text with `\\\\`, `\\'`, `\\\"`, `\\n`, `\\r` and `\\t` resolved.\n */\nfunction unescapeQuoted(text: string): string {\n return text.replace(/\\\\(.)/g, (_, char: string) => {\n if (char === \"n\") return \"\\n\";\n if (char === \"r\") return \"\\r\";\n if (char === \"t\") return \"\\t\";\n return char;\n });\n}\n"],"mappings":"AAsFA,SAAS,EAAW,GAA+B;CAC/C,IAAI,IAAS,GACT,IAAQ;CACZ,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAO,EAAO,MAAM,EAAO;EAGjC,IAFA,EAAO,OAAO,GACd,MAAW,IAAO,OAAQ,KAAK,GAC/B,EAAK,IAAO,MAAa,OAAO;EAEhC,IADA,KAAS,GACL,IAAQ,IAAI,OAAO;CAC3B;CACA,OAAO;AACX;AAUA,SAAS,EAAU,GAAgB,GAA2B;CAC1D,QAAQ,GAAR;EACI,KAAK,GACD,OAAO,EAAW,CAAM,MAAM;EAClC,KAAK,GAED,OADA,EAAO,OAAO,GACP,EAAO,OAAO,EAAO;EAChC,KAAK,GAAuB;GACxB,IAAM,IAAS,EAAW,CAAM;GAGhC,OAFI,MAAW,SACf,EAAO,OAAO,GACP,EAAO,OAAO,EAAO;EAChC;EACA,KAAK,GAED,OADA,EAAO,OAAO,GACP,EAAO,OAAO,EAAO;EAChC,SACI,OAAO;CACf;AACJ;AAYA,SAAS,EACL,GACA,IAAmB,SACkB;CACrC,IAAM,IAAS,EAAW,CAAM;CAChC,IAAI,MAAW,QAAQ,IAAS,GAAU,OAAO;CACjD,IAAM,IAAQ,EAAO,KACf,IAAM,IAAQ;CAGpB,OAFI,IAAM,EAAO,MAAY,QAC7B,EAAO,MAAM,GACN;EAAE;EAAO;CAAI;AACxB;AAUA,SAAS,EACL,GACA,GACA,GACgC;CAChC,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM,GAC1C,IAAU,IAAI,YAAY,SAAS,EAAE,OAAO,GAAM,CAAC,GACrD,IAAqB,MACrB,IAAuB;CAE3B,OAAO,EAAO,MAAM,IAAK;EACrB,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM,OAAO;EACzB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IACI,MAAa,MACZ,MAAU,KAAmB,MAAU,IAC1C;GACE,IAAM,IAAQ,EAAoB,CAAM;GACxC,IAAI,MAAU,MAAM,OAAO;GAC3B,IAAM,IAAO,EAAQ,OAAO,EAAM,SAAS,EAAM,OAAO,EAAM,GAAG,CAAC;GAClE,AAAI,MAAU,IAAiB,IAAM,IAChC,IAAQ;GACb;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG,OAAO;CAC7C;CAGA,OADI,MAAQ,QAAQ,MAAU,OAAa,OACpC,CAAC,GAAK,CAAK;AACtB;AAUA,SAAgB,EACZ,GACgC;CAChC,IAAM,IAAQ,aAAiB,aAAa,IAAQ,IAAI,WAAW,CAAK,GAClE,IAAiB;EAAE;EAAO,KAAK,EAAM;EAAQ,KAAK;CAAE,GACpD,IAAmC,CAAC;CAE1C,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM;EAClB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,MAA8B,MAAa,GAAuB;GAC5E,IAAM,IAAQ,EAAoB,CAAM;GACxC,IAAI,MAAU,MAAM;GACpB,IAAM,IAAQ,EAAU,GAAO,EAAM,OAAO,EAAM,GAAG;GACrD,AAAI,MAAO,EAAS,EAAM,MAAM,EAAM;GACtC;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG;CACtC;CAEA,OAAO;AACX;AASA,IAAM,IAA6B;CAAE,UAAU;CAAM,OAAO,CAAC;AAAE;AAY/D,SAAS,EAAc,GAAmB,GAAe,GAA0B;CAC/E,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM;CAChD,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM,OAAO;EACzB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,KAAmB,MAAa,GAAa;GACvD,IAAM,IAAQ,EAAW,CAAM;GAC/B,OAAO,MAAU,QAAQ,OAAO,cAAc,CAAK,KAAK,IAAQ,IAAI,IAAQ;EAChF;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG,OAAO;CAC7C;CACA,OAAO;AACX;AAWA,SAAS,EAAU,GAAmB,GAAe,GAA4B;CAC7E,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM,GAC1C,IAAsB,CAAC;CAC7B,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM,OAAO,CAAC;EAC1B,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,KAAmB,MAAa,GAAuB;GACjE,IAAM,IAAQ,EAAoB,CAAM;GACxC,IAAI,MAAU,MAAM,OAAO,CAAC;GAC5B,EAAK,KAAK,EAAc,GAAO,EAAM,OAAO,EAAM,GAAG,CAAC;GACtD;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG,OAAO,CAAC;CAC9C;CACA,OAAO;AACX;AAWA,SAAS,EAAe,GAAmB,GAAe,GAA6B;CACnF,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM,GAC5C,IAA0B,MAC1B,IAAuB,CAAC;CAC5B,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM;EAClB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,KAA0B,MAAa,GAAa;GAC9D,IAAW,EAAW,CAAM;GAC5B;EACJ;EACA,IAAI,MAAU,KAAsB,MAAa,GAAuB;GACpE,IAAM,IAAQ,EAAoB,CAAM;GACxC,IAAI,MAAU,MAAM;GACpB,IAAQ,EAAU,GAAO,EAAM,OAAO,EAAM,GAAG;GAC/C;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG;CACtC;CACA,OAAO;EAAE;EAAU;CAAM;AAC7B;AAWA,SAAS,EAAS,GAAmB,GAAe,GAA6B;CAC7E,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM;CAChD,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM,OAAO;EACzB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,KAAqB,MAAa,GAAuB;GACnE,IAAM,IAAQ,EAAoB,CAAM;GAExC,OADI,MAAU,OAAa,IACpB,EAAe,GAAO,EAAM,OAAO,EAAM,GAAG;EACvD;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG,OAAO;CAC7C;CACA,OAAO;AACX;AAWA,SAAS,EACL,GACA,GACA,GACmD;CACnD,IAAM,IAAiB;EAAE;EAAO;EAAK,KAAK;CAAM,GAC5C,IAAsB,MACtB,IAA2B;CAC/B,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM,OAAO;EACzB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAa,GAAuB;GACpC,IAAM,IAAQ,EAAoB,CAAM;GACxC,IAAI,MAAU,MAAM,OAAO;GAC3B,AAAI,MAAU,IACV,IAAO,IAAI,YAAY,SAAS,EAAE,OAAO,GAAM,CAAC,CAAC,CAAC,OAC9C,EAAM,SAAS,EAAM,OAAO,EAAM,GAAG,CACzC,IACO,MAAU,MACjB,IAAW,EAAS,GAAO,EAAM,OAAO,EAAM,GAAG;GAErD;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG,OAAO;CAC7C;CAEA,OADI,MAAS,OAAa,OACnB;EAAE;EAAM,GAAG;CAAS;AAC/B;AAcA,SAAS,EAAgB,GAAkD;CACvE,IAAM,IAAQ,aAAiB,aAAa,IAAQ,IAAI,WAAW,CAAK,GAClE,IAAiB;EAAE;EAAO,KAAK,EAAM;EAAQ,KAAK;CAAE,GACpD,IAAyD,CAAC,GAC1D,IAA0D,CAAC;CAEjE,OAAO,EAAO,MAAM,EAAO,MAAK;EAC5B,IAAM,IAAM,EAAW,CAAM;EAC7B,IAAI,MAAQ,MAAM;EAClB,IAAM,IAAQ,MAAQ,GAChB,IAAW,IAAM;EACvB,IAAI,MAAU,KAAqB,MAAa,GAAuB;GACnE,IAAM,IAAQ,EAAoB,GAAQ,EAAM,MAAM;GACtD,IAAI,MAAU,MAAM;GACpB,IAAM,IAAgB;IAAE;IAAO,KAAK,EAAM;IAAK,KAAK,EAAM;GAAM;GAChE,OAAO,EAAM,MAAM,EAAM,MAAK;IAC1B,IAAM,IAAW,EAAW,CAAK;IACjC,IAAI,MAAa,MAAM;IACvB,IAAM,IAAa,MAAa,GAC1B,IAAY,IAAW;IAC7B,KACK,MAAe,MAAqB,MAAe,OACpD,MAAc,GAChB;KACE,IAAM,IAAQ,EAAoB,CAAK;KACvC,IAAI,MAAU,MAAM;KACpB,IAAM,IAAO,EAAc,GAAO,EAAM,OAAO,EAAM,GAAG;KACxD,AAAI,MAAO,MAAe,KAAoB,IAAS,EAAA,CAAS,KAAK,CAAI;KACzE;IACJ;IACA,IAAI,CAAC,EAAU,GAAO,CAAS,GAAG;GACtC;GACA;EACJ;EACA,IAAI,CAAC,EAAU,GAAQ,CAAQ,GAAG;CACtC;CAEA,OAAO;EAAE;EAAQ;CAAQ;AAC7B;AAgBA,SAAgB,EACZ,GACgC;CAChC,IAAM,IAAgC,CAAC;CACvC,KAAK,IAAM,KAAS,EAAgB,CAAK,CAAC,CAAC,QACvC,AAAI,EAAM,aAAa,SAAM,EAAM,EAAM,QAAQ,EAAM;CAE3D,OAAO;AACX;AAsBA,SAAgB,EAAgB,GAG9B;CACE,IAAM,EAAE,WAAQ,eAAY,EAAgB,CAAK;CACjD,OAAO;EACH,QAAQ,OAAO,YAAY,EAAO,KAAK,MAAU,CAAC,EAAM,MAAM,EAAM,KAAK,CAAC,CAAC;EAC3E,SAAS,OAAO,YAAY,EAAQ,KAAK,MAAU,CAAC,EAAM,MAAM,EAAM,KAAK,CAAC,CAAC;CACjF;AACJ;AAeA,SAAgB,EACZ,GACwB;CACxB,OAAO,EAAW,GAAU,KAAK;AACrC;AAaA,SAAgB,EAAW,GAAuD;CAC9E,IAAM,IAAM,GAAS,KAAK;CAC1B,IAAI,CAAC,KAAO,CAAC,EAAI,WAAW,GAAG,KAAK,CAAC,EAAI,SAAS,GAAG,GAAG,OAAO;CAE/D,IAAM,IAAO,EAAI,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;CACnC,IAAI,CAAC,GAAM,OAAO;CAElB,IAAM,oBAAQ,IAAI,IAAoB,GAChC,IAAe,8DACjB,IAAW;CACf,KAAK,IAAM,KAAS,EAAK,SAAS,CAAY,GAAG;EAC7C,IAAM,IAAK,OAAO,EAAM,EAAE,GACpB,IAAO,EAAM,MAAM,EAAM;EAC/B,IAAI,CAAC,OAAO,UAAU,CAAE,KAAK,MAAS,KAAA,GAAW,OAAO;EAExD,AADA,EAAM,IAAI,GAAI,EAAe,CAAI,CAAC,GAClC,KAAY,EAAM,EAAE,CAAC;CACzB;CAIA,IAHI,EAAM,SAAS,KAEA,EAAK,SAAS,IAChB,EAAM,OAAO,GAAG,OAAO;CAExC,IAAM,IAAoB,CAAC;CAC3B,KAAK,IAAI,IAAK,GAAG,IAAK,EAAM,MAAM,KAAM,GAAG;EACvC,IAAM,IAAO,EAAM,IAAI,CAAE;EACzB,IAAI,MAAS,KAAA,GAAW,OAAO;EAC/B,EAAQ,KAAK,CAAI;CACrB;CACA,OAAO;AACX;AAQA,SAAS,EAAe,GAAsB;CAC1C,OAAO,EAAK,QAAQ,WAAW,GAAG,MAC1B,MAAS,MAAY,OACrB,MAAS,MAAY,OACrB,MAAS,MAAY,MAClB,CACV;AACL"}
@@ -1,2 +1,2 @@
1
- const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./exceptions.cjs"),n=require("./dtypes.cjs"),r=require("./graph.cjs"),i=require("./metadata.cjs"),a=require("./providers.cjs");let o=require("onnxruntime-web");o=e.__toESM(o,1);var s=`ort_vision_sdk.graph_optimization`,c=`CAcSDm9ydC12aXNpb24tc2RrOjoKEAoBeBIBeSIISWRlbnRpdHkSBHdhcm1aDwoBeBIKCggIARIECgIIAWIPCgF5EgoKCAgBEgQKAggBQgQKABAN`,l=new Map;function u(e){let t=e.map(a.providerName).join(`,`),n=l.get(t);return n===void 0&&(n=(async()=>{try{let t=Uint8Array.from(atob(c),e=>e.charCodeAt(0));await(await o.InferenceSession.create(t,{executionProviders:e})).release()}catch{return}})(),l.set(t,n)),n}function d(){console.warn(`[@ort-vision-sdk/web] This model was pre-optimized by optimize_model, which targets the WASM backend; on WebGPU some of its fused nodes fall back to the CPU. For WebGPU, ship the original export instead.`)}var f=`ort_vision_sdk.quantization`;function p(e,t){if(t[`ort_vision_sdk.quantization`]===void 0)return[...e];let n=e.filter(e=>a.providerName(e)!==`webgpu`);return n.length===e.length?n:(console.warn(`[@ort-vision-sdk/web] This model was quantized by quantize_model (${t[f]}); ONNX Runtime Web's WebGPU backend cannot run its quantized operators, so it runs on WASM.`),n.length>0?n:[a.FALLBACK_PROVIDER])}var m=`ort-vision-sdk-models`;async function h(e,t){let n=t===null?null:await _(t);if(n!==null){let t=await n.match(e).catch(()=>void 0);if(t!==void 0)return new Uint8Array(await t.arrayBuffer())}try{let t=await fetch(e);if(!t.ok)return v(e,`HTTP ${t.status} ${t.statusText}`),e;let r=await t.arrayBuffer();return n!==null&&await g(n,e,r),new Uint8Array(r)}catch(t){return v(e,t.message),e}}async function g(e,t,n){try{await e.put(t,new Response(n))}catch{return}}async function _(e){if(typeof caches>`u`)return null;try{return await caches.open(e)}catch{return null}}function v(e,t){console.warn(`[@ort-vision-sdk/web] Could not fetch ${e} to read its metadata (${t}). Letting ONNX Runtime load it instead: the model will work, but its baked-in class names are unavailable, so labels fall back to class_0, class_1, ... Pass \`labels\` explicitly to name them.`)}function y(e,t){let n=e.filter(e=>!t.includes(e));n.length!==0&&console.warn(`This browser cannot offer the requested execution provider(s) ${JSON.stringify(n)}; the session will run on ${JSON.stringify(t)}. Inference still produces correct results, on the fallback provider.`)}function b(e){let t=i.readModelInputTypes(e),r={};for(let[e,i]of Object.entries(t))r[e]=n.tensorTypeFor(i);return r}function x(){console.warn(`Could not read any input type from this model's bytes; feeds will be built as float32. A half-precision model will fail at inference with 'Unexpected input data type'. Please report this with the model that produced it.`)}function S(e){let r=Object.entries(e).filter(([,e])=>e===`float16`);if(r.length===0||n.hasFloat16Array())return;let i=r.map(([e])=>e).join(`, `);throw new t.ModelLoadError(`This model declares half-precision input(s) [${i}], but this environment has no Float16Array, which ONNX Runtime requires for a float16 tensor. Use a float32 export of the model, or run in a browser that supports Float16Array.`)}var C=class e{_session;providers;_metadata;requestedProviders;_inputTypes;constructor(e,t,n,r,i={}){this._session=e,this.providers=t,this._metadata=n,this.requestedProviders=r,this._inputTypes=i}_runQueue=Promise.resolve();static async create(n,r={}){let s=a.resolveProviders(r.providers),c=r.readMetadata!==!1,l=r.cache===!0?m:r.cache?r.cache:null,f=typeof n==`string`&&(c||l!==null),g=a.detectProviders(s).then(e=>e.length>0?e:[a.FALLBACK_PROVIDER]),[_,v]=await Promise.all([g,f?h(n,l):Promise.resolve(n),f?g.then(u):Promise.resolve()]),C=c&&typeof v!=`string`?i.readModelMetadata(v):{},w=p(_,C),T=s.map(a.providerName),E=w.map(a.providerName);r.providers!==void 0&&r.providers.length>0&&y(T,_.map(a.providerName)),C[`ort_vision_sdk.graph_optimization`]!==void 0&&E.includes(`webgpu`)&&d();let D={...C[`ort_vision_sdk.graph_optimization`]!==void 0&&r.sessionOptions?.graphOptimizationLevel===void 0?{graphOptimizationLevel:`disabled`}:{},...r.sessionOptions??{},executionProviders:w},O=typeof v==`string`?{}:b(v);typeof v!=`string`&&Object.keys(O).length===0&&x(),S(O);let k;try{k=(typeof v==`string`||v instanceof Uint8Array,await o.InferenceSession.create(v,D))}catch(e){throw new t.ModelLoadError(`Failed to load ONNX model: ${e.message}`,{cause:e})}return new e(k,E,C,T,O)}get inputDtypes(){return this.inputNames.map(e=>this._inputTypes[e]??`float32`)}get inputDtype(){return this._inputTypes[this.inputName]??`float32`}get inputNames(){return this._session.inputNames}get inputName(){let e=this._session.inputNames[0];if(e===void 0)throw new t.InferenceError(`Model has no inputs.`);return e}get outputNames(){return this._session.outputNames}get inputShapes(){return r.declaredShapesFrom(this._session.inputMetadata)}get inputShape(){return this.inputShapes[0]??[]}get outputShapes(){return r.declaredShapesFrom(this._session.outputMetadata)}get outputShape(){return this.outputShapes[0]??[]}get metadata(){return this._metadata}async release(){await this._session.release().catch(()=>void 0)}get raw(){return this._session}run(e){let t=this._runQueue.then(()=>this._runNow(e));return this._runQueue=t.catch(()=>void 0),t}async _runNow(e){try{return await this._session.run(this._asDeclaredTypes(e))}catch(e){throw new t.InferenceError(`Inference failed: ${e.message}`,{cause:e})}}_asDeclaredTypes(e){let t=null;for(let[r,i]of Object.entries(e)){let a=this._inputTypes[r];if(a===void 0||a===i.type||!(i.data instanceof Float32Array))continue;let s=n.toFeedData(i.data,a);s!==i.data&&(t??={...e},t[r]=new o.Tensor(a,s,i.dims))}return t??e}};exports.DEFAULT_MODEL_CACHE=m,exports.GRAPH_OPTIMIZATION_KEY=s,exports.OrtSession=C,exports.QUANTIZATION_KEY=f;
1
+ const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./exceptions.cjs"),n=require("./dtypes.cjs"),r=require("./graph.cjs"),i=require("./metadata.cjs"),a=require("./providers.cjs");let o=require("onnxruntime-web");o=e.__toESM(o,1);var s=`ort_vision_sdk.graph_optimization`,c=`CAcSDm9ydC12aXNpb24tc2RrOjoKEAoBeBIBeSIISWRlbnRpdHkSBHdhcm1aDwoBeBIKCggIARIECgIIAWIPCgF5EgoKCAgBEgQKAggBQgQKABAN`,l=new Map;function u(e){let t=e.map(a.providerName).join(`,`),n=l.get(t);return n===void 0&&(n=(async()=>{try{let t=Uint8Array.from(atob(c),e=>e.charCodeAt(0));await(await o.InferenceSession.create(t,{executionProviders:e})).release()}catch{return}})(),l.set(t,n)),n}function d(){console.warn(`[@ort-vision-sdk/web] This model was pre-optimized by optimize_model, which targets the WASM backend; on WebGPU some of its fused nodes fall back to the CPU. For WebGPU, ship the original export instead.`)}var f=`ort_vision_sdk.quantization`;function p(e,t){if(t[`ort_vision_sdk.quantization`]===void 0)return[...e];let n=e.filter(e=>a.providerName(e)!==`webgpu`);return n.length===e.length?n:(console.warn(`[@ort-vision-sdk/web] This model was quantized by quantize_model (${t[f]}); ONNX Runtime Web's WebGPU backend cannot run its quantized operators, so it runs on WASM.`),n.length>0?n:[a.FALLBACK_PROVIDER])}var m=`ort-vision-sdk-models`;async function h(e,t){let n=t===null?null:await _(t);if(n!==null){let t=await n.match(e).catch(()=>void 0);if(t!==void 0)return new Uint8Array(await t.arrayBuffer())}try{let t=await fetch(e);if(!t.ok)return v(e,`HTTP ${t.status} ${t.statusText}`),e;let r=await t.arrayBuffer();return n!==null&&await g(n,e,r),new Uint8Array(r)}catch(t){return v(e,t.message),e}}async function g(e,t,n){try{await e.put(t,new Response(n))}catch{return}}async function _(e){if(typeof caches>`u`)return null;try{return await caches.open(e)}catch{return null}}function v(e,t){console.warn(`[@ort-vision-sdk/web] Could not fetch ${e} to read its metadata (${t}). Letting ONNX Runtime load it instead: the model will work, but its baked-in class names are unavailable, so labels fall back to class_0, class_1, ... Pass \`labels\` explicitly to name them.`)}function y(e,t){let n=e.filter(e=>!t.includes(e));n.length!==0&&console.warn(`This browser cannot offer the requested execution provider(s) ${JSON.stringify(n)}; the session will run on ${JSON.stringify(t)}. Inference still produces correct results, on the fallback provider.`)}function b(e){let t=i.readModelInputTypes(e),r={};for(let[e,i]of Object.entries(t))r[e]=n.tensorTypeFor(i);return r}function x(){console.warn(`Could not read any input type from this model's bytes; feeds will be built as float32. A half-precision model will fail at inference with 'Unexpected input data type'. Please report this with the model that produced it.`)}function S(e){let r=Object.entries(e).filter(([,e])=>e===`float16`);if(r.length===0||n.hasFloat16Array())return;let i=r.map(([e])=>e).join(`, `);throw new t.ModelLoadError(`This model declares half-precision input(s) [${i}], but this environment has no Float16Array, which ONNX Runtime requires for a float16 tensor. Use a float32 export of the model, or run in a browser that supports Float16Array.`)}var C=class e{_session;providers;_metadata;requestedProviders;_inputTypes;_fileShapes;constructor(e,t,n,r,i={},a={inputs:{},outputs:{}}){this._session=e,this.providers=t,this._metadata=n,this.requestedProviders=r,this._inputTypes=i,this._fileShapes=a}_runQueue=Promise.resolve();static async create(n,r={}){let s=a.resolveProviders(r.providers),c=r.readMetadata!==!1,l=r.cache===!0?m:r.cache?r.cache:null,f=typeof n==`string`&&(c||l!==null),g=a.detectProviders(s).then(e=>e.length>0?e:[a.FALLBACK_PROVIDER]),[_,v]=await Promise.all([g,f?h(n,l):Promise.resolve(n),f?g.then(u):Promise.resolve()]),C=c&&typeof v!=`string`?i.readModelMetadata(v):{},w=p(_,C),T=s.map(a.providerName),E=w.map(a.providerName);r.providers!==void 0&&r.providers.length>0&&y(T,_.map(a.providerName)),C[`ort_vision_sdk.graph_optimization`]!==void 0&&E.includes(`webgpu`)&&d();let D={...C[`ort_vision_sdk.graph_optimization`]!==void 0&&r.sessionOptions?.graphOptimizationLevel===void 0?{graphOptimizationLevel:`disabled`}:{},...r.sessionOptions??{},executionProviders:w},O=typeof v==`string`?{}:b(v),k=typeof v==`string`?{inputs:{},outputs:{}}:i.readModelShapes(v);typeof v!=`string`&&Object.keys(O).length===0&&x(),S(O);let A;try{A=(typeof v==`string`||v instanceof Uint8Array,await o.InferenceSession.create(v,D))}catch(e){throw new t.ModelLoadError(`Failed to load ONNX model: ${e.message}`,{cause:e})}return new e(A,E,C,T,O,k)}get inputDtypes(){return this.inputNames.map(e=>this._inputTypes[e]??`float32`)}get inputDtype(){return this._inputTypes[this.inputName]??`float32`}get inputNames(){return this._session.inputNames}get inputName(){let e=this._session.inputNames[0];if(e===void 0)throw new t.InferenceError(`Model has no inputs.`);return e}get outputNames(){return this._session.outputNames}get inputShapes(){return this._shapesOf(this._session.inputMetadata,this._session.inputNames,this._fileShapes.inputs)}get inputShape(){return this.inputShapes[0]??[]}get outputShapes(){return this._shapesOf(this._session.outputMetadata,this._session.outputNames,this._fileShapes.outputs)}_shapesOf(e,t,n){let i=r.declaredShapesFrom(e);return i.length>0?i:t.map(e=>n[e]??[])}get outputShape(){return this.outputShapes[0]??[]}get metadata(){return this._metadata}async release(){await this._session.release().catch(()=>void 0)}get raw(){return this._session}run(e){let t=this._runQueue.then(()=>this._runNow(e));return this._runQueue=t.catch(()=>void 0),t}async _runNow(e){try{return await this._session.run(this._asDeclaredTypes(e))}catch(e){throw new t.InferenceError(`Inference failed: ${e.message}`,{cause:e})}}_asDeclaredTypes(e){let t=null;for(let[r,i]of Object.entries(e)){let a=this._inputTypes[r];if(a===void 0||a===i.type||!(i.data instanceof Float32Array))continue;let s=n.toFeedData(i.data,a);s!==i.data&&(t??={...e},t[r]=new o.Tensor(a,s,i.dims))}return t??e}};exports.DEFAULT_MODEL_CACHE=m,exports.GRAPH_OPTIMIZATION_KEY=s,exports.OrtSession=C,exports.QUANTIZATION_KEY=f;
2
2
  //# sourceMappingURL=session.cjs.map