tempest-react-sdk 0.38.2 → 0.38.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/lib/design/collect.mjs +19 -0
- package/bin/lib/design/functions.mjs +5 -0
- package/bin/lib/design/index.mjs +8 -3
- package/bin/lib/design/index.test.mjs +31 -0
- package/bin/lib/design/scan.mjs +34 -2
- package/bin/lib/design/scan.test.mjs +78 -0
- package/bin/lib/doctor/doctor.e2e.test.mjs +85 -0
- package/bin/tempest.mjs +90 -6
- package/dist/audio/level-meter.cjs.map +1 -1
- package/dist/audio/level-meter.js.map +1 -1
- package/dist/audio/use-audio-recorder.cjs.map +1 -1
- package/dist/audio/use-audio-recorder.js.map +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js.map +1 -1
- package/dist/auth/use-passkey.cjs.map +1 -1
- package/dist/auth/use-passkey.js.map +1 -1
- package/dist/br/BrazilMap.cjs.map +1 -1
- package/dist/br/BrazilMap.js.map +1 -1
- package/dist/br/BrazilStateCitySelect.cjs.map +1 -1
- package/dist/br/BrazilStateCitySelect.js.map +1 -1
- package/dist/br/BrazilStateMap.cjs.map +1 -1
- package/dist/br/BrazilStateMap.js.map +1 -1
- package/dist/br/PixQRCode.cjs.map +1 -1
- package/dist/br/PixQRCode.js.map +1 -1
- package/dist/br/boleto.cjs.map +1 -1
- package/dist/br/boleto.js.map +1 -1
- package/dist/br/pix.cjs.map +1 -1
- package/dist/br/pix.js.map +1 -1
- package/dist/br.d.ts +8 -0
- package/dist/capture/media-recorder.cjs.map +1 -1
- package/dist/capture/media-recorder.js.map +1 -1
- package/dist/capture/use-barcode-scanner.cjs.map +1 -1
- package/dist/capture/use-barcode-scanner.js.map +1 -1
- package/dist/capture/use-screen-capture.cjs.map +1 -1
- package/dist/capture/use-screen-capture.js.map +1 -1
- package/dist/capture/use-speech-recognition.cjs.map +1 -1
- package/dist/capture/use-speech-recognition.js.map +1 -1
- package/dist/capture/use-video-recorder.cjs.map +1 -1
- package/dist/capture/use-video-recorder.js.map +1 -1
- package/dist/charts/types.cjs.map +1 -1
- package/dist/charts/types.js.map +1 -1
- package/dist/charts.d.ts +8 -0
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
- package/dist/components/AIChat/AIChatComposer.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/AppBar/AppBar.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -1
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.cjs.map +1 -1
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Carousel/Carousel.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.js.map +1 -1
- package/dist/components/Chat/Chat.cjs.map +1 -1
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChipInput/ChipInput.cjs.map +1 -1
- package/dist/components/ChipInput/ChipInput.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/Combobox/Combobox.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Command/Command.cjs.map +1 -1
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/CopyButton/CopyButton.cjs.map +1 -1
- package/dist/components/CopyButton/CopyButton.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.module.js.map +1 -1
- package/dist/components/DataTable/EditableCell.cjs.map +1 -1
- package/dist/components/DataTable/EditableCell.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/Dropzone/Dropzone.cjs.map +1 -1
- package/dist/components/Dropzone/Dropzone.js.map +1 -1
- package/dist/components/FileUpload/FileUpload.cjs.map +1 -1
- package/dist/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/components/FilterBar/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar/FilterBar.js.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.js.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.cjs.map +1 -1
- package/dist/components/InstallBanner/InstallBanner.js.map +1 -1
- package/dist/components/Kanban/Kanban.cjs.map +1 -1
- package/dist/components/Kanban/Kanban.js.map +1 -1
- package/dist/components/Lightbox/Lightbox.cjs.map +1 -1
- package/dist/components/Lightbox/Lightbox.js.map +1 -1
- package/dist/components/ListTile/ListTile.cjs.map +1 -1
- package/dist/components/ListTile/ListTile.js.map +1 -1
- package/dist/components/Markdown/Markdown.cjs.map +1 -1
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Markdown/markdown-parse.cjs.map +1 -1
- package/dist/components/Markdown/markdown-parse.js.map +1 -1
- package/dist/components/Menubar/Menubar.cjs.map +1 -1
- package/dist/components/Menubar/Menubar.js.map +1 -1
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.cjs.map +1 -1
- package/dist/components/ModalsManager/ModalsManager.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.cjs.map +1 -1
- package/dist/components/NavigationMenu/NavigationMenu.js.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.cjs.map +1 -1
- package/dist/components/NotificationCenter/NotificationCenter.js.map +1 -1
- package/dist/components/Page/Page.cjs.map +1 -1
- package/dist/components/Page/Page.js.map +1 -1
- package/dist/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/dist/components/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/PinInput/PinInput.cjs.map +1 -1
- package/dist/components/PinInput/PinInput.js.map +1 -1
- package/dist/components/Popover/Popover.cjs.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Progress/Progress.cjs.map +1 -1
- package/dist/components/Progress/Progress.js.map +1 -1
- package/dist/components/QRCode/qr-encode.cjs.map +1 -1
- package/dist/components/QRCode/qr-encode.js.map +1 -1
- package/dist/components/Radio/Radio.cjs.map +1 -1
- package/dist/components/Radio/Radio.js.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/RatingStars/RatingStars.cjs.map +1 -1
- package/dist/components/RatingStars/RatingStars.js.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.cjs.map +1 -1
- package/dist/components/RefreshIndicator/RefreshIndicator.js.map +1 -1
- package/dist/components/Resizable/Resizable.cjs.map +1 -1
- package/dist/components/Resizable/Resizable.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.cjs.map +1 -1
- package/dist/components/SignaturePad/SignaturePad.js.map +1 -1
- package/dist/components/Slider/Slider.cjs.map +1 -1
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.cjs.map +1 -1
- package/dist/components/Sparkline/Sparkline.js.map +1 -1
- package/dist/components/StepperInput/StepperInput.cjs.map +1 -1
- package/dist/components/StepperInput/StepperInput.js.map +1 -1
- package/dist/components/Table/Table.cjs.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.cjs.map +1 -1
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/components/Tour/Tour.cjs.map +1 -1
- package/dist/components/Tour/Tour.js.map +1 -1
- package/dist/components/Transfer/Transfer.cjs.map +1 -1
- package/dist/components/Transfer/Transfer.js.map +1 -1
- package/dist/components/TreeView/TreeView.cjs.map +1 -1
- package/dist/components/TreeView/TreeView.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.js.map +1 -1
- package/dist/components/Wizard/Wizard.cjs.map +1 -1
- package/dist/components/Wizard/Wizard.js.map +1 -1
- package/dist/editor/RichTextEditor.cjs.map +1 -1
- package/dist/editor/RichTextEditor.js.map +1 -1
- package/dist/forms/FormField.cjs.map +1 -1
- package/dist/forms/FormField.js.map +1 -1
- package/dist/geo/TrajectoryMap.cjs.map +1 -1
- package/dist/geo/TrajectoryMap.js.map +1 -1
- package/dist/geo/estimate.cjs.map +1 -1
- package/dist/geo/estimate.js.map +1 -1
- package/dist/geo/projection.cjs.map +1 -1
- package/dist/geo/projection.js.map +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-event-listener.js.map +1 -1
- package/dist/hooks/use-local-storage.cjs.map +1 -1
- package/dist/hooks/use-local-storage.js.map +1 -1
- package/dist/hooks/use-sortable.cjs.map +1 -1
- package/dist/hooks/use-sortable.js.map +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/errors.cjs.map +1 -1
- package/dist/http/errors.js.map +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/upload-with-progress.cjs.map +1 -1
- package/dist/http/upload-with-progress.js.map +1 -1
- package/dist/i18n/I18nProvider.cjs.map +1 -1
- package/dist/i18n/I18nProvider.js.map +1 -1
- package/dist/imaging/canvas.cjs.map +1 -1
- package/dist/imaging/canvas.js.map +1 -1
- package/dist/imaging.d.ts +5 -0
- package/dist/logger/logger.cjs.map +1 -1
- package/dist/logger/logger.js.map +1 -1
- package/dist/oauth/GoogleSignIn.cjs.map +1 -1
- package/dist/oauth/GoogleSignIn.js.map +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js.map +1 -1
- package/dist/perf/cache-size.cjs +1 -1
- package/dist/perf/cache-size.cjs.map +1 -1
- package/dist/perf/cache-size.js +27 -6
- package/dist/perf/cache-size.js.map +1 -1
- package/dist/sse/create-event-stream.cjs.map +1 -1
- package/dist/sse/create-event-stream.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/sw/background-sync.cjs.map +1 -1
- package/dist/sw/background-sync.js.map +1 -1
- package/dist/sw/cache.cjs.map +1 -1
- package/dist/sw/cache.js.map +1 -1
- package/dist/sw.d.ts +12 -0
- package/dist/tabular/compact.cjs.map +1 -1
- package/dist/tabular/compact.js.map +1 -1
- package/dist/tabular/predictor.cjs.map +1 -1
- package/dist/tabular/predictor.js.map +1 -1
- package/dist/tabular.d.ts +7 -2
- package/dist/tempest-react-sdk.d.ts +133 -6
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/color.cjs.map +1 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/create-theme.cjs.map +1 -1
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/theme/data-viz-ramps.cjs +1 -1
- package/dist/theme/data-viz-ramps.cjs.map +1 -1
- package/dist/theme/data-viz-ramps.js +1 -1
- package/dist/theme/data-viz-ramps.js.map +1 -1
- package/dist/utils/storage.cjs.map +1 -1
- package/dist/utils/storage.js.map +1 -1
- package/dist/vision/core/canvas.cjs.map +1 -1
- package/dist/vision/core/canvas.js.map +1 -1
- package/dist/vision/core/exceptions.cjs.map +1 -1
- package/dist/vision/core/exceptions.js.map +1 -1
- package/dist/vision/core/graph.cjs.map +1 -1
- package/dist/vision/core/graph.js.map +1 -1
- package/dist/vision/core/metadata.cjs.map +1 -1
- package/dist/vision/core/metadata.js.map +1 -1
- package/dist/vision/core/providers.cjs.map +1 -1
- package/dist/vision/core/providers.js.map +1 -1
- package/dist/vision/core/session.cjs.map +1 -1
- package/dist/vision/core/session.js.map +1 -1
- package/dist/vision/core/timing.cjs.map +1 -1
- package/dist/vision/core/timing.js.map +1 -1
- package/dist/vision/io/image.cjs.map +1 -1
- package/dist/vision/io/image.js.map +1 -1
- package/dist/vision/labels.cjs.map +1 -1
- package/dist/vision/labels.js.map +1 -1
- package/dist/vision/luminance.cjs.map +1 -1
- package/dist/vision/luminance.js.map +1 -1
- package/dist/vision/postprocess/classification.cjs.map +1 -1
- package/dist/vision/postprocess/classification.js.map +1 -1
- package/dist/vision/postprocess/detection.cjs.map +1 -1
- package/dist/vision/postprocess/detection.js.map +1 -1
- package/dist/vision/postprocess/segmentation.cjs.map +1 -1
- package/dist/vision/postprocess/segmentation.js.map +1 -1
- package/dist/vision/preprocess/image.cjs.map +1 -1
- package/dist/vision/preprocess/image.js.map +1 -1
- package/dist/vision/results.cjs.map +1 -1
- package/dist/vision/results.js.map +1 -1
- package/dist/vision/tasks/base.cjs.map +1 -1
- package/dist/vision/tasks/base.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision/tasks/detector.cjs.map +1 -1
- package/dist/vision/tasks/detector.js.map +1 -1
- package/dist/vision/tasks/segmenter.cjs.map +1 -1
- package/dist/vision/tasks/segmenter.js.map +1 -1
- package/dist/vision/types.cjs.map +1 -1
- package/dist/vision/types.js.map +1 -1
- package/dist/vision.d.ts +6 -0
- package/dist/vite/tempest-icons.cjs.map +1 -1
- package/dist/vite/tempest-icons.js.map +1 -1
- package/dist/vite/tempest-pwa-icons.cjs.map +1 -1
- package/dist/vite/tempest-pwa-icons.js.map +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exceptions.js","names":[],"sources":["../../../src/vision/core/exceptions.ts"],"sourcesContent":["/**\n * Exceptions raised by the SDK.\n *\n * All exceptions inherit from {@link OrtVisionError}, so callers can catch\n * the base class to handle any SDK-originated failure uniformly.\n */\n\nexport class OrtVisionError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/** Raised when an ONNX model cannot be loaded into an inference session. */\nexport class ModelLoadError extends OrtVisionError {}\n\n/** Raised when ONNX Runtime fails while executing a model. */\nexport class InferenceError extends OrtVisionError {}\n\n/** Raised when a requested execution provider is not available. */\nexport class ProviderNotAvailableError extends OrtVisionError {}\n\n/** Raised when an input image cannot be decoded into the canonical format. */\nexport class ImageLoadError extends OrtVisionError {}\n\n/** Raised when class labels cannot be resolved from the supplied spec. */\nexport class LabelMapError extends OrtVisionError {}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"exceptions.js","names":[],"sources":["../../../src/vision/core/exceptions.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Exceptions raised by the SDK.\n *\n * All exceptions inherit from {@link OrtVisionError}, so callers can catch\n * the base class to handle any SDK-originated failure uniformly.\n */\n\nexport class OrtVisionError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/** Raised when an ONNX model cannot be loaded into an inference session. */\nexport class ModelLoadError extends OrtVisionError {}\n\n/** Raised when ONNX Runtime fails while executing a model. */\nexport class InferenceError extends OrtVisionError {}\n\n/** Raised when a requested execution provider is not available. */\nexport class ProviderNotAvailableError extends OrtVisionError {}\n\n/** Raised when an input image cannot be decoded into the canonical format. */\nexport class ImageLoadError extends OrtVisionError {}\n\n/** Raised when class labels cannot be resolved from the supplied spec. */\nexport class LabelMapError extends OrtVisionError {}\n"],"mappings":";AAQA,IAAa,IAAb,cAAoC,MAAM;CACtC,YAAY,GAAiB,GAAwB;EAEjD,AADA,MAAM,GAAS,CAAO,GACtB,KAAK,OAAO,IAAI,OAAO;CAC3B;AACJ,GAGa,IAAb,cAAoC,EAAe,CAAC,GAGvC,IAAb,cAAoC,EAAe,CAAC,GAGvC,IAAb,cAA+C,EAAe,CAAC,GAGlD,IAAb,cAAoC,EAAe,CAAC,GAGvC,IAAb,cAAmC,EAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.cjs","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph.cjs","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":"AAiCA,SAAgB,EACZ,EACwB,CAExB,OADI,IAAa,IAAA,GAAkB,CAAC,EAC7B,EAAS,IAAK,GACjB,EAAM,SACA,EAAM,MAAM,IAAK,GACb,OAAO,GAAQ,UAAY,OAAO,UAAU,CAAG,GAAK,EAAM,EAAI,EAAM,IACxE,EACA,CAAC,CACX,CACJ,CAUA,SAAgB,EAAiB,EAAwD,CACrF,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,IAAM,EAAS,EAAM,GACf,EAAQ,EAAM,GAGpB,OAFI,GAAW,MAAgC,GAAU,KAC9C,KACJ,CAAC,EAAO,CAAM,CACzB,CAaA,SAAgB,EAAoB,EAAqC,CACrE,IAAM,EAAa,EAAM,OAAQ,GAAuB,IAAQ,MAAQ,EAAM,CAAC,EAC/E,GAAI,EAAW,SAAW,EAAG,OAAO,KACpC,IAAM,EAAW,KAAK,IAAI,GAAG,CAAU,EAEvC,OADI,EAAW,EAAU,KAClB,EAAW,CACtB,CAUA,SAAgB,EAAyB,EAAqC,CAC1E,IAAM,EAAO,EAAM,EAAM,OAAS,GAElC,OADI,GAAS,MAA8B,EAAO,EAAU,KACrD,CACX,CAuBA,SAAgB,EAAiB,EAA6D,CAC1F,IAAM,EAAQ,EAAQ,aAAe,IAAA,GAAY,KAAO,EAAiB,EAAQ,UAAU,EACrF,EAAY,EAAQ,UAQ1B,OAPI,IAAU,KAAa,GAAa,EAAQ,UAC5C,IAAc,IAAA,KAAc,EAAU,KAAO,EAAM,IAAM,EAAU,KAAO,EAAM,KAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,EAEG,EACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"graph.js","names":[],"sources":["../../../src/vision/core/graph.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * What the ONNX graph itself says about its inputs.\n *\n * The resolution a session must be fed at is a property of the exported model,\n * not of the configuration around it. Feeding a 640x640 tensor to a graph\n * exported at 224x224 makes ORT abort the run with\n * `Got invalid dimensions for input: images ... Got: 640 Expected: 224`, and the\n * caller has no way to see that coming from the outside — the number lives in\n * the file. So the SDK reads it from the graph and treats any configured size as\n * a fallback for when the graph leaves it open.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\n/**\n * One declared dimension: a number when the graph pins it, `null` when the\n * dimension is symbolic (dynamic).\n */\nexport type DeclaredDim = number | null;\n\n/** A declared input/output shape, dynamic axes appearing as `null`. */\nexport type DeclaredShape = readonly DeclaredDim[];\n\n/**\n * Convert ORT value metadata into declared shapes.\n *\n * @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or\n * `undefined` on ORT builds that predate it (added in onnxruntime 1.21).\n * @returns One shape per value, in declaration order. Non-tensor values and\n * builds without metadata yield empty shapes, which read as \"nothing\n * declared\" everywhere downstream.\n */\nexport function declaredShapesFrom(\n metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined,\n): readonly DeclaredShape[] {\n if (metadata === undefined) return [];\n return metadata.map((value) =>\n value.isTensor\n ? value.shape.map((dim) =>\n typeof dim === \"number\" && Number.isInteger(dim) && dim > 0 ? dim : null,\n )\n : [],\n );\n}\n\n/**\n * Read the spatial input size out of a declared NCHW shape.\n *\n * @param shape The declared shape of the model's image input.\n * @returns `[width, height]` in pixels, or `null` when the shape is not 4D or\n * leaves either spatial axis dynamic — in which case the model accepts more\n * than one resolution and there is nothing to correct.\n */\nexport function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null {\n if (shape.length !== 4) return null;\n const height = shape[2];\n const width = shape[3];\n if (height === null || height === undefined || width === null || width === undefined)\n return null;\n return [width, height];\n}\n\n/**\n * Infer how many classes a YOLO detection/segmentation head emits.\n *\n * Such a head declares `(B, 4 + nc, N)` — four box coordinates stacked above one\n * score per class, over `N` candidate anchors. `N` is in the thousands and the\n * batch is 1, so the channel axis is the smallest static axis above 1.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the shape leaves it undeterminable —\n * fully dynamic, or too small to hold boxes plus at least one class.\n */\nexport function detectionNumClasses(shape: DeclaredShape): number | null {\n const staticDims = shape.filter((dim): dim is number => dim !== null && dim > 1);\n if (staticDims.length === 0) return null;\n const channels = Math.min(...staticDims);\n if (channels < 5) return null;\n return channels - 4;\n}\n\n/**\n * Infer how many classes a classification head emits.\n *\n * A classifier declares `(B, nc)`, so the count is the last static axis.\n *\n * @param shape Declared shape of the model's first output.\n * @returns The class count, or `null` when the last axis is dynamic or absent.\n */\nexport function classificationNumClasses(shape: DeclaredShape): number | null {\n const last = shape[shape.length - 1];\n if (last === null || last === undefined || last < 1) return null;\n return last;\n}\n\nexport interface ResolveInputSizeOptions {\n /** Declared shape of the model's image input, from {@link declaredShapesFrom}. */\n readonly graphShape?: DeclaredShape;\n /** Size the caller asked for, if any. */\n readonly requested?: readonly [number, number];\n /** Size to use when neither the graph nor the caller pins one. */\n readonly fallback: readonly [number, number];\n}\n\n/**\n * Decide the input size a task will preprocess to.\n *\n * Precedence is graph → caller → fallback. The graph wins over an explicit\n * `inputSize` because a static shape is not a preference, it is what ORT will\n * accept: honoring the caller there would only turn a fixable mismatch into a\n * failed run. A disagreement is a configuration bug in the caller, so it is\n * reported through `console.warn` instead of being swallowed.\n *\n * @param options Graph shape, requested size and per-task fallback.\n * @returns The `[width, height]` to preprocess to.\n */\nexport function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number] {\n const graph = options.graphShape === undefined ? null : spatialInputSize(options.graphShape);\n const requested = options.requested;\n if (graph === null) return requested ?? options.fallback;\n if (requested !== undefined && (requested[0] !== graph[0] || requested[1] !== graph[1])) {\n console.warn(\n `[ort-vision-sdk] The model declares a ${graph[0]}x${graph[1]} input; ` +\n `ignoring the requested ${requested[0]}x${requested[1]}, which ONNX Runtime would reject.`,\n );\n }\n return graph;\n}\n"],"mappings":";AAiCA,SAAgB,EACZ,GACwB;CAExB,OADI,MAAa,KAAA,IAAkB,CAAC,IAC7B,EAAS,KAAK,MACjB,EAAM,WACA,EAAM,MAAM,KAAK,MACb,OAAO,KAAQ,YAAY,OAAO,UAAU,CAAG,KAAK,IAAM,IAAI,IAAM,IACxE,IACA,CAAC,CACX;AACJ;AAUA,SAAgB,EAAiB,GAAwD;CACrF,IAAI,EAAM,WAAW,GAAG,OAAO;CAC/B,IAAM,IAAS,EAAM,IACf,IAAQ,EAAM;CAGpB,OAFI,KAAW,QAAgC,KAAU,OAC9C,OACJ,CAAC,GAAO,CAAM;AACzB;AAaA,SAAgB,EAAoB,GAAqC;CACrE,IAAM,IAAa,EAAM,QAAQ,MAAuB,MAAQ,QAAQ,IAAM,CAAC;CAC/E,IAAI,EAAW,WAAW,GAAG,OAAO;CACpC,IAAM,IAAW,KAAK,IAAI,GAAG,CAAU;CAEvC,OADI,IAAW,IAAU,OAClB,IAAW;AACtB;AAUA,SAAgB,EAAyB,GAAqC;CAC1E,IAAM,IAAO,EAAM,EAAM,SAAS;CAElC,OADI,KAAS,QAA8B,IAAO,IAAU,OACrD;AACX;AAuBA,SAAgB,EAAiB,GAA6D;CAC1F,IAAM,IAAQ,EAAQ,eAAe,KAAA,IAAY,OAAO,EAAiB,EAAQ,UAAU,GACrF,IAAY,EAAQ;CAQ1B,OAPI,MAAU,OAAa,KAAa,EAAQ,YAC5C,MAAc,KAAA,MAAc,EAAU,OAAO,EAAM,MAAM,EAAU,OAAO,EAAM,OAChF,QAAQ,KACJ,yCAAyC,EAAM,GAAG,GAAG,EAAM,GAAG,iCAChC,EAAU,GAAG,GAAG,EAAU,GAAG,mCAC/D,GAEG;AACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.cjs","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/**\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 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 */\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 * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds {@link MAX_FIELD_BYTES}.\n */\nfunction readLengthDelimited(cursor: Cursor): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > MAX_FIELD_BYTES) 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 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 const raw = metadata?.names?.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\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\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 */\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 * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds {@link MAX_FIELD_BYTES}.\n */\nfunction readLengthDelimited(cursor: Cursor): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > MAX_FIELD_BYTES) 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 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 const raw = metadata?.names?.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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","names":[],"sources":["../../../src/vision/core/metadata.ts"],"sourcesContent":["/**\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 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 */\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 * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds {@link MAX_FIELD_BYTES}.\n */\nfunction readLengthDelimited(cursor: Cursor): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > MAX_FIELD_BYTES) 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 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 const raw = metadata?.names?.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\n/** Field number of `metadata_props` in `ModelProto` (repeated StringStringEntryProto). */\nconst MODEL_METADATA_PROPS_FIELD = 14;\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 */\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 * @returns Start and end offsets of the payload, or `null` when the length is\n * truncated, overruns the buffer, or exceeds {@link MAX_FIELD_BYTES}.\n */\nfunction readLengthDelimited(cursor: Cursor): { start: number; end: number } | null {\n const length = readVarint(cursor);\n if (length === null || length > MAX_FIELD_BYTES) 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 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 const raw = metadata?.names?.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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.cjs","names":[],"sources":["../../../src/vision/core/providers.ts"],"sourcesContent":["/**\n * Execution-provider defaults for ONNX Runtime Web sessions.\n *\n * Unlike Node ORT, the browser ORT cannot enumerate \"available providers\" at\n * runtime — `webgpu` either works or ORT silently falls back to the next\n * provider in the list. We just expose a sensible default order.\n */\n\n/**\n * Default execution provider preference order for browser ORT.\n *\n * `webgpu` is tried first when available; ORT-Web falls back to `wasm`\n * automatically when WebGPU is not supported by the browser or device.\n */\nexport const DEFAULT_PROVIDERS: readonly string[] = [\"webgpu\", \"wasm\"];\n\n/**\n * Resolve the execution providers to pass to `InferenceSession.create`.\n *\n * @param requested Explicit provider list in preference order; `undefined` returns the default.\n */\nexport function resolveProviders(requested?: readonly string[]): string[] {\n if (requested === undefined) {\n return [...DEFAULT_PROVIDERS];\n }\n if (requested.length === 0) {\n return [...DEFAULT_PROVIDERS];\n }\n return [...requested];\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"providers.cjs","names":[],"sources":["../../../src/vision/core/providers.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Execution-provider defaults for ONNX Runtime Web sessions.\n *\n * Unlike Node ORT, the browser ORT cannot enumerate \"available providers\" at\n * runtime — `webgpu` either works or ORT silently falls back to the next\n * provider in the list. We just expose a sensible default order.\n */\n\n/**\n * Default execution provider preference order for browser ORT.\n *\n * `webgpu` is tried first when available; ORT-Web falls back to `wasm`\n * automatically when WebGPU is not supported by the browser or device.\n */\nexport const DEFAULT_PROVIDERS: readonly string[] = [\"webgpu\", \"wasm\"];\n\n/**\n * Resolve the execution providers to pass to `InferenceSession.create`.\n *\n * @param requested Explicit provider list in preference order; `undefined` returns the default.\n */\nexport function resolveProviders(requested?: readonly string[]): string[] {\n if (requested === undefined) {\n return [...DEFAULT_PROVIDERS];\n }\n if (requested.length === 0) {\n return [...DEFAULT_PROVIDERS];\n }\n return [...requested];\n}\n"],"mappings":"AAeA,IAAa,EAAuC,CAAC,SAAU,MAAM,EAOrE,SAAgB,EAAiB,EAAyC,CAOtE,OANI,IAAc,IAAA,IAGd,EAAU,SAAW,EACd,CAAC,GAAG,CAAiB,EAEzB,CAAC,GAAG,CAAS,CACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","names":[],"sources":["../../../src/vision/core/providers.ts"],"sourcesContent":["/**\n * Execution-provider defaults for ONNX Runtime Web sessions.\n *\n * Unlike Node ORT, the browser ORT cannot enumerate \"available providers\" at\n * runtime — `webgpu` either works or ORT silently falls back to the next\n * provider in the list. We just expose a sensible default order.\n */\n\n/**\n * Default execution provider preference order for browser ORT.\n *\n * `webgpu` is tried first when available; ORT-Web falls back to `wasm`\n * automatically when WebGPU is not supported by the browser or device.\n */\nexport const DEFAULT_PROVIDERS: readonly string[] = [\"webgpu\", \"wasm\"];\n\n/**\n * Resolve the execution providers to pass to `InferenceSession.create`.\n *\n * @param requested Explicit provider list in preference order; `undefined` returns the default.\n */\nexport function resolveProviders(requested?: readonly string[]): string[] {\n if (requested === undefined) {\n return [...DEFAULT_PROVIDERS];\n }\n if (requested.length === 0) {\n return [...DEFAULT_PROVIDERS];\n }\n return [...requested];\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"providers.js","names":[],"sources":["../../../src/vision/core/providers.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Execution-provider defaults for ONNX Runtime Web sessions.\n *\n * Unlike Node ORT, the browser ORT cannot enumerate \"available providers\" at\n * runtime — `webgpu` either works or ORT silently falls back to the next\n * provider in the list. We just expose a sensible default order.\n */\n\n/**\n * Default execution provider preference order for browser ORT.\n *\n * `webgpu` is tried first when available; ORT-Web falls back to `wasm`\n * automatically when WebGPU is not supported by the browser or device.\n */\nexport const DEFAULT_PROVIDERS: readonly string[] = [\"webgpu\", \"wasm\"];\n\n/**\n * Resolve the execution providers to pass to `InferenceSession.create`.\n *\n * @param requested Explicit provider list in preference order; `undefined` returns the default.\n */\nexport function resolveProviders(requested?: readonly string[]): string[] {\n if (requested === undefined) {\n return [...DEFAULT_PROVIDERS];\n }\n if (requested.length === 0) {\n return [...DEFAULT_PROVIDERS];\n }\n return [...requested];\n}\n"],"mappings":";AAeA,IAAa,IAAuC,CAAC,UAAU,MAAM;AAOrE,SAAgB,EAAiB,GAAyC;CAOtE,OANI,MAAc,KAAA,KAGd,EAAU,WAAW,IACd,CAAC,GAAG,CAAiB,IAEzB,CAAC,GAAG,CAAS;AACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.cjs","names":[],"sources":["../../../src/vision/core/session.ts"],"sourcesContent":["/**\n * Thin wrapper around `onnxruntime-web` `InferenceSession` with typed metadata.\n */\n\nimport type * as ort from \"onnxruntime-web\";\nimport * as ortRuntime from \"onnxruntime-web\";\n\nimport { InferenceError, ModelLoadError } from \"./exceptions\";\nimport { type DeclaredShape, declaredShapesFrom } from \"./graph\";\nimport { readModelMetadata } from \"./metadata\";\nimport { resolveProviders } from \"./providers\";\n\n/** Anything `InferenceSession.create` accepts. */\nexport type ModelSource = string | ArrayBufferLike | Uint8Array;\n\n/**\n * Fetch a model URL as bytes so its metadata can be read.\n *\n * Falls back to the URL itself when the fetch fails, letting ORT try its own\n * load path: losing the metadata map is a downgrade, but failing to load a model\n * that ORT could have fetched would be a regression.\n *\n * @param url Where the `.onnx` lives.\n * @returns The model bytes, or the original URL when they could not be fetched.\n */\nasync function fetchModel(url: string): Promise<Uint8Array | string> {\n try {\n const response = await fetch(url);\n if (!response.ok) return url;\n return new Uint8Array(await response.arrayBuffer());\n } catch {\n return url;\n }\n}\n\nexport interface OrtSessionOptions {\n /** Execution providers in preference order. `undefined` uses {@link DEFAULT_PROVIDERS}. */\n readonly providers?: readonly string[];\n /** Optional ORT session options forwarded to `InferenceSession.create`. */\n readonly sessionOptions?: ort.InferenceSession.SessionOptions;\n /**\n * Whether to read the model's custom metadata map (`names`, `task`, `imgsz`).\n * Defaults to `true`.\n *\n * The runtime does not expose that map, so it is read from the file itself —\n * which means a URL model is fetched here and handed to ORT as bytes instead\n * of letting ORT fetch it. That is the same single download either way, and\n * it is what lets a task resolve its labels off the model. Set to `false` to\n * keep the URL path untouched and leave {@link OrtSession.metadata} empty.\n *\n * `false` is also the escape hatch when a device cannot afford the bytes: the\n * fetched buffer is dropped before ORT builds the graph (see\n * {@link OrtSession.create}), but ORT's own load path still keeps the model out\n * of reach of anything the SDK holds. A session built this way resolves its\n * input size from the graph as usual — only the class names are lost, so a\n * caller taking this route has to pass `labels` itself.\n */\n readonly readMetadata?: boolean;\n}\n\n/**\n * Wrap an ONNX Runtime Web `InferenceSession` with convenient metadata access.\n *\n * The wrapper exposes input/output names and the shapes the graph declares,\n * manages execution-provider selection, provides a typed {@link OrtSession.run}\n * method, and releases the native session through {@link OrtSession.release}.\n */\nexport class OrtSession {\n private constructor(\n private readonly _session: ort.InferenceSession,\n public readonly providers: readonly string[],\n private readonly _metadata: Readonly<Record<string, string>>,\n ) {}\n\n /**\n * Load an ONNX model into an ORT inference session.\n *\n * The metadata map is read **before** the session is built, and that order is\n * load-bearing on memory-constrained devices. ORT copies the model into its\n * WASM heap and then allocates the graph and the weights on top of that copy;\n * a `readModelMetadata` call placed after `InferenceSession.create` keeps the\n * JavaScript-side buffer reachable across the whole build, so a 5 MB model\n * costs 5 MB of JS heap plus 5 MB of WASM heap plus the weights at the same\n * instant. Reading first makes the buffer collectable as soon as ORT has copied\n * it — on a phone that was the difference between a session and\n * `Can't create a session. failed to allocate a buffer of size N`.\n *\n * @param model Either a URL string, or a `Uint8Array`/`ArrayBuffer` containing the model bytes.\n * @param options Provider list, pass-through `SessionOptions`, and whether to\n * read the model's metadata map (see {@link OrtSessionOptions.readMetadata}).\n * @throws {@link ModelLoadError} if the model cannot be loaded.\n */\n static async create(model: ModelSource, options: OrtSessionOptions = {}): Promise<OrtSession> {\n const providers = resolveProviders(options.providers);\n const sessionOptions: ort.InferenceSession.SessionOptions = {\n ...(options.sessionOptions ?? {}),\n executionProviders:\n providers as ort.InferenceSession.SessionOptions[\"executionProviders\"],\n };\n const wantsMetadata = options.readMetadata !== false;\n const source = typeof model === \"string\" && wantsMetadata ? await fetchModel(model) : model;\n const metadata =\n wantsMetadata && typeof source !== \"string\" ? readModelMetadata(source) : {};\n\n let session: ort.InferenceSession;\n try {\n if (typeof source === \"string\") {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else if (source instanceof Uint8Array) {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else {\n session = await ortRuntime.InferenceSession.create(\n source as ArrayBuffer,\n sessionOptions,\n );\n }\n } catch (err) {\n throw new ModelLoadError(`Failed to load ONNX model: ${(err as Error).message}`, {\n cause: err,\n });\n }\n\n return new OrtSession(session, providers, metadata);\n }\n\n /** Names of the model's inputs, in declaration order. */\n get inputNames(): readonly string[] {\n return this._session.inputNames;\n }\n\n /** Name of the first (and usually only) input. */\n get inputName(): string {\n const name = this._session.inputNames[0];\n if (name === undefined) {\n throw new InferenceError(\"Model has no inputs.\");\n }\n return name;\n }\n\n /** Names of the model's outputs, in declaration order. */\n get outputNames(): readonly string[] {\n return this._session.outputNames;\n }\n\n /**\n * Shapes the graph declares for its inputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Empty shapes mean the runtime\n * reported no metadata — either a non-tensor input, or an `onnxruntime-web`\n * older than 1.21, which predates input metadata.\n */\n get inputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.inputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first input, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get inputShape(): DeclaredShape {\n return this.inputShapes[0] ?? [];\n }\n\n /**\n * Shapes the graph declares for its outputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Reading them is how a task can\n * tell how many classes a head emits without being told.\n */\n get outputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.outputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first output, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get outputShape(): DeclaredShape {\n return this.outputShapes[0] ?? [];\n }\n\n /**\n * The model's custom metadata map — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export.\n *\n * Read from the model's bytes at load time, since the runtime does not expose\n * it. Empty when the session was created with `readMetadata: false`, from a\n * URL that could not be fetched here, or from a model carrying no metadata.\n */\n get metadata(): Readonly<Record<string, string>> {\n return this._metadata;\n }\n\n /**\n * Release the native session and free its memory.\n *\n * Call it when a session is discarded while the page lives on — rebuilding a\n * task at a different input size, swapping in a newer model. A failure from\n * the runtime is ignored: a session being torn down has nothing left to fail\n * at, and the caller is already moving on.\n */\n async release(): Promise<void> {\n await this._session.release().catch(() => undefined);\n }\n\n /** The underlying `onnxruntime-web` session, for advanced use cases. */\n get raw(): ort.InferenceSession {\n return this._session;\n }\n\n /**\n * Run inference and return all outputs.\n *\n * @param feeds Map of input name to `ort.Tensor`. Keys must match {@link inputNames}.\n * @throws {@link InferenceError} if ORT raises any error during execution.\n */\n async run(feeds: Record<string, ort.Tensor>): Promise<Record<string, ort.Tensor>> {\n try {\n const result = await this._session.run(feeds);\n return result as Record<string, ort.Tensor>;\n } catch (err) {\n throw new InferenceError(`Inference failed: ${(err as Error).message}`, { cause: err });\n }\n }\n}\n"],"mappings":"0NAyBA,eAAe,EAAW,EAA2C,CACjE,GAAI,CACA,IAAM,EAAW,MAAM,MAAM,CAAG,EAEhC,OADK,EAAS,GACP,IAAI,WAAW,MAAM,EAAS,YAAY,CAAC,EADzB,CAE7B,MAAQ,CACJ,OAAO,CACX,CACJ,CAkCA,IAAa,EAAb,MAAa,CAAW,CAEC,SACD,UACC,UAHrB,YACI,EACA,EACA,EACF,CAHmB,KAAA,SAAA,EACD,KAAA,UAAA,EACC,KAAA,UAAA,CAClB,CAoBH,aAAa,OAAO,EAAoB,EAA6B,CAAC,EAAwB,CAC1F,IAAM,EAAY,EAAA,iBAAiB,EAAQ,SAAS,EAC9C,EAAsD,CACxD,GAAI,EAAQ,gBAAkB,CAAC,EAC/B,mBACI,CACR,EACM,EAAgB,EAAQ,eAAiB,GACzC,EAAS,OAAO,GAAU,UAAY,EAAgB,MAAM,EAAW,CAAK,EAAI,EAChF,EACF,GAAiB,OAAO,GAAW,SAAW,EAAA,kBAAkB,CAAM,EAAI,CAAC,EAE3E,EACJ,GAAI,CACA,AAKI,GALA,OAAO,GAAW,UAEX,aAAkB,WADf,MAAM,EAAW,iBAAiB,OAAO,EAAQ,CAAc,EASjF,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,8BAA+B,EAAc,UAAW,CAC7E,MAAO,CACX,CAAC,CACL,CAEA,OAAO,IAAI,EAAW,EAAS,EAAW,CAAQ,CACtD,CAGA,IAAI,YAAgC,CAChC,OAAO,KAAK,SAAS,UACzB,CAGA,IAAI,WAAoB,CACpB,IAAM,EAAO,KAAK,SAAS,WAAW,GACtC,GAAI,IAAS,IAAA,GACT,MAAM,IAAI,EAAA,eAAe,sBAAsB,EAEnD,OAAO,CACX,CAGA,IAAI,aAAiC,CACjC,OAAO,KAAK,SAAS,WACzB,CASA,IAAI,aAAwC,CACxC,OAAO,EAAA,mBACH,KAAK,SAAS,aAElB,CACJ,CAOA,IAAI,YAA4B,CAC5B,OAAO,KAAK,YAAY,IAAM,CAAC,CACnC,CAQA,IAAI,cAAyC,CACzC,OAAO,EAAA,mBACH,KAAK,SAAS,cAElB,CACJ,CAOA,IAAI,aAA6B,CAC7B,OAAO,KAAK,aAAa,IAAM,CAAC,CACpC,CAUA,IAAI,UAA6C,CAC7C,OAAO,KAAK,SAChB,CAUA,MAAM,SAAyB,CAC3B,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC,UAAY,IAAA,EAAS,CACvD,CAGA,IAAI,KAA4B,CAC5B,OAAO,KAAK,QAChB,CAQA,MAAM,IAAI,EAAwE,CAC9E,GAAI,CAEA,OAAO,MADc,KAAK,SAAS,IAAI,CAAK,CAEhD,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,qBAAsB,EAAc,UAAW,CAAE,MAAO,CAAI,CAAC,CAC1F,CACJ,CACJ"}
|
|
1
|
+
{"version":3,"file":"session.cjs","names":[],"sources":["../../../src/vision/core/session.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Thin wrapper around `onnxruntime-web` `InferenceSession` with typed metadata.\n */\n\nimport type * as ort from \"onnxruntime-web\";\nimport * as ortRuntime from \"onnxruntime-web\";\n\nimport { InferenceError, ModelLoadError } from \"./exceptions\";\nimport { type DeclaredShape, declaredShapesFrom } from \"./graph\";\nimport { readModelMetadata } from \"./metadata\";\nimport { resolveProviders } from \"./providers\";\n\n/** Anything `InferenceSession.create` accepts. */\nexport type ModelSource = string | ArrayBufferLike | Uint8Array;\n\n/**\n * Fetch a model URL as bytes so its metadata can be read.\n *\n * Falls back to the URL itself when the fetch fails, letting ORT try its own\n * load path: losing the metadata map is a downgrade, but failing to load a model\n * that ORT could have fetched would be a regression.\n *\n * @param url Where the `.onnx` lives.\n * @returns The model bytes, or the original URL when they could not be fetched.\n */\nasync function fetchModel(url: string): Promise<Uint8Array | string> {\n try {\n const response = await fetch(url);\n if (!response.ok) return url;\n return new Uint8Array(await response.arrayBuffer());\n } catch {\n return url;\n }\n}\n\nexport interface OrtSessionOptions {\n /** Execution providers in preference order. `undefined` uses {@link DEFAULT_PROVIDERS}. */\n readonly providers?: readonly string[];\n /** Optional ORT session options forwarded to `InferenceSession.create`. */\n readonly sessionOptions?: ort.InferenceSession.SessionOptions;\n /**\n * Whether to read the model's custom metadata map (`names`, `task`, `imgsz`).\n * Defaults to `true`.\n *\n * The runtime does not expose that map, so it is read from the file itself —\n * which means a URL model is fetched here and handed to ORT as bytes instead\n * of letting ORT fetch it. That is the same single download either way, and\n * it is what lets a task resolve its labels off the model. Set to `false` to\n * keep the URL path untouched and leave {@link OrtSession.metadata} empty.\n *\n * `false` is also the escape hatch when a device cannot afford the bytes: the\n * fetched buffer is dropped before ORT builds the graph (see\n * {@link OrtSession.create}), but ORT's own load path still keeps the model out\n * of reach of anything the SDK holds. A session built this way resolves its\n * input size from the graph as usual — only the class names are lost, so a\n * caller taking this route has to pass `labels` itself.\n */\n readonly readMetadata?: boolean;\n}\n\n/**\n * Wrap an ONNX Runtime Web `InferenceSession` with convenient metadata access.\n *\n * The wrapper exposes input/output names and the shapes the graph declares,\n * manages execution-provider selection, provides a typed {@link OrtSession.run}\n * method, and releases the native session through {@link OrtSession.release}.\n */\nexport class OrtSession {\n private constructor(\n private readonly _session: ort.InferenceSession,\n public readonly providers: readonly string[],\n private readonly _metadata: Readonly<Record<string, string>>,\n ) {}\n\n /**\n * Load an ONNX model into an ORT inference session.\n *\n * The metadata map is read **before** the session is built, and that order is\n * load-bearing on memory-constrained devices. ORT copies the model into its\n * WASM heap and then allocates the graph and the weights on top of that copy;\n * a `readModelMetadata` call placed after `InferenceSession.create` keeps the\n * JavaScript-side buffer reachable across the whole build, so a 5 MB model\n * costs 5 MB of JS heap plus 5 MB of WASM heap plus the weights at the same\n * instant. Reading first makes the buffer collectable as soon as ORT has copied\n * it — on a phone that was the difference between a session and\n * `Can't create a session. failed to allocate a buffer of size N`.\n *\n * @param model Either a URL string, or a `Uint8Array`/`ArrayBuffer` containing the model bytes.\n * @param options Provider list, pass-through `SessionOptions`, and whether to\n * read the model's metadata map (see {@link OrtSessionOptions.readMetadata}).\n * @throws {@link ModelLoadError} if the model cannot be loaded.\n */\n static async create(model: ModelSource, options: OrtSessionOptions = {}): Promise<OrtSession> {\n const providers = resolveProviders(options.providers);\n const sessionOptions: ort.InferenceSession.SessionOptions = {\n ...(options.sessionOptions ?? {}),\n executionProviders:\n providers as ort.InferenceSession.SessionOptions[\"executionProviders\"],\n };\n const wantsMetadata = options.readMetadata !== false;\n const source = typeof model === \"string\" && wantsMetadata ? await fetchModel(model) : model;\n const metadata =\n wantsMetadata && typeof source !== \"string\" ? readModelMetadata(source) : {};\n\n let session: ort.InferenceSession;\n try {\n if (typeof source === \"string\") {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else if (source instanceof Uint8Array) {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else {\n session = await ortRuntime.InferenceSession.create(\n source as ArrayBuffer,\n sessionOptions,\n );\n }\n } catch (err) {\n throw new ModelLoadError(`Failed to load ONNX model: ${(err as Error).message}`, {\n cause: err,\n });\n }\n\n return new OrtSession(session, providers, metadata);\n }\n\n /** Names of the model's inputs, in declaration order. */\n get inputNames(): readonly string[] {\n return this._session.inputNames;\n }\n\n /** Name of the first (and usually only) input. */\n get inputName(): string {\n const name = this._session.inputNames[0];\n if (name === undefined) {\n throw new InferenceError(\"Model has no inputs.\");\n }\n return name;\n }\n\n /** Names of the model's outputs, in declaration order. */\n get outputNames(): readonly string[] {\n return this._session.outputNames;\n }\n\n /**\n * Shapes the graph declares for its inputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Empty shapes mean the runtime\n * reported no metadata — either a non-tensor input, or an `onnxruntime-web`\n * older than 1.21, which predates input metadata.\n */\n get inputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.inputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first input, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get inputShape(): DeclaredShape {\n return this.inputShapes[0] ?? [];\n }\n\n /**\n * Shapes the graph declares for its outputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Reading them is how a task can\n * tell how many classes a head emits without being told.\n */\n get outputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.outputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first output, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get outputShape(): DeclaredShape {\n return this.outputShapes[0] ?? [];\n }\n\n /**\n * The model's custom metadata map — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export.\n *\n * Read from the model's bytes at load time, since the runtime does not expose\n * it. Empty when the session was created with `readMetadata: false`, from a\n * URL that could not be fetched here, or from a model carrying no metadata.\n */\n get metadata(): Readonly<Record<string, string>> {\n return this._metadata;\n }\n\n /**\n * Release the native session and free its memory.\n *\n * Call it when a session is discarded while the page lives on — rebuilding a\n * task at a different input size, swapping in a newer model. A failure from\n * the runtime is ignored: a session being torn down has nothing left to fail\n * at, and the caller is already moving on.\n */\n async release(): Promise<void> {\n await this._session.release().catch(() => undefined);\n }\n\n /** The underlying `onnxruntime-web` session, for advanced use cases. */\n get raw(): ort.InferenceSession {\n return this._session;\n }\n\n /**\n * Run inference and return all outputs.\n *\n * @param feeds Map of input name to `ort.Tensor`. Keys must match {@link inputNames}.\n * @throws {@link InferenceError} if ORT raises any error during execution.\n */\n async run(feeds: Record<string, ort.Tensor>): Promise<Record<string, ort.Tensor>> {\n try {\n const result = await this._session.run(feeds);\n return result as Record<string, ort.Tensor>;\n } catch (err) {\n throw new InferenceError(`Inference failed: ${(err as Error).message}`, { cause: err });\n }\n }\n}\n"],"mappings":"0NA0BA,eAAe,EAAW,EAA2C,CACjE,GAAI,CACA,IAAM,EAAW,MAAM,MAAM,CAAG,EAEhC,OADK,EAAS,GACP,IAAI,WAAW,MAAM,EAAS,YAAY,CAAC,EADzB,CAE7B,MAAQ,CACJ,OAAO,CACX,CACJ,CAkCA,IAAa,EAAb,MAAa,CAAW,CAEC,SACD,UACC,UAHrB,YACI,EACA,EACA,EACF,CAHmB,KAAA,SAAA,EACD,KAAA,UAAA,EACC,KAAA,UAAA,CAClB,CAoBH,aAAa,OAAO,EAAoB,EAA6B,CAAC,EAAwB,CAC1F,IAAM,EAAY,EAAA,iBAAiB,EAAQ,SAAS,EAC9C,EAAsD,CACxD,GAAI,EAAQ,gBAAkB,CAAC,EAC/B,mBACI,CACR,EACM,EAAgB,EAAQ,eAAiB,GACzC,EAAS,OAAO,GAAU,UAAY,EAAgB,MAAM,EAAW,CAAK,EAAI,EAChF,EACF,GAAiB,OAAO,GAAW,SAAW,EAAA,kBAAkB,CAAM,EAAI,CAAC,EAE3E,EACJ,GAAI,CACA,AAKI,GALA,OAAO,GAAW,UAEX,aAAkB,WADf,MAAM,EAAW,iBAAiB,OAAO,EAAQ,CAAc,EASjF,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,8BAA+B,EAAc,UAAW,CAC7E,MAAO,CACX,CAAC,CACL,CAEA,OAAO,IAAI,EAAW,EAAS,EAAW,CAAQ,CACtD,CAGA,IAAI,YAAgC,CAChC,OAAO,KAAK,SAAS,UACzB,CAGA,IAAI,WAAoB,CACpB,IAAM,EAAO,KAAK,SAAS,WAAW,GACtC,GAAI,IAAS,IAAA,GACT,MAAM,IAAI,EAAA,eAAe,sBAAsB,EAEnD,OAAO,CACX,CAGA,IAAI,aAAiC,CACjC,OAAO,KAAK,SAAS,WACzB,CASA,IAAI,aAAwC,CACxC,OAAO,EAAA,mBACH,KAAK,SAAS,aAElB,CACJ,CAOA,IAAI,YAA4B,CAC5B,OAAO,KAAK,YAAY,IAAM,CAAC,CACnC,CAQA,IAAI,cAAyC,CACzC,OAAO,EAAA,mBACH,KAAK,SAAS,cAElB,CACJ,CAOA,IAAI,aAA6B,CAC7B,OAAO,KAAK,aAAa,IAAM,CAAC,CACpC,CAUA,IAAI,UAA6C,CAC7C,OAAO,KAAK,SAChB,CAUA,MAAM,SAAyB,CAC3B,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC,UAAY,IAAA,EAAS,CACvD,CAGA,IAAI,KAA4B,CAC5B,OAAO,KAAK,QAChB,CAQA,MAAM,IAAI,EAAwE,CAC9E,GAAI,CAEA,OAAO,MADc,KAAK,SAAS,IAAI,CAAK,CAEhD,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,qBAAsB,EAAc,UAAW,CAAE,MAAO,CAAI,CAAC,CAC1F,CACJ,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":[],"sources":["../../../src/vision/core/session.ts"],"sourcesContent":["/**\n * Thin wrapper around `onnxruntime-web` `InferenceSession` with typed metadata.\n */\n\nimport type * as ort from \"onnxruntime-web\";\nimport * as ortRuntime from \"onnxruntime-web\";\n\nimport { InferenceError, ModelLoadError } from \"./exceptions\";\nimport { type DeclaredShape, declaredShapesFrom } from \"./graph\";\nimport { readModelMetadata } from \"./metadata\";\nimport { resolveProviders } from \"./providers\";\n\n/** Anything `InferenceSession.create` accepts. */\nexport type ModelSource = string | ArrayBufferLike | Uint8Array;\n\n/**\n * Fetch a model URL as bytes so its metadata can be read.\n *\n * Falls back to the URL itself when the fetch fails, letting ORT try its own\n * load path: losing the metadata map is a downgrade, but failing to load a model\n * that ORT could have fetched would be a regression.\n *\n * @param url Where the `.onnx` lives.\n * @returns The model bytes, or the original URL when they could not be fetched.\n */\nasync function fetchModel(url: string): Promise<Uint8Array | string> {\n try {\n const response = await fetch(url);\n if (!response.ok) return url;\n return new Uint8Array(await response.arrayBuffer());\n } catch {\n return url;\n }\n}\n\nexport interface OrtSessionOptions {\n /** Execution providers in preference order. `undefined` uses {@link DEFAULT_PROVIDERS}. */\n readonly providers?: readonly string[];\n /** Optional ORT session options forwarded to `InferenceSession.create`. */\n readonly sessionOptions?: ort.InferenceSession.SessionOptions;\n /**\n * Whether to read the model's custom metadata map (`names`, `task`, `imgsz`).\n * Defaults to `true`.\n *\n * The runtime does not expose that map, so it is read from the file itself —\n * which means a URL model is fetched here and handed to ORT as bytes instead\n * of letting ORT fetch it. That is the same single download either way, and\n * it is what lets a task resolve its labels off the model. Set to `false` to\n * keep the URL path untouched and leave {@link OrtSession.metadata} empty.\n *\n * `false` is also the escape hatch when a device cannot afford the bytes: the\n * fetched buffer is dropped before ORT builds the graph (see\n * {@link OrtSession.create}), but ORT's own load path still keeps the model out\n * of reach of anything the SDK holds. A session built this way resolves its\n * input size from the graph as usual — only the class names are lost, so a\n * caller taking this route has to pass `labels` itself.\n */\n readonly readMetadata?: boolean;\n}\n\n/**\n * Wrap an ONNX Runtime Web `InferenceSession` with convenient metadata access.\n *\n * The wrapper exposes input/output names and the shapes the graph declares,\n * manages execution-provider selection, provides a typed {@link OrtSession.run}\n * method, and releases the native session through {@link OrtSession.release}.\n */\nexport class OrtSession {\n private constructor(\n private readonly _session: ort.InferenceSession,\n public readonly providers: readonly string[],\n private readonly _metadata: Readonly<Record<string, string>>,\n ) {}\n\n /**\n * Load an ONNX model into an ORT inference session.\n *\n * The metadata map is read **before** the session is built, and that order is\n * load-bearing on memory-constrained devices. ORT copies the model into its\n * WASM heap and then allocates the graph and the weights on top of that copy;\n * a `readModelMetadata` call placed after `InferenceSession.create` keeps the\n * JavaScript-side buffer reachable across the whole build, so a 5 MB model\n * costs 5 MB of JS heap plus 5 MB of WASM heap plus the weights at the same\n * instant. Reading first makes the buffer collectable as soon as ORT has copied\n * it — on a phone that was the difference between a session and\n * `Can't create a session. failed to allocate a buffer of size N`.\n *\n * @param model Either a URL string, or a `Uint8Array`/`ArrayBuffer` containing the model bytes.\n * @param options Provider list, pass-through `SessionOptions`, and whether to\n * read the model's metadata map (see {@link OrtSessionOptions.readMetadata}).\n * @throws {@link ModelLoadError} if the model cannot be loaded.\n */\n static async create(model: ModelSource, options: OrtSessionOptions = {}): Promise<OrtSession> {\n const providers = resolveProviders(options.providers);\n const sessionOptions: ort.InferenceSession.SessionOptions = {\n ...(options.sessionOptions ?? {}),\n executionProviders:\n providers as ort.InferenceSession.SessionOptions[\"executionProviders\"],\n };\n const wantsMetadata = options.readMetadata !== false;\n const source = typeof model === \"string\" && wantsMetadata ? await fetchModel(model) : model;\n const metadata =\n wantsMetadata && typeof source !== \"string\" ? readModelMetadata(source) : {};\n\n let session: ort.InferenceSession;\n try {\n if (typeof source === \"string\") {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else if (source instanceof Uint8Array) {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else {\n session = await ortRuntime.InferenceSession.create(\n source as ArrayBuffer,\n sessionOptions,\n );\n }\n } catch (err) {\n throw new ModelLoadError(`Failed to load ONNX model: ${(err as Error).message}`, {\n cause: err,\n });\n }\n\n return new OrtSession(session, providers, metadata);\n }\n\n /** Names of the model's inputs, in declaration order. */\n get inputNames(): readonly string[] {\n return this._session.inputNames;\n }\n\n /** Name of the first (and usually only) input. */\n get inputName(): string {\n const name = this._session.inputNames[0];\n if (name === undefined) {\n throw new InferenceError(\"Model has no inputs.\");\n }\n return name;\n }\n\n /** Names of the model's outputs, in declaration order. */\n get outputNames(): readonly string[] {\n return this._session.outputNames;\n }\n\n /**\n * Shapes the graph declares for its inputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Empty shapes mean the runtime\n * reported no metadata — either a non-tensor input, or an `onnxruntime-web`\n * older than 1.21, which predates input metadata.\n */\n get inputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.inputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first input, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get inputShape(): DeclaredShape {\n return this.inputShapes[0] ?? [];\n }\n\n /**\n * Shapes the graph declares for its outputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Reading them is how a task can\n * tell how many classes a head emits without being told.\n */\n get outputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.outputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first output, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get outputShape(): DeclaredShape {\n return this.outputShapes[0] ?? [];\n }\n\n /**\n * The model's custom metadata map — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export.\n *\n * Read from the model's bytes at load time, since the runtime does not expose\n * it. Empty when the session was created with `readMetadata: false`, from a\n * URL that could not be fetched here, or from a model carrying no metadata.\n */\n get metadata(): Readonly<Record<string, string>> {\n return this._metadata;\n }\n\n /**\n * Release the native session and free its memory.\n *\n * Call it when a session is discarded while the page lives on — rebuilding a\n * task at a different input size, swapping in a newer model. A failure from\n * the runtime is ignored: a session being torn down has nothing left to fail\n * at, and the caller is already moving on.\n */\n async release(): Promise<void> {\n await this._session.release().catch(() => undefined);\n }\n\n /** The underlying `onnxruntime-web` session, for advanced use cases. */\n get raw(): ort.InferenceSession {\n return this._session;\n }\n\n /**\n * Run inference and return all outputs.\n *\n * @param feeds Map of input name to `ort.Tensor`. Keys must match {@link inputNames}.\n * @throws {@link InferenceError} if ORT raises any error during execution.\n */\n async run(feeds: Record<string, ort.Tensor>): Promise<Record<string, ort.Tensor>> {\n try {\n const result = await this._session.run(feeds);\n return result as Record<string, ort.Tensor>;\n } catch (err) {\n throw new InferenceError(`Inference failed: ${(err as Error).message}`, { cause: err });\n }\n }\n}\n"],"mappings":";;;;;;AAyBA,eAAe,EAAW,GAA2C;CACjE,IAAI;EACA,IAAM,IAAW,MAAM,MAAM,CAAG;EAEhC,OADK,EAAS,KACP,IAAI,WAAW,MAAM,EAAS,YAAY,CAAC,IADzB;CAE7B,QAAQ;EACJ,OAAO;CACX;AACJ;AAkCA,IAAa,IAAb,MAAa,EAAW;CAEC;CACD;CACC;CAHrB,YACI,GACA,GACA,GACF;EADmB,AAFA,KAAA,WAAA,GACD,KAAA,YAAA,GACC,KAAA,YAAA;CAClB;CAoBH,aAAa,OAAO,GAAoB,IAA6B,CAAC,GAAwB;EAC1F,IAAM,IAAY,EAAiB,EAAQ,SAAS,GAC9C,IAAsD;GACxD,GAAI,EAAQ,kBAAkB,CAAC;GAC/B,oBACI;EACR,GACM,IAAgB,EAAQ,iBAAiB,IACzC,IAAS,OAAO,KAAU,YAAY,IAAgB,MAAM,EAAW,CAAK,IAAI,GAChF,IACF,KAAiB,OAAO,KAAW,WAAW,EAAkB,CAAM,IAAI,CAAC,GAE3E;EACJ,IAAI;GACA,AAKI,KALA,OAAO,KAAW,YAEX,aAAkB,YADf,MAAM,EAAW,iBAAiB,OAAO,GAAQ,CAAc;EASjF,SAAS,GAAK;GACV,MAAM,IAAI,EAAe,8BAA+B,EAAc,WAAW,EAC7E,OAAO,EACX,CAAC;EACL;EAEA,OAAO,IAAI,EAAW,GAAS,GAAW,CAAQ;CACtD;CAGA,IAAI,aAAgC;EAChC,OAAO,KAAK,SAAS;CACzB;CAGA,IAAI,YAAoB;EACpB,IAAM,IAAO,KAAK,SAAS,WAAW;EACtC,IAAI,MAAS,KAAA,GACT,MAAM,IAAI,EAAe,sBAAsB;EAEnD,OAAO;CACX;CAGA,IAAI,cAAiC;EACjC,OAAO,KAAK,SAAS;CACzB;CASA,IAAI,cAAwC;EACxC,OAAO,EACH,KAAK,SAAS,aAElB;CACJ;CAOA,IAAI,aAA4B;EAC5B,OAAO,KAAK,YAAY,MAAM,CAAC;CACnC;CAQA,IAAI,eAAyC;EACzC,OAAO,EACH,KAAK,SAAS,cAElB;CACJ;CAOA,IAAI,cAA6B;EAC7B,OAAO,KAAK,aAAa,MAAM,CAAC;CACpC;CAUA,IAAI,WAA6C;EAC7C,OAAO,KAAK;CAChB;CAUA,MAAM,UAAyB;EAC3B,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC,YAAY,KAAA,CAAS;CACvD;CAGA,IAAI,MAA4B;EAC5B,OAAO,KAAK;CAChB;CAQA,MAAM,IAAI,GAAwE;EAC9E,IAAI;GAEA,OAAO,MADc,KAAK,SAAS,IAAI,CAAK;EAEhD,SAAS,GAAK;GACV,MAAM,IAAI,EAAe,qBAAsB,EAAc,WAAW,EAAE,OAAO,EAAI,CAAC;EAC1F;CACJ;AACJ"}
|
|
1
|
+
{"version":3,"file":"session.js","names":[],"sources":["../../../src/vision/core/session.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Thin wrapper around `onnxruntime-web` `InferenceSession` with typed metadata.\n */\n\nimport type * as ort from \"onnxruntime-web\";\nimport * as ortRuntime from \"onnxruntime-web\";\n\nimport { InferenceError, ModelLoadError } from \"./exceptions\";\nimport { type DeclaredShape, declaredShapesFrom } from \"./graph\";\nimport { readModelMetadata } from \"./metadata\";\nimport { resolveProviders } from \"./providers\";\n\n/** Anything `InferenceSession.create` accepts. */\nexport type ModelSource = string | ArrayBufferLike | Uint8Array;\n\n/**\n * Fetch a model URL as bytes so its metadata can be read.\n *\n * Falls back to the URL itself when the fetch fails, letting ORT try its own\n * load path: losing the metadata map is a downgrade, but failing to load a model\n * that ORT could have fetched would be a regression.\n *\n * @param url Where the `.onnx` lives.\n * @returns The model bytes, or the original URL when they could not be fetched.\n */\nasync function fetchModel(url: string): Promise<Uint8Array | string> {\n try {\n const response = await fetch(url);\n if (!response.ok) return url;\n return new Uint8Array(await response.arrayBuffer());\n } catch {\n return url;\n }\n}\n\nexport interface OrtSessionOptions {\n /** Execution providers in preference order. `undefined` uses {@link DEFAULT_PROVIDERS}. */\n readonly providers?: readonly string[];\n /** Optional ORT session options forwarded to `InferenceSession.create`. */\n readonly sessionOptions?: ort.InferenceSession.SessionOptions;\n /**\n * Whether to read the model's custom metadata map (`names`, `task`, `imgsz`).\n * Defaults to `true`.\n *\n * The runtime does not expose that map, so it is read from the file itself —\n * which means a URL model is fetched here and handed to ORT as bytes instead\n * of letting ORT fetch it. That is the same single download either way, and\n * it is what lets a task resolve its labels off the model. Set to `false` to\n * keep the URL path untouched and leave {@link OrtSession.metadata} empty.\n *\n * `false` is also the escape hatch when a device cannot afford the bytes: the\n * fetched buffer is dropped before ORT builds the graph (see\n * {@link OrtSession.create}), but ORT's own load path still keeps the model out\n * of reach of anything the SDK holds. A session built this way resolves its\n * input size from the graph as usual — only the class names are lost, so a\n * caller taking this route has to pass `labels` itself.\n */\n readonly readMetadata?: boolean;\n}\n\n/**\n * Wrap an ONNX Runtime Web `InferenceSession` with convenient metadata access.\n *\n * The wrapper exposes input/output names and the shapes the graph declares,\n * manages execution-provider selection, provides a typed {@link OrtSession.run}\n * method, and releases the native session through {@link OrtSession.release}.\n */\nexport class OrtSession {\n private constructor(\n private readonly _session: ort.InferenceSession,\n public readonly providers: readonly string[],\n private readonly _metadata: Readonly<Record<string, string>>,\n ) {}\n\n /**\n * Load an ONNX model into an ORT inference session.\n *\n * The metadata map is read **before** the session is built, and that order is\n * load-bearing on memory-constrained devices. ORT copies the model into its\n * WASM heap and then allocates the graph and the weights on top of that copy;\n * a `readModelMetadata` call placed after `InferenceSession.create` keeps the\n * JavaScript-side buffer reachable across the whole build, so a 5 MB model\n * costs 5 MB of JS heap plus 5 MB of WASM heap plus the weights at the same\n * instant. Reading first makes the buffer collectable as soon as ORT has copied\n * it — on a phone that was the difference between a session and\n * `Can't create a session. failed to allocate a buffer of size N`.\n *\n * @param model Either a URL string, or a `Uint8Array`/`ArrayBuffer` containing the model bytes.\n * @param options Provider list, pass-through `SessionOptions`, and whether to\n * read the model's metadata map (see {@link OrtSessionOptions.readMetadata}).\n * @throws {@link ModelLoadError} if the model cannot be loaded.\n */\n static async create(model: ModelSource, options: OrtSessionOptions = {}): Promise<OrtSession> {\n const providers = resolveProviders(options.providers);\n const sessionOptions: ort.InferenceSession.SessionOptions = {\n ...(options.sessionOptions ?? {}),\n executionProviders:\n providers as ort.InferenceSession.SessionOptions[\"executionProviders\"],\n };\n const wantsMetadata = options.readMetadata !== false;\n const source = typeof model === \"string\" && wantsMetadata ? await fetchModel(model) : model;\n const metadata =\n wantsMetadata && typeof source !== \"string\" ? readModelMetadata(source) : {};\n\n let session: ort.InferenceSession;\n try {\n if (typeof source === \"string\") {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else if (source instanceof Uint8Array) {\n session = await ortRuntime.InferenceSession.create(source, sessionOptions);\n } else {\n session = await ortRuntime.InferenceSession.create(\n source as ArrayBuffer,\n sessionOptions,\n );\n }\n } catch (err) {\n throw new ModelLoadError(`Failed to load ONNX model: ${(err as Error).message}`, {\n cause: err,\n });\n }\n\n return new OrtSession(session, providers, metadata);\n }\n\n /** Names of the model's inputs, in declaration order. */\n get inputNames(): readonly string[] {\n return this._session.inputNames;\n }\n\n /** Name of the first (and usually only) input. */\n get inputName(): string {\n const name = this._session.inputNames[0];\n if (name === undefined) {\n throw new InferenceError(\"Model has no inputs.\");\n }\n return name;\n }\n\n /** Names of the model's outputs, in declaration order. */\n get outputNames(): readonly string[] {\n return this._session.outputNames;\n }\n\n /**\n * Shapes the graph declares for its inputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Empty shapes mean the runtime\n * reported no metadata — either a non-tensor input, or an `onnxruntime-web`\n * older than 1.21, which predates input metadata.\n */\n get inputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.inputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first input, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get inputShape(): DeclaredShape {\n return this.inputShapes[0] ?? [];\n }\n\n /**\n * Shapes the graph declares for its outputs, in declaration order.\n *\n * Dynamic (symbolic) axes appear as `null`. Reading them is how a task can\n * tell how many classes a head emits without being told.\n */\n get outputShapes(): readonly DeclaredShape[] {\n return declaredShapesFrom(\n this._session.outputMetadata as\n readonly ort.InferenceSession.ValueMetadata[] | undefined,\n );\n }\n\n /**\n * Shape the graph declares for its first output, dynamic axes as `null`.\n *\n * Empty when the runtime reports no metadata for it.\n */\n get outputShape(): DeclaredShape {\n return this.outputShapes[0] ?? [];\n }\n\n /**\n * The model's custom metadata map — `names`, `task`, `imgsz`, ... for an\n * Ultralytics export.\n *\n * Read from the model's bytes at load time, since the runtime does not expose\n * it. Empty when the session was created with `readMetadata: false`, from a\n * URL that could not be fetched here, or from a model carrying no metadata.\n */\n get metadata(): Readonly<Record<string, string>> {\n return this._metadata;\n }\n\n /**\n * Release the native session and free its memory.\n *\n * Call it when a session is discarded while the page lives on — rebuilding a\n * task at a different input size, swapping in a newer model. A failure from\n * the runtime is ignored: a session being torn down has nothing left to fail\n * at, and the caller is already moving on.\n */\n async release(): Promise<void> {\n await this._session.release().catch(() => undefined);\n }\n\n /** The underlying `onnxruntime-web` session, for advanced use cases. */\n get raw(): ort.InferenceSession {\n return this._session;\n }\n\n /**\n * Run inference and return all outputs.\n *\n * @param feeds Map of input name to `ort.Tensor`. Keys must match {@link inputNames}.\n * @throws {@link InferenceError} if ORT raises any error during execution.\n */\n async run(feeds: Record<string, ort.Tensor>): Promise<Record<string, ort.Tensor>> {\n try {\n const result = await this._session.run(feeds);\n return result as Record<string, ort.Tensor>;\n } catch (err) {\n throw new InferenceError(`Inference failed: ${(err as Error).message}`, { cause: err });\n }\n }\n}\n"],"mappings":";;;;;;AA0BA,eAAe,EAAW,GAA2C;CACjE,IAAI;EACA,IAAM,IAAW,MAAM,MAAM,CAAG;EAEhC,OADK,EAAS,KACP,IAAI,WAAW,MAAM,EAAS,YAAY,CAAC,IADzB;CAE7B,QAAQ;EACJ,OAAO;CACX;AACJ;AAkCA,IAAa,IAAb,MAAa,EAAW;CAEC;CACD;CACC;CAHrB,YACI,GACA,GACA,GACF;EADmB,AAFA,KAAA,WAAA,GACD,KAAA,YAAA,GACC,KAAA,YAAA;CAClB;CAoBH,aAAa,OAAO,GAAoB,IAA6B,CAAC,GAAwB;EAC1F,IAAM,IAAY,EAAiB,EAAQ,SAAS,GAC9C,IAAsD;GACxD,GAAI,EAAQ,kBAAkB,CAAC;GAC/B,oBACI;EACR,GACM,IAAgB,EAAQ,iBAAiB,IACzC,IAAS,OAAO,KAAU,YAAY,IAAgB,MAAM,EAAW,CAAK,IAAI,GAChF,IACF,KAAiB,OAAO,KAAW,WAAW,EAAkB,CAAM,IAAI,CAAC,GAE3E;EACJ,IAAI;GACA,AAKI,KALA,OAAO,KAAW,YAEX,aAAkB,YADf,MAAM,EAAW,iBAAiB,OAAO,GAAQ,CAAc;EASjF,SAAS,GAAK;GACV,MAAM,IAAI,EAAe,8BAA+B,EAAc,WAAW,EAC7E,OAAO,EACX,CAAC;EACL;EAEA,OAAO,IAAI,EAAW,GAAS,GAAW,CAAQ;CACtD;CAGA,IAAI,aAAgC;EAChC,OAAO,KAAK,SAAS;CACzB;CAGA,IAAI,YAAoB;EACpB,IAAM,IAAO,KAAK,SAAS,WAAW;EACtC,IAAI,MAAS,KAAA,GACT,MAAM,IAAI,EAAe,sBAAsB;EAEnD,OAAO;CACX;CAGA,IAAI,cAAiC;EACjC,OAAO,KAAK,SAAS;CACzB;CASA,IAAI,cAAwC;EACxC,OAAO,EACH,KAAK,SAAS,aAElB;CACJ;CAOA,IAAI,aAA4B;EAC5B,OAAO,KAAK,YAAY,MAAM,CAAC;CACnC;CAQA,IAAI,eAAyC;EACzC,OAAO,EACH,KAAK,SAAS,cAElB;CACJ;CAOA,IAAI,cAA6B;EAC7B,OAAO,KAAK,aAAa,MAAM,CAAC;CACpC;CAUA,IAAI,WAA6C;EAC7C,OAAO,KAAK;CAChB;CAUA,MAAM,UAAyB;EAC3B,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC,YAAY,KAAA,CAAS;CACvD;CAGA,IAAI,MAA4B;EAC5B,OAAO,KAAK;CAChB;CAQA,MAAM,IAAI,GAAwE;EAC9E,IAAI;GAEA,OAAO,MADc,KAAK,SAAS,IAAI,CAAK;EAEhD,SAAS,GAAK;GACV,MAAM,IAAI,EAAe,qBAAsB,EAAc,WAAW,EAAE,OAAO,EAAI,CAAC;EAC1F;CACJ;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.cjs","names":[],"sources":["../../../src/vision/core/timing.ts"],"sourcesContent":["/**\n * Per-stage timing for a single `predict()` call.\n *\n * Populates the `speed` field every `Results` envelope carries, mirroring\n * Ultralytics' `results[0].speed`. All values are milliseconds measured with\n * `performance.now()`.\n */\n\n/**\n * Stage durations of one inference, in milliseconds.\n *\n * `preprocess`, `inference` and `postprocess` are the three keys Ultralytics\n * reports, measured over the same boundaries. `load` is specific to this SDK:\n * `predict()` accepts a URL, `Blob` or DOM element and decodes it internally,\n * so the fetch/decode cost would otherwise be invisible — and on a cold cache\n * it dominates everything else.\n */\nexport interface Speed {\n /** Fetching and decoding the input into an `RGBImage`. */\n load: number;\n /** Letterbox/resize, normalization and tensor packing. */\n preprocess: number;\n /** The ONNX Runtime forward pass. */\n inference: number;\n /** Decoding raw outputs into results (NMS, mask assembly, top-k). */\n postprocess: number;\n}\n\n/**\n * Accumulate stage durations while a `predict()` call runs.\n *\n * Each `stage()` call closes the previous stage: the elapsed time since the\n * last boundary is attributed to the name given. This keeps the call sites\n * free of paired start/stop bookkeeping and guarantees the four stages tile\n * the whole call without gaps.\n */\nexport class SpeedTimer {\n private _last: number;\n private readonly _speed: Speed = {\n load: 0,\n preprocess: 0,\n inference: 0,\n postprocess: 0,\n };\n\n constructor() {\n this._last = performance.now();\n }\n\n /**\n * Attribute the time elapsed since the previous boundary to `stage`.\n *\n * @param stage Which stage just finished.\n */\n stage(stage: keyof Speed): void {\n const now = performance.now();\n this._speed[stage] += now - this._last;\n this._last = now;\n }\n\n /**\n * The accumulated durations.\n *\n * @returns The `speed` object to hand to the `Results` envelope.\n */\n speed(): Speed {\n return { ...this._speed };\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"timing.cjs","names":[],"sources":["../../../src/vision/core/timing.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Per-stage timing for a single `predict()` call.\n *\n * Populates the `speed` field every `Results` envelope carries, mirroring\n * Ultralytics' `results[0].speed`. All values are milliseconds measured with\n * `performance.now()`.\n */\n\n/**\n * Stage durations of one inference, in milliseconds.\n *\n * `preprocess`, `inference` and `postprocess` are the three keys Ultralytics\n * reports, measured over the same boundaries. `load` is specific to this SDK:\n * `predict()` accepts a URL, `Blob` or DOM element and decodes it internally,\n * so the fetch/decode cost would otherwise be invisible — and on a cold cache\n * it dominates everything else.\n */\nexport interface Speed {\n /** Fetching and decoding the input into an `RGBImage`. */\n load: number;\n /** Letterbox/resize, normalization and tensor packing. */\n preprocess: number;\n /** The ONNX Runtime forward pass. */\n inference: number;\n /** Decoding raw outputs into results (NMS, mask assembly, top-k). */\n postprocess: number;\n}\n\n/**\n * Accumulate stage durations while a `predict()` call runs.\n *\n * Each `stage()` call closes the previous stage: the elapsed time since the\n * last boundary is attributed to the name given. This keeps the call sites\n * free of paired start/stop bookkeeping and guarantees the four stages tile\n * the whole call without gaps.\n */\nexport class SpeedTimer {\n private _last: number;\n private readonly _speed: Speed = {\n load: 0,\n preprocess: 0,\n inference: 0,\n postprocess: 0,\n };\n\n constructor() {\n this._last = performance.now();\n }\n\n /**\n * Attribute the time elapsed since the previous boundary to `stage`.\n *\n * @param stage Which stage just finished.\n */\n stage(stage: keyof Speed): void {\n const now = performance.now();\n this._speed[stage] += now - this._last;\n this._last = now;\n }\n\n /**\n * The accumulated durations.\n *\n * @returns The `speed` object to hand to the `Results` envelope.\n */\n speed(): Speed {\n return { ...this._speed };\n }\n}\n"],"mappings":"AAqCA,IAAa,EAAb,KAAwB,CACpB,MACA,OAAiC,CAC7B,KAAM,EACN,WAAY,EACZ,UAAW,EACX,YAAa,CACjB,EAEA,aAAc,CACV,KAAK,MAAQ,YAAY,IAAI,CACjC,CAOA,MAAM,EAA0B,CAC5B,IAAM,EAAM,YAAY,IAAI,EAC5B,KAAK,OAAO,IAAU,EAAM,KAAK,MACjC,KAAK,MAAQ,CACjB,CAOA,OAAe,CACX,MAAO,CAAE,GAAG,KAAK,MAAO,CAC5B,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.js","names":[],"sources":["../../../src/vision/core/timing.ts"],"sourcesContent":["/**\n * Per-stage timing for a single `predict()` call.\n *\n * Populates the `speed` field every `Results` envelope carries, mirroring\n * Ultralytics' `results[0].speed`. All values are milliseconds measured with\n * `performance.now()`.\n */\n\n/**\n * Stage durations of one inference, in milliseconds.\n *\n * `preprocess`, `inference` and `postprocess` are the three keys Ultralytics\n * reports, measured over the same boundaries. `load` is specific to this SDK:\n * `predict()` accepts a URL, `Blob` or DOM element and decodes it internally,\n * so the fetch/decode cost would otherwise be invisible — and on a cold cache\n * it dominates everything else.\n */\nexport interface Speed {\n /** Fetching and decoding the input into an `RGBImage`. */\n load: number;\n /** Letterbox/resize, normalization and tensor packing. */\n preprocess: number;\n /** The ONNX Runtime forward pass. */\n inference: number;\n /** Decoding raw outputs into results (NMS, mask assembly, top-k). */\n postprocess: number;\n}\n\n/**\n * Accumulate stage durations while a `predict()` call runs.\n *\n * Each `stage()` call closes the previous stage: the elapsed time since the\n * last boundary is attributed to the name given. This keeps the call sites\n * free of paired start/stop bookkeeping and guarantees the four stages tile\n * the whole call without gaps.\n */\nexport class SpeedTimer {\n private _last: number;\n private readonly _speed: Speed = {\n load: 0,\n preprocess: 0,\n inference: 0,\n postprocess: 0,\n };\n\n constructor() {\n this._last = performance.now();\n }\n\n /**\n * Attribute the time elapsed since the previous boundary to `stage`.\n *\n * @param stage Which stage just finished.\n */\n stage(stage: keyof Speed): void {\n const now = performance.now();\n this._speed[stage] += now - this._last;\n this._last = now;\n }\n\n /**\n * The accumulated durations.\n *\n * @returns The `speed` object to hand to the `Results` envelope.\n */\n speed(): Speed {\n return { ...this._speed };\n }\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"timing.js","names":[],"sources":["../../../src/vision/core/timing.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Per-stage timing for a single `predict()` call.\n *\n * Populates the `speed` field every `Results` envelope carries, mirroring\n * Ultralytics' `results[0].speed`. All values are milliseconds measured with\n * `performance.now()`.\n */\n\n/**\n * Stage durations of one inference, in milliseconds.\n *\n * `preprocess`, `inference` and `postprocess` are the three keys Ultralytics\n * reports, measured over the same boundaries. `load` is specific to this SDK:\n * `predict()` accepts a URL, `Blob` or DOM element and decodes it internally,\n * so the fetch/decode cost would otherwise be invisible — and on a cold cache\n * it dominates everything else.\n */\nexport interface Speed {\n /** Fetching and decoding the input into an `RGBImage`. */\n load: number;\n /** Letterbox/resize, normalization and tensor packing. */\n preprocess: number;\n /** The ONNX Runtime forward pass. */\n inference: number;\n /** Decoding raw outputs into results (NMS, mask assembly, top-k). */\n postprocess: number;\n}\n\n/**\n * Accumulate stage durations while a `predict()` call runs.\n *\n * Each `stage()` call closes the previous stage: the elapsed time since the\n * last boundary is attributed to the name given. This keeps the call sites\n * free of paired start/stop bookkeeping and guarantees the four stages tile\n * the whole call without gaps.\n */\nexport class SpeedTimer {\n private _last: number;\n private readonly _speed: Speed = {\n load: 0,\n preprocess: 0,\n inference: 0,\n postprocess: 0,\n };\n\n constructor() {\n this._last = performance.now();\n }\n\n /**\n * Attribute the time elapsed since the previous boundary to `stage`.\n *\n * @param stage Which stage just finished.\n */\n stage(stage: keyof Speed): void {\n const now = performance.now();\n this._speed[stage] += now - this._last;\n this._last = now;\n }\n\n /**\n * The accumulated durations.\n *\n * @returns The `speed` object to hand to the `Results` envelope.\n */\n speed(): Speed {\n return { ...this._speed };\n }\n}\n"],"mappings":";AAqCA,IAAa,IAAb,MAAwB;CACpB;CACA,SAAiC;EAC7B,MAAM;EACN,YAAY;EACZ,WAAW;EACX,aAAa;CACjB;CAEA,cAAc;EACV,KAAK,QAAQ,YAAY,IAAI;CACjC;CAOA,MAAM,GAA0B;EAC5B,IAAM,IAAM,YAAY,IAAI;EAE5B,AADA,KAAK,OAAO,MAAU,IAAM,KAAK,OACjC,KAAK,QAAQ;CACjB;CAOA,QAAe;EACX,OAAO,EAAE,GAAG,KAAK,OAAO;CAC5B;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.cjs","names":[],"sources":["../../../src/vision/io/image.ts"],"sourcesContent":["/**\n * Image loading utilities — convert any supported source into the canonical\n * {@link RGBImage} format.\n *\n * Browser-only: uses `fetch`, `createImageBitmap`, and a Canvas 2D context to\n * decode arbitrary inputs into a tightly-packed `Uint8Array` of HWC RGB pixels.\n */\n\nimport { createCanvas, get2DContext, imageDataToRGB } from \"../core/canvas\";\nimport { ImageLoadError } from \"../core/exceptions\";\nimport { RGBImage } from \"../types\";\n\n/** Anything {@link loadImage} accepts as an image input. */\nexport type ImageInput =\n | string\n | Blob\n | HTMLImageElement\n | HTMLCanvasElement\n | OffscreenCanvas\n | ImageBitmap\n | ImageData\n | RGBImage;\n\n/**\n * Load an image from any supported source into a HWC uint8 RGB array.\n *\n * @throws {@link ImageLoadError} if the source cannot be decoded or has an unsupported shape.\n */\nexport async function loadImage(source: ImageInput): Promise<RGBImage> {\n if (source instanceof RGBImage) {\n return source;\n }\n\n if (typeof ImageData !== \"undefined\" && source instanceof ImageData) {\n return imageDataToRGB(source);\n }\n\n if (typeof source === \"string\") {\n return loadFromUrl(source);\n }\n\n if (typeof Blob !== \"undefined\" && source instanceof Blob) {\n return loadFromBlob(source);\n }\n\n if (typeof HTMLImageElement !== \"undefined\" && source instanceof HTMLImageElement) {\n await waitForImageElement(source);\n return drawableToRGB(source, source.naturalWidth, source.naturalHeight);\n }\n\n if (typeof HTMLCanvasElement !== \"undefined\" && source instanceof HTMLCanvasElement) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof OffscreenCanvas !== \"undefined\" && source instanceof OffscreenCanvas) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n throw new ImageLoadError(\n `Unsupported image source type: ${Object.prototype.toString.call(source)}`,\n );\n}\n\nasync function loadFromUrl(url: string): Promise<RGBImage> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (err) {\n throw new ImageLoadError(`Failed to fetch image from ${url}: ${(err as Error).message}`, {\n cause: err,\n });\n }\n if (!response.ok) {\n throw new ImageLoadError(\n `Failed to fetch image from ${url}: HTTP ${response.status} ${response.statusText}`,\n );\n }\n const blob = await response.blob();\n return loadFromBlob(blob);\n}\n\nasync function loadFromBlob(blob: Blob): Promise<RGBImage> {\n let bitmap: ImageBitmap;\n try {\n bitmap = await createImageBitmap(blob);\n } catch (err) {\n throw new ImageLoadError(`Failed to decode image blob: ${(err as Error).message}`, {\n cause: err,\n });\n }\n try {\n return drawableToRGB(bitmap, bitmap.width, bitmap.height);\n } finally {\n bitmap.close();\n }\n}\n\nfunction waitForImageElement(img: HTMLImageElement): Promise<void> {\n if (img.complete && img.naturalWidth > 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const onLoad = (): void => {\n cleanup();\n resolve();\n };\n const onError = (): void => {\n cleanup();\n reject(new ImageLoadError(\"Failed to load HTMLImageElement (load event errored)\"));\n };\n const cleanup = (): void => {\n img.removeEventListener(\"load\", onLoad);\n img.removeEventListener(\"error\", onError);\n };\n img.addEventListener(\"load\", onLoad, { once: true });\n img.addEventListener(\"error\", onError, { once: true });\n });\n}\n\nfunction drawableToRGB(drawable: CanvasImageSource, width: number, height: number): RGBImage {\n if (width === 0 || height === 0) {\n throw new ImageLoadError(`Cannot load image with zero dimension (${width}x${height}).`);\n }\n const canvas = createCanvas(width, height);\n const ctx = get2DContext(canvas);\n ctx.drawImage(drawable, 0, 0);\n const imageData = ctx.getImageData(0, 0, width, height);\n return imageDataToRGB(imageData);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"image.cjs","names":[],"sources":["../../../src/vision/io/image.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Image loading utilities — convert any supported source into the canonical\n * {@link RGBImage} format.\n *\n * Browser-only: uses `fetch`, `createImageBitmap`, and a Canvas 2D context to\n * decode arbitrary inputs into a tightly-packed `Uint8Array` of HWC RGB pixels.\n */\n\nimport { createCanvas, get2DContext, imageDataToRGB } from \"../core/canvas\";\nimport { ImageLoadError } from \"../core/exceptions\";\nimport { RGBImage } from \"../types\";\n\n/** Anything {@link loadImage} accepts as an image input. */\nexport type ImageInput =\n | string\n | Blob\n | HTMLImageElement\n | HTMLCanvasElement\n | OffscreenCanvas\n | ImageBitmap\n | ImageData\n | RGBImage;\n\n/**\n * Load an image from any supported source into a HWC uint8 RGB array.\n *\n * @throws {@link ImageLoadError} if the source cannot be decoded or has an unsupported shape.\n */\nexport async function loadImage(source: ImageInput): Promise<RGBImage> {\n if (source instanceof RGBImage) {\n return source;\n }\n\n if (typeof ImageData !== \"undefined\" && source instanceof ImageData) {\n return imageDataToRGB(source);\n }\n\n if (typeof source === \"string\") {\n return loadFromUrl(source);\n }\n\n if (typeof Blob !== \"undefined\" && source instanceof Blob) {\n return loadFromBlob(source);\n }\n\n if (typeof HTMLImageElement !== \"undefined\" && source instanceof HTMLImageElement) {\n await waitForImageElement(source);\n return drawableToRGB(source, source.naturalWidth, source.naturalHeight);\n }\n\n if (typeof HTMLCanvasElement !== \"undefined\" && source instanceof HTMLCanvasElement) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof OffscreenCanvas !== \"undefined\" && source instanceof OffscreenCanvas) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n throw new ImageLoadError(\n `Unsupported image source type: ${Object.prototype.toString.call(source)}`,\n );\n}\n\nasync function loadFromUrl(url: string): Promise<RGBImage> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (err) {\n throw new ImageLoadError(`Failed to fetch image from ${url}: ${(err as Error).message}`, {\n cause: err,\n });\n }\n if (!response.ok) {\n throw new ImageLoadError(\n `Failed to fetch image from ${url}: HTTP ${response.status} ${response.statusText}`,\n );\n }\n const blob = await response.blob();\n return loadFromBlob(blob);\n}\n\nasync function loadFromBlob(blob: Blob): Promise<RGBImage> {\n let bitmap: ImageBitmap;\n try {\n bitmap = await createImageBitmap(blob);\n } catch (err) {\n throw new ImageLoadError(`Failed to decode image blob: ${(err as Error).message}`, {\n cause: err,\n });\n }\n try {\n return drawableToRGB(bitmap, bitmap.width, bitmap.height);\n } finally {\n bitmap.close();\n }\n}\n\nfunction waitForImageElement(img: HTMLImageElement): Promise<void> {\n if (img.complete && img.naturalWidth > 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const onLoad = (): void => {\n cleanup();\n resolve();\n };\n const onError = (): void => {\n cleanup();\n reject(new ImageLoadError(\"Failed to load HTMLImageElement (load event errored)\"));\n };\n const cleanup = (): void => {\n img.removeEventListener(\"load\", onLoad);\n img.removeEventListener(\"error\", onError);\n };\n img.addEventListener(\"load\", onLoad, { once: true });\n img.addEventListener(\"error\", onError, { once: true });\n });\n}\n\nfunction drawableToRGB(drawable: CanvasImageSource, width: number, height: number): RGBImage {\n if (width === 0 || height === 0) {\n throw new ImageLoadError(`Cannot load image with zero dimension (${width}x${height}).`);\n }\n const canvas = createCanvas(width, height);\n const ctx = get2DContext(canvas);\n ctx.drawImage(drawable, 0, 0);\n const imageData = ctx.getImageData(0, 0, width, height);\n return imageDataToRGB(imageData);\n}\n"],"mappings":"oGA6BA,eAAsB,EAAU,EAAuC,CACnE,GAAI,aAAkB,EAAA,SAClB,OAAO,EAGX,GAAI,OAAO,UAAc,KAAe,aAAkB,UACtD,OAAO,EAAA,eAAe,CAAM,EAGhC,GAAI,OAAO,GAAW,SAClB,OAAO,EAAY,CAAM,EAG7B,GAAI,OAAO,KAAS,KAAe,aAAkB,KACjD,OAAO,EAAa,CAAM,EAG9B,GAAI,OAAO,iBAAqB,KAAe,aAAkB,iBAE7D,OADA,MAAM,EAAoB,CAAM,EACzB,EAAc,EAAQ,EAAO,aAAc,EAAO,aAAa,EAW1E,GARI,OAAO,kBAAsB,KAAe,aAAkB,mBAI9D,OAAO,gBAAoB,KAAe,aAAkB,iBAI5D,OAAO,YAAgB,KAAe,aAAkB,YACxD,OAAO,EAAc,EAAQ,EAAO,MAAO,EAAO,MAAM,EAG5D,MAAM,IAAI,EAAA,eACN,kCAAkC,OAAO,UAAU,SAAS,KAAK,CAAM,GAC3E,CACJ,CAEA,eAAe,EAAY,EAAgC,CACvD,IAAI,EACJ,GAAI,CACA,EAAW,MAAM,MAAM,CAAG,CAC9B,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,8BAA8B,EAAI,IAAK,EAAc,UAAW,CACrF,MAAO,CACX,CAAC,CACL,CACA,GAAI,CAAC,EAAS,GACV,MAAM,IAAI,EAAA,eACN,8BAA8B,EAAI,SAAS,EAAS,OAAO,GAAG,EAAS,YAC3E,EAGJ,OAAO,EAAa,MADD,EAAS,KAAK,CACT,CAC5B,CAEA,eAAe,EAAa,EAA+B,CACvD,IAAI,EACJ,GAAI,CACA,EAAS,MAAM,kBAAkB,CAAI,CACzC,OAAS,EAAK,CACV,MAAM,IAAI,EAAA,eAAe,gCAAiC,EAAc,UAAW,CAC/E,MAAO,CACX,CAAC,CACL,CACA,GAAI,CACA,OAAO,EAAc,EAAQ,EAAO,MAAO,EAAO,MAAM,CAC5D,QAAU,CACN,EAAO,MAAM,CACjB,CACJ,CAEA,SAAS,EAAoB,EAAsC,CAI/D,OAHI,EAAI,UAAY,EAAI,aAAe,EAC5B,QAAQ,QAAQ,EAEpB,IAAI,SAAe,EAAS,IAAW,CAC1C,IAAM,MAAqB,CACvB,EAAQ,EACR,EAAQ,CACZ,EACM,MAAsB,CACxB,EAAQ,EACR,EAAO,IAAI,EAAA,eAAe,sDAAsD,CAAC,CACrF,EACM,MAAsB,CACxB,EAAI,oBAAoB,OAAQ,CAAM,EACtC,EAAI,oBAAoB,QAAS,CAAO,CAC5C,EACA,EAAI,iBAAiB,OAAQ,EAAQ,CAAE,KAAM,EAAK,CAAC,EACnD,EAAI,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,CACzD,CAAC,CACL,CAEA,SAAS,EAAc,EAA6B,EAAe,EAA0B,CACzF,GAAI,IAAU,GAAK,IAAW,EAC1B,MAAM,IAAI,EAAA,eAAe,0CAA0C,EAAM,GAAG,EAAO,GAAG,EAG1F,IAAM,EAAM,EAAA,aADG,EAAA,aAAa,EAAO,CACV,CAAM,EAG/B,OAFA,EAAI,UAAU,EAAU,EAAG,CAAC,EAErB,EAAA,eADW,EAAI,aAAa,EAAG,EAAG,EAAO,CAC1B,CAAS,CACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","names":[],"sources":["../../../src/vision/io/image.ts"],"sourcesContent":["/**\n * Image loading utilities — convert any supported source into the canonical\n * {@link RGBImage} format.\n *\n * Browser-only: uses `fetch`, `createImageBitmap`, and a Canvas 2D context to\n * decode arbitrary inputs into a tightly-packed `Uint8Array` of HWC RGB pixels.\n */\n\nimport { createCanvas, get2DContext, imageDataToRGB } from \"../core/canvas\";\nimport { ImageLoadError } from \"../core/exceptions\";\nimport { RGBImage } from \"../types\";\n\n/** Anything {@link loadImage} accepts as an image input. */\nexport type ImageInput =\n | string\n | Blob\n | HTMLImageElement\n | HTMLCanvasElement\n | OffscreenCanvas\n | ImageBitmap\n | ImageData\n | RGBImage;\n\n/**\n * Load an image from any supported source into a HWC uint8 RGB array.\n *\n * @throws {@link ImageLoadError} if the source cannot be decoded or has an unsupported shape.\n */\nexport async function loadImage(source: ImageInput): Promise<RGBImage> {\n if (source instanceof RGBImage) {\n return source;\n }\n\n if (typeof ImageData !== \"undefined\" && source instanceof ImageData) {\n return imageDataToRGB(source);\n }\n\n if (typeof source === \"string\") {\n return loadFromUrl(source);\n }\n\n if (typeof Blob !== \"undefined\" && source instanceof Blob) {\n return loadFromBlob(source);\n }\n\n if (typeof HTMLImageElement !== \"undefined\" && source instanceof HTMLImageElement) {\n await waitForImageElement(source);\n return drawableToRGB(source, source.naturalWidth, source.naturalHeight);\n }\n\n if (typeof HTMLCanvasElement !== \"undefined\" && source instanceof HTMLCanvasElement) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof OffscreenCanvas !== \"undefined\" && source instanceof OffscreenCanvas) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n throw new ImageLoadError(\n `Unsupported image source type: ${Object.prototype.toString.call(source)}`,\n );\n}\n\nasync function loadFromUrl(url: string): Promise<RGBImage> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (err) {\n throw new ImageLoadError(`Failed to fetch image from ${url}: ${(err as Error).message}`, {\n cause: err,\n });\n }\n if (!response.ok) {\n throw new ImageLoadError(\n `Failed to fetch image from ${url}: HTTP ${response.status} ${response.statusText}`,\n );\n }\n const blob = await response.blob();\n return loadFromBlob(blob);\n}\n\nasync function loadFromBlob(blob: Blob): Promise<RGBImage> {\n let bitmap: ImageBitmap;\n try {\n bitmap = await createImageBitmap(blob);\n } catch (err) {\n throw new ImageLoadError(`Failed to decode image blob: ${(err as Error).message}`, {\n cause: err,\n });\n }\n try {\n return drawableToRGB(bitmap, bitmap.width, bitmap.height);\n } finally {\n bitmap.close();\n }\n}\n\nfunction waitForImageElement(img: HTMLImageElement): Promise<void> {\n if (img.complete && img.naturalWidth > 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const onLoad = (): void => {\n cleanup();\n resolve();\n };\n const onError = (): void => {\n cleanup();\n reject(new ImageLoadError(\"Failed to load HTMLImageElement (load event errored)\"));\n };\n const cleanup = (): void => {\n img.removeEventListener(\"load\", onLoad);\n img.removeEventListener(\"error\", onError);\n };\n img.addEventListener(\"load\", onLoad, { once: true });\n img.addEventListener(\"error\", onError, { once: true });\n });\n}\n\nfunction drawableToRGB(drawable: CanvasImageSource, width: number, height: number): RGBImage {\n if (width === 0 || height === 0) {\n throw new ImageLoadError(`Cannot load image with zero dimension (${width}x${height}).`);\n }\n const canvas = createCanvas(width, height);\n const ctx = get2DContext(canvas);\n ctx.drawImage(drawable, 0, 0);\n const imageData = ctx.getImageData(0, 0, width, height);\n return imageDataToRGB(imageData);\n}\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"image.js","names":[],"sources":["../../../src/vision/io/image.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Image loading utilities — convert any supported source into the canonical\n * {@link RGBImage} format.\n *\n * Browser-only: uses `fetch`, `createImageBitmap`, and a Canvas 2D context to\n * decode arbitrary inputs into a tightly-packed `Uint8Array` of HWC RGB pixels.\n */\n\nimport { createCanvas, get2DContext, imageDataToRGB } from \"../core/canvas\";\nimport { ImageLoadError } from \"../core/exceptions\";\nimport { RGBImage } from \"../types\";\n\n/** Anything {@link loadImage} accepts as an image input. */\nexport type ImageInput =\n | string\n | Blob\n | HTMLImageElement\n | HTMLCanvasElement\n | OffscreenCanvas\n | ImageBitmap\n | ImageData\n | RGBImage;\n\n/**\n * Load an image from any supported source into a HWC uint8 RGB array.\n *\n * @throws {@link ImageLoadError} if the source cannot be decoded or has an unsupported shape.\n */\nexport async function loadImage(source: ImageInput): Promise<RGBImage> {\n if (source instanceof RGBImage) {\n return source;\n }\n\n if (typeof ImageData !== \"undefined\" && source instanceof ImageData) {\n return imageDataToRGB(source);\n }\n\n if (typeof source === \"string\") {\n return loadFromUrl(source);\n }\n\n if (typeof Blob !== \"undefined\" && source instanceof Blob) {\n return loadFromBlob(source);\n }\n\n if (typeof HTMLImageElement !== \"undefined\" && source instanceof HTMLImageElement) {\n await waitForImageElement(source);\n return drawableToRGB(source, source.naturalWidth, source.naturalHeight);\n }\n\n if (typeof HTMLCanvasElement !== \"undefined\" && source instanceof HTMLCanvasElement) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof OffscreenCanvas !== \"undefined\" && source instanceof OffscreenCanvas) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n return drawableToRGB(source, source.width, source.height);\n }\n\n throw new ImageLoadError(\n `Unsupported image source type: ${Object.prototype.toString.call(source)}`,\n );\n}\n\nasync function loadFromUrl(url: string): Promise<RGBImage> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (err) {\n throw new ImageLoadError(`Failed to fetch image from ${url}: ${(err as Error).message}`, {\n cause: err,\n });\n }\n if (!response.ok) {\n throw new ImageLoadError(\n `Failed to fetch image from ${url}: HTTP ${response.status} ${response.statusText}`,\n );\n }\n const blob = await response.blob();\n return loadFromBlob(blob);\n}\n\nasync function loadFromBlob(blob: Blob): Promise<RGBImage> {\n let bitmap: ImageBitmap;\n try {\n bitmap = await createImageBitmap(blob);\n } catch (err) {\n throw new ImageLoadError(`Failed to decode image blob: ${(err as Error).message}`, {\n cause: err,\n });\n }\n try {\n return drawableToRGB(bitmap, bitmap.width, bitmap.height);\n } finally {\n bitmap.close();\n }\n}\n\nfunction waitForImageElement(img: HTMLImageElement): Promise<void> {\n if (img.complete && img.naturalWidth > 0) {\n return Promise.resolve();\n }\n return new Promise<void>((resolve, reject) => {\n const onLoad = (): void => {\n cleanup();\n resolve();\n };\n const onError = (): void => {\n cleanup();\n reject(new ImageLoadError(\"Failed to load HTMLImageElement (load event errored)\"));\n };\n const cleanup = (): void => {\n img.removeEventListener(\"load\", onLoad);\n img.removeEventListener(\"error\", onError);\n };\n img.addEventListener(\"load\", onLoad, { once: true });\n img.addEventListener(\"error\", onError, { once: true });\n });\n}\n\nfunction drawableToRGB(drawable: CanvasImageSource, width: number, height: number): RGBImage {\n if (width === 0 || height === 0) {\n throw new ImageLoadError(`Cannot load image with zero dimension (${width}x${height}).`);\n }\n const canvas = createCanvas(width, height);\n const ctx = get2DContext(canvas);\n ctx.drawImage(drawable, 0, 0);\n const imageData = ctx.getImageData(0, 0, width, height);\n return imageDataToRGB(imageData);\n}\n"],"mappings":";;;;AA6BA,eAAsB,EAAU,GAAuC;CACnE,IAAI,aAAkB,GAClB,OAAO;CAGX,IAAI,OAAO,YAAc,OAAe,aAAkB,WACtD,OAAO,EAAe,CAAM;CAGhC,IAAI,OAAO,KAAW,UAClB,OAAO,EAAY,CAAM;CAG7B,IAAI,OAAO,OAAS,OAAe,aAAkB,MACjD,OAAO,EAAa,CAAM;CAG9B,IAAI,OAAO,mBAAqB,OAAe,aAAkB,kBAE7D,OADA,MAAM,EAAoB,CAAM,GACzB,EAAc,GAAQ,EAAO,cAAc,EAAO,aAAa;CAW1E,IARI,OAAO,oBAAsB,OAAe,aAAkB,qBAI9D,OAAO,kBAAoB,OAAe,aAAkB,mBAI5D,OAAO,cAAgB,OAAe,aAAkB,aACxD,OAAO,EAAc,GAAQ,EAAO,OAAO,EAAO,MAAM;CAG5D,MAAM,IAAI,EACN,kCAAkC,OAAO,UAAU,SAAS,KAAK,CAAM,GAC3E;AACJ;AAEA,eAAe,EAAY,GAAgC;CACvD,IAAI;CACJ,IAAI;EACA,IAAW,MAAM,MAAM,CAAG;CAC9B,SAAS,GAAK;EACV,MAAM,IAAI,EAAe,8BAA8B,EAAI,IAAK,EAAc,WAAW,EACrF,OAAO,EACX,CAAC;CACL;CACA,IAAI,CAAC,EAAS,IACV,MAAM,IAAI,EACN,8BAA8B,EAAI,SAAS,EAAS,OAAO,GAAG,EAAS,YAC3E;CAGJ,OAAO,EAAa,MADD,EAAS,KAAK,CACT;AAC5B;AAEA,eAAe,EAAa,GAA+B;CACvD,IAAI;CACJ,IAAI;EACA,IAAS,MAAM,kBAAkB,CAAI;CACzC,SAAS,GAAK;EACV,MAAM,IAAI,EAAe,gCAAiC,EAAc,WAAW,EAC/E,OAAO,EACX,CAAC;CACL;CACA,IAAI;EACA,OAAO,EAAc,GAAQ,EAAO,OAAO,EAAO,MAAM;CAC5D,UAAU;EACN,EAAO,MAAM;CACjB;AACJ;AAEA,SAAS,EAAoB,GAAsC;CAI/D,OAHI,EAAI,YAAY,EAAI,eAAe,IAC5B,QAAQ,QAAQ,IAEpB,IAAI,SAAe,GAAS,MAAW;EAC1C,IAAM,UAAqB;GAEvB,AADA,EAAQ,GACR,EAAQ;EACZ,GACM,UAAsB;GAExB,AADA,EAAQ,GACR,EAAO,IAAI,EAAe,sDAAsD,CAAC;EACrF,GACM,UAAsB;GAExB,AADA,EAAI,oBAAoB,QAAQ,CAAM,GACtC,EAAI,oBAAoB,SAAS,CAAO;EAC5C;EAEA,AADA,EAAI,iBAAiB,QAAQ,GAAQ,EAAE,MAAM,GAAK,CAAC,GACnD,EAAI,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC;CACzD,CAAC;AACL;AAEA,SAAS,EAAc,GAA6B,GAAe,GAA0B;CACzF,IAAI,MAAU,KAAK,MAAW,GAC1B,MAAM,IAAI,EAAe,0CAA0C,EAAM,GAAG,EAAO,GAAG;CAG1F,IAAM,IAAM,EADG,EAAa,GAAO,CACV,CAAM;CAG/B,OAFA,EAAI,UAAU,GAAU,GAAG,CAAC,GAErB,EADW,EAAI,aAAa,GAAG,GAAG,GAAO,CAC1B,CAAS;AACnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labels.cjs","names":[],"sources":["../../src/vision/labels.ts"],"sourcesContent":["/**\n * Class label resolution: presets, lists, dicts, or auto-generated.\n *\n * Tasks call {@link resolveLabels} once at construction time to turn whatever\n * the caller passed (preset name, array, dict, or `null`) into an ordered\n * array of class names indexed by class id.\n *\n * In the browser there is no filesystem, so this module does not load labels\n * from a path — fetch the file yourself and pass an array.\n */\n\nimport { LabelMapError } from \"./core/exceptions\";\n\n/**\n * Anything accepted by {@link resolveLabels}.\n *\n * - `string[]` / `readonly string[]`: explicit names indexed by class id.\n * - `Record<number, string>`: sparse mapping (gaps filled with `class_<id>`).\n * - `string`: a preset name (e.g. `\"coco\"`).\n * - `null` / `undefined`: auto-generate `class_0` ... `class_{numClasses-1}`.\n */\nexport type LabelSpec = readonly string[] | Record<number, string> | string | null | undefined;\n\n/** COCO 2017 80-class labels in canonical class-id order. */\nexport const COCO_CLASSES: readonly string[] = Object.freeze([\n \"person\",\n \"bicycle\",\n \"car\",\n \"motorcycle\",\n \"airplane\",\n \"bus\",\n \"train\",\n \"truck\",\n \"boat\",\n \"traffic light\",\n \"fire hydrant\",\n \"stop sign\",\n \"parking meter\",\n \"bench\",\n \"bird\",\n \"cat\",\n \"dog\",\n \"horse\",\n \"sheep\",\n \"cow\",\n \"elephant\",\n \"bear\",\n \"zebra\",\n \"giraffe\",\n \"backpack\",\n \"umbrella\",\n \"handbag\",\n \"tie\",\n \"suitcase\",\n \"frisbee\",\n \"skis\",\n \"snowboard\",\n \"sports ball\",\n \"kite\",\n \"baseball bat\",\n \"baseball glove\",\n \"skateboard\",\n \"surfboard\",\n \"tennis racket\",\n \"bottle\",\n \"wine glass\",\n \"cup\",\n \"fork\",\n \"knife\",\n \"spoon\",\n \"bowl\",\n \"banana\",\n \"apple\",\n \"sandwich\",\n \"orange\",\n \"broccoli\",\n \"carrot\",\n \"hot dog\",\n \"pizza\",\n \"donut\",\n \"cake\",\n \"chair\",\n \"couch\",\n \"potted plant\",\n \"bed\",\n \"dining table\",\n \"toilet\",\n \"tv\",\n \"laptop\",\n \"mouse\",\n \"remote\",\n \"keyboard\",\n \"cell phone\",\n \"microwave\",\n \"oven\",\n \"toaster\",\n \"sink\",\n \"refrigerator\",\n \"book\",\n \"clock\",\n \"vase\",\n \"scissors\",\n \"teddy bear\",\n \"hair drier\",\n \"toothbrush\",\n]);\n\nconst PRESETS: Readonly<Record<string, readonly string[]>> = {\n coco: COCO_CLASSES,\n};\n\nexport interface ResolveLabelsOptions {\n /**\n * Expected number of classes.\n *\n * - When `spec` is `null`/`undefined`, this is required to auto-generate names.\n * - When `spec` is provided, it validates that the resolved length matches.\n */\n readonly numClasses?: number;\n}\n\n/**\n * Resolve a labels specification into an ordered array of class names.\n *\n * @throws {@link LabelMapError} if the spec is invalid, the preset is unknown,\n * or the resolved length disagrees with `numClasses`.\n */\nexport function resolveLabels(\n spec: LabelSpec,\n options: ResolveLabelsOptions = {},\n): readonly string[] {\n const labels = resolve(spec, options.numClasses);\n if (options.numClasses !== undefined && labels.length !== options.numClasses) {\n throw new LabelMapError(\n `Resolved ${labels.length} labels but the model has ${options.numClasses} classes.`,\n );\n }\n return labels;\n}\n\nfunction resolve(spec: LabelSpec, numClasses: number | undefined): readonly string[] {\n if (spec === null || spec === undefined) {\n if (numClasses === undefined) {\n throw new LabelMapError(\n \"Cannot auto-generate labels without numClasses. Pass an explicit labels spec or numClasses.\",\n );\n }\n return Array.from({ length: numClasses }, (_, i) => `class_${i}`);\n }\n\n if (Array.isArray(spec)) {\n return [...spec];\n }\n\n if (typeof spec === \"string\") {\n const preset = PRESETS[spec];\n if (preset !== undefined) {\n return preset;\n }\n throw new LabelMapError(\n `Unknown labels preset: ${JSON.stringify(spec)}. Known presets: ${Object.keys(PRESETS).join(\", \")}.`,\n );\n }\n\n if (typeof spec === \"object\") {\n const map = spec as Record<number, string>;\n const ids = Object.keys(map).map((k) => Number(k));\n if (ids.length === 0) {\n return [];\n }\n const maxId = Math.max(...ids);\n return Array.from({ length: maxId + 1 }, (_, i) => map[i] ?? `class_${i}`);\n }\n\n throw new LabelMapError(`Unsupported labels spec type: ${typeof spec}.`);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"labels.cjs","names":[],"sources":["../../src/vision/labels.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Class label resolution: presets, lists, dicts, or auto-generated.\n *\n * Tasks call {@link resolveLabels} once at construction time to turn whatever\n * the caller passed (preset name, array, dict, or `null`) into an ordered\n * array of class names indexed by class id.\n *\n * In the browser there is no filesystem, so this module does not load labels\n * from a path — fetch the file yourself and pass an array.\n */\n\nimport { LabelMapError } from \"./core/exceptions\";\n\n/**\n * Anything accepted by {@link resolveLabels}.\n *\n * - `string[]` / `readonly string[]`: explicit names indexed by class id.\n * - `Record<number, string>`: sparse mapping (gaps filled with `class_<id>`).\n * - `string`: a preset name (e.g. `\"coco\"`).\n * - `null` / `undefined`: auto-generate `class_0` ... `class_{numClasses-1}`.\n */\nexport type LabelSpec = readonly string[] | Record<number, string> | string | null | undefined;\n\n/** COCO 2017 80-class labels in canonical class-id order. */\nexport const COCO_CLASSES: readonly string[] = Object.freeze([\n \"person\",\n \"bicycle\",\n \"car\",\n \"motorcycle\",\n \"airplane\",\n \"bus\",\n \"train\",\n \"truck\",\n \"boat\",\n \"traffic light\",\n \"fire hydrant\",\n \"stop sign\",\n \"parking meter\",\n \"bench\",\n \"bird\",\n \"cat\",\n \"dog\",\n \"horse\",\n \"sheep\",\n \"cow\",\n \"elephant\",\n \"bear\",\n \"zebra\",\n \"giraffe\",\n \"backpack\",\n \"umbrella\",\n \"handbag\",\n \"tie\",\n \"suitcase\",\n \"frisbee\",\n \"skis\",\n \"snowboard\",\n \"sports ball\",\n \"kite\",\n \"baseball bat\",\n \"baseball glove\",\n \"skateboard\",\n \"surfboard\",\n \"tennis racket\",\n \"bottle\",\n \"wine glass\",\n \"cup\",\n \"fork\",\n \"knife\",\n \"spoon\",\n \"bowl\",\n \"banana\",\n \"apple\",\n \"sandwich\",\n \"orange\",\n \"broccoli\",\n \"carrot\",\n \"hot dog\",\n \"pizza\",\n \"donut\",\n \"cake\",\n \"chair\",\n \"couch\",\n \"potted plant\",\n \"bed\",\n \"dining table\",\n \"toilet\",\n \"tv\",\n \"laptop\",\n \"mouse\",\n \"remote\",\n \"keyboard\",\n \"cell phone\",\n \"microwave\",\n \"oven\",\n \"toaster\",\n \"sink\",\n \"refrigerator\",\n \"book\",\n \"clock\",\n \"vase\",\n \"scissors\",\n \"teddy bear\",\n \"hair drier\",\n \"toothbrush\",\n]);\n\nconst PRESETS: Readonly<Record<string, readonly string[]>> = {\n coco: COCO_CLASSES,\n};\n\nexport interface ResolveLabelsOptions {\n /**\n * Expected number of classes.\n *\n * - When `spec` is `null`/`undefined`, this is required to auto-generate names.\n * - When `spec` is provided, it validates that the resolved length matches.\n */\n readonly numClasses?: number;\n}\n\n/**\n * Resolve a labels specification into an ordered array of class names.\n *\n * @throws {@link LabelMapError} if the spec is invalid, the preset is unknown,\n * or the resolved length disagrees with `numClasses`.\n */\nexport function resolveLabels(\n spec: LabelSpec,\n options: ResolveLabelsOptions = {},\n): readonly string[] {\n const labels = resolve(spec, options.numClasses);\n if (options.numClasses !== undefined && labels.length !== options.numClasses) {\n throw new LabelMapError(\n `Resolved ${labels.length} labels but the model has ${options.numClasses} classes.`,\n );\n }\n return labels;\n}\n\nfunction resolve(spec: LabelSpec, numClasses: number | undefined): readonly string[] {\n if (spec === null || spec === undefined) {\n if (numClasses === undefined) {\n throw new LabelMapError(\n \"Cannot auto-generate labels without numClasses. Pass an explicit labels spec or numClasses.\",\n );\n }\n return Array.from({ length: numClasses }, (_, i) => `class_${i}`);\n }\n\n if (Array.isArray(spec)) {\n return [...spec];\n }\n\n if (typeof spec === \"string\") {\n const preset = PRESETS[spec];\n if (preset !== undefined) {\n return preset;\n }\n throw new LabelMapError(\n `Unknown labels preset: ${JSON.stringify(spec)}. Known presets: ${Object.keys(PRESETS).join(\", \")}.`,\n );\n }\n\n if (typeof spec === \"object\") {\n const map = spec as Record<number, string>;\n const ids = Object.keys(map).map((k) => Number(k));\n if (ids.length === 0) {\n return [];\n }\n const maxId = Math.max(...ids);\n return Array.from({ length: maxId + 1 }, (_, i) => map[i] ?? `class_${i}`);\n }\n\n throw new LabelMapError(`Unsupported labels spec type: ${typeof spec}.`);\n}\n"],"mappings":"yCAyBA,IAAa,EAAkC,OAAO,OAAO,wnBAiF7D,CAAC,EAEK,EAAuD,CACzD,KAAM,CACV,EAkBA,SAAgB,EACZ,EACA,EAAgC,CAAC,EAChB,CACjB,IAAM,EAAS,EAAQ,EAAM,EAAQ,UAAU,EAC/C,GAAI,EAAQ,aAAe,IAAA,IAAa,EAAO,SAAW,EAAQ,WAC9D,MAAM,IAAI,EAAA,cACN,YAAY,EAAO,OAAO,4BAA4B,EAAQ,WAAW,UAC7E,EAEJ,OAAO,CACX,CAEA,SAAS,EAAQ,EAAiB,EAAmD,CACjF,GAAI,GAAS,KAA4B,CACrC,GAAI,IAAe,IAAA,GACf,MAAM,IAAI,EAAA,cACN,6FACJ,EAEJ,OAAO,MAAM,KAAK,CAAE,OAAQ,CAAW,GAAI,EAAG,IAAM,SAAS,GAAG,CACpE,CAEA,GAAI,MAAM,QAAQ,CAAI,EAClB,MAAO,CAAC,GAAG,CAAI,EAGnB,GAAI,OAAO,GAAS,SAAU,CAC1B,IAAM,EAAS,EAAQ,GACvB,GAAI,IAAW,IAAA,GACX,OAAO,EAEX,MAAM,IAAI,EAAA,cACN,0BAA0B,KAAK,UAAU,CAAI,EAAE,mBAAmB,OAAO,KAAK,CAAO,CAAC,CAAC,KAAK,IAAI,EAAE,EACtG,CACJ,CAEA,GAAI,OAAO,GAAS,SAAU,CAC1B,IAAM,EAAM,EACN,EAAM,OAAO,KAAK,CAAG,CAAC,CAAC,IAAK,GAAM,OAAO,CAAC,CAAC,EACjD,GAAI,EAAI,SAAW,EACf,MAAO,CAAC,EAEZ,IAAM,EAAQ,KAAK,IAAI,GAAG,CAAG,EAC7B,OAAO,MAAM,KAAK,CAAE,OAAQ,EAAQ,CAAE,GAAI,EAAG,IAAM,EAAI,IAAM,SAAS,GAAG,CAC7E,CAEA,MAAM,IAAI,EAAA,cAAc,iCAAiC,OAAO,EAAK,EAAE,CAC3E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labels.js","names":[],"sources":["../../src/vision/labels.ts"],"sourcesContent":["/**\n * Class label resolution: presets, lists, dicts, or auto-generated.\n *\n * Tasks call {@link resolveLabels} once at construction time to turn whatever\n * the caller passed (preset name, array, dict, or `null`) into an ordered\n * array of class names indexed by class id.\n *\n * In the browser there is no filesystem, so this module does not load labels\n * from a path — fetch the file yourself and pass an array.\n */\n\nimport { LabelMapError } from \"./core/exceptions\";\n\n/**\n * Anything accepted by {@link resolveLabels}.\n *\n * - `string[]` / `readonly string[]`: explicit names indexed by class id.\n * - `Record<number, string>`: sparse mapping (gaps filled with `class_<id>`).\n * - `string`: a preset name (e.g. `\"coco\"`).\n * - `null` / `undefined`: auto-generate `class_0` ... `class_{numClasses-1}`.\n */\nexport type LabelSpec = readonly string[] | Record<number, string> | string | null | undefined;\n\n/** COCO 2017 80-class labels in canonical class-id order. */\nexport const COCO_CLASSES: readonly string[] = Object.freeze([\n \"person\",\n \"bicycle\",\n \"car\",\n \"motorcycle\",\n \"airplane\",\n \"bus\",\n \"train\",\n \"truck\",\n \"boat\",\n \"traffic light\",\n \"fire hydrant\",\n \"stop sign\",\n \"parking meter\",\n \"bench\",\n \"bird\",\n \"cat\",\n \"dog\",\n \"horse\",\n \"sheep\",\n \"cow\",\n \"elephant\",\n \"bear\",\n \"zebra\",\n \"giraffe\",\n \"backpack\",\n \"umbrella\",\n \"handbag\",\n \"tie\",\n \"suitcase\",\n \"frisbee\",\n \"skis\",\n \"snowboard\",\n \"sports ball\",\n \"kite\",\n \"baseball bat\",\n \"baseball glove\",\n \"skateboard\",\n \"surfboard\",\n \"tennis racket\",\n \"bottle\",\n \"wine glass\",\n \"cup\",\n \"fork\",\n \"knife\",\n \"spoon\",\n \"bowl\",\n \"banana\",\n \"apple\",\n \"sandwich\",\n \"orange\",\n \"broccoli\",\n \"carrot\",\n \"hot dog\",\n \"pizza\",\n \"donut\",\n \"cake\",\n \"chair\",\n \"couch\",\n \"potted plant\",\n \"bed\",\n \"dining table\",\n \"toilet\",\n \"tv\",\n \"laptop\",\n \"mouse\",\n \"remote\",\n \"keyboard\",\n \"cell phone\",\n \"microwave\",\n \"oven\",\n \"toaster\",\n \"sink\",\n \"refrigerator\",\n \"book\",\n \"clock\",\n \"vase\",\n \"scissors\",\n \"teddy bear\",\n \"hair drier\",\n \"toothbrush\",\n]);\n\nconst PRESETS: Readonly<Record<string, readonly string[]>> = {\n coco: COCO_CLASSES,\n};\n\nexport interface ResolveLabelsOptions {\n /**\n * Expected number of classes.\n *\n * - When `spec` is `null`/`undefined`, this is required to auto-generate names.\n * - When `spec` is provided, it validates that the resolved length matches.\n */\n readonly numClasses?: number;\n}\n\n/**\n * Resolve a labels specification into an ordered array of class names.\n *\n * @throws {@link LabelMapError} if the spec is invalid, the preset is unknown,\n * or the resolved length disagrees with `numClasses`.\n */\nexport function resolveLabels(\n spec: LabelSpec,\n options: ResolveLabelsOptions = {},\n): readonly string[] {\n const labels = resolve(spec, options.numClasses);\n if (options.numClasses !== undefined && labels.length !== options.numClasses) {\n throw new LabelMapError(\n `Resolved ${labels.length} labels but the model has ${options.numClasses} classes.`,\n );\n }\n return labels;\n}\n\nfunction resolve(spec: LabelSpec, numClasses: number | undefined): readonly string[] {\n if (spec === null || spec === undefined) {\n if (numClasses === undefined) {\n throw new LabelMapError(\n \"Cannot auto-generate labels without numClasses. Pass an explicit labels spec or numClasses.\",\n );\n }\n return Array.from({ length: numClasses }, (_, i) => `class_${i}`);\n }\n\n if (Array.isArray(spec)) {\n return [...spec];\n }\n\n if (typeof spec === \"string\") {\n const preset = PRESETS[spec];\n if (preset !== undefined) {\n return preset;\n }\n throw new LabelMapError(\n `Unknown labels preset: ${JSON.stringify(spec)}. Known presets: ${Object.keys(PRESETS).join(\", \")}.`,\n );\n }\n\n if (typeof spec === \"object\") {\n const map = spec as Record<number, string>;\n const ids = Object.keys(map).map((k) => Number(k));\n if (ids.length === 0) {\n return [];\n }\n const maxId = Math.max(...ids);\n return Array.from({ length: maxId + 1 }, (_, i) => map[i] ?? `class_${i}`);\n }\n\n throw new LabelMapError(`Unsupported labels spec type: ${typeof spec}.`);\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"labels.js","names":[],"sources":["../../src/vision/labels.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Class label resolution: presets, lists, dicts, or auto-generated.\n *\n * Tasks call {@link resolveLabels} once at construction time to turn whatever\n * the caller passed (preset name, array, dict, or `null`) into an ordered\n * array of class names indexed by class id.\n *\n * In the browser there is no filesystem, so this module does not load labels\n * from a path — fetch the file yourself and pass an array.\n */\n\nimport { LabelMapError } from \"./core/exceptions\";\n\n/**\n * Anything accepted by {@link resolveLabels}.\n *\n * - `string[]` / `readonly string[]`: explicit names indexed by class id.\n * - `Record<number, string>`: sparse mapping (gaps filled with `class_<id>`).\n * - `string`: a preset name (e.g. `\"coco\"`).\n * - `null` / `undefined`: auto-generate `class_0` ... `class_{numClasses-1}`.\n */\nexport type LabelSpec = readonly string[] | Record<number, string> | string | null | undefined;\n\n/** COCO 2017 80-class labels in canonical class-id order. */\nexport const COCO_CLASSES: readonly string[] = Object.freeze([\n \"person\",\n \"bicycle\",\n \"car\",\n \"motorcycle\",\n \"airplane\",\n \"bus\",\n \"train\",\n \"truck\",\n \"boat\",\n \"traffic light\",\n \"fire hydrant\",\n \"stop sign\",\n \"parking meter\",\n \"bench\",\n \"bird\",\n \"cat\",\n \"dog\",\n \"horse\",\n \"sheep\",\n \"cow\",\n \"elephant\",\n \"bear\",\n \"zebra\",\n \"giraffe\",\n \"backpack\",\n \"umbrella\",\n \"handbag\",\n \"tie\",\n \"suitcase\",\n \"frisbee\",\n \"skis\",\n \"snowboard\",\n \"sports ball\",\n \"kite\",\n \"baseball bat\",\n \"baseball glove\",\n \"skateboard\",\n \"surfboard\",\n \"tennis racket\",\n \"bottle\",\n \"wine glass\",\n \"cup\",\n \"fork\",\n \"knife\",\n \"spoon\",\n \"bowl\",\n \"banana\",\n \"apple\",\n \"sandwich\",\n \"orange\",\n \"broccoli\",\n \"carrot\",\n \"hot dog\",\n \"pizza\",\n \"donut\",\n \"cake\",\n \"chair\",\n \"couch\",\n \"potted plant\",\n \"bed\",\n \"dining table\",\n \"toilet\",\n \"tv\",\n \"laptop\",\n \"mouse\",\n \"remote\",\n \"keyboard\",\n \"cell phone\",\n \"microwave\",\n \"oven\",\n \"toaster\",\n \"sink\",\n \"refrigerator\",\n \"book\",\n \"clock\",\n \"vase\",\n \"scissors\",\n \"teddy bear\",\n \"hair drier\",\n \"toothbrush\",\n]);\n\nconst PRESETS: Readonly<Record<string, readonly string[]>> = {\n coco: COCO_CLASSES,\n};\n\nexport interface ResolveLabelsOptions {\n /**\n * Expected number of classes.\n *\n * - When `spec` is `null`/`undefined`, this is required to auto-generate names.\n * - When `spec` is provided, it validates that the resolved length matches.\n */\n readonly numClasses?: number;\n}\n\n/**\n * Resolve a labels specification into an ordered array of class names.\n *\n * @throws {@link LabelMapError} if the spec is invalid, the preset is unknown,\n * or the resolved length disagrees with `numClasses`.\n */\nexport function resolveLabels(\n spec: LabelSpec,\n options: ResolveLabelsOptions = {},\n): readonly string[] {\n const labels = resolve(spec, options.numClasses);\n if (options.numClasses !== undefined && labels.length !== options.numClasses) {\n throw new LabelMapError(\n `Resolved ${labels.length} labels but the model has ${options.numClasses} classes.`,\n );\n }\n return labels;\n}\n\nfunction resolve(spec: LabelSpec, numClasses: number | undefined): readonly string[] {\n if (spec === null || spec === undefined) {\n if (numClasses === undefined) {\n throw new LabelMapError(\n \"Cannot auto-generate labels without numClasses. Pass an explicit labels spec or numClasses.\",\n );\n }\n return Array.from({ length: numClasses }, (_, i) => `class_${i}`);\n }\n\n if (Array.isArray(spec)) {\n return [...spec];\n }\n\n if (typeof spec === \"string\") {\n const preset = PRESETS[spec];\n if (preset !== undefined) {\n return preset;\n }\n throw new LabelMapError(\n `Unknown labels preset: ${JSON.stringify(spec)}. Known presets: ${Object.keys(PRESETS).join(\", \")}.`,\n );\n }\n\n if (typeof spec === \"object\") {\n const map = spec as Record<number, string>;\n const ids = Object.keys(map).map((k) => Number(k));\n if (ids.length === 0) {\n return [];\n }\n const maxId = Math.max(...ids);\n return Array.from({ length: maxId + 1 }, (_, i) => map[i] ?? `class_${i}`);\n }\n\n throw new LabelMapError(`Unsupported labels spec type: ${typeof spec}.`);\n}\n"],"mappings":";;AAyBA,IAAa,IAAkC,OAAO,OAAO,woBAiF7D,CAAC,GAEK,IAAuD,EACzD,MAAM,EACV;AAkBA,SAAgB,EACZ,GACA,IAAgC,CAAC,GAChB;CACjB,IAAM,IAAS,EAAQ,GAAM,EAAQ,UAAU;CAC/C,IAAI,EAAQ,eAAe,KAAA,KAAa,EAAO,WAAW,EAAQ,YAC9D,MAAM,IAAI,EACN,YAAY,EAAO,OAAO,4BAA4B,EAAQ,WAAW,UAC7E;CAEJ,OAAO;AACX;AAEA,SAAS,EAAQ,GAAiB,GAAmD;CACjF,IAAI,KAAS,MAA4B;EACrC,IAAI,MAAe,KAAA,GACf,MAAM,IAAI,EACN,6FACJ;EAEJ,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAW,IAAI,GAAG,MAAM,SAAS,GAAG;CACpE;CAEA,IAAI,MAAM,QAAQ,CAAI,GAClB,OAAO,CAAC,GAAG,CAAI;CAGnB,IAAI,OAAO,KAAS,UAAU;EAC1B,IAAM,IAAS,EAAQ;EACvB,IAAI,MAAW,KAAA,GACX,OAAO;EAEX,MAAM,IAAI,EACN,0BAA0B,KAAK,UAAU,CAAI,EAAE,mBAAmB,OAAO,KAAK,CAAO,CAAC,CAAC,KAAK,IAAI,EAAE,EACtG;CACJ;CAEA,IAAI,OAAO,KAAS,UAAU;EAC1B,IAAM,IAAM,GACN,IAAM,OAAO,KAAK,CAAG,CAAC,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC;EACjD,IAAI,EAAI,WAAW,GACf,OAAO,CAAC;EAEZ,IAAM,IAAQ,KAAK,IAAI,GAAG,CAAG;EAC7B,OAAO,MAAM,KAAK,EAAE,QAAQ,IAAQ,EAAE,IAAI,GAAG,MAAM,EAAI,MAAM,SAAS,GAAG;CAC7E;CAEA,MAAM,IAAI,EAAc,iCAAiC,OAAO,EAAK,EAAE;AAC3E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"luminance.cjs","names":[],"sources":["../../src/vision/luminance.ts"],"sourcesContent":["/**\n * Frame-brightness helpers — measure the mean luminance of an already-decoded\n * frame (`<img>`, `<video>`, `<canvas>`, `ImageBitmap` or `OffscreenCanvas`) so\n * a UI can reject underexposed captures before paying the cost of downstream\n * inference.\n *\n * These are framework-agnostic pure functions; {@link useLiveLuminance} wires\n * {@link computeImageLuminance} into a React `requestAnimationFrame` loop for\n * live camera feedback.\n */\n\n/**\n * Longest edge (in pixels) the source is downsampled to before sampling.\n * Averaging over a small downsample is statistically equivalent for a\n * brightness threshold and orders of magnitude faster than reading every pixel\n * of a full-resolution camera frame.\n */\nexport const LUMINANCE_SAMPLE_MAX_EDGE = 256;\n\n/**\n * Drawable source we can sample luminance from.\n *\n * The list tracks what `CanvasRenderingContext2D.drawImage` accepts and we can\n * read a pixel size off, which is what the implementation actually needs.\n * `ImageBitmap` matters for the decode-downscaled path: `createImageBitmap(blob,\n * { resizeWidth })` is how a caller avoids materialising a full-resolution\n * phone photo, and the frame it hands back is the frame whose brightness has to\n * be checked.\n */\nexport type LuminanceSource =\n HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas;\n\n/**\n * Natural pixel size of the source (`0`/`0` while it is still unloaded).\n *\n * `ImageBitmap` and `OffscreenCanvas` both expose plain `width`/`height`, so\n * they fall through to the same branch as a canvas — but they are named\n * explicitly rather than left to the `naturalWidth || width` fallback, which\n * only reads as intentional for an `<img>`.\n */\nfunction sourceSize(source: LuminanceSource): { width: number; height: number } {\n if (source instanceof HTMLVideoElement) {\n return { width: source.videoWidth, height: source.videoHeight };\n }\n if (source instanceof HTMLImageElement) {\n return {\n width: source.naturalWidth || source.width,\n height: source.naturalHeight || source.height,\n };\n }\n return { width: source.width, height: source.height };\n}\n\n/**\n * Mean BT.709 luminance (`0.2126*R + 0.7152*G + 0.0722*B`) of a decoded frame,\n * scaled to `0..255`. See {@link LuminanceSource} for what counts as one.\n *\n * The source is downsampled so its longest edge is at most\n * {@link LUMINANCE_SAMPLE_MAX_EDGE} before pixels are read. The 2D context is\n * created with `willReadFrequently` so repeated sampling (live feedback) stays\n * on the fast path.\n *\n * Pass `reusableCanvas` to avoid allocating a fresh canvas every frame in a hot\n * loop; when omitted a one-shot detached canvas is created.\n *\n * @param source - the decoded frame to sample.\n * @param reusableCanvas - optional canvas reused across frames to avoid GC churn.\n * @returns The mean luminance in `0..255`, or `0` when the source is unloaded\n * (zero-sized) or a 2D context is unavailable.\n */\nexport function computeImageLuminance(\n source: LuminanceSource,\n reusableCanvas?: HTMLCanvasElement,\n): number {\n const { width: srcW, height: srcH } = sourceSize(source);\n if (srcW === 0 || srcH === 0) return 0;\n\n const scale = Math.min(1, LUMINANCE_SAMPLE_MAX_EDGE / Math.max(srcW, srcH));\n const w = Math.max(1, Math.round(srcW * scale));\n const h = Math.max(1, Math.round(srcH * scale));\n\n const canvas = reusableCanvas ?? document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) return 0;\n ctx.drawImage(source, 0, 0, w, h);\n\n const data = ctx.getImageData(0, 0, w, h).data;\n let sum = 0;\n const pixelCount = w * h;\n for (let i = 0; i < data.length; i += 4) {\n sum += 0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2];\n }\n return sum / pixelCount;\n}\n\n/**\n * Whether a measured luminance clears a brightness threshold.\n *\n * `threshold` is intentionally required — a sensible value is\n * application-specific (it depends on the model, the lighting the model was\n * trained on, and the acceptable false-reject rate), so the SDK does not bake\n * in a default.\n *\n * @param luminance - measured mean luminance in `0..255`.\n * @param threshold - minimum acceptable luminance in `0..255`.\n * @returns `true` when `luminance >= threshold`.\n */\nexport function isLuminanceAcceptable(luminance: number, threshold: number): boolean {\n return luminance >= threshold;\n}\n\n/**\n * Error raised when a captured frame is too dark to be analysed reliably.\n * Carries the measured luminance and the threshold it failed so callers can\n * surface actionable feedback.\n */\nexport class LowLuminanceError extends Error {\n /** Measured mean luminance, `0..255`. */\n readonly luminance: number;\n /** Threshold that was checked against, `0..255`. */\n readonly threshold: number;\n\n /**\n * @param luminance - the measured mean luminance in `0..255`.\n * @param threshold - the threshold the measurement failed to reach.\n */\n constructor(luminance: number, threshold: number) {\n super(\"Image is too dark to analyse. Capture again in a brighter environment.\");\n this.name = \"LowLuminanceError\";\n this.luminance = luminance;\n this.threshold = threshold;\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"luminance.cjs","names":[],"sources":["../../src/vision/luminance.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Frame-brightness helpers — measure the mean luminance of an already-decoded\n * frame (`<img>`, `<video>`, `<canvas>`, `ImageBitmap` or `OffscreenCanvas`) so\n * a UI can reject underexposed captures before paying the cost of downstream\n * inference.\n *\n * These are framework-agnostic pure functions; {@link useLiveLuminance} wires\n * {@link computeImageLuminance} into a React `requestAnimationFrame` loop for\n * live camera feedback.\n */\n\n/**\n * Longest edge (in pixels) the source is downsampled to before sampling.\n * Averaging over a small downsample is statistically equivalent for a\n * brightness threshold and orders of magnitude faster than reading every pixel\n * of a full-resolution camera frame.\n */\nexport const LUMINANCE_SAMPLE_MAX_EDGE = 256;\n\n/**\n * Drawable source we can sample luminance from.\n *\n * The list tracks what `CanvasRenderingContext2D.drawImage` accepts and we can\n * read a pixel size off, which is what the implementation actually needs.\n * `ImageBitmap` matters for the decode-downscaled path: `createImageBitmap(blob,\n * { resizeWidth })` is how a caller avoids materialising a full-resolution\n * phone photo, and the frame it hands back is the frame whose brightness has to\n * be checked.\n */\nexport type LuminanceSource =\n HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas;\n\n/**\n * Natural pixel size of the source (`0`/`0` while it is still unloaded).\n *\n * `ImageBitmap` and `OffscreenCanvas` both expose plain `width`/`height`, so\n * they fall through to the same branch as a canvas — but they are named\n * explicitly rather than left to the `naturalWidth || width` fallback, which\n * only reads as intentional for an `<img>`.\n */\nfunction sourceSize(source: LuminanceSource): { width: number; height: number } {\n if (source instanceof HTMLVideoElement) {\n return { width: source.videoWidth, height: source.videoHeight };\n }\n if (source instanceof HTMLImageElement) {\n return {\n width: source.naturalWidth || source.width,\n height: source.naturalHeight || source.height,\n };\n }\n return { width: source.width, height: source.height };\n}\n\n/**\n * Mean BT.709 luminance (`0.2126*R + 0.7152*G + 0.0722*B`) of a decoded frame,\n * scaled to `0..255`. See {@link LuminanceSource} for what counts as one.\n *\n * The source is downsampled so its longest edge is at most\n * {@link LUMINANCE_SAMPLE_MAX_EDGE} before pixels are read. The 2D context is\n * created with `willReadFrequently` so repeated sampling (live feedback) stays\n * on the fast path.\n *\n * Pass `reusableCanvas` to avoid allocating a fresh canvas every frame in a hot\n * loop; when omitted a one-shot detached canvas is created.\n *\n * @param source - the decoded frame to sample.\n * @param reusableCanvas - optional canvas reused across frames to avoid GC churn.\n * @returns The mean luminance in `0..255`, or `0` when the source is unloaded\n * (zero-sized) or a 2D context is unavailable.\n */\nexport function computeImageLuminance(\n source: LuminanceSource,\n reusableCanvas?: HTMLCanvasElement,\n): number {\n const { width: srcW, height: srcH } = sourceSize(source);\n if (srcW === 0 || srcH === 0) return 0;\n\n const scale = Math.min(1, LUMINANCE_SAMPLE_MAX_EDGE / Math.max(srcW, srcH));\n const w = Math.max(1, Math.round(srcW * scale));\n const h = Math.max(1, Math.round(srcH * scale));\n\n const canvas = reusableCanvas ?? document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) return 0;\n ctx.drawImage(source, 0, 0, w, h);\n\n const data = ctx.getImageData(0, 0, w, h).data;\n let sum = 0;\n const pixelCount = w * h;\n for (let i = 0; i < data.length; i += 4) {\n sum += 0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2];\n }\n return sum / pixelCount;\n}\n\n/**\n * Whether a measured luminance clears a brightness threshold.\n *\n * `threshold` is intentionally required — a sensible value is\n * application-specific (it depends on the model, the lighting the model was\n * trained on, and the acceptable false-reject rate), so the SDK does not bake\n * in a default.\n *\n * @param luminance - measured mean luminance in `0..255`.\n * @param threshold - minimum acceptable luminance in `0..255`.\n * @returns `true` when `luminance >= threshold`.\n */\nexport function isLuminanceAcceptable(luminance: number, threshold: number): boolean {\n return luminance >= threshold;\n}\n\n/**\n * Error raised when a captured frame is too dark to be analysed reliably.\n * Carries the measured luminance and the threshold it failed so callers can\n * surface actionable feedback.\n */\nexport class LowLuminanceError extends Error {\n /** Measured mean luminance, `0..255`. */\n readonly luminance: number;\n /** Threshold that was checked against, `0..255`. */\n readonly threshold: number;\n\n /**\n * @param luminance - the measured mean luminance in `0..255`.\n * @param threshold - the threshold the measurement failed to reach.\n */\n constructor(luminance: number, threshold: number) {\n super(\"Image is too dark to analyse. Capture again in a brighter environment.\");\n this.name = \"LowLuminanceError\";\n this.luminance = luminance;\n this.threshold = threshold;\n }\n}\n"],"mappings":"AAkBA,IAAa,EAA4B,IAuBzC,SAAS,EAAW,EAA4D,CAU5E,OATI,aAAkB,iBACX,CAAE,MAAO,EAAO,WAAY,OAAQ,EAAO,WAAY,EAE9D,aAAkB,iBACX,CACH,MAAO,EAAO,cAAgB,EAAO,MACrC,OAAQ,EAAO,eAAiB,EAAO,MAC3C,EAEG,CAAE,MAAO,EAAO,MAAO,OAAQ,EAAO,MAAO,CACxD,CAmBA,SAAgB,EACZ,EACA,EACM,CACN,GAAM,CAAE,MAAO,EAAM,OAAQ,GAAS,EAAW,CAAM,EACvD,GAAI,IAAS,GAAK,IAAS,EAAG,MAAO,GAErC,IAAM,EAAQ,KAAK,IAAI,EAAA,IAA+B,KAAK,IAAI,EAAM,CAAI,CAAC,EACpE,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAO,CAAK,CAAC,EACxC,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAO,CAAK,CAAC,EAExC,EAAS,GAAkB,SAAS,cAAc,QAAQ,EAChE,EAAO,MAAQ,EACf,EAAO,OAAS,EAChB,IAAM,EAAM,EAAO,WAAW,KAAM,CAAE,mBAAoB,EAAK,CAAC,EAChE,GAAI,CAAC,EAAK,MAAO,GACjB,EAAI,UAAU,EAAQ,EAAG,EAAG,EAAG,CAAC,EAEhC,IAAM,EAAO,EAAI,aAAa,EAAG,EAAG,EAAG,CAAC,CAAC,CAAC,KACtC,EAAM,EACJ,EAAa,EAAI,EACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,GAAK,EAClC,GAAO,MAAS,EAAK,GAAK,MAAS,EAAK,EAAI,GAAK,MAAS,EAAK,EAAI,GAEvE,OAAO,EAAM,CACjB,CAcA,SAAgB,EAAsB,EAAmB,EAA4B,CACjF,OAAO,GAAa,CACxB,CAOA,IAAa,EAAb,cAAuC,KAAM,CAEzC,UAEA,UAMA,YAAY,EAAmB,EAAmB,CAC9C,MAAM,wEAAwE,EAC9E,KAAK,KAAO,oBACZ,KAAK,UAAY,EACjB,KAAK,UAAY,CACrB,CACJ"}
|