diff --git a/.agents/skills/react-native-vision-camera-mlkit/SKILL.md b/.agents/skills/react-native-vision-camera-mlkit/SKILL.md deleted file mode 100644 index 1721f1f..0000000 --- a/.agents/skills/react-native-vision-camera-mlkit/SKILL.md +++ /dev/null @@ -1,137 +0,0 @@ -```markdown -# react-native-vision-camera-mlkit Development Patterns - -> Auto-generated skill from repository analysis - -## Overview - -This skill teaches you how to contribute to the `react-native-vision-camera-mlkit` repository, a React Native module that integrates ML Kit features (like barcode scanning and text recognition) into mobile camera applications. You'll learn the project's coding conventions, commit patterns, and the main development workflows for adding features, improving code quality, updating iOS dependencies, and maintaining documentation. - ---- - -## Coding Conventions - -**File Naming** -- Use **PascalCase** for file and directory names. - - Example: `VisionCameraMLKitModule.swift`, `PluginRegistry.kt` - -**Import Style** -- Use **relative imports** in TypeScript/JavaScript. - - Example: - ```ts - import { BarcodeScanner } from './BarcodeScanner' - ``` - -**Export Style** -- Use **named exports**. - - Example: - ```ts - export const BarcodeScanner = { ... } - export type Barcode = { ... } - ``` - -**Commit Messages** -- Follow **Conventional Commits**: `fix:`, `feat:`, `chore:`, `docs:`, `perf:` -- Keep commit messages concise (~52 characters on average). - - Example: `feat: add face detection plugin for iOS` - ---- - -## Workflows - -### Add or Update Native ML Kit Feature -**Trigger:** When you want to add or significantly update a native ML Kit feature (e.g., barcode scanning, text recognition). -**Command:** `/add-mlkit-feature` - -1. **Android:** - - Add/update handlers, plugins, models, factories, adapters, serializers, and registry files under `android/src/main/java/com/visioncameramlkit/bridge/`. - - Update `android/build.gradle` if needed. -2. **iOS:** - - Add/update handlers, plugins, models, factories, adapters, serializers, and registry files under `ios/Bridge/`. - - Update `ios/VisionCameraMLKit.mm` and `ios/Infrastructure/Modules/VisionCameraMLKitModule.swift` as needed. -3. **Cross-platform:** - - Update or add TypeScript feature files: `src/features/*/index.ts`, `src/features/*/types.ts`, and `src/index.ts`. -4. **Example App:** - - Integrate the new or updated feature in `example/src/components/views/CameraView.tsx`, `example/src/screens/`, and `example/src/stores/`. - - Update iOS example project files: `example/ios/Podfile.lock`, `example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj`. -5. **Documentation:** - - Update `README.md` and/or create or edit `docs/feature.md` to document the new feature. - -**Example commit:** -```sh -feat: add text recognition support for Android -``` - ---- - -### Code Quality Fixes (Native) -**Trigger:** When you want to improve code quality, readability, or maintainability in native Android (Kotlin) and/or iOS (Swift) code. -**Command:** `/code-quality-native` - -1. Identify code quality issues in Android and/or iOS native code. -2. Refactor or clean up code in relevant files (handlers, plugins, models, modules, etc.). -3. Commit changes with a `fix:` or `chore:` message. - -**Example commit:** -```sh -chore: refactor plugin registry for clarity -``` - ---- - -### Update iOS Pods and Xcode Project -**Trigger:** When you need to update iOS dependencies (Pods) or adapt to new Xcode versions. -**Command:** `/update-ios-pods` - -1. Update `example/ios/Podfile` and/or `Podfile.lock` as needed. -2. Update `example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj` for project configuration changes. -3. Commit with a `chore(xcode):` or similar message. - -**Example commit:** -```sh -chore(xcode): update Podfile for Xcode 15 compatibility -``` - ---- - -### Documentation Update -**Trigger:** When you want to update documentation for new features, fixes, or developer guidance. -**Command:** `/update-docs` - -1. Edit `README.md` or any file under `docs/` to add, clarify, or reorganize information. -2. Commit with a `docs:` message. - -**Example commit:** -```sh -docs: add usage example for barcode scanning -``` - ---- - -## Testing Patterns - -- **Test File Naming:** Test files use the `*.test.*` pattern (e.g., `BarcodeScanner.test.ts`). -- **Testing Framework:** Not explicitly detected; check existing test files for framework usage. -- **Test Placement:** Tests are typically placed alongside the files they test. - -**Example:** -```ts -// BarcodeScanner.test.ts -import { BarcodeScanner } from './BarcodeScanner' - -test('scans a barcode', () => { - // ...test implementation -}) -``` - ---- - -## Commands - -| Command | Purpose | -|----------------------|----------------------------------------------------------------| -| /add-mlkit-feature | Add or update a native ML Kit feature (Android/iOS/TS/docs) | -| /code-quality-native | Refactor or improve code quality in native codebases | -| /update-ios-pods | Update iOS Podfile, Podfile.lock, or Xcode project files | -| /update-docs | Update documentation (README.md, docs/*.md) | -``` \ No newline at end of file diff --git a/.agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml b/.agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml deleted file mode 100644 index 590a783..0000000 --- a/.agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml +++ /dev/null @@ -1,6 +0,0 @@ -interface: - display_name: "React Native Vision Camera Mlkit" - short_description: "Repo-specific patterns and workflows for react-native-vision-camera-mlkit" - default_prompt: "Use the react-native-vision-camera-mlkit repo skill to follow existing architecture, testing, and workflow conventions." -policy: - allow_implicit_invocation: true \ No newline at end of file diff --git a/.claude/commands/add-or-update-native-mlkit-feature.md b/.claude/commands/add-or-update-native-mlkit-feature.md deleted file mode 100644 index 1ae3d8b..0000000 --- a/.claude/commands/add-or-update-native-mlkit-feature.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: add-or-update-native-mlkit-feature -description: Workflow command scaffold for add-or-update-native-mlkit-feature in react-native-vision-camera-mlkit. -allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"] ---- - -# /add-or-update-native-mlkit-feature - -Use this workflow when working on **add-or-update-native-mlkit-feature** in `react-native-vision-camera-mlkit`. - -## Goal - -Adds a new ML Kit feature (e.g., barcode scanning, text recognition) or updates an existing one, including native Android/iOS code, plugin registry, and example integration. - -## Common Files - -- `android/src/main/java/com/visioncameramlkit/bridge/handlers/*` -- `android/src/main/java/com/visioncameramlkit/bridge/plugins/*` -- `android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt` -- `android/src/main/java/com/visioncameramlkit/domain/models/*` -- `android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/*` -- `android/build.gradle` - -## Suggested Sequence - -1. Understand the current state and failure mode before editing. -2. Make the smallest coherent change that satisfies the workflow goal. -3. Run the most relevant verification for touched files. -4. Summarize what changed and what still needs review. - -## Typical Commit Signals - -- Add or update native Android files (handlers, plugins, models, factories, adapters, serializers, registry, build.gradle). -- Add or update native iOS files (handlers, plugins, models, factories, adapters, serializers, registry, VisionCameraMLKit.mm). -- Update or add cross-platform TypeScript files (feature index, types, src/index.ts). -- Update example app integration (screens, stores, CameraView, Podfile.lock, project.pbxproj). -- Update documentation (README.md, docs/feature.md). - -## Notes - -- Treat this as a scaffold, not a hard-coded script. -- Update the command if the workflow evolves materially. \ No newline at end of file diff --git a/.claude/commands/code-quality-fixes-native.md b/.claude/commands/code-quality-fixes-native.md deleted file mode 100644 index 93e985c..0000000 --- a/.claude/commands/code-quality-fixes-native.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: code-quality-fixes-native -description: Workflow command scaffold for code-quality-fixes-native in react-native-vision-camera-mlkit. -allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"] ---- - -# /code-quality-fixes-native - -Use this workflow when working on **code-quality-fixes-native** in `react-native-vision-camera-mlkit`. - -## Goal - -Performs code quality improvements or refactoring for native Android (Kotlin) and iOS (Swift) codebases, often in tandem. - -## Common Files - -- `android/src/main/java/com/visioncameramlkit/bridge/handlers/*` -- `android/src/main/java/com/visioncameramlkit/bridge/plugins/*` -- `android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt` -- `android/src/main/java/com/visioncameramlkit/domain/models/*` -- `android/src/main/java/com/visioncameramlkit/infrastructure/modules/VisionCameraMLKitModule.kt` -- `ios/Bridge/Handlers/*` - -## Suggested Sequence - -1. Understand the current state and failure mode before editing. -2. Make the smallest coherent change that satisfies the workflow goal. -3. Run the most relevant verification for touched files. -4. Summarize what changed and what still needs review. - -## Typical Commit Signals - -- Identify code quality issues in Android and/or iOS native code. -- Refactor or clean up code in multiple related files (handlers, plugins, models, modules, etc.). -- Commit changes with a fix or chore message. - -## Notes - -- Treat this as a scaffold, not a hard-coded script. -- Update the command if the workflow evolves materially. \ No newline at end of file diff --git a/.claude/commands/feature-development.md b/.claude/commands/feature-development.md deleted file mode 100644 index fad2168..0000000 --- a/.claude/commands/feature-development.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: feature-development -description: Workflow command scaffold for feature-development in react-native-vision-camera-mlkit. -allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"] ---- - -# /feature-development - -Use this workflow when working on **feature-development** in `react-native-vision-camera-mlkit`. - -## Goal - -Standard feature implementation workflow - -## Common Files - -- `example/src/screens/*` -- `example/src/components/ui/*` -- `example/src/stores/*` -- `**/*.test.*` - -## Suggested Sequence - -1. Understand the current state and failure mode before editing. -2. Make the smallest coherent change that satisfies the workflow goal. -3. Run the most relevant verification for touched files. -4. Summarize what changed and what still needs review. - -## Typical Commit Signals - -- Add feature implementation -- Add tests for feature -- Update documentation - -## Notes - -- Treat this as a scaffold, not a hard-coded script. -- Update the command if the workflow evolves materially. \ No newline at end of file diff --git a/.claude/ecc-tools.json b/.claude/ecc-tools.json deleted file mode 100644 index 6165044..0000000 --- a/.claude/ecc-tools.json +++ /dev/null @@ -1,286 +0,0 @@ -{ - "version": "1.3", - "schemaVersion": "1.0", - "generatedBy": "ecc-tools", - "generatedAt": "2026-07-05T23:56:54.166Z", - "repo": "https://github.com/pedrol2b/react-native-vision-camera-mlkit", - "referenceSetReadiness": { - "score": 0, - "present": 0, - "total": 7, - "items": [ - { - "id": "deep-analyzer-corpus", - "label": "Deep analyzer corpus", - "status": "missing", - "evidence": [], - "recommendation": "Add analyzer fixture, golden, benchmark, or reference-set files that can catch analyzer regressions." - }, - { - "id": "rag-evaluator", - "label": "RAG/evaluator comparison", - "status": "missing", - "evidence": [], - "recommendation": "Add retrieval or evaluator reference-set comparison fixtures with expected ranking behavior." - }, - { - "id": "pr-salvage", - "label": "PR salvage/review corpus", - "status": "missing", - "evidence": [], - "recommendation": "Add stale-PR, review-thread, reopen-flow, or salvage reference cases for queue cleanup automation." - }, - { - "id": "discussion-triage", - "label": "Discussion triage corpus", - "status": "missing", - "evidence": [], - "recommendation": "Add public discussion triage fixtures, golden cases, or reference sets for informational, answered, and no-response classifications." - }, - { - "id": "harness-compatibility", - "label": "Harness compatibility", - "status": "missing", - "evidence": [], - "recommendation": "Add cross-harness, adapter-compliance, or harness-audit evidence for Claude, Codex, OpenCode, Zed, dmux, and agent surfaces." - }, - { - "id": "security-evidence", - "label": "Security evidence", - "status": "missing", - "evidence": [], - "recommendation": "Attach security evidence such as SBOMs, SARIF, audit reports, or AgentShield evidence packs." - }, - { - "id": "ci-failure-mode", - "label": "CI failure-mode evidence", - "status": "missing", - "evidence": [], - "recommendation": "Add captured CI failure logs, dry-run fixtures, or troubleshooting docs for common workflow failure modes." - } - ] - }, - "profiles": { - "requested": "developer", - "recommended": "developer", - "effective": "developer", - "requestedAlias": "developer", - "recommendedAlias": "developer", - "effectiveAlias": "developer" - }, - "requestedProfile": "developer", - "profile": "developer", - "recommendedProfile": "developer", - "effectiveProfile": "developer", - "tier": "free", - "requestedComponents": [ - "repo-baseline", - "workflow-automation" - ], - "selectedComponents": [ - "repo-baseline", - "workflow-automation" - ], - "requestedAddComponents": [], - "requestedRemoveComponents": [], - "blockedRemovalComponents": [], - "tierFilteredComponents": [], - "requestedRootPackages": [ - "runtime-core", - "workflow-pack" - ], - "selectedRootPackages": [ - "runtime-core", - "workflow-pack" - ], - "requestedPackages": [ - "runtime-core", - "workflow-pack" - ], - "requestedAddPackages": [], - "requestedRemovePackages": [], - "selectedPackages": [ - "runtime-core", - "workflow-pack" - ], - "packages": [ - "runtime-core", - "workflow-pack" - ], - "blockedRemovalPackages": [], - "tierFilteredRootPackages": [], - "tierFilteredPackages": [], - "conflictingPackages": [], - "dependencyGraph": { - "runtime-core": [], - "workflow-pack": [ - "runtime-core" - ] - }, - "resolutionOrder": [ - "runtime-core", - "workflow-pack" - ], - "requestedModules": [ - "runtime-core", - "workflow-pack" - ], - "selectedModules": [ - "runtime-core", - "workflow-pack" - ], - "modules": [ - "runtime-core", - "workflow-pack" - ], - "managedFiles": [ - ".claude/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml", - ".claude/identity.json", - ".codex/config.toml", - ".codex/AGENTS.md", - ".codex/agents/explorer.toml", - ".codex/agents/reviewer.toml", - ".codex/agents/docs-researcher.toml", - ".claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml", - ".claude/commands/feature-development.md", - ".claude/commands/add-or-update-native-mlkit-feature.md", - ".claude/commands/code-quality-fixes-native.md" - ], - "packageFiles": { - "runtime-core": [ - ".claude/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml", - ".claude/identity.json", - ".codex/config.toml", - ".codex/AGENTS.md", - ".codex/agents/explorer.toml", - ".codex/agents/reviewer.toml", - ".codex/agents/docs-researcher.toml", - ".claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml" - ], - "workflow-pack": [ - ".claude/commands/feature-development.md", - ".claude/commands/add-or-update-native-mlkit-feature.md", - ".claude/commands/code-quality-fixes-native.md" - ] - }, - "moduleFiles": { - "runtime-core": [ - ".claude/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/SKILL.md", - ".agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml", - ".claude/identity.json", - ".codex/config.toml", - ".codex/AGENTS.md", - ".codex/agents/explorer.toml", - ".codex/agents/reviewer.toml", - ".codex/agents/docs-researcher.toml", - ".claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml" - ], - "workflow-pack": [ - ".claude/commands/feature-development.md", - ".claude/commands/add-or-update-native-mlkit-feature.md", - ".claude/commands/code-quality-fixes-native.md" - ] - }, - "files": [ - { - "moduleId": "runtime-core", - "path": ".claude/skills/react-native-vision-camera-mlkit/SKILL.md", - "description": "Repository-specific Claude Code skill generated from git history." - }, - { - "moduleId": "runtime-core", - "path": ".agents/skills/react-native-vision-camera-mlkit/SKILL.md", - "description": "Codex-facing copy of the generated repository skill." - }, - { - "moduleId": "runtime-core", - "path": ".agents/skills/react-native-vision-camera-mlkit/agents/openai.yaml", - "description": "Codex skill metadata so the repo skill appears cleanly in the skill interface." - }, - { - "moduleId": "runtime-core", - "path": ".claude/identity.json", - "description": "Suggested identity.json baseline derived from repository conventions." - }, - { - "moduleId": "runtime-core", - "path": ".codex/config.toml", - "description": "Repo-local Codex MCP and multi-agent baseline aligned with ECC defaults." - }, - { - "moduleId": "runtime-core", - "path": ".codex/AGENTS.md", - "description": "Codex usage guide that points at the generated repo skill and workflow bundle." - }, - { - "moduleId": "runtime-core", - "path": ".codex/agents/explorer.toml", - "description": "Read-only explorer role config for Codex multi-agent work." - }, - { - "moduleId": "runtime-core", - "path": ".codex/agents/reviewer.toml", - "description": "Read-only reviewer role config focused on correctness and security." - }, - { - "moduleId": "runtime-core", - "path": ".codex/agents/docs-researcher.toml", - "description": "Read-only docs researcher role config for API verification." - }, - { - "moduleId": "runtime-core", - "path": ".claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml", - "description": "Continuous-learning instincts derived from repository patterns." - }, - { - "moduleId": "workflow-pack", - "path": ".claude/commands/feature-development.md", - "description": "Workflow command scaffold for feature-development." - }, - { - "moduleId": "workflow-pack", - "path": ".claude/commands/add-or-update-native-mlkit-feature.md", - "description": "Workflow command scaffold for add-or-update-native-mlkit-feature." - }, - { - "moduleId": "workflow-pack", - "path": ".claude/commands/code-quality-fixes-native.md", - "description": "Workflow command scaffold for code-quality-fixes-native." - } - ], - "workflows": [ - { - "command": "feature-development", - "path": ".claude/commands/feature-development.md" - }, - { - "command": "add-or-update-native-mlkit-feature", - "path": ".claude/commands/add-or-update-native-mlkit-feature.md" - }, - { - "command": "code-quality-fixes-native", - "path": ".claude/commands/code-quality-fixes-native.md" - } - ], - "adapters": { - "claudeCode": { - "skillPath": ".claude/skills/react-native-vision-camera-mlkit/SKILL.md", - "identityPath": ".claude/identity.json", - "commandPaths": [ - ".claude/commands/feature-development.md", - ".claude/commands/add-or-update-native-mlkit-feature.md", - ".claude/commands/code-quality-fixes-native.md" - ] - }, - "codex": { - "configPath": ".codex/config.toml", - "agentsGuidePath": ".codex/AGENTS.md", - "skillPath": ".agents/skills/react-native-vision-camera-mlkit/SKILL.md" - } - } -} \ No newline at end of file diff --git a/.claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml b/.claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml deleted file mode 100644 index b458d58..0000000 --- a/.claude/homunculus/instincts/inherited/react-native-vision-camera-mlkit-instincts.yaml +++ /dev/null @@ -1,548 +0,0 @@ -# Instincts generated from https://github.com/pedrol2b/react-native-vision-camera-mlkit -# Generated: 2026-07-05T23:57:28.965Z -# Version: 2.0 -# NOTE: This file supplements (does not replace) any existing curated instincts. -# High-confidence manually curated instincts should be preserved alongside these. - ---- -id: react-native-vision-camera-mlkit-commit-conventional -trigger: "when writing a commit message" -confidence: 0.85 -domain: git -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Commit Conventional - -## Action - -Use conventional commit format with prefixes: fix, feat, chore, docs, perf - -## Evidence - -- 17 commits analyzed -- Detected conventional commit pattern -- Examples: chore(barcodeScanning): add native deps for barcodeScanning, docs(README): add quote to md line - ---- -id: react-native-vision-camera-mlkit-commit-length -trigger: "when writing a commit message" -confidence: 0.6 -domain: git -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Commit Length - -## Action - -Write moderate-length commit messages (~52 characters) - -## Evidence - -- Average commit message length: 52 chars -- Based on 17 commits - ---- -id: react-native-vision-camera-mlkit-naming-files -trigger: "when creating a new file" -confidence: 0.8 -domain: code-style -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Naming Files - -## Action - -Use PascalCase naming convention - -## Evidence - -- Analyzed file naming patterns in repository -- Dominant pattern: PascalCase - ---- -id: react-native-vision-camera-mlkit-import-relative -trigger: "when importing modules" -confidence: 0.75 -domain: code-style -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Import Relative - -## Action - -Use relative imports for project files - -## Evidence - -- Import analysis shows relative import pattern -- Example: import { x } from '../lib/x' - ---- -id: react-native-vision-camera-mlkit-export-style -trigger: "when exporting from a module" -confidence: 0.7 -domain: code-style -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Export Style - -## Action - -Prefer named exports - -## Evidence - -- Export pattern analysis -- Dominant style: named - ---- -id: react-native-vision-camera-mlkit-arch-type-based -trigger: "when adding new code" -confidence: 0.8 -domain: architecture -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Arch Type Based - -## Action - -Place code in the appropriate type folder (components/, services/, utils/, etc.) - -## Evidence - -- Type-based module organization detected -- Folders: core, features - ---- -id: react-native-vision-camera-mlkit-test-separate -trigger: "when writing tests" -confidence: 0.8 -domain: testing -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Test Separate - -## Action - -Place tests in the tests/ or __tests__/ directory, mirroring src structure - -## Evidence - -- Separate test directory pattern detected -- Tests live in dedicated test folders - ---- -id: react-native-vision-camera-mlkit-workflow-feature-development -trigger: "when implementing a new feature" -confidence: 0.9 -domain: workflow -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Workflow Feature Development - -## Action - -Follow the feature-development workflow: -1. Add feature implementation -2. Add tests for feature -3. Update documentation - -## Evidence - -- Workflow detected from commit patterns -- Frequency: ~14x per month -- Files: example/src/screens/*, example/src/components/ui/*, example/src/stores/* - ---- -id: react-native-vision-camera-mlkit-workflow-add-or-update-native-mlkit-feature -trigger: "when doing add or update native mlkit feature" -confidence: 0.55 -domain: workflow -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Workflow Add Or Update Native Mlkit Feature - -## Action - -Follow the add-or-update-native-mlkit-feature workflow: -1. Add or update native Android files (handlers, plugins, models, factories, adapters, serializers, registry, build.gradle). -2. Add or update native iOS files (handlers, plugins, models, factories, adapters, serializers, registry, VisionCameraMLKit.mm). -3. Update or add cross-platform TypeScript files (feature index, types, src/index.ts). -4. Update example app integration (screens, stores, CameraView, Podfile.lock, project.pbxproj). -5. Update documentation (README.md, docs/feature.md). - -## Evidence - -- Workflow detected from commit patterns -- Frequency: ~1x per month -- Files: android/src/main/java/com/visioncameramlkit/bridge/handlers/*, android/src/main/java/com/visioncameramlkit/bridge/plugins/*, android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt - ---- -id: react-native-vision-camera-mlkit-workflow-code-quality-fixes-native -trigger: "when doing code quality fixes native" -confidence: 0.55 -domain: workflow -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Workflow Code Quality Fixes Native - -## Action - -Follow the code-quality-fixes-native workflow: -1. Identify code quality issues in Android and/or iOS native code. -2. Refactor or clean up code in multiple related files (handlers, plugins, models, modules, etc.). -3. Commit changes with a fix or chore message. - -## Evidence - -- Workflow detected from commit patterns -- Frequency: ~1x per month -- Files: android/src/main/java/com/visioncameramlkit/bridge/handlers/*, android/src/main/java/com/visioncameramlkit/bridge/plugins/*, android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt - ---- -id: react-native-vision-camera-mlkit-workflow-update-ios-pods-and-xcode-project -trigger: "when doing update ios pods and xcode project" -confidence: 0.55 -domain: workflow -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Workflow Update Ios Pods And Xcode Project - -## Action - -Follow the update-ios-pods-and-xcode-project workflow: -1. Update example/ios/Podfile and/or Podfile.lock. -2. Update example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj. -3. Commit with chore(xcode) or similar message. - -## Evidence - -- Workflow detected from commit patterns -- Frequency: ~1x per month -- Files: example/ios/Podfile, example/ios/Podfile.lock, example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj - ---- -id: react-native-vision-camera-mlkit-workflow-documentation-update -trigger: "when doing documentation update" -confidence: 0.6 -domain: workflow -source: repo-analysis -source_repo: https://github.com/pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Workflow Documentation Update - -## Action - -Follow the documentation-update workflow: -1. Edit README.md or docs/*.md to add, clarify, or reorganize information. -2. Commit with docs(...) message. - -## Evidence - -- Workflow detected from commit patterns -- Frequency: ~2x per month -- Files: README.md, docs/*.md - ---- -id: react-native-vision-camera-mlkit-instinct-file-naming -trigger: "When creating or renaming a file in the Swift codebase" -confidence: 0.9 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct File Naming - -## Action - -Use PascalCase for file names - -## Evidence - -- Pattern in codeStyle.namingConventions.files -- Observed in ios/Bridge/Handlers/*, ios/Domain/Models/* - ---- -id: react-native-vision-camera-mlkit-instinct-function-naming -trigger: "When defining a function in Swift" -confidence: 0.9 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Function Naming - -## Action - -Use camelCase for function names - -## Evidence - -- Pattern in codeStyle.namingConventions.functions -- Observed in ios/Infrastructure/MLKit/* - ---- -id: react-native-vision-camera-mlkit-instinct-class-naming -trigger: "When defining a class in Swift" -confidence: 0.9 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Class Naming - -## Action - -Use PascalCase for class names - -## Evidence - -- Pattern in codeStyle.namingConventions.classes -- Observed in ios/Domain/Models/* - ---- -id: react-native-vision-camera-mlkit-instinct-constant-naming -trigger: "When declaring a constant in Swift" -confidence: 0.9 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Constant Naming - -## Action - -Use SCREAMING_SNAKE_CASE for constant names - -## Evidence - -- Pattern in codeStyle.namingConventions.constants -- Observed in ios/Infrastructure/MLKit/* - ---- -id: react-native-vision-camera-mlkit-instinct-import-style -trigger: "When importing modules in Swift or TypeScript" -confidence: 0.8 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Import Style - -## Action - -Use relative import paths - -## Evidence - -- Pattern in codeStyle.importStyle -- Seen in src/features/*/index.ts - ---- -id: react-native-vision-camera-mlkit-instinct-export-style -trigger: "When exporting modules in TypeScript" -confidence: 0.8 -domain: code-style -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Export Style - -## Action - -Use named exports - -## Evidence - -- Pattern in codeStyle.exportStyle -- Seen in src/features/*/index.ts - ---- -id: react-native-vision-camera-mlkit-instinct-test-location -trigger: "When adding or updating tests" -confidence: 0.8 -domain: testing -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Test Location - -## Action - -Place test files in a separate test directory - -## Evidence - -- Pattern in architecture.folderStructure.testLocation -- Files like **/*.test.* - ---- -id: react-native-vision-camera-mlkit-instinct-test-feature-workflow -trigger: "When implementing a new feature" -confidence: 0.85 -domain: testing -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Test Feature Workflow - -## Action - -Add corresponding tests for the feature - -## Evidence - -- Workflow feature-development includes 'Add tests for feature' -- example/src/screens/*, example/src/components/ui/*, **/*.test.* - ---- -id: react-native-vision-camera-mlkit-instinct-git-commit-format -trigger: "When making a commit" -confidence: 0.9 -domain: git -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Git Commit Format - -## Action - -Use conventional commit format: (): - -## Evidence - -- Pattern in commits.type and commits.prefixes -- Examples like 'feat(example/HomeScreen): improve UI by sorting list by status complete' - ---- -id: react-native-vision-camera-mlkit-instinct-git-commit-length -trigger: "When writing a commit message" -confidence: 0.7 -domain: git -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Git Commit Length - -## Action - -Keep the commit message around 52 characters on average - -## Evidence - -- Pattern in commits.averageLength -- Examples in commit history - ---- -id: react-native-vision-camera-mlkit-instinct-add-mlkit-feature -trigger: "When adding or updating a native ML Kit feature (e.g., barcode scanning, text recognition)" -confidence: 0.95 -domain: workflow -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Add Mlkit Feature - -## Action - -Update native Android/iOS files, cross-platform TypeScript files, example integration, and documentation in a coordinated sequence - -## Evidence - -- Workflow add-or-update-native-mlkit-feature -- Files and commit sequences in workflow and example - ---- -id: react-native-vision-camera-mlkit-instinct-code-quality-native -trigger: "When improving code quality in native Android or iOS code" -confidence: 0.9 -domain: workflow -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Code Quality Native - -## Action - -Refactor or clean up code in related native files and commit with fix or chore message - -## Evidence - -- Workflow code-quality-fixes-native -- Commits like 'fix(android): kotlin code quality fixes' - ---- -id: react-native-vision-camera-mlkit-instinct-update-ios-pods -trigger: "When iOS dependencies or Xcode versions change" -confidence: 0.88 -domain: workflow -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Update Ios Pods - -## Action - -Update Podfile, Podfile.lock, and Xcode project files and commit with chore(xcode) or similar message - -## Evidence - -- Workflow update-ios-pods-and-xcode-project -- Files example/ios/Podfile, Podfile.lock, VisionCameraMLKitExample.xcodeproj/project.pbxproj - ---- -id: react-native-vision-camera-mlkit-instinct-documentation-update -trigger: "When features, fixes, or developer guidance change" -confidence: 0.85 -domain: workflow -source: repo-analysis -source_repo: pedrol2b/react-native-vision-camera-mlkit ---- - -# React Native Vision Camera Mlkit Instinct Documentation Update - -## Action - -Edit README.md or docs/*.md and commit with docs(...) message - -## Evidence - -- Workflow documentation-update -- Commits like 'docs(README): add quote to md line' - diff --git a/.claude/identity.json b/.claude/identity.json deleted file mode 100644 index ffb8f52..0000000 --- a/.claude/identity.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "version": "2.0", - "technicalLevel": "technical", - "preferredStyle": { - "verbosity": "moderate", - "codeComments": true, - "explanations": true - }, - "domains": [ - "swift", - "react" - ], - "suggestedBy": "ecc-tools-repo-analysis", - "createdAt": "2026-07-05T23:57:28.965Z" -} \ No newline at end of file diff --git a/.claude/skills/react-native-vision-camera-mlkit/SKILL.md b/.claude/skills/react-native-vision-camera-mlkit/SKILL.md deleted file mode 100644 index 1721f1f..0000000 --- a/.claude/skills/react-native-vision-camera-mlkit/SKILL.md +++ /dev/null @@ -1,137 +0,0 @@ -```markdown -# react-native-vision-camera-mlkit Development Patterns - -> Auto-generated skill from repository analysis - -## Overview - -This skill teaches you how to contribute to the `react-native-vision-camera-mlkit` repository, a React Native module that integrates ML Kit features (like barcode scanning and text recognition) into mobile camera applications. You'll learn the project's coding conventions, commit patterns, and the main development workflows for adding features, improving code quality, updating iOS dependencies, and maintaining documentation. - ---- - -## Coding Conventions - -**File Naming** -- Use **PascalCase** for file and directory names. - - Example: `VisionCameraMLKitModule.swift`, `PluginRegistry.kt` - -**Import Style** -- Use **relative imports** in TypeScript/JavaScript. - - Example: - ```ts - import { BarcodeScanner } from './BarcodeScanner' - ``` - -**Export Style** -- Use **named exports**. - - Example: - ```ts - export const BarcodeScanner = { ... } - export type Barcode = { ... } - ``` - -**Commit Messages** -- Follow **Conventional Commits**: `fix:`, `feat:`, `chore:`, `docs:`, `perf:` -- Keep commit messages concise (~52 characters on average). - - Example: `feat: add face detection plugin for iOS` - ---- - -## Workflows - -### Add or Update Native ML Kit Feature -**Trigger:** When you want to add or significantly update a native ML Kit feature (e.g., barcode scanning, text recognition). -**Command:** `/add-mlkit-feature` - -1. **Android:** - - Add/update handlers, plugins, models, factories, adapters, serializers, and registry files under `android/src/main/java/com/visioncameramlkit/bridge/`. - - Update `android/build.gradle` if needed. -2. **iOS:** - - Add/update handlers, plugins, models, factories, adapters, serializers, and registry files under `ios/Bridge/`. - - Update `ios/VisionCameraMLKit.mm` and `ios/Infrastructure/Modules/VisionCameraMLKitModule.swift` as needed. -3. **Cross-platform:** - - Update or add TypeScript feature files: `src/features/*/index.ts`, `src/features/*/types.ts`, and `src/index.ts`. -4. **Example App:** - - Integrate the new or updated feature in `example/src/components/views/CameraView.tsx`, `example/src/screens/`, and `example/src/stores/`. - - Update iOS example project files: `example/ios/Podfile.lock`, `example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj`. -5. **Documentation:** - - Update `README.md` and/or create or edit `docs/feature.md` to document the new feature. - -**Example commit:** -```sh -feat: add text recognition support for Android -``` - ---- - -### Code Quality Fixes (Native) -**Trigger:** When you want to improve code quality, readability, or maintainability in native Android (Kotlin) and/or iOS (Swift) code. -**Command:** `/code-quality-native` - -1. Identify code quality issues in Android and/or iOS native code. -2. Refactor or clean up code in relevant files (handlers, plugins, models, modules, etc.). -3. Commit changes with a `fix:` or `chore:` message. - -**Example commit:** -```sh -chore: refactor plugin registry for clarity -``` - ---- - -### Update iOS Pods and Xcode Project -**Trigger:** When you need to update iOS dependencies (Pods) or adapt to new Xcode versions. -**Command:** `/update-ios-pods` - -1. Update `example/ios/Podfile` and/or `Podfile.lock` as needed. -2. Update `example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj` for project configuration changes. -3. Commit with a `chore(xcode):` or similar message. - -**Example commit:** -```sh -chore(xcode): update Podfile for Xcode 15 compatibility -``` - ---- - -### Documentation Update -**Trigger:** When you want to update documentation for new features, fixes, or developer guidance. -**Command:** `/update-docs` - -1. Edit `README.md` or any file under `docs/` to add, clarify, or reorganize information. -2. Commit with a `docs:` message. - -**Example commit:** -```sh -docs: add usage example for barcode scanning -``` - ---- - -## Testing Patterns - -- **Test File Naming:** Test files use the `*.test.*` pattern (e.g., `BarcodeScanner.test.ts`). -- **Testing Framework:** Not explicitly detected; check existing test files for framework usage. -- **Test Placement:** Tests are typically placed alongside the files they test. - -**Example:** -```ts -// BarcodeScanner.test.ts -import { BarcodeScanner } from './BarcodeScanner' - -test('scans a barcode', () => { - // ...test implementation -}) -``` - ---- - -## Commands - -| Command | Purpose | -|----------------------|----------------------------------------------------------------| -| /add-mlkit-feature | Add or update a native ML Kit feature (Android/iOS/TS/docs) | -| /code-quality-native | Refactor or improve code quality in native codebases | -| /update-ios-pods | Update iOS Podfile, Podfile.lock, or Xcode project files | -| /update-docs | Update documentation (README.md, docs/*.md) | -``` \ No newline at end of file diff --git a/.codex/AGENTS.md b/.codex/AGENTS.md deleted file mode 100644 index 0ddc597..0000000 --- a/.codex/AGENTS.md +++ /dev/null @@ -1,28 +0,0 @@ -# ECC for Codex CLI - -This supplements the root `AGENTS.md` with a repo-local ECC baseline. - -## Repo Skill - -- Repo-generated Codex skill: `.agents/skills/react-native-vision-camera-mlkit/SKILL.md` -- Claude-facing companion skill: `.claude/skills/react-native-vision-camera-mlkit/SKILL.md` -- Keep user-specific credentials and private MCPs in `~/.codex/config.toml`, not in this repo. - -## MCP Baseline - -Treat `.codex/config.toml` as the default ECC-safe baseline for work in this repository. -The generated baseline enables GitHub, Context7, Exa, Memory, Playwright, and Sequential Thinking. - -## Multi-Agent Support - -- Explorer: read-only evidence gathering -- Reviewer: correctness, security, and regression review -- Docs researcher: API and release-note verification - -## Workflow Files - -- `.claude/commands/feature-development.md` -- `.claude/commands/add-or-update-native-mlkit-feature.md` -- `.claude/commands/code-quality-fixes-native.md` - -Use these workflow files as reusable task scaffolds when the detected repository workflows recur. \ No newline at end of file diff --git a/.codex/agents/docs-researcher.toml b/.codex/agents/docs-researcher.toml deleted file mode 100644 index 0daae57..0000000 --- a/.codex/agents/docs-researcher.toml +++ /dev/null @@ -1,9 +0,0 @@ -model = "gpt-5.4" -model_reasoning_effort = "medium" -sandbox_mode = "read-only" - -developer_instructions = """ -Verify APIs, framework behavior, and release-note claims against primary documentation before changes land. -Cite the exact docs or file paths that support each claim. -Do not invent undocumented behavior. -""" \ No newline at end of file diff --git a/.codex/agents/explorer.toml b/.codex/agents/explorer.toml deleted file mode 100644 index 732df7a..0000000 --- a/.codex/agents/explorer.toml +++ /dev/null @@ -1,9 +0,0 @@ -model = "gpt-5.4" -model_reasoning_effort = "medium" -sandbox_mode = "read-only" - -developer_instructions = """ -Stay in exploration mode. -Trace the real execution path, cite files and symbols, and avoid proposing fixes unless the parent agent asks for them. -Prefer targeted search and file reads over broad scans. -""" \ No newline at end of file diff --git a/.codex/agents/reviewer.toml b/.codex/agents/reviewer.toml deleted file mode 100644 index b13ed9c..0000000 --- a/.codex/agents/reviewer.toml +++ /dev/null @@ -1,9 +0,0 @@ -model = "gpt-5.4" -model_reasoning_effort = "high" -sandbox_mode = "read-only" - -developer_instructions = """ -Review like an owner. -Prioritize correctness, security, behavioral regressions, and missing tests. -Lead with concrete findings and avoid style-only feedback unless it hides a real bug. -""" \ No newline at end of file diff --git a/.codex/config.toml b/.codex/config.toml deleted file mode 100644 index bc1ee67..0000000 --- a/.codex/config.toml +++ /dev/null @@ -1,48 +0,0 @@ -#:schema https://developers.openai.com/codex/config-schema.json - -# ECC Tools generated Codex baseline -approval_policy = "on-request" -sandbox_mode = "workspace-write" -web_search = "live" - -[mcp_servers.github] -command = "npx" -args = ["-y", "@modelcontextprotocol/server-github"] - -[mcp_servers.context7] -command = "npx" -args = ["-y", "@upstash/context7-mcp@latest"] - -[mcp_servers.exa] -url = "https://mcp.exa.ai/mcp" - -[mcp_servers.memory] -command = "npx" -args = ["-y", "@modelcontextprotocol/server-memory"] - -[mcp_servers.playwright] -command = "npx" -args = ["-y", "@playwright/mcp@latest", "--extension"] - -[mcp_servers.sequential-thinking] -command = "npx" -args = ["-y", "@modelcontextprotocol/server-sequential-thinking"] - -[features] -multi_agent = true - -[agents] -max_threads = 6 -max_depth = 1 - -[agents.explorer] -description = "Read-only codebase explorer for gathering evidence before changes are proposed." -config_file = "agents/explorer.toml" - -[agents.reviewer] -description = "PR reviewer focused on correctness, security, and missing tests." -config_file = "agents/reviewer.toml" - -[agents.docs_researcher] -description = "Documentation specialist that verifies APIs, framework behavior, and release notes." -config_file = "agents/docs-researcher.toml" \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index 65365be..8faf7cf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,7 @@ end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true + +[*.{kt,kts}] +# Kotlin extension filenames intentionally mirror Swift's Type+operation style. +ktlint_standard_filename = disabled diff --git a/.gitattributes b/.gitattributes index e27f70f..548d575 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ -*.pbxproj -text -# specific for windows script files -*.bat text eol=crlf +# Nitrogen owns generated formatting, including intentional trailing spaces. +nitrogen/generated/** -whitespace diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 8bfb66a..fda4334 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,7 +1,7 @@ name: 🐛 Bug Report description: File a bug report for react-native-vision-camera-mlkit title: '🐛 Bug: ' -labels: [🐛 bug] +labels: ["type: bug"] body: - type: dropdown attributes: diff --git a/.github/ISSUE_TEMPLATE/build-error.yml b/.github/ISSUE_TEMPLATE/build-error.yml index c4bf8b4..f79f1f4 100644 --- a/.github/ISSUE_TEMPLATE/build-error.yml +++ b/.github/ISSUE_TEMPLATE/build-error.yml @@ -1,7 +1,7 @@ name: 🔧 Build Error description: Report build issues with react-native-vision-camera-mlkit title: '🔧 Build error: ' -labels: [🔧 build error] +labels: ["type: bug", "area: build"] body: - type: dropdown attributes: diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index b473e8a..c8c6a66 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,7 +1,7 @@ name: ✨ Feature Request description: Suggest a new ML Kit feature or enhancement title: '✨ Feature Request: ' -labels: [✨ feature] +labels: ["type: feature"] body: - type: dropdown attributes: diff --git a/.github/labels.yml b/.github/labels.yml index a34ed09..b095bcf 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -1,102 +1,200 @@ -- name: 🐛 bug - description: Something isn't working as expected - color: d73a49 -- name: ✨ feature - description: New feature request - color: a2eeef -- name: 🚀 enhancement - description: Enhancement to existing feature - color: 84B6EB -- name: 🔧 build error - description: Build or compilation issues - color: 008672 -- name: 📚 documentation - description: Documentation improvements or additions - color: 0075ca -- name: 💭 question - description: Questions or clarifications needed - color: d876e3 -- name: 🤖 android - description: Android platform specific - color: 4BC74F -- name: 🍏 ios - description: iOS platform specific - color: 3DDC84 -- name: 📝 text-recognition - description: Text Recognition feature - color: fbca04 -- name: 👤 face-detection - description: Face Detection feature - color: f9d0c4 -- name: 🎭 face-mesh-detection - description: Face Mesh Detection feature - color: e99695 -- name: 🏃 pose-detection - description: Pose Detection feature - color: d4c5f9 -- name: ✂️ selfie-segmentation - description: Selfie Segmentation feature - color: bfc1c6 -- name: 📐 subject-segmentation - description: Subject Segmentation feature - color: 8b4513 -- name: 📄 document-scanner - description: Document Scanner feature - color: 2e8b57 -- name: 📱 barcode-scanning - description: Barcode Scanning feature - color: ff69b4 -- name: 🏷️ image-labeling - description: Image Labeling feature - color: 00ced1 -- name: 🔍 object-detection - description: Object Detection feature - color: dc143c -- name: ✍️ digital-ink-recognition - description: Digital Ink Recognition feature - color: 8a2be2 -- name: ❌ needs-reproduction - description: Issue needs reproduction steps - color: FF0000 -- name: ⌛ awaiting-author - description: Waiting for author feedback or requested information - color: FBCA04 -- name: 🖇 duplicate - description: This issue or pull request already exists - color: cfd3d7 -- name: ❌ invalid - description: This doesn't seem right - color: e4e669 -- name: ☠️ wontfix - description: This will not be worked on - color: ffffff -- name: ⏳ stale - description: Issue has not had recent activity - color: 808080 -- name: 🚧 wip - description: Work in progress - color: fbca04 -- name: 🔴 critical - description: Critical issue affecting core functionality - color: b60205 -- name: 🟠 high - description: High priority issue - color: fbca04 -- name: 🟡 medium - description: Medium priority issue - color: fef2c0 -- name: 🟢 low - description: Low priority issue - color: 0e8a16 -- name: ⚠️ breaking change - description: Breaking change that requires migration - color: d93f0b -- name: 🎈 performance - description: Performance related issue or improvement - color: 006b75 -- name: 📦 dependencies - description: Pull requests that update dependencies - color: 0366d6 -- name: 💄 types - description: TypeScript type definitions or issues - color: 1d76db +# ============================================================================= +# Type +# ============================================================================= +- name: "type: bug" + description: "Something is not working as expected" + color: "D73A4A" +- name: "type: feature" + description: "Introduces new functionality" + color: "1D76DB" +- name: "type: enhancement" + description: "Improves existing functionality or behavior" + color: "A2EEEF" +- name: "type: refactor" + description: "Restructures code without intentionally changing behavior" + color: "5319E7" +- name: "type: maintenance" + description: "Routine maintenance, tooling, configuration, or internal project work" + color: "C2E0C6" +- name: "type: documentation" + description: "Adds, updates, or corrects documentation" + color: "0075CA" +- name: "type: test" + description: "Adds, updates, or fixes automated tests" + color: "BFDADC" +- name: "type: cleanup" + description: "Removes unused code or improves project organization" + color: "C5DEF5" +- name: "type: dependency" + description: "Adds, removes, or updates a project dependency" + color: "0366D6" +- name: "type: breaking change" + description: "Introduces an incompatible change that may require migration" + color: "B60205" +- name: "type: deprecation" + description: "Deprecates functionality, APIs, or implementation paths" + color: "8B0000" +- name: "type: question" + description: "Requests clarification, guidance, or additional information" + color: "D876E3" + +# ============================================================================= +# Status +# ============================================================================= +- name: "status: blocked" + description: "Progress is blocked by a dependency, decision, or external factor" + color: "B60205" +- name: "status: needs information" + description: "Additional information is required before work can continue" + color: "D93F0B" +- name: "status: needs reproduction" + description: "Reproduction steps or a minimal reproducible example are required" + color: "D93F0B" +- name: "status: ready" + description: "Ready to be worked on or reviewed" + color: "0E8A16" +- name: "status: in progress" + description: "Work is currently in progress" + color: "FBCA04" +- name: "status: needs review" + description: "Ready for code, product, design, or technical review" + color: "0052CC" +- name: "status: changes requested" + description: "Changes are required before the work can be approved" + color: "D93F0B" +- name: "status: duplicate" + description: "This issue or pull request duplicates existing work" + color: "CFD3D7" +- name: "status: invalid" + description: "This issue or pull request is incomplete, incorrect, or not actionable" + color: "E4E669" +- name: "status: stale" + description: "This issue or pull request has had no recent activity" + color: "EDEDED" +- name: "status: wontfix" + description: "This issue is acknowledged but will not be addressed" + color: "FFFFFF" + +# ============================================================================= +# Priority +# ============================================================================= +- name: "priority: critical" + description: "Requires immediate attention due to severe user or business impact" + color: "B60205" +- name: "priority: high" + description: "High-impact work that should be addressed soon" + color: "D93F0B" +- name: "priority: medium" + description: "Normal-priority work" + color: "FBCA04" +- name: "priority: low" + description: "Low-impact work that can be handled when capacity allows" + color: "0E8A16" + +# ============================================================================= +# Platform +# ============================================================================= +- name: "platform: android" + description: "Specific to Android" + color: "3DDC84" +- name: "platform: ios" + description: "Specific to iOS" + color: "A2AAAD" +- name: "platform: shared" + description: "Affects shared or cross-platform application code" + color: "6F42C1" + +# ============================================================================= +# Technology +# ============================================================================= +- name: "technology: kotlin" + description: "Specific to Kotlin code or tooling" + color: "7F52FF" +- name: "technology: swift" + description: "Specific to Swift code or tooling" + color: "F05138" +- name: "technology: react native" + description: "Specific to React Native" + color: "61DAFB" +- name: "technology: typescript" + description: "Specific to TypeScript code or tooling" + color: "3178C6" + +# ============================================================================= +# Area +# ============================================================================= +- name: "area: accessibility" + description: "Accessibility behavior, support, or compliance" + color: "D4C5F9" +- name: "area: build" + description: "Build configuration, compilation, signing, packaging, or release builds" + color: "006B75" +- name: "area: ci/cd" + description: "Continuous integration, delivery, automation, or deployment pipelines" + color: "0E8A16" +- name: "area: navigation" + description: "Application navigation, routing, deep links, or screen transitions" + color: "84B6EB" +- name: "area: performance" + description: "Startup time, responsiveness, memory, battery, or resource usage" + color: "F9C513" +- name: "area: permissions" + description: "System permissions, privacy prompts, or permission handling" + color: "D4C5F9" +- name: "area: release" + description: "Versioning, publishing, store submission, rollout, or release management" + color: "0E8A16" +- name: "area: security" + description: "Security vulnerabilities, hardening, data protection, or privacy concerns" + color: "B60205" +- name: "area: testing" + description: "Test infrastructure, fixtures, mocks, coverage, or test reliability" + color: "BFDADC" +- name: "area: ui/ux" + description: "User interface, interaction, layout, or user experience" + color: "E99695" + +# ============================================================================= +# Quality and impact +# ============================================================================= +- name: "impact: crash" + description: "Causes or prevents an application crash" + color: "B60205" +- name: "impact: regression" + description: "Previously working behavior has stopped working" + color: "D93F0B" +- name: "impact: user-facing" + description: "Directly changes or affects the user experience" + color: "1D76DB" +- name: "impact: internal" + description: "Primarily affects internal implementation or developer workflows" + color: "C5DEF5" + +# ============================================================================= +# Pull request +# ============================================================================= +- name: "pr: do not merge" + description: "Must not be merged until the blocking condition is resolved" + color: "B60205" +- name: "pr: ready for review" + description: "The pull request is ready for review" + color: "0E8A16" +- name: "pr: work in progress" + description: "The pull request is still under active development" + color: "FBCA04" +- name: "pr: requires migration" + description: "Requires a data, configuration, API, or consumer migration" + color: "D93F0B" +- name: "pr: requires release notes" + description: "Requires an entry in the changelog or release notes" + color: "0075CA" + +# ============================================================================= +# Contribution +# ============================================================================= +- name: "contribution: good first issue" + description: "Suitable for first-time contributors" + color: "7057FF" +- name: "contribution: help wanted" + description: "Additional assistance or community contributions are welcome" + color: "008672" diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index d9cb0d6..4d7cbce 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -2,19 +2,29 @@ name: Build Example (Android) on: pull_request: - branches: [main] + branches: [main, develop] paths: + - '.github/workflows/build-android.yml' - 'android/**' + - 'cpp/**' - 'example/android/**' + - 'nitrogen/**' + - 'nitro.json' + - 'src/specs/**' - 'package.json' - 'yarn.lock' - '*.gradle' - '*.gradle.kts' push: - branches: [main] + branches: [main, develop] paths: + - '.github/workflows/build-android.yml' - 'android/**' + - 'cpp/**' - 'example/android/**' + - 'nitrogen/**' + - 'nitro.json' + - 'src/specs/**' - 'package.json' - 'yarn.lock' - '*.gradle' @@ -79,3 +89,9 @@ jobs: - name: Build Android example run: yarn turbo run build:android + + - name: Compile library with v2 features disabled + working-directory: example/android + env: + VISION_CAMERA_MLKIT_DISABLE_V2_FEATURES: 'true' + run: ./gradlew :react-native-vision-camera-mlkit:compileDebugKotlin --no-daemon diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index 8ed619d..aab7a2a 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -2,18 +2,28 @@ name: Build Example (iOS) on: pull_request: - branches: [main] + branches: [main, develop] paths: + - '.github/workflows/build-ios.yml' + - 'cpp/**' - 'ios/**' - 'example/ios/**' + - 'nitrogen/**' + - 'nitro.json' + - 'src/specs/**' - '*.podspec' - 'package.json' - 'yarn.lock' push: - branches: [main] + branches: [main, develop] paths: + - '.github/workflows/build-ios.yml' + - 'cpp/**' - 'ios/**' - 'example/ios/**' + - 'nitrogen/**' + - 'nitro.json' + - 'src/specs/**' - '*.podspec' - 'package.json' - 'yarn.lock' @@ -32,7 +42,7 @@ jobs: runs-on: macos-latest env: - XCODE_VERSION: 16.3 + XCODE_VERSION: latest-stable RCT_USE_RN_DEP: 1 RCT_USE_PREBUILT_RNCORE: 1 @@ -86,7 +96,7 @@ jobs: exit 1 fi - echo "IOS_DESTINATION=platform=iOS Simulator,OS=${IOS_RUNTIME},name=iPhone 15" >> "$GITHUB_ENV" + echo "IOS_DESTINATION=OS=${IOS_RUNTIME},name=iPhone 15" >> "$GITHUB_ENV" - name: Install CocoaPods run: | diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 110f739..c52bb1c 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -2,9 +2,9 @@ name: Build Package on: pull_request: - branches: [main] + branches: [main, develop] push: - branches: [main] + branches: [main, develop] permissions: contents: read @@ -23,5 +23,15 @@ jobs: - name: Setup environment uses: ./.github/actions/setup + - name: Verify generated Nitro specs are current + run: | + yarn specs + if [ -n "$(git status --porcelain --untracked-files=all -- nitrogen)" ]; then + echo "Generated Nitro specs are out of date. Run 'yarn specs' and commit the results." + git status --short --untracked-files=all -- nitrogen + git diff -- nitrogen + exit 1 + fi + - name: Build library run: yarn prepare diff --git a/.github/workflows/ktlint-format.yml b/.github/workflows/ktlint-format.yml index 65f867a..3955319 100644 --- a/.github/workflows/ktlint-format.yml +++ b/.github/workflows/ktlint-format.yml @@ -2,14 +2,14 @@ name: Ktlint Format (Android) on: push: - branches: [main] + branches: [main, develop] paths: - '.github/workflows/ktlint-format.yml' - 'android/**/*.kt' - 'android/**/*.kts' - '.editorconfig' pull_request: - branches: [main] + branches: [main, develop] paths: - '.github/workflows/ktlint-format.yml' - 'android/**/*.kt' diff --git a/.github/workflows/lint-typecheck.yml b/.github/workflows/lint-typecheck.yml index f9d24de..1c5b1f3 100644 --- a/.github/workflows/lint-typecheck.yml +++ b/.github/workflows/lint-typecheck.yml @@ -2,9 +2,9 @@ name: Lint & Typecheck on: pull_request: - branches: [main] + branches: [main, develop] push: - branches: [main] + branches: [main, develop] permissions: contents: read diff --git a/.github/workflows/npm-release.yml b/.github/workflows/npm-release.yml index 9f77bb3..c406bcc 100644 --- a/.github/workflows/npm-release.yml +++ b/.github/workflows/npm-release.yml @@ -3,38 +3,55 @@ name: NPM Release on: release: types: [published] - workflow_dispatch: permissions: contents: read - id-token: write jobs: build: name: Build package runs-on: ubuntu-latest + outputs: + tarball: ${{ steps.pack.outputs.tarball }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup environment uses: ./.github/actions/setup + - name: Validate release tag + run: | + PACKAGE_VERSION="$(node -p "require('./package.json').version")" + EXPECTED_TAG="v${PACKAGE_VERSION}" + + if [[ "$GITHUB_REF_TYPE" != "tag" || "$GITHUB_REF_NAME" != "$EXPECTED_TAG" ]]; then + echo "Release ref must be the package version tag: $EXPECTED_TAG" >&2 + exit 1 + fi + - name: Build package run: yarn prepare - - name: Upload build artifacts - uses: actions/upload-artifact@v4 + - name: Pack package + id: pack + run: | + TARBALL="$(npm pack | tail -n 1)" + + if [[ ! "$TARBALL" =~ ^react-native-vision-camera-mlkit-[0-9A-Za-z._-]+\.tgz$ ]]; then + echo "Unexpected package tarball name: $TARBALL" >&2 + exit 1 + fi + + echo "tarball=$TARBALL" >> "$GITHUB_OUTPUT" + + - name: Upload package tarball + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: lib - path: | - bin - android - ios - package.json - README.md - LICENSE* + name: package-tarball + path: ${{ steps.pack.outputs.tarball }} + if-no-files-found: error publish: name: Publish to npm @@ -46,22 +63,18 @@ jobs: id-token: write steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup environment - uses: ./.github/actions/setup - - name: Setup Node.js for npm - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20 + # npm trusted publishing requires npm >=11.5.1 and Node >=22.14.0. + # Node 24.7.0 ships npm 11.5.1. + node-version: 24.7.0 registry-url: https://registry.npmjs.org - - name: Download build artifacts (overwrite into repo root) - uses: actions/download-artifact@v4 + - name: Download package tarball + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: - name: lib + name: package-tarball path: . - name: Determine npm tag @@ -80,9 +93,11 @@ jobs: fi - name: Publish package + env: + PACKAGE_TARBALL: ${{ needs.build.outputs.tarball }} run: | if [ "${{ steps.npm-tag.outputs.tag }}" = "latest" ]; then - npm publish --provenance --access public + npm publish "$PACKAGE_TARBALL" --ignore-scripts --provenance --access public else - npm publish --provenance --access public --tag ${{ steps.npm-tag.outputs.tag }} + npm publish "$PACKAGE_TARBALL" --ignore-scripts --provenance --access public --tag ${{ steps.npm-tag.outputs.tag }} fi diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index b155a72..00c05e1 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -32,10 +32,10 @@ jobs: close-pr-message: > This PR was closed because it remained inactive for 7 days after being marked stale. - stale-issue-label: ⏳ stale - stale-pr-label: ⏳ stale + stale-issue-label: "status: stale" + stale-pr-label: "status: stale" - only-labels: ⌛ awaiting-author + only-labels: "status: needs information" days-before-stale-issues: 30 days-before-stale-prs: 30 @@ -51,8 +51,8 @@ jobs: close-pr-message-when-labeled: > This PR was closed because the author did not follow up after 7 days. - exempt-issue-labels: ☠️ wontfix, 🔴 critical - exempt-pr-labels: ☠️ wontfix, 🔴 critical + exempt-issue-labels: "status: wontfix, priority: critical" + exempt-pr-labels: "status: wontfix, priority: critical" exempt-all-milestones: true remove-stale-when-updated: true diff --git a/.github/workflows/swift-format.yml b/.github/workflows/swift-format.yml index 82df3de..26ee93a 100644 --- a/.github/workflows/swift-format.yml +++ b/.github/workflows/swift-format.yml @@ -2,13 +2,13 @@ name: Swift Format (iOS) on: pull_request: - branches: [main] + branches: [main, develop] paths: - '.github/workflows/swift-format.yml' - 'ios/**/*.swift' - '.swift-format' push: - branches: [main] + branches: [main, develop] paths: - '.github/workflows/swift-format.yml' - 'ios/**/*.swift' diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f5be3ba..240e6ca 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -2,9 +2,9 @@ name: Unit Tests on: pull_request: - branches: [main] + branches: [main, develop] push: - branches: [main] + branches: [main, develop] permissions: contents: read diff --git a/.gitignore b/.gitignore index 07e33b1..512508d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,15 @@ .vscode/ jsconfig.json +# Local AI development context +.context/ + +# AI tooling (local-only for now; revisit what, if anything, should be +# deployed to the git remote) +.agents/ +.claude/ +.codex/ + # Xcode # build/ @@ -83,6 +92,3 @@ lib/ # React Native Codegen ios/generated android/generated - -# React Native Nitro Modules -nitrogen/ diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 805edd4..9439505 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -59,7 +59,9 @@ representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at [issues](https://github.com/pedrol2b/react-native-vision-camera-mlkit/issues). +reported to the community leaders responsible for enforcement by emailing +**pedrolbb.e@gmail.com**. Please do not report Code of Conduct violations via +public GitHub issues, since those reports are not private. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5e6e45d..84f3e2f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,16 @@ If you want to use Android Studio or XCode to edit the native code, you can open To edit the Java or Kotlin files, open `android` in Android studio and find the source files at `react-native-vision-camera-mlkit` under `Android`. +> If you hit an iOS build failure in Pods referencing `fmt/include/fmt/base.h` or `FMT_USE_CONSTEVAL` on Xcode 26.4, see [docs/xcode-26.4-fmt-consteval-workaround.md](docs/xcode-26.4-fmt-consteval-workaround.md). + +### Working with the Nitro spec + +This library is a [Nitro Module](https://nitro.margelo.com). The native interface is defined in `src/specs/*.nitro.ts`. If you change a `.nitro.ts` spec file, regenerate the generated Swift/Kotlin/C++ bindings before rebuilding the example app: + +```sh +yarn specs +``` + You can use various commands from the root directory to work with the project. To start the packager, `cd` into the `example` directory, `cd example`, and then: @@ -73,11 +83,14 @@ We follow the [conventional commits specification](https://www.conventionalcommi - `fix`: bug fixes, e.g. fix crash due to deprecated method. - `feat`: new features, e.g. add new method to the module. - `refactor`: code refactor, e.g. migrate from class components to hooks. -- `docs`: changes into documentation, e.g. add usage example for the module.. +- `docs`: changes into documentation, e.g. add usage example for the module. - `test`: adding or updating tests, e.g. add integration tests using detox. -- `chore`: tooling changes, e.g. change CI config. +- `chore`: tooling changes, e.g. change dependency versions. +- `perf`: performance improvements, e.g. optimize a hot path. +- `ci`: CI/CD pipeline changes, e.g. update a GitHub Actions workflow. +- `build`: build system or external dependency changes, e.g. bump the RN version. -Our pre-commit hooks verify that your commit message matches this format when committing. +Our `commit-msg` hook (via commitlint) verifies that your commit message matches this format when committing. ### Linting and tests @@ -85,7 +98,7 @@ Our pre-commit hooks verify that your commit message matches this format when co We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. -Our pre-commit hooks verify that the linter and tests pass when committing. +Our `pre-commit` hook (via lefthook) runs ESLint and a TypeScript check on staged files. Tests aren't run automatically on commit, so run `yarn test` yourself before opening a pull request. ### Scripts @@ -95,9 +108,12 @@ The `package.json` file contains various scripts for common tasks: - `yarn typecheck`: type-check files with TypeScript. - `yarn lint`: lint files with ESLint. - `yarn test`: run unit tests with Jest. +- `yarn specs`: regenerate native bindings from the Nitro spec (`src/specs/*.nitro.ts`) with nitrogen. +- `yarn clean`: remove build artifacts for the library and the example app (Android/iOS). - `yarn start`: start the Metro server for the example app. - `yarn android`: run the example app on Android. - `yarn ios`: run the example app on iOS. +- `yarn prepare`: build the library for publishing with `react-native-builder-bob` (runs automatically as Yarn's `prepare` lifecycle hook after install; rarely needed manually). ### Sending a pull request @@ -108,5 +124,4 @@ When you're sending a pull request: - Prefer small pull requests focused on one change. - Verify that linters and tests are passing. - Review the documentation to make sure it looks good. -- Follow the pull request template when opening a pull request. -- For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. +- For pull requests that change the API or implementation, discuss with maintainers first by opening an issue (see the [issue templates](.github/ISSUE_TEMPLATE) for bug reports, build errors, and feature requests). diff --git a/README.md b/README.md index 3e5877e..69e5d84 100644 --- a/README.md +++ b/README.md @@ -16,40 +16,53 @@ [![MIT License][license-shield]][license-url] [![NPM Version][npm-version-shield]][npm-version-url] -A [React Native Vision Camera](https://github.com/mrousavy/react-native-vision-camera) plugin that exposes high-performance [Google ML Kit](https://developers.google.com/ml-kit) [frame processor](https://react-native-vision-camera.com/docs/guides/frame-processors) features such as text recognition (OCR), face detection, barcode scanning, pose detection, and more. +A Nitro-based [React Native Vision Camera](https://github.com/mrousavy/react-native-vision-camera) v5 plugin that exposes high-performance [Google ML Kit](https://developers.google.com/ml-kit) [frame output](https://visioncamera.margelo.com/docs/frame-output) features. v2 implements text recognition (OCR) and barcode scanning for live frames and static images. Other ML Kit vision features are post-v2 roadmap items. > The example app is intentionally heavy and demo-focused. For integration details, follow the documentation below. ## Requirements -- iOS 12+ and Android SDK 21+ -- [react-native-vision-camera](https://www.npmjs.com/package/react-native-vision-camera) -- [react-native-worklets-core](https://www.npmjs.com/package/react-native-worklets-core) +- React Native 0.86+ +- iOS 15.1+ and Android SDK 24+ +- [react-native-vision-camera](https://www.npmjs.com/package/react-native-vision-camera) `>=5` (Nitro-based v5, not v4) +- [react-native-nitro-modules](https://www.npmjs.com/package/react-native-nitro-modules) -Install Vision Camera (React Native): +Install Vision Camera and its Nitro dependency: ```sh -npm i react-native-vision-camera +npm i react-native-vision-camera react-native-nitro-modules cd ios && pod install ``` -Install Worklets Core: +> `react-native-vision-camera` has its own peer dependencies (currently +> `react-native-nitro-image`); follow the prompts from your package manager +> or the [Vision Camera docs](https://visioncamera.margelo.com/docs) to +> install those too. + +If you're using the **live-frame hooks** (`useTextRecognition`, +`useBarcodeScanning`), you also need Vision Camera's frame processor +dependencies, since those hooks run inside a `useFrameOutput` worklet: ```sh -npm i react-native-worklets-core -# or -yarn add react-native-worklets-core +npm i react-native-vision-camera-worklets react-native-worklets ``` -Add the Babel plugin in `babel.config.js`: - ```js +// babel.config.js module.exports = { - plugins: [['react-native-worklets-core/plugin']], + plugins: [['react-native-worklets/plugin']], }; ``` -> For Expo, follow the Vision Camera guide: [react-native-vision-camera.com/docs/guides](https://react-native-vision-camera.com/docs/guides) +The **static-image APIs** (`processImageTextRecognition`, +`processImageBarcodeScanning`) don't use frame outputs, Worklets, or a camera. +They do use the package's configured Nitro recognizers, so VisionCamera v5 and +Nitro Modules remain installation requirements for the native package. + +> For Expo, follow the Vision Camera guide for camera permissions/setup: +> [visioncamera.margelo.com/docs](https://visioncamera.margelo.com/docs). +> This library's own Expo config plugin (selective ML Kit dependencies) is +> documented below. ## Installation @@ -63,7 +76,17 @@ cd ios && pod install ## ML Kit Models Installation (Selective) -By default, all ML Kit features are enabled. You can selectively include only the models you need to reduce binary size. +v2 implements two feature families: text recognition and barcode scanning. +Both are enabled by default, including all five OCR language models. Disable +OCR languages you do not need to reduce binary size. Configuration keys for +post-v2 roadmap features remain reserved and disabled; enabling one does not +provide a public JS/Nitro API in v2. + +Both `textRecognition` and `barcodeScanning` are fully optional at compile +time on both platforms: disabling one removes its native SDK from the build +entirely instead of only gating it at runtime, so consumers who only need +barcode scanning (or only text recognition) do not pay for the other's +dependencies or binary size. ### Android (Gradle) @@ -77,17 +100,7 @@ ext["react-native-vision-camera-mlkit"] = [ textRecognitionDevanagari: false, textRecognitionJapanese: false, textRecognitionKorean: false, - faceDetection: false, - faceMeshDetection: false, - poseDetection: false, - poseDetectionAccurate: false, - selfieSegmentation: false, - subjectSegmentation: false, - documentScanner: false, barcodeScanning: true, - imageLabeling: false, - objectDetection: false, - digitalInkRecognition: false, ] ] ``` @@ -103,28 +116,65 @@ $VisionCameraMLKit = { 'textRecognitionDevanagari' => false, 'textRecognitionJapanese' => false, 'textRecognitionKorean' => false, - 'faceDetection' => false, - 'poseDetection' => false, - 'poseDetectionAccurate' => false, - 'selfieSegmentation' => false, 'barcodeScanning' => true, - 'imageLabeling' => false, - 'objectDetection' => false, - 'digitalInkRecognition' => false, } ``` -Android-only keys: `faceMeshDetection`, `subjectSegmentation`, `documentScanner`. +### Expo (config plugin) + +If you're using an Expo prebuild workflow (`expo prebuild`, EAS Build, or a +custom dev client), a config plugin mirrors the same selective ML Kit flags +into the generated `android/build.gradle` and `ios/Podfile` automatically, so +you don't have to hand-edit native config. Add it to your `app.json`/ +`app.config.js` `plugins` array with the same keys as above: + +```json +{ + "expo": { + "plugins": [ + [ + "react-native-vision-camera-mlkit", + { + "textRecognition": true, + "barcodeScanning": true + } + ] + ] + } +} +``` + +Any key you omit keeps the library's own default (see the Android/iOS +sections above). Passing an unrecognized key throws at prebuild time instead +of silently being ignored. Requires `@expo/config-plugins` (already a +dependency of `expo` itself, so Expo projects have it for free). See +[docs/expo-plugin.md](docs/expo-plugin.md) for platform-specific caveats +(Android-only keys, Kotlin DSL support, idempotency). + +Static-image processing accepts local files up to 25 MB encoded size. iOS +accepts sources up to 25 megapixels and 10,000 pixels on either dimension, then +downsamples them to at most 4 megapixels and 4,096 pixels per dimension during +ImageIO decode. Android currently accepts decoded dimensions up to 4 megapixels +and 4,096 pixels per dimension. Larger inputs are rejected before full decode +to protect application disk, memory, and CPU resources. ## Usage -### Text Recognition (Frame Processor) +### API Docs + +- [Text Recognition API](docs/text-recognition.md) +- [Barcode Scanning API](docs/barcode-scanning.md) +- [Selective ML Kit Installation](docs/selective-mlkit-install.md) +- [Expo Config Plugin](docs/expo-plugin.md) +- [Migrating from v1 to v2](docs/migration-v1-to-v2.md) + +### Text Recognition (Frame Output) ```ts import { - useFrameProcessor, - runAsync, - runAtTargetFps, + useFrameOutput, + CommonResolutions, + Camera, } from 'react-native-vision-camera'; import { useTextRecognition } from 'react-native-vision-camera-mlkit'; @@ -134,23 +184,29 @@ const { textRecognition } = useTextRecognition({ invertColors: false, }); -const frameProcessor = useFrameProcessor( - (frame) => { +const frameOutput = useFrameOutput({ + targetResolution: CommonResolutions.VGA_16_9, + pixelFormat: 'yuv', + onFrame(frame) { 'worklet'; - runAtTargetFps(10, () => { - 'worklet'; - runAsync(frame, () => { - 'worklet'; - const result = textRecognition(frame, { - outputOrientation: 'portrait', - }); - console.log(result.text); + try { + const result = textRecognition(frame, { + outputOrientation: 'portrait', }); - }); + console.log(result.text); + } finally { + frame.dispose(); + } }, - [textRecognition] -); +}); + +; ``` `TextRecognitionOptions`: @@ -158,7 +214,8 @@ const frameProcessor = useFrameProcessor( - `language?: 'LATIN' | 'CHINESE' | 'DEVANAGARI' | 'JAPANESE' | 'KOREAN'` - `scaleFactor?: number` (0.9-1.0) - `invertColors?: boolean` -- `frameProcessInterval?: number` (deprecated, use `runAtTargetFps`) +- `roi?: RegionOfInterest` (crop processing to a rectangle of the frame; see [Region of Interest](#region-of-interest)) +- `frameProcessInterval?: number` (deprecated compatibility field; v2 does not use it to throttle processing) `TextRecognitionArguments`: @@ -166,7 +223,10 @@ const frameProcessor = useFrameProcessor( ### Image Processing (Static Images) -Use `processImageTextRecognition` to analyze a file path or URI without the camera (for example, images picked from the gallery). +Use `processImageTextRecognition` to analyze a local image without the camera +(for example, an image picked from the gallery). Each call creates a Nitro text +recognizer configured with the supplied options, then processes the image +asynchronously. ```ts import { processImageTextRecognition } from 'react-native-vision-camera-mlkit'; @@ -183,10 +243,137 @@ console.log(result.blocks); `TextRecognitionImageOptions`: - `language?: 'LATIN' | 'CHINESE' | 'DEVANAGARI' | 'JAPANESE' | 'KOREAN'` -- `orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` +- `orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (overrides EXIF orientation; omit it to use image metadata) +- `invertColors?: boolean` +- `scaleFactor?: number` (0.9-1.0) +- `roi?: RegionOfInterest` (crop processing to a rectangle of the image; see [Region of Interest](#region-of-interest)) + +> Static images must be local and readable. On iOS, the target must be a +> regular, non-symlink file supplied as an absolute path or `file://` URI. +> Android accepts an absolute path, `file://` URI, or +> `content://` URI (copied to a temporary cache file for processing). Remote +> URLs and platform-library schemes such as `ph://` are not supported. + +### Barcode Scanning (Frame Output) + +```ts +import { + useFrameOutput, + CommonResolutions, + Camera, +} from 'react-native-vision-camera'; +import { useBarcodeScanning } from 'react-native-vision-camera-mlkit'; + +const { barcodeScanning } = useBarcodeScanning({ + formats: ['QR_CODE', 'CODE_128'], + enableAllPotentialBarcodes: true, + scaleFactor: 1, + invertColors: false, +}); + +const frameOutput = useFrameOutput({ + targetResolution: CommonResolutions.VGA_16_9, + pixelFormat: 'yuv', + onFrame(frame) { + 'worklet'; + + try { + const result = barcodeScanning(frame, { + outputOrientation: 'portrait', + }); + + for (const barcode of result.barcodes) { + console.log( + barcode.formatName, + barcode.valueTypeName, + barcode.rawValue + ); + if (barcode.value?.type === 'TYPE_URL') { + console.log(barcode.value.data.url); + } + } + } finally { + frame.dispose(); + } + }, +}); + +; +``` + +`BarcodeScanningOptions`: + +- `formats?: ('UNKNOWN' | 'ALL_FORMATS' | 'CODE_128' | 'CODE_39' | 'CODE_93' | 'CODABAR' | 'DATA_MATRIX' | 'EAN_13' | 'EAN_8' | 'ITF' | 'QR_CODE' | 'UPC_A' | 'UPC_E' | 'PDF417' | 'AZTEC')[]` +- `enableAllPotentialBarcodes?: boolean` (Android only) +- `scaleFactor?: number` (0.9-1.0) - `invertColors?: boolean` +- `roi?: RegionOfInterest` (crop processing to a rectangle of the frame; see [Region of Interest](#region-of-interest)) +- `frameProcessInterval?: number` (deprecated compatibility field; v2 does not use it to throttle processing) + +Supported `formats` values: + +| Value | Symbology | +| ------------- | ----------- | +| `ALL_FORMATS` | All types | +| `QR_CODE` | QR Code | +| `AZTEC` | Aztec | +| `PDF417` | PDF417 | +| `DATA_MATRIX` | Data Matrix | +| `CODE_128` | Code 128 | +| `CODE_39` | Code 39 | +| `CODE_93` | Code 93 | +| `CODABAR` | Codabar | +| `EAN_13` | EAN-13 | +| `EAN_8` | EAN-8 | +| `ITF` | ITF | +| `UPC_A` | UPC-A | +| `UPC_E` | UPC-E | +| `UNKNOWN` | Unknown | + +`BarcodeScanningArguments`: -The native bridge normalizes URIs (`file://` is removed on iOS and added on Android if missing). Supported formats: JPEG, PNG, WebP. +- `outputOrientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (iOS only) + +### Barcode Scanning (Static Images) + +Use `processImageBarcodeScanning` to analyze a local image without the camera. +Each call creates a Nitro barcode scanner configured with the supplied options, +then processes the image asynchronously. + +```ts +import { processImageBarcodeScanning } from 'react-native-vision-camera-mlkit'; + +const result = await processImageBarcodeScanning(imageUri, { + formats: ['QR_CODE', 'PDF417'], + enableAllPotentialBarcodes: true, + orientation: 'portrait', + invertColors: false, + scaleFactor: 1, +}); + +for (const barcode of result.barcodes) { + console.log(barcode.formatName, barcode.valueTypeName, barcode.displayValue); +} +``` + +`BarcodeScanningImageOptions`: + +- `formats?: ('UNKNOWN' | 'ALL_FORMATS' | 'CODE_128' | 'CODE_39' | 'CODE_93' | 'CODABAR' | 'DATA_MATRIX' | 'EAN_13' | 'EAN_8' | 'ITF' | 'QR_CODE' | 'UPC_A' | 'UPC_E' | 'PDF417' | 'AZTEC')[]` +- `enableAllPotentialBarcodes?: boolean` (Android only) +- `orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (overrides EXIF orientation; omit it to use image metadata) +- `invertColors?: boolean` +- `scaleFactor?: number` (0.9-1.0) +- `roi?: RegionOfInterest` (crop processing to a rectangle of the image; see [Region of Interest](#region-of-interest)) + +`BarcodeScanningResult` includes: + +- `barcodes[]` with `format`, `formatName`, `valueType`, `valueTypeName`, `rawValue`, `displayValue`, `rawBytes`, `bounds`, `corners`, `isPotential` +- `value?: { type: TYPE_*, data: ... }` for parsed payloads (WiFi, URL, SMS, Contact, Calendar Event, Driver License, etc.) ### Feature Utilities @@ -208,13 +395,20 @@ import { ### Error Handling -Frame processors throw a setup error when the feature is not enabled in Gradle/Podfile. For static image processing, the following error strings are exported: +Recognizer creation throws a setup error when OCR or barcode scanning is not +enabled in Gradle/Podfile. Static Nitro calls reject invalid schemes, missing +or unreadable files, and images the platform decoder cannot read. The package +also exports these compatibility error-message constants: - `IMAGE_NOT_FOUND_ERROR` - `INVALID_URI_ERROR` - `IMAGE_PROCESSING_FAILED_ERROR` - `UNSUPPORTED_IMAGE_FORMAT_ERROR` +These constants are retained for source compatibility and user-facing fallback +messages. Nitro rejection messages include platform-specific file details and +are not guaranteed to equal these strings; do not branch on `error.message`. + Use the feature helpers to provide user-friendly configuration hints: ```ts @@ -226,16 +420,42 @@ import { assertFeatureAvailable(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION); ``` +### Region of Interest + +Every feature accepts an optional `roi` to crop processing to a rectangle of the frame/image before running ML Kit, reducing CPU/GPU work. Result coordinates (bounding boxes, corners) are always mapped back to full source coordinates, so overlays don't need to account for the crop. + +```ts +type RegionOfInterest = { + x: number; + y: number; + width: number; + height: number; + /** @default 'normalized' */ + unit?: 'normalized' | 'pixel'; +}; +``` + +By default `x`/`y`/`width`/`height` are normalized to the `0..1` range relative to the source frame/image (so `x + width` and `y + height` must each be `<= 1`); set `unit: 'pixel'` to use absolute pixel values instead. + +```ts +const { textRecognition } = useTextRecognition({ + roi: { x: 0.25, y: 0.25, width: 0.5, height: 0.5 }, +}); +``` + ## Performance -- Follow the Vision Camera [performance guide](https://react-native-vision-camera.com/docs/guides/performance) -- Prefer `runAsync(...)` for heavy ML work to keep the frame processor responsive. -- Use `runAtTargetFps(...)` to throttle processing instead of `frameProcessInterval`. +- Follow the Vision Camera [performance guide](https://visioncamera.margelo.com/docs/performance) +- Always call `frame.dispose()` exactly once for every frame delivered to `onFrame`, including skipped frames. A `try`/`finally` around the whole callback is the safest pattern; unreleased v5 frames can stall the camera buffer pool. +- `frameProcessInterval` is retained only for source compatibility and has no throttling effect in the Nitro recognizers. Throttle in `onFrame` by deciding whether to call the recognizer while still disposing every frame. +- `useAsyncRunner()` can offload genuinely independent heavy work to a separate thread, but avoid wrapping a single native plugin call in it - passing a plugin's worklet-callable method through nested worklet closures into a different Worklet Runtime is fragile and can throw at runtime. ## iOS Orientation Notes (Text Recognition) iOS camera sensors are fixed in landscape orientation. The frame buffer stays landscape-shaped even when the UI rotates, so ML Kit needs an explicit orientation hint to rotate text correctly. On iOS, pass `outputOrientation` to `textRecognition(frame, { outputOrientation })` so ML Kit can map the buffer to upright text. Android handles rotation automatically. +## Troubleshooting + ### ⚠️ iOS Simulator (Apple Silicon) – Heads-up On Apple Silicon Macs, building for the **iOS Simulator (arm64)** may fail after installing this package. @@ -243,21 +463,28 @@ On Apple Silicon Macs, building for the **iOS Simulator (arm64)** may fail after This is a **known limitation of Google ML Kit**, which does not currently ship an `arm64-simulator` slice for some iOS frameworks. The library works correctly on **physical iOS devices** and on the **iOS Simulator when running under Rosetta**. +### Xcode 26.4 Build Failures (fmt / consteval) + +If your iOS build fails in Pods with errors referencing `fmt/include/fmt/base.h` or `FMT_USE_CONSTEVAL` after updating to Xcode 26.4, see [docs/xcode-26.4-fmt-consteval-workaround.md](docs/xcode-26.4-fmt-consteval-workaround.md) for the root cause and a `post_install` Podfile patch. This is a React Native / Xcode toolchain issue, not specific to this library. + ## Google ML Kit Vision Features Roadmap -| # | Feature | Status | Platform | -| --- | --------------------------------- | ------------------------------------------ | ------------------------------------------------- | -| 0 | **Text recognition v2** | [![complete][complete]][complete] | [![android][android]][android] [![ios][ios]][ios] | -| 1 | **Face detection** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 2 | **Face mesh detection** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] | -| 3 | **Pose detection** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 4 | **Selfie segmentation** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 5 | **Subject segmentation** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] | -| 6 | **Document scanner** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] | -| 7 | **Barcode scanning** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 8 | **Image labeling** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 9 | **Object detection and tracking** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | -| 10 | **Digital ink recognition** | [![in-progress][in-progress]][in-progress] | [![android][android]][android] [![ios][ios]][ios] | +| Feature | Release status | Intended platform | +| --------------------------------- | ----------------- | ----------------- | +| **Text recognition v2** | Available in v2 | Android and iOS | +| **Barcode scanning** | Available in v2 | Android and iOS | +| **Face detection** | Post-v2 roadmap | Android and iOS | +| **Face mesh detection** | Post-v2 roadmap | Android | +| **Pose detection** | Post-v2 roadmap | Android and iOS | +| **Selfie segmentation** | Post-v2 roadmap | Android and iOS | +| **Subject segmentation** | Post-v2 roadmap | Android | +| **Document scanner** | Post-v2 roadmap | Android | +| **Image labeling** | Post-v2 roadmap | Android and iOS | +| **Object detection and tracking** | Post-v2 roadmap | Android and iOS | +| **Digital ink recognition** | Post-v2 roadmap | Android and iOS | + +Roadmap entries are not implemented public APIs and are not commitments to a +particular release. ## Sponsor on GitHub @@ -267,12 +494,6 @@ react-native-vision-camera-mlkit is provided as is and maintained in my free tim If you’re integrating this library into a production app, consider funding the project. -[complete]: https://img.shields.io/badge/COMPLETE-5E5CE6 -[in-progress]: https://img.shields.io/badge/IN%20PROGRESS-FFD60A - -[android]: https://img.shields.io/badge/ANDROID-3DDC84 -[ios]: https://img.shields.io/badge/IOS-0A84FF - [contributors-shield]: https://img.shields.io/github/contributors/pedrol2b/react-native-vision-camera-mlkit.svg?style=for-the-badge [contributors-url]: https://github.com/pedrol2b/react-native-vision-camera-mlkit/graphs/contributors [forks-shield]: https://img.shields.io/github/forks/pedrol2b/react-native-vision-camera-mlkit.svg?style=for-the-badge diff --git a/VisionCameraMLKit.podspec b/VisionCameraMLKit.podspec index e7625ab..88f71d1 100644 --- a/VisionCameraMLKit.podspec +++ b/VisionCameraMLKit.podspec @@ -1,6 +1,7 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) +load 'nitrogen/generated/ios/VisionCameraMLKit+autolinking.rb' # Load MLKit configuration from global variable set in Podfile # Default configuration @@ -14,7 +15,7 @@ default_config = { 'poseDetection' => false, 'poseDetectionAccurate' => false, 'selfieSegmentation' => false, - 'barcodeScanning' => false, + 'barcodeScanning' => true, 'imageLabeling' => false, 'objectDetection' => false, 'digitalInkRecognition' => false, @@ -45,8 +46,16 @@ Pod::Spec.new do |s| s.dependency "VisionCamera" + # Compute whether any text recognition variant is enabled + any_text_recognition = mlkit_config['textRecognition'] || + mlkit_config['textRecognitionChinese'] || + mlkit_config['textRecognitionDevanagari'] || + mlkit_config['textRecognitionJapanese'] || + mlkit_config['textRecognitionKorean'] + # Generate Swift compiler flags for conditional compilation swift_flags = [] + swift_flags << "MLKIT_TEXT_RECOGNITION_ANY" if any_text_recognition swift_flags << "MLKIT_TEXT_RECOGNITION" if mlkit_config['textRecognition'] swift_flags << "MLKIT_TEXT_RECOGNITION_CHINESE" if mlkit_config['textRecognitionChinese'] swift_flags << "MLKIT_TEXT_RECOGNITION_DEVANAGARI" if mlkit_config['textRecognitionDevanagari'] @@ -74,7 +83,9 @@ Pod::Spec.new do |s| # Text recognition v2 # https://developers.google.com/ml-kit/vision/text-recognition/v2/ios - if mlkit_config['textRecognition'] + # Base TextRecognition is required whenever any text recognition variant is enabled, + # as it provides shared types (TextRecognizer, CommonTextRecognizerOptions, Text, etc.) + if any_text_recognition s.dependency "GoogleMLKit/TextRecognition" end if mlkit_config['textRecognitionChinese'] @@ -143,6 +154,8 @@ Pod::Spec.new do |s| # ===== GoogleMLKit Vision ===== + add_nitrogen_files(s) + if respond_to?(:install_modules_dependencies, true) install_modules_dependencies(s) else diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt new file mode 100644 index 0000000..d229575 --- /dev/null +++ b/android/CMakeLists.txt @@ -0,0 +1,60 @@ +project(VisionCameraMLKit) +cmake_minimum_required(VERSION 3.9.0) + +set(PACKAGE_NAME VisionCameraMLKit) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_STANDARD 20) + +add_library(${PACKAGE_NAME} SHARED + src/main/cpp/cpp-adapter.cpp +) + +add_definitions(-DBUILDING_VISIONCAMERAMLKIT_WITH_GENERATED_CMAKE_PROJECT) +add_definitions(-DRN_SERIALIZABLE_STATE) + +include_directories( + "../nitrogen/generated/shared/c++" + "../nitrogen/generated/android/c++" + "../nitrogen/generated/android/" + "src/main/cpp" + "../cpp" +) + +target_sources( + ${PACKAGE_NAME} PRIVATE + ../nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp + ../nitrogen/generated/shared/c++/HybridTextRecognizerSpec.cpp + ../nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.cpp + ../nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.cpp + ../nitrogen/generated/android/c++/JHybridTextRecognizerSpec.cpp + ../nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.cpp + ../nitrogen/generated/android/c++/JVariant_NullType_Double.cpp +) + +find_library(LOG_LIB log) +find_package(fbjni REQUIRED) +find_package(ReactAndroid REQUIRED) +find_package(react-native-nitro-modules REQUIRED) +find_package(react-native-vision-camera REQUIRED) + +target_link_libraries( + ${PACKAGE_NAME} + ${LOG_LIB} + android + fbjni::fbjni + ReactAndroid::jsi + react-native-nitro-modules::NitroModules + react-native-vision-camera::VisionCamera +) + +if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76) + target_link_libraries( + ${PACKAGE_NAME} + ReactAndroid::reactnative + ) +else() + target_link_libraries( + ${PACKAGE_NAME} + ReactAndroid::react_nativemodule_core + ) +endif() diff --git a/android/build.gradle b/android/build.gradle index 2dfea3f..c156d5b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,6 +21,11 @@ apply plugin: "kotlin-android" apply plugin: "com.facebook.react" +def reactNativeArchitectures() { + def value = rootProject.getProperties().get("reactNativeArchitectures") + return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] +} + def getExtOrIntegerDefault(name) { return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["VisionCameraMLKit_" + name]).toInteger() } @@ -42,7 +47,7 @@ def getMLKitConfig() { selfieSegmentation : false, subjectSegmentation : false, documentScanner : false, - barcodeScanning : false, + barcodeScanning : true, imageLabeling : false, objectDetection : false, digitalInkRecognition : false, @@ -69,9 +74,17 @@ def getMLKitConfig() { def mlkitConfig = getMLKitConfig() +// Compute whether any text recognition variant is enabled +def anyTextRecognition = mlkitConfig.textRecognition || + mlkitConfig.textRecognitionChinese || + mlkitConfig.textRecognitionDevanagari || + mlkitConfig.textRecognitionJapanese || + mlkitConfig.textRecognitionKorean + android { namespace "com.visioncameramlkit" + ndkVersion getExtOrDefault("ndkVersion") compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") defaultConfig { @@ -79,6 +92,7 @@ android { targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") // Add build config fields for conditional compilation + buildConfigField "boolean", "MLKIT_TEXT_RECOGNITION_ANY", "${anyTextRecognition}" buildConfigField "boolean", "MLKIT_TEXT_RECOGNITION", "${mlkitConfig.textRecognition}" buildConfigField "boolean", "MLKIT_TEXT_RECOGNITION_CHINESE", "${mlkitConfig.textRecognitionChinese}" buildConfigField "boolean", "MLKIT_TEXT_RECOGNITION_DEVANAGARI", "${mlkitConfig.textRecognitionDevanagari}" @@ -95,10 +109,41 @@ android { buildConfigField "boolean", "MLKIT_IMAGE_LABELING", "${mlkitConfig.imageLabeling}" buildConfigField "boolean", "MLKIT_OBJECT_DETECTION", "${mlkitConfig.objectDetection}" buildConfigField "boolean", "MLKIT_DIGITAL_INK_RECOGNITION", "${mlkitConfig.digitalInkRecognition}" + + externalNativeBuild { + cmake { + cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all" + arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON" + abiFilters (*reactNativeArchitectures()) + + buildTypes { + debug { + cppFlags "-O1 -g" + } + release { + cppFlags "-O2" + } + } + } + } + } + + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } } buildFeatures { buildConfig true + prefab true + prefabPublishing true + } + + prefab { + VisionCameraMLKit { + headers "${project.buildDir}/headers/visioncameramlkit/" + } } buildTypes { @@ -120,7 +165,10 @@ android { main { java.srcDirs += [ "generated/java", - "generated/jni" + "generated/jni", + "../nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit", + anyTextRecognition ? "src/textRecognitionEnabled/java" : "src/textRecognitionDisabled/java", + mlkitConfig.barcodeScanning ? "src/barcodeScanningEnabled/java" : "src/barcodeScanningDisabled/java", ] } } @@ -136,15 +184,23 @@ def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { implementation "com.facebook.react:react-android" api project(":react-native-vision-camera") + implementation project(":react-native-nitro-modules") implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "androidx.camera:camera-core:1.5.2" + implementation "androidx.exifinterface:exifinterface:1.3.7" // ===== GoogleMLKit Vision ===== - // Only include dependencies for enabled features + // vision-common is always present: it's a small shared-types artifact (InputImage, + // etc.) used by the image-preprocessing pipeline regardless of which MLKit feature + // is enabled, and carries no OCR/barcode model weights. Every feature-specific SDK + // below stays properly gated behind its own flag and its own conditional Kotlin + // source set (see sourceSets above), so enabling only one feature (e.g. barcode + // scanning) does not pull in or compile against the others. + implementation "com.google.mlkit:vision-common:17.3.0" // Text recognition v2 // https://developers.google.com/ml-kit/vision/text-recognition/v2/android - if (mlkitConfig.textRecognition) { + if (anyTextRecognition) { implementation "com.google.mlkit:text-recognition:16.0.1" } if (mlkitConfig.textRecognitionChinese) { @@ -225,3 +281,15 @@ dependencies { // ===== GoogleMLKit Vision ===== } + +tasks.register('prepareHeaders', Copy) { + from fileTree('./src/main/cpp').filter { it.isFile() } + from fileTree('../cpp/').filter { it.isFile() } + from fileTree('../nitrogen/generated/android/c++').filter { it.isFile() } + from fileTree('../nitrogen/generated/shared/c++').filter { it.isFile() } + include "*.hpp" + into "${project.buildDir}/headers/visioncameramlkit/VisionCameraMLKit/" + includeEmptyDirs = false +} + +preBuild.dependsOn(prepareHeaders) diff --git a/android/src/barcodeScanningDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt b/android/src/barcodeScanningDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt new file mode 100644 index 0000000..e0b0b1a --- /dev/null +++ b/android/src/barcodeScanningDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt @@ -0,0 +1,13 @@ +package com.visioncameramlkit.infrastructure.mlkit.factories + +import com.visioncameramlkit.domain.models.BarcodeScanningOptions +import com.visioncameramlkit.domain.models.BarcodeScanningResult +import com.visioncameramlkit.domain.services.IRecognitionService + +object BarcodeScanningServiceFactory { + fun create(options: BarcodeScanningOptions = BarcodeScanningOptions()): IRecognitionService = + throw IllegalStateException( + "Barcode scanning is not enabled in this build. Enable barcodeScanning in your MLKit " + + "configuration to use this feature.", + ) +} diff --git a/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitBarcodeScanningService.kt b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitBarcodeScanningService.kt new file mode 100644 index 0000000..b38a87b --- /dev/null +++ b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitBarcodeScanningService.kt @@ -0,0 +1,31 @@ +package com.visioncameramlkit.infrastructure.mlkit + +import com.google.android.gms.tasks.Tasks +import com.google.mlkit.vision.barcode.BarcodeScanner +import com.google.mlkit.vision.barcode.common.Barcode +import com.visioncameramlkit.domain.models.BarcodeScanningResult +import com.visioncameramlkit.domain.models.ProcessedImage +import com.visioncameramlkit.domain.services.IRecognitionService +import com.visioncameramlkit.infrastructure.mlkit.adapters.MLKitBarcodeAdapter + +class MLKitBarcodeScanningService( + private val barcodeScanner: BarcodeScanner, +) : IRecognitionService { + // ML Kit's on-device detectors are not documented as safe for concurrent use. + // This instance is shared between the synchronous frame-processor path and the + // async static-image path, so calls (and disposal) must be serialized. + private val lock = Any() + + override fun recognize(image: ProcessedImage): BarcodeScanningResult = + synchronized(lock) { + val task = barcodeScanner.process(image.image) + val barcodes: List = Tasks.await(task) + MLKitBarcodeAdapter.toDomain(barcodes) + } + + override fun close() { + synchronized(lock) { + barcodeScanner.close() + } + } +} diff --git a/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitBarcodeAdapter.kt b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitBarcodeAdapter.kt new file mode 100644 index 0000000..06ae9a0 --- /dev/null +++ b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitBarcodeAdapter.kt @@ -0,0 +1,320 @@ +package com.visioncameramlkit.infrastructure.mlkit.adapters + +import com.google.mlkit.vision.barcode.common.Barcode +import com.visioncameramlkit.domain.models.BarcodeData +import com.visioncameramlkit.domain.models.BarcodeParsedValue +import com.visioncameramlkit.domain.models.BarcodeScanningResult +import com.visioncameramlkit.domain.models.BoundingBox +import com.visioncameramlkit.domain.models.Corner + +@Suppress("TooManyFunctions") +object MLKitBarcodeAdapter { + private const val BYTE_MASK = 0xFF + + private val formatNameMap: Map = + mapOf( + Barcode.FORMAT_CODE_128 to "CODE_128", + Barcode.FORMAT_CODE_39 to "CODE_39", + Barcode.FORMAT_CODE_93 to "CODE_93", + Barcode.FORMAT_CODABAR to "CODABAR", + Barcode.FORMAT_DATA_MATRIX to "DATA_MATRIX", + Barcode.FORMAT_EAN_13 to "EAN_13", + Barcode.FORMAT_EAN_8 to "EAN_8", + Barcode.FORMAT_ITF to "ITF", + Barcode.FORMAT_QR_CODE to "QR_CODE", + Barcode.FORMAT_UPC_A to "UPC_A", + Barcode.FORMAT_UPC_E to "UPC_E", + Barcode.FORMAT_PDF417 to "PDF417", + Barcode.FORMAT_AZTEC to "AZTEC", + Barcode.FORMAT_UNKNOWN to "UNKNOWN", + ) + + private val valueTypeNameMap: Map = + mapOf( + Barcode.TYPE_CONTACT_INFO to "TYPE_CONTACT_INFO", + Barcode.TYPE_EMAIL to "TYPE_EMAIL", + Barcode.TYPE_ISBN to "TYPE_ISBN", + Barcode.TYPE_PHONE to "TYPE_PHONE", + Barcode.TYPE_PRODUCT to "TYPE_PRODUCT", + Barcode.TYPE_SMS to "TYPE_SMS", + Barcode.TYPE_TEXT to "TYPE_TEXT", + Barcode.TYPE_URL to "TYPE_URL", + Barcode.TYPE_WIFI to "TYPE_WIFI", + Barcode.TYPE_GEO to "TYPE_GEO", + Barcode.TYPE_CALENDAR_EVENT to "TYPE_CALENDAR_EVENT", + Barcode.TYPE_DRIVER_LICENSE to "TYPE_DRIVER_LICENSE", + Barcode.TYPE_UNKNOWN to "TYPE_UNKNOWN", + ) + + private val parsedValueExtractors: Map BarcodeParsedValue?> = + mapOf( + Barcode.TYPE_WIFI to { barcode -> barcode.wifi?.let(::toWifi) }, + Barcode.TYPE_URL to { barcode -> barcode.url?.let(::toUrl) }, + Barcode.TYPE_SMS to { barcode -> barcode.sms?.let(::toSms) }, + Barcode.TYPE_EMAIL to { barcode -> barcode.email?.let(::toEmail) }, + Barcode.TYPE_PHONE to { barcode -> barcode.phone?.let(::toPhone) }, + Barcode.TYPE_CONTACT_INFO to { barcode -> barcode.contactInfo?.let(::toContactInfo) }, + Barcode.TYPE_CALENDAR_EVENT to { barcode -> barcode.calendarEvent?.let(::toCalendarEvent) }, + Barcode.TYPE_GEO to { barcode -> barcode.geoPoint?.let(::toGeoPoint) }, + Barcode.TYPE_DRIVER_LICENSE to { barcode -> barcode.driverLicense?.let(::toDriverLicense) }, + ) + + private val rawValueTypeMappings: Map> = + mapOf( + Barcode.TYPE_TEXT to ("TYPE_TEXT" to "text"), + Barcode.TYPE_PRODUCT to ("TYPE_PRODUCT" to "product"), + Barcode.TYPE_ISBN to ("TYPE_ISBN" to "isbn"), + ) + + fun toDomain(barcodes: List): BarcodeScanningResult = + BarcodeScanningResult( + barcodes = barcodes.map(::toBarcodeData), + ) + + private fun toBarcodeData(barcode: Barcode): BarcodeData = + BarcodeData( + bounds = barcode.boundingBox?.let(::toBoundingBox), + corners = barcode.cornerPoints?.map(::toCorner), + format = barcode.format, + formatName = formatName(barcode.format), + valueType = barcode.valueType, + valueTypeName = valueTypeName(barcode.valueType), + rawValue = barcode.rawValue, + displayValue = barcode.displayValue, + rawBytes = barcode.rawBytes?.map { byte -> byte.toInt() and BYTE_MASK }, + isPotential = barcode.rawValue == null && barcode.rawBytes == null, + value = toParsedValue(barcode), + ) + + private fun toParsedValue(barcode: Barcode): BarcodeParsedValue? { + parsedValueExtractors[barcode.valueType]?.invoke(barcode)?.let { parsed -> + return parsed + } + + val rawMapping = rawValueTypeMappings[barcode.valueType] ?: return null + val rawValue = barcode.rawValue ?: return null + return BarcodeParsedValue( + type = rawMapping.first, + data = mapOf(rawMapping.second to rawValue), + ) + } + + private fun toWifi(wifi: Barcode.WiFi): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_WIFI", + data = + mapOf( + "ssid" to wifi.ssid, + "password" to wifi.password, + "encryptionType" to wifi.encryptionType, + "encryptionTypeName" to wifiEncryptionName(wifi.encryptionType), + ), + ) + + private fun toUrl(url: Barcode.UrlBookmark): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_URL", + data = + mapOf( + "title" to url.title, + "url" to url.url, + ), + ) + + private fun toSms(sms: Barcode.Sms): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_SMS", + data = + mapOf( + "message" to sms.message, + "phoneNumber" to sms.phoneNumber, + ), + ) + + private fun toEmail(email: Barcode.Email): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_EMAIL", + data = + mapOf( + "address" to email.address, + "subject" to email.subject, + "body" to email.body, + "type" to email.type, + "typeName" to emailTypeName(email.type), + ), + ) + + private fun toPhone(phone: Barcode.Phone): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_PHONE", + data = + mapOf( + "number" to phone.number, + "type" to phone.type, + "typeName" to phoneTypeName(phone.type), + ), + ) + + private fun toContactInfo(contactInfo: Barcode.ContactInfo): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_CONTACT_INFO", + data = + mapOf( + "name" to contactInfo.name?.let(::toPersonName), + "organization" to contactInfo.organization, + "title" to contactInfo.title, + "phones" to contactInfo.phones.map(::toPhoneMap), + "emails" to contactInfo.emails.map(::toEmailMap), + "addresses" to contactInfo.addresses.map(::toAddressMap), + "urls" to contactInfo.urls, + ), + ) + + private fun toCalendarEvent(event: Barcode.CalendarEvent): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_CALENDAR_EVENT", + data = + mapOf( + "summary" to event.summary, + "description" to event.description, + "location" to event.location, + "organizer" to event.organizer, + "status" to event.status, + "start" to event.start?.let(::toCalendarDateTime), + "end" to event.end?.let(::toCalendarDateTime), + ), + ) + + private fun toGeoPoint(geoPoint: Barcode.GeoPoint): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_GEO", + data = + mapOf( + "lat" to geoPoint.lat, + "lng" to geoPoint.lng, + ), + ) + + private fun toDriverLicense(driverLicense: Barcode.DriverLicense): BarcodeParsedValue = + BarcodeParsedValue( + type = "TYPE_DRIVER_LICENSE", + data = + mapOf( + "documentType" to driverLicense.documentType, + "licenseNumber" to driverLicense.licenseNumber, + "firstName" to driverLicense.firstName, + "middleName" to driverLicense.middleName, + "lastName" to driverLicense.lastName, + "gender" to driverLicense.gender, + "addressStreet" to driverLicense.addressStreet, + "addressCity" to driverLicense.addressCity, + "addressState" to driverLicense.addressState, + "addressZip" to driverLicense.addressZip, + "birthDate" to driverLicense.birthDate, + "issueDate" to driverLicense.issueDate, + "expiryDate" to driverLicense.expiryDate, + "issuingCountry" to driverLicense.issuingCountry, + ), + ) + + private fun toPersonName(name: Barcode.PersonName): Map = + mapOf( + "formattedName" to name.formattedName, + "pronunciation" to name.pronunciation, + "prefix" to name.prefix, + "first" to name.first, + "middle" to name.middle, + "last" to name.last, + "suffix" to name.suffix, + ) + + private fun toPhoneMap(phone: Barcode.Phone): Map = + mapOf( + "number" to phone.number, + "type" to phone.type, + "typeName" to phoneTypeName(phone.type), + ) + + private fun toEmailMap(email: Barcode.Email): Map = + mapOf( + "address" to email.address, + "subject" to email.subject, + "body" to email.body, + "type" to email.type, + "typeName" to emailTypeName(email.type), + ) + + private fun toAddressMap(address: Barcode.Address): Map = + mapOf( + "addressLines" to address.addressLines.toList(), + "type" to address.type, + "typeName" to addressTypeName(address.type), + ) + + private fun toCalendarDateTime(dateTime: Barcode.CalendarDateTime): Map = + mapOf( + "year" to dateTime.year, + "month" to dateTime.month, + "day" to dateTime.day, + "hours" to dateTime.hours, + "minutes" to dateTime.minutes, + "seconds" to dateTime.seconds, + "isUtc" to dateTime.isUtc, + "rawValue" to dateTime.rawValue, + ) + + private fun toBoundingBox(rect: android.graphics.Rect): BoundingBox = + BoundingBox( + x = rect.exactCenterX().toDouble(), + y = rect.exactCenterY().toDouble(), + centerX = rect.centerX().toDouble(), + centerY = rect.centerY().toDouble(), + width = rect.width().toDouble(), + height = rect.height().toDouble(), + top = rect.top.toDouble(), + left = rect.left.toDouble(), + bottom = rect.bottom.toDouble(), + right = rect.right.toDouble(), + ) + + private fun toCorner(point: android.graphics.Point): Corner = + Corner( + x = point.x.toDouble(), + y = point.y.toDouble(), + ) + + private fun formatName(format: Int): String = formatNameMap[format] ?: "UNKNOWN" + + private fun valueTypeName(valueType: Int): String = valueTypeNameMap[valueType] ?: "TYPE_UNKNOWN" + + private fun wifiEncryptionName(type: Int): String = + when (type) { + Barcode.WiFi.TYPE_OPEN -> "OPEN" + Barcode.WiFi.TYPE_WEP -> "WEP" + Barcode.WiFi.TYPE_WPA -> "WPA" + else -> "UNKNOWN" + } + + private fun phoneTypeName(type: Int): String = + when (type) { + Barcode.Phone.TYPE_FAX -> "FAX" + Barcode.Phone.TYPE_HOME -> "HOME" + Barcode.Phone.TYPE_MOBILE -> "MOBILE" + Barcode.Phone.TYPE_WORK -> "WORK" + else -> "UNKNOWN" + } + + private fun emailTypeName(type: Int): String = + when (type) { + Barcode.Email.TYPE_HOME -> "HOME" + Barcode.Email.TYPE_WORK -> "WORK" + else -> "UNKNOWN" + } + + private fun addressTypeName(type: Int): String = + when (type) { + Barcode.Address.TYPE_HOME -> "HOME" + Barcode.Address.TYPE_WORK -> "WORK" + else -> "UNKNOWN" + } +} diff --git a/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt new file mode 100644 index 0000000..e172a34 --- /dev/null +++ b/android/src/barcodeScanningEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/BarcodeScanningServiceFactory.kt @@ -0,0 +1,59 @@ +package com.visioncameramlkit.infrastructure.mlkit.factories + +import com.google.mlkit.vision.barcode.BarcodeScanner +import com.google.mlkit.vision.barcode.BarcodeScannerOptions +import com.google.mlkit.vision.barcode.BarcodeScanning +import com.google.mlkit.vision.barcode.common.Barcode +import com.visioncameramlkit.domain.models.BarcodeFormatOption +import com.visioncameramlkit.domain.models.BarcodeScanningOptions +import com.visioncameramlkit.infrastructure.mlkit.MLKitBarcodeScanningService + +object BarcodeScanningServiceFactory { + private val barcodeFormatMap: Map = + mapOf( + BarcodeFormatOption.UNKNOWN to Barcode.FORMAT_UNKNOWN, + BarcodeFormatOption.ALL_FORMATS to Barcode.FORMAT_ALL_FORMATS, + BarcodeFormatOption.CODE_128 to Barcode.FORMAT_CODE_128, + BarcodeFormatOption.CODE_39 to Barcode.FORMAT_CODE_39, + BarcodeFormatOption.CODE_93 to Barcode.FORMAT_CODE_93, + BarcodeFormatOption.CODABAR to Barcode.FORMAT_CODABAR, + BarcodeFormatOption.DATA_MATRIX to Barcode.FORMAT_DATA_MATRIX, + BarcodeFormatOption.EAN_13 to Barcode.FORMAT_EAN_13, + BarcodeFormatOption.EAN_8 to Barcode.FORMAT_EAN_8, + BarcodeFormatOption.ITF to Barcode.FORMAT_ITF, + BarcodeFormatOption.QR_CODE to Barcode.FORMAT_QR_CODE, + BarcodeFormatOption.UPC_A to Barcode.FORMAT_UPC_A, + BarcodeFormatOption.UPC_E to Barcode.FORMAT_UPC_E, + BarcodeFormatOption.PDF417 to Barcode.FORMAT_PDF417, + BarcodeFormatOption.AZTEC to Barcode.FORMAT_AZTEC, + ) + + fun createBarcodeScanner(options: BarcodeScanningOptions = BarcodeScanningOptions()): BarcodeScanner { + val builder = BarcodeScannerOptions.Builder() + + val selectedFormats = + options.formats + .map(::toMlKitFormat) + .filter { it != Barcode.FORMAT_UNKNOWN && it != Barcode.FORMAT_ALL_FORMATS } + + if (selectedFormats.isNotEmpty()) { + val first = selectedFormats.first() + val rest = selectedFormats.drop(1).toIntArray() + @Suppress("SpreadOperator") + builder.setBarcodeFormats(first, *rest) + } + + if (options.enableAllPotentialBarcodes) { + builder.enableAllPotentialBarcodes() + } + + return BarcodeScanning.getClient(builder.build()) + } + + fun create(options: BarcodeScanningOptions = BarcodeScanningOptions()): MLKitBarcodeScanningService { + val scanner = createBarcodeScanner(options) + return MLKitBarcodeScanningService(scanner) + } + + private fun toMlKitFormat(format: BarcodeFormatOption): Int = barcodeFormatMap[format] ?: Barcode.FORMAT_UNKNOWN +} diff --git a/android/src/main/cpp/cpp-adapter.cpp b/android/src/main/cpp/cpp-adapter.cpp new file mode 100644 index 0000000..6c6a5d9 --- /dev/null +++ b/android/src/main/cpp/cpp-adapter.cpp @@ -0,0 +1,41 @@ +#include "VisionCameraMLKitOnLoad.hpp" +#include "JHybridBarcodeScannerSpec.hpp" +#include "JHybridTextRecognizerSpec.hpp" +#include "JHybridVisionCameraMLKitSpec.hpp" +#include +#include +#include + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + return facebook::jni::initialize(vm, []() { + margelo::nitro::visioncameramlkit::registerAllNatives(); + }); +} + +namespace margelo::nitro::visioncameramlkit { + +struct JHybridVisionCameraMLKitSpecImpl: + public facebook::jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKit;"; + + static std::shared_ptr create() { + static const auto constructorFn = javaClassStatic()->getConstructor(); + facebook::jni::local_ref javaPart = javaClassStatic()->newObject(constructorFn); + return javaPart->getJHybridVisionCameraMLKitSpec(); + } +}; + +void registerAllNatives() { + JHybridBarcodeScannerSpec::CxxPart::registerNatives(); + JHybridTextRecognizerSpec::CxxPart::registerNatives(); + JHybridVisionCameraMLKitSpec::CxxPart::registerNatives(); + + margelo::nitro::HybridObjectRegistry::registerHybridObjectConstructor( + "VisionCameraMLKit", + []() -> std::shared_ptr { + return JHybridVisionCameraMLKitSpecImpl::create(); + } + ); +} + +} // namespace margelo::nitro::visioncameramlkit diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeFormat+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeFormat+toDomain.kt new file mode 100644 index 0000000..8e86109 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeFormat+toDomain.kt @@ -0,0 +1,9 @@ +package com.margelo.nitro.visioncameramlkit + +import com.visioncameramlkit.domain.models.BarcodeFormatOption + +internal fun BarcodeFormat.toDomainBarcodeFormat(): BarcodeFormatOption = + runCatching { BarcodeFormatOption.valueOf(name) }.getOrDefault(BarcodeFormatOption.UNKNOWN) + +internal fun Array?.toDomainBarcodeFormats(): List = + this?.map { it.toDomainBarcodeFormat() } ?: emptyList() diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeParsedValue+toNitroAnyMap.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeParsedValue+toNitroAnyMap.kt new file mode 100644 index 0000000..ab2479f --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeParsedValue+toNitroAnyMap.kt @@ -0,0 +1,13 @@ +package com.margelo.nitro.visioncameramlkit + +import com.margelo.nitro.core.AnyMap +import com.visioncameramlkit.domain.models.BarcodeParsedValue + +internal fun BarcodeParsedValue.toNitroAnyMap(): AnyMap = + AnyMap.fromMap( + mapOf( + "type" to type, + "data" to data, + ), + ignoreIncompatible = false, + ) diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions+toDomain.kt new file mode 100644 index 0000000..9958ec1 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions+toDomain.kt @@ -0,0 +1,20 @@ +package com.margelo.nitro.visioncameramlkit + +import com.visioncameramlkit.domain.models.BarcodeScanningOptions +import com.visioncameramlkit.domain.models.ImagePreprocessingOptions + +internal fun BarcodeScannerOptions.toDomainBarcodeScanningOptions(): BarcodeScanningOptions = + BarcodeScanningOptions( + formats = formats.toDomainBarcodeFormats(), + enableAllPotentialBarcodes = enableAllPotentialBarcodes ?: false, + invertColors = invertColors ?: false, + scaleFactor = scaleFactor?.toFloat() ?: 1.0f, + ) + +internal fun BarcodeScannerOptions.toImagePreprocessingOptions(): ImagePreprocessingOptions = + ImagePreprocessingOptions( + invertColors = invertColors ?: false, + scaleFactor = scaleFactor?.toFloat() ?: 1.0f, + roi = roi.toDomainRegionOfInterest(), + orientation = orientation.toDomainOrientation(), + ) diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScanningResult+toNitro.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScanningResult+toNitro.kt new file mode 100644 index 0000000..87d2e41 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BarcodeScanningResult+toNitro.kt @@ -0,0 +1,26 @@ +package com.margelo.nitro.visioncameramlkit + +internal fun com.visioncameramlkit.domain.models.BarcodeScanningResult.toNitroResult(): BarcodeScannerResult = + BarcodeScannerResult( + barcodes = barcodes.map { it.toNitroBarcode() }.toTypedArray(), + ) + +private fun com.visioncameramlkit.domain.models.BarcodeData.toNitroBarcode(): BarcodeScannerBarcode = + BarcodeScannerBarcode( + bounds = bounds?.toNitroBoundingBox(), + corners = corners?.toNitroCorners(), + format = format.toDouble(), + formatName = formatName.toNitroBarcodeFormat(), + valueType = valueType.toDouble(), + valueTypeName = valueTypeName.toNitroBarcodeValueTypeName(), + rawValue = rawValue, + displayValue = displayValue, + rawBytes = rawBytes?.map { it.toDouble() }?.toDoubleArray(), + value = value?.toNitroAnyMap(), + isPotential = isPotential, + ) + +private fun String.toNitroBarcodeFormat(): BarcodeFormat = runCatching { BarcodeFormat.valueOf(this) }.getOrDefault(BarcodeFormat.UNKNOWN) + +private fun String.toNitroBarcodeValueTypeName(): BarcodeValueTypeName = + runCatching { BarcodeValueTypeName.valueOf(this) }.getOrDefault(BarcodeValueTypeName.TYPE_UNKNOWN) diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/BoundingBox+toNitro.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BoundingBox+toNitro.kt new file mode 100644 index 0000000..dc6cf4f --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/BoundingBox+toNitro.kt @@ -0,0 +1,31 @@ +package com.margelo.nitro.visioncameramlkit + +private val emptyBoundingBox = + BoundingBox( + x = 0.0, + y = 0.0, + centerX = 0.0, + centerY = 0.0, + width = 0.0, + height = 0.0, + top = 0.0, + left = 0.0, + bottom = 0.0, + right = 0.0, + ) + +internal fun com.visioncameramlkit.domain.models.BoundingBox?.toNitroBoundingBox(): BoundingBox = + this?.let { + BoundingBox( + x = it.x, + y = it.y, + centerX = it.centerX, + centerY = it.centerY, + width = it.width, + height = it.height, + top = it.top, + left = it.left, + bottom = it.bottom, + right = it.right, + ) + } ?: emptyBoundingBox diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/Corner+toNitro.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Corner+toNitro.kt new file mode 100644 index 0000000..42c97bb --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Corner+toNitro.kt @@ -0,0 +1,10 @@ +package com.margelo.nitro.visioncameramlkit + +internal fun com.visioncameramlkit.domain.models.Corner.toNitroCorner(): Corner = + Corner( + x = x, + y = y, + ) + +internal fun List?.toNitroCorners(): Array = + this?.map { it.toNitroCorner() }?.toTypedArray() ?: emptyArray() diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/Double+toNullableVariant.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Double+toNullableVariant.kt new file mode 100644 index 0000000..bcbd1bf --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Double+toNullableVariant.kt @@ -0,0 +1,7 @@ +package com.margelo.nitro.visioncameramlkit + +import com.margelo.nitro.core.NullType + +internal fun Double?.toNullableDoubleVariant(): Variant_NullType_Double = + this?.let { Variant_NullType_Double.create(it) } + ?: Variant_NullType_Double.create(NullType.NULL) diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridBarcodeScanner.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridBarcodeScanner.kt new file mode 100644 index 0000000..b3c19aa --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridBarcodeScanner.kt @@ -0,0 +1,49 @@ +package com.margelo.nitro.visioncameramlkit + +import android.util.Log +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.camera.HybridFrameSpec +import com.margelo.nitro.core.Promise +import com.visioncameramlkit.domain.models.remap +import com.visioncameramlkit.infrastructure.image.ImagePreprocessor +import com.visioncameramlkit.infrastructure.mlkit.factories.BarcodeScanningServiceFactory +import java.util.concurrent.atomic.AtomicBoolean + +@DoNotStrip +@Keep +class HybridBarcodeScanner( + private val options: BarcodeScannerOptions, +) : HybridBarcodeScannerSpec() { + private val imagePreprocessor = ImagePreprocessor() + private val barcodeOptions = options.toDomainBarcodeScanningOptions() + private val imageOptions = options.toImagePreprocessingOptions() + private val recognitionService = BarcodeScanningServiceFactory.create(barcodeOptions) + private val isDisposed = AtomicBoolean(false) + + override fun recognize( + frame: HybridFrameSpec, + args: MLKitBaseArguments?, + ): BarcodeScannerResult { + val processedImage = frame.toProcessedImage(imagePreprocessor, imageOptions) + val result = recognitionService.recognize(processedImage) + return result.remap(processedImage.metadata).toNitroResult() + } + + override fun recognizeImage(uri: String): Promise = + Promise.parallel { + StaticImageUriResolver.resolve(uri).use { resolvedImage -> + val processedImage = imagePreprocessor.preprocessImage(resolvedImage.file, imageOptions) + val result = recognitionService.recognize(processedImage) + result.remap(processedImage.metadata).toNitroResult() + } + } + + override fun dispose() { + if (isDisposed.compareAndSet(false, true)) { + runCatching { recognitionService.close() } + .onFailure { error -> Log.w(TAG, "Failed to close barcode scanner", error) } + } + super.dispose() + } +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridFrameSpec+toProcessedImage.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridFrameSpec+toProcessedImage.kt new file mode 100644 index 0000000..ed6bbd1 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridFrameSpec+toProcessedImage.kt @@ -0,0 +1,89 @@ +package com.margelo.nitro.visioncameramlkit + +import androidx.camera.core.ImageProxy +import androidx.core.graphics.scale +import com.google.mlkit.vision.common.InputImage +import com.margelo.nitro.camera.HybridFrameSpec +import com.margelo.nitro.camera.extensions.toBitmap +import com.margelo.nitro.camera.public.NativeFrame +import com.visioncameramlkit.domain.models.ImageMetadata +import com.visioncameramlkit.domain.models.ImagePreprocessingOptions +import com.visioncameramlkit.domain.models.ProcessedImage +import com.visioncameramlkit.infrastructure.image.ImagePreprocessor + +internal fun HybridFrameSpec.toProcessedImage( + imagePreprocessor: ImagePreprocessor, + options: ImagePreprocessingOptions, +): ProcessedImage { + val nativeFrame = + this as? NativeFrame + ?: throw IllegalArgumentException("Expected a VisionCamera native frame.") + + return imagePreprocessor.preprocessFrame(nativeFrame.image, this, options) +} + +internal fun ImagePreprocessor.preprocessFrame( + image: ImageProxy, + frame: HybridFrameSpec, + options: ImagePreprocessingOptions, +): ProcessedImage { + val effectiveScale = options.scaleFactor.coerceIn(0.9f, 1.0f) + val needsBitmapProcessing = + options.invertColors || + effectiveScale < 1.0f || + frame.isMirrored || + options.roi != null + + if (!needsBitmapProcessing) { + val mediaImage = + image.image + ?: throw UnsupportedOperationException("VisionCamera frame does not expose a media image.") + + val inputImage = InputImage.fromMediaImage(mediaImage, image.imageInfo.rotationDegrees) + return ProcessedImage( + image = inputImage, + metadata = + ImageMetadata( + width = image.width, + height = image.height, + rotation = image.imageInfo.rotationDegrees, + isInverted = false, + ), + ) + } + + val orientedBitmap = image.toBitmap(frame.orientation, frame.isMirrored) + val (croppedBitmap, cropRect) = cropToRegionOfInterest(orientedBitmap, options.roi) + + val scaledBitmap = + if (effectiveScale < 1.0f) { + croppedBitmap.scale( + (croppedBitmap.width * effectiveScale).toInt(), + (croppedBitmap.height * effectiveScale).toInt(), + false, + ) + } else { + croppedBitmap + } + + val processedBitmap = + if (options.invertColors) { + invertBitmap(scaledBitmap) + } else { + scaledBitmap + } + + return ProcessedImage( + image = InputImage.fromBitmap(processedBitmap, 0), + metadata = + ImageMetadata( + width = processedBitmap.width, + height = processedBitmap.height, + rotation = 0, + isInverted = options.invertColors, + offsetX = cropRect.left, + offsetY = cropRect.top, + scaleFactor = effectiveScale, + ), + ) +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridTextRecognizer.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridTextRecognizer.kt new file mode 100644 index 0000000..bf281f8 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridTextRecognizer.kt @@ -0,0 +1,49 @@ +package com.margelo.nitro.visioncameramlkit + +import android.util.Log +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.camera.HybridFrameSpec +import com.margelo.nitro.core.Promise +import com.visioncameramlkit.domain.models.remap +import com.visioncameramlkit.infrastructure.image.ImagePreprocessor +import com.visioncameramlkit.infrastructure.mlkit.factories.TextRecognitionServiceFactory +import java.util.concurrent.atomic.AtomicBoolean + +@DoNotStrip +@Keep +class HybridTextRecognizer( + private val options: TextRecognizerOptions, +) : HybridTextRecognizerSpec() { + private val imagePreprocessor = ImagePreprocessor() + private val textOptions = options.toDomainTextRecognitionOptions() + private val imageOptions = options.toImagePreprocessingOptions() + private val recognitionService = TextRecognitionServiceFactory.create(textOptions.language) + private val isDisposed = AtomicBoolean(false) + + override fun recognize( + frame: HybridFrameSpec, + args: MLKitBaseArguments?, + ): TextRecognitionResult { + val processedImage = frame.toProcessedImage(imagePreprocessor, imageOptions) + val result = recognitionService.recognize(processedImage) + return result.remap(processedImage.metadata).toNitroResult() + } + + override fun recognizeImage(uri: String): Promise = + Promise.parallel { + StaticImageUriResolver.resolve(uri).use { resolvedImage -> + val processedImage = imagePreprocessor.preprocessImage(resolvedImage.file, imageOptions) + val result = recognitionService.recognize(processedImage) + result.remap(processedImage.metadata).toNitroResult() + } + } + + override fun dispose() { + if (isDisposed.compareAndSet(false, true)) { + runCatching { recognitionService.close() } + .onFailure { error -> Log.w(TAG, "Failed to close text recognizer", error) } + } + super.dispose() + } +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKit.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKit.kt new file mode 100644 index 0000000..01a151d --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKit.kt @@ -0,0 +1,40 @@ +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import com.visioncameramlkit.BuildConfig + +@DoNotStrip +@Keep +class HybridVisionCameraMLKit : HybridVisionCameraMLKitSpec() { + override fun isFeatureAvailable(feature: MLKitFeature): Boolean = + when (feature) { + MLKitFeature.TEXTRECOGNITION -> BuildConfig.MLKIT_TEXT_RECOGNITION_ANY + MLKitFeature.BARCODESCANNING -> BuildConfig.MLKIT_BARCODE_SCANNING + MLKitFeature.FACEDETECTION -> BuildConfig.MLKIT_FACE_DETECTION + MLKitFeature.FACEMESHDETECTION -> BuildConfig.MLKIT_FACE_MESH_DETECTION + MLKitFeature.POSEDETECTION -> BuildConfig.MLKIT_POSE_DETECTION + MLKitFeature.SELFIESEGMENTATION -> BuildConfig.MLKIT_SELFIE_SEGMENTATION + MLKitFeature.SUBJECTSEGMENTATION -> BuildConfig.MLKIT_SUBJECT_SEGMENTATION + MLKitFeature.DOCUMENTSCANNER -> BuildConfig.MLKIT_DOCUMENT_SCANNER + MLKitFeature.IMAGELABELING -> BuildConfig.MLKIT_IMAGE_LABELING + MLKitFeature.OBJECTDETECTION -> BuildConfig.MLKIT_OBJECT_DETECTION + MLKitFeature.DIGITALINKRECOGNITION -> BuildConfig.MLKIT_DIGITAL_INK_RECOGNITION + } + + override fun createTextRecognizer(options: TextRecognizerOptions): HybridTextRecognizerSpec { + if (!isFeatureAvailable(MLKitFeature.TEXTRECOGNITION)) { + throw Error("TextRecognition is not enabled in the native ML Kit configuration.") + } + + return HybridTextRecognizer(options) + } + + override fun createBarcodeScanner(options: BarcodeScannerOptions): HybridBarcodeScannerSpec { + if (!isFeatureAvailable(MLKitFeature.BARCODESCANNING)) { + throw Error("BarcodeScanning is not enabled in the native ML Kit configuration.") + } + + return HybridBarcodeScanner(options) + } +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/Orientation+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Orientation+toDomain.kt new file mode 100644 index 0000000..3b16a80 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/Orientation+toDomain.kt @@ -0,0 +1,12 @@ +package com.margelo.nitro.visioncameramlkit + +import com.visioncameramlkit.domain.models.Orientation as DomainOrientation + +internal fun Orientation?.toDomainOrientation(): DomainOrientation? = + when (this) { + Orientation.PORTRAIT -> DomainOrientation.PORTRAIT + Orientation.PORTRAIT_UPSIDE_DOWN -> DomainOrientation.PORTRAIT_UPSIDE_DOWN + Orientation.LANDSCAPE_LEFT -> DomainOrientation.LANDSCAPE_LEFT + Orientation.LANDSCAPE_RIGHT -> DomainOrientation.LANDSCAPE_RIGHT + null -> null + } diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/RegionOfInterest+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/RegionOfInterest+toDomain.kt new file mode 100644 index 0000000..f3e80a9 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/RegionOfInterest+toDomain.kt @@ -0,0 +1,21 @@ +package com.margelo.nitro.visioncameramlkit + +internal fun RegionOfInterest?.toDomainRegionOfInterest(): com.visioncameramlkit.domain.models.RegionOfInterest? = + this?.let { + com.visioncameramlkit.domain.models.RegionOfInterest( + x = it.x.toFloat(), + y = it.y.toFloat(), + width = it.width.toFloat(), + height = it.height.toFloat(), + unit = it.unit.toDomainRegionOfInterestUnit(), + ) + } + +private fun RegionOfInterestUnit?.toDomainRegionOfInterestUnit(): com.visioncameramlkit.domain.models.RegionOfInterestUnit = + when (this) { + RegionOfInterestUnit.PIXEL -> com.visioncameramlkit.domain.models.RegionOfInterestUnit.PIXEL + + RegionOfInterestUnit.NORMALIZED, + null, + -> com.visioncameramlkit.domain.models.RegionOfInterestUnit.NORMALIZED + } diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/ResolvedStaticImage.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/ResolvedStaticImage.kt new file mode 100644 index 0000000..a5f4517 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/ResolvedStaticImage.kt @@ -0,0 +1,16 @@ +package com.margelo.nitro.visioncameramlkit + +import java.io.Closeable +import java.io.File +import java.io.IOException + +internal class ResolvedStaticImage( + val file: File, + private val deleteOnClose: Boolean, +) : Closeable { + override fun close() { + if (deleteOnClose && file.exists() && !file.delete()) { + throw IOException("Failed to delete temporary image file.") + } + } +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/StaticImageUriResolver.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/StaticImageUriResolver.kt new file mode 100644 index 0000000..227ebb0 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/StaticImageUriResolver.kt @@ -0,0 +1,90 @@ +package com.margelo.nitro.visioncameramlkit + +import android.net.Uri +import com.margelo.nitro.NitroModules +import com.visioncameramlkit.domain.models.StaticImageLimits +import java.io.File +import java.io.FileNotFoundException +import java.io.IOException + +internal object StaticImageUriResolver { + fun resolve(value: String): ResolvedStaticImage { + require(value.isNotBlank()) { "Image URI must not be blank." } + + val uri = Uri.parse(value) + val scheme = uri.scheme + return when { + scheme == null -> resolveAbsolutePath(value) + scheme.equals("content", ignoreCase = true) -> resolveContentUri(uri) + scheme.equals("file", ignoreCase = true) -> resolveFileUri(uri, value) + else -> throw IllegalArgumentException("Unsupported image URI scheme: $scheme") + } + } + + private fun resolveContentUri(uri: Uri): ResolvedStaticImage { + val context = + NitroModules.applicationContext + ?: throw IllegalStateException("NitroModules application context is unavailable.") + val temporaryFile = File.createTempFile("vision-camera-mlkit-", ".image", context.cacheDir) + val resolvedImage = ResolvedStaticImage(temporaryFile, deleteOnClose = true) + + try { + val input = + context.contentResolver.openInputStream(uri) + ?: throw FileNotFoundException("Unable to open content URI: $uri") + input.use { source -> + temporaryFile.outputStream().use { destination -> + val buffer = ByteArray(DEFAULT_BUFFER_SIZE) + var copiedBytes = 0L + while (true) { + val bytesRead = source.read(buffer) + if (bytesRead < 0) break + copiedBytes += bytesRead + require(copiedBytes <= StaticImageLimits.MAX_ENCODED_BYTES) { + "Static image exceeds the 25 MB encoded-size limit." + } + destination.write(buffer, 0, bytesRead) + } + } + } + return resolvedImage + } catch (error: Throwable) { + try { + resolvedImage.close() + } catch (cleanupError: Throwable) { + error.addSuppressed(cleanupError) + } + throw error + } + } + + private fun resolveFileUri( + uri: Uri, + originalValue: String, + ): ResolvedStaticImage { + val path = uri.path ?: throw IllegalArgumentException("File URI has no path: $originalValue") + return resolveExistingFile(File(path), originalValue) + } + + private fun resolveAbsolutePath(value: String): ResolvedStaticImage { + val file = File(value) + require(file.isAbsolute) { "Image path must be absolute: $value" } + return resolveExistingFile(file, value) + } + + private fun resolveExistingFile( + file: File, + originalValue: String, + ): ResolvedStaticImage { + if (!file.isFile) { + throw FileNotFoundException("Image file not found: $originalValue") + } + if (!file.canRead()) { + throw IOException("Image file is not readable: $originalValue") + } + require(file.length() <= StaticImageLimits.MAX_ENCODED_BYTES) { + "Static image exceeds the 25 MB encoded-size limit." + } + return ResolvedStaticImage(file, deleteOnClose = false) + } +} diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage+toDomain.kt new file mode 100644 index 0000000..e2e4776 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage+toDomain.kt @@ -0,0 +1,16 @@ +package com.margelo.nitro.visioncameramlkit + +internal fun TextRecognitionLanguage?.toDomainLanguage(): com.visioncameramlkit.domain.models.TextRecognitionLanguage = + when (this) { + TextRecognitionLanguage.CHINESE -> com.visioncameramlkit.domain.models.TextRecognitionLanguage.CHINESE + + TextRecognitionLanguage.DEVANAGARI -> com.visioncameramlkit.domain.models.TextRecognitionLanguage.DEVANAGARI + + TextRecognitionLanguage.JAPANESE -> com.visioncameramlkit.domain.models.TextRecognitionLanguage.JAPANESE + + TextRecognitionLanguage.KOREAN -> com.visioncameramlkit.domain.models.TextRecognitionLanguage.KOREAN + + TextRecognitionLanguage.LATIN, + null, + -> com.visioncameramlkit.domain.models.TextRecognitionLanguage.LATIN + } diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionResult+toNitro.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionResult+toNitro.kt new file mode 100644 index 0000000..92bf029 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognitionResult+toNitro.kt @@ -0,0 +1,48 @@ +package com.margelo.nitro.visioncameramlkit + +internal fun com.visioncameramlkit.domain.models.TextRecognitionResult.toNitroResult(): TextRecognitionResult = + TextRecognitionResult( + text = text ?: "", + blocks = blocks.map { it.toNitroTextBlock() }.toTypedArray(), + ) + +private fun com.visioncameramlkit.domain.models.TextBlock.toNitroTextBlock(): TextBlock = + TextBlock( + bounds = bounds.toNitroBoundingBox(), + corners = corners.toNitroCorners(), + languages = languages.toTypedArray(), + text = text, + lines = lines.map { it.toNitroTextLine() }.toTypedArray(), + ) + +private fun com.visioncameramlkit.domain.models.TextLine.toNitroTextLine(): TextLine = + TextLine( + bounds = bounds.toNitroBoundingBox(), + corners = corners.toNitroCorners(), + confidence = confidence.toNullableDoubleVariant(), + angle = angle.toNullableDoubleVariant(), + languages = languages.toTypedArray(), + text = text, + elements = elements.map { it.toNitroTextElement() }.toTypedArray(), + ) + +private fun com.visioncameramlkit.domain.models.TextElement.toNitroTextElement(): TextElement = + TextElement( + bounds = bounds.toNitroBoundingBox(), + corners = corners.toNitroCorners(), + confidence = confidence.toNullableDoubleVariant(), + angle = angle.toNullableDoubleVariant(), + languages = languages.toTypedArray(), + text = text, + symbols = symbols.map { it.toNitroTextSymbol() }.toTypedArray(), + ) + +private fun com.visioncameramlkit.domain.models.TextSymbol.toNitroTextSymbol(): TextSymbol = + TextSymbol( + bounds = bounds.toNitroBoundingBox(), + corners = corners.toNitroCorners(), + confidence = confidence ?: 0.0, + angle = angle ?: 0.0, + languages = languages.toTypedArray(), + text = text, + ) diff --git a/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions+toDomain.kt b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions+toDomain.kt new file mode 100644 index 0000000..4b1b172 --- /dev/null +++ b/android/src/main/java/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions+toDomain.kt @@ -0,0 +1,19 @@ +package com.margelo.nitro.visioncameramlkit + +import com.visioncameramlkit.domain.models.ImagePreprocessingOptions +import com.visioncameramlkit.domain.models.TextRecognitionOptions + +internal fun TextRecognizerOptions.toDomainTextRecognitionOptions(): TextRecognitionOptions = + TextRecognitionOptions( + language = language.toDomainLanguage(), + invertColors = invertColors ?: false, + scaleFactor = scaleFactor?.toFloat() ?: 1.0f, + ) + +internal fun TextRecognizerOptions.toImagePreprocessingOptions(): ImagePreprocessingOptions = + ImagePreprocessingOptions( + invertColors = invertColors ?: false, + scaleFactor = scaleFactor?.toFloat() ?: 1.0f, + roi = roi.toDomainRegionOfInterest(), + orientation = orientation.toDomainOrientation(), + ) diff --git a/android/src/main/java/com/visioncameramlkit/VisionCameraMLKitPackage.kt b/android/src/main/java/com/visioncameramlkit/VisionCameraMLKitPackage.kt index b3451cc..16b0765 100644 --- a/android/src/main/java/com/visioncameramlkit/VisionCameraMLKitPackage.kt +++ b/android/src/main/java/com/visioncameramlkit/VisionCameraMLKitPackage.kt @@ -6,40 +6,24 @@ import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.module.model.ReactModuleInfo import com.facebook.react.module.model.ReactModuleInfoProvider import com.facebook.react.uimanager.ViewManager -import com.visioncameramlkit.bridge.registry.PluginRegistry -import com.visioncameramlkit.infrastructure.modules.VisionCameraMLKitModule +import com.margelo.nitro.visioncameramlkit.VisionCameraMLKitOnLoad class VisionCameraMLKitPackage : BaseReactPackage() { override fun getModule( name: String, reactContext: ReactApplicationContext, - ): NativeModule? = - when (name) { - VisionCameraMLKitModule.NAME -> { - PluginRegistry.ensureRegistered() - VisionCameraMLKitModule(reactContext) - } - - else -> { - null - } - } + ): NativeModule? = null override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider { - PluginRegistry.ensureRegistered() - mapOf( - VisionCameraMLKitModule.NAME to - ReactModuleInfo( - VisionCameraMLKitModule.NAME, - VisionCameraMLKitModule.NAME, - canOverrideExistingModule = false, - needsEagerInit = false, - isCxxModule = false, - isTurboModule = false, - ), - ) + emptyMap() } override fun createViewManagers(reactContext: ReactApplicationContext): List> = emptyList() + + companion object { + init { + VisionCameraMLKitOnLoad.initializeNative() + } + } } diff --git a/android/src/main/java/com/visioncameramlkit/application/usecases/RecognizeTextUseCase.kt b/android/src/main/java/com/visioncameramlkit/application/usecases/RecognizeTextUseCase.kt deleted file mode 100644 index 33ceee7..0000000 --- a/android/src/main/java/com/visioncameramlkit/application/usecases/RecognizeTextUseCase.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.visioncameramlkit.application.usecases - -import com.mrousavy.camera.frameprocessors.Frame -import com.visioncameramlkit.domain.models.ImagePreprocessingOptions -import com.visioncameramlkit.domain.models.TextRecognitionOptions -import com.visioncameramlkit.domain.models.TextRecognitionResult -import com.visioncameramlkit.domain.services.IImagePreprocessor -import com.visioncameramlkit.domain.services.IRecognitionService -import java.io.File - -class RecognizeTextUseCase( - private val imagePreprocessor: IImagePreprocessor, - private val recognitionService: IRecognitionService, -) { - fun execute( - frame: Frame, - options: TextRecognitionOptions, - ): TextRecognitionResult { - val preprocessingOptions = - ImagePreprocessingOptions( - invertColors = options.invertColors, - outputOrientation = options.outputOrientation, - scaleFactor = options.scaleFactor, - ) - - val processedImage = imagePreprocessor.preprocessFrame(frame, preprocessingOptions) - return recognitionService.recognize(processedImage) - } - - fun execute( - imageFile: File, - imageOptions: ImagePreprocessingOptions, - @Suppress("unused") textOptions: TextRecognitionOptions, - ): TextRecognitionResult { - val preprocessingOptions = - ImagePreprocessingOptions( - invertColors = imageOptions.invertColors, - orientation = imageOptions.orientation, - scaleFactor = imageOptions.scaleFactor, - ) - - val processedImage = imagePreprocessor.preprocessImage(imageFile, preprocessingOptions) - return recognitionService.recognize(processedImage) - } -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/constants/MLKitFeatureKeys.kt b/android/src/main/java/com/visioncameramlkit/bridge/constants/MLKitFeatureKeys.kt deleted file mode 100644 index 79ff40b..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/constants/MLKitFeatureKeys.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.visioncameramlkit.bridge.constants - -@Suppress("unused") -object MLKitFeatureKeys { - const val TEXT_RECOGNITION = "TextRecognition" - const val FACE_DETECTION = "FaceDetection" - const val FACE_MESH_DETECTION = "FaceMeshDetection" - const val POSE_DETECTION = "PoseDetection" - const val SELFIE_SEGMENTATION = "SelfieSegmentation" - const val SUBJECT_SEGMENTATION = "SubjectSegmentation" - const val DOCUMENT_SCANNER = "DocumentScanner" - const val BARCODE_SCANNING = "BarcodeScanning" - const val IMAGE_LABELING = "ImageLabeling" - const val OBJECT_DETECTION = "ObjectDetection" - const val DIGITAL_INK_RECOGNITION = "DigitalInkRecognition" -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/handlers/IStaticImageHandler.kt b/android/src/main/java/com/visioncameramlkit/bridge/handlers/IStaticImageHandler.kt deleted file mode 100644 index 8b52d93..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/handlers/IStaticImageHandler.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.visioncameramlkit.bridge.handlers - -import com.facebook.react.bridge.Promise -import com.facebook.react.bridge.ReadableMap - -interface IStaticImageHandler { - fun process( - path: String, - options: ReadableMap, - promise: Promise, - ) -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/handlers/StaticTextRecognitionHandler.kt b/android/src/main/java/com/visioncameramlkit/bridge/handlers/StaticTextRecognitionHandler.kt deleted file mode 100644 index 2f32c28..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/handlers/StaticTextRecognitionHandler.kt +++ /dev/null @@ -1,164 +0,0 @@ -package com.visioncameramlkit.bridge.handlers - -import android.net.Uri -import androidx.core.net.toUri -import com.facebook.react.bridge.Promise -import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.bridge.ReadableMap -import com.visioncameramlkit.application.usecases.RecognizeTextUseCase -import com.visioncameramlkit.domain.models.ImagePreprocessingOptions -import com.visioncameramlkit.domain.models.Orientation -import com.visioncameramlkit.domain.models.TextRecognitionLanguage -import com.visioncameramlkit.domain.models.TextRecognitionOptions -import com.visioncameramlkit.infrastructure.image.ImagePreprocessor -import com.visioncameramlkit.infrastructure.mlkit.factories.TextRecognitionServiceFactory -import com.visioncameramlkit.infrastructure.serializers.TextRecognitionSerializer -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import java.io.File -import java.io.FileOutputStream - -class StaticTextRecognitionHandler( - private val reactContext: ReactApplicationContext, -) : IStaticImageHandler { - private var cachedUseCase: RecognizeTextUseCase? = null - - private fun getRecognizeTextUseCase(language: TextRecognitionLanguage): RecognizeTextUseCase { - if (cachedUseCase != null) { - return cachedUseCase!! - } - val recognitionService = TextRecognitionServiceFactory.create(language) - val newUseCase = - RecognizeTextUseCase( - ImagePreprocessor(), - recognitionService, - ) - cachedUseCase = newUseCase - return newUseCase - } - - override fun process( - path: String, - options: ReadableMap, - promise: Promise, - ) { - CoroutineScope(Dispatchers.IO).launch { - var resolvedImage: ResolvedImage? = null - try { - resolvedImage = resolveImage(path) - val imageFile = resolvedImage.file - if (!imageFile.exists()) { - promise.reject("IMAGE_NOT_FOUND_ERROR", "Image file not found at path: $path") - return@launch - } - - // Parse options - val imageOptions = parseImageOptions(options) - - // Create text recognition options - val languageString = options.getString("language") ?: "LATIN" - val language = parseLanguage(languageString) - val textOptions = TextRecognitionOptions(language = language) - - // Get use case for the language - val recognizeTextUseCase = getRecognizeTextUseCase(language) - - // Process the image - val result = - recognizeTextUseCase.execute( - imageFile, - imageOptions, - textOptions, - ) - - // Serialize result - val serializedResult = TextRecognitionSerializer.toWritableMap(result) - - promise.resolve(serializedResult) - } catch ( - @Suppress("TooGenericExceptionCaught") e: Exception, - ) { - when (e) { - is IllegalArgumentException -> { - promise.reject("INVALID_URI_ERROR", e.message) - } - - is UnsupportedOperationException -> { - promise.reject( - "UNSUPPORTED_IMAGE_FORMAT_ERROR", - e.message, - ) - } - - else -> { - promise.reject( - "IMAGE_PROCESSING_FAILED_ERROR", - e.message ?: "Text recognition failed", - ) - } - } - } finally { - val imageFile = resolvedImage?.file - if (resolvedImage?.shouldDelete == true && imageFile != null && imageFile.exists()) { - imageFile.delete() - } - } - } - } - - private data class ResolvedImage( - val file: File, - val shouldDelete: Boolean, - ) - - private fun resolveImage(path: String): ResolvedImage { - val uri = path.toUri() - return when (uri.scheme) { - "content" -> ResolvedImage(copyContentToCache(uri), true) - "file" -> ResolvedImage(File(uri.path ?: path), false) - null -> ResolvedImage(File(path), false) - else -> ResolvedImage(File(path), false) - } - } - - private fun copyContentToCache(uri: Uri): File { - val cacheFile = File(reactContext.cacheDir, "mlkit_${System.currentTimeMillis()}.tmp") - val inputStream = - reactContext.contentResolver.openInputStream(uri) - ?: throw IllegalArgumentException("Unable to open content URI: $uri") - inputStream.use { input -> - FileOutputStream(cacheFile).use { output -> - input.copyTo(output) - } - } - return cacheFile - } - - private fun parseImageOptions(options: ReadableMap): ImagePreprocessingOptions = - ImagePreprocessingOptions( - invertColors = options.getBoolean("invertColors"), - orientation = - options.getString("orientation")?.let { parseOrientation(it) } - ?: Orientation.PORTRAIT, - ) - - private fun parseOrientation(orientation: String): Orientation = - when (orientation) { - "portrait" -> Orientation.PORTRAIT - "portrait-upside-down" -> Orientation.PORTRAIT_UPSIDE_DOWN - "landscape-left" -> Orientation.LANDSCAPE_LEFT - "landscape-right" -> Orientation.LANDSCAPE_RIGHT - else -> Orientation.PORTRAIT - } - - private fun parseLanguage(language: String): TextRecognitionLanguage = - when (language) { - "LATIN" -> TextRecognitionLanguage.LATIN - "CHINESE" -> TextRecognitionLanguage.CHINESE - "DEVANAGARI" -> TextRecognitionLanguage.DEVANAGARI - "JAPANESE" -> TextRecognitionLanguage.JAPANESE - "KOREAN" -> TextRecognitionLanguage.KOREAN - else -> TextRecognitionLanguage.LATIN - } -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/plugins/BaseMLKitPlugin.kt b/android/src/main/java/com/visioncameramlkit/bridge/plugins/BaseMLKitPlugin.kt deleted file mode 100644 index 66fb982..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/plugins/BaseMLKitPlugin.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.visioncameramlkit.bridge.plugins - -import android.util.Log -import com.google.mlkit.common.MlKitException -import com.mrousavy.camera.core.FrameInvalidError -import com.mrousavy.camera.frameprocessors.Frame -import com.mrousavy.camera.frameprocessors.FrameProcessorPlugin -import com.mrousavy.camera.frameprocessors.VisionCameraProxy - -@Suppress("MagicNumber") -abstract class BaseMLKitPlugin( - protected val proxy: VisionCameraProxy, - protected val options: Map?, -) : FrameProcessorPlugin() { - protected abstract val tag: String - - private val frameProcessInterval: Int = - (options?.get("frameProcessInterval") as? Number)?.toInt() ?: 0 - private var frameCounter: Int = 0 - protected val invertColors: Boolean = options?.get("invertColors") as? Boolean ?: false - protected val scaleFactor: Float = - (options?.get("scaleFactor") as? Number)?.toFloat()?.coerceIn(0.9f, 1.0f) ?: 1.0f - - // Android handles rotation automatically, so outputOrientation is ignored. Added for iOS parity. - protected val outputOrientation: com.visioncameramlkit.domain.models.OutputOrientation? = - com.visioncameramlkit.domain.models.OutputOrientation - .fromString(options?.get("outputOrientation") as? String) - - protected abstract fun processFrame( - frame: Frame, - arguments: Map?, - ): HashMap - - override fun callback( - frame: Frame, - arguments: Map?, - ): HashMap { - // Process 1 frame, skip N frames, repeat - // Note: Consider using runAtTargetFps() from Vision Camera instead - if (frameProcessInterval > 0) { - frameCounter++ - if (frameCounter <= frameProcessInterval) { - return hashMapOf() - } - frameCounter = 0 - } - - return try { - processFrame(frame, arguments) - } catch (e: FrameInvalidError) { - Log.e(tag, "FrameInvalidError occurred while processing the frame", e) - hashMapOf() - } catch (e: MlKitException) { - Log.e(tag, "MlKitException occurred while processing the image with ML Kit", e) - hashMapOf() - } catch ( - @Suppress("TooGenericExceptionCaught") e: Exception, - ) { - Log.e(tag, "Unexpected error occurred during recognition", e) - hashMapOf() - } - } -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/plugins/TextRecognitionPlugin.kt b/android/src/main/java/com/visioncameramlkit/bridge/plugins/TextRecognitionPlugin.kt deleted file mode 100644 index 808b48c..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/plugins/TextRecognitionPlugin.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.visioncameramlkit.bridge.plugins - -import com.mrousavy.camera.frameprocessors.Frame -import com.mrousavy.camera.frameprocessors.VisionCameraProxy -import com.visioncameramlkit.application.usecases.RecognizeTextUseCase -import com.visioncameramlkit.domain.models.TextRecognitionLanguage -import com.visioncameramlkit.domain.models.TextRecognitionOptions -import com.visioncameramlkit.infrastructure.image.ImagePreprocessor -import com.visioncameramlkit.infrastructure.mlkit.MLKitTextRecognitionService -import com.visioncameramlkit.infrastructure.mlkit.factories.TextRecognitionServiceFactory -import com.visioncameramlkit.infrastructure.serializers.TextRecognitionSerializer - -@Suppress("unused") -class TextRecognitionPlugin( - proxy: VisionCameraProxy, - options: Map?, -) : BaseMLKitPlugin(proxy, options) { - override val tag = "TextRecognitionPlugin" - - private val textRecognitionOptions: TextRecognitionOptions - private val recognizeTextUseCase: RecognizeTextUseCase - - init { - val languageString = options?.get("language") as? String ?: "LATIN" - - val language = - try { - TextRecognitionLanguage.valueOf(languageString) - } catch ( - @Suppress("SwallowedException") _: IllegalArgumentException, - ) { - TextRecognitionLanguage.LATIN - } - - textRecognitionOptions = - TextRecognitionOptions( - language = language, - invertColors = invertColors, - outputOrientation = outputOrientation, - scaleFactor = scaleFactor, - ) - - val textRecognizer = TextRecognitionServiceFactory.createTextRecognizer(language) - val recognitionService = MLKitTextRecognitionService(textRecognizer) - val imagePreprocessor = ImagePreprocessor() - - recognizeTextUseCase = RecognizeTextUseCase(imagePreprocessor, recognitionService) - } - - override fun processFrame( - frame: Frame, - arguments: Map?, - ): HashMap { - // Android handles rotation automatically, so outputOrientation is ignored. Added for iOS parity. - // val outputOrientation = arguments?.get("outputOrientation") as? String - - val result = recognizeTextUseCase.execute(frame, textRecognitionOptions) - return TextRecognitionSerializer.toReactNativeMap(result) - } -} diff --git a/android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt b/android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt deleted file mode 100644 index 8ce35eb..0000000 --- a/android/src/main/java/com/visioncameramlkit/bridge/registry/PluginRegistry.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.visioncameramlkit.bridge.registry - -import com.mrousavy.camera.frameprocessors.FrameProcessorPluginRegistry -import com.visioncameramlkit.BuildConfig -import com.visioncameramlkit.bridge.constants.MLKitFeatureKeys - -object PluginRegistry { - private val isRegistered by lazy { - registerPlugins() - true - } - - fun ensureRegistered() { - isRegistered - } - - private fun registerPlugins() { - @Suppress("KotlinConstantConditions") - if (BuildConfig.MLKIT_TEXT_RECOGNITION) { - registerTextRecognitionPlugin() - } - } - - private fun registerTextRecognitionPlugin() { - try { - // Dynamically load the plugin class to avoid compilation errors - // when the MLKit dependencies are not included - val pluginClass = - Class.forName("com.visioncameramlkit.bridge.plugins.TextRecognitionPlugin") - - FrameProcessorPluginRegistry.addFrameProcessorPlugin( - MLKitFeatureKeys.TEXT_RECOGNITION, - ) { proxy, options -> - val constructor = - pluginClass.getConstructor( - com.mrousavy.camera.frameprocessors.VisionCameraProxy::class.java, - Map::class.java, - ) - constructor.newInstance( - proxy, - options, - ) as com.mrousavy.camera.frameprocessors.FrameProcessorPlugin - } - } catch (e: ClassNotFoundException) { - // Plugin class not found - feature not enabled - android.util.Log.w("VisionCameraMLKit", "TextRecognitionPlugin not available: ${e.message}") - } catch ( - @Suppress("TooGenericExceptionCaught") e: Exception, - ) { - android.util.Log.e("VisionCameraMLKit", "Error registering TextRecognitionPlugin", e) - } - } -} diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningOptions.kt b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningOptions.kt new file mode 100644 index 0000000..ac69be6 --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningOptions.kt @@ -0,0 +1,28 @@ +package com.visioncameramlkit.domain.models + +data class BarcodeScanningOptions( + val formats: List = emptyList(), + val enableAllPotentialBarcodes: Boolean = false, + val invertColors: Boolean = false, + // Android handles rotation automatically, so outputOrientation is ignored. Added for iOS parity. + val outputOrientation: OutputOrientation? = null, + val scaleFactor: Float = 1.0f, +) + +enum class BarcodeFormatOption { + UNKNOWN, + ALL_FORMATS, + CODE_128, + CODE_39, + CODE_93, + CODABAR, + DATA_MATRIX, + EAN_13, + EAN_8, + ITF, + QR_CODE, + UPC_A, + UPC_E, + PDF417, + AZTEC, +} diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult+remap.kt b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult+remap.kt new file mode 100644 index 0000000..c5db25d --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult+remap.kt @@ -0,0 +1,14 @@ +package com.visioncameramlkit.domain.models + +/** + * Remaps every bounding box and corner in this result from processed-image coordinates + * back to source image/frame coordinates, using [metadata]'s crop offset and scale + * factor. See [BoundingBox.remap] and [Corner.remap] for the primitive. + */ +fun BarcodeScanningResult.remap(metadata: ImageMetadata): BarcodeScanningResult = copy(barcodes = barcodes.map { it.remap(metadata) }) + +private fun BarcodeData.remap(metadata: ImageMetadata): BarcodeData = + copy( + bounds = bounds?.remap(metadata), + corners = corners?.map { it.remap(metadata) }, + ) diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult.kt b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult.kt new file mode 100644 index 0000000..0c6d1ae --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/BarcodeScanningResult.kt @@ -0,0 +1,24 @@ +package com.visioncameramlkit.domain.models + +data class BarcodeScanningResult( + val barcodes: List, +) + +data class BarcodeData( + val bounds: BoundingBox?, + val corners: List?, + val format: Int, + val formatName: String, + val valueType: Int, + val valueTypeName: String, + val rawValue: String?, + val displayValue: String?, + val rawBytes: List?, + val isPotential: Boolean, + val value: BarcodeParsedValue?, +) + +data class BarcodeParsedValue( + val type: String, + val data: Map, +) diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/CoordinateRemap.kt b/android/src/main/java/com/visioncameramlkit/domain/models/CoordinateRemap.kt new file mode 100644 index 0000000..1fd1f9f --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/CoordinateRemap.kt @@ -0,0 +1,35 @@ +package com.visioncameramlkit.domain.models + +/** + * Translates a coordinate produced against a processed (cropped and/or scaled) image + * back into the original source image/frame's pixel space. + * + * Preprocessing crops first (in pre-scale pixel space), then scales. To invert that, + * this first undoes the scale factor (dividing by it), then adds back the crop offset, + * which was recorded in pre-scale pixel space: `source = offset + processed / scaleFactor`. + */ +private fun remapPoint( + value: Double, + offset: Int, + scaleFactor: Float, +): Double = offset + value / scaleFactor + +fun BoundingBox.remap(metadata: ImageMetadata): BoundingBox = + BoundingBox( + x = remapPoint(x, metadata.offsetX, metadata.scaleFactor), + y = remapPoint(y, metadata.offsetY, metadata.scaleFactor), + centerX = remapPoint(centerX, metadata.offsetX, metadata.scaleFactor), + centerY = remapPoint(centerY, metadata.offsetY, metadata.scaleFactor), + width = width / metadata.scaleFactor, + height = height / metadata.scaleFactor, + top = remapPoint(top, metadata.offsetY, metadata.scaleFactor), + left = remapPoint(left, metadata.offsetX, metadata.scaleFactor), + bottom = remapPoint(bottom, metadata.offsetY, metadata.scaleFactor), + right = remapPoint(right, metadata.offsetX, metadata.scaleFactor), + ) + +fun Corner.remap(metadata: ImageMetadata): Corner = + Corner( + x = remapPoint(x, metadata.offsetX, metadata.scaleFactor), + y = remapPoint(y, metadata.offsetY, metadata.scaleFactor), + ) diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/ImagePreprocessingOptions.kt b/android/src/main/java/com/visioncameramlkit/domain/models/ImagePreprocessingOptions.kt index 496e483..ea4563a 100644 --- a/android/src/main/java/com/visioncameramlkit/domain/models/ImagePreprocessingOptions.kt +++ b/android/src/main/java/com/visioncameramlkit/domain/models/ImagePreprocessingOptions.kt @@ -5,5 +5,6 @@ data class ImagePreprocessingOptions( // Android handles rotation automatically, so outputOrientation is ignored. Added for iOS parity. val outputOrientation: OutputOrientation? = null, val scaleFactor: Float = 1.0f, - val orientation: Orientation = Orientation.PORTRAIT, + val orientation: Orientation? = null, + val roi: RegionOfInterest? = null, ) diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/Orientation.kt b/android/src/main/java/com/visioncameramlkit/domain/models/Orientation.kt index 9b52e0f..017edcc 100644 --- a/android/src/main/java/com/visioncameramlkit/domain/models/Orientation.kt +++ b/android/src/main/java/com/visioncameramlkit/domain/models/Orientation.kt @@ -1,5 +1,6 @@ package com.visioncameramlkit.domain.models +@Suppress("unused") enum class Orientation { PORTRAIT, PORTRAIT_UPSIDE_DOWN, diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/ProcessedImage.kt b/android/src/main/java/com/visioncameramlkit/domain/models/ProcessedImage.kt index da5856c..24da288 100644 --- a/android/src/main/java/com/visioncameramlkit/domain/models/ProcessedImage.kt +++ b/android/src/main/java/com/visioncameramlkit/domain/models/ProcessedImage.kt @@ -12,4 +12,11 @@ data class ImageMetadata( val height: Int, val rotation: Int, val isInverted: Boolean, + // Crop origin (in post-rotation, pre-scale pixel space) applied by an ROI, if any. + // Downstream result remapping adds this back onto ML Kit's result coordinates. + val offsetX: Int = 0, + val offsetY: Int = 0, + // Scale factor applied during preprocessing, needed to unscale result coordinates + // back to source image/frame pixel space. + val scaleFactor: Float = 1.0f, ) diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/RegionOfInterest.kt b/android/src/main/java/com/visioncameramlkit/domain/models/RegionOfInterest.kt new file mode 100644 index 0000000..1810b80 --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/RegionOfInterest.kt @@ -0,0 +1,57 @@ +package com.visioncameramlkit.domain.models + +import android.graphics.Rect + +enum class RegionOfInterestUnit { + NORMALIZED, + PIXEL, +} + +data class RegionOfInterest( + val x: Float, + val y: Float, + val width: Float, + val height: Float, + val unit: RegionOfInterestUnit = RegionOfInterestUnit.NORMALIZED, +) { + init { + require(x >= 0 && y >= 0) { + "Invalid RegionOfInterest: x and y must be >= 0 (got x=$x, y=$y)." + } + require(width > 0 && height > 0) { + "Invalid RegionOfInterest: width and height must be > 0 (got width=$width, height=$height)." + } + if (unit == RegionOfInterestUnit.NORMALIZED) { + require(x + width <= 1f && y + height <= 1f) { + "Invalid RegionOfInterest: normalized x + width and y + height must be <= 1 " + + "(got x=$x, width=$width, y=$y, height=$height)." + } + } + } +} + +/** + * Resolves this [RegionOfInterest] into a pixel-space [Rect] for an image of the given + * dimensions, clamping the result to stay within the image bounds. + */ +fun RegionOfInterest.resolveToPixelRect( + imageWidth: Int, + imageHeight: Int, +): Rect { + val (px, py, pw, ph) = + when (unit) { + RegionOfInterestUnit.PIXEL -> { + listOf(x, y, width, height) + } + + RegionOfInterestUnit.NORMALIZED -> { + listOf(x * imageWidth, y * imageHeight, width * imageWidth, height * imageHeight) + } + } + + val left = px.toInt().coerceIn(0, imageWidth) + val top = py.toInt().coerceIn(0, imageHeight) + val right = (px + pw).toInt().coerceIn(left, imageWidth) + val bottom = (py + ph).toInt().coerceIn(top, imageHeight) + return Rect(left, top, right, bottom) +} diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/StaticImageLimits.kt b/android/src/main/java/com/visioncameramlkit/domain/models/StaticImageLimits.kt new file mode 100644 index 0000000..e9eb53e --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/StaticImageLimits.kt @@ -0,0 +1,7 @@ +package com.visioncameramlkit.domain.models + +object StaticImageLimits { + const val MAX_ENCODED_BYTES: Long = 25L * 1024L * 1024L + const val MAX_PIXEL_COUNT: Long = 4_000_000L + const val MAX_DIMENSION: Int = 4_096 +} diff --git a/android/src/main/java/com/visioncameramlkit/domain/models/TextRecognitionResult+remap.kt b/android/src/main/java/com/visioncameramlkit/domain/models/TextRecognitionResult+remap.kt new file mode 100644 index 0000000..3a1923c --- /dev/null +++ b/android/src/main/java/com/visioncameramlkit/domain/models/TextRecognitionResult+remap.kt @@ -0,0 +1,35 @@ +package com.visioncameramlkit.domain.models + +/** + * Remaps every bounding box and corner in this result tree from processed-image + * coordinates back to source image/frame coordinates, using [metadata]'s crop offset + * and scale factor. See [BoundingBox.remap] and [Corner.remap] for the primitive. + */ +fun TextRecognitionResult.remap(metadata: ImageMetadata): TextRecognitionResult = copy(blocks = blocks.map { it.remap(metadata) }) + +private fun TextBlock.remap(metadata: ImageMetadata): TextBlock = + copy( + bounds = bounds?.remap(metadata), + corners = corners?.map { it.remap(metadata) }, + lines = lines.map { it.remap(metadata) }, + ) + +private fun TextLine.remap(metadata: ImageMetadata): TextLine = + copy( + bounds = bounds?.remap(metadata), + corners = corners?.map { it.remap(metadata) }, + elements = elements.map { it.remap(metadata) }, + ) + +private fun TextElement.remap(metadata: ImageMetadata): TextElement = + copy( + bounds = bounds?.remap(metadata), + corners = corners?.map { it.remap(metadata) }, + symbols = symbols.map { it.remap(metadata) }, + ) + +private fun TextSymbol.remap(metadata: ImageMetadata): TextSymbol = + copy( + bounds = bounds?.remap(metadata), + corners = corners?.map { it.remap(metadata) }, + ) diff --git a/android/src/main/java/com/visioncameramlkit/domain/services/IImagePreprocessor.kt b/android/src/main/java/com/visioncameramlkit/domain/services/IImagePreprocessor.kt index 541358c..eb36774 100644 --- a/android/src/main/java/com/visioncameramlkit/domain/services/IImagePreprocessor.kt +++ b/android/src/main/java/com/visioncameramlkit/domain/services/IImagePreprocessor.kt @@ -1,16 +1,10 @@ package com.visioncameramlkit.domain.services -import com.mrousavy.camera.frameprocessors.Frame import com.visioncameramlkit.domain.models.ImagePreprocessingOptions import com.visioncameramlkit.domain.models.ProcessedImage import java.io.File interface IImagePreprocessor { - fun preprocessFrame( - frame: Frame, - options: ImagePreprocessingOptions, - ): ProcessedImage - fun preprocessImage( imageFile: File, options: ImagePreprocessingOptions, diff --git a/android/src/main/java/com/visioncameramlkit/domain/services/IRecognitionService.kt b/android/src/main/java/com/visioncameramlkit/domain/services/IRecognitionService.kt index 9f7f406..18b5cbf 100644 --- a/android/src/main/java/com/visioncameramlkit/domain/services/IRecognitionService.kt +++ b/android/src/main/java/com/visioncameramlkit/domain/services/IRecognitionService.kt @@ -2,6 +2,6 @@ package com.visioncameramlkit.domain.services import com.visioncameramlkit.domain.models.ProcessedImage -interface IRecognitionService { +interface IRecognitionService : AutoCloseable { fun recognize(image: ProcessedImage): T } diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/image/ImagePreprocessor.kt b/android/src/main/java/com/visioncameramlkit/infrastructure/image/ImagePreprocessor.kt index 52a5a88..231a944 100644 --- a/android/src/main/java/com/visioncameramlkit/infrastructure/image/ImagePreprocessor.kt +++ b/android/src/main/java/com/visioncameramlkit/infrastructure/image/ImagePreprocessor.kt @@ -8,15 +8,17 @@ import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter import android.graphics.Matrix import android.graphics.Paint -import android.media.Image +import android.graphics.Rect import androidx.core.graphics.scale +import androidx.exifinterface.media.ExifInterface import com.google.mlkit.vision.common.InputImage -import com.google.mlkit.vision.common.internal.ImageConvertUtils -import com.mrousavy.camera.frameprocessors.Frame import com.visioncameramlkit.domain.models.ImageMetadata import com.visioncameramlkit.domain.models.ImagePreprocessingOptions import com.visioncameramlkit.domain.models.Orientation import com.visioncameramlkit.domain.models.ProcessedImage +import com.visioncameramlkit.domain.models.RegionOfInterest +import com.visioncameramlkit.domain.models.StaticImageLimits +import com.visioncameramlkit.domain.models.resolveToPixelRect import com.visioncameramlkit.domain.services.IImagePreprocessor import java.io.File @@ -28,81 +30,24 @@ class ImagePreprocessor : IImagePreprocessor { return scale.coerceIn(0.9f, 1.0f) } - override fun preprocessFrame( - frame: Frame, - options: ImagePreprocessingOptions, - ): ProcessedImage { - val effectiveScale = clampScale(options.scaleFactor) - - val inputImage = - if (options.invertColors) { - createInvertedInputImage(frame, effectiveScale) - } else { - createInputImage(frame, effectiveScale) - } - - val metadata = - ImageMetadata( - width = (frame.imageProxy.width * effectiveScale).toInt(), - height = (frame.imageProxy.height * effectiveScale).toInt(), - rotation = frame.imageProxy.imageInfo.rotationDegrees, - isInverted = options.invertColors, - ) - - return ProcessedImage(inputImage, metadata) - } - - private fun createInputImage( - frame: Frame, - scaleFactor: Float, - ): InputImage { - val mediaImage: Image = frame.image - - val image = InputImage.fromMediaImage(mediaImage, frame.imageProxy.imageInfo.rotationDegrees) - val frameBitmap = ImageConvertUtils.getInstance().getUpRightBitmap(image) - - val finalBitmap = - if (scaleFactor < 1.0f) { - frameBitmap.scale( - (frameBitmap.width * scaleFactor).toInt(), - (frameBitmap.height * scaleFactor).toInt(), - false, - ) - } else { - frameBitmap - } - - return InputImage.fromBitmap(finalBitmap, 0) - } - - private fun createInvertedInputImage( - frame: Frame, - scaleFactor: Float, - ): InputImage { - val mediaImage: Image = frame.image - - val image = InputImage.fromMediaImage(mediaImage, frame.imageProxy.imageInfo.rotationDegrees) - val frameBitmap = ImageConvertUtils.getInstance().getUpRightBitmap(image) - - // Scale first if needed - val scaledBitmap = - if (scaleFactor < 1.0f) { - frameBitmap.scale( - (frameBitmap.width * scaleFactor).toInt(), - (frameBitmap.height * scaleFactor).toInt(), - false, - ) - } else { - frameBitmap - } - - // Then invert - val invertedBitmap = invertBitmap(scaledBitmap) - - return InputImage.fromBitmap(invertedBitmap, 0) + /** + * Crops [bitmap] to the given [roi], if any. Returns the (possibly unchanged) bitmap + * alongside the pixel offset of the crop origin, so callers can remap result + * coordinates back to the pre-crop pixel space. + */ + fun cropToRegionOfInterest( + bitmap: Bitmap, + roi: RegionOfInterest?, + ): Pair { + if (roi == null) { + return bitmap to Rect(0, 0, bitmap.width, bitmap.height) + } + val rect = roi.resolveToPixelRect(bitmap.width, bitmap.height) + val croppedBitmap = createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height()) + return croppedBitmap to rect } - private fun invertBitmap(bitmap: Bitmap): Bitmap = + fun invertBitmap(bitmap: Bitmap): Bitmap = createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888).apply { val canvas = Canvas(this) val paint = Paint() @@ -147,36 +92,56 @@ class ImagePreprocessor : IImagePreprocessor { imageFile: File, options: ImagePreprocessingOptions, ): ProcessedImage { + val bounds = BitmapFactory.Options().apply { inJustDecodeBounds = true } + BitmapFactory.decodeFile(imageFile.absolutePath, bounds) + require(bounds.outWidth > 0 && bounds.outHeight > 0) { + "Failed to read static image dimensions" + } + require( + bounds.outWidth <= StaticImageLimits.MAX_DIMENSION && + bounds.outHeight <= StaticImageLimits.MAX_DIMENSION && + bounds.outWidth.toLong() * bounds.outHeight.toLong() <= StaticImageLimits.MAX_PIXEL_COUNT, + ) { + "Static image exceeds the 4 MP or 4,096 px dimension limit." + } + val bitmap = BitmapFactory.decodeFile(imageFile.absolutePath) ?: throw UnsupportedOperationException("Failed to decode image file") - val rotatedBitmap = rotateBitmap(bitmap, options.orientation) + // Use the user-provided orientation override, or fall back to the image's + // embedded EXIF orientation metadata. + val effectiveOrientation = options.orientation ?: readExifOrientation(imageFile) + + val rotatedBitmap = rotateBitmap(bitmap, effectiveOrientation) + // Bitmap.createBitmap returns the source instance itself when no transform is + // actually applied (e.g. no rotation needed), so only recycle on a genuine copy. + if (rotatedBitmap !== bitmap) bitmap.recycle() + val effectiveScale = clampScale(options.scaleFactor) + val (croppedBitmap, cropRect) = cropToRegionOfInterest(rotatedBitmap, options.roi) + if (croppedBitmap !== rotatedBitmap) rotatedBitmap.recycle() + + val scaledBitmap = + if (effectiveScale < 1.0f) { + croppedBitmap.scale( + (croppedBitmap.width * effectiveScale).toInt(), + (croppedBitmap.height * effectiveScale).toInt(), + false, + ) + } else { + croppedBitmap + } + if (scaledBitmap !== croppedBitmap) croppedBitmap.recycle() + val processedBitmap = if (options.invertColors) { - val scaledBitmap = - if (effectiveScale < 1.0f) { - rotatedBitmap.scale( - (rotatedBitmap.width * effectiveScale).toInt(), - (rotatedBitmap.height * effectiveScale).toInt(), - false, - ) - } else { - rotatedBitmap - } - invertBitmap(scaledBitmap) + val invertedBitmap = invertBitmap(scaledBitmap) + scaledBitmap.recycle() + invertedBitmap } else { - if (effectiveScale < 1.0f) { - rotatedBitmap.scale( - (rotatedBitmap.width * effectiveScale).toInt(), - (rotatedBitmap.height * effectiveScale).toInt(), - false, - ) - } else { - rotatedBitmap - } + scaledBitmap } val inputImage = InputImage.fromBitmap(processedBitmap, 0) @@ -187,11 +152,46 @@ class ImagePreprocessor : IImagePreprocessor { height = processedBitmap.height, rotation = 0, // Static images are already oriented isInverted = options.invertColors, + offsetX = cropRect.left, + offsetY = cropRect.top, + scaleFactor = effectiveScale, ) return ProcessedImage(inputImage, metadata) } + /** + * Reads EXIF orientation from the image file and maps it to an [Orientation]. + * Falls back to [Orientation.PORTRAIT] if EXIF data is unavailable or unrecognized. + */ + private fun readExifOrientation(imageFile: File): Orientation = + try { + val exif = ExifInterface(imageFile.absolutePath) + when (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) { + ExifInterface.ORIENTATION_NORMAL, + ExifInterface.ORIENTATION_FLIP_HORIZONTAL, + -> Orientation.PORTRAIT + + ExifInterface.ORIENTATION_ROTATE_180, + ExifInterface.ORIENTATION_FLIP_VERTICAL, + -> Orientation.PORTRAIT_UPSIDE_DOWN + + ExifInterface.ORIENTATION_ROTATE_90, + ExifInterface.ORIENTATION_TRANSPOSE, + -> Orientation.LANDSCAPE_LEFT + + ExifInterface.ORIENTATION_ROTATE_270, + ExifInterface.ORIENTATION_TRANSVERSE, + -> Orientation.LANDSCAPE_RIGHT + + else -> Orientation.PORTRAIT + } + } catch ( + @Suppress("TooGenericExceptionCaught") e: Exception, + ) { + Orientation.PORTRAIT + } + private fun rotateBitmap( bitmap: Bitmap, orientation: Orientation, diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt b/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt deleted file mode 100644 index bc124c6..0000000 --- a/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.visioncameramlkit.infrastructure.mlkit.factories - -import com.google.mlkit.vision.text.TextRecognition -import com.google.mlkit.vision.text.TextRecognizer -import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions -import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions -import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions -import com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions -import com.google.mlkit.vision.text.latin.TextRecognizerOptions -import com.visioncameramlkit.domain.models.TextRecognitionLanguage -import com.visioncameramlkit.infrastructure.mlkit.MLKitTextRecognitionService - -object TextRecognitionServiceFactory { - fun createTextRecognizer(language: TextRecognitionLanguage): TextRecognizer { - val options = - when (language) { - TextRecognitionLanguage.LATIN -> TextRecognizerOptions.DEFAULT_OPTIONS - TextRecognitionLanguage.CHINESE -> ChineseTextRecognizerOptions.Builder().build() - TextRecognitionLanguage.DEVANAGARI -> DevanagariTextRecognizerOptions.Builder().build() - TextRecognitionLanguage.JAPANESE -> JapaneseTextRecognizerOptions.Builder().build() - TextRecognitionLanguage.KOREAN -> KoreanTextRecognizerOptions.Builder().build() - } - - return TextRecognition.getClient(options) - } - - fun create(language: TextRecognitionLanguage = TextRecognitionLanguage.LATIN): MLKitTextRecognitionService { - val textRecognizer = createTextRecognizer(language) - return MLKitTextRecognitionService(textRecognizer) - } -} diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/modules/VisionCameraMLKitModule.kt b/android/src/main/java/com/visioncameramlkit/infrastructure/modules/VisionCameraMLKitModule.kt deleted file mode 100644 index 1a9bef6..0000000 --- a/android/src/main/java/com/visioncameramlkit/infrastructure/modules/VisionCameraMLKitModule.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.visioncameramlkit.infrastructure.modules - -import com.facebook.react.bridge.Arguments -import com.facebook.react.bridge.Promise -import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.bridge.ReactContextBaseJavaModule -import com.facebook.react.bridge.ReactMethod -import com.facebook.react.bridge.ReadableMap -import com.facebook.react.module.annotations.ReactModule -import com.visioncameramlkit.bridge.constants.MLKitFeatureKeys -import com.visioncameramlkit.bridge.handlers.IStaticImageHandler -import com.visioncameramlkit.bridge.handlers.StaticTextRecognitionHandler - -@ReactModule(name = VisionCameraMLKitModule.NAME) -class VisionCameraMLKitModule( - reactContext: ReactApplicationContext, -) : ReactContextBaseJavaModule(reactContext) { - companion object { - const val NAME = "VisionCameraMLKitModule" - } - - private val handlers by lazy { - mapOf( - MLKitFeatureKeys.TEXT_RECOGNITION to StaticTextRecognitionHandler(reactApplicationContext), - ) - } - - override fun getName(): String = NAME - - @ReactMethod - fun processImage( - feature: String, - path: String, - options: ReadableMap?, - promise: Promise, - ) { - val safeOptions = options ?: Arguments.createMap() - val handler = handlers[feature] - if (handler == null) { - promise.reject("UNSUPPORTED_FEATURE", "Feature $feature is not supported") - return - } - - handler.process(path, safeOptions, promise) - } -} diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/serializers/TextRecognitionSerializer.kt b/android/src/main/java/com/visioncameramlkit/infrastructure/serializers/TextRecognitionSerializer.kt deleted file mode 100644 index 292c30d..0000000 --- a/android/src/main/java/com/visioncameramlkit/infrastructure/serializers/TextRecognitionSerializer.kt +++ /dev/null @@ -1,116 +0,0 @@ -package com.visioncameramlkit.infrastructure.serializers - -import com.facebook.react.bridge.WritableNativeArray -import com.facebook.react.bridge.WritableNativeMap -import com.visioncameramlkit.domain.models.BoundingBox -import com.visioncameramlkit.domain.models.Corner -import com.visioncameramlkit.domain.models.TextBlock -import com.visioncameramlkit.domain.models.TextElement -import com.visioncameramlkit.domain.models.TextLine -import com.visioncameramlkit.domain.models.TextRecognitionResult -import com.visioncameramlkit.domain.models.TextSymbol - -@Suppress("TooManyFunctions") -object TextRecognitionSerializer { - fun toWritableMap(result: TextRecognitionResult): WritableNativeMap = - WritableNativeMap().apply { - putString("text", result.text) - putArray("blocks", toBlocksArray(result.blocks)) - } - - fun toReactNativeMap(result: TextRecognitionResult): HashMap { - @Suppress("UNCHECKED_CAST") - return toWritableMap(result).toHashMap() as HashMap - } - - private fun toBlocksArray(blocks: List): WritableNativeArray = - WritableNativeArray().apply { - blocks.forEach { block -> pushMap(toBlockMap(block)) } - } - - private fun toBlockMap(block: TextBlock): WritableNativeMap = - WritableNativeMap().apply { - putString("text", block.text) - block.bounds?.let { putMap("bounds", toBoundsMap(it)) } - block.corners?.let { putArray("corners", toCornersArray(it)) } - putArray("lines", toLinesArray(block.lines)) - putArray("languages", toLanguagesArray(block.languages)) - } - - private fun toLinesArray(lines: List): WritableNativeArray = - WritableNativeArray().apply { - lines.forEach { line -> pushMap(toLineMap(line)) } - } - - private fun toLineMap(line: TextLine): WritableNativeMap = - WritableNativeMap().apply { - putString("text", line.text) - line.bounds?.let { putMap("bounds", toBoundsMap(it)) } - line.corners?.let { putArray("corners", toCornersArray(it)) } - putArray("elements", toElementsArray(line.elements)) - line.confidence?.let { putDouble("confidence", it) } - line.angle?.let { putDouble("angle", it) } - putArray("languages", toLanguagesArray(line.languages)) - } - - private fun toElementsArray(elements: List): WritableNativeArray = - WritableNativeArray().apply { - elements.forEach { element -> pushMap(toElementMap(element)) } - } - - private fun toElementMap(element: TextElement): WritableNativeMap = - WritableNativeMap().apply { - putString("text", element.text) - element.bounds?.let { putMap("bounds", toBoundsMap(it)) } - element.corners?.let { putArray("corners", toCornersArray(it)) } - putArray("symbols", toSymbolsArray(element.symbols)) - element.confidence?.let { putDouble("confidence", it) } - element.angle?.let { putDouble("angle", it) } - putArray("languages", toLanguagesArray(element.languages)) - } - - private fun toSymbolsArray(symbols: List): WritableNativeArray = - WritableNativeArray().apply { - symbols.forEach { symbol -> pushMap(toSymbolMap(symbol)) } - } - - private fun toSymbolMap(symbol: TextSymbol): WritableNativeMap = - WritableNativeMap().apply { - putString("text", symbol.text) - symbol.bounds?.let { putMap("bounds", toBoundsMap(it)) } - symbol.corners?.let { putArray("corners", toCornersArray(it)) } - symbol.confidence?.let { putDouble("confidence", it) } - symbol.angle?.let { putDouble("angle", it) } - putArray("languages", toLanguagesArray(symbol.languages)) - } - - private fun toBoundsMap(bounds: BoundingBox): WritableNativeMap = - WritableNativeMap().apply { - putDouble("x", bounds.x) - putDouble("y", bounds.y) - putDouble("centerX", bounds.centerX) - putDouble("centerY", bounds.centerY) - putDouble("width", bounds.width) - putDouble("height", bounds.height) - putDouble("top", bounds.top) - putDouble("left", bounds.left) - putDouble("bottom", bounds.bottom) - putDouble("right", bounds.right) - } - - private fun toCornersArray(corners: List): WritableNativeArray = - WritableNativeArray().apply { - corners.forEach { corner -> pushMap(toCornerMap(corner)) } - } - - private fun toCornerMap(corner: Corner): WritableNativeMap = - WritableNativeMap().apply { - putDouble("x", corner.x) - putDouble("y", corner.y) - } - - private fun toLanguagesArray(languages: List): WritableNativeArray = - WritableNativeArray().apply { - languages.forEach { pushString(it) } - } -} diff --git a/android/src/textRecognitionDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt b/android/src/textRecognitionDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt new file mode 100644 index 0000000..74383f9 --- /dev/null +++ b/android/src/textRecognitionDisabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt @@ -0,0 +1,13 @@ +package com.visioncameramlkit.infrastructure.mlkit.factories + +import com.visioncameramlkit.domain.models.TextRecognitionLanguage +import com.visioncameramlkit.domain.models.TextRecognitionResult +import com.visioncameramlkit.domain.services.IRecognitionService + +object TextRecognitionServiceFactory { + fun create(language: TextRecognitionLanguage = TextRecognitionLanguage.LATIN): IRecognitionService = + throw IllegalStateException( + "Text recognition is not enabled in this build. Enable textRecognition (or a language " + + "variant) in your MLKit configuration to use this feature.", + ) +} diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt b/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt similarity index 54% rename from android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt rename to android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt index 08f7a00..1c3722e 100644 --- a/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt +++ b/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/MLKitTextRecognitionService.kt @@ -11,9 +11,21 @@ import com.visioncameramlkit.infrastructure.mlkit.adapters.MLKitTextAdapter class MLKitTextRecognitionService( private val textRecognizer: TextRecognizer, ) : IRecognitionService { - override fun recognize(image: ProcessedImage): TextRecognitionResult { - val task = textRecognizer.process(image.image) - val mlkitText: Text? = Tasks.await(task) - return MLKitTextAdapter.toDomain(mlkitText) + // ML Kit's on-device detectors are not documented as safe for concurrent use. + // This instance is shared between the synchronous frame-processor path and the + // async static-image path, so calls (and disposal) must be serialized. + private val lock = Any() + + override fun recognize(image: ProcessedImage): TextRecognitionResult = + synchronized(lock) { + val task = textRecognizer.process(image.image) + val mlkitText: Text? = Tasks.await(task) + MLKitTextAdapter.toDomain(mlkitText) + } + + override fun close() { + synchronized(lock) { + textRecognizer.close() + } } } diff --git a/android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitTextAdapter.kt b/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitTextAdapter.kt similarity index 100% rename from android/src/main/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitTextAdapter.kt rename to android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/adapters/MLKitTextAdapter.kt diff --git a/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt b/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt new file mode 100644 index 0000000..41584d9 --- /dev/null +++ b/android/src/textRecognitionEnabled/java/com/visioncameramlkit/infrastructure/mlkit/factories/TextRecognitionServiceFactory.kt @@ -0,0 +1,107 @@ +package com.visioncameramlkit.infrastructure.mlkit.factories + +import com.google.mlkit.vision.text.TextRecognition +import com.google.mlkit.vision.text.TextRecognizer +import com.google.mlkit.vision.text.TextRecognizerOptionsInterface +import com.google.mlkit.vision.text.latin.TextRecognizerOptions +import com.visioncameramlkit.BuildConfig +import com.visioncameramlkit.domain.models.TextRecognitionLanguage +import com.visioncameramlkit.infrastructure.mlkit.MLKitTextRecognitionService + +object TextRecognitionServiceFactory { + @Suppress("LongMethod", "ThrowsCount") + fun createTextRecognizer(language: TextRecognitionLanguage): TextRecognizer { + val options: TextRecognizerOptionsInterface = + when (language) { + TextRecognitionLanguage.LATIN -> { + @Suppress("KotlinConstantConditions") + if (!BuildConfig.MLKIT_TEXT_RECOGNITION) { + throw IllegalStateException( + "Text recognition for Latin is not enabled. " + + "Set textRecognition to true in your MLKit configuration.", + ) + } + TextRecognizerOptions.DEFAULT_OPTIONS + } + + TextRecognitionLanguage.CHINESE -> { + @Suppress("KotlinConstantConditions") + if (!BuildConfig.MLKIT_TEXT_RECOGNITION_CHINESE) { + throw IllegalStateException( + "Text recognition for Chinese is not enabled. " + + "Set textRecognitionChinese to true in your MLKit configuration.", + ) + } + createOptionsViaReflection( + "com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions", + ) + } + + TextRecognitionLanguage.DEVANAGARI -> { + @Suppress("KotlinConstantConditions") + if (!BuildConfig.MLKIT_TEXT_RECOGNITION_DEVANAGARI) { + throw IllegalStateException( + "Text recognition for Devanagari is not enabled. " + + "Set textRecognitionDevanagari to true in your MLKit configuration.", + ) + } + createOptionsViaReflection( + "com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions", + ) + } + + TextRecognitionLanguage.JAPANESE -> { + @Suppress("KotlinConstantConditions") + if (!BuildConfig.MLKIT_TEXT_RECOGNITION_JAPANESE) { + throw IllegalStateException( + "Text recognition for Japanese is not enabled. " + + "Set textRecognitionJapanese to true in your MLKit configuration.", + ) + } + createOptionsViaReflection( + "com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions", + ) + } + + TextRecognitionLanguage.KOREAN -> { + @Suppress("KotlinConstantConditions") + if (!BuildConfig.MLKIT_TEXT_RECOGNITION_KOREAN) { + throw IllegalStateException( + "Text recognition for Korean is not enabled. " + + "Set textRecognitionKorean to true in your MLKit configuration.", + ) + } + createOptionsViaReflection( + "com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions", + ) + } + } + + return TextRecognition.getClient(options) + } + + /** + * Creates language-specific TextRecognizerOptions via reflection to avoid hard + * class dependencies on variant modules that may not be included in the build. + * Each variant options class follows the Builder pattern: OptionsClass.Builder().build() + */ + private fun createOptionsViaReflection(className: String): TextRecognizerOptionsInterface { + try { + val builderClass = Class.forName("$className\$Builder") + val builder = builderClass.getDeclaredConstructor().newInstance() + val buildMethod = builderClass.getMethod("build") + return buildMethod.invoke(builder) as TextRecognizerOptionsInterface + } catch (e: ClassNotFoundException) { + throw IllegalStateException( + "MLKit class $className not found. " + + "Ensure the corresponding text recognition dependency is included.", + e, + ) + } + } + + fun create(language: TextRecognitionLanguage = TextRecognitionLanguage.LATIN): MLKitTextRecognitionService { + val textRecognizer = createTextRecognizer(language) + return MLKitTextRecognitionService(textRecognizer) + } +} diff --git a/app.plugin.js b/app.plugin.js new file mode 100644 index 0000000..7590f2e --- /dev/null +++ b/app.plugin.js @@ -0,0 +1 @@ +module.exports = require('./plugin'); diff --git a/docs/barcode-scanning.md b/docs/barcode-scanning.md new file mode 100644 index 0000000..c45496f --- /dev/null +++ b/docs/barcode-scanning.md @@ -0,0 +1,164 @@ +# Barcode Scanning API + +This page documents the Barcode Scanning API in more detail than the README quick-start. + +Barcode scanning is implemented by configured Nitro recognizers for both live +frames and static images. + +## Imports + +```ts +import { useFrameOutput } from 'react-native-vision-camera'; +import { + useBarcodeScanning, + processImageBarcodeScanning, + type BarcodeScanningOptions, + type BarcodeScanningArguments, + type BarcodeScanningImageOptions, + type BarcodeScanningResult, +} from 'react-native-vision-camera-mlkit'; +``` + +## Frame Output + +Use `useBarcodeScanning()` for live camera frames, inside a `useFrameOutput` +`onFrame` worklet. + +```ts +const { barcodeScanning } = useBarcodeScanning({ + formats: ['QR_CODE', 'CODE_128'], + enableAllPotentialBarcodes: true, + scaleFactor: 1, + invertColors: false, +}); + +const frameOutput = useFrameOutput({ + onFrame(frame) { + 'worklet'; + + try { + const result = barcodeScanning(frame, { + outputOrientation: 'portrait', + }); + console.log(result.barcodes); + } finally { + frame.dispose(); + } + }, +}); +``` + +### Frame options + +- `formats?: BarcodeFormat[]` +- `enableAllPotentialBarcodes?: boolean` (Android only) +- `scaleFactor?: number` (`0.9`-`1.0`) +- `invertColors?: boolean` +- `roi?: RegionOfInterest` (crop processing to a rectangle of the frame; see the [Region of Interest](../README.md#region-of-interest) section in the main README) +- `frameProcessInterval?: number` (deprecated compatibility field; v2 does not use it to throttle processing) + +### Frame arguments + +- `outputOrientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (iOS only) + +## Static Image Processing + +Use `processImageBarcodeScanning(uri, options)` for local images. Each call +creates a Nitro scanner with `options` and runs recognition asynchronously. + +```ts +const result = await processImageBarcodeScanning(imageUri, { + formats: ['QR_CODE', 'PDF417'], + enableAllPotentialBarcodes: true, + orientation: 'portrait', + invertColors: false, + scaleFactor: 1, +}); +``` + +### Image options + +- `formats?: BarcodeFormat[]` +- `enableAllPotentialBarcodes?: boolean` (Android only) +- `orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (overrides EXIF orientation; omit it to use image metadata) +- `invertColors?: boolean` +- `scaleFactor?: number` (`0.9`-`1.0`) +- `roi?: RegionOfInterest` (crop processing to a rectangle of the image; see the [Region of Interest](../README.md#region-of-interest) section in the main README) + +Static images must be local and readable. iOS accepts an absolute path or a +`file://` URI. Android also accepts `content://` URIs, which are copied to a +temporary cache file. Remote URLs and platform-library schemes such as +`ph://` are not supported. Static processing does not require Worklets or a +camera, but VisionCamera v5 and Nitro Modules remain native package +dependencies. + +## Supported formats + +- `ALL_FORMATS` +- `QR_CODE` +- `AZTEC` +- `PDF417` +- `DATA_MATRIX` +- `CODE_128` +- `CODE_39` +- `CODE_93` +- `CODABAR` +- `EAN_13` +- `EAN_8` +- `ITF` +- `UPC_A` +- `UPC_E` +- `UNKNOWN` + +## Result shape + +`BarcodeScanningResult` contains `barcodes[]`. + +Each barcode includes: + +- geometry: `bounds`, `corners` (optional — may be absent for potential barcodes) +- identity: `format`, `formatName`, `valueType`, `valueTypeName` — `format`/`valueType` are the raw ML Kit numeric codes; the `*Name` variants are the human-readable string equivalents and are what you should match against in application code +- raw payload: `rawValue`, `displayValue`, `rawBytes` +- `isPotential` (true for potential/undecoded barcode candidates; when `true`, `rawValue`/`rawBytes` may be `null`) +- parsed payload: `value?: BarcodeParsedValue` + +### Parsed value typing + +`BarcodeParsedValue` is a discriminated union with `type` as `TYPE_*` values. + +Examples: + +- `TYPE_WIFI` +- `TYPE_URL` +- `TYPE_CONTACT_INFO` +- `TYPE_CALENDAR_EVENT` +- `TYPE_DRIVER_LICENSE` +- `TYPE_TEXT` +- `TYPE_PRODUCT` +- `TYPE_ISBN` + +Use `switch (barcode.value?.type)` for strong type inference in TypeScript. + +## Errors + +Static Nitro calls reject invalid schemes, missing or unreadable files, and +images the platform decoder cannot read. The package exports these +compatibility error-message constants: + +- `IMAGE_NOT_FOUND_ERROR` +- `INVALID_URI_ERROR` +- `IMAGE_PROCESSING_FAILED_ERROR` +- `UNSUPPORTED_IMAGE_FORMAT_ERROR` + +These constants are retained for source compatibility and user-facing fallback +messages. Nitro rejection messages are platform-specific and are not guaranteed +to equal these strings; do not branch on `error.message`. + +## Performance guidance + +- Filter `formats` whenever possible for better performance. +- Always call `frame.dispose()` exactly once for every frame, including frames + you skip; keep disposal in a `finally` block around the whole callback. +- `frameProcessInterval` has no throttling effect in v2. Decide whether to call + the scanner inside `onFrame`, while still disposing every frame. +- Keep `scaleFactor` as high as possible for decoding reliability. diff --git a/docs/expo-plugin.md b/docs/expo-plugin.md new file mode 100644 index 0000000..63b1c29 --- /dev/null +++ b/docs/expo-plugin.md @@ -0,0 +1,129 @@ +# Expo Config Plugin + +This page documents this library's Expo config plugin in more detail than the README quick-start. + +If you're using an Expo prebuild workflow (`expo prebuild`, EAS Build, or a +custom dev client), this library ships a config plugin that mirrors the same +[selective ML Kit configuration](selective-mlkit-install.md) into the +generated `android/build.gradle` and `ios/Podfile` automatically, so you +don't have to hand-edit native config after every prebuild. + +## Requirements + +The plugin depends on `@expo/config-plugins`, which is already a transitive +dependency of `expo` itself — Expo projects have it for free, nothing extra +to install. + +## Usage + +Add the plugin to your `app.json`/`app.config.js`/`app.config.ts` `plugins` +array, with the same keys documented in +[Selective ML Kit Installation](selective-mlkit-install.md#defaults): + +```json +{ + "expo": { + "plugins": [ + [ + "react-native-vision-camera-mlkit", + { + "textRecognition": true, + "textRecognitionChinese": false, + "textRecognitionDevanagari": false, + "textRecognitionJapanese": false, + "textRecognitionKorean": false, + "barcodeScanning": false + } + ] + ] + } +} +``` + +Or in `app.config.js`: + +```js +module.exports = { + expo: { + plugins: [ + [ + 'react-native-vision-camera-mlkit', + { + textRecognition: true, + barcodeScanning: false, + }, + ], + ], + }, +}; +``` + +Any key you omit keeps the library's own default (see +[Defaults](selective-mlkit-install.md#defaults)). Run `npx expo prebuild` +(or let EAS Build run it for you) to regenerate the native projects with +your configuration applied. + +## What it actually does + +The plugin has two halves, one per platform, both driven by the same +options object: + +- **Android** (`withVisionCameraMLKitAndroid`): prepends an + `ext["react-native-vision-camera-mlkit"] = [ mlkit: [ ... ] ]` Groovy block + to the top of the generated project-level `android/build.gradle` — the + exact same block documented for manual installation. This library's own + `android/build.gradle` reads it via `rootProject.ext` at build time. +- **iOS** (`withVisionCameraMLKitIOS`): inserts a `$VisionCameraMLKit = { ... }` + Ruby hash into the generated `ios/Podfile`, immediately before the first + `target` block — again, the same hash documented for manual installation. + `VisionCameraMLKit.podspec` reads the `$VisionCameraMLKit` global at + `pod install` time. + +Both platform writers are pure string transforms under the hood +(`insertAndroidConfig`/`insertIOSConfig`), so they're easy to reason about +and unit tested directly in this repo (`plugin/__tests__/withAndroid.test.js`, +`plugin/__tests__/withIOS.test.js`). + +## Validation + +Unknown option keys throw at prebuild time instead of silently being +ignored — a typo like `"textRecogniton": true` fails fast with an error +listing every valid key, rather than quietly doing nothing: + +``` +react-native-vision-camera-mlkit config plugin: unknown option(s) "textRecogniton". Valid options: textRecognition, textRecognitionChinese, ... +``` + +## Platform-specific behavior to be aware of + +- **Android-only keys are silently dropped for iOS.** `faceMeshDetection`, + `subjectSegmentation`, and `documentScanner` have no ML Kit iOS + equivalent, so the plugin omits them from the generated `$VisionCameraMLKit` + hash entirely rather than writing a key iOS can't use. This isn't an + error — it's expected, since these are Android-only roadmap features to + begin with. +- **Only Groovy `android/build.gradle` is supported**, not Kotlin DSL + (`.kts`). If your Expo project's generated Android build uses `.kts`, the + plugin throws instead of silently producing a broken file. This mirrors + the library's own native Android config, which is also Groovy-only. +- **Idempotent across repeated prebuilds.** Both writers check for a marker + comment (`// react-native-vision-camera-mlkit selective ML Kit dependencies` + on Android, `# react-native-vision-camera-mlkit selective ML Kit + dependencies` on iOS) and skip re-inserting if it's already present, so + running `expo prebuild` more than once — or across a clean vs. non-clean + prebuild — doesn't duplicate the config block. +- **Runs once per config, even if listed twice.** The plugin is wrapped in + Expo's `createRunOncePlugin`, so listing it more than once in your + `plugins` array (e.g. from a nested config) still only applies it a + single time. +- **Config only, not installation.** The plugin edits `android/build.gradle` + and `ios/Podfile` — it does not run `pod install` or a Gradle sync for + you. Follow your normal Expo prebuild/EAS Build workflow after changing + the plugin's options. + +## When you don't need this plugin + +If you're not using Expo prebuild (bare React Native, or Expo with a fully +custom native project you maintain by hand), skip the plugin and edit +`android/build.gradle`/`ios/Podfile` directly — see +[Selective ML Kit Installation](selective-mlkit-install.md). diff --git a/docs/migration-v1-to-v2.md b/docs/migration-v1-to-v2.md new file mode 100644 index 0000000..f1100f7 --- /dev/null +++ b/docs/migration-v1-to-v2.md @@ -0,0 +1,72 @@ +# Migrating from v1 to v2 + +v2 moves the library to React Native 0.86, VisionCamera v5 frame outputs, and +Nitro Modules. It supports iOS 15.1+ and Android SDK 24+. VisionCamera v4 users +must remain on a v1 tag until their camera integration can move to v5. + +## Dependency changes + +Install the v2 native dependencies: + +```sh +npm install react-native-vision-camera-mlkit@^2 \ + react-native-vision-camera@^5 \ + react-native-nitro-modules +cd ios && pod install +``` + +Live-frame recognition also needs VisionCamera's frame-output Worklets +dependencies: + +```sh +npm install react-native-vision-camera-worklets react-native-worklets +``` + +Configure `react-native-worklets/plugin` in `babel.config.js`. Remove the v1 +`react-native-worklets-core` dependency and Babel plugin if nothing else in +your app uses them. Static-image APIs do not need Worklets or a camera, but the +package still requires VisionCamera v5 and Nitro Modules at build time. + +## Live-frame API changes + +Replace the v1 `useFrameProcessor` integration with VisionCamera v5's +`useFrameOutput`. Call `textRecognition(frame, args)` or +`barcodeScanning(frame, args)` directly in its `onFrame` worklet. + +- Remove `runAsync(frame, ...)` and `runAtTargetFps(...)`; those v1 patterns do + not belong to the v5 frame-output API. +- Dispose every delivered frame exactly once, including skipped or failed + frames. Put `frame.dispose()` in a `finally` block around the whole callback. +- Remove `frameProcessInterval`. It remains in the type for compatibility but + has no throttling effect in the v2 Nitro recognizers. Make the call/skip + decision inside `onFrame` and dispose either way. +- Continue passing `outputOrientation` for iOS live frames when required. + +See the complete [text recognition](text-recognition.md) and +[barcode scanning](barcode-scanning.md) examples. + +## Static-image behavior + +The public functions remain `processImageTextRecognition(uri, options)` and +`processImageBarcodeScanning(uri, options)`, but v2 runs them through configured +Nitro recognizers. The supplied language, formats, orientation, scale, color +inversion, and ROI options configure that recognizer. + +Only local, readable images are accepted. iOS supports absolute paths and +`file://` URIs. Android additionally supports `content://` URIs. Remote URLs +and platform-library schemes such as `ph://` are not supported. Omit +`orientation` to use EXIF metadata; pass it only to override missing or wrong +metadata. + +## Feature availability + +v2 implements text recognition and barcode scanning. Both are enabled by +default, including all OCR language models. Other ML Kit feature keys are +reserved, disabled roadmap configuration and do not expose public APIs in v2. + +## v1 maintenance + +Published v1 tags remain available for applications that still use +VisionCamera v4, but v1 is not the active development line. The project does +not currently publish a security or critical-fix support guarantee for v1; +plan to migrate to v2 rather than relying on future v1 releases. diff --git a/docs/selective-mlkit-install.md b/docs/selective-mlkit-install.md new file mode 100644 index 0000000..fd916cd --- /dev/null +++ b/docs/selective-mlkit-install.md @@ -0,0 +1,147 @@ +# Selective ML Kit Installation + +This page documents the selective-install configuration in more detail than the README quick-start. + +react-native-vision-camera-mlkit is designed to expose the full set of Google +ML Kit vision APIs, but no single app needs all of them. A consumer who only +wants barcode scanning shouldn't have to ship the text-recognition SDK (or +vice versa) — every additional native SDK adds to APK/IPA size. The +`textRecognition` and `barcodeScanning` flags (and the reserved roadmap keys) +let you opt in to only what your app actually uses. + +## What "selective" means here + +Disabling a feature removes its native SDK from the build **entirely**, +on both platforms — it is not just a runtime gate: + +- **Android**: the corresponding `com.google.mlkit:*` Gradle dependency is + wrapped in `if (mlkitConfig.) { implementation "..." }` in this + library's `android/build.gradle`, and the Kotlin source files that touch + that SDK's types live in a Gradle source set that's only added to the + compile classpath when the flag is on. When disabled, a lightweight stub + takes its place so the rest of the module still compiles; that stub is + never actually reached at runtime. +- **iOS**: the corresponding `GoogleMLKit/*` CocoaPods dependency in + `VisionCameraMLKit.podspec` is wrapped in the same conditional, and every + Swift file that touches that SDK's types is wrapped in a matching + `#if MLKIT_TEXT_RECOGNITION_ANY` / `#if MLKIT_BARCODE_SCANNING` compiler + condition, so the guarded code (and its imports) is fully elided from + compilation when the flag is off. + +Both platforms give you the same guarantee: disable a feature you don't use, +and its model weights and native SDK genuinely never end up in your binary. + +## Feature families + +v2 implements two feature families with a public JS/Nitro API: + +- `textRecognition` (plus the four optional OCR language variants: + `textRecognitionChinese`, `textRecognitionDevanagari`, + `textRecognitionJapanese`, `textRecognitionKorean`) +- `barcodeScanning` + +All other configuration keys are reserved for the +[post-v2 roadmap](../README.md#google-ml-kit-vision-features-roadmap): +`faceDetection`, `faceMeshDetection`, `poseDetection`, +`poseDetectionAccurate`, `selfieSegmentation`, `subjectSegmentation`, +`documentScanner`, `imageLabeling`, `objectDetection`, +`digitalInkRecognition`. Enabling one of these keys today does not provide a +public API — there's nothing to selectively install yet for these, since +they aren't implemented. + +## Defaults + +| Key | Default | Notes | +| ---------------------------- | :-----: | ----------------------------------------- | +| `textRecognition` | `true` | Latin OCR (the base text-recognition SDK) | +| `textRecognitionChinese` | `true` | Adds ~a few MB; disable if unused | +| `textRecognitionDevanagari` | `true` | Adds ~a few MB; disable if unused | +| `textRecognitionJapanese` | `true` | Adds ~a few MB; disable if unused | +| `textRecognitionKorean` | `true` | Adds ~a few MB; disable if unused | +| `barcodeScanning` | `true` | | +| all roadmap keys | `false` | Reserved, no public API | + +If you only need barcode scanning, set `textRecognition` (and all four +language variants) to `false`. If you only need Latin-script OCR, keep +`textRecognition: true` and disable the four language variants — that keeps +the base SDK but drops the larger per-language model packages. + +## Android (Gradle) + +Add this to your app's **root** `android/build.gradle` (not +`android/app/build.gradle`), before the `apply plugin: "com.facebook.react.rootproject"` +line or anywhere at the top level of the file: + +```gradle +ext["react-native-vision-camera-mlkit"] = [ + mlkit: [ + textRecognition: true, + textRecognitionChinese: false, + textRecognitionDevanagari: false, + textRecognitionJapanese: false, + textRecognitionKorean: false, + barcodeScanning: false, + ] +] +``` + +Omit any key to keep its default. This library's own `android/build.gradle` +reads `rootProject.ext["react-native-vision-camera-mlkit"].mlkit`, merges it +over its defaults, and uses the result to both pick the compile-time source +set (see above) and generate `BuildConfig` fields that gate the feature at +runtime as a second layer of protection. + +## iOS (Podfile) + +Add a `$VisionCameraMLKit` hash to your `ios/Podfile`, **before** the first +`target` block: + +```ruby +$VisionCameraMLKit = { + 'textRecognition' => true, + 'textRecognitionChinese' => false, + 'textRecognitionDevanagari' => false, + 'textRecognitionJapanese' => false, + 'textRecognitionKorean' => false, + 'barcodeScanning' => false, +} +``` + +Run `pod install` after changing this hash — CocoaPods only re-resolves +dependencies (including conditional ones) on install/update, not on every +build. + +Omit any key to keep its default. `VisionCameraMLKit.podspec` reads +`$VisionCameraMLKit` the same way `android/build.gradle` reads +`rootProject.ext`. + +## Expo + +If you use an Expo prebuild workflow, use this library's config plugin +instead of hand-editing `android/build.gradle`/`ios/Podfile` — see +[Expo Config Plugin](expo-plugin.md). + +## Verifying a feature was actually excluded + +To confirm a disabled feature's SDK is really gone (not just gated), inspect +the resolved dependency graph after a clean build: + +```sh +# Android — run from the app's android/ directory +./gradlew :app:dependencies --configuration debugRuntimeClasspath | grep mlkit + +# iOS — check the generated Podfile.lock +grep -A2 "GoogleMLKit" ios/Podfile.lock +``` + +A disabled feature's `com.google.mlkit:*` / `GoogleMLKit/*` entries should be +absent entirely, not merely present-but-unused. + +## Calling a disabled feature at runtime + +`useTextRecognition`/`useBarcodeScanning`/`processImageTextRecognition`/ +`processImageBarcodeScanning` throw a setup error if the corresponding flag +was disabled at build time — see +[Error Handling](../README.md#error-handling) and the `getAvailableFeatures`/ +`isFeatureAvailable`/`assertFeatureAvailable` helpers for checking +availability before rendering feature-dependent UI. diff --git a/docs/text-recognition.md b/docs/text-recognition.md new file mode 100644 index 0000000..9ad9b51 --- /dev/null +++ b/docs/text-recognition.md @@ -0,0 +1,135 @@ +# Text Recognition API + +This page documents the Text Recognition API in more detail than the README quick-start. + +Text recognition is implemented by configured Nitro recognizers for both live +frames and static images. + +## Imports + +```ts +import { useFrameOutput } from 'react-native-vision-camera'; +import { + useTextRecognition, + processImageTextRecognition, + type TextRecognitionOptions, + type TextRecognitionArguments, + type TextRecognitionImageOptions, + type TextRecognitionResult, +} from 'react-native-vision-camera-mlkit'; +``` + +## Frame Output + +Use `useTextRecognition()` for live camera frames, inside a `useFrameOutput` +`onFrame` worklet. + +```ts +const { textRecognition } = useTextRecognition({ + language: 'LATIN', + scaleFactor: 1, + invertColors: false, +}); + +const frameOutput = useFrameOutput({ + onFrame(frame) { + 'worklet'; + + try { + const result = textRecognition(frame, { + outputOrientation: 'portrait', + }); + console.log(result.text); + } finally { + frame.dispose(); + } + }, +}); +``` + +### Frame options + +- `language?: 'LATIN' | 'CHINESE' | 'DEVANAGARI' | 'JAPANESE' | 'KOREAN'` +- `scaleFactor?: number` (`0.9`-`1.0`) +- `invertColors?: boolean` +- `roi?: RegionOfInterest` (crop processing to a rectangle of the frame; see the [Region of Interest](../README.md#region-of-interest) section in the main README) +- `frameProcessInterval?: number` (deprecated compatibility field; v2 does not use it to throttle processing) + +### Frame arguments + +- `outputOrientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (iOS only) + +## Static Image Processing + +Use `processImageTextRecognition(uri, options)` for local images. Each call +creates a Nitro recognizer with `options` and runs recognition asynchronously. + +```ts +const result = await processImageTextRecognition(imageUri, { + language: 'LATIN', + orientation: 'portrait', + invertColors: false, + scaleFactor: 1, +}); +``` + +### Image options + +- `language?: 'LATIN' | 'CHINESE' | 'DEVANAGARI' | 'JAPANESE' | 'KOREAN'` +- `orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'` (overrides EXIF orientation; omit it to use image metadata) +- `invertColors?: boolean` +- `scaleFactor?: number` (`0.9`-`1.0`) +- `roi?: RegionOfInterest` (crop processing to a rectangle of the image; see the [Region of Interest](../README.md#region-of-interest) section in the main README) + +Static images must be local and readable. iOS accepts an absolute path or a +`file://` URI. Android also accepts `content://` URIs, which are copied to a +temporary cache file. Remote URLs and platform-library schemes such as +`ph://` are not supported. Static processing does not require Worklets or a +camera, but VisionCamera v5 and Nitro Modules remain native package +dependencies. + +## Result shape + +`TextRecognitionResult` is a nested hierarchy: text → blocks → lines → elements +(→ symbols on Android). Every level carries its own `bounds`/`corners` +geometry, already mapped back to full source coordinates (see +[Region of Interest](../README.md#region-of-interest)). + +- `text: string` — the full recognized text. +- `blocks: TextBlock[]` + - `text: string`, `bounds`, `corners`, `languages: string[]` (ISO 639-1/639-2) + - `lines: TextLine[]` + - `text: string`, `bounds`, `corners`, `languages: string[]` + - `confidence: number | null`, `angle: number | null` (Android only) + - `elements: TextElement[]` + - `text: string`, `bounds`, `corners`, `languages: string[]` + - `confidence: number | null`, `angle: number | null` (Android only) + - `symbols: TextSymbol[]` (Android only) — `text`, `bounds`, `corners`, `confidence`, `angle` + +## iOS orientation note + +For frame processing on iOS, pass `outputOrientation` to ensure ML Kit receives the correct image orientation. +Android rotation is handled automatically. + +## Errors + +Static Nitro calls reject invalid schemes, missing or unreadable files, and +images the platform decoder cannot read. The package exports these +compatibility error-message constants: + +- `IMAGE_NOT_FOUND_ERROR` +- `INVALID_URI_ERROR` +- `IMAGE_PROCESSING_FAILED_ERROR` +- `UNSUPPORTED_IMAGE_FORMAT_ERROR` + +These constants are retained for source compatibility and user-facing fallback +messages. Nitro rejection messages are platform-specific and are not guaranteed +to equal these strings; do not branch on `error.message`. + +## Performance guidance + +- Always call `frame.dispose()` exactly once for every frame, including frames + you skip; keep disposal in a `finally` block around the whole callback. +- `frameProcessInterval` has no throttling effect in v2. Decide whether to call + the recognizer inside `onFrame`, while still disposing every frame. +- Keep `scaleFactor` as high as possible for OCR accuracy. diff --git a/docs/xcode-26.4-fmt-consteval-workaround.md b/docs/xcode-26.4-fmt-consteval-workaround.md new file mode 100644 index 0000000..88a3c6c --- /dev/null +++ b/docs/xcode-26.4-fmt-consteval-workaround.md @@ -0,0 +1,79 @@ +# Xcode 26.4 + fmt Build Failure Workaround (React Native / iOS) + +## Problem + +After updating to Xcode 26.4 (including betas/RC), iOS builds can fail in Pods with errors related to the `fmt` C++ library. + +Typical symptom: + +- build fails in `fmt/include/fmt/base.h` +- errors reference `consteval` or macros around `FMT_USE_CONSTEVAL` + +## Root cause + +`fmt` checks compiler support and enables: + +```cpp +FMT_USE_CONSTEVAL 1 +``` + +On Xcode 26.4 toolchains, `__cpp_consteval` can be detected, but compilation may still fail for this path. + +## Workaround + +Patch `fmt/include/fmt/base.h` after `pod install` and force: + +- `FMT_USE_CONSTEVAL 1` -> `FMT_USE_CONSTEVAL 0` + +This is safe for app behavior; it only disables that compile-time optimization path and falls back to non-`consteval` handling. + +## Podfile patch + +Add this in your `Podfile` (inside your target where `post_install` exists): + +```ruby +def apply_fmt_xcode_26_workaround(installer) + fmt_base = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h') + return unless File.exist?(fmt_base) + + content = File.read(fmt_base) + return if content.include?('Xcode 26 workaround: disable consteval') + + patched = content.gsub( + /^(#elif defined\(__cpp_consteval\)\n# define FMT_USE_CONSTEVAL) 1$/, + "// Xcode 26 workaround: disable consteval\n\\1 0" + ) + + return if patched == content + + File.chmod(0o644, fmt_base) + File.write(fmt_base, patched) + Pod::UI.puts('Applied Xcode 26 fmt workaround (FMT_USE_CONSTEVAL=0)'.yellow) +end + +post_install do |installer| + react_native_post_install( + installer, + config[:reactNativePath], + :mac_catalyst_enabled => false, + ) + + apply_fmt_xcode_26_workaround(installer) +end +``` + +## Apply it + +From your iOS folder: + +```bash +pod install +``` + +Then rebuild in Xcode. + +## Notes + +- This is a temporary workaround until upstream toolchain/library compatibility is fully resolved. +- Keep this patch only while affected by Xcode 26.4 toolchains. +- Because it runs in `post_install`, it is re-applied automatically on future `pod install` runs. diff --git a/example/Gemfile b/example/Gemfile index 6a4c5f1..5151523 100644 --- a/example/Gemfile +++ b/example/Gemfile @@ -14,3 +14,4 @@ gem 'bigdecimal' gem 'logger' gem 'benchmark' gem 'mutex_m' +gem 'nkf' diff --git a/example/Gemfile.lock b/example/Gemfile.lock new file mode 100644 index 0000000..1f89b08 --- /dev/null +++ b/example/Gemfile.lock @@ -0,0 +1,124 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.9) + activesupport (7.1.6) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) + tzinfo (~> 2.0) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.3.0) + benchmark (0.5.0) + bigdecimal (4.1.2) + claide (1.1.0) + cocoapods (1.15.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.15.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.23.0, < 2.0) + cocoapods-core (1.15.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.3.3) + connection_pool (2.5.5) + drb (2.2.3) + escape (0.0.4) + ethon (0.18.0) + ffi (>= 1.15.0) + logger + ffi (1.17.4) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.9.0) + mutex_m + i18n (1.14.8) + concurrent-ruby (~> 1.0) + json (2.20.0) + logger (1.7.0) + minitest (5.26.1) + molinillo (0.8.0) + mutex_m (0.3.0) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + nkf (0.3.0) + public_suffix (4.0.7) + rexml (3.4.4) + ruby-macho (2.5.1) + securerandom (0.3.2) + typhoeus (1.6.0) + ethon (>= 0.18.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.25.1) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (>= 3.3.6, < 4.0) + +PLATFORMS + ruby + +DEPENDENCIES + activesupport (>= 6.1.7.5, != 7.1.0) + benchmark + bigdecimal + cocoapods (>= 1.13, != 1.15.1, != 1.15.0) + concurrent-ruby (< 1.3.4) + logger + mutex_m + nkf + xcodeproj (< 1.26.0) + +RUBY VERSION + ruby 2.7.4p191 + +BUNDLED WITH + 4.0.17 diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index e5897f4..59d0d41 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -19,9 +19,9 @@ react { /* Variants */ // The list of variants to that are debuggable. For those we're going to - // skip the bundling of the JS bundle and the assets. By default is just 'debug'. + // skip the bundling of the JS bundle and the assets. Default is "debug", "debugOptimized". // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. - // debuggableVariants = ["liteDebug", "prodDebug"] + // debuggableVariants = ["liteDebug", "liteDebugOptimized", "prodDebug", "prodDebugOptimized"] /* Bundling */ // A list containing the node command and its flags. Default is just 'node'. diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 11c23b4..0000000 --- a/example/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 8c2000f..2901510 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ - + diff --git a/example/android/app/src/main/java/visioncameramlkit/example/MainApplication.kt b/example/android/app/src/main/java/visioncameramlkit/example/MainApplication.kt index 25e969a..ac5880e 100644 --- a/example/android/app/src/main/java/visioncameramlkit/example/MainApplication.kt +++ b/example/android/app/src/main/java/visioncameramlkit/example/MainApplication.kt @@ -5,31 +5,20 @@ import com.facebook.react.PackageList import com.facebook.react.ReactApplication import com.facebook.react.ReactHost import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative -import com.facebook.react.ReactNativeHost -import com.facebook.react.ReactPackage import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost -import com.facebook.react.defaults.DefaultReactNativeHost class MainApplication : Application(), ReactApplication { - override val reactNativeHost: ReactNativeHost = - object : DefaultReactNativeHost(this) { - override fun getPackages(): List = - PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: - // add(MyReactNativePackage()) - } - - override fun getJSMainModuleName(): String = "index" - - override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG - - override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED - override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED - } - - override val reactHost: ReactHost - get() = getDefaultReactHost(applicationContext, reactNativeHost) + override val reactHost: ReactHost by lazy { + getDefaultReactHost( + context = applicationContext, + packageList = + PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + }, + ) + } override fun onCreate() { super.onCreate() diff --git a/example/android/build.gradle b/example/android/build.gradle index 19c421d..04c24b3 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,5 +1,8 @@ buildscript { ext { + def v2FeaturesEnabled = + !Boolean.parseBoolean(System.getenv("VISION_CAMERA_MLKIT_DISABLE_V2_FEATURES")) + buildToolsVersion = "36.0.0" minSdkVersion = 24 compileSdkVersion = 36 @@ -9,11 +12,11 @@ buildscript { set('react-native-vision-camera-mlkit', [ mlkit: [ - textRecognition : true, - textRecognitionChinese : true, - textRecognitionDevanagari: true, - textRecognitionJapanese : true, - textRecognitionKorean : true, + textRecognition : v2FeaturesEnabled, + textRecognitionChinese : v2FeaturesEnabled, + textRecognitionDevanagari: v2FeaturesEnabled, + textRecognitionJapanese : v2FeaturesEnabled, + textRecognitionKorean : v2FeaturesEnabled, faceDetection : false, faceMeshDetection : false, poseDetection : false, @@ -21,7 +24,7 @@ buildscript { selfieSegmentation : false, subjectSegmentation : false, documentScanner : false, - barcodeScanning : false, + barcodeScanning : v2FeaturesEnabled, imageLabeling : false, objectDetection : false, digitalInkRecognition : false, diff --git a/example/android/gradle/wrapper/gradle-wrapper.jar b/example/android/gradle/wrapper/gradle-wrapper.jar index 1b33c55..61285a6 100644 Binary files a/example/android/gradle/wrapper/gradle-wrapper.jar and b/example/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index d4081da..37f78a6 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/example/android/gradlew b/example/android/gradlew index 23d15a9..adff685 100755 --- a/example/android/gradlew +++ b/example/android/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/example/android/gradlew.bat b/example/android/gradlew.bat index dd2b8ee..4626b90 100644 --- a/example/android/gradlew.bat +++ b/example/android/gradlew.bat @@ -75,11 +75,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/example/babel.config.js b/example/babel.config.js index 9ab06a3..63495de 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -10,10 +10,7 @@ const workletsPluginOptions = {}; module.exports = getConfig( { presets: ['module:@react-native/babel-preset'], - plugins: [ - ['react-native-worklets-core/plugin'], - ['react-native-worklets/plugin', workletsPluginOptions], - ], + plugins: [['react-native-worklets/plugin', workletsPluginOptions]], }, { root, pkg } ); diff --git a/example/ios/Podfile b/example/ios/Podfile index 2bfec14..b482b85 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -10,7 +10,7 @@ $VisionCameraMLKit = { 'poseDetection' => false, 'poseDetectionAccurate' => false, 'selfieSegmentation' => false, - 'barcodeScanning' => false, + 'barcodeScanning' => true, 'imageLabeling' => false, 'objectDetection' => false, 'digitalInkRecognition' => false, @@ -53,13 +53,86 @@ target 'VisionCameraMLKitExample' do :app_path => "#{Pod::Config.instance.installation_root}/.." ) + def apply_fmt_xcode_26_workaround(installer) + fmt_base = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h') + return unless File.exist?(fmt_base) + + content = File.read(fmt_base) + return if content.include?('Xcode 26 workaround: disable consteval') + + patched = content.gsub( + /^(#elif defined\(__cpp_consteval\)\n# define FMT_USE_CONSTEVAL) 1$/, + "// Xcode 26 workaround: disable consteval\n\\1 0" + ) + + return if patched == content + + File.chmod(0o644, fmt_base) + File.write(fmt_base, patched) + Pod::UI.puts('Applied Xcode 26 fmt workaround (FMT_USE_CONSTEVAL=0)'.yellow) + end + + def apply_glog_xcode_26_workaround(installer) + modulemap = File.join(installer.sandbox.root, 'Target Support Files', 'glog', 'glog.modulemap') + patched = false + + if File.exist?(modulemap) + content = File.read(modulemap) + modulemap_content = content.gsub(/\n module \* \{ export \*\ }/, '') + + if modulemap_content != content + File.write(modulemap, modulemap_content) + patched = true + end + end + + Dir.glob(File.join(installer.sandbox.root, 'Target Support Files', '**', '*.xcconfig')).each do |xcconfig| + content = File.read(xcconfig) + xcconfig_content = content + .gsub(' -Xcc -fmodule-map-file="${PODS_ROOT}/Headers/Public/glog/glog.modulemap"', '') + .gsub(' -fmodule-map-file="${PODS_ROOT}/Headers/Public/glog/glog.modulemap"', '') + + if xcconfig_content != content + File.write(xcconfig, xcconfig_content) + patched = true + end + end + + Pod::UI.puts('Applied Xcode 26 glog workaround'.yellow) if patched + end + + def apply_worklets_header_search_paths_workaround(installer) + header_path = '"${PODS_ROOT}/Headers/Private/React-Core"' + patched = false + + Dir.glob(File.join(installer.sandbox.root, 'Target Support Files', 'VisionCameraWorklets', '*.xcconfig')).each do |xcconfig| + content = File.read(xcconfig) + next if content.include?(header_path) + + xcconfig_content = content.gsub( + /^(HEADER_SEARCH_PATHS = .*)$/, + "\\1 #{header_path}" + ) + + next if xcconfig_content == content + + File.write(xcconfig, xcconfig_content) + patched = true + end + + Pod::UI.puts('Applied VisionCameraWorklets React-Core header path workaround'.yellow) if patched + end + post_install do |installer| - # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, # :ccache_enabled => true ) + + apply_fmt_xcode_26_workaround(installer) + apply_glog_xcode_26_workaround(installer) + apply_worklets_header_search_paths_workaround(installer) end end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 0788f76..dbdeaca 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,43 +1,34 @@ PODS: - - boost (1.84.0) - - DoubleConversion (1.1.6) - - fast_float (8.0.0) - - FBLazyVector (0.81.1) - - fmt (11.0.2) - - glog (0.3.5) + - FBLazyVector (0.86.0) - GoogleDataTransport (9.4.1): - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30911.0, >= 2.30908.0) - PromisesObjC (< 3.0, >= 1.2) - - GoogleMLKit/MLKitCore (5.0.0): - - MLKitCommon (~> 10.0.0) - - GoogleMLKit/TextRecognition (5.0.0): + - GoogleMLKit/BarcodeScanning (6.0.0): - GoogleMLKit/MLKitCore - - MLKitTextRecognition (~> 3.0.0) - - GoogleMLKit/TextRecognitionChinese (5.0.0): + - MLKitBarcodeScanning (~> 5.0.0) + - GoogleMLKit/MLKitCore (6.0.0): + - MLKitCommon (~> 11.0.0) + - GoogleMLKit/TextRecognition (6.0.0): - GoogleMLKit/MLKitCore - - MLKitTextRecognitionChinese (~> 2.0.0) - - GoogleMLKit/TextRecognitionDevanagari (5.0.0): + - MLKitTextRecognition (~> 4.0.0) + - GoogleMLKit/TextRecognitionChinese (6.0.0): - GoogleMLKit/MLKitCore - - MLKitTextRecognitionDevanagari (~> 2.0.0) - - GoogleMLKit/TextRecognitionJapanese (5.0.0): + - MLKitTextRecognitionChinese (~> 3.0.0) + - GoogleMLKit/TextRecognitionDevanagari (6.0.0): - GoogleMLKit/MLKitCore - - MLKitTextRecognitionJapanese (~> 2.0.0) - - GoogleMLKit/TextRecognitionKorean (5.0.0): + - MLKitTextRecognitionDevanagari (~> 3.0.0) + - GoogleMLKit/TextRecognitionJapanese (6.0.0): - GoogleMLKit/MLKitCore - - MLKitTextRecognitionKorean (~> 2.0.0) - - GoogleToolboxForMac/DebugUtils (2.3.2): - - GoogleToolboxForMac/Defines (= 2.3.2) - - GoogleToolboxForMac/Defines (2.3.2) - - GoogleToolboxForMac/Logger (2.3.2): - - GoogleToolboxForMac/Defines (= 2.3.2) - - "GoogleToolboxForMac/NSData+zlib (2.3.2)": - - GoogleToolboxForMac/Defines (= 2.3.2) - - "GoogleToolboxForMac/NSDictionary+URLArguments (2.3.2)": - - GoogleToolboxForMac/DebugUtils (= 2.3.2) - - GoogleToolboxForMac/Defines (= 2.3.2) - - "GoogleToolboxForMac/NSString+URLArguments (= 2.3.2)" - - "GoogleToolboxForMac/NSString+URLArguments (2.3.2)" + - MLKitTextRecognitionJapanese (~> 3.0.0) + - GoogleMLKit/TextRecognitionKorean (6.0.0): + - GoogleMLKit/MLKitCore + - MLKitTextRecognitionKorean (~> 3.0.0) + - GoogleToolboxForMac/Defines (4.2.1) + - GoogleToolboxForMac/Logger (4.2.1): + - GoogleToolboxForMac/Defines (= 4.2.1) + - "GoogleToolboxForMac/NSData+zlib (4.2.1)": + - GoogleToolboxForMac/Defines (= 4.2.1) - GoogleUtilities/Environment (7.13.3): - GoogleUtilities/Privacy - PromisesObjC (< 3.0, >= 1.2) @@ -51,103 +42,130 @@ PODS: - GoogleUtilitiesComponents (1.1.0): - GoogleUtilities/Logger - GTMSessionFetcher/Core (3.5.0) - - hermes-engine (0.81.1): - - hermes-engine/Pre-built (= 0.81.1) - - hermes-engine/Pre-built (0.81.1) + - hermes-engine (250829098.0.14): + - hermes-engine/Pre-built (= 250829098.0.14) + - hermes-engine/Pre-built (250829098.0.14) - MLImage (1.0.0-beta5) - - MLKitCommon (10.0.0): - - GoogleDataTransport (~> 9.0) - - GoogleToolboxForMac/Logger (~> 2.1) - - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" - - GoogleUtilities/UserDefaults (~> 7.0) + - MLKitBarcodeScanning (5.0.0): + - MLKitCommon (~> 11.0) + - MLKitVision (~> 7.0) + - MLKitCommon (11.0.0): + - GoogleDataTransport (< 10.0, >= 9.4.1) + - GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1) + - "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)" + - GoogleUtilities/UserDefaults (< 8.0, >= 7.13.0) - GoogleUtilitiesComponents (~> 1.0) - - GTMSessionFetcher/Core (< 4.0, >= 1.1) - - MLKitTextRecognition (3.0.0): - - MLKitCommon (~> 10.0) - - MLKitTextRecognitionCommon (= 2.0.0) - - MLKitVision (~> 6.0) - - MLKitTextRecognitionChinese (2.0.0): - - MLKitCommon (~> 10.0) - - MLKitTextRecognitionCommon (= 2.0.0) - - MLKitVision (~> 6.0) - - MLKitTextRecognitionCommon (2.0.0): - - MLKitCommon (~> 10.0) - - MLKitVision (~> 6.0) - - MLKitTextRecognitionDevanagari (2.0.0): - - MLKitCommon (~> 10.0) - - MLKitTextRecognitionCommon (= 2.0.0) - - MLKitVision (~> 6.0) - - MLKitTextRecognitionJapanese (2.0.0): - - MLKitCommon (~> 10.0) - - MLKitTextRecognitionCommon (= 2.0.0) - - MLKitVision (~> 6.0) - - MLKitTextRecognitionKorean (2.0.0): - - MLKitCommon (~> 10.0) - - MLKitTextRecognitionCommon (= 2.0.0) - - MLKitVision (~> 6.0) - - MLKitVision (6.0.0): - - GoogleToolboxForMac/Logger (~> 2.1) - - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - - GTMSessionFetcher/Core (< 4.0, >= 1.1) + - GTMSessionFetcher/Core (< 4.0, >= 3.3.2) + - MLKitTextRecognition (4.0.0): + - MLKitCommon (~> 11.0) + - MLKitTextRecognitionCommon (= 3.0.0) + - MLKitVision (~> 7.0) + - MLKitTextRecognitionChinese (3.0.0): + - MLKitCommon (~> 11.0) + - MLKitTextRecognitionCommon (= 3.0.0) + - MLKitVision (~> 7.0) + - MLKitTextRecognitionCommon (3.0.0): + - MLKitCommon (~> 11.0) + - MLKitVision (~> 7.0) + - MLKitTextRecognitionDevanagari (3.0.0): + - MLKitCommon (~> 11.0) + - MLKitTextRecognitionCommon (= 3.0.0) + - MLKitVision (~> 7.0) + - MLKitTextRecognitionJapanese (3.0.0): + - MLKitCommon (~> 11.0) + - MLKitTextRecognitionCommon (= 3.0.0) + - MLKitVision (~> 7.0) + - MLKitTextRecognitionKorean (3.0.0): + - MLKitCommon (~> 11.0) + - MLKitTextRecognitionCommon (= 3.0.0) + - MLKitVision (~> 7.0) + - MLKitVision (7.0.0): + - GoogleToolboxForMac/Logger (< 5.0, >= 4.2.1) + - "GoogleToolboxForMac/NSData+zlib (< 5.0, >= 4.2.1)" + - GTMSessionFetcher/Core (< 4.0, >= 3.3.2) - MLImage (= 1.0.0-beta5) - - MLKitCommon (~> 10.0) + - MLKitCommon (~> 11.0) - nanopb (2.30910.0): - nanopb/decode (= 2.30910.0) - nanopb/encode (= 2.30910.0) - nanopb/decode (2.30910.0) - nanopb/encode (2.30910.0) + - NitroImage (0.15.1): + - hermes-engine + - NitroModules + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - NitroModules (0.36.1): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga - PromisesObjC (2.4.0) - - RCT-Folly (2024.11.18.00): - - boost - - DoubleConversion - - fast_float (= 8.0.0) - - fmt (= 11.0.2) - - glog - - RCT-Folly/Default (= 2024.11.18.00) - - RCT-Folly/Default (2024.11.18.00): - - boost - - DoubleConversion - - fast_float (= 8.0.0) - - fmt (= 11.0.2) - - glog - - RCT-Folly/Fabric (2024.11.18.00): - - boost - - DoubleConversion - - fast_float (= 8.0.0) - - fmt (= 11.0.2) - - glog - - RCTDeprecation (0.81.1) - - RCTRequired (0.81.1) - - RCTTypeSafety (0.81.1): - - FBLazyVector (= 0.81.1) - - RCTRequired (= 0.81.1) - - React-Core (= 0.81.1) - - React (0.81.1): - - React-Core (= 0.81.1) - - React-Core/DevSupport (= 0.81.1) - - React-Core/RCTWebSocket (= 0.81.1) - - React-RCTActionSheet (= 0.81.1) - - React-RCTAnimation (= 0.81.1) - - React-RCTBlob (= 0.81.1) - - React-RCTImage (= 0.81.1) - - React-RCTLinking (= 0.81.1) - - React-RCTNetwork (= 0.81.1) - - React-RCTSettings (= 0.81.1) - - React-RCTText (= 0.81.1) - - React-RCTVibration (= 0.81.1) - - React-callinvoker (0.81.1) - - React-Core (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - RCTDeprecation (0.86.0) + - RCTRequired (0.86.0) + - RCTSwiftUI (0.86.0) + - RCTSwiftUIWrapper (0.86.0): + - RCTSwiftUI + - RCTTypeSafety (0.86.0): + - FBLazyVector (= 0.86.0) + - RCTRequired (= 0.86.0) + - React-Core (= 0.86.0) + - React (0.86.0): + - React-Core (= 0.86.0) + - React-Core/DevSupport (= 0.86.0) + - React-Core/RCTWebSocket (= 0.86.0) + - React-RCTActionSheet (= 0.86.0) + - React-RCTAnimation (= 0.86.0) + - React-RCTBlob (= 0.86.0) + - React-RCTImage (= 0.86.0) + - React-RCTLinking (= 0.86.0) + - React-RCTNetwork (= 0.86.0) + - React-RCTSettings (= 0.86.0) + - React-RCTText (= 0.86.0) + - React-RCTVibration (= 0.86.0) + - React-callinvoker (0.86.0) + - React-Core (0.86.0): + - hermes-engine - RCTDeprecation - - React-Core/Default (= 0.81.1) + - React-Core-prebuilt + - React-Core/Default (= 0.86.0) - React-cxxreact - React-featureflags - React-hermes @@ -160,18 +178,14 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/CoreModulesHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core-prebuilt (0.86.0): + - ReactNativeDependencies + - React-Core/CoreModulesHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -185,18 +199,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/Default (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/Default (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-cxxreact - React-featureflags - React-hermes @@ -209,20 +217,14 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/DevSupport (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/DevSupport (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.81.1) - - React-Core/RCTWebSocket (= 0.81.1) + - React-Core-prebuilt + - React-Core/Default (= 0.86.0) + - React-Core/RCTWebSocket (= 0.86.0) - React-cxxreact - React-featureflags - React-hermes @@ -235,18 +237,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTActionSheetHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTActionSheetHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -260,18 +256,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTAnimationHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTAnimationHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -285,18 +275,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTBlobHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTBlobHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -310,18 +294,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTImageHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTImageHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -335,18 +313,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTLinkingHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTLinkingHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -360,18 +332,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTNetworkHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTNetworkHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -385,18 +351,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTSettingsHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTSettingsHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -410,18 +370,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTTextHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTTextHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -435,18 +389,12 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTVibrationHeaders (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTVibrationHeaders (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation + - React-Core-prebuilt - React-Core/Default - React-cxxreact - React-featureflags @@ -460,19 +408,13 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Core/RCTWebSocket (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core/RCTWebSocket (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.81.1) + - React-Core-prebuilt + - React-Core/Default (= 0.86.0) - React-cxxreact - React-featureflags - React-hermes @@ -485,76 +427,65 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket - - Yoga - - React-CoreModules (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - RCTTypeSafety (= 0.81.1) - - React-Core/CoreModulesHeaders (= 0.81.1) - - React-jsi (= 0.81.1) + - ReactNativeDependencies + - Yoga + - React-CoreModules (0.86.0): + - RCTTypeSafety (= 0.86.0) + - React-Core-prebuilt + - React-Core/CoreModulesHeaders (= 0.86.0) + - React-debug + - React-featureflags + - React-jsi (= 0.86.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-NativeModulesApple - React-RCTBlob - React-RCTFBReactNativeSpec - - React-RCTImage (= 0.81.1) + - React-RCTImage (= 0.86.0) - React-runtimeexecutor + - React-utils - ReactCommon - - SocketRocket - - React-cxxreact (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-debug (= 0.81.1) - - React-jsi (= 0.81.1) + - ReactNativeDependencies + - React-cxxreact (0.86.0): + - hermes-engine + - React-callinvoker (= 0.86.0) + - React-Core-prebuilt + - React-debug (= 0.86.0) + - React-jsi (= 0.86.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) + - React-logger (= 0.86.0) + - React-perflogger (= 0.86.0) - React-runtimeexecutor - - React-timing (= 0.81.1) - - SocketRocket - - React-debug (0.81.1) - - React-defaultsnativemodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-timing (= 0.86.0) + - React-utils + - ReactNativeDependencies + - React-debug (0.86.0): + - React-debug/redbox (= 0.86.0) + - React-debug/redbox (0.86.0) + - React-defaultsnativemodule (0.86.0): + - hermes-engine + - React-Core-prebuilt - React-domnativemodule + - React-Fabric/animated + - React-featureflags - React-featureflagsnativemodule - React-idlecallbacksnativemodule + - React-intersectionobservernativemodule - React-jsi - React-jsiexecutor - React-microtasksnativemodule + - React-mutationobservernativemodule - React-RCTFBReactNativeSpec - - SocketRocket - - React-domnativemodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-viewtransitionnativemodule + - React-webperformancenativemodule + - ReactNativeDependencies + - Yoga + - React-domnativemodule (0.86.0): + - hermes-engine + - React-Core-prebuilt - React-Fabric - React-Fabric/bridging - React-FabricComponents @@ -564,39 +495,35 @@ PODS: - React-RCTFBReactNativeSpec - React-runtimeexecutor - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Fabric (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Fabric (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - - React-Fabric/animations (= 0.81.1) - - React-Fabric/attributedstring (= 0.81.1) - - React-Fabric/bridging (= 0.81.1) - - React-Fabric/componentregistry (= 0.81.1) - - React-Fabric/componentregistrynative (= 0.81.1) - - React-Fabric/components (= 0.81.1) - - React-Fabric/consistency (= 0.81.1) - - React-Fabric/core (= 0.81.1) - - React-Fabric/dom (= 0.81.1) - - React-Fabric/imagemanager (= 0.81.1) - - React-Fabric/leakchecker (= 0.81.1) - - React-Fabric/mounting (= 0.81.1) - - React-Fabric/observers (= 0.81.1) - - React-Fabric/scheduler (= 0.81.1) - - React-Fabric/telemetry (= 0.81.1) - - React-Fabric/templateprocessor (= 0.81.1) - - React-Fabric/uimanager (= 0.81.1) + - React-Fabric/animated (= 0.86.0) + - React-Fabric/animationbackend (= 0.86.0) + - React-Fabric/animations (= 0.86.0) + - React-Fabric/attributedstring (= 0.86.0) + - React-Fabric/bridging (= 0.86.0) + - React-Fabric/componentregistry (= 0.86.0) + - React-Fabric/componentregistrynative (= 0.86.0) + - React-Fabric/components (= 0.86.0) + - React-Fabric/consistency (= 0.86.0) + - React-Fabric/core (= 0.86.0) + - React-Fabric/dom (= 0.86.0) + - React-Fabric/imagemanager (= 0.86.0) + - React-Fabric/leakchecker (= 0.86.0) + - React-Fabric/mounting (= 0.86.0) + - React-Fabric/observers (= 0.86.0) + - React-Fabric/scheduler (= 0.86.0) + - React-Fabric/telemetry (= 0.86.0) + - React-Fabric/uimanager (= 0.86.0) + - React-Fabric/viewtransition (= 0.86.0) - React-featureflags - React-graphics - React-jsi @@ -607,21 +534,16 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/animations (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/animated (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug + - React-Fabric/animationbackend - React-featureflags - React-graphics - React-jsi @@ -632,19 +554,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/attributedstring (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/animationbackend (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -657,19 +573,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/bridging (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/animations (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -682,19 +592,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/componentregistry (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/attributedstring (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -707,19 +611,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/componentregistrynative (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/bridging (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -732,25 +630,15 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/components (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/componentregistry (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - - React-Fabric/components/legacyviewmanagerinterop (= 0.81.1) - - React-Fabric/components/root (= 0.81.1) - - React-Fabric/components/scrollview (= 0.81.1) - - React-Fabric/components/view (= 0.81.1) - React-featureflags - React-graphics - React-jsi @@ -761,19 +649,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/components/legacyviewmanagerinterop (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/componentregistrynative (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -786,21 +668,19 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/components/root (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/components (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug + - React-Fabric/components/legacyviewmanagerinterop (= 0.86.0) + - React-Fabric/components/root (= 0.86.0) + - React-Fabric/components/scrollview (= 0.86.0) + - React-Fabric/components/view (= 0.86.0) - React-featureflags - React-graphics - React-jsi @@ -811,19 +691,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/components/scrollview (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/components/legacyviewmanagerinterop (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -836,19 +710,51 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/components/view (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/components/root (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt + - React-cxxreact + - React-debug + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-logger + - React-rendererdebug + - React-runtimeexecutor + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - React-Fabric/components/scrollview (0.86.0): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-cxxreact + - React-debug + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-logger + - React-rendererdebug + - React-runtimeexecutor + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - React-Fabric/components/view (0.86.0): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -862,20 +768,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-Fabric/consistency (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Fabric/consistency (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -888,19 +788,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/core (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/core (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -913,19 +807,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/dom (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/dom (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -938,19 +826,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/imagemanager (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/imagemanager (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -963,21 +845,57 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/leakchecker (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/leakchecker (0.86.0): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-cxxreact + - React-debug + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-logger + - React-rendererdebug + - React-runtimeexecutor + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - React-Fabric/mounting (0.86.0): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-cxxreact + - React-debug + - React-featureflags + - React-graphics + - React-jsi + - React-jsiexecutor + - React-jsinspectortracing + - React-logger + - React-rendererdebug + - React-runtimeexecutor + - React-runtimescheduler + - React-utils + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - React-Fabric/observers (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug + - React-Fabric/observers/events (= 0.86.0) + - React-Fabric/observers/intersection (= 0.86.0) + - React-Fabric/observers/mutation (= 0.86.0) - React-featureflags - React-graphics - React-jsi @@ -988,19 +906,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/mounting (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/observers/events (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -1013,22 +925,15 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/observers (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/observers/intersection (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - - React-Fabric/observers/events (= 0.81.1) - React-featureflags - React-graphics - React-jsi @@ -1039,19 +944,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/observers/events (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/observers/mutation (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -1064,46 +963,37 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/scheduler (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/scheduler (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug + - React-Fabric/animationbackend - React-Fabric/observers/events + - React-Fabric/viewtransition - React-featureflags - React-graphics - React-jsi - React-jsiexecutor - React-logger + - React-performancecdpmetrics - React-performancetimeline - React-rendererdebug - React-runtimeexecutor - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/telemetry (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/telemetry (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -1116,47 +1006,36 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/templateprocessor (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/uimanager (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug + - React-Fabric/uimanager/consistency (= 0.86.0) - React-featureflags - React-graphics - React-jsi - React-jsiexecutor - React-logger + - React-rendererconsistency - React-rendererdebug - React-runtimeexecutor - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/uimanager (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/uimanager/consistency (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - - React-Fabric/uimanager/consistency (= 0.81.1) - React-featureflags - React-graphics - React-jsi @@ -1168,19 +1047,13 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-Fabric/uimanager/consistency (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-Fabric/viewtransition (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -1188,30 +1061,23 @@ PODS: - React-jsi - React-jsiexecutor - React-logger - - React-rendererconsistency - React-rendererdebug - React-runtimeexecutor - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket - - React-FabricComponents (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-FabricComponents (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components (= 0.81.1) - - React-FabricComponents/textlayoutmanager (= 0.81.1) + - React-FabricComponents/components (= 0.86.0) + - React-FabricComponents/textlayoutmanager (= 0.86.0) - React-featureflags - React-graphics - React-jsi @@ -1222,34 +1088,28 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components/inputaccessory (= 0.81.1) - - React-FabricComponents/components/iostextinput (= 0.81.1) - - React-FabricComponents/components/modal (= 0.81.1) - - React-FabricComponents/components/rncore (= 0.81.1) - - React-FabricComponents/components/safeareaview (= 0.81.1) - - React-FabricComponents/components/scrollview (= 0.81.1) - - React-FabricComponents/components/switch (= 0.81.1) - - React-FabricComponents/components/text (= 0.81.1) - - React-FabricComponents/components/textinput (= 0.81.1) - - React-FabricComponents/components/unimplementedview (= 0.81.1) - - React-FabricComponents/components/virtualview (= 0.81.1) + - React-FabricComponents/components/inputaccessory (= 0.86.0) + - React-FabricComponents/components/iostextinput (= 0.86.0) + - React-FabricComponents/components/modal (= 0.86.0) + - React-FabricComponents/components/rncore (= 0.86.0) + - React-FabricComponents/components/safeareaview (= 0.86.0) + - React-FabricComponents/components/scrollview (= 0.86.0) + - React-FabricComponents/components/switch (= 0.86.0) + - React-FabricComponents/components/text (= 0.86.0) + - React-FabricComponents/components/textinput (= 0.86.0) + - React-FabricComponents/components/unimplementedview (= 0.86.0) + - React-FabricComponents/components/virtualview (= 0.86.0) - React-featureflags - React-graphics - React-jsi @@ -1260,20 +1120,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/inputaccessory (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/inputaccessory (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1287,20 +1141,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/iostextinput (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/iostextinput (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1314,20 +1162,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/modal (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/modal (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1341,20 +1183,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/rncore (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/rncore (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1368,20 +1204,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/safeareaview (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/safeareaview (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1395,20 +1225,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/scrollview (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/scrollview (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1422,20 +1246,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/switch (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/switch (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1449,20 +1267,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/text (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/text (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1476,20 +1288,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/textinput (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/textinput (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1503,20 +1309,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/unimplementedview (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/unimplementedview (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1530,20 +1330,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/components/virtualview (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/components/virtualview (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1557,20 +1351,14 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricComponents/textlayoutmanager (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricComponents/textlayoutmanager (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-cxxreact - React-debug - React-Fabric @@ -1584,300 +1372,201 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-FabricImage (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-FabricImage (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - RCTRequired (= 0.81.1) - - RCTTypeSafety (= 0.81.1) + - RCTRequired (= 0.86.0) + - RCTTypeSafety (= 0.86.0) + - React-Core-prebuilt - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - React-jsiexecutor (= 0.81.1) + - React-jsiexecutor (= 0.86.0) - React-logger - React-rendererdebug - React-utils - ReactCommon - - SocketRocket + - ReactNativeDependencies - Yoga - - React-featureflags (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - SocketRocket - - React-featureflagsnativemodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-featureflags (0.86.0): + - React-Core-prebuilt + - ReactNativeDependencies + - React-featureflagsnativemodule (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-featureflags - React-jsi - React-jsiexecutor - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - - SocketRocket - - React-graphics (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-graphics (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt + - React-featureflags - React-jsi - React-jsiexecutor + - React-rendererdebug - React-utils - - SocketRocket - - React-hermes (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-hermes (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) + - React-Core-prebuilt + - React-cxxreact (= 0.86.0) - React-jsi - - React-jsiexecutor (= 0.81.1) + - React-jsiexecutor (= 0.86.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-perflogger (= 0.81.1) + - React-jsitooling + - React-oscompat + - React-perflogger (= 0.86.0) - React-runtimeexecutor - - SocketRocket - - React-idlecallbacksnativemodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-idlecallbacksnativemodule (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-jsi - React-jsiexecutor - React-RCTFBReactNativeSpec - React-runtimeexecutor - React-runtimescheduler - ReactCommon/turbomodule/core - - SocketRocket - - React-ImageManager (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-ImageManager (0.86.0): + - React-Core-prebuilt - React-Core/Default - React-debug - React-Fabric - React-graphics - React-rendererdebug - React-utils - - SocketRocket - - React-jserrorhandler (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-intersectionobservernativemodule (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt + - React-cxxreact + - React-Fabric + - React-Fabric/bridging + - React-graphics + - React-jsi + - React-jsiexecutor + - React-RCTFBReactNativeSpec + - React-runtimeexecutor + - React-runtimescheduler + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - React-jserrorhandler (0.86.0): + - hermes-engine + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags - React-jsi - ReactCommon/turbomodule/bridging - - SocketRocket - - React-jsi (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - SocketRocket - - React-jsiexecutor (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) + - ReactNativeDependencies + - React-jsi (0.86.0): + - hermes-engine + - React-Core-prebuilt + - ReactNativeDependencies + - React-jsiexecutor (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-cxxreact + - React-debug + - React-jserrorhandler + - React-jsi - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-perflogger (= 0.81.1) + - React-jsitooling + - React-perflogger - React-runtimeexecutor - - SocketRocket - - React-jsinspector (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-utils + - ReactNativeDependencies + - React-jsinspector (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-featureflags - React-jsi - React-jsinspectorcdp - React-jsinspectornetwork - React-jsinspectortracing - React-oscompat - - React-perflogger (= 0.81.1) + - React-perflogger (= 0.86.0) - React-runtimeexecutor - - SocketRocket - - React-jsinspectorcdp (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - SocketRocket - - React-jsinspectornetwork (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - React-featureflags + - React-utils + - ReactNativeDependencies + - React-jsinspectorcdp (0.86.0): + - React-Core-prebuilt + - ReactNativeDependencies + - React-jsinspectornetwork (0.86.0): + - React-Core-prebuilt - React-jsinspectorcdp - - React-performancetimeline - - React-timing - - SocketRocket - - React-jsinspectortracing (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-jsinspectortracing (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-jsi + - React-jsinspectornetwork - React-oscompat - React-timing - - SocketRocket - - React-jsitooling (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) + - React-utils + - ReactNativeDependencies + - React-jsitooling (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-cxxreact (= 0.86.0) + - React-debug + - React-jsi (= 0.86.0) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-runtimeexecutor - - SocketRocket - - React-jsitracing (0.81.1): - - React-jsi - - React-logger (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - SocketRocket - - React-Mapbuffer (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - React-debug - - SocketRocket - - React-microtasksnativemodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-utils + - ReactNativeDependencies + - React-jsitracing (0.86.0): + - React-jsi + - React-logger (0.86.0): + - React-Core-prebuilt + - ReactNativeDependencies + - React-Mapbuffer (0.86.0): + - React-Core-prebuilt + - React-debug + - ReactNativeDependencies + - React-microtasksnativemodule (0.86.0): + - hermes-engine + - React-Core-prebuilt - React-jsi - React-jsiexecutor - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - - SocketRocket - - react-native-blur (4.4.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-mutationobservernativemodule (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - RCTRequired - - RCTTypeSafety - - React-Core - - React-debug + - React-Core-prebuilt + - React-cxxreact - React-Fabric + - React-Fabric/bridging + - React-Fabric/observers/mutation - React-featureflags - - React-graphics - - React-ImageManager - React-jsi - - React-NativeModulesApple - - React-RCTFabric - - React-renderercss - - React-rendererdebug - - React-utils - - ReactCodegen - - ReactCommon/turbomodule/bridging + - React-jsiexecutor + - React-RCTFBReactNativeSpec + - React-runtimeexecutor - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-image-picker (8.2.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-blur (4.4.1): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -1892,28 +1581,20 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-safe-area-context (5.6.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-image-picker (8.2.1): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - react-native-safe-area-context/common (= 5.6.2) - - react-native-safe-area-context/fabric (= 5.6.2) - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -1922,26 +1603,22 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-safe-area-context/common (5.6.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-safe-area-context (5.8.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi + - react-native-safe-area-context/common (= 5.8.0) + - react-native-safe-area-context/fabric (= 5.8.0) - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -1950,27 +1627,20 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-safe-area-context/fabric (5.6.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-safe-area-context/common (5.8.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - react-native-safe-area-context/common - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -1979,27 +1649,21 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-slider (5.1.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-safe-area-context/fabric (5.8.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - react-native-slider/common (= 5.1.2) + - react-native-safe-area-context/common - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -2008,26 +1672,21 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-slider/common (5.1.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-slider (5.1.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi + - react-native-slider/common (= 5.1.2) - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -2036,20 +1695,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - react-native-worklets-core (1.6.2): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - react-native-slider/common (5.1.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2064,20 +1717,15 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - React-NativeModulesApple (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-NativeModulesApple (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - React-callinvoker - React-Core + - React-Core-prebuilt - React-cxxreact + - React-debug - React-featureflags - React-jsi - React-jsinspector @@ -2085,60 +1733,53 @@ PODS: - React-runtimeexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket - - React-oscompat (0.81.1) - - React-perflogger (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - SocketRocket - - React-performancetimeline (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-networking (0.86.0): + - React-Core-prebuilt + - React-jsinspectornetwork + - React-jsinspectortracing + - React-performancetimeline + - React-timing + - ReactNativeDependencies + - React-oscompat (0.86.0) + - React-perflogger (0.86.0): + - React-Core-prebuilt + - ReactNativeDependencies + - React-performancecdpmetrics (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-jsi + - React-performancetimeline + - React-runtimeexecutor + - React-timing + - ReactNativeDependencies + - React-performancetimeline (0.86.0): + - React-Core-prebuilt - React-featureflags + - React-jsinspector - React-jsinspectortracing - React-perflogger - React-timing - - SocketRocket - - React-RCTActionSheet (0.81.1): - - React-Core/RCTActionSheetHeaders (= 0.81.1) - - React-RCTAnimation (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-RCTActionSheet (0.86.0): + - React-Core/RCTActionSheetHeaders (= 0.86.0) + - React-RCTAnimation (0.86.0): - RCTTypeSafety + - React-Core-prebuilt - React-Core/RCTAnimationHeaders + - React-debug - React-featureflags - React-jsi - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - SocketRocket - - React-RCTAppDelegate (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RCTAppDelegate (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-CoreModules - React-debug - React-defaultsnativemodule @@ -2160,16 +1801,10 @@ PODS: - React-runtimescheduler - React-utils - ReactCommon - - SocketRocket - - React-RCTBlob (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-RCTBlob (0.86.0): + - hermes-engine + - React-Core-prebuilt - React-Core/RCTBlobHeaders - React-Core/RCTWebSocket - React-jsi @@ -2179,17 +1814,12 @@ PODS: - React-RCTFBReactNativeSpec - React-RCTNetwork - ReactCommon - - SocketRocket - - React-RCTFabric (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RCTFabric (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - RCTSwiftUIWrapper - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-FabricComponents @@ -2200,8 +1830,9 @@ PODS: - React-jsi - React-jsinspector - React-jsinspectorcdp - - React-jsinspectornetwork - React-jsinspectortracing + - React-networking + - React-performancecdpmetrics - React-performancetimeline - React-RCTAnimation - React-RCTFBReactNativeSpec @@ -2213,37 +1844,25 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket + - ReactNativeDependencies - Yoga - - React-RCTFBReactNativeSpec (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-RCTFBReactNativeSpec (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-jsi - React-NativeModulesApple - - React-RCTFBReactNativeSpec/components (= 0.81.1) + - React-RCTFBReactNativeSpec/components (= 0.86.0) - ReactCommon - - SocketRocket - - React-RCTFBReactNativeSpec/components (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RCTFBReactNativeSpec/components (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2253,59 +1872,44 @@ PODS: - React-rendererdebug - React-utils - ReactCommon - - SocketRocket + - ReactNativeDependencies - Yoga - - React-RCTImage (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - React-RCTImage (0.86.0): - RCTTypeSafety + - React-Core-prebuilt - React-Core/RCTImageHeaders - React-jsi - React-NativeModulesApple - React-RCTFBReactNativeSpec - React-RCTNetwork - ReactCommon - - SocketRocket - - React-RCTLinking (0.81.1): - - React-Core/RCTLinkingHeaders (= 0.81.1) - - React-jsi (= 0.81.1) + - ReactNativeDependencies + - React-RCTLinking (0.86.0): + - React-Core/RCTLinkingHeaders (= 0.86.0) + - React-jsi (= 0.86.0) - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - ReactCommon/turbomodule/core (= 0.81.1) - - React-RCTNetwork (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactCommon/turbomodule/core (= 0.86.0) + - React-RCTNetwork (0.86.0): - RCTTypeSafety + - React-Core-prebuilt - React-Core/RCTNetworkHeaders + - React-debug - React-featureflags - React-jsi - React-jsinspectorcdp - React-jsinspectornetwork - React-NativeModulesApple + - React-networking - React-RCTFBReactNativeSpec - ReactCommon - - SocketRocket - - React-RCTRuntime (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RCTRuntime (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - React-Core + - React-Core-prebuilt + - React-debug - React-jsi - React-jsinspector - React-jsinspectorcdp @@ -2315,63 +1919,40 @@ PODS: - React-RuntimeCore - React-runtimeexecutor - React-RuntimeHermes - - SocketRocket - - React-RCTSettings (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - React-utils + - ReactNativeDependencies + - React-RCTSettings (0.86.0): - RCTTypeSafety + - React-Core-prebuilt - React-Core/RCTSettingsHeaders - React-jsi - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - SocketRocket - - React-RCTText (0.81.1): - - React-Core/RCTTextHeaders (= 0.81.1) - - Yoga - - React-RCTVibration (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-RCTText (0.86.0): + - React-Core/RCTTextHeaders (= 0.86.0) + - Yoga + - React-RCTVibration (0.86.0): + - React-Core-prebuilt - React-Core/RCTVibrationHeaders - React-jsi - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - SocketRocket - - React-rendererconsistency (0.81.1) - - React-renderercss (0.81.1): - - React-debug - - React-utils - - React-rendererdebug (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - React-debug - - SocketRocket - - React-RuntimeApple (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-rendererconsistency (0.86.0) + - React-renderercss (0.86.0): + - React-debug + - React-utils + - React-rendererdebug (0.86.0): + - React-Core-prebuilt + - React-debug + - ReactNativeDependencies + - React-RuntimeApple (0.86.0): + - hermes-engine - React-callinvoker + - React-Core-prebuilt - React-Core/Default - React-CoreModules - React-cxxreact @@ -2390,16 +1971,10 @@ PODS: - React-RuntimeHermes - React-runtimescheduler - React-utils - - SocketRocket - - React-RuntimeCore (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RuntimeCore (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-cxxreact - React-Fabric - React-featureflags @@ -2412,29 +1987,17 @@ PODS: - React-runtimeexecutor - React-runtimescheduler - React-utils - - SocketRocket - - React-runtimeexecutor (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - React-runtimeexecutor (0.86.0): + - React-Core-prebuilt - React-debug - React-featureflags - - React-jsi (= 0.81.1) + - React-jsi (= 0.86.0) - React-utils - - SocketRocket - - React-RuntimeHermes (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-RuntimeHermes (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-featureflags - React-hermes - React-jsi @@ -2446,17 +2009,11 @@ PODS: - React-RuntimeCore - React-runtimeexecutor - React-utils - - SocketRocket - - React-runtimescheduler (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactNativeDependencies + - React-runtimescheduler (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - React-callinvoker + - React-Core-prebuilt - React-cxxreact - React-debug - React-featureflags @@ -2468,35 +2025,46 @@ PODS: - React-runtimeexecutor - React-timing - React-utils - - SocketRocket - - React-timing (0.81.1): + - ReactNativeDependencies + - React-timing (0.86.0): - React-debug - - React-utils (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-utils (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - React-Core-prebuilt - React-debug - - React-jsi (= 0.81.1) - - SocketRocket - - ReactAppDependencyProvider (0.81.1): + - React-jsi (= 0.86.0) + - ReactNativeDependencies + - React-viewtransitionnativemodule (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-Fabric + - React-Fabric/bridging + - React-jsi + - React-jsiexecutor + - React-RCTFBReactNativeSpec + - React-runtimeexecutor + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - React-webperformancenativemodule (0.86.0): + - hermes-engine + - React-Core-prebuilt + - React-cxxreact + - React-jsi + - React-jsiexecutor + - React-performancetimeline + - React-RCTFBReactNativeSpec + - React-runtimeexecutor + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - ReactAppDependencyProvider (0.86.0): - ReactCodegen - - ReactCodegen (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - ReactCodegen (0.86.0): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-FabricImage @@ -2510,79 +2078,72 @@ PODS: - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket - - ReactCommon (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - RCT-Folly - - RCT-Folly/Fabric - - ReactCommon/turbomodule (= 0.81.1) - - SocketRocket - - ReactCommon/turbomodule (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) - - ReactCommon/turbomodule/bridging (= 0.81.1) - - ReactCommon/turbomodule/core (= 0.81.1) - - SocketRocket - - ReactCommon/turbomodule/bridging (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) - - SocketRocket - - ReactCommon/turbomodule/core (0.81.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-callinvoker (= 0.81.1) - - React-cxxreact (= 0.81.1) - - React-debug (= 0.81.1) - - React-featureflags (= 0.81.1) - - React-jsi (= 0.81.1) - - React-logger (= 0.81.1) - - React-perflogger (= 0.81.1) - - React-utils (= 0.81.1) - - SocketRocket - - RNGestureHandler (2.30.0): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - ReactNativeDependencies + - ReactCommon (0.86.0): + - React-Core-prebuilt + - ReactCommon/turbomodule (= 0.86.0) + - ReactNativeDependencies + - ReactCommon/turbomodule (0.86.0): + - hermes-engine + - React-callinvoker (= 0.86.0) + - React-Core-prebuilt + - React-cxxreact (= 0.86.0) + - React-jsi (= 0.86.0) + - React-logger (= 0.86.0) + - React-perflogger (= 0.86.0) + - ReactCommon/turbomodule/bridging (= 0.86.0) + - ReactCommon/turbomodule/core (= 0.86.0) + - ReactNativeDependencies + - ReactCommon/turbomodule/bridging (0.86.0): + - hermes-engine + - React-callinvoker (= 0.86.0) + - React-Core-prebuilt + - React-cxxreact (= 0.86.0) + - React-jsi (= 0.86.0) + - React-logger (= 0.86.0) + - React-perflogger (= 0.86.0) + - ReactNativeDependencies + - ReactCommon/turbomodule/core (0.86.0): + - hermes-engine + - React-callinvoker (= 0.86.0) + - React-Core-prebuilt + - React-cxxreact (= 0.86.0) + - React-debug (= 0.86.0) + - React-featureflags (= 0.86.0) + - React-jsi (= 0.86.0) + - React-logger (= 0.86.0) + - React-perflogger (= 0.86.0) + - React-utils (= 0.86.0) + - ReactNativeDependencies + - ReactNativeBottomSheet (0.17.0-next.1): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - ReactNativeDependencies (0.86.0) + - RNGestureHandler (3.1.0): + - hermes-engine - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2597,20 +2158,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - RNPermissions (5.4.4): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNPermissions (5.6.1): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2625,20 +2180,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - RNReanimated (4.2.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNReanimated (4.5.3): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2654,22 +2203,18 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated (= 4.2.1) + - ReactNativeDependencies + - RNReanimated/apple (= 4.5.3) + - RNReanimated/common (= 4.5.3) + - RNReanimated/view (= 4.5.3) - RNWorklets - - SocketRocket - Yoga - - RNReanimated/reanimated (4.2.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNReanimated/apple (4.5.3): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2685,22 +2230,15 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated/apple (= 4.2.1) + - ReactNativeDependencies - RNWorklets - - SocketRocket - Yoga - - RNReanimated/reanimated/apple (4.2.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNReanimated/common (4.5.3): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2716,21 +2254,39 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - ReactNativeDependencies - RNWorklets - - SocketRocket - Yoga - - RNScreens (4.20.0): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNReanimated/view (4.5.3): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - RNWorklets + - Yoga + - RNScreens (4.26.2): + - hermes-engine + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2746,21 +2302,15 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNScreens/common (= 4.20.0) - - SocketRocket + - ReactNativeDependencies + - RNScreens/common (= 4.26.2) - Yoga - - RNScreens/common (4.20.0): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNScreens/common (4.26.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2776,20 +2326,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - RNSVG (15.15.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNSVG (15.15.5): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2804,21 +2348,15 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNSVG/common (= 15.15.1) - - SocketRocket + - ReactNativeDependencies + - RNSVG/common (= 15.15.5) - Yoga - - RNSVG/common (15.15.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNSVG/common (15.15.5): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2833,20 +2371,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - RNWorklets (0.7.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNWorklets (0.10.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2862,21 +2394,16 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/worklets (= 0.7.1) - - SocketRocket + - ReactNativeDependencies + - RNWorklets/apple (= 0.10.2) + - RNWorklets/common (= 0.10.2) - Yoga - - RNWorklets/worklets (0.7.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNWorklets/apple (0.10.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2892,21 +2419,14 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/worklets/apple (= 0.7.1) - - SocketRocket + - ReactNativeDependencies - Yoga - - RNWorklets/worklets/apple (0.7.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - RNWorklets/common (0.10.2): - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2922,38 +2442,71 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies - Yoga - - SocketRocket (0.7.1) - - VisionCamera (4.7.3): - - VisionCamera/Core (= 4.7.3) - - VisionCamera/FrameProcessors (= 4.7.3) - - VisionCamera/React (= 4.7.3) - - VisionCamera/Core (4.7.3) - - VisionCamera/FrameProcessors (4.7.3): - - React + - VisionCamera (5.2.1): + - hermes-engine + - NitroImage + - NitroModules + - RCTRequired + - RCTTypeSafety - React-callinvoker - - react-native-worklets-core - - VisionCamera/React (4.7.3): - - React-Core - - VisionCamera/FrameProcessors - - VisionCameraMLKit (1.0.0): - - boost - - DoubleConversion - - fast_float - - fmt - - glog + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - Yoga + - VisionCameraMLKit (2.0.0): + - GoogleMLKit/BarcodeScanning - GoogleMLKit/TextRecognition - GoogleMLKit/TextRecognitionChinese - GoogleMLKit/TextRecognitionDevanagari - GoogleMLKit/TextRecognitionJapanese - GoogleMLKit/TextRecognitionKorean - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric + - NitroModules + - RCTRequired + - RCTTypeSafety + - React-Core + - React-Core-prebuilt + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - ReactNativeDependencies + - VisionCamera + - Yoga + - VisionCameraWorklets (5.2.1): + - hermes-engine + - NitroModules - RCTRequired - RCTTypeSafety + - React-callinvoker - React-Core + - React-Core-prebuilt - React-debug - React-Fabric - React-featureflags @@ -2968,26 +2521,26 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SocketRocket + - ReactNativeDependencies + - RNWorklets - VisionCamera - Yoga - Yoga (0.0.0) DEPENDENCIES: - - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - fast_float (from `../node_modules/react-native/third-party-podspecs/fast_float.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) + - NitroImage (from `../node_modules/react-native-nitro-image`) + - NitroModules (from `../node_modules/react-native-nitro-modules`) - RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`) - RCTRequired (from `../node_modules/react-native/Libraries/Required`) + - RCTSwiftUI (from `../node_modules/react-native/ReactApple/RCTSwiftUI`) + - RCTSwiftUIWrapper (from `../node_modules/react-native/ReactApple/RCTSwiftUIWrapper`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - React (from `../node_modules/react-native/`) - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) - React-Core (from `../node_modules/react-native/`) + - React-Core-prebuilt (from `../node_modules/react-native/React-Core-prebuilt.podspec`) - React-Core/RCTWebSocket (from `../node_modules/react-native/`) - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) @@ -3003,6 +2556,7 @@ DEPENDENCIES: - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) - React-idlecallbacksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks`) - React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`) + - React-intersectionobservernativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/intersectionobserver`) - React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`) - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) @@ -3015,14 +2569,16 @@ DEPENDENCIES: - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`) - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) + - React-mutationobservernativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/mutationobserver`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-image-picker (from `../node_modules/react-native-image-picker`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - "react-native-slider (from `../node_modules/@react-native-community/slider`)" - - react-native-worklets-core (from `../node_modules/react-native-worklets-core`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) + - React-networking (from `../node_modules/react-native/ReactCommon/react/networking`) - React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) + - React-performancecdpmetrics (from `../node_modules/react-native/ReactCommon/react/performance/cdpmetrics`) - React-performancetimeline (from `../node_modules/react-native/ReactCommon/react/performance/timeline`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -3047,18 +2603,22 @@ DEPENDENCIES: - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) - React-timing (from `../node_modules/react-native/ReactCommon/react/timing`) - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) - - ReactAppDependencyProvider (from `build/generated/ios`) - - ReactCodegen (from `build/generated/ios`) + - React-viewtransitionnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/viewtransition`) + - React-webperformancenativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/webperformance`) + - ReactAppDependencyProvider (from `build/generated/ios/ReactAppDependencyProvider`) + - ReactCodegen (from `build/generated/ios/ReactCodegen`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - "ReactNativeBottomSheet (from `../node_modules/@swmansion/react-native-bottom-sheet`)" + - ReactNativeDependencies (from `../node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNPermissions (from `../node_modules/react-native-permissions`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) - RNWorklets (from `../node_modules/react-native-worklets`) - - SocketRocket (~> 0.7.1) - VisionCamera (from `../node_modules/react-native-vision-camera`) - VisionCameraMLKit (from `../..`) + - VisionCameraWorklets (from `../node_modules/react-native-vision-camera-worklets`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -3070,6 +2630,7 @@ SPEC REPOS: - GoogleUtilitiesComponents - GTMSessionFetcher - MLImage + - MLKitBarcodeScanning - MLKitCommon - MLKitTextRecognition - MLKitTextRecognitionChinese @@ -3080,30 +2641,25 @@ SPEC REPOS: - MLKitVision - nanopb - PromisesObjC - - SocketRocket EXTERNAL SOURCES: - boost: - :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" - DoubleConversion: - :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" - fast_float: - :podspec: "../node_modules/react-native/third-party-podspecs/fast_float.podspec" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" - fmt: - :podspec: "../node_modules/react-native/third-party-podspecs/fmt.podspec" - glog: - :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" - :tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782 - RCT-Folly: - :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" + :tag: hermes-v250829098.0.14 + NitroImage: + :path: "../node_modules/react-native-nitro-image" + NitroModules: + :path: "../node_modules/react-native-nitro-modules" RCTDeprecation: :path: "../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation" RCTRequired: :path: "../node_modules/react-native/Libraries/Required" + RCTSwiftUI: + :path: "../node_modules/react-native/ReactApple/RCTSwiftUI" + RCTSwiftUIWrapper: + :path: "../node_modules/react-native/ReactApple/RCTSwiftUIWrapper" RCTTypeSafety: :path: "../node_modules/react-native/Libraries/TypeSafety" React: @@ -3112,6 +2668,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/callinvoker" React-Core: :path: "../node_modules/react-native/" + React-Core-prebuilt: + :podspec: "../node_modules/react-native/React-Core-prebuilt.podspec" React-CoreModules: :path: "../node_modules/react-native/React/CoreModules" React-cxxreact: @@ -3140,6 +2698,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks" React-ImageManager: :path: "../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios" + React-intersectionobservernativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/intersectionobserver" React-jserrorhandler: :path: "../node_modules/react-native/ReactCommon/jserrorhandler" React-jsi: @@ -3164,6 +2724,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" React-microtasksnativemodule: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks" + React-mutationobservernativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/mutationobserver" react-native-blur: :path: "../node_modules/@react-native-community/blur" react-native-image-picker: @@ -3172,14 +2734,16 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-safe-area-context" react-native-slider: :path: "../node_modules/@react-native-community/slider" - react-native-worklets-core: - :path: "../node_modules/react-native-worklets-core" React-NativeModulesApple: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" + React-networking: + :path: "../node_modules/react-native/ReactCommon/react/networking" React-oscompat: :path: "../node_modules/react-native/ReactCommon/oscompat" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" + React-performancecdpmetrics: + :path: "../node_modules/react-native/ReactCommon/react/performance/cdpmetrics" React-performancetimeline: :path: "../node_modules/react-native/ReactCommon/react/performance/timeline" React-RCTActionSheet: @@ -3228,12 +2792,20 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/react/timing" React-utils: :path: "../node_modules/react-native/ReactCommon/react/utils" + React-viewtransitionnativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/viewtransition" + React-webperformancenativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/webperformance" ReactAppDependencyProvider: - :path: build/generated/ios + :path: build/generated/ios/ReactAppDependencyProvider ReactCodegen: - :path: build/generated/ios + :path: build/generated/ios/ReactCodegen ReactCommon: :path: "../node_modules/react-native/ReactCommon" + ReactNativeBottomSheet: + :path: "../node_modules/@swmansion/react-native-bottom-sheet" + ReactNativeDependencies: + :podspec: "../node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNPermissions: @@ -3250,113 +2822,122 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-vision-camera" VisionCameraMLKit: :path: "../.." + VisionCameraWorklets: + :path: "../node_modules/react-native-vision-camera-worklets" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb - fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 - FBLazyVector: b8f1312d48447cca7b4abc21ed155db14742bd03 - fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd - glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 + FBLazyVector: b3e7ad108f0d882e30445c5527d774e3fd432f3d GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a - GoogleMLKit: 90ba06e028795a50261f29500d238d6061538711 - GoogleToolboxForMac: 8bef7c7c5cf7291c687cf5354f39f9db6399ad34 + GoogleMLKit: 97ac7af399057e99182ee8edfa8249e3226a4065 + GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8 GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 GoogleUtilitiesComponents: 679b2c881db3b615a2777504623df6122dd20afe GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - hermes-engine: 4f8246b1f6d79f625e0d99472d1f3a71da4d28ca + hermes-engine: 81dcdbf6d754602a93d3f56df72372aff2585329 MLImage: 1824212150da33ef225fbd3dc49f184cf611046c - MLKitCommon: afcd11b6c0735066a0dde8b4bf2331f6197cbca2 - MLKitTextRecognition: 91706574e4db9b48cd2e66cbbcc6b58956156b0a - MLKitTextRecognitionChinese: 19d3a70799f17cf2115b6381964b87e874d96dcd - MLKitTextRecognitionCommon: 3bd8375160d21dc9f9cc512d1fab2530ecc43dde - MLKitTextRecognitionDevanagari: 9c689b259f6654fdaa1004a769dcec55b257a02a - MLKitTextRecognitionJapanese: 9afa94ad6d622a69c2043def562fffa9be8d269d - MLKitTextRecognitionKorean: 4b37d1a034af61bf9699d791ae8bcf04cb1e97b7 - MLKitVision: 90922bca854014a856f8b649d1f1f04f63fd9c79 + MLKitBarcodeScanning: 10ca0845a6d15f2f6e911f682a1998b68b973e8b + MLKitCommon: afec63980417d29ffbb4790529a1b0a2291699e1 + MLKitTextRecognition: c83c18ad25496f2077f6ec93c5940487ff2eb343 + MLKitTextRecognitionChinese: 09d6e22bbc2f1687573473ebb6e470af11c65e7a + MLKitTextRecognitionCommon: c0b3a63d529296a19bce1f8bc8a513644ed4d1f6 + MLKitTextRecognitionDevanagari: abd49431a28e385eaa98edcc2da9664e1eb05b51 + MLKitTextRecognitionJapanese: f59521572316562030b20cc98b8e635fc282a172 + MLKitTextRecognitionKorean: 4877b6a8d95cd8846586e83f85b2f3e9ac93a737 + MLKitVision: e858c5f125ecc288e4a31127928301eaba9ae0c1 nanopb: 438bc412db1928dac798aa6fd75726007be04262 + NitroImage: 0bbe0fc7032343a8e574e9ebcfafbbd81e1b37c2 + NitroModules: 7e004af1d2cbc3072b071de62aeb9c147ef79d34 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f - RCTDeprecation: c4b9e2fd0ab200e3af72b013ed6113187c607077 - RCTRequired: e97dd5dafc1db8094e63bc5031e0371f092ae92a - RCTTypeSafety: 720403058b7c1380c6a3ae5706981d6362962c89 - React: f1486d005993b0af01943af1850d3d4f3b597545 - React-callinvoker: 133f69368c8559e744efa345223625d412f5dfbe - React-Core: d6d8c1fd33697cec596d33b820456505ee305686 - React-CoreModules: 81ab751a7668ba161440f9623b994e1a6a3019fe - React-cxxreact: 16f2a2751d0dce8b569f23c1914edc90f655b01b - React-debug: e01581e1589f329e61c95b332bf7f4969b10564b - React-defaultsnativemodule: e956b1d8fe15cc79d23061db229bf88170565f2f - React-domnativemodule: a18b0f7a31b9c75f12fa369baece5542d1265b36 - React-Fabric: c0237a32c3c0dbea2d2b294c8e95605e1dfe2f57 - React-FabricComponents: 65b03884bd5d9f24c79a631d7d26f0fa079bc4aa - React-FabricImage: de1ea2f2a0b32ad02e5cbb64827d1eec0439cf0d - React-featureflags: 02de9c35256cc624269b01d670d99e1fd706ea8d - React-featureflagsnativemodule: 8b84e67edbaa7b9318390c5bd3ae19790a74f356 - React-graphics: 004b40c1b236ea3bb8de6693439bef9797922ba9 - React-hermes: 2179a018b2f86652f6f33ef23efd9e5ac284b247 - React-idlecallbacksnativemodule: f54ea68f984b12e42feed1e7110623b2c38df4d1 - React-ImageManager: 9dd04b7b62bc5397f876ca5fb1b712e700ce390c - React-jserrorhandler: 2f90bf50fffea1d012e7f3d717c6adf748b1813d - React-jsi: b27208f8866e53238534f65f304903e4eff25e05 - React-jsiexecutor: 1d3e827797f592c393860dea91aaa6d53c7715e7 - React-jsinspector: bda319277ae779bc476b736fe3a497c6aed304cd - React-jsinspectorcdp: 69e1736edfd5420037680b7b4557fa748c3c8216 - React-jsinspectornetwork: 7aa707b057c6129b4af59e0c9160436bbab25022 - React-jsinspectortracing: b4a8a328ad2697f9638daa4b7cc054e0303fa47f - React-jsitooling: a6c7e2829437b28665e97a398b3374d443125e24 - React-jsitracing: d87ae17dd0eef7844e605945da926c5433fe2b51 - React-logger: d27dd2000f520bf891d24f6e141cde34df41f0ee - React-Mapbuffer: 0746ffab5ac0f49b7c9347338e3d0c1d9dd634c8 - React-microtasksnativemodule: b0fb3f97372df39bda3e657536039f1af227cc29 - react-native-blur: ba0e9ad6274783c8d45f42da82acae02e25784ad - react-native-image-picker: 43e6cd4231e670030fe09b079d696fa5a634ccfc - react-native-safe-area-context: 54d812805f3c4e08a4580ad086cbde1d8780c2e4 - react-native-slider: 5da4af460d0dd1346f927e829dfecbb81bd46f91 - react-native-worklets-core: 5abf7405ae179fd6b3a45899b1a0e5777aa389d3 - React-NativeModulesApple: 9ec9240159974c94886ebbe4caec18e3395f6aef - React-oscompat: b12c633e9c00f1f99467b1e0e0b8038895dae436 - React-perflogger: ccf4fd2664b00818645e588623c7531a8b32d114 - React-performancetimeline: a866ba759d8e06e9ba174b4421677edcae487baf - React-RCTActionSheet: 3f741a3712653611a6bfc5abceb8260af9d0b218 - React-RCTAnimation: 2edeebfba175cc2e937e2752209ab605d3c48f21 - React-RCTAppDelegate: e292321e83ee966897244a032216a70930b758d6 - React-RCTBlob: 8dfb24b6dd4a5af45e1e59e2fd925b2df1e44d08 - React-RCTFabric: b25b02a2016f5cb15926a60c77a8d75865aa3558 - React-RCTFBReactNativeSpec: 20338571a1ed853d01da6c68576aa6e8e107b6f6 - React-RCTImage: c7fe8c2f2ae8bad98ab4d944d5d50a889da4b652 - React-RCTLinking: 9ac21ce9f1af914bb01c06af3752db2ec840d0ee - React-RCTNetwork: 09a5de71d757dbad4b3fe3615839290200b932aa - React-RCTRuntime: da3f1e0ce088c20350044cdf1efcd7f8d9b9b40c - React-RCTSettings: fee112652ac7569ea9abe910206e1685f5f9adba - React-RCTText: 7ee9d0bc16b3a8149f8df6d70c48e724d0db1d89 - React-RCTVibration: 619d613abaeb05f6fbc2b2e5e33f724f05df8eb8 - React-rendererconsistency: a05f6c37f9389c53213d1e28798e441fa6fbdbcd - React-renderercss: 3decb27a81648fcdee837c59994b51fff5be5a67 - React-rendererdebug: 3b9a92d36932af52e1b473f2a89ea4b05dbdecdf - React-RuntimeApple: 4e35fb74be4b721c2e1fd6d54ec66456fa7043e9 - React-RuntimeCore: 0fd7ac6e3e9dd20cb47e87c6b9f35832dd445d5e - React-runtimeexecutor: 7680156c9f3a5a49c688bc33f9ec5ea1b00527f5 - React-RuntimeHermes: 435b7104a3c749af6251353dcb7317a8e53cbd73 - React-runtimescheduler: 8056b916168e446ea44531883928034e62e76a81 - React-timing: 36da85e32e53008ce73f87528818191e7f2508ba - React-utils: 71e53d55ce778c6e7c7c9db4b1b9d63ef8f55289 - ReactAppDependencyProvider: 448b422f8af1dedf81374eacc90a15439a0ed7f5 - ReactCodegen: 3baedb0c33f963250c866151b825a3c5194b12f1 - ReactCommon: e897f9a1b4afab370cfefaaf5fb3c80371bc3937 - RNGestureHandler: 92ad734ef0da16d69d0a325b7e1e9ae80bdce1f9 - RNPermissions: ff3bee717e3df88d22727cc9ee672d9401c8108e - RNReanimated: f2cdef8c5ec70e440498b949f9af3ea39f70fcec - RNScreens: b2a5c76af24a02a2fd71bfce42780fdd9c79cc6d - RNSVG: 046b3f72f0ddbe895a88cdd3bfc3b19822c9efab - RNWorklets: ab7740c2a152f77ff76a40d52be860d8f128fab1 - SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - VisionCamera: 47f10351a1b6a8d251b90986ae72ca5f52331954 - VisionCameraMLKit: 218fa89d2b7fc41d4c18e7d02388acfee540f414 - Yoga: fa23995c18b65978347b096d0836f4f5093df545 + RCTDeprecation: 2a74a2c57675e64419bd89078efde81f7c1de90b + RCTRequired: 30451112e6fef4e6f31b4e7eee0845156e35e4b0 + RCTSwiftUI: 5aaf0b07e747ba749dc6acc94d8bd41eea4b570f + RCTSwiftUIWrapper: 1feaf484029fd6294fe8bc401d28e1d803eca142 + RCTTypeSafety: 3eaed17dbddb0b989208b062ea14c44d412b9780 + React: 2574546f2d017abd14d0c9b48cf2b6a0547c2591 + React-callinvoker: 03cd4b931d1d583d87aae99b8f7b6fe26bf571ee + React-Core: b0a0038e05720fb8148759404e9c354e3e60043c + React-Core-prebuilt: 7da85c26e5616d52f119b81ce5e3e6fc5c9bda49 + React-CoreModules: a1121b3182200be11e078940159c67ff95ee98b4 + React-cxxreact: 8f74977959064bee99af63bb0ad95b6c3dbec921 + React-debug: 8cc8d99ccc664ef9e873027f7fc3fb0a50496012 + React-defaultsnativemodule: 7c8182addbb79ec576c589186b51e3fb405da7da + React-domnativemodule: 576bd1e6ad81477997dcb556e6db1f005134356b + React-Fabric: 4cbd22315ddb9e33441437f851117d314d1b4ad3 + React-FabricComponents: efe374aecaf1bbc2fb9a195ece4b50fd9f66bfa0 + React-FabricImage: cfeffc0b527de8bc2dc5a50618dad119361d0ec3 + React-featureflags: 98931b22f5f4b861a3985b75bd79c5fcbe4618ab + React-featureflagsnativemodule: 518c2e279cdb3835604f7e8fb15f4c2691336b4c + React-graphics: ac9ff09da733d98c0e5eddb589dc7f9f082c9531 + React-hermes: bd1a14a982e63ee75e9c9cb8d11d3d4b5f330196 + React-idlecallbacksnativemodule: b6378d3bca83d8284e1abaa51251ee1ce570d85a + React-ImageManager: 4936349da191d1bc29ed2bbaf5a2dd74bfdf5ed8 + React-intersectionobservernativemodule: d9a6451f2aa1f1c989d5d5e0d967db2c07d0c48c + React-jserrorhandler: 2455567e21fcc036f96015b2b8eb4eb13e0d8d05 + React-jsi: bf5ec8e7a7b26bddc39ab7f821af5aad8bb94a33 + React-jsiexecutor: cf6c957f578dd491ec8ae516a39aff2cf7369f1a + React-jsinspector: 63e9b9f9a5b6c51bf38deea2b379a63754c0ab0d + React-jsinspectorcdp: 327082854cdebb1f500a669c51146b9fd871058c + React-jsinspectornetwork: bbc5c2e881252075d63dc679f18cd856c2def94e + React-jsinspectortracing: ea6ec857ead0de4e6bbb2e12ee48ae4381938874 + React-jsitooling: 52e278666b35e856414d613d7dc50d1f0d50d9a5 + React-jsitracing: 642172314677a1d1780b81f4e2e4a3f4d3ccf238 + React-logger: 35cda3ab8977c6c4546e3cf6dc8f91bacec25934 + React-Mapbuffer: c058c051f571589e37a29bce18d0e9b730faa9d0 + React-microtasksnativemodule: 03752e60738a797bb49f4d6cb0291dfa398099b8 + React-mutationobservernativemodule: 2e568e13c98bd185fe83266795233fa7ad2cbc19 + react-native-blur: baf5874b4abf3bb8b2012172a3d0905653a1a2b5 + react-native-image-picker: 2146157d5d37a34c2063d1d2ed01081b56d0b87b + react-native-safe-area-context: c1eb308f4b36372a4de4b3bdaa8ed695ec3dd461 + react-native-slider: 73473ab537b86b7ca1b21a28d16019d3cb63e927 + React-NativeModulesApple: a4713821c9caae40ae33eef933a6e692a6f4a81d + React-networking: b344a1a41a4729ef859123b7a234f3092761cb25 + React-oscompat: 0b72a7e926954a0415ccd83e0748b6561fe45367 + React-perflogger: a0d581c6cc174e847877107ddac3f4fc9b518dc7 + React-performancecdpmetrics: 91d3d0dce2e3a239ea68cc2882e75b11a61cbf2e + React-performancetimeline: 4b9e04002c1ddba95167276a86424e5face65605 + React-RCTActionSheet: 902c79deec52f99cc48b1051b59bcbe86787d339 + React-RCTAnimation: f50eac1c9dbea36c4abc69cb24e2da4364374055 + React-RCTAppDelegate: a5d746fec869d15a8f6eecce60510c18e52135d5 + React-RCTBlob: e544dc72edc6f277c67e85493b0a405e1993c250 + React-RCTFabric: 8003ea99830c294857d41469a888b033e5ad91a6 + React-RCTFBReactNativeSpec: 8a3506041284fdc75da90e6fa40fb9b575414a39 + React-RCTImage: fb85496986a53d9e11a835124a083b7c7c33f898 + React-RCTLinking: b8eafcdedaebf981a18396db61d1190f5279ea81 + React-RCTNetwork: 03573c4fcc73e28f48fea7aea69310b6955a749c + React-RCTRuntime: 08d58920b217b2d7715d5da595794e63520cd2d9 + React-RCTSettings: f9b278b46e5de1ff8b843bb7aefaee721f06572d + React-RCTText: 7266943febf3382dac8adce9ba0de95b90c26e9e + React-RCTVibration: 27e1952701ec858922062f25a59b0c48e7153151 + React-rendererconsistency: ef8519bdd9931261c6561bfad6506356b8108387 + React-renderercss: edc1b0a18b12d681f8edbc779039dc6db32cf7b2 + React-rendererdebug: 074ec3420f3bab2bea498da65e5a17e9288c90d0 + React-RuntimeApple: 180682587e82ae4fc525f7d6636ed5db39c1e78c + React-RuntimeCore: 991cdb27072f7885750fdad4a70c2b919533e4ef + React-runtimeexecutor: bfec6ca5e62c6b2460a4adf0fddce0c4db0a8748 + React-RuntimeHermes: dcb07afe0f38c1cbaf48b7a1bf4904e867529726 + React-runtimescheduler: fdf0b71e519e416ad38c76525df43eba8dd78db2 + React-timing: 7b538f379678210bf30d8541eb4cf007c000c6f3 + React-utils: a15da1da76aee3dd0ed9f51d62bf1c09be17c221 + React-viewtransitionnativemodule: 8556c844dcd691ab3fe1b32bbf8f58c8c9a49c75 + React-webperformancenativemodule: 4d1d0258107fe0cb8ef5c9ac17a6a099785f2995 + ReactAppDependencyProvider: adf5403892170fbe996fce485a703f25df08db66 + ReactCodegen: ee39bbc365b4791c9b5183b52c533ebf586e1d8d + ReactCommon: 4d01bfb533b93a2103329dfefc74db6a9e272888 + ReactNativeBottomSheet: 3551d418c1d10cd49e0907d68300374544fb8d00 + ReactNativeDependencies: fa0a54b3f5319ae0e3b9aff32bfee7a424b88e66 + RNGestureHandler: 6206fc566272f60a2d57a0b3258c495a73b7dc90 + RNPermissions: 509028712d9e899fcce678c315989a6d439b003c + RNReanimated: 5cc36a25f9e60c523734a60783f84d363e73b4dc + RNScreens: dcd5c85a822d9cbb21fc321bbbbcf918f3d48c23 + RNSVG: ffe18ba0e8fbad864bf22d6f0060a4ee88ec9bf3 + RNWorklets: 82a5f27dcf3bb69267ec6ce662a756a4d3f61522 + VisionCamera: 4e3e123f4d14c7d3934748c84fe6ddfa5046c5ee + VisionCameraMLKit: 08f7f64b2794cde438ca7ab82a4d904d52d44dd3 + VisionCameraWorklets: 0d8b34820c6aa351fbba9fab3d8ee8e8d98e1990 + Yoga: 94172d87dd5d83fc929bf1ee53121b5d4490b5f2 -PODFILE CHECKSUM: 41a62ebecc21ff87e3b5d0c2e79112ee681909eb +PODFILE CHECKSUM: bfa9c28a161369f7b66f55890deec95fe59f1504 COCOAPODS: 1.16.2 diff --git a/example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj b/example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj index 8a05b0c..4135522 100644 --- a/example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj +++ b/example/ios/VisionCameraMLKitExample.xcodeproj/project.pbxproj @@ -9,22 +9,22 @@ /* Begin PBXBuildFile section */ 057CEFDD928055D235F3DB7A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 390372C79ECA56845CF0980F /* libPods-VisionCameraMLKitExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A05D4578D644FAE34FCA956C /* libPods-VisionCameraMLKitExample.a */; }; 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + A215E534AD4A8AF0FC2576BB /* libPods-VisionCameraMLKitExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5356D6FA4FBA3F96B78CB5C2 /* libPods-VisionCameraMLKitExample.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 0BC6BB36A04F6716F2FD86A6 /* Pods-VisionCameraMLKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraMLKitExample.release.xcconfig"; path = "Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample.release.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* VisionCameraMLKitExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VisionCameraMLKitExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = VisionCameraMLKitExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = VisionCameraMLKitExample/Info.plist; sourceTree = ""; }; 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = VisionCameraMLKitExample/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 5356D6FA4FBA3F96B78CB5C2 /* libPods-VisionCameraMLKitExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VisionCameraMLKitExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 625C59F936557B13E231DCEB /* Pods-VisionCameraMLKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraMLKitExample.debug.xcconfig"; path = "Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample.debug.xcconfig"; sourceTree = ""; }; 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = VisionCameraMLKitExample/AppDelegate.swift; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = VisionCameraMLKitExample/LaunchScreen.storyboard; sourceTree = ""; }; - A05D4578D644FAE34FCA956C /* libPods-VisionCameraMLKitExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VisionCameraMLKitExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + E68B4C59D121CD78D0153B88 /* Pods-VisionCameraMLKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraMLKitExample.release.xcconfig"; path = "Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; - EF06C59FC6233A25C9565962 /* Pods-VisionCameraMLKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisionCameraMLKitExample.debug.xcconfig"; path = "Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -32,7 +32,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 390372C79ECA56845CF0980F /* libPods-VisionCameraMLKitExample.a in Frameworks */, + A215E534AD4A8AF0FC2576BB /* libPods-VisionCameraMLKitExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -55,7 +55,7 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - A05D4578D644FAE34FCA956C /* libPods-VisionCameraMLKitExample.a */, + 5356D6FA4FBA3F96B78CB5C2 /* libPods-VisionCameraMLKitExample.a */, ); name = Frameworks; sourceTree = ""; @@ -92,8 +92,8 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - EF06C59FC6233A25C9565962 /* Pods-VisionCameraMLKitExample.debug.xcconfig */, - 0BC6BB36A04F6716F2FD86A6 /* Pods-VisionCameraMLKitExample.release.xcconfig */, + 625C59F936557B13E231DCEB /* Pods-VisionCameraMLKitExample.debug.xcconfig */, + E68B4C59D121CD78D0153B88 /* Pods-VisionCameraMLKitExample.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -105,13 +105,13 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "VisionCameraMLKitExample" */; buildPhases = ( - 426E5821A05DA85CA40980A2 /* [CP] Check Pods Manifest.lock */, + 00F024070541868F49A03B54 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - E734EAFC8B4C50F49B773837 /* [CP] Embed Pods Frameworks */, - 8F49C75216F54AC817EEDA3D /* [CP] Copy Pods Resources */, + 6C1BBF82F44D50DC71B59ABF /* [CP] Embed Pods Frameworks */, + B937774704109FDAC544271B /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -182,9 +182,9 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; + shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"\\\"$WITH_ENVIRONMENT\\\" \\\"$REACT_NATIVE_XCODE\\\"\"\n"; }; - 426E5821A05DA85CA40980A2 /* [CP] Check Pods Manifest.lock */ = { + 00F024070541868F49A03B54 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -206,38 +206,38 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8F49C75216F54AC817EEDA3D /* [CP] Copy Pods Resources */ = { + 6C1BBF82F44D50DC71B59ABF /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - E734EAFC8B4C50F49B773837 /* [CP] Embed Pods Frameworks */ = { + B937774704109FDAC544271B /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VisionCameraMLKitExample/Pods-VisionCameraMLKitExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -256,7 +256,7 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EF06C59FC6233A25C9565962 /* Pods-VisionCameraMLKitExample.debug.xcconfig */; + baseConfigurationReference = 625C59F936557B13E231DCEB /* Pods-VisionCameraMLKitExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -289,7 +289,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0BC6BB36A04F6716F2FD86A6 /* Pods-VisionCameraMLKitExample.release.xcconfig */; + baseConfigurationReference = E68B4C59D121CD78D0153B88 /* Pods-VisionCameraMLKitExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -381,6 +381,10 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -388,11 +392,14 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); + PODFILE_DIR = "$(SRCROOT)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; + SWIFT_ENABLE_EXPLICIT_MODULES = NO; USE_HERMES = true; }; name = Debug; @@ -452,6 +459,10 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -459,11 +470,14 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); + PODFILE_DIR = "$(SRCROOT)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_ENABLE_EXPLICIT_MODULES = NO; USE_HERMES = true; VALIDATE_PRODUCT = YES; }; diff --git a/example/ios/VisionCameraMLKitExample/Info.plist b/example/ios/VisionCameraMLKitExample/Info.plist index b86ed8d..bab19d4 100644 --- a/example/ios/VisionCameraMLKitExample/Info.plist +++ b/example/ios/VisionCameraMLKitExample/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion en CFBundleDisplayName diff --git a/example/jest.config.js b/example/jest.config.js index 8eb675e..294be30 100644 --- a/example/jest.config.js +++ b/example/jest.config.js @@ -1,3 +1,3 @@ module.exports = { - preset: 'react-native', + preset: '@react-native/jest-preset', }; diff --git a/example/package.json b/example/package.json index e6672bc..adeacbd 100644 --- a/example/package.json +++ b/example/package.json @@ -7,45 +7,47 @@ "ios": "react-native run-ios", "start": "react-native start", "build:android": "react-native build-android --extra-params \"--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a\"", - "build:ios": "react-native build-ios --mode Debug --destination \"${IOS_DESTINATION:-generic/platform=iOS Simulator}\"" + "build:ios": "react-native build-ios --mode Debug --destination \"${IOS_DESTINATION:-OS=latest,name=iPhone 15}\"" }, "dependencies": { - "@gorhom/bottom-sheet": "^5", "@react-native-community/blur": "^4.4.1", "@react-native-community/slider": "^5.1.2", "@react-navigation/elements": "^2.9.3", "@react-navigation/native": "^7.1.26", "@react-navigation/native-stack": "^7.9.0", + "@swmansion/react-native-bottom-sheet": "0.17.0-next.1", "lucide-react-native": "^0.562.0", - "react": "19.1.0", - "react-native": "0.81.1", - "react-native-gesture-handler": "^2.30.0", + "react": "19.2.3", + "react-native": "0.86.0", + "react-native-gesture-handler": "^3.0.2", "react-native-image-picker": "^8.2.1", + "react-native-nitro-image": "0.15.1", + "react-native-nitro-modules": "0.36.1", "react-native-permissions": "^5.4.4", - "react-native-reanimated": "^4.2.1", + "react-native-reanimated": "^4.5.1", "react-native-safe-area-context": "^5.6.2", - "react-native-screens": "^4.20.0", - "react-native-svg": "^15.15.1", - "react-native-vision-camera": "^4.7.3", - "react-native-worklets": "^0.7.1", - "react-native-worklets-core": "^1.6.2", + "react-native-screens": "^4.26.0", + "react-native-svg": "^15.15.5", + "react-native-vision-camera": "^5.1.0", + "react-native-vision-camera-worklets": "^5.1.0", + "react-native-worklets": "0.10.2", "zustand": "^5.0.9" }, "devDependencies": { "@babel/core": "^7.25.2", "@babel/preset-env": "^7.25.3", "@babel/runtime": "^7.25.0", - "@react-native-community/cli": "20.0.0", - "@react-native-community/cli-platform-android": "20.0.0", - "@react-native-community/cli-platform-ios": "20.0.0", - "@react-native/babel-preset": "0.81.1", - "@react-native/metro-config": "0.81.1", - "@react-native/typescript-config": "0.81.1", - "@types/react": "^19.1.0", + "@react-native-community/cli": "20.1.0", + "@react-native-community/cli-platform-android": "20.1.0", + "@react-native-community/cli-platform-ios": "20.1.0", + "@react-native/babel-preset": "0.86.0", + "@react-native/metro-config": "0.86.0", + "@react-native/typescript-config": "0.86.0", + "@types/react": "^19.2.0", "react-native-builder-bob": "^0.40.13", "react-native-monorepo-config": "^0.1.9" }, "engines": { - "node": ">=22" + "node": ">=22.11.0" } } diff --git a/example/react-native.config.js b/example/react-native.config.js index 59d9698..0b9606d 100644 --- a/example/react-native.config.js +++ b/example/react-native.config.js @@ -10,12 +10,6 @@ module.exports = { dependencies: { [pkg.name]: { root: path.join(__dirname, '..'), - platforms: { - // Codegen script incorrectly fails without this - // So we explicitly specify the platforms with empty object - ios: {}, - android: {}, - }, }, }, }; diff --git a/example/src/App.tsx b/example/src/App.tsx index 71918c2..960904f 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,4 +1,4 @@ -import { BottomSheetModalProvider } from '@gorhom/bottom-sheet'; +import { BottomSheetProvider } from '@swmansion/react-native-bottom-sheet'; import { StyleSheet } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { SafeAreaProvider } from 'react-native-safe-area-context'; @@ -15,13 +15,13 @@ const App = () => ( - + - + diff --git a/example/src/components/ui/CameraButton.tsx b/example/src/components/ui/CameraButton.tsx index 81f4c54..422e95d 100644 --- a/example/src/components/ui/CameraButton.tsx +++ b/example/src/components/ui/CameraButton.tsx @@ -7,7 +7,7 @@ import Reanimated, { withSpring, type SharedValue, } from 'react-native-reanimated'; -import type { Orientation } from 'react-native-vision-camera'; +import type { Orientation } from 'react-native-vision-camera-mlkit'; const ROTATION_MAP = { 'portrait': '0deg', diff --git a/example/src/components/ui/CameraControls.tsx b/example/src/components/ui/CameraControls.tsx index e2923b1..e9aa8c0 100644 --- a/example/src/components/ui/CameraControls.tsx +++ b/example/src/components/ui/CameraControls.tsx @@ -9,7 +9,7 @@ import { } from 'lucide-react-native'; import { StyleSheet, View } from 'react-native'; import type { SharedValue } from 'react-native-reanimated'; -import type { Orientation } from 'react-native-vision-camera'; +import type { Orientation } from 'react-native-vision-camera-mlkit'; /** Defaults to dark theme for the CameraView */ import { darkTheme as theme } from '../../styles/themes'; @@ -23,7 +23,7 @@ type CameraControlsProps = { onToggleTorch: () => void; onToggleFpsGraph: () => void; onOpenSettings: () => void; - onOpenTerminal: () => void; + onToggleTerminal: () => void; outputOrientation: SharedValue; }; @@ -33,7 +33,7 @@ const CameraControls = ({ onToggleTorch, onToggleFpsGraph, onOpenSettings, - onOpenTerminal, + onToggleTerminal, outputOrientation, }: CameraControlsProps) => { const Torch = torch === 'on' ? Zap : ZapOff; @@ -71,9 +71,9 @@ const CameraControls = ({ diff --git a/example/src/components/ui/RegionOfInterestControl.tsx b/example/src/components/ui/RegionOfInterestControl.tsx new file mode 100644 index 0000000..c700ee3 --- /dev/null +++ b/example/src/components/ui/RegionOfInterestControl.tsx @@ -0,0 +1,107 @@ +import { useState } from 'react'; +import type { RegionOfInterest } from 'react-native-vision-camera-mlkit'; +import { SectionSlider } from './SectionSlider'; +import { SectionSwitch } from './SectionSwitch'; + +type NormalizedRect = { + x: number; + y: number; + width: number; + height: number; +}; + +type RegionOfInterestControlProps = { + value: RegionOfInterest | undefined; + onValueChange: (roi: RegionOfInterest | undefined) => void; +}; + +const DEFAULT_RECT: NormalizedRect = { + x: 0.25, + y: 0.25, + width: 0.5, + height: 0.5, +}; + +const RegionOfInterestControl = ({ + value, + onValueChange, +}: RegionOfInterestControlProps) => { + const [rect, setRect] = useState(() => ({ + x: value?.x ?? DEFAULT_RECT.x, + y: value?.y ?? DEFAULT_RECT.y, + width: value?.width ?? DEFAULT_RECT.width, + height: value?.height ?? DEFAULT_RECT.height, + })); + + const enabled = value !== undefined; + + const updateRect = (patch: Partial) => { + const next = { ...rect, ...patch }; + const clamped: NormalizedRect = { + x: Math.min(next.x, 1 - next.width), + y: Math.min(next.y, 1 - next.height), + width: next.width, + height: next.height, + }; + + setRect(clamped); + if (enabled) { + onValueChange({ ...clamped, unit: 'normalized' }); + } + }; + + return ( + <> + + onValueChange(next ? { ...rect, unit: 'normalized' } : undefined) + } + /> + updateRect({ x })} + /> + updateRect({ y })} + /> + updateRect({ width })} + /> + updateRect({ height })} + /> + + ); +}; + +export { RegionOfInterestControl }; diff --git a/example/src/components/ui/SectionImageInput.tsx b/example/src/components/ui/SectionImageInput.tsx index 36596d7..26c94d8 100644 --- a/example/src/components/ui/SectionImageInput.tsx +++ b/example/src/components/ui/SectionImageInput.tsx @@ -144,7 +144,7 @@ const styles = StyleSheet.create({ marginVertical: 12, }, disabled: { - opacity: 0.8, + opacity: 0.6, }, }); diff --git a/example/src/components/ui/SectionPicker.tsx b/example/src/components/ui/SectionPicker.tsx index 7d5dd65..d8563f8 100644 --- a/example/src/components/ui/SectionPicker.tsx +++ b/example/src/components/ui/SectionPicker.tsx @@ -17,30 +17,61 @@ type SectionPickerOption = { value: T; }; -type SectionPickerProps = { - label: string; - description?: string; - value: T; - options: SectionPickerOption[]; - onValueChange: (value: T) => void; - disabled?: boolean; -}; +type SectionPickerProps = + | { + label: string; + description?: string; + value: T; + options: SectionPickerOption[]; + onValueChange: (value: T) => void; + disabled?: boolean; + multiple?: false; + } + | { + label: string; + description?: string; + value: T[]; + options: SectionPickerOption[]; + onValueChange: (value: T[]) => void; + disabled?: boolean; + multiple: true; + }; -const SectionPicker = ({ - label, - description, - value, - options, - onValueChange, - disabled = false, -}: SectionPickerProps) => { +const SectionPicker = (props: SectionPickerProps) => { + const { label, description, options, disabled = false } = props; + const isMultiple = props.multiple === true; const { theme } = useTheme(); const [isPickerVisible, setPickerVisible] = useState(false); - const selectedOption = options.find((opt) => opt.value === value); + const selectedValues = Array.isArray(props.value) + ? props.value + : [props.value]; + const selectedOptions = options.filter((opt) => + selectedValues.includes(opt.value) + ); + + const selectedLabel = (() => { + if (isMultiple) { + if (selectedOptions.length === 0) return 'Select'; + if (selectedOptions.length <= 2) { + return selectedOptions.map((opt) => opt.label).join(', '); + } + return `${selectedOptions.length} selected`; + } + return selectedOptions[0]?.label; + })(); const handleSelect = (selectedValue: T) => { - onValueChange(selectedValue); + if (isMultiple) { + const currentValues = Array.isArray(props.value) ? props.value : []; + const isSelected = currentValues.includes(selectedValue); + const nextValues = isSelected + ? currentValues.filter((item) => item !== selectedValue) + : [...currentValues, selectedValue]; + props.onValueChange(nextValues); + return; + } + props.onValueChange(selectedValue as T); setPickerVisible(false); }; @@ -85,7 +116,7 @@ const SectionPicker = ({ variant="sm" style={[styles.valueText, { color: theme.colors.primary }]} > - {selectedOption?.label} + {selectedLabel} @@ -129,7 +160,7 @@ const SectionPicker = ({ {options.map((option) => { - const isSelected = option.value === value; + const isSelected = selectedValues.includes(option.value); return ( { if (data === null || data === undefined) return data; @@ -46,15 +50,20 @@ const normalizeResultObject = (data: unknown) => { } }; -type CameraViewProps = ComponentProps & { +const FPS_SAMPLE_INTERVAL_MS = 500; +const FPS_HISTORY_LENGTH = 20; +const FPS_GRAPH_MAX_SCALE = 60; + +type CameraViewProps = Omit, 'device'> & { + device: CameraDevice; pluginId: PLUGIN_ID; flipCamera: () => void; isFrameProcessorEnabled?: boolean; - frameOutputOrientation: SharedWorkletsValue; - onOutputOrientationChangedCallback: (o: Orientation) => void; + isFpsGraphEnabled?: boolean; + frameOutputOrientation: SharedValue; }; -const CameraView = forwardRef( +const CameraView = forwardRef( ( { device, @@ -62,8 +71,9 @@ const CameraView = forwardRef( pluginId, flipCamera, isFrameProcessorEnabled = true, + isFpsGraphEnabled = false, frameOutputOrientation, - onOutputOrientationChangedCallback, + torchMode, ...props }, ref @@ -75,27 +85,90 @@ const CameraView = forwardRef( enableZoomGesture, enableTapGesture, enableDoubleTapGesture, + exposureBias, + enableLowLightBoost, + targetFps, + videoStabilizationMode, + orientationSource, } = useSettingsStore(); const { sharedOptions, pluginOptions } = usePluginOptionsStore(); - // Initialize plugins with options from store + const frameArrivalCount = useSharedValue(0); + const [fps, setFps] = useState(0); + const [fpsHistory, setFpsHistory] = useState([]); + + useEffect(() => { + if (!isFpsGraphEnabled) return; + + const interval = setInterval(() => { + const framesSinceLastSample = frameArrivalCount.value; + frameArrivalCount.value = 0; + + const instantaneousFps = Math.round( + (framesSinceLastSample * 1000) / FPS_SAMPLE_INTERVAL_MS + ); + + setFps(instantaneousFps); + setFpsHistory((prev) => + [...prev, instantaneousFps].slice(-FPS_HISTORY_LENGTH) + ); + }, FPS_SAMPLE_INTERVAL_MS); + + return () => clearInterval(interval); + }, [isFpsGraphEnabled, frameArrivalCount]); + const textRecognitionPlugin = useTextRecognition({ language: pluginOptions[PLUGIN_ID.TEXT_RECOGNITION].language, ...sharedOptions, }); + const barcodeScanningPlugin = useBarcodeScanning({ + formats: pluginOptions[PLUGIN_ID.BARCODE_SCANNING].formats, + enableAllPotentialBarcodes: + pluginOptions[PLUGIN_ID.BARCODE_SCANNING].enableAllPotentialBarcodes, + ...sharedOptions, + }); + const [focusPoint, setFocusPoint] = useState<{ x: number; y: number }>(); const scale = useSharedValue(0); const opacity = useSharedValue(0); + const frameCount = useSharedValue(0); + const zoom = useSharedValue(device?.minZoom ?? 1); + const savedZoom = useSharedValue(device?.minZoom ?? 1); + const exposure = useSharedValue(0); + + useEffect(() => { + zoom.value = device?.minZoom ?? 1; + }, [device, zoom]); - const format = useCameraFormat(device, Templates.FrameProcessing); + useEffect(() => { + if (!device?.supportsExposureBias) { + exposure.value = 0; + return; + } + + exposure.value = Math.min( + Math.max(exposureBias, device.minExposureBias), + device.maxExposureBias + ); + }, [device, exposureBias, exposure]); + + const frameInterval = useMemo( + () => Math.max(1, Math.round(30 / frameProcessorFps)), + [frameProcessorFps] + ); const focus = useCallback( (point: { x: number; y: number }) => { if (typeof ref === 'function' || !ref?.current) return; - ref.current.focus(point); + ref.current.focusTo(point).catch((error: Error) => { + // A new focus request cancels any still-settling previous one - + // this is expected whenever the user taps again quickly. + if (error.message.includes('canceled')) return; + console.error(error); + }); setFocusPoint(point); scale.value = 0; @@ -124,62 +197,87 @@ const CameraView = forwardRef( scheduleOnRN(flipCamera); }); + const pinchGesture = Gesture.Pinch() + .onStart(() => { + savedZoom.value = zoom.value; + }) + .onUpdate((event) => { + if (!device) return; + const nextZoom = savedZoom.value * event.scale; + zoom.value = Math.min( + Math.max(nextZoom, device.minZoom), + device.maxZoom + ); + }); + const gestures = []; if (enableDoubleTapGesture) gestures.push(doubleTapGesture); if (enableTapGesture) gestures.push(tapGesture); - const gesture = + const tapGestureComposition = gestures.length > 0 ? Gesture.Exclusive(...gestures) : Gesture.Tap(); + const gesture = enableZoomGesture + ? Gesture.Simultaneous(pinchGesture, tapGestureComposition) + : tapGestureComposition; + const focusOverlayStyle = useAnimatedStyle(() => ({ opacity: opacity.value, transform: [{ scale: scale.value }], })); - const handleResultWorklet = useRunOnJS((data: unknown) => { + const addResult = useCallback((data: unknown) => { console.log(data); useTerminalStore .getState() .addEntry(normalizeResultObject(data), 'camera'); }, []); - const frameProcessor = useFrameProcessor( - (frame) => { + const frameOutput = useFrameOutput({ + targetResolution: CommonResolutions.VGA_16_9, + pixelFormat, + onFrame(frame) { 'worklet'; - runAtTargetFps(frameProcessorFps, () => { - 'worklet'; + frameArrivalCount.value += 1; - runAsync(frame, () => { - 'worklet'; + if (!isFrameProcessorEnabled) { + frame.dispose(); + return; + } - let resultObject: any = null; + frameCount.value = (frameCount.value + 1) % frameInterval; + if (frameCount.value !== 0) { + frame.dispose(); + return; + } - if (pluginId === PLUGIN_ID.TEXT_RECOGNITION) { - const withArguments = { - outputOrientation: frameOutputOrientation.value, - }; + try { + let resultObject: any = null; + const withArguments = { + outputOrientation: frameOutputOrientation.value, + }; - resultObject = textRecognitionPlugin.textRecognition( - frame, - withArguments - ); - } + if (pluginId === PLUGIN_ID.TEXT_RECOGNITION) { + resultObject = textRecognitionPlugin.textRecognition( + frame, + withArguments + ); + } else if (pluginId === PLUGIN_ID.BARCODE_SCANNING) { + resultObject = barcodeScanningPlugin.barcodeScanning( + frame, + withArguments + ); + } - if (resultObject) { - handleResultWorklet(resultObject); - } - }); - }); + if (resultObject) { + scheduleOnRN(addResult, resultObject); + } + } finally { + frame.dispose(); + } }, - [ - frameProcessorFps, - pluginId, - frameOutputOrientation, - textRecognitionPlugin, - handleResultWorklet, - ] - ); + }); return ( @@ -188,23 +286,26 @@ const CameraView = forwardRef( accessibilityLabel="Camera viewfinder" accessibilityHint="Tap to focus, double tap to flip camera" > - {focusPoint && ( ( ]} /> )} + {isFpsGraphEnabled && ( + + )} + {sharedOptions.roi && } ); diff --git a/example/src/components/views/FpsGraphOverlay.tsx b/example/src/components/views/FpsGraphOverlay.tsx new file mode 100644 index 0000000..cd9fc8f --- /dev/null +++ b/example/src/components/views/FpsGraphOverlay.tsx @@ -0,0 +1,66 @@ +import { StyleSheet, Text, View } from 'react-native'; +import { useTheme } from '../../providers/ThemeProvider'; + +type FpsGraphOverlayProps = { + fps: number; + history: number[]; + maxFps: number; +}; + +const FpsGraphOverlay = ({ fps, history, maxFps }: FpsGraphOverlayProps) => { + const { theme } = useTheme(); + + return ( + + + {fps} FPS + + + {history.map((sample, index) => ( + + ))} + + + ); +}; + +const styles = StyleSheet.create({ + container: { + position: 'absolute', + top: 12, + left: 12, + borderRadius: 8, + paddingHorizontal: 8, + paddingVertical: 6, + opacity: 0.9, + }, + label: { + fontSize: 12, + fontWeight: '600', + marginBottom: 4, + }, + bars: { + flexDirection: 'row', + alignItems: 'flex-end', + height: 28, + gap: 2, + }, + bar: { + width: 3, + borderRadius: 1, + }, +}); + +export { FpsGraphOverlay }; diff --git a/example/src/components/views/ROIOverlay.tsx b/example/src/components/views/ROIOverlay.tsx new file mode 100644 index 0000000..0617d2c --- /dev/null +++ b/example/src/components/views/ROIOverlay.tsx @@ -0,0 +1,41 @@ +import { StyleSheet, View } from 'react-native'; +import type { RegionOfInterest } from 'react-native-vision-camera-mlkit'; +import { useTheme } from '../../providers/ThemeProvider'; + +type ROIOverlayProps = { + roi: RegionOfInterest; +}; + +const ROIOverlay = ({ roi }: ROIOverlayProps) => { + const { theme } = useTheme(); + + if (roi.unit === 'pixel') return null; + + return ( + + ); +}; + +const styles = StyleSheet.create({ + rect: { + position: 'absolute', + borderWidth: 2, + borderStyle: 'dashed', + borderRadius: 4, + }, +}); + +export { ROIOverlay }; diff --git a/example/src/components/views/TerminalBottomSheet.tsx b/example/src/components/views/TerminalBottomSheet.tsx index 5c7a2a4..65a1de0 100644 --- a/example/src/components/views/TerminalBottomSheet.tsx +++ b/example/src/components/views/TerminalBottomSheet.tsx @@ -1,12 +1,12 @@ -import { BottomSheetFlatList, BottomSheetModal } from '@gorhom/bottom-sheet'; +import { ModalBottomSheet } from '@swmansion/react-native-bottom-sheet'; +import { useCallback, useMemo, useState } from 'react'; import { - forwardRef, - useCallback, - useMemo, - useState, - type ComponentProps, -} from 'react'; -import { Pressable, StyleSheet, View } from 'react-native'; + FlatList, + Pressable, + StyleSheet, + useWindowDimensions, + View, +} from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useTheme } from '../../providers/ThemeProvider'; import { @@ -15,31 +15,30 @@ import { } from '../../stores/terminalStore'; import { TerminalEntryRow, Text } from '../ui'; -type Optional = Omit & Partial>; +type TerminalBottomSheetProps = { + index: number; + onIndexChange: (index: number) => void; +}; -type TerminalBottomSheetProps = Optional< - ComponentProps, - 'children' ->; - -const TerminalBottomSheet = forwardRef< - BottomSheetModal, - TerminalBottomSheetProps ->((props, ref) => { +const TerminalBottomSheet = ({ + index, + onIndexChange, +}: TerminalBottomSheetProps) => { const { theme } = useTheme(); const insets = useSafeAreaInsets(); + const { width: windowWidth, height: windowHeight } = useWindowDimensions(); const entries = useTerminalStore((state) => state.entries); const clear = useTerminalStore((state) => state.clear); const [wrapLines, setWrapLines] = useState(true); - const snapPoints = useMemo(() => ['25%', '60%', '90%'], []); + const detents = useMemo( + () => [0, windowHeight * 0.25, windowHeight * 0.6, windowHeight * 0.9], + [windowHeight] + ); - const handleClose = useCallback(() => { - if (!ref || typeof ref === 'function') return; - ref.current?.dismiss(); - }, [ref]); + const handleClose = useCallback(() => onIndexChange(0), [onIndexChange]); const renderItem = useCallback( ({ item }: { item: TerminalEntry }) => ( @@ -64,17 +63,38 @@ const TerminalBottomSheet = forwardRef< [] ); + const surface = useMemo( + () => ( + + ), + [theme.colors.surface] + ); + return ( - + + + - item.id} renderItem={renderItem} @@ -121,9 +141,9 @@ const TerminalBottomSheet = forwardRef< maxToRenderPerBatch={8} ItemSeparatorComponent={ItemSeparatorComponent} /> - + ); -}); +}; const styles = StyleSheet.create({ header: { @@ -150,10 +170,21 @@ const styles = StyleSheet.create({ paddingHorizontal: 16, paddingTop: 12, }, - modalContainer: { + surface: { + borderRadius: 15, + }, + sheetHost: { zIndex: 10, elevation: 10, }, + handleContainer: { + alignItems: 'center', + paddingVertical: 10, + }, + handleIndicator: { + height: 4, + borderRadius: 4, + }, itemSeparator: { height: 12, }, @@ -163,6 +194,4 @@ const styles = StyleSheet.create({ }, }); -TerminalBottomSheet.displayName = 'TerminalBottomSheet'; - export { TerminalBottomSheet }; diff --git a/example/src/components/views/index.ts b/example/src/components/views/index.ts index 576ceff..d473728 100644 --- a/example/src/components/views/index.ts +++ b/example/src/components/views/index.ts @@ -1,7 +1,9 @@ export { CameraView } from './CameraView'; +export { FpsGraphOverlay } from './FpsGraphOverlay'; export { HeaderView } from './HeaderView'; export { NoCameraPermissionErrorView } from './NoCameraPermissionErrorView'; export { NoDeviceErrorView } from './NoDeviceErrorView'; export { NoPluginErrorView } from './NoPluginErrorView'; export { PortalSegmentedToggle } from './PortalSegmentedToggle'; +export { ROIOverlay } from './ROIOverlay'; export { TerminalBottomSheet } from './TerminalBottomSheet'; diff --git a/example/src/providers/TerminalProvider.tsx b/example/src/providers/TerminalProvider.tsx index 993ceba..4e42b32 100644 --- a/example/src/providers/TerminalProvider.tsx +++ b/example/src/providers/TerminalProvider.tsx @@ -1,19 +1,20 @@ -import type { SNAP_POINT_TYPE } from '@gorhom/bottom-sheet'; -import { BottomSheetModal } from '@gorhom/bottom-sheet'; import type { ReactNode } from 'react'; import { createContext, useCallback, useContext, useMemo, - useRef, useState, } from 'react'; import { TerminalBottomSheet } from '../components/views'; +const CLOSED_INDEX = 0; +const OPEN_INDEX = 1; + type TerminalContextType = { open: () => void; close: () => void; + toggle: () => void; isOpen: boolean; }; @@ -24,29 +25,25 @@ type TerminalProviderProps = { }; export const TerminalProvider = ({ children }: TerminalProviderProps) => { - const modalRef = useRef(null); - - const [isOpen, setIsOpen] = useState(false); + const [index, setIndex] = useState(CLOSED_INDEX); - const handleChange = useCallback( - (index: number, _position: number, _type: SNAP_POINT_TYPE) => - setIsOpen(index >= 0), + const open = useCallback(() => setIndex(OPEN_INDEX), []); + const close = useCallback(() => setIndex(CLOSED_INDEX), []); + const toggle = useCallback( + () => + setIndex((prev) => (prev === CLOSED_INDEX ? OPEN_INDEX : CLOSED_INDEX)), [] ); const value = useMemo( - () => ({ - open: () => modalRef.current?.present(), - close: () => modalRef.current?.dismiss(), - isOpen, - }), - [isOpen] + () => ({ open, close, toggle, isOpen: index > CLOSED_INDEX }), + [open, close, toggle, index] ); return ( {children} - + ); }; diff --git a/example/src/screens/CameraScreen.tsx b/example/src/screens/CameraScreen.tsx index 3c18f50..f287c26 100644 --- a/example/src/screens/CameraScreen.tsx +++ b/example/src/screens/CameraScreen.tsx @@ -1,5 +1,6 @@ import { StackActions, + useFocusEffect, useIsFocused, useNavigation, useRoute, @@ -9,12 +10,11 @@ import { import { useCallback, useEffect, useRef, useState } from 'react'; import { useSharedValue } from 'react-native-reanimated'; import { + type CameraRef, useCameraDevice, useCameraPermission, - type Camera, - type Orientation, } from 'react-native-vision-camera'; -import { useSharedValue as useWorkletsSharedValue } from 'react-native-worklets-core'; +import type { Orientation } from 'react-native-vision-camera-mlkit'; import { CameraControls } from '../components/ui'; import { CameraView, @@ -38,16 +38,14 @@ const DEFAULT_ORIENTATION: Orientation = 'portrait'; const CameraScreen = () => { const navigation = useNavigation>(); const { params, name } = useRoute>(); - const { open: openTerminal } = useTerminal(); + const { toggle: toggleTerminal, close: closeTerminal } = useTerminal(); - const cameraRef = useRef(null); + const cameraRef = useRef(null); const [cameraPosition, setCameraPosition] = useState('back'); const [torchState, setTorchState] = useState('off'); const [isFpsGraphEnabled, setIsFpsGraphEnabled] = useState(false); - const frameOutputOrientation = - useWorkletsSharedValue(DEFAULT_ORIENTATION); const outputOrientation = useSharedValue(DEFAULT_ORIENTATION); const { isFrameProcessorEnabled } = useSettingsStore(); @@ -62,14 +60,6 @@ const CameraScreen = () => { const isActive = isFocused && appState === 'active'; - const onOutputOrientationChangedCallback = useCallback( - (o: Orientation) => { - outputOrientation.value = o; - frameOutputOrientation.value = o; - }, - [outputOrientation, frameOutputOrientation] - ); - const flipCamera = () => setCameraPosition((prev) => (prev === 'back' ? 'front' : 'back')); @@ -87,6 +77,12 @@ const CameraScreen = () => { !hasCameraPermission && requestCameraPermission(); }, [hasCameraPermission, requestCameraPermission]); + useFocusEffect( + useCallback(() => { + return () => closeTerminal(); + }, [closeTerminal]) + ); + if (!hasCameraPermission) return ; if (!device) return ; if (!isPluginId(params.id)) return ; @@ -100,17 +96,16 @@ const CameraScreen = () => { pluginId={params.id} flipCamera={flipCamera} isFrameProcessorEnabled={isFrameProcessorEnabled} - frameOutputOrientation={frameOutputOrientation} - onOutputOrientationChangedCallback={onOutputOrientationChangedCallback} - torch={torchState} - enableFpsGraph={isFpsGraphEnabled} + frameOutputOrientation={outputOrientation} + torchMode={torchState} + isFpsGraphEnabled={isFpsGraphEnabled} /> diff --git a/example/src/screens/HomeScreen.tsx b/example/src/screens/HomeScreen.tsx index 183503c..1c13927 100644 --- a/example/src/screens/HomeScreen.tsx +++ b/example/src/screens/HomeScreen.tsx @@ -91,7 +91,7 @@ const BASE_DATA: Array> = [ isBeta: false, android: true, ios: true, - status: 'in-progress', + status: 'complete', }, { id: PLUGIN_ID.IMAGE_LABELING, @@ -155,12 +155,23 @@ const HomeScreen = () => { const deferredSearchQuery = useDeferredValue(searchQuery); const filteredData = useMemo(() => { + const sortedData = [...data].sort((left, right) => { + const leftIsComplete = left.status === 'complete'; + const rightIsComplete = right.status === 'complete'; + + if (leftIsComplete === rightIsComplete) { + return 0; + } + + return leftIsComplete ? -1 : 1; + }); + if (!deferredSearchQuery.trim()) { - return data; + return sortedData; } const query = deferredSearchQuery.toLowerCase(); - return data.filter( + return sortedData.filter( (item) => item.title.toLowerCase().includes(query) || item.description?.toLowerCase().includes(query) diff --git a/example/src/screens/ImageScreen.tsx b/example/src/screens/ImageScreen.tsx index 07a88cd..f8c0629 100644 --- a/example/src/screens/ImageScreen.tsx +++ b/example/src/screens/ImageScreen.tsx @@ -1,17 +1,22 @@ import { StackActions, + useFocusEffect, useNavigation, useRoute, type NavigationProp, type RouteProp, } from '@react-navigation/native'; -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { Image, ScrollView, StyleSheet, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { processImageTextRecognition } from 'react-native-vision-camera-mlkit'; +import { + processImageBarcodeScanning, + processImageTextRecognition, +} from 'react-native-vision-camera-mlkit'; import { Button, Divider, + RegionOfInterestControl, Section, SectionImageInput, SectionPicker, @@ -29,16 +34,23 @@ import { useImageProcessingOptionsStore, useTerminalStore } from '../stores'; const IMAGE_PROCESSOR_MAP = { [PLUGIN_ID.TEXT_RECOGNITION]: processImageTextRecognition, + [PLUGIN_ID.BARCODE_SCANNING]: processImageBarcodeScanning, } as const; const ImageScreen = () => { const { theme } = useTheme(); const insets = useSafeAreaInsets(); - const { open: openTerminal } = useTerminal(); + const { open: openTerminal, close: closeTerminal } = useTerminal(); const addEntry = useTerminalStore((state) => state.addEntry); + useFocusEffect( + useCallback(() => { + return () => closeTerminal(); + }, [closeTerminal]) + ); + const BOTTOM_OFFSET = insets.bottom + 46; const navigation = useNavigation>(); @@ -168,22 +180,29 @@ const ImageScreen = () => { /> setSharedOption('orientation', value)} + onValueChange={(value) => + setSharedOption( + 'orientation', + value === 'auto' ? undefined : value + ) + } /> {pluginId === PLUGIN_ID.TEXT_RECOGNITION && ( { } /> )} + setSharedOption('roi', roi)} + /> + {pluginId === PLUGIN_ID.BARCODE_SCANNING && ( + <> + + setImageProcessingOption( + PLUGIN_ID.BARCODE_SCANNING, + 'enableAllPotentialBarcodes', + value + ) + } + /> + + setImageProcessingOption( + PLUGIN_ID.BARCODE_SCANNING, + 'formats', + value === 'ALL_FORMATS' ? [] : [value as any] + ) + } + /> + + )} { setEnableTapGesture, enableDoubleTapGesture, setEnableDoubleTapGesture, + exposureBias, + setExposureBias, + enableLowLightBoost, + setEnableLowLightBoost, + targetFps, + setTargetFps, + videoStabilizationMode, + setVideoStabilizationMode, + orientationSource, + setOrientationSource, } = useSettingsStore(); const { sharedOptions, pluginOptions, setSharedOption, setPluginOption } = @@ -46,8 +57,8 @@ const SettingsScreen = () => { onValueChange={setFrameProcessorEnabled} /> { value={Boolean(sharedOptions.invertColors)} onValueChange={(value) => setSharedOption('invertColors', value)} /> - - setSharedOption('frameProcessInterval', Number(value)) - } - /> { { } /> )} + {pluginId === PLUGIN_ID.BARCODE_SCANNING && ( + <> + + setPluginOption( + PLUGIN_ID.BARCODE_SCANNING, + 'enableAllPotentialBarcodes', + value + ) + } + /> + + setPluginOption( + PLUGIN_ID.BARCODE_SCANNING, + 'formats', + value === 'ALL_FORMATS' ? [] : [value as any] + ) + } + /> + + )}
@@ -126,6 +175,67 @@ const SettingsScreen = () => { ]} onValueChange={setPixelFormat} /> + + + setTargetFps(Number(value))} + /> + + setVideoStabilizationMode(value as typeof videoStabilizationMode) + } + /> + + setOrientationSource(value as typeof orientationSource) + } + /> { onValueChange={setEnableDoubleTapGesture} />
+ +
+ setSharedOption('roi', roi)} + /> +
); }; diff --git a/example/src/stores/imageProcessingOptionsStore.ts b/example/src/stores/imageProcessingOptionsStore.ts index 0fbc4e6..7150ac2 100644 --- a/example/src/stores/imageProcessingOptionsStore.ts +++ b/example/src/stores/imageProcessingOptionsStore.ts @@ -1,16 +1,17 @@ import type { + BarcodeScanningImageOptions, ImageProcessingBaseOptions as SharedImageProcessingOptions, - TextRecognitionLanguage, + TextRecognitionImageOptions, } from 'react-native-vision-camera-mlkit'; import { create } from 'zustand'; import { PLUGIN_ID } from '../constants/PLUGINS'; -type TextRecognitionOptions = { - language: TextRecognitionLanguage; -}; - type SpecificImageProcessingOptions = { - [PLUGIN_ID.TEXT_RECOGNITION]: TextRecognitionOptions; + [PLUGIN_ID.TEXT_RECOGNITION]: Pick; + [PLUGIN_ID.BARCODE_SCANNING]: Pick< + BarcodeScanningImageOptions, + 'formats' | 'enableAllPotentialBarcodes' + >; }; type ImageProcessingOptionsState = { @@ -34,12 +35,16 @@ export const useImageProcessingOptionsStore = create((set) => ({ sharedOptions: { invertColors: false, - orientation: 'portrait', + orientation: undefined, }, imageProcessingOptions: { [PLUGIN_ID.TEXT_RECOGNITION]: { language: 'LATIN', }, + [PLUGIN_ID.BARCODE_SCANNING]: { + formats: [], + enableAllPotentialBarcodes: false, + }, }, setSharedOption: (key, value) => set((state) => ({ diff --git a/example/src/stores/pluginOptionsStore.ts b/example/src/stores/pluginOptionsStore.ts index eb3bb39..ab5c4e9 100644 --- a/example/src/stores/pluginOptionsStore.ts +++ b/example/src/stores/pluginOptionsStore.ts @@ -1,16 +1,17 @@ import type { + BarcodeScanningOptions, MLKitBaseOptions as SharedPluginOptions, - TextRecognitionLanguage, + TextRecognitionOptions, } from 'react-native-vision-camera-mlkit'; import { create } from 'zustand'; import { PLUGIN_ID } from '../constants/PLUGINS'; -type TextRecognitionOptions = { - language: TextRecognitionLanguage; -}; - type SpecificPluginOptions = { - [PLUGIN_ID.TEXT_RECOGNITION]: TextRecognitionOptions; + [PLUGIN_ID.TEXT_RECOGNITION]: Pick; + [PLUGIN_ID.BARCODE_SCANNING]: Pick< + BarcodeScanningOptions, + 'formats' | 'enableAllPotentialBarcodes' + >; }; type PluginOptionsState = { @@ -40,6 +41,10 @@ export const usePluginOptionsStore = create((set) => ({ [PLUGIN_ID.TEXT_RECOGNITION]: { language: 'LATIN', }, + [PLUGIN_ID.BARCODE_SCANNING]: { + formats: [], + enableAllPotentialBarcodes: false, + }, }, setSharedOption: (key, value) => set((state) => ({ diff --git a/example/src/stores/settingsStore.ts b/example/src/stores/settingsStore.ts index 2e9b0b8..c67c13c 100644 --- a/example/src/stores/settingsStore.ts +++ b/example/src/stores/settingsStore.ts @@ -1,3 +1,7 @@ +import type { + OrientationSource, + TargetStabilizationMode, +} from 'react-native-vision-camera'; import { create } from 'zustand'; type PixelFormat = 'yuv' | 'rgb'; @@ -15,6 +19,16 @@ type SettingsState = { setEnableTapGesture: (enabled: boolean) => void; enableDoubleTapGesture: boolean; setEnableDoubleTapGesture: (enabled: boolean) => void; + exposureBias: number; + setExposureBias: (bias: number) => void; + enableLowLightBoost: boolean; + setEnableLowLightBoost: (enabled: boolean) => void; + targetFps: number; + setTargetFps: (fps: number) => void; + videoStabilizationMode: TargetStabilizationMode; + setVideoStabilizationMode: (mode: TargetStabilizationMode) => void; + orientationSource: OrientationSource; + setOrientationSource: (source: OrientationSource) => void; }; export const useSettingsStore = create((set) => ({ @@ -33,4 +47,17 @@ export const useSettingsStore = create((set) => ({ enableDoubleTapGesture: true, setEnableDoubleTapGesture: (enabled: boolean) => set({ enableDoubleTapGesture: enabled }), + exposureBias: 0, + setExposureBias: (bias: number) => set({ exposureBias: bias }), + enableLowLightBoost: false, + setEnableLowLightBoost: (enabled: boolean) => + set({ enableLowLightBoost: enabled }), + targetFps: 30, + setTargetFps: (fps: number) => set({ targetFps: fps }), + videoStabilizationMode: 'auto', + setVideoStabilizationMode: (mode: TargetStabilizationMode) => + set({ videoStabilizationMode: mode }), + orientationSource: 'device', + setOrientationSource: (source: OrientationSource) => + set({ orientationSource: source }), })); diff --git a/ios/Application/UseCases/RecognizeTextUseCase.swift b/ios/Application/UseCases/RecognizeTextUseCase.swift deleted file mode 100644 index 6be6323..0000000 --- a/ios/Application/UseCases/RecognizeTextUseCase.swift +++ /dev/null @@ -1,69 +0,0 @@ -import Foundation -import VisionCamera - -class RecognizeTextUseCase { - private let imagePreprocessor: IImagePreprocessor - private let recognitionService: MLKitTextRecognitionService - - init( - imagePreprocessor: IImagePreprocessor, - recognitionService: MLKitTextRecognitionService - ) { - self.imagePreprocessor = imagePreprocessor - self.recognitionService = recognitionService - } - - func execute(frame: Frame, options: TextRecognitionOptions) throws - -> TextRecognitionResult - { - // autoreleasepool at frame boundary to drain autoreleased Obj-C objects - // after each frame is processed, preventing buildup across multiple frames - return try autoreleasepool { - let preprocessingOptions = ImagePreprocessingOptions( - invertColors: options.invertColors, - outputOrientation: options.outputOrientation, - scaleFactor: options.scaleFactor - ) - - guard - let processedImage = imagePreprocessor.preprocessFrame( - frame: frame, - options: preprocessingOptions - ) - else { - throw NSError( - domain: "RecognizeTextUseCase", - code: -1, - userInfo: [NSLocalizedDescriptionKey: "Failed to preprocess image"] - ) - } - - return try recognitionService.recognize(image: processedImage) - } - } - - func execute( - imageFile: URL, - imageOptions: ImagePreprocessingOptions, - textOptions: TextRecognitionOptions - ) throws -> TextRecognitionResult { - // autoreleasepool here ensures predictable memory cleanup, - // especially if this method is called repeatedly or in batches - return try autoreleasepool { - guard - let processedImage = imagePreprocessor.preprocessImage( - imageFile: imageFile, - options: imageOptions - ) - else { - throw NSError( - domain: "RecognizeTextUseCase", - code: -1, - userInfo: [NSLocalizedDescriptionKey: "Failed to preprocess image"] - ) - } - - return try recognitionService.recognize(image: processedImage) - } - } -} diff --git a/ios/Bridge/Constants/MLKitFeatureKeys.swift b/ios/Bridge/Constants/MLKitFeatureKeys.swift deleted file mode 100644 index 912f061..0000000 --- a/ios/Bridge/Constants/MLKitFeatureKeys.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Foundation - -enum MLKitFeatureKeys { - static let TEXT_RECOGNITION = "TextRecognition" - static let FACE_DETECTION = "FaceDetection" - static let FACE_MESH_DETECTION = "FaceMeshDetection" - static let POSE_DETECTION = "PoseDetection" - static let SELFIE_SEGMENTATION = "SelfieSegmentation" - static let SUBJECT_SEGMENTATION = "SubjectSegmentation" - static let DOCUMENT_SCANNER = "DocumentScanner" - static let BARCODE_SCANNING = "BarcodeScanning" - static let IMAGE_LABELING = "ImageLabeling" - static let OBJECT_DETECTION = "ObjectDetection" - static let DIGITAL_INK_RECOGNITION = "DigitalInkRecognition" -} diff --git a/ios/Bridge/Handlers/IStaticImageHandler.swift b/ios/Bridge/Handlers/IStaticImageHandler.swift deleted file mode 100644 index de5ee0d..0000000 --- a/ios/Bridge/Handlers/IStaticImageHandler.swift +++ /dev/null @@ -1,13 +0,0 @@ -import Foundation - -typealias PromiseResolver = (Any?) -> Void -typealias PromiseRejecter = (String, String, Error?) -> Void - -protocol IStaticImageHandler { - func process( - path: String, - options: [String: Any], - resolver: @escaping PromiseResolver, - rejecter: @escaping PromiseRejecter - ) -} diff --git a/ios/Bridge/Handlers/StaticTextRecognitionHandler.swift b/ios/Bridge/Handlers/StaticTextRecognitionHandler.swift deleted file mode 100644 index b646a9a..0000000 --- a/ios/Bridge/Handlers/StaticTextRecognitionHandler.swift +++ /dev/null @@ -1,157 +0,0 @@ -import Foundation - -class StaticTextRecognitionHandler: IStaticImageHandler { - private let textRecognitionSerializer = TextRecognitionSerializer() - private var cachedUseCase: RecognizeTextUseCase? - - private func getRecognizeTextUseCase(for language: TextRecognitionLanguage) - -> RecognizeTextUseCase - { - if let useCase = cachedUseCase { - return useCase - } - let newUseCase = RecognizeTextUseCase( - imagePreprocessor: ImagePreprocessor(), - recognitionService: TextRecognitionServiceFactory.create( - language: language - ) - ) - cachedUseCase = newUseCase - return newUseCase - } - - func process( - path: String, - options: [String: Any], - resolver: @escaping PromiseResolver, - rejecter: @escaping PromiseRejecter - ) { - Task { - do { - guard let fileURL = resolveFileURL(from: path) else { - rejecter( - "IMAGE_NOT_FOUND_ERROR", - "Unsupported image URI: \(path)", - nil - ) - return - } - - // Check if file exists - if fileURL.isFileURL - && !FileManager.default.fileExists(atPath: fileURL.path) - { - rejecter( - "IMAGE_NOT_FOUND_ERROR", - "Image file not found at path: \(path)", - nil - ) - return - } - - // Parse options - let imageOptions = parseImageOptions(options) - - // Create text recognition options - let languageString = options["language"] as? String ?? "LATIN" - let language = parseLanguage(languageString) - let textOptions = TextRecognitionOptions(language: language) - - // Get use case for the language - let recognizeTextUseCase = getRecognizeTextUseCase(for: language) - - // Process the image - let result = try recognizeTextUseCase.execute( - imageFile: fileURL, - imageOptions: imageOptions, - textOptions: textOptions - ) - - // Serialize result - let serializedResult = TextRecognitionSerializer.toReactNativeMap( - result - ) - - resolver(serializedResult) - } catch { - switch error { - case let nsError as NSError: - if nsError.domain == NSCocoaErrorDomain - && nsError.code == NSFileReadNoSuchFileError - { - rejecter("IMAGE_NOT_FOUND_ERROR", "Image file not found", error) - } else { - rejecter( - "IMAGE_PROCESSING_FAILED_ERROR", - error.localizedDescription, - error - ) - } - default: - rejecter( - "IMAGE_PROCESSING_FAILED_ERROR", - error.localizedDescription, - error - ) - } - } - } - } - - private func parseImageOptions(_ options: [String: Any]) - -> ImagePreprocessingOptions - { - let invertColors = options["invertColors"] as? Bool ?? false - let orientationString = options["orientation"] as? String ?? "portrait" - let orientation = parseOrientation(orientationString) - - return ImagePreprocessingOptions( - invertColors: invertColors, - orientation: orientation - ) - } - - private func parseOrientation(_ orientation: String) -> Orientation { - switch orientation { - case "portrait": - return .portrait - case "portrait-upside-down": - return .portraitUpsideDown - case "landscape-left": - return .landscapeLeft - case "landscape-right": - return .landscapeRight - default: - return .portrait - } - } - - private func parseLanguage(_ language: String) -> TextRecognitionLanguage { - switch language { - case "LATIN": - return .latin - case "CHINESE": - return .chinese - case "DEVANAGARI": - return .devanagari - case "JAPANESE": - return .japanese - case "KOREAN": - return .korean - default: - return .latin - } - } - - private func resolveFileURL(from path: String) -> URL? { - if path.hasPrefix("file://") { - return URL(string: path) - } - - if let url = URL(string: path), url.scheme != nil { - return url - } - - return URL(fileURLWithPath: path) - } -} diff --git a/ios/Bridge/Hybrid/BarcodeFormat+toDomain.swift b/ios/Bridge/Hybrid/BarcodeFormat+toDomain.swift new file mode 100644 index 0000000..3daeedc --- /dev/null +++ b/ios/Bridge/Hybrid/BarcodeFormat+toDomain.swift @@ -0,0 +1,5 @@ +extension BarcodeFormat { + func toDomainBarcodeFormat() -> BarcodeFormatOption { + return BarcodeFormatOption(rawValue: stringValue) ?? .formatUnknown + } +} diff --git a/ios/Bridge/Hybrid/BarcodeParsedValue+toAnyMap.swift b/ios/Bridge/Hybrid/BarcodeParsedValue+toAnyMap.swift new file mode 100644 index 0000000..ed3ec08 --- /dev/null +++ b/ios/Bridge/Hybrid/BarcodeParsedValue+toAnyMap.swift @@ -0,0 +1,34 @@ +import Foundation +import NitroModules + +#if MLKIT_BARCODE_SCANNING + extension BarcodeParsedValue { + func toAnyMap() throws -> AnyMap { + let map = AnyMap(withPreallocatedSize: 2) + map.setString(key: "type", value: type) + map.setObject(key: "data", value: try data.mapValues { try toAnyValue($0) }) + return map + } + } + + private func toAnyValue(_ value: Any?) throws -> AnyValue { + switch value { + case nil, is NSNull: + return .null + case let value as Bool: + return .bool(value) + case let value as String: + return .string(value) + case let value as NSNumber: + return .number(value.doubleValue) + case let value as [Any?]: + return .array(try value.map { try toAnyValue($0) }) + case let value as [String: Any?]: + return .object(try value.mapValues { try toAnyValue($0) }) + default: + throw RuntimeError.error( + withMessage: "Barcode value contains an unsupported value: \(String(describing: value))" + ) + } + } +#endif diff --git a/ios/Bridge/Hybrid/BarcodeScannerOptions+toDomain.swift b/ios/Bridge/Hybrid/BarcodeScannerOptions+toDomain.swift new file mode 100644 index 0000000..f7f174f --- /dev/null +++ b/ios/Bridge/Hybrid/BarcodeScannerOptions+toDomain.swift @@ -0,0 +1,21 @@ +import Foundation + +extension BarcodeScannerOptions { + func toDomainBarcodeScanningOptions() -> BarcodeScanningOptions { + return BarcodeScanningOptions( + formats: formats?.map { $0.toDomainBarcodeFormat() } ?? [], + enableAllPotentialBarcodes: enableAllPotentialBarcodes ?? false, + invertColors: invertColors ?? false, + scaleFactor: CGFloat(scaleFactor ?? 1.0) + ) + } + + func toImagePreprocessingOptions() -> ImagePreprocessingOptions { + return ImagePreprocessingOptions( + invertColors: invertColors ?? false, + scaleFactor: CGFloat(scaleFactor ?? 1.0), + orientation: orientation?.toDomainOrientation(), + roi: roi?.toDomainRegionOfInterest() + ) + } +} diff --git a/ios/Bridge/Hybrid/BarcodeScanningResult+toNitro.swift b/ios/Bridge/Hybrid/BarcodeScanningResult+toNitro.swift new file mode 100644 index 0000000..40fe015 --- /dev/null +++ b/ios/Bridge/Hybrid/BarcodeScanningResult+toNitro.swift @@ -0,0 +1,27 @@ +#if MLKIT_BARCODE_SCANNING + extension BarcodeScanningResult { + func toNitroResult() throws -> BarcodeScannerResult { + return BarcodeScannerResult( + barcodes: try barcodes.map { try $0.toNitroBarcode() } + ) + } + } + + extension BarcodeData { + fileprivate func toNitroBarcode() throws -> BarcodeScannerBarcode { + return BarcodeScannerBarcode( + bounds: bounds?.toNitroBoundingBox(), + corners: corners?.map { $0.toNitroCorner() }, + format: Double(format), + formatName: BarcodeFormat(fromString: formatName) ?? .unknown, + valueType: Double(valueType), + valueTypeName: BarcodeValueTypeName(fromString: valueTypeName) ?? .typeUnknown, + rawValue: rawValue, + displayValue: displayValue, + rawBytes: rawBytes?.map { Double($0) }, + value: try value?.toAnyMap(), + isPotential: isPotential + ) + } + } +#endif diff --git a/ios/Bridge/Hybrid/CameraOrientation+asUIImageOrientation.swift b/ios/Bridge/Hybrid/CameraOrientation+asUIImageOrientation.swift new file mode 100644 index 0000000..3f02335 --- /dev/null +++ b/ios/Bridge/Hybrid/CameraOrientation+asUIImageOrientation.swift @@ -0,0 +1,17 @@ +import UIKit +import VisionCamera + +extension CameraOrientation { + var asUIImageOrientation: UIImage.Orientation { + switch self { + case .up: + return .up + case .right: + return .right + case .down: + return .down + case .left: + return .left + } + } +} diff --git a/ios/Bridge/Hybrid/DomainBoundingBox+toNitro.swift b/ios/Bridge/Hybrid/DomainBoundingBox+toNitro.swift new file mode 100644 index 0000000..221b821 --- /dev/null +++ b/ios/Bridge/Hybrid/DomainBoundingBox+toNitro.swift @@ -0,0 +1,39 @@ +private let emptyNitroBoundingBox = BoundingBox( + x: 0.0, + y: 0.0, + centerX: 0.0, + centerY: 0.0, + width: 0.0, + height: 0.0, + top: 0.0, + left: 0.0, + bottom: 0.0, + right: 0.0 +) + +extension Optional where Wrapped == DomainBoundingBox { + func toNitroBoundingBox() -> BoundingBox { + guard let bounds = self else { + return emptyNitroBoundingBox + } + + return bounds.toNitroBoundingBox() + } +} + +extension DomainBoundingBox { + func toNitroBoundingBox() -> BoundingBox { + return BoundingBox( + x: x, + y: y, + centerX: centerX, + centerY: centerY, + width: width, + height: height, + top: top, + left: left, + bottom: bottom, + right: right + ) + } +} diff --git a/ios/Bridge/Hybrid/DomainCorner+toNitro.swift b/ios/Bridge/Hybrid/DomainCorner+toNitro.swift new file mode 100644 index 0000000..30d188e --- /dev/null +++ b/ios/Bridge/Hybrid/DomainCorner+toNitro.swift @@ -0,0 +1,11 @@ +extension DomainCorner { + func toNitroCorner() -> Corner { + return Corner(x: x, y: y) + } +} + +extension Optional where Wrapped == [DomainCorner] { + func toNitroCorners() -> [Corner] { + return self?.map { $0.toNitroCorner() } ?? [] + } +} diff --git a/ios/Bridge/Hybrid/DomainTextRecognitionResult+toNitro.swift b/ios/Bridge/Hybrid/DomainTextRecognitionResult+toNitro.swift new file mode 100644 index 0000000..9565af9 --- /dev/null +++ b/ios/Bridge/Hybrid/DomainTextRecognitionResult+toNitro.swift @@ -0,0 +1,61 @@ +extension DomainTextRecognitionResult { + func toNitroResult() -> TextRecognitionResult { + return TextRecognitionResult( + text: text ?? "", + blocks: blocks.map { $0.toNitroTextBlock() } + ) + } +} + +private extension DomainTextBlock { + func toNitroTextBlock() -> TextBlock { + return TextBlock( + bounds: bounds.toNitroBoundingBox(), + corners: corners.toNitroCorners(), + languages: languages, + text: text, + lines: lines.map { $0.toNitroTextLine() } + ) + } +} + +private extension DomainTextLine { + func toNitroTextLine() -> TextLine { + return TextLine( + bounds: bounds.toNitroBoundingBox(), + corners: corners.toNitroCorners(), + confidence: confidence.toNullableDoubleVariant(), + angle: angle.toNullableDoubleVariant(), + languages: languages, + text: text, + elements: elements.map { $0.toNitroTextElement() } + ) + } +} + +private extension DomainTextElement { + func toNitroTextElement() -> TextElement { + return TextElement( + bounds: bounds.toNitroBoundingBox(), + corners: corners.toNitroCorners(), + confidence: confidence.toNullableDoubleVariant(), + angle: angle.toNullableDoubleVariant(), + languages: languages, + text: text, + symbols: symbols.map { $0.toNitroTextSymbol() } + ) + } +} + +private extension DomainTextSymbol { + func toNitroTextSymbol() -> TextSymbol { + return TextSymbol( + bounds: bounds.toNitroBoundingBox(), + corners: corners.toNitroCorners(), + confidence: confidence ?? 0.0, + angle: angle ?? 0.0, + languages: languages, + text: text + ) + } +} diff --git a/ios/Bridge/Hybrid/Double+toNullableVariant.swift b/ios/Bridge/Hybrid/Double+toNullableVariant.swift new file mode 100644 index 0000000..28bbbda --- /dev/null +++ b/ios/Bridge/Hybrid/Double+toNullableVariant.swift @@ -0,0 +1,11 @@ +import NitroModules + +extension Optional where Wrapped == Double { + func toNullableDoubleVariant() -> Variant_NullType_Double { + guard let value = self else { + return .first(NullType.null) + } + + return .second(value) + } +} diff --git a/ios/Bridge/Hybrid/HybridBarcodeScanner.swift b/ios/Bridge/Hybrid/HybridBarcodeScanner.swift new file mode 100644 index 0000000..3dfb13c --- /dev/null +++ b/ios/Bridge/Hybrid/HybridBarcodeScanner.swift @@ -0,0 +1,81 @@ +import Foundation +import NitroModules +import VisionCamera + +final class HybridBarcodeScanner: HybridBarcodeScannerSpec { + private let options: BarcodeScannerOptions + private let recognitionQueue = DispatchQueue( + label: "com.visioncameramlkit.barcode-scanner" + ) + #if MLKIT_BARCODE_SCANNING + private let imagePreprocessor = ImagePreprocessor() + private let barcodeOptions: BarcodeScanningOptions + private let imageOptions: ImagePreprocessingOptions + private let recognitionService: MLKitBarcodeScanningService + private let staticRecognitionService: MLKitBarcodeScanningService + #endif + + init(options: BarcodeScannerOptions) { + self.options = options + #if MLKIT_BARCODE_SCANNING + let resolvedBarcodeOptions = options.toDomainBarcodeScanningOptions() + self.barcodeOptions = resolvedBarcodeOptions + self.imageOptions = options.toImagePreprocessingOptions() + self.recognitionService = BarcodeScanningServiceFactory.create( + options: resolvedBarcodeOptions + ) + self.staticRecognitionService = BarcodeScanningServiceFactory.create( + options: resolvedBarcodeOptions + ) + #endif + } + + func recognize(frame: any HybridFrameSpec, args: MLKitBaseArguments?) throws + -> BarcodeScannerResult + { + #if MLKIT_BARCODE_SCANNING + let callImageOptions = imageOptions.withOutputOrientation( + args?.outputOrientation?.toOutputOrientation() + ) + guard + let processedImage = imagePreprocessor.preprocessFrame( + frame: frame, + options: callImageOptions + ) + else { + throw RuntimeError.error(withMessage: "Failed to preprocess VisionCamera frame.") + } + + let result = try recognitionService.recognize(image: processedImage) + return try result.remapped(using: processedImage.metadata).toNitroResult() + #else + throw RuntimeError.error( + withMessage: "BarcodeScanning is not enabled in the native ML Kit configuration.") + #endif + } + + func recognizeImage(uri: String) throws -> Promise { + #if MLKIT_BARCODE_SCANNING + return Promise.parallel(recognitionQueue) { + let imageFile = try StaticImageURLResolver.resolve(uri) + guard + let processedImage = self.imagePreprocessor.preprocessImage( + imageFile: imageFile, + options: self.imageOptions + ) + else { + throw RuntimeError.error(withMessage: "Failed to preprocess static image: \(uri)") + } + + let result = try self.staticRecognitionService.recognize(image: processedImage) + return try result.remapped(using: processedImage.metadata).toNitroResult() + } + #else + return Promise.rejected( + withError: RuntimeError.error( + withMessage: "BarcodeScanning is not enabled in the native ML Kit configuration." + ) + ) + #endif + } +} diff --git a/ios/Bridge/Hybrid/HybridTextRecognizer.swift b/ios/Bridge/Hybrid/HybridTextRecognizer.swift new file mode 100644 index 0000000..d9b42b0 --- /dev/null +++ b/ios/Bridge/Hybrid/HybridTextRecognizer.swift @@ -0,0 +1,81 @@ +import Foundation +import NitroModules +import VisionCamera + +final class HybridTextRecognizer: HybridTextRecognizerSpec { + private let options: TextRecognizerOptions + private let recognitionQueue = DispatchQueue( + label: "com.visioncameramlkit.text-recognizer" + ) + #if MLKIT_TEXT_RECOGNITION_ANY + private let imagePreprocessor = ImagePreprocessor() + private let textOptions: TextRecognitionOptions + private let imageOptions: ImagePreprocessingOptions + private let recognitionService: MLKitTextRecognitionService + private let staticRecognitionService: MLKitTextRecognitionService + #endif + + init(options: TextRecognizerOptions) { + self.options = options + #if MLKIT_TEXT_RECOGNITION_ANY + let resolvedTextOptions = options.toDomainTextRecognitionOptions() + self.textOptions = resolvedTextOptions + self.imageOptions = options.toImagePreprocessingOptions() + self.recognitionService = TextRecognitionServiceFactory.create( + language: resolvedTextOptions.language + ) + self.staticRecognitionService = TextRecognitionServiceFactory.create( + language: resolvedTextOptions.language + ) + #endif + } + + func recognize(frame: any HybridFrameSpec, args: MLKitBaseArguments?) throws + -> TextRecognitionResult + { + #if MLKIT_TEXT_RECOGNITION_ANY + let callImageOptions = imageOptions.withOutputOrientation( + args?.outputOrientation?.toOutputOrientation() + ) + guard + let processedImage = imagePreprocessor.preprocessFrame( + frame: frame, + options: callImageOptions + ) + else { + throw RuntimeError.error(withMessage: "Failed to preprocess VisionCamera frame.") + } + + let result = try recognitionService.recognize(image: processedImage) + return result.remapped(using: processedImage.metadata).toNitroResult() + #else + throw RuntimeError.error( + withMessage: "TextRecognition is not enabled in the native ML Kit configuration.") + #endif + } + + func recognizeImage(uri: String) throws -> Promise { + #if MLKIT_TEXT_RECOGNITION_ANY + return Promise.parallel(recognitionQueue) { + let imageFile = try StaticImageURLResolver.resolve(uri) + guard + let processedImage = self.imagePreprocessor.preprocessImage( + imageFile: imageFile, + options: self.imageOptions + ) + else { + throw RuntimeError.error(withMessage: "Failed to preprocess static image: \(uri)") + } + + let result = try self.staticRecognitionService.recognize(image: processedImage) + return result.remapped(using: processedImage.metadata).toNitroResult() + } + #else + return Promise.rejected( + withError: RuntimeError.error( + withMessage: "TextRecognition is not enabled in the native ML Kit configuration." + ) + ) + #endif + } +} diff --git a/ios/Bridge/Hybrid/HybridVisionCameraMLKit.swift b/ios/Bridge/Hybrid/HybridVisionCameraMLKit.swift new file mode 100644 index 0000000..ef2e725 --- /dev/null +++ b/ios/Bridge/Hybrid/HybridVisionCameraMLKit.swift @@ -0,0 +1,75 @@ +import Foundation +import NitroModules + +final class HybridVisionCameraMLKit: HybridVisionCameraMLKitSpec { + func isFeatureAvailable(feature: MLKitFeature) throws -> Bool { + switch feature { + case .textrecognition: + #if MLKIT_TEXT_RECOGNITION_ANY + return true + #else + return false + #endif + case .barcodescanning: + #if MLKIT_BARCODE_SCANNING + return true + #else + return false + #endif + case .facedetection: + #if MLKIT_FACE_DETECTION + return true + #else + return false + #endif + case .posedetection: + #if MLKIT_POSE_DETECTION + return true + #else + return false + #endif + case .selfiesegmentation: + #if MLKIT_SELFIE_SEGMENTATION + return true + #else + return false + #endif + case .imagelabeling: + #if MLKIT_IMAGE_LABELING + return true + #else + return false + #endif + case .objectdetection: + #if MLKIT_OBJECT_DETECTION + return true + #else + return false + #endif + case .digitalinkrecognition: + #if MLKIT_DIGITAL_INK_RECOGNITION + return true + #else + return false + #endif + case .facemeshdetection, .subjectsegmentation, .documentscanner: + return false + } + } + + func createTextRecognizer(options: TextRecognizerOptions) throws -> any HybridTextRecognizerSpec { + guard try isFeatureAvailable(feature: .textrecognition) else { + throw RuntimeError.error(withMessage: "TextRecognition is not enabled in the native ML Kit configuration.") + } + + return HybridTextRecognizer(options: options) + } + + func createBarcodeScanner(options: BarcodeScannerOptions) throws -> any HybridBarcodeScannerSpec { + guard try isFeatureAvailable(feature: .barcodescanning) else { + throw RuntimeError.error(withMessage: "BarcodeScanning is not enabled in the native ML Kit configuration.") + } + + return HybridBarcodeScanner(options: options) + } +} diff --git a/ios/Bridge/Hybrid/Orientation+toDomain.swift b/ios/Bridge/Hybrid/Orientation+toDomain.swift new file mode 100644 index 0000000..a750271 --- /dev/null +++ b/ios/Bridge/Hybrid/Orientation+toDomain.swift @@ -0,0 +1,19 @@ +extension Orientation { + func toDomainOrientation() -> DomainOrientation { + switch self { + case .portrait: return .portrait + case .portraitUpsideDown: return .portraitUpsideDown + case .landscapeLeft: return .landscapeLeft + case .landscapeRight: return .landscapeRight + } + } + + func toOutputOrientation() -> OutputOrientation { + switch self { + case .portrait: return .portrait + case .portraitUpsideDown: return .portraitUpsideDown + case .landscapeLeft: return .landscapeLeft + case .landscapeRight: return .landscapeRight + } + } +} diff --git a/ios/Bridge/Hybrid/RegionOfInterest+toDomain.swift b/ios/Bridge/Hybrid/RegionOfInterest+toDomain.swift new file mode 100644 index 0000000..bcc46d1 --- /dev/null +++ b/ios/Bridge/Hybrid/RegionOfInterest+toDomain.swift @@ -0,0 +1,14 @@ +import Foundation + +extension RegionOfInterest { + func toDomainRegionOfInterest() -> DomainRegionOfInterest { + let domainUnit: DomainRegionOfInterestUnit = unit == .pixel ? .pixel : .normalized + return DomainRegionOfInterest( + x: CGFloat(x), + y: CGFloat(y), + width: CGFloat(width), + height: CGFloat(height), + unit: domainUnit + ) + } +} diff --git a/ios/Bridge/Hybrid/TextRecognitionLanguage+toDomain.swift b/ios/Bridge/Hybrid/TextRecognitionLanguage+toDomain.swift new file mode 100644 index 0000000..5ffc947 --- /dev/null +++ b/ios/Bridge/Hybrid/TextRecognitionLanguage+toDomain.swift @@ -0,0 +1,16 @@ +extension TextRecognitionLanguage { + func toDomainLanguage() -> DomainTextRecognitionLanguage { + switch self { + case .chinese: + return .chinese + case .devanagari: + return .devanagari + case .japanese: + return .japanese + case .korean: + return .korean + case .latin: + return .latin + } + } +} diff --git a/ios/Bridge/Hybrid/TextRecognizerOptions+toDomain.swift b/ios/Bridge/Hybrid/TextRecognizerOptions+toDomain.swift new file mode 100644 index 0000000..3706487 --- /dev/null +++ b/ios/Bridge/Hybrid/TextRecognizerOptions+toDomain.swift @@ -0,0 +1,20 @@ +import Foundation + +extension TextRecognizerOptions { + func toDomainTextRecognitionOptions() -> TextRecognitionOptions { + return TextRecognitionOptions( + language: language?.toDomainLanguage() ?? .latin, + invertColors: invertColors ?? false, + scaleFactor: CGFloat(scaleFactor ?? 1.0) + ) + } + + func toImagePreprocessingOptions() -> ImagePreprocessingOptions { + return ImagePreprocessingOptions( + invertColors: invertColors ?? false, + scaleFactor: CGFloat(scaleFactor ?? 1.0), + orientation: orientation?.toDomainOrientation(), + roi: roi?.toDomainRegionOfInterest() + ) + } +} diff --git a/ios/Bridge/Plugins/BaseMLKitPlugin.swift b/ios/Bridge/Plugins/BaseMLKitPlugin.swift deleted file mode 100644 index 611c4f4..0000000 --- a/ios/Bridge/Plugins/BaseMLKitPlugin.swift +++ /dev/null @@ -1,71 +0,0 @@ -import Foundation -import VisionCamera - -@objc -public class BaseMLKitPlugin: FrameProcessorPlugin { - - let proxy: VisionCameraProxyHolder - let options: [AnyHashable: Any]? - - private let frameProcessInterval: Int - private var frameCounter: Int = 0 - let invertColors: Bool - let scaleFactor: CGFloat - - var outputOrientation: OutputOrientation? - - public override init( - proxy: VisionCameraProxyHolder, - options: [AnyHashable: Any]? - ) { - self.proxy = proxy - self.options = options - self.frameProcessInterval = options?["frameProcessInterval"] as? Int ?? 0 - self.invertColors = options?["invertColors"] as? Bool ?? false - - let sf = options?["scaleFactor"] as? NSNumber - let sfValue = sf?.doubleValue ?? 1.0 - - self.scaleFactor = min(max(CGFloat(sfValue), 0.9), 1.0) - - super.init(proxy: proxy, options: options) - } - - public override func callback( - _ frame: Frame, - withArguments arguments: [AnyHashable: Any]? - ) -> Any { - // Extract outputOrientation from arguments for rotation support - outputOrientation = OutputOrientation( - string: arguments?["outputOrientation"] as? String - ) - - // Process 1 frame, skip N frames, repeat - // Note: Consider using runAtTargetFps() from Vision Camera instead - if frameProcessInterval > 0 { - frameCounter += 1 - if frameCounter <= frameProcessInterval { - return [:] - } - frameCounter = 0 - } - - do { - return try processFrame(frame, withArguments: arguments) - } catch { - print("[\(pluginName)] Error occurred: \(error.localizedDescription)") - return [:] - } - } - - public func processFrame( - _ frame: Frame, - withArguments arguments: [AnyHashable: Any]? - ) throws -> [String: Any] { - fatalError("processFrame must be overridden by subclass") - } - - var pluginName: String { - return String(describing: type(of: self)) - } -} diff --git a/ios/Bridge/Plugins/TextRecognitionPlugin.swift b/ios/Bridge/Plugins/TextRecognitionPlugin.swift deleted file mode 100644 index 85157a6..0000000 --- a/ios/Bridge/Plugins/TextRecognitionPlugin.swift +++ /dev/null @@ -1,66 +0,0 @@ -import Foundation -import VisionCamera - -#if MLKIT_TEXT_RECOGNITION - - @objc(TextRecognitionPlugin) - public class TextRecognitionPlugin: BaseMLKitPlugin { - - private let language: TextRecognitionLanguage - - private lazy var recognitionOptions: TextRecognitionOptions = { - TextRecognitionOptions( - language: self.language, - invertColors: self.invertColors, - scaleFactor: self.scaleFactor - ) - }() - - private lazy var recognizeTextUseCase: RecognizeTextUseCase = { - let textRecognizer = TextRecognitionServiceFactory.createTextRecognizer( - language: self.language - ) - let recognitionService = MLKitTextRecognitionService( - textRecognizer: textRecognizer - ) - let imagePreprocessor = ImagePreprocessor() - - return RecognizeTextUseCase( - imagePreprocessor: imagePreprocessor, - recognitionService: recognitionService - ) - }() - - @objc - public override init( - proxy: VisionCameraProxyHolder, - options: [AnyHashable: Any]? = [:] - ) { - let languageString = options?["language"] as? String ?? "LATIN" - self.language = - TextRecognitionLanguage(rawValue: languageString) ?? .latin - - super.init(proxy: proxy, options: options) - } - - public override func processFrame( - _ frame: Frame, - withArguments arguments: [AnyHashable: Any]? - ) throws -> [String: Any] { - let options = TextRecognitionOptions( - language: recognitionOptions.language, - invertColors: recognitionOptions.invertColors, - outputOrientation: outputOrientation, - scaleFactor: recognitionOptions.scaleFactor - ) - - let result = try recognizeTextUseCase.execute( - frame: frame, - options: options - ) - - return TextRecognitionSerializer.toReactNativeMap(result) - } - } - -#endif diff --git a/ios/Bridge/Registry/PluginRegistry.swift b/ios/Bridge/Registry/PluginRegistry.swift deleted file mode 100644 index 82917b2..0000000 --- a/ios/Bridge/Registry/PluginRegistry.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation -import VisionCamera - -@objc -public class PluginRegistry: NSObject { - - @objc - public static func registerTextRecognitionPlugin() { - // Plugin registration is handled by the Objective-C bridge in VisionCameraMLKit.mm - // This class exists for consistency with Android architecture - } -} diff --git a/ios/Domain/Models/BarcodeScanningOptions.swift b/ios/Domain/Models/BarcodeScanningOptions.swift new file mode 100644 index 0000000..cd49f4d --- /dev/null +++ b/ios/Domain/Models/BarcodeScanningOptions.swift @@ -0,0 +1,43 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + struct BarcodeScanningOptions { + let formats: [BarcodeFormatOption] + let enableAllPotentialBarcodes: Bool + let invertColors: Bool + let outputOrientation: OutputOrientation? + let scaleFactor: CGFloat + + init( + formats: [BarcodeFormatOption] = [], + enableAllPotentialBarcodes: Bool = false, + invertColors: Bool = false, + outputOrientation: OutputOrientation? = nil, + scaleFactor: CGFloat = 1.0 + ) { + self.formats = formats + self.enableAllPotentialBarcodes = enableAllPotentialBarcodes + self.invertColors = invertColors + self.outputOrientation = outputOrientation + self.scaleFactor = scaleFactor + } + } + + enum BarcodeFormatOption: String, CaseIterable { + case formatUnknown = "UNKNOWN" + case formatAllFormats = "ALL_FORMATS" + case formatCode128 = "CODE_128" + case formatCode39 = "CODE_39" + case formatCode93 = "CODE_93" + case formatCodabar = "CODABAR" + case formatDataMatrix = "DATA_MATRIX" + case formatEan13 = "EAN_13" + case formatEan8 = "EAN_8" + case formatItf = "ITF" + case formatQrCode = "QR_CODE" + case formatUpcA = "UPC_A" + case formatUpcE = "UPC_E" + case formatPdf417 = "PDF417" + case formatAztec = "AZTEC" + } +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Domain/Models/BarcodeScanningResult+remap.swift b/ios/Domain/Models/BarcodeScanningResult+remap.swift new file mode 100644 index 0000000..0cd9442 --- /dev/null +++ b/ios/Domain/Models/BarcodeScanningResult+remap.swift @@ -0,0 +1,35 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + #if canImport(MLKitVision) + import MLKitVision + + extension BarcodeScanningResult { + /// Remaps each barcode's bounding box and corner points back onto full-source-image + /// coordinates, undoing the ROI crop offset and preprocessing scale. + func remapped(using metadata: ImageMetadata) -> BarcodeScanningResult { + return BarcodeScanningResult( + barcodes: barcodes.map { $0.remapped(using: metadata) } + ) + } + } + + extension BarcodeData { + fileprivate func remapped(using metadata: ImageMetadata) -> BarcodeData { + return BarcodeData( + bounds: bounds?.remapped(using: metadata), + corners: corners?.map { $0.remapped(using: metadata) }, + format: format, + formatName: formatName, + valueType: valueType, + valueTypeName: valueTypeName, + rawValue: rawValue, + displayValue: displayValue, + rawBytes: rawBytes, + isPotential: isPotential, + value: value + ) + } + } + #endif +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Domain/Models/BarcodeScanningResult.swift b/ios/Domain/Models/BarcodeScanningResult.swift new file mode 100644 index 0000000..ea5be7a --- /dev/null +++ b/ios/Domain/Models/BarcodeScanningResult.swift @@ -0,0 +1,26 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + struct BarcodeScanningResult { + let barcodes: [BarcodeData] + } + + struct BarcodeData { + let bounds: DomainBoundingBox? + let corners: [DomainCorner]? + let format: Int + let formatName: String + let valueType: Int + let valueTypeName: String + let rawValue: String? + let displayValue: String? + let rawBytes: [Int]? + let isPotential: Bool + let value: BarcodeParsedValue? + } + + struct BarcodeParsedValue { + let type: String + let data: [String: Any?] + } +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Domain/Models/CoordinateRemap.swift b/ios/Domain/Models/CoordinateRemap.swift new file mode 100644 index 0000000..c3048f8 --- /dev/null +++ b/ios/Domain/Models/CoordinateRemap.swift @@ -0,0 +1,52 @@ +import Foundation + +#if canImport(MLKitVision) + import MLKitVision + + /// Shared primitive for mapping a processed-image coordinate (post-crop, post-scale) back onto + /// full-source-image coordinates: translate by the crop offset, then unscale. + /// `sourceX = offsetX + processedX / scaleFactor`. + /// Domain result coordinates are `Double` (matching `DomainBoundingBox`/`DomainCorner`), while + /// `ImageMetadata`'s offset/scale are `CGFloat`; both convert freely since neither loses + /// precision on 64-bit Apple platforms. + func remapPoint(x: Double, y: Double, metadata: ImageMetadata) -> (x: Double, y: Double) { + let scale = metadata.scaleFactor == 0 ? 1.0 : Double(metadata.scaleFactor) + return ( + x: Double(metadata.offsetX) + x / scale, + y: Double(metadata.offsetY) + y / scale + ) + } + + extension DomainBoundingBox { + /// Remaps every coordinate field onto full-source-image coordinates using the given + /// preprocessing metadata. `width`/`height` only unscale (no translation), matching every + /// other field which translates by the crop offset then unscales. + func remapped(using metadata: ImageMetadata) -> DomainBoundingBox { + let scale = metadata.scaleFactor == 0 ? 1.0 : Double(metadata.scaleFactor) + let origin = remapPoint(x: x, y: y, metadata: metadata) + let center = remapPoint(x: centerX, y: centerY, metadata: metadata) + let topLeft = remapPoint(x: left, y: top, metadata: metadata) + let bottomRight = remapPoint(x: right, y: bottom, metadata: metadata) + + return DomainBoundingBox( + x: origin.x, + y: origin.y, + centerX: center.x, + centerY: center.y, + width: width / scale, + height: height / scale, + top: topLeft.y, + left: topLeft.x, + bottom: bottomRight.y, + right: bottomRight.x + ) + } + } + + extension DomainCorner { + func remapped(using metadata: ImageMetadata) -> DomainCorner { + let point = remapPoint(x: x, y: y, metadata: metadata) + return DomainCorner(x: point.x, y: point.y) + } + } +#endif diff --git a/ios/Domain/Models/BoundingBox.swift b/ios/Domain/Models/DomainBoundingBox.swift similarity index 88% rename from ios/Domain/Models/BoundingBox.swift rename to ios/Domain/Models/DomainBoundingBox.swift index 471026d..5ed8218 100644 --- a/ios/Domain/Models/BoundingBox.swift +++ b/ios/Domain/Models/DomainBoundingBox.swift @@ -1,6 +1,6 @@ import Foundation -struct BoundingBox { +struct DomainBoundingBox { let x: Double let y: Double let centerX: Double diff --git a/ios/Domain/Models/Corner.swift b/ios/Domain/Models/DomainCorner.swift similarity index 70% rename from ios/Domain/Models/Corner.swift rename to ios/Domain/Models/DomainCorner.swift index 3c87553..ecd5841 100644 --- a/ios/Domain/Models/Corner.swift +++ b/ios/Domain/Models/DomainCorner.swift @@ -1,6 +1,6 @@ import Foundation -struct Corner { +struct DomainCorner { let x: Double let y: Double } diff --git a/ios/Domain/Models/DomainOrientation.swift b/ios/Domain/Models/DomainOrientation.swift new file mode 100644 index 0000000..a0cb59a --- /dev/null +++ b/ios/Domain/Models/DomainOrientation.swift @@ -0,0 +1,42 @@ +import Foundation + +import UIKit + +enum DomainOrientation: Int { + case portrait + case portraitUpsideDown + case landscapeLeft + case landscapeRight + + init?(string: String?) { + switch string { + case "portrait": self = .portrait + case "portrait-upside-down": self = .portraitUpsideDown + case "landscape-left": self = .landscapeLeft + case "landscape-right": self = .landscapeRight + default: return nil + } + } + + /// Maps a UIImage.Orientation (typically from EXIF metadata) back to a DomainOrientation value. + static func fromUIImageOrientation(_ imageOrientation: UIImage.Orientation) + -> DomainOrientation + { + switch imageOrientation { + case .up, .upMirrored: return .portrait + case .down, .downMirrored: return .portraitUpsideDown + case .left, .leftMirrored: return .landscapeLeft + case .right, .rightMirrored: return .landscapeRight + default: return .portrait + } + } + + var asUIImageOrientation: UIImage.Orientation { + switch self { + case .portrait: return .up + case .portraitUpsideDown: return .down + case .landscapeLeft: return .left + case .landscapeRight: return .right + } + } +} diff --git a/ios/Domain/Models/DomainRegionOfInterest.swift b/ios/Domain/Models/DomainRegionOfInterest.swift new file mode 100644 index 0000000..eed5b1f --- /dev/null +++ b/ios/Domain/Models/DomainRegionOfInterest.swift @@ -0,0 +1,89 @@ +import Foundation + +enum DomainRegionOfInterestUnit { + case normalized + case pixel +} + +/// Domain-layer Region of Interest, distinct from the Nitro-bridge `RegionOfInterest` +/// (see `RegionOfInterest+toDomain.swift` for the conversion), matching how `DomainOrientation` +/// is kept separate from the Nitro `Orientation` type. +struct DomainRegionOfInterest { + let x: CGFloat + let y: CGFloat + let width: CGFloat + let height: CGFloat + let unit: DomainRegionOfInterestUnit + + init( + x: CGFloat, + y: CGFloat, + width: CGFloat, + height: CGFloat, + unit: DomainRegionOfInterestUnit = .normalized + ) { + self.x = x + self.y = y + self.width = width + self.height = height + self.unit = unit + } +} + +enum RegionOfInterestValidationError: Error, LocalizedError { + case negativeOrigin(x: CGFloat, y: CGFloat) + case nonPositiveSize(width: CGFloat, height: CGFloat) + case normalizedOutOfBounds(x: CGFloat, width: CGFloat, y: CGFloat, height: CGFloat) + + var errorDescription: String? { + switch self { + case .negativeOrigin(let x, let y): + return "Invalid RegionOfInterest: x and y must be >= 0 (got x=\(x), y=\(y))." + case .nonPositiveSize(let width, let height): + return + "Invalid RegionOfInterest: width and height must be > 0 (got width=\(width), height=\(height))." + case .normalizedOutOfBounds(let x, let width, let y, let height): + return + "Invalid RegionOfInterest: normalized x + width and y + height must be <= 1 (got x=\(x), width=\(width), y=\(y), height=\(height))." + } + } +} + +extension DomainRegionOfInterest { + /// Mirrors the JS-side `validateRegionOfInterest` rules so native preprocessing fails fast + /// instead of producing a nonsensical crop deep inside the pipeline. + func validate() throws { + if x < 0 || y < 0 { + throw RegionOfInterestValidationError.negativeOrigin(x: x, y: y) + } + + if width <= 0 || height <= 0 { + throw RegionOfInterestValidationError.nonPositiveSize(width: width, height: height) + } + + if unit == .normalized && (x + width > 1 || y + height > 1) { + throw RegionOfInterestValidationError.normalizedOutOfBounds( + x: x, width: width, y: y, height: height + ) + } + } + + /// Resolves this region into a pixel rectangle clamped to the given image dimensions. + /// `imageWidth`/`imageHeight` must be in the same pixel space the crop will be applied to + /// (post-orientation-normalization, pre-scale). + func resolvedPixelRect(imageWidth: CGFloat, imageHeight: CGFloat) -> CGRect { + let (px, py, pw, ph): (CGFloat, CGFloat, CGFloat, CGFloat) + switch unit { + case .pixel: + (px, py, pw, ph) = (x, y, width, height) + case .normalized: + (px, py, pw, ph) = (x * imageWidth, y * imageHeight, width * imageWidth, height * imageHeight) + } + + let left = max(0, min(px, imageWidth)) + let top = max(0, min(py, imageHeight)) + let right = max(left, min(px + pw, imageWidth)) + let bottom = max(top, min(py + ph, imageHeight)) + return CGRect(x: left, y: top, width: right - left, height: bottom - top) + } +} diff --git a/ios/Domain/Models/DomainTextRecognitionResult+remap.swift b/ios/Domain/Models/DomainTextRecognitionResult+remap.swift new file mode 100644 index 0000000..cd1c42f --- /dev/null +++ b/ios/Domain/Models/DomainTextRecognitionResult+remap.swift @@ -0,0 +1,70 @@ +import Foundation + +#if canImport(MLKitVision) + import MLKitVision + + extension DomainTextRecognitionResult { + /// Remaps every bounding box and corner point in the result tree back onto full-source-image + /// coordinates, undoing the ROI crop offset and preprocessing scale. No-op when neither a + /// crop nor a scale was applied (offset is zero and scale is 1.0). + func remapped(using metadata: ImageMetadata) -> DomainTextRecognitionResult { + return DomainTextRecognitionResult( + text: text, + blocks: blocks.map { $0.remapped(using: metadata) } + ) + } + } + + extension DomainTextBlock { + fileprivate func remapped(using metadata: ImageMetadata) -> DomainTextBlock { + return DomainTextBlock( + text: text, + bounds: bounds?.remapped(using: metadata), + corners: corners?.map { $0.remapped(using: metadata) }, + lines: lines.map { $0.remapped(using: metadata) }, + languages: languages + ) + } + } + + extension DomainTextLine { + fileprivate func remapped(using metadata: ImageMetadata) -> DomainTextLine { + return DomainTextLine( + text: text, + bounds: bounds?.remapped(using: metadata), + corners: corners?.map { $0.remapped(using: metadata) }, + elements: elements.map { $0.remapped(using: metadata) }, + confidence: confidence, + angle: angle, + languages: languages + ) + } + } + + extension DomainTextElement { + fileprivate func remapped(using metadata: ImageMetadata) -> DomainTextElement { + return DomainTextElement( + text: text, + bounds: bounds?.remapped(using: metadata), + corners: corners?.map { $0.remapped(using: metadata) }, + symbols: symbols.map { $0.remapped(using: metadata) }, + confidence: confidence, + angle: angle, + languages: languages + ) + } + } + + extension DomainTextSymbol { + fileprivate func remapped(using metadata: ImageMetadata) -> DomainTextSymbol { + return DomainTextSymbol( + text: text, + bounds: bounds?.remapped(using: metadata), + corners: corners?.map { $0.remapped(using: metadata) }, + confidence: confidence, + angle: angle, + languages: languages + ) + } + } +#endif diff --git a/ios/Domain/Models/DomainTextRecognitionResult.swift b/ios/Domain/Models/DomainTextRecognitionResult.swift new file mode 100644 index 0000000..35aaeac --- /dev/null +++ b/ios/Domain/Models/DomainTextRecognitionResult.swift @@ -0,0 +1,43 @@ +import Foundation + +struct DomainTextRecognitionResult { + let text: String? + let blocks: [DomainTextBlock] +} + +struct DomainTextBlock { + let text: String + let bounds: DomainBoundingBox? + let corners: [DomainCorner]? + let lines: [DomainTextLine] + let languages: [String] +} + +struct DomainTextLine { + let text: String + let bounds: DomainBoundingBox? + let corners: [DomainCorner]? + let elements: [DomainTextElement] + let confidence: Double? + let angle: Double? + let languages: [String] +} + +struct DomainTextElement { + let text: String + let bounds: DomainBoundingBox? + let corners: [DomainCorner]? + let symbols: [DomainTextSymbol] + let confidence: Double? + let angle: Double? + let languages: [String] +} + +struct DomainTextSymbol { + let text: String + let bounds: DomainBoundingBox? + let corners: [DomainCorner]? + let confidence: Double? + let angle: Double? + let languages: [String] +} diff --git a/ios/Domain/Models/ImagePreprocessingOptions+withOutputOrientation.swift b/ios/Domain/Models/ImagePreprocessingOptions+withOutputOrientation.swift new file mode 100644 index 0000000..7639c93 --- /dev/null +++ b/ios/Domain/Models/ImagePreprocessingOptions+withOutputOrientation.swift @@ -0,0 +1,11 @@ +extension ImagePreprocessingOptions { + func withOutputOrientation(_ outputOrientation: OutputOrientation?) -> ImagePreprocessingOptions { + return ImagePreprocessingOptions( + invertColors: invertColors, + outputOrientation: outputOrientation, + scaleFactor: scaleFactor, + orientation: orientation, + roi: roi + ) + } +} diff --git a/ios/Domain/Models/ImagePreprocessingOptions.swift b/ios/Domain/Models/ImagePreprocessingOptions.swift index 5b86b37..664775c 100644 --- a/ios/Domain/Models/ImagePreprocessingOptions.swift +++ b/ios/Domain/Models/ImagePreprocessingOptions.swift @@ -1,20 +1,23 @@ -import UIKit +import Foundation public struct ImagePreprocessingOptions { let invertColors: Bool let outputOrientation: OutputOrientation? let scaleFactor: CGFloat - let orientation: Orientation + let orientation: DomainOrientation? + let roi: DomainRegionOfInterest? - public init( + init( invertColors: Bool = false, outputOrientation: OutputOrientation? = nil, scaleFactor: CGFloat = 1.0, - orientation: Orientation = .portrait + orientation: DomainOrientation? = nil, + roi: DomainRegionOfInterest? = nil ) { self.invertColors = invertColors self.outputOrientation = outputOrientation self.scaleFactor = scaleFactor self.orientation = orientation + self.roi = roi } } diff --git a/ios/Domain/Models/Orientation.swift b/ios/Domain/Models/Orientation.swift deleted file mode 100644 index 27dc518..0000000 --- a/ios/Domain/Models/Orientation.swift +++ /dev/null @@ -1,27 +0,0 @@ -import UIKit - -@objc public enum Orientation: Int { - case portrait - case portraitUpsideDown - case landscapeLeft - case landscapeRight - - public init?(string: String?) { - switch string { - case "portrait": self = .portrait - case "portrait-upside-down": self = .portraitUpsideDown - case "landscape-left": self = .landscapeLeft - case "landscape-right": self = .landscapeRight - default: return nil - } - } - - public var asUIImageOrientation: UIImage.Orientation { - switch self { - case .portrait: return .up - case .portraitUpsideDown: return .down - case .landscapeLeft: return .left - case .landscapeRight: return .right - } - } -} diff --git a/ios/Domain/Models/OutputOrientation.swift b/ios/Domain/Models/OutputOrientation.swift index 8d0497b..6708e23 100644 --- a/ios/Domain/Models/OutputOrientation.swift +++ b/ios/Domain/Models/OutputOrientation.swift @@ -1,4 +1,4 @@ -import UIKit +import Foundation @objc public enum OutputOrientation: Int { case portrait diff --git a/ios/Domain/Models/ProcessedImage.swift b/ios/Domain/Models/ProcessedImage.swift index c695c4f..b93bde7 100644 --- a/ios/Domain/Models/ProcessedImage.swift +++ b/ios/Domain/Models/ProcessedImage.swift @@ -1,14 +1,43 @@ import Foundation -import MLKitVision - -struct ProcessedImage { - let image: VisionImage - let metadata: ImageMetadata -} - -struct ImageMetadata { - let width: Int - let height: Int - let orientation: UIImage.Orientation - let isInverted: Bool -} + +#if canImport(MLKitVision) + import MLKitVision + + struct ProcessedImage { + let image: VisionImage + let metadata: ImageMetadata + } + + struct ImageMetadata { + let width: Int + let height: Int + let orientation: UIImage.Orientation + let isInverted: Bool + /// Origin of the ROI crop, in the same pixel space as `width`/`height` (post-orientation, + /// pre-scale). Downstream code adds this back onto ML Kit result coordinates to remap them + /// to full-source-image coordinates. Zero when no ROI crop was applied. + let offsetX: CGFloat + let offsetY: CGFloat + /// Scale factor applied during preprocessing, needed to unscale result coordinates when + /// remapping them back to full-source-image coordinates. + let scaleFactor: CGFloat + + init( + width: Int, + height: Int, + orientation: UIImage.Orientation, + isInverted: Bool, + offsetX: CGFloat = 0, + offsetY: CGFloat = 0, + scaleFactor: CGFloat = 1.0 + ) { + self.width = width + self.height = height + self.orientation = orientation + self.isInverted = isInverted + self.offsetX = offsetX + self.offsetY = offsetY + self.scaleFactor = scaleFactor + } + } +#endif diff --git a/ios/Domain/Models/StaticImageDecodePlan.swift b/ios/Domain/Models/StaticImageDecodePlan.swift new file mode 100644 index 0000000..f49d17f --- /dev/null +++ b/ios/Domain/Models/StaticImageDecodePlan.swift @@ -0,0 +1,80 @@ +import Foundation + +struct StaticImageDecodePlan: Equatable { + let sourceWidth: Int + let sourceHeight: Int + let outputWidth: Int + let outputHeight: Int + + var thumbnailMaxPixelSize: Int { + max(outputWidth, outputHeight) + } + + var outputPixelCount: Int { + outputWidth * outputHeight + } + + func sourceScaleFactor(decodedWidth: Int, decodedHeight: Int) -> Double { + Double(max(decodedWidth, decodedHeight)) + / Double(max(sourceWidth, sourceHeight)) + } + + static func make(sourceWidth: Int, sourceHeight: Int) -> StaticImageDecodePlan? { + guard + sourceWidth > 0, + sourceHeight > 0, + sourceWidth <= StaticImageLimits.maxSourceDimension, + sourceHeight <= StaticImageLimits.maxSourceDimension, + sourceWidth <= StaticImageLimits.maxSourcePixelCount / sourceHeight + else { + return nil + } + + let pixelScale = sqrt( + Double(StaticImageLimits.maxDecodedPixelCount) + / Double(sourceWidth * sourceHeight) + ) + let dimensionScale = + Double(StaticImageLimits.maxDecodedDimension) + / Double(max(sourceWidth, sourceHeight)) + let scale = min(1, pixelScale, dimensionScale) + + let sourceMaxDimension = max(sourceWidth, sourceHeight) + var maxPixelSize = max(1, Int(floor(Double(sourceMaxDimension) * scale))) + + while maxPixelSize > 0 { + // ImageIO may round the secondary dimension up. Plan with ceil so the actual + // thumbnail still satisfies the decoded pixel-count ceiling. + let outputWidth = max( + 1, + Int( + ceil( + Double(sourceWidth) * Double(maxPixelSize) + / Double(sourceMaxDimension) + ) + ) + ) + let outputHeight = max( + 1, + Int( + ceil( + Double(sourceHeight) * Double(maxPixelSize) + / Double(sourceMaxDimension) + ) + ) + ) + + if StaticImageLimits.acceptsDecoded(width: outputWidth, height: outputHeight) { + return StaticImageDecodePlan( + sourceWidth: sourceWidth, + sourceHeight: sourceHeight, + outputWidth: outputWidth, + outputHeight: outputHeight + ) + } + maxPixelSize -= 1 + } + + return nil + } +} diff --git a/ios/Domain/Models/StaticImageLimits.swift b/ios/Domain/Models/StaticImageLimits.swift new file mode 100644 index 0000000..d3b7b43 --- /dev/null +++ b/ios/Domain/Models/StaticImageLimits.swift @@ -0,0 +1,29 @@ +enum StaticImageLimits { + static let maxEncodedBytes = 25 * 1024 * 1024 + static let maxSourcePixelCount = 25_000_000 + static let maxSourceDimension = 10_000 + static let maxDecodedPixelCount = 4_000_000 + static let maxDecodedDimension = 4_096 + + static func acceptsFile( + isRegularFile: Bool?, + isSymbolicLink: Bool?, + encodedBytes: Int? + ) -> Bool { + guard let encodedBytes else { + return false + } + return isRegularFile == true + && isSymbolicLink == false + && encodedBytes >= 0 + && encodedBytes <= maxEncodedBytes + } + + static func acceptsDecoded(width: Int, height: Int) -> Bool { + width > 0 + && height > 0 + && width <= maxDecodedDimension + && height <= maxDecodedDimension + && width <= maxDecodedPixelCount / height + } +} diff --git a/ios/Domain/Models/TextRecognitionOptions.swift b/ios/Domain/Models/TextRecognitionOptions.swift index a53cb11..424c2f1 100644 --- a/ios/Domain/Models/TextRecognitionOptions.swift +++ b/ios/Domain/Models/TextRecognitionOptions.swift @@ -1,14 +1,13 @@ import Foundation -import UIKit struct TextRecognitionOptions { - let language: TextRecognitionLanguage + let language: DomainTextRecognitionLanguage let invertColors: Bool let outputOrientation: OutputOrientation? let scaleFactor: CGFloat init( - language: TextRecognitionLanguage = .latin, + language: DomainTextRecognitionLanguage = .latin, invertColors: Bool = false, outputOrientation: OutputOrientation? = nil, scaleFactor: CGFloat = 1.0 @@ -20,7 +19,7 @@ struct TextRecognitionOptions { } } -enum TextRecognitionLanguage: String { +enum DomainTextRecognitionLanguage: String { case latin = "LATIN" case chinese = "CHINESE" case devanagari = "DEVANAGARI" diff --git a/ios/Domain/Models/TextRecognitionResult.swift b/ios/Domain/Models/TextRecognitionResult.swift deleted file mode 100644 index 5a2f2ce..0000000 --- a/ios/Domain/Models/TextRecognitionResult.swift +++ /dev/null @@ -1,43 +0,0 @@ -import Foundation - -struct TextRecognitionResult { - let text: String? - let blocks: [TextBlock] -} - -struct TextBlock { - let text: String - let bounds: BoundingBox? - let corners: [Corner]? - let lines: [TextLine] - let languages: [String] -} - -struct TextLine { - let text: String - let bounds: BoundingBox? - let corners: [Corner]? - let elements: [TextElement] - let confidence: Double? - let angle: Double? - let languages: [String] -} - -struct TextElement { - let text: String - let bounds: BoundingBox? - let corners: [Corner]? - let symbols: [TextSymbol] - let confidence: Double? - let angle: Double? - let languages: [String] -} - -struct TextSymbol { - let text: String - let bounds: BoundingBox? - let corners: [Corner]? - let confidence: Double? - let angle: Double? - let languages: [String] -} diff --git a/ios/Domain/Services/IImagePreprocessor.swift b/ios/Domain/Services/IImagePreprocessor.swift index f5781b9..9df1533 100644 --- a/ios/Domain/Services/IImagePreprocessor.swift +++ b/ios/Domain/Services/IImagePreprocessor.swift @@ -1,10 +1,13 @@ import Foundation -import VisionCamera -protocol IImagePreprocessor { - func preprocessFrame(frame: Frame, options: ImagePreprocessingOptions) - -> ProcessedImage? +#if canImport(VisionCamera) + import VisionCamera - func preprocessImage(imageFile: URL, options: ImagePreprocessingOptions) - -> ProcessedImage? -} + protocol IImagePreprocessor { + func preprocessFrame(frame: any HybridFrameSpec, options: ImagePreprocessingOptions) + -> ProcessedImage? + + func preprocessImage(imageFile: URL, options: ImagePreprocessingOptions) + -> ProcessedImage? + } +#endif diff --git a/ios/Infrastructure/Image/ImagePreprocessor.swift b/ios/Infrastructure/Image/ImagePreprocessor.swift index 5580a43..0ff0756 100644 --- a/ios/Infrastructure/Image/ImagePreprocessor.swift +++ b/ios/Infrastructure/Image/ImagePreprocessor.swift @@ -1,332 +1,491 @@ import Foundation -import MLKitVision -import VisionCamera - -class ImagePreprocessor: IImagePreprocessor { - - // Reuse CIContext across frames to avoid repeated allocation overhead - // CIContext creation is expensive (~10-20ms), reusing reduces per-frame cost significantly - private static let sharedContext: CIContext = { - // Use Metal if available for better performance, otherwise use CPU - if let metalDevice = MTLCreateSystemDefaultDevice() { - return CIContext( - mtlDevice: metalDevice, - options: [.useSoftwareRenderer: false] - ) - } else { - return CIContext(options: [.useSoftwareRenderer: false]) - } - }() +import ImageIO - // Clamp scaleFactor to safe range for ML accuracy - private func clampScale(_ scaleFactor: CGFloat?) -> CGFloat { - let scale = scaleFactor ?? 1.0 - return min(max(scale, 0.9), 1.0) - } +#if canImport(MLKitVision) && canImport(VisionCamera) + import MLKitVision + import VisionCamera - // Create scaled VisionImage from CIImage using Core Image affine transform - private func createScaledVisionImage( - from ciImage: CIImage, - scaleFactor: CGFloat, - frameOrientation: UIImage.Orientation, - outputOrientation: OutputOrientation? - ) -> VisionImage? { - // Apply scaling using CIAffineTransform - let scaledCIImage = ciImage.transformed( - by: CGAffineTransform(scaleX: scaleFactor, y: scaleFactor) - ) + class ImagePreprocessor: IImagePreprocessor { - // Render to CGImage - guard - let cgImage = ImagePreprocessor.sharedContext.createCGImage( - scaledCIImage, - from: scaledCIImage.extent - ) - else { - return nil + private struct DecodedStaticImage { + let image: UIImage + let sourceScaleFactor: CGFloat } - // Create UIImage with .up orientation (orientation handled by VisionImage) - let uiImage = UIImage( - cgImage: cgImage, - scale: 1.0, - orientation: .up - ) - - let visionImage = VisionImage(image: uiImage) - visionImage.orientation = getVisionOrientation( - frameOrientation: frameOrientation, - outputOrientation: outputOrientation - ) - return visionImage - } + // Reuse CIContext across frames to avoid repeated allocation overhead + // CIContext creation is expensive (~10-20ms), reusing reduces per-frame cost significantly + private static let sharedContext: CIContext = { + // Use Metal if available for better performance, otherwise use CPU + if let metalDevice = MTLCreateSystemDefaultDevice() { + return CIContext( + mtlDevice: metalDevice, + options: [.useSoftwareRenderer: false] + ) + } else { + return CIContext(options: [.useSoftwareRenderer: false]) + } + }() - // Create filter per call to avoid threading issues with shared state - // CIFilter is not thread-safe; creating per-call ensures safe concurrent frame processing - private func createColorInvertFilter() -> CIFilter? { - let filter = CIFilter(name: "CIColorInvert") - filter?.setDefaults() - return filter - } + // Clamp scaleFactor to safe range for ML accuracy + private func clampScale(_ scaleFactor: CGFloat?) -> CGFloat { + let scale = scaleFactor ?? 1.0 + return min(max(scale, 0.9), 1.0) + } - func preprocessFrame(frame: Frame, options: ImagePreprocessingOptions) - -> ProcessedImage? - { - let effectiveScale = clampScale(options.scaleFactor) + // Create scaled VisionImage from CIImage using Core Image affine transform. + // Crop happens before scale, matching the static-image pipeline's crop-then-scale order. + private func createScaledVisionImage( + from ciImage: CIImage, + scaleFactor: CGFloat, + visionOrientation: UIImage.Orientation, + roi: DomainRegionOfInterest? + ) -> VisionImage? { + var workingImage = ciImage + + if let roi = roi { + guard (try? roi.validate()) != nil else { + return nil + } + let extent = workingImage.extent + let pixelRect = roi.resolvedPixelRect( + imageWidth: extent.width, + imageHeight: extent.height + ) + // CIImage's coordinate origin is at the extent's origin (not necessarily .zero), + // so the crop rect must be offset into the image's own coordinate space. + let cropRect = pixelRect.offsetBy(dx: extent.minX, dy: extent.minY) + workingImage = workingImage.cropped(to: cropRect) + } - let image: VisionImage + // Apply scaling using CIAffineTransform + let scaledCIImage = workingImage.transformed( + by: CGAffineTransform(scaleX: scaleFactor, y: scaleFactor) + ) - if options.invertColors { + // Render to CGImage guard - let invertedImage = createInvertedVisionImageFromFrame( - frame: frame, - outputOrientation: options.outputOrientation, - scaleFactor: effectiveScale + let cgImage = ImagePreprocessor.sharedContext.createCGImage( + scaledCIImage, + from: scaledCIImage.extent ) else { return nil } - image = invertedImage - } else { - image = createVisionImageFromFrame( - frame: frame, - outputOrientation: options.outputOrientation, - scaleFactor: effectiveScale + + // Create UIImage with .up orientation (orientation handled by VisionImage) + let uiImage = UIImage( + cgImage: cgImage, + scale: 1.0, + orientation: .up ) + + let visionImage = VisionImage(image: uiImage) + visionImage.orientation = visionOrientation + return visionImage } - let buffer: CMSampleBuffer = frame.buffer - guard let imageBuffer = CMSampleBufferGetImageBuffer(buffer) else { - return nil + // Create filter per call to avoid threading issues with shared state + // CIFilter is not thread-safe; creating per-call ensures safe concurrent frame processing + private func createColorInvertFilter() -> CIFilter? { + let filter = CIFilter(name: "CIColorInvert") + filter?.setDefaults() + return filter } - // Use scaled dimensions for metadata - let originalWidth = CVPixelBufferGetWidth(imageBuffer) - let originalHeight = CVPixelBufferGetHeight(imageBuffer) - let width = Int(CGFloat(originalWidth) * effectiveScale) - let height = Int(CGFloat(originalHeight) * effectiveScale) - - let metadata = ImageMetadata( - width: width, - height: height, - orientation: frame.orientation, - isInverted: options.invertColors - ) + func preprocessFrame(frame: any HybridFrameSpec, options: ImagePreprocessingOptions) + -> ProcessedImage? + { + guard + let nativeFrame = frame as? NativeFrame, + let sampleBuffer = nativeFrame.sampleBuffer + else { + return nil + } - return ProcessedImage(image: image, metadata: metadata) - } + let effectiveScale = clampScale(options.scaleFactor) + let frameOrientation = frame.orientation.asUIImageOrientation + let visionOrientation = resolveVisionOrientation( + frameOrientation: frameOrientation, + outputOrientation: options.outputOrientation + ) - private func createVisionImageFromFrame( - frame: Frame, - outputOrientation: OutputOrientation?, - scaleFactor: CGFloat - ) -> VisionImage { - let buffer: CMSampleBuffer = frame.buffer - - // MLKit works more reliably when frames are converted to UIImage - // YUV CMSampleBuffer can have orientation and format handling issues - if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) { - let pixelFormatType = CVPixelBufferGetPixelFormatType(pixelBuffer) - - // Only use BGRA directly with MLKit - convert everything else - // YUV formats can have issues with CMSampleBuffer, so convert to BGRA for reliability - let needsConversion = - pixelFormatType != kCVPixelFormatType_32BGRA - || pixelFormatType - == kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarVideoRange - || pixelFormatType - == kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarFullRange - || pixelFormatType - == kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarVideoRange - || pixelFormatType - == kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarFullRange - - // Force conversion when scaling is needed to ensure consistent behavior - // Never bypass scaling if scaleFactor < 1.0 - if needsConversion || scaleFactor < 1.0 { - if let convertedImage = convertToSupportedFormat( - pixelBuffer: pixelBuffer, - frameOrientation: frame.orientation, - outputOrientation: outputOrientation, - scaleFactor: scaleFactor - ) { - return convertedImage + if let roi = options.roi { + guard (try? roi.validate()) != nil else { + return nil + } + } + + let image: VisionImage + + if options.invertColors { + guard + let invertedImage = createInvertedVisionImageFromFrame( + sampleBuffer: sampleBuffer, + visionOrientation: visionOrientation, + scaleFactor: effectiveScale, + roi: options.roi + ) + else { + return nil + } + image = invertedImage + } else { + guard + let convertedImage = createVisionImageFromFrame( + sampleBuffer: sampleBuffer, + visionOrientation: visionOrientation, + scaleFactor: effectiveScale, + roi: options.roi + ) + else { + return nil } - // Conversion failed - this should not happen for scaling cases - fatalError("Conversion failed when scaling is required") + image = convertedImage } + + guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { + return nil + } + + // Use pre-crop, pre-scale pixel-buffer dimensions to resolve the ROI's pixel rect so the + // crop offset lands in the same coordinate space as the scaled width/height below. + let originalWidth = CGFloat(CVPixelBufferGetWidth(imageBuffer)) + let originalHeight = CGFloat(CVPixelBufferGetHeight(imageBuffer)) + + var offsetX: CGFloat = 0 + var offsetY: CGFloat = 0 + var croppedWidth = originalWidth + var croppedHeight = originalHeight + + if let roi = options.roi { + let pixelRect = roi.resolvedPixelRect( + imageWidth: originalWidth, + imageHeight: originalHeight + ) + offsetX = pixelRect.origin.x + offsetY = pixelRect.origin.y + croppedWidth = pixelRect.width + croppedHeight = pixelRect.height + } + + // Use scaled dimensions for metadata + let width = Int(croppedWidth * effectiveScale) + let height = Int(croppedHeight * effectiveScale) + + let metadata = ImageMetadata( + width: width, + height: height, + orientation: visionOrientation, + isInverted: options.invertColors, + offsetX: offsetX, + offsetY: offsetY, + scaleFactor: effectiveScale + ) + + return ProcessedImage(image: image, metadata: metadata) } - // Fallback: Use CMSampleBuffer directly (for BGRA and scaleFactor == 1.0) - let image = VisionImage(buffer: buffer) - image.orientation = getVisionOrientation( - frameOrientation: frame.orientation, - outputOrientation: outputOrientation - ) - return image - } + private func createVisionImageFromFrame( + sampleBuffer: CMSampleBuffer, + visionOrientation: UIImage.Orientation, + scaleFactor: CGFloat, + roi: DomainRegionOfInterest? + ) -> VisionImage? { + // MLKit works more reliably when frames are converted to UIImage + // YUV CMSampleBuffer can have orientation and format handling issues + if let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) { + let pixelFormatType = CVPixelBufferGetPixelFormatType(pixelBuffer) + + // Only use BGRA directly with MLKit - convert everything else + // YUV formats can have issues with CMSampleBuffer, so convert to BGRA for reliability + let needsConversion = + pixelFormatType != kCVPixelFormatType_32BGRA + || pixelFormatType + == kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarVideoRange + || pixelFormatType + == kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarFullRange + || pixelFormatType + == kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarVideoRange + || pixelFormatType + == kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarFullRange + + // Force conversion when scaling or an ROI crop is needed to ensure consistent behavior. + // Never bypass scaling/cropping if scaleFactor < 1.0 or an ROI is set, since the raw + // CMSampleBuffer fast path below cannot crop. + if needsConversion || scaleFactor < 1.0 || roi != nil { + guard + let convertedImage = convertToSupportedFormat( + pixelBuffer: pixelBuffer, + visionOrientation: visionOrientation, + scaleFactor: scaleFactor, + roi: roi + ) + else { + // Conversion failed - this should not happen for scaling/cropping cases + return nil + } + return convertedImage + } + } - private func createInvertedVisionImageFromFrame( - frame: Frame, - outputOrientation: OutputOrientation?, - scaleFactor: CGFloat - ) -> VisionImage? { - guard let buffer = CMSampleBufferGetImageBuffer(frame.buffer) else { - return nil + // Fallback: Use CMSampleBuffer directly (for BGRA, scaleFactor == 1.0, and no ROI) + let image = VisionImage(buffer: sampleBuffer) + image.orientation = visionOrientation + return image } - let ciImage = CIImage(cvPixelBuffer: buffer) + private func createInvertedVisionImageFromFrame( + sampleBuffer: CMSampleBuffer, + visionOrientation: UIImage.Orientation, + scaleFactor: CGFloat, + roi: DomainRegionOfInterest? + ) -> VisionImage? { + guard let buffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { + return nil + } + + let ciImage = CIImage(cvPixelBuffer: buffer) + + guard let invertedCIImage = invertCIImageColor(image: ciImage) else { + return nil + } - guard let invertedCIImage = invertCIImageColor(image: ciImage) else { - return nil + // Apply scaling and create VisionImage using the new method + return createScaledVisionImage( + from: invertedCIImage, + scaleFactor: scaleFactor, + visionOrientation: visionOrientation, + roi: roi + ) } - // Apply scaling and create VisionImage using the new method - return createScaledVisionImage( - from: invertedCIImage, - scaleFactor: scaleFactor, - frameOrientation: frame.orientation, - outputOrientation: outputOrientation + private func resolveVisionOrientation( + frameOrientation: UIImage.Orientation, + outputOrientation: OutputOrientation? ) - } + -> UIImage.Orientation + { + if let outputOrientation = outputOrientation { + return outputOrientation.asUIImageOrientation + } + // Remap for iOS camera sensor orientation quirks when no outputOrientation provided. + switch frameOrientation { + case .left: + return .right + case .right: + return .left + default: + return frameOrientation + } + } - private func getVisionOrientation( - frameOrientation: UIImage.Orientation, - outputOrientation: OutputOrientation? - ) - -> UIImage.Orientation - { - if let outputOrientation = outputOrientation { - return outputOrientation.asUIImageOrientation + private func invertCIImageColor(image: CIImage) -> CIImage? { + guard let filter = createColorInvertFilter() else { return nil } + filter.setValue(image, forKey: kCIInputImageKey) + return filter.outputImage } - // Remap for iOS camera sensor orientation quirks when no outputOrientation provided. - switch frameOrientation { - case .left: - return .right - case .right: - return .left - default: - return frameOrientation + + private func convertToSupportedFormat( + pixelBuffer: CVPixelBuffer, + visionOrientation: UIImage.Orientation, + scaleFactor: CGFloat, + roi: DomainRegionOfInterest? + ) -> VisionImage? { + // Convert to CIImage + let ciImage = CIImage(cvPixelBuffer: pixelBuffer) + + // Apply scaling and create VisionImage using the new method + return createScaledVisionImage( + from: ciImage, + scaleFactor: scaleFactor, + visionOrientation: visionOrientation, + roi: roi + ) } - } - private func invertCIImageColor(image: CIImage) -> CIImage? { - guard let filter = createColorInvertFilter() else { return nil } - filter.setValue(image, forKey: kCIInputImageKey) - return filter.outputImage - } + func preprocessImage(imageFile: URL, options: ImagePreprocessingOptions) + -> ProcessedImage? + { + guard + let decoded = decodeStaticImage( + imageFile, + explicitOrientation: options.orientation?.asUIImageOrientation + ) + else { + return nil + } - private func convertToSupportedFormat( - pixelBuffer: CVPixelBuffer, - frameOrientation: UIImage.Orientation, - outputOrientation: OutputOrientation?, - scaleFactor: CGFloat - ) -> VisionImage? { - // Convert to CIImage - let ciImage = CIImage(cvPixelBuffer: pixelBuffer) - - // Apply scaling and create VisionImage using the new method - return createScaledVisionImage( - from: ciImage, - scaleFactor: scaleFactor, - frameOrientation: frameOrientation, - outputOrientation: outputOrientation - ) - } + // An explicit orientation describes the source pixels and overrides embedded EXIF. + // Normalize either orientation into pixels before resolving ROI coordinates. + let effectiveOrientation = + options.orientation?.asUIImageOrientation ?? decoded.image.imageOrientation + guard let normalizedImage = decoded.image.normalized(to: effectiveOrientation) else { + return nil + } + let effectiveScale = clampScale(options.scaleFactor) - func preprocessImage(imageFile: URL, options: ImagePreprocessingOptions) - -> ProcessedImage? - { - guard let imageData = try? Data(contentsOf: imageFile), - let uiImage = UIImage(data: imageData) - else { - return nil - } + var processedImage = normalizedImage + var offsetX: CGFloat = 0 + var offsetY: CGFloat = 0 - // Rotate image based on orientation - let rotatedImage = rotateUIImage(uiImage, orientation: options.orientation) + // Apply optional ROI crop in normalized, visually oriented pixel coordinates. + if let roi = options.roi { + guard (try? roi.validate()) != nil else { + return nil + } - // Apply color inversion if needed - let processedImage: UIImage - if options.invertColors { - processedImage = invertUIImageColors(rotatedImage) - } else { - processedImage = rotatedImage - } + // Crop in the same pixel space ML Kit will see: the CGImage's pixel dimensions, + // not the orientation-aware `image.size`. + guard let cgImage = processedImage.cgImage else { + return nil + } - // Create VisionImage - let visionImage = VisionImage(image: processedImage) - visionImage.orientation = options.orientation.asUIImageOrientation + let pixelRect = roi.resolvedPixelRect( + imageWidth: CGFloat(cgImage.width), + imageHeight: CGFloat(cgImage.height) + ) - let metadata = ImageMetadata( - width: Int(processedImage.size.width), - height: Int(processedImage.size.height), - orientation: options.orientation.asUIImageOrientation, - isInverted: options.invertColors - ) + guard let croppedCGImage = cgImage.cropping(to: pixelRect) else { + return nil + } - return ProcessedImage(image: visionImage, metadata: metadata) - } + offsetX = pixelRect.origin.x / decoded.sourceScaleFactor + offsetY = pixelRect.origin.y / decoded.sourceScaleFactor + processedImage = UIImage( + cgImage: croppedCGImage, + scale: processedImage.scale, + orientation: .up + ) + } + + // Apply optional downscale for static images. + if effectiveScale < 1.0 { + processedImage = scaleUIImage(processedImage, scaleFactor: effectiveScale) + } - private func rotateUIImage(_ image: UIImage, orientation: Orientation) - -> UIImage - { - let degrees: CGFloat - switch orientation { - case .portrait: - degrees = 0 - case .portraitUpsideDown: - degrees = 180 - case .landscapeLeft: - degrees = 90 - case .landscapeRight: - degrees = 270 + // Apply color inversion if needed + if options.invertColors { + processedImage = invertUIImageColors(processedImage) + } + + // Create VisionImage + let visionImage = VisionImage(image: processedImage) + visionImage.orientation = .up + + let pixelWidth = + processedImage.cgImage?.width + ?? Int(processedImage.size.width * processedImage.scale) + let pixelHeight = + processedImage.cgImage?.height + ?? Int(processedImage.size.height * processedImage.scale) + + let metadata = ImageMetadata( + width: pixelWidth, + height: pixelHeight, + orientation: .up, + isInverted: options.invertColors, + offsetX: offsetX, + offsetY: offsetY, + scaleFactor: decoded.sourceScaleFactor * effectiveScale + ) + + return ProcessedImage(image: visionImage, metadata: metadata) } - let radians = degrees * .pi / 180 - let rotatedSize = CGRect(origin: .zero, size: image.size) - .applying(CGAffineTransform(rotationAngle: radians)) - .integral + private func decodeStaticImage( + _ imageFile: URL, + explicitOrientation: UIImage.Orientation? + ) -> DecodedStaticImage? { + guard + let source = CGImageSourceCreateWithURL(imageFile as CFURL, nil), + let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) + as? [CFString: Any], + let width = properties[kCGImagePropertyPixelWidth] as? Int, + let height = properties[kCGImagePropertyPixelHeight] as? Int, + let decodePlan = StaticImageDecodePlan.make( + sourceWidth: width, + sourceHeight: height + ) + else { + return nil + } + + let thumbnailOptions: [CFString: Any] = [ + kCGImageSourceCreateThumbnailFromImageAlways: true, + kCGImageSourceCreateThumbnailWithTransform: explicitOrientation == nil, + kCGImageSourceThumbnailMaxPixelSize: decodePlan.thumbnailMaxPixelSize, + kCGImageSourceShouldCacheImmediately: true, + ] - UIGraphicsBeginImageContext(rotatedSize.size) - defer { UIGraphicsEndImageContext() } + guard + let thumbnail = CGImageSourceCreateThumbnailAtIndex( + source, + 0, + thumbnailOptions as CFDictionary + ) + else { + return nil + } - guard let context = UIGraphicsGetCurrentContext() else { return image } + guard + StaticImageLimits.acceptsDecoded( + width: thumbnail.width, + height: thumbnail.height + ) + else { + return nil + } - context.translateBy( - x: rotatedSize.size.width / 2, - y: rotatedSize.size.height / 2 - ) - context.rotate(by: radians) - image.draw( - in: CGRect( - x: -image.size.width / 2, - y: -image.size.height / 2, - width: image.size.width, - height: image.size.height + let actualScale = CGFloat( + decodePlan.sourceScaleFactor( + decodedWidth: thumbnail.width, + decodedHeight: thumbnail.height + ) ) - ) - return UIGraphicsGetImageFromCurrentImageContext() ?? image - } - - private func invertUIImageColors(_ image: UIImage) -> UIImage { - guard let filter = createColorInvertFilter(), - let ciImage = CIImage(image: image) - else { - return image + return DecodedStaticImage( + image: UIImage( + cgImage: thumbnail, + scale: 1, + orientation: explicitOrientation ?? .up + ), + sourceScaleFactor: actualScale + ) } - filter.setValue(ciImage, forKey: kCIInputImageKey) - guard let outputImage = filter.outputImage, - let cgImage = ImagePreprocessor.sharedContext.createCGImage( - outputImage, - from: outputImage.extent + private func scaleUIImage(_ image: UIImage, scaleFactor: CGFloat) -> UIImage { + let targetSize = CGSize( + width: image.size.width * scaleFactor, + height: image.size.height * scaleFactor ) - else { - return image + + let rendererFormat = UIGraphicsImageRendererFormat.default() + rendererFormat.scale = image.scale + + let renderer = UIGraphicsImageRenderer(size: targetSize, format: rendererFormat) + return renderer.image { _ in + image.draw(in: CGRect(origin: .zero, size: targetSize)) + } } - return UIImage(cgImage: cgImage) + private func invertUIImageColors(_ image: UIImage) -> UIImage { + guard let filter = createColorInvertFilter(), + let ciImage = CIImage(image: image) + else { + return image + } + + filter.setValue(ciImage, forKey: kCIInputImageKey) + guard let outputImage = filter.outputImage, + let cgImage = ImagePreprocessor.sharedContext.createCGImage( + outputImage, + from: outputImage.extent + ) + else { + return image + } + + return UIImage(cgImage: cgImage) + } } -} +#endif diff --git a/ios/Infrastructure/Image/StaticImageURLResolver.swift b/ios/Infrastructure/Image/StaticImageURLResolver.swift new file mode 100644 index 0000000..03eb9a4 --- /dev/null +++ b/ios/Infrastructure/Image/StaticImageURLResolver.swift @@ -0,0 +1,49 @@ +import Foundation +import NitroModules + +enum StaticImageURLResolver { + static func resolve(_ uri: String) throws -> URL { + let fileURL: URL + + if let url = URL(string: uri), url.scheme != nil { + guard url.isFileURL else { + throw RuntimeError.error( + withMessage: "Static image URI must use the file scheme: \(uri)" + ) + } + fileURL = url + } else { + guard uri.hasPrefix("/") else { + throw RuntimeError.error( + withMessage: "Static image URI must be a file URL or absolute path: \(uri)" + ) + } + fileURL = URL(fileURLWithPath: uri) + } + + let path = fileURL.standardizedFileURL.path + guard FileManager.default.fileExists(atPath: path) else { + throw RuntimeError.error(withMessage: "Static image file does not exist: \(path)") + } + guard FileManager.default.isReadableFile(atPath: path) else { + throw RuntimeError.error(withMessage: "Static image file is not readable: \(path)") + } + + let resourceValues = try fileURL.resourceValues( + forKeys: [.fileSizeKey, .isRegularFileKey, .isSymbolicLinkKey] + ) + guard + StaticImageLimits.acceptsFile( + isRegularFile: resourceValues.isRegularFile, + isSymbolicLink: resourceValues.isSymbolicLink, + encodedBytes: resourceValues.fileSize + ) + else { + throw RuntimeError.error( + withMessage: "Static image must be a regular, non-symlink file up to 25 MB." + ) + } + + return URL(fileURLWithPath: path) + } +} diff --git a/ios/Infrastructure/Image/UIImage+normalizedOrientation.swift b/ios/Infrastructure/Image/UIImage+normalizedOrientation.swift new file mode 100644 index 0000000..0b010c7 --- /dev/null +++ b/ios/Infrastructure/Image/UIImage+normalizedOrientation.swift @@ -0,0 +1,36 @@ +import UIKit + +extension UIImage { + func normalized(to orientation: UIImage.Orientation) -> UIImage? { + guard let cgImage else { + return nil + } + + // `.up` means the pixel data already matches the desired visual orientation, + // so there's nothing to bake in — skip the redundant render pass. + if orientation == .up { + return UIImage(cgImage: cgImage, scale: 1, orientation: .up) + } + + let swapsDimensions: Bool + switch orientation { + case .left, .leftMirrored, .right, .rightMirrored: + swapsDimensions = true + default: + swapsDimensions = false + } + + let pixelSize = CGSize( + width: swapsDimensions ? cgImage.height : cgImage.width, + height: swapsDimensions ? cgImage.width : cgImage.height + ) + let orientedImage = UIImage(cgImage: cgImage, scale: 1, orientation: orientation) + let rendererFormat = UIGraphicsImageRendererFormat.default() + rendererFormat.scale = 1 + let renderer = UIGraphicsImageRenderer(size: pixelSize, format: rendererFormat) + + return renderer.image { _ in + orientedImage.draw(in: CGRect(origin: .zero, size: pixelSize)) + } + } +} diff --git a/ios/Infrastructure/MLKit/Adapters/MLKitBarcodeAdapter.swift b/ios/Infrastructure/MLKit/Adapters/MLKitBarcodeAdapter.swift new file mode 100644 index 0000000..ab8d210 --- /dev/null +++ b/ios/Infrastructure/MLKit/Adapters/MLKitBarcodeAdapter.swift @@ -0,0 +1,325 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + import MLKitBarcodeScanning + + class MLKitBarcodeAdapter { + + static func toDomain(_ barcodes: [Barcode]) -> BarcodeScanningResult { + return BarcodeScanningResult(barcodes: barcodes.map { toBarcodeData($0) }) + } + + private static func toBarcodeData(_ barcode: Barcode) -> BarcodeData { + return BarcodeData( + bounds: toBoundingBox(barcode.frame), + corners: barcode.cornerPoints?.map { toCorner($0.cgPointValue) }, + format: Int(barcode.format.rawValue), + formatName: formatName(barcode.format), + valueType: Int(barcode.valueType.rawValue), + valueTypeName: valueTypeName(barcode.valueType), + rawValue: barcode.rawValue, + displayValue: barcode.displayValue, + rawBytes: barcode.rawData.map { Array($0).map { Int($0) } }, + isPotential: barcode.rawValue == nil && barcode.rawData == nil, + value: toParsedValue(barcode) + ) + } + + private static func toParsedValue(_ barcode: Barcode) -> BarcodeParsedValue? { + if let wifi = barcode.wifi { + return BarcodeParsedValue( + type: "TYPE_WIFI", + data: [ + "ssid": wifi.ssid, + "password": wifi.password, + "encryptionType": Int(wifi.type.rawValue), + "encryptionTypeName": wifiEncryptionName(wifi.type), + ] + ) + } + + if let url = barcode.url { + return BarcodeParsedValue( + type: "TYPE_URL", + data: [ + "title": url.title, + "url": url.url, + ] + ) + } + + if let sms = barcode.sms { + return BarcodeParsedValue( + type: "TYPE_SMS", + data: [ + "message": sms.message, + "phoneNumber": sms.phoneNumber, + ] + ) + } + + if let email = barcode.email { + return BarcodeParsedValue( + type: "TYPE_EMAIL", + data: [ + "address": email.address, + "subject": email.subject, + "body": email.body, + "type": Int(email.type.rawValue), + "typeName": emailTypeName(email.type), + ] + ) + } + + if let phone = barcode.phone { + return BarcodeParsedValue( + type: "TYPE_PHONE", + data: [ + "number": phone.number, + "type": Int(phone.type.rawValue), + "typeName": phoneTypeName(phone.type), + ] + ) + } + + if let geo = barcode.geoPoint { + return BarcodeParsedValue( + type: "TYPE_GEO", + data: [ + "lat": geo.latitude, + "lng": geo.longitude, + ] + ) + } + + if let calendarEvent = barcode.calendarEvent { + return BarcodeParsedValue( + type: "TYPE_CALENDAR_EVENT", + data: [ + "summary": calendarEvent.summary, + "description": calendarEvent.eventDescription, + "location": calendarEvent.location, + "organizer": calendarEvent.organizer, + "status": calendarEvent.status, + "start": toDateInfo(calendarEvent.start), + "end": toDateInfo(calendarEvent.end), + ] + ) + } + + if let contactInfo = barcode.contactInfo { + return BarcodeParsedValue( + type: "TYPE_CONTACT_INFO", + data: [ + "name": contactInfo.name.map { toPersonName($0) }, + "organization": contactInfo.organization, + "title": contactInfo.jobTitle, + "phones": contactInfo.phones?.map { toPhone($0) }, + "emails": contactInfo.emails?.map { toEmail($0) }, + "addresses": contactInfo.addresses?.map { toAddress($0) }, + "urls": contactInfo.urls, + ] + ) + } + + if let driverLicense = barcode.driverLicense { + return BarcodeParsedValue( + type: "TYPE_DRIVER_LICENSE", + data: [ + "documentType": driverLicense.documentType, + "licenseNumber": driverLicense.licenseNumber, + "firstName": driverLicense.firstName, + "middleName": driverLicense.middleName, + "lastName": driverLicense.lastName, + "gender": driverLicense.gender, + "addressStreet": driverLicense.addressStreet, + "addressCity": driverLicense.addressCity, + "addressState": driverLicense.addressState, + "addressZip": driverLicense.addressZip, + "birthDate": driverLicense.birthDate, + "issueDate": driverLicense.issuingDate, + "expiryDate": driverLicense.expiryDate, + "issuingCountry": driverLicense.issuingCountry, + ] + ) + } + + if let rawValue = barcode.rawValue { + let type = valueTypeName(barcode.valueType) + let dataKey: String + switch type { + case "TYPE_TEXT": dataKey = "text" + case "TYPE_PRODUCT": dataKey = "product" + case "TYPE_ISBN": dataKey = "isbn" + default: dataKey = "rawValue" + } + + return BarcodeParsedValue( + type: type, + data: [dataKey: rawValue] + ) + } + + return nil + } + + private static func toPersonName(_ name: BarcodePersonName) -> [String: Any?] { + return [ + "formattedName": name.formattedName, + "pronunciation": name.pronunciation, + "prefix": name.prefix, + "first": name.first, + "middle": name.middle, + "last": name.last, + "suffix": name.suffix, + ] + } + + private static func toPhone(_ phone: BarcodePhone) -> [String: Any?] { + return [ + "number": phone.number, + "type": Int(phone.type.rawValue), + "typeName": phoneTypeName(phone.type), + ] + } + + private static func toEmail(_ email: BarcodeEmail) -> [String: Any?] { + return [ + "address": email.address, + "subject": email.subject, + "body": email.body, + "type": Int(email.type.rawValue), + "typeName": emailTypeName(email.type), + ] + } + + private static func toAddress(_ address: BarcodeAddress) -> [String: Any?] { + return [ + "addressLines": address.addressLines, + "type": Int(address.type.rawValue), + "typeName": addressTypeName(address.type), + ] + } + + private static func toDateInfo(_ date: Date?) -> [String: Any?]? { + guard let date else { + return nil + } + + let calendar = Calendar(identifier: .gregorian) + let components = calendar.dateComponents( + [.year, .month, .day, .hour, .minute, .second], + from: date + ) + + return [ + "year": components.year, + "month": components.month, + "day": components.day, + "hours": components.hour, + "minutes": components.minute, + "seconds": components.second, + "isUtc": false, + "rawValue": ISO8601DateFormatter().string(from: date), + ] + } + + private static func toBoundingBox(_ rect: CGRect) -> DomainBoundingBox { + let offsetX = (rect.midX - ceil(rect.width)) / 2.0 + let offsetY = (rect.midY - ceil(rect.height)) / 2.0 + + let x = rect.maxX + offsetX + let y = rect.minY + offsetY + + return DomainBoundingBox( + x: rect.midX + (rect.midX - x), + y: rect.midY + (y - rect.midY), + centerX: rect.midX, + centerY: rect.midY, + width: rect.width, + height: rect.height, + top: rect.maxY, + left: rect.minX, + bottom: rect.minY, + right: rect.maxX + ) + } + + private static func toCorner(_ point: CGPoint) -> DomainCorner { + return DomainCorner(x: Double(point.x), y: Double(point.y)) + } + + private static func formatName(_ format: MLKitBarcodeScanning.BarcodeFormat) -> String { + switch Int(format.rawValue) { + case 1: return "CODE_128" + case 2: return "CODE_39" + case 4: return "CODE_93" + case 8: return "CODABAR" + case 16: return "DATA_MATRIX" + case 32: return "EAN_13" + case 64: return "EAN_8" + case 128: return "ITF" + case 256: return "QR_CODE" + case 512: return "UPC_A" + case 1024: return "UPC_E" + case 2048: return "PDF417" + case 4096: return "AZTEC" + default: return "UNKNOWN" + } + } + + private static func valueTypeName(_ valueType: MLKitBarcodeScanning.BarcodeValueType) -> String + { + switch Int(valueType.rawValue) { + case 1: return "TYPE_CONTACT_INFO" + case 2: return "TYPE_EMAIL" + case 3: return "TYPE_ISBN" + case 4: return "TYPE_PHONE" + case 5: return "TYPE_PRODUCT" + case 6: return "TYPE_SMS" + case 7: return "TYPE_TEXT" + case 8: return "TYPE_URL" + case 9: return "TYPE_WIFI" + case 10: return "TYPE_GEO" + case 11: return "TYPE_CALENDAR_EVENT" + case 12: return "TYPE_DRIVER_LICENSE" + default: return "TYPE_UNKNOWN" + } + } + + private static func wifiEncryptionName(_ type: BarcodeWiFiEncryptionType) -> String { + switch Int(type.rawValue) { + case 1: return "OPEN" + case 2: return "WPA" + case 3: return "WEP" + default: return "UNKNOWN" + } + } + + private static func phoneTypeName(_ type: BarcodePhoneType) -> String { + switch Int(type.rawValue) { + case 1: return "WORK" + case 2: return "HOME" + case 3: return "FAX" + case 4: return "MOBILE" + default: return "UNKNOWN" + } + } + + private static func emailTypeName(_ type: BarcodeEmailType) -> String { + switch Int(type.rawValue) { + case 1: return "WORK" + case 2: return "HOME" + default: return "UNKNOWN" + } + } + + private static func addressTypeName(_ type: BarcodeAddressType) -> String { + switch Int(type.rawValue) { + case 1: return "WORK" + case 2: return "HOME" + default: return "UNKNOWN" + } + } + } +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Infrastructure/MLKit/Adapters/MLKitTextAdapter.swift b/ios/Infrastructure/MLKit/Adapters/MLKitTextAdapter.swift index 17135c9..8ba3aae 100644 --- a/ios/Infrastructure/MLKit/Adapters/MLKitTextAdapter.swift +++ b/ios/Infrastructure/MLKit/Adapters/MLKitTextAdapter.swift @@ -1,77 +1,80 @@ import Foundation -import MLKitTextRecognition -class MLKitTextAdapter { +#if MLKIT_TEXT_RECOGNITION_ANY + import MLKitTextRecognition - static func toDomain(_ mlkitText: Text?) -> TextRecognitionResult { - return TextRecognitionResult( - text: mlkitText?.text, - blocks: mlkitText?.blocks.map { toTextBlock($0) } ?? [] - ) - } + class MLKitTextAdapter { - private static func toTextBlock(_ block: MLKitTextRecognition.TextBlock) - -> TextBlock - { - return TextBlock( - text: block.text, - bounds: toBoundingBox(block.frame), - corners: block.cornerPoints.map { toCorner($0.cgPointValue) }, - lines: block.lines.map { toTextLine($0) }, - languages: block.recognizedLanguages.map { $0.languageCode ?? "" } - ) - } + static func toDomain(_ mlkitText: Text?) -> DomainTextRecognitionResult { + return DomainTextRecognitionResult( + text: mlkitText?.text, + blocks: mlkitText?.blocks.map { toTextBlock($0) } ?? [] + ) + } - private static func toTextLine(_ line: MLKitTextRecognition.TextLine) - -> TextLine - { - return TextLine( - text: line.text, - bounds: toBoundingBox(line.frame), - corners: line.cornerPoints.map { toCorner($0.cgPointValue) }, - elements: line.elements.map { toTextElement($0) }, - confidence: nil, - angle: nil, - languages: line.recognizedLanguages.map { $0.languageCode ?? "" } - ) - } + private static func toTextBlock(_ block: MLKitTextRecognition.TextBlock) + -> DomainTextBlock + { + return DomainTextBlock( + text: block.text, + bounds: toBoundingBox(block.frame), + corners: block.cornerPoints.map { toCorner($0.cgPointValue) }, + lines: block.lines.map { toTextLine($0) }, + languages: block.recognizedLanguages.map { $0.languageCode ?? "" } + ) + } - private static func toTextElement(_ element: MLKitTextRecognition.TextElement) - -> TextElement - { - return TextElement( - text: element.text, - bounds: toBoundingBox(element.frame), - corners: element.cornerPoints.map { toCorner($0.cgPointValue) }, - symbols: [], - confidence: nil, - angle: nil, - languages: element.recognizedLanguages.map { $0.languageCode ?? "" } - ) - } + private static func toTextLine(_ line: MLKitTextRecognition.TextLine) + -> DomainTextLine + { + return DomainTextLine( + text: line.text, + bounds: toBoundingBox(line.frame), + corners: line.cornerPoints.map { toCorner($0.cgPointValue) }, + elements: line.elements.map { toTextElement($0) }, + confidence: nil, + angle: nil, + languages: line.recognizedLanguages.map { $0.languageCode ?? "" } + ) + } - private static func toBoundingBox(_ bounds: CGRect) -> BoundingBox { - let offsetX = (bounds.midX - ceil(bounds.width)) / 2.0 - let offsetY = (bounds.midY - ceil(bounds.height)) / 2.0 + private static func toTextElement(_ element: MLKitTextRecognition.TextElement) + -> DomainTextElement + { + return DomainTextElement( + text: element.text, + bounds: toBoundingBox(element.frame), + corners: element.cornerPoints.map { toCorner($0.cgPointValue) }, + symbols: [], + confidence: nil, + angle: nil, + languages: element.recognizedLanguages.map { $0.languageCode ?? "" } + ) + } - let x = bounds.maxX + offsetX - let y = bounds.minY + offsetY + private static func toBoundingBox(_ bounds: CGRect) -> DomainBoundingBox { + let offsetX = (bounds.midX - ceil(bounds.width)) / 2.0 + let offsetY = (bounds.midY - ceil(bounds.height)) / 2.0 - return BoundingBox( - x: bounds.midX + (bounds.midX - x), - y: bounds.midY + (y - bounds.midY), - centerX: bounds.midX, - centerY: bounds.midY, - width: bounds.width, - height: bounds.height, - top: bounds.maxY, - left: bounds.minX, - bottom: bounds.minY, - right: bounds.maxX - ) - } + let x = bounds.maxX + offsetX + let y = bounds.minY + offsetY + + return DomainBoundingBox( + x: bounds.midX + (bounds.midX - x), + y: bounds.midY + (y - bounds.midY), + centerX: bounds.midX, + centerY: bounds.midY, + width: bounds.width, + height: bounds.height, + top: bounds.maxY, + left: bounds.minX, + bottom: bounds.minY, + right: bounds.maxX + ) + } - private static func toCorner(_ point: CGPoint) -> Corner { - return Corner(x: Double(point.x), y: Double(point.y)) + private static func toCorner(_ point: CGPoint) -> DomainCorner { + return DomainCorner(x: Double(point.x), y: Double(point.y)) + } } -} +#endif // MLKIT_TEXT_RECOGNITION_ANY diff --git a/ios/Infrastructure/MLKit/Factories/BarcodeScanningServiceFactory.swift b/ios/Infrastructure/MLKit/Factories/BarcodeScanningServiceFactory.swift new file mode 100644 index 0000000..a51dd62 --- /dev/null +++ b/ios/Infrastructure/MLKit/Factories/BarcodeScanningServiceFactory.swift @@ -0,0 +1,69 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + import MLKitBarcodeScanning + + class BarcodeScanningServiceFactory { + + static func createBarcodeScanner(options: BarcodeScanningOptions) + -> BarcodeScanner + { + let scannerOptions: MLKitBarcodeScanning.BarcodeScannerOptions + if options.formats.isEmpty || options.formats.contains(.formatAllFormats) { + scannerOptions = MLKitBarcodeScanning.BarcodeScannerOptions() + } else { + scannerOptions = MLKitBarcodeScanning.BarcodeScannerOptions( + formats: toMLKitFormats(options.formats) + ) + } + return BarcodeScanner.barcodeScanner(options: scannerOptions) + } + + static func create(options: BarcodeScanningOptions = BarcodeScanningOptions()) + -> MLKitBarcodeScanningService + { + let scanner = createBarcodeScanner(options: options) + return MLKitBarcodeScanningService(barcodeScanner: scanner) + } + + private static func toMLKitFormats(_ formats: [BarcodeFormatOption]) + -> MLKitBarcodeScanning.BarcodeFormat + { + var rawValue = 0 + for format in formats { + switch format { + case .formatUnknown, .formatAllFormats: + continue + case .formatCode128: + rawValue |= 1 + case .formatCode39: + rawValue |= 2 + case .formatCode93: + rawValue |= 4 + case .formatCodabar: + rawValue |= 8 + case .formatDataMatrix: + rawValue |= 16 + case .formatEan13: + rawValue |= 32 + case .formatEan8: + rawValue |= 64 + case .formatItf: + rawValue |= 128 + case .formatQrCode: + rawValue |= 256 + case .formatUpcA: + rawValue |= 512 + case .formatUpcE: + rawValue |= 1024 + case .formatPdf417: + rawValue |= 2048 + case .formatAztec: + rawValue |= 4096 + } + } + + return MLKitBarcodeScanning.BarcodeFormat(rawValue: rawValue) + } + } +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Infrastructure/MLKit/Factories/TextRecognitionServiceFactory.swift b/ios/Infrastructure/MLKit/Factories/TextRecognitionServiceFactory.swift index 6cf5717..a5353e4 100644 --- a/ios/Infrastructure/MLKit/Factories/TextRecognitionServiceFactory.swift +++ b/ios/Infrastructure/MLKit/Factories/TextRecognitionServiceFactory.swift @@ -1,6 +1,6 @@ import Foundation -#if MLKIT_TEXT_RECOGNITION +#if MLKIT_TEXT_RECOGNITION_ANY import MLKitTextRecognition #endif @@ -20,10 +20,10 @@ import Foundation import MLKitTextRecognitionKorean #endif -#if MLKIT_TEXT_RECOGNITION +#if MLKIT_TEXT_RECOGNITION_ANY class TextRecognitionServiceFactory { - static func createTextRecognizer(language: TextRecognitionLanguage) + static func createTextRecognizer(language: DomainTextRecognitionLanguage) -> TextRecognizer { let options: CommonTextRecognizerOptions @@ -31,7 +31,7 @@ import Foundation switch language { #if MLKIT_TEXT_RECOGNITION case .latin: - options = TextRecognizerOptions() + options = MLKitTextRecognition.TextRecognizerOptions() #endif #if MLKIT_TEXT_RECOGNITION_CHINESE case .chinese: @@ -54,11 +54,11 @@ import Foundation return TextRecognizer.textRecognizer(options: options) } - static func create(language: TextRecognitionLanguage = .latin) + static func create(language: DomainTextRecognitionLanguage = .latin) -> MLKitTextRecognitionService { let textRecognizer = createTextRecognizer(language: language) return MLKitTextRecognitionService(textRecognizer: textRecognizer) } } -#endif +#endif // MLKIT_TEXT_RECOGNITION_ANY diff --git a/ios/Infrastructure/MLKit/MLKitBarcodeScanningService.swift b/ios/Infrastructure/MLKit/MLKitBarcodeScanningService.swift new file mode 100644 index 0000000..f217f6f --- /dev/null +++ b/ios/Infrastructure/MLKit/MLKitBarcodeScanningService.swift @@ -0,0 +1,20 @@ +import Foundation + +#if MLKIT_BARCODE_SCANNING + import MLKitBarcodeScanning + + class MLKitBarcodeScanningService: IRecognitionService { + typealias ResultType = BarcodeScanningResult + + private let barcodeScanner: BarcodeScanner + + init(barcodeScanner: BarcodeScanner) { + self.barcodeScanner = barcodeScanner + } + + func recognize(image: ProcessedImage) throws -> BarcodeScanningResult { + let barcodes = try barcodeScanner.results(in: image.image) + return MLKitBarcodeAdapter.toDomain(barcodes) + } + } +#endif // MLKIT_BARCODE_SCANNING diff --git a/ios/Infrastructure/MLKit/MLKitTextRecognitionService.swift b/ios/Infrastructure/MLKit/MLKitTextRecognitionService.swift index a2bfad0..b1d3f50 100644 --- a/ios/Infrastructure/MLKit/MLKitTextRecognitionService.swift +++ b/ios/Infrastructure/MLKit/MLKitTextRecognitionService.swift @@ -1,6 +1,6 @@ import Foundation -#if MLKIT_TEXT_RECOGNITION +#if MLKIT_TEXT_RECOGNITION_ANY import MLKitTextRecognition #endif @@ -20,9 +20,9 @@ import Foundation import MLKitTextRecognitionKorean #endif -#if MLKIT_TEXT_RECOGNITION +#if MLKIT_TEXT_RECOGNITION_ANY class MLKitTextRecognitionService: IRecognitionService { - typealias ResultType = TextRecognitionResult + typealias ResultType = DomainTextRecognitionResult private let textRecognizer: TextRecognizer @@ -30,9 +30,9 @@ import Foundation self.textRecognizer = textRecognizer } - func recognize(image: ProcessedImage) throws -> TextRecognitionResult { + func recognize(image: ProcessedImage) throws -> DomainTextRecognitionResult { let text = try textRecognizer.results(in: image.image) return MLKitTextAdapter.toDomain(text) } } -#endif +#endif // MLKIT_TEXT_RECOGNITION_ANY diff --git a/ios/Infrastructure/Modules/VisionCameraMLKitModule.swift b/ios/Infrastructure/Modules/VisionCameraMLKitModule.swift deleted file mode 100644 index 3ae6c6f..0000000 --- a/ios/Infrastructure/Modules/VisionCameraMLKitModule.swift +++ /dev/null @@ -1,35 +0,0 @@ -import Foundation -import React - -@objc(VisionCameraMLKitModule) -class VisionCameraMLKitModule: NSObject { - private lazy var handlers: [String: IStaticImageHandler] = [ - MLKitFeatureKeys.TEXT_RECOGNITION: StaticTextRecognitionHandler() - ] - - @objc - func processImage( - _ feature: String, - path: String, - options: Any?, - resolver resolve: @escaping RCTPromiseResolveBlock, - rejecter reject: @escaping RCTPromiseRejectBlock - ) { - let safeOptions = options as? [String: Any] ?? [:] - guard let handler = handlers[feature] else { - reject("UNSUPPORTED_FEATURE", "Feature \(feature) is not supported", nil) - return - } - - handler.process( - path: path, - options: safeOptions, - resolver: { result in resolve(result) }, - rejecter: { code, message, error in reject(code, message, error) } - ) - } - - @objc static func requiresMainQueueSetup() -> Bool { - false - } -} diff --git a/ios/Infrastructure/Serializers/TextRecognitionSerializer.swift b/ios/Infrastructure/Serializers/TextRecognitionSerializer.swift deleted file mode 100644 index 8112f52..0000000 --- a/ios/Infrastructure/Serializers/TextRecognitionSerializer.swift +++ /dev/null @@ -1,114 +0,0 @@ -import Foundation - -class TextRecognitionSerializer { - - static func toReactNativeMap(_ result: TextRecognitionResult) -> [String: Any] - { - var map = [String: Any]() - map["text"] = result.text - map["blocks"] = toBlocksArray(result.blocks) - return map - } - - private static func toBlocksArray(_ blocks: [TextBlock]) -> [[String: Any]] { - return blocks.map { toBlockMap($0) } - } - - private static func toBlockMap(_ block: TextBlock) -> [String: Any] { - var map = [String: Any]() - map["text"] = block.text - if let bounds = block.bounds { - map["bounds"] = toBoundsMap(bounds) - } - if let corners = block.corners { - map["corners"] = toCornersArray(corners) - } - map["lines"] = toLinesArray(block.lines) - map["languages"] = block.languages - return map - } - - private static func toLinesArray(_ lines: [TextLine]) -> [[String: Any]] { - return lines.map { toLineMap($0) } - } - - private static func toLineMap(_ line: TextLine) -> [String: Any] { - var map = [String: Any]() - map["text"] = line.text - if let bounds = line.bounds { - map["bounds"] = toBoundsMap(bounds) - } - if let corners = line.corners { - map["corners"] = toCornersArray(corners) - } - map["elements"] = toElementsArray(line.elements) - map["confidence"] = line.confidence - map["angle"] = line.angle - map["languages"] = line.languages - return map - } - - private static func toElementsArray(_ elements: [TextElement]) -> [[String: - Any]] - { - return elements.map { toElementMap($0) } - } - - private static func toElementMap(_ element: TextElement) -> [String: Any] { - var map = [String: Any]() - map["text"] = element.text - if let bounds = element.bounds { - map["bounds"] = toBoundsMap(bounds) - } - if let corners = element.corners { - map["corners"] = toCornersArray(corners) - } - map["symbols"] = element.symbols.map { toSymbolMap($0) } - map["confidence"] = element.confidence - map["angle"] = element.angle - map["languages"] = element.languages - return map - } - - private static func toSymbolMap(_ symbol: TextSymbol) -> [String: Any] { - var map = [String: Any]() - map["text"] = symbol.text - if let bounds = symbol.bounds { - map["bounds"] = toBoundsMap(bounds) - } - if let corners = symbol.corners { - map["corners"] = toCornersArray(corners) - } - map["confidence"] = symbol.confidence - map["angle"] = symbol.angle - map["languages"] = symbol.languages - return map - } - - private static func toBoundsMap(_ bounds: BoundingBox) -> [String: Double] { - return [ - "x": bounds.x, - "y": bounds.y, - "centerX": bounds.centerX, - "centerY": bounds.centerY, - "width": bounds.width, - "height": bounds.height, - "top": bounds.top, - "left": bounds.left, - "bottom": bounds.bottom, - "right": bounds.right, - ] - } - - private static func toCornersArray(_ corners: [Corner]) -> [[String: Double]] - { - return corners.map { toCornerMap($0) } - } - - private static func toCornerMap(_ corner: Corner) -> [String: Double] { - return [ - "x": corner.x, - "y": corner.y, - ] - } -} diff --git a/ios/VisionCameraMLKit-Bridging-Header.h b/ios/VisionCameraMLKit-Bridging-Header.h deleted file mode 100644 index 3fdf142..0000000 --- a/ios/VisionCameraMLKit-Bridging-Header.h +++ /dev/null @@ -1,4 +0,0 @@ -#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS -#import -#import -#endif diff --git a/ios/VisionCameraMLKit.mm b/ios/VisionCameraMLKit.mm deleted file mode 100644 index 0e49dce..0000000 --- a/ios/VisionCameraMLKit.mm +++ /dev/null @@ -1,37 +0,0 @@ -#import -#import -#import -#import -#import - -#if __has_include("VisionCameraMLKit/VisionCameraMLKit-Swift.h") -#import "VisionCameraMLKit/VisionCameraMLKit-Swift.h" -#else -#import "VisionCameraMLKit-Swift.h" -#endif - -@interface RCT_EXTERN_MODULE (VisionCameraMLKitModule, NSObject) -RCT_EXTERN_METHOD(processImage : (NSString *)feature path : ( - NSString *)path options : (id)options resolver : (RCTPromiseResolveBlock) - resolve rejecter : (RCTPromiseRejectBlock)reject) -@end - -#define REGISTER_PLUGIN(PLUGIN_CLASS, PLUGIN_NAME) \ - @interface PLUGIN_CLASS (FrameProcessorPluginLoader) \ - @end \ - \ - @implementation PLUGIN_CLASS (FrameProcessorPluginLoader) \ - +(void)load { \ - [FrameProcessorPluginRegistry \ - addFrameProcessorPlugin:PLUGIN_NAME \ - withInitializer:^FrameProcessorPlugin *( \ - VisionCameraProxyHolder * proxy, NSDictionary * options) { \ - return [[PLUGIN_CLASS alloc] initWithProxy:proxy \ - withOptions:options]; \ - }]; \ - } \ - @end - -#ifdef MLKIT_TEXT_RECOGNITION -REGISTER_PLUGIN(TextRecognitionPlugin, @"TextRecognition") -#endif diff --git a/nitro.json b/nitro.json new file mode 100644 index 0000000..1952026 --- /dev/null +++ b/nitro.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://nitro.margelo.com/nitro.schema.json", + "cxxNamespace": ["visioncameramlkit"], + "ios": { + "iosModuleName": "VisionCameraMLKit" + }, + "android": { + "androidNamespace": ["visioncameramlkit"], + "androidCxxLibName": "VisionCameraMLKit" + }, + "autolinking": { + "VisionCameraMLKit": { + "ios": { + "language": "swift", + "implementationClassName": "HybridVisionCameraMLKit" + }, + "android": { + "language": "kotlin", + "implementationClassName": "HybridVisionCameraMLKit" + } + } + }, + "ignorePaths": ["**/example/**", "**/node_modules/**"], + "gitAttributesGeneratedFlag": true +} diff --git a/nitrogen/generated/.gitattributes b/nitrogen/generated/.gitattributes new file mode 100644 index 0000000..fb7a0d5 --- /dev/null +++ b/nitrogen/generated/.gitattributes @@ -0,0 +1 @@ +** linguist-generated=true diff --git a/nitrogen/generated/android/VisionCameraMLKit+autolinking.cmake b/nitrogen/generated/android/VisionCameraMLKit+autolinking.cmake new file mode 100644 index 0000000..45a377a --- /dev/null +++ b/nitrogen/generated/android/VisionCameraMLKit+autolinking.cmake @@ -0,0 +1,86 @@ +# +# VisionCameraMLKit+autolinking.cmake +# This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +# https://github.com/mrousavy/nitro +# Copyright © Marc Rousavy @ Margelo +# + +# This is a CMake file that adds all files generated by Nitrogen +# to the current CMake project. +# +# To use it, add this to your CMakeLists.txt: +# ```cmake +# include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/VisionCameraMLKit+autolinking.cmake) +# ``` + +# Define a flag to check if we are building properly +add_definitions(-DBUILDING_VISIONCAMERAMLKIT_WITH_GENERATED_CMAKE_PROJECT) + +# Enable Raw Props parsing in react-native (for Nitro Views) +add_definitions(-DRN_SERIALIZABLE_STATE) + +# Add all headers that were generated by Nitrogen +include_directories( + "../nitrogen/generated/shared/c++" + "../nitrogen/generated/android/c++" + "../nitrogen/generated/android/" +) + +# Add all .cpp sources that were generated by Nitrogen +target_sources( + # CMake project name (Android C++ library name) + VisionCameraMLKit PRIVATE + # Autolinking Setup + ../nitrogen/generated/android/VisionCameraMLKitOnLoad.cpp + # Shared Nitrogen C++ sources + ../nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp + ../nitrogen/generated/shared/c++/HybridTextRecognizerSpec.cpp + ../nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.cpp + # Android-specific Nitrogen C++ sources + ../nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.cpp + ../nitrogen/generated/android/c++/JHybridTextRecognizerSpec.cpp + ../nitrogen/generated/android/c++/JVariant_NullType_Double.cpp + ../nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.cpp +) + +# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake +# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake +target_compile_definitions( + VisionCameraMLKit PRIVATE + -DFOLLY_NO_CONFIG=1 + -DFOLLY_HAVE_CLOCK_GETTIME=1 + -DFOLLY_USE_LIBCPP=1 + -DFOLLY_CFG_NO_COROUTINES=1 + -DFOLLY_MOBILE=1 + -DFOLLY_HAVE_RECVMMSG=1 + -DFOLLY_HAVE_PTHREAD=1 + # Once we target android-23 above, we can comment + # the following line. NDK uses GNU style stderror_r() after API 23. + -DFOLLY_HAVE_XSI_STRERROR_R=1 +) + +# Add all libraries required by the generated specs +find_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++ +find_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule) +find_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library + +# Link all libraries together +target_link_libraries( + VisionCameraMLKit + fbjni::fbjni # <-- Facebook C++ JNI helpers + ReactAndroid::jsi # <-- RN: JSI + react-native-nitro-modules::NitroModules # <-- NitroModules Core :) +) + +# Link react-native (different prefab between RN 0.75 and RN 0.76) +if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76) + target_link_libraries( + VisionCameraMLKit + ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab + ) +else() + target_link_libraries( + VisionCameraMLKit + ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core + ) +endif() diff --git a/nitrogen/generated/android/VisionCameraMLKit+autolinking.gradle b/nitrogen/generated/android/VisionCameraMLKit+autolinking.gradle new file mode 100644 index 0000000..de2ad60 --- /dev/null +++ b/nitrogen/generated/android/VisionCameraMLKit+autolinking.gradle @@ -0,0 +1,27 @@ +/// +/// VisionCameraMLKit+autolinking.gradle +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/// This is a Gradle file that adds all files generated by Nitrogen +/// to the current Gradle project. +/// +/// To use it, add this to your build.gradle: +/// ```gradle +/// apply from: '../nitrogen/generated/android/VisionCameraMLKit+autolinking.gradle' +/// ``` + +logger.warn("[NitroModules] 🔥 VisionCameraMLKit is boosted by nitro!") + +android { + sourceSets { + main { + java.srcDirs += [ + // Nitrogen files + "${project.projectDir}/../nitrogen/generated/android/kotlin" + ] + } + } +} diff --git a/nitrogen/generated/android/VisionCameraMLKitOnLoad.cpp b/nitrogen/generated/android/VisionCameraMLKitOnLoad.cpp new file mode 100644 index 0000000..8a5e802 --- /dev/null +++ b/nitrogen/generated/android/VisionCameraMLKitOnLoad.cpp @@ -0,0 +1,58 @@ +/// +/// VisionCameraMLKitOnLoad.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#ifndef BUILDING_VISIONCAMERAMLKIT_WITH_GENERATED_CMAKE_PROJECT +#error VisionCameraMLKitOnLoad.cpp is not being built with the autogenerated CMakeLists.txt project. Is a different CMakeLists.txt building this? +#endif + +#include "VisionCameraMLKitOnLoad.hpp" + +#include +#include +#include + +#include "JHybridBarcodeScannerSpec.hpp" +#include "JHybridTextRecognizerSpec.hpp" +#include "JHybridVisionCameraMLKitSpec.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + +int initialize(JavaVM* vm) { + return facebook::jni::initialize(vm, []() { + ::margelo::nitro::visioncameramlkit::registerAllNatives(); + }); +} + +struct JHybridVisionCameraMLKitSpecImpl: public jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKit;"; + static std::shared_ptr create() { + static const auto constructorFn = javaClassStatic()->getConstructor(); + jni::local_ref javaPart = javaClassStatic()->newObject(constructorFn); + return javaPart->getJHybridVisionCameraMLKitSpec(); + } +}; + +void registerAllNatives() { + using namespace margelo::nitro; + using namespace margelo::nitro::visioncameramlkit; + + // Register native JNI methods + margelo::nitro::visioncameramlkit::JHybridBarcodeScannerSpec::CxxPart::registerNatives(); + margelo::nitro::visioncameramlkit::JHybridTextRecognizerSpec::CxxPart::registerNatives(); + margelo::nitro::visioncameramlkit::JHybridVisionCameraMLKitSpec::CxxPart::registerNatives(); + + // Register Nitro Hybrid Objects + HybridObjectRegistry::registerHybridObjectConstructor( + "VisionCameraMLKit", + []() -> std::shared_ptr { + return JHybridVisionCameraMLKitSpecImpl::create(); + } + ); +} + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/VisionCameraMLKitOnLoad.hpp b/nitrogen/generated/android/VisionCameraMLKitOnLoad.hpp new file mode 100644 index 0000000..ae3c5bf --- /dev/null +++ b/nitrogen/generated/android/VisionCameraMLKitOnLoad.hpp @@ -0,0 +1,34 @@ +/// +/// VisionCameraMLKitOnLoad.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + [[deprecated("Use registerNatives() instead.")]] + int initialize(JavaVM* vm); + + /** + * Register the native (C++) part of VisionCameraMLKit, and autolinks all Hybrid Objects. + * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`), + * inside a `facebook::jni::initialize(vm, ...)` call. + * Example: + * ```cpp (cpp-adapter.cpp) + * JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + * return facebook::jni::initialize(vm, []() { + * // register all VisionCameraMLKit HybridObjects + * margelo::nitro::visioncameramlkit::registerNatives(); + * // any other custom registrations go here. + * }); + * } + * ``` + */ + void registerAllNatives(); + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBarcodeFormat.hpp b/nitrogen/generated/android/c++/JBarcodeFormat.hpp new file mode 100644 index 0000000..e7bac27 --- /dev/null +++ b/nitrogen/generated/android/c++/JBarcodeFormat.hpp @@ -0,0 +1,97 @@ +/// +/// JBarcodeFormat.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BarcodeFormat.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "BarcodeFormat" and the Kotlin enum "BarcodeFormat". + */ + struct JBarcodeFormat final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BarcodeFormat;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum BarcodeFormat. + */ + [[maybe_unused]] + [[nodiscard]] + BarcodeFormat toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(BarcodeFormat value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case BarcodeFormat::UNKNOWN: + static const auto fieldUNKNOWN = clazz->getStaticField("UNKNOWN"); + return clazz->getStaticFieldValue(fieldUNKNOWN); + case BarcodeFormat::ALL_FORMATS: + static const auto fieldALL_FORMATS = clazz->getStaticField("ALL_FORMATS"); + return clazz->getStaticFieldValue(fieldALL_FORMATS); + case BarcodeFormat::CODE_128: + static const auto fieldCODE_128 = clazz->getStaticField("CODE_128"); + return clazz->getStaticFieldValue(fieldCODE_128); + case BarcodeFormat::CODE_39: + static const auto fieldCODE_39 = clazz->getStaticField("CODE_39"); + return clazz->getStaticFieldValue(fieldCODE_39); + case BarcodeFormat::CODE_93: + static const auto fieldCODE_93 = clazz->getStaticField("CODE_93"); + return clazz->getStaticFieldValue(fieldCODE_93); + case BarcodeFormat::CODABAR: + static const auto fieldCODABAR = clazz->getStaticField("CODABAR"); + return clazz->getStaticFieldValue(fieldCODABAR); + case BarcodeFormat::DATA_MATRIX: + static const auto fieldDATA_MATRIX = clazz->getStaticField("DATA_MATRIX"); + return clazz->getStaticFieldValue(fieldDATA_MATRIX); + case BarcodeFormat::EAN_13: + static const auto fieldEAN_13 = clazz->getStaticField("EAN_13"); + return clazz->getStaticFieldValue(fieldEAN_13); + case BarcodeFormat::EAN_8: + static const auto fieldEAN_8 = clazz->getStaticField("EAN_8"); + return clazz->getStaticFieldValue(fieldEAN_8); + case BarcodeFormat::ITF: + static const auto fieldITF = clazz->getStaticField("ITF"); + return clazz->getStaticFieldValue(fieldITF); + case BarcodeFormat::QR_CODE: + static const auto fieldQR_CODE = clazz->getStaticField("QR_CODE"); + return clazz->getStaticFieldValue(fieldQR_CODE); + case BarcodeFormat::UPC_A: + static const auto fieldUPC_A = clazz->getStaticField("UPC_A"); + return clazz->getStaticFieldValue(fieldUPC_A); + case BarcodeFormat::UPC_E: + static const auto fieldUPC_E = clazz->getStaticField("UPC_E"); + return clazz->getStaticFieldValue(fieldUPC_E); + case BarcodeFormat::PDF417: + static const auto fieldPDF417 = clazz->getStaticField("PDF417"); + return clazz->getStaticFieldValue(fieldPDF417); + case BarcodeFormat::AZTEC: + static const auto fieldAZTEC = clazz->getStaticField("AZTEC"); + return clazz->getStaticFieldValue(fieldAZTEC); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBarcodeScannerBarcode.hpp b/nitrogen/generated/android/c++/JBarcodeScannerBarcode.hpp new file mode 100644 index 0000000..bc882bf --- /dev/null +++ b/nitrogen/generated/android/c++/JBarcodeScannerBarcode.hpp @@ -0,0 +1,137 @@ +/// +/// JBarcodeScannerBarcode.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BarcodeScannerBarcode.hpp" + +#include "BarcodeFormat.hpp" +#include "BarcodeValueTypeName.hpp" +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBarcodeFormat.hpp" +#include "JBarcodeValueTypeName.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "BarcodeScannerBarcode" and the Kotlin data class "BarcodeScannerBarcode". + */ + struct JBarcodeScannerBarcode final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BarcodeScannerBarcode;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct BarcodeScannerBarcode by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + BarcodeScannerBarcode toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBounds = clazz->getField("bounds"); + jni::local_ref bounds = this->getFieldValue(fieldBounds); + static const auto fieldCorners = clazz->getField>("corners"); + jni::local_ref> corners = this->getFieldValue(fieldCorners); + static const auto fieldFormat = clazz->getField("format"); + double format = this->getFieldValue(fieldFormat); + static const auto fieldFormatName = clazz->getField("formatName"); + jni::local_ref formatName = this->getFieldValue(fieldFormatName); + static const auto fieldValueType = clazz->getField("valueType"); + double valueType = this->getFieldValue(fieldValueType); + static const auto fieldValueTypeName = clazz->getField("valueTypeName"); + jni::local_ref valueTypeName = this->getFieldValue(fieldValueTypeName); + static const auto fieldRawValue = clazz->getField("rawValue"); + jni::local_ref rawValue = this->getFieldValue(fieldRawValue); + static const auto fieldDisplayValue = clazz->getField("displayValue"); + jni::local_ref displayValue = this->getFieldValue(fieldDisplayValue); + static const auto fieldRawBytes = clazz->getField("rawBytes"); + jni::local_ref rawBytes = this->getFieldValue(fieldRawBytes); + static const auto fieldValue = clazz->getField("value"); + jni::local_ref value = this->getFieldValue(fieldValue); + static const auto fieldIsPotential = clazz->getField("isPotential"); + jboolean isPotential = this->getFieldValue(fieldIsPotential); + return BarcodeScannerBarcode( + bounds != nullptr ? std::make_optional(bounds->toCpp()) : std::nullopt, + corners != nullptr ? std::make_optional([&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(corners)) : std::nullopt, + format, + formatName->toCpp(), + valueType, + valueTypeName->toCpp(), + rawValue != nullptr ? std::make_optional(rawValue->toStdString()) : std::nullopt, + displayValue != nullptr ? std::make_optional(displayValue->toStdString()) : std::nullopt, + rawBytes != nullptr ? std::make_optional([&]() { + size_t __size = rawBytes->size(); + std::vector __vector(__size); + rawBytes->getRegion(0, __size, __vector.data()); + return __vector; + }()) : std::nullopt, + value != nullptr ? std::make_optional(value->cthis()->getMap()) : std::nullopt, + static_cast(isPotential) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const BarcodeScannerBarcode& value) { + using JSignature = JBarcodeScannerBarcode(jni::alias_ref, jni::alias_ref>, double, jni::alias_ref, double, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jboolean); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.bounds.has_value() ? JBoundingBox::fromCpp(value.bounds.value()) : nullptr, + value.corners.has_value() ? [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JCorner::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.corners.value()) : nullptr, + value.format, + JBarcodeFormat::fromCpp(value.formatName), + value.valueType, + JBarcodeValueTypeName::fromCpp(value.valueTypeName), + value.rawValue.has_value() ? jni::make_jstring(value.rawValue.value()) : nullptr, + value.displayValue.has_value() ? jni::make_jstring(value.displayValue.value()) : nullptr, + value.rawBytes.has_value() ? [&]() { + size_t __size = value.rawBytes.value().size(); + jni::local_ref __array = jni::JArrayDouble::newArray(__size); + __array->setRegion(0, __size, value.rawBytes.value().data()); + return __array; + }() : nullptr, + value.value.has_value() ? JAnyMap::create(value.value.value()) : nullptr, + value.isPotential + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp b/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp new file mode 100644 index 0000000..3fecf07 --- /dev/null +++ b/nitrogen/generated/android/c++/JBarcodeScannerOptions.hpp @@ -0,0 +1,108 @@ +/// +/// JBarcodeScannerOptions.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BarcodeScannerOptions.hpp" + +#include "BarcodeFormat.hpp" +#include "JBarcodeFormat.hpp" +#include "JOrientation.hpp" +#include "JRegionOfInterest.hpp" +#include "JRegionOfInterestUnit.hpp" +#include "Orientation.hpp" +#include "RegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "BarcodeScannerOptions" and the Kotlin data class "BarcodeScannerOptions". + */ + struct JBarcodeScannerOptions final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BarcodeScannerOptions;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct BarcodeScannerOptions by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + BarcodeScannerOptions toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldFormats = clazz->getField>("formats"); + jni::local_ref> formats = this->getFieldValue(fieldFormats); + static const auto fieldEnableAllPotentialBarcodes = clazz->getField("enableAllPotentialBarcodes"); + jni::local_ref enableAllPotentialBarcodes = this->getFieldValue(fieldEnableAllPotentialBarcodes); + static const auto fieldScaleFactor = clazz->getField("scaleFactor"); + jni::local_ref scaleFactor = this->getFieldValue(fieldScaleFactor); + static const auto fieldInvertColors = clazz->getField("invertColors"); + jni::local_ref invertColors = this->getFieldValue(fieldInvertColors); + static const auto fieldFrameProcessInterval = clazz->getField("frameProcessInterval"); + jni::local_ref frameProcessInterval = this->getFieldValue(fieldFrameProcessInterval); + static const auto fieldRoi = clazz->getField("roi"); + jni::local_ref roi = this->getFieldValue(fieldRoi); + static const auto fieldOrientation = clazz->getField("orientation"); + jni::local_ref orientation = this->getFieldValue(fieldOrientation); + return BarcodeScannerOptions( + formats != nullptr ? std::make_optional([&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(formats)) : std::nullopt, + enableAllPotentialBarcodes != nullptr ? std::make_optional(static_cast(enableAllPotentialBarcodes->value())) : std::nullopt, + scaleFactor != nullptr ? std::make_optional(scaleFactor->value()) : std::nullopt, + invertColors != nullptr ? std::make_optional(static_cast(invertColors->value())) : std::nullopt, + frameProcessInterval != nullptr ? std::make_optional(frameProcessInterval->value()) : std::nullopt, + roi != nullptr ? std::make_optional(roi->toCpp()) : std::nullopt, + orientation != nullptr ? std::make_optional(orientation->toCpp()) : std::nullopt + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const BarcodeScannerOptions& value) { + using JSignature = JBarcodeScannerOptions(jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.formats.has_value() ? [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JBarcodeFormat::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.formats.value()) : nullptr, + value.enableAllPotentialBarcodes.has_value() ? jni::JBoolean::valueOf(value.enableAllPotentialBarcodes.value()) : nullptr, + value.scaleFactor.has_value() ? jni::JDouble::valueOf(value.scaleFactor.value()) : nullptr, + value.invertColors.has_value() ? jni::JBoolean::valueOf(value.invertColors.value()) : nullptr, + value.frameProcessInterval.has_value() ? jni::JDouble::valueOf(value.frameProcessInterval.value()) : nullptr, + value.roi.has_value() ? JRegionOfInterest::fromCpp(value.roi.value()) : nullptr, + value.orientation.has_value() ? JOrientation::fromCpp(value.orientation.value()) : nullptr + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBarcodeScannerResult.hpp b/nitrogen/generated/android/c++/JBarcodeScannerResult.hpp new file mode 100644 index 0000000..cd0a0c0 --- /dev/null +++ b/nitrogen/generated/android/c++/JBarcodeScannerResult.hpp @@ -0,0 +1,89 @@ +/// +/// JBarcodeScannerResult.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BarcodeScannerResult.hpp" + +#include "BarcodeFormat.hpp" +#include "BarcodeScannerBarcode.hpp" +#include "BarcodeValueTypeName.hpp" +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBarcodeFormat.hpp" +#include "JBarcodeScannerBarcode.hpp" +#include "JBarcodeValueTypeName.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "BarcodeScannerResult" and the Kotlin data class "BarcodeScannerResult". + */ + struct JBarcodeScannerResult final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BarcodeScannerResult;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct BarcodeScannerResult by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + BarcodeScannerResult toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBarcodes = clazz->getField>("barcodes"); + jni::local_ref> barcodes = this->getFieldValue(fieldBarcodes); + return BarcodeScannerResult( + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(barcodes) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const BarcodeScannerResult& value) { + using JSignature = JBarcodeScannerResult(jni::alias_ref>); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JBarcodeScannerBarcode::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.barcodes) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBarcodeValueTypeName.hpp b/nitrogen/generated/android/c++/JBarcodeValueTypeName.hpp new file mode 100644 index 0000000..6393072 --- /dev/null +++ b/nitrogen/generated/android/c++/JBarcodeValueTypeName.hpp @@ -0,0 +1,91 @@ +/// +/// JBarcodeValueTypeName.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BarcodeValueTypeName.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "BarcodeValueTypeName" and the Kotlin enum "BarcodeValueTypeName". + */ + struct JBarcodeValueTypeName final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BarcodeValueTypeName;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum BarcodeValueTypeName. + */ + [[maybe_unused]] + [[nodiscard]] + BarcodeValueTypeName toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(BarcodeValueTypeName value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case BarcodeValueTypeName::TYPE_UNKNOWN: + static const auto fieldTYPE_UNKNOWN = clazz->getStaticField("TYPE_UNKNOWN"); + return clazz->getStaticFieldValue(fieldTYPE_UNKNOWN); + case BarcodeValueTypeName::TYPE_CONTACT_INFO: + static const auto fieldTYPE_CONTACT_INFO = clazz->getStaticField("TYPE_CONTACT_INFO"); + return clazz->getStaticFieldValue(fieldTYPE_CONTACT_INFO); + case BarcodeValueTypeName::TYPE_EMAIL: + static const auto fieldTYPE_EMAIL = clazz->getStaticField("TYPE_EMAIL"); + return clazz->getStaticFieldValue(fieldTYPE_EMAIL); + case BarcodeValueTypeName::TYPE_ISBN: + static const auto fieldTYPE_ISBN = clazz->getStaticField("TYPE_ISBN"); + return clazz->getStaticFieldValue(fieldTYPE_ISBN); + case BarcodeValueTypeName::TYPE_PHONE: + static const auto fieldTYPE_PHONE = clazz->getStaticField("TYPE_PHONE"); + return clazz->getStaticFieldValue(fieldTYPE_PHONE); + case BarcodeValueTypeName::TYPE_PRODUCT: + static const auto fieldTYPE_PRODUCT = clazz->getStaticField("TYPE_PRODUCT"); + return clazz->getStaticFieldValue(fieldTYPE_PRODUCT); + case BarcodeValueTypeName::TYPE_SMS: + static const auto fieldTYPE_SMS = clazz->getStaticField("TYPE_SMS"); + return clazz->getStaticFieldValue(fieldTYPE_SMS); + case BarcodeValueTypeName::TYPE_TEXT: + static const auto fieldTYPE_TEXT = clazz->getStaticField("TYPE_TEXT"); + return clazz->getStaticFieldValue(fieldTYPE_TEXT); + case BarcodeValueTypeName::TYPE_URL: + static const auto fieldTYPE_URL = clazz->getStaticField("TYPE_URL"); + return clazz->getStaticFieldValue(fieldTYPE_URL); + case BarcodeValueTypeName::TYPE_WIFI: + static const auto fieldTYPE_WIFI = clazz->getStaticField("TYPE_WIFI"); + return clazz->getStaticFieldValue(fieldTYPE_WIFI); + case BarcodeValueTypeName::TYPE_GEO: + static const auto fieldTYPE_GEO = clazz->getStaticField("TYPE_GEO"); + return clazz->getStaticFieldValue(fieldTYPE_GEO); + case BarcodeValueTypeName::TYPE_CALENDAR_EVENT: + static const auto fieldTYPE_CALENDAR_EVENT = clazz->getStaticField("TYPE_CALENDAR_EVENT"); + return clazz->getStaticFieldValue(fieldTYPE_CALENDAR_EVENT); + case BarcodeValueTypeName::TYPE_DRIVER_LICENSE: + static const auto fieldTYPE_DRIVER_LICENSE = clazz->getStaticField("TYPE_DRIVER_LICENSE"); + return clazz->getStaticFieldValue(fieldTYPE_DRIVER_LICENSE); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JBoundingBox.hpp b/nitrogen/generated/android/c++/JBoundingBox.hpp new file mode 100644 index 0000000..7905314 --- /dev/null +++ b/nitrogen/generated/android/c++/JBoundingBox.hpp @@ -0,0 +1,93 @@ +/// +/// JBoundingBox.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "BoundingBox.hpp" + + + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "BoundingBox" and the Kotlin data class "BoundingBox". + */ + struct JBoundingBox final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/BoundingBox;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct BoundingBox by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + BoundingBox toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldX = clazz->getField("x"); + double x = this->getFieldValue(fieldX); + static const auto fieldY = clazz->getField("y"); + double y = this->getFieldValue(fieldY); + static const auto fieldCenterX = clazz->getField("centerX"); + double centerX = this->getFieldValue(fieldCenterX); + static const auto fieldCenterY = clazz->getField("centerY"); + double centerY = this->getFieldValue(fieldCenterY); + static const auto fieldWidth = clazz->getField("width"); + double width = this->getFieldValue(fieldWidth); + static const auto fieldHeight = clazz->getField("height"); + double height = this->getFieldValue(fieldHeight); + static const auto fieldTop = clazz->getField("top"); + double top = this->getFieldValue(fieldTop); + static const auto fieldLeft = clazz->getField("left"); + double left = this->getFieldValue(fieldLeft); + static const auto fieldBottom = clazz->getField("bottom"); + double bottom = this->getFieldValue(fieldBottom); + static const auto fieldRight = clazz->getField("right"); + double right = this->getFieldValue(fieldRight); + return BoundingBox( + x, + y, + centerX, + centerY, + width, + height, + top, + left, + bottom, + right + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const BoundingBox& value) { + using JSignature = JBoundingBox(double, double, double, double, double, double, double, double, double, double); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.x, + value.y, + value.centerX, + value.centerY, + value.width, + value.height, + value.top, + value.left, + value.bottom, + value.right + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JCorner.hpp b/nitrogen/generated/android/c++/JCorner.hpp new file mode 100644 index 0000000..227cf63 --- /dev/null +++ b/nitrogen/generated/android/c++/JCorner.hpp @@ -0,0 +1,61 @@ +/// +/// JCorner.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "Corner.hpp" + + + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "Corner" and the Kotlin data class "Corner". + */ + struct JCorner final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/Corner;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct Corner by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + Corner toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldX = clazz->getField("x"); + double x = this->getFieldValue(fieldX); + static const auto fieldY = clazz->getField("y"); + double y = this->getFieldValue(fieldY); + return Corner( + x, + y + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const Corner& value) { + using JSignature = JCorner(double, double); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.x, + value.y + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.cpp b/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.cpp new file mode 100644 index 0000000..12e2b59 --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.cpp @@ -0,0 +1,111 @@ +/// +/// JHybridBarcodeScannerSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "JHybridBarcodeScannerSpec.hpp" + +// Forward declaration of `BarcodeScannerResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerResult; } +// Forward declaration of `BarcodeScannerBarcode` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerBarcode; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `BarcodeValueTypeName` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeValueTypeName; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "BarcodeScannerResult.hpp" +#include "JBarcodeScannerResult.hpp" +#include "BarcodeScannerBarcode.hpp" +#include +#include "JBarcodeScannerBarcode.hpp" +#include "BoundingBox.hpp" +#include +#include "JBoundingBox.hpp" +#include "Corner.hpp" +#include "JCorner.hpp" +#include "BarcodeFormat.hpp" +#include "JBarcodeFormat.hpp" +#include "BarcodeValueTypeName.hpp" +#include "JBarcodeValueTypeName.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include "MLKitBaseArguments.hpp" +#include "JMLKitBaseArguments.hpp" +#include "Orientation.hpp" +#include "JOrientation.hpp" + +namespace margelo::nitro::visioncameramlkit { + + std::shared_ptr JHybridBarcodeScannerSpec::JavaPart::getJHybridBarcodeScannerSpec() { + auto hybridObject = JHybridObject::JavaPart::getJHybridObject(); + auto castHybridObject = std::dynamic_pointer_cast(hybridObject); + if (castHybridObject == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to downcast JHybridObject to JHybridBarcodeScannerSpec!"); + } + return castHybridObject; + } + + jni::local_ref JHybridBarcodeScannerSpec::CxxPart::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); + } + + std::shared_ptr JHybridBarcodeScannerSpec::CxxPart::createHybridObject(const jni::local_ref& javaPart) { + auto castJavaPart = jni::dynamic_ref_cast(javaPart); + if (castJavaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridBarcodeScannerSpec::JavaPart!"); + } + return std::make_shared(castJavaPart); + } + + void JHybridBarcodeScannerSpec::CxxPart::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JHybridBarcodeScannerSpec::CxxPart::initHybrid), + }); + } + + // Properties + + + // Methods + BarcodeScannerResult JHybridBarcodeScannerSpec::recognize(const std::shared_ptr& frame, const std::optional& args) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* frame */, jni::alias_ref /* args */)>("recognize"); + auto __result = method(_javaPart, std::dynamic_pointer_cast(frame)->getJavaPart(), args.has_value() ? JMLKitBaseArguments::fromCpp(args.value()) : nullptr); + return __result->toCpp(); + } + std::shared_ptr> JHybridBarcodeScannerSpec::recognizeImage(const std::string& uri) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* uri */)>("recognizeImage"); + auto __result = method(_javaPart, jni::make_jstring(uri)); + return [&]() { + auto __promise = Promise::create(); + __result->cthis()->addOnResolvedListener([=](const jni::alias_ref& __boxedResult) { + auto __result = jni::static_ref_cast(__boxedResult); + __promise->resolve(__result->toCpp()); + }); + __result->cthis()->addOnRejectedListener([=](const jni::alias_ref& __throwable) { + jni::JniException __jniError(__throwable); + __promise->reject(std::make_exception_ptr(__jniError)); + }); + return __promise; + }(); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.hpp b/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.hpp new file mode 100644 index 0000000..9c21a2a --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridBarcodeScannerSpec.hpp @@ -0,0 +1,64 @@ +/// +/// HybridBarcodeScannerSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include +#include "HybridBarcodeScannerSpec.hpp" + + + + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + class JHybridBarcodeScannerSpec: public virtual HybridBarcodeScannerSpec, public virtual JHybridObject { + public: + struct JavaPart: public jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridBarcodeScannerSpec;"; + std::shared_ptr getJHybridBarcodeScannerSpec(); + }; + struct CxxPart: public jni::HybridClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridBarcodeScannerSpec$CxxPart;"; + static jni::local_ref initHybrid(jni::alias_ref jThis); + static void registerNatives(); + using HybridBase::HybridBase; + protected: + std::shared_ptr createHybridObject(const jni::local_ref& javaPart) override; + }; + + public: + explicit JHybridBarcodeScannerSpec(const jni::local_ref& javaPart): + HybridObject(HybridBarcodeScannerSpec::TAG), + JHybridObject(javaPart), + _javaPart(jni::make_global(javaPart)) {} + ~JHybridBarcodeScannerSpec() override { + // Hermes GC can destroy JS objects on a non-JNI Thread. + jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); + } + + public: + inline const jni::global_ref& getJavaPart() const noexcept { + return _javaPart; + } + + public: + // Properties + + + public: + // Methods + BarcodeScannerResult recognize(const std::shared_ptr& frame, const std::optional& args) override; + std::shared_ptr> recognizeImage(const std::string& uri) override; + + private: + jni::global_ref _javaPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.cpp b/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.cpp new file mode 100644 index 0000000..551a930 --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.cpp @@ -0,0 +1,117 @@ +/// +/// JHybridTextRecognizerSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "JHybridTextRecognizerSpec.hpp" + +// Forward declaration of `TextRecognitionResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognitionResult; } +// Forward declaration of `TextBlock` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextBlock; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `TextLine` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextLine; } +// Forward declaration of `TextElement` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextElement; } +// Forward declaration of `TextSymbol` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextSymbol; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "TextRecognitionResult.hpp" +#include "JTextRecognitionResult.hpp" +#include +#include "TextBlock.hpp" +#include +#include "JTextBlock.hpp" +#include "BoundingBox.hpp" +#include "JBoundingBox.hpp" +#include "Corner.hpp" +#include "JCorner.hpp" +#include "TextLine.hpp" +#include "JTextLine.hpp" +#include +#include +#include +#include "JVariant_NullType_Double.hpp" +#include +#include "TextElement.hpp" +#include "JTextElement.hpp" +#include "TextSymbol.hpp" +#include "JTextSymbol.hpp" +#include +#include +#include +#include +#include +#include "MLKitBaseArguments.hpp" +#include "JMLKitBaseArguments.hpp" +#include "Orientation.hpp" +#include "JOrientation.hpp" + +namespace margelo::nitro::visioncameramlkit { + + std::shared_ptr JHybridTextRecognizerSpec::JavaPart::getJHybridTextRecognizerSpec() { + auto hybridObject = JHybridObject::JavaPart::getJHybridObject(); + auto castHybridObject = std::dynamic_pointer_cast(hybridObject); + if (castHybridObject == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to downcast JHybridObject to JHybridTextRecognizerSpec!"); + } + return castHybridObject; + } + + jni::local_ref JHybridTextRecognizerSpec::CxxPart::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); + } + + std::shared_ptr JHybridTextRecognizerSpec::CxxPart::createHybridObject(const jni::local_ref& javaPart) { + auto castJavaPart = jni::dynamic_ref_cast(javaPart); + if (castJavaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridTextRecognizerSpec::JavaPart!"); + } + return std::make_shared(castJavaPart); + } + + void JHybridTextRecognizerSpec::CxxPart::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JHybridTextRecognizerSpec::CxxPart::initHybrid), + }); + } + + // Properties + + + // Methods + TextRecognitionResult JHybridTextRecognizerSpec::recognize(const std::shared_ptr& frame, const std::optional& args) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* frame */, jni::alias_ref /* args */)>("recognize"); + auto __result = method(_javaPart, std::dynamic_pointer_cast(frame)->getJavaPart(), args.has_value() ? JMLKitBaseArguments::fromCpp(args.value()) : nullptr); + return __result->toCpp(); + } + std::shared_ptr> JHybridTextRecognizerSpec::recognizeImage(const std::string& uri) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* uri */)>("recognizeImage"); + auto __result = method(_javaPart, jni::make_jstring(uri)); + return [&]() { + auto __promise = Promise::create(); + __result->cthis()->addOnResolvedListener([=](const jni::alias_ref& __boxedResult) { + auto __result = jni::static_ref_cast(__boxedResult); + __promise->resolve(__result->toCpp()); + }); + __result->cthis()->addOnRejectedListener([=](const jni::alias_ref& __throwable) { + jni::JniException __jniError(__throwable); + __promise->reject(std::make_exception_ptr(__jniError)); + }); + return __promise; + }(); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.hpp b/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.hpp new file mode 100644 index 0000000..69c4cfd --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridTextRecognizerSpec.hpp @@ -0,0 +1,64 @@ +/// +/// HybridTextRecognizerSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include +#include "HybridTextRecognizerSpec.hpp" + + + + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + class JHybridTextRecognizerSpec: public virtual HybridTextRecognizerSpec, public virtual JHybridObject { + public: + struct JavaPart: public jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridTextRecognizerSpec;"; + std::shared_ptr getJHybridTextRecognizerSpec(); + }; + struct CxxPart: public jni::HybridClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridTextRecognizerSpec$CxxPart;"; + static jni::local_ref initHybrid(jni::alias_ref jThis); + static void registerNatives(); + using HybridBase::HybridBase; + protected: + std::shared_ptr createHybridObject(const jni::local_ref& javaPart) override; + }; + + public: + explicit JHybridTextRecognizerSpec(const jni::local_ref& javaPart): + HybridObject(HybridTextRecognizerSpec::TAG), + JHybridObject(javaPart), + _javaPart(jni::make_global(javaPart)) {} + ~JHybridTextRecognizerSpec() override { + // Hermes GC can destroy JS objects on a non-JNI Thread. + jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); + } + + public: + inline const jni::global_ref& getJavaPart() const noexcept { + return _javaPart; + } + + public: + // Properties + + + public: + // Methods + TextRecognitionResult recognize(const std::shared_ptr& frame, const std::optional& args) override; + std::shared_ptr> recognizeImage(const std::string& uri) override; + + private: + jni::global_ref _javaPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.cpp b/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.cpp new file mode 100644 index 0000000..5be7333 --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.cpp @@ -0,0 +1,104 @@ +/// +/// JHybridVisionCameraMLKitSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "JHybridVisionCameraMLKitSpec.hpp" + +// Forward declaration of `HybridTextRecognizerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridTextRecognizerSpec; } +// Forward declaration of `HybridBarcodeScannerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridBarcodeScannerSpec; } +// Forward declaration of `MLKitFeature` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class MLKitFeature; } +// Forward declaration of `TextRecognizerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognizerOptions; } +// Forward declaration of `TextRecognitionLanguage` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class TextRecognitionLanguage; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `RegionOfInterestUnit` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class RegionOfInterestUnit; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } +// Forward declaration of `BarcodeScannerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerOptions; } +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } + +#include +#include "HybridTextRecognizerSpec.hpp" +#include "JHybridTextRecognizerSpec.hpp" +#include "HybridBarcodeScannerSpec.hpp" +#include "JHybridBarcodeScannerSpec.hpp" +#include "MLKitFeature.hpp" +#include "JMLKitFeature.hpp" +#include "TextRecognizerOptions.hpp" +#include "JTextRecognizerOptions.hpp" +#include "TextRecognitionLanguage.hpp" +#include +#include "JTextRecognitionLanguage.hpp" +#include "RegionOfInterest.hpp" +#include "JRegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include "JRegionOfInterestUnit.hpp" +#include "Orientation.hpp" +#include "JOrientation.hpp" +#include "BarcodeScannerOptions.hpp" +#include "JBarcodeScannerOptions.hpp" +#include "BarcodeFormat.hpp" +#include +#include "JBarcodeFormat.hpp" + +namespace margelo::nitro::visioncameramlkit { + + std::shared_ptr JHybridVisionCameraMLKitSpec::JavaPart::getJHybridVisionCameraMLKitSpec() { + auto hybridObject = JHybridObject::JavaPart::getJHybridObject(); + auto castHybridObject = std::dynamic_pointer_cast(hybridObject); + if (castHybridObject == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to downcast JHybridObject to JHybridVisionCameraMLKitSpec!"); + } + return castHybridObject; + } + + jni::local_ref JHybridVisionCameraMLKitSpec::CxxPart::initHybrid(jni::alias_ref jThis) { + return makeCxxInstance(jThis); + } + + std::shared_ptr JHybridVisionCameraMLKitSpec::CxxPart::createHybridObject(const jni::local_ref& javaPart) { + auto castJavaPart = jni::dynamic_ref_cast(javaPart); + if (castJavaPart == nullptr) [[unlikely]] { + throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridVisionCameraMLKitSpec::JavaPart!"); + } + return std::make_shared(castJavaPart); + } + + void JHybridVisionCameraMLKitSpec::CxxPart::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JHybridVisionCameraMLKitSpec::CxxPart::initHybrid), + }); + } + + // Properties + + + // Methods + bool JHybridVisionCameraMLKitSpec::isFeatureAvailable(MLKitFeature feature) { + static const auto method = _javaPart->javaClassStatic()->getMethod /* feature */)>("isFeatureAvailable"); + auto __result = method(_javaPart, JMLKitFeature::fromCpp(feature)); + return static_cast(__result); + } + std::shared_ptr JHybridVisionCameraMLKitSpec::createTextRecognizer(const TextRecognizerOptions& options) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* options */)>("createTextRecognizer"); + auto __result = method(_javaPart, JTextRecognizerOptions::fromCpp(options)); + return __result->getJHybridTextRecognizerSpec(); + } + std::shared_ptr JHybridVisionCameraMLKitSpec::createBarcodeScanner(const BarcodeScannerOptions& options) { + static const auto method = _javaPart->javaClassStatic()->getMethod(jni::alias_ref /* options */)>("createBarcodeScanner"); + auto __result = method(_javaPart, JBarcodeScannerOptions::fromCpp(options)); + return __result->getJHybridBarcodeScannerSpec(); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.hpp b/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.hpp new file mode 100644 index 0000000..13df72b --- /dev/null +++ b/nitrogen/generated/android/c++/JHybridVisionCameraMLKitSpec.hpp @@ -0,0 +1,65 @@ +/// +/// HybridVisionCameraMLKitSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include +#include "HybridVisionCameraMLKitSpec.hpp" + + + + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + class JHybridVisionCameraMLKitSpec: public virtual HybridVisionCameraMLKitSpec, public virtual JHybridObject { + public: + struct JavaPart: public jni::JavaClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKitSpec;"; + std::shared_ptr getJHybridVisionCameraMLKitSpec(); + }; + struct CxxPart: public jni::HybridClass { + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKitSpec$CxxPart;"; + static jni::local_ref initHybrid(jni::alias_ref jThis); + static void registerNatives(); + using HybridBase::HybridBase; + protected: + std::shared_ptr createHybridObject(const jni::local_ref& javaPart) override; + }; + + public: + explicit JHybridVisionCameraMLKitSpec(const jni::local_ref& javaPart): + HybridObject(HybridVisionCameraMLKitSpec::TAG), + JHybridObject(javaPart), + _javaPart(jni::make_global(javaPart)) {} + ~JHybridVisionCameraMLKitSpec() override { + // Hermes GC can destroy JS objects on a non-JNI Thread. + jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); }); + } + + public: + inline const jni::global_ref& getJavaPart() const noexcept { + return _javaPart; + } + + public: + // Properties + + + public: + // Methods + bool isFeatureAvailable(MLKitFeature feature) override; + std::shared_ptr createTextRecognizer(const TextRecognizerOptions& options) override; + std::shared_ptr createBarcodeScanner(const BarcodeScannerOptions& options) override; + + private: + jni::global_ref _javaPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JMLKitBaseArguments.hpp b/nitrogen/generated/android/c++/JMLKitBaseArguments.hpp new file mode 100644 index 0000000..9f998bf --- /dev/null +++ b/nitrogen/generated/android/c++/JMLKitBaseArguments.hpp @@ -0,0 +1,59 @@ +/// +/// JMLKitBaseArguments.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "MLKitBaseArguments.hpp" + +#include "JOrientation.hpp" +#include "Orientation.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "MLKitBaseArguments" and the Kotlin data class "MLKitBaseArguments". + */ + struct JMLKitBaseArguments final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/MLKitBaseArguments;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct MLKitBaseArguments by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + MLKitBaseArguments toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOutputOrientation = clazz->getField("outputOrientation"); + jni::local_ref outputOrientation = this->getFieldValue(fieldOutputOrientation); + return MLKitBaseArguments( + outputOrientation != nullptr ? std::make_optional(outputOrientation->toCpp()) : std::nullopt + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const MLKitBaseArguments& value) { + using JSignature = JMLKitBaseArguments(jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.outputOrientation.has_value() ? JOrientation::fromCpp(value.outputOrientation.value()) : nullptr + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JMLKitFeature.hpp b/nitrogen/generated/android/c++/JMLKitFeature.hpp new file mode 100644 index 0000000..b241ead --- /dev/null +++ b/nitrogen/generated/android/c++/JMLKitFeature.hpp @@ -0,0 +1,85 @@ +/// +/// JMLKitFeature.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "MLKitFeature.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "MLKitFeature" and the Kotlin enum "MLKitFeature". + */ + struct JMLKitFeature final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/MLKitFeature;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum MLKitFeature. + */ + [[maybe_unused]] + [[nodiscard]] + MLKitFeature toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(MLKitFeature value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case MLKitFeature::TEXTRECOGNITION: + static const auto fieldTEXTRECOGNITION = clazz->getStaticField("TEXTRECOGNITION"); + return clazz->getStaticFieldValue(fieldTEXTRECOGNITION); + case MLKitFeature::FACEDETECTION: + static const auto fieldFACEDETECTION = clazz->getStaticField("FACEDETECTION"); + return clazz->getStaticFieldValue(fieldFACEDETECTION); + case MLKitFeature::FACEMESHDETECTION: + static const auto fieldFACEMESHDETECTION = clazz->getStaticField("FACEMESHDETECTION"); + return clazz->getStaticFieldValue(fieldFACEMESHDETECTION); + case MLKitFeature::POSEDETECTION: + static const auto fieldPOSEDETECTION = clazz->getStaticField("POSEDETECTION"); + return clazz->getStaticFieldValue(fieldPOSEDETECTION); + case MLKitFeature::SELFIESEGMENTATION: + static const auto fieldSELFIESEGMENTATION = clazz->getStaticField("SELFIESEGMENTATION"); + return clazz->getStaticFieldValue(fieldSELFIESEGMENTATION); + case MLKitFeature::SUBJECTSEGMENTATION: + static const auto fieldSUBJECTSEGMENTATION = clazz->getStaticField("SUBJECTSEGMENTATION"); + return clazz->getStaticFieldValue(fieldSUBJECTSEGMENTATION); + case MLKitFeature::DOCUMENTSCANNER: + static const auto fieldDOCUMENTSCANNER = clazz->getStaticField("DOCUMENTSCANNER"); + return clazz->getStaticFieldValue(fieldDOCUMENTSCANNER); + case MLKitFeature::BARCODESCANNING: + static const auto fieldBARCODESCANNING = clazz->getStaticField("BARCODESCANNING"); + return clazz->getStaticFieldValue(fieldBARCODESCANNING); + case MLKitFeature::IMAGELABELING: + static const auto fieldIMAGELABELING = clazz->getStaticField("IMAGELABELING"); + return clazz->getStaticFieldValue(fieldIMAGELABELING); + case MLKitFeature::OBJECTDETECTION: + static const auto fieldOBJECTDETECTION = clazz->getStaticField("OBJECTDETECTION"); + return clazz->getStaticFieldValue(fieldOBJECTDETECTION); + case MLKitFeature::DIGITALINKRECOGNITION: + static const auto fieldDIGITALINKRECOGNITION = clazz->getStaticField("DIGITALINKRECOGNITION"); + return clazz->getStaticFieldValue(fieldDIGITALINKRECOGNITION); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JOrientation.hpp b/nitrogen/generated/android/c++/JOrientation.hpp new file mode 100644 index 0000000..2c6f089 --- /dev/null +++ b/nitrogen/generated/android/c++/JOrientation.hpp @@ -0,0 +1,64 @@ +/// +/// JOrientation.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "Orientation.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "Orientation" and the Kotlin enum "Orientation". + */ + struct JOrientation final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/Orientation;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum Orientation. + */ + [[maybe_unused]] + [[nodiscard]] + Orientation toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(Orientation value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case Orientation::PORTRAIT: + static const auto fieldPORTRAIT = clazz->getStaticField("PORTRAIT"); + return clazz->getStaticFieldValue(fieldPORTRAIT); + case Orientation::PORTRAIT_UPSIDE_DOWN: + static const auto fieldPORTRAIT_UPSIDE_DOWN = clazz->getStaticField("PORTRAIT_UPSIDE_DOWN"); + return clazz->getStaticFieldValue(fieldPORTRAIT_UPSIDE_DOWN); + case Orientation::LANDSCAPE_LEFT: + static const auto fieldLANDSCAPE_LEFT = clazz->getStaticField("LANDSCAPE_LEFT"); + return clazz->getStaticFieldValue(fieldLANDSCAPE_LEFT); + case Orientation::LANDSCAPE_RIGHT: + static const auto fieldLANDSCAPE_RIGHT = clazz->getStaticField("LANDSCAPE_RIGHT"); + return clazz->getStaticFieldValue(fieldLANDSCAPE_RIGHT); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JRegionOfInterest.hpp b/nitrogen/generated/android/c++/JRegionOfInterest.hpp new file mode 100644 index 0000000..0a5ce83 --- /dev/null +++ b/nitrogen/generated/android/c++/JRegionOfInterest.hpp @@ -0,0 +1,75 @@ +/// +/// JRegionOfInterest.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "RegionOfInterest.hpp" + +#include "JRegionOfInterestUnit.hpp" +#include "RegionOfInterestUnit.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "RegionOfInterest" and the Kotlin data class "RegionOfInterest". + */ + struct JRegionOfInterest final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/RegionOfInterest;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct RegionOfInterest by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + RegionOfInterest toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldX = clazz->getField("x"); + double x = this->getFieldValue(fieldX); + static const auto fieldY = clazz->getField("y"); + double y = this->getFieldValue(fieldY); + static const auto fieldWidth = clazz->getField("width"); + double width = this->getFieldValue(fieldWidth); + static const auto fieldHeight = clazz->getField("height"); + double height = this->getFieldValue(fieldHeight); + static const auto fieldUnit = clazz->getField("unit"); + jni::local_ref unit = this->getFieldValue(fieldUnit); + return RegionOfInterest( + x, + y, + width, + height, + unit != nullptr ? std::make_optional(unit->toCpp()) : std::nullopt + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const RegionOfInterest& value) { + using JSignature = JRegionOfInterest(double, double, double, double, jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.x, + value.y, + value.width, + value.height, + value.unit.has_value() ? JRegionOfInterestUnit::fromCpp(value.unit.value()) : nullptr + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JRegionOfInterestUnit.hpp b/nitrogen/generated/android/c++/JRegionOfInterestUnit.hpp new file mode 100644 index 0000000..6166c88 --- /dev/null +++ b/nitrogen/generated/android/c++/JRegionOfInterestUnit.hpp @@ -0,0 +1,58 @@ +/// +/// JRegionOfInterestUnit.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "RegionOfInterestUnit.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "RegionOfInterestUnit" and the Kotlin enum "RegionOfInterestUnit". + */ + struct JRegionOfInterestUnit final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/RegionOfInterestUnit;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum RegionOfInterestUnit. + */ + [[maybe_unused]] + [[nodiscard]] + RegionOfInterestUnit toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(RegionOfInterestUnit value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case RegionOfInterestUnit::NORMALIZED: + static const auto fieldNORMALIZED = clazz->getStaticField("NORMALIZED"); + return clazz->getStaticFieldValue(fieldNORMALIZED); + case RegionOfInterestUnit::PIXEL: + static const auto fieldPIXEL = clazz->getStaticField("PIXEL"); + return clazz->getStaticFieldValue(fieldPIXEL); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextBlock.hpp b/nitrogen/generated/android/c++/JTextBlock.hpp new file mode 100644 index 0000000..e2f8f1c --- /dev/null +++ b/nitrogen/generated/android/c++/JTextBlock.hpp @@ -0,0 +1,143 @@ +/// +/// JTextBlock.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextBlock.hpp" + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include "JTextElement.hpp" +#include "JTextLine.hpp" +#include "JTextSymbol.hpp" +#include "JVariant_NullType_Double.hpp" +#include "TextElement.hpp" +#include "TextLine.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextBlock" and the Kotlin data class "TextBlock". + */ + struct JTextBlock final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextBlock;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextBlock by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextBlock toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBounds = clazz->getField("bounds"); + jni::local_ref bounds = this->getFieldValue(fieldBounds); + static const auto fieldCorners = clazz->getField>("corners"); + jni::local_ref> corners = this->getFieldValue(fieldCorners); + static const auto fieldLanguages = clazz->getField>("languages"); + jni::local_ref> languages = this->getFieldValue(fieldLanguages); + static const auto fieldText = clazz->getField("text"); + jni::local_ref text = this->getFieldValue(fieldText); + static const auto fieldLines = clazz->getField>("lines"); + jni::local_ref> lines = this->getFieldValue(fieldLines); + return TextBlock( + bounds->toCpp(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(corners), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toStdString()); + } + return __vector; + }(languages), + text->toStdString(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(lines) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextBlock& value) { + using JSignature = JTextBlock(jni::alias_ref, jni::alias_ref>, jni::alias_ref>, jni::alias_ref, jni::alias_ref>); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + JBoundingBox::fromCpp(value.bounds), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JCorner::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.corners), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = jni::make_jstring(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.languages), + jni::make_jstring(value.text), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JTextLine::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.lines) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextElement.hpp b/nitrogen/generated/android/c++/JTextElement.hpp new file mode 100644 index 0000000..ee39031 --- /dev/null +++ b/nitrogen/generated/android/c++/JTextElement.hpp @@ -0,0 +1,147 @@ +/// +/// JTextElement.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextElement.hpp" + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include "JTextSymbol.hpp" +#include "JVariant_NullType_Double.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextElement" and the Kotlin data class "TextElement". + */ + struct JTextElement final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextElement;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextElement by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextElement toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBounds = clazz->getField("bounds"); + jni::local_ref bounds = this->getFieldValue(fieldBounds); + static const auto fieldCorners = clazz->getField>("corners"); + jni::local_ref> corners = this->getFieldValue(fieldCorners); + static const auto fieldConfidence = clazz->getField("confidence"); + jni::local_ref confidence = this->getFieldValue(fieldConfidence); + static const auto fieldAngle = clazz->getField("angle"); + jni::local_ref angle = this->getFieldValue(fieldAngle); + static const auto fieldLanguages = clazz->getField>("languages"); + jni::local_ref> languages = this->getFieldValue(fieldLanguages); + static const auto fieldText = clazz->getField("text"); + jni::local_ref text = this->getFieldValue(fieldText); + static const auto fieldSymbols = clazz->getField>("symbols"); + jni::local_ref> symbols = this->getFieldValue(fieldSymbols); + return TextElement( + bounds->toCpp(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(corners), + confidence != nullptr ? std::make_optional(confidence->toCpp()) : std::nullopt, + angle != nullptr ? std::make_optional(angle->toCpp()) : std::nullopt, + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toStdString()); + } + return __vector; + }(languages), + text->toStdString(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(symbols) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextElement& value) { + using JSignature = JTextElement(jni::alias_ref, jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref>, jni::alias_ref, jni::alias_ref>); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + JBoundingBox::fromCpp(value.bounds), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JCorner::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.corners), + value.confidence.has_value() ? JVariant_NullType_Double::fromCpp(value.confidence.value()) : nullptr, + value.angle.has_value() ? JVariant_NullType_Double::fromCpp(value.angle.value()) : nullptr, + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = jni::make_jstring(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.languages), + jni::make_jstring(value.text), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JTextSymbol::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.symbols) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextLine.hpp b/nitrogen/generated/android/c++/JTextLine.hpp new file mode 100644 index 0000000..ea33db4 --- /dev/null +++ b/nitrogen/generated/android/c++/JTextLine.hpp @@ -0,0 +1,149 @@ +/// +/// JTextLine.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextLine.hpp" + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include "JTextElement.hpp" +#include "JTextSymbol.hpp" +#include "JVariant_NullType_Double.hpp" +#include "TextElement.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextLine" and the Kotlin data class "TextLine". + */ + struct JTextLine final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextLine;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextLine by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextLine toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBounds = clazz->getField("bounds"); + jni::local_ref bounds = this->getFieldValue(fieldBounds); + static const auto fieldCorners = clazz->getField>("corners"); + jni::local_ref> corners = this->getFieldValue(fieldCorners); + static const auto fieldConfidence = clazz->getField("confidence"); + jni::local_ref confidence = this->getFieldValue(fieldConfidence); + static const auto fieldAngle = clazz->getField("angle"); + jni::local_ref angle = this->getFieldValue(fieldAngle); + static const auto fieldLanguages = clazz->getField>("languages"); + jni::local_ref> languages = this->getFieldValue(fieldLanguages); + static const auto fieldText = clazz->getField("text"); + jni::local_ref text = this->getFieldValue(fieldText); + static const auto fieldElements = clazz->getField>("elements"); + jni::local_ref> elements = this->getFieldValue(fieldElements); + return TextLine( + bounds->toCpp(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(corners), + confidence != nullptr ? std::make_optional(confidence->toCpp()) : std::nullopt, + angle != nullptr ? std::make_optional(angle->toCpp()) : std::nullopt, + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toStdString()); + } + return __vector; + }(languages), + text->toStdString(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(elements) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextLine& value) { + using JSignature = JTextLine(jni::alias_ref, jni::alias_ref>, jni::alias_ref, jni::alias_ref, jni::alias_ref>, jni::alias_ref, jni::alias_ref>); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + JBoundingBox::fromCpp(value.bounds), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JCorner::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.corners), + value.confidence.has_value() ? JVariant_NullType_Double::fromCpp(value.confidence.value()) : nullptr, + value.angle.has_value() ? JVariant_NullType_Double::fromCpp(value.angle.value()) : nullptr, + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = jni::make_jstring(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.languages), + jni::make_jstring(value.text), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JTextElement::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.elements) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextRecognitionLanguage.hpp b/nitrogen/generated/android/c++/JTextRecognitionLanguage.hpp new file mode 100644 index 0000000..0e3c461 --- /dev/null +++ b/nitrogen/generated/android/c++/JTextRecognitionLanguage.hpp @@ -0,0 +1,67 @@ +/// +/// JTextRecognitionLanguage.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextRecognitionLanguage.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "TextRecognitionLanguage" and the Kotlin enum "TextRecognitionLanguage". + */ + struct JTextRecognitionLanguage final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextRecognitionLanguage;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum TextRecognitionLanguage. + */ + [[maybe_unused]] + [[nodiscard]] + TextRecognitionLanguage toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(TextRecognitionLanguage value) { + static const auto clazz = javaClassStatic(); + switch (value) { + case TextRecognitionLanguage::LATIN: + static const auto fieldLATIN = clazz->getStaticField("LATIN"); + return clazz->getStaticFieldValue(fieldLATIN); + case TextRecognitionLanguage::CHINESE: + static const auto fieldCHINESE = clazz->getStaticField("CHINESE"); + return clazz->getStaticFieldValue(fieldCHINESE); + case TextRecognitionLanguage::DEVANAGARI: + static const auto fieldDEVANAGARI = clazz->getStaticField("DEVANAGARI"); + return clazz->getStaticFieldValue(fieldDEVANAGARI); + case TextRecognitionLanguage::JAPANESE: + static const auto fieldJAPANESE = clazz->getStaticField("JAPANESE"); + return clazz->getStaticFieldValue(fieldJAPANESE); + case TextRecognitionLanguage::KOREAN: + static const auto fieldKOREAN = clazz->getStaticField("KOREAN"); + return clazz->getStaticFieldValue(fieldKOREAN); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextRecognitionResult.hpp b/nitrogen/generated/android/c++/JTextRecognitionResult.hpp new file mode 100644 index 0000000..093ba58 --- /dev/null +++ b/nitrogen/generated/android/c++/JTextRecognitionResult.hpp @@ -0,0 +1,97 @@ +/// +/// JTextRecognitionResult.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextRecognitionResult.hpp" + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include "JTextBlock.hpp" +#include "JTextElement.hpp" +#include "JTextLine.hpp" +#include "JTextSymbol.hpp" +#include "JVariant_NullType_Double.hpp" +#include "TextBlock.hpp" +#include "TextElement.hpp" +#include "TextLine.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextRecognitionResult" and the Kotlin data class "TextRecognitionResult". + */ + struct JTextRecognitionResult final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextRecognitionResult;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextRecognitionResult by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextRecognitionResult toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldText = clazz->getField("text"); + jni::local_ref text = this->getFieldValue(fieldText); + static const auto fieldBlocks = clazz->getField>("blocks"); + jni::local_ref> blocks = this->getFieldValue(fieldBlocks); + return TextRecognitionResult( + text->toStdString(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(blocks) + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextRecognitionResult& value) { + using JSignature = JTextRecognitionResult(jni::alias_ref, jni::alias_ref>); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + jni::make_jstring(value.text), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JTextBlock::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.blocks) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextRecognizerOptions.hpp b/nitrogen/generated/android/c++/JTextRecognizerOptions.hpp new file mode 100644 index 0000000..d69be4f --- /dev/null +++ b/nitrogen/generated/android/c++/JTextRecognizerOptions.hpp @@ -0,0 +1,85 @@ +/// +/// JTextRecognizerOptions.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextRecognizerOptions.hpp" + +#include "JOrientation.hpp" +#include "JRegionOfInterest.hpp" +#include "JRegionOfInterestUnit.hpp" +#include "JTextRecognitionLanguage.hpp" +#include "Orientation.hpp" +#include "RegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include "TextRecognitionLanguage.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextRecognizerOptions" and the Kotlin data class "TextRecognizerOptions". + */ + struct JTextRecognizerOptions final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextRecognizerOptions;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextRecognizerOptions by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextRecognizerOptions toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldLanguage = clazz->getField("language"); + jni::local_ref language = this->getFieldValue(fieldLanguage); + static const auto fieldScaleFactor = clazz->getField("scaleFactor"); + jni::local_ref scaleFactor = this->getFieldValue(fieldScaleFactor); + static const auto fieldInvertColors = clazz->getField("invertColors"); + jni::local_ref invertColors = this->getFieldValue(fieldInvertColors); + static const auto fieldFrameProcessInterval = clazz->getField("frameProcessInterval"); + jni::local_ref frameProcessInterval = this->getFieldValue(fieldFrameProcessInterval); + static const auto fieldRoi = clazz->getField("roi"); + jni::local_ref roi = this->getFieldValue(fieldRoi); + static const auto fieldOrientation = clazz->getField("orientation"); + jni::local_ref orientation = this->getFieldValue(fieldOrientation); + return TextRecognizerOptions( + language != nullptr ? std::make_optional(language->toCpp()) : std::nullopt, + scaleFactor != nullptr ? std::make_optional(scaleFactor->value()) : std::nullopt, + invertColors != nullptr ? std::make_optional(static_cast(invertColors->value())) : std::nullopt, + frameProcessInterval != nullptr ? std::make_optional(frameProcessInterval->value()) : std::nullopt, + roi != nullptr ? std::make_optional(roi->toCpp()) : std::nullopt, + orientation != nullptr ? std::make_optional(orientation->toCpp()) : std::nullopt + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextRecognizerOptions& value) { + using JSignature = JTextRecognizerOptions(jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref, jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + value.language.has_value() ? JTextRecognitionLanguage::fromCpp(value.language.value()) : nullptr, + value.scaleFactor.has_value() ? jni::JDouble::valueOf(value.scaleFactor.value()) : nullptr, + value.invertColors.has_value() ? jni::JBoolean::valueOf(value.invertColors.value()) : nullptr, + value.frameProcessInterval.has_value() ? jni::JDouble::valueOf(value.frameProcessInterval.value()) : nullptr, + value.roi.has_value() ? JRegionOfInterest::fromCpp(value.roi.value()) : nullptr, + value.orientation.has_value() ? JOrientation::fromCpp(value.orientation.value()) : nullptr + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JTextSymbol.hpp b/nitrogen/generated/android/c++/JTextSymbol.hpp new file mode 100644 index 0000000..7349be5 --- /dev/null +++ b/nitrogen/generated/android/c++/JTextSymbol.hpp @@ -0,0 +1,118 @@ +/// +/// JTextSymbol.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "TextSymbol.hpp" + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "JBoundingBox.hpp" +#include "JCorner.hpp" +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "TextSymbol" and the Kotlin data class "TextSymbol". + */ + struct JTextSymbol final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/TextSymbol;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct TextSymbol by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + TextSymbol toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldBounds = clazz->getField("bounds"); + jni::local_ref bounds = this->getFieldValue(fieldBounds); + static const auto fieldCorners = clazz->getField>("corners"); + jni::local_ref> corners = this->getFieldValue(fieldCorners); + static const auto fieldConfidence = clazz->getField("confidence"); + double confidence = this->getFieldValue(fieldConfidence); + static const auto fieldAngle = clazz->getField("angle"); + double angle = this->getFieldValue(fieldAngle); + static const auto fieldLanguages = clazz->getField>("languages"); + jni::local_ref> languages = this->getFieldValue(fieldLanguages); + static const auto fieldText = clazz->getField("text"); + jni::local_ref text = this->getFieldValue(fieldText); + return TextSymbol( + bounds->toCpp(), + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(corners), + confidence, + angle, + [&](auto&& __input) { + size_t __size = __input->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __input->getElement(__i); + __vector.push_back(__element->toStdString()); + } + return __vector; + }(languages), + text->toStdString() + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const TextSymbol& value) { + using JSignature = JTextSymbol(jni::alias_ref, jni::alias_ref>, double, double, jni::alias_ref>, jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + JBoundingBox::fromCpp(value.bounds), + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = JCorner::fromCpp(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.corners), + value.confidence, + value.angle, + [&](auto&& __input) { + size_t __size = __input.size(); + jni::local_ref> __array = jni::JArrayClass::newArray(__size); + for (size_t __i = 0; __i < __size; __i++) { + const auto& __element = __input[__i]; + auto __elementJni = jni::make_jstring(__element); + __array->setElement(__i, *__elementJni); + } + return __array; + }(value.languages), + jni::make_jstring(value.text) + ); + } + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp b/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp new file mode 100644 index 0000000..855daf5 --- /dev/null +++ b/nitrogen/generated/android/c++/JVariant_NullType_Double.cpp @@ -0,0 +1,26 @@ +/// +/// JVariant_NullType_Double.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "JVariant_NullType_Double.hpp" + +namespace margelo::nitro::visioncameramlkit { + /** + * Converts JVariant_NullType_Double to std::variant + */ + std::variant JVariant_NullType_Double::toCpp() const { + if (isInstanceOf(JVariant_NullType_Double_impl::First::javaClassStatic())) { + // It's a `nitro::NullType` + auto jniValue = static_cast(this)->getValue(); + return nitro::null; + } else if (isInstanceOf(JVariant_NullType_Double_impl::Second::javaClassStatic())) { + // It's a `double` + auto jniValue = static_cast(this)->getValue(); + return jniValue; + } + throw std::invalid_argument("Variant is unknown Kotlin instance!"); + } +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp b/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp new file mode 100644 index 0000000..4a5e380 --- /dev/null +++ b/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp @@ -0,0 +1,69 @@ +/// +/// JVariant_NullType_Double.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include + +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ std::variant and the Java class "Variant_NullType_Double". + */ + class JVariant_NullType_Double: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/Variant_NullType_Double;"; + + static jni::local_ref create_0(jni::alias_ref value) { + static const auto method = javaClassStatic()->getStaticMethod)>("create"); + return method(javaClassStatic(), value); + } + static jni::local_ref create_1(double value) { + static const auto method = javaClassStatic()->getStaticMethod("create"); + return method(javaClassStatic(), value); + } + + static jni::local_ref fromCpp(const std::variant& variant) { + switch (variant.index()) { + case 0: return create_0(JNull::null()); + case 1: return create_1(std::get<1>(variant)); + default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")"); + } + } + + [[nodiscard]] std::variant toCpp() const; + }; + + namespace JVariant_NullType_Double_impl { + class First final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/Variant_NullType_Double$First;"; + + [[nodiscard]] jni::local_ref getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + + class Second final: public jni::JavaClass { + public: + static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/visioncameramlkit/Variant_NullType_Double$Second;"; + + [[nodiscard]] double getValue() const { + static const auto field = javaClassStatic()->getField("value"); + return getFieldValue(field); + } + }; + } // namespace JVariant_NullType_Double_impl +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeFormat.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeFormat.kt new file mode 100644 index 0000000..48de5ae --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeFormat.kt @@ -0,0 +1,36 @@ +/// +/// BarcodeFormat.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "BarcodeFormat". + */ +@DoNotStrip +@Keep +enum class BarcodeFormat(@DoNotStrip @Keep val value: Int) { + UNKNOWN(0), + ALL_FORMATS(1), + CODE_128(2), + CODE_39(3), + CODE_93(4), + CODABAR(5), + DATA_MATRIX(6), + EAN_13(7), + EAN_8(8), + ITF(9), + QR_CODE(10), + UPC_A(11), + UPC_E(12), + PDF417(13), + AZTEC(14); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerBarcode.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerBarcode.kt new file mode 100644 index 0000000..5939fc7 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerBarcode.kt @@ -0,0 +1,101 @@ +/// +/// BarcodeScannerBarcode.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects +import com.margelo.nitro.core.AnyMap + +/** + * Represents the JavaScript object/struct "BarcodeScannerBarcode". + */ +@DoNotStrip +@Keep +data class BarcodeScannerBarcode( + @DoNotStrip + @Keep + val bounds: BoundingBox?, + @DoNotStrip + @Keep + val corners: Array?, + @DoNotStrip + @Keep + val format: Double, + @DoNotStrip + @Keep + val formatName: BarcodeFormat, + @DoNotStrip + @Keep + val valueType: Double, + @DoNotStrip + @Keep + val valueTypeName: BarcodeValueTypeName, + @DoNotStrip + @Keep + val rawValue: String?, + @DoNotStrip + @Keep + val displayValue: String?, + @DoNotStrip + @Keep + val rawBytes: DoubleArray?, + @DoNotStrip + @Keep + val value: AnyMap?, + @DoNotStrip + @Keep + val isPotential: Boolean +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is BarcodeScannerBarcode) return false + return Objects.deepEquals(this.bounds, other.bounds) + && Objects.deepEquals(this.corners, other.corners) + && Objects.deepEquals(this.format, other.format) + && Objects.deepEquals(this.formatName, other.formatName) + && Objects.deepEquals(this.valueType, other.valueType) + && Objects.deepEquals(this.valueTypeName, other.valueTypeName) + && Objects.deepEquals(this.rawValue, other.rawValue) + && Objects.deepEquals(this.displayValue, other.displayValue) + && Objects.deepEquals(this.rawBytes, other.rawBytes) + && Objects.deepEquals(this.value, other.value) + && Objects.deepEquals(this.isPotential, other.isPotential) + } + + override fun hashCode(): Int { + return arrayOf( + bounds, + corners, + format, + formatName, + valueType, + valueTypeName, + rawValue, + displayValue, + rawBytes, + value, + isPotential + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(bounds: BoundingBox?, corners: Array?, format: Double, formatName: BarcodeFormat, valueType: Double, valueTypeName: BarcodeValueTypeName, rawValue: String?, displayValue: String?, rawBytes: DoubleArray?, value: AnyMap?, isPotential: Boolean): BarcodeScannerBarcode { + return BarcodeScannerBarcode(bounds, corners, format, formatName, valueType, valueTypeName, rawValue, displayValue, rawBytes, value, isPotential) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions.kt new file mode 100644 index 0000000..da34102 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerOptions.kt @@ -0,0 +1,81 @@ +/// +/// BarcodeScannerOptions.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "BarcodeScannerOptions". + */ +@DoNotStrip +@Keep +data class BarcodeScannerOptions( + @DoNotStrip + @Keep + val formats: Array?, + @DoNotStrip + @Keep + val enableAllPotentialBarcodes: Boolean?, + @DoNotStrip + @Keep + val scaleFactor: Double?, + @DoNotStrip + @Keep + val invertColors: Boolean?, + @DoNotStrip + @Keep + val frameProcessInterval: Double?, + @DoNotStrip + @Keep + val roi: RegionOfInterest?, + @DoNotStrip + @Keep + val orientation: Orientation? +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is BarcodeScannerOptions) return false + return Objects.deepEquals(this.formats, other.formats) + && Objects.deepEquals(this.enableAllPotentialBarcodes, other.enableAllPotentialBarcodes) + && Objects.deepEquals(this.scaleFactor, other.scaleFactor) + && Objects.deepEquals(this.invertColors, other.invertColors) + && Objects.deepEquals(this.frameProcessInterval, other.frameProcessInterval) + && Objects.deepEquals(this.roi, other.roi) + && Objects.deepEquals(this.orientation, other.orientation) + } + + override fun hashCode(): Int { + return arrayOf( + formats, + enableAllPotentialBarcodes, + scaleFactor, + invertColors, + frameProcessInterval, + roi, + orientation + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(formats: Array?, enableAllPotentialBarcodes: Boolean?, scaleFactor: Double?, invertColors: Boolean?, frameProcessInterval: Double?, roi: RegionOfInterest?, orientation: Orientation?): BarcodeScannerOptions { + return BarcodeScannerOptions(formats, enableAllPotentialBarcodes, scaleFactor, invertColors, frameProcessInterval, roi, orientation) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerResult.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerResult.kt new file mode 100644 index 0000000..2fff1d5 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeScannerResult.kt @@ -0,0 +1,51 @@ +/// +/// BarcodeScannerResult.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "BarcodeScannerResult". + */ +@DoNotStrip +@Keep +data class BarcodeScannerResult( + @DoNotStrip + @Keep + val barcodes: Array +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is BarcodeScannerResult) return false + return Objects.deepEquals(this.barcodes, other.barcodes) + } + + override fun hashCode(): Int { + return arrayOf( + barcodes + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(barcodes: Array): BarcodeScannerResult { + return BarcodeScannerResult(barcodes) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeValueTypeName.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeValueTypeName.kt new file mode 100644 index 0000000..ef833da --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BarcodeValueTypeName.kt @@ -0,0 +1,34 @@ +/// +/// BarcodeValueTypeName.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "BarcodeValueTypeName". + */ +@DoNotStrip +@Keep +enum class BarcodeValueTypeName(@DoNotStrip @Keep val value: Int) { + TYPE_UNKNOWN(0), + TYPE_CONTACT_INFO(1), + TYPE_EMAIL(2), + TYPE_ISBN(3), + TYPE_PHONE(4), + TYPE_PRODUCT(5), + TYPE_SMS(6), + TYPE_TEXT(7), + TYPE_URL(8), + TYPE_WIFI(9), + TYPE_GEO(10), + TYPE_CALENDAR_EVENT(11), + TYPE_DRIVER_LICENSE(12); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BoundingBox.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BoundingBox.kt new file mode 100644 index 0000000..2ccfc45 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/BoundingBox.kt @@ -0,0 +1,96 @@ +/// +/// BoundingBox.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "BoundingBox". + */ +@DoNotStrip +@Keep +data class BoundingBox( + @DoNotStrip + @Keep + val x: Double, + @DoNotStrip + @Keep + val y: Double, + @DoNotStrip + @Keep + val centerX: Double, + @DoNotStrip + @Keep + val centerY: Double, + @DoNotStrip + @Keep + val width: Double, + @DoNotStrip + @Keep + val height: Double, + @DoNotStrip + @Keep + val top: Double, + @DoNotStrip + @Keep + val left: Double, + @DoNotStrip + @Keep + val bottom: Double, + @DoNotStrip + @Keep + val right: Double +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is BoundingBox) return false + return Objects.deepEquals(this.x, other.x) + && Objects.deepEquals(this.y, other.y) + && Objects.deepEquals(this.centerX, other.centerX) + && Objects.deepEquals(this.centerY, other.centerY) + && Objects.deepEquals(this.width, other.width) + && Objects.deepEquals(this.height, other.height) + && Objects.deepEquals(this.top, other.top) + && Objects.deepEquals(this.left, other.left) + && Objects.deepEquals(this.bottom, other.bottom) + && Objects.deepEquals(this.right, other.right) + } + + override fun hashCode(): Int { + return arrayOf( + x, + y, + centerX, + centerY, + width, + height, + top, + left, + bottom, + right + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(x: Double, y: Double, centerX: Double, centerY: Double, width: Double, height: Double, top: Double, left: Double, bottom: Double, right: Double): BoundingBox { + return BoundingBox(x, y, centerX, centerY, width, height, top, left, bottom, right) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Corner.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Corner.kt new file mode 100644 index 0000000..3dfc9bc --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Corner.kt @@ -0,0 +1,56 @@ +/// +/// Corner.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "Corner". + */ +@DoNotStrip +@Keep +data class Corner( + @DoNotStrip + @Keep + val x: Double, + @DoNotStrip + @Keep + val y: Double +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Corner) return false + return Objects.deepEquals(this.x, other.x) + && Objects.deepEquals(this.y, other.y) + } + + override fun hashCode(): Int { + return arrayOf( + x, + y + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(x: Double, y: Double): Corner { + return Corner(x, y) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridBarcodeScannerSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridBarcodeScannerSpec.kt new file mode 100644 index 0000000..8ffcd0d --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridBarcodeScannerSpec.kt @@ -0,0 +1,60 @@ +/// +/// HybridBarcodeScannerSpec.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.camera.HybridFrameSpec +import com.margelo.nitro.core.Promise +import com.margelo.nitro.core.HybridObject + +/** + * A Kotlin class representing the BarcodeScanner HybridObject. + * Implement this abstract class to create Kotlin-based instances of BarcodeScanner. + */ +@DoNotStrip +@Keep +@Suppress( + "KotlinJniMissingFunction", "unused", + "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", + "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" +) +abstract class HybridBarcodeScannerSpec: HybridObject() { + // Properties + + + // Methods + @DoNotStrip + @Keep + abstract fun recognize(frame: com.margelo.nitro.camera.HybridFrameSpec, args: MLKitBaseArguments?): BarcodeScannerResult + + @DoNotStrip + @Keep + abstract fun recognizeImage(uri: String): Promise + + // Default implementation of `HybridObject.toString()` + override fun toString(): String { + return "[HybridObject BarcodeScanner]" + } + + // C++ backing class + @DoNotStrip + @Keep + protected open class CxxPart(javaPart: HybridBarcodeScannerSpec): HybridObject.CxxPart(javaPart) { + // C++ JHybridBarcodeScannerSpec::CxxPart::initHybrid(...) + external override fun initHybrid(): HybridData + } + override fun createCxxPart(): CxxPart { + return CxxPart(this) + } + + companion object { + protected const val TAG = "HybridBarcodeScannerSpec" + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridTextRecognizerSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridTextRecognizerSpec.kt new file mode 100644 index 0000000..ab6499a --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridTextRecognizerSpec.kt @@ -0,0 +1,60 @@ +/// +/// HybridTextRecognizerSpec.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.camera.HybridFrameSpec +import com.margelo.nitro.core.Promise +import com.margelo.nitro.core.HybridObject + +/** + * A Kotlin class representing the TextRecognizer HybridObject. + * Implement this abstract class to create Kotlin-based instances of TextRecognizer. + */ +@DoNotStrip +@Keep +@Suppress( + "KotlinJniMissingFunction", "unused", + "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", + "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" +) +abstract class HybridTextRecognizerSpec: HybridObject() { + // Properties + + + // Methods + @DoNotStrip + @Keep + abstract fun recognize(frame: com.margelo.nitro.camera.HybridFrameSpec, args: MLKitBaseArguments?): TextRecognitionResult + + @DoNotStrip + @Keep + abstract fun recognizeImage(uri: String): Promise + + // Default implementation of `HybridObject.toString()` + override fun toString(): String { + return "[HybridObject TextRecognizer]" + } + + // C++ backing class + @DoNotStrip + @Keep + protected open class CxxPart(javaPart: HybridTextRecognizerSpec): HybridObject.CxxPart(javaPart) { + // C++ JHybridTextRecognizerSpec::CxxPart::initHybrid(...) + external override fun initHybrid(): HybridData + } + override fun createCxxPart(): CxxPart { + return CxxPart(this) + } + + companion object { + protected const val TAG = "HybridTextRecognizerSpec" + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKitSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKitSpec.kt new file mode 100644 index 0000000..1708610 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/HybridVisionCameraMLKitSpec.kt @@ -0,0 +1,62 @@ +/// +/// HybridVisionCameraMLKitSpec.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.core.HybridObject + +/** + * A Kotlin class representing the VisionCameraMLKit HybridObject. + * Implement this abstract class to create Kotlin-based instances of VisionCameraMLKit. + */ +@DoNotStrip +@Keep +@Suppress( + "KotlinJniMissingFunction", "unused", + "RedundantSuppression", "RedundantUnitReturnType", "SimpleRedundantLet", + "LocalVariableName", "PropertyName", "PrivatePropertyName", "FunctionName" +) +abstract class HybridVisionCameraMLKitSpec: HybridObject() { + // Properties + + + // Methods + @DoNotStrip + @Keep + abstract fun isFeatureAvailable(feature: MLKitFeature): Boolean + + @DoNotStrip + @Keep + abstract fun createTextRecognizer(options: TextRecognizerOptions): HybridTextRecognizerSpec + + @DoNotStrip + @Keep + abstract fun createBarcodeScanner(options: BarcodeScannerOptions): HybridBarcodeScannerSpec + + // Default implementation of `HybridObject.toString()` + override fun toString(): String { + return "[HybridObject VisionCameraMLKit]" + } + + // C++ backing class + @DoNotStrip + @Keep + protected open class CxxPart(javaPart: HybridVisionCameraMLKitSpec): HybridObject.CxxPart(javaPart) { + // C++ JHybridVisionCameraMLKitSpec::CxxPart::initHybrid(...) + external override fun initHybrid(): HybridData + } + override fun createCxxPart(): CxxPart { + return CxxPart(this) + } + + companion object { + protected const val TAG = "HybridVisionCameraMLKitSpec" + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitBaseArguments.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitBaseArguments.kt new file mode 100644 index 0000000..ef94e51 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitBaseArguments.kt @@ -0,0 +1,51 @@ +/// +/// MLKitBaseArguments.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "MLKitBaseArguments". + */ +@DoNotStrip +@Keep +data class MLKitBaseArguments( + @DoNotStrip + @Keep + val outputOrientation: Orientation? +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is MLKitBaseArguments) return false + return Objects.deepEquals(this.outputOrientation, other.outputOrientation) + } + + override fun hashCode(): Int { + return arrayOf( + outputOrientation + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(outputOrientation: Orientation?): MLKitBaseArguments { + return MLKitBaseArguments(outputOrientation) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitFeature.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitFeature.kt new file mode 100644 index 0000000..abd7e6b --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/MLKitFeature.kt @@ -0,0 +1,32 @@ +/// +/// MLKitFeature.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "MLKitFeature". + */ +@DoNotStrip +@Keep +enum class MLKitFeature(@DoNotStrip @Keep val value: Int) { + TEXTRECOGNITION(0), + FACEDETECTION(1), + FACEMESHDETECTION(2), + POSEDETECTION(3), + SELFIESEGMENTATION(4), + SUBJECTSEGMENTATION(5), + DOCUMENTSCANNER(6), + BARCODESCANNING(7), + IMAGELABELING(8), + OBJECTDETECTION(9), + DIGITALINKRECOGNITION(10); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Orientation.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Orientation.kt new file mode 100644 index 0000000..603ec61 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Orientation.kt @@ -0,0 +1,25 @@ +/// +/// Orientation.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "Orientation". + */ +@DoNotStrip +@Keep +enum class Orientation(@DoNotStrip @Keep val value: Int) { + PORTRAIT(0), + PORTRAIT_UPSIDE_DOWN(1), + LANDSCAPE_LEFT(2), + LANDSCAPE_RIGHT(3); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterest.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterest.kt new file mode 100644 index 0000000..776b400 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterest.kt @@ -0,0 +1,71 @@ +/// +/// RegionOfInterest.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "RegionOfInterest". + */ +@DoNotStrip +@Keep +data class RegionOfInterest( + @DoNotStrip + @Keep + val x: Double, + @DoNotStrip + @Keep + val y: Double, + @DoNotStrip + @Keep + val width: Double, + @DoNotStrip + @Keep + val height: Double, + @DoNotStrip + @Keep + val unit: RegionOfInterestUnit? +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is RegionOfInterest) return false + return Objects.deepEquals(this.x, other.x) + && Objects.deepEquals(this.y, other.y) + && Objects.deepEquals(this.width, other.width) + && Objects.deepEquals(this.height, other.height) + && Objects.deepEquals(this.unit, other.unit) + } + + override fun hashCode(): Int { + return arrayOf( + x, + y, + width, + height, + unit + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(x: Double, y: Double, width: Double, height: Double, unit: RegionOfInterestUnit?): RegionOfInterest { + return RegionOfInterest(x, y, width, height, unit) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterestUnit.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterestUnit.kt new file mode 100644 index 0000000..3cf1a6f --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/RegionOfInterestUnit.kt @@ -0,0 +1,23 @@ +/// +/// RegionOfInterestUnit.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "RegionOfInterestUnit". + */ +@DoNotStrip +@Keep +enum class RegionOfInterestUnit(@DoNotStrip @Keep val value: Int) { + NORMALIZED(0), + PIXEL(1); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextBlock.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextBlock.kt new file mode 100644 index 0000000..11b406e --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextBlock.kt @@ -0,0 +1,71 @@ +/// +/// TextBlock.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "TextBlock". + */ +@DoNotStrip +@Keep +data class TextBlock( + @DoNotStrip + @Keep + val bounds: BoundingBox, + @DoNotStrip + @Keep + val corners: Array, + @DoNotStrip + @Keep + val languages: Array, + @DoNotStrip + @Keep + val text: String, + @DoNotStrip + @Keep + val lines: Array +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextBlock) return false + return Objects.deepEquals(this.bounds, other.bounds) + && Objects.deepEquals(this.corners, other.corners) + && Objects.deepEquals(this.languages, other.languages) + && Objects.deepEquals(this.text, other.text) + && Objects.deepEquals(this.lines, other.lines) + } + + override fun hashCode(): Int { + return arrayOf( + bounds, + corners, + languages, + text, + lines + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(bounds: BoundingBox, corners: Array, languages: Array, text: String, lines: Array): TextBlock { + return TextBlock(bounds, corners, languages, text, lines) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextElement.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextElement.kt new file mode 100644 index 0000000..9d11599 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextElement.kt @@ -0,0 +1,81 @@ +/// +/// TextElement.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects +import com.margelo.nitro.core.NullType + +/** + * Represents the JavaScript object/struct "TextElement". + */ +@DoNotStrip +@Keep +data class TextElement( + @DoNotStrip + @Keep + val bounds: BoundingBox, + @DoNotStrip + @Keep + val corners: Array, + @DoNotStrip + @Keep + val confidence: Variant_NullType_Double?, + @DoNotStrip + @Keep + val angle: Variant_NullType_Double?, + @DoNotStrip + @Keep + val languages: Array, + @DoNotStrip + @Keep + val text: String, + @DoNotStrip + @Keep + val symbols: Array +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextElement) return false + return Objects.deepEquals(this.bounds, other.bounds) + && Objects.deepEquals(this.corners, other.corners) + && Objects.deepEquals(this.confidence, other.confidence) + && Objects.deepEquals(this.angle, other.angle) + && Objects.deepEquals(this.languages, other.languages) + && Objects.deepEquals(this.text, other.text) + && Objects.deepEquals(this.symbols, other.symbols) + } + + override fun hashCode(): Int { + return arrayOf( + bounds, + corners, + confidence, + angle, + languages, + text, + symbols + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(bounds: BoundingBox, corners: Array, confidence: Variant_NullType_Double?, angle: Variant_NullType_Double?, languages: Array, text: String, symbols: Array): TextElement { + return TextElement(bounds, corners, confidence, angle, languages, text, symbols) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextLine.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextLine.kt new file mode 100644 index 0000000..3e85714 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextLine.kt @@ -0,0 +1,81 @@ +/// +/// TextLine.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects +import com.margelo.nitro.core.NullType + +/** + * Represents the JavaScript object/struct "TextLine". + */ +@DoNotStrip +@Keep +data class TextLine( + @DoNotStrip + @Keep + val bounds: BoundingBox, + @DoNotStrip + @Keep + val corners: Array, + @DoNotStrip + @Keep + val confidence: Variant_NullType_Double?, + @DoNotStrip + @Keep + val angle: Variant_NullType_Double?, + @DoNotStrip + @Keep + val languages: Array, + @DoNotStrip + @Keep + val text: String, + @DoNotStrip + @Keep + val elements: Array +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextLine) return false + return Objects.deepEquals(this.bounds, other.bounds) + && Objects.deepEquals(this.corners, other.corners) + && Objects.deepEquals(this.confidence, other.confidence) + && Objects.deepEquals(this.angle, other.angle) + && Objects.deepEquals(this.languages, other.languages) + && Objects.deepEquals(this.text, other.text) + && Objects.deepEquals(this.elements, other.elements) + } + + override fun hashCode(): Int { + return arrayOf( + bounds, + corners, + confidence, + angle, + languages, + text, + elements + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(bounds: BoundingBox, corners: Array, confidence: Variant_NullType_Double?, angle: Variant_NullType_Double?, languages: Array, text: String, elements: Array): TextLine { + return TextLine(bounds, corners, confidence, angle, languages, text, elements) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage.kt new file mode 100644 index 0000000..40d14a2 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionLanguage.kt @@ -0,0 +1,26 @@ +/// +/// TextRecognitionLanguage.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "TextRecognitionLanguage". + */ +@DoNotStrip +@Keep +enum class TextRecognitionLanguage(@DoNotStrip @Keep val value: Int) { + LATIN(0), + CHINESE(1), + DEVANAGARI(2), + JAPANESE(3), + KOREAN(4); + + companion object +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionResult.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionResult.kt new file mode 100644 index 0000000..cd7a232 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognitionResult.kt @@ -0,0 +1,56 @@ +/// +/// TextRecognitionResult.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "TextRecognitionResult". + */ +@DoNotStrip +@Keep +data class TextRecognitionResult( + @DoNotStrip + @Keep + val text: String, + @DoNotStrip + @Keep + val blocks: Array +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextRecognitionResult) return false + return Objects.deepEquals(this.text, other.text) + && Objects.deepEquals(this.blocks, other.blocks) + } + + override fun hashCode(): Int { + return arrayOf( + text, + blocks + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(text: String, blocks: Array): TextRecognitionResult { + return TextRecognitionResult(text, blocks) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions.kt new file mode 100644 index 0000000..7467558 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextRecognizerOptions.kt @@ -0,0 +1,76 @@ +/// +/// TextRecognizerOptions.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "TextRecognizerOptions". + */ +@DoNotStrip +@Keep +data class TextRecognizerOptions( + @DoNotStrip + @Keep + val language: TextRecognitionLanguage?, + @DoNotStrip + @Keep + val scaleFactor: Double?, + @DoNotStrip + @Keep + val invertColors: Boolean?, + @DoNotStrip + @Keep + val frameProcessInterval: Double?, + @DoNotStrip + @Keep + val roi: RegionOfInterest?, + @DoNotStrip + @Keep + val orientation: Orientation? +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextRecognizerOptions) return false + return Objects.deepEquals(this.language, other.language) + && Objects.deepEquals(this.scaleFactor, other.scaleFactor) + && Objects.deepEquals(this.invertColors, other.invertColors) + && Objects.deepEquals(this.frameProcessInterval, other.frameProcessInterval) + && Objects.deepEquals(this.roi, other.roi) + && Objects.deepEquals(this.orientation, other.orientation) + } + + override fun hashCode(): Int { + return arrayOf( + language, + scaleFactor, + invertColors, + frameProcessInterval, + roi, + orientation + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(language: TextRecognitionLanguage?, scaleFactor: Double?, invertColors: Boolean?, frameProcessInterval: Double?, roi: RegionOfInterest?, orientation: Orientation?): TextRecognizerOptions { + return TextRecognizerOptions(language, scaleFactor, invertColors, frameProcessInterval, roi, orientation) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextSymbol.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextSymbol.kt new file mode 100644 index 0000000..a9c70e2 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/TextSymbol.kt @@ -0,0 +1,76 @@ +/// +/// TextSymbol.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip +import java.util.Objects + + +/** + * Represents the JavaScript object/struct "TextSymbol". + */ +@DoNotStrip +@Keep +data class TextSymbol( + @DoNotStrip + @Keep + val bounds: BoundingBox, + @DoNotStrip + @Keep + val corners: Array, + @DoNotStrip + @Keep + val confidence: Double, + @DoNotStrip + @Keep + val angle: Double, + @DoNotStrip + @Keep + val languages: Array, + @DoNotStrip + @Keep + val text: String +) { + /* primary constructor */ + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is TextSymbol) return false + return Objects.deepEquals(this.bounds, other.bounds) + && Objects.deepEquals(this.corners, other.corners) + && Objects.deepEquals(this.confidence, other.confidence) + && Objects.deepEquals(this.angle, other.angle) + && Objects.deepEquals(this.languages, other.languages) + && Objects.deepEquals(this.text, other.text) + } + + override fun hashCode(): Int { + return arrayOf( + bounds, + corners, + confidence, + angle, + languages, + text + ).contentDeepHashCode() + } + + companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(bounds: BoundingBox, corners: Array, confidence: Double, angle: Double, languages: Array, text: String): TextSymbol { + return TextSymbol(bounds, corners, confidence, angle, languages, text) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Variant_NullType_Double.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Variant_NullType_Double.kt new file mode 100644 index 0000000..1c1deef --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/Variant_NullType_Double.kt @@ -0,0 +1,62 @@ +/// +/// Variant_NullType_Double.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import com.facebook.proguard.annotations.DoNotStrip +import com.margelo.nitro.core.NullType + +/** + * Represents the TypeScript variant "NullType | Double". + */ +@Suppress("ClassName") +@DoNotStrip +sealed class Variant_NullType_Double { + @DoNotStrip + data class First(@DoNotStrip val value: NullType): Variant_NullType_Double() + @DoNotStrip + data class Second(@DoNotStrip val value: Double): Variant_NullType_Double() + + inline fun asType(): T? { + return when (this) { + is First -> (value) as? T + is Second -> (value) as? T + } + } + inline fun isType(): Boolean { + return asType() != null + } + inline fun match(first: (NullType) -> R, second: (Double) -> R): R { + return when (this) { + is First -> first(value) + is Second -> second(value) + } + } + + val isFirst: Boolean + get() = this is First + val isSecond: Boolean + get() = this is Second + + fun asFirstOrNull(): NullType? { + val value = (this as? First)?.value ?: return null + return value + } + fun asSecondOrNull(): Double? { + val value = (this as? Second)?.value ?: return null + return value + } + + companion object { + @JvmStatic + @DoNotStrip + fun create(value: NullType): Variant_NullType_Double = First(value) + @JvmStatic + @DoNotStrip + fun create(value: Double): Variant_NullType_Double = Second(value) + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/VisionCameraMLKitOnLoad.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/VisionCameraMLKitOnLoad.kt new file mode 100644 index 0000000..e63a5bf --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/visioncameramlkit/VisionCameraMLKitOnLoad.kt @@ -0,0 +1,35 @@ +/// +/// VisionCameraMLKitOnLoad.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.visioncameramlkit + +import android.util.Log + +internal class VisionCameraMLKitOnLoad { + companion object { + private const val TAG = "VisionCameraMLKitOnLoad" + private var didLoad = false + /** + * Initializes the native part of "VisionCameraMLKit". + * This method is idempotent and can be called more than once. + */ + @JvmStatic + fun initializeNative() { + if (didLoad) return + try { + Log.i(TAG, "Loading VisionCameraMLKit C++ library...") + System.loadLibrary("VisionCameraMLKit") + Log.i(TAG, "Successfully loaded VisionCameraMLKit C++ library!") + didLoad = true + } catch (e: Error) { + Log.e(TAG, "Failed to load VisionCameraMLKit C++ library! Is it properly installed and linked? " + + "Is the name correct? (see `CMakeLists.txt`, at `add_library(...)`)", e) + throw e + } + } + } +} diff --git a/nitrogen/generated/ios/VisionCameraMLKit+autolinking.rb b/nitrogen/generated/ios/VisionCameraMLKit+autolinking.rb new file mode 100644 index 0000000..2d1a84f --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKit+autolinking.rb @@ -0,0 +1,62 @@ +# +# VisionCameraMLKit+autolinking.rb +# This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +# https://github.com/mrousavy/nitro +# Copyright © Marc Rousavy @ Margelo +# + +# This is a Ruby script that adds all files generated by Nitrogen +# to the given podspec. +# +# To use it, add this to your .podspec: +# ```ruby +# Pod::Spec.new do |spec| +# # ... +# +# # Add all files generated by Nitrogen +# load 'nitrogen/generated/ios/VisionCameraMLKit+autolinking.rb' +# add_nitrogen_files(spec) +# end +# ``` + +def add_nitrogen_files(spec) + Pod::UI.puts "[NitroModules] 🔥 VisionCameraMLKit is boosted by nitro!" + + spec.dependency "NitroModules" + + current_source_files = Array(spec.attributes_hash['source_files']) + spec.source_files = current_source_files + [ + # Generated cross-platform specs + "nitrogen/generated/shared/**/*.{h,hpp,c,cpp,swift}", + # Generated bridges for the cross-platform specs + "nitrogen/generated/ios/**/*.{h,hpp,c,cpp,mm,swift}", + ] + + current_public_header_files = Array(spec.attributes_hash['public_header_files']) + spec.public_header_files = current_public_header_files + [ + # Generated specs + "nitrogen/generated/shared/**/*.{h,hpp}", + # Swift to C++ bridging helpers + "nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.hpp" + ] + + current_private_header_files = Array(spec.attributes_hash['private_header_files']) + spec.private_header_files = current_private_header_files + [ + # iOS specific specs + "nitrogen/generated/ios/c++/**/*.{h,hpp}", + # Views are framework-specific and should be private + "nitrogen/generated/shared/**/views/**/*" + ] + + current_pod_target_xcconfig = spec.attributes_hash['pod_target_xcconfig'] || {} + spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({ + # Use C++ 20 + "CLANG_CXX_LANGUAGE_STANDARD" => "c++20", + # Enables C++ <-> Swift interop (by default it's only ObjC) + "SWIFT_OBJC_INTEROP_MODE" => "objcxx", + # Enables stricter modular headers + "DEFINES_MODULE" => "YES", + # Disable auto-generated ObjC header for Swift (Static linkage on Xcode 26.4 breaks here) + "SWIFT_INSTALL_OBJC_HEADER" => "NO", + }) +end diff --git a/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.cpp b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.cpp new file mode 100644 index 0000000..627efef --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.cpp @@ -0,0 +1,102 @@ +/// +/// VisionCameraMLKit-Swift-Cxx-Bridge.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "VisionCameraMLKit-Swift-Cxx-Bridge.hpp" + +// Include C++ implementation defined types +#include "HybridBarcodeScannerSpecSwift.hpp" +#include "HybridTextRecognizerSpecSwift.hpp" +#include "HybridVisionCameraMLKitSpecSwift.hpp" +#include "VisionCameraMLKit-Swift-Cxx-Umbrella.hpp" +#include +#include + +namespace margelo::nitro::visioncameramlkit::bridge::swift { + + // pragma MARK: std::shared_ptr + std::shared_ptr create_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(void* NON_NULL swiftUnsafePointer) noexcept { + // Implemented in VisionCamera + return margelo::nitro::camera::bridge::swift::create_std__shared_ptr_HybridFrameSpec_(swiftUnsafePointer); + } + void* NON_NULL get_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_ cppType) { + // Implemented in VisionCamera + return margelo::nitro::camera::bridge::swift::get_std__shared_ptr_HybridFrameSpec_(cppType); + } + + // pragma MARK: std::function + Func_void_BarcodeScannerResult create_Func_void_BarcodeScannerResult(void* NON_NULL swiftClosureWrapper) noexcept { + auto swiftClosure = VisionCameraMLKit::Func_void_BarcodeScannerResult::fromUnsafe(swiftClosureWrapper); + return [swiftClosure = std::move(swiftClosure)](const BarcodeScannerResult& result) mutable -> void { + swiftClosure.call(result); + }; + } + + // pragma MARK: std::function + Func_void_std__exception_ptr create_Func_void_std__exception_ptr(void* NON_NULL swiftClosureWrapper) noexcept { + auto swiftClosure = VisionCameraMLKit::Func_void_std__exception_ptr::fromUnsafe(swiftClosureWrapper); + return [swiftClosure = std::move(swiftClosure)](const std::exception_ptr& error) mutable -> void { + swiftClosure.call(error); + }; + } + + // pragma MARK: std::shared_ptr + std::shared_ptr create_std__shared_ptr_HybridBarcodeScannerSpec_(void* NON_NULL swiftUnsafePointer) noexcept { + VisionCameraMLKit::HybridBarcodeScannerSpec_cxx swiftPart = VisionCameraMLKit::HybridBarcodeScannerSpec_cxx::fromUnsafe(swiftUnsafePointer); + return std::make_shared(swiftPart); + } + void* NON_NULL get_std__shared_ptr_HybridBarcodeScannerSpec_(std__shared_ptr_HybridBarcodeScannerSpec_ cppType) { + std::shared_ptr swiftWrapper = std::dynamic_pointer_cast(cppType); + #ifdef NITRO_DEBUG + if (swiftWrapper == nullptr) [[unlikely]] { + throw std::runtime_error("Class \"HybridBarcodeScannerSpec\" is not implemented in Swift!"); + } + #endif + VisionCameraMLKit::HybridBarcodeScannerSpec_cxx& swiftPart = swiftWrapper->getSwiftPart(); + return swiftPart.toUnsafe(); + } + + // pragma MARK: std::function + Func_void_TextRecognitionResult create_Func_void_TextRecognitionResult(void* NON_NULL swiftClosureWrapper) noexcept { + auto swiftClosure = VisionCameraMLKit::Func_void_TextRecognitionResult::fromUnsafe(swiftClosureWrapper); + return [swiftClosure = std::move(swiftClosure)](const TextRecognitionResult& result) mutable -> void { + swiftClosure.call(result); + }; + } + + // pragma MARK: std::shared_ptr + std::shared_ptr create_std__shared_ptr_HybridTextRecognizerSpec_(void* NON_NULL swiftUnsafePointer) noexcept { + VisionCameraMLKit::HybridTextRecognizerSpec_cxx swiftPart = VisionCameraMLKit::HybridTextRecognizerSpec_cxx::fromUnsafe(swiftUnsafePointer); + return std::make_shared(swiftPart); + } + void* NON_NULL get_std__shared_ptr_HybridTextRecognizerSpec_(std__shared_ptr_HybridTextRecognizerSpec_ cppType) { + std::shared_ptr swiftWrapper = std::dynamic_pointer_cast(cppType); + #ifdef NITRO_DEBUG + if (swiftWrapper == nullptr) [[unlikely]] { + throw std::runtime_error("Class \"HybridTextRecognizerSpec\" is not implemented in Swift!"); + } + #endif + VisionCameraMLKit::HybridTextRecognizerSpec_cxx& swiftPart = swiftWrapper->getSwiftPart(); + return swiftPart.toUnsafe(); + } + + // pragma MARK: std::shared_ptr + std::shared_ptr create_std__shared_ptr_HybridVisionCameraMLKitSpec_(void* NON_NULL swiftUnsafePointer) noexcept { + VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx swiftPart = VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx::fromUnsafe(swiftUnsafePointer); + return std::make_shared(swiftPart); + } + void* NON_NULL get_std__shared_ptr_HybridVisionCameraMLKitSpec_(std__shared_ptr_HybridVisionCameraMLKitSpec_ cppType) { + std::shared_ptr swiftWrapper = std::dynamic_pointer_cast(cppType); + #ifdef NITRO_DEBUG + if (swiftWrapper == nullptr) [[unlikely]] { + throw std::runtime_error("Class \"HybridVisionCameraMLKitSpec\" is not implemented in Swift!"); + } + #endif + VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx& swiftPart = swiftWrapper->getSwiftPart(); + return swiftPart.toUnsafe(); + } + +} // namespace margelo::nitro::visioncameramlkit::bridge::swift diff --git a/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.hpp b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.hpp new file mode 100644 index 0000000..1b0992a --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Bridge.hpp @@ -0,0 +1,641 @@ +/// +/// VisionCameraMLKit-Swift-Cxx-Bridge.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +// Forward declarations of C++ defined types +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `BarcodeScannerBarcode` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerBarcode; } +// Forward declaration of `BarcodeScannerResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerResult; } +// Forward declaration of `BarcodeValueTypeName` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeValueTypeName; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `HybridBarcodeScannerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridBarcodeScannerSpec; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `HybridTextRecognizerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridTextRecognizerSpec; } +// Forward declaration of `HybridVisionCameraMLKitSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridVisionCameraMLKitSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } +// Forward declaration of `RegionOfInterestUnit` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class RegionOfInterestUnit; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `TextBlock` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextBlock; } +// Forward declaration of `TextElement` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextElement; } +// Forward declaration of `TextLine` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextLine; } +// Forward declaration of `TextRecognitionLanguage` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class TextRecognitionLanguage; } +// Forward declaration of `TextRecognitionResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognitionResult; } +// Forward declaration of `TextSymbol` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextSymbol; } + +// Forward declarations of Swift defined types +// Forward declaration of `HybridBarcodeScannerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridBarcodeScannerSpec_cxx; } +// Forward declaration of `HybridFrameSpec_cxx` to properly resolve imports. +namespace VisionCamera { class HybridFrameSpec_cxx; } +// Forward declaration of `HybridTextRecognizerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridTextRecognizerSpec_cxx; } +// Forward declaration of `HybridVisionCameraMLKitSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridVisionCameraMLKitSpec_cxx; } + +// Include C++ defined types +#include "BarcodeFormat.hpp" +#include "BarcodeScannerBarcode.hpp" +#include "BarcodeScannerResult.hpp" +#include "BarcodeValueTypeName.hpp" +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "HybridBarcodeScannerSpec.hpp" +#include "HybridTextRecognizerSpec.hpp" +#include "HybridVisionCameraMLKitSpec.hpp" +#include "MLKitBaseArguments.hpp" +#include "Orientation.hpp" +#include "RegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include "TextBlock.hpp" +#include "TextElement.hpp" +#include "TextLine.hpp" +#include "TextRecognitionLanguage.hpp" +#include "TextRecognitionResult.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Contains specialized versions of C++ templated types so they can be accessed from Swift, + * as well as helper functions to interact with those C++ types from Swift. + */ +namespace margelo::nitro::visioncameramlkit::bridge::swift { + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_BoundingBox_ = std::optional; + inline std::optional create_std__optional_BoundingBox_(const BoundingBox& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_BoundingBox_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline BoundingBox get_std__optional_BoundingBox_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_Corner_ = std::vector; + inline std::vector create_std__vector_Corner_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::optional> + /** + * Specialized version of `std::optional>`. + */ + using std__optional_std__vector_Corner__ = std::optional>; + inline std::optional> create_std__optional_std__vector_Corner__(const std::vector& value) noexcept { + return std::optional>(value); + } + inline bool has_value_std__optional_std__vector_Corner__(const std::optional>& optional) noexcept { + return optional.has_value(); + } + inline std::vector get_std__optional_std__vector_Corner__(const std::optional>& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_std__string_ = std::optional; + inline std::optional create_std__optional_std__string_(const std::string& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_std__string_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline std::string get_std__optional_std__string_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_double_ = std::vector; + inline std::vector create_std__vector_double_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::optional> + /** + * Specialized version of `std::optional>`. + */ + using std__optional_std__vector_double__ = std::optional>; + inline std::optional> create_std__optional_std__vector_double__(const std::vector& value) noexcept { + return std::optional>(value); + } + inline bool has_value_std__optional_std__vector_double__(const std::optional>& optional) noexcept { + return optional.has_value(); + } + inline std::vector get_std__optional_std__vector_double__(const std::optional>& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional> + /** + * Specialized version of `std::optional>`. + */ + using std__optional_std__shared_ptr_AnyMap__ = std::optional>; + inline std::optional> create_std__optional_std__shared_ptr_AnyMap__(const std::shared_ptr& value) noexcept { + return std::optional>(value); + } + inline bool has_value_std__optional_std__shared_ptr_AnyMap__(const std::optional>& optional) noexcept { + return optional.has_value(); + } + inline std::shared_ptr get_std__optional_std__shared_ptr_AnyMap__(const std::optional>& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_BarcodeScannerBarcode_ = std::vector; + inline std::vector create_std__vector_BarcodeScannerBarcode_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::shared_ptr + /** + * Specialized version of `std::shared_ptr`. + */ + using std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_ = std::shared_ptr; + std::shared_ptr create_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(void* NON_NULL swiftUnsafePointer) noexcept; + void* NON_NULL get_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_ cppType); + + // pragma MARK: std::weak_ptr + using std__weak_ptr_margelo__nitro__camera__HybridFrameSpec_ = std::weak_ptr; + inline std__weak_ptr_margelo__nitro__camera__HybridFrameSpec_ weakify_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(const std::shared_ptr& strong) noexcept { return strong; } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_Orientation_ = std::optional; + inline std::optional create_std__optional_Orientation_(const Orientation& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_Orientation_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline Orientation get_std__optional_Orientation_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_MLKitBaseArguments_ = std::optional; + inline std::optional create_std__optional_MLKitBaseArguments_(const MLKitBaseArguments& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_MLKitBaseArguments_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline MLKitBaseArguments get_std__optional_MLKitBaseArguments_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::shared_ptr> + /** + * Specialized version of `std::shared_ptr>`. + */ + using std__shared_ptr_Promise_BarcodeScannerResult__ = std::shared_ptr>; + inline std::shared_ptr> create_std__shared_ptr_Promise_BarcodeScannerResult__() noexcept { + return Promise::create(); + } + inline PromiseHolder wrap_std__shared_ptr_Promise_BarcodeScannerResult__(std::shared_ptr> promise) noexcept { + return PromiseHolder(std::move(promise)); + } + + // pragma MARK: std::function + /** + * Specialized version of `std::function`. + */ + using Func_void_BarcodeScannerResult = std::function; + /** + * Wrapper class for a `std::function`, this can be used from Swift. + */ + class Func_void_BarcodeScannerResult_Wrapper final { + public: + explicit Func_void_BarcodeScannerResult_Wrapper(std::function&& func): _function(std::make_unique>(std::move(func))) {} + inline void call(BarcodeScannerResult result) const noexcept { + _function->operator()(result); + } + private: + std::unique_ptr> _function; + } SWIFT_NONCOPYABLE; + Func_void_BarcodeScannerResult create_Func_void_BarcodeScannerResult(void* NON_NULL swiftClosureWrapper) noexcept; + inline Func_void_BarcodeScannerResult_Wrapper wrap_Func_void_BarcodeScannerResult(Func_void_BarcodeScannerResult value) noexcept { + return Func_void_BarcodeScannerResult_Wrapper(std::move(value)); + } + + // pragma MARK: std::function + /** + * Specialized version of `std::function`. + */ + using Func_void_std__exception_ptr = std::function; + /** + * Wrapper class for a `std::function`, this can be used from Swift. + */ + class Func_void_std__exception_ptr_Wrapper final { + public: + explicit Func_void_std__exception_ptr_Wrapper(std::function&& func): _function(std::make_unique>(std::move(func))) {} + inline void call(std::exception_ptr error) const noexcept { + _function->operator()(error); + } + private: + std::unique_ptr> _function; + } SWIFT_NONCOPYABLE; + Func_void_std__exception_ptr create_Func_void_std__exception_ptr(void* NON_NULL swiftClosureWrapper) noexcept; + inline Func_void_std__exception_ptr_Wrapper wrap_Func_void_std__exception_ptr(Func_void_std__exception_ptr value) noexcept { + return Func_void_std__exception_ptr_Wrapper(std::move(value)); + } + + // pragma MARK: std::shared_ptr + /** + * Specialized version of `std::shared_ptr`. + */ + using std__shared_ptr_HybridBarcodeScannerSpec_ = std::shared_ptr; + std::shared_ptr create_std__shared_ptr_HybridBarcodeScannerSpec_(void* NON_NULL swiftUnsafePointer) noexcept; + void* NON_NULL get_std__shared_ptr_HybridBarcodeScannerSpec_(std__shared_ptr_HybridBarcodeScannerSpec_ cppType); + + // pragma MARK: std::weak_ptr + using std__weak_ptr_HybridBarcodeScannerSpec_ = std::weak_ptr; + inline std__weak_ptr_HybridBarcodeScannerSpec_ weakify_std__shared_ptr_HybridBarcodeScannerSpec_(const std::shared_ptr& strong) noexcept { return strong; } + + // pragma MARK: Result + using Result_BarcodeScannerResult_ = Result; + inline Result_BarcodeScannerResult_ create_Result_BarcodeScannerResult_(const BarcodeScannerResult& value) noexcept { + return Result::withValue(value); + } + inline Result_BarcodeScannerResult_ create_Result_BarcodeScannerResult_(const std::exception_ptr& error) noexcept { + return Result::withError(error); + } + + // pragma MARK: Result>> + using Result_std__shared_ptr_Promise_BarcodeScannerResult___ = Result>>; + inline Result_std__shared_ptr_Promise_BarcodeScannerResult___ create_Result_std__shared_ptr_Promise_BarcodeScannerResult___(const std::shared_ptr>& value) noexcept { + return Result>>::withValue(value); + } + inline Result_std__shared_ptr_Promise_BarcodeScannerResult___ create_Result_std__shared_ptr_Promise_BarcodeScannerResult___(const std::exception_ptr& error) noexcept { + return Result>>::withError(error); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_std__string_ = std::vector; + inline std::vector create_std__vector_std__string_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::variant + /** + * Wrapper struct for `std::variant`. + * std::variant cannot be used in Swift because of a Swift bug. + * Not even specializing it works. So we create a wrapper struct. + */ + struct std__variant_nitro__NullType__double_ final { + std::variant variant; + std__variant_nitro__NullType__double_(std::variant variant): variant(variant) { } + operator std::variant() const noexcept { + return variant; + } + inline size_t index() const noexcept { + return variant.index(); + } + inline nitro::NullType get_0() const noexcept { + return std::get<0>(variant); + } + inline double get_1() const noexcept { + return std::get<1>(variant); + } + }; + inline std__variant_nitro__NullType__double_ create_std__variant_nitro__NullType__double_(nitro::NullType value) noexcept { + return std__variant_nitro__NullType__double_(value); + } + inline std__variant_nitro__NullType__double_ create_std__variant_nitro__NullType__double_(double value) noexcept { + return std__variant_nitro__NullType__double_(value); + } + + // pragma MARK: std::optional> + /** + * Specialized version of `std::optional>`. + */ + using std__optional_std__variant_nitro__NullType__double__ = std::optional>; + inline std::optional> create_std__optional_std__variant_nitro__NullType__double__(const std::variant& value) noexcept { + return std::optional>(value); + } + inline bool has_value_std__optional_std__variant_nitro__NullType__double__(const std::optional>& optional) noexcept { + return optional.has_value(); + } + inline std::variant get_std__optional_std__variant_nitro__NullType__double__(const std::optional>& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_TextSymbol_ = std::vector; + inline std::vector create_std__vector_TextSymbol_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_TextElement_ = std::vector; + inline std::vector create_std__vector_TextElement_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_TextLine_ = std::vector; + inline std::vector create_std__vector_TextLine_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_TextBlock_ = std::vector; + inline std::vector create_std__vector_TextBlock_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::shared_ptr> + /** + * Specialized version of `std::shared_ptr>`. + */ + using std__shared_ptr_Promise_TextRecognitionResult__ = std::shared_ptr>; + inline std::shared_ptr> create_std__shared_ptr_Promise_TextRecognitionResult__() noexcept { + return Promise::create(); + } + inline PromiseHolder wrap_std__shared_ptr_Promise_TextRecognitionResult__(std::shared_ptr> promise) noexcept { + return PromiseHolder(std::move(promise)); + } + + // pragma MARK: std::function + /** + * Specialized version of `std::function`. + */ + using Func_void_TextRecognitionResult = std::function; + /** + * Wrapper class for a `std::function`, this can be used from Swift. + */ + class Func_void_TextRecognitionResult_Wrapper final { + public: + explicit Func_void_TextRecognitionResult_Wrapper(std::function&& func): _function(std::make_unique>(std::move(func))) {} + inline void call(TextRecognitionResult result) const noexcept { + _function->operator()(result); + } + private: + std::unique_ptr> _function; + } SWIFT_NONCOPYABLE; + Func_void_TextRecognitionResult create_Func_void_TextRecognitionResult(void* NON_NULL swiftClosureWrapper) noexcept; + inline Func_void_TextRecognitionResult_Wrapper wrap_Func_void_TextRecognitionResult(Func_void_TextRecognitionResult value) noexcept { + return Func_void_TextRecognitionResult_Wrapper(std::move(value)); + } + + // pragma MARK: std::shared_ptr + /** + * Specialized version of `std::shared_ptr`. + */ + using std__shared_ptr_HybridTextRecognizerSpec_ = std::shared_ptr; + std::shared_ptr create_std__shared_ptr_HybridTextRecognizerSpec_(void* NON_NULL swiftUnsafePointer) noexcept; + void* NON_NULL get_std__shared_ptr_HybridTextRecognizerSpec_(std__shared_ptr_HybridTextRecognizerSpec_ cppType); + + // pragma MARK: std::weak_ptr + using std__weak_ptr_HybridTextRecognizerSpec_ = std::weak_ptr; + inline std__weak_ptr_HybridTextRecognizerSpec_ weakify_std__shared_ptr_HybridTextRecognizerSpec_(const std::shared_ptr& strong) noexcept { return strong; } + + // pragma MARK: Result + using Result_TextRecognitionResult_ = Result; + inline Result_TextRecognitionResult_ create_Result_TextRecognitionResult_(const TextRecognitionResult& value) noexcept { + return Result::withValue(value); + } + inline Result_TextRecognitionResult_ create_Result_TextRecognitionResult_(const std::exception_ptr& error) noexcept { + return Result::withError(error); + } + + // pragma MARK: Result>> + using Result_std__shared_ptr_Promise_TextRecognitionResult___ = Result>>; + inline Result_std__shared_ptr_Promise_TextRecognitionResult___ create_Result_std__shared_ptr_Promise_TextRecognitionResult___(const std::shared_ptr>& value) noexcept { + return Result>>::withValue(value); + } + inline Result_std__shared_ptr_Promise_TextRecognitionResult___ create_Result_std__shared_ptr_Promise_TextRecognitionResult___(const std::exception_ptr& error) noexcept { + return Result>>::withError(error); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_TextRecognitionLanguage_ = std::optional; + inline std::optional create_std__optional_TextRecognitionLanguage_(const TextRecognitionLanguage& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_TextRecognitionLanguage_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline TextRecognitionLanguage get_std__optional_TextRecognitionLanguage_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_double_ = std::optional; + inline std::optional create_std__optional_double_(const double& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_double_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline double get_std__optional_double_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_bool_ = std::optional; + inline std::optional create_std__optional_bool_(const bool& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_bool_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline bool get_std__optional_bool_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_RegionOfInterestUnit_ = std::optional; + inline std::optional create_std__optional_RegionOfInterestUnit_(const RegionOfInterestUnit& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_RegionOfInterestUnit_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline RegionOfInterestUnit get_std__optional_RegionOfInterestUnit_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::optional + /** + * Specialized version of `std::optional`. + */ + using std__optional_RegionOfInterest_ = std::optional; + inline std::optional create_std__optional_RegionOfInterest_(const RegionOfInterest& value) noexcept { + return std::optional(value); + } + inline bool has_value_std__optional_RegionOfInterest_(const std::optional& optional) noexcept { + return optional.has_value(); + } + inline RegionOfInterest get_std__optional_RegionOfInterest_(const std::optional& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_BarcodeFormat_ = std::vector; + inline std::vector create_std__vector_BarcodeFormat_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + + // pragma MARK: std::optional> + /** + * Specialized version of `std::optional>`. + */ + using std__optional_std__vector_BarcodeFormat__ = std::optional>; + inline std::optional> create_std__optional_std__vector_BarcodeFormat__(const std::vector& value) noexcept { + return std::optional>(value); + } + inline bool has_value_std__optional_std__vector_BarcodeFormat__(const std::optional>& optional) noexcept { + return optional.has_value(); + } + inline std::vector get_std__optional_std__vector_BarcodeFormat__(const std::optional>& optional) noexcept { + return optional.value(); + } + + // pragma MARK: std::shared_ptr + /** + * Specialized version of `std::shared_ptr`. + */ + using std__shared_ptr_HybridVisionCameraMLKitSpec_ = std::shared_ptr; + std::shared_ptr create_std__shared_ptr_HybridVisionCameraMLKitSpec_(void* NON_NULL swiftUnsafePointer) noexcept; + void* NON_NULL get_std__shared_ptr_HybridVisionCameraMLKitSpec_(std__shared_ptr_HybridVisionCameraMLKitSpec_ cppType); + + // pragma MARK: std::weak_ptr + using std__weak_ptr_HybridVisionCameraMLKitSpec_ = std::weak_ptr; + inline std__weak_ptr_HybridVisionCameraMLKitSpec_ weakify_std__shared_ptr_HybridVisionCameraMLKitSpec_(const std::shared_ptr& strong) noexcept { return strong; } + + // pragma MARK: Result + using Result_bool_ = Result; + inline Result_bool_ create_Result_bool_(bool value) noexcept { + return Result::withValue(std::move(value)); + } + inline Result_bool_ create_Result_bool_(const std::exception_ptr& error) noexcept { + return Result::withError(error); + } + + // pragma MARK: Result> + using Result_std__shared_ptr_HybridTextRecognizerSpec__ = Result>; + inline Result_std__shared_ptr_HybridTextRecognizerSpec__ create_Result_std__shared_ptr_HybridTextRecognizerSpec__(const std::shared_ptr& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__shared_ptr_HybridTextRecognizerSpec__ create_Result_std__shared_ptr_HybridTextRecognizerSpec__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + + // pragma MARK: Result> + using Result_std__shared_ptr_HybridBarcodeScannerSpec__ = Result>; + inline Result_std__shared_ptr_HybridBarcodeScannerSpec__ create_Result_std__shared_ptr_HybridBarcodeScannerSpec__(const std::shared_ptr& value) noexcept { + return Result>::withValue(value); + } + inline Result_std__shared_ptr_HybridBarcodeScannerSpec__ create_Result_std__shared_ptr_HybridBarcodeScannerSpec__(const std::exception_ptr& error) noexcept { + return Result>::withError(error); + } + +} // namespace margelo::nitro::visioncameramlkit::bridge::swift diff --git a/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Umbrella.hpp b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Umbrella.hpp new file mode 100644 index 0000000..67dd681 --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKit-Swift-Cxx-Umbrella.hpp @@ -0,0 +1,122 @@ +/// +/// VisionCameraMLKit-Swift-Cxx-Umbrella.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +// Forward declarations of C++ defined types +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `BarcodeScannerBarcode` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerBarcode; } +// Forward declaration of `BarcodeScannerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerOptions; } +// Forward declaration of `BarcodeScannerResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerResult; } +// Forward declaration of `BarcodeValueTypeName` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeValueTypeName; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `HybridBarcodeScannerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridBarcodeScannerSpec; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `HybridTextRecognizerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridTextRecognizerSpec; } +// Forward declaration of `HybridVisionCameraMLKitSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridVisionCameraMLKitSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `MLKitFeature` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class MLKitFeature; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } +// Forward declaration of `RegionOfInterestUnit` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class RegionOfInterestUnit; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `TextBlock` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextBlock; } +// Forward declaration of `TextElement` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextElement; } +// Forward declaration of `TextLine` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextLine; } +// Forward declaration of `TextRecognitionLanguage` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class TextRecognitionLanguage; } +// Forward declaration of `TextRecognitionResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognitionResult; } +// Forward declaration of `TextRecognizerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognizerOptions; } +// Forward declaration of `TextSymbol` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextSymbol; } + +// Include C++ defined types +#include "BarcodeFormat.hpp" +#include "BarcodeScannerBarcode.hpp" +#include "BarcodeScannerOptions.hpp" +#include "BarcodeScannerResult.hpp" +#include "BarcodeValueTypeName.hpp" +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "HybridBarcodeScannerSpec.hpp" +#include "HybridTextRecognizerSpec.hpp" +#include "HybridVisionCameraMLKitSpec.hpp" +#include "MLKitBaseArguments.hpp" +#include "MLKitFeature.hpp" +#include "Orientation.hpp" +#include "RegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include "TextBlock.hpp" +#include "TextElement.hpp" +#include "TextLine.hpp" +#include "TextRecognitionLanguage.hpp" +#include "TextRecognitionResult.hpp" +#include "TextRecognizerOptions.hpp" +#include "TextSymbol.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// C++ helpers for Swift +#include "VisionCameraMLKit-Swift-Cxx-Bridge.hpp" + +// Common C++ types used in Swift +#include +#include +#include +#include + +// Forward declarations of Swift defined types +// Forward declaration of `HybridBarcodeScannerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridBarcodeScannerSpec_cxx; } +// Forward declaration of `HybridFrameSpec_cxx` to properly resolve imports. +namespace VisionCamera { class HybridFrameSpec_cxx; } +// Forward declaration of `HybridTextRecognizerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridTextRecognizerSpec_cxx; } +// Forward declaration of `HybridVisionCameraMLKitSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridVisionCameraMLKitSpec_cxx; } + +// Include Swift defined types +#if __has_include("VisionCameraMLKit-Swift.h") +// This header is generated by Xcode/Swift on every app build. +// If it cannot be found, make sure the Swift module's name (= podspec name) is actually "VisionCameraMLKit". +#include "VisionCameraMLKit-Swift.h" +// Same as above, but used when building with frameworks (`use_frameworks`) +#elif __has_include() +#include +#else +#error VisionCameraMLKit's autogenerated Swift header cannot be found! Make sure the Swift module's name (= podspec name) is actually "VisionCameraMLKit", and try building the app first. +#endif diff --git a/nitrogen/generated/ios/VisionCameraMLKitAutolinking.mm b/nitrogen/generated/ios/VisionCameraMLKitAutolinking.mm new file mode 100644 index 0000000..e0f195e --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKitAutolinking.mm @@ -0,0 +1,33 @@ +/// +/// VisionCameraMLKitAutolinking.mm +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#import +#import +#import "VisionCameraMLKit-Swift-Cxx-Umbrella.hpp" +#import + +#include "HybridVisionCameraMLKitSpecSwift.hpp" + +@interface VisionCameraMLKitAutolinking : NSObject +@end + +@implementation VisionCameraMLKitAutolinking + ++ (void) load { + using namespace margelo::nitro; + using namespace margelo::nitro::visioncameramlkit; + + HybridObjectRegistry::registerHybridObjectConstructor( + "VisionCameraMLKit", + []() -> std::shared_ptr { + std::shared_ptr hybridObject = VisionCameraMLKit::VisionCameraMLKitAutolinking::createVisionCameraMLKit(); + return hybridObject; + } + ); +} + +@end diff --git a/nitrogen/generated/ios/VisionCameraMLKitAutolinking.swift b/nitrogen/generated/ios/VisionCameraMLKitAutolinking.swift new file mode 100644 index 0000000..ea9ddd3 --- /dev/null +++ b/nitrogen/generated/ios/VisionCameraMLKitAutolinking.swift @@ -0,0 +1,26 @@ +/// +/// VisionCameraMLKitAutolinking.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +// TODO: Use empty enums once Swift supports exporting them as namespaces +// See: https://github.com/swiftlang/swift/pull/83616 +public final class VisionCameraMLKitAutolinking { + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + public static func createVisionCameraMLKit() -> bridge.std__shared_ptr_HybridVisionCameraMLKitSpec_ { + let hybridObject = HybridVisionCameraMLKit() + return { () -> bridge.std__shared_ptr_HybridVisionCameraMLKitSpec_ in + let __cxxWrapped = hybridObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() + }() + } + + public static func isVisionCameraMLKitRecyclable() -> Bool { + return HybridVisionCameraMLKit.self is any RecyclableView.Type + } +} diff --git a/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.cpp b/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.cpp new file mode 100644 index 0000000..4f850da --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.cpp @@ -0,0 +1,11 @@ +/// +/// HybridBarcodeScannerSpecSwift.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridBarcodeScannerSpecSwift.hpp" + +namespace margelo::nitro::visioncameramlkit { +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.hpp b/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.hpp new file mode 100644 index 0000000..48d857f --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridBarcodeScannerSpecSwift.hpp @@ -0,0 +1,121 @@ +/// +/// HybridBarcodeScannerSpecSwift.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include "HybridBarcodeScannerSpec.hpp" + +// Forward declaration of `HybridBarcodeScannerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridBarcodeScannerSpec_cxx; } + +// Forward declaration of `BarcodeScannerResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerResult; } +// Forward declaration of `BarcodeScannerBarcode` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerBarcode; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `BarcodeValueTypeName` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeValueTypeName; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "BarcodeScannerResult.hpp" +#include "BarcodeScannerBarcode.hpp" +#include +#include "BoundingBox.hpp" +#include +#include "Corner.hpp" +#include "BarcodeFormat.hpp" +#include "BarcodeValueTypeName.hpp" +#include +#include +#include +#include +#include "MLKitBaseArguments.hpp" +#include "Orientation.hpp" +#include + +#include "VisionCameraMLKit-Swift-Cxx-Umbrella.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * The C++ part of HybridBarcodeScannerSpec_cxx.swift. + * + * HybridBarcodeScannerSpecSwift (C++) accesses HybridBarcodeScannerSpec_cxx (Swift), and might + * contain some additional bridging code for C++ <> Swift interop. + * + * Since this obviously introduces an overhead, I hope at some point in + * the future, HybridBarcodeScannerSpec_cxx can directly inherit from the C++ class HybridBarcodeScannerSpec + * to simplify the whole structure and memory management. + */ + class HybridBarcodeScannerSpecSwift: public virtual HybridBarcodeScannerSpec { + public: + // Constructor from a Swift instance + explicit HybridBarcodeScannerSpecSwift(const VisionCameraMLKit::HybridBarcodeScannerSpec_cxx& swiftPart): + HybridObject(HybridBarcodeScannerSpec::TAG), + _swiftPart(swiftPart) { } + + public: + // Get the Swift part + inline VisionCameraMLKit::HybridBarcodeScannerSpec_cxx& getSwiftPart() noexcept { + return _swiftPart; + } + + public: + inline size_t getExternalMemorySize() noexcept override { + return _swiftPart.getMemorySize(); + } + bool equals(const std::shared_ptr& other) override { + if (auto otherCast = std::dynamic_pointer_cast(other)) { + return _swiftPart.equals(otherCast->_swiftPart); + } + return false; + } + void dispose() noexcept override { + _swiftPart.dispose(); + } + std::string toString() override { + return _swiftPart.toString(); + } + + public: + // Properties + + + public: + // Methods + inline BarcodeScannerResult recognize(const std::shared_ptr& frame, const std::optional& args) override { + auto __result = _swiftPart.recognize(frame, args); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::shared_ptr> recognizeImage(const std::string& uri) override { + auto __result = _swiftPart.recognizeImage(uri); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + + private: + VisionCameraMLKit::HybridBarcodeScannerSpec_cxx _swiftPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.cpp b/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.cpp new file mode 100644 index 0000000..2b94b1d --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.cpp @@ -0,0 +1,11 @@ +/// +/// HybridTextRecognizerSpecSwift.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridTextRecognizerSpecSwift.hpp" + +namespace margelo::nitro::visioncameramlkit { +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.hpp b/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.hpp new file mode 100644 index 0000000..7dc3c66 --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridTextRecognizerSpecSwift.hpp @@ -0,0 +1,125 @@ +/// +/// HybridTextRecognizerSpecSwift.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include "HybridTextRecognizerSpec.hpp" + +// Forward declaration of `HybridTextRecognizerSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridTextRecognizerSpec_cxx; } + +// Forward declaration of `TextRecognitionResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognitionResult; } +// Forward declaration of `TextBlock` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextBlock; } +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `TextLine` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextLine; } +// Forward declaration of `TextElement` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextElement; } +// Forward declaration of `TextSymbol` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextSymbol; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "TextRecognitionResult.hpp" +#include +#include "TextBlock.hpp" +#include +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include "TextLine.hpp" +#include +#include +#include +#include "TextElement.hpp" +#include "TextSymbol.hpp" +#include +#include +#include "MLKitBaseArguments.hpp" +#include "Orientation.hpp" +#include + +#include "VisionCameraMLKit-Swift-Cxx-Umbrella.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * The C++ part of HybridTextRecognizerSpec_cxx.swift. + * + * HybridTextRecognizerSpecSwift (C++) accesses HybridTextRecognizerSpec_cxx (Swift), and might + * contain some additional bridging code for C++ <> Swift interop. + * + * Since this obviously introduces an overhead, I hope at some point in + * the future, HybridTextRecognizerSpec_cxx can directly inherit from the C++ class HybridTextRecognizerSpec + * to simplify the whole structure and memory management. + */ + class HybridTextRecognizerSpecSwift: public virtual HybridTextRecognizerSpec { + public: + // Constructor from a Swift instance + explicit HybridTextRecognizerSpecSwift(const VisionCameraMLKit::HybridTextRecognizerSpec_cxx& swiftPart): + HybridObject(HybridTextRecognizerSpec::TAG), + _swiftPart(swiftPart) { } + + public: + // Get the Swift part + inline VisionCameraMLKit::HybridTextRecognizerSpec_cxx& getSwiftPart() noexcept { + return _swiftPart; + } + + public: + inline size_t getExternalMemorySize() noexcept override { + return _swiftPart.getMemorySize(); + } + bool equals(const std::shared_ptr& other) override { + if (auto otherCast = std::dynamic_pointer_cast(other)) { + return _swiftPart.equals(otherCast->_swiftPart); + } + return false; + } + void dispose() noexcept override { + _swiftPart.dispose(); + } + std::string toString() override { + return _swiftPart.toString(); + } + + public: + // Properties + + + public: + // Methods + inline TextRecognitionResult recognize(const std::shared_ptr& frame, const std::optional& args) override { + auto __result = _swiftPart.recognize(frame, args); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::shared_ptr> recognizeImage(const std::string& uri) override { + auto __result = _swiftPart.recognizeImage(uri); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + + private: + VisionCameraMLKit::HybridTextRecognizerSpec_cxx _swiftPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.cpp b/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.cpp new file mode 100644 index 0000000..ed5a009 --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.cpp @@ -0,0 +1,11 @@ +/// +/// HybridVisionCameraMLKitSpecSwift.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridVisionCameraMLKitSpecSwift.hpp" + +namespace margelo::nitro::visioncameramlkit { +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.hpp b/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.hpp new file mode 100644 index 0000000..b73a252 --- /dev/null +++ b/nitrogen/generated/ios/c++/HybridVisionCameraMLKitSpecSwift.hpp @@ -0,0 +1,129 @@ +/// +/// HybridVisionCameraMLKitSpecSwift.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#include "HybridVisionCameraMLKitSpec.hpp" + +// Forward declaration of `HybridVisionCameraMLKitSpec_cxx` to properly resolve imports. +namespace VisionCameraMLKit { class HybridVisionCameraMLKitSpec_cxx; } + +// Forward declaration of `MLKitFeature` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class MLKitFeature; } +// Forward declaration of `HybridTextRecognizerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridTextRecognizerSpec; } +// Forward declaration of `TextRecognizerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognizerOptions; } +// Forward declaration of `TextRecognitionLanguage` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class TextRecognitionLanguage; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `RegionOfInterestUnit` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class RegionOfInterestUnit; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } +// Forward declaration of `HybridBarcodeScannerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridBarcodeScannerSpec; } +// Forward declaration of `BarcodeScannerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerOptions; } +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } + +#include "MLKitFeature.hpp" +#include +#include "HybridTextRecognizerSpec.hpp" +#include "TextRecognizerOptions.hpp" +#include "TextRecognitionLanguage.hpp" +#include +#include "RegionOfInterest.hpp" +#include "RegionOfInterestUnit.hpp" +#include "Orientation.hpp" +#include "HybridBarcodeScannerSpec.hpp" +#include "BarcodeScannerOptions.hpp" +#include "BarcodeFormat.hpp" +#include + +#include "VisionCameraMLKit-Swift-Cxx-Umbrella.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * The C++ part of HybridVisionCameraMLKitSpec_cxx.swift. + * + * HybridVisionCameraMLKitSpecSwift (C++) accesses HybridVisionCameraMLKitSpec_cxx (Swift), and might + * contain some additional bridging code for C++ <> Swift interop. + * + * Since this obviously introduces an overhead, I hope at some point in + * the future, HybridVisionCameraMLKitSpec_cxx can directly inherit from the C++ class HybridVisionCameraMLKitSpec + * to simplify the whole structure and memory management. + */ + class HybridVisionCameraMLKitSpecSwift: public virtual HybridVisionCameraMLKitSpec { + public: + // Constructor from a Swift instance + explicit HybridVisionCameraMLKitSpecSwift(const VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx& swiftPart): + HybridObject(HybridVisionCameraMLKitSpec::TAG), + _swiftPart(swiftPart) { } + + public: + // Get the Swift part + inline VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx& getSwiftPart() noexcept { + return _swiftPart; + } + + public: + inline size_t getExternalMemorySize() noexcept override { + return _swiftPart.getMemorySize(); + } + bool equals(const std::shared_ptr& other) override { + if (auto otherCast = std::dynamic_pointer_cast(other)) { + return _swiftPart.equals(otherCast->_swiftPart); + } + return false; + } + void dispose() noexcept override { + _swiftPart.dispose(); + } + std::string toString() override { + return _swiftPart.toString(); + } + + public: + // Properties + + + public: + // Methods + inline bool isFeatureAvailable(MLKitFeature feature) override { + auto __result = _swiftPart.isFeatureAvailable(static_cast(feature)); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::shared_ptr createTextRecognizer(const TextRecognizerOptions& options) override { + auto __result = _swiftPart.createTextRecognizer(std::forward(options)); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + inline std::shared_ptr createBarcodeScanner(const BarcodeScannerOptions& options) override { + auto __result = _swiftPart.createBarcodeScanner(std::forward(options)); + if (__result.hasError()) [[unlikely]] { + std::rethrow_exception(__result.error()); + } + auto __value = std::move(__result.value()); + return __value; + } + + private: + VisionCameraMLKit::HybridVisionCameraMLKitSpec_cxx _swiftPart; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/ios/swift/BarcodeFormat.swift b/nitrogen/generated/ios/swift/BarcodeFormat.swift new file mode 100644 index 0000000..65e565e --- /dev/null +++ b/nitrogen/generated/ios/swift/BarcodeFormat.swift @@ -0,0 +1,92 @@ +/// +/// BarcodeFormat.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `BarcodeFormat`, backed by a C++ enum. + */ +public typealias BarcodeFormat = margelo.nitro.visioncameramlkit.BarcodeFormat + +public extension BarcodeFormat { + /** + * Get a BarcodeFormat for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "UNKNOWN": + self = .unknown + case "ALL_FORMATS": + self = .allFormats + case "CODE_128": + self = .code128 + case "CODE_39": + self = .code39 + case "CODE_93": + self = .code93 + case "CODABAR": + self = .codabar + case "DATA_MATRIX": + self = .dataMatrix + case "EAN_13": + self = .ean13 + case "EAN_8": + self = .ean8 + case "ITF": + self = .itf + case "QR_CODE": + self = .qrCode + case "UPC_A": + self = .upcA + case "UPC_E": + self = .upcE + case "PDF417": + self = .pdf417 + case "AZTEC": + self = .aztec + default: + return nil + } + } + + /** + * Get the String value this BarcodeFormat represents. + */ + var stringValue: String { + switch self { + case .unknown: + return "UNKNOWN" + case .allFormats: + return "ALL_FORMATS" + case .code128: + return "CODE_128" + case .code39: + return "CODE_39" + case .code93: + return "CODE_93" + case .codabar: + return "CODABAR" + case .dataMatrix: + return "DATA_MATRIX" + case .ean13: + return "EAN_13" + case .ean8: + return "EAN_8" + case .itf: + return "ITF" + case .qrCode: + return "QR_CODE" + case .upcA: + return "UPC_A" + case .upcE: + return "UPC_E" + case .pdf417: + return "PDF417" + case .aztec: + return "AZTEC" + } + } +} diff --git a/nitrogen/generated/ios/swift/BarcodeScannerBarcode.swift b/nitrogen/generated/ios/swift/BarcodeScannerBarcode.swift new file mode 100644 index 0000000..a788533 --- /dev/null +++ b/nitrogen/generated/ios/swift/BarcodeScannerBarcode.swift @@ -0,0 +1,162 @@ +/// +/// BarcodeScannerBarcode.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `BarcodeScannerBarcode`, backed by a C++ struct. + */ +public typealias BarcodeScannerBarcode = margelo.nitro.visioncameramlkit.BarcodeScannerBarcode + +public extension BarcodeScannerBarcode { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `BarcodeScannerBarcode`. + */ + init(bounds: BoundingBox?, corners: [Corner]?, format: Double, formatName: BarcodeFormat, valueType: Double, valueTypeName: BarcodeValueTypeName, rawValue: String?, displayValue: String?, rawBytes: [Double]?, value: AnyMap?, isPotential: Bool) { + self.init({ () -> bridge.std__optional_BoundingBox_ in + if let __unwrappedValue = bounds { + return bridge.create_std__optional_BoundingBox_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__vector_Corner__ in + if let __unwrappedValue = corners { + return bridge.create_std__optional_std__vector_Corner__({ () -> bridge.std__vector_Corner_ in + var __vector = bridge.create_std__vector_Corner_(__unwrappedValue.count) + for __item in __unwrappedValue { + __vector.push_back(__item) + } + return __vector + }()) + } else { + return .init() + } + }(), format, formatName, valueType, valueTypeName, { () -> bridge.std__optional_std__string_ in + if let __unwrappedValue = rawValue { + return bridge.create_std__optional_std__string_(std.string(__unwrappedValue)) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__string_ in + if let __unwrappedValue = displayValue { + return bridge.create_std__optional_std__string_(std.string(__unwrappedValue)) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__vector_double__ in + if let __unwrappedValue = rawBytes { + return bridge.create_std__optional_std__vector_double__({ () -> bridge.std__vector_double_ in + var __vector = bridge.create_std__vector_double_(__unwrappedValue.count) + for __item in __unwrappedValue { + __vector.push_back(__item) + } + return __vector + }()) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__shared_ptr_AnyMap__ in + if let __unwrappedValue = value { + return bridge.create_std__optional_std__shared_ptr_AnyMap__(__unwrappedValue.cppPart) + } else { + return .init() + } + }(), isPotential) + } + + @inline(__always) + var bounds: BoundingBox? { + return self.__bounds.value + } + + @inline(__always) + var corners: [Corner]? { + return { () -> [Corner]? in + if bridge.has_value_std__optional_std__vector_Corner__(self.__corners) { + let __unwrapped = bridge.get_std__optional_std__vector_Corner__(self.__corners) + return __unwrapped.map({ __item in __item }) + } else { + return nil + } + }() + } + + @inline(__always) + var format: Double { + return self.__format + } + + @inline(__always) + var formatName: BarcodeFormat { + return self.__formatName + } + + @inline(__always) + var valueType: Double { + return self.__valueType + } + + @inline(__always) + var valueTypeName: BarcodeValueTypeName { + return self.__valueTypeName + } + + @inline(__always) + var rawValue: String? { + return { () -> String? in + if bridge.has_value_std__optional_std__string_(self.__rawValue) { + let __unwrapped = bridge.get_std__optional_std__string_(self.__rawValue) + return String(__unwrapped) + } else { + return nil + } + }() + } + + @inline(__always) + var displayValue: String? { + return { () -> String? in + if bridge.has_value_std__optional_std__string_(self.__displayValue) { + let __unwrapped = bridge.get_std__optional_std__string_(self.__displayValue) + return String(__unwrapped) + } else { + return nil + } + }() + } + + @inline(__always) + var rawBytes: [Double]? { + return { () -> [Double]? in + if bridge.has_value_std__optional_std__vector_double__(self.__rawBytes) { + let __unwrapped = bridge.get_std__optional_std__vector_double__(self.__rawBytes) + return __unwrapped.map({ __item in __item }) + } else { + return nil + } + }() + } + + @inline(__always) + var value: AnyMap? { + return { () -> AnyMap? in + if bridge.has_value_std__optional_std__shared_ptr_AnyMap__(self.__value) { + let __unwrapped = bridge.get_std__optional_std__shared_ptr_AnyMap__(self.__value) + return AnyMap(withCppPart: __unwrapped) + } else { + return nil + } + }() + } + + @inline(__always) + var isPotential: Bool { + return self.__isPotential + } +} diff --git a/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift b/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift new file mode 100644 index 0000000..44913a2 --- /dev/null +++ b/nitrogen/generated/ios/swift/BarcodeScannerOptions.swift @@ -0,0 +1,142 @@ +/// +/// BarcodeScannerOptions.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `BarcodeScannerOptions`, backed by a C++ struct. + */ +public typealias BarcodeScannerOptions = margelo.nitro.visioncameramlkit.BarcodeScannerOptions + +public extension BarcodeScannerOptions { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `BarcodeScannerOptions`. + */ + init(formats: [BarcodeFormat]?, enableAllPotentialBarcodes: Bool?, scaleFactor: Double?, invertColors: Bool?, frameProcessInterval: Double?, roi: RegionOfInterest?, orientation: Orientation?) { + self.init({ () -> bridge.std__optional_std__vector_BarcodeFormat__ in + if let __unwrappedValue = formats { + return bridge.create_std__optional_std__vector_BarcodeFormat__({ () -> bridge.std__vector_BarcodeFormat_ in + var __vector = bridge.create_std__vector_BarcodeFormat_(__unwrappedValue.count) + for __item in __unwrappedValue { + __vector.push_back(__item) + } + return __vector + }()) + } else { + return .init() + } + }(), { () -> bridge.std__optional_bool_ in + if let __unwrappedValue = enableAllPotentialBarcodes { + return bridge.create_std__optional_bool_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_double_ in + if let __unwrappedValue = scaleFactor { + return bridge.create_std__optional_double_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_bool_ in + if let __unwrappedValue = invertColors { + return bridge.create_std__optional_bool_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_double_ in + if let __unwrappedValue = frameProcessInterval { + return bridge.create_std__optional_double_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_RegionOfInterest_ in + if let __unwrappedValue = roi { + return bridge.create_std__optional_RegionOfInterest_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_Orientation_ in + if let __unwrappedValue = orientation { + return bridge.create_std__optional_Orientation_(__unwrappedValue) + } else { + return .init() + } + }()) + } + + @inline(__always) + var formats: [BarcodeFormat]? { + return { () -> [BarcodeFormat]? in + if bridge.has_value_std__optional_std__vector_BarcodeFormat__(self.__formats) { + let __unwrapped = bridge.get_std__optional_std__vector_BarcodeFormat__(self.__formats) + return __unwrapped.map({ __item in __item }) + } else { + return nil + } + }() + } + + @inline(__always) + var enableAllPotentialBarcodes: Bool? { + return { () -> Bool? in + if bridge.has_value_std__optional_bool_(self.__enableAllPotentialBarcodes) { + let __unwrapped = bridge.get_std__optional_bool_(self.__enableAllPotentialBarcodes) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var scaleFactor: Double? { + return { () -> Double? in + if bridge.has_value_std__optional_double_(self.__scaleFactor) { + let __unwrapped = bridge.get_std__optional_double_(self.__scaleFactor) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var invertColors: Bool? { + return { () -> Bool? in + if bridge.has_value_std__optional_bool_(self.__invertColors) { + let __unwrapped = bridge.get_std__optional_bool_(self.__invertColors) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var frameProcessInterval: Double? { + return { () -> Double? in + if bridge.has_value_std__optional_double_(self.__frameProcessInterval) { + let __unwrapped = bridge.get_std__optional_double_(self.__frameProcessInterval) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var roi: RegionOfInterest? { + return self.__roi.value + } + + @inline(__always) + var orientation: Orientation? { + return self.__orientation.value + } +} diff --git a/nitrogen/generated/ios/swift/BarcodeScannerResult.swift b/nitrogen/generated/ios/swift/BarcodeScannerResult.swift new file mode 100644 index 0000000..4d4d679 --- /dev/null +++ b/nitrogen/generated/ios/swift/BarcodeScannerResult.swift @@ -0,0 +1,35 @@ +/// +/// BarcodeScannerResult.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `BarcodeScannerResult`, backed by a C++ struct. + */ +public typealias BarcodeScannerResult = margelo.nitro.visioncameramlkit.BarcodeScannerResult + +public extension BarcodeScannerResult { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `BarcodeScannerResult`. + */ + init(barcodes: [BarcodeScannerBarcode]) { + self.init({ () -> bridge.std__vector_BarcodeScannerBarcode_ in + var __vector = bridge.create_std__vector_BarcodeScannerBarcode_(barcodes.count) + for __item in barcodes { + __vector.push_back(__item) + } + return __vector + }()) + } + + @inline(__always) + var barcodes: [BarcodeScannerBarcode] { + return self.__barcodes.map({ __item in __item }) + } +} diff --git a/nitrogen/generated/ios/swift/BarcodeValueTypeName.swift b/nitrogen/generated/ios/swift/BarcodeValueTypeName.swift new file mode 100644 index 0000000..8dfd6a9 --- /dev/null +++ b/nitrogen/generated/ios/swift/BarcodeValueTypeName.swift @@ -0,0 +1,84 @@ +/// +/// BarcodeValueTypeName.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `BarcodeValueTypeName`, backed by a C++ enum. + */ +public typealias BarcodeValueTypeName = margelo.nitro.visioncameramlkit.BarcodeValueTypeName + +public extension BarcodeValueTypeName { + /** + * Get a BarcodeValueTypeName for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "TYPE_UNKNOWN": + self = .typeUnknown + case "TYPE_CONTACT_INFO": + self = .typeContactInfo + case "TYPE_EMAIL": + self = .typeEmail + case "TYPE_ISBN": + self = .typeIsbn + case "TYPE_PHONE": + self = .typePhone + case "TYPE_PRODUCT": + self = .typeProduct + case "TYPE_SMS": + self = .typeSms + case "TYPE_TEXT": + self = .typeText + case "TYPE_URL": + self = .typeUrl + case "TYPE_WIFI": + self = .typeWifi + case "TYPE_GEO": + self = .typeGeo + case "TYPE_CALENDAR_EVENT": + self = .typeCalendarEvent + case "TYPE_DRIVER_LICENSE": + self = .typeDriverLicense + default: + return nil + } + } + + /** + * Get the String value this BarcodeValueTypeName represents. + */ + var stringValue: String { + switch self { + case .typeUnknown: + return "TYPE_UNKNOWN" + case .typeContactInfo: + return "TYPE_CONTACT_INFO" + case .typeEmail: + return "TYPE_EMAIL" + case .typeIsbn: + return "TYPE_ISBN" + case .typePhone: + return "TYPE_PHONE" + case .typeProduct: + return "TYPE_PRODUCT" + case .typeSms: + return "TYPE_SMS" + case .typeText: + return "TYPE_TEXT" + case .typeUrl: + return "TYPE_URL" + case .typeWifi: + return "TYPE_WIFI" + case .typeGeo: + return "TYPE_GEO" + case .typeCalendarEvent: + return "TYPE_CALENDAR_EVENT" + case .typeDriverLicense: + return "TYPE_DRIVER_LICENSE" + } + } +} diff --git a/nitrogen/generated/ios/swift/BoundingBox.swift b/nitrogen/generated/ios/swift/BoundingBox.swift new file mode 100644 index 0000000..d230897 --- /dev/null +++ b/nitrogen/generated/ios/swift/BoundingBox.swift @@ -0,0 +1,74 @@ +/// +/// BoundingBox.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `BoundingBox`, backed by a C++ struct. + */ +public typealias BoundingBox = margelo.nitro.visioncameramlkit.BoundingBox + +public extension BoundingBox { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `BoundingBox`. + */ + init(x: Double, y: Double, centerX: Double, centerY: Double, width: Double, height: Double, top: Double, left: Double, bottom: Double, right: Double) { + self.init(x, y, centerX, centerY, width, height, top, left, bottom, right) + } + + @inline(__always) + var x: Double { + return self.__x + } + + @inline(__always) + var y: Double { + return self.__y + } + + @inline(__always) + var centerX: Double { + return self.__centerX + } + + @inline(__always) + var centerY: Double { + return self.__centerY + } + + @inline(__always) + var width: Double { + return self.__width + } + + @inline(__always) + var height: Double { + return self.__height + } + + @inline(__always) + var top: Double { + return self.__top + } + + @inline(__always) + var left: Double { + return self.__left + } + + @inline(__always) + var bottom: Double { + return self.__bottom + } + + @inline(__always) + var right: Double { + return self.__right + } +} diff --git a/nitrogen/generated/ios/swift/Corner.swift b/nitrogen/generated/ios/swift/Corner.swift new file mode 100644 index 0000000..f62d6da --- /dev/null +++ b/nitrogen/generated/ios/swift/Corner.swift @@ -0,0 +1,34 @@ +/// +/// Corner.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `Corner`, backed by a C++ struct. + */ +public typealias Corner = margelo.nitro.visioncameramlkit.Corner + +public extension Corner { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `Corner`. + */ + init(x: Double, y: Double) { + self.init(x, y) + } + + @inline(__always) + var x: Double { + return self.__x + } + + @inline(__always) + var y: Double { + return self.__y + } +} diff --git a/nitrogen/generated/ios/swift/Func_void_BarcodeScannerResult.swift b/nitrogen/generated/ios/swift/Func_void_BarcodeScannerResult.swift new file mode 100644 index 0000000..1863916 --- /dev/null +++ b/nitrogen/generated/ios/swift/Func_void_BarcodeScannerResult.swift @@ -0,0 +1,46 @@ +/// +/// Func_void_BarcodeScannerResult.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Wraps a Swift `(_ value: BarcodeScannerResult) -> Void` as a class. + * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`. + */ +public final class Func_void_BarcodeScannerResult { + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + private let closure: (_ value: BarcodeScannerResult) -> Void + + public init(_ closure: @escaping (_ value: BarcodeScannerResult) -> Void) { + self.closure = closure + } + + @inline(__always) + public func call(value: BarcodeScannerResult) -> Void { + self.closure(value) + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + @inline(__always) + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `Func_void_BarcodeScannerResult`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + @inline(__always) + public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_BarcodeScannerResult { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } +} diff --git a/nitrogen/generated/ios/swift/Func_void_TextRecognitionResult.swift b/nitrogen/generated/ios/swift/Func_void_TextRecognitionResult.swift new file mode 100644 index 0000000..6627cb1 --- /dev/null +++ b/nitrogen/generated/ios/swift/Func_void_TextRecognitionResult.swift @@ -0,0 +1,46 @@ +/// +/// Func_void_TextRecognitionResult.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Wraps a Swift `(_ value: TextRecognitionResult) -> Void` as a class. + * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`. + */ +public final class Func_void_TextRecognitionResult { + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + private let closure: (_ value: TextRecognitionResult) -> Void + + public init(_ closure: @escaping (_ value: TextRecognitionResult) -> Void) { + self.closure = closure + } + + @inline(__always) + public func call(value: TextRecognitionResult) -> Void { + self.closure(value) + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + @inline(__always) + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `Func_void_TextRecognitionResult`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + @inline(__always) + public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_TextRecognitionResult { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } +} diff --git a/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift b/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift new file mode 100644 index 0000000..7c53657 --- /dev/null +++ b/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift @@ -0,0 +1,46 @@ +/// +/// Func_void_std__exception_ptr.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Wraps a Swift `(_ error: Error) -> Void` as a class. + * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`. + */ +public final class Func_void_std__exception_ptr { + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + private let closure: (_ error: Error) -> Void + + public init(_ closure: @escaping (_ error: Error) -> Void) { + self.closure = closure + } + + @inline(__always) + public func call(error: std.exception_ptr) -> Void { + self.closure(RuntimeError.from(cppError: error)) + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + @inline(__always) + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `Func_void_std__exception_ptr`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + @inline(__always) + public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_std__exception_ptr { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } +} diff --git a/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec.swift b/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec.swift new file mode 100644 index 0000000..6122920 --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec.swift @@ -0,0 +1,57 @@ +/// +/// HybridBarcodeScannerSpec.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import VisionCamera +import NitroModules + +/// See ``HybridBarcodeScannerSpec`` +public protocol HybridBarcodeScannerSpec_protocol: HybridObject { + // Properties + + + // Methods + func recognize(frame: (any HybridFrameSpec), args: MLKitBaseArguments?) throws -> BarcodeScannerResult + func recognizeImage(uri: String) throws -> Promise +} + +public extension HybridBarcodeScannerSpec_protocol { + /// Default implementation of ``HybridObject.toString`` + func toString() -> String { + return "[HybridObject BarcodeScanner]" + } +} + +/// See ``HybridBarcodeScannerSpec`` +open class HybridBarcodeScannerSpec_base { + private weak var cxxWrapper: HybridBarcodeScannerSpec_cxx? = nil + public init() { } + public func getCxxWrapper() -> HybridBarcodeScannerSpec_cxx { + #if DEBUG + guard self is any HybridBarcodeScannerSpec else { + fatalError("`self` is not a `HybridBarcodeScannerSpec`! Did you accidentally inherit from `HybridBarcodeScannerSpec_base` instead of `HybridBarcodeScannerSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridBarcodeScannerSpec_cxx(self as! any HybridBarcodeScannerSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } +} + +/** + * A Swift base-protocol representing the BarcodeScanner HybridObject. + * Implement this protocol to create Swift-based instances of BarcodeScanner. + * ```swift + * class HybridBarcodeScanner : HybridBarcodeScannerSpec { + * // ... + * } + * ``` + */ +public typealias HybridBarcodeScannerSpec = HybridBarcodeScannerSpec_protocol & HybridBarcodeScannerSpec_base diff --git a/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec_cxx.swift b/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec_cxx.swift new file mode 100644 index 0000000..cfc0080 --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridBarcodeScannerSpec_cxx.swift @@ -0,0 +1,162 @@ +/// +/// HybridBarcodeScannerSpec_cxx.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules +import VisionCamera + +/** + * A class implementation that bridges HybridBarcodeScannerSpec over to C++. + * In C++, we cannot use Swift protocols - so we need to wrap it in a class to make it strongly defined. + * + * Also, some Swift types need to be bridged with special handling: + * - Enums need to be wrapped in Structs, otherwise they cannot be accessed bi-directionally (Swift bug: https://github.com/swiftlang/swift/issues/75330) + * - Other HybridObjects need to be wrapped/unwrapped from the Swift TCxx wrapper + * - Throwing methods need to be wrapped with a Result type, as exceptions cannot be propagated to C++ + */ +open class HybridBarcodeScannerSpec_cxx { + /** + * The Swift <> C++ bridge's namespace (`margelo::nitro::visioncameramlkit::bridge::swift`) + * from `VisionCameraMLKit-Swift-Cxx-Bridge.hpp`. + * This contains specialized C++ templates, and C++ helper functions that can be accessed from Swift. + */ + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Holds an instance of the `HybridBarcodeScannerSpec` Swift protocol. + */ + private var __implementation: any HybridBarcodeScannerSpec + + /** + * Holds a weak pointer to the C++ class that wraps the Swift class. + */ + private var __cxxPart: bridge.std__weak_ptr_HybridBarcodeScannerSpec_ + + /** + * Create a new `HybridBarcodeScannerSpec_cxx` that wraps the given `HybridBarcodeScannerSpec`. + * All properties and methods bridge to C++ types. + */ + public init(_ implementation: any HybridBarcodeScannerSpec) { + self.__implementation = implementation + self.__cxxPart = .init() + /* no base class */ + } + + /** + * Get the actual `HybridBarcodeScannerSpec` instance this class wraps. + */ + @inline(__always) + public func getHybridBarcodeScannerSpec() -> any HybridBarcodeScannerSpec { + return __implementation + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `HybridBarcodeScannerSpec_cxx`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + public class func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> HybridBarcodeScannerSpec_cxx { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } + + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_HybridBarcodeScannerSpec_ { + let cachedCxxPart = self.__cxxPart.lock() + if Bool(fromCxx: cachedCxxPart) { + return cachedCxxPart + } else { + let newCxxPart = bridge.create_std__shared_ptr_HybridBarcodeScannerSpec_(self.toUnsafe()) + __cxxPart = bridge.weakify_std__shared_ptr_HybridBarcodeScannerSpec_(newCxxPart) + return newCxxPart + } + } + + + + /** + * Get the memory size of the Swift class (plus size of any other allocations) + * so the JS VM can properly track it and garbage-collect the JS object if needed. + */ + @inline(__always) + public var memorySize: Int { + return MemoryHelper.getSizeOf(self.__implementation) + self.__implementation.memorySize + } + + /** + * Compares this object with the given [other] object for reference equality. + */ + @inline(__always) + public func equals(other: HybridBarcodeScannerSpec_cxx) -> Bool { + return self.__implementation === other.__implementation + } + + /** + * Call dispose() on the Swift class. + * This _may_ be called manually from JS. + */ + @inline(__always) + public func dispose() { + self.__implementation.dispose() + } + + /** + * Call toString() on the Swift class. + */ + @inline(__always) + public func toString() -> String { + return self.__implementation.toString() + } + + // Properties + + + // Methods + @inline(__always) + public final func recognize(frame: bridge.std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_, args: bridge.std__optional_MLKitBaseArguments_) -> bridge.Result_BarcodeScannerResult_ { + do { + let __result = try self.__implementation.recognize(frame: { () -> any HybridFrameSpec in + let __unsafePointer = bridge.get_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(frame) + let __instance = HybridFrameSpec_cxx.fromUnsafe(__unsafePointer) + return __instance.getHybridFrameSpec() + }(), args: args.value) + let __resultCpp = __result + return bridge.create_Result_BarcodeScannerResult_(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_BarcodeScannerResult_(__exceptionPtr) + } + } + + @inline(__always) + public final func recognizeImage(uri: std.string) -> bridge.Result_std__shared_ptr_Promise_BarcodeScannerResult___ { + do { + let __result = try self.__implementation.recognizeImage(uri: String(uri)) + let __resultCpp = { () -> bridge.std__shared_ptr_Promise_BarcodeScannerResult__ in + let __promise = bridge.create_std__shared_ptr_Promise_BarcodeScannerResult__() + let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_BarcodeScannerResult__(__promise) + __result + .then({ __result in __promiseHolder.resolve(__result) }) + .catch({ __error in __promiseHolder.reject(__error.toCpp()) }) + return __promise + }() + return bridge.create_Result_std__shared_ptr_Promise_BarcodeScannerResult___(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__shared_ptr_Promise_BarcodeScannerResult___(__exceptionPtr) + } + } +} diff --git a/nitrogen/generated/ios/swift/HybridTextRecognizerSpec.swift b/nitrogen/generated/ios/swift/HybridTextRecognizerSpec.swift new file mode 100644 index 0000000..8dff317 --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridTextRecognizerSpec.swift @@ -0,0 +1,57 @@ +/// +/// HybridTextRecognizerSpec.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import VisionCamera +import NitroModules + +/// See ``HybridTextRecognizerSpec`` +public protocol HybridTextRecognizerSpec_protocol: HybridObject { + // Properties + + + // Methods + func recognize(frame: (any HybridFrameSpec), args: MLKitBaseArguments?) throws -> TextRecognitionResult + func recognizeImage(uri: String) throws -> Promise +} + +public extension HybridTextRecognizerSpec_protocol { + /// Default implementation of ``HybridObject.toString`` + func toString() -> String { + return "[HybridObject TextRecognizer]" + } +} + +/// See ``HybridTextRecognizerSpec`` +open class HybridTextRecognizerSpec_base { + private weak var cxxWrapper: HybridTextRecognizerSpec_cxx? = nil + public init() { } + public func getCxxWrapper() -> HybridTextRecognizerSpec_cxx { + #if DEBUG + guard self is any HybridTextRecognizerSpec else { + fatalError("`self` is not a `HybridTextRecognizerSpec`! Did you accidentally inherit from `HybridTextRecognizerSpec_base` instead of `HybridTextRecognizerSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridTextRecognizerSpec_cxx(self as! any HybridTextRecognizerSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } +} + +/** + * A Swift base-protocol representing the TextRecognizer HybridObject. + * Implement this protocol to create Swift-based instances of TextRecognizer. + * ```swift + * class HybridTextRecognizer : HybridTextRecognizerSpec { + * // ... + * } + * ``` + */ +public typealias HybridTextRecognizerSpec = HybridTextRecognizerSpec_protocol & HybridTextRecognizerSpec_base diff --git a/nitrogen/generated/ios/swift/HybridTextRecognizerSpec_cxx.swift b/nitrogen/generated/ios/swift/HybridTextRecognizerSpec_cxx.swift new file mode 100644 index 0000000..013329e --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridTextRecognizerSpec_cxx.swift @@ -0,0 +1,162 @@ +/// +/// HybridTextRecognizerSpec_cxx.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules +import VisionCamera + +/** + * A class implementation that bridges HybridTextRecognizerSpec over to C++. + * In C++, we cannot use Swift protocols - so we need to wrap it in a class to make it strongly defined. + * + * Also, some Swift types need to be bridged with special handling: + * - Enums need to be wrapped in Structs, otherwise they cannot be accessed bi-directionally (Swift bug: https://github.com/swiftlang/swift/issues/75330) + * - Other HybridObjects need to be wrapped/unwrapped from the Swift TCxx wrapper + * - Throwing methods need to be wrapped with a Result type, as exceptions cannot be propagated to C++ + */ +open class HybridTextRecognizerSpec_cxx { + /** + * The Swift <> C++ bridge's namespace (`margelo::nitro::visioncameramlkit::bridge::swift`) + * from `VisionCameraMLKit-Swift-Cxx-Bridge.hpp`. + * This contains specialized C++ templates, and C++ helper functions that can be accessed from Swift. + */ + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Holds an instance of the `HybridTextRecognizerSpec` Swift protocol. + */ + private var __implementation: any HybridTextRecognizerSpec + + /** + * Holds a weak pointer to the C++ class that wraps the Swift class. + */ + private var __cxxPart: bridge.std__weak_ptr_HybridTextRecognizerSpec_ + + /** + * Create a new `HybridTextRecognizerSpec_cxx` that wraps the given `HybridTextRecognizerSpec`. + * All properties and methods bridge to C++ types. + */ + public init(_ implementation: any HybridTextRecognizerSpec) { + self.__implementation = implementation + self.__cxxPart = .init() + /* no base class */ + } + + /** + * Get the actual `HybridTextRecognizerSpec` instance this class wraps. + */ + @inline(__always) + public func getHybridTextRecognizerSpec() -> any HybridTextRecognizerSpec { + return __implementation + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `HybridTextRecognizerSpec_cxx`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + public class func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> HybridTextRecognizerSpec_cxx { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } + + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_HybridTextRecognizerSpec_ { + let cachedCxxPart = self.__cxxPart.lock() + if Bool(fromCxx: cachedCxxPart) { + return cachedCxxPart + } else { + let newCxxPart = bridge.create_std__shared_ptr_HybridTextRecognizerSpec_(self.toUnsafe()) + __cxxPart = bridge.weakify_std__shared_ptr_HybridTextRecognizerSpec_(newCxxPart) + return newCxxPart + } + } + + + + /** + * Get the memory size of the Swift class (plus size of any other allocations) + * so the JS VM can properly track it and garbage-collect the JS object if needed. + */ + @inline(__always) + public var memorySize: Int { + return MemoryHelper.getSizeOf(self.__implementation) + self.__implementation.memorySize + } + + /** + * Compares this object with the given [other] object for reference equality. + */ + @inline(__always) + public func equals(other: HybridTextRecognizerSpec_cxx) -> Bool { + return self.__implementation === other.__implementation + } + + /** + * Call dispose() on the Swift class. + * This _may_ be called manually from JS. + */ + @inline(__always) + public func dispose() { + self.__implementation.dispose() + } + + /** + * Call toString() on the Swift class. + */ + @inline(__always) + public func toString() -> String { + return self.__implementation.toString() + } + + // Properties + + + // Methods + @inline(__always) + public final func recognize(frame: bridge.std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_, args: bridge.std__optional_MLKitBaseArguments_) -> bridge.Result_TextRecognitionResult_ { + do { + let __result = try self.__implementation.recognize(frame: { () -> any HybridFrameSpec in + let __unsafePointer = bridge.get_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(frame) + let __instance = HybridFrameSpec_cxx.fromUnsafe(__unsafePointer) + return __instance.getHybridFrameSpec() + }(), args: args.value) + let __resultCpp = __result + return bridge.create_Result_TextRecognitionResult_(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_TextRecognitionResult_(__exceptionPtr) + } + } + + @inline(__always) + public final func recognizeImage(uri: std.string) -> bridge.Result_std__shared_ptr_Promise_TextRecognitionResult___ { + do { + let __result = try self.__implementation.recognizeImage(uri: String(uri)) + let __resultCpp = { () -> bridge.std__shared_ptr_Promise_TextRecognitionResult__ in + let __promise = bridge.create_std__shared_ptr_Promise_TextRecognitionResult__() + let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_TextRecognitionResult__(__promise) + __result + .then({ __result in __promiseHolder.resolve(__result) }) + .catch({ __error in __promiseHolder.reject(__error.toCpp()) }) + return __promise + }() + return bridge.create_Result_std__shared_ptr_Promise_TextRecognitionResult___(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__shared_ptr_Promise_TextRecognitionResult___(__exceptionPtr) + } + } +} diff --git a/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec.swift b/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec.swift new file mode 100644 index 0000000..0c0ed11 --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec.swift @@ -0,0 +1,57 @@ +/// +/// HybridVisionCameraMLKitSpec.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/// See ``HybridVisionCameraMLKitSpec`` +public protocol HybridVisionCameraMLKitSpec_protocol: HybridObject { + // Properties + + + // Methods + func isFeatureAvailable(feature: MLKitFeature) throws -> Bool + func createTextRecognizer(options: TextRecognizerOptions) throws -> (any HybridTextRecognizerSpec) + func createBarcodeScanner(options: BarcodeScannerOptions) throws -> (any HybridBarcodeScannerSpec) +} + +public extension HybridVisionCameraMLKitSpec_protocol { + /// Default implementation of ``HybridObject.toString`` + func toString() -> String { + return "[HybridObject VisionCameraMLKit]" + } +} + +/// See ``HybridVisionCameraMLKitSpec`` +open class HybridVisionCameraMLKitSpec_base { + private weak var cxxWrapper: HybridVisionCameraMLKitSpec_cxx? = nil + public init() { } + public func getCxxWrapper() -> HybridVisionCameraMLKitSpec_cxx { + #if DEBUG + guard self is any HybridVisionCameraMLKitSpec else { + fatalError("`self` is not a `HybridVisionCameraMLKitSpec`! Did you accidentally inherit from `HybridVisionCameraMLKitSpec_base` instead of `HybridVisionCameraMLKitSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridVisionCameraMLKitSpec_cxx(self as! any HybridVisionCameraMLKitSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } +} + +/** + * A Swift base-protocol representing the VisionCameraMLKit HybridObject. + * Implement this protocol to create Swift-based instances of VisionCameraMLKit. + * ```swift + * class HybridVisionCameraMLKit : HybridVisionCameraMLKitSpec { + * // ... + * } + * ``` + */ +public typealias HybridVisionCameraMLKitSpec = HybridVisionCameraMLKitSpec_protocol & HybridVisionCameraMLKitSpec_base diff --git a/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec_cxx.swift b/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec_cxx.swift new file mode 100644 index 0000000..713de6d --- /dev/null +++ b/nitrogen/generated/ios/swift/HybridVisionCameraMLKitSpec_cxx.swift @@ -0,0 +1,168 @@ +/// +/// HybridVisionCameraMLKitSpec_cxx.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * A class implementation that bridges HybridVisionCameraMLKitSpec over to C++. + * In C++, we cannot use Swift protocols - so we need to wrap it in a class to make it strongly defined. + * + * Also, some Swift types need to be bridged with special handling: + * - Enums need to be wrapped in Structs, otherwise they cannot be accessed bi-directionally (Swift bug: https://github.com/swiftlang/swift/issues/75330) + * - Other HybridObjects need to be wrapped/unwrapped from the Swift TCxx wrapper + * - Throwing methods need to be wrapped with a Result type, as exceptions cannot be propagated to C++ + */ +open class HybridVisionCameraMLKitSpec_cxx { + /** + * The Swift <> C++ bridge's namespace (`margelo::nitro::visioncameramlkit::bridge::swift`) + * from `VisionCameraMLKit-Swift-Cxx-Bridge.hpp`. + * This contains specialized C++ templates, and C++ helper functions that can be accessed from Swift. + */ + public typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Holds an instance of the `HybridVisionCameraMLKitSpec` Swift protocol. + */ + private var __implementation: any HybridVisionCameraMLKitSpec + + /** + * Holds a weak pointer to the C++ class that wraps the Swift class. + */ + private var __cxxPart: bridge.std__weak_ptr_HybridVisionCameraMLKitSpec_ + + /** + * Create a new `HybridVisionCameraMLKitSpec_cxx` that wraps the given `HybridVisionCameraMLKitSpec`. + * All properties and methods bridge to C++ types. + */ + public init(_ implementation: any HybridVisionCameraMLKitSpec) { + self.__implementation = implementation + self.__cxxPart = .init() + /* no base class */ + } + + /** + * Get the actual `HybridVisionCameraMLKitSpec` instance this class wraps. + */ + @inline(__always) + public func getHybridVisionCameraMLKitSpec() -> any HybridVisionCameraMLKitSpec { + return __implementation + } + + /** + * Casts this instance to a retained unsafe raw pointer. + * This acquires one additional strong reference on the object! + */ + public func toUnsafe() -> UnsafeMutableRawPointer { + return Unmanaged.passRetained(self).toOpaque() + } + + /** + * Casts an unsafe pointer to a `HybridVisionCameraMLKitSpec_cxx`. + * The pointer has to be a retained opaque `Unmanaged`. + * This removes one strong reference from the object! + */ + public class func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> HybridVisionCameraMLKitSpec_cxx { + return Unmanaged.fromOpaque(pointer).takeRetainedValue() + } + + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_HybridVisionCameraMLKitSpec_ { + let cachedCxxPart = self.__cxxPart.lock() + if Bool(fromCxx: cachedCxxPart) { + return cachedCxxPart + } else { + let newCxxPart = bridge.create_std__shared_ptr_HybridVisionCameraMLKitSpec_(self.toUnsafe()) + __cxxPart = bridge.weakify_std__shared_ptr_HybridVisionCameraMLKitSpec_(newCxxPart) + return newCxxPart + } + } + + + + /** + * Get the memory size of the Swift class (plus size of any other allocations) + * so the JS VM can properly track it and garbage-collect the JS object if needed. + */ + @inline(__always) + public var memorySize: Int { + return MemoryHelper.getSizeOf(self.__implementation) + self.__implementation.memorySize + } + + /** + * Compares this object with the given [other] object for reference equality. + */ + @inline(__always) + public func equals(other: HybridVisionCameraMLKitSpec_cxx) -> Bool { + return self.__implementation === other.__implementation + } + + /** + * Call dispose() on the Swift class. + * This _may_ be called manually from JS. + */ + @inline(__always) + public func dispose() { + self.__implementation.dispose() + } + + /** + * Call toString() on the Swift class. + */ + @inline(__always) + public func toString() -> String { + return self.__implementation.toString() + } + + // Properties + + + // Methods + @inline(__always) + public final func isFeatureAvailable(feature: Int32) -> bridge.Result_bool_ { + do { + let __result = try self.__implementation.isFeatureAvailable(feature: margelo.nitro.visioncameramlkit.MLKitFeature(rawValue: feature)!) + let __resultCpp = __result + return bridge.create_Result_bool_(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_bool_(__exceptionPtr) + } + } + + @inline(__always) + public final func createTextRecognizer(options: TextRecognizerOptions) -> bridge.Result_std__shared_ptr_HybridTextRecognizerSpec__ { + do { + let __result = try self.__implementation.createTextRecognizer(options: options) + let __resultCpp = { () -> bridge.std__shared_ptr_HybridTextRecognizerSpec_ in + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() + }() + return bridge.create_Result_std__shared_ptr_HybridTextRecognizerSpec__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__shared_ptr_HybridTextRecognizerSpec__(__exceptionPtr) + } + } + + @inline(__always) + public final func createBarcodeScanner(options: BarcodeScannerOptions) -> bridge.Result_std__shared_ptr_HybridBarcodeScannerSpec__ { + do { + let __result = try self.__implementation.createBarcodeScanner(options: options) + let __resultCpp = { () -> bridge.std__shared_ptr_HybridBarcodeScannerSpec_ in + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() + }() + return bridge.create_Result_std__shared_ptr_HybridBarcodeScannerSpec__(__resultCpp) + } catch (let __error) { + let __exceptionPtr = __error.toCpp() + return bridge.create_Result_std__shared_ptr_HybridBarcodeScannerSpec__(__exceptionPtr) + } + } +} diff --git a/nitrogen/generated/ios/swift/MLKitBaseArguments.swift b/nitrogen/generated/ios/swift/MLKitBaseArguments.swift new file mode 100644 index 0000000..6012fd4 --- /dev/null +++ b/nitrogen/generated/ios/swift/MLKitBaseArguments.swift @@ -0,0 +1,35 @@ +/// +/// MLKitBaseArguments.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `MLKitBaseArguments`, backed by a C++ struct. + */ +public typealias MLKitBaseArguments = margelo.nitro.visioncameramlkit.MLKitBaseArguments + +public extension MLKitBaseArguments { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `MLKitBaseArguments`. + */ + init(outputOrientation: Orientation?) { + self.init({ () -> bridge.std__optional_Orientation_ in + if let __unwrappedValue = outputOrientation { + return bridge.create_std__optional_Orientation_(__unwrappedValue) + } else { + return .init() + } + }()) + } + + @inline(__always) + var outputOrientation: Orientation? { + return self.__outputOrientation.value + } +} diff --git a/nitrogen/generated/ios/swift/MLKitFeature.swift b/nitrogen/generated/ios/swift/MLKitFeature.swift new file mode 100644 index 0000000..8ce63b7 --- /dev/null +++ b/nitrogen/generated/ios/swift/MLKitFeature.swift @@ -0,0 +1,76 @@ +/// +/// MLKitFeature.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `MLKitFeature`, backed by a C++ enum. + */ +public typealias MLKitFeature = margelo.nitro.visioncameramlkit.MLKitFeature + +public extension MLKitFeature { + /** + * Get a MLKitFeature for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "TextRecognition": + self = .textrecognition + case "FaceDetection": + self = .facedetection + case "FaceMeshDetection": + self = .facemeshdetection + case "PoseDetection": + self = .posedetection + case "SelfieSegmentation": + self = .selfiesegmentation + case "SubjectSegmentation": + self = .subjectsegmentation + case "DocumentScanner": + self = .documentscanner + case "BarcodeScanning": + self = .barcodescanning + case "ImageLabeling": + self = .imagelabeling + case "ObjectDetection": + self = .objectdetection + case "DigitalInkRecognition": + self = .digitalinkrecognition + default: + return nil + } + } + + /** + * Get the String value this MLKitFeature represents. + */ + var stringValue: String { + switch self { + case .textrecognition: + return "TextRecognition" + case .facedetection: + return "FaceDetection" + case .facemeshdetection: + return "FaceMeshDetection" + case .posedetection: + return "PoseDetection" + case .selfiesegmentation: + return "SelfieSegmentation" + case .subjectsegmentation: + return "SubjectSegmentation" + case .documentscanner: + return "DocumentScanner" + case .barcodescanning: + return "BarcodeScanning" + case .imagelabeling: + return "ImageLabeling" + case .objectdetection: + return "ObjectDetection" + case .digitalinkrecognition: + return "DigitalInkRecognition" + } + } +} diff --git a/nitrogen/generated/ios/swift/Orientation.swift b/nitrogen/generated/ios/swift/Orientation.swift new file mode 100644 index 0000000..338dcb4 --- /dev/null +++ b/nitrogen/generated/ios/swift/Orientation.swift @@ -0,0 +1,48 @@ +/// +/// Orientation.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `Orientation`, backed by a C++ enum. + */ +public typealias Orientation = margelo.nitro.visioncameramlkit.Orientation + +public extension Orientation { + /** + * Get a Orientation for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "portrait": + self = .portrait + case "portrait-upside-down": + self = .portraitUpsideDown + case "landscape-left": + self = .landscapeLeft + case "landscape-right": + self = .landscapeRight + default: + return nil + } + } + + /** + * Get the String value this Orientation represents. + */ + var stringValue: String { + switch self { + case .portrait: + return "portrait" + case .portraitUpsideDown: + return "portrait-upside-down" + case .landscapeLeft: + return "landscape-left" + case .landscapeRight: + return "landscape-right" + } + } +} diff --git a/nitrogen/generated/ios/swift/RegionOfInterest.swift b/nitrogen/generated/ios/swift/RegionOfInterest.swift new file mode 100644 index 0000000..67af6d1 --- /dev/null +++ b/nitrogen/generated/ios/swift/RegionOfInterest.swift @@ -0,0 +1,55 @@ +/// +/// RegionOfInterest.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `RegionOfInterest`, backed by a C++ struct. + */ +public typealias RegionOfInterest = margelo.nitro.visioncameramlkit.RegionOfInterest + +public extension RegionOfInterest { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `RegionOfInterest`. + */ + init(x: Double, y: Double, width: Double, height: Double, unit: RegionOfInterestUnit?) { + self.init(x, y, width, height, { () -> bridge.std__optional_RegionOfInterestUnit_ in + if let __unwrappedValue = unit { + return bridge.create_std__optional_RegionOfInterestUnit_(__unwrappedValue) + } else { + return .init() + } + }()) + } + + @inline(__always) + var x: Double { + return self.__x + } + + @inline(__always) + var y: Double { + return self.__y + } + + @inline(__always) + var width: Double { + return self.__width + } + + @inline(__always) + var height: Double { + return self.__height + } + + @inline(__always) + var unit: RegionOfInterestUnit? { + return self.__unit.value + } +} diff --git a/nitrogen/generated/ios/swift/RegionOfInterestUnit.swift b/nitrogen/generated/ios/swift/RegionOfInterestUnit.swift new file mode 100644 index 0000000..1a4e5ac --- /dev/null +++ b/nitrogen/generated/ios/swift/RegionOfInterestUnit.swift @@ -0,0 +1,40 @@ +/// +/// RegionOfInterestUnit.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `RegionOfInterestUnit`, backed by a C++ enum. + */ +public typealias RegionOfInterestUnit = margelo.nitro.visioncameramlkit.RegionOfInterestUnit + +public extension RegionOfInterestUnit { + /** + * Get a RegionOfInterestUnit for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "normalized": + self = .normalized + case "pixel": + self = .pixel + default: + return nil + } + } + + /** + * Get the String value this RegionOfInterestUnit represents. + */ + var stringValue: String { + switch self { + case .normalized: + return "normalized" + case .pixel: + return "pixel" + } + } +} diff --git a/nitrogen/generated/ios/swift/TextBlock.swift b/nitrogen/generated/ios/swift/TextBlock.swift new file mode 100644 index 0000000..0c0cb43 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextBlock.swift @@ -0,0 +1,67 @@ +/// +/// TextBlock.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextBlock`, backed by a C++ struct. + */ +public typealias TextBlock = margelo.nitro.visioncameramlkit.TextBlock + +public extension TextBlock { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextBlock`. + */ + init(bounds: BoundingBox, corners: [Corner], languages: [String], text: String, lines: [TextLine]) { + self.init(bounds, { () -> bridge.std__vector_Corner_ in + var __vector = bridge.create_std__vector_Corner_(corners.count) + for __item in corners { + __vector.push_back(__item) + } + return __vector + }(), { () -> bridge.std__vector_std__string_ in + var __vector = bridge.create_std__vector_std__string_(languages.count) + for __item in languages { + __vector.push_back(std.string(__item)) + } + return __vector + }(), std.string(text), { () -> bridge.std__vector_TextLine_ in + var __vector = bridge.create_std__vector_TextLine_(lines.count) + for __item in lines { + __vector.push_back(__item) + } + return __vector + }()) + } + + @inline(__always) + var bounds: BoundingBox { + return self.__bounds + } + + @inline(__always) + var corners: [Corner] { + return self.__corners.map({ __item in __item }) + } + + @inline(__always) + var languages: [String] { + return self.__languages.map({ __item in String(__item) }) + } + + @inline(__always) + var text: String { + return String(self.__text) + } + + @inline(__always) + var lines: [TextLine] { + return self.__lines.map({ __item in __item }) + } +} diff --git a/nitrogen/generated/ios/swift/TextElement.swift b/nitrogen/generated/ios/swift/TextElement.swift new file mode 100644 index 0000000..c91f560 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextElement.swift @@ -0,0 +1,141 @@ +/// +/// TextElement.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextElement`, backed by a C++ struct. + */ +public typealias TextElement = margelo.nitro.visioncameramlkit.TextElement + +public extension TextElement { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextElement`. + */ + init(bounds: BoundingBox, corners: [Corner], confidence: Variant_NullType_Double?, angle: Variant_NullType_Double?, languages: [String], text: String, symbols: [TextSymbol]) { + self.init(bounds, { () -> bridge.std__vector_Corner_ in + var __vector = bridge.create_std__vector_Corner_(corners.count) + for __item in corners { + __vector.push_back(__item) + } + return __vector + }(), { () -> bridge.std__optional_std__variant_nitro__NullType__double__ in + if let __unwrappedValue = confidence { + return bridge.create_std__optional_std__variant_nitro__NullType__double__({ () -> bridge.std__variant_nitro__NullType__double_ in + switch __unwrappedValue { + case .first(let __value): + return bridge.create_std__variant_nitro__NullType__double_(margelo.nitro.NullType.null) + case .second(let __value): + return bridge.create_std__variant_nitro__NullType__double_(__value) + } + }().variant) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__variant_nitro__NullType__double__ in + if let __unwrappedValue = angle { + return bridge.create_std__optional_std__variant_nitro__NullType__double__({ () -> bridge.std__variant_nitro__NullType__double_ in + switch __unwrappedValue { + case .first(let __value): + return bridge.create_std__variant_nitro__NullType__double_(margelo.nitro.NullType.null) + case .second(let __value): + return bridge.create_std__variant_nitro__NullType__double_(__value) + } + }().variant) + } else { + return .init() + } + }(), { () -> bridge.std__vector_std__string_ in + var __vector = bridge.create_std__vector_std__string_(languages.count) + for __item in languages { + __vector.push_back(std.string(__item)) + } + return __vector + }(), std.string(text), { () -> bridge.std__vector_TextSymbol_ in + var __vector = bridge.create_std__vector_TextSymbol_(symbols.count) + for __item in symbols { + __vector.push_back(__item) + } + return __vector + }()) + } + + @inline(__always) + var bounds: BoundingBox { + return self.__bounds + } + + @inline(__always) + var corners: [Corner] { + return self.__corners.map({ __item in __item }) + } + + @inline(__always) + var confidence: Variant_NullType_Double? { + return { () -> Variant_NullType_Double? in + if bridge.has_value_std__optional_std__variant_nitro__NullType__double__(self.__confidence) { + let __unwrapped = bridge.get_std__optional_std__variant_nitro__NullType__double__(self.__confidence) + return { () -> Variant_NullType_Double in + let __variant = bridge.std__variant_nitro__NullType__double_(__unwrapped) + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(NullType.null) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }() + } else { + return nil + } + }() + } + + @inline(__always) + var angle: Variant_NullType_Double? { + return { () -> Variant_NullType_Double? in + if bridge.has_value_std__optional_std__variant_nitro__NullType__double__(self.__angle) { + let __unwrapped = bridge.get_std__optional_std__variant_nitro__NullType__double__(self.__angle) + return { () -> Variant_NullType_Double in + let __variant = bridge.std__variant_nitro__NullType__double_(__unwrapped) + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(NullType.null) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }() + } else { + return nil + } + }() + } + + @inline(__always) + var languages: [String] { + return self.__languages.map({ __item in String(__item) }) + } + + @inline(__always) + var text: String { + return String(self.__text) + } + + @inline(__always) + var symbols: [TextSymbol] { + return self.__symbols.map({ __item in __item }) + } +} diff --git a/nitrogen/generated/ios/swift/TextLine.swift b/nitrogen/generated/ios/swift/TextLine.swift new file mode 100644 index 0000000..3fd2d75 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextLine.swift @@ -0,0 +1,141 @@ +/// +/// TextLine.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextLine`, backed by a C++ struct. + */ +public typealias TextLine = margelo.nitro.visioncameramlkit.TextLine + +public extension TextLine { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextLine`. + */ + init(bounds: BoundingBox, corners: [Corner], confidence: Variant_NullType_Double?, angle: Variant_NullType_Double?, languages: [String], text: String, elements: [TextElement]) { + self.init(bounds, { () -> bridge.std__vector_Corner_ in + var __vector = bridge.create_std__vector_Corner_(corners.count) + for __item in corners { + __vector.push_back(__item) + } + return __vector + }(), { () -> bridge.std__optional_std__variant_nitro__NullType__double__ in + if let __unwrappedValue = confidence { + return bridge.create_std__optional_std__variant_nitro__NullType__double__({ () -> bridge.std__variant_nitro__NullType__double_ in + switch __unwrappedValue { + case .first(let __value): + return bridge.create_std__variant_nitro__NullType__double_(margelo.nitro.NullType.null) + case .second(let __value): + return bridge.create_std__variant_nitro__NullType__double_(__value) + } + }().variant) + } else { + return .init() + } + }(), { () -> bridge.std__optional_std__variant_nitro__NullType__double__ in + if let __unwrappedValue = angle { + return bridge.create_std__optional_std__variant_nitro__NullType__double__({ () -> bridge.std__variant_nitro__NullType__double_ in + switch __unwrappedValue { + case .first(let __value): + return bridge.create_std__variant_nitro__NullType__double_(margelo.nitro.NullType.null) + case .second(let __value): + return bridge.create_std__variant_nitro__NullType__double_(__value) + } + }().variant) + } else { + return .init() + } + }(), { () -> bridge.std__vector_std__string_ in + var __vector = bridge.create_std__vector_std__string_(languages.count) + for __item in languages { + __vector.push_back(std.string(__item)) + } + return __vector + }(), std.string(text), { () -> bridge.std__vector_TextElement_ in + var __vector = bridge.create_std__vector_TextElement_(elements.count) + for __item in elements { + __vector.push_back(__item) + } + return __vector + }()) + } + + @inline(__always) + var bounds: BoundingBox { + return self.__bounds + } + + @inline(__always) + var corners: [Corner] { + return self.__corners.map({ __item in __item }) + } + + @inline(__always) + var confidence: Variant_NullType_Double? { + return { () -> Variant_NullType_Double? in + if bridge.has_value_std__optional_std__variant_nitro__NullType__double__(self.__confidence) { + let __unwrapped = bridge.get_std__optional_std__variant_nitro__NullType__double__(self.__confidence) + return { () -> Variant_NullType_Double in + let __variant = bridge.std__variant_nitro__NullType__double_(__unwrapped) + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(NullType.null) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }() + } else { + return nil + } + }() + } + + @inline(__always) + var angle: Variant_NullType_Double? { + return { () -> Variant_NullType_Double? in + if bridge.has_value_std__optional_std__variant_nitro__NullType__double__(self.__angle) { + let __unwrapped = bridge.get_std__optional_std__variant_nitro__NullType__double__(self.__angle) + return { () -> Variant_NullType_Double in + let __variant = bridge.std__variant_nitro__NullType__double_(__unwrapped) + switch __variant.index() { + case 0: + let __actual = __variant.get_0() + return .first(NullType.null) + case 1: + let __actual = __variant.get_1() + return .second(__actual) + default: + fatalError("Variant can never have index \(__variant.index())!") + } + }() + } else { + return nil + } + }() + } + + @inline(__always) + var languages: [String] { + return self.__languages.map({ __item in String(__item) }) + } + + @inline(__always) + var text: String { + return String(self.__text) + } + + @inline(__always) + var elements: [TextElement] { + return self.__elements.map({ __item in __item }) + } +} diff --git a/nitrogen/generated/ios/swift/TextRecognitionLanguage.swift b/nitrogen/generated/ios/swift/TextRecognitionLanguage.swift new file mode 100644 index 0000000..1831fa7 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextRecognitionLanguage.swift @@ -0,0 +1,52 @@ +/// +/// TextRecognitionLanguage.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `TextRecognitionLanguage`, backed by a C++ enum. + */ +public typealias TextRecognitionLanguage = margelo.nitro.visioncameramlkit.TextRecognitionLanguage + +public extension TextRecognitionLanguage { + /** + * Get a TextRecognitionLanguage for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "LATIN": + self = .latin + case "CHINESE": + self = .chinese + case "DEVANAGARI": + self = .devanagari + case "JAPANESE": + self = .japanese + case "KOREAN": + self = .korean + default: + return nil + } + } + + /** + * Get the String value this TextRecognitionLanguage represents. + */ + var stringValue: String { + switch self { + case .latin: + return "LATIN" + case .chinese: + return "CHINESE" + case .devanagari: + return "DEVANAGARI" + case .japanese: + return "JAPANESE" + case .korean: + return "KOREAN" + } + } +} diff --git a/nitrogen/generated/ios/swift/TextRecognitionResult.swift b/nitrogen/generated/ios/swift/TextRecognitionResult.swift new file mode 100644 index 0000000..40ff4a7 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextRecognitionResult.swift @@ -0,0 +1,40 @@ +/// +/// TextRecognitionResult.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextRecognitionResult`, backed by a C++ struct. + */ +public typealias TextRecognitionResult = margelo.nitro.visioncameramlkit.TextRecognitionResult + +public extension TextRecognitionResult { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextRecognitionResult`. + */ + init(text: String, blocks: [TextBlock]) { + self.init(std.string(text), { () -> bridge.std__vector_TextBlock_ in + var __vector = bridge.create_std__vector_TextBlock_(blocks.count) + for __item in blocks { + __vector.push_back(__item) + } + return __vector + }()) + } + + @inline(__always) + var text: String { + return String(self.__text) + } + + @inline(__always) + var blocks: [TextBlock] { + return self.__blocks.map({ __item in __item }) + } +} diff --git a/nitrogen/generated/ios/swift/TextRecognizerOptions.swift b/nitrogen/generated/ios/swift/TextRecognizerOptions.swift new file mode 100644 index 0000000..ec3f15a --- /dev/null +++ b/nitrogen/generated/ios/swift/TextRecognizerOptions.swift @@ -0,0 +1,111 @@ +/// +/// TextRecognizerOptions.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextRecognizerOptions`, backed by a C++ struct. + */ +public typealias TextRecognizerOptions = margelo.nitro.visioncameramlkit.TextRecognizerOptions + +public extension TextRecognizerOptions { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextRecognizerOptions`. + */ + init(language: TextRecognitionLanguage?, scaleFactor: Double?, invertColors: Bool?, frameProcessInterval: Double?, roi: RegionOfInterest?, orientation: Orientation?) { + self.init({ () -> bridge.std__optional_TextRecognitionLanguage_ in + if let __unwrappedValue = language { + return bridge.create_std__optional_TextRecognitionLanguage_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_double_ in + if let __unwrappedValue = scaleFactor { + return bridge.create_std__optional_double_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_bool_ in + if let __unwrappedValue = invertColors { + return bridge.create_std__optional_bool_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_double_ in + if let __unwrappedValue = frameProcessInterval { + return bridge.create_std__optional_double_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_RegionOfInterest_ in + if let __unwrappedValue = roi { + return bridge.create_std__optional_RegionOfInterest_(__unwrappedValue) + } else { + return .init() + } + }(), { () -> bridge.std__optional_Orientation_ in + if let __unwrappedValue = orientation { + return bridge.create_std__optional_Orientation_(__unwrappedValue) + } else { + return .init() + } + }()) + } + + @inline(__always) + var language: TextRecognitionLanguage? { + return self.__language.value + } + + @inline(__always) + var scaleFactor: Double? { + return { () -> Double? in + if bridge.has_value_std__optional_double_(self.__scaleFactor) { + let __unwrapped = bridge.get_std__optional_double_(self.__scaleFactor) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var invertColors: Bool? { + return { () -> Bool? in + if bridge.has_value_std__optional_bool_(self.__invertColors) { + let __unwrapped = bridge.get_std__optional_bool_(self.__invertColors) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var frameProcessInterval: Double? { + return { () -> Double? in + if bridge.has_value_std__optional_double_(self.__frameProcessInterval) { + let __unwrapped = bridge.get_std__optional_double_(self.__frameProcessInterval) + return __unwrapped + } else { + return nil + } + }() + } + + @inline(__always) + var roi: RegionOfInterest? { + return self.__roi.value + } + + @inline(__always) + var orientation: Orientation? { + return self.__orientation.value + } +} diff --git a/nitrogen/generated/ios/swift/TextSymbol.swift b/nitrogen/generated/ios/swift/TextSymbol.swift new file mode 100644 index 0000000..d1e03f5 --- /dev/null +++ b/nitrogen/generated/ios/swift/TextSymbol.swift @@ -0,0 +1,66 @@ +/// +/// TextSymbol.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * Represents an instance of `TextSymbol`, backed by a C++ struct. + */ +public typealias TextSymbol = margelo.nitro.visioncameramlkit.TextSymbol + +public extension TextSymbol { + private typealias bridge = margelo.nitro.visioncameramlkit.bridge.swift + + /** + * Create a new instance of `TextSymbol`. + */ + init(bounds: BoundingBox, corners: [Corner], confidence: Double, angle: Double, languages: [String], text: String) { + self.init(bounds, { () -> bridge.std__vector_Corner_ in + var __vector = bridge.create_std__vector_Corner_(corners.count) + for __item in corners { + __vector.push_back(__item) + } + return __vector + }(), confidence, angle, { () -> bridge.std__vector_std__string_ in + var __vector = bridge.create_std__vector_std__string_(languages.count) + for __item in languages { + __vector.push_back(std.string(__item)) + } + return __vector + }(), std.string(text)) + } + + @inline(__always) + var bounds: BoundingBox { + return self.__bounds + } + + @inline(__always) + var corners: [Corner] { + return self.__corners.map({ __item in __item }) + } + + @inline(__always) + var confidence: Double { + return self.__confidence + } + + @inline(__always) + var angle: Double { + return self.__angle + } + + @inline(__always) + var languages: [String] { + return self.__languages.map({ __item in String(__item) }) + } + + @inline(__always) + var text: String { + return String(self.__text) + } +} diff --git a/nitrogen/generated/ios/swift/Variant_NullType_Double.swift b/nitrogen/generated/ios/swift/Variant_NullType_Double.swift new file mode 100644 index 0000000..8918a71 --- /dev/null +++ b/nitrogen/generated/ios/swift/Variant_NullType_Double.swift @@ -0,0 +1,30 @@ +/// +/// Variant_NullType_Double.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +import NitroModules + +/** + * An Swift enum with associated values representing a Variant/Union type. + * JS type: `null | number` + */ +@frozen +public enum Variant_NullType_Double { + case first(NullType) + case second(Double) +} + +public extension Variant_NullType_Double { + func asType(_ type: T.Type = T.self) -> T? { + switch self { + case .first(let value): return value as? T + case .second(let value): return value as? T + } + } + func isType(_ type: T.Type = T.self) -> Bool { + return self.asType(type) != nil + } +} diff --git a/nitrogen/generated/shared/c++/BarcodeFormat.hpp b/nitrogen/generated/shared/c++/BarcodeFormat.hpp new file mode 100644 index 0000000..8b621db --- /dev/null +++ b/nitrogen/generated/shared/c++/BarcodeFormat.hpp @@ -0,0 +1,128 @@ +/// +/// BarcodeFormat.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (BarcodeFormat). + */ + enum class BarcodeFormat { + UNKNOWN SWIFT_NAME(unknown) = 0, + ALL_FORMATS SWIFT_NAME(allFormats) = 1, + CODE_128 SWIFT_NAME(code128) = 2, + CODE_39 SWIFT_NAME(code39) = 3, + CODE_93 SWIFT_NAME(code93) = 4, + CODABAR SWIFT_NAME(codabar) = 5, + DATA_MATRIX SWIFT_NAME(dataMatrix) = 6, + EAN_13 SWIFT_NAME(ean13) = 7, + EAN_8 SWIFT_NAME(ean8) = 8, + ITF SWIFT_NAME(itf) = 9, + QR_CODE SWIFT_NAME(qrCode) = 10, + UPC_A SWIFT_NAME(upcA) = 11, + UPC_E SWIFT_NAME(upcE) = 12, + PDF417 SWIFT_NAME(pdf417) = 13, + AZTEC SWIFT_NAME(aztec) = 14, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BarcodeFormat <> JS BarcodeFormat (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BarcodeFormat fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("UNKNOWN"): return margelo::nitro::visioncameramlkit::BarcodeFormat::UNKNOWN; + case hashString("ALL_FORMATS"): return margelo::nitro::visioncameramlkit::BarcodeFormat::ALL_FORMATS; + case hashString("CODE_128"): return margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_128; + case hashString("CODE_39"): return margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_39; + case hashString("CODE_93"): return margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_93; + case hashString("CODABAR"): return margelo::nitro::visioncameramlkit::BarcodeFormat::CODABAR; + case hashString("DATA_MATRIX"): return margelo::nitro::visioncameramlkit::BarcodeFormat::DATA_MATRIX; + case hashString("EAN_13"): return margelo::nitro::visioncameramlkit::BarcodeFormat::EAN_13; + case hashString("EAN_8"): return margelo::nitro::visioncameramlkit::BarcodeFormat::EAN_8; + case hashString("ITF"): return margelo::nitro::visioncameramlkit::BarcodeFormat::ITF; + case hashString("QR_CODE"): return margelo::nitro::visioncameramlkit::BarcodeFormat::QR_CODE; + case hashString("UPC_A"): return margelo::nitro::visioncameramlkit::BarcodeFormat::UPC_A; + case hashString("UPC_E"): return margelo::nitro::visioncameramlkit::BarcodeFormat::UPC_E; + case hashString("PDF417"): return margelo::nitro::visioncameramlkit::BarcodeFormat::PDF417; + case hashString("AZTEC"): return margelo::nitro::visioncameramlkit::BarcodeFormat::AZTEC; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum BarcodeFormat - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::BarcodeFormat arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::BarcodeFormat::UNKNOWN: return JSIConverter::toJSI(runtime, "UNKNOWN"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::ALL_FORMATS: return JSIConverter::toJSI(runtime, "ALL_FORMATS"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_128: return JSIConverter::toJSI(runtime, "CODE_128"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_39: return JSIConverter::toJSI(runtime, "CODE_39"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::CODE_93: return JSIConverter::toJSI(runtime, "CODE_93"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::CODABAR: return JSIConverter::toJSI(runtime, "CODABAR"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::DATA_MATRIX: return JSIConverter::toJSI(runtime, "DATA_MATRIX"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::EAN_13: return JSIConverter::toJSI(runtime, "EAN_13"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::EAN_8: return JSIConverter::toJSI(runtime, "EAN_8"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::ITF: return JSIConverter::toJSI(runtime, "ITF"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::QR_CODE: return JSIConverter::toJSI(runtime, "QR_CODE"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::UPC_A: return JSIConverter::toJSI(runtime, "UPC_A"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::UPC_E: return JSIConverter::toJSI(runtime, "UPC_E"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::PDF417: return JSIConverter::toJSI(runtime, "PDF417"); + case margelo::nitro::visioncameramlkit::BarcodeFormat::AZTEC: return JSIConverter::toJSI(runtime, "AZTEC"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert BarcodeFormat to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("UNKNOWN"): + case hashString("ALL_FORMATS"): + case hashString("CODE_128"): + case hashString("CODE_39"): + case hashString("CODE_93"): + case hashString("CODABAR"): + case hashString("DATA_MATRIX"): + case hashString("EAN_13"): + case hashString("EAN_8"): + case hashString("ITF"): + case hashString("QR_CODE"): + case hashString("UPC_A"): + case hashString("UPC_E"): + case hashString("PDF417"): + case hashString("AZTEC"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/BarcodeScannerBarcode.hpp b/nitrogen/generated/shared/c++/BarcodeScannerBarcode.hpp new file mode 100644 index 0000000..75e2d10 --- /dev/null +++ b/nitrogen/generated/shared/c++/BarcodeScannerBarcode.hpp @@ -0,0 +1,137 @@ +/// +/// BarcodeScannerBarcode.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `BarcodeValueTypeName` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeValueTypeName; } + +#include "BoundingBox.hpp" +#include +#include "Corner.hpp" +#include +#include "BarcodeFormat.hpp" +#include "BarcodeValueTypeName.hpp" +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (BarcodeScannerBarcode). + */ + struct BarcodeScannerBarcode final { + public: + std::optional bounds SWIFT_PRIVATE; + std::optional> corners SWIFT_PRIVATE; + double format SWIFT_PRIVATE; + BarcodeFormat formatName SWIFT_PRIVATE; + double valueType SWIFT_PRIVATE; + BarcodeValueTypeName valueTypeName SWIFT_PRIVATE; + std::optional rawValue SWIFT_PRIVATE; + std::optional displayValue SWIFT_PRIVATE; + std::optional> rawBytes SWIFT_PRIVATE; + std::optional> value SWIFT_PRIVATE; + bool isPotential SWIFT_PRIVATE; + + public: + BarcodeScannerBarcode() = default; + explicit BarcodeScannerBarcode(std::optional bounds, std::optional> corners, double format, BarcodeFormat formatName, double valueType, BarcodeValueTypeName valueTypeName, std::optional rawValue, std::optional displayValue, std::optional> rawBytes, std::optional> value, bool isPotential): bounds(bounds), corners(corners), format(format), formatName(formatName), valueType(valueType), valueTypeName(valueTypeName), rawValue(rawValue), displayValue(displayValue), rawBytes(rawBytes), value(value), isPotential(isPotential) {} + + public: + friend bool operator==(const BarcodeScannerBarcode& lhs, const BarcodeScannerBarcode& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BarcodeScannerBarcode <> JS BarcodeScannerBarcode (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BarcodeScannerBarcode fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::BarcodeScannerBarcode( + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "format"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "formatName"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "valueType"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "valueTypeName"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "rawValue"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "displayValue"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "rawBytes"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isPotential"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::BarcodeScannerBarcode& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bounds"), JSIConverter>::toJSI(runtime, arg.bounds)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "corners"), JSIConverter>>::toJSI(runtime, arg.corners)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "format"), JSIConverter::toJSI(runtime, arg.format)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "formatName"), JSIConverter::toJSI(runtime, arg.formatName)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "valueType"), JSIConverter::toJSI(runtime, arg.valueType)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "valueTypeName"), JSIConverter::toJSI(runtime, arg.valueTypeName)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "rawValue"), JSIConverter>::toJSI(runtime, arg.rawValue)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "displayValue"), JSIConverter>::toJSI(runtime, arg.displayValue)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "rawBytes"), JSIConverter>>::toJSI(runtime, arg.rawBytes)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "value"), JSIConverter>>::toJSI(runtime, arg.value)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "isPotential"), JSIConverter::toJSI(runtime, arg.isPotential)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "format")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "formatName")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "valueType")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "valueTypeName")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "rawValue")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "displayValue")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "rawBytes")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "value")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "isPotential")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp b/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp new file mode 100644 index 0000000..edec6fd --- /dev/null +++ b/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp @@ -0,0 +1,116 @@ +/// +/// BarcodeScannerOptions.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BarcodeFormat` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class BarcodeFormat; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "BarcodeFormat.hpp" +#include +#include +#include "RegionOfInterest.hpp" +#include "Orientation.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (BarcodeScannerOptions). + */ + struct BarcodeScannerOptions final { + public: + std::optional> formats SWIFT_PRIVATE; + std::optional enableAllPotentialBarcodes SWIFT_PRIVATE; + std::optional scaleFactor SWIFT_PRIVATE; + std::optional invertColors SWIFT_PRIVATE; + std::optional frameProcessInterval SWIFT_PRIVATE; + std::optional roi SWIFT_PRIVATE; + std::optional orientation SWIFT_PRIVATE; + + public: + BarcodeScannerOptions() = default; + explicit BarcodeScannerOptions(std::optional> formats, std::optional enableAllPotentialBarcodes, std::optional scaleFactor, std::optional invertColors, std::optional frameProcessInterval, std::optional roi, std::optional orientation): formats(formats), enableAllPotentialBarcodes(enableAllPotentialBarcodes), scaleFactor(scaleFactor), invertColors(invertColors), frameProcessInterval(frameProcessInterval), roi(roi), orientation(orientation) {} + + public: + friend bool operator==(const BarcodeScannerOptions& lhs, const BarcodeScannerOptions& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BarcodeScannerOptions <> JS BarcodeScannerOptions (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BarcodeScannerOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::BarcodeScannerOptions( + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "formats"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "invertColors"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "roi"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "orientation"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::BarcodeScannerOptions& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "formats"), JSIConverter>>::toJSI(runtime, arg.formats)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes"), JSIConverter>::toJSI(runtime, arg.enableAllPotentialBarcodes)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor"), JSIConverter>::toJSI(runtime, arg.scaleFactor)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "invertColors"), JSIConverter>::toJSI(runtime, arg.invertColors)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval"), JSIConverter>::toJSI(runtime, arg.frameProcessInterval)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "roi"), JSIConverter>::toJSI(runtime, arg.roi)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "orientation"), JSIConverter>::toJSI(runtime, arg.orientation)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "formats")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "enableAllPotentialBarcodes")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "invertColors")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "roi")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "orientation")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/BarcodeScannerResult.hpp b/nitrogen/generated/shared/c++/BarcodeScannerResult.hpp new file mode 100644 index 0000000..42d50df --- /dev/null +++ b/nitrogen/generated/shared/c++/BarcodeScannerResult.hpp @@ -0,0 +1,85 @@ +/// +/// BarcodeScannerResult.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BarcodeScannerBarcode` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerBarcode; } + +#include "BarcodeScannerBarcode.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (BarcodeScannerResult). + */ + struct BarcodeScannerResult final { + public: + std::vector barcodes SWIFT_PRIVATE; + + public: + BarcodeScannerResult() = default; + explicit BarcodeScannerResult(std::vector barcodes): barcodes(barcodes) {} + + public: + friend bool operator==(const BarcodeScannerResult& lhs, const BarcodeScannerResult& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BarcodeScannerResult <> JS BarcodeScannerResult (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BarcodeScannerResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::BarcodeScannerResult( + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodes"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::BarcodeScannerResult& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "barcodes"), JSIConverter>::toJSI(runtime, arg.barcodes)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "barcodes")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/BarcodeValueTypeName.hpp b/nitrogen/generated/shared/c++/BarcodeValueTypeName.hpp new file mode 100644 index 0000000..ba08c0d --- /dev/null +++ b/nitrogen/generated/shared/c++/BarcodeValueTypeName.hpp @@ -0,0 +1,120 @@ +/// +/// BarcodeValueTypeName.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (BarcodeValueTypeName). + */ + enum class BarcodeValueTypeName { + TYPE_UNKNOWN SWIFT_NAME(typeUnknown) = 0, + TYPE_CONTACT_INFO SWIFT_NAME(typeContactInfo) = 1, + TYPE_EMAIL SWIFT_NAME(typeEmail) = 2, + TYPE_ISBN SWIFT_NAME(typeIsbn) = 3, + TYPE_PHONE SWIFT_NAME(typePhone) = 4, + TYPE_PRODUCT SWIFT_NAME(typeProduct) = 5, + TYPE_SMS SWIFT_NAME(typeSms) = 6, + TYPE_TEXT SWIFT_NAME(typeText) = 7, + TYPE_URL SWIFT_NAME(typeUrl) = 8, + TYPE_WIFI SWIFT_NAME(typeWifi) = 9, + TYPE_GEO SWIFT_NAME(typeGeo) = 10, + TYPE_CALENDAR_EVENT SWIFT_NAME(typeCalendarEvent) = 11, + TYPE_DRIVER_LICENSE SWIFT_NAME(typeDriverLicense) = 12, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BarcodeValueTypeName <> JS BarcodeValueTypeName (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BarcodeValueTypeName fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("TYPE_UNKNOWN"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_UNKNOWN; + case hashString("TYPE_CONTACT_INFO"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_CONTACT_INFO; + case hashString("TYPE_EMAIL"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_EMAIL; + case hashString("TYPE_ISBN"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_ISBN; + case hashString("TYPE_PHONE"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_PHONE; + case hashString("TYPE_PRODUCT"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_PRODUCT; + case hashString("TYPE_SMS"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_SMS; + case hashString("TYPE_TEXT"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_TEXT; + case hashString("TYPE_URL"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_URL; + case hashString("TYPE_WIFI"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_WIFI; + case hashString("TYPE_GEO"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_GEO; + case hashString("TYPE_CALENDAR_EVENT"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_CALENDAR_EVENT; + case hashString("TYPE_DRIVER_LICENSE"): return margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_DRIVER_LICENSE; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum BarcodeValueTypeName - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::BarcodeValueTypeName arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_UNKNOWN: return JSIConverter::toJSI(runtime, "TYPE_UNKNOWN"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_CONTACT_INFO: return JSIConverter::toJSI(runtime, "TYPE_CONTACT_INFO"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_EMAIL: return JSIConverter::toJSI(runtime, "TYPE_EMAIL"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_ISBN: return JSIConverter::toJSI(runtime, "TYPE_ISBN"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_PHONE: return JSIConverter::toJSI(runtime, "TYPE_PHONE"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_PRODUCT: return JSIConverter::toJSI(runtime, "TYPE_PRODUCT"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_SMS: return JSIConverter::toJSI(runtime, "TYPE_SMS"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_TEXT: return JSIConverter::toJSI(runtime, "TYPE_TEXT"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_URL: return JSIConverter::toJSI(runtime, "TYPE_URL"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_WIFI: return JSIConverter::toJSI(runtime, "TYPE_WIFI"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_GEO: return JSIConverter::toJSI(runtime, "TYPE_GEO"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_CALENDAR_EVENT: return JSIConverter::toJSI(runtime, "TYPE_CALENDAR_EVENT"); + case margelo::nitro::visioncameramlkit::BarcodeValueTypeName::TYPE_DRIVER_LICENSE: return JSIConverter::toJSI(runtime, "TYPE_DRIVER_LICENSE"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert BarcodeValueTypeName to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("TYPE_UNKNOWN"): + case hashString("TYPE_CONTACT_INFO"): + case hashString("TYPE_EMAIL"): + case hashString("TYPE_ISBN"): + case hashString("TYPE_PHONE"): + case hashString("TYPE_PRODUCT"): + case hashString("TYPE_SMS"): + case hashString("TYPE_TEXT"): + case hashString("TYPE_URL"): + case hashString("TYPE_WIFI"): + case hashString("TYPE_GEO"): + case hashString("TYPE_CALENDAR_EVENT"): + case hashString("TYPE_DRIVER_LICENSE"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/BoundingBox.hpp b/nitrogen/generated/shared/c++/BoundingBox.hpp new file mode 100644 index 0000000..c614613 --- /dev/null +++ b/nitrogen/generated/shared/c++/BoundingBox.hpp @@ -0,0 +1,119 @@ +/// +/// BoundingBox.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + + + + + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (BoundingBox). + */ + struct BoundingBox final { + public: + double x SWIFT_PRIVATE; + double y SWIFT_PRIVATE; + double centerX SWIFT_PRIVATE; + double centerY SWIFT_PRIVATE; + double width SWIFT_PRIVATE; + double height SWIFT_PRIVATE; + double top SWIFT_PRIVATE; + double left SWIFT_PRIVATE; + double bottom SWIFT_PRIVATE; + double right SWIFT_PRIVATE; + + public: + BoundingBox() = default; + explicit BoundingBox(double x, double y, double centerX, double centerY, double width, double height, double top, double left, double bottom, double right): x(x), y(y), centerX(centerX), centerY(centerY), width(width), height(height), top(top), left(left), bottom(bottom), right(right) {} + + public: + friend bool operator==(const BoundingBox& lhs, const BoundingBox& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ BoundingBox <> JS BoundingBox (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::BoundingBox fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::BoundingBox( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "centerX"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "centerY"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "top"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "left"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottom"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "right"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::BoundingBox& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "x"), JSIConverter::toJSI(runtime, arg.x)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "y"), JSIConverter::toJSI(runtime, arg.y)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "centerX"), JSIConverter::toJSI(runtime, arg.centerX)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "centerY"), JSIConverter::toJSI(runtime, arg.centerY)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter::toJSI(runtime, arg.width)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter::toJSI(runtime, arg.height)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "top"), JSIConverter::toJSI(runtime, arg.top)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "left"), JSIConverter::toJSI(runtime, arg.left)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bottom"), JSIConverter::toJSI(runtime, arg.bottom)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "right"), JSIConverter::toJSI(runtime, arg.right)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "centerX")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "centerY")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "top")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "left")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottom")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "right")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/Corner.hpp b/nitrogen/generated/shared/c++/Corner.hpp new file mode 100644 index 0000000..3665d97 --- /dev/null +++ b/nitrogen/generated/shared/c++/Corner.hpp @@ -0,0 +1,87 @@ +/// +/// Corner.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + + + + + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (Corner). + */ + struct Corner final { + public: + double x SWIFT_PRIVATE; + double y SWIFT_PRIVATE; + + public: + Corner() = default; + explicit Corner(double x, double y): x(x), y(y) {} + + public: + friend bool operator==(const Corner& lhs, const Corner& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ Corner <> JS Corner (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::Corner fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::Corner( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::Corner& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "x"), JSIConverter::toJSI(runtime, arg.x)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "y"), JSIConverter::toJSI(runtime, arg.y)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp b/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp new file mode 100644 index 0000000..da0f630 --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp @@ -0,0 +1,22 @@ +/// +/// HybridBarcodeScannerSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridBarcodeScannerSpec.hpp" + +namespace margelo::nitro::visioncameramlkit { + + void HybridBarcodeScannerSpec::loadHybridMethods() { + // load base methods/properties + HybridObject::loadHybridMethods(); + // load custom methods/properties + registerHybrids(this, [](Prototype& prototype) { + prototype.registerHybridMethod("recognize", &HybridBarcodeScannerSpec::recognize); + prototype.registerHybridMethod("recognizeImage", &HybridBarcodeScannerSpec::recognizeImage); + }); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.hpp b/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.hpp new file mode 100644 index 0000000..be81b72 --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.hpp @@ -0,0 +1,74 @@ +/// +/// HybridBarcodeScannerSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BarcodeScannerResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerResult; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } + +#include "BarcodeScannerResult.hpp" +#include +#include +#include "MLKitBaseArguments.hpp" +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace margelo::nitro; + + /** + * An abstract base class for `BarcodeScanner` + * Inherit this class to create instances of `HybridBarcodeScannerSpec` in C++. + * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual. + * @example + * ```cpp + * class HybridBarcodeScanner: public HybridBarcodeScannerSpec { + * public: + * HybridBarcodeScanner(...): HybridObject(TAG) { ... } + * // ... + * }; + * ``` + */ + class HybridBarcodeScannerSpec: public virtual HybridObject { + public: + // Constructor + explicit HybridBarcodeScannerSpec(): HybridObject(TAG) { } + + // Destructor + ~HybridBarcodeScannerSpec() override = default; + + public: + // Properties + + + public: + // Methods + virtual BarcodeScannerResult recognize(const std::shared_ptr& frame, const std::optional& args) = 0; + virtual std::shared_ptr> recognizeImage(const std::string& uri) = 0; + + protected: + // Hybrid Setup + void loadHybridMethods() override; + + protected: + // Tag for logging + static constexpr auto TAG = "BarcodeScanner"; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.cpp b/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.cpp new file mode 100644 index 0000000..cabcd68 --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.cpp @@ -0,0 +1,22 @@ +/// +/// HybridTextRecognizerSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridTextRecognizerSpec.hpp" + +namespace margelo::nitro::visioncameramlkit { + + void HybridTextRecognizerSpec::loadHybridMethods() { + // load base methods/properties + HybridObject::loadHybridMethods(); + // load custom methods/properties + registerHybrids(this, [](Prototype& prototype) { + prototype.registerHybridMethod("recognize", &HybridTextRecognizerSpec::recognize); + prototype.registerHybridMethod("recognizeImage", &HybridTextRecognizerSpec::recognizeImage); + }); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.hpp b/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.hpp new file mode 100644 index 0000000..9e09106 --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridTextRecognizerSpec.hpp @@ -0,0 +1,74 @@ +/// +/// HybridTextRecognizerSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `TextRecognitionResult` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognitionResult; } +// Forward declaration of `HybridFrameSpec` to properly resolve imports. +namespace margelo::nitro::camera { class HybridFrameSpec; } +// Forward declaration of `MLKitBaseArguments` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct MLKitBaseArguments; } + +#include "TextRecognitionResult.hpp" +#include +#include +#include "MLKitBaseArguments.hpp" +#include +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + using namespace margelo::nitro; + + /** + * An abstract base class for `TextRecognizer` + * Inherit this class to create instances of `HybridTextRecognizerSpec` in C++. + * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual. + * @example + * ```cpp + * class HybridTextRecognizer: public HybridTextRecognizerSpec { + * public: + * HybridTextRecognizer(...): HybridObject(TAG) { ... } + * // ... + * }; + * ``` + */ + class HybridTextRecognizerSpec: public virtual HybridObject { + public: + // Constructor + explicit HybridTextRecognizerSpec(): HybridObject(TAG) { } + + // Destructor + ~HybridTextRecognizerSpec() override = default; + + public: + // Properties + + + public: + // Methods + virtual TextRecognitionResult recognize(const std::shared_ptr& frame, const std::optional& args) = 0; + virtual std::shared_ptr> recognizeImage(const std::string& uri) = 0; + + protected: + // Hybrid Setup + void loadHybridMethods() override; + + protected: + // Tag for logging + static constexpr auto TAG = "TextRecognizer"; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.cpp b/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.cpp new file mode 100644 index 0000000..f28b2bd --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.cpp @@ -0,0 +1,23 @@ +/// +/// HybridVisionCameraMLKitSpec.cpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#include "HybridVisionCameraMLKitSpec.hpp" + +namespace margelo::nitro::visioncameramlkit { + + void HybridVisionCameraMLKitSpec::loadHybridMethods() { + // load base methods/properties + HybridObject::loadHybridMethods(); + // load custom methods/properties + registerHybrids(this, [](Prototype& prototype) { + prototype.registerHybridMethod("isFeatureAvailable", &HybridVisionCameraMLKitSpec::isFeatureAvailable); + prototype.registerHybridMethod("createTextRecognizer", &HybridVisionCameraMLKitSpec::createTextRecognizer); + prototype.registerHybridMethod("createBarcodeScanner", &HybridVisionCameraMLKitSpec::createBarcodeScanner); + }); + } + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.hpp b/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.hpp new file mode 100644 index 0000000..dded17f --- /dev/null +++ b/nitrogen/generated/shared/c++/HybridVisionCameraMLKitSpec.hpp @@ -0,0 +1,78 @@ +/// +/// HybridVisionCameraMLKitSpec.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `MLKitFeature` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class MLKitFeature; } +// Forward declaration of `HybridTextRecognizerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridTextRecognizerSpec; } +// Forward declaration of `TextRecognizerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextRecognizerOptions; } +// Forward declaration of `HybridBarcodeScannerSpec` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { class HybridBarcodeScannerSpec; } +// Forward declaration of `BarcodeScannerOptions` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BarcodeScannerOptions; } + +#include "MLKitFeature.hpp" +#include +#include "HybridTextRecognizerSpec.hpp" +#include "TextRecognizerOptions.hpp" +#include "HybridBarcodeScannerSpec.hpp" +#include "BarcodeScannerOptions.hpp" + +namespace margelo::nitro::visioncameramlkit { + + using namespace margelo::nitro; + + /** + * An abstract base class for `VisionCameraMLKit` + * Inherit this class to create instances of `HybridVisionCameraMLKitSpec` in C++. + * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual. + * @example + * ```cpp + * class HybridVisionCameraMLKit: public HybridVisionCameraMLKitSpec { + * public: + * HybridVisionCameraMLKit(...): HybridObject(TAG) { ... } + * // ... + * }; + * ``` + */ + class HybridVisionCameraMLKitSpec: public virtual HybridObject { + public: + // Constructor + explicit HybridVisionCameraMLKitSpec(): HybridObject(TAG) { } + + // Destructor + ~HybridVisionCameraMLKitSpec() override = default; + + public: + // Properties + + + public: + // Methods + virtual bool isFeatureAvailable(MLKitFeature feature) = 0; + virtual std::shared_ptr createTextRecognizer(const TextRecognizerOptions& options) = 0; + virtual std::shared_ptr createBarcodeScanner(const BarcodeScannerOptions& options) = 0; + + protected: + // Hybrid Setup + void loadHybridMethods() override; + + protected: + // Tag for logging + static constexpr auto TAG = "VisionCameraMLKit"; + }; + +} // namespace margelo::nitro::visioncameramlkit diff --git a/nitrogen/generated/shared/c++/MLKitBaseArguments.hpp b/nitrogen/generated/shared/c++/MLKitBaseArguments.hpp new file mode 100644 index 0000000..b225cd4 --- /dev/null +++ b/nitrogen/generated/shared/c++/MLKitBaseArguments.hpp @@ -0,0 +1,85 @@ +/// +/// MLKitBaseArguments.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "Orientation.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (MLKitBaseArguments). + */ + struct MLKitBaseArguments final { + public: + std::optional outputOrientation SWIFT_PRIVATE; + + public: + MLKitBaseArguments() = default; + explicit MLKitBaseArguments(std::optional outputOrientation): outputOrientation(outputOrientation) {} + + public: + friend bool operator==(const MLKitBaseArguments& lhs, const MLKitBaseArguments& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ MLKitBaseArguments <> JS MLKitBaseArguments (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::MLKitBaseArguments fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::MLKitBaseArguments( + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "outputOrientation"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::MLKitBaseArguments& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "outputOrientation"), JSIConverter>::toJSI(runtime, arg.outputOrientation)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "outputOrientation")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/MLKitFeature.hpp b/nitrogen/generated/shared/c++/MLKitFeature.hpp new file mode 100644 index 0000000..3ed1d2c --- /dev/null +++ b/nitrogen/generated/shared/c++/MLKitFeature.hpp @@ -0,0 +1,112 @@ +/// +/// MLKitFeature.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (MLKitFeature). + */ + enum class MLKitFeature { + TEXTRECOGNITION SWIFT_NAME(textrecognition) = 0, + FACEDETECTION SWIFT_NAME(facedetection) = 1, + FACEMESHDETECTION SWIFT_NAME(facemeshdetection) = 2, + POSEDETECTION SWIFT_NAME(posedetection) = 3, + SELFIESEGMENTATION SWIFT_NAME(selfiesegmentation) = 4, + SUBJECTSEGMENTATION SWIFT_NAME(subjectsegmentation) = 5, + DOCUMENTSCANNER SWIFT_NAME(documentscanner) = 6, + BARCODESCANNING SWIFT_NAME(barcodescanning) = 7, + IMAGELABELING SWIFT_NAME(imagelabeling) = 8, + OBJECTDETECTION SWIFT_NAME(objectdetection) = 9, + DIGITALINKRECOGNITION SWIFT_NAME(digitalinkrecognition) = 10, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ MLKitFeature <> JS MLKitFeature (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::MLKitFeature fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("TextRecognition"): return margelo::nitro::visioncameramlkit::MLKitFeature::TEXTRECOGNITION; + case hashString("FaceDetection"): return margelo::nitro::visioncameramlkit::MLKitFeature::FACEDETECTION; + case hashString("FaceMeshDetection"): return margelo::nitro::visioncameramlkit::MLKitFeature::FACEMESHDETECTION; + case hashString("PoseDetection"): return margelo::nitro::visioncameramlkit::MLKitFeature::POSEDETECTION; + case hashString("SelfieSegmentation"): return margelo::nitro::visioncameramlkit::MLKitFeature::SELFIESEGMENTATION; + case hashString("SubjectSegmentation"): return margelo::nitro::visioncameramlkit::MLKitFeature::SUBJECTSEGMENTATION; + case hashString("DocumentScanner"): return margelo::nitro::visioncameramlkit::MLKitFeature::DOCUMENTSCANNER; + case hashString("BarcodeScanning"): return margelo::nitro::visioncameramlkit::MLKitFeature::BARCODESCANNING; + case hashString("ImageLabeling"): return margelo::nitro::visioncameramlkit::MLKitFeature::IMAGELABELING; + case hashString("ObjectDetection"): return margelo::nitro::visioncameramlkit::MLKitFeature::OBJECTDETECTION; + case hashString("DigitalInkRecognition"): return margelo::nitro::visioncameramlkit::MLKitFeature::DIGITALINKRECOGNITION; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum MLKitFeature - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::MLKitFeature arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::MLKitFeature::TEXTRECOGNITION: return JSIConverter::toJSI(runtime, "TextRecognition"); + case margelo::nitro::visioncameramlkit::MLKitFeature::FACEDETECTION: return JSIConverter::toJSI(runtime, "FaceDetection"); + case margelo::nitro::visioncameramlkit::MLKitFeature::FACEMESHDETECTION: return JSIConverter::toJSI(runtime, "FaceMeshDetection"); + case margelo::nitro::visioncameramlkit::MLKitFeature::POSEDETECTION: return JSIConverter::toJSI(runtime, "PoseDetection"); + case margelo::nitro::visioncameramlkit::MLKitFeature::SELFIESEGMENTATION: return JSIConverter::toJSI(runtime, "SelfieSegmentation"); + case margelo::nitro::visioncameramlkit::MLKitFeature::SUBJECTSEGMENTATION: return JSIConverter::toJSI(runtime, "SubjectSegmentation"); + case margelo::nitro::visioncameramlkit::MLKitFeature::DOCUMENTSCANNER: return JSIConverter::toJSI(runtime, "DocumentScanner"); + case margelo::nitro::visioncameramlkit::MLKitFeature::BARCODESCANNING: return JSIConverter::toJSI(runtime, "BarcodeScanning"); + case margelo::nitro::visioncameramlkit::MLKitFeature::IMAGELABELING: return JSIConverter::toJSI(runtime, "ImageLabeling"); + case margelo::nitro::visioncameramlkit::MLKitFeature::OBJECTDETECTION: return JSIConverter::toJSI(runtime, "ObjectDetection"); + case margelo::nitro::visioncameramlkit::MLKitFeature::DIGITALINKRECOGNITION: return JSIConverter::toJSI(runtime, "DigitalInkRecognition"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert MLKitFeature to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("TextRecognition"): + case hashString("FaceDetection"): + case hashString("FaceMeshDetection"): + case hashString("PoseDetection"): + case hashString("SelfieSegmentation"): + case hashString("SubjectSegmentation"): + case hashString("DocumentScanner"): + case hashString("BarcodeScanning"): + case hashString("ImageLabeling"): + case hashString("ObjectDetection"): + case hashString("DigitalInkRecognition"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/Orientation.hpp b/nitrogen/generated/shared/c++/Orientation.hpp new file mode 100644 index 0000000..b0fb591 --- /dev/null +++ b/nitrogen/generated/shared/c++/Orientation.hpp @@ -0,0 +1,84 @@ +/// +/// Orientation.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (Orientation). + */ + enum class Orientation { + PORTRAIT SWIFT_NAME(portrait) = 0, + PORTRAIT_UPSIDE_DOWN SWIFT_NAME(portraitUpsideDown) = 1, + LANDSCAPE_LEFT SWIFT_NAME(landscapeLeft) = 2, + LANDSCAPE_RIGHT SWIFT_NAME(landscapeRight) = 3, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ Orientation <> JS Orientation (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::Orientation fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("portrait"): return margelo::nitro::visioncameramlkit::Orientation::PORTRAIT; + case hashString("portrait-upside-down"): return margelo::nitro::visioncameramlkit::Orientation::PORTRAIT_UPSIDE_DOWN; + case hashString("landscape-left"): return margelo::nitro::visioncameramlkit::Orientation::LANDSCAPE_LEFT; + case hashString("landscape-right"): return margelo::nitro::visioncameramlkit::Orientation::LANDSCAPE_RIGHT; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum Orientation - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::Orientation arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::Orientation::PORTRAIT: return JSIConverter::toJSI(runtime, "portrait"); + case margelo::nitro::visioncameramlkit::Orientation::PORTRAIT_UPSIDE_DOWN: return JSIConverter::toJSI(runtime, "portrait-upside-down"); + case margelo::nitro::visioncameramlkit::Orientation::LANDSCAPE_LEFT: return JSIConverter::toJSI(runtime, "landscape-left"); + case margelo::nitro::visioncameramlkit::Orientation::LANDSCAPE_RIGHT: return JSIConverter::toJSI(runtime, "landscape-right"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert Orientation to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("portrait"): + case hashString("portrait-upside-down"): + case hashString("landscape-left"): + case hashString("landscape-right"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/RegionOfInterest.hpp b/nitrogen/generated/shared/c++/RegionOfInterest.hpp new file mode 100644 index 0000000..d32427b --- /dev/null +++ b/nitrogen/generated/shared/c++/RegionOfInterest.hpp @@ -0,0 +1,101 @@ +/// +/// RegionOfInterest.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `RegionOfInterestUnit` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class RegionOfInterestUnit; } + +#include "RegionOfInterestUnit.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (RegionOfInterest). + */ + struct RegionOfInterest final { + public: + double x SWIFT_PRIVATE; + double y SWIFT_PRIVATE; + double width SWIFT_PRIVATE; + double height SWIFT_PRIVATE; + std::optional unit SWIFT_PRIVATE; + + public: + RegionOfInterest() = default; + explicit RegionOfInterest(double x, double y, double width, double height, std::optional unit): x(x), y(y), width(width), height(height), unit(unit) {} + + public: + friend bool operator==(const RegionOfInterest& lhs, const RegionOfInterest& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ RegionOfInterest <> JS RegionOfInterest (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::RegionOfInterest fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::RegionOfInterest( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "unit"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::RegionOfInterest& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "x"), JSIConverter::toJSI(runtime, arg.x)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "y"), JSIConverter::toJSI(runtime, arg.y)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter::toJSI(runtime, arg.width)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter::toJSI(runtime, arg.height)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "unit"), JSIConverter>::toJSI(runtime, arg.unit)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "unit")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/RegionOfInterestUnit.hpp b/nitrogen/generated/shared/c++/RegionOfInterestUnit.hpp new file mode 100644 index 0000000..01651f5 --- /dev/null +++ b/nitrogen/generated/shared/c++/RegionOfInterestUnit.hpp @@ -0,0 +1,76 @@ +/// +/// RegionOfInterestUnit.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (RegionOfInterestUnit). + */ + enum class RegionOfInterestUnit { + NORMALIZED SWIFT_NAME(normalized) = 0, + PIXEL SWIFT_NAME(pixel) = 1, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ RegionOfInterestUnit <> JS RegionOfInterestUnit (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::RegionOfInterestUnit fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("normalized"): return margelo::nitro::visioncameramlkit::RegionOfInterestUnit::NORMALIZED; + case hashString("pixel"): return margelo::nitro::visioncameramlkit::RegionOfInterestUnit::PIXEL; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum RegionOfInterestUnit - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::RegionOfInterestUnit arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::RegionOfInterestUnit::NORMALIZED: return JSIConverter::toJSI(runtime, "normalized"); + case margelo::nitro::visioncameramlkit::RegionOfInterestUnit::PIXEL: return JSIConverter::toJSI(runtime, "pixel"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert RegionOfInterestUnit to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("normalized"): + case hashString("pixel"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextBlock.hpp b/nitrogen/generated/shared/c++/TextBlock.hpp new file mode 100644 index 0000000..11b7ac5 --- /dev/null +++ b/nitrogen/generated/shared/c++/TextBlock.hpp @@ -0,0 +1,108 @@ +/// +/// TextBlock.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `TextLine` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextLine; } + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include +#include +#include "TextLine.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextBlock). + */ + struct TextBlock final { + public: + BoundingBox bounds SWIFT_PRIVATE; + std::vector corners SWIFT_PRIVATE; + std::vector languages SWIFT_PRIVATE; + std::string text SWIFT_PRIVATE; + std::vector lines SWIFT_PRIVATE; + + public: + TextBlock() = default; + explicit TextBlock(BoundingBox bounds, std::vector corners, std::vector languages, std::string text, std::vector lines): bounds(bounds), corners(corners), languages(languages), text(text), lines(lines) {} + + public: + friend bool operator==(const TextBlock& lhs, const TextBlock& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextBlock <> JS TextBlock (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextBlock fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextBlock( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "lines"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextBlock& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bounds"), JSIConverter::toJSI(runtime, arg.bounds)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "corners"), JSIConverter>::toJSI(runtime, arg.corners)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "languages"), JSIConverter>::toJSI(runtime, arg.languages)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "text"), JSIConverter::toJSI(runtime, arg.text)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "lines"), JSIConverter>::toJSI(runtime, arg.lines)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "lines")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextElement.hpp b/nitrogen/generated/shared/c++/TextElement.hpp new file mode 100644 index 0000000..50b7531 --- /dev/null +++ b/nitrogen/generated/shared/c++/TextElement.hpp @@ -0,0 +1,119 @@ +/// +/// TextElement.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `TextSymbol` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextSymbol; } + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include +#include +#include +#include +#include +#include "TextSymbol.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextElement). + */ + struct TextElement final { + public: + BoundingBox bounds SWIFT_PRIVATE; + std::vector corners SWIFT_PRIVATE; + std::optional> confidence SWIFT_PRIVATE; + std::optional> angle SWIFT_PRIVATE; + std::vector languages SWIFT_PRIVATE; + std::string text SWIFT_PRIVATE; + std::vector symbols SWIFT_PRIVATE; + + public: + TextElement() = default; + explicit TextElement(BoundingBox bounds, std::vector corners, std::optional> confidence, std::optional> angle, std::vector languages, std::string text, std::vector symbols): bounds(bounds), corners(corners), confidence(confidence), angle(angle), languages(languages), text(text), symbols(symbols) {} + + public: + friend bool operator==(const TextElement& lhs, const TextElement& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextElement <> JS TextElement (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextElement fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextElement( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "symbols"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextElement& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bounds"), JSIConverter::toJSI(runtime, arg.bounds)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "corners"), JSIConverter>::toJSI(runtime, arg.corners)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "confidence"), JSIConverter>>::toJSI(runtime, arg.confidence)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "angle"), JSIConverter>>::toJSI(runtime, arg.angle)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "languages"), JSIConverter>::toJSI(runtime, arg.languages)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "text"), JSIConverter::toJSI(runtime, arg.text)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "symbols"), JSIConverter>::toJSI(runtime, arg.symbols)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "symbols")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextLine.hpp b/nitrogen/generated/shared/c++/TextLine.hpp new file mode 100644 index 0000000..e559e5c --- /dev/null +++ b/nitrogen/generated/shared/c++/TextLine.hpp @@ -0,0 +1,119 @@ +/// +/// TextLine.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } +// Forward declaration of `TextElement` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextElement; } + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include +#include +#include +#include +#include +#include "TextElement.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextLine). + */ + struct TextLine final { + public: + BoundingBox bounds SWIFT_PRIVATE; + std::vector corners SWIFT_PRIVATE; + std::optional> confidence SWIFT_PRIVATE; + std::optional> angle SWIFT_PRIVATE; + std::vector languages SWIFT_PRIVATE; + std::string text SWIFT_PRIVATE; + std::vector elements SWIFT_PRIVATE; + + public: + TextLine() = default; + explicit TextLine(BoundingBox bounds, std::vector corners, std::optional> confidence, std::optional> angle, std::vector languages, std::string text, std::vector elements): bounds(bounds), corners(corners), confidence(confidence), angle(angle), languages(languages), text(text), elements(elements) {} + + public: + friend bool operator==(const TextLine& lhs, const TextLine& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextLine <> JS TextLine (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextLine fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextLine( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence"))), + JSIConverter>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "elements"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextLine& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bounds"), JSIConverter::toJSI(runtime, arg.bounds)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "corners"), JSIConverter>::toJSI(runtime, arg.corners)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "confidence"), JSIConverter>>::toJSI(runtime, arg.confidence)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "angle"), JSIConverter>>::toJSI(runtime, arg.angle)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "languages"), JSIConverter>::toJSI(runtime, arg.languages)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "text"), JSIConverter::toJSI(runtime, arg.text)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "elements"), JSIConverter>::toJSI(runtime, arg.elements)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence")))) return false; + if (!JSIConverter>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "elements")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextRecognitionLanguage.hpp b/nitrogen/generated/shared/c++/TextRecognitionLanguage.hpp new file mode 100644 index 0000000..8aa38de --- /dev/null +++ b/nitrogen/generated/shared/c++/TextRecognitionLanguage.hpp @@ -0,0 +1,88 @@ +/// +/// TextRecognitionLanguage.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::visioncameramlkit { + + /** + * An enum which can be represented as a JavaScript union (TextRecognitionLanguage). + */ + enum class TextRecognitionLanguage { + LATIN SWIFT_NAME(latin) = 0, + CHINESE SWIFT_NAME(chinese) = 1, + DEVANAGARI SWIFT_NAME(devanagari) = 2, + JAPANESE SWIFT_NAME(japanese) = 3, + KOREAN SWIFT_NAME(korean) = 4, + } CLOSED_ENUM; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextRecognitionLanguage <> JS TextRecognitionLanguage (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextRecognitionLanguage fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("LATIN"): return margelo::nitro::visioncameramlkit::TextRecognitionLanguage::LATIN; + case hashString("CHINESE"): return margelo::nitro::visioncameramlkit::TextRecognitionLanguage::CHINESE; + case hashString("DEVANAGARI"): return margelo::nitro::visioncameramlkit::TextRecognitionLanguage::DEVANAGARI; + case hashString("JAPANESE"): return margelo::nitro::visioncameramlkit::TextRecognitionLanguage::JAPANESE; + case hashString("KOREAN"): return margelo::nitro::visioncameramlkit::TextRecognitionLanguage::KOREAN; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum TextRecognitionLanguage - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::visioncameramlkit::TextRecognitionLanguage arg) { + switch (arg) { + case margelo::nitro::visioncameramlkit::TextRecognitionLanguage::LATIN: return JSIConverter::toJSI(runtime, "LATIN"); + case margelo::nitro::visioncameramlkit::TextRecognitionLanguage::CHINESE: return JSIConverter::toJSI(runtime, "CHINESE"); + case margelo::nitro::visioncameramlkit::TextRecognitionLanguage::DEVANAGARI: return JSIConverter::toJSI(runtime, "DEVANAGARI"); + case margelo::nitro::visioncameramlkit::TextRecognitionLanguage::JAPANESE: return JSIConverter::toJSI(runtime, "JAPANESE"); + case margelo::nitro::visioncameramlkit::TextRecognitionLanguage::KOREAN: return JSIConverter::toJSI(runtime, "KOREAN"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert TextRecognitionLanguage to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("LATIN"): + case hashString("CHINESE"): + case hashString("DEVANAGARI"): + case hashString("JAPANESE"): + case hashString("KOREAN"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextRecognitionResult.hpp b/nitrogen/generated/shared/c++/TextRecognitionResult.hpp new file mode 100644 index 0000000..45a5d9d --- /dev/null +++ b/nitrogen/generated/shared/c++/TextRecognitionResult.hpp @@ -0,0 +1,90 @@ +/// +/// TextRecognitionResult.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `TextBlock` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct TextBlock; } + +#include +#include "TextBlock.hpp" +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextRecognitionResult). + */ + struct TextRecognitionResult final { + public: + std::string text SWIFT_PRIVATE; + std::vector blocks SWIFT_PRIVATE; + + public: + TextRecognitionResult() = default; + explicit TextRecognitionResult(std::string text, std::vector blocks): text(text), blocks(blocks) {} + + public: + friend bool operator==(const TextRecognitionResult& lhs, const TextRecognitionResult& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextRecognitionResult <> JS TextRecognitionResult (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextRecognitionResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextRecognitionResult( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blocks"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextRecognitionResult& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "text"), JSIConverter::toJSI(runtime, arg.text)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "blocks"), JSIConverter>::toJSI(runtime, arg.blocks)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blocks")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextRecognizerOptions.hpp b/nitrogen/generated/shared/c++/TextRecognizerOptions.hpp new file mode 100644 index 0000000..ad501f2 --- /dev/null +++ b/nitrogen/generated/shared/c++/TextRecognizerOptions.hpp @@ -0,0 +1,111 @@ +/// +/// TextRecognizerOptions.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `TextRecognitionLanguage` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class TextRecognitionLanguage; } +// Forward declaration of `RegionOfInterest` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct RegionOfInterest; } +// Forward declaration of `Orientation` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { enum class Orientation; } + +#include "TextRecognitionLanguage.hpp" +#include +#include "RegionOfInterest.hpp" +#include "Orientation.hpp" + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextRecognizerOptions). + */ + struct TextRecognizerOptions final { + public: + std::optional language SWIFT_PRIVATE; + std::optional scaleFactor SWIFT_PRIVATE; + std::optional invertColors SWIFT_PRIVATE; + std::optional frameProcessInterval SWIFT_PRIVATE; + std::optional roi SWIFT_PRIVATE; + std::optional orientation SWIFT_PRIVATE; + + public: + TextRecognizerOptions() = default; + explicit TextRecognizerOptions(std::optional language, std::optional scaleFactor, std::optional invertColors, std::optional frameProcessInterval, std::optional roi, std::optional orientation): language(language), scaleFactor(scaleFactor), invertColors(invertColors), frameProcessInterval(frameProcessInterval), roi(roi), orientation(orientation) {} + + public: + friend bool operator==(const TextRecognizerOptions& lhs, const TextRecognizerOptions& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextRecognizerOptions <> JS TextRecognizerOptions (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextRecognizerOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextRecognizerOptions( + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "language"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "invertColors"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "roi"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "orientation"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextRecognizerOptions& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "language"), JSIConverter>::toJSI(runtime, arg.language)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor"), JSIConverter>::toJSI(runtime, arg.scaleFactor)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "invertColors"), JSIConverter>::toJSI(runtime, arg.invertColors)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval"), JSIConverter>::toJSI(runtime, arg.frameProcessInterval)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "roi"), JSIConverter>::toJSI(runtime, arg.roi)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "orientation"), JSIConverter>::toJSI(runtime, arg.orientation)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "language")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "scaleFactor")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "invertColors")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "frameProcessInterval")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "roi")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "orientation")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/TextSymbol.hpp b/nitrogen/generated/shared/c++/TextSymbol.hpp new file mode 100644 index 0000000..a5a8b15 --- /dev/null +++ b/nitrogen/generated/shared/c++/TextSymbol.hpp @@ -0,0 +1,109 @@ +/// +/// TextSymbol.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `BoundingBox` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct BoundingBox; } +// Forward declaration of `Corner` to properly resolve imports. +namespace margelo::nitro::visioncameramlkit { struct Corner; } + +#include "BoundingBox.hpp" +#include "Corner.hpp" +#include +#include + +namespace margelo::nitro::visioncameramlkit { + + /** + * A struct which can be represented as a JavaScript object (TextSymbol). + */ + struct TextSymbol final { + public: + BoundingBox bounds SWIFT_PRIVATE; + std::vector corners SWIFT_PRIVATE; + double confidence SWIFT_PRIVATE; + double angle SWIFT_PRIVATE; + std::vector languages SWIFT_PRIVATE; + std::string text SWIFT_PRIVATE; + + public: + TextSymbol() = default; + explicit TextSymbol(BoundingBox bounds, std::vector corners, double confidence, double angle, std::vector languages, std::string text): bounds(bounds), corners(corners), confidence(confidence), angle(angle), languages(languages), text(text) {} + + public: + friend bool operator==(const TextSymbol& lhs, const TextSymbol& rhs) = default; + }; + +} // namespace margelo::nitro::visioncameramlkit + +namespace margelo::nitro { + + // C++ TextSymbol <> JS TextSymbol (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::visioncameramlkit::TextSymbol fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::visioncameramlkit::TextSymbol( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle"))), + JSIConverter>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages"))), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text"))) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::visioncameramlkit::TextSymbol& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "bounds"), JSIConverter::toJSI(runtime, arg.bounds)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "corners"), JSIConverter>::toJSI(runtime, arg.corners)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "confidence"), JSIConverter::toJSI(runtime, arg.confidence)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "angle"), JSIConverter::toJSI(runtime, arg.angle)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "languages"), JSIConverter>::toJSI(runtime, arg.languages)); + obj.setProperty(runtime, PropNameIDCache::get(runtime, "text"), JSIConverter::toJSI(runtime, arg.text)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bounds")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "corners")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "confidence")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "angle")))) return false; + if (!JSIConverter>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "languages")))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "text")))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/package.json b/package.json index 356868e..9be7424 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-vision-camera-mlkit", - "version": "1.0.0", - "description": "A powerful React Native Vision Camera plugin delivering high-performance Google ML Kit frame processor features—including text recognition (OCR), face detection, barcode scanning, pose detection, and more. Seamlessly bridges native ML Kit capabilities for real-time, on-device computer vision in your React Native apps.", + "version": "2.0.0", + "description": "A React Native Vision Camera (v5, Nitro-based) plugin for Google ML Kit vision features. Ships text recognition (OCR) and barcode scanning today, each independently selectable to keep binary size down, for real-time frame processing and static images, with more ML Kit vision features (face detection, pose detection, and others) on the roadmap.", "main": "./lib/module/index.js", "types": "./lib/typescript/src/index.d.ts", "exports": { @@ -10,6 +10,7 @@ "types": "./lib/typescript/src/index.d.ts", "default": "./lib/module/index.js" }, + "./app.plugin.js": "./app.plugin.js", "./package.json": "./package.json" }, "files": [ @@ -18,14 +19,21 @@ "android", "ios", "cpp", + "nitrogen", + "nitro.json", "*.podspec", + "app.plugin.js", + "plugin", "react-native.config.js", "!ios/build", "!android/build", + "!android/app/build", "!android/gradle", "!android/gradlew", "!android/gradlew.bat", "!android/local.properties", + "!**/*.test.*", + "!**/*.spec.*", "!**/__tests__", "!**/__fixtures__", "!**/__mocks__", @@ -37,6 +45,7 @@ "prepare": "bob build", "typecheck": "tsc --noEmit", "lint": "eslint \"**/*.{js,ts,tsx}\"", + "specs": "nitrogen", "release": "release-it --only-version", "test": "jest" }, @@ -58,9 +67,12 @@ "image-processing", "camera", "text-detection", - "face-detection", + "text-recognition", "barcode-scanner", - "pose-detection" + "barcode-scanning", + "nitro", + "expo", + "config-plugin" ], "repository": { "type": "git", @@ -76,16 +88,19 @@ "registry": "https://registry.npmjs.org/" }, "devDependencies": { + "@babel/core": "^7.25.2", "@commitlint/config-conventional": "^19.8.1", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.35.0", - "@react-native-community/cli": "20.0.1", - "@react-native/babel-preset": "0.81.1", - "@react-native/eslint-config": "^0.81.1", + "@expo/config-plugins": "57.0.6", + "@react-native-community/cli": "20.1.0", + "@react-native/babel-preset": "0.86.0", + "@react-native/eslint-config": "^0.86.0", + "@react-native/jest-preset": "0.86.0", "@release-it/conventional-changelog": "^10.0.1", "@types/jest": "^29.5.14", - "@types/react": "^19.1.0", + "@types/react": "^19.2.0", "commitlint": "^19.8.1", "del-cli": "^6.0.0", "eslint": "^9.35.0", @@ -93,25 +108,36 @@ "eslint-plugin-prettier": "^5.5.4", "jest": "^29.7.0", "lefthook": "^2.0.3", + "nitrogen": "0.36.1", "prettier": "^2.8.8", - "react": "19.1.0", - "react-native": "0.81.1", + "react": "19.2.3", + "react-native": "0.86.0", "react-native-builder-bob": "^0.40.13", - "react-native-vision-camera": "^4.7.3", - "react-native-worklets-core": "^1.6.2", + "react-native-nitro-modules": "0.36.1", + "react-native-vision-camera": "^5.1.0", "release-it": "^19.0.4", "turbo": "^2.5.6", "typescript": "^5.9.2" }, "peerDependencies": { + "@expo/config-plugins": "^57.0.0", "react": "*", "react-native": "*", - "react-native-vision-camera": "*", - "react-native-worklets-core": "*" + "react-native-nitro-modules": "*", + "react-native-vision-camera": ">=5" + }, + "peerDependenciesMeta": { + "@expo/config-plugins": { + "optional": true + } }, "workspaces": [ "example" ], + "resolutions": { + "@babel/plugin-transform-modules-systemjs": "7.29.8", + "undici": "6.28.0" + }, "packageManager": "yarn@4.11.0", "react-native-builder-bob": { "source": "src", @@ -131,14 +157,6 @@ ] ] }, - "codegenConfig": { - "name": "VisionCameraMLKitSpec", - "type": "modules", - "jsSrcsDir": "src", - "android": { - "javaPackageName": "com.visioncameramlkit" - } - }, "prettier": { "quoteProps": "consistent", "singleQuote": true, @@ -171,11 +189,33 @@ } }, "jest": { - "preset": "react-native", + "preset": "@react-native/jest-preset", "modulePathIgnorePatterns": [ "/example/node_modules", "/lib/" - ] + ], + "collectCoverageFrom": [ + "src/**/*.{ts,tsx}", + "plugin/**/*.js", + "!src/**/*.test.{ts,tsx}", + "!src/**/__tests__/**", + "!src/**/types.ts", + "!src/specs/**", + "!plugin/**/__tests__/**" + ], + "coverageThreshold": { + "global": { + "branches": 80, + "functions": 80, + "lines": 80, + "statements": 80 + } + } + }, + "codegenConfig": { + "name": "VisionCameraMLKitSpec", + "type": "modules", + "jsSrcsDir": "src/specs" }, "create-react-native-library": { "languages": "kotlin-objc", diff --git a/plugin/__tests__/mlkitConfig.test.js b/plugin/__tests__/mlkitConfig.test.js new file mode 100644 index 0000000..50043b9 --- /dev/null +++ b/plugin/__tests__/mlkitConfig.test.js @@ -0,0 +1,39 @@ +const { parseMLKitConfig, MLKIT_FEATURE_KEYS } = require('../mlkitConfig'); + +describe('parseMLKitConfig', () => { + test('keeps only recognized keys, coerced to booleans', () => { + const result = parseMLKitConfig({ + textRecognition: true, + barcodeScanning: 1, + faceDetection: false, + }); + + expect(result).toEqual({ + textRecognition: true, + barcodeScanning: true, + faceDetection: false, + }); + }); + + test('omits keys the caller did not set', () => { + const result = parseMLKitConfig({ textRecognition: true }); + expect(Object.keys(result)).toEqual(['textRecognition']); + }); + + test('defaults to an empty config when no props are given', () => { + expect(parseMLKitConfig()).toEqual({}); + }); + + test('throws on unknown option names', () => { + expect(() => parseMLKitConfig({ faceDeteciton: true })).toThrow( + /unknown option\(s\) "faceDeteciton"/ + ); + }); + + test('every documented feature key round-trips', () => { + const allTrue = Object.fromEntries( + MLKIT_FEATURE_KEYS.map((k) => [k, true]) + ); + expect(parseMLKitConfig(allTrue)).toEqual(allTrue); + }); +}); diff --git a/plugin/__tests__/withAndroid.test.js b/plugin/__tests__/withAndroid.test.js new file mode 100644 index 0000000..3048a3c --- /dev/null +++ b/plugin/__tests__/withAndroid.test.js @@ -0,0 +1,54 @@ +const { insertAndroidConfig } = require('../withAndroid'); + +const BASE_GRADLE = `buildscript {\n ext {\n kotlinVersion = "1.9.0"\n }\n}\n\napply plugin: "com.android.application"\n`; + +describe('insertAndroidConfig', () => { + test('prepends the ext block with the given config', () => { + const result = insertAndroidConfig( + BASE_GRADLE, + { textRecognition: true, faceDetection: false }, + { language: 'groovy' } + ); + + expect(result).toContain('ext["react-native-vision-camera-mlkit"] = ['); + expect(result).toContain('textRecognition: true,'); + expect(result).toContain('faceDetection: false,'); + expect( + result.indexOf('ext["react-native-vision-camera-mlkit"]') + ).toBeLessThan(result.indexOf('buildscript')); + }); + + test('is idempotent - running twice does not duplicate the block', () => { + const once = insertAndroidConfig( + BASE_GRADLE, + { textRecognition: true }, + { + language: 'groovy', + } + ); + const twice = insertAndroidConfig( + once, + { textRecognition: true }, + { + language: 'groovy', + } + ); + + expect(twice).toBe(once); + expect( + once.split( + 'react-native-vision-camera-mlkit selective ML Kit dependencies' + ).length - 1 + ).toBe(1); + }); + + test('throws for Kotlin DSL build.gradle.kts', () => { + expect(() => + insertAndroidConfig( + BASE_GRADLE, + { textRecognition: true }, + { language: 'kt' } + ) + ).toThrow(/Kotlin DSL/); + }); +}); diff --git a/plugin/__tests__/withIOS.test.js b/plugin/__tests__/withIOS.test.js new file mode 100644 index 0000000..00be0cf --- /dev/null +++ b/plugin/__tests__/withIOS.test.js @@ -0,0 +1,43 @@ +const { insertIOSConfig } = require('../withIOS'); + +const BASE_PODFILE = `require File.join(File.dirname(\`node --print "require.resolve('expo/package.json')"\`), "scripts/autolinking")\n\nplatform :ios, '15.1'\n\ntarget 'ExampleApp' do\n use_expo_modules!\nend\n`; + +describe('insertIOSConfig', () => { + test('inserts the hash before the target block, dropping Android-only keys', () => { + const result = insertIOSConfig(BASE_PODFILE, { + textRecognition: true, + faceMeshDetection: true, + subjectSegmentation: true, + documentScanner: true, + barcodeScanning: false, + }); + + expect(result).toContain('$VisionCameraMLKit = {'); + expect(result).toContain("'textRecognition' => true,"); + expect(result).toContain("'barcodeScanning' => false,"); + expect(result).not.toContain('faceMeshDetection'); + expect(result).not.toContain('subjectSegmentation'); + expect(result).not.toContain('documentScanner'); + expect(result.indexOf('$VisionCameraMLKit')).toBeLessThan( + result.indexOf("target 'ExampleApp'") + ); + }); + + test('is idempotent - running twice does not duplicate the block', () => { + const once = insertIOSConfig(BASE_PODFILE, { textRecognition: true }); + const twice = insertIOSConfig(once, { textRecognition: true }); + + expect(twice).toBe(once); + expect( + once.split( + 'react-native-vision-camera-mlkit selective ML Kit dependencies' + ).length - 1 + ).toBe(1); + }); + + test('throws when no target block is found', () => { + expect(() => insertIOSConfig("platform :ios, '15.1'\n", {})).toThrow( + /could not find a `target` block/ + ); + }); +}); diff --git a/plugin/index.js b/plugin/index.js new file mode 100644 index 0000000..2e80c96 --- /dev/null +++ b/plugin/index.js @@ -0,0 +1,22 @@ +const { createRunOncePlugin } = require('@expo/config-plugins'); +const { name, version } = require('../package.json'); +const { parseMLKitConfig } = require('./mlkitConfig'); +const { withVisionCameraMLKitAndroid } = require('./withAndroid'); +const { withVisionCameraMLKitIOS } = require('./withIOS'); + +/** + * Expo config plugin mirroring this library's selective ML Kit dependency + * flags (see README "ML Kit Models Installation (Selective)") into the + * generated `android/build.gradle` and `ios/Podfile` during `expo prebuild`, + * so Expo users don't have to hand-edit native config. + * @throws {Error} If `props` contains an option outside the documented + * ML Kit feature flags. + */ +const withVisionCameraMLKit = (config, props = {}) => { + const mlkitConfig = parseMLKitConfig(props); + config = withVisionCameraMLKitAndroid(config, mlkitConfig); + config = withVisionCameraMLKitIOS(config, mlkitConfig); + return config; +}; + +module.exports = createRunOncePlugin(withVisionCameraMLKit, name, version); diff --git a/plugin/mlkitConfig.js b/plugin/mlkitConfig.js new file mode 100644 index 0000000..e3b130f --- /dev/null +++ b/plugin/mlkitConfig.js @@ -0,0 +1,57 @@ +/** + * Shared feature-flag list for the selective ML Kit dependency config, + * mirroring the Android `rootProject.ext["react-native-vision-camera-mlkit"]` + * and iOS `$VisionCameraMLKit` keys documented in the README. + */ +const MLKIT_FEATURE_KEYS = [ + 'textRecognition', + 'textRecognitionChinese', + 'textRecognitionDevanagari', + 'textRecognitionJapanese', + 'textRecognitionKorean', + 'faceDetection', + 'faceMeshDetection', + 'poseDetection', + 'poseDetectionAccurate', + 'selfieSegmentation', + 'subjectSegmentation', + 'documentScanner', + 'barcodeScanning', + 'imageLabeling', + 'objectDetection', + 'digitalInkRecognition', +]; + +/** Keys with no iOS ML Kit equivalent - dropped before writing the Podfile hash. */ +const ANDROID_ONLY_KEYS = new Set([ + 'faceMeshDetection', + 'subjectSegmentation', + 'documentScanner', +]); + +/** + * Validates and normalizes the plugin's `props` into a flat `{ key: boolean }` + * map, throwing on unknown keys instead of silently ignoring typos. + * @throws {Error} If `props` contains a key outside {@link MLKIT_FEATURE_KEYS}. + */ +const parseMLKitConfig = (props = {}) => { + const unknownKeys = Object.keys(props).filter( + (key) => !MLKIT_FEATURE_KEYS.includes(key) + ); + + if (unknownKeys.length > 0) { + throw new Error( + `react-native-vision-camera-mlkit config plugin: unknown option(s) ${unknownKeys + .map((key) => `"${key}"`) + .join(', ')}. Valid options: ${MLKIT_FEATURE_KEYS.join(', ')}.` + ); + } + + const config = {}; + for (const key of MLKIT_FEATURE_KEYS) { + if (props[key] !== undefined) config[key] = Boolean(props[key]); + } + return config; +}; + +module.exports = { MLKIT_FEATURE_KEYS, ANDROID_ONLY_KEYS, parseMLKitConfig }; diff --git a/plugin/withAndroid.js b/plugin/withAndroid.js new file mode 100644 index 0000000..bb2ccf5 --- /dev/null +++ b/plugin/withAndroid.js @@ -0,0 +1,54 @@ +const { withProjectBuildGradle } = require('@expo/config-plugins'); + +const MARKER = + '// react-native-vision-camera-mlkit selective ML Kit dependencies'; + +/** + * Renders `mlkitConfig` as the Groovy block consumers are otherwise told to + * hand-write at the top of `android/build.gradle` (see README "ML Kit Models + * Installation (Selective)"). + */ +const toGroovyBlock = (mlkitConfig) => { + const entries = Object.entries(mlkitConfig) + .map(([key, value]) => ` ${key}: ${value},`) + .join('\n'); + + return `${MARKER}\next["react-native-vision-camera-mlkit"] = [\n mlkit: [\n${entries}\n ]\n]\n`; +}; + +/** + * Prepends the selective ML Kit dependency block to `contents` (the + * project-level `android/build.gradle` source), unless already present. + * Pure string transform, kept separate from the Expo mod plumbing so it can + * be unit tested directly. + * @throws {Error} If `language` isn't Groovy (`.kts` is not supported by this + * plugin, matching the library's own native config). + */ +const insertAndroidConfig = (contents, mlkitConfig, { language }) => { + if (language !== 'groovy') { + throw new Error( + 'react-native-vision-camera-mlkit config plugin only supports Groovy android/build.gradle files, not Kotlin DSL (.kts).' + ); + } + + if (contents.includes(MARKER)) return contents; + + return `${toGroovyBlock(mlkitConfig)}\n${contents}`; +}; + +/** + * Applies {@link insertAndroidConfig} to the project-level + * `android/build.gradle`, mirroring what `getMLKitConfig()` in the library's + * own `android/build.gradle` reads via `rootProject.ext`. + */ +const withVisionCameraMLKitAndroid = (config, mlkitConfig) => + withProjectBuildGradle(config, (modConfig) => { + modConfig.modResults.contents = insertAndroidConfig( + modConfig.modResults.contents, + mlkitConfig, + { language: modConfig.modResults.language } + ); + return modConfig; + }); + +module.exports = { withVisionCameraMLKitAndroid, insertAndroidConfig }; diff --git a/plugin/withIOS.js b/plugin/withIOS.js new file mode 100644 index 0000000..c5ef374 --- /dev/null +++ b/plugin/withIOS.js @@ -0,0 +1,60 @@ +const { withPodfile } = require('@expo/config-plugins'); +const { ANDROID_ONLY_KEYS } = require('./mlkitConfig'); + +const MARKER = + '# react-native-vision-camera-mlkit selective ML Kit dependencies'; + +/** + * Renders the iOS subset of `mlkitConfig` (Android-only keys dropped) as the + * Ruby hash consumers are otherwise told to hand-write before `target` in + * `ios/Podfile` (see README "ML Kit Models Installation (Selective)"). + */ +const toRubyBlock = (mlkitConfig) => { + const entries = Object.entries(mlkitConfig) + .filter(([key]) => !ANDROID_ONLY_KEYS.has(key)) + .map(([key, value]) => ` '${key}' => ${value},`) + .join('\n'); + + return `${MARKER}\n$VisionCameraMLKit = {\n${entries}\n}\n`; +}; + +/** + * Inserts the selective ML Kit dependency hash into `contents` (the + * `ios/Podfile` source) before the first `target` block, unless already + * present. Pure string transform, kept separate from the Expo mod plumbing + * so it can be unit tested directly. + * @throws {Error} If no `target` block is found to insert before. + */ +const insertIOSConfig = (contents, mlkitConfig) => { + if (contents.includes(MARKER)) return contents; + + const targetIndex = contents.search(/^target\s/m); + if (targetIndex === -1) { + throw new Error( + 'react-native-vision-camera-mlkit config plugin: could not find a `target` block in ios/Podfile to insert the ML Kit configuration before.' + ); + } + + return ( + contents.slice(0, targetIndex) + + toRubyBlock(mlkitConfig) + + '\n' + + contents.slice(targetIndex) + ); +}; + +/** + * Applies {@link insertIOSConfig} to `ios/Podfile`, mirroring what + * `VisionCameraMLKit.podspec` reads via the global `$VisionCameraMLKit` + * variable. + */ +const withVisionCameraMLKitIOS = (config, mlkitConfig) => + withPodfile(config, (modConfig) => { + modConfig.modResults.contents = insertIOSConfig( + modConfig.modResults.contents, + mlkitConfig + ); + return modConfig; + }); + +module.exports = { withVisionCameraMLKitIOS, insertIOSConfig }; diff --git a/react-native.config.js b/react-native.config.js new file mode 100644 index 0000000..21645be --- /dev/null +++ b/react-native.config.js @@ -0,0 +1,16 @@ +// https://github.com/react-native-community/cli/blob/main/docs/dependencies.md + +module.exports = { + dependency: { + platforms: { + /** + * @type {import('@react-native-community/cli-types').IOSDependencyParams} + */ + ios: {}, + /** + * @type {import('@react-native-community/cli-types').AndroidDependencyParams} + */ + android: {}, + }, + }, +}; diff --git a/src/VisionCameraMLKitSpec.ts b/src/VisionCameraMLKitSpec.ts deleted file mode 100644 index a4ea67c..0000000 --- a/src/VisionCameraMLKitSpec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { TurboModule } from 'react-native'; -import { TurboModuleRegistry } from 'react-native'; - -export interface Spec extends TurboModule { - processImage(feature: string, path: string, options: object): Promise; -} - -export default TurboModuleRegistry.getEnforcing( - 'VisionCameraMLKitModule' -); diff --git a/src/__tests__/NativeBridge.test.ts b/src/__tests__/NativeBridge.test.ts deleted file mode 100644 index dfeb783..0000000 --- a/src/__tests__/NativeBridge.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { MLKIT_FEATURE_KEYS } from '../core/constants'; -import type { MLKitFeature } from '../core/types'; -import { INVALID_URI_ERROR, MISSING_MODULE_ERROR } from '../shared/constants'; - -const feature: MLKitFeature = MLKIT_FEATURE_KEYS.TEXT_RECOGNITION; -const createBridge = ( - platform: 'ios' | 'android', - moduleMock: { processImage?: jest.Mock } | undefined -) => { - jest.resetModules(); - jest.doMock('react-native', () => ({ - Platform: { - OS: platform, - select: (options: Record) => - options[platform] ?? options.default, - }, - })); - jest.doMock('../VisionCameraMLKitSpec', () => ({ - __esModule: true, - default: moduleMock, - })); - - return require('../core/NativeBridge') - .NativeBridge as typeof import('../core/NativeBridge').NativeBridge; -}; - -describe('NativeBridge', () => { - afterEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - }); - - it('throws when the native module is missing', async () => { - const NativeBridge = createBridge('ios', undefined); - - await expect( - NativeBridge.processImage(feature, 'file://image.jpg') - ).rejects.toThrow(MISSING_MODULE_ERROR); - }); - - it('rejects invalid image URIs', async () => { - const processImage = jest.fn().mockResolvedValue({}); - const NativeBridge = createBridge('android', { processImage }); - - await expect(NativeBridge.processImage(feature, ' ')).rejects.toThrow( - INVALID_URI_ERROR - ); - expect(processImage).not.toHaveBeenCalled(); - }); - - it('strips file prefixes on iOS', async () => { - const result = { ok: true }; - const processImage = jest.fn().mockResolvedValue(result); - const NativeBridge = createBridge('ios', { processImage }); - const response = await NativeBridge.processImage( - feature, - 'file://path/to/image.jpg', - { orientation: 'portrait' } - ); - - expect(processImage).toHaveBeenCalledWith(feature, 'path/to/image.jpg', { - orientation: 'portrait', - }); - expect(response).toBe(result); - }); - - it('adds file prefixes on Android for bare paths', async () => { - const processImage = jest.fn().mockResolvedValue({}); - const NativeBridge = createBridge('android', { processImage }); - - await NativeBridge.processImage(feature, '/tmp/image.jpg'); - - expect(processImage).toHaveBeenCalledWith( - feature, - 'file:///tmp/image.jpg', - {} - ); - }); -}); diff --git a/src/__tests__/PluginFactory.test.ts b/src/__tests__/PluginFactory.test.ts new file mode 100644 index 0000000..36ab917 --- /dev/null +++ b/src/__tests__/PluginFactory.test.ts @@ -0,0 +1,86 @@ +import { MLKIT_FEATURE_KEYS } from '../core/constants'; + +const loadPluginFactory = () => { + jest.resetModules(); + const isFeatureAvailable = jest.fn(() => true); + + jest.doMock('react-native', () => ({ + Platform: { + OS: 'ios', + select: (options: Record) => + options.ios ?? options.default, + }, + })); + jest.doMock('../core/VisionCameraMLKit', () => ({ + VisionCameraMLKit: { + isFeatureAvailable, + createTextRecognizer: jest.fn(), + createBarcodeScanner: jest.fn(), + }, + })); + + return { + PluginFactory: require('../core/PluginFactory') + .PluginFactory as typeof import('../core/PluginFactory').PluginFactory, + isFeatureAvailable, + }; +}; + +describe('PluginFactory.initPlugin', () => { + afterEach(() => { + jest.clearAllMocks(); + jest.resetModules(); + }); + + it.each([null, [], 'not-an-object', 42])( + 'rejects invalid options before reading roi: %p', + (options) => { + const { PluginFactory, isFeatureAvailable } = loadPluginFactory(); + + expect(() => + PluginFactory.initPlugin(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, options) + ).toThrow('Invalid MLKit plugin options: expected a plain object.'); + expect(isFeatureAvailable).toHaveBeenCalledWith( + MLKIT_FEATURE_KEYS.TEXT_RECOGNITION + ); + } + ); + + it.each([ + { scaleFactor: Number.NaN }, + { scaleFactor: Number.POSITIVE_INFINITY }, + { scaleFactor: '0.9' }, + { invertColors: 'true' }, + { frameProcessInterval: -1 }, + { frameProcessInterval: 1.5 }, + { orientation: 'sideways' }, + ])('rejects invalid base options: %p', (options) => { + const { PluginFactory } = loadPluginFactory(); + + expect(() => + PluginFactory.initPlugin(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, options) + ).toThrow('Invalid MLKit plugin option'); + }); + + it('rejects invalid text-recognition language values', () => { + const { PluginFactory } = loadPluginFactory(); + + expect(() => + PluginFactory.initPlugin(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, { + language: 'KLINGON', + }) + ).toThrow('Invalid MLKit plugin option "language".'); + }); + + it.each([ + { formats: 'QR_CODE' }, + { formats: ['NOT_A_FORMAT'] }, + { enableAllPotentialBarcodes: 1 }, + ])('rejects invalid barcode options: %p', (options) => { + const { PluginFactory } = loadPluginFactory(); + + expect(() => + PluginFactory.initPlugin(MLKIT_FEATURE_KEYS.BARCODE_SCANNING, options) + ).toThrow('Invalid MLKit plugin option'); + }); +}); diff --git a/src/__tests__/frameProcessingHooks.test.ts b/src/__tests__/frameProcessingHooks.test.ts new file mode 100644 index 0000000..4c0fe51 --- /dev/null +++ b/src/__tests__/frameProcessingHooks.test.ts @@ -0,0 +1,94 @@ +import type { Frame } from 'react-native-vision-camera'; +import { MLKIT_FEATURE_KEYS } from '../core/constants'; +import type { TextRecognitionResult } from '../features/text-recognition/types'; +import type { BarcodeScanningResult } from '../features/barcode-scanning/types'; + +const loadFrameProcessingHooks = () => { + jest.resetModules(); + + const textResult: TextRecognitionResult = { + text: 'Olá, 世界', + blocks: [], + }; + const barcodeResult: BarcodeScanningResult = { barcodes: [] }; + const recognizeText = jest.fn(() => textResult); + const recognizeBarcodes = jest.fn(() => barcodeResult); + const useMLKitPlugin = jest.fn((feature: string) => + feature === MLKIT_FEATURE_KEYS.TEXT_RECOGNITION + ? { recognize: recognizeText } + : { recognize: recognizeBarcodes } + ); + const useMemo = jest.fn((factory: () => unknown) => factory()); + + jest.doMock('react', () => ({ useMemo })); + jest.doMock('../hooks/useMLKitPlugin', () => ({ useMLKitPlugin })); + jest.doMock('../core/PluginFactory', () => ({ + PluginFactory: { initPlugin: jest.fn() }, + })); + + return { + useTextRecognition: require('../features/text-recognition') + .useTextRecognition as typeof import('../features/text-recognition').useTextRecognition, + useBarcodeScanning: require('../features/barcode-scanning') + .useBarcodeScanning as typeof import('../features/barcode-scanning').useBarcodeScanning, + recognizeText, + recognizeBarcodes, + textResult, + barcodeResult, + useMLKitPlugin, + useMemo, + }; +}; + +describe('frame processing hooks', () => { + afterEach(() => { + jest.clearAllMocks(); + jest.resetModules(); + }); + + it('creates a text recognizer and forwards frame-processing arguments', () => { + const { + useTextRecognition, + recognizeText, + textResult, + useMLKitPlugin, + useMemo, + } = loadFrameProcessingHooks(); + const options = { language: 'LATIN' as const }; + const frame = { width: 1920, height: 1080 } as Frame; + const args = { outputOrientation: 'landscape-right' as const }; + + const plugin = useTextRecognition(options); + const result = plugin.textRecognition(frame, args); + + expect(useMLKitPlugin).toHaveBeenCalledWith( + MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, + options + ); + expect(useMemo).toHaveBeenCalledWith(expect.any(Function), [ + { recognize: recognizeText }, + ]); + expect(recognizeText).toHaveBeenCalledWith(frame, args); + expect(result).toBe(textResult); + }); + + it('creates a barcode scanner with defaults and supplies empty arguments', () => { + const { + useBarcodeScanning, + recognizeBarcodes, + barcodeResult, + useMLKitPlugin, + } = loadFrameProcessingHooks(); + const frame = { width: 640, height: 480 } as Frame; + + const plugin = useBarcodeScanning(); + const result = plugin.barcodeScanning(frame); + + expect(useMLKitPlugin).toHaveBeenCalledWith( + MLKIT_FEATURE_KEYS.BARCODE_SCANNING, + {} + ); + expect(recognizeBarcodes).toHaveBeenCalledWith(frame, {}); + expect(result).toBe(barcodeResult); + }); +}); diff --git a/src/__tests__/staticImageNitro.test.ts b/src/__tests__/staticImageNitro.test.ts new file mode 100644 index 0000000..1f22644 --- /dev/null +++ b/src/__tests__/staticImageNitro.test.ts @@ -0,0 +1,259 @@ +import type { + TextRecognitionImageOptions, + TextRecognitionResult, +} from '../features/text-recognition'; +import type { BarcodeScanningImageOptions } from '../features/barcode-scanning'; +import type { BarcodeScannerResult } from '../specs/BarcodeScannerTypes'; + +type StaticImageApis = Pick< + typeof import('../features/text-recognition') & + typeof import('../features/barcode-scanning'), + 'processImageTextRecognition' | 'processImageBarcodeScanning' +>; + +type StaticTextRecognizer = { + recognizeImage(uri: string): Promise; + dispose(): void; +}; + +type StaticBarcodeScanner = { + recognizeImage(uri: string): Promise; + dispose(): void; +}; + +type StaticNitroRoot = { + isFeatureAvailable(feature: string): boolean; + createTextRecognizer( + options: TextRecognitionImageOptions + ): StaticTextRecognizer; + createBarcodeScanner( + options: BarcodeScanningImageOptions + ): StaticBarcodeScanner; +}; + +const loadStaticImageApis = () => { + jest.resetModules(); + + const recognizeTextImage = jest.fn< + Promise, + [uri: string] + >(); + const recognizeBarcodeImage = jest.fn< + Promise, + [uri: string] + >(); + const disposeTextRecognizer = jest.fn(); + const disposeBarcodeScanner = jest.fn(); + const textRecognizer: StaticTextRecognizer = { + recognizeImage: recognizeTextImage, + dispose: disposeTextRecognizer, + }; + const barcodeScanner: StaticBarcodeScanner = { + recognizeImage: recognizeBarcodeImage, + dispose: disposeBarcodeScanner, + }; + const staticNitroRoot = { + isFeatureAvailable: jest.fn(() => true), + createTextRecognizer: jest.fn< + StaticTextRecognizer, + [options: TextRecognitionImageOptions] + >(() => textRecognizer), + createBarcodeScanner: jest.fn< + StaticBarcodeScanner, + [options: BarcodeScanningImageOptions] + >(() => barcodeScanner), + } satisfies StaticNitroRoot; + const { createTextRecognizer, createBarcodeScanner } = staticNitroRoot; + const legacyNativeModuleAccess = jest.fn(() => { + throw new Error( + 'Static image processing must not use a legacy native module' + ); + }); + + jest.doMock('../core/VisionCameraMLKit', () => ({ + __esModule: true, + VisionCameraMLKit: staticNitroRoot, + })); + jest.doMock('react-native', () => ({ + Platform: { + OS: 'ios', + select: (options: Record) => + options.ios ?? options.default, + }, + NativeModules: new Proxy( + {}, + { + get: legacyNativeModuleAccess, + } + ), + TurboModuleRegistry: { + getEnforcing: legacyNativeModuleAccess, + }, + })); + + const textRecognition = require('../features/text-recognition') as Pick< + StaticImageApis, + 'processImageTextRecognition' + >; + const barcodeScanning = require('../features/barcode-scanning') as Pick< + StaticImageApis, + 'processImageBarcodeScanning' + >; + + return { + ...textRecognition, + ...barcodeScanning, + createTextRecognizer, + createBarcodeScanner, + recognizeTextImage, + recognizeBarcodeImage, + disposeTextRecognizer, + disposeBarcodeScanner, + legacyNativeModuleAccess, + }; +}; + +describe('static image recognition through Nitro', () => { + afterEach(() => { + jest.clearAllMocks(); + jest.resetModules(); + }); + + it('creates a configured text recognizer and recognizes the image URI', async () => { + const { + processImageTextRecognition, + createTextRecognizer, + recognizeTextImage, + disposeTextRecognizer, + legacyNativeModuleAccess, + } = loadStaticImageApis(); + const result: TextRecognitionResult = { text: 'Olá, 世界', blocks: [] }; + const options: TextRecognitionImageOptions = { + language: 'JAPANESE', + orientation: 'landscape-right', + scaleFactor: 0.9, + invertColors: true, + roi: { + x: 0.1, + y: 0.2, + width: 0.5, + height: 0.4, + unit: 'normalized', + }, + }; + recognizeTextImage.mockResolvedValue(result); + + const response = await processImageTextRecognition( + 'file:///tmp/receipt-日本語.jpg', + options + ); + + expect(createTextRecognizer).toHaveBeenCalledWith(options); + expect(recognizeTextImage).toHaveBeenCalledWith( + 'file:///tmp/receipt-日本語.jpg' + ); + expect(legacyNativeModuleAccess).not.toHaveBeenCalled(); + expect(disposeTextRecognizer).toHaveBeenCalledTimes(1); + expect(response).toBe(result); + }); + + it('creates a configured barcode scanner and recognizes the image URI', async () => { + const { + processImageBarcodeScanning, + createBarcodeScanner, + recognizeBarcodeImage, + disposeBarcodeScanner, + legacyNativeModuleAccess, + } = loadStaticImageApis(); + const result: BarcodeScannerResult = { barcodes: [] }; + const options: BarcodeScanningImageOptions = { + formats: ['QR_CODE', 'EAN_13'], + enableAllPotentialBarcodes: true, + orientation: 'portrait', + scaleFactor: 0.95, + invertColors: true, + roi: { x: 20, y: 40, width: 200, height: 100, unit: 'pixel' }, + }; + recognizeBarcodeImage.mockResolvedValue(result); + + const response = await processImageBarcodeScanning( + 'file:///tmp/qr-code.png', + options + ); + + expect(createBarcodeScanner).toHaveBeenCalledWith(options); + expect(recognizeBarcodeImage).toHaveBeenCalledWith( + 'file:///tmp/qr-code.png' + ); + expect(legacyNativeModuleAccess).not.toHaveBeenCalled(); + expect(disposeBarcodeScanner).toHaveBeenCalledTimes(1); + expect(response).toEqual(result); + }); + + it('configures both recognizers with empty defaults when options are omitted', async () => { + const { + processImageTextRecognition, + processImageBarcodeScanning, + createTextRecognizer, + createBarcodeScanner, + recognizeTextImage, + recognizeBarcodeImage, + disposeTextRecognizer, + disposeBarcodeScanner, + legacyNativeModuleAccess, + } = loadStaticImageApis(); + recognizeTextImage.mockResolvedValue({ text: '', blocks: [] }); + recognizeBarcodeImage.mockResolvedValue({ barcodes: [] }); + + await processImageTextRecognition('file:///tmp/empty-text.png'); + await processImageBarcodeScanning('file:///tmp/empty-barcode.png'); + + expect(createTextRecognizer).toHaveBeenCalledWith({}); + expect(createBarcodeScanner).toHaveBeenCalledWith({}); + expect(recognizeTextImage).toHaveBeenCalledWith( + 'file:///tmp/empty-text.png' + ); + expect(recognizeBarcodeImage).toHaveBeenCalledWith( + 'file:///tmp/empty-barcode.png' + ); + expect(legacyNativeModuleAccess).not.toHaveBeenCalled(); + expect(disposeTextRecognizer).toHaveBeenCalledTimes(1); + expect(disposeBarcodeScanner).toHaveBeenCalledTimes(1); + }); + + it('propagates asynchronous recognizer errors without falling back to the legacy bridge', async () => { + const { + processImageTextRecognition, + recognizeTextImage, + disposeTextRecognizer, + legacyNativeModuleAccess, + } = loadStaticImageApis(); + const failure = new Error('The image could not be read'); + recognizeTextImage.mockRejectedValue(failure); + + await expect( + processImageTextRecognition('file:///tmp/unreadable.jpg') + ).rejects.toBe(failure); + + expect(legacyNativeModuleAccess).not.toHaveBeenCalled(); + expect(disposeTextRecognizer).toHaveBeenCalledTimes(1); + }); + + it('propagates asynchronous barcode scanner errors without falling back to the legacy bridge', async () => { + const { + processImageBarcodeScanning, + recognizeBarcodeImage, + disposeBarcodeScanner, + legacyNativeModuleAccess, + } = loadStaticImageApis(); + const failure = new Error('The barcode image could not be read'); + recognizeBarcodeImage.mockRejectedValue(failure); + + await expect( + processImageBarcodeScanning('file:///tmp/unreadable-barcode.jpg') + ).rejects.toBe(failure); + + expect(legacyNativeModuleAccess).not.toHaveBeenCalled(); + expect(disposeBarcodeScanner).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/__tests__/useMLKitPlugin.test.ts b/src/__tests__/useMLKitPlugin.test.ts new file mode 100644 index 0000000..b0e58e9 --- /dev/null +++ b/src/__tests__/useMLKitPlugin.test.ts @@ -0,0 +1,57 @@ +import { MLKIT_FEATURE_KEYS } from '../core/constants'; + +const loadUseMLKitPlugin = () => { + jest.resetModules(); + + const initPlugin = jest.fn(); + const useMemo = jest.fn((factory: () => unknown) => factory()); + + jest.doMock('react', () => ({ useMemo })); + jest.doMock('../core/PluginFactory', () => ({ + PluginFactory: { initPlugin }, + })); + + return { + useMLKitPlugin: require('../hooks/useMLKitPlugin') + .useMLKitPlugin as typeof import('../hooks/useMLKitPlugin').useMLKitPlugin, + initPlugin, + useMemo, + }; +}; + +describe('useMLKitPlugin', () => { + afterEach(() => { + jest.clearAllMocks(); + jest.resetModules(); + }); + + it('initializes the requested plugin with feature and options dependencies', () => { + const { useMLKitPlugin, initPlugin, useMemo } = loadUseMLKitPlugin(); + const plugin = { recognize: jest.fn() }; + const options = { scaleFactor: 0.9 }; + initPlugin.mockReturnValue(plugin); + + const result = useMLKitPlugin(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, options); + + expect(initPlugin).toHaveBeenCalledWith( + MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, + options + ); + expect(useMemo).toHaveBeenCalledWith(expect.any(Function), [ + MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, + options, + ]); + expect(result).toBe(plugin); + }); + + it('uses empty options when the caller omits them', () => { + const { useMLKitPlugin, initPlugin } = loadUseMLKitPlugin(); + + useMLKitPlugin(MLKIT_FEATURE_KEYS.BARCODE_SCANNING); + + expect(initPlugin).toHaveBeenCalledWith( + MLKIT_FEATURE_KEYS.BARCODE_SCANNING, + {} + ); + }); +}); diff --git a/src/__tests__/validateRegionOfInterest.test.ts b/src/__tests__/validateRegionOfInterest.test.ts new file mode 100644 index 0000000..5ae5405 --- /dev/null +++ b/src/__tests__/validateRegionOfInterest.test.ts @@ -0,0 +1,136 @@ +import { validateRegionOfInterest } from '../core/validateRegionOfInterest'; +import type { RegionOfInterest } from '../core/types'; + +describe('validateRegionOfInterest', () => { + it.each([null, [], 'not-an-object', 42])( + 'rejects a non-object ROI: %p', + (roi) => { + expect(() => validateRegionOfInterest(roi)).toThrow( + 'Invalid RegionOfInterest: expected a plain object.' + ); + } + ); + + it.each(['x', 'y', 'width', 'height'] as const)( + 'rejects an ROI missing its own %s field', + (missingField) => { + const roi = { x: 0, y: 0, width: 1, height: 1 }; + delete roi[missingField]; + + expect(() => validateRegionOfInterest(roi)).toThrow( + 'Invalid RegionOfInterest: x, y, width, and height must be own finite numbers.' + ); + } + ); + + it.each([ + { x: Number.NaN, y: 0, width: 1, height: 1 }, + { x: 0, y: Number.POSITIVE_INFINITY, width: 1, height: 1 }, + { x: 0, y: 0, width: Number.NEGATIVE_INFINITY, height: 1 }, + { x: 0, y: 0, width: 1, height: Number.NaN }, + ])('rejects non-finite ROI dimensions: %p', (roi) => { + expect(() => validateRegionOfInterest(roi)).toThrow( + 'Invalid RegionOfInterest: x, y, width, and height must be own finite numbers.' + ); + }); + + it('rejects an unsupported ROI unit', () => { + expect(() => + validateRegionOfInterest({ + x: 0, + y: 0, + width: 1, + height: 1, + unit: 'view', + }) + ).toThrow( + 'Invalid RegionOfInterest: unit must be "normalized" or "pixel" when provided.' + ); + }); + + it('rejects fields inherited from another object', () => { + const inheritedRoi = Object.create({ x: 0, y: 0, width: 1, height: 1 }); + + expect(() => validateRegionOfInterest(inheritedRoi)).toThrow( + 'Invalid RegionOfInterest: expected a plain object.' + ); + }); + + it('accepts a valid normalized region', () => { + expect(() => + validateRegionOfInterest({ x: 0.25, y: 0.25, width: 0.5, height: 0.5 }) + ).not.toThrow(); + }); + + it('accepts a valid normalized region with unit explicitly set', () => { + expect(() => + validateRegionOfInterest({ + x: 0, + y: 0, + width: 1, + height: 1, + unit: 'normalized', + }) + ).not.toThrow(); + }); + + it('accepts a valid pixel region regardless of magnitude', () => { + expect(() => + validateRegionOfInterest({ + x: 100, + y: 100, + width: 800, + height: 600, + unit: 'pixel', + }) + ).not.toThrow(); + }); + + it('throws when x is negative', () => { + expect(() => + validateRegionOfInterest({ x: -0.1, y: 0, width: 0.5, height: 0.5 }) + ).toThrow(/x and y must be >= 0/); + }); + + it('throws when y is negative', () => { + expect(() => + validateRegionOfInterest({ x: 0, y: -0.1, width: 0.5, height: 0.5 }) + ).toThrow(/x and y must be >= 0/); + }); + + it('throws when width is zero or negative', () => { + expect(() => + validateRegionOfInterest({ x: 0, y: 0, width: 0, height: 0.5 }) + ).toThrow(/width and height must be > 0/); + }); + + it('throws when height is zero or negative', () => { + expect(() => + validateRegionOfInterest({ x: 0, y: 0, width: 0.5, height: -1 }) + ).toThrow(/width and height must be > 0/); + }); + + it('throws when normalized x + width exceeds 1', () => { + expect(() => + validateRegionOfInterest({ x: 0.6, y: 0, width: 0.5, height: 0.5 }) + ).toThrow(/x \+ width and y \+ height must be <= 1/); + }); + + it('throws when normalized y + height exceeds 1', () => { + expect(() => + validateRegionOfInterest({ x: 0, y: 0.6, width: 0.5, height: 0.5 }) + ).toThrow(/x \+ width and y \+ height must be <= 1/); + }); + + it('does not apply the normalized bounds check for pixel regions', () => { + const roi: RegionOfInterest = { + x: 500, + y: 500, + width: 500, + height: 500, + unit: 'pixel', + }; + + expect(() => validateRegionOfInterest(roi)).not.toThrow(); + }); +}); diff --git a/src/core/NativeBridge.ts b/src/core/NativeBridge.ts deleted file mode 100644 index 3667ea0..0000000 --- a/src/core/NativeBridge.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Platform } from 'react-native'; -import VisionCameraMLKitModule from '../VisionCameraMLKitSpec'; -import { INVALID_URI_ERROR, MISSING_MODULE_ERROR } from '../shared/constants'; -import type { MLKitFeature } from './types'; - -/** - * Bridge class for native MLKit image processing - */ -export class NativeBridge { - /** - * Process a static image using the specified MLKit feature. - * @param {MLKitFeature} feature - The MLKit feature to use. - * @param {string} uri - The file path or URI of the image. - * @param {object} options - Additional options for processing. - * @returns {Promise} Promise resolving to the processing result. - */ - static async processImage( - feature: MLKitFeature, - uri: string, - options: object = {} - ): Promise { - if ( - !VisionCameraMLKitModule || - typeof VisionCameraMLKitModule.processImage !== 'function' - ) { - throw new Error(MISSING_MODULE_ERROR); - } - const normalizedUri = this.validateAndNormalizeUri(uri); - - return await VisionCameraMLKitModule.processImage( - feature, - normalizedUri, - options - ); - } - - /** - * Validates and normalizes the image URI for different platforms. - * @param {string} uri - The input URI. - * @returns {string} The normalized URI. - * @throws {Error} If the URI is invalid. - */ - private static validateAndNormalizeUri(uri: string): string { - if (!uri || typeof uri !== 'string') { - throw new Error(INVALID_URI_ERROR); - } - - // Check for basic URI validity - if (uri.trim().length === 0) { - throw new Error(INVALID_URI_ERROR); - } - - // Normalize the URI for different platforms - let processUri = uri; - - if (Platform.OS === 'ios') { - // iOS: Remove file:// prefix if present - processUri = uri.replace('file://', ''); - } else { - // Android: Ensure proper file:// prefix for absolute file paths without any scheme - const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(processUri); - if (!hasScheme) { - processUri = `file://${processUri}`; - } - } - - return processUri; - } -} diff --git a/src/core/PluginFactory.ts b/src/core/PluginFactory.ts index 6c17b5c..261a0fd 100644 --- a/src/core/PluginFactory.ts +++ b/src/core/PluginFactory.ts @@ -1,9 +1,123 @@ import { Platform } from 'react-native'; -import { VisionCameraProxy } from 'react-native-vision-camera'; -import { FEATURE_ERROR_MAP, LINKING_ERROR } from '../shared/constants'; +import { FEATURE_ERROR_MAP } from '../shared/constants'; +import type { BarcodeScanningOptions } from '../features/barcode-scanning/types'; +import type { TextRecognitionOptions } from '../features/text-recognition/types'; import { MLKIT_FEATURE_KEYS } from './constants'; +import { validateRegionOfInterest } from './validateRegionOfInterest'; +import { VisionCameraMLKit } from './VisionCameraMLKit'; import type { MLKitBaseOptions, MLKitFeature } from './types'; +const isPlainObject = (value: unknown): value is Record => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; +}; + +const ORIENTATIONS = new Set([ + 'portrait', + 'portrait-upside-down', + 'landscape-left', + 'landscape-right', +]); +const TEXT_LANGUAGES = new Set([ + 'LATIN', + 'CHINESE', + 'DEVANAGARI', + 'JAPANESE', + 'KOREAN', +]); +const BARCODE_FORMATS = new Set([ + 'UNKNOWN', + 'ALL_FORMATS', + 'CODE_128', + 'CODE_39', + 'CODE_93', + 'CODABAR', + 'DATA_MATRIX', + 'EAN_13', + 'EAN_8', + 'ITF', + 'QR_CODE', + 'UPC_A', + 'UPC_E', + 'PDF417', + 'AZTEC', +]); + +const hasDefinedOption = ( + options: Record, + key: string +): boolean => + Object.prototype.hasOwnProperty.call(options, key) && + options[key] !== undefined; + +const invalidOption = (key: string): never => { + throw new Error(`Invalid MLKit plugin option "${key}".`); +}; + +const validateBaseOptions = (options: Record): void => { + if ( + hasDefinedOption(options, 'scaleFactor') && + (typeof options.scaleFactor !== 'number' || + !Number.isFinite(options.scaleFactor)) + ) { + invalidOption('scaleFactor'); + } + if ( + hasDefinedOption(options, 'invertColors') && + typeof options.invertColors !== 'boolean' + ) { + invalidOption('invertColors'); + } + if ( + hasDefinedOption(options, 'frameProcessInterval') && + (typeof options.frameProcessInterval !== 'number' || + !Number.isSafeInteger(options.frameProcessInterval) || + options.frameProcessInterval < 0) + ) { + invalidOption('frameProcessInterval'); + } + if ( + hasDefinedOption(options, 'orientation') && + !ORIENTATIONS.has(options.orientation as string) + ) { + invalidOption('orientation'); + } +}; + +const validateFeatureOptions = ( + feature: MLKitFeature, + options: Record +): void => { + if ( + feature === MLKIT_FEATURE_KEYS.TEXT_RECOGNITION && + hasDefinedOption(options, 'language') && + !TEXT_LANGUAGES.has(options.language as string) + ) { + invalidOption('language'); + } + if (feature !== MLKIT_FEATURE_KEYS.BARCODE_SCANNING) return; + + if ( + hasDefinedOption(options, 'formats') && + (!Array.isArray(options.formats) || + !options.formats.every( + (format) => typeof format === 'string' && BARCODE_FORMATS.has(format) + )) + ) { + invalidOption('formats'); + } + if ( + hasDefinedOption(options, 'enableAllPotentialBarcodes') && + typeof options.enableAllPotentialBarcodes !== 'boolean' + ) { + invalidOption('enableAllPotentialBarcodes'); + } +}; + /** * Factory class for managing MLKit Vision Camera plugins */ @@ -66,19 +180,40 @@ buildscript { /** * Initializes the Vision Camera plugin for a given feature. * @param {MLKitFeature} feature - The MLKit feature to initialize. - * @param {MLKitBaseOptions} options - Options for the plugin. + * @param {unknown} options - Options for the plugin. * @returns The initialized plugin. */ - static initPlugin(feature: MLKitFeature, options: MLKitBaseOptions) { + static initPlugin(feature: MLKitFeature, options: unknown) { PluginFactory.assertFeatureAvailable(feature); - const plugin = VisionCameraProxy.initFrameProcessorPlugin(feature, options); + if (!isPlainObject(options)) { + throw new Error('Invalid MLKit plugin options: expected a plain object.'); + } + + validateBaseOptions(options); + validateFeatureOptions(feature, options); - if (!plugin) { - throw new Error(LINKING_ERROR); + if ( + Object.prototype.hasOwnProperty.call(options, 'roi') && + options.roi !== undefined + ) { + validateRegionOfInterest(options.roi); } - return plugin; + const validatedOptions = options as MLKitBaseOptions; + + switch (feature) { + case MLKIT_FEATURE_KEYS.TEXT_RECOGNITION: + return VisionCameraMLKit.createTextRecognizer( + validatedOptions as TextRecognitionOptions + ); + case MLKIT_FEATURE_KEYS.BARCODE_SCANNING: + return VisionCameraMLKit.createBarcodeScanner( + validatedOptions as BarcodeScanningOptions + ); + default: + throw new Error(PluginFactory.getFeatureErrorMessage(feature)); + } } /** @@ -88,8 +223,7 @@ buildscript { */ static isFeatureAvailable(feature: MLKitFeature): boolean { try { - const plugin = VisionCameraProxy.initFrameProcessorPlugin(feature, {}); - return plugin !== undefined && plugin !== null; + return VisionCameraMLKit.isFeatureAvailable(feature); } catch { return false; } diff --git a/src/core/VisionCameraMLKit.ts b/src/core/VisionCameraMLKit.ts new file mode 100644 index 0000000..0fcb2cc --- /dev/null +++ b/src/core/VisionCameraMLKit.ts @@ -0,0 +1,5 @@ +import { NitroModules } from 'react-native-nitro-modules'; +import type { VisionCameraMLKit as VisionCameraMLKitSpec } from '../specs/VisionCameraMLKit.nitro'; + +export const VisionCameraMLKit = + NitroModules.createHybridObject('VisionCameraMLKit'); diff --git a/src/core/normalizeImageUri.test.ts b/src/core/normalizeImageUri.test.ts new file mode 100644 index 0000000..9b02041 --- /dev/null +++ b/src/core/normalizeImageUri.test.ts @@ -0,0 +1,58 @@ +import { INVALID_URI_ERROR } from '../shared/constants'; + +const loadNormalizeImageUri = (platform: 'ios' | 'android') => { + jest.resetModules(); + jest.doMock('react-native', () => ({ + Platform: { + OS: platform, + select: (options: Record) => + options[platform] ?? options.default, + }, + })); + + return require('./normalizeImageUri') + .normalizeImageUri as typeof import('./normalizeImageUri').normalizeImageUri; +}; + +describe('normalizeImageUri', () => { + afterEach(() => { + jest.clearAllMocks(); + jest.resetModules(); + }); + + it.each([undefined, null, '', ' '])('rejects an invalid URI: %p', (uri) => { + const normalizeImageUri = loadNormalizeImageUri('ios'); + + expect(() => normalizeImageUri(uri)).toThrow(INVALID_URI_ERROR); + }); + + it('preserves file URLs on iOS so native URL parsing decodes them safely', () => { + const normalizeImageUri = loadNormalizeImageUri('ios'); + + expect(normalizeImageUri('file:///tmp/My%20Image.jpg')).toBe( + 'file:///tmp/My%20Image.jpg' + ); + }); + + it('does not strip a file prefix embedded later in an iOS URI', () => { + const normalizeImageUri = loadNormalizeImageUri('ios'); + const uri = 'https://example.com/redirect?target=file://image.jpg'; + + expect(normalizeImageUri(uri)).toBe(uri); + }); + + it('adds the file prefix to Android bare paths', () => { + const normalizeImageUri = loadNormalizeImageUri('android'); + + expect(normalizeImageUri('/tmp/image.jpg')).toBe('file:///tmp/image.jpg'); + }); + + it.each(['file:///tmp/image.jpg', 'content://media/image/1'])( + 'preserves an existing Android scheme: %s', + (uri) => { + const normalizeImageUri = loadNormalizeImageUri('android'); + + expect(normalizeImageUri(uri)).toBe(uri); + } + ); +}); diff --git a/src/core/normalizeImageUri.ts b/src/core/normalizeImageUri.ts new file mode 100644 index 0000000..b1c2a81 --- /dev/null +++ b/src/core/normalizeImageUri.ts @@ -0,0 +1,18 @@ +import { Platform } from 'react-native'; +import { INVALID_URI_ERROR } from '../shared/constants'; + +/** + * Validates and normalizes an image URI for the static Nitro APIs. + */ +export const normalizeImageUri = (uri: unknown): string => { + if (typeof uri !== 'string' || uri.trim().length === 0) { + throw new Error(INVALID_URI_ERROR); + } + + if (Platform.OS === 'ios') { + return uri; + } + + const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(uri); + return hasScheme ? uri : `file://${uri}`; +}; diff --git a/src/core/types.ts b/src/core/types.ts index 4c00467..6fe1717 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -21,6 +21,30 @@ export type Corner = { y: number; }; +/** + * Whether a {@link RegionOfInterest}'s `x`/`y`/`width`/`height` are + * normalized to the `0..1` range (relative to the source frame/image) or + * absolute pixel values. + */ +export type RegionOfInterestUnit = 'normalized' | 'pixel'; + +/** + * Restricts ML Kit processing to a rectangular region of the source + * frame/image. Cropping happens before recognition to reduce CPU/GPU work; + * result coordinates (bounding boxes, corners) are always mapped back to + * full source coordinates, so overlays don't need to know a crop happened. + */ +export type RegionOfInterest = { + x: number; + y: number; + width: number; + height: number; + /** + * @default 'normalized' + */ + unit?: RegionOfInterestUnit; +}; + export type MLKitBaseOptions = { /** * Optional image downscaling for performance optimization. @@ -35,18 +59,27 @@ export type MLKitBaseOptions = { */ invertColors?: boolean; /** - * @deprecated Use `runAtTargetFps()` from Vision Camera instead for better frame rate control. + * Crop processing to a rectangular region of the frame before running + * ML Kit, to reduce CPU/GPU work. Result coordinates are mapped back to + * full source coordinates. + */ + roi?: RegionOfInterest; + /** + * @deprecated Throttle frames manually inside your `useFrameOutput` `onFrame` callback instead. * Process one frame, then skip the next N frames before processing again. * For example, `frameProcessInterval: 2` means: process frame 1, skip frames 2-3, process frame 4, etc. * @example * ```ts - * const frameProcessor = useFrameProcessor((frame) => { - * 'worklet' - * runAtTargetFps(10, () => { + * const frameOutput = useFrameOutput({ + * onFrame(frame) { * 'worklet' + * if (frameCount.value++ % 10 !== 0) { + * frame.dispose() + * return + * } * const result = textRecognition(frame) - * }) - * }, []) + * }, + * }) * ``` * @default 0 (process every frame) */ @@ -78,8 +111,17 @@ export type MLKitBaseArguments = { export type ImageProcessingBaseOptions = { /** - * The orientation of the image. Pass this to support rotation in text recognition. - * @default 'portrait' + * Optional image downscaling for performance optimization. + * Clamped to the range [0.9, 1.0] to preserve ML accuracy. + * Example: 0.9 reduces width/height by ~10% (~19% fewer pixels). + * @default 1.0 + */ + scaleFactor?: number; + /** + * Override the image orientation for processing. + * When omitted, the orientation is automatically detected from the image's + * EXIF metadata. Provide an explicit value only if the metadata is missing + * or incorrect. */ orientation?: Orientation; /** @@ -87,6 +129,12 @@ export type ImageProcessingBaseOptions = { * @default false */ invertColors?: boolean; + /** + * Crop processing to a rectangular region of the image before running + * ML Kit, to reduce CPU/GPU work. Result coordinates are mapped back to + * full source coordinates. + */ + roi?: RegionOfInterest; }; export type ImageProcessingError = diff --git a/src/core/validateRegionOfInterest.ts b/src/core/validateRegionOfInterest.ts new file mode 100644 index 0000000..22f2fe2 --- /dev/null +++ b/src/core/validateRegionOfInterest.ts @@ -0,0 +1,76 @@ +const hasOwnProperty = (value: object, property: string): boolean => + Object.prototype.hasOwnProperty.call(value, property); + +const isPlainObject = (value: unknown): value is Record => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; +}; + +type RegionOfInterestDimensions = Record & { + x: number; + y: number; + width: number; + height: number; +}; + +const hasOwnFiniteDimensions = ( + roi: Record +): roi is RegionOfInterestDimensions => + ['x', 'y', 'width', 'height'].every( + (property) => + hasOwnProperty(roi, property) && + typeof roi[property] === 'number' && + Number.isFinite(roi[property]) + ); + +/** + * Validates a {@link RegionOfInterest} before it crosses into native code. + * Fails fast on out-of-bounds values instead of letting native preprocessing + * fail deep inside the crop step. + * @throws {Error} If the region is invalid for its unit. + */ +export const validateRegionOfInterest = (roi: unknown): void => { + if (!isPlainObject(roi)) { + throw new Error('Invalid RegionOfInterest: expected a plain object.'); + } + + if (!hasOwnFiniteDimensions(roi)) { + throw new Error( + 'Invalid RegionOfInterest: x, y, width, and height must be own finite numbers.' + ); + } + + const unit = hasOwnProperty(roi, 'unit') ? roi.unit : undefined; + if (unit !== undefined && unit !== 'normalized' && unit !== 'pixel') { + throw new Error( + 'Invalid RegionOfInterest: unit must be "normalized" or "pixel" when provided.' + ); + } + + const { x, y, width, height } = roi; + + if (x < 0 || y < 0) { + throw new Error( + `Invalid RegionOfInterest: x and y must be >= 0 (got x=${x}, y=${y}).` + ); + } + + if (width <= 0 || height <= 0) { + throw new Error( + `Invalid RegionOfInterest: width and height must be > 0 (got width=${width}, height=${height}).` + ); + } + + if ( + (unit === undefined || unit === 'normalized') && + (x + width > 1 || y + height > 1) + ) { + throw new Error( + `Invalid RegionOfInterest: normalized x + width and y + height must be <= 1 (got x=${x}, width=${width}, y=${y}, height=${height}).` + ); + } +}; diff --git a/src/features/barcode-scanning/index.ts b/src/features/barcode-scanning/index.ts new file mode 100644 index 0000000..8a55074 --- /dev/null +++ b/src/features/barcode-scanning/index.ts @@ -0,0 +1,69 @@ +import { useMemo } from 'react'; +import type { Frame } from 'react-native-vision-camera'; +import { MLKIT_FEATURE_KEYS } from '../../core/constants'; +import { normalizeImageUri } from '../../core/normalizeImageUri'; +import { PluginFactory } from '../../core/PluginFactory'; +import { useMLKitPlugin } from '../../hooks/useMLKitPlugin'; +import type { BarcodeScanner } from '../../specs/BarcodeScanner.nitro'; +import { mapStaticBarcodeResult } from './mapStaticBarcodeResult'; +import type { + BarcodeScanningArguments, + BarcodeScanningImageOptions, + BarcodeScanningOptions, + BarcodeScanningResult, +} from './types'; + +/** + * Scan barcodes from a static image file. + */ +export const processImageBarcodeScanning = async ( + uri: string, + options: BarcodeScanningImageOptions = {} +): Promise => { + const scanner = PluginFactory.initPlugin( + MLKIT_FEATURE_KEYS.BARCODE_SCANNING, + options + ) as BarcodeScanner; + + try { + return mapStaticBarcodeResult( + await scanner.recognizeImage(normalizeImageUri(uri)) + ); + } finally { + scanner.dispose(); + } +}; + +/** + * Hook for barcode scanning from camera frames. + */ +export const useBarcodeScanning = (options: BarcodeScanningOptions = {}) => { + const plugin = useMLKitPlugin( + MLKIT_FEATURE_KEYS.BARCODE_SCANNING, + options + ); + + return useMemo( + () => ({ + barcodeScanning: ( + frame: Frame, + args?: BarcodeScanningArguments + ): BarcodeScanningResult => { + 'worklet'; + return plugin.recognize(frame, args ?? {}) as BarcodeScanningResult; + }, + }), + [plugin] + ); +}; + +export type { + BarcodeData, + BarcodeFormat, + BarcodeParsedValue, + BarcodeScanningArguments, + BarcodeScanningImageOptions, + BarcodeScanningOptions, + BarcodeScanningResult, + BarcodeValueTypeName, +} from './types'; diff --git a/src/features/barcode-scanning/mapStaticBarcodeResult.test.ts b/src/features/barcode-scanning/mapStaticBarcodeResult.test.ts new file mode 100644 index 0000000..70e5470 --- /dev/null +++ b/src/features/barcode-scanning/mapStaticBarcodeResult.test.ts @@ -0,0 +1,149 @@ +import type { BarcodeParsedValue, BarcodeScanningResult } from './types'; +import type { BarcodeScannerResult } from '../../specs/BarcodeScannerTypes'; +import { mapStaticBarcodeResult } from './mapStaticBarcodeResult'; + +const barcode = { + format: 256, + formatName: 'QR_CODE' as const, + valueType: 9, + valueTypeName: 'TYPE_WIFI' as const, + isPotential: false, +}; + +const parsedValueError = 'Invalid barcode parsed value'; + +const resultWithValue = ( + value: BarcodeScannerResult['barcodes'][number]['value'] +): BarcodeScannerResult => ({ + barcodes: [{ ...barcode, value }], +}); + +const validParsedValues: readonly BarcodeParsedValue[] = [ + { type: 'TYPE_UNKNOWN', data: { rawValue: 'unknown' } }, + { + type: 'TYPE_CONTACT_INFO', + data: { + name: { first: 'Ada' }, + organization: 'Analytical Engines', + phones: [{ number: '+15551234567', type: 'WORK', typeName: 'WORK' }], + emails: [{ address: 'ada@example.com', type: 1, typeName: 'WORK' }], + addresses: [{ addressLines: ['1 Logic Lane'], type: 'HOME' }], + urls: ['https://example.com'], + }, + }, + { type: 'TYPE_EMAIL', data: { address: 'ada@example.com', type: 'WORK' } }, + { type: 'TYPE_ISBN', data: { isbn: '9780132350884' } }, + { type: 'TYPE_PHONE', data: { number: '+15551234567', type: 1 } }, + { type: 'TYPE_PRODUCT', data: { product: '012345678905' } }, + { type: 'TYPE_SMS', data: { message: 'Hello', phoneNumber: '+15551234567' } }, + { type: 'TYPE_TEXT', data: { text: 'Hello' } }, + { type: 'TYPE_URL', data: { title: 'Example', url: 'https://example.com' } }, + { + type: 'TYPE_WIFI', + data: { ssid: 'guest-network', password: null, encryptionType: 2 }, + }, + { type: 'TYPE_GEO', data: { lat: -23.55052, lng: -46.633308 } }, + { + type: 'TYPE_CALENDAR_EVENT', + data: { + summary: 'Launch', + start: { year: 2026, month: 8, day: 2, isUtc: true }, + end: null, + }, + }, + { + type: 'TYPE_DRIVER_LICENSE', + data: { documentType: 'DL', licenseNumber: 'D1234567', gender: 'F' }, + }, +]; + +describe('mapStaticBarcodeResult', () => { + it.each(validParsedValues)('maps the valid $type parsed value', (value) => { + expect(mapStaticBarcodeResult(resultWithValue(value))).toEqual({ + barcodes: [ + { + ...barcode, + rawValue: null, + displayValue: null, + rawBytes: null, + value, + }, + ], + } satisfies BarcodeScanningResult); + }); + + it.each([ + ['a Wi-Fi string field', { type: 'TYPE_WIFI', data: { ssid: 7 } }], + [ + 'a calendar date-time field', + { type: 'TYPE_CALENDAR_EVENT', data: { start: { year: '2026' } } }, + ], + [ + 'a contact name field', + { type: 'TYPE_CONTACT_INFO', data: { name: { first: 7 } } }, + ], + [ + 'a contact phone field', + { type: 'TYPE_CONTACT_INFO', data: { phones: [{ number: 7 }] } }, + ], + [ + 'a contact email field', + { type: 'TYPE_CONTACT_INFO', data: { emails: [{ address: 7 }] } }, + ], + [ + 'a contact address field', + { + type: 'TYPE_CONTACT_INFO', + data: { addresses: [{ addressLines: ['1 Logic Lane', 7] }] }, + }, + ], + ])('throws for %s with the wrong type', (_description, value) => { + expect(() => mapStaticBarcodeResult(resultWithValue(value))).toThrow( + parsedValueError + ); + }); + + it.each([ + [ + 'a type/data mismatch', + { type: 'TYPE_WIFI', data: { text: 'not Wi-Fi data' } }, + ], + ['an unknown discriminator', { type: 'TYPE_CUSTOM', data: {} }], + ['a non-record payload', { type: 'TYPE_WIFI', data: null }], + ['a non-string discriminator', { type: { name: 'TYPE_WIFI' }, data: {} }], + ])('throws for %s', (_description, value) => { + expect(() => mapStaticBarcodeResult(resultWithValue(value))).toThrow( + parsedValueError + ); + }); + + it('leaves an absent parsed value absent', () => { + expect(mapStaticBarcodeResult({ barcodes: [{ ...barcode }] })).toEqual({ + barcodes: [ + { + ...barcode, + rawValue: null, + displayValue: null, + rawBytes: null, + }, + ], + }); + }); + + it('normalizes explicitly undefined static fields to the public null shape', () => { + const result: BarcodeScannerResult = { + barcodes: [{ ...barcode, rawValue: undefined, displayValue: undefined }], + }; + + expect(mapStaticBarcodeResult(result)).toEqual({ + barcodes: [ + { + ...barcode, + rawValue: null, + displayValue: null, + rawBytes: null, + }, + ], + }); + }); +}); diff --git a/src/features/barcode-scanning/mapStaticBarcodeResult.ts b/src/features/barcode-scanning/mapStaticBarcodeResult.ts new file mode 100644 index 0000000..8cf176a --- /dev/null +++ b/src/features/barcode-scanning/mapStaticBarcodeResult.ts @@ -0,0 +1,294 @@ +import type { + BarcodeAddressData, + BarcodeCalendarDateTime, + BarcodeCalendarEventData, + BarcodeContactInfoData, + BarcodeData, + BarcodeDriverLicenseData, + BarcodeEmailData, + BarcodeGeoData, + BarcodeIsbnData, + BarcodeParsedValue, + BarcodePersonName, + BarcodePhoneData, + BarcodeProductData, + BarcodeScanningResult, + BarcodeSmsData, + BarcodeTextData, + BarcodeUnknownData, + BarcodeUrlData, + BarcodeWifiData, +} from './types'; +import type { + BarcodeScannerBarcode, + BarcodeScannerResult, +} from '../../specs/BarcodeScannerTypes'; + +const parsedValueError = 'Invalid barcode parsed value'; + +type ValueValidator = (value: unknown) => boolean; + +const isRecord = (value: unknown): value is Record => + typeof value === 'object' && value !== null && !Array.isArray(value); + +const isNullableString: ValueValidator = (value) => + value === null || typeof value === 'string'; + +const isNullableNumber: ValueValidator = (value) => + value === null || typeof value === 'number'; + +const isNullableBoolean: ValueValidator = (value) => + value === null || typeof value === 'boolean'; + +const isNullableStringOrNumber: ValueValidator = (value) => + value === null || typeof value === 'string' || typeof value === 'number'; + +const isOptional = + (validator: ValueValidator): ValueValidator => + (value) => + value === undefined || validator(value); + +const isNullableRecord = + (validator: ValueValidator): ValueValidator => + (value) => + value === null || validator(value); + +const isArrayOf = + (validator: ValueValidator): ValueValidator => + (value) => + Array.isArray(value) && value.every(validator); + +const hasValidProperties = ( + value: Record, + validators: Record +): boolean => + Object.keys(value).every((key) => { + const validator = validators[key]; + return validator !== undefined && validator(value[key]); + }); + +const hasSchema = ( + value: unknown, + validators: Record +): value is Record => + isRecord(value) && hasValidProperties(value, validators); + +const isStringArray = isArrayOf((value) => typeof value === 'string'); + +const isCalendarDateTime = (value: unknown): value is BarcodeCalendarDateTime => + hasSchema(value, { + year: isOptional(isNullableNumber), + month: isOptional(isNullableNumber), + day: isOptional(isNullableNumber), + hours: isOptional(isNullableNumber), + minutes: isOptional(isNullableNumber), + seconds: isOptional(isNullableNumber), + isUtc: isOptional(isNullableBoolean), + rawValue: isOptional(isNullableString), + }); + +const isPersonName = (value: unknown): value is BarcodePersonName => + hasSchema(value, { + formattedName: isOptional(isNullableString), + pronunciation: isOptional(isNullableString), + prefix: isOptional(isNullableString), + first: isOptional(isNullableString), + middle: isOptional(isNullableString), + last: isOptional(isNullableString), + suffix: isOptional(isNullableString), + }); + +const isPhoneData = (value: unknown): value is BarcodePhoneData => + hasSchema(value, { + number: isOptional(isNullableString), + type: isOptional(isNullableStringOrNumber), + typeName: isOptional(isNullableString), + }); + +const isEmailData = (value: unknown): value is BarcodeEmailData => + hasSchema(value, { + address: isOptional(isNullableString), + subject: isOptional(isNullableString), + body: isOptional(isNullableString), + type: isOptional(isNullableStringOrNumber), + typeName: isOptional(isNullableString), + }); + +const isAddressData = (value: unknown): value is BarcodeAddressData => + hasSchema(value, { + addressLines: isOptional(isNullableRecord(isStringArray)), + type: isOptional(isNullableStringOrNumber), + typeName: isOptional(isNullableString), + }); + +const isWifiData = (value: unknown): value is BarcodeWifiData => + hasSchema(value, { + ssid: isOptional(isNullableString), + password: isOptional(isNullableString), + encryptionType: isOptional(isNullableNumber), + encryptionTypeName: isOptional(isNullableString), + type: isOptional(isNullableStringOrNumber), + typeName: isOptional(isNullableString), + }); + +const isUrlData = (value: unknown): value is BarcodeUrlData => + hasSchema(value, { + title: isOptional(isNullableString), + url: isOptional(isNullableString), + }); + +const isSmsData = (value: unknown): value is BarcodeSmsData => + hasSchema(value, { + message: isOptional(isNullableString), + phoneNumber: isOptional(isNullableString), + }); + +const isGeoData = (value: unknown): value is BarcodeGeoData => + hasSchema(value, { + lat: isOptional(isNullableNumber), + lng: isOptional(isNullableNumber), + }); + +const isCalendarEventData = ( + value: unknown +): value is BarcodeCalendarEventData => + hasSchema(value, { + summary: isOptional(isNullableString), + description: isOptional(isNullableString), + location: isOptional(isNullableString), + organizer: isOptional(isNullableString), + status: isOptional(isNullableString), + start: isOptional(isNullableRecord(isCalendarDateTime)), + end: isOptional(isNullableRecord(isCalendarDateTime)), + }); + +const isContactInfoData = (value: unknown): value is BarcodeContactInfoData => + hasSchema(value, { + name: isOptional(isNullableRecord(isPersonName)), + organization: isOptional(isNullableString), + title: isOptional(isNullableString), + phones: isOptional(isNullableRecord(isArrayOf(isPhoneData))), + emails: isOptional(isNullableRecord(isArrayOf(isEmailData))), + addresses: isOptional(isNullableRecord(isArrayOf(isAddressData))), + urls: isOptional(isNullableRecord(isStringArray)), + }); + +const isDriverLicenseData = ( + value: unknown +): value is BarcodeDriverLicenseData => + hasSchema(value, { + documentType: isOptional(isNullableString), + licenseNumber: isOptional(isNullableString), + firstName: isOptional(isNullableString), + middleName: isOptional(isNullableString), + lastName: isOptional(isNullableString), + gender: isOptional(isNullableStringOrNumber), + addressStreet: isOptional(isNullableString), + addressCity: isOptional(isNullableString), + addressState: isOptional(isNullableString), + addressZip: isOptional(isNullableString), + birthDate: isOptional(isNullableString), + issueDate: isOptional(isNullableString), + expiryDate: isOptional(isNullableString), + issuingCountry: isOptional(isNullableString), + }); + +const isTextData = (value: unknown): value is BarcodeTextData => + hasSchema(value, { text: isOptional(isNullableString) }); + +const isProductData = (value: unknown): value is BarcodeProductData => + hasSchema(value, { product: isOptional(isNullableString) }); + +const isIsbnData = (value: unknown): value is BarcodeIsbnData => + hasSchema(value, { isbn: isOptional(isNullableString) }); + +const isUnknownData = (value: unknown): value is BarcodeUnknownData => + hasSchema(value, { rawValue: isOptional(isNullableString) }); + +const invalidParsedValue = (): never => { + throw new Error(parsedValueError); +}; + +const mapParsedValue = (value: unknown): BarcodeParsedValue => { + if (!isRecord(value) || !isRecord(value.data)) { + return invalidParsedValue(); + } + + switch (value.type) { + case 'TYPE_WIFI': + return isWifiData(value.data) + ? { type: 'TYPE_WIFI', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_URL': + return isUrlData(value.data) + ? { type: 'TYPE_URL', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_SMS': + return isSmsData(value.data) + ? { type: 'TYPE_SMS', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_EMAIL': + return isEmailData(value.data) + ? { type: 'TYPE_EMAIL', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_PHONE': + return isPhoneData(value.data) + ? { type: 'TYPE_PHONE', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_GEO': + return isGeoData(value.data) + ? { type: 'TYPE_GEO', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_CALENDAR_EVENT': + return isCalendarEventData(value.data) + ? { type: 'TYPE_CALENDAR_EVENT', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_CONTACT_INFO': + return isContactInfoData(value.data) + ? { type: 'TYPE_CONTACT_INFO', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_DRIVER_LICENSE': + return isDriverLicenseData(value.data) + ? { type: 'TYPE_DRIVER_LICENSE', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_TEXT': + return isTextData(value.data) + ? { type: 'TYPE_TEXT', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_PRODUCT': + return isProductData(value.data) + ? { type: 'TYPE_PRODUCT', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_ISBN': + return isIsbnData(value.data) + ? { type: 'TYPE_ISBN', data: { ...value.data } } + : invalidParsedValue(); + case 'TYPE_UNKNOWN': + return isUnknownData(value.data) + ? { type: 'TYPE_UNKNOWN', data: { ...value.data } } + : invalidParsedValue(); + default: + return invalidParsedValue(); + } +}; + +const mapStaticBarcode = (barcode: BarcodeScannerBarcode): BarcodeData => { + const { value, ...barcodeData } = barcode; + + return { + ...barcodeData, + rawValue: barcode.rawValue ?? null, + displayValue: barcode.displayValue ?? null, + rawBytes: barcode.rawBytes ?? null, + ...(value === undefined ? {} : { value: mapParsedValue(value) }), + }; +}; + +/** + * Converts the codegen-safe static Nitro result to the public barcode result. + */ +export const mapStaticBarcodeResult = ( + result: BarcodeScannerResult +): BarcodeScanningResult => ({ + barcodes: result.barcodes.map(mapStaticBarcode), +}); diff --git a/src/features/barcode-scanning/types.ts b/src/features/barcode-scanning/types.ts new file mode 100644 index 0000000..c854489 --- /dev/null +++ b/src/features/barcode-scanning/types.ts @@ -0,0 +1,277 @@ +import type { + BoundingBox, + Corner, + ImageProcessingBaseOptions, + MLKitBaseArguments, + MLKitBaseOptions, +} from '../../core/types'; + +export type BarcodeFormat = + | 'UNKNOWN' + | 'ALL_FORMATS' + | 'CODE_128' + | 'CODE_39' + | 'CODE_93' + | 'CODABAR' + | 'DATA_MATRIX' + | 'EAN_13' + | 'EAN_8' + | 'ITF' + | 'QR_CODE' + | 'UPC_A' + | 'UPC_E' + | 'PDF417' + | 'AZTEC'; + +export type BarcodeScanningOptions = MLKitBaseOptions & { + /** Restrict detected barcode formats for better performance. */ + formats?: BarcodeFormat[]; + /** + * Android only: include potential barcodes that could not be decoded yet. + * For potential barcodes, `rawValue` and `rawBytes` may be null. + */ + enableAllPotentialBarcodes?: boolean; +}; + +export type BarcodeScanningImageOptions = ImageProcessingBaseOptions & { + /** Restrict detected barcode formats for better performance. */ + formats?: BarcodeFormat[]; + /** + * Android only: include potential barcodes that could not be decoded yet. + * For potential barcodes, `rawValue` and `rawBytes` may be null. + */ + enableAllPotentialBarcodes?: boolean; +}; + +export type BarcodeScanningArguments = MLKitBaseArguments & {}; + +export type BarcodeScanningResult = { + barcodes: BarcodeData[]; +}; + +export type BarcodeData = { + bounds?: BoundingBox; + corners?: Corner[]; + format: number; + formatName: BarcodeFormat; + valueType: number; + valueTypeName: BarcodeValueTypeName; + rawValue: string | null; + displayValue: string | null; + rawBytes?: number[] | null; + isPotential: boolean; + value?: BarcodeParsedValue; +}; + +export type BarcodeValueTypeName = + | 'TYPE_UNKNOWN' + | 'TYPE_CONTACT_INFO' + | 'TYPE_EMAIL' + | 'TYPE_ISBN' + | 'TYPE_PHONE' + | 'TYPE_PRODUCT' + | 'TYPE_SMS' + | 'TYPE_TEXT' + | 'TYPE_URL' + | 'TYPE_WIFI' + | 'TYPE_GEO' + | 'TYPE_CALENDAR_EVENT' + | 'TYPE_DRIVER_LICENSE'; + +export type BarcodeCalendarDateTime = { + year?: number | null; + month?: number | null; + day?: number | null; + hours?: number | null; + minutes?: number | null; + seconds?: number | null; + isUtc?: boolean | null; + rawValue?: string | null; +}; + +export type BarcodePersonName = { + formattedName?: string | null; + pronunciation?: string | null; + prefix?: string | null; + first?: string | null; + middle?: string | null; + last?: string | null; + suffix?: string | null; +}; + +export type BarcodePhoneData = { + number?: string | null; + type?: number | string | null; + typeName?: string | null; +}; + +export type BarcodeEmailData = { + address?: string | null; + subject?: string | null; + body?: string | null; + type?: number | string | null; + typeName?: string | null; +}; + +export type BarcodeAddressData = { + addressLines?: string[] | null; + type?: number | string | null; + typeName?: string | null; +}; + +export type BarcodeWifiData = { + ssid?: string | null; + password?: string | null; + encryptionType?: number | null; + encryptionTypeName?: string | null; + type?: number | string | null; + typeName?: string | null; +}; + +export type BarcodeUrlData = { + title?: string | null; + url?: string | null; +}; + +export type BarcodeSmsData = { + message?: string | null; + phoneNumber?: string | null; +}; + +export type BarcodeGeoData = { + lat?: number | null; + lng?: number | null; +}; + +export type BarcodeCalendarEventData = { + summary?: string | null; + description?: string | null; + location?: string | null; + organizer?: string | null; + status?: string | null; + start?: BarcodeCalendarDateTime | null; + end?: BarcodeCalendarDateTime | null; +}; + +export type BarcodeContactInfoData = { + name?: BarcodePersonName | null; + organization?: string | null; + title?: string | null; + phones?: BarcodePhoneData[] | null; + emails?: BarcodeEmailData[] | null; + addresses?: BarcodeAddressData[] | null; + urls?: string[] | null; +}; + +export type BarcodeDriverLicenseData = { + documentType?: string | null; + licenseNumber?: string | null; + firstName?: string | null; + middleName?: string | null; + lastName?: string | null; + gender?: string | number | null; + addressStreet?: string | null; + addressCity?: string | null; + addressState?: string | null; + addressZip?: string | null; + birthDate?: string | null; + issueDate?: string | null; + expiryDate?: string | null; + issuingCountry?: string | null; +}; + +export type BarcodeTextData = { + text?: string | null; +}; + +export type BarcodeProductData = { + product?: string | null; +}; + +export type BarcodeIsbnData = { + isbn?: string | null; +}; + +export type BarcodeUnknownData = { + rawValue?: string | null; +}; + +export type BarcodeWifiParsedValue = { + type: 'TYPE_WIFI'; + data: BarcodeWifiData; +}; + +export type BarcodeUrlParsedValue = { + type: 'TYPE_URL'; + data: BarcodeUrlData; +}; + +export type BarcodeSmsParsedValue = { + type: 'TYPE_SMS'; + data: BarcodeSmsData; +}; + +export type BarcodeEmailParsedValue = { + type: 'TYPE_EMAIL'; + data: BarcodeEmailData; +}; + +export type BarcodePhoneParsedValue = { + type: 'TYPE_PHONE'; + data: BarcodePhoneData; +}; + +export type BarcodeGeoParsedValue = { + type: 'TYPE_GEO'; + data: BarcodeGeoData; +}; + +export type BarcodeCalendarParsedValue = { + type: 'TYPE_CALENDAR_EVENT'; + data: BarcodeCalendarEventData; +}; + +export type BarcodeContactParsedValue = { + type: 'TYPE_CONTACT_INFO'; + data: BarcodeContactInfoData; +}; + +export type BarcodeDriverLicenseParsedValue = { + type: 'TYPE_DRIVER_LICENSE'; + data: BarcodeDriverLicenseData; +}; + +export type BarcodeTextParsedValue = { + type: 'TYPE_TEXT'; + data: BarcodeTextData; +}; + +export type BarcodeProductParsedValue = { + type: 'TYPE_PRODUCT'; + data: BarcodeProductData; +}; + +export type BarcodeIsbnParsedValue = { + type: 'TYPE_ISBN'; + data: BarcodeIsbnData; +}; + +export type BarcodeUnknownParsedValue = { + type: 'TYPE_UNKNOWN'; + data: BarcodeUnknownData; +}; + +export type BarcodeParsedValue = + | BarcodeWifiParsedValue + | BarcodeUrlParsedValue + | BarcodeSmsParsedValue + | BarcodeEmailParsedValue + | BarcodePhoneParsedValue + | BarcodeGeoParsedValue + | BarcodeCalendarParsedValue + | BarcodeContactParsedValue + | BarcodeDriverLicenseParsedValue + | BarcodeTextParsedValue + | BarcodeProductParsedValue + | BarcodeIsbnParsedValue + | BarcodeUnknownParsedValue; diff --git a/src/features/text-recognition/index.ts b/src/features/text-recognition/index.ts index af698d7..726efe6 100644 --- a/src/features/text-recognition/index.ts +++ b/src/features/text-recognition/index.ts @@ -1,7 +1,10 @@ +import { useMemo } from 'react'; import type { Frame } from 'react-native-vision-camera'; -import { NativeBridge } from '../../core/NativeBridge'; import { MLKIT_FEATURE_KEYS } from '../../core/constants'; +import { normalizeImageUri } from '../../core/normalizeImageUri'; +import { PluginFactory } from '../../core/PluginFactory'; import { useMLKitPlugin } from '../../hooks/useMLKitPlugin'; +import type { TextRecognizer } from '../../specs/TextRecognizer.nitro'; import type { TextRecognitionArguments, TextRecognitionImageOptions, @@ -19,11 +22,16 @@ export const processImageTextRecognition = async ( uri: string, options: TextRecognitionImageOptions = {} ): Promise => { - return await NativeBridge.processImage( + const recognizer = PluginFactory.initPlugin( MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, - uri, options - ); + ) as TextRecognizer; + + try { + return await recognizer.recognizeImage(normalizeImageUri(uri)); + } finally { + recognizer.dispose(); + } }; /** @@ -32,17 +40,23 @@ export const processImageTextRecognition = async ( * @returns Plugin object with textRecognition method. */ export const useTextRecognition = (options: TextRecognitionOptions = {}) => { - const plugin = useMLKitPlugin(MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, options); + const plugin = useMLKitPlugin( + MLKIT_FEATURE_KEYS.TEXT_RECOGNITION, + options + ); - return { - textRecognition: ( - frame: Frame, - args?: TextRecognitionArguments - ): TextRecognitionResult => { - 'worklet'; - return plugin.recognize(frame, args); - }, - }; + return useMemo( + () => ({ + textRecognition: ( + frame: Frame, + args?: TextRecognitionArguments + ): TextRecognitionResult => { + 'worklet'; + return plugin.recognize(frame, args ?? {}); + }, + }), + [plugin] + ); }; export type { diff --git a/src/hooks/useMLKitPlugin.ts b/src/hooks/useMLKitPlugin.ts index 77439ab..08b08a2 100644 --- a/src/hooks/useMLKitPlugin.ts +++ b/src/hooks/useMLKitPlugin.ts @@ -1,34 +1,27 @@ import { useMemo } from 'react'; -import type { Frame } from 'react-native-vision-camera'; import { PluginFactory } from '../core/PluginFactory'; -import type { - MLKitBaseArguments, - MLKitBaseOptions, - MLKitFeature, -} from '../core/types'; - -export interface MLKitPlugin { - recognize: (frame: Frame, args?: MLKitBaseArguments) => any; -} +import type { MLKitBaseOptions, MLKitFeature } from '../core/types'; /** - * Generic hook to create and use any MLKit frame processor plugin. + * Generic hook to create any MLKit frame processor plugin. + * + * Returns the native `HybridObject` directly (memoized) rather than a + * JS-level wrapper, so callers can invoke its `recognize` method from a + * single Worklet closure. Wrapping it in an extra `'worklet'` function + * here would create a worklet-closing-over-a-worklet chain that does not + * reliably survive being shared into a different Worklet Runtime (e.g. + * via `useAsyncRunner`'s native-thread-backed runtime). + * @template T - The concrete HybridObject type for the requested feature. * @param {MLKitFeature} feature - The MLKit feature to use. * @param {MLKitBaseOptions} options - Options for the plugin. - * @returns {MLKitPlugin} An object with a recognize method for processing frames. + * @returns The native MLKit plugin HybridObject. */ -export const useMLKitPlugin = ( +export const useMLKitPlugin = ( feature: MLKitFeature, options: MLKitBaseOptions = {} -): MLKitPlugin => { - return useMemo(() => { - const plugin = PluginFactory.initPlugin(feature, options); - - return { - recognize: (frame: Frame, args?: MLKitBaseArguments): any => { - 'worklet'; - return plugin.call(frame, args ?? {}); - }, - }; - }, [feature, options]); +): T => { + return useMemo( + () => PluginFactory.initPlugin(feature, options) as T, + [feature, options] + ); }; diff --git a/src/index.ts b/src/index.ts index 182f296..8774457 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ import { PluginFactory } from './core/PluginFactory'; +export { VisionCameraMLKit } from './core/VisionCameraMLKit'; + export const getFeatureErrorMessage = PluginFactory.getFeatureErrorMessage; export const isFeatureAvailable = PluginFactory.isFeatureAvailable; export const assertFeatureAvailable = PluginFactory.assertFeatureAvailable; @@ -23,6 +25,22 @@ export { type MLKitBaseOptions, type MLKitFeature, type Orientation, + type RegionOfInterest, + type RegionOfInterestUnit, } from './core/types'; +export type { BarcodeScanner } from './specs/BarcodeScanner.nitro'; +export type { + BarcodeScannerBarcode, + BarcodeScannerResult, +} from './specs/BarcodeScannerTypes'; +export type { + BarcodeScannerOptions, + MLKitRecognizerOptions, + TextRecognizerOptions, +} from './specs/MLKitVisionTypes'; +export type { TextRecognizer } from './specs/TextRecognizer.nitro'; +export type { VisionCameraMLKit as VisionCameraMLKitSpec } from './specs/VisionCameraMLKit.nitro'; + +export * from './features/barcode-scanning'; export * from './features/text-recognition'; diff --git a/src/shared/constants.ts b/src/shared/constants.ts index b94d1ff..1529311 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -1,13 +1,6 @@ -import { Platform } from 'react-native'; import { MLKIT_FEATURE_KEYS } from '../core/constants'; import type { MLKitFeature } from '../core/types'; -export const LINKING_ERROR = - `The package 'react-native-vision-camera-mlkit' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo Go\n'; - const TEXT_RECOGNITION_ERROR = 'Text Recognition feature is not enabled. Please enable it in your Podfile (iOS) or build.gradle (Android) and rebuild your app.'; @@ -65,6 +58,3 @@ export const IMAGE_PROCESSING_FAILED_ERROR = export const UNSUPPORTED_IMAGE_FORMAT_ERROR = 'Unsupported image format. Only JPEG, PNG, and WebP are supported.'; - -export const MISSING_MODULE_ERROR = - 'VisionCameraMLKit native module is not available. Ensure it is linked, pods are installed, and the app was rebuilt.'; diff --git a/src/specs/BarcodeScanner.nitro.ts b/src/specs/BarcodeScanner.nitro.ts new file mode 100644 index 0000000..558526c --- /dev/null +++ b/src/specs/BarcodeScanner.nitro.ts @@ -0,0 +1,25 @@ +import type { HybridObject } from 'react-native-nitro-modules'; +import type { Frame } from 'react-native-vision-camera/lib/specs/instances/Frame.nitro'; +import type { BarcodeScanningArguments } from '../features/barcode-scanning/types'; +import type { BarcodeScannerResult } from './BarcodeScannerTypes'; + +/** + * Scans barcodes from live VisionCamera frames. + * + * @see {@linkcode VisionCameraMLKit.createBarcodeScanner} + */ +export interface BarcodeScanner + extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { + /** + * Runs ML Kit barcode scanning on a single camera frame. + */ + recognize( + frame: Frame, + args?: BarcodeScanningArguments + ): BarcodeScannerResult; + + /** + * Runs ML Kit barcode scanning on a static image URI. + */ + recognizeImage(uri: string): Promise; +} diff --git a/src/specs/BarcodeScannerTypes.ts b/src/specs/BarcodeScannerTypes.ts new file mode 100644 index 0000000..dc3ddf7 --- /dev/null +++ b/src/specs/BarcodeScannerTypes.ts @@ -0,0 +1,77 @@ +import type { BoundingBox, Corner } from '../core/types'; +import type { AnyMap } from 'react-native-nitro-modules'; +import type { + BarcodeFormat, + BarcodeValueTypeName, +} from '../features/barcode-scanning/types'; + +/** + * Codegen-safe barcode data returned by the live Nitro scanner. + */ +export interface BarcodeScannerBarcode { + /** + * Barcode bounds in frame coordinates when available. + */ + bounds?: BoundingBox; + + /** + * Barcode corner points in frame coordinates when available. + */ + corners?: Corner[]; + + /** + * Native ML Kit barcode format integer. + */ + format: number; + + /** + * Named ML Kit barcode format. + */ + formatName: BarcodeFormat; + + /** + * Native ML Kit value type integer. + */ + valueType: number; + + /** + * Named ML Kit value type. + */ + valueTypeName: BarcodeValueTypeName; + + /** + * Raw barcode payload when ML Kit decoded it. + */ + rawValue?: string; + + /** + * Display-ready barcode payload when ML Kit provides one. + */ + displayValue?: string; + + /** + * Raw byte payload when available. + */ + rawBytes?: number[]; + + /** + * Parsed ML Kit barcode payload. This stays untyped at the Nitro boundary + * because its public representation is a discriminated union. + */ + value?: AnyMap; + + /** + * Whether this is an undecoded potential barcode. + */ + isPotential: boolean; +} + +/** + * Codegen-safe live barcode scanning result. + */ +export interface BarcodeScannerResult { + /** + * Barcodes detected in the frame. + */ + barcodes: BarcodeScannerBarcode[]; +} diff --git a/src/specs/MLKitVisionTypes.ts b/src/specs/MLKitVisionTypes.ts new file mode 100644 index 0000000..4ac9d8d --- /dev/null +++ b/src/specs/MLKitVisionTypes.ts @@ -0,0 +1,76 @@ +import type { BarcodeFormat } from '../features/barcode-scanning/types'; +import type { TextRecognitionLanguage } from '../features/text-recognition/types'; +import type { Orientation, RegionOfInterest } from '../core/types'; + +/** + * ML Kit features that can be compiled into this package. + */ +export type MLKitFeature = + | 'TextRecognition' + | 'FaceDetection' + | 'FaceMeshDetection' + | 'PoseDetection' + | 'SelfieSegmentation' + | 'SubjectSegmentation' + | 'DocumentScanner' + | 'BarcodeScanning' + | 'ImageLabeling' + | 'ObjectDetection' + | 'DigitalInkRecognition'; + +/** + * Shared options for live frame recognizers. + */ +export interface MLKitRecognizerOptions { + /** + * Optional image downscaling for performance optimization. + */ + scaleFactor?: number; + + /** + * Invert colors before processing. + */ + invertColors?: boolean; + + /** + * Legacy frame skipping option kept for compatibility while v5 examples use frame output throttling. + */ + frameProcessInterval?: number; + + /** + * Crop processing to a rectangular region of the frame before running + * ML Kit, to reduce CPU/GPU work. Result coordinates are mapped back to + * full source frame coordinates. + */ + roi?: RegionOfInterest; + + /** + * Override the source image orientation when recognizing a static image. + */ + orientation?: Orientation; +} + +/** + * Options for creating a configured text recognizer. + */ +export interface TextRecognizerOptions extends MLKitRecognizerOptions { + /** + * Language model used by ML Kit text recognition. + */ + language?: TextRecognitionLanguage; +} + +/** + * Options for creating a configured barcode scanner. + */ +export interface BarcodeScannerOptions extends MLKitRecognizerOptions { + /** + * Restricts detected barcode formats. + */ + formats?: BarcodeFormat[]; + + /** + * Android-only option for returning potential barcodes. + */ + enableAllPotentialBarcodes?: boolean; +} diff --git a/src/specs/TextRecognizer.nitro.ts b/src/specs/TextRecognizer.nitro.ts new file mode 100644 index 0000000..623d2d9 --- /dev/null +++ b/src/specs/TextRecognizer.nitro.ts @@ -0,0 +1,27 @@ +import type { HybridObject } from 'react-native-nitro-modules'; +import type { Frame } from 'react-native-vision-camera/lib/specs/instances/Frame.nitro'; +import type { + TextRecognitionArguments, + TextRecognitionResult, +} from '../features/text-recognition/types'; + +/** + * Recognizes text from live VisionCamera frames. + * + * @see {@linkcode VisionCameraMLKit.createTextRecognizer} + */ +export interface TextRecognizer + extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { + /** + * Runs ML Kit text recognition on a single camera frame. + */ + recognize( + frame: Frame, + args?: TextRecognitionArguments + ): TextRecognitionResult; + + /** + * Runs ML Kit text recognition on a static image URI. + */ + recognizeImage(uri: string): Promise; +} diff --git a/src/specs/VisionCameraMLKit.nitro.ts b/src/specs/VisionCameraMLKit.nitro.ts new file mode 100644 index 0000000..8f262c0 --- /dev/null +++ b/src/specs/VisionCameraMLKit.nitro.ts @@ -0,0 +1,29 @@ +import type { HybridObject } from 'react-native-nitro-modules'; +import type { BarcodeScanner } from './BarcodeScanner.nitro'; +import type { + BarcodeScannerOptions, + MLKitFeature, + TextRecognizerOptions, +} from './MLKitVisionTypes'; +import type { TextRecognizer } from './TextRecognizer.nitro'; + +/** + * Root factory for ML Kit recognizers backed by VisionCamera v5 Nitro frames. + */ +export interface VisionCameraMLKit + extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { + /** + * Returns whether a feature was compiled into the native package. + */ + isFeatureAvailable(feature: MLKitFeature): boolean; + + /** + * Creates a configured text recognizer. + */ + createTextRecognizer(options: TextRecognizerOptions): TextRecognizer; + + /** + * Creates a configured barcode scanner. + */ + createBarcodeScanner(options: BarcodeScannerOptions): BarcodeScanner; +} diff --git a/turbo.json b/turbo.json index c4d78c4..a52d06e 100644 --- a/turbo.json +++ b/turbo.json @@ -23,7 +23,8 @@ "env": [ "RCT_NEW_ARCH_ENABLED", "RCT_USE_RN_DEP", - "RCT_USE_PREBUILT_RNCORE" + "RCT_USE_PREBUILT_RNCORE", + "IOS_DESTINATION" ], "inputs": [ "package.json", diff --git a/yarn.lock b/yarn.lock index 1bba5fc..6db7427 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,23 +5,23 @@ __metadata: version: 8 cacheKey: 10c0 -"@ark/schema@npm:0.56.0": - version: 0.56.0 - resolution: "@ark/schema@npm:0.56.0" +"@ark/schema@npm:0.56.2": + version: 0.56.2 + resolution: "@ark/schema@npm:0.56.2" dependencies: - "@ark/util": "npm:0.56.0" - checksum: 10c0/89fb7e4e1304ea9b34c834a8cb34bc05201b4e3a1b26277f7d74b9505a2d7ed398bb55a77e491e7a14a7f0807424a5467e1d32ee725ee2f7b9d158ae30d8121a + "@ark/util": "npm:0.56.2" + checksum: 10c0/0825c34969dcf3ff199a50b663eb792469f1c78b45f7dea565b2101fda9ab4e91eb5e088e0a5b6a667a05ddd1cc8b1bcbd6369ab2337655c40e680022fa00892 languageName: node linkType: hard -"@ark/util@npm:0.56.0": - version: 0.56.0 - resolution: "@ark/util@npm:0.56.0" - checksum: 10c0/dfef779c90f9f814ba97069c63bf91fa67569b87c5cd925d0e2d96b91aa677c019ed1dd5ff95332d9bb0598f785057439074b8cbfcaa2578770616e260fc5761 +"@ark/util@npm:0.56.2": + version: 0.56.2 + resolution: "@ark/util@npm:0.56.2" + checksum: 10c0/dc5757fa7281ec2f202c7b6df8ff3bb154ee6a027eb5c69e7bbc30596fe7385109347c6124bee1e9c3a30c8def3dee7aaaa963103abd4c91dfb4bb1433a537ca languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.27.1": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.27.1": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" dependencies: @@ -32,13 +32,31 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.5": +"@babel/code-frame@npm:^7.20.0, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/code-frame@npm:7.29.7" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.29.7" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/169fc2080169a40c1760155eaaaf739bcb882df0bec76a83adbda5493645bc17270a3434b8848c494b1933e96fe1d147370001e3cda09a39f43ae30f08ef2069 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.28.5": version: 7.28.5 resolution: "@babel/compat-data@npm:7.28.5" checksum: 10c0/702a25de73087b0eba325c1d10979eed7c9b6662677386ba7b5aa6eace0fc0676f78343bae080a0176ae26f58bd5535d73b9d0fbb547fef377692e8b249353a7 languageName: node linkType: hard +"@babel/compat-data@npm:^7.28.6, @babel/compat-data@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/compat-data@npm:7.29.7" + checksum: 10c0/47913f05e08a45a1c9df38c02b4b49e391005085b489432647a1abe112e5d9c75e3be8ea5972b7f6da4ec5d1339922ceb9ea02b8a25d4ed1cb8636e5261f344e + languageName: node + linkType: hard + "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.25.2": version: 7.28.5 resolution: "@babel/core@npm:7.28.5" @@ -62,6 +80,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.24.4": + version: 7.29.7 + resolution: "@babel/core@npm:7.29.7" + dependencies: + "@babel/code-frame": "npm:^7.29.7" + "@babel/generator": "npm:^7.29.7" + "@babel/helper-compilation-targets": "npm:^7.29.7" + "@babel/helper-module-transforms": "npm:^7.29.7" + "@babel/helpers": "npm:^7.29.7" + "@babel/parser": "npm:^7.29.7" + "@babel/template": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/112fb09c24de7a1de64d1de2c31fe65c4e6af4cb2fb6e6d99ea5373e6fc51e75b88581c0efae4c4c68f119a02a988c7106e95011a41530a2fb8ed793c7eaa07b + languageName: node + linkType: hard + "@babel/eslint-parser@npm:^7.25.1": version: 7.28.5 resolution: "@babel/eslint-parser@npm:7.28.5" @@ -76,7 +117,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.28.5, @babel/generator@npm:^7.7.2": +"@babel/generator@npm:^7.28.5, @babel/generator@npm:^7.7.2": version: 7.28.5 resolution: "@babel/generator@npm:7.28.5" dependencies: @@ -89,6 +130,32 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.29.1, @babel/generator@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/generator@npm:7.29.7" + dependencies: + "@babel/parser": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/9bf72b01b5bd0ea5b1288a0e37dbd360bff2f2b1ce73342c0d40fb3db2ec3dc004ada5ffa925c5e12939a416eed59e600d562b8ecd938ce0d27dfd0eb6c6c2b7 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.29.8": + version: 7.29.8 + resolution: "@babel/generator@npm:7.29.8" + dependencies: + "@babel/parser": "npm:^7.29.8" + "@babel/types": "npm:^7.29.8" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/7b896696314a659652393b76d78276e236acd0f7fae40a9a1af7f01c76aeafc630dd0966aad6f9386d35d7c674a8e6e2d8e217c44d25fb11460e68afa9ba8441 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" @@ -98,6 +165,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.29.7" + dependencies: + "@babel/types": "npm:^7.29.7" + checksum: 10c0/c56536b52d17632d89d49db2063ed6102f0e3bbadf6a0ccb74e6599d6a77173b644c7fe8c3ef17c7a162709d55b75ee5145ef6db917d16ba7f375fbffcf2e942 + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": version: 7.27.2 resolution: "@babel/helper-compilation-targets@npm:7.27.2" @@ -111,6 +187,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.28.6, @babel/helper-compilation-targets@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-compilation-targets@npm:7.29.7" + dependencies: + "@babel/compat-data": "npm:^7.29.7" + "@babel/helper-validator-option": "npm:^7.29.7" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/4c15fd4c69a0a7047799a28a88460c19cede0a0ee8af994ea169114986f4af48b92c7393a4a3fee0456c11a656eece3448a6ed06354453d6c27cccf17195453b + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3, @babel/helper-create-class-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" @@ -128,6 +217,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-create-class-features-plugin@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-member-expression-to-functions": "npm:^7.29.7" + "@babel/helper-optimise-call-expression": "npm:^7.29.7" + "@babel/helper-replace-supers": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/75f34905b5e708b473f1e9b33e07b2fcc8f4c60676df8bc74541bb91c77f387c32a948dd04d5071e469ba454d72d0a872e3ace40fbb1d1e7aaa8569efcf09ed4 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": version: 7.28.5 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" @@ -156,6 +262,21 @@ __metadata: languageName: node linkType: hard +"@babel/helper-define-polyfill-provider@npm:^0.6.8": + version: 0.6.8 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.8" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + debug: "npm:^4.4.3" + lodash.debounce: "npm:^4.0.8" + resolve: "npm:^1.22.11" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10c0/306a169f2cb285f368578219ef18ea9702860d3d02d64334f8d45ea38648be0b9e1edad8c8f732fa34bb4206ccbb9883c395570fd57ab7bbcf293bc5964c5b3a + languageName: node + linkType: hard + "@babel/helper-globals@npm:^7.28.0": version: 7.28.0 resolution: "@babel/helper-globals@npm:7.28.0" @@ -163,6 +284,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-globals@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-globals@npm:7.29.7" + checksum: 10c0/f38417c40b1129a1b2b519ca961b9040c8827d1444fd74068702286b91b77089431dc76b6b9d5c1496e5da2a4f3ad329c6946e688ba3fa0d1d0b3d2b4f34f36a + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.27.1, @babel/helper-member-expression-to-functions@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5" @@ -173,6 +301,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-member-expression-to-functions@npm:7.29.7" + dependencies: + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/eef7940ce0797208854a5af1049a98fee9abbffb5c619640c69ff5a555f8e3552295bb18756490b02bc6af7df8c1babcb83f12203aac2deb9dfecfc78846e12d + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" @@ -183,6 +321,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-module-imports@npm:7.29.7" + dependencies: + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/6adf60d97356027413342a092f818d9678c4f5caff716a33e3284b5ae14e47a9e88059d421dde4ee4894691260039a12602c0e7becadc175602194b40dfa345d + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": version: 7.28.3 resolution: "@babel/helper-module-transforms@npm:7.28.3" @@ -196,6 +344,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-module-transforms@npm:7.29.7" + dependencies: + "@babel/helper-module-imports": "npm:^7.29.7" + "@babel/helper-validator-identifier": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/ee5a2172c24a42be696836f4b0d947489c9729d8adf5821885cf77d1ad5333e3c447368e9a71f67df1099570490553dccf9f888ef0a92a48aa63cb086bd8c7e1 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" @@ -205,6 +366,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.29.7" + dependencies: + "@babel/types": "npm:^7.29.7" + checksum: 10c0/fd0244b9bfbb487db02d59aa2703c6991d654ea5f3f39d912682842bdca2e87b5ae8643b0ce8069bf5fbee39d1aa9db7abefeb5e6ba1aa650dca12777cf5b7e2 + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.27.1 resolution: "@babel/helper-plugin-utils@npm:7.27.1" @@ -212,6 +382,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-plugin-utils@npm:7.29.7" + checksum: 10c0/380477a06133274a2759f9355929cb60a95e8b8fee624a1ae1fa349e1d1645b89daca456f72833f6d1062bffa12ee4271c5bf0cc5a61c0166cdc24c7591e2408 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" @@ -238,6 +415,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-replace-supers@npm:7.29.7" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.29.7" + "@babel/helper-optimise-call-expression": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/1c7ae37797f226e965ab85f6affa53d25a10c169c604a4daeb36f9df09e673471e6522f631c13761cf9fbafeca2ea14c241dea8d723a51039d561beb01d86ac4 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -248,6 +438,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.29.7" + dependencies: + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/8c59493621487fc491f27adfc200af82a6aca3b9a5511e4e6050f8716593b4b243472cb56c8d2016e828b7ae12d605a819205aa8600ca08ee291dcd58d65c832 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-string-parser@npm:7.27.1" @@ -255,6 +455,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-string-parser@npm:7.29.7" + checksum: 10c0/194bc0f1716e396d5ffde56ad6119745fb9557662c98611590e5e454906783a4ccb21ce93056b8eb69a4909044834e45d96e50ac695bbe9e3221648fe033c06c + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-validator-identifier@npm:7.28.5" @@ -262,6 +469,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-validator-identifier@npm:7.29.7" + checksum: 10c0/4795354e7ae0dcafa72de1cd04ec51252dc1498517170beaf019e03effc5b7bf13c6b21a3949a77e07b8125be7f106ed1131350d8ebd4566ae874094a726d62b + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-option@npm:7.27.1" @@ -269,6 +483,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-validator-option@npm:7.29.7" + checksum: 10c0/d2a06c6d0ac40ba4a2f219fc2cab249c7a94bacdb2686273b7f9598571c908809b48468ff588915a346e6cc7296f60b581023d1d498b747fed06f779d335c2cc + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.27.1": version: 7.28.3 resolution: "@babel/helper-wrap-function@npm:7.28.3" @@ -290,7 +511,17 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": +"@babel/helpers@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helpers@npm:7.29.7" + dependencies: + "@babel/template": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/218e8d10953647c9f44775f5a022b227a182674853b5ea8631889deb7e1a3e4bc870388aaecf59bb8bd92a87f9a96220ed3f70a35bffec6bcf9169ecb67891ac + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": version: 7.28.5 resolution: "@babel/parser@npm:7.28.5" dependencies: @@ -301,6 +532,28 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.24.4, @babel/parser@npm:^7.29.0, @babel/parser@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/parser@npm:7.29.7" + dependencies: + "@babel/types": "npm:^7.29.7" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/65133038f80b54a714d6027cb77cee3f9a6b5c4c6842ce674301e13947cbcbfa8055e63acaf1b84c085d34226a14425b2c2b97b829e0e226d2e8f1299942a51d + languageName: node + linkType: hard + +"@babel/parser@npm:^7.29.8": + version: 7.29.8 + resolution: "@babel/parser@npm:7.29.8" + dependencies: + "@babel/types": "npm:^7.29.8" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/acc890c5e6a6dd40863a47b50bac111d7185ee6fbbe163ebe11d5214854ca2adb901462ad4d718a65090ef84bd2230e9e8ab45a2e0caccc685f1f57ab0bb1e28 + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.28.5" @@ -512,6 +765,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1736000de183538ba8eef34520105508860e48b0c763254ba9158af5e814ed8bbceeedbb4281fbda33de787ae5b3870e92f60c6ae7131e7d322e451d57387896 + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -611,6 +875,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-syntax-typescript@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c49883b0327e8683b770dc823205af5c697da216e590dcf5bf53f3f031e7e381de450b164f8f99853f0837a3de5cb793298e2be6697a0f6e452bb9dd34b5165e + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -623,7 +898,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:7.27.1, @babel/plugin-transform-arrow-functions@npm:^7.24.7, @babel/plugin-transform-arrow-functions@npm:^7.27.1": +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: @@ -682,7 +957,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:7.27.1, @babel/plugin-transform-class-properties@npm:^7.25.4, @babel/plugin-transform-class-properties@npm:^7.27.1": +"@babel/plugin-transform-class-properties@npm:^7.25.4, @babel/plugin-transform-class-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" dependencies: @@ -694,6 +969,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-class-properties@npm:7.29.7" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c370700423439aa9f0c1f8c4b97f2ef7c2dc46a1b04ec3b10e83e6bae5e4e2159f56d8e4376c9d669b3cf827650cc3740170a36e3924e3e9970d27fd85f4e48a + languageName: node + linkType: hard + "@babel/plugin-transform-class-static-block@npm:^7.28.3": version: 7.28.3 resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" @@ -706,7 +993,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:7.28.4, @babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.28.4": +"@babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.28.4": version: 7.28.4 resolution: "@babel/plugin-transform-classes@npm:7.28.4" dependencies: @@ -722,7 +1009,23 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.7, @babel/plugin-transform-computed-properties@npm:^7.27.1": +"@babel/plugin-transform-classes@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-classes@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-compilation-targets": "npm:^7.29.7" + "@babel/helper-globals": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-replace-supers": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/53a55bc5348d82ca744dbfcfedf33ab79877e609a5308f43976de8c240bd09cee195a535bf54a01b28d7080eebe759735b1c6cf39f252eef469eefc1d838d2a2 + languageName: node + linkType: hard + +"@babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" dependencies: @@ -850,7 +1153,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.1, @babel/plugin-transform-function-name@npm:^7.27.1": +"@babel/plugin-transform-function-name@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-function-name@npm:7.27.1" dependencies: @@ -874,7 +1177,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.2, @babel/plugin-transform-literals@npm:^7.27.1": +"@babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" dependencies: @@ -885,7 +1188,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7, @babel/plugin-transform-logical-assignment-operators@npm:^7.28.5": +"@babel/plugin-transform-logical-assignment-operators@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.5" dependencies: @@ -931,17 +1234,29 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.28.5": - version: 7.28.5 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.28.5" +"@babel/plugin-transform-modules-commonjs@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.29.7" dependencies: - "@babel/helper-module-transforms": "npm:^7.28.3" - "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/helper-validator-identifier": "npm:^7.28.5" - "@babel/traverse": "npm:^7.28.5" + "@babel/helper-module-transforms": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/9791cb524438b2a8ba6cb8715788fa1e202fbecd4e76b3ccab0af0819fd69212b40ae30d72ac377012f7149889f7792ed8bf91e97bbe9113ca9641f8ad3bf332 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-systemjs@npm:7.29.8": + version: 7.29.8 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.8" + dependencies: + "@babel/helper-module-transforms": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-validator-identifier": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.8" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/7e8c0bcff79689702b974f6a0fedb5d0c6eeb5a5e3384deb7028e7cfe92a5242cc80e981e9c1817aad29f2ecc01841753365dd38d877aa0b91737ceec2acfd07 + checksum: 10c0/18167443bae93f485a43a1acdba9e53ac143043b93553d2ca1178030b68d4c1a7d5f5e717198aa8d73f39f33c023090af2270da774484105307e0fada5654687 languageName: node linkType: hard @@ -980,7 +1295,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" dependencies: @@ -991,7 +1306,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.7, @babel/plugin-transform-numeric-separator@npm:^7.27.1": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b0c186fe38bc66830e1be76f06fabbae8a655d3896a841ba5ffa12d6c40bb9c8a6ecd38a7e2196034b1d7470653109b1ceac1ef5e46a5fdc9291d14afa56e0d0 + languageName: node + linkType: hard + +"@babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" dependencies: @@ -1002,7 +1328,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.7, @babel/plugin-transform-object-rest-spread@npm:^7.28.4": +"@babel/plugin-transform-object-rest-spread@npm:^7.28.4": version: 7.28.4 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" dependencies: @@ -1040,31 +1366,31 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" +"@babel/plugin-transform-optional-chaining@npm:^7.24.8, @babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.5" dependencies: "@babel/helper-plugin-utils": "npm:^7.27.1" "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/5b18ff5124e503f0a25d6b195be7351a028b3992d6f2a91fb4037e2a2c386400d66bc1df8f6df0a94c708524f318729e81a95c41906e5a7919a06a43e573a525 + checksum: 10c0/adf5f70b1f9eb0dd6ff3d159a714683af3c910775653e667bd9f864c3dc2dc9872aba95f6c1e5f2a9675067241942f4fd0d641147ef4bf2bd8bc15f1fa0f2ed5 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.8, @babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.5": - version: 7.28.5 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.5" +"@babel/plugin-transform-optional-chaining@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.29.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/adf5f70b1f9eb0dd6ff3d159a714683af3c910775653e667bd9f864c3dc2dc9872aba95f6c1e5f2a9675067241942f4fd0d641147ef4bf2bd8bc15f1fa0f2ed5 + checksum: 10c0/71feacf9a7083030f4c69bf4e91db75f2fceae28e58c58b63db040006d908e15bc1e85a464f24ad659f17702e91a64eabbff9f1dd555ba33d78bb1af8a1d697a languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.27.7": +"@babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" dependencies: @@ -1232,7 +1558,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:7.27.1, @babel/plugin-transform-shorthand-properties@npm:^7.24.7, @babel/plugin-transform-shorthand-properties@npm:^7.27.1": +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" dependencies: @@ -1243,7 +1569,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.7, @babel/plugin-transform-spread@npm:^7.27.1": +"@babel/plugin-transform-spread@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-spread@npm:7.27.1" dependencies: @@ -1255,7 +1581,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.7, @babel/plugin-transform-sticky-regex@npm:^7.27.1": +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" dependencies: @@ -1277,7 +1603,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:7.27.1, @babel/plugin-transform-template-literals@npm:^7.27.1": +"@babel/plugin-transform-template-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" dependencies: @@ -1299,7 +1625,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.25.2, @babel/plugin-transform-typescript@npm:^7.27.1, @babel/plugin-transform-typescript@npm:^7.28.5": +"@babel/plugin-transform-typescript@npm:^7.25.2, @babel/plugin-transform-typescript@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-typescript@npm:7.28.5" dependencies: @@ -1314,6 +1640,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-transform-typescript@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + "@babel/plugin-syntax-typescript": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/8bf6a89c6827af6f11d4b189f1f97a64b8d754cc4caa5cbae16a6a8b113294d7f310dd40efd82e87ebcff2a1c683584b872d6d8960abe88d48f441d42f94c4d1 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" @@ -1337,7 +1678,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:7.27.1, @babel/plugin-transform-unicode-regex@npm:^7.24.7, @babel/plugin-transform-unicode-regex@npm:^7.27.1": +"@babel/plugin-transform-unicode-regex@npm:^7.24.7, @babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" dependencies: @@ -1470,33 +1811,33 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:7.27.1": - version: 7.27.1 - resolution: "@babel/preset-typescript@npm:7.27.1" +"@babel/preset-typescript@npm:^7.24.7": + version: 7.28.5 + resolution: "@babel/preset-typescript@npm:7.28.5" dependencies: "@babel/helper-plugin-utils": "npm:^7.27.1" "@babel/helper-validator-option": "npm:^7.27.1" "@babel/plugin-syntax-jsx": "npm:^7.27.1" "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" - "@babel/plugin-transform-typescript": "npm:^7.27.1" + "@babel/plugin-transform-typescript": "npm:^7.28.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/cba6ca793d915f8aff9fe2f13b0dfbf5fd3f2e9a17f17478ec9878e9af0d206dcfe93154b9fd353727f16c1dca7c7a3ceb4943f8d28b216235f106bc0fbbcaa3 + checksum: 10c0/b3d55548854c105085dd80f638147aa8295bc186d70492289242d6c857cb03a6c61ec15186440ea10ed4a71cdde7d495f5eb3feda46273f36b0ac926e8409629 languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.24.7": - version: 7.28.5 - resolution: "@babel/preset-typescript@npm:7.28.5" +"@babel/preset-typescript@npm:^7.28.5": + version: 7.29.7 + resolution: "@babel/preset-typescript@npm:7.29.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/helper-validator-option": "npm:^7.27.1" - "@babel/plugin-syntax-jsx": "npm:^7.27.1" - "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" - "@babel/plugin-transform-typescript": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-validator-option": "npm:^7.29.7" + "@babel/plugin-syntax-jsx": "npm:^7.29.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.29.7" + "@babel/plugin-transform-typescript": "npm:^7.29.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/b3d55548854c105085dd80f638147aa8295bc186d70492289242d6c857cb03a6c61ec15186440ea10ed4a71cdde7d495f5eb3feda46273f36b0ac926e8409629 + checksum: 10c0/40746a23a7ab46c0beb1c02d69883d9ffbe3043685cb3ae5363644391376b9261189fdad317191349e322c2c9bc550b031daa42470a1f8987362e4c56e492194 languageName: node linkType: hard @@ -1507,7 +1848,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.25.0, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -1518,7 +1859,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5": +"@babel/template@npm:^7.28.6, @babel/template@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/template@npm:7.29.7" + dependencies: + "@babel/code-frame": "npm:^7.29.7" + "@babel/parser": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/8bb7f900dcab0e9e1c5ffbc33ca10e0d26b7b2e2ca804becb73ee771b9c4ed6e2908a4ae4a14c08560febb45d2b6b9a173955e42ad404d05f8b04840a14d9c58 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5": version: 7.28.5 resolution: "@babel/traverse@npm:7.28.5" dependencies: @@ -1533,7 +1885,37 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.2, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/traverse@npm:^7.29.0, @babel/traverse@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/traverse@npm:7.29.7" + dependencies: + "@babel/code-frame": "npm:^7.29.7" + "@babel/generator": "npm:^7.29.7" + "@babel/helper-globals": "npm:^7.29.7" + "@babel/parser": "npm:^7.29.7" + "@babel/template": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + debug: "npm:^4.3.1" + checksum: 10c0/e256a1fbdb956555b76f3c285b1e453f6bedec8b3afb61751d99d933efd11c7d79caf5ddf2493570058a9f7deaa1b48324380d7c1aa1443fd9508becbf56331a + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.29.8": + version: 7.29.8 + resolution: "@babel/traverse@npm:7.29.8" + dependencies: + "@babel/code-frame": "npm:^7.29.7" + "@babel/generator": "npm:^7.29.8" + "@babel/helper-globals": "npm:^7.29.7" + "@babel/parser": "npm:^7.29.8" + "@babel/template": "npm:^7.29.7" + "@babel/types": "npm:^7.29.8" + debug: "npm:^4.3.1" + checksum: 10c0/87a28989c434add26d787776ac6d30f749b89cb030f2a605c89f671a516a6fa165ac0476f07e2b69feed70128b2734cae1cbbf41dfe95ccf22081bd8f8b91923 + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" dependencies: @@ -1543,6 +1925,26 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/types@npm:7.29.7" + dependencies: + "@babel/helper-string-parser": "npm:^7.29.7" + "@babel/helper-validator-identifier": "npm:^7.29.7" + checksum: 10c0/b6623994c69717fa27294f5fa46d59140338e2d86c6c1c13085c84ef7d53086ee357fbf4fe9abe3dd3da75734dc77c4c0df2f90fb29e667558bb3b3fb705e88f + languageName: node + linkType: hard + +"@babel/types@npm:^7.29.8": + version: 7.29.8 + resolution: "@babel/types@npm:7.29.8" + dependencies: + "@babel/helper-string-parser": "npm:^7.29.7" + "@babel/helper-validator-identifier": "npm:^7.29.7" + checksum: 10c0/be7c279f0abf2a086c633e21b49c7ca80275d05283cc5a268b67a708c9914bd0c944f1422b3eb3cb37682a2af5d560abf520ccf9b01b53ecbfe6b71fbc3fdde6 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -1760,16 +2162,26 @@ __metadata: languageName: node linkType: hard -"@egjs/hammerjs@npm:^2.0.17": - version: 2.0.17 - resolution: "@egjs/hammerjs@npm:2.0.17" +"@conventional-changelog/git-client@npm:^2.7.0": + version: 2.7.0 + resolution: "@conventional-changelog/git-client@npm:2.7.0" dependencies: - "@types/hammerjs": "npm:^2.0.36" - checksum: 10c0/dbedc15a0e633f887c08394bd636faf6a3abd05726dc0909a0e01209d5860a752d9eca5e512da623aecfabe665f49f1d035de3103eb2f9022c5cea692f9cc9be + "@simple-libs/child-process-utils": "npm:^1.0.0" + "@simple-libs/stream-utils": "npm:^1.2.0" + semver: "npm:^7.5.2" + peerDependencies: + conventional-commits-filter: ^5.0.0 + conventional-commits-parser: ^6.4.0 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true + checksum: 10c0/798097baa08a13311989e803451b9a8e602f404fcde1ec9fef609512625674c2d2a2f4368fbe00754a36f255e5b93dd852e7d3f2a9814215f9887ffa55c93993 languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.8.0": +"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": version: 4.9.1 resolution: "@eslint-community/eslint-utils@npm:4.9.1" dependencies: @@ -1780,7 +2192,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": +"@eslint-community/regexpp@npm:^4.12.1, @eslint-community/regexpp@npm:^4.12.2": version: 4.12.2 resolution: "@eslint-community/regexpp@npm:4.12.2" checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d @@ -1801,14 +2213,14 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.21.1": - version: 0.21.1 - resolution: "@eslint/config-array@npm:0.21.1" +"@eslint/config-array@npm:^0.21.2": + version: 0.21.2 + resolution: "@eslint/config-array@npm:0.21.2" dependencies: "@eslint/object-schema": "npm:^2.1.7" debug: "npm:^4.3.1" - minimatch: "npm:^3.1.2" - checksum: 10c0/2f657d4edd6ddcb920579b72e7a5b127865d4c3fb4dda24f11d5c4f445a93ca481aebdbd6bf3291c536f5d034458dbcbb298ee3b698bc6c9dd02900fe87eec3c + minimatch: "npm:^3.1.5" + checksum: 10c0/89dfe815d18456177c0a1f238daf4593107fd20298b3598e0103054360d3b8d09d967defd8318f031185d68df1f95cfa68becf1390a9c5c6887665f1475142e3 languageName: node linkType: hard @@ -1847,7 +2259,31 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.39.2, @eslint/js@npm:^9.35.0": +"@eslint/eslintrc@npm:^3.3.6": + version: 3.3.6 + resolution: "@eslint/eslintrc@npm:3.3.6" + dependencies: + ajv: "npm:^6.14.0" + debug: "npm:^4.3.2" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.3.0" + minimatch: "npm:^3.1.5" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/349697171ee116f501a2f483bf47cd38937a61880aeb1c23481a69afc95e95859430a0947acbe1f5507f223180bf57530ecf2989e73bcbea763a6dcffdf1d010 + languageName: node + linkType: hard + +"@eslint/js@npm:9.39.5": + version: 9.39.5 + resolution: "@eslint/js@npm:9.39.5" + checksum: 10c0/49894e98ba313a7d3bfb1b20d55c0f9826be45a7db876fd84e533ac7f101b1d95b51cd22c6a6db3a45066b9c0d068c31b4a22fa0db8a6cc8744a25540efdb824 + languageName: node + linkType: hard + +"@eslint/js@npm:^9.35.0": version: 9.39.2 resolution: "@eslint/js@npm:9.39.2" checksum: 10c0/00f51c52b04ac79faebfaa65a9652b2093b9c924e945479f1f3945473f78aee83cbc76c8d70bbffbf06f7024626575b16d97b66eab16182e1d0d39daff2f26f5 @@ -1871,42 +2307,80 @@ __metadata: languageName: node linkType: hard -"@gorhom/bottom-sheet@npm:^5": - version: 5.2.8 - resolution: "@gorhom/bottom-sheet@npm:5.2.8" +"@expo/config-plugins@npm:57.0.6": + version: 57.0.6 + resolution: "@expo/config-plugins@npm:57.0.6" dependencies: - "@gorhom/portal": "npm:1.0.14" - invariant: "npm:^2.2.4" - peerDependencies: - "@types/react": "*" - "@types/react-native": "*" - react: "*" - react-native: "*" - react-native-gesture-handler: ">=2.16.1" - react-native-reanimated: "*" - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-native": - optional: true - checksum: 10c0/9bb71a375cdcaec650e8c84ab5e3e42f55b3ae19d9e08cf90688cf72706588d211f3aeef28b857a37e9e411efa8fdf038429c90a8855167c7ab3dce5c595dfca + "@expo/config-types": "npm:^57.0.2" + "@expo/json-file": "npm:~11.0.1" + "@expo/plist": "npm:^0.8.1" + "@expo/require-utils": "npm:^57.0.4" + "@expo/sdk-runtime-versions": "npm:^1.0.0" + chalk: "npm:^4.1.2" + debug: "npm:^4.3.5" + getenv: "npm:^2.0.0" + glob: "npm:^13.0.0" + semver: "npm:^7.5.4" + slugify: "npm:^1.6.6" + xcode: "npm:^3.0.1" + xml2js: "npm:0.6.0" + checksum: 10c0/98ff17edf2bf90d9fa56dde28d0d13b3c11e4767dd0e21c4cf5187990526eb21949718a9dcc5f062a8903ab56c9382ccea75d871d4a9f72f1ab1a91e001a1826 + languageName: node + linkType: hard + +"@expo/config-types@npm:^57.0.2": + version: 57.0.2 + resolution: "@expo/config-types@npm:57.0.2" + checksum: 10c0/3e3a8abcab03791dfccc758bde5ce85f0fa4b14c22df072e6cc72c670945fc65433239bf2ce39f86bbda422b338d19323612d61eabb2442f988713214837a6dc languageName: node linkType: hard -"@gorhom/portal@npm:1.0.14": - version: 1.0.14 - resolution: "@gorhom/portal@npm:1.0.14" +"@expo/json-file@npm:~11.0.1": + version: 11.0.1 + resolution: "@expo/json-file@npm:11.0.1" dependencies: - nanoid: "npm:^3.3.1" - peerDependencies: - react: "*" - react-native: "*" - checksum: 10c0/86f33afc2ac2656a86a6f3fd1e41565419839576ede2c38333434a93a0a2fe4fb6fc18ab3360579427f2a1fc3b4564b933cc5ae1793a7e2825c93860a00b215f + "@babel/code-frame": "npm:^7.20.0" + json5: "npm:^2.2.3" + checksum: 10c0/b93e8bf0654c7d417bf00a418932a3f676bc24bed75ff63a8c683229e2d1f3b7a48206fc3af7db307ed93a776adab51cb62ebb6a0ed77f86067c7ae85cc2f74d languageName: node linkType: hard -"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": - version: 9.3.0 +"@expo/plist@npm:^0.8.1": + version: 0.8.1 + resolution: "@expo/plist@npm:0.8.1" + dependencies: + "@xmldom/xmldom": "npm:^0.8.8" + base64-js: "npm:^1.5.1" + xmlbuilder: "npm:^15.1.1" + checksum: 10c0/45f130f3d5155d46dc415ab61b97449d5cc7bf47e41ed37965f12e50cc9728aa7c4da83fc958a8d7113e31e4342baebc1b2517de7e20186f3e64d53be378a9ce + languageName: node + linkType: hard + +"@expo/require-utils@npm:^57.0.4": + version: 57.0.4 + resolution: "@expo/require-utils@npm:57.0.4" + dependencies: + "@babel/code-frame": "npm:^7.20.0" + "@babel/core": "npm:^7.25.2" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" + peerDependencies: + typescript: ^5.0.0 || ^5.0.0-0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/63ebc03ff9930af4c1680365b524ebe8aedab430273ad39a64c9afd5842e26fbfd7e38f10d5d2d2c6fc3849065ad1c9288a555596a1fd6fddb97c12e6844694f + languageName: node + linkType: hard + +"@expo/sdk-runtime-versions@npm:^1.0.0": + version: 1.0.0 + resolution: "@expo/sdk-runtime-versions@npm:1.0.0" + checksum: 10c0/f80ae78a294daf396f3eff2eb412948ced5501395a6d3b88058866da9c5135dbacbb2804f8d062222e7452159a61eebefd2f548a2939f539f0f0efe8145588a2 + languageName: node + linkType: hard + +"@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": + version: 9.3.0 resolution: "@hapi/hoek@npm:9.3.0" checksum: 10c0/a096063805051fb8bba4c947e293c664b05a32b47e13bc654c0dd43813a1cec993bdd8f29ceb838020299e1d0f89f68dc0d62a603c13c9cc8541963f0beca055 languageName: node @@ -2199,22 +2673,6 @@ __metadata: languageName: node linkType: hard -"@isaacs/balanced-match@npm:^4.0.1": - version: 4.0.1 - resolution: "@isaacs/balanced-match@npm:4.0.1" - checksum: 10c0/7da011805b259ec5c955f01cee903da72ad97c5e6f01ca96197267d3f33103d5b2f8a1af192140f3aa64526c593c8d098ae366c2b11f7f17645d12387c2fd420 - languageName: node - linkType: hard - -"@isaacs/brace-expansion@npm:^5.0.0": - version: 5.0.0 - resolution: "@isaacs/brace-expansion@npm:5.0.0" - dependencies: - "@isaacs/balanced-match": "npm:^4.0.1" - checksum: 10c0/b4d4812f4be53afc2c5b6c545001ff7a4659af68d4484804e9d514e183d20269bb81def8682c01a22b17c4d6aed14292c8494f7d2ac664e547101c1a905aa977 - languageName: node - linkType: hard - "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -2603,28 +3061,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/agent@npm:^4.0.0": - version: 4.0.0 - resolution: "@npmcli/agent@npm:4.0.0" - dependencies: - agent-base: "npm:^7.1.0" - http-proxy-agent: "npm:^7.0.0" - https-proxy-agent: "npm:^7.0.1" - lru-cache: "npm:^11.2.1" - socks-proxy-agent: "npm:^8.0.3" - checksum: 10c0/f7b5ce0f3dd42c3f8c6546e8433573d8049f67ef11ec22aa4704bc41483122f68bf97752e06302c455ead667af5cb753e6a09bff06632bc465c1cfd4c4b75a53 - languageName: node - linkType: hard - -"@npmcli/fs@npm:^5.0.0": - version: 5.0.0 - resolution: "@npmcli/fs@npm:5.0.0" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/26e376d780f60ff16e874a0ac9bc3399186846baae0b6e1352286385ac134d900cc5dafaded77f38d77f86898fc923ae1cee9d7399f0275b1aa24878915d722b - languageName: node - linkType: hard - "@octokit/auth-token@npm:^6.0.0": version: 6.0.0 resolution: "@octokit/auth-token@npm:6.0.0" @@ -2763,10 +3199,10 @@ __metadata: languageName: node linkType: hard -"@pkgr/core@npm:^0.2.9": - version: 0.2.9 - resolution: "@pkgr/core@npm:0.2.9" - checksum: 10c0/ac8e4e8138b1a7a4ac6282873aef7389c352f1f8b577b4850778f5182e4a39a5241facbe48361fec817f56d02b51691b383010843fb08b34a8e8ea3614688fd5 +"@pkgr/core@npm:^0.3.6": + version: 0.3.6 + resolution: "@pkgr/core@npm:0.3.6" + checksum: 10c0/153f0f4563f505faeba13c733efa0e05e467ce1c6b941055a5fd3b4560da60fbf1dff4b11da0075f034ddda11f2842b90395f60895dde5825875b616edccc11c languageName: node linkType: hard @@ -2780,245 +3216,119 @@ __metadata: languageName: node linkType: hard -"@react-native-community/cli-clean@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-clean@npm:20.0.0" +"@react-native-community/cli-clean@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-clean@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-glob: "npm:^3.3.2" - checksum: 10c0/cd65907bf2bff82abe8a6616802cf1f756340983e9154a93e771710059ccbf863e45046d2568a6bcb85ef1b4e51b883866ce6371950ec27309a6d1e3fc10cbf4 - languageName: node - linkType: hard - -"@react-native-community/cli-clean@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-clean@npm:20.0.1" - dependencies: - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" - execa: "npm:^5.0.0" - fast-glob: "npm:^3.3.2" - checksum: 10c0/7057ca335f8b01ce49a15b2937e84590a6747f8ad267c4dd0df9eb21c3bf3c8c0f8756f06ef8d57cec9d938c6108cd7f289241ff75619828e83c409db3bceb74 - languageName: node - linkType: hard - -"@react-native-community/cli-config-android@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config-android@npm:20.0.0" - dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" - fast-glob: "npm:^3.3.2" - fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/79298ecde495e0587585e8d67431e9543ac83392a06e5c8fb736853d199f0aae014858b1d3db81ce3decf58c2172c95c78eeb27e0f2be2b8a5ad43b96331d0ce + picocolors: "npm:^1.1.1" + checksum: 10c0/5d7fce73545154035e55801e9596b634c85bbe7bb04861f3d0787f2a9588b7b6f927709bfce4e45a8d62da03e5a92789281e07dafd29e2db86ca52ca3e5ad49c languageName: node linkType: hard -"@react-native-community/cli-config-android@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-config-android@npm:20.0.1" +"@react-native-community/cli-config-android@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config-android@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" fast-glob: "npm:^3.3.2" fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/6d7607af8a88339764fdc551d8293ddaf648b8ece3cd309a3ebfac25038e2761c9dad2e10705b3481defbb9e9388dba7073d6e7b76d2297e708934c593ffb96a - languageName: node - linkType: hard - -"@react-native-community/cli-config-apple@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config-apple@npm:20.0.0" - dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" - execa: "npm:^5.0.0" - fast-glob: "npm:^3.3.2" - checksum: 10c0/1b11e1dde776ccc3244eb3029eb49239120a89a12ed84bd4957e4e7b81bba4b332ed04a2fb081fd9a9711be65d1a85cf429247fa2daa4010ba4b42b5bf273c2f + picocolors: "npm:^1.1.1" + checksum: 10c0/66e95adf2fb9750a12592a146b034ab4b8ea15aa41efb5d497d6be2f08029a59a0be2450e97de0bf59aa6b66778b3af0bbd693a42b7e7f9f60c9d9b5f966aadc languageName: node linkType: hard -"@react-native-community/cli-config-apple@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-config-apple@npm:20.0.1" +"@react-native-community/cli-config-apple@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config-apple@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-glob: "npm:^3.3.2" - checksum: 10c0/4924ecb3f405f5da2ff2acc968232d451c8862a11e0d877ee898347ecc467e9664aee2cbab2df488250776b171acafde33212a7880bb4e2e0c35b5e82e24c5ea - languageName: node - linkType: hard - -"@react-native-community/cli-config@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config@npm:20.0.0" - dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" - cosmiconfig: "npm:^9.0.0" - deepmerge: "npm:^4.3.0" - fast-glob: "npm:^3.3.2" - joi: "npm:^17.2.1" - checksum: 10c0/766364c0c1d0f551a98b86317b74e7942521a05111f6c7e2898341c0413c6a55ae91d184bd549109edd61f02065662ada142788dba1090db200cbec00fdfeede + picocolors: "npm:^1.1.1" + checksum: 10c0/2c7b7116594c7b0035ef7e41e0219fcff664c3883471460ae48f19dd88ec9a26dd5b4bd60e33c054603b3a10efd78570490bc84599ad987e4ffb274b05512351 languageName: node linkType: hard -"@react-native-community/cli-config@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-config@npm:20.0.1" +"@react-native-community/cli-config@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" cosmiconfig: "npm:^9.0.0" deepmerge: "npm:^4.3.0" fast-glob: "npm:^3.3.2" joi: "npm:^17.2.1" - checksum: 10c0/5c1a78fc8f2e65fa1dcf99e63dbd7b72bd875c3acf5c649b8b917c41cdbeb355617a844db079b2723e835ed2ff9059dec8a4ced03b383005d09c737813ea4e07 - languageName: node - linkType: hard - -"@react-native-community/cli-doctor@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-doctor@npm:20.0.0" - dependencies: - "@react-native-community/cli-config": "npm:20.0.0" - "@react-native-community/cli-platform-android": "npm:20.0.0" - "@react-native-community/cli-platform-apple": "npm:20.0.0" - "@react-native-community/cli-platform-ios": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" - command-exists: "npm:^1.2.8" - deepmerge: "npm:^4.3.0" - envinfo: "npm:^7.13.0" - execa: "npm:^5.0.0" - node-stream-zip: "npm:^1.9.1" - ora: "npm:^5.4.1" - semver: "npm:^7.5.2" - wcwidth: "npm:^1.0.1" - yaml: "npm:^2.2.1" - checksum: 10c0/843a7e8e5969154ed171616c3c556389d7debc30035bb6a9d6392876d22ef84d390d02673032bb8c8ac164380a97fe9f62971476aacb06ba3a3b849358e4cb99 + picocolors: "npm:^1.1.1" + checksum: 10c0/e3d863ffc5d18aa7b7406908c1360de7ea7a1bab32897e34d0afe184f4682bb5d110d4db0c6ba2c35c4f1330ca4a281b8fc3548e53a2978b8b07ca3beca5765c languageName: node linkType: hard -"@react-native-community/cli-doctor@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-doctor@npm:20.0.1" +"@react-native-community/cli-doctor@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-doctor@npm:20.1.0" dependencies: - "@react-native-community/cli-config": "npm:20.0.1" - "@react-native-community/cli-platform-android": "npm:20.0.1" - "@react-native-community/cli-platform-apple": "npm:20.0.1" - "@react-native-community/cli-platform-ios": "npm:20.0.1" - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config": "npm:20.1.0" + "@react-native-community/cli-platform-android": "npm:20.1.0" + "@react-native-community/cli-platform-apple": "npm:20.1.0" + "@react-native-community/cli-platform-ios": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" command-exists: "npm:^1.2.8" deepmerge: "npm:^4.3.0" envinfo: "npm:^7.13.0" execa: "npm:^5.0.0" node-stream-zip: "npm:^1.9.1" ora: "npm:^5.4.1" + picocolors: "npm:^1.1.1" semver: "npm:^7.5.2" wcwidth: "npm:^1.0.1" yaml: "npm:^2.2.1" - checksum: 10c0/c316fd13a8ed8fa862608c7c9e28a42845dcd50a757954993f036206306beed288fff6e9f29d38e53b3a35277c1e2a9dbec30f7900199517c93c54eac7275206 + checksum: 10c0/79762f3e789fe98f21c6f500f6c65df399508979f05174272652a9422295f4dace099e87575776bf209b533a6667070fc355c5b510e14a8a61b31a9a8af7b3be languageName: node linkType: hard -"@react-native-community/cli-platform-android@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-android@npm:20.0.0" +"@react-native-community/cli-platform-android@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-android@npm:20.1.0" dependencies: - "@react-native-community/cli-config-android": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config-android": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" logkitty: "npm:^0.7.1" - checksum: 10c0/9c17cbc0661698dd8154286ce893205b91a9f71cb8af8505641fb82ab99217116300fe0dfb8b5e6e9270cf3917c0fb227d45f90322ad7e624d9c65aacf086012 - languageName: node - linkType: hard - -"@react-native-community/cli-platform-android@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-platform-android@npm:20.0.1" - dependencies: - "@react-native-community/cli-config-android": "npm:20.0.1" - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" - execa: "npm:^5.0.0" - logkitty: "npm:^0.7.1" - checksum: 10c0/5178f85aa1c7ee321776055f84c4e8413f7daf745da703a9f35f36800d745e6c3aff85262fffce7102cd49b9aa54d47ce25613804682983a8247e5e8a52d93f5 - languageName: node - linkType: hard - -"@react-native-community/cli-platform-apple@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-apple@npm:20.0.0" - dependencies: - "@react-native-community/cli-config-apple": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" - execa: "npm:^5.0.0" - fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/a6b2296d6291853f59d3c68302676fea54d68fa6626c14727b7db63280761714785fd70a75d7ae036644a7ea5ebd8211235c64d4dec5297565d734a1c5a3b6c9 + picocolors: "npm:^1.1.1" + checksum: 10c0/8b44178a78245085824c3fda9d6753d03cd817772fdde82b1d4f1a89f177f10339822401c0b8ef17e8353f3168c3971ae4cfb0a158cef03c22e55f5dff66179b languageName: node linkType: hard -"@react-native-community/cli-platform-apple@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-platform-apple@npm:20.0.1" +"@react-native-community/cli-platform-apple@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-apple@npm:20.1.0" dependencies: - "@react-native-community/cli-config-apple": "npm:20.0.1" - "@react-native-community/cli-tools": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config-apple": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/2ca9669339f616ba6a6d0df299cd0828fed3497b1d16414be0f92fa46b2395e7ab12c7c0a7bd7c66ce026a100225dde9ba133796813365d0f4dc31681a8a82e7 - languageName: node - linkType: hard - -"@react-native-community/cli-platform-ios@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-ios@npm:20.0.0" - dependencies: - "@react-native-community/cli-platform-apple": "npm:20.0.0" - checksum: 10c0/6eb77946cb3392cc548007723b790796360651e62422095da2bbc8a20b7c8e79d9fc32c0155ba669a10c556e6e7327964d59e5755c64f6099708701e4acf8fd3 - languageName: node - linkType: hard - -"@react-native-community/cli-platform-ios@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-platform-ios@npm:20.0.1" - dependencies: - "@react-native-community/cli-platform-apple": "npm:20.0.1" - checksum: 10c0/9989444c4490413104f5ca7de666f90a97a7b1901d9a301e36242ee80e5f5bdffd2899858c3a0476c6e46bf3b0bd17da87e76970b688bcea90ff6b02bf4a612c + picocolors: "npm:^1.1.1" + checksum: 10c0/2218e172bf13c0bb027f7f2a036a0515f8fe023d98fc65d22d0dab601036c5b461b1af7a5d826df2dd3e86a3894f9531d43e8861746a071ee22c0b33b8e47c29 languageName: node linkType: hard -"@react-native-community/cli-server-api@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-server-api@npm:20.0.0" +"@react-native-community/cli-platform-ios@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-ios@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - body-parser: "npm:^1.20.3" - compression: "npm:^1.7.1" - connect: "npm:^3.6.5" - errorhandler: "npm:^1.5.1" - nocache: "npm:^3.0.1" - open: "npm:^6.2.0" - pretty-format: "npm:^29.7.0" - serve-static: "npm:^1.13.1" - ws: "npm:^6.2.3" - checksum: 10c0/105099a3b667978880144eb4e1ca1725c57f1fe6bb6f8d09b189f021ecc1ad70f8e865667ef1d921fb85f1bea8d1da766d713672dfde80d6d2cdde47e800d5a8 + "@react-native-community/cli-platform-apple": "npm:20.1.0" + checksum: 10c0/f5eef9dfbe3dad7dc69f4b3a37ebee9d124f3a649071e0275624f88468a7f506b622646dcbd61ba0435cc35e705badfc287690d6b7c3867c0a86c9a45d4f463e languageName: node linkType: hard -"@react-native-community/cli-server-api@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-server-api@npm:20.0.1" +"@react-native-community/cli-server-api@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-server-api@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.1" + "@react-native-community/cli-tools": "npm:20.1.0" body-parser: "npm:^1.20.3" compression: "npm:^1.7.1" connect: "npm:^3.6.5" @@ -3028,111 +3338,59 @@ __metadata: pretty-format: "npm:^29.7.0" serve-static: "npm:^1.13.1" ws: "npm:^6.2.3" - checksum: 10c0/29dd846b8836059333e4dc83e8867b3d65916af3a5c3287933ff04c73a86aeb078e0f1ccdf42aaf2660b654b9094ed4c6b0724d229067fb1966ae12715e3d7b2 + checksum: 10c0/d83c9bbff36fb84201478ed8efc17c80f1474cb0346a2577eee7299407e9e34892c213e2316062a2c59d47ebfe9f0c8215b82cd1abb05c85fe7702a94a52cdf5 languageName: node linkType: hard -"@react-native-community/cli-tools@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-tools@npm:20.0.0" +"@react-native-community/cli-tools@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-tools@npm:20.1.0" dependencies: "@vscode/sudo-prompt": "npm:^9.0.0" appdirsjs: "npm:^1.2.4" - chalk: "npm:^4.1.2" - execa: "npm:^5.0.0" - find-up: "npm:^5.0.0" - launch-editor: "npm:^2.9.1" - mime: "npm:^2.4.1" - ora: "npm:^5.4.1" - prompts: "npm:^2.4.2" - semver: "npm:^7.5.2" - checksum: 10c0/3a379558f2673de68d872d740754e242d9dd84dd0a837f94910936faad632f35fc9b61dd9d256e635391815da7a4cbc42c3ca918371d60fb4d5a3b4acea6bffd - languageName: node - linkType: hard - -"@react-native-community/cli-tools@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-tools@npm:20.0.1" - dependencies: - "@vscode/sudo-prompt": "npm:^9.0.0" - appdirsjs: "npm:^1.2.4" - chalk: "npm:^4.1.2" execa: "npm:^5.0.0" find-up: "npm:^5.0.0" launch-editor: "npm:^2.9.1" mime: "npm:^2.4.1" ora: "npm:^5.4.1" + picocolors: "npm:^1.1.1" prompts: "npm:^2.4.2" semver: "npm:^7.5.2" - checksum: 10c0/d6f083b2592250b11c114e3abe6ef38c70653aac1316750b8ba9dcbc81b99c25879999164498511128b8ebcaa083aa0427181225b178d70ca76b4c5f466f952f - languageName: node - linkType: hard - -"@react-native-community/cli-types@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-types@npm:20.0.0" - dependencies: - joi: "npm:^17.2.1" - checksum: 10c0/328f623579b3b8e797d833aeb76fad86a75f9da84b45da1d9ffe4c6429a57cd3440d401d3448d15c2b44b69137459033522e3dff87767f887772d8f6055dccc9 + checksum: 10c0/993f5dfbc1ae6301e616269896b2e5ecc29888cc8a12325881148b546b07d45572bd065e392ceaad32f86067e31b0eabedbe71fac3b1b820cd489ab86e56094d languageName: node linkType: hard -"@react-native-community/cli-types@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli-types@npm:20.0.1" +"@react-native-community/cli-types@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-types@npm:20.1.0" dependencies: joi: "npm:^17.2.1" - checksum: 10c0/dd1e2013594fa8f30ff0f1494bb67ccb62fd9a5d4933294e8e193f8074362559f863eaddacb6e127505490929aef4f59c7019032606ca21964bdbf205fc4171d - languageName: node - linkType: hard - -"@react-native-community/cli@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli@npm:20.0.0" - dependencies: - "@react-native-community/cli-clean": "npm:20.0.0" - "@react-native-community/cli-config": "npm:20.0.0" - "@react-native-community/cli-doctor": "npm:20.0.0" - "@react-native-community/cli-server-api": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - "@react-native-community/cli-types": "npm:20.0.0" - chalk: "npm:^4.1.2" - commander: "npm:^9.4.1" - deepmerge: "npm:^4.3.0" - execa: "npm:^5.0.0" - find-up: "npm:^5.0.0" - fs-extra: "npm:^8.1.0" - graceful-fs: "npm:^4.1.3" - prompts: "npm:^2.4.2" - semver: "npm:^7.5.2" - bin: - rnc-cli: build/bin.js - checksum: 10c0/ccdbc8ba1f678274772237941993e68143707240762194842fa756fc7d53bcee9114e0b7d3eefaa750ccba41189909fbd7ceaa3a99f5ae781ccf2e98c5ff10b6 + checksum: 10c0/247deebf26b435c0cbabfb7dd7de09a4e79c544ee72a2ef2817268108f7c085dab4d54c7fbc8111ad89360e13227f2041c5eac208971c251da332e4d33311a7b languageName: node linkType: hard -"@react-native-community/cli@npm:20.0.1": - version: 20.0.1 - resolution: "@react-native-community/cli@npm:20.0.1" +"@react-native-community/cli@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli@npm:20.1.0" dependencies: - "@react-native-community/cli-clean": "npm:20.0.1" - "@react-native-community/cli-config": "npm:20.0.1" - "@react-native-community/cli-doctor": "npm:20.0.1" - "@react-native-community/cli-server-api": "npm:20.0.1" - "@react-native-community/cli-tools": "npm:20.0.1" - "@react-native-community/cli-types": "npm:20.0.1" - chalk: "npm:^4.1.2" + "@react-native-community/cli-clean": "npm:20.1.0" + "@react-native-community/cli-config": "npm:20.1.0" + "@react-native-community/cli-doctor": "npm:20.1.0" + "@react-native-community/cli-server-api": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" + "@react-native-community/cli-types": "npm:20.1.0" commander: "npm:^9.4.1" deepmerge: "npm:^4.3.0" execa: "npm:^5.0.0" find-up: "npm:^5.0.0" fs-extra: "npm:^8.1.0" graceful-fs: "npm:^4.1.3" + picocolors: "npm:^1.1.1" prompts: "npm:^2.4.2" semver: "npm:^7.5.2" bin: rnc-cli: build/bin.js - checksum: 10c0/70fab833b60ba73d8afb95715ae390695b2fe4831bd70ba65cc3362bf9790f95ffe789ff019d14faf951e1d153dea3e31527efc73fc1f4ffe6f03c5b6583835a + checksum: 10c0/f3fa43fc8c170ba291ae81e796f4ac35956e143bf1094f15f91061b93835ed0665749ca11da91df7fbfcdd96ee32fc16da6cab60adef1a21022195aa1947bd5d languageName: node linkType: hard @@ -3143,26 +3401,26 @@ __metadata: languageName: node linkType: hard -"@react-native/assets-registry@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/assets-registry@npm:0.81.1" - checksum: 10c0/44ee4e31bd08770eb59116097c38e8146eb6821a4bf932e7733c04d56a1e8b0263befd8642477824fc836b61c31d99405cbf36b15b4e131dcd82ca21f171db66 +"@react-native/assets-registry@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/assets-registry@npm:0.86.0" + checksum: 10c0/9cd7e96d99bb5b1da0b83ad4362966749c367081bd4272ca65c8ce4933cea9caad6bbf1d6e404832447c9b200495d707809bbb1db2fd5d9a6f7ae25a50a96bf8 languageName: node linkType: hard -"@react-native/babel-plugin-codegen@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/babel-plugin-codegen@npm:0.81.1" +"@react-native/babel-plugin-codegen@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/babel-plugin-codegen@npm:0.86.0" dependencies: - "@babel/traverse": "npm:^7.25.3" - "@react-native/codegen": "npm:0.81.1" - checksum: 10c0/e039e517454cf261c34f3300a1cb7475a8f11f2c2c997cad9688c9878200199fc716ba8d26b3f6c0e614b72aa89ae91dba5e81ffdaf2789e3cd7dafd69e9fa6d + "@babel/traverse": "npm:^7.29.0" + "@react-native/codegen": "npm:0.86.0" + checksum: 10c0/b9263b7fd6a40411639e2343e17454fa9e988e651f44ec9149bd0c3a7945166863713b01d21249b81e62bd9ec67e356fbbee860e7b7f8479df26310b90d2bd4e languageName: node linkType: hard -"@react-native/babel-preset@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/babel-preset@npm:0.81.1" +"@react-native/babel-preset@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/babel-preset@npm:0.86.0" dependencies: "@babel/core": "npm:^7.25.2" "@babel/plugin-proposal-export-default-from": "npm:^7.24.7" @@ -3170,27 +3428,19 @@ __metadata: "@babel/plugin-syntax-export-default-from": "npm:^7.24.7" "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" "@babel/plugin-transform-async-generator-functions": "npm:^7.25.4" "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" "@babel/plugin-transform-block-scoping": "npm:^7.25.0" "@babel/plugin-transform-class-properties": "npm:^7.25.4" "@babel/plugin-transform-classes": "npm:^7.25.4" - "@babel/plugin-transform-computed-properties": "npm:^7.24.7" "@babel/plugin-transform-destructuring": "npm:^7.24.8" "@babel/plugin-transform-flow-strip-types": "npm:^7.25.2" "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.25.1" - "@babel/plugin-transform-literals": "npm:^7.25.2" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" - "@babel/plugin-transform-parameters": "npm:^7.24.7" "@babel/plugin-transform-private-methods": "npm:^7.24.7" "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" "@babel/plugin-transform-react-display-name": "npm:^7.24.7" @@ -3199,186 +3449,209 @@ __metadata: "@babel/plugin-transform-react-jsx-source": "npm:^7.24.7" "@babel/plugin-transform-regenerator": "npm:^7.24.7" "@babel/plugin-transform-runtime": "npm:^7.24.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" - "@babel/plugin-transform-spread": "npm:^7.24.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" "@babel/plugin-transform-typescript": "npm:^7.25.2" "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" - "@babel/template": "npm:^7.25.0" - "@react-native/babel-plugin-codegen": "npm:0.81.1" - babel-plugin-syntax-hermes-parser: "npm:0.29.1" + "@react-native/babel-plugin-codegen": "npm:0.86.0" + babel-plugin-syntax-hermes-parser: "npm:0.36.0" babel-plugin-transform-flow-enums: "npm:^0.0.2" react-refresh: "npm:^0.14.0" peerDependencies: "@babel/core": "*" - checksum: 10c0/d04b9c1d445d84a6c4793605f411a9cfc296f6e4e09d82268db25e715e7ba89136340267f125258d742e732d2dfe86608f3b011d05dc9117f9ee1870d244ba30 + checksum: 10c0/cf86875fa72d9bdd0b6ac3819b7a683764f154ff8df5144cce9cc60dd734d9d100bde563acbb48104e0033650dcc28d968eb985ff59e47349dc6861169df02f6 languageName: node linkType: hard -"@react-native/codegen@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/codegen@npm:0.81.1" +"@react-native/codegen@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/codegen@npm:0.86.0" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/parser": "npm:^7.25.3" - glob: "npm:^7.1.1" - hermes-parser: "npm:0.29.1" + "@babel/parser": "npm:^7.29.0" + hermes-parser: "npm:0.36.0" invariant: "npm:^2.2.4" nullthrows: "npm:^1.1.1" + tinyglobby: "npm:^0.2.15" yargs: "npm:^17.6.2" peerDependencies: "@babel/core": "*" - checksum: 10c0/d0910a99e4174f7aaec5328a92a56c70fa0acf84062282f56dcf1ac3389e9d5b21a16b049049a79648e1b632f11872c2dca6be9670593b92ccb656922485ca2b + checksum: 10c0/22ca5657595438f5e464223a65b25567b3e7106995c8ae59c5853d8cdb3df59065db54c4cb74e958bbe2930b0aded8cd518c2fc1ef13a4740a05fb1faa3ae160 languageName: node linkType: hard -"@react-native/community-cli-plugin@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/community-cli-plugin@npm:0.81.1" +"@react-native/community-cli-plugin@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/community-cli-plugin@npm:0.86.0" dependencies: - "@react-native/dev-middleware": "npm:0.81.1" + "@react-native/dev-middleware": "npm:0.86.0" debug: "npm:^4.4.0" invariant: "npm:^2.2.4" - metro: "npm:^0.83.1" - metro-config: "npm:^0.83.1" - metro-core: "npm:^0.83.1" + metro: "npm:^0.84.3" + metro-config: "npm:^0.84.3" + metro-core: "npm:^0.84.3" semver: "npm:^7.1.3" peerDependencies: "@react-native-community/cli": "*" - "@react-native/metro-config": "*" + "@react-native/metro-config": 0.86.0 peerDependenciesMeta: "@react-native-community/cli": optional: true "@react-native/metro-config": optional: true - checksum: 10c0/96811ba146d1a591aa2e96abb6cc2ce06a3076457b2bba3cd3bc2f792f81c6d540378dd22af09e632a7dfaecc3b45a179224ab453fe71a3ddc8d29d060b87451 + checksum: 10c0/62c70f1e99eb48dad8516fed9a15415e8de85ee76018f00231f4473e9fedbfc8c9b4932fc531b9307c3a6d681278b61fa7e63ba2fa250628451662f815a3366e languageName: node linkType: hard -"@react-native/debugger-frontend@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/debugger-frontend@npm:0.81.1" - checksum: 10c0/282c957fa6af485496b6e5fbc16266f8463bb2474cdaa6c3e41b4a061ffc6432bd3d18ceedfba35ff47648876c71021abfbb17f0f8e0a4d7f8edec4eb94bb811 +"@react-native/debugger-frontend@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/debugger-frontend@npm:0.86.0" + checksum: 10c0/bc86a765dfbcaae35f501244d5a52aa0723196fe34ba177c2e3398491df6af1aa084ace044fde668e05bfec3daf15f735c20c79a8b98bd578b38891913e337e2 languageName: node linkType: hard -"@react-native/dev-middleware@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/dev-middleware@npm:0.81.1" +"@react-native/debugger-shell@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/debugger-shell@npm:0.86.0" + dependencies: + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.4.0" + fb-dotslash: "npm:0.5.8" + checksum: 10c0/4cc7626b826195403c9b9ac8ad1ed9938ad83858424aa59b980882349966aa0fa6b509066006bc7c7be2c0d20767fbc7d75c8df0007f853b57646c9157fcb3e7 + languageName: node + linkType: hard + +"@react-native/dev-middleware@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/dev-middleware@npm:0.86.0" dependencies: "@isaacs/ttlcache": "npm:^1.4.1" - "@react-native/debugger-frontend": "npm:0.81.1" + "@react-native/debugger-frontend": "npm:0.86.0" + "@react-native/debugger-shell": "npm:0.86.0" chrome-launcher: "npm:^0.15.2" - chromium-edge-launcher: "npm:^0.2.0" + chromium-edge-launcher: "npm:^0.3.0" connect: "npm:^3.6.5" debug: "npm:^4.4.0" invariant: "npm:^2.2.4" nullthrows: "npm:^1.1.1" open: "npm:^7.0.3" serve-static: "npm:^1.16.2" - ws: "npm:^6.2.3" - checksum: 10c0/ab5d09709efe4ede4f09e94923208e82636d7be5b6b9871c4daf58c728bda7be1dcc0dbee65897fc9429d381cc148bcd595116d0e822fba685d0b92ed8309dbc + ws: "npm:^7.5.10" + checksum: 10c0/14e704d723d7c3eaae94552251b50b31b3769dbfbc2b48f6cabe422b1bfc640dae20751997d8fd8bbe26a22c6865a46083e4d3621d7b200b19c79e515ef54bb9 languageName: node linkType: hard -"@react-native/eslint-config@npm:^0.81.1": - version: 0.81.5 - resolution: "@react-native/eslint-config@npm:0.81.5" +"@react-native/eslint-config@npm:^0.86.0": + version: 0.86.0 + resolution: "@react-native/eslint-config@npm:0.86.0" dependencies: "@babel/core": "npm:^7.25.2" "@babel/eslint-parser": "npm:^7.25.1" - "@react-native/eslint-plugin": "npm:0.81.5" - "@typescript-eslint/eslint-plugin": "npm:^7.1.1" - "@typescript-eslint/parser": "npm:^7.1.1" + "@react-native/eslint-plugin": "npm:0.86.0" + "@typescript-eslint/eslint-plugin": "npm:^8.36.0" + "@typescript-eslint/parser": "npm:^8.36.0" eslint-config-prettier: "npm:^8.5.0" eslint-plugin-eslint-comments: "npm:^3.2.0" eslint-plugin-ft-flow: "npm:^2.0.1" - eslint-plugin-jest: "npm:^27.9.0" - eslint-plugin-react: "npm:^7.30.1" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-native: "npm:^4.0.0" + eslint-plugin-jest: "npm:^29.0.1" + eslint-plugin-react: "npm:^7.37.5" + eslint-plugin-react-hooks: "npm:^7.0.1" + eslint-plugin-react-native: "npm:^5.0.0" peerDependencies: - eslint: ">=8" + eslint: ^8.0.0 || ^9.0.0 prettier: ">=2" - checksum: 10c0/86847d8277136c3ff6d59a9e4b5408a56e6297790f460a2f90e130afe365f7cdcabd1a32c893cb59f3616a5a425b04d7008120771d3c67de71b36945d3da70c5 + checksum: 10c0/51b3ab96620c8b4ebe14887b9455074de5dbecf87c8860fa065be13a1070a2f69270ecd7eb3a44e215cb49c1eeaa89204e9511606e7c6b452dbb87a1d2bedf3d + languageName: node + linkType: hard + +"@react-native/eslint-plugin@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/eslint-plugin@npm:0.86.0" + checksum: 10c0/4d8bd7451d75dc572369ab2769647b5ec624bbb13e4a924a35cd526ee57507e3667b2eeedfd79568073dc2fa9db598788fc81b39e0b071397fc854ffd36a3ee5 languageName: node linkType: hard -"@react-native/eslint-plugin@npm:0.81.5": - version: 0.81.5 - resolution: "@react-native/eslint-plugin@npm:0.81.5" - checksum: 10c0/fe95aee1b8b34c53be0b6f04d2e6a650790f220607ecfa2a5e48d18c90adfbd7117f605564d192a7dc6f675cc9745596902496b2541c5a31bef8d103412ad06e +"@react-native/gradle-plugin@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/gradle-plugin@npm:0.86.0" + checksum: 10c0/02d8f7ae14c3163a6acf7098b1227a7ffd66cbfde96b6b151a02739bfbc27f123e023bd3411383e9a7a33f18e4d4d82100448615b8955a0ff95e8dee5d1ef4e8 languageName: node linkType: hard -"@react-native/gradle-plugin@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/gradle-plugin@npm:0.81.1" - checksum: 10c0/875317017d583ff17c2ef17bcf39399d13abc41921f9659c9f62e9308e344202430a3051ac06e62843d1be0194e2acef0df660ba35d7a9bfc3607c43e9162ebd +"@react-native/jest-preset@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/jest-preset@npm:0.86.0" + dependencies: + "@jest/create-cache-key-function": "npm:^29.7.0" + "@react-native/js-polyfills": "npm:0.86.0" + babel-jest: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + regenerator-runtime: "npm:^0.13.2" + peerDependencies: + react: ^19.2.3 + checksum: 10c0/34f6ffe9c6cedbb23eaeffa801a3dfea75034740dca2c7685aa1bbef42a5f12aa735c17e041142a4551176410b641c35656861c94827e73341a39d40b20b5fbb languageName: node linkType: hard -"@react-native/js-polyfills@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/js-polyfills@npm:0.81.1" - checksum: 10c0/91b970ce9177e5dc8a5cd654036c2d912b322e9da09c618190fd8f5d9ef2ecac2ee43004b58c73bd93ec3035156c2707d3097755b8c943079ae85c5c38bdc1b8 +"@react-native/js-polyfills@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/js-polyfills@npm:0.86.0" + checksum: 10c0/63379d40d37b09fe371cc4f8a60304479ee59667a032072dded0b1e475519ff17f27bbaa39fcd463949ea9068c65eb045d5d4639ede8236a241f6e3cd295174c languageName: node linkType: hard -"@react-native/metro-babel-transformer@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/metro-babel-transformer@npm:0.81.1" +"@react-native/metro-babel-transformer@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/metro-babel-transformer@npm:0.86.0" dependencies: "@babel/core": "npm:^7.25.2" - "@react-native/babel-preset": "npm:0.81.1" - hermes-parser: "npm:0.29.1" + "@react-native/babel-preset": "npm:0.86.0" + hermes-parser: "npm:0.36.0" nullthrows: "npm:^1.1.1" peerDependencies: "@babel/core": "*" - checksum: 10c0/8604e71343af7dd53fc414d837b27e976dcd919ce9a2d78bab2c9d40c0ac231ce8fb3254fdfbd1d486c0b105e6afb20b8a669f28facf1e23e79420b27c95d55f + checksum: 10c0/8b4ab63d32f28f3663204110d37c50a8dd82eef622d57fb236f3d05b69bdfc1fe277f7572e4cf9135790921922f35fe4aea5f7c183fe17cd2ead19ed8e1db5d1 languageName: node linkType: hard -"@react-native/metro-config@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/metro-config@npm:0.81.1" +"@react-native/metro-config@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/metro-config@npm:0.86.0" dependencies: - "@react-native/js-polyfills": "npm:0.81.1" - "@react-native/metro-babel-transformer": "npm:0.81.1" - metro-config: "npm:^0.83.1" - metro-runtime: "npm:^0.83.1" - checksum: 10c0/117d3a39a5cb7fa277aba05b8f353a66ea913220ba1ec513cf89b20419b15bba4191e195289f206b2d04d42fd63728988f2e02319caae69e20e271a1ffcffc05 + "@react-native/js-polyfills": "npm:0.86.0" + "@react-native/metro-babel-transformer": "npm:0.86.0" + metro-config: "npm:^0.84.3" + metro-runtime: "npm:^0.84.3" + checksum: 10c0/92c043b8e4d959a3d8c0aa56940a9ff455c9de21bb6fe2a799fb5a847e45587d9783c3b55e3254f2b17fa71dfc66fff30ce0a70505e0d699dbbf2c76e0ff539c languageName: node linkType: hard -"@react-native/normalize-colors@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/normalize-colors@npm:0.81.1" - checksum: 10c0/67abd4b6e1a3871bd2f3a548bc6b9643245c0706e2d86a35de3fddd59b6fd93d0db2f5dbca4cdb0aa0104f6a9364705d200cc6a784e67acda10674d5900ecc9f +"@react-native/normalize-colors@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/normalize-colors@npm:0.86.0" + checksum: 10c0/d836506a642e1c636015fca23c84ca372b10fb1457df98f95e8bc5716399292d5740b94efe13f9be08c21323ddc3c2c45205d316f0f5440f24e5919b5075f69a languageName: node linkType: hard -"@react-native/typescript-config@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/typescript-config@npm:0.81.1" - checksum: 10c0/7a7bcf658ba1728c12515013821692e5303f2e31d6589e0df9ba525cf877e8429ee6dbb6f79bb9a1a9d38d93f2bf3bd8e38369a57e760abe12d0e55cceb398e7 +"@react-native/typescript-config@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/typescript-config@npm:0.86.0" + checksum: 10c0/66020e6d945e863847639b4932ef22082dad8ba4e345fe785b85987ae18a6cb56b31539c3502731238580ad96a9b1de32fac55e2e245debf693f039ec36fcffc languageName: node linkType: hard -"@react-native/virtualized-lists@npm:0.81.1": - version: 0.81.1 - resolution: "@react-native/virtualized-lists@npm:0.81.1" +"@react-native/virtualized-lists@npm:0.86.0": + version: 0.86.0 + resolution: "@react-native/virtualized-lists@npm:0.86.0" dependencies: invariant: "npm:^2.2.4" nullthrows: "npm:^1.1.1" peerDependencies: - "@types/react": ^19.1.0 + "@types/react": ^19.2.0 react: "*" - react-native: "*" + react-native: 0.86.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/1cf1c39afdd60c8d72a53250aa0284fcba1680b9218cb287b5ca6a4f1776e0200c6769bbf3e3c75dfe28a05a8797b9f7b562b1699de379c7f438cf2216270fb4 + checksum: 10c0/df5006e01e2f527f4fd46b93db17f3dbf8fd18c832e4ad9b1b43c544a83b4b2fca34ba72114ad9679968043e7fa6f9fe352bcee250799b9b973d0998b446ca50 languageName: node linkType: hard @@ -3513,6 +3786,13 @@ __metadata: languageName: node linkType: hard +"@simple-libs/hosted-git-info@npm:^1.0.2": + version: 1.0.2 + resolution: "@simple-libs/hosted-git-info@npm:1.0.2" + checksum: 10c0/6f22b598b9d37f3e37e409eb588126d14a68f62d52f6e2bb1d99745eb86de8843a02a6fbf7e7f4d026a07fcb1f98d0036d9dcb47363275fa86e67c237fadac75 + languageName: node + linkType: hard + "@simple-libs/stream-utils@npm:^1.1.0": version: 1.1.0 resolution: "@simple-libs/stream-utils@npm:1.1.0" @@ -3522,6 +3802,13 @@ __metadata: languageName: node linkType: hard +"@simple-libs/stream-utils@npm:^1.2.0": + version: 1.2.0 + resolution: "@simple-libs/stream-utils@npm:1.2.0" + checksum: 10c0/2788ac7b167d1b6c81b8c6fae2f5d9688b1f02ab31e9e15b33c9dc2ae920cf7de87869de10679be8957f9adb645c91c8919e271f3e34b6b4ec56daf725522dc7 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -3554,6 +3841,16 @@ __metadata: languageName: node linkType: hard +"@swmansion/react-native-bottom-sheet@npm:0.17.0-next.1": + version: 0.17.0-next.1 + resolution: "@swmansion/react-native-bottom-sheet@npm:0.17.0-next.1" + peerDependencies: + react: ">=18.0.0" + react-native: ">=0.76.0" + checksum: 10c0/8ea6751efc9cb2c11ede4f90d2378c95270dc707c08b9718b11bf28c1a4e5b09d33887801e682a7273c9cb1ce8675daba7cf0da0e6ac5f944faf259326d528a9 + languageName: node + linkType: hard + "@tootallnate/quickjs-emscripten@npm:^0.23.0": version: 0.23.0 resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" @@ -3561,6 +3858,59 @@ __metadata: languageName: node linkType: hard +"@ts-morph/common@npm:~0.29.0": + version: 0.29.0 + resolution: "@ts-morph/common@npm:0.29.0" + dependencies: + minimatch: "npm:^10.0.1" + path-browserify: "npm:^1.0.1" + tinyglobby: "npm:^0.2.14" + checksum: 10c0/97ab8ca66558b817e5475a8893ee1476ab760a3ac71fa9868413d95ddbaaf909eda81716e3a8d14291cbf449e624af66de81bcddd3ec2e36525728b4edf5e8ee + languageName: node + linkType: hard + +"@turbo/darwin-64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/darwin-64@npm:2.10.8" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@turbo/darwin-arm64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/darwin-arm64@npm:2.10.8" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@turbo/linux-64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/linux-64@npm:2.10.8" + conditions: (os=android | os=linux) & cpu=x64 + languageName: node + linkType: hard + +"@turbo/linux-arm64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/linux-arm64@npm:2.10.8" + conditions: (os=android | os=linux) & cpu=arm64 + languageName: node + linkType: hard + +"@turbo/windows-64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/windows-64@npm:2.10.8" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@turbo/windows-arm64@npm:2.10.8": + version: 2.10.8 + resolution: "@turbo/windows-arm64@npm:2.10.8" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@types/babel__core@npm:^7.1.14": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" @@ -3627,13 +3977,6 @@ __metadata: languageName: node linkType: hard -"@types/hammerjs@npm:^2.0.36": - version: 2.0.46 - resolution: "@types/hammerjs@npm:2.0.46" - checksum: 10c0/f3c1cb20dc2f0523f7b8c76065078544d50d8ae9b0edc1f62fed657210ed814266ff2dfa835d2c157a075991001eec3b64c88bf92e3e6e895c0db78d05711d06 - languageName: node - linkType: hard - "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" @@ -3669,7 +4012,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -3708,19 +4051,21 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^19.1.0": - version: 19.2.7 - resolution: "@types/react@npm:19.2.7" +"@types/react-test-renderer@npm:^19.1.0": + version: 19.1.0 + resolution: "@types/react-test-renderer@npm:19.1.0" dependencies: - csstype: "npm:^3.2.2" - checksum: 10c0/a7b75f1f9fcb34badd6f84098be5e35a0aeca614bc91f93d2698664c0b2ba5ad128422bd470ada598238cebe4f9e604a752aead7dc6f5a92261d0c7f9b27cfd1 + "@types/react": "npm:*" + checksum: 10c0/799654e430df10aeaf267d71507fb64ec151359ead7e3774111bfd4abce7e0911dba461811195c06c22a6d17496ea92537d3185320ff4112fe29954cad1b9152 languageName: node linkType: hard -"@types/semver@npm:^7.3.12": - version: 7.7.1 - resolution: "@types/semver@npm:7.7.1" - checksum: 10c0/c938aef3bf79a73f0f3f6037c16e2e759ff40c54122ddf0b2583703393d8d3127130823facb880e694caa324eb6845628186aac1997ee8b31dc2d18fafe26268 +"@types/react@npm:*, @types/react@npm:^19.2.0": + version: 19.2.17 + resolution: "@types/react@npm:19.2.17" + dependencies: + csstype: "npm:^3.2.2" + checksum: 10c0/bc2c4af96b3e480604424de70d5ebda90c5f4b485df471858c0bc2d7d70364b606ec3c4d8579f94f01aa0c6c0591f56bcf14cba5689f5eea4b74250ccdc3a232 languageName: node linkType: hard @@ -3747,184 +4092,138 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.1.1": - version: 7.18.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" +"@typescript-eslint/eslint-plugin@npm:^8.36.0": + version: 8.63.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.63.0" dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/type-utils": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" + "@eslint-community/regexpp": "npm:^4.12.2" + "@typescript-eslint/scope-manager": "npm:8.63.0" + "@typescript-eslint/type-utils": "npm:8.63.0" + "@typescript-eslint/utils": "npm:8.63.0" + "@typescript-eslint/visitor-keys": "npm:8.63.0" + ignore: "npm:^7.0.5" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^1.3.0" + ts-api-utils: "npm:^2.5.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/2b37948fa1b0dab77138909dabef242a4d49ab93e4019d4ef930626f0a7d96b03e696cd027fa0087881c20e73be7be77c942606b4a76fa599e6b37f6985304c3 + "@typescript-eslint/parser": ^8.63.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/906a406d85ad80cbe06cb688d4382c34dfb36ebfbd710814f7f9651265b88cf53684ee5275a402eb0eb1243628c504019714f00c1331e54d499cdc7d7c14b5ba languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.1.1": - version: 7.18.0 - resolution: "@typescript-eslint/parser@npm:7.18.0" +"@typescript-eslint/parser@npm:^8.36.0": + version: 8.63.0 + resolution: "@typescript-eslint/parser@npm:8.63.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" + "@typescript-eslint/scope-manager": "npm:8.63.0" + "@typescript-eslint/types": "npm:8.63.0" + "@typescript-eslint/typescript-estree": "npm:8.63.0" + "@typescript-eslint/visitor-keys": "npm:8.63.0" + debug: "npm:^4.4.3" peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/370e73fca4278091bc1b657f85e7d74cd52b24257ea20c927a8e17546107ce04fbf313fec99aed0cc2a145ddbae1d3b12e9cc2c1320117636dc1281bcfd08059 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/28fd1db23ff16627936a0d630c6761df1d17046147b6e0ce6a144d60c0fbeddc756c3208e552f9e53c4d6a35f554205f7de3184b1ab45220a2fbc3bb8d1ac62b languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" +"@typescript-eslint/project-service@npm:8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/project-service@npm:8.63.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - checksum: 10c0/861253235576c1c5c1772d23cdce1418c2da2618a479a7de4f6114a12a7ca853011a1e530525d0931c355a8fd237b9cd828fac560f85f9623e24054fd024726f + "@typescript-eslint/tsconfig-utils": "npm:^8.63.0" + "@typescript-eslint/types": "npm:^8.63.0" + debug: "npm:^4.4.3" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/d49ce51b128d83a0e87e01d7a30f2295d77713d913abddc817df7ac3aeb1333b5dbb0c634ad0d0941f51cdd84ad86a036178b90bb370aa819ff59082377ca0ee languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/scope-manager@npm:7.18.0" +"@typescript-eslint/scope-manager@npm:8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/scope-manager@npm:8.63.0" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e + "@typescript-eslint/types": "npm:8.63.0" + "@typescript-eslint/visitor-keys": "npm:8.63.0" + checksum: 10c0/394245a25f852170adbdaaca9364d5d36a0e97e69e691e5594d5a3ced892a7eb78cf6e7a17cbc095490a168b60bb3ad6f6d48cd167c4b9cbc568bf0f785ab926 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/type-utils@npm:7.18.0" - dependencies: - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.3.0" +"@typescript-eslint/tsconfig-utils@npm:8.63.0, @typescript-eslint/tsconfig-utils@npm:^8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.63.0" peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/ad92a38007be620f3f7036f10e234abdc2fdc518787b5a7227e55fd12896dacf56e8b34578723fbf9bea8128df2510ba8eb6739439a3879eda9519476d5783fd + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/378a220fa5d0aaaf38887d667d1ddf8addfb7601af491230e77e32773158f9aad7723b8e25cebf0f95debc2217ca7b9ddf4e9ebd506e319fe1f9fe4244274013 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 10c0/7febd3a7f0701c0b927e094f02e82d8ee2cada2b186fcb938bc2b94ff6fbad88237afc304cbaf33e82797078bbbb1baf91475f6400912f8b64c89be79bfa4ddf - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/types@npm:7.18.0" - checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" +"@typescript-eslint/type-utils@npm:8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/type-utils@npm:8.63.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/d7984a3e9d56897b2481940ec803cb8e7ead03df8d9cfd9797350be82ff765dfcf3cfec04e7355e1779e948da8f02bc5e11719d07a596eb1cb995c48a95e38cf + "@typescript-eslint/types": "npm:8.63.0" + "@typescript-eslint/typescript-estree": "npm:8.63.0" + "@typescript-eslint/utils": "npm:8.63.0" + debug: "npm:^4.4.3" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/36f6ba389d05e57f2f1de0f21406a46694e39da83248d7d5eefb1601d6a37a3d2382ee6f1b1b0e63b78465d8d830eeaec1503aaefbad70b1030e59fb15307aae languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 +"@typescript-eslint/types@npm:8.63.0, @typescript-eslint/types@npm:^8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/types@npm:8.63.0" + checksum: 10c0/270bd2b2affdc173dd7e9e1bf1419a6f7a2fa8ff1fca5c613da88f6e44c433a1412887e513d24233a4a6112bdc3439d3e4cadc4f492eb1a6dc2a377495a38836 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/utils@npm:7.18.0" +"@typescript-eslint/typescript-estree@npm:8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.63.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/project-service": "npm:8.63.0" + "@typescript-eslint/tsconfig-utils": "npm:8.63.0" + "@typescript-eslint/types": "npm:8.63.0" + "@typescript-eslint/visitor-keys": "npm:8.63.0" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.5.0" peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/84ca87141a0e7d59fb91e7baef36e20d4f00f1996aec6dfb1909c40496f13e54a13102c12b7cbe89285d04ca7975faa64d5683ff0d44ec9baa7be5207540142c languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.10.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" +"@typescript-eslint/utils@npm:8.63.0, @typescript-eslint/utils@npm:^8.0.0": + version: 8.63.0 + resolution: "@typescript-eslint/utils@npm:8.63.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" - semver: "npm:^7.3.7" + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.63.0" + "@typescript-eslint/types": "npm:8.63.0" + "@typescript-eslint/typescript-estree": "npm:8.63.0" peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/f09b7d9952e4a205eb1ced31d7684dd55cee40bf8c2d78e923aa8a255318d97279825733902742c09d8690f37a50243f4c4d383ab16bd7aefaf9c4b438f785e1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/1b0bb66c2dc11d7c3ea4e840294e35062e5f85b6d1d7d94b37e94e52a2fa71e76adf277602a183832c23d3deeb1f129d7aeb3ce960c1fc9b6d1136a4d61bd54a languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" +"@typescript-eslint/visitor-keys@npm:8.63.0": + version: 8.63.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.63.0" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - eslint-visitor-keys: "npm:^3.3.0" - checksum: 10c0/7c3b8e4148e9b94d9b7162a596a1260d7a3efc4e65199693b8025c71c4652b8042501c0bc9f57654c1e2943c26da98c0f77884a746c6ae81389fcb0b513d995d - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 + "@typescript-eslint/types": "npm:8.63.0" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10c0/595b47b08efecc35d93a8ac072798f9dc2371a371f03a1a03ab134a8505fe422fc647014bd096eac75a3d487c5eecf24393048ca88ed06f759d00115c11dd8bc languageName: node linkType: hard @@ -3935,6 +4234,20 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:^0.8.8": + version: 0.8.13 + resolution: "@xmldom/xmldom@npm:0.8.13" + checksum: 10c0/06405ee6fffba631abf715a305ace338420ebcea8baf1317f19f2752f5c505952b7df45159908e7be8451a42faa54326b780616ab4d08242b20477b2973da24b + languageName: node + linkType: hard + +"@xmldom/xmldom@npm:^0.9.10": + version: 0.9.10 + resolution: "@xmldom/xmldom@npm:0.9.10" + checksum: 10c0/38a9c9b95450d7fccebc61371c8e0b90ceaae992886484108333d29ccbd2640e3555b6af012f15ce1beb5067aeb40486659b6183fad38af179e82d28028bfc5d + languageName: node + linkType: hard + "JSONStream@npm:^1.3.5": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -3947,10 +4260,10 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:^4.0.0": - version: 4.0.0 - resolution: "abbrev@npm:4.0.0" - checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5 +"abbrev@npm:^5.0.0": + version: 5.0.0 + resolution: "abbrev@npm:5.0.0" + checksum: 10c0/8e88f5c798ea4562d28c5a3e9ad69e3879890bc5d695d8f2dffb8609be4c890aacc8f80ef4553fdd2c6a62d70c2ce8bc57b38074e383beb7487bdafa9ed42ea5 languageName: node linkType: hard @@ -3963,7 +4276,17 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.7, accepts@npm:~1.3.8": +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef + languageName: node + linkType: hard + +"accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -3983,11 +4306,11 @@ __metadata: linkType: hard "acorn@npm:^8.15.0": - version: 8.15.0 - resolution: "acorn@npm:8.15.0" + version: 8.18.0 + resolution: "acorn@npm:8.18.0" bin: acorn: bin/acorn - checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec + checksum: 10c0/be771be2135cc07910cf76f444ad514d7dcfd6d4a8026e597e93155275abc8ef61eee12211d52146e9d962874269b634f397464942087be013c89d0c54c5f8e5 languageName: node linkType: hard @@ -4008,27 +4331,27 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" +"ajv@npm:^6.12.4, ajv@npm:^6.14.0": + version: 6.15.0 + resolution: "ajv@npm:6.15.0" dependencies: fast-deep-equal: "npm:^3.1.1" fast-json-stable-stringify: "npm:^2.0.0" json-schema-traverse: "npm:^0.4.1" uri-js: "npm:^4.2.2" - checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 + checksum: 10c0/67966499dd272ecde1c2e467084411132891523d057487587879d39ac04207f4351b7b2324c83198013967fbfa632c1612adc960114a30770fbe07a0773b32c2 languageName: node linkType: hard "ajv@npm:^8.11.0": - version: 8.17.1 - resolution: "ajv@npm:8.17.1" + version: 8.20.0 + resolution: "ajv@npm:8.20.0" dependencies: fast-deep-equal: "npm:^3.1.3" fast-uri: "npm:^3.0.1" json-schema-traverse: "npm:^1.0.0" require-from-string: "npm:^2.0.2" - checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + checksum: 10c0/5df9a1c8f83863cde1bd3a9ddb426f599718f88e3dc9153616c79fb28e0be455335830d7f21d745576519f057b371352daa31047b6a33d7036fe08777d60cf2a languageName: node linkType: hard @@ -4073,7 +4396,7 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^6.0.1": +"ansi-regex@npm:^6.2.2": version: 6.2.2 resolution: "ansi-regex@npm:6.2.2" checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f @@ -4105,7 +4428,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.1.0": +"ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": version: 6.2.3 resolution: "ansi-styles@npm:6.2.3" checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 @@ -4123,9 +4446,9 @@ __metadata: linkType: hard "appdirsjs@npm:^1.2.4": - version: 1.2.7 - resolution: "appdirsjs@npm:1.2.7" - checksum: 10c0/79dd8d7a764cdde2b47efc4383e054814be917ba0cd661ee324bdf3fd11542834548316faea31344f96a7ebc898b5f89c11d1418f825a1d40c396bf1ecb0902b + version: 1.2.8 + resolution: "appdirsjs@npm:1.2.8" + checksum: 10c0/dc16a9aa5e9fd2fc8c7a0daaa7184b74c6e4e52afe9242ae73b683af16468d55eb9325b03926721c77307de668696a2e2e935253d107babe8daed96f822d849b languageName: node linkType: hard @@ -4145,23 +4468,23 @@ __metadata: languageName: node linkType: hard -"arkregex@npm:0.0.5": - version: 0.0.5 - resolution: "arkregex@npm:0.0.5" +"arkregex@npm:0.0.8": + version: 0.0.8 + resolution: "arkregex@npm:0.0.8" dependencies: - "@ark/util": "npm:0.56.0" - checksum: 10c0/1a39510e04d69b9287b9b53d3965afcc4ef27bdd9ff9c21a78092fcb841f35c11227d8476be66d2f76347deccfd10c202f395bd871383c328057ad004ffe7ebd + "@ark/util": "npm:0.56.2" + checksum: 10c0/ea1385599fded2e4153ce5cfb75f86e18f221b9c73ddd4071ffe3f63cfffcacd7a16748f1588de48658f7def2069e2a6b7235c3da7f1e11f12d1b05d2c892f9a languageName: node linkType: hard "arktype@npm:^2.1.15": - version: 2.1.29 - resolution: "arktype@npm:2.1.29" + version: 2.2.3 + resolution: "arktype@npm:2.2.3" dependencies: - "@ark/schema": "npm:0.56.0" - "@ark/util": "npm:0.56.0" - arkregex: "npm:0.0.5" - checksum: 10c0/c89cd5cc9eee7a5e14df0f32b228c06760b99440dabf2ed2d9272877a1607d7f27641d4105d1466b70fc620007fe864ddd826acee11c07102388c8dd301a20fe + "@ark/schema": "npm:0.56.2" + "@ark/util": "npm:0.56.2" + arkregex: "npm:0.0.8" + checksum: 10c0/01d6cd9f1c84807772623ad8df5825df9646de1aca4b17869604d523942c92c297b654c930f405338065e18ab52691e00da3e7e2b581039e4aded62d1a9c9e0f languageName: node linkType: hard @@ -4376,15 +4699,15 @@ __metadata: linkType: hard "babel-plugin-polyfill-corejs2@npm:^0.4.14": - version: 0.4.14 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.14" + version: 0.4.17 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.17" dependencies: - "@babel/compat-data": "npm:^7.27.7" - "@babel/helper-define-polyfill-provider": "npm:^0.6.5" + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-define-polyfill-provider": "npm:^0.6.8" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10c0/d74cba0600a6508e86d220bde7164eb528755d91be58020e5ea92ea7fbb12c9d8d2c29246525485adfe7f68ae02618ec428f9a589cac6cbedf53cc3972ad7fbe + checksum: 10c0/1284960ea403c63b0dd598f338666c4b17d489aefee30b4da6a7313eff1d91edffb0ccf26341a6e5d94231684b74e016eade66b3921ea112f8b0e4980fa08a5c languageName: node linkType: hard @@ -4401,22 +4724,22 @@ __metadata: linkType: hard "babel-plugin-polyfill-regenerator@npm:^0.6.5": - version: 0.6.5 - resolution: "babel-plugin-polyfill-regenerator@npm:0.6.5" + version: 0.6.8 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.8" dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.6.5" + "@babel/helper-define-polyfill-provider": "npm:^0.6.8" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 10c0/63aa8ed716df6a9277c6ab42b887858fa9f57a70cc1d0ae2b91bdf081e45d4502848cba306fb60b02f59f99b32fd02ff4753b373cac48ccdac9b7d19dd56f06d + checksum: 10c0/7c8b2497c29fa880e0acdc8e7b93e29b81b154179b83beb0476eb2c4e7a78b6b42fc35c2554ca250c9bd6d39941eaf75416254b8592ce50979f9a12e1d51c049 languageName: node linkType: hard -"babel-plugin-syntax-hermes-parser@npm:0.29.1": - version: 0.29.1 - resolution: "babel-plugin-syntax-hermes-parser@npm:0.29.1" +"babel-plugin-syntax-hermes-parser@npm:0.36.0": + version: 0.36.0 + resolution: "babel-plugin-syntax-hermes-parser@npm:0.36.0" dependencies: - hermes-parser: "npm:0.29.1" - checksum: 10c0/a6d95e4a7079976e477636d18509272a7a185930e143c61d0421a36096e85905563630ac4f0f317518b6db37f50daaefc1828d575b3d5fb090a55e9d39d2534c + hermes-parser: "npm:0.36.0" + checksum: 10c0/3c20d2b2595e890bf7bf14b48a1dc6eb2ad2625e04f942254f3676440e20489eb8266fba8f8077194d294dfb67552b6b969bb40b93c873b88fdc319528dc2606 languageName: node linkType: hard @@ -4482,6 +4805,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b + languageName: node + linkType: hard + "base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -4489,19 +4819,19 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.9.0": - version: 2.9.11 - resolution: "baseline-browser-mapping@npm:2.9.11" +"baseline-browser-mapping@npm:^2.10.44": + version: 2.11.10 + resolution: "baseline-browser-mapping@npm:2.11.10" bin: - baseline-browser-mapping: dist/cli.js - checksum: 10c0/eba49fcc1b33ab994aeeb73a4848f2670e06a0886dd5b903689ae6f60d47e7f1bea9262dbb2548c48179e858f7eda2b82ddf941ae783b862f4dcc51085a246f2 + baseline-browser-mapping: dist/cli.cjs + checksum: 10c0/6e46bf9e1e46d96d909b4f754968603a291dea22fbb051cf86aa73b53f3a4c8ba922bdc1d6b617f5147403b289746e8549e344affcee7a1be87a09020cd73ce1 languageName: node linkType: hard "basic-ftp@npm:^5.0.2": - version: 5.1.0 - resolution: "basic-ftp@npm:5.1.0" - checksum: 10c0/397d5ed490f4d3b8b2dcd7afdf8e9fcf714a7d1c394a6c66b31704baf49c9fc250f1742f6189136a76b983675edf3d986b7ed93d253dc6477e65a567cf1e04c0 + version: 5.3.1 + resolution: "basic-ftp@npm:5.3.1" + checksum: 10c0/03511b488cd292abfa82a8c0ea3b9573b40d12d2f1518d6f41a9461b012b3376d3e6d50679b38d9b2b4f48fd6e8e0418ac196312ee7e2da13cb801169940d1c3 languageName: node linkType: hard @@ -4512,6 +4842,13 @@ __metadata: languageName: node linkType: hard +"big-integer@npm:1.6.x": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 10c0/9604224b4c2ab3c43c075d92da15863077a9f59e5d4205f4e7e76acd0cd47e8d469ec5e5dba8d9b32aa233951893b29329ca56ac80c20ce094b4a647a66abae0 + languageName: node + linkType: hard + "bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -4524,8 +4861,8 @@ __metadata: linkType: hard "body-parser@npm:^1.20.3": - version: 1.20.4 - resolution: "body-parser@npm:1.20.4" + version: 1.20.6 + resolution: "body-parser@npm:1.20.6" dependencies: bytes: "npm:~3.1.2" content-type: "npm:~1.0.5" @@ -4535,11 +4872,11 @@ __metadata: http-errors: "npm:~2.0.1" iconv-lite: "npm:~0.4.24" on-finished: "npm:~2.4.1" - qs: "npm:~6.14.0" + qs: "npm:~6.15.1" raw-body: "npm:~2.5.3" type-is: "npm:~1.6.18" unpipe: "npm:~1.0.0" - checksum: 10c0/569c1e896297d1fcd8f34026c8d0ab70b90d45343c15c5d8dff5de2bad08125fc1e2f8c2f3f4c1ac6c0caaad115218202594d37dcb8d89d9b5dcae1c2b736aa9 + checksum: 10c0/ad477209f1e714c41fa892a7d2fe22e10b23262103cc25cc6492dd3e6f7869cd2d8b00928b543a1a14d3c3663432452a192efd00422fad6f3687b0e38f7e3b07 languageName: node linkType: hard @@ -4550,22 +4887,49 @@ __metadata: languageName: node linkType: hard +"bplist-creator@npm:0.1.1": + version: 0.1.1 + resolution: "bplist-creator@npm:0.1.1" + dependencies: + stream-buffers: "npm:2.2.x" + checksum: 10c0/427ec37263ce0e8c68a83f595fc9889a9cbf2e6fda2de18e1f8ef7f0c6ce68c0cdbb7c9c1f3bb3f2d217407af8cffbdf254bf0f71c99f2186175d07752f08a47 + languageName: node + linkType: hard + +"bplist-parser@npm:0.3.2": + version: 0.3.2 + resolution: "bplist-parser@npm:0.3.2" + dependencies: + big-integer: "npm:1.6.x" + checksum: 10c0/4dc307c11d2511a01255e87e370d4ab6f1962b35fdc27605fd4ce9a557a259c2dc9f87822617ddb1f7aa062a71e30ef20d6103329ac7ce235628f637fb0ed763 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": - version: 1.1.12 - resolution: "brace-expansion@npm:1.1.12" + version: 1.1.18 + resolution: "brace-expansion@npm:1.1.18" dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10c0/975fecac2bb7758c062c20d0b3b6288c7cc895219ee25f0a64a9de662dbac981ff0b6e89909c3897c1f84fa353113a721923afdec5f8b2350255b097f12b1f73 + checksum: 10c0/3432c18a9e2ebf94162d4effb62198bd0adea06a9f332b2c0188df5d5e30b1e51ea3c848b6608e47d0b857ebe1ea5b3888ed3326dd3c4f6f9645c94153cf9c14 languageName: node linkType: hard -"brace-expansion@npm:^2.0.1": - version: 2.0.2 - resolution: "brace-expansion@npm:2.0.2" +"brace-expansion@npm:^2.0.2": + version: 2.1.4 + resolution: "brace-expansion@npm:2.1.4" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf + checksum: 10c0/6c0a0e2573eac1dc565b52b1e1bfbeba39bf1830d106ebbc61ff1eaefcf610e9111cd3baa091addd18e33292135c99e019d3184d966389d85dc958fdcdc1449f + languageName: node + linkType: hard + +"brace-expansion@npm:^5.0.8": + version: 5.0.9 + resolution: "brace-expansion@npm:5.0.9" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10c0/3dea38884a1c3c8b1c9c44a7402a0c76fca460f70cffb3127242b0b4cbf4472019e022ade021eec44838ff19f1dac2625dfd11dd459d7e1e055b0698a8d52fec languageName: node linkType: hard @@ -4578,18 +4942,18 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.20.4, browserslist@npm:^4.24.0, browserslist@npm:^4.28.0": - version: 4.28.1 - resolution: "browserslist@npm:4.28.1" +"browserslist@npm:^4.20.4, browserslist@npm:^4.24.0, browserslist@npm:^4.28.1": + version: 4.28.7 + resolution: "browserslist@npm:4.28.7" dependencies: - baseline-browser-mapping: "npm:^2.9.0" - caniuse-lite: "npm:^1.0.30001759" - electron-to-chromium: "npm:^1.5.263" - node-releases: "npm:^2.0.27" - update-browserslist-db: "npm:^1.2.0" + baseline-browser-mapping: "npm:^2.10.44" + caniuse-lite: "npm:^1.0.30001806" + electron-to-chromium: "npm:^1.5.393" + node-releases: "npm:^2.0.51" + update-browserslist-db: "npm:^1.2.3" bin: browserslist: cli.js - checksum: 10c0/545a5fa9d7234e3777a7177ec1e9134bb2ba60a69e6b95683f6982b1473aad347c77c1264ccf2ac5dea609a9731fbfbda6b85782bdca70f80f86e28a402504bd + checksum: 10c0/dc41922a9ff0d81e5492498bdab2d932e3a3222f4277814ba38ee64f4e51f26e5244a7cce0777b4cac3ceff6eb196f5cadbb2a832620973a7f9c39611f6bc78e languageName: node linkType: hard @@ -4660,26 +5024,7 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^20.0.1": - version: 20.0.3 - resolution: "cacache@npm:20.0.3" - dependencies: - "@npmcli/fs": "npm:^5.0.0" - fs-minipass: "npm:^3.0.0" - glob: "npm:^13.0.0" - lru-cache: "npm:^11.1.0" - minipass: "npm:^7.0.3" - minipass-collect: "npm:^2.0.1" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - p-map: "npm:^7.0.2" - ssri: "npm:^13.0.0" - unique-filename: "npm:^5.0.0" - checksum: 10c0/c7da1ca694d20e8f8aedabd21dc11518f809a7d2b59aa76a1fc655db5a9e62379e465c157ddd2afe34b19230808882288effa6911b2de26a088a6d5645123462 - languageName: node - linkType: hard - -"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": +"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" dependencies: @@ -4689,15 +5034,15 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": - version: 1.0.8 - resolution: "call-bind@npm:1.0.8" +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8, call-bind@npm:^1.0.9": + version: 1.0.9 + resolution: "call-bind@npm:1.0.9" dependencies: - call-bind-apply-helpers: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + get-intrinsic: "npm:^1.3.0" set-function-length: "npm:^1.2.2" - checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4 + checksum: 10c0/a6621f6da1444481919ce3b4983dff725691e0754d3507ae483ce56e54985f2da7d6f1df512c56dbf28660745cf1ca52553f1fc9aef5557f3ce353ef14fab714 languageName: node linkType: hard @@ -4732,10 +5077,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001759": - version: 1.0.30001762 - resolution: "caniuse-lite@npm:1.0.30001762" - checksum: 10c0/93707eac5b0240af3f2ce6e2d7ab504a6fefcf9c2f9cd8fb9d488e496a333c61e557dab0472c1b00c17bc386a5dbb792aa4c778cda2d768e17f986617d7aec53 +"caniuse-lite@npm:^1.0.30001806": + version: 1.0.30001806 + resolution: "caniuse-lite@npm:1.0.30001806" + checksum: 10c0/9442c8afff0968e9b2ce0104a7340c1ce4a5c09f469ccb9eef10d25712ea0afe542486e5318c697c70dd502f988cfc04eaa1c9438c92ac3bcf4d708a2a17bee1 languageName: node linkType: hard @@ -4764,9 +5109,9 @@ __metadata: linkType: hard "chardet@npm:^2.1.1": - version: 2.1.1 - resolution: "chardet@npm:2.1.1" - checksum: 10c0/d8391dd412338442b3de0d3a488aa9327f8bcf74b62b8723d6bd0b85c4084d50b731320e0a7c710edb1d44de75969995d2784b80e4c13b004a6c7a0db4c6e793 + version: 2.2.0 + resolution: "chardet@npm:2.2.0" + checksum: 10c0/8d43a1dd3ce535aa070d04139fae62f879b4388394eb1d857364ce416675a1f0f63974fba8208e9cd11b49e1a6da3e65ea6393d0fc654a8c4217c0d74c16b1b4 languageName: node linkType: hard @@ -4800,17 +5145,16 @@ __metadata: languageName: node linkType: hard -"chromium-edge-launcher@npm:^0.2.0": - version: 0.2.0 - resolution: "chromium-edge-launcher@npm:0.2.0" +"chromium-edge-launcher@npm:^0.3.0": + version: 0.3.0 + resolution: "chromium-edge-launcher@npm:0.3.0" dependencies: "@types/node": "npm:*" escape-string-regexp: "npm:^4.0.0" is-wsl: "npm:^2.2.0" lighthouse-logger: "npm:^1.0.0" mkdirp: "npm:^1.0.4" - rimraf: "npm:^3.0.2" - checksum: 10c0/880972816dd9b95c0eb77d1f707569667a8cce7cc29fe9c8d199c47fdfbe4971e9da3e5a29f61c4ecec29437ac7cebbbb5afc30bec96306579d1121e7340606a + checksum: 10c0/ad04a75bf53ebed0b7adc5bd133587369b0c2e55c92fe460eb6ccec5efe03c161a7466756173969867a2acbe02dd40449186bd74671dd892520492283d4ff43d languageName: node linkType: hard @@ -4829,9 +5173,9 @@ __metadata: linkType: hard "ci-info@npm:^4.3.1": - version: 4.3.1 - resolution: "ci-info@npm:4.3.1" - checksum: 10c0/7dd82000f514d76ddfe7775e4cb0d66e5c638f5fa0e2a3be29557e898da0d32ac04f231217d414d07fb968b1fbc6d980ee17ddde0d2c516f23da9cfff608f6c1 + version: 4.4.0 + resolution: "ci-info@npm:4.4.0" + checksum: 10c0/44156201545b8dde01aa8a09ee2fe9fc7a73b1bef9adbd4606c9f61c8caeeb73fb7a575c88b0443f7b4edb5ee45debaa59ed54ba5f99698339393ca01349eb3a languageName: node linkType: hard @@ -4844,6 +5188,13 @@ __metadata: languageName: node linkType: hard +"citty@npm:^0.2.2": + version: 0.2.2 + resolution: "citty@npm:0.2.2" + checksum: 10c0/c896c9dcd187d2a16685706d11428dcdec9eb59aa13fe50aff7b12e1d3521f1bf434d6a5316fe75a341f8ba5ce1d2beceb84f7f261d018985a73d3f6f2a793e3 + languageName: node + linkType: hard + "cjs-module-lexer@npm:^1.0.0": version: 1.4.3 resolution: "cjs-module-lexer@npm:1.4.3" @@ -4884,9 +5235,9 @@ __metadata: linkType: hard "cli-spinners@npm:^3.2.0": - version: 3.3.0 - resolution: "cli-spinners@npm:3.3.0" - checksum: 10c0/ce7278be322655e564df4383a2d79ad2c357b43e5771428f33ca69334fde6881d050652ee19854e9ab177867850c9365c2090fdb9fae145b23ceee21bdc77b7e + version: 3.4.0 + resolution: "cli-spinners@npm:3.4.0" + checksum: 10c0/91296c32e147d5b973c9d439d1512306499215437b92f0c0d8be44ec850b555acb8795c19c606b2f6747f31d50c4e41fdde7dcef653f18f0ae7cdd58e99a4764 languageName: node linkType: hard @@ -4919,6 +5270,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^9.0.1": + version: 9.0.1 + resolution: "cliui@npm:9.0.1" + dependencies: + string-width: "npm:^7.2.0" + strip-ansi: "npm:^7.1.0" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/13441832e9efe7c7a76bd2b8e683555c478d461a9f249dc5db9b17fe8d4b47fa9277b503914b90bd00e4a151abb6b9b02b2288972ffe2e5e3ca40bcb1c2330d3 + languageName: node + linkType: hard + "clone@npm:^1.0.2": version: 1.0.4 resolution: "clone@npm:1.0.4" @@ -4933,6 +5295,13 @@ __metadata: languageName: node linkType: hard +"code-block-writer@npm:^13.0.3": + version: 13.0.3 + resolution: "code-block-writer@npm:13.0.3" + checksum: 10c0/87db97b37583f71cfd7eced8bf3f0a0a0ca53af912751a734372b36c08cd27f3e8a4878ec05591c0cd9ae11bea8add1423e132d660edd86aab952656dd41fd66 + languageName: node + linkType: hard + "collect-v8-coverage@npm:^1.0.0": version: 1.0.3 resolution: "collect-v8-coverage@npm:1.0.3" @@ -5092,10 +5461,10 @@ __metadata: languageName: node linkType: hard -"confbox@npm:^0.2.2": - version: 0.2.2 - resolution: "confbox@npm:0.2.2" - checksum: 10c0/7c246588d533d31e8cdf66cb4701dff6de60f9be77ab54c0d0338e7988750ac56863cc0aca1b3f2046f45ff223a765d3e5d4977a7674485afcd37b6edf3fd129 +"confbox@npm:^0.2.2, confbox@npm:^0.2.4": + version: 0.2.4 + resolution: "confbox@npm:0.2.4" + checksum: 10c0/4c36af33d9df7034300c452f7b289179264493bd0671fa81b995a0d70dc897b1d37f1af10d3ffb187f178d17ba1ed2ba167ed0f599ba3a139c271205dd553f73 languageName: node linkType: hard @@ -5111,7 +5480,7 @@ __metadata: languageName: node linkType: hard -"consola@npm:^3.2.3, consola@npm:^3.4.0, consola@npm:^3.4.2": +"consola@npm:^3.2.3, consola@npm:^3.4.0": version: 3.4.2 resolution: "consola@npm:3.4.2" checksum: 10c0/7cebe57ecf646ba74b300bcce23bff43034ed6fbec9f7e39c27cee1dc00df8a21cd336b466ad32e304ea70fba04ec9e890c200270de9a526ce021ba8a7e4c11a @@ -5135,11 +5504,11 @@ __metadata: linkType: hard "conventional-changelog-angular@npm:^8.1.0": - version: 8.1.0 - resolution: "conventional-changelog-angular@npm:8.1.0" + version: 8.3.1 + resolution: "conventional-changelog-angular@npm:8.3.1" dependencies: compare-func: "npm:^2.0.0" - checksum: 10c0/b82aab869117fd9bd6ccfa960521e7638d3c2a3599c95fd5ba30d3b3fe972b5f819af4d57229f2973a7129ea18546cdf5822004565cab1ee35355cc90ac4588f + checksum: 10c0/a3776ff7066004040d7d25d2b72fe8f9fee4f1fc5dc6c929ab281899b8c7a6dd6408130064344515b37a4f91d2a9fb90b69cce0bab55415c72a8ba3ee801c2b6 languageName: node linkType: hard @@ -5153,11 +5522,11 @@ __metadata: linkType: hard "conventional-changelog-conventionalcommits@npm:^9.1.0": - version: 9.1.0 - resolution: "conventional-changelog-conventionalcommits@npm:9.1.0" + version: 9.3.1 + resolution: "conventional-changelog-conventionalcommits@npm:9.3.1" dependencies: compare-func: "npm:^2.0.0" - checksum: 10c0/b1dfbb8ce5983bb80837c35f089fb0f9603a1b067f34be680f88fde20871792e461e29d119d468bc293f38a1ca916c1c40a841f8c049a0a1efaa40582f4fecc9 + checksum: 10c0/e3d0dfe5680899da3660a7fbc859de1a92dd9358dc497624c3582596173713a80dcc8236d844116a3ba8403350e244c007c0c7fa5796631aea19e464cc6c2f44 languageName: node linkType: hard @@ -5168,35 +5537,37 @@ __metadata: languageName: node linkType: hard -"conventional-changelog-writer@npm:^8.2.0": - version: 8.2.0 - resolution: "conventional-changelog-writer@npm:8.2.0" +"conventional-changelog-writer@npm:^8.4.0": + version: 8.4.0 + resolution: "conventional-changelog-writer@npm:8.4.0" dependencies: + "@simple-libs/stream-utils": "npm:^1.2.0" conventional-commits-filter: "npm:^5.0.0" handlebars: "npm:^4.7.7" meow: "npm:^13.0.0" semver: "npm:^7.5.2" bin: conventional-changelog-writer: dist/cli/index.js - checksum: 10c0/e25052bb366ecee6389326fd5b7d3ecbd6f6a65439f45b5a2b1d4096baeb1bbfa93cd6bea686f419423265db5bbb02870a014cb92f43f972c00191c60711e9b6 + checksum: 10c0/d657bf74c470e5d515d3a07814d266e6e2aea018e6867bfefa4bc486bb3f948b47b01936d65e46b3090111823364c21c201f9fbe875b1fc805cdf884bb032bc1 languageName: node linkType: hard "conventional-changelog@npm:^7.1.1": - version: 7.1.1 - resolution: "conventional-changelog@npm:7.1.1" + version: 7.2.1 + resolution: "conventional-changelog@npm:7.2.1" dependencies: - "@conventional-changelog/git-client": "npm:^2.5.1" + "@conventional-changelog/git-client": "npm:^2.7.0" + "@simple-libs/hosted-git-info": "npm:^1.0.2" "@types/normalize-package-data": "npm:^2.4.4" conventional-changelog-preset-loader: "npm:^5.0.0" - conventional-changelog-writer: "npm:^8.2.0" - conventional-commits-parser: "npm:^6.2.0" + conventional-changelog-writer: "npm:^8.4.0" + conventional-commits-parser: "npm:^6.4.0" fd-package-json: "npm:^2.0.0" meow: "npm:^13.0.0" normalize-package-data: "npm:^7.0.0" bin: conventional-changelog: dist/cli/index.js - checksum: 10c0/8f2c36b7a463bdedc9f919a50458a061b8017d003452b5bc648a6c43a0affe2e76ed9cb5933aa55ad4d6c99061c0b9a567ec5c528333593ec0f210151e1e11b7 + checksum: 10c0/10e0c7b1904c8f557099485b21fdf2cd3359b67a9e917be4cae0636b9f111520c76208949823082747486b4ab4db6602f724f57878c28257bbd0012590fb9fe9 languageName: node linkType: hard @@ -5221,14 +5592,15 @@ __metadata: languageName: node linkType: hard -"conventional-commits-parser@npm:^6.1.0, conventional-commits-parser@npm:^6.2.0": - version: 6.2.1 - resolution: "conventional-commits-parser@npm:6.2.1" +"conventional-commits-parser@npm:^6.1.0, conventional-commits-parser@npm:^6.4.0": + version: 6.4.0 + resolution: "conventional-commits-parser@npm:6.4.0" dependencies: + "@simple-libs/stream-utils": "npm:^1.2.0" meow: "npm:^13.0.0" bin: conventional-commits-parser: dist/cli/index.js - checksum: 10c0/217b3fff627802f7fd7cb09bdfe897aa76986865543dfaa99b7957e4717d039e1e12c4a9b72706f098a5716bbbbdae540ef0b2429f7219d5fc5be0f190f1bc1e + checksum: 10c0/3595b85b420a3f431dbad65f7c367e803ee8bca500ec24482e8669d4ed5ff6febbb5e9a17c52f07ebe882abdee3418e759245bcb06e4d1e2cce09d638f31d5ce languageName: node linkType: hard @@ -5247,7 +5619,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:2.0.0, convert-source-map@npm:^2.0.0": +"convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b @@ -5255,30 +5627,30 @@ __metadata: linkType: hard "core-js-compat@npm:^3.43.0": - version: 3.47.0 - resolution: "core-js-compat@npm:3.47.0" + version: 3.49.0 + resolution: "core-js-compat@npm:3.49.0" dependencies: - browserslist: "npm:^4.28.0" - checksum: 10c0/71da415899633120db7638dd7b250eee56031f63c4560dcba8eeeafd1168fae171d59b223e3fd2e0aa543a490d64bac7d946764721e2c05897056fdfb22cce33 + browserslist: "npm:^4.28.1" + checksum: 10c0/546e64b7ce45f724825bc13c1347f35c0459a6e71c0dcccff3ec21fbff463f5b0b97fc1220e6d90302153863489301793276fe2bf96f46001ff555ead4140308 languageName: node linkType: hard "cosmiconfig-typescript-loader@npm:^6.1.0": - version: 6.2.0 - resolution: "cosmiconfig-typescript-loader@npm:6.2.0" + version: 6.3.0 + resolution: "cosmiconfig-typescript-loader@npm:6.3.0" dependencies: - jiti: "npm:^2.6.1" + jiti: "npm:2.6.1" peerDependencies: "@types/node": "*" cosmiconfig: ">=9" typescript: ">=5" - checksum: 10c0/0fd8fd9b9b6a04eec75617b965ce0a1f63310fe29a361c1f95cb971e05dbbb935291899c2b15abfd69e09db58dbe97077f24a7c61414bbc6c3e78349b4314ad7 + checksum: 10c0/dd53519bf59b31c32a831f1140eaa44f4f0bf49229b7e3ba27bb6f26097c3ecff955a490e70b31349049463066b5047bd129ab82ed078be9b1f1f22ccb776c6a languageName: node linkType: hard "cosmiconfig@npm:^9.0.0": - version: 9.0.0 - resolution: "cosmiconfig@npm:9.0.0" + version: 9.0.2 + resolution: "cosmiconfig@npm:9.0.2" dependencies: env-paths: "npm:^2.2.1" import-fresh: "npm:^3.3.0" @@ -5289,7 +5661,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/1c1703be4f02a250b1d6ca3267e408ce16abfe8364193891afc94c2d5c060b69611fdc8d97af74b7e6d5d1aac0ab2fb94d6b079573146bc2d756c2484ce5f0ee + checksum: 10c0/132d32863c0b3d9ace7010a10011e09089532b36e3b11e02004d671dcbd8b8f2f16293b82d510d9c15890f30358baf8722127c7b1c011449c90b6a178f9c6594 languageName: node linkType: hard @@ -5406,9 +5778,9 @@ __metadata: linkType: hard "dayjs@npm:^1.8.15": - version: 1.11.19 - resolution: "dayjs@npm:1.11.19" - checksum: 10c0/7d8a6074a343f821f81ea284d700bd34ea6c7abbe8d93bce7aba818948957c1b7f56131702e5e890a5622cdfc05dcebe8aed0b8313bdc6838a594d7846b0b000 + version: 1.11.21 + resolution: "dayjs@npm:1.11.21" + checksum: 10c0/bd97dfdc4bfea3c66268635690313828b386faa040fbc1f829ff42a2bd748b72c9d9b3c8f9616ce9e61fcb78923f1461a462c969c54b1084458ae1b715898fb0 languageName: node linkType: hard @@ -5421,7 +5793,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -5455,14 +5827,14 @@ __metadata: linkType: hard "dedent@npm:^1.0.0": - version: 1.7.1 - resolution: "dedent@npm:1.7.1" + version: 1.7.2 + resolution: "dedent@npm:1.7.2" peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: babel-plugin-macros: optional: true - checksum: 10c0/ae29ec1c5bd5216c698c9f23acaa5b720260fd4cef3c8b5af887eb5f8c9e6fdd5fed8668767437b4efea35e2991bd798987717633411a1734807c28255769b78 + checksum: 10c0/acaff07cac355b93f17b1b17ebbb84d3cc55af6ab4b7814c3f505e061903e168bc6bf9ddce331552d64dee1525f0b4c549c9ade46aebfac6f69caaed74e90751 languageName: node linkType: hard @@ -5488,12 +5860,12 @@ __metadata: linkType: hard "default-browser@npm:^5.2.1": - version: 5.4.0 - resolution: "default-browser@npm:5.4.0" + version: 5.5.0 + resolution: "default-browser@npm:5.5.0" dependencies: bundle-name: "npm:^4.1.0" default-browser-id: "npm:^5.0.0" - checksum: 10c0/a49ddd0c7b1a319163f64a5fc68ebb45a98548ea23a3155e04518f026173d85cfa2f451b646366c36c8f70b01e4cb773e23d1d22d2c61d8b84e5fbf151b4b609 + checksum: 10c0/576593b617b17a7223014b4571bfe1c06a2581a4eb8b130985d90d253afa3f40999caec70eb0e5776e80d4af6a41cce91018cd3f86e57ad578bf59e46fb19abe languageName: node linkType: hard @@ -5536,9 +5908,9 @@ __metadata: linkType: hard "defu@npm:^6.1.4": - version: 6.1.4 - resolution: "defu@npm:6.1.4" - checksum: 10c0/2d6cc366262dc0cb8096e429368e44052fdf43ed48e53ad84cc7c9407f890301aa5fcb80d0995abaaf842b3949f154d060be4160f7a46cb2bc2f7726c81526f5 + version: 6.1.7 + resolution: "defu@npm:6.1.7" + checksum: 10c0/e6635388103c8be3c574ac31302f6930e5e6eeedba32cb1b30cf993c7d9fb571aec2485446dfa23bfa63e55e66156fe109027a9695db82a50f931e91e8d4bedb languageName: node linkType: hard @@ -5698,9 +6070,9 @@ __metadata: linkType: hard "dotenv@npm:^17.2.3": - version: 17.2.3 - resolution: "dotenv@npm:17.2.3" - checksum: 10c0/c884403209f713214a1b64d4d1defa4934c2aa5b0002f5a670ae298a51e3c3ad3ba79dfee2f8df49f01ae74290fcd9acdb1ab1d09c7bfb42b539036108bb2ba0 + version: 17.4.2 + resolution: "dotenv@npm:17.4.2" + checksum: 10c0/164f8e77a646c8446867d5b588d26ea6005c8ea7c5eb41cf926f6113d23f2191355f6e0cfd95ea9bab98394a5b0a3f1e51a8399711b666fe55cc7b0bd745f942 languageName: node linkType: hard @@ -5729,10 +6101,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.263": - version: 1.5.267 - resolution: "electron-to-chromium@npm:1.5.267" - checksum: 10c0/0732bdb891b657f2e43266a3db8cf86fff6cecdcc8d693a92beff214e136cb5c2ee7dc5945ed75fa1db16e16bad0c38695527a020d15f39e79084e0b2e447621 +"electron-to-chromium@npm:^1.5.393": + version: 1.5.399 + resolution: "electron-to-chromium@npm:1.5.399" + checksum: 10c0/5b2ab966e0748d00a2bc2dfd7eee203fe872ce2ca4478eea94f1ceda629172770378128cd6d20be4af8c21874ef250163cd47735e01f38f1182f4312d8c7e78b languageName: node linkType: hard @@ -5743,6 +6115,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^10.3.0": + version: 10.6.0 + resolution: "emoji-regex@npm:10.6.0" + checksum: 10c0/1e4aa097bb007301c3b4b1913879ae27327fdc48e93eeefefe3b87e495eb33c5af155300be951b4349ff6ac084f4403dc9eff970acba7c1c572d89396a9a32d7 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -5771,15 +6150,6 @@ __metadata: languageName: node linkType: hard -"encoding@npm:^0.1.13": - version: 0.1.13 - resolution: "encoding@npm:0.1.13" - dependencies: - iconv-lite: "npm:^0.6.2" - checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 - languageName: node - linkType: hard - "end-of-stream@npm:^1.1.0": version: 1.4.5 resolution: "end-of-stream@npm:1.4.5" @@ -5812,13 +6182,6 @@ __metadata: languageName: node linkType: hard -"err-code@npm:^2.0.2": - version: 2.0.3 - resolution: "err-code@npm:2.0.3" - checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 - languageName: node - linkType: hard - "error-ex@npm:^1.3.1": version: 1.3.4 resolution: "error-ex@npm:1.3.4" @@ -5847,9 +6210,21 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0, es-abstract@npm:^1.24.1": - version: 1.24.1 - resolution: "es-abstract@npm:1.24.1" +"es-abstract-get@npm:^1.0.0": + version: 1.0.0 + resolution: "es-abstract-get@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.2" + is-callable: "npm:^1.2.7" + object-inspect: "npm:^1.13.4" + checksum: 10c0/f9b4838ae719752207383a6d95a74590f891122bf26b92f5e72eeedbe53771029e4561f1cf75ea19330b71bcf3d4f536fb0c8f7e2b601fe24d284f46e488c7e3 + languageName: node + linkType: hard + +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0, es-abstract@npm:^1.24.2": + version: 1.24.2 + resolution: "es-abstract@npm:1.24.2" dependencies: array-buffer-byte-length: "npm:^1.0.2" arraybuffer.prototype.slice: "npm:^1.0.4" @@ -5905,7 +6280,7 @@ __metadata: typed-array-length: "npm:^1.0.7" unbox-primitive: "npm:^1.1.0" which-typed-array: "npm:^1.1.19" - checksum: 10c0/fca062ef8b5daacf743732167d319a212d45cb655b0bb540821d38d715416ae15b04b84fc86da9e2c89135aa7b337337b6c867f84dcde698d75d55688d5d765c + checksum: 10c0/67a5bf21ef5c7d775e6f6131a836323900b4d87194cf544394ac68fe31c57fa53828b978af4a4f551ef307f83a2f910a16b6b982760ad3ddc3dc471f98d5fd1b languageName: node linkType: hard @@ -5924,13 +6299,13 @@ __metadata: linkType: hard "es-iterator-helpers@npm:^1.2.1": - version: 1.2.2 - resolution: "es-iterator-helpers@npm:1.2.2" + version: 1.4.0 + resolution: "es-iterator-helpers@npm:1.4.0" dependencies: - call-bind: "npm:^1.0.8" + call-bind: "npm:^1.0.9" call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.24.1" + es-abstract: "npm:^1.24.2" es-errors: "npm:^1.3.0" es-set-tostringtag: "npm:^2.1.0" function-bind: "npm:^1.1.2" @@ -5942,17 +6317,17 @@ __metadata: has-symbols: "npm:^1.1.0" internal-slot: "npm:^1.1.0" iterator.prototype: "npm:^1.1.5" - safe-array-concat: "npm:^1.1.3" - checksum: 10c0/1ced8abf845a45e660dd77b5f3a64358421df70e4a0bd1897d5ddfefffed8409a6a2ca21241b9367e639df9eca74abc1c678b3020bffe6bee1f1826393658ddb + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/839a5e881446e1b4ab270a9ad5d01a23b83a38fadb9e526674df171357e90ad3111dc8c0b15e7d30db1958f2c3332dd963fab7d55f406a660d098b2b7eefb218 languageName: node linkType: hard -"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": - version: 1.1.1 - resolution: "es-object-atoms@npm:1.1.1" +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1, es-object-atoms@npm:^1.1.2": + version: 1.1.2 + resolution: "es-object-atoms@npm:1.1.2" dependencies: es-errors: "npm:^1.3.0" - checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c + checksum: 10c0/1772861f094f739d6f41b579cfb9a18579daffeb434552a370a5fbef50a32d22227e27b63fdbb757b7ddd429d1b42fe52ccae7966d9302a2ec221b6f1b41bbc4 languageName: node linkType: hard @@ -5978,13 +6353,16 @@ __metadata: linkType: hard "es-to-primitive@npm:^1.3.0": - version: 1.3.0 - resolution: "es-to-primitive@npm:1.3.0" + version: 1.3.4 + resolution: "es-to-primitive@npm:1.3.4" dependencies: + es-abstract-get: "npm:^1.0.0" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" is-callable: "npm:^1.2.7" - is-date-object: "npm:^1.0.5" - is-symbol: "npm:^1.0.4" - checksum: 10c0/c7e87467abb0b438639baa8139f701a06537d2b9bc758f23e8622c3b42fd0fdb5bde0f535686119e446dd9d5e4c0f238af4e14960f4771877cf818d023f6730b + is-date-object: "npm:^1.1.0" + is-symbol: "npm:^1.1.1" + checksum: 10c0/b10029f8b0b13841bade224ff39005a13d76d9cb803cd1efb18cc96a24414e83e2e7ed15d7ad9d0d0bda66884afd211b7b579b8fa31940e05b060934aa7077d8 languageName: node linkType: hard @@ -6095,30 +6473,33 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jest@npm:^27.9.0": - version: 27.9.0 - resolution: "eslint-plugin-jest@npm:27.9.0" +"eslint-plugin-jest@npm:^29.0.1": + version: 29.16.0 + resolution: "eslint-plugin-jest@npm:29.16.0" dependencies: - "@typescript-eslint/utils": "npm:^5.10.0" + "@typescript-eslint/utils": "npm:^8.0.0" peerDependencies: - "@typescript-eslint/eslint-plugin": ^5.0.0 || ^6.0.0 || ^7.0.0 - eslint: ^7.0.0 || ^8.0.0 + "@typescript-eslint/eslint-plugin": ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 jest: "*" + typescript: ">=4.8.4 <8.0.0" peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true jest: optional: true - checksum: 10c0/b8b09f7d8ba3d84a8779a6e95702a6e4dce45ab034e4edf5ddb631e77cd38dcdf791dfd9228e0a0d1d80d1eb2d278deb62ad2ec39f10fb8fd43cec07304e0c38 + typescript: + optional: true + checksum: 10c0/ac3b0b0502c48285063a968219852979b0526f814bee90c65ef417e495b270a5aee437961ab51941caa1d0ae4ae5387a55374946165c17cf5e4f001972e0de44 languageName: node linkType: hard "eslint-plugin-prettier@npm:^5.5.4": - version: 5.5.4 - resolution: "eslint-plugin-prettier@npm:5.5.4" + version: 5.5.6 + resolution: "eslint-plugin-prettier@npm:5.5.6" dependencies: - prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.11.7" + prettier-linter-helpers: "npm:^1.0.1" + synckit: "npm:^0.11.13" peerDependencies: "@types/eslint": ">=8.0.0" eslint: ">=8.0.0" @@ -6129,16 +6510,22 @@ __metadata: optional: true eslint-config-prettier: optional: true - checksum: 10c0/5cc780e0ab002f838ad8057409e86de4ff8281aa2704a50fa8511abff87028060c2e45741bc9cbcbd498712e8d189de8026e70aed9e20e50fe5ba534ee5a8442 + checksum: 10c0/af37126c947ff3e87ff1ea76408db8cb1c7da966ebdaba68c6dd5924da7eb1b43b1abc4796d753a97b1bc26ea94c5497093e6ab9f8588fffe558d5a554e19bbf languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^5.2.0": - version: 5.2.0 - resolution: "eslint-plugin-react-hooks@npm:5.2.0" +"eslint-plugin-react-hooks@npm:^7.0.1": + version: 7.1.1 + resolution: "eslint-plugin-react-hooks@npm:7.1.1" + dependencies: + "@babel/core": "npm:^7.24.4" + "@babel/parser": "npm:^7.24.4" + hermes-parser: "npm:^0.25.1" + zod: "npm:^3.25.0 || ^4.0.0" + zod-validation-error: "npm:^3.5.0 || ^4.0.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + checksum: 10c0/cee8454915d71ac5d70a0d8f4f260e76eaf45fcd4162747dd4282b792ee5616d187351dabe6cdcff9040c79d0cec625635c4fd0777276be119efa88ebe058525 languageName: node linkType: hard @@ -6149,18 +6536,18 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-native@npm:^4.0.0": - version: 4.1.0 - resolution: "eslint-plugin-react-native@npm:4.1.0" +"eslint-plugin-react-native@npm:^5.0.0": + version: 5.0.0 + resolution: "eslint-plugin-react-native@npm:5.0.0" dependencies: eslint-plugin-react-native-globals: "npm:^0.1.1" peerDependencies: - eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10c0/9aedccde6227b78bad7c243844aca0860fca2dccd635e91e745bcd617c1e7fb889fa212917cf7b56860335a147fc7c8dc339d1976330ec4f896fe9156b35b162 + eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 10c0/c7c927bc743abf0cb367cc64fea5b28b28ea0c58be2990cab858a050b4855e89d90513afa44d73012c9fd670810ad0da2ac72e3e4bdfedf0ce0cbb65e901af7f languageName: node linkType: hard -"eslint-plugin-react@npm:^7.30.1": +"eslint-plugin-react@npm:^7.37.5": version: 7.37.5 resolution: "eslint-plugin-react@npm:7.37.5" dependencies: @@ -6188,7 +6575,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": +"eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" dependencies: @@ -6215,7 +6602,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 @@ -6229,23 +6616,30 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^5.0.0": + version: 5.0.1 + resolution: "eslint-visitor-keys@npm:5.0.1" + checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678 + languageName: node + linkType: hard + "eslint@npm:^9.35.0": - version: 9.39.2 - resolution: "eslint@npm:9.39.2" + version: 9.39.5 + resolution: "eslint@npm:9.39.5" dependencies: "@eslint-community/eslint-utils": "npm:^4.8.0" "@eslint-community/regexpp": "npm:^4.12.1" - "@eslint/config-array": "npm:^0.21.1" + "@eslint/config-array": "npm:^0.21.2" "@eslint/config-helpers": "npm:^0.4.2" "@eslint/core": "npm:^0.17.0" - "@eslint/eslintrc": "npm:^3.3.1" - "@eslint/js": "npm:9.39.2" + "@eslint/eslintrc": "npm:^3.3.6" + "@eslint/js": "npm:9.39.5" "@eslint/plugin-kit": "npm:^0.4.1" "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.4.2" "@types/estree": "npm:^1.0.6" - ajv: "npm:^6.12.4" + ajv: "npm:^6.14.0" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.6" debug: "npm:^4.3.2" @@ -6264,7 +6658,7 @@ __metadata: is-glob: "npm:^4.0.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" + minimatch: "npm:^3.1.5" natural-compare: "npm:^1.4.0" optionator: "npm:^0.9.3" peerDependencies: @@ -6274,7 +6668,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/bb88ca8fd16bb7e1ac3e13804c54d41c583214460c0faa7b3e7c574e69c5600c7122295500fb4b0c06067831111db740931e98da1340329527658e1cf80073d3 + checksum: 10c0/46335bfcf180ffea9955b38122b578ac9e075b6220e5695be1c988354ea429b04f5db05edc132aa9019ce9847736e9ca0c9ea6d6cedda3c06209c9b52dbd0fd5 languageName: node linkType: hard @@ -6437,10 +6831,10 @@ __metadata: languageName: node linkType: hard -"exsolve@npm:^1.0.7, exsolve@npm:^1.0.8": - version: 1.0.8 - resolution: "exsolve@npm:1.0.8" - checksum: 10c0/65e44ae05bd4a4a5d87cfdbbd6b8f24389282cf9f85fa5feb17ca87ad3f354877e6af4cd99e02fc29044174891f82d1d68c77f69234410eb8f163530e6278c67 +"exsolve@npm:^1.0.8": + version: 1.1.1 + resolution: "exsolve@npm:1.1.1" + checksum: 10c0/0b157a7600408bd356ff78cff5ad9c8c0dd7ca5e7f246216c3c9b66196e76277d3130021122b9c5078a3462751fd7aa988fe3dc1e3b80c79cb873c1623f628e1 languageName: node linkType: hard @@ -6493,20 +6887,20 @@ __metadata: linkType: hard "fast-uri@npm:^3.0.1": - version: 3.1.0 - resolution: "fast-uri@npm:3.1.0" - checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7 + version: 3.1.5 + resolution: "fast-uri@npm:3.1.5" + checksum: 10c0/2bf60eb800dd610c65e17be436425dcb21c92aff3a87d442a8bccab0b7b071e88cf1a5d7d1ea946370b937e6fc0375c405c0296c10587e57de4f78be4646d1d0 languageName: node linkType: hard "fast-xml-parser@npm:^4.4.1": - version: 4.5.3 - resolution: "fast-xml-parser@npm:4.5.3" + version: 4.5.7 + resolution: "fast-xml-parser@npm:4.5.7" dependencies: - strnum: "npm:^1.1.1" + strnum: "npm:^1.0.5" bin: fxparser: src/cli/cli.js - checksum: 10c0/bf9ccadacfadc95f6e3f0e7882a380a7f219cf0a6f96575149f02cb62bf44c3b7f0daee75b8ff3847bcfd7fbcb201e402c71045936c265cf6d94b141ec4e9327 + checksum: 10c0/5fccf3f53d6b2b83143d73089f04ef5db5343422891193cf10d92d3eb856007b7337818494109e46f6fa47b31b9716be15c4b275ff87a0aeb6f7315aa2edc181 languageName: node linkType: hard @@ -6519,6 +6913,15 @@ __metadata: languageName: node linkType: hard +"fb-dotslash@npm:0.5.8": + version: 0.5.8 + resolution: "fb-dotslash@npm:0.5.8" + bin: + dotslash: bin/dotslash + checksum: 10c0/6c693ecb8e61cd8571e0ad6a923e0582cf8e481695e906e17c8e31620402e06f8b80d95111a420d2f62349d9bebc2b820bae14c2c54a814e72abdc710dc1d3ed + languageName: node + linkType: hard + "fb-watchman@npm:^2.0.0": version: 2.0.2 resolution: "fb-watchman@npm:2.0.2" @@ -6631,9 +7034,9 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.3 - resolution: "flatted@npm:3.3.3" - checksum: 10c0/e957a1c6b0254aa15b8cce8533e24165abd98fadc98575db082b786b5da1b7d72062b81bfdcd1da2f4d46b6ed93bec2434e62333e9b4261d79ef2e75a10dd538 + version: 3.4.4 + resolution: "flatted@npm:3.4.4" + checksum: 10c0/a3a52a88ea5a4c333e5a1f097dcd87a037fa31c236a77cf46222c2aa4036ef895ab9bc76138a66d9dc22bdb3652128f9598cd26e7439561bf19f67276e2bc37e languageName: node linkType: hard @@ -6692,15 +7095,6 @@ __metadata: languageName: node linkType: hard -"fs-minipass@npm:^3.0.0": - version: 3.0.3 - resolution: "fs-minipass@npm:3.0.3" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 - languageName: node - linkType: hard - "fs.realpath@npm:^1.0.0": version: 1.0.0 resolution: "fs.realpath@npm:1.0.0" @@ -6735,16 +7129,19 @@ __metadata: linkType: hard "function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": - version: 1.1.8 - resolution: "function.prototype.name@npm:1.1.8" + version: 1.2.0 + resolution: "function.prototype.name@npm:1.2.0" dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" - define-properties: "npm:^1.2.1" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" functions-have-names: "npm:^1.2.3" - hasown: "npm:^2.0.2" + has-property-descriptors: "npm:^1.0.2" + hasown: "npm:^2.0.4" is-callable: "npm:^1.2.7" - checksum: 10c0/e920a2ab52663005f3cbe7ee3373e3c71c1fb5558b0b0548648cdf3e51961085032458e26c71ff1a8c8c20e7ee7caeb03d43a5d1fa8610c459333323a2e71253 + is-document.all: "npm:^1.0.0" + checksum: 10c0/b20e6370ef4f7d56d0bedf5719f6684a517a8dd3334209b4d9f51e8834859302a584187156bf024cda9f50ba2479e4d6764ac34af9532ea47d2f4d9fa6bcf90d languageName: node linkType: hard @@ -6776,10 +7173,10 @@ __metadata: languageName: node linkType: hard -"get-east-asian-width@npm:^1.3.0": - version: 1.4.0 - resolution: "get-east-asian-width@npm:1.4.0" - checksum: 10c0/4e481d418e5a32061c36fbb90d1b225a254cc5b2df5f0b25da215dcd335a3c111f0c2023ffda43140727a9cafb62dac41d022da82c08f31083ee89f714ee3b83 +"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.5.0": + version: 1.6.0 + resolution: "get-east-asian-width@npm:1.6.0" + checksum: 10c0/7e72e9550fd49ca5b246f9af6bb2afc129c96412845ff6556b3274fd44817a381702ca17028efe9866b261a3d44254cbf21e6c90cf05b4b61675630af776d431 languageName: node linkType: hard @@ -6866,6 +7263,13 @@ __metadata: languageName: node linkType: hard +"getenv@npm:^2.0.0": + version: 2.0.0 + resolution: "getenv@npm:2.0.0" + checksum: 10c0/397ff641dd70cd78e414430258651e9a2228d3c5553a8cf15ae7840f75d3f10dfcb83f668f84829e84ea665b0fce2f08a9eddda3c9dcd7faa2d3da1c182c1854 + languageName: node + linkType: hard + "giget@npm:^2.0.0": version: 2.0.0 resolution: "giget@npm:2.0.0" @@ -6949,17 +7353,17 @@ __metadata: linkType: hard "glob@npm:^13.0.0": - version: 13.0.0 - resolution: "glob@npm:13.0.0" + version: 13.0.6 + resolution: "glob@npm:13.0.6" dependencies: - minimatch: "npm:^10.1.1" - minipass: "npm:^7.1.2" - path-scurry: "npm:^2.0.0" - checksum: 10c0/8e2f5821f3f7c312dd102e23a15b80c79e0837a9872784293ba2e15ec73b3f3749a49a42a31bfcb4e52c84820a474e92331c2eebf18819d20308f5c33876630a + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a languageName: node linkType: hard -"glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4": +"glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -6999,7 +7403,7 @@ __metadata: languageName: node linkType: hard -"globby@npm:^11.0.1, globby@npm:^11.1.0": +"globby@npm:^11.0.1": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: @@ -7041,16 +7445,9 @@ __metadata: languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31 - languageName: node - linkType: hard - "handlebars@npm:^4.7.7": - version: 4.7.8 - resolution: "handlebars@npm:4.7.8" + version: 4.7.9 + resolution: "handlebars@npm:4.7.9" dependencies: minimist: "npm:^1.2.5" neo-async: "npm:^2.6.2" @@ -7062,7 +7459,7 @@ __metadata: optional: true bin: handlebars: bin/handlebars - checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d + checksum: 10c0/22f8105a7e68e81aff2662bb434edf05f757d21d850731d71cec886d69c10cd33d3c43e34b2892968ec62de8241611851d3d0674c8ef324ea3e01dc66262faa9 languageName: node linkType: hard @@ -7114,12 +7511,26 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.2": - version: 2.0.2 - resolution: "hasown@npm:2.0.2" +"hasown@npm:^2.0.2, hasown@npm:^2.0.3, hasown@npm:^2.0.4": + version: 2.0.4 + resolution: "hasown@npm:2.0.4" dependencies: function-bind: "npm:^1.1.2" - checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 + checksum: 10c0/2d8de939e270b70618f8cebb69746620db10617dbb495bc66ddad326955ea24d3ca4af133aff3eb7c1853e0218f867bc2b050ec26fe02e3aea58f880ffc5e506 + languageName: node + linkType: hard + +"hermes-compiler@npm:250829098.0.14": + version: 250829098.0.14 + resolution: "hermes-compiler@npm:250829098.0.14" + checksum: 10c0/b9f4024ac7377bebec61b91e1cee8f3909a8ecad0ea786c6b7c3863f8b65bd94f928850b341c82865a9435b8390d33f03e149e9d479c6870b6f5a754d101fde7 + languageName: node + linkType: hard + +"hermes-estree@npm:0.25.1": + version: 0.25.1 + resolution: "hermes-estree@npm:0.25.1" + checksum: 10c0/48be3b2fa37a0cbc77a112a89096fa212f25d06de92781b163d67853d210a8a5c3784fac23d7d48335058f7ed283115c87b4332c2a2abaaccc76d0ead1a282ac languageName: node linkType: hard @@ -7130,17 +7541,17 @@ __metadata: languageName: node linkType: hard -"hermes-estree@npm:0.29.1": - version: 0.29.1 - resolution: "hermes-estree@npm:0.29.1" - checksum: 10c0/e6b01f79ba708697d61a74b871d5ebae5f863c6d782657d8e2d2256eb838f1eb86ff9c34773a81d9cc69e54be3a5059c686e0ab54a4afba903b40dde92dd0ccb +"hermes-estree@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-estree@npm:0.35.0" + checksum: 10c0/a88c9dc63b8b3679b1aeb43e72e977597096c1bd7d59978c952f1d6df6d1a517c4a817c70b1b701854996b485adfa66c2fc7f80871029a7f0c04306f6717b59a languageName: node linkType: hard -"hermes-estree@npm:0.32.0": - version: 0.32.0 - resolution: "hermes-estree@npm:0.32.0" - checksum: 10c0/3b67d1fe44336240ef7f9c40ecbf363279ba263d51efe120570c3862cc109e652fc09aebddfe6b73d0f0246610bee130e4064c359f1f4cbf002bdb1d99717ef2 +"hermes-estree@npm:0.36.0": + version: 0.36.0 + resolution: "hermes-estree@npm:0.36.0" + checksum: 10c0/fe27f57b0f8c3921e9dc48c517e25f4399609ca386353f90e04d3f859bacbee93184af80a6b930db5e981e8953a5c4083147556b21b19519917e131e7533b27c languageName: node linkType: hard @@ -7153,30 +7564,30 @@ __metadata: languageName: node linkType: hard -"hermes-parser@npm:0.29.1": - version: 0.29.1 - resolution: "hermes-parser@npm:0.29.1" +"hermes-parser@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-parser@npm:0.35.0" dependencies: - hermes-estree: "npm:0.29.1" - checksum: 10c0/7f40d9bdfb5acaa700f333a24c644b17f5f8d0e823b1e7a9fb6dcf253a54d54716ae63c74effa023688ee4f09013c80188c40d601570fee256a44954e04c2926 + hermes-estree: "npm:0.35.0" + checksum: 10c0/49d98093a2094758db5b536627c6cf5146b140f66e63143acf471c62f1d3fd8bd6ae10a33f2372f72e3653deda5d4615c6dae89d01248849440916209901fc4a languageName: node linkType: hard -"hermes-parser@npm:0.32.0": - version: 0.32.0 - resolution: "hermes-parser@npm:0.32.0" +"hermes-parser@npm:0.36.0": + version: 0.36.0 + resolution: "hermes-parser@npm:0.36.0" dependencies: - hermes-estree: "npm:0.32.0" - checksum: 10c0/5902d2c5d347c0629fba07a47eaad5569590ac69bc8bfb2e454e08d2dfbe1ebd989d88518dca2cba64061689b5eac5960ae6bd15a4a66600bbf377498a3234b7 + hermes-estree: "npm:0.36.0" + checksum: 10c0/76e726366ac2ea91e9464853f439d582ddee9c07ccb84cac35297ce1a5d197bf96b84ab030423a22940b55a0fa5bb191bc0ebeebd95f8e34116900decdccdb86 languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.0": - version: 3.3.2 - resolution: "hoist-non-react-statics@npm:3.3.2" +"hermes-parser@npm:^0.25.1": + version: 0.25.1 + resolution: "hermes-parser@npm:0.25.1" dependencies: - react-is: "npm:^16.7.0" - checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74 + hermes-estree: "npm:0.25.1" + checksum: 10c0/3abaa4c6f1bcc25273f267297a89a4904963ea29af19b8e4f6eabe04f1c2c7e9abd7bfc4730ddb1d58f2ea04b6fee74053d8bddb5656ec6ebf6c79cc8d14202c languageName: node linkType: hard @@ -7196,13 +7607,6 @@ __metadata: languageName: node linkType: hard -"http-cache-semantics@npm:^4.1.1": - version: 4.2.0 - resolution: "http-cache-semantics@npm:4.2.0" - checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 - languageName: node - linkType: hard - "http-errors@npm:~2.0.1": version: 2.0.1 resolution: "http-errors@npm:2.0.1" @@ -7226,7 +7630,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.5, https-proxy-agent@npm:^7.0.6": +"https-proxy-agent@npm:^7.0.5, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -7257,21 +7661,12 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 - languageName: node - linkType: hard - "iconv-lite@npm:^0.7.0": - version: 0.7.1 - resolution: "iconv-lite@npm:0.7.1" + version: 0.7.3 + resolution: "iconv-lite@npm:0.7.3" dependencies: safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10c0/f5c9e2bddd7101a71b07a381ace44ebdc65ca76a10be0e9e64d372b511132acc4ee41b830962f438840d492cd6f9e08c237289f760d6a7fed754e61cffcb6757 + checksum: 10c0/be2fd2414f7e94be3a63063fa0ad5919c16bc7b6e00c77eea0765ced6db405739f38dd51016583058fba25cc1d0106ba30b83fbb7a7e32f824d4db76f23d8d33 languageName: node linkType: hard @@ -7291,17 +7686,17 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.5, ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"ignore@npm:^5.0.5, ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard -"ignore@npm:^7.0.3": - version: 7.0.5 - resolution: "ignore@npm:7.0.5" - checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d +"ignore@npm:^7.0.3, ignore@npm:^7.0.5": + version: 7.0.6 + resolution: "ignore@npm:7.0.6" + checksum: 10c0/fc01ef1d14efbe003439b60538726351e81483d1b6f55bdbb3a4465c6346d9481afad5b350dfbd604ddd7049618ef9093ff26dc147984aabc303c56ba53ea3b5 languageName: node linkType: hard @@ -7423,10 +7818,10 @@ __metadata: languageName: node linkType: hard -"ip-address@npm:^10.0.1": - version: 10.1.0 - resolution: "ip-address@npm:10.1.0" - checksum: 10c0/0103516cfa93f6433b3bd7333fa876eb21263912329bfa47010af5e16934eeeff86f3d2ae700a3744a137839ddfad62b900c7a445607884a49b5d1e32a3d7566 +"ip-address@npm:^10.1.1": + version: 10.4.0 + resolution: "ip-address@npm:10.4.0" + checksum: 10c0/d7b0bd2624fd861afbae6e49036a9b56f9506eaff7ff38592b7b4492dd5c272b53f5356dc8cc019e318acf29a96c90a3d1af1df761960267d23efa96858270fa languageName: node linkType: hard @@ -7504,12 +7899,12 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.1": - version: 2.16.1 - resolution: "is-core-module@npm:2.16.1" +"is-core-module@npm:^2.16.1, is-core-module@npm:^2.16.2": + version: 2.16.2 + resolution: "is-core-module@npm:2.16.2" dependencies: - hasown: "npm:^2.0.2" - checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd + hasown: "npm:^2.0.3" + checksum: 10c0/14b4258390283709c15476d023ec173e27458d5d014ccdb8ed39d576e551c3fa45498b7c9fe178f1529c4cb2648ddd58852a6a62107a019f6e349529f277518a languageName: node linkType: hard @@ -7524,7 +7919,7 @@ __metadata: languageName: node linkType: hard -"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0": +"is-date-object@npm:^1.1.0": version: 1.1.0 resolution: "is-date-object@npm:1.1.0" dependencies: @@ -7552,6 +7947,15 @@ __metadata: languageName: node linkType: hard +"is-document.all@npm:^1.0.0": + version: 1.0.0 + resolution: "is-document.all@npm:1.0.0" + dependencies: + call-bound: "npm:^1.0.4" + checksum: 10c0/955c20ed5bf01d49da8243b4c714947a6ff64b6d9ba0e12bdbfa654a3e7c47f72cc01c6cd2905e85512d02bc3a1290edd73857bca8842566ff9dcfb7c3f92dae + languageName: node + linkType: hard + "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -7792,7 +8196,7 @@ __metadata: languageName: node linkType: hard -"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": +"is-symbol@npm:^1.1.1": version: 1.1.1 resolution: "is-symbol@npm:1.1.1" dependencies: @@ -7894,11 +8298,11 @@ __metadata: linkType: hard "is-wsl@npm:^3.1.0": - version: 3.1.0 - resolution: "is-wsl@npm:3.1.0" + version: 3.1.1 + resolution: "is-wsl@npm:3.1.1" dependencies: is-inside-container: "npm:^1.0.0" - checksum: 10c0/d3317c11995690a32c362100225e22ba793678fe8732660c6de511ae71a0ff05b06980cf21f98a6bf40d7be0e9e9506f859abe00a1118287d63e53d0a3d06947 + checksum: 10c0/7e5023522bfb8f27de4de960b0d82c4a8146c0bddb186529a3616d78b5bbbfc19ef0c5fc60d0b3a3cc0bf95a415fbdedc18454310ea3049587c879b07ace5107 languageName: node linkType: hard @@ -7916,10 +8320,10 @@ __metadata: languageName: node linkType: hard -"isexe@npm:^3.1.1": - version: 3.1.1 - resolution: "isexe@npm:3.1.1" - checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce languageName: node linkType: hard @@ -8467,7 +8871,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^2.6.1": +"jiti@npm:2.6.1": version: 2.6.1 resolution: "jiti@npm:2.6.1" bin: @@ -8476,16 +8880,25 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^2.6.1": + version: 2.7.0 + resolution: "jiti@npm:2.7.0" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10c0/1b1e2310a490dce1aeea3da5f5dfe18273516c20ce48be2e98eb8ea452d5f3dcc8fd0cfd6d28b4052a24c5dbab6e3089b2d7e79f0bce7915b10d750929563c42 + languageName: node + linkType: hard + "joi@npm:^17.2.1": - version: 17.13.3 - resolution: "joi@npm:17.13.3" + version: 17.13.4 + resolution: "joi@npm:17.13.4" dependencies: "@hapi/hoek": "npm:^9.3.0" "@hapi/topo": "npm:^5.1.0" "@sideway/address": "npm:^4.1.5" "@sideway/formula": "npm:^3.0.1" "@sideway/pinpoint": "npm:^2.0.0" - checksum: 10c0/9262aef1da3f1bec5b03caf50c46368899fe03b8ff26cbe3d53af4584dd1049079fc97230bbf1500b6149db7cc765b9ee45f0deb24bb6fc3fa06229d7148c17f + checksum: 10c0/5addfef638e90eb6a45a72e3884128d8d9a80c487cb8bfcb949be179b875ad1095af347fa1bd05c4ebec2b2ccbc3f3db5f34501c8672ecd16100de2b77087122 languageName: node linkType: hard @@ -8497,25 +8910,25 @@ __metadata: linkType: hard "js-yaml@npm:^3.13.1": - version: 3.14.2 - resolution: "js-yaml@npm:3.14.2" + version: 3.15.1 + resolution: "js-yaml@npm:3.15.1" dependencies: argparse: "npm:^1.0.7" esprima: "npm:^4.0.0" bin: js-yaml: bin/js-yaml.js - checksum: 10c0/3261f25912f5dd76605e5993d0a126c2b6c346311885d3c483706cd722efe34f697ea0331f654ce27c00a42b426e524518ec89d65ed02ea47df8ad26dcc8ce69 + checksum: 10c0/6c693b8c59ffe12021df3b36994b090df19d920826dd810baab81652b40861e1974509dd11fe92225ab4c00cc14de053300c94db015c2c0e211edea39b118737 languageName: node linkType: hard -"js-yaml@npm:^4.1.0, js-yaml@npm:^4.1.1": - version: 4.1.1 - resolution: "js-yaml@npm:4.1.1" +"js-yaml@npm:^4.1.0, js-yaml@npm:^4.1.1, js-yaml@npm:^4.3.0": + version: 4.3.1 + resolution: "js-yaml@npm:4.3.1" dependencies: argparse: "npm:^2.0.1" bin: js-yaml: bin/js-yaml.js - checksum: 10c0/561c7d7088c40a9bb53cc75becbfb1df6ae49b34b5e6e5a81744b14ae8667ec564ad2527709d1a6e7d5e5fa6d483aa0f373a50ad98d42fde368ec4a190d4fae7 + checksum: 10c0/13c500ca322e0c3f8c81686e6ecda96d2ea37b45247a420c17c7db36932d6965cc27391abc2d1a104501600e7f0d947a5f8b7be6db619c4fefa87901b3512807 languageName: node linkType: hard @@ -8592,15 +9005,15 @@ __metadata: linkType: hard "jsonfile@npm:^6.0.1": - version: 6.2.0 - resolution: "jsonfile@npm:6.2.0" + version: 6.2.1 + resolution: "jsonfile@npm:6.2.1" dependencies: graceful-fs: "npm:^4.1.6" universalify: "npm:^2.0.0" dependenciesMeta: graceful-fs: optional: true - checksum: 10c0/7f4f43b08d1869ded8a6822213d13ae3b99d651151d77efd1557ced0889c466296a7d9684e397bd126acf5eb2cfcb605808c3e681d0fdccd2fe5a04b47e76c0d + checksum: 10c0/e1abf000ecee9942d4d028a8e02dc752617face227d72afd1cfb2187e2433079e625bf82b807a313689db71b6472c6b2b389a2340d2798737b1199a39631c28a languageName: node linkType: hard @@ -8647,99 +9060,99 @@ __metadata: linkType: hard "launch-editor@npm:^2.9.1": - version: 2.12.0 - resolution: "launch-editor@npm:2.12.0" + version: 2.14.1 + resolution: "launch-editor@npm:2.14.1" dependencies: picocolors: "npm:^1.1.1" - shell-quote: "npm:^1.8.3" - checksum: 10c0/fac5e7ad90bf185594cad4c831a52419eef50e667c4eddb5b0a58eb5f944e16d947636ee767b9896ffd46a51db34925edd3b854c48efb47f6d767ffd7d904e71 + shell-quote: "npm:^1.8.4" + checksum: 10c0/bb0ab182086afaf1c391abd38d6fc9d5391cb43d0c2da1d96176f79e9995635cdf34dcfd8df3f756bb82d7bbbb7d37014d5eb312f337350889c0cff92db53dab languageName: node linkType: hard -"lefthook-darwin-arm64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-darwin-arm64@npm:2.0.13" +"lefthook-darwin-arm64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-darwin-arm64@npm:2.1.10" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lefthook-darwin-x64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-darwin-x64@npm:2.0.13" +"lefthook-darwin-x64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-darwin-x64@npm:2.1.10" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lefthook-freebsd-arm64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-freebsd-arm64@npm:2.0.13" +"lefthook-freebsd-arm64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-freebsd-arm64@npm:2.1.10" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"lefthook-freebsd-x64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-freebsd-x64@npm:2.0.13" +"lefthook-freebsd-x64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-freebsd-x64@npm:2.1.10" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lefthook-linux-arm64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-linux-arm64@npm:2.0.13" +"lefthook-linux-arm64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-linux-arm64@npm:2.1.10" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"lefthook-linux-x64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-linux-x64@npm:2.0.13" +"lefthook-linux-x64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-linux-x64@npm:2.1.10" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"lefthook-openbsd-arm64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-openbsd-arm64@npm:2.0.13" +"lefthook-openbsd-arm64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-openbsd-arm64@npm:2.1.10" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"lefthook-openbsd-x64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-openbsd-x64@npm:2.0.13" +"lefthook-openbsd-x64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-openbsd-x64@npm:2.1.10" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"lefthook-windows-arm64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-windows-arm64@npm:2.0.13" +"lefthook-windows-arm64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-windows-arm64@npm:2.1.10" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lefthook-windows-x64@npm:2.0.13": - version: 2.0.13 - resolution: "lefthook-windows-x64@npm:2.0.13" +"lefthook-windows-x64@npm:2.1.10": + version: 2.1.10 + resolution: "lefthook-windows-x64@npm:2.1.10" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "lefthook@npm:^2.0.3": - version: 2.0.13 - resolution: "lefthook@npm:2.0.13" - dependencies: - lefthook-darwin-arm64: "npm:2.0.13" - lefthook-darwin-x64: "npm:2.0.13" - lefthook-freebsd-arm64: "npm:2.0.13" - lefthook-freebsd-x64: "npm:2.0.13" - lefthook-linux-arm64: "npm:2.0.13" - lefthook-linux-x64: "npm:2.0.13" - lefthook-openbsd-arm64: "npm:2.0.13" - lefthook-openbsd-x64: "npm:2.0.13" - lefthook-windows-arm64: "npm:2.0.13" - lefthook-windows-x64: "npm:2.0.13" + version: 2.1.10 + resolution: "lefthook@npm:2.1.10" + dependencies: + lefthook-darwin-arm64: "npm:2.1.10" + lefthook-darwin-x64: "npm:2.1.10" + lefthook-freebsd-arm64: "npm:2.1.10" + lefthook-freebsd-x64: "npm:2.1.10" + lefthook-linux-arm64: "npm:2.1.10" + lefthook-linux-x64: "npm:2.1.10" + lefthook-openbsd-arm64: "npm:2.1.10" + lefthook-openbsd-x64: "npm:2.1.10" + lefthook-windows-arm64: "npm:2.1.10" + lefthook-windows-x64: "npm:2.1.10" dependenciesMeta: lefthook-darwin-arm64: optional: true @@ -8763,7 +9176,7 @@ __metadata: optional: true bin: lefthook: bin/index.js - checksum: 10c0/11dc5a952c24325b19803c261331f1e12ea8eaf31c0ab131815955a6e7210323828995c2b9cc73b79c23de960beda27ab71de88afdf00e40f367c6b13cee1ce3 + checksum: 10c0/be812e1517a967977750a41f15a2070cea63e1774137737426f636e1bd379f4dfc73482fa7f07df6b9a1413ee50c6e2d790936d7986bdcafd46255d871c17b76 languageName: node linkType: hard @@ -8934,9 +9347,9 @@ __metadata: linkType: hard "lodash@npm:^4.15.0, lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + version: 4.18.1 + resolution: "lodash@npm:4.18.1" + checksum: 10c0/757228fc68805c59789e82185135cf85f05d0b2d3d54631d680ca79ec21944ec8314d4533639a14b8bcfbd97a517e78960933041a5af17ecb693ec6eecb99a27 languageName: node linkType: hard @@ -8991,10 +9404,10 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": - version: 11.2.4 - resolution: "lru-cache@npm:11.2.4" - checksum: 10c0/4a24f9b17537619f9144d7b8e42cd5a225efdfd7076ebe7b5e7dc02b860a818455201e67fbf000765233fe7e339d3c8229fc815e9b58ee6ede511e07608c19b2 +"lru-cache@npm:^11.0.0": + version: 11.5.2 + resolution: "lru-cache@npm:11.5.2" + checksum: 10c0/ece1ad731f5b655e85d67047d04bfc13823dc77aa61c5454924a9869ba600a0104e39cc33d726021feef812bc347ca34a5608a5eb1972a5dd0870b7ecd42c3f2 languageName: node linkType: hard @@ -9026,9 +9439,9 @@ __metadata: linkType: hard "macos-release@npm:^3.3.0": - version: 3.4.0 - resolution: "macos-release@npm:3.4.0" - checksum: 10c0/cb6ea203cc2a2b2cc2214db4658d0da0e52f8298c5c43c94cf9cb9e871daac59e4e56a2559859727a4b43b0afec1123f998ef62c58d1ac6c6c8a5c8a808330cb + version: 3.5.1 + resolution: "macos-release@npm:3.5.1" + checksum: 10c0/a940167179ba1eeb0b514c447f0c2cc40e7301289ba0941e3c98b80262e34d4790bba73e4e99b215f44909e38f841fac72f93c89a94851d58431d275981979f8 languageName: node linkType: hard @@ -9041,25 +9454,6 @@ __metadata: languageName: node linkType: hard -"make-fetch-happen@npm:^15.0.0": - version: 15.0.3 - resolution: "make-fetch-happen@npm:15.0.3" - dependencies: - "@npmcli/agent": "npm:^4.0.0" - cacache: "npm:^20.0.1" - http-cache-semantics: "npm:^4.1.1" - minipass: "npm:^7.0.2" - minipass-fetch: "npm:^5.0.0" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^1.0.0" - proc-log: "npm:^6.0.0" - promise-retry: "npm:^2.0.1" - ssri: "npm:^13.0.0" - checksum: 10c0/525f74915660be60b616bcbd267c4a5b59481b073ba125e45c9c3a041bb1a47a2bd0ae79d028eb6f5f95bf9851a4158423f5068539c3093621abb64027e8e461 - languageName: node - linkType: hard - "makeerror@npm:1.0.12": version: 1.0.12 resolution: "makeerror@npm:1.0.12" @@ -9132,69 +9526,70 @@ __metadata: languageName: node linkType: hard -"metro-babel-transformer@npm:0.83.3": - version: 0.83.3 - resolution: "metro-babel-transformer@npm:0.83.3" +"metro-babel-transformer@npm:0.84.4": + version: 0.84.4 + resolution: "metro-babel-transformer@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" flow-enums-runtime: "npm:^0.0.6" - hermes-parser: "npm:0.32.0" + hermes-parser: "npm:0.35.0" + metro-cache-key: "npm:0.84.4" nullthrows: "npm:^1.1.1" - checksum: 10c0/b0107f86cdc9ef9419d669b5b3dac22e35b02c67c480563a63d98f5fb50953587938769efc854bfc09c225557790cd6488dbe3fed6f05c2b3f322cfb2e5ff577 + checksum: 10c0/d1ac996666334bc1cfe9d399cbf4cd747b675f6f8f758c2317eebcc52bd76046ed864ddb7b270efeb8cf337940a61fb03912e5c859b7cbc54687c2f5c41a9d2a languageName: node linkType: hard -"metro-cache-key@npm:0.83.3": - version: 0.83.3 - resolution: "metro-cache-key@npm:0.83.3" +"metro-cache-key@npm:0.84.4": + version: 0.84.4 + resolution: "metro-cache-key@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/403a2ca5b5bbb31a979effaa31fba0c47e2eb3830428c39c99db58aa0739a6fcc386f5a56c91495c53a4569065f0bda29e3038e9c41ca17af443971395f257dc + checksum: 10c0/a82ab6367f11886d960cc8fa1f3aa54f6529fe30c16059c141c3e789084c50838fdd7e1a5528534cd9c11a74c63aa5c6a7461dbfa50e8c449b6141eaf2fd05e0 languageName: node linkType: hard -"metro-cache@npm:0.83.3": - version: 0.83.3 - resolution: "metro-cache@npm:0.83.3" +"metro-cache@npm:0.84.4": + version: 0.84.4 + resolution: "metro-cache@npm:0.84.4" dependencies: exponential-backoff: "npm:^3.1.1" flow-enums-runtime: "npm:^0.0.6" https-proxy-agent: "npm:^7.0.5" - metro-core: "npm:0.83.3" - checksum: 10c0/608e85d819092c0b472c9adabb5de58e88355739de71833230626c1af7f3ce5dd1dca9f1ff3a836d995201f717315fd769c4c646a818c1f490ea2ec29417e32a + metro-core: "npm:0.84.4" + checksum: 10c0/3bf7f3a1f85b4f1af05f4b2c71c78e56fd3262d967ee43f02e9ff6820254063af33a70b6549e3dc5e993a6a0b9df92e9279632ad9a8b1cde2577342f93df45eb languageName: node linkType: hard -"metro-config@npm:0.83.3, metro-config@npm:^0.83.1": - version: 0.83.3 - resolution: "metro-config@npm:0.83.3" +"metro-config@npm:0.84.4, metro-config@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-config@npm:0.84.4" dependencies: connect: "npm:^3.6.5" flow-enums-runtime: "npm:^0.0.6" jest-validate: "npm:^29.7.0" - metro: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-core: "npm:0.83.3" - metro-runtime: "npm:0.83.3" + metro: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-core: "npm:0.84.4" + metro-runtime: "npm:0.84.4" yaml: "npm:^2.6.1" - checksum: 10c0/c53e4a061cfc776a65cdb5055c0be840055f9741dae25e7d407835988618b15f1407270dbd957c7333d01e9c79eccbf8e6bcb76421b2145bd134b53df459a033 + checksum: 10c0/f8aaf7d8cff9b486353b62f4746b0a70f99749bd4061f5ae847524aaedcd9c5a34bf176cbbe12fb33e771e8ed3c1496654b2578fa5ba8b9e4f856f0589744d98 languageName: node linkType: hard -"metro-core@npm:0.83.3, metro-core@npm:^0.83.1": - version: 0.83.3 - resolution: "metro-core@npm:0.83.3" +"metro-core@npm:0.84.4, metro-core@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-core@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" lodash.throttle: "npm:^4.1.1" - metro-resolver: "npm:0.83.3" - checksum: 10c0/d44c1f117c4b27f18abd27110e9536abf3105733e8fccaa522bd0e008248cce0260130517840c4914d7ce5df498f39ecfd43b6046a0f0b1c0f8ada7de38e52c4 + metro-resolver: "npm:0.84.4" + checksum: 10c0/19d859de16b5e082c9c31bed981c579a4e6d31a626c7829b725df9ae0ffb755d0ef7809ba9f8adf22d3921f5ffdd931ed77b21b95ca2ea17895f0c99b3cab831 languageName: node linkType: hard -"metro-file-map@npm:0.83.3": - version: 0.83.3 - resolution: "metro-file-map@npm:0.83.3" +"metro-file-map@npm:0.84.4": + version: 0.84.4 + resolution: "metro-file-map@npm:0.84.4" dependencies: debug: "npm:^4.4.0" fb-watchman: "npm:^2.0.0" @@ -9205,146 +9600,144 @@ __metadata: micromatch: "npm:^4.0.4" nullthrows: "npm:^1.1.1" walker: "npm:^1.0.7" - checksum: 10c0/4bf9c0fcdb5a5c08851f7370d6427fb68a770f156c4eabbddf20bd3583fb25ae428507eaeb8dc525e792db41d048620209750f33735055863abc909cbb6ef71a + checksum: 10c0/09ca829570d1d6dc5beb0534da8a7f2bfcae5415b0974fd5f58b4a05da95dbafdd47f7dc8dedeb11b6562ee9a92c4d918466d02a05cda6e1eaf2c400cbbe6fb4 languageName: node linkType: hard -"metro-minify-terser@npm:0.83.3": - version: 0.83.3 - resolution: "metro-minify-terser@npm:0.83.3" +"metro-minify-terser@npm:0.84.4": + version: 0.84.4 + resolution: "metro-minify-terser@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" terser: "npm:^5.15.0" - checksum: 10c0/9158e3199c0ea647776a7ed5c68ec1bb493f5347ac979f1ca75020cf1c39f907bd29983d60f8cb24dca17053d6b5c35f140c6d720fad0bd0fa9728e8c51e95c6 + checksum: 10c0/c9b36c2adb8254c38bdedad9da8bf2b7fae7f45cbd883e590430a5fc9cad808af24dd08a9420925e15733dab886528ad553e3eeb3faffc53d3ad80e7e03e5f6d languageName: node linkType: hard -"metro-resolver@npm:0.83.3": - version: 0.83.3 - resolution: "metro-resolver@npm:0.83.3" +"metro-resolver@npm:0.84.4": + version: 0.84.4 + resolution: "metro-resolver@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/1d6c030a00b987fbee38e5c632219b2be602e38c9aa9628bb4b591f646e64130d08adb8dcb35076c5c8cc151135557b655f3dee514c0df9f26d3416629eb006b + checksum: 10c0/468334270598222e15cbee32af51a3b5e1f4fa6869794955b95d1134b28a58594e8e3879e841ccf00bbb5cd86c689a4481714d6c6a464931987d5333d2c55f80 languageName: node linkType: hard -"metro-runtime@npm:0.83.3, metro-runtime@npm:^0.83.1": - version: 0.83.3 - resolution: "metro-runtime@npm:0.83.3" +"metro-runtime@npm:0.84.4, metro-runtime@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-runtime@npm:0.84.4" dependencies: "@babel/runtime": "npm:^7.25.0" flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/1d788483b6c2f13e0ea9ff4564996154754d3de84f683812ac848053eaea9243144adee3e8ffe90789e6c253f7402211d72b1b5ebf09e6c23841bc956a680253 + checksum: 10c0/e2b2e819027940c6bbd081e5650238d52b6c6d78561cd486b8c10cd1e7fce0213c66fa7f885e37ad5377fcd5726b1c9e473fba6de13938cdf2c966e82968c05f languageName: node linkType: hard -"metro-source-map@npm:0.83.3, metro-source-map@npm:^0.83.1": - version: 0.83.3 - resolution: "metro-source-map@npm:0.83.3" +"metro-source-map@npm:0.84.4, metro-source-map@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-source-map@npm:0.84.4" dependencies: - "@babel/traverse": "npm:^7.25.3" - "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3" - "@babel/types": "npm:^7.25.2" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" invariant: "npm:^2.2.4" - metro-symbolicate: "npm:0.83.3" + metro-symbolicate: "npm:0.84.4" nullthrows: "npm:^1.1.1" - ob1: "npm:0.83.3" + ob1: "npm:0.84.4" source-map: "npm:^0.5.6" vlq: "npm:^1.0.0" - checksum: 10c0/47e984bde1f8f06348298771f44b5803657c9cfa387df8ff36a359cc72ae3bc0e9c4ea6141345609b183ac8c63dcc997000d3626006e388c24779abb57c6f82c + checksum: 10c0/39df4524022e07aa4b4d09dd874a9509eb9e2e1e491e80a35099020347ab6be2407851b026452296aad314b0eb7ecf14f9b6bab96bd7c31d47d8b1eb30279aaf languageName: node linkType: hard -"metro-symbolicate@npm:0.83.3": - version: 0.83.3 - resolution: "metro-symbolicate@npm:0.83.3" +"metro-symbolicate@npm:0.84.4": + version: 0.84.4 + resolution: "metro-symbolicate@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" invariant: "npm:^2.2.4" - metro-source-map: "npm:0.83.3" + metro-source-map: "npm:0.84.4" nullthrows: "npm:^1.1.1" source-map: "npm:^0.5.6" vlq: "npm:^1.0.0" bin: metro-symbolicate: src/index.js - checksum: 10c0/bd3d234c7581466a9a78f952caa25816666753f6b560fe41502727b3e59931ac65225c9909635dc7c25d4dfaf392631366ef3ec5fa8490413385d60f8d900112 + checksum: 10c0/416a9ef694150a8ec708187743b74ab67e0b4fec39c64610b3771b584830117670a62acb9aa824f84a44efbb1cfec07aaf943d1aaf349d977eecf7c72bd8c0bf languageName: node linkType: hard -"metro-transform-plugins@npm:0.83.3": - version: 0.83.3 - resolution: "metro-transform-plugins@npm:0.83.3" +"metro-transform-plugins@npm:0.84.4": + version: 0.84.4 + resolution: "metro-transform-plugins@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" + "@babel/generator": "npm:^7.29.1" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" nullthrows: "npm:^1.1.1" - checksum: 10c0/df3c6db6a69d4888e1b6aad40d48ffec0c3c3faa38e89c07633432fc107ef12c47d55598904c91aadfe0751c5bcb7ec191f8a5ee70c18d253201150fc617ca37 + checksum: 10c0/7edb0c0d3655e9f5f5fb8bd8221ec297394b8730c959a3245ea81e50da8177ad7782f21696201a0dcb922281efd919e9548d5b819d8338e52d4b130f06333123 languageName: node linkType: hard -"metro-transform-worker@npm:0.83.3": - version: 0.83.3 - resolution: "metro-transform-worker@npm:0.83.3" +"metro-transform-worker@npm:0.84.4": + version: 0.84.4 + resolution: "metro-transform-worker@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" - metro: "npm:0.83.3" - metro-babel-transformer: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-cache-key: "npm:0.83.3" - metro-minify-terser: "npm:0.83.3" - metro-source-map: "npm:0.83.3" - metro-transform-plugins: "npm:0.83.3" + metro: "npm:0.84.4" + metro-babel-transformer: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-cache-key: "npm:0.84.4" + metro-minify-terser: "npm:0.84.4" + metro-source-map: "npm:0.84.4" + metro-transform-plugins: "npm:0.84.4" nullthrows: "npm:^1.1.1" - checksum: 10c0/bea0cbcc7d13cd2b97a2159257b3a53b9ecfb15da18ace82ae05bf2d0ac7cc1806c0bd77ed3b8f4c82c9532773fb99f3938e4b1480e2673f5eda69575ee1d7ef + checksum: 10c0/95924f9bcaf6df931bba2783f440d8fab29909bdde8cecdcc3bc7603e7de71e51728a34288f045694b616c94216d1fc683493b8a470e074c9c8a7f220aa9f9b5 languageName: node linkType: hard -"metro@npm:0.83.3, metro@npm:^0.83.1": - version: 0.83.3 - resolution: "metro@npm:0.83.3" +"metro@npm:0.84.4, metro@npm:^0.84.3": + version: 0.84.4 + resolution: "metro@npm:0.84.4" dependencies: - "@babel/code-frame": "npm:^7.24.7" + "@babel/code-frame": "npm:^7.29.0" "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" - accepts: "npm:^1.3.7" - chalk: "npm:^4.0.0" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + accepts: "npm:^2.0.0" ci-info: "npm:^2.0.0" connect: "npm:^3.6.5" debug: "npm:^4.4.0" error-stack-parser: "npm:^2.0.6" flow-enums-runtime: "npm:^0.0.6" graceful-fs: "npm:^4.2.4" - hermes-parser: "npm:0.32.0" + hermes-parser: "npm:0.35.0" image-size: "npm:^1.0.2" invariant: "npm:^2.2.4" jest-worker: "npm:^29.7.0" jsc-safe-url: "npm:^0.2.2" lodash.throttle: "npm:^4.1.1" - metro-babel-transformer: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-cache-key: "npm:0.83.3" - metro-config: "npm:0.83.3" - metro-core: "npm:0.83.3" - metro-file-map: "npm:0.83.3" - metro-resolver: "npm:0.83.3" - metro-runtime: "npm:0.83.3" - metro-source-map: "npm:0.83.3" - metro-symbolicate: "npm:0.83.3" - metro-transform-plugins: "npm:0.83.3" - metro-transform-worker: "npm:0.83.3" - mime-types: "npm:^2.1.27" + metro-babel-transformer: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-cache-key: "npm:0.84.4" + metro-config: "npm:0.84.4" + metro-core: "npm:0.84.4" + metro-file-map: "npm:0.84.4" + metro-resolver: "npm:0.84.4" + metro-runtime: "npm:0.84.4" + metro-source-map: "npm:0.84.4" + metro-symbolicate: "npm:0.84.4" + metro-transform-plugins: "npm:0.84.4" + metro-transform-worker: "npm:0.84.4" + mime-types: "npm:^3.0.1" nullthrows: "npm:^1.1.1" serialize-error: "npm:^2.1.0" source-map: "npm:^0.5.6" @@ -9353,7 +9746,7 @@ __metadata: yargs: "npm:^17.6.2" bin: metro: src/cli.js - checksum: 10c0/9513c05725c3984ce3b72896c4f7d019ad4fd024a1231b8b84c5c655a0563fc7f26725f28c20c5d3511e3825d64fec3a1e68621f6a6af34d785c5e714ed7da89 + checksum: 10c0/ff92915119db29cd855274f3789d391cba83c50cb92e22d1e9b8c729e7f6d39495e32540a22ca4c6591eea6a847ade49fcfa5faab01b2300227e3f1fc7df359c languageName: node linkType: hard @@ -9381,7 +9774,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:3.0.2": +"mime-types@npm:3.0.2, mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": version: 3.0.2 resolution: "mime-types@npm:3.0.2" dependencies: @@ -9390,7 +9783,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.27, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -9438,30 +9831,30 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.1.1": - version: 10.1.1 - resolution: "minimatch@npm:10.1.1" +"minimatch@npm:^10.0.1, minimatch@npm:^10.2.2": + version: 10.2.6 + resolution: "minimatch@npm:10.2.6" dependencies: - "@isaacs/brace-expansion": "npm:^5.0.0" - checksum: 10c0/c85d44821c71973d636091fddbfbffe62370f5ee3caf0241c5b60c18cd289e916200acb2361b7e987558cd06896d153e25d505db9fc1e43e6b4b6752e2702902 + brace-expansion: "npm:^5.0.8" + checksum: 10c0/4559a836243b98bd4d17ea9f7edae698717c76399eea7be374f3737f33164e4907f19e9726891ddeb122f750a5a7fa80d2ac43e851d6e5984dc4ff42ec127d3a languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2, minimatch@npm:^3.1.5": + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" dependencies: brace-expansion: "npm:^1.1.7" - checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 + checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70 languageName: node linkType: hard "minimatch@npm:^9.0.4": - version: 9.0.5 - resolution: "minimatch@npm:9.0.5" + version: 9.0.9 + resolution: "minimatch@npm:9.0.9" dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed + brace-expansion: "npm:^2.0.2" + checksum: 10c0/0b6a58530dbb00361745aa6c8cffaba4c90f551afe7c734830bd95fd88ebf469dd7355a027824ea1d09e37181cfeb0a797fb17df60c15ac174303ac110eb7e86 languageName: node linkType: hard @@ -9472,74 +9865,14 @@ __metadata: languageName: node linkType: hard -"minipass-collect@npm:^2.0.1": - version: 2.0.1 - resolution: "minipass-collect@npm:2.0.1" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e - languageName: node - linkType: hard - -"minipass-fetch@npm:^5.0.0": - version: 5.0.0 - resolution: "minipass-fetch@npm:5.0.0" - dependencies: - encoding: "npm:^0.1.13" - minipass: "npm:^7.0.3" - minipass-sized: "npm:^1.0.3" - minizlib: "npm:^3.0.1" - dependenciesMeta: - encoding: - optional: true - checksum: 10c0/9443aab5feab190972f84b64116e54e58dd87a58e62399cae0a4a7461b80568281039b7c3a38ba96453431ebc799d1e26999e548540156216729a4967cd5ef06 - languageName: node - linkType: hard - -"minipass-flush@npm:^1.0.5": - version: 1.0.5 - resolution: "minipass-flush@npm:1.0.5" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd - languageName: node - linkType: hard - -"minipass-pipeline@npm:^1.2.4": - version: 1.2.4 - resolution: "minipass-pipeline@npm:1.2.4" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 - languageName: node - linkType: hard - -"minipass-sized@npm:^1.0.3": - version: 1.0.3 - resolution: "minipass-sized@npm:1.0.3" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb - languageName: node - linkType: hard - -"minipass@npm:^3.0.0": - version: 3.3.6 - resolution: "minipass@npm:3.3.6" - dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c - languageName: node - linkType: hard - -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb languageName: node linkType: hard -"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": +"minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" dependencies: @@ -9578,12 +9911,12 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.1, nanoid@npm:^3.3.11": - version: 3.3.11 - resolution: "nanoid@npm:3.3.11" +"nanoid@npm:^3.3.11": + version: 3.3.16 + resolution: "nanoid@npm:3.3.16" bin: nanoid: bin/nanoid.cjs - checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b + checksum: 10c0/bbf2dcffe22d2b62d16de2711752070b539c0f644c7916f823ad6521986b2078cbe524f2d6240f58c46e9141ea0c7b87a029e100c0f7f175228cacaf30e41bba languageName: node linkType: hard @@ -9623,9 +9956,9 @@ __metadata: linkType: hard "netmask@npm:^2.0.2": - version: 2.0.2 - resolution: "netmask@npm:2.0.2" - checksum: 10c0/cafd28388e698e1138ace947929f842944d0f1c0b87d3fa2601a61b38dc89397d33c0ce2c8e7b99e968584b91d15f6810b91bef3f3826adf71b1833b61d4bf4f + version: 2.1.1 + resolution: "netmask@npm:2.1.1" + checksum: 10c0/c78e31869b0578fb0a9874a0c0fdf0e1f8b3492392d1043355fb11d9ea42ef94e0216c6aee7d8e15db39d1a8caf331f9b144ae3ee43fd951b73a66837711fb09 languageName: node linkType: hard @@ -9638,6 +9971,21 @@ __metadata: languageName: node linkType: hard +"nitrogen@npm:0.36.1": + version: 0.36.1 + resolution: "nitrogen@npm:0.36.1" + dependencies: + chalk: "npm:^5.3.0" + react-native-nitro-modules: "npm:^0.36.1" + ts-morph: "npm:^28.0.0" + yargs: "npm:^18.0.0" + zod: "npm:^4.4.3" + bin: + nitrogen: lib/index.js + checksum: 10c0/a639dbadeca131be7dc059558b599fc2a1d45a88c4260d936a77e9402d1f81208f770c6085c4f5f13f48a10ec1cba04425278558dc0cfd41434e41d1a555cacb + languageName: node + linkType: hard + "nocache@npm:^3.0.1": version: 3.0.4 resolution: "nocache@npm:3.0.4" @@ -9645,6 +9993,18 @@ __metadata: languageName: node linkType: hard +"node-exports-info@npm:^1.6.0": + version: 1.6.2 + resolution: "node-exports-info@npm:1.6.2" + dependencies: + array.prototype.flatmap: "npm:^1.3.3" + es-errors: "npm:^1.3.0" + object.entries: "npm:^1.1.9" + semver: "npm:^6.3.1" + checksum: 10c0/5278fab18e8c97f45275c51819c3078ca9488361e875bc01b680776a339d2fee1ca9c6fcfb972df14945a1b184cc9924a1d9ba87e90f6cb3422c7f5b6900f4bc + languageName: node + linkType: hard + "node-fetch-native@npm:^1.6.6": version: 1.6.7 resolution: "node-fetch-native@npm:1.6.7" @@ -9653,22 +10013,22 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 12.1.0 - resolution: "node-gyp@npm:12.1.0" + version: 13.0.1 + resolution: "node-gyp@npm:13.0.1" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" graceful-fs: "npm:^4.2.6" - make-fetch-happen: "npm:^15.0.0" - nopt: "npm:^9.0.0" - proc-log: "npm:^6.0.0" + nopt: "npm:^10.0.0" + proc-log: "npm:^7.0.0" semver: "npm:^7.3.5" - tar: "npm:^7.5.2" + tar: "npm:^7.5.4" tinyglobby: "npm:^0.2.12" - which: "npm:^6.0.0" + undici: "npm:^8.4.1" + which: "npm:^7.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/f43efea8aaf0beb6b2f6184e533edad779b2ae38062953e21951f46221dd104006cc574154f2ad4a135467a5aae92c49e84ef289311a82e08481c5df0e8dc495 + checksum: 10c0/424077bc9e9bbe953a8e86db473ba818cbc6a121714008c977fd589e21e5f0c811fbf22faac730dc7182450b5e52df301811d01ae3373898658d999b7710f4e6 languageName: node linkType: hard @@ -9679,28 +10039,28 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.27": - version: 2.0.27 - resolution: "node-releases@npm:2.0.27" - checksum: 10c0/f1e6583b7833ea81880627748d28a3a7ff5703d5409328c216ae57befbced10ce2c991bea86434e8ec39003bd017f70481e2e5f8c1f7e0a7663241f81d6e00e2 +"node-releases@npm:^2.0.51": + version: 2.0.51 + resolution: "node-releases@npm:2.0.51" + checksum: 10c0/6cf3fe1f9eabe02ce6de67e9db77b73edc9f5625003791e1f8f239f8e2a851450a5aeb1eff2cc43cfb26312e19b26bfe07626bf428479e6a76f56553fc6148da languageName: node linkType: hard "node-stream-zip@npm:^1.9.1": - version: 1.15.0 - resolution: "node-stream-zip@npm:1.15.0" - checksum: 10c0/429fce95d7e90e846adbe096c61d2ea8d18defc155c0345d25d0f98dd6fc72aeb95039318484a4e0a01dc3814b6d0d1ae0fe91847a29669dff8676ec064078c9 + version: 1.16.0 + resolution: "node-stream-zip@npm:1.16.0" + checksum: 10c0/3e201e39b42b46c2e543bd11c71821aa675a98d6cb4901840bd952281696599c9c29c630cd00e8da9bee4b02879fee2d0194a225b359d48a3bf966bdd63d8648 languageName: node linkType: hard -"nopt@npm:^9.0.0": - version: 9.0.0 - resolution: "nopt@npm:9.0.0" +"nopt@npm:^10.0.0": + version: 10.0.1 + resolution: "nopt@npm:10.0.1" dependencies: - abbrev: "npm:^4.0.0" + abbrev: "npm:^5.0.0" bin: nopt: bin/nopt.js - checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd + checksum: 10c0/980d89257f9587f3e1f77877ddbf905d6aa3b738ec33e49a4fa1a059a0dd82eb28063982b150654a7ae9de386f2ead60e56172db7d37cf56de545f7392a2a26a languageName: node linkType: hard @@ -9757,26 +10117,24 @@ __metadata: linkType: hard "nypm@npm:^0.6.0": - version: 0.6.2 - resolution: "nypm@npm:0.6.2" + version: 0.6.9 + resolution: "nypm@npm:0.6.9" dependencies: - citty: "npm:^0.1.6" - consola: "npm:^3.4.2" + citty: "npm:^0.2.2" pathe: "npm:^2.0.3" - pkg-types: "npm:^2.3.0" - tinyexec: "npm:^1.0.1" + tinyexec: "npm:^1.2.4" bin: - nypm: dist/cli.mjs - checksum: 10c0/b1aca658e29ed616ad6e487f9c3fd76773485ad75c1f99efe130ccb304de60b639a3dda43c3ce6c060113a3eebaee7ccbea554f5fbd1f244474181dc9bf3f17c + nypm: ./dist/cli.mjs + checksum: 10c0/8014c1842e554531a5092bae9f483d22413fe5f68fd2e15e74a2b7dc5b94e36cac836b9ebe9a70fd7ccba65a663c517c98663368f5b5e48d6bc65d74f0752d72 languageName: node linkType: hard -"ob1@npm:0.83.3": - version: 0.83.3 - resolution: "ob1@npm:0.83.3" +"ob1@npm:0.84.4": + version: 0.84.4 + resolution: "ob1@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/9231315de39cf0612a01e283c7d7ef31d16618e598de96e44ae1ab3007629296ce1a3d5d02ef60ff22d9fefe33050358c10e7fcba8278861157b89befe13cb3d + checksum: 10c0/8bf3a3bdc2b27f1b1b60569c31ff2d9d829025f9a1ce7388b5e810242e48672c8d6b24e5972d6e30aef4d84f6894d12b13d0c6c418460d031da1972b96920bba languageName: node linkType: hard @@ -10009,13 +10367,14 @@ __metadata: linkType: hard "own-keys@npm:^1.0.1": - version: 1.0.1 - resolution: "own-keys@npm:1.0.1" + version: 1.0.2 + resolution: "own-keys@npm:1.0.2" dependencies: - get-intrinsic: "npm:^1.2.6" + call-bound: "npm:^1.0.4" + get-intrinsic: "npm:^1.3.0" object-keys: "npm:^1.1.1" safe-push-apply: "npm:^1.0.0" - checksum: 10c0/6dfeb3455bff92ec3f16a982d4e3e65676345f6902d9f5ded1d8265a6318d0200ce461956d6d1c70053c7fe9f9fe65e552faac03f8140d37ef0fdd108e67013a + checksum: 10c0/84b0d9959475231166c3d4b9abd1b8af8042911e2e5625761eed980d1a1e4381cf52b34d907cae21ee8766c79de943f3cd85eba636149dee5e64cceff3ccdb78 languageName: node linkType: hard @@ -10083,9 +10442,9 @@ __metadata: linkType: hard "p-map@npm:^7.0.2": - version: 7.0.4 - resolution: "p-map@npm:7.0.4" - checksum: 10c0/a5030935d3cb2919d7e89454d1ce82141e6f9955413658b8c9403cfe379283770ed3048146b44cde168aa9e8c716505f196d5689db0ae3ce9a71521a2fef3abd + version: 7.0.6 + resolution: "p-map@npm:7.0.6" + checksum: 10c0/46e3b3c79b6179613161aa1a28c72cfe7155f27f1928afee1b2406858728f9dd4c29637bba25cef9b50517caacdcb71549f5ff228292524b0069b2310922b22e languageName: node linkType: hard @@ -10176,6 +10535,13 @@ __metadata: languageName: node linkType: hard +"path-browserify@npm:^1.0.1": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: 10c0/8b8c3fd5c66bd340272180590ae4ff139769e9ab79522e2eb82e3d571a89b8117c04147f65ad066dccfb42fcad902e5b7d794b3d35e0fd840491a8ddbedf8c66 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -10228,13 +10594,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^2.0.0": - version: 2.0.1 - resolution: "path-scurry@npm:2.0.1" +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" dependencies: lru-cache: "npm:^11.0.0" minipass: "npm:^7.1.2" - checksum: 10c0/2a16ed0e81fbc43513e245aa5763354e25e787dab0d539581a6c3f0f967461a159ed6236b2559de23aa5b88e7dc32b469b6c47568833dd142a4b24b4f5cd2620 + checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 languageName: node linkType: hard @@ -10260,9 +10626,9 @@ __metadata: linkType: hard "perfect-debounce@npm:^2.0.0": - version: 2.0.0 - resolution: "perfect-debounce@npm:2.0.0" - checksum: 10c0/c08d7bf9c43f262206eceb9b3dfd332e2470b5488bb93f87721c498045e61e4f3f1d21abfe3236a8eab547c7cc031d3efb64cd3b38a85a820d5cafb4c897a8d4 + version: 2.1.0 + resolution: "perfect-debounce@npm:2.1.0" + checksum: 10c0/c4f833816f249129cea996d60b1351b640cf06954ab4eecaca440234ef70f4aefe6483637049750f5b00e15a5036307ea77f831c9779d6ad878457680af49b6d languageName: node linkType: hard @@ -10274,16 +10640,16 @@ __metadata: linkType: hard "picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + version: 2.3.2 + resolution: "picomatch@npm:2.3.2" + checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 languageName: node linkType: hard -"picomatch@npm:^4.0.3": - version: 4.0.3 - resolution: "picomatch@npm:4.0.3" - checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 +"picomatch@npm:^4.0.3, picomatch@npm:^4.0.4": + version: 4.0.5 + resolution: "picomatch@npm:4.0.5" + checksum: 10c0/947bc6b6e1ff1e6c5aaf95b107a0839d12802f4f7b867663f67d47accba939ca1cb582cf99dfc30438efa1c4648ac5990967e783e8929c36b03e8440704ef1bd languageName: node linkType: hard @@ -10304,17 +10670,28 @@ __metadata: linkType: hard "pkg-types@npm:^2.3.0": - version: 2.3.0 - resolution: "pkg-types@npm:2.3.0" + version: 2.3.1 + resolution: "pkg-types@npm:2.3.1" dependencies: - confbox: "npm:^0.2.2" - exsolve: "npm:^1.0.7" + confbox: "npm:^0.2.4" + exsolve: "npm:^1.0.8" pathe: "npm:^2.0.3" - checksum: 10c0/d2bbddc5b81bd4741e1529c08ef4c5f1542bbdcf63498b73b8e1d84cff71806d1b8b1577800549bb569cb7aa20056257677b979bff48c97967cba7e64f72ae12 + checksum: 10c0/dd9b20682426abaddcac9dc786aa22542e12df15a03dea2afa7bf54da0933358c6c7f545c0c3c1c7b24a2904ab4a451bf4e34a50c6837e458359eea30c257ed4 + languageName: node + linkType: hard + +"plist@npm:^3.0.5": + version: 3.1.1 + resolution: "plist@npm:3.1.1" + dependencies: + "@xmldom/xmldom": "npm:^0.9.10" + base64-js: "npm:^1.5.1" + xmlbuilder: "npm:^15.1.1" + checksum: 10c0/af681277c2e541c6aab0ddee57f59459c43beeea1ee7aa2d4218aa39595fb41c068e2d2be3e4abb17e3252eaf2c1b806ecfb1d402fa5a3f4a6e1a7a32c880c9a languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": +"possible-typed-array-names@npm:^1.0.0, possible-typed-array-names@npm:^1.1.0": version: 1.1.0 resolution: "possible-typed-array-names@npm:1.1.0" checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196 @@ -10335,7 +10712,7 @@ __metadata: languageName: node linkType: hard -"prettier-linter-helpers@npm:^1.0.0": +"prettier-linter-helpers@npm:^1.0.1": version: 1.0.1 resolution: "prettier-linter-helpers@npm:1.0.1" dependencies: @@ -10364,20 +10741,10 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^6.0.0": - version: 6.1.0 - resolution: "proc-log@npm:6.1.0" - checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82 - languageName: node - linkType: hard - -"promise-retry@npm:^2.0.1": - version: 2.0.1 - resolution: "promise-retry@npm:2.0.1" - dependencies: - err-code: "npm:^2.0.2" - retry: "npm:^0.12.0" - checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 +"proc-log@npm:^7.0.0": + version: 7.0.0 + resolution: "proc-log@npm:7.0.0" + checksum: 10c0/b89c2d862604f35fec795477b0c7e376feab3ba0d4f4d291c4e959567442697cf451ac557d0623c1cc38af45a78128b983410f397a10c5d3a67f76c33de4754b languageName: node linkType: hard @@ -10442,12 +10809,12 @@ __metadata: linkType: hard "pump@npm:^3.0.0": - version: 3.0.3 - resolution: "pump@npm:3.0.3" + version: 3.0.4 + resolution: "pump@npm:3.0.4" dependencies: end-of-stream: "npm:^1.1.0" once: "npm:^1.3.1" - checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 + checksum: 10c0/2780e66b5471c19e3e3e1063b84f3f6a3a08367f24c5ed552f98cd5901e6ada27c7ad6495d4244f553fd03b01884a4561933064f053f47c8994d84fd352768ea languageName: node linkType: hard @@ -10465,12 +10832,13 @@ __metadata: languageName: node linkType: hard -"qs@npm:~6.14.0": - version: 6.14.1 - resolution: "qs@npm:6.14.1" +"qs@npm:~6.15.1": + version: 6.15.3 + resolution: "qs@npm:6.15.3" dependencies: - side-channel: "npm:^1.1.0" - checksum: 10c0/0e3b22dc451f48ce5940cbbc7c7d9068d895074f8c969c0801ac15c1313d1859c4d738e46dc4da2f498f41a9ffd8c201bd9fb12df67799b827db94cc373d2613 + es-define-property: "npm:^1.0.1" + side-channel: "npm:^1.1.1" + checksum: 10c0/8f3f6e45ece255347d57696628401cde29e9ec649fff698b53bd3150dea7cefdf33036e1bc1826b9f110bfa7cb0ec4ab9f5297eca628ce216c55af82c304e08e languageName: node linkType: hard @@ -10550,7 +10918,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.1, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 @@ -10565,15 +10933,15 @@ __metadata: linkType: hard "react-is@npm:^19.1.0": - version: 19.2.3 - resolution: "react-is@npm:19.2.3" - checksum: 10c0/2b54c422c21b8dbd68a435a1cce21ecd5b6f06f48659531f7d53dd7368365da5a67e946f352fb2010d11ca40658aa67bec90995f0f1ec5556c0f71dbffe54994 + version: 19.2.8 + resolution: "react-is@npm:19.2.8" + checksum: 10c0/ed5322c84efe035c8fc814b1614ff5ca7fb8c2872a7c045197daf99f9b1bd68f32a2c79ffcbcfcff2fc5d93924ff9f9447400898f5b1534e6302bb0736a257f0 languageName: node linkType: hard "react-native-builder-bob@npm:^0.40.13": - version: 0.40.17 - resolution: "react-native-builder-bob@npm:0.40.17" + version: 0.40.18 + resolution: "react-native-builder-bob@npm:0.40.18" dependencies: "@babel/core": "npm:^7.25.2" "@babel/plugin-transform-flow-strip-types": "npm:^7.26.5" @@ -10594,26 +10962,25 @@ __metadata: json5: "npm:^2.2.1" kleur: "npm:^4.1.4" prompts: "npm:^2.4.2" - react-native-monorepo-config: "npm:^0.3.1" + react-native-monorepo-config: "npm:^0.3.3" which: "npm:^2.0.2" yargs: "npm:^17.5.1" bin: bob: bin/bob - checksum: 10c0/b3bb6f907a181ea0473cbf68cbc9f594eb5f2adc885011f4d29c961258d5f123494c28565881c0190f9f1a297b11aad7a1238742dd88345b0390e4343d9c2c11 + checksum: 10c0/5f1c969d339ece33208faebbf7022c1db3ec127ab91a0f21a29e0d7cbd18dfa702586fa1169f9dd642fbceeb2733af4651143d50010effb8bb150a9bfd4cc4ff languageName: node linkType: hard -"react-native-gesture-handler@npm:^2.30.0": - version: 2.30.0 - resolution: "react-native-gesture-handler@npm:2.30.0" +"react-native-gesture-handler@npm:^3.0.2": + version: 3.1.0 + resolution: "react-native-gesture-handler@npm:3.1.0" dependencies: - "@egjs/hammerjs": "npm:^2.0.17" - hoist-non-react-statics: "npm:^3.3.0" + "@types/react-test-renderer": "npm:^19.1.0" invariant: "npm:^2.2.4" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/26b94b0f97433fc6fb5b1c196ef29fce4f5a66c77fabb1bc33db91099357fbd44a5220783fcbb91d42700bcd578f2fd114314029d9e0d4674878767d9b7f5df6 + checksum: 10c0/3d5e93b7f490abb6eecfa7b292c15f14fcb89103f6adfb9a9f7a2216924ee3e860d9e68ee9973df5b42a53229174043a50b679443ff13a7bbd2bf1077c44258d languageName: node linkType: hard @@ -10627,13 +10994,13 @@ __metadata: languageName: node linkType: hard -"react-native-is-edge-to-edge@npm:1.2.1": - version: 1.2.1 - resolution: "react-native-is-edge-to-edge@npm:1.2.1" +"react-native-is-edge-to-edge@npm:^1.3.1": + version: 1.3.1 + resolution: "react-native-is-edge-to-edge@npm:1.3.1" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/87d20b900aded7d44c90afb946a7aa03c23a94ca3dd547bdddc2303b85357e4aab22567a57b19f1558d6c8be7058e3dcf34faa1e15182d1604f90974266d9a1d + checksum: 10c0/28cebd5f1f3632864ff5e342278721d1e5e38627ae73859a8814012116ef15c629fee7137a6c9c97bb05d94bbe639b0b47e69b36fc2735ab53ed31570140663f languageName: node linkType: hard @@ -10647,78 +11014,108 @@ __metadata: languageName: node linkType: hard -"react-native-monorepo-config@npm:^0.3.1": - version: 0.3.2 - resolution: "react-native-monorepo-config@npm:0.3.2" +"react-native-monorepo-config@npm:^0.3.3": + version: 0.3.5 + resolution: "react-native-monorepo-config@npm:0.3.5" dependencies: escape-string-regexp: "npm:^5.0.0" fast-glob: "npm:^3.3.3" - checksum: 10c0/c711f6a898ae263b68aef3bf8bd9c3806cd489676da8c5480dd155859b47bcd49a7700f3c056896c19b3ce2c2c3ea42a5482def93b0ff03febbe023ceb128c96 + checksum: 10c0/e0343807046c16d5fb5999b966e0a70fd8a757d658f58f10bee830485fa600ffb8de9100dea1cdead36a639c3e18a0f697b35e22a5564cb74e437d8aeca30d87 + languageName: node + linkType: hard + +"react-native-nitro-image@npm:0.15.1": + version: 0.15.1 + resolution: "react-native-nitro-image@npm:0.15.1" + peerDependencies: + react: "*" + react-native: "*" + react-native-nitro-modules: "*" + checksum: 10c0/c8599543167ce1f53c838c2ec4a38923b617945d6dbea9717383a21688fa30d409f91a03a4d2645efa2fcd3523a4f06bdc97484507e99ebf10ac7236da55d735 + languageName: node + linkType: hard + +"react-native-nitro-modules@npm:0.36.1": + version: 0.36.1 + resolution: "react-native-nitro-modules@npm:0.36.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/8f0a56371d2de36531208794f81c457bbd00f00ae8f9c914fb752606585297607cbc1ad38681a1efb7d8cf4322537f300e0a822954a4b15c8d8c8f2c9d61cd12 + languageName: node + linkType: hard + +"react-native-nitro-modules@npm:^0.36.1": + version: 0.36.5 + resolution: "react-native-nitro-modules@npm:0.36.5" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/c7b2133f924967b68c0f0f678b5a5dce1a784a7e22f57ebf203ef5803a5c9c745b6d4dda8c9bcedd13f7c5ca53a8707784e98572a2ca8a864fe0b905163a34b5 languageName: node linkType: hard "react-native-permissions@npm:^5.4.4": - version: 5.4.4 - resolution: "react-native-permissions@npm:5.4.4" + version: 5.6.1 + resolution: "react-native-permissions@npm:5.6.1" peerDependencies: - react: ">=18.1.0" - react-native: ">=0.70.0" - react-native-windows: ">=0.70.0" + react: "*" + react-native: "*" + react-native-windows: "*" peerDependenciesMeta: react-native-windows: optional: true - checksum: 10c0/9a4fa223053db242a66c18303a525e7552e849876e927427485b0e799f46131ccbbd1ad85e6dfac146d12af942a77a95caa8649b9f4ebcfbb7f2ff6dd8fece04 + checksum: 10c0/8c64576c12df4abcdbd156ad26b9e1c272873b16de350618854225df504052b556ef7a2610e15952894072e6ae447a513773dffcca87c42395e1ad0f26d0c6c6 languageName: node linkType: hard -"react-native-reanimated@npm:^4.2.1": - version: 4.2.1 - resolution: "react-native-reanimated@npm:4.2.1" +"react-native-reanimated@npm:^4.5.1": + version: 4.5.3 + resolution: "react-native-reanimated@npm:4.5.3" dependencies: - react-native-is-edge-to-edge: "npm:1.2.1" - semver: "npm:7.7.3" + react-native-is-edge-to-edge: "npm:^1.3.1" + semver: "npm:^7.7.3" peerDependencies: react: "*" - react-native: "*" - react-native-worklets: ">=0.7.0" - checksum: 10c0/1458fb634d374125931c5815b2b0941e12b1a880ba12b4ff6bba12b6c101e0ce1f5c32a2226034ae762558e38077ae112d8498eb2c8af6bd967524c7e7f87c6b + react-native: 0.83 - 0.86 + react-native-worklets: 0.10.x - 0.11.x + checksum: 10c0/8297fab7ac5b4f26448f6d83f5a795045ad1dde798e7b73256728e2363b957a27f2db3c2a3c0a4c3ff96cff28da9392263a1ced64e3187d7080c647641b935d1 languageName: node linkType: hard "react-native-safe-area-context@npm:^5.6.2": - version: 5.6.2 - resolution: "react-native-safe-area-context@npm:5.6.2" + version: 5.8.0 + resolution: "react-native-safe-area-context@npm:5.8.0" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/3c8df21a1dbac83116b9c9bd5d20b7c1bb7649ecef44a111af6fb6b237241f5f4d692189eec30a69f5701b857249257da3621b9e17165460a2bb71faac7b92ae + checksum: 10c0/86d1375ce17d549b541d157148d9d093f9e918de47d3b0a5cbc4cb6afe619aa52e99f07dc62ee0878eaa70e8da3411193b24cfee1b7b271ffd295d0fce83d128 languageName: node linkType: hard -"react-native-screens@npm:^4.20.0": - version: 4.20.0 - resolution: "react-native-screens@npm:4.20.0" +"react-native-screens@npm:^4.26.0": + version: 4.26.2 + resolution: "react-native-screens@npm:4.26.2" dependencies: react-freeze: "npm:^1.0.0" warn-once: "npm:^0.1.0" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/f5d18bef4bee5b65470f76048dd3511d4ef18d1cf3566b6479a70a67e75c92aca3549342ee96c418e68997380dc562fbf4e63b5d411975c2265f106fecb242cd + checksum: 10c0/3cdc702d8e21c63331e306a2b971307d5d9e13df52d94f435c5bb8d5dcf09fed00f4ef788e85ba87fae1ba5b155f4cdc2ee177a70f1f512adff73f94eef844d1 languageName: node linkType: hard -"react-native-svg@npm:^15.15.1": - version: 15.15.1 - resolution: "react-native-svg@npm:15.15.1" +"react-native-svg@npm:^15.15.5": + version: 15.15.5 + resolution: "react-native-svg@npm:15.15.5" dependencies: css-select: "npm:^5.1.0" css-tree: "npm:^1.1.3" - warn-once: "npm:0.1.1" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/9e047e8afdd5121296a3402c5c37363b9b37fbddc41f7b0b49b923ac4d2898954c8b57a6784a625321236987e494ee54f594e22f9de815f807e03a3433d7fefd + checksum: 10c0/34b71b6c83d7235efbc4263abaffcbad780375f9e0fca95786e4f1a543a2b6d07e90c7df426f708e85be68331c412066cdc639f4a6ce82bed42bc728050d9402 languageName: node linkType: hard @@ -10729,34 +11126,36 @@ __metadata: "@babel/core": "npm:^7.25.2" "@babel/preset-env": "npm:^7.25.3" "@babel/runtime": "npm:^7.25.0" - "@gorhom/bottom-sheet": "npm:^5" "@react-native-community/blur": "npm:^4.4.1" - "@react-native-community/cli": "npm:20.0.0" - "@react-native-community/cli-platform-android": "npm:20.0.0" - "@react-native-community/cli-platform-ios": "npm:20.0.0" + "@react-native-community/cli": "npm:20.1.0" + "@react-native-community/cli-platform-android": "npm:20.1.0" + "@react-native-community/cli-platform-ios": "npm:20.1.0" "@react-native-community/slider": "npm:^5.1.2" - "@react-native/babel-preset": "npm:0.81.1" - "@react-native/metro-config": "npm:0.81.1" - "@react-native/typescript-config": "npm:0.81.1" + "@react-native/babel-preset": "npm:0.86.0" + "@react-native/metro-config": "npm:0.86.0" + "@react-native/typescript-config": "npm:0.86.0" "@react-navigation/elements": "npm:^2.9.3" "@react-navigation/native": "npm:^7.1.26" "@react-navigation/native-stack": "npm:^7.9.0" - "@types/react": "npm:^19.1.0" + "@swmansion/react-native-bottom-sheet": "npm:0.17.0-next.1" + "@types/react": "npm:^19.2.0" lucide-react-native: "npm:^0.562.0" - react: "npm:19.1.0" - react-native: "npm:0.81.1" + react: "npm:19.2.3" + react-native: "npm:0.86.0" react-native-builder-bob: "npm:^0.40.13" - react-native-gesture-handler: "npm:^2.30.0" + react-native-gesture-handler: "npm:^3.0.2" react-native-image-picker: "npm:^8.2.1" react-native-monorepo-config: "npm:^0.1.9" + react-native-nitro-image: "npm:0.15.1" + react-native-nitro-modules: "npm:0.36.1" react-native-permissions: "npm:^5.4.4" - react-native-reanimated: "npm:^4.2.1" + react-native-reanimated: "npm:^4.5.1" react-native-safe-area-context: "npm:^5.6.2" - react-native-screens: "npm:^4.20.0" - react-native-svg: "npm:^15.15.1" - react-native-vision-camera: "npm:^4.7.3" - react-native-worklets: "npm:^0.7.1" - react-native-worklets-core: "npm:^1.6.2" + react-native-screens: "npm:^4.26.0" + react-native-svg: "npm:^15.15.5" + react-native-vision-camera: "npm:^5.1.0" + react-native-vision-camera-worklets: "npm:^5.1.0" + react-native-worklets: "npm:0.10.2" zustand: "npm:^5.0.9" languageName: unknown linkType: soft @@ -10765,16 +11164,19 @@ __metadata: version: 0.0.0-use.local resolution: "react-native-vision-camera-mlkit@workspace:." dependencies: + "@babel/core": "npm:^7.25.2" "@commitlint/config-conventional": "npm:^19.8.1" "@eslint/compat": "npm:^1.3.2" "@eslint/eslintrc": "npm:^3.3.1" "@eslint/js": "npm:^9.35.0" - "@react-native-community/cli": "npm:20.0.1" - "@react-native/babel-preset": "npm:0.81.1" - "@react-native/eslint-config": "npm:^0.81.1" + "@expo/config-plugins": "npm:57.0.6" + "@react-native-community/cli": "npm:20.1.0" + "@react-native/babel-preset": "npm:0.86.0" + "@react-native/eslint-config": "npm:^0.86.0" + "@react-native/jest-preset": "npm:0.86.0" "@release-it/conventional-changelog": "npm:^10.0.1" "@types/jest": "npm:^29.5.14" - "@types/react": "npm:^19.1.0" + "@types/react": "npm:^19.2.0" commitlint: "npm:^19.8.1" del-cli: "npm:^6.0.0" eslint: "npm:^9.35.0" @@ -10782,125 +11184,126 @@ __metadata: eslint-plugin-prettier: "npm:^5.5.4" jest: "npm:^29.7.0" lefthook: "npm:^2.0.3" + nitrogen: "npm:0.36.1" prettier: "npm:^2.8.8" - react: "npm:19.1.0" - react-native: "npm:0.81.1" + react: "npm:19.2.3" + react-native: "npm:0.86.0" react-native-builder-bob: "npm:^0.40.13" - react-native-vision-camera: "npm:^4.7.3" - react-native-worklets-core: "npm:^1.6.2" + react-native-nitro-modules: "npm:0.36.1" + react-native-vision-camera: "npm:^5.1.0" release-it: "npm:^19.0.4" turbo: "npm:^2.5.6" typescript: "npm:^5.9.2" peerDependencies: + "@expo/config-plugins": ^57.0.0 react: "*" react-native: "*" - react-native-vision-camera: "*" - react-native-worklets-core: "*" + react-native-nitro-modules: "*" + react-native-vision-camera: ">=5" + peerDependenciesMeta: + "@expo/config-plugins": + optional: true languageName: unknown linkType: soft -"react-native-vision-camera@npm:^4.7.3": - version: 4.7.3 - resolution: "react-native-vision-camera@npm:4.7.3" +"react-native-vision-camera-worklets@npm:^5.1.0": + version: 5.2.1 + resolution: "react-native-vision-camera-worklets@npm:5.2.1" peerDependencies: - "@shopify/react-native-skia": "*" react: "*" react-native: "*" - react-native-reanimated: "*" - react-native-worklets-core: "*" - peerDependenciesMeta: - "@shopify/react-native-skia": - optional: true - react-native-reanimated: - optional: true - react-native-worklets-core: - optional: true - checksum: 10c0/46001037f4f9a85e75c023e5082b137c179fd520741e088009d217f0a6eaf3a819b9784ae68aced95fa70c3345346c79dd2ee70bc04cfd811c7eefeda675cab2 + react-native-nitro-modules: "*" + react-native-vision-camera: "*" + react-native-worklets: "*" + checksum: 10c0/c1c5d70220722d468b8b4bde4e11aa42414810618c8e969b2edf475fbc835bc51c83095f040c51d556916b3b586146272fb4a7d7592ee9e2084e0a5d2870a7aa languageName: node linkType: hard -"react-native-worklets-core@npm:^1.6.2": - version: 1.6.2 - resolution: "react-native-worklets-core@npm:1.6.2" - dependencies: - string-hash-64: "npm:^1.0.3" +"react-native-vision-camera@npm:^5.1.0": + version: 5.2.1 + resolution: "react-native-vision-camera@npm:5.2.1" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/c10a6edb0b8c8f7f9573ac24e0808dc01bfc90581d0b0aa6d264457ef7805f54358226b5afe4ce67ac9fa00c861ec65d1ebfd9657f97197068f10240758b1175 + react-native-nitro-image: "*" + react-native-nitro-modules: "*" + checksum: 10c0/58e6d11ef9456f54f4b3efb770aaecec966f15798c12b5ca01863b65190df71f734d89f81b78450dad14767432a5769555c6a8bb2f3a923e1dba296319bf4a9a languageName: node linkType: hard -"react-native-worklets@npm:^0.7.1": - version: 0.7.1 - resolution: "react-native-worklets@npm:0.7.1" - dependencies: - "@babel/plugin-transform-arrow-functions": "npm:7.27.1" - "@babel/plugin-transform-class-properties": "npm:7.27.1" - "@babel/plugin-transform-classes": "npm:7.28.4" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:7.27.1" - "@babel/plugin-transform-optional-chaining": "npm:7.27.1" - "@babel/plugin-transform-shorthand-properties": "npm:7.27.1" - "@babel/plugin-transform-template-literals": "npm:7.27.1" - "@babel/plugin-transform-unicode-regex": "npm:7.27.1" - "@babel/preset-typescript": "npm:7.27.1" - convert-source-map: "npm:2.0.0" - semver: "npm:7.7.3" +"react-native-worklets@npm:0.10.2": + version: 0.10.2 + resolution: "react-native-worklets@npm:0.10.2" + dependencies: + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-class-properties": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.28.6" + "@babel/plugin-transform-optional-chaining": "npm:^7.28.6" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/preset-typescript": "npm:^7.28.5" + "@babel/types": "npm:^7.27.1" + convert-source-map: "npm:^2.0.0" + semver: "npm:^7.7.4" peerDependencies: "@babel/core": "*" + "@react-native/metro-config": "*" react: "*" - react-native: "*" - checksum: 10c0/6965ff3cef7981e10585e15c222fb78f12c54807fcd6f7f9fccdd4dea2bd59d234797fe26a9f47d5c5ba6609f653b807d67f2d03e513e179a25ba28c3ad413ff + react-native: 0.83 - 0.86 + checksum: 10c0/5c4aa9940fb63cd1b0585b618fff84716c028011c9235e10d451b6436c7fb4dec9474a5dd9fa38d74aedd4a5b46f916470fb73aedaca4b0ba47b364d26fbf193 languageName: node linkType: hard -"react-native@npm:0.81.1": - version: 0.81.1 - resolution: "react-native@npm:0.81.1" +"react-native@npm:0.86.0": + version: 0.86.0 + resolution: "react-native@npm:0.86.0" dependencies: - "@jest/create-cache-key-function": "npm:^29.7.0" - "@react-native/assets-registry": "npm:0.81.1" - "@react-native/codegen": "npm:0.81.1" - "@react-native/community-cli-plugin": "npm:0.81.1" - "@react-native/gradle-plugin": "npm:0.81.1" - "@react-native/js-polyfills": "npm:0.81.1" - "@react-native/normalize-colors": "npm:0.81.1" - "@react-native/virtualized-lists": "npm:0.81.1" + "@react-native/assets-registry": "npm:0.86.0" + "@react-native/codegen": "npm:0.86.0" + "@react-native/community-cli-plugin": "npm:0.86.0" + "@react-native/gradle-plugin": "npm:0.86.0" + "@react-native/js-polyfills": "npm:0.86.0" + "@react-native/normalize-colors": "npm:0.86.0" + "@react-native/virtualized-lists": "npm:0.86.0" abort-controller: "npm:^3.0.0" anser: "npm:^1.4.9" ansi-regex: "npm:^5.0.0" - babel-jest: "npm:^29.7.0" - babel-plugin-syntax-hermes-parser: "npm:0.29.1" + babel-plugin-syntax-hermes-parser: "npm:0.36.0" base64-js: "npm:^1.5.1" commander: "npm:^12.0.0" flow-enums-runtime: "npm:^0.0.6" - glob: "npm:^7.1.1" + hermes-compiler: "npm:250829098.0.14" invariant: "npm:^2.2.4" - jest-environment-node: "npm:^29.7.0" memoize-one: "npm:^5.0.0" - metro-runtime: "npm:^0.83.1" - metro-source-map: "npm:^0.83.1" + metro-runtime: "npm:^0.84.3" + metro-source-map: "npm:^0.84.3" nullthrows: "npm:^1.1.1" pretty-format: "npm:^29.7.0" promise: "npm:^8.3.0" react-devtools-core: "npm:^6.1.5" react-refresh: "npm:^0.14.0" regenerator-runtime: "npm:^0.13.2" - scheduler: "npm:0.26.0" + scheduler: "npm:0.27.0" semver: "npm:^7.1.3" stacktrace-parser: "npm:^0.1.10" + tinyglobby: "npm:^0.2.15" whatwg-fetch: "npm:^3.0.0" - ws: "npm:^6.2.3" + ws: "npm:^7.5.10" yargs: "npm:^17.6.2" peerDependencies: - "@types/react": ^19.1.0 - react: ^19.1.0 + "@react-native/jest-preset": 0.86.0 + "@types/react": ^19.1.1 + react: ^19.2.3 peerDependenciesMeta: + "@react-native/jest-preset": + optional: true "@types/react": optional: true bin: react-native: cli.js - checksum: 10c0/d8cf1c441e7b33a9e23eb1e0f9fcbceace05ed49b2222f2fe4f249fb84956684db02643cfc703cdfa7fb23a3e24c80c91f24b6a5acd26d4d5771fe9f18d1cd46 + checksum: 10c0/47a569c47a22b37526ac54e17d1f42c6a191ca7cd30230bc16ee5307ac53da1db89d27ba20c76e9756fb646866d89fedfc1852b1ddc15c47bde45c899079096a languageName: node linkType: hard @@ -10911,10 +11314,10 @@ __metadata: languageName: node linkType: hard -"react@npm:19.1.0": - version: 19.1.0 - resolution: "react@npm:19.1.0" - checksum: 10c0/530fb9a62237d54137a13d2cfb67a7db6a2156faed43eecc423f4713d9b20c6f2728b026b45e28fcd72e8eadb9e9ed4b089e99f5e295d2f0ad3134251bdd3698 +"react@npm:19.2.3": + version: 19.2.3 + resolution: "react@npm:19.2.3" + checksum: 10c0/094220b3ba3a76c1b668f972ace1dd15509b157aead1b40391d1c8e657e720c201d9719537375eff08f5e0514748c0319063392a6f000e31303aafc4471f1436 languageName: node linkType: hard @@ -10936,7 +11339,7 @@ __metadata: languageName: node linkType: hard -"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": +"reflect.getprototypeof@npm:^1.0.10, reflect.getprototypeof@npm:^1.0.9": version: 1.0.10 resolution: "reflect.getprototypeof@npm:1.0.10" dependencies: @@ -11011,19 +11414,19 @@ __metadata: linkType: hard "regjsparser@npm:^0.13.0": - version: 0.13.0 - resolution: "regjsparser@npm:0.13.0" + version: 0.13.2 + resolution: "regjsparser@npm:0.13.2" dependencies: jsesc: "npm:~3.1.0" bin: regjsparser: bin/parser - checksum: 10c0/4702f85cda09f67747c1b2fb673a0f0e5d1ba39d55f177632265a0be471ba59e3f320623f411649141f752b126b8126eac3ff4c62d317921e430b0472bfc6071 + checksum: 10c0/261667a3da2552619adbf331eb32b139fef6af59a88343213df2fd5635ec02eb4e7d62a5fcb3b6aecec0df84d5746d36eabfff2502fd34b8ef01b1f983779274 languageName: node linkType: hard "release-it@npm:^19.0.4": - version: 19.2.2 - resolution: "release-it@npm:19.2.2" + version: 19.2.4 + resolution: "release-it@npm:19.2.4" dependencies: "@nodeutils/defaults-deep": "npm:1.1.0" "@octokit/rest": "npm:22.0.1" @@ -11044,13 +11447,13 @@ __metadata: proxy-agent: "npm:6.5.0" semver: "npm:7.7.3" tinyglobby: "npm:0.2.15" - undici: "npm:6.22.0" + undici: "npm:6.23.0" url-join: "npm:5.0.0" wildcard-match: "npm:5.1.4" yargs-parser: "npm:21.1.1" bin: release-it: bin/release-it.js - checksum: 10c0/922a84d79631178da8badb7ae35eb831af09220f368a3b2d8dbb97f884e8942603aa082e166da40c342710afdb479cbdee4ff5b813730cace019e871ee7d0df2 + checksum: 10c0/54888f271b665a4efc57b635664438ab256193d24a10928e19997c38b854056ad1bb2d653ede85c7552d45ecdcb1f1aa8861b8c0c27f9aaaf00ba916d3ae1781 languageName: node linkType: hard @@ -11105,55 +11508,63 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.20.0, resolve@npm:^1.22.10": - version: 1.22.11 - resolution: "resolve@npm:1.22.11" +"resolve@npm:^1.20.0, resolve@npm:^1.22.10, resolve@npm:^1.22.11": + version: 1.22.12 + resolution: "resolve@npm:1.22.12" dependencies: + es-errors: "npm:^1.3.0" is-core-module: "npm:^2.16.1" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/f657191507530f2cbecb5815b1ee99b20741ea6ee02a59c57028e9ec4c2c8d7681afcc35febbd554ac0ded459db6f2d8153382c53a2f266cee2575e512674409 + checksum: 10c0/b16dc9b537c02e8c3388f7d3dcff9741d3071625f9a97ac1c885f2b0ca51e78df22328fb6d6ef214dd9101fb7cfc19aa2836fe3410402a94f3f7b8639c7149bf languageName: node linkType: hard "resolve@npm:^2.0.0-next.5": - version: 2.0.0-next.5 - resolution: "resolve@npm:2.0.0-next.5" + version: 2.0.0-next.7 + resolution: "resolve@npm:2.0.0-next.7" dependencies: - is-core-module: "npm:^2.13.0" + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.2" + node-exports-info: "npm:^1.6.0" + object-keys: "npm:^1.1.1" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/a6c33555e3482ea2ec4c6e3d3bf0d78128abf69dca99ae468e64f1e30acaa318fd267fb66c8836b04d558d3e2d6ed875fe388067e7d8e0de647d3c21af21c43a + checksum: 10c0/8c6fa17ccdb826a3a52387ed8c42bf705dbc19d5494da52a86661b124b5b88fad5d8edbbb4434a1b563ecf7768368b7da9fb9489e20f36e02f7551a4ea87d707 languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.10#optional!builtin": - version: 1.22.11 - resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=c3c19d" +"resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.10#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": + version: 1.22.12 + resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=c3c19d" dependencies: + es-errors: "npm:^1.3.0" is-core-module: "npm:^2.16.1" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/ee5b182f2e37cb1165465e58c6abc797fec0a80b5ba3231607beb4677db0c9291ac010c47cf092b6daa2b7f518d69a0e21888e7e2b633f68d501a874212a8c63 + checksum: 10c0/fc6519984ae1f894d877c0060ba8b1f5ba3bc0e85a02f74e141929c118c23d74d9735619a9cc2965397387e514884245c65d72a40731dcb6cfc84c7bcdc8321e languageName: node linkType: hard "resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": - version: 2.0.0-next.5 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" + version: 2.0.0-next.7 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.7#optional!builtin::version=2.0.0-next.7&hash=c3c19d" dependencies: - is-core-module: "npm:^2.13.0" + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.2" + node-exports-info: "npm:^1.6.0" + object-keys: "npm:^1.1.1" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/78ad6edb8309a2bfb720c2c1898f7907a37f858866ce11a5974643af1203a6a6e05b2fa9c53d8064a673a447b83d42569260c306d43628bff5bb101969708355 + checksum: 10c0/6bb6f1d8a1789f7a5b4e35d950e76bc0ba632ff7d51fe86b6f34fb5f41e1ce0f7b884ec166828cfc0728ddffeaee49527711d752d12398297f90c51acd22195e languageName: node linkType: hard @@ -11184,13 +11595,6 @@ __metadata: languageName: node linkType: hard -"retry@npm:^0.12.0": - version: 0.12.0 - resolution: "retry@npm:0.12.0" - checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe - languageName: node - linkType: hard - "reusify@npm:^1.0.4": version: 1.1.0 resolution: "reusify@npm:1.1.0" @@ -11242,15 +11646,15 @@ __metadata: linkType: hard "safe-array-concat@npm:^1.1.3": - version: 1.1.3 - resolution: "safe-array-concat@npm:1.1.3" + version: 1.1.4 + resolution: "safe-array-concat@npm:1.1.4" dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.6" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + get-intrinsic: "npm:^1.3.0" has-symbols: "npm:^1.1.0" isarray: "npm:^2.0.5" - checksum: 10c0/43c86ffdddc461fb17ff8a17c5324f392f4868f3c7dd2c6a5d9f5971713bc5fd755667212c80eab9567595f9a7509cc2f83e590ddaebd1bd19b780f9c79f9a8d + checksum: 10c0/95fb4904ab1d9360a666fe5ba6d88f1c4a3a39682739e4512cff809fc6b5722a94bd95189211015bfb45859a7ffbc3340ea303ae22721c91c59e8946d310975a languageName: node linkType: hard @@ -11289,14 +11693,21 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:0.26.0": - version: 0.26.0 - resolution: "scheduler@npm:0.26.0" - checksum: 10c0/5b8d5bfddaae3513410eda54f2268e98a376a429931921a81b5c3a2873aab7ca4d775a8caac5498f8cbc7d0daeab947cf923dbd8e215d61671f9f4e392d34356 +"sax@npm:>=0.6.0": + version: 1.6.1 + resolution: "sax@npm:1.6.1" + checksum: 10c0/c91a71043d60da50fdf1e2cee936fc7ad4c9376afb8d1022aef5655f279433640859ec06b3b49abfcbe578fc7da2828cc1661e45aaedf835f5393496193437fa languageName: node linkType: hard -"semver@npm:7.7.3, semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.3": +"scheduler@npm:0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 + languageName: node + linkType: hard + +"semver@npm:7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -11314,6 +11725,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.3, semver@npm:^7.7.4": + version: 7.8.5 + resolution: "semver@npm:7.8.5" + bin: + semver: bin/semver.js + checksum: 10c0/b1f3127a5be8125a94f37188b361c212466c292c6910adce3ec106cff5dc211ccaedc4739c11bb70fda59d6fc1f040a9bca289f4e093451521a2372e5231fe0c + languageName: node + linkType: hard + "send@npm:~0.19.1": version: 0.19.2 resolution: "send@npm:0.19.2" @@ -11428,20 +11848,20 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3": - version: 1.8.3 - resolution: "shell-quote@npm:1.8.3" - checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd +"shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.4": + version: 1.10.0 + resolution: "shell-quote@npm:1.10.0" + checksum: 10c0/46ee59bfd972ce6a45500c44ed130dff2d0a7d6fbac9841e59d548518cad8060a06393c9a5dcbc0cede294ad80b2a2cd8c904679e09265f53efc0a0879f30961 languageName: node linkType: hard -"side-channel-list@npm:^1.0.0": - version: 1.0.0 - resolution: "side-channel-list@npm:1.0.0" +"side-channel-list@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-list@npm:1.0.1" dependencies: es-errors: "npm:^1.3.0" - object-inspect: "npm:^1.13.3" - checksum: 10c0/644f4ac893456c9490ff388bf78aea9d333d5e5bfc64cfb84be8f04bf31ddc111a8d4b83b85d7e7e8a7b845bc185a9ad02c052d20e086983cf59f0be517d9b3d + object-inspect: "npm:^1.13.4" + checksum: 10c0/d346c787fd2f9f1c2fdea14f00e8250118db0e7596d85a6cb9faa75f105d31a73a8f7a341c93d7df2a2429098c3d37a77bd3be9e88c37094b8c01807bc77c7a2 languageName: node linkType: hard @@ -11470,16 +11890,16 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.1.0": - version: 1.1.0 - resolution: "side-channel@npm:1.1.0" +"side-channel@npm:^1.1.0, side-channel@npm:^1.1.1": + version: 1.1.1 + resolution: "side-channel@npm:1.1.1" dependencies: es-errors: "npm:^1.3.0" - object-inspect: "npm:^1.13.3" - side-channel-list: "npm:^1.0.0" + object-inspect: "npm:^1.13.4" + side-channel-list: "npm:^1.0.1" side-channel-map: "npm:^1.0.1" side-channel-weakmap: "npm:^1.0.2" - checksum: 10c0/cb20dad41eb032e6c24c0982e1e5a24963a28aa6122b4f05b3f3d6bf8ae7fd5474ef382c8f54a6a3ab86e0cac4d41a23bd64ede3970e5bfb50326ba02a7996e6 + checksum: 10c0/dc0ab81d67f61bda9247d053ce93f41c3fd8ad2bdcb9cf9d8d2f8540d488f26d87a5e99ebfc07eea49ec025867b2452b705442d974b1478f0395e69f6bfb3270 languageName: node linkType: hard @@ -11497,6 +11917,17 @@ __metadata: languageName: node linkType: hard +"simple-plist@npm:^1.1.0": + version: 1.4.0 + resolution: "simple-plist@npm:1.4.0" + dependencies: + bplist-creator: "npm:0.1.1" + bplist-parser: "npm:0.3.2" + plist: "npm:^3.0.5" + checksum: 10c0/226c283492d8518d715e4133d94bdbd15c0619561bcde583b4807b36cde106c0078c615b9b4e25c0e8758a4ae4e79ed5dd76e57cd528d8b7001ecab5ad35e343 + languageName: node + linkType: hard + "simple-swizzle@npm:^0.2.2": version: 0.2.4 resolution: "simple-swizzle@npm:0.2.4" @@ -11538,6 +11969,13 @@ __metadata: languageName: node linkType: hard +"slugify@npm:^1.6.6": + version: 1.6.9 + resolution: "slugify@npm:1.6.9" + checksum: 10c0/8473c566ae00c5db26bfbf6182a4a9478ab3c912a9c926e1fdb410736a77228bfca4fdc5c755b46fafa7d2d9900de482fd7a9bd5e5c91128c4743c2c072d88da + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -11545,7 +11983,7 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.3, socks-proxy-agent@npm:^8.0.5": +"socks-proxy-agent@npm:^8.0.5": version: 8.0.5 resolution: "socks-proxy-agent@npm:8.0.5" dependencies: @@ -11557,12 +11995,12 @@ __metadata: linkType: hard "socks@npm:^2.8.3": - version: 2.8.7 - resolution: "socks@npm:2.8.7" + version: 2.8.9 + resolution: "socks@npm:2.8.9" dependencies: - ip-address: "npm:^10.0.1" + ip-address: "npm:^10.1.1" smart-buffer: "npm:^4.2.0" - checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 + checksum: 10c0/2d4350c31142b0931eb1758825b426bcbf4bfb5eed682ca48bc46dc9e7d1930ec366ea574ad49fc6c1fd9e9e17ce243be0ef13e31fc4b0319d9093f1fb19743c languageName: node linkType: hard @@ -11628,9 +12066,9 @@ __metadata: linkType: hard "spdx-license-ids@npm:^3.0.0": - version: 3.0.22 - resolution: "spdx-license-ids@npm:3.0.22" - checksum: 10c0/4a85e44c2ccfc06eebe63239193f526508ebec1abc7cf7bca8ee43923755636234395447c2c87f40fb672cf580a9c8e684513a676bfb2da3d38a4983684bbb38 + version: 3.0.23 + resolution: "spdx-license-ids@npm:3.0.23" + checksum: 10c0/8495620f6f2a237749cce922ea2d593a66f7885c301b1a0f5542183e7041182f27f616a8f13345cefdea0c9b3e0899328e0aa8cec100cf4f3fac4bb3bd975515 languageName: node linkType: hard @@ -11655,15 +12093,6 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^13.0.0": - version: 13.0.0 - resolution: "ssri@npm:13.0.0" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/405f3a531cd98b013cecb355d63555dca42fd12c7bc6671738aaa9a82882ff41cdf0ef9a2b734ca4f9a760338f114c29d01d9238a65db3ccac27929bd6e6d4b2 - languageName: node - linkType: hard - "stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -11720,6 +12149,13 @@ __metadata: languageName: node linkType: hard +"stream-buffers@npm:2.2.x": + version: 2.2.0 + resolution: "stream-buffers@npm:2.2.0" + checksum: 10c0/14a351f0a066eaa08c8c64a74f4aedd87dd7a8e59d4be224703da33dca3eb370828ee6c0ae3fff59a9c743e8098728fc95c5f052ae7741672a31e6b1430ba50a + languageName: node + linkType: hard + "strict-uri-encode@npm:^2.0.0": version: 2.0.0 resolution: "strict-uri-encode@npm:2.0.0" @@ -11727,13 +12163,6 @@ __metadata: languageName: node linkType: hard -"string-hash-64@npm:^1.0.3": - version: 1.0.3 - resolution: "string-hash-64@npm:1.0.3" - checksum: 10c0/ac175f71b383af1487ab16b4cc1b42b5302bea08bdf1cc1ea04bacb293fb9b35afc6c58260e1fc728627e7265519da01976822a188d493d7e7625b9628173ea3 - languageName: node - linkType: hard - "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -11773,13 +12202,24 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^8.1.0": - version: 8.1.0 - resolution: "string-width@npm:8.1.0" +"string-width@npm:^7.0.0, string-width@npm:^7.2.0": + version: 7.2.0 + resolution: "string-width@npm:7.2.0" dependencies: - get-east-asian-width: "npm:^1.3.0" + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" strip-ansi: "npm:^7.1.0" - checksum: 10c0/749b5d0dab2532b4b6b801064230f4da850f57b3891287023117ab63a464ad79dd208f42f793458f48f3ad121fe2e1f01dd525ff27ead957ed9f205e27406593 + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 + languageName: node + linkType: hard + +"string-width@npm:^8.1.0, string-width@npm:^8.2.1": + version: 8.2.2 + resolution: "string-width@npm:8.2.2" + dependencies: + get-east-asian-width: "npm:^1.5.0" + strip-ansi: "npm:^7.1.2" + checksum: 10c0/895624534e4e2f229e880bbc30aa77bdeb758e1a0edce203e0a17b8b4f08b8d3c1156516efc50a35e3efd0052d938a73797692111250ac9f52ee384710a01714 languageName: node linkType: hard @@ -11815,29 +12255,30 @@ __metadata: linkType: hard "string.prototype.trim@npm:^1.2.10": - version: 1.2.10 - resolution: "string.prototype.trim@npm:1.2.10" + version: 1.2.11 + resolution: "string.prototype.trim@npm:1.2.11" dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.2" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" define-data-property: "npm:^1.1.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.5" - es-object-atoms: "npm:^1.0.0" + es-abstract: "npm:^1.24.2" + es-object-atoms: "npm:^1.1.2" has-property-descriptors: "npm:^1.0.2" - checksum: 10c0/8a8854241c4b54a948e992eb7dd6b8b3a97185112deb0037a134f5ba57541d8248dd610c966311887b6c2fd1181a3877bffb14d873ce937a344535dabcc648f8 + safe-regex-test: "npm:^1.1.0" + checksum: 10c0/b153cf8ed06db82ff40e27829e88e5c13f45eff9799f1d5707626e25989b488b059d6f5d57011e07f77745e28451e16735f295bc59c8ae146a4fd73a442366b0 languageName: node linkType: hard "string.prototype.trimend@npm:^1.0.9": - version: 1.0.9 - resolution: "string.prototype.trimend@npm:1.0.9" + version: 1.0.10 + resolution: "string.prototype.trimend@npm:1.0.10" dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.2" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/59e1a70bf9414cb4c536a6e31bef5553c8ceb0cf44d8b4d0ed65c9653358d1c64dd0ec203b100df83d0413bbcde38b8c5d49e14bc4b86737d74adc593a0d35b6 + es-object-atoms: "npm:^1.1.2" + checksum: 10c0/cc09233181769047a5330becfd5740fec5f0c8137886e7b553626788b00f75df9f34db1159bc52dbb7fc389b8ebb6e1dab44c8c9e31eb600039729a542013286 languageName: node linkType: hard @@ -11880,11 +12321,11 @@ __metadata: linkType: hard "strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0, strip-ansi@npm:^7.1.2": - version: 7.1.2 - resolution: "strip-ansi@npm:7.1.2" + version: 7.2.0 + resolution: "strip-ansi@npm:7.2.0" dependencies: - ansi-regex: "npm:^6.0.1" - checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b + ansi-regex: "npm:^6.2.2" + checksum: 10c0/544d13b7582f8254811ea97db202f519e189e59d35740c46095897e254e4f1aa9fe1524a83ad6bc5ad67d4dd6c0281d2e0219ed62b880a6238a16a17d375f221 languageName: node linkType: hard @@ -11916,7 +12357,7 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.1.1": +"strnum@npm:^1.0.5": version: 1.1.2 resolution: "strnum@npm:1.1.2" checksum: 10c0/a0fce2498fa3c64ce64a40dada41beb91cabe3caefa910e467dc0518ef2ebd7e4d10f8c2202a6104f1410254cae245066c0e94e2521fb4061a5cb41831952392 @@ -11948,31 +12389,31 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.11.7": - version: 0.11.11 - resolution: "synckit@npm:0.11.11" +"synckit@npm:^0.11.13": + version: 0.11.13 + resolution: "synckit@npm:0.11.13" dependencies: - "@pkgr/core": "npm:^0.2.9" - checksum: 10c0/f0761495953d12d94a86edf6326b3a565496c72f9b94c02549b6961fb4d999f4ca316ce6b3eb8ed2e4bfc5056a8de65cda0bd03a233333a35221cd2fdc0e196b + "@pkgr/core": "npm:^0.3.6" + checksum: 10c0/5a6c19f4f79045aaa7994106401bff6dbe7cca23a6d0a0723ff14eb8b1bebeb4a71729118f6914905598e304ea2fa13509885e11ba07d92e7cb68a06740cb328 languageName: node linkType: hard -"tar@npm:^7.5.2": - version: 7.5.2 - resolution: "tar@npm:7.5.2" +"tar@npm:^7.5.4": + version: 7.5.22 + resolution: "tar@npm:7.5.22" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467 + checksum: 10c0/1311f6be85a8157ac4c9147bae43e13923d2a1aae15e4aa1bd5239e4e03d2cf53cfe103dde7f35832fbb4c938b042856bc8e9a0afd29abd05e2d1608788c4fea languageName: node linkType: hard "terser@npm:^5.15.0": - version: 5.44.1 - resolution: "terser@npm:5.44.1" + version: 5.49.0 + resolution: "terser@npm:5.49.0" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.15.0" @@ -11980,7 +12421,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10c0/ee7a76692cb39b1ed22c30ff366c33ff3c977d9bb769575338ff5664676168fcba59192fb5168ef80c7cd901ef5411a1b0351261f5eaa50decf0fc71f63bde75 + checksum: 10c0/c1f628a7a6226f7283db92ce43247306d612b80a60a075d97e1f5539a032beee05c87f889eacff2ffabd2fa9ac6bd1c147e5eb49c6546c9b174ed241d5f056a7 languageName: node linkType: hard @@ -12016,14 +12457,14 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^1.0.0, tinyexec@npm:^1.0.1": - version: 1.0.2 - resolution: "tinyexec@npm:1.0.2" - checksum: 10c0/1261a8e34c9b539a9aae3b7f0bb5372045ff28ee1eba035a2a059e532198fe1a182ec61ac60fa0b4a4129f0c4c4b1d2d57355b5cb9aa2d17ac9454ecace502ee +"tinyexec@npm:^1.0.0, tinyexec@npm:^1.2.4": + version: 1.3.0 + resolution: "tinyexec@npm:1.3.0" + checksum: 10c0/e9b89f97489d2aab2cef408da279e6b32547e738d1275032ccb8fd0028a006d93eb70fc51c6cffd9fc2f5aca6c2a273d8b6f73b52d46ee5116da6b94969ef958 languageName: node linkType: hard -"tinyglobby@npm:0.2.15, tinyglobby@npm:^0.2.12": +"tinyglobby@npm:0.2.15": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -12033,6 +12474,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.17 + resolution: "tinyglobby@npm:0.2.17" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10c0/7f7bb0f197c88bc4b20c231e0deca4240ca3bf313a88f5a7fee93a872b84966a4d50220947c0455ad07a60b3b360961c5b7fd979222aeb716a9f99b412002e4c + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -12056,19 +12507,22 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.4.3 - resolution: "ts-api-utils@npm:1.4.3" +"ts-api-utils@npm:^2.5.0": + version: 2.5.0 + resolution: "ts-api-utils@npm:2.5.0" peerDependencies: - typescript: ">=4.2.0" - checksum: 10c0/e65dc6e7e8141140c23e1dc94984bf995d4f6801919c71d6dc27cf0cd51b100a91ffcfe5217626193e5bea9d46831e8586febdc7e172df3f1091a7384299e23a + typescript: ">=4.8.4" + checksum: 10c0/767849383c114e7f1971fa976b20e73ac28fd0c70d8d65c0004790bf4d8f89888c7e4cf6d5949f9c1beae9bc3c64835bef77bbe27fddf45a3c7b60cebcf85c8c languageName: node linkType: hard -"tslib@npm:^1.8.1": - version: 1.14.1 - resolution: "tslib@npm:1.14.1" - checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 +"ts-morph@npm:^28.0.0": + version: 28.0.0 + resolution: "ts-morph@npm:28.0.0" + dependencies: + "@ts-morph/common": "npm:~0.29.0" + code-block-writer: "npm:^13.0.3" + checksum: 10c0/969570a5e983b4193735fff43878ce7b78787b4860bf3d23f330c86d7de707286969e5a82d486dce333eea27bf9d373a46f9de58a80c0bf86d2a462620563a55 languageName: node linkType: hard @@ -12079,85 +12533,32 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 - languageName: node - linkType: hard - -"turbo-darwin-64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-darwin-64@npm:2.7.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"turbo-darwin-arm64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-darwin-arm64@npm:2.7.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"turbo-linux-64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-linux-64@npm:2.7.2" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"turbo-linux-arm64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-linux-arm64@npm:2.7.2" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"turbo-windows-64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-windows-64@npm:2.7.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"turbo-windows-arm64@npm:2.7.2": - version: 2.7.2 - resolution: "turbo-windows-arm64@npm:2.7.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "turbo@npm:^2.5.6": - version: 2.7.2 - resolution: "turbo@npm:2.7.2" - dependencies: - turbo-darwin-64: "npm:2.7.2" - turbo-darwin-arm64: "npm:2.7.2" - turbo-linux-64: "npm:2.7.2" - turbo-linux-arm64: "npm:2.7.2" - turbo-windows-64: "npm:2.7.2" - turbo-windows-arm64: "npm:2.7.2" + version: 2.10.8 + resolution: "turbo@npm:2.10.8" + dependencies: + "@turbo/darwin-64": "npm:2.10.8" + "@turbo/darwin-arm64": "npm:2.10.8" + "@turbo/linux-64": "npm:2.10.8" + "@turbo/linux-arm64": "npm:2.10.8" + "@turbo/windows-64": "npm:2.10.8" + "@turbo/windows-arm64": "npm:2.10.8" dependenciesMeta: - turbo-darwin-64: + "@turbo/darwin-64": optional: true - turbo-darwin-arm64: + "@turbo/darwin-arm64": optional: true - turbo-linux-64: + "@turbo/linux-64": optional: true - turbo-linux-arm64: + "@turbo/linux-arm64": optional: true - turbo-windows-64: + "@turbo/windows-64": optional: true - turbo-windows-arm64: + "@turbo/windows-arm64": optional: true bin: turbo: bin/turbo - checksum: 10c0/390937a32070ac52120af56705006e831de2edf8e22a2b0146006d07740cd413b3a36335339e7617b57cf74b008f4b15931cf56e1c7c0c03808f028ed937c4de + checksum: 10c0/892459ca52bdcc0ecd50d0bd5e092bc97052ff726fd727af7df997e6b8ff20b1aea6040caac14c2ceb661f18b08e7abd2027d188f8a67bc74dcab0c043060026 languageName: node linkType: hard @@ -12248,16 +12649,16 @@ __metadata: linkType: hard "typed-array-length@npm:^1.0.7": - version: 1.0.7 - resolution: "typed-array-length@npm:1.0.7" + version: 1.0.8 + resolution: "typed-array-length@npm:1.0.8" dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - is-typed-array: "npm:^1.1.13" - possible-typed-array-names: "npm:^1.0.0" - reflect.getprototypeof: "npm:^1.0.6" - checksum: 10c0/e38f2ae3779584c138a2d8adfa8ecf749f494af3cd3cdafe4e688ce51418c7d2c5c88df1bd6be2bbea099c3f7cea58c02ca02ed438119e91f162a9de23f61295 + call-bind: "npm:^1.0.9" + for-each: "npm:^0.3.5" + gopd: "npm:^1.2.0" + is-typed-array: "npm:^1.1.15" + possible-typed-array-names: "npm:^1.1.0" + reflect.getprototypeof: "npm:^1.0.10" + checksum: 10c0/5319f740fc426a3217182c2f7c87656acb0903e046de5a938e30167337d26abf1bb3ad4b32833a72521a4cc58223aec80627b38b357d0a3d5fd64881427e77ab languageName: node linkType: hard @@ -12330,10 +12731,10 @@ __metadata: languageName: node linkType: hard -"undici@npm:6.22.0": - version: 6.22.0 - resolution: "undici@npm:6.22.0" - checksum: 10c0/47903c489d73e26bd47960cf2f04d63282ed050818b672cb05f8dfb6403381b850cf1b1751832654fd3af22aacd9d780e5e61aff563cd97943f5c4f10d5b3e23 +"undici@npm:6.28.0": + version: 6.28.0 + resolution: "undici@npm:6.28.0" + checksum: 10c0/3029a70df06b38b5b2f30732932a1e92544c753cd82c8abdf0d35afad48e0ba91612e79fe3a442dbbb9434d6a9eba2b714d5ea28984c903dda2b5d5444f38354 languageName: node linkType: hard @@ -12382,24 +12783,6 @@ __metadata: languageName: node linkType: hard -"unique-filename@npm:^5.0.0": - version: 5.0.0 - resolution: "unique-filename@npm:5.0.0" - dependencies: - unique-slug: "npm:^6.0.0" - checksum: 10c0/afb897e9cf4c2fb622ea716f7c2bb462001928fc5f437972213afdf1cc32101a230c0f1e9d96fc91ee5185eca0f2feb34127145874975f347be52eb91d6ccc2c - languageName: node - linkType: hard - -"unique-slug@npm:^6.0.0": - version: 6.0.0 - resolution: "unique-slug@npm:6.0.0" - dependencies: - imurmurhash: "npm:^0.1.4" - checksum: 10c0/da7ade4cb04eb33ad0499861f82fe95ce9c7c878b7139dc54d140ecfb6a6541c18a5c8dac16188b8b379fe62c0c1f1b710814baac910cde5f4fec06212126c6a - languageName: node - linkType: hard - "universal-user-agent@npm:^7.0.0, universal-user-agent@npm:^7.0.2": version: 7.0.3 resolution: "universal-user-agent@npm:7.0.3" @@ -12428,7 +12811,7 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.2.0": +"update-browserslist-db@npm:^1.2.3": version: 1.2.3 resolution: "update-browserslist-db@npm:1.2.3" dependencies: @@ -12490,6 +12873,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^7.0.3": + version: 7.0.3 + resolution: "uuid@npm:7.0.3" + bin: + uuid: dist/bin/uuid + checksum: 10c0/2eee5723b0fcce8256f5bfd3112af6c453b5471db00af9c3533e3d5a6e57de83513f9a145a570890457bd7abf2c2aa05797291d950ac666e5a074895dc63168b + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.3.0 resolution: "v8-to-istanbul@npm:9.3.0" @@ -12541,7 +12933,7 @@ __metadata: languageName: node linkType: hard -"warn-once@npm:0.1.1, warn-once@npm:^0.1.0, warn-once@npm:^0.1.1": +"warn-once@npm:^0.1.0, warn-once@npm:^0.1.1": version: 0.1.1 resolution: "warn-once@npm:0.1.1" checksum: 10c0/f531e7b2382124f51e6d8f97b8c865246db8ab6ff4e53257a2d274e0f02b97d7201eb35db481843dc155815e154ad7afb53b01c4d4db15fb5aa073562496aff7 @@ -12618,17 +13010,17 @@ __metadata: linkType: hard "which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": - version: 1.1.19 - resolution: "which-typed-array@npm:1.1.19" + version: 1.1.22 + resolution: "which-typed-array@npm:1.1.22" dependencies: available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.8" + call-bind: "npm:^1.0.9" call-bound: "npm:^1.0.4" for-each: "npm:^0.3.5" get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-tostringtag: "npm:^1.0.2" - checksum: 10c0/702b5dc878addafe6c6300c3d0af5983b175c75fcb4f2a72dfc3dd38d93cf9e89581e4b29c854b16ea37e50a7d7fca5ae42ece5c273d8060dcd603b2404bbb3f + checksum: 10c0/e59db184a4e78b461fac3b05fafc1e7badbbedafbf04a967ee1de73717f1f9723a79699e7b5de71d449541cb5da8353efc01a4f8a72a152479850e54fa196c40 languageName: node linkType: hard @@ -12643,14 +13035,14 @@ __metadata: languageName: node linkType: hard -"which@npm:^6.0.0": - version: 6.0.0 - resolution: "which@npm:6.0.0" +"which@npm:^7.0.0": + version: 7.0.0 + resolution: "which@npm:7.0.0" dependencies: - isexe: "npm:^3.1.1" + isexe: "npm:^4.0.0" bin: node-which: bin/which.js - checksum: 10c0/fe9d6463fe44a76232bb6e3b3181922c87510a5b250a98f1e43a69c99c079b3f42ddeca7e03d3e5f2241bf2d334f5a7657cfa868b97c109f3870625842f4cc15 + checksum: 10c0/ca0b54f198f78bbc4b7c02e34bda8d335cb352e0adb4cbca1c37b1a957af3a879a82c4c27ca6525bc942f548d8b64f816ef6528360af9f3de55ffb9b979b620d languageName: node linkType: hard @@ -12717,6 +13109,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^9.0.0": + version: 9.0.2 + resolution: "wrap-ansi@npm:9.0.2" + dependencies: + ansi-styles: "npm:^6.2.1" + string-width: "npm:^7.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/3305839b9a0d6fb930cb63a52f34d3936013d8b0682ff3ec133c9826512620f213800ffa19ea22904876d5b7e9a3c1f40682f03597d986a4ca881fa7b033688c + languageName: node + linkType: hard + "wrappy@npm:1": version: 1.0.2 resolution: "wrappy@npm:1.0.2" @@ -12735,17 +13138,17 @@ __metadata: linkType: hard "ws@npm:^6.2.3": - version: 6.2.3 - resolution: "ws@npm:6.2.3" + version: 6.2.6 + resolution: "ws@npm:6.2.6" dependencies: async-limiter: "npm:~1.0.0" - checksum: 10c0/56a35b9799993cea7ce2260197e7879f21bbbb194a967f31acbbda6f7f46ecda4365951966fb062044c95197e19fb2f053be6f65c172435455186835f494de41 + checksum: 10c0/24245efc3c09b6175df32ddb4a06f85432c4c88abb0e75f43f2551c1d5de456218b1b6c7685c414b8e03a68a167488e4aadf04a895681c8e01502025ce505742 languageName: node linkType: hard "ws@npm:^7, ws@npm:^7.5.10": - version: 7.5.10 - resolution: "ws@npm:7.5.10" + version: 7.5.13 + resolution: "ws@npm:7.5.13" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -12754,7 +13157,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d + checksum: 10c0/e223726bbda5768ed58ec9252d04eda7018ef380ea122bb94e595a4d7a02b5baeb423933936576fddb8fa51b642375f7ae814bf0f6f5d9a3ce290566578a8c5a languageName: node linkType: hard @@ -12767,6 +13170,40 @@ __metadata: languageName: node linkType: hard +"xcode@npm:^3.0.1": + version: 3.0.1 + resolution: "xcode@npm:3.0.1" + dependencies: + simple-plist: "npm:^1.1.0" + uuid: "npm:^7.0.3" + checksum: 10c0/51bf35cee52909aeb18f868ecf9828f93b8042fadf968159320f9f11e757a52e43f6563a53b586986cfe5a34d576f3300c4c0cf1e14300084344ae206eaa53c3 + languageName: node + linkType: hard + +"xml2js@npm:0.6.0": + version: 0.6.0 + resolution: "xml2js@npm:0.6.0" + dependencies: + sax: "npm:>=0.6.0" + xmlbuilder: "npm:~11.0.0" + checksum: 10c0/db1ad659210eda4b77929aa692271308ec7e04830112161b8c707f3bcc7138947409c8461ae5c8bcb36b378d62594a8d1cb78770ff5c3dc46a68c67a0838b486 + languageName: node + linkType: hard + +"xmlbuilder@npm:^15.1.1": + version: 15.1.1 + resolution: "xmlbuilder@npm:15.1.1" + checksum: 10c0/665266a8916498ff8d82b3d46d3993913477a254b98149ff7cff060d9b7cc0db7cf5a3dae99aed92355254a808c0e2e3ec74ad1b04aa1061bdb8dfbea26c18b8 + languageName: node + linkType: hard + +"xmlbuilder@npm:~11.0.0": + version: 11.0.1 + resolution: "xmlbuilder@npm:11.0.1" + checksum: 10c0/74b979f89a0a129926bc786b913459bdbcefa809afaa551c5ab83f89b1915bdaea14c11c759284bb9b931e3b53004dbc2181e21d3ca9553eeb0b2a7b4e40c35b + languageName: node + linkType: hard + "y18n@npm:^4.0.0": version: 4.0.3 resolution: "y18n@npm:4.0.3" @@ -12788,13 +13225,6 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^4.0.0": - version: 4.0.0 - resolution: "yallist@npm:4.0.0" - checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a - languageName: node - linkType: hard - "yallist@npm:^5.0.0": version: 5.0.0 resolution: "yallist@npm:5.0.0" @@ -12803,11 +13233,11 @@ __metadata: linkType: hard "yaml@npm:^2.2.1, yaml@npm:^2.6.1": - version: 2.8.2 - resolution: "yaml@npm:2.8.2" + version: 2.9.0 + resolution: "yaml@npm:2.9.0" bin: yaml: bin.mjs - checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96 + checksum: 10c0/f340718df45e97a9551b9bf9dac61c80050bc464513b710debfb5067c380c8472e3b67809cffacb4ab5ffb5e66ef9310816c88b05f371cec60abfedd8c88e0a2 languageName: node linkType: hard @@ -12828,6 +13258,13 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^22.0.0": + version: 22.0.0 + resolution: "yargs-parser@npm:22.0.0" + checksum: 10c0/cb7ef81759c4271cb1d96b9351dbbc9a9ce35d3e1122d2b739bf6c432603824fa02c67cc12dcef6ea80283379d63495686e8f41cc7b06c6576e792aba4d33e1c + languageName: node + linkType: hard + "yargs@npm:^15.1.0": version: 15.4.1 resolution: "yargs@npm:15.4.1" @@ -12848,8 +13285,8 @@ __metadata: linkType: hard "yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" + version: 17.7.3 + resolution: "yargs@npm:17.7.3" dependencies: cliui: "npm:^8.0.1" escalade: "npm:^3.1.1" @@ -12858,7 +13295,21 @@ __metadata: string-width: "npm:^4.2.3" y18n: "npm:^5.0.5" yargs-parser: "npm:^21.1.1" - checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + checksum: 10c0/7a28572f7e785a57886e34fdbddb9b28756dec552e1453d5f6e7cdd00ad8721a4e8c4321d33683f5e61cacb36ad43258adbb48396b71ec4ed14abee0fc0d0c1f + languageName: node + linkType: hard + +"yargs@npm:^18.0.0": + version: 18.1.0 + resolution: "yargs@npm:18.1.0" + dependencies: + cliui: "npm:^9.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + string-width: "npm:^8.2.1" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^22.0.0" + checksum: 10c0/86052bbed90a9aaaaf1eabe004f47c7420e1b7f8d314170cfb0ad4721f518ec2fb7ba5a6daa20708b1595aba257f1554b2d5b3f5606356f86aa9dae18de0bec5 languageName: node linkType: hard @@ -12884,15 +13335,31 @@ __metadata: linkType: hard "yoctocolors@npm:^2.1.1": - version: 2.1.2 - resolution: "yoctocolors@npm:2.1.2" - checksum: 10c0/b220f30f53ebc2167330c3adc86a3c7f158bcba0236f6c67e25644c3188e2571a6014ffc1321943bb619460259d3d27eb4c9cc58c2d884c1b195805883ec7066 + version: 2.2.0 + resolution: "yoctocolors@npm:2.2.0" + checksum: 10c0/ca179aa83401aa0711f268fda38145a44c828e612a5f5265439efb5796cd63c46ca6b786bae3b74c75440a48518c36b5b23cba7fbb76ea8af5a9f85f830a5754 + languageName: node + linkType: hard + +"zod-validation-error@npm:^3.5.0 || ^4.0.0": + version: 4.0.2 + resolution: "zod-validation-error@npm:4.0.2" + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + checksum: 10c0/0ccfec48c46de1be440b719cd02044d4abb89ed0e14c13e637cd55bf29102f67ccdba373f25def0fc7130e5f15025be4d557a7edcc95d5a3811599aade689e1b + languageName: node + linkType: hard + +"zod@npm:^3.25.0 || ^4.0.0, zod@npm:^4.4.3": + version: 4.4.3 + resolution: "zod@npm:4.4.3" + checksum: 10c0/7ea31b558e88f9faf44f31dd185e2e1cbf51fed3081787fb96cc2534749b50c0acfc6da7f0922a7353ed092dd358c7d50c28ea96c94d04af64191bd33152eca3 languageName: node linkType: hard "zustand@npm:^5.0.9": - version: 5.0.9 - resolution: "zustand@npm:5.0.9" + version: 5.0.14 + resolution: "zustand@npm:5.0.14" peerDependencies: "@types/react": ">=18.0.0" immer: ">=9.0.6" @@ -12907,6 +13374,6 @@ __metadata: optional: true use-sync-external-store: optional: true - checksum: 10c0/552849e4546c7760704d6509a5c412d57c62a1fa9e53169c939ba5e3d75f8cb3df50a64c3a22e6c3f1c8cc00de7543e4edd61ab5ae0c9169ba9a98e28303aba6 + checksum: 10c0/89de0c8119f1e0861b2f896a0b4df0d67994a373ecee02628d4e7b97cee1885207f646917d3ede395c3a5083316d48846855cfbc84aced7cd23a6db3238930a8 languageName: node linkType: hard