[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\nexecutors:\n  default:\n    docker:\n      - image: circleci/node:10\n    working_directory: ~/project\n\ncommands:\n  attach_project:\n    steps:\n      - attach_workspace:\n          at: ~/project\n\njobs:\n  install-dependencies:\n    executor: default\n    steps:\n      - checkout\n      - attach_project\n      - restore_cache:\n          keys:\n            - dependencies-{{ checksum \"package.json\" }}\n            - dependencies-\n      - restore_cache:\n          keys:\n            - dependencies-example-{{ checksum \"example/package.json\" }}\n            - dependencies-example-\n      - run:\n          name: Install dependencies\n          command: |\n            yarn install --cwd example --frozen-lockfile\n            yarn install --frozen-lockfile\n      - save_cache:\n          key: dependencies-{{ checksum \"package.json\" }}\n          paths: node_modules\n      - save_cache:\n          key: dependencies-example-{{ checksum \"example/package.json\" }}\n          paths: example/node_modules\n      - persist_to_workspace:\n          root: .\n          paths: .\n\n  lint:\n    executor: default\n    steps:\n      - attach_project\n      - run:\n          name: Lint files\n          command: |\n            yarn lint\n\n  typescript:\n    executor: default\n    steps:\n      - attach_project\n      - run:\n          name: Typecheck files\n          command: |\n            yarn typescript\n\n  unit-tests:\n    executor: default\n    steps:\n      - attach_project\n      - run:\n          name: Run unit tests\n          command: |\n            yarn test --coverage\n      - store_artifacts:\n          path: coverage\n          destination: coverage\n\n  build-package:\n    executor: default\n    steps:\n      - attach_project\n      - run:\n          name: Build package\n          command: |\n            yarn prepare\n\nworkflows:\n  build-and-test:\n    jobs:\n      - install-dependencies\n      - lint:\n          requires:\n            - install-dependencies\n      - typescript:\n          requires:\n            - install-dependencies\n      - unit-tests:\n          requires:\n            - install-dependencies\n      - build-package:\n          requires:\n            - install-dependencies\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: baronha\npatreon: baronha\nopen_collective: # Replace with a single Open Collective username\nko_fi: baoha\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\nlfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "content": "name: Deploy to GitHub Pages\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - 'docs/**'\n      \njobs:\n  build:\n    name: Build Docusaurus\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 18\n          cache: yarn\n\n      - name: Install dependencies\n        working-directory: docs\n        run: yarn install --frozen-lockfile\n      - name: Build docs\n        working-directory: docs\n        run: yarn build\n\n      - name: Upload Build Artifact\n        uses: actions/upload-pages-artifact@v3\n        with:\n          path: docs/build\n\n  deploy:\n    name: Deploy to GitHub Pages\n    needs: build\n\n    # Grant GITHUB_TOKEN the permissions required to make a Pages deployment\n    permissions:\n      pages: write # to deploy to Pages\n      id-token: write # to verify the deployment originates from an appropriate source\n\n    # Deploy to the github-pages environment\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n\n    runs-on: ubuntu-latest\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "# OSX\n#\n.DS_Store\n\n# XDE\n.expo/\n\n# VSCode\n.vscode/\njsconfig.json\n\n# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n*.xccheckout\n*.moved-aside\nDerivedData\n*.hmap\n*.ipa\n*.xcuserstate\nproject.xcworkspace\n\n# Android/IJ\n#\n.classpath\n.cxx\n.gradle\n.idea\n.project\n.settings\nlocal.properties\nandroid.iml\n\n# Cocoapods\n#\nexample/ios/Pods\n\n# Ruby\nexample/vendor/\n\n# node.js\n#\nnode_modules/\nnpm-debug.log\nyarn-debug.log\nyarn-error.log\n\n# BUCK\nbuck-out/\n\\.buckd/\nandroid/app/libs\nandroid/keystores/debug.keystore\n\n# Yarn\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n\n# Expo\n.expo/\n\n# Turborepo\n.turbo/\n\n# generated by bob\nlib/\n"
  },
  {
    "path": ".npmignore",
    "content": "example/\nfiles/\nnode_modules/\nnpm-debug.log\npackage-lock.json\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nWe want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project.\n\n## Development workflow\n\nTo get started with the project, run `yarn` in the root directory to install the required dependencies for each package:\n\n```sh\nyarn\n```\n\nWhile developing, you can run the [example app](/example/) to test your changes.\n\nTo start the packager:\n\n```sh\nyarn example start\n```\n\nTo run the example app on Android:\n\n```sh\nyarn example android\n```\n\nTo run the example app on iOS:\n\n```sh\nyarn example ios\n```\n\nMake sure your code passes TypeScript and ESLint. Run the following to verify:\n\n```sh\nyarn typescript\nyarn lint\n```\n\nTo fix formatting errors, run the following:\n\n```sh\nyarn lint --fix\n```\n\nRemember to add tests for your change if possible. Run the unit tests by:\n\n```sh\nyarn test\n```\n\nTo edit the Objective-C files, open `example/ios/MultipleImagePickerExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > react-native-multiple-image-picker`.\n\nTo edit the Kotlin files, open `example/android` in Android studio and find the source files at `reactnativemultipleimagepicker` under `Android`.\n\n### Commit message convention\n\nWe follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages:\n\n- `fix`: bug fixes, e.g. fix crash due to deprecated method.\n- `feat`: new features, e.g. add new method to the module.\n- `refactor`: code refactor, e.g. migrate from class components to hooks.\n- `docs`: changes into documentation, e.g. add usage example for the module..\n- `test`: adding or updating tests, e.g. add integration tests using detox.\n- `chore`: tooling changes, e.g. change CI config.\n\nOur pre-commit hooks verify that your commit message matches this format when committing.\n\n### Linting and tests\n\n[ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/)\n\nWe 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.\n\nOur pre-commit hooks verify that the linter and tests pass when committing.\n\n### Scripts\n\nThe `package.json` file contains various scripts for common tasks:\n\n- `yarn bootstrap`: setup project by installing all dependencies and pods.\n- `yarn typescript`: type-check files with TypeScript.\n- `yarn lint`: lint files with ESLint.\n- `yarn test`: run unit tests with Jest.\n- `yarn example start`: start the Metro server for the example app.\n- `yarn example android`: run the example app on Android.\n- `yarn example ios`: run the example app on iOS.\n\n### Sending a pull request\n\n> **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).\n\nWhen you're sending a pull request:\n\n- Prefer small pull requests focused on one change.\n- Verify that linters and tests are passing.\n- Review the documentation to make sure it looks good.\n- Follow the pull request template when opening a pull request.\n- For pull requests that change the API or implementation, discuss with maintainers first by opening an issue.\n\n## Code of Conduct\n\n### Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.\n\n### Our Standards\n\nExamples of behavior that contributes to a positive environment for our community include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n### Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.\n\n### Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.\n\n### Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the reporter of any incident.\n\n### Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:\n\n#### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.\n\n#### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of actions.\n\n**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.\n\n#### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.\n\n#### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the community.\n\n### Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,\navailable at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Baron Ha.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MultipleImagePicker.podspec",
    "content": "require \"json\"\n\npackage = JSON.parse(File.read(File.join(__dir__, \"package.json\")))\n\nPod::Spec.new do |s|\n  s.name         = \"MultipleImagePicker\"\n  s.version      = package[\"version\"]\n  s.summary      = package[\"description\"]\n  s.homepage     = package[\"homepage\"]\n  s.license      = package[\"license\"]\n  s.authors      = package[\"author\"]\n\n  s.platforms    = { :ios => min_ios_version_supported }\n  s.source       = { :git => \"https://github.com/baronha/react-native-multiple-image-picker.git\", :tag => \"#{s.version}\" }\n\n  s.source_files = [\n    # Implementation (Swift)\n    \"ios/**/*.{swift}\",\n    # Autolinking/Registration (Objective-C++)\n    \"ios/**/*.{m,mm}\",\n    # Implementation (C++ objects)\n    \"cpp/**/*.{hpp,cpp}\",\n  ]\n\n  s.resource_bundles = {\n    \"MultipleImagePicker\" => [\"ios/Assets.xcassets\"]\n  }\n\n\n  s.dependency \"HXPhotoPicker/Picker\", \"4.2.4\"\n  s.dependency \"HXPhotoPicker/Camera/Lite\", \"4.2.4\"\n  s.dependency \"HXPhotoPicker/Editor\", \"4.2.4\"\n\n  s.pod_target_xcconfig = {\n    # C++ compiler flags, mainly for folly.\n    \"CLANG_CXX_LANGUAGE_STANDARD\" => \"c++20\",\n    \"GCC_PREPROCESSOR_DEFINITIONS\" => \"$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES FOLLY_MOBILE\"\n  }\n\n  if ENV[\"USE_FRAMEWORKS\"]\n    s.dependency \"React-Core\"\n    add_dependency(s, \"React-jsinspector\", :framework_name => \"jsinspector_modern\")\n    add_dependency(s, \"React-rendererconsistency\", :framework_name => \"React_rendererconsistency\")\n    add_dependency(s, \"React-jsinspectortracing\", :framework_name => 'jsinspector_moderntracing')\n    add_dependency(s, \"React-jsinspectorcdp\", :framework_name => 'jsinspector_moderncdp')\n  end\n\n  load 'nitrogen/generated/ios/MultipleImagePicker+autolinking.rb'\n\n  add_nitrogen_files(s)\n\n  s.dependency 'React-jsi'\n  s.dependency 'React-callinvoker'\n\n  install_modules_dependencies(s)\nend"
  },
  {
    "path": "README.md",
    "content": "![Logo][Logo]\n\n<p align=\"center\">\n  <img src=\"./files/banner.png\" width=\"100%\">\n</p>\n\n[![iOS][iOS]][iOS-URL] [![Android][Android]][Android-URL] [![Swift][Swift]][Swift-URL] [![Kotlin][Kotlin]][Kotlin-URL] [![React-Native][React-Native]][React-Native-URL]\n\n## Overview 🎇\n\nhttps://github.com/user-attachments/assets/79580bc7-237c-46b7-b92e-1479cc6d9079\n\nReact Native Multiple Image Picker **(RNMIP)** enables application to pick images and videos from multiple smart album in iOS/Android. React Native Multiple Image Picker is based on two libraries available, [HXPhotoPicker](https://github.com/SilenceLove/HXPhotoPicker) and [PictureSelector](https://github.com/LuckSiege/PictureSelector)\n\n## Documentation 📚\n\n## Features 🔥\n\n| 🤩  | ![Logo][Logo]                                                                         |\n| --- | ------------------------------------------------------------------------------------- |\n| 🍕  | [**Crop**](/docs/docs/CROP.mdx) single/multiple image.                                |\n| 🎑  | [**Preview**](/docs/docs/PREVIEW.mdx) image/video.                                    |\n| 📸  | [**Camera**](/docs/docs/CAMERA.mdx) module for capturing photos and recording videos. |\n| 🐳  | Keep the previous selection.                                                          |\n| 0️⃣  | Selected order index.                                                                 |\n| 🎨  | UI Customization (numberOfColumn, spacing, primaryColor ... )                         |\n| 🌚  | Dark Mode, Light Mode                                                                 |\n| 🌄  | Choose multiple images/video.                                                         |\n| 📦  | Support smart album `(camera roll, selfies, panoramas, favorites, videos...)`.        |\n| 📺  | Display video duration.                                                               |\n| ⛅️ | Support iCloud Photo Library.                                                         |\n| 🌪  | Scrolling performance. ☕️                                                             |\n\n## Requirements\n\nBecause RNMIP uses Nitro Module, it complies with Nitro Modules' requirements.\nView Nitro Modules' requirements [here](https://nitro.margelo.com/docs/minimum-requirements)\n\n- `Xcode 16+`\n- `iOS 13+`\n- `react-native 0.75+`\n- `compileSdkVersion 34+`\n\n## Installation\n\nSee more [**Installation**](https://nitrogenzlab.github.io/react-native-multiple-image-picker/getting-started)\n\n## Usage\n\nHere is a simple usage of the Multiple Image Picker. <br/>\nSee more [**Config**](https://nitrogenzlab.github.io/react-native-multiple-image-picker/config)\n\n```typescript\nimport { openPicker, Config } from '@baronha/react-native-multiple-image-picker'\n\nconst config: Config = {\n  maxSelect: 10,\n  maxVideo: 10,\n  primaryColor: '#FB9300',\n  backgroundDark: '#2f2f2f',\n  numberOfColumn: 4,\n  mediaType: 'all',\n  selectBoxStyle: 'number',\n  selectMode: 'multiple',\n  language: 'vi', // 🇻🇳 Vietnamese\n  theme: 'dark',\n  isHiddenOriginalButton: false,\n  primaryColor: '#F6B35D',\n}\n\nconst onPicker = async () => {\n  try {\n    const response = await openPicker(config)\n    setImages(response)\n  } catch (e) {\n    // catch error for multiple image picker\n  }\n}\n```\n\n## To Do\n\n- [x] Crop Image in iOS.\n- [x] Preview Controller for `iOS`.\n- [x] Handle Permission when limited on `iOS`.\n- [x] Migrating Library to the New Architecture.\n- [x] Multiple Crop Image.\n- [x] Multiple Preview Image.\n- [x] Dynamic Theme.\n- [x] Dynamic Language\n- [x] Open Crop Controller.\n- [x] Open Preview Controller.\n- [x] Open Camera Controller.\n\n## Sponsor & Support ☕️\n\n[![BuyMeACoffee][BuyMeACoffee]][BuyMeACoffee-URL] [![Kofi][Kofi]][Kofi-URL]\n\n[BuyMeACoffee]: https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black\n[BuyMeACoffee-URL]: https://buymeacoffee.com/baronha\n[Kofi]: https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white\n[Kofi-URL]: https://ko-fi.com/baoha\nTo keep this library maintained and up-to-date please consider [sponsoring it on GitHub](https://github.com/sponsors/baronha). Or if you are looking for a private support or help in customizing the experience, then reach out to me on Twitter [@\\_baronha](https://twitter.com/_baronha).<br/>\nBesides, I also built a product using HXPhotoPicker here, Hope you support:<br/>\n\n<a href=\"https://apps.apple.com/vn/app/binsoo-photo-filters-editor/id6502683720\" target=\"_blank\">\n  <img  width=\"64px\" height=\"64px\" src=\"https://github.com/user-attachments/assets/71b5ddf7-3da1-4091-aae6-9aa7e411ce75\" />\n</a>\n\n## Built With ❤️\n\n[![NitroModules](https://img.shields.io/badge/Nitro_Modules-0052CC?style=for-the-badge)](https://nitro.margelo.com/docs/nitro-modules)\n<br/>\n[![HXPhotoPicker](https://img.shields.io/badge/HXPhotoPicker-F05138?style=for-the-badge)](https://github.com/SilenceLove/HXPhotoPicker)\n<br/>\n[![PictureSelector](https://img.shields.io/badge/Picture_Selector-b07219?style=for-the-badge)](https://github.com/LuckSiege/PictureSelector)\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=baronha/react-native-multiple-image-picker&type=Date)](https://star-history.com/#bytebase/star-history&Date)\n\n## Showcase ✨\n\nList of used applications with `@baronha/react-native-multiple-image-picker`\n\nContributions are welcome! If you have an application that uses `@baronha/react-native-multiple-image-picker`, please open a [pull request](/docs/docs/SHOWCASE/showcase.json) to add it to the list.\n\nSee all [**Showcase**](https://nitrogenzlab.github.io/react-native-multiple-image-picker/showcase)\n\n## Performance\n\nWe're trying to improve performance. If you have a better solution, please open a [issue](https://github.com/NitrogenZLab/react-native-multiple-image-picker/issues)\nor [pull request](https://github.com/NitrogenZLab/react-native-multiple-image-picker/pulls). Best regards!\n\n## License\n\nMIT\n<br>\n[TLPhotoPicker](https://github.com/tilltue/TLPhotoPicker/blob/master/LICENSE)\n<br>\n[PictureSelector](https://github.com/LuckSiege/PictureSelector/blob/master/LICENSE)\n\n<!-- Badge for README -->\n\n[iOS]: https://img.shields.io/badge/iOS-000000?style=for-the-badge&logo=ios&logoColor=white\n[iOS-URL]: https://www.apple.com/ios\n[Android]: https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white\n[Android-URL]: https://www.android.com/\n[React-Native]: https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB\n[React-Native-URL]: https://reactnative.dev/\n[React-Native]: https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB\n[React-Native-URL]: https://reactnative.dev/\n[Swift]: https://img.shields.io/badge/Swift-FA7343?style=for-the-badge&logo=swift&logoColor=white\n[Swift-URL]: https://developer.apple.com/swift/\n[Kotlin]: https://img.shields.io/badge/Kotlin-0095D5?&style=for-the-badge&logo=kotlin&logoColor=white\n[Kotlin-URL]: https://kotlinlang.org/\n[Logo]: https://img.shields.io/badge/React_Native_Multiple_Image_Picker-DF78C3?style=for-the-badge\n"
  },
  {
    "path": "android/CMakeLists.txt",
    "content": "project(MultipleImagePicker)\ncmake_minimum_required(VERSION 3.9.0)\n\nset (PACKAGE_NAME MultipleImagePicker)\nset (CMAKE_VERBOSE_MAKEFILE ON)\nset (CMAKE_CXX_STANDARD 20)\n\n# Define C++ library and add all sources\nadd_library(${PACKAGE_NAME} SHARED\n        src/main/cpp/cpp-adapter.cpp\n)\n\n# Add Nitrogen specs :)\ninclude(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/MultipleImagePicker+autolinking.cmake)\n\n# Set up local includes\ninclude_directories(\n        \"src/main/cpp\"\n        \"../cpp\"\n)\n\nfind_library(LOG_LIB log)\n\n# Link all libraries together\ntarget_link_libraries(\n        ${PACKAGE_NAME}\n        ${LOG_LIB}\n        android                                   # <-- Android core\n)\n"
  },
  {
    "path": "android/build.gradle",
    "content": "buildscript {\n    repositories {\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath \"com.android.tools.build:gradle:7.2.1\"\n    }\n}\n\ndef reactNativeArchitectures() {\n    def value = rootProject.getProperties().get(\"reactNativeArchitectures\")\n    return value ? value.split(\",\") : [\"armeabi-v7a\", \"x86\", \"x86_64\", \"arm64-v8a\"]\n}\n\ndef isNewArchitectureEnabled() {\n    return rootProject.hasProperty(\"newArchEnabled\") && rootProject.getProperty(\"newArchEnabled\") == \"true\"\n}\n\napply plugin: \"com.android.library\"\napply plugin: 'org.jetbrains.kotlin.android'\napply from: '../nitrogen/generated/android/MultipleImagePicker+autolinking.gradle'\n\nif (isNewArchitectureEnabled()) {\n    apply plugin: \"com.facebook.react\"\n}\n\ndef getExtOrDefault(name) {\n    return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties[\"MultipleImagePicker_\" + name]\n}\n\ndef getExtOrIntegerDefault(name) {\n    return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties[\"MultipleImagePicker_\" + name]).toInteger()\n}\n\nandroid {\n    namespace \"com.margelo.nitro.multipleimagepicker\"\n\n    ndkVersion getExtOrDefault(\"ndkVersion\")\n    compileSdkVersion getExtOrIntegerDefault(\"compileSdkVersion\")\n\n    defaultConfig {\n        minSdkVersion getExtOrIntegerDefault(\"minSdkVersion\")\n        targetSdkVersion getExtOrIntegerDefault(\"targetSdkVersion\")\n        buildConfigField \"boolean\", \"IS_NEW_ARCHITECTURE_ENABLED\", isNewArchitectureEnabled().toString()\n\n        externalNativeBuild {\n            cmake {\n                cppFlags \"-O2 -frtti -fexceptions -Wall -fstack-protector-all\"\n                arguments \"-DANDROID_STL=c++_shared\"\n                abiFilters(*reactNativeArchitectures())\n            }\n        }\n    }\n\n    externalNativeBuild {\n        cmake {\n            path \"CMakeLists.txt\"\n        }\n    }\n\n    packagingOptions {\n        excludes = [\"META-INF\",\n                    \"META-INF/**\",\n                    \"**/libc++_shared.so\",\n                    \"**/libfbjni.so\",\n                    \"**/libjsi.so\",\n                    \"**/libfolly_json.so\",\n                    \"**/libfolly_runtime.so\",\n                    \"**/libglog.so\",\n                    \"**/libhermes.so\",\n                    \"**/libhermes-executor-debug.so\",\n                    \"**/libhermes_executor.so\",\n                    \"**/libreactnative.so\",\n                    \"**/libreactnativejni.so\",\n                    \"**/libturbomodulejsijni.so\",\n                    \"**/libreact_nativemodule_core.so\",\n                    \"**/libjscexecutor.so\"]\n    }\n\n    buildFeatures {\n        buildConfig true\n        prefab true\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n        }\n    }\n\n    lintOptions {\n        disable \"GradleCompatible\"\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    sourceSets {\n        main {\n            if (isNewArchitectureEnabled()) {\n                java.srcDirs += [\n                        // React Codegen files\n                        \"${project.buildDir}/generated/source/codegen/java\"]\n            }\n        }\n    }\n}\n\nrepositories {\n    mavenCentral()\n    google()\n}\n\n\ndependencies {\n    // For < 0.71, this will be from the local maven repo\n    // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin\n    //noinspection GradleDynamicVersion\n\n    // Add a dependency on NitroModules\n    implementation 'com.github.bumptech.glide:glide:4.16.0'\n    annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'\n    // PictureSelector basic (Necessary)\n    implementation 'io.github.lucksiege:pictureselector:v3.11.2'\n\n    // image compress library (Not necessary)\n    implementation 'io.github.lucksiege:compress:v3.11.2'\n\n    // uCrop library (Not necessary)\n    implementation 'io.github.lucksiege:ucrop:v3.11.2'\n\n    // simple camerax library (Not necessary)\n    implementation 'io.github.lucksiege:camerax:v3.11.2'\n\n    // exoplayer\n    implementation \"com.google.android.exoplayer:exoplayer:2.19.1\"\n\n\n    implementation \"com.facebook.react:react-native:+\"\n\n    // Add a dependency on NitroModules\n    implementation project(\":react-native-nitro-modules\")\n}\n\nif (isNewArchitectureEnabled()) {\n    react {\n        jsRootDir = file(\"../src/\")\n        libraryName = \"MultipleImagePicker\"\n        codegenJavaPackageName = \"com.margelo.nitro.multipleimagepicker\"\n    }\n}\n\n"
  },
  {
    "path": "android/gradle.properties",
    "content": "MultipleImagePicker_kotlinVersion=1.9.24\nMultipleImagePicker_minSdkVersion=23\nMultipleImagePicker_targetSdkVersion=34\nMultipleImagePicker_compileSdkVersion=34\nMultipleImagePicker_ndkVersion=26.1.10909125\n"
  },
  {
    "path": "android/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\">\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission tools:ignore=\"ProtectedPermissions\" android:name=\"android.permission.WRITE_MEDIA_STORAGE\" />\n    <uses-permission tools:ignore=\"ProtectedPermissions\" android:name=\"android.permission.WRITE_SETTINGS\" />\n    <uses-permission tools:ignore=\"ProtectedPermissions\" android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission tools:ignore=\"ProtectedPermissions\" android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission tools:ignore=\"ProtectedPermissions\" android:name=\"android.permission.RECORD_AUDIO\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.VIBRATE\" />\n    <uses-permission android:name=\"android.permission.BLUETOOTH\" />\n\n    <!-- Android 13 -->\n    <uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\" />\n    <uses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\" />\n    <uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\" />\n\n    <application android:requestLegacyExternalStorage=\"true\" />\n</manifest>\n"
  },
  {
    "path": "android/src/main/cpp/cpp-adapter.cpp",
    "content": "#include <jni.h>\n#include \"MultipleImagePickerOnLoad.hpp\"\n\nJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {\n  return margelo::nitro::multipleimagepicker::initialize(vm);\n}\n"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/CameraEngine.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.content.Context\nimport android.graphics.Color\nimport androidx.fragment.app.Fragment\nimport com.bumptech.glide.Glide\nimport com.facebook.react.bridge.ColorPropConverter\nimport com.luck.lib.camerax.SimpleCameraX\nimport com.luck.picture.lib.interfaces.OnCameraInterceptListener\nimport java.io.File\n\nclass CameraEngine(\n    private val appContext: Context,\n    val config: NitroCameraConfig,\n) :\n    OnCameraInterceptListener {\n    override fun openCamera(fragment: Fragment, cameraMode: Int, requestCode: Int) {\n        val camera = SimpleCameraX.of()\n\n        camera.setImageEngine { context, url, imageView ->\n            Glide.with(context).load(url).into(imageView)\n        }\n\n        camera.isAutoRotation(true)\n        camera.setCameraMode(cameraMode)\n        camera.isDisplayRecordChangeTime(true)\n        camera.isManualFocusCameraPreview(true)\n        camera.isZoomCameraPreview(true)\n        camera.setRecordVideoMaxSecond(config.videoMaximumDuration?.toInt() ?: 60)\n        camera.setCameraAroundState(config.cameraDevice == CameraDevice.FRONT)\n        camera.setOutputPathDir(getSandboxCameraOutputPath())\n\n        config.color?.let {\n            val primaryColor = ColorPropConverter.getColor(it, appContext) ?: Color.BLACK\n            camera.setCaptureLoadingColor(primaryColor)\n        }\n\n        camera.start(fragment.requireActivity(), fragment, requestCode)\n    }\n\n    private fun getSandboxCameraOutputPath(): String {\n        val externalFilesDir: File? = appContext.getExternalFilesDir(\"\")\n        val customFile = File(externalFilesDir?.absolutePath, \"Sandbox\")\n        if (!customFile.exists()) {\n            customFile.mkdirs()\n        }\n        return customFile.absolutePath + File.separator\n\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/Constant.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nobject Constant {\n    const val TOOLBAR_TEXT_SIZE = 12\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/CropEngine.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport android.net.Uri\nimport android.widget.ImageView\nimport androidx.fragment.app.Fragment\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.request.target.CustomTarget\nimport com.bumptech.glide.request.transition.Transition\nimport com.luck.picture.lib.config.PictureMimeType\nimport com.luck.picture.lib.engine.CropFileEngine\nimport com.luck.picture.lib.entity.LocalMedia\nimport com.luck.picture.lib.interfaces.OnMediaEditInterceptListener\nimport com.luck.picture.lib.utils.DateUtils\nimport com.margelo.nitro.multipleimagepicker.ImageLoaderUtils.assertValidRequest\nimport com.yalantis.ucrop.UCrop\nimport com.yalantis.ucrop.UCrop.Options\nimport com.yalantis.ucrop.UCropImageEngine\nimport java.io.File\n\nclass CropImageEngine : UCropImageEngine {\n    override fun loadImage(context: Context, url: String, imageView: ImageView) {\n        if (!assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context).load(url).override(180, 180).into(imageView)\n    }\n\n    override fun loadImage(\n        context: Context,\n        url: Uri,\n        maxWidth: Int,\n        maxHeight: Int,\n        call: UCropImageEngine.OnCallbackListener<Bitmap>\n    ) {\n        Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight)\n            .into(object : CustomTarget<Bitmap?>() {\n                override fun onResourceReady(\n                    resource: Bitmap, transition: Transition<in Bitmap?>?\n                ) {\n                    call.onCall(resource)\n                }\n\n                override fun onLoadCleared(placeholder: Drawable?) {\n                    call.onCall(null)\n                }\n            })\n    }\n}\n\nclass CropEngine(cropOption: Options) : CropFileEngine {\n    private val options: Options = cropOption\n\n    override fun onStartCrop(\n        fragment: Fragment,\n        srcUri: Uri?,\n        destinationUri: Uri?,\n        dataSource: ArrayList<String?>?,\n        requestCode: Int\n    ) {\n        val uCrop = UCrop.of(srcUri!!, destinationUri!!, dataSource)\n        uCrop.withOptions(options)\n        uCrop.setImageEngine(CropImageEngine())\n        uCrop.start(fragment.requireActivity(), fragment, requestCode)\n    }\n}\n\nclass MediaEditInterceptListener(\n    private val outputCropPath: String,\n    private val options: Options,\n) : OnMediaEditInterceptListener {\n    override fun onStartMediaEdit(\n        fragment: Fragment, currentLocalMedia: LocalMedia, requestCode: Int\n    ) {\n        val currentEditPath = currentLocalMedia.availablePath\n        val inputUri =\n            if (PictureMimeType.isContent(currentEditPath)) Uri.parse(currentEditPath)\n            else Uri.fromFile(File(currentEditPath))\n\n        val destinationUri = Uri.fromFile(\n            File(outputCropPath, DateUtils.getCreateFileName(\"CROP_\") + \".jpeg\")\n        )\n\n        val uCrop = UCrop.of<Any>(inputUri, destinationUri)\n\n        uCrop.withOptions(options)\n\n        // set engine\n        uCrop.setImageEngine(CropImageEngine())\n\n        // start edit\n        uCrop.startEdit(fragment.requireActivity(), fragment, requestCode)\n    }\n}\n\n\nfun getSandboxPath(context: Context): String {\n    val externalFilesDir: File? = context.getExternalFilesDir(\"\")\n    val customFile = File(externalFilesDir?.absolutePath, \"Sandbox\")\n    if (!customFile.exists()) {\n        customFile.mkdirs()\n    }\n    return customFile.absolutePath + File.separator\n}\n\n\n"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/ExoPlayerEngine.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.content.Context\nimport android.net.Uri\nimport android.view.View\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.MediaItem\nimport com.google.android.exoplayer2.PlaybackException\nimport com.google.android.exoplayer2.Player\nimport com.google.android.exoplayer2.ui.StyledPlayerView\nimport com.luck.picture.lib.config.PictureMimeType\nimport com.luck.picture.lib.config.SelectorProviders\nimport com.luck.picture.lib.engine.VideoPlayerEngine\nimport com.luck.picture.lib.entity.LocalMedia\nimport com.luck.picture.lib.interfaces.OnPlayerListener\nimport java.io.File\nimport java.util.concurrent.CopyOnWriteArrayList\n\n\nclass ExoPlayerEngine : VideoPlayerEngine<StyledPlayerView> {\n    private val listeners = CopyOnWriteArrayList<OnPlayerListener>()\n\n    override fun onCreateVideoPlayer(context: Context): View {\n        val exoPlayer = StyledPlayerView(context)\n        exoPlayer.useController = true\n        return exoPlayer\n    }\n\n    override fun onStarPlayer(exoPlayer: StyledPlayerView, media: LocalMedia) {\n        val player = exoPlayer.player\n        if (player != null) {\n            val mediaItem: MediaItem\n            val path = media.availablePath\n            mediaItem = if (PictureMimeType.isContent(path)) {\n                MediaItem.fromUri(Uri.parse(path))\n            } else if (PictureMimeType.isHasHttp(path)) {\n                MediaItem.fromUri(path)\n            } else {\n                MediaItem.fromUri(Uri.fromFile(File(path)))\n            }\n            val config = SelectorProviders.getInstance().selectorConfig\n            player.repeatMode =\n                if (config.isLoopAutoPlay) Player.REPEAT_MODE_ALL else Player.REPEAT_MODE_OFF\n            player.setMediaItem(mediaItem)\n            player.prepare()\n            player.play()\n        }\n    }\n\n    override fun onResume(exoPlayer: StyledPlayerView) {\n        val player = exoPlayer.player\n        player?.play()\n    }\n\n    override fun onPause(exoPlayer: StyledPlayerView) {\n        val player = exoPlayer.player\n        player?.pause()\n    }\n\n    override fun isPlaying(exoPlayer: StyledPlayerView): Boolean {\n        val player = exoPlayer.player\n        return player != null && player.isPlaying\n    }\n\n\n    override fun addPlayListener(playerListener: OnPlayerListener) {\n        if (!listeners.contains(playerListener)) {\n            listeners.add(playerListener)\n        }\n    }\n\n    override fun removePlayListener(playerListener: OnPlayerListener) {\n        listeners.remove(playerListener)\n    }\n\n    override fun onPlayerAttachedToWindow(exoPlayer: StyledPlayerView) {\n        val player: Player = ExoPlayer.Builder(exoPlayer.context).build()\n        exoPlayer.player = player\n        player.addListener(mPlayerListener)\n    }\n\n    override fun onPlayerDetachedFromWindow(exoPlayer: StyledPlayerView) {\n        val player = exoPlayer.player\n        if (player != null) {\n            player.removeListener(mPlayerListener)\n            player.release()\n            exoPlayer.player = null\n        }\n    }\n\n    override fun destroy(exoPlayer: StyledPlayerView) {\n        val player = exoPlayer.player\n        if (player != null) {\n            player.removeListener(mPlayerListener)\n            player.release()\n        }\n    }\n\n    private val mPlayerListener: Player.Listener = object : Player.Listener {\n        override fun onPlayerError(error: PlaybackException) {\n            for (i in listeners.indices) {\n                val playerListener = listeners[i]\n                playerListener.onPlayerError()\n            }\n        }\n\n        override fun onPlaybackStateChanged(playbackState: Int) {\n            if (playbackState == Player.STATE_READY) {\n                for (i in listeners.indices) {\n                    val playerListener = listeners[i]\n                    playerListener.onPlayerReady()\n                }\n            } else if (playbackState == Player.STATE_BUFFERING) {\n                for (i in listeners.indices) {\n                    val playerListener = listeners[i]\n                    playerListener.onPlayerLoading()\n                }\n            } else if (playbackState == Player.STATE_ENDED) {\n                for (i in listeners.indices) {\n                    val playerListener = listeners[i]\n                    playerListener.onPlayerEnd()\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/GlideEngine.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.content.Context\nimport android.widget.ImageView\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.load.resource.bitmap.CenterCrop\nimport com.bumptech.glide.load.resource.bitmap.RoundedCorners\nimport com.luck.picture.lib.engine.ImageEngine\nimport com.luck.picture.lib.utils.ActivityCompatHelper\n\nclass GlideEngine private constructor() : ImageEngine {\n    override fun loadImage(context: Context, url: String, imageView: ImageView) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context)\n            .load(url)\n            .into(imageView)\n    }\n\n    override fun loadImage(\n        context: Context,\n        imageView: ImageView,\n        url: String,\n        maxWidth: Int,\n        maxHeight: Int\n    ) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context)\n            .load(url)\n            .override(maxWidth, maxHeight)\n            .into(imageView)\n    }\n\n    override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context)\n            .asBitmap()\n            .load(url)\n            .override(180, 180)\n            .sizeMultiplier(0.5f)\n            .transform(CenterCrop(), RoundedCorners(8))\n            .into(imageView)\n    }\n\n    override fun loadGridImage(context: Context, url: String, imageView: ImageView) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context)\n            .load(url)\n            .override(200, 200)\n            .centerCrop()\n            .placeholder(com.luck.picture.lib.R.drawable.ps_image_placeholder)\n            .into(imageView)\n    }\n\n    override fun pauseRequests(context: Context) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context).pauseRequests()\n    }\n\n    override fun resumeRequests(context: Context) {\n        if (!ActivityCompatHelper.assertValidRequest(context)) {\n            return\n        }\n        Glide.with(context).resumeRequests()\n    }\n\n    private object InstanceHolder {\n        val instance = GlideEngine()\n    }\n\n    companion object {\n        fun createGlideEngine(): GlideEngine {\n            return InstanceHolder.instance\n        }\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/ImageLoaderUtils.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.ContextWrapper\n\nobject ImageLoaderUtils {\n    fun assertValidRequest(context: Context?): Boolean {\n        if (context is Activity) {\n            return !isDestroy(context)\n        } else if (context is ContextWrapper) {\n            if (context.baseContext is Activity) {\n                val activity = context.baseContext as Activity\n                return !isDestroy(activity)\n            }\n        }\n        return true\n    }\n\n    private fun isDestroy(activity: Activity?): Boolean {\n        return if (activity == null) {\n            true\n        } else activity.isFinishing || activity.isDestroyed\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/LoadingDialog.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\n\nimport android.app.Dialog\nimport android.content.Context\nimport android.os.Bundle\nimport android.view.Gravity\nimport android.view.ViewGroup\n\n\nclass LoadingDialog(context: Context?) :\n    Dialog(context!!, R.style.Picture_Theme_AlertDialog) {\n    init {\n        setCancelable(true)\n        setCanceledOnTouchOutside(false)\n    }\n\n    override fun onCreate(savedInstanceState: Bundle) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.loading_dialog)\n        setDialogSize()\n    }\n\n    private fun setDialogSize() {\n        val params = window!!.attributes\n        params.width = ViewGroup.LayoutParams.WRAP_CONTENT\n        params.height = ViewGroup.LayoutParams.WRAP_CONTENT\n        params.gravity = Gravity.CENTER\n        window!!.setWindowAnimations(R.style.PictureThemeDialogWindowStyle)\n        window!!.attributes = params\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePicker.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport com.margelo.nitro.NitroModules\n\n\nclass MultipleImagePicker : HybridMultipleImagePickerSpec() {\n    override val memorySize: Long\n        get() = 5\n\n    private val pickerModule = MultipleImagePickerImp(NitroModules.applicationContext)\n\n    override fun openPicker(\n        config: NitroConfig,\n        resolved: (result: Array<PickerResult>) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        pickerModule.openPicker(config, resolved, rejected)\n    }\n\n    override fun openCrop(\n        image: String,\n        config: NitroCropConfig,\n        resolved: (result: CropResult) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        pickerModule.openCrop(image, config, resolved, rejected)\n    }\n\n    override fun openPreview(\n        media: Array<MediaPreview>,\n        index: Double,\n        config: NitroPreviewConfig,\n        onLongPress: (index: Double) -> Unit\n    ) {\n        pickerModule.openPreview(media, index.toInt(), config, onLongPress)\n    }\n\n    override fun openCamera(\n        config: NitroCameraConfig,\n        resolved: (result: CameraResult) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        pickerModule.openCamera(config, resolved, rejected)\n    }\n\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePickerImp.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Color\nimport android.net.Uri\nimport androidx.core.content.ContextCompat\nimport com.facebook.react.bridge.BaseActivityEventListener\nimport com.facebook.react.bridge.ColorPropConverter\nimport com.facebook.react.bridge.ReactApplicationContext\nimport com.facebook.react.bridge.ReactContextBaseJavaModule\nimport com.facebook.react.bridge.ReactMethod\nimport com.luck.picture.lib.app.IApp\nimport com.luck.picture.lib.app.PictureAppMaster\nimport com.luck.picture.lib.basic.PictureSelector\nimport com.luck.picture.lib.config.PictureMimeType\nimport com.luck.picture.lib.config.SelectMimeType\nimport com.luck.picture.lib.config.SelectModeConfig\nimport com.luck.picture.lib.engine.PictureSelectorEngine\nimport com.luck.picture.lib.entity.LocalMedia\nimport com.luck.picture.lib.interfaces.OnCustomLoadingListener\nimport com.luck.picture.lib.interfaces.OnExternalPreviewEventListener\nimport com.luck.picture.lib.interfaces.OnMediaEditInterceptListener\nimport com.luck.picture.lib.interfaces.OnResultCallbackListener\nimport com.luck.picture.lib.language.LanguageConfig\nimport com.luck.picture.lib.style.BottomNavBarStyle\nimport com.luck.picture.lib.style.PictureSelectorStyle\nimport com.luck.picture.lib.style.PictureWindowAnimationStyle\nimport com.luck.picture.lib.style.SelectMainStyle\nimport com.luck.picture.lib.style.TitleBarStyle\nimport com.luck.picture.lib.utils.DateUtils\nimport com.luck.picture.lib.utils.DensityUtil\nimport com.luck.picture.lib.utils.MediaUtils\nimport com.yalantis.ucrop.UCrop\nimport com.yalantis.ucrop.UCrop.Options\nimport com.yalantis.ucrop.UCrop.REQUEST_CROP\nimport com.yalantis.ucrop.model.AspectRatio\nimport java.io.File\nimport java.net.HttpURLConnection\nimport java.net.URL\n\n\nclass MultipleImagePickerImp(reactContext: ReactApplicationContext?) :\n    ReactContextBaseJavaModule(reactContext), IApp {\n\n    override fun getName(): String {\n        return \"MultipleImagePicker\"\n    }\n\n    companion object {\n        const val TAG = \"MultipleImagePicker\"\n    }\n\n    private var style = PictureSelectorStyle()\n    private lateinit var config: NitroConfig\n    private var cropOption = Options()\n    private var dataList = mutableListOf<LocalMedia>()\n\n\n    @ReactMethod\n    fun openPicker(\n        options: NitroConfig,\n        resolved: (result: Array<PickerResult>) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        PictureAppMaster.getInstance().app = this\n        val activity = reactApplicationContext.currentActivity\n            ?: throw IllegalStateException(\"No current Activity available\")\n        val imageEngine = GlideEngine.createGlideEngine()\n\n        // set global config\n        config = options\n\n        setStyle() // set style for UI\n        handleSelectedAssets(config)\n\n        val chooseMode = getChooseMode(config.mediaType)\n\n        val maxSelect = config.maxSelect?.toInt() ?: 20\n        val maxVideo = config.maxVideo?.toInt() ?: 20\n        val isPreview = config.isPreview ?: true\n        val maxFileSize = config.maxFileSize?.toLong()\n        val maxDuration = config.maxVideoDuration?.toInt()\n        val minDuration = config.minVideoDuration?.toInt()\n        val allowSwipeToSelect = config.allowSwipeToSelect ?: false\n        val isMultiple = config.selectMode == SelectMode.MULTIPLE\n        val selectMode = if (isMultiple) SelectModeConfig.MULTIPLE else SelectModeConfig.SINGLE\n\n        val isCrop = config.crop != null\n\n        PictureSelector.create(activity)\n            .openGallery(chooseMode)\n            .setImageEngine(imageEngine)\n            .setSelectedData(dataList)\n            .setSelectorUIStyle(style)\n            .apply {\n                if (isCrop) {\n                    setCropOption(config.crop)\n                    // Disabled force crop engine for multiple\n                    if (!isMultiple) setCropEngine(CropEngine(cropOption))\n                    else setEditMediaInterceptListener(setEditMediaEvent())\n                }\n                maxDuration?.let {\n                    setFilterVideoMaxSecond(it)\n                }\n\n                minDuration?.let {\n                    setFilterVideoMinSecond(it)\n                }\n\n                maxFileSize?.let {\n                    setFilterMaxFileSize(it)\n                }\n\n                isDisplayCamera(config.camera != null)\n\n                config.camera?.let {\n                    val cameraConfig = NitroCameraConfig(\n                        mediaType = MediaType.ALL,\n                        presentation = Presentation.FULLSCREENMODAL,\n                        language = Language.SYSTEM,\n                        crop = null,\n                        isSaveSystemAlbum = false,\n                        color = config.primaryColor,\n                        cameraDevice = it.cameraDevice,\n                        videoMaximumDuration = it.videoMaximumDuration\n                    )\n\n                    setCameraInterceptListener(CameraEngine(appContext, cameraConfig))\n                }\n            }\n            .setVideoThumbnailListener(VideoThumbnailEngine(getVideoThumbnailDir()))\n            .setImageSpanCount(config.numberOfColumn?.toInt() ?: 3)\n            .setMaxSelectNum(maxSelect)\n            .isDirectReturnSingle(true)\n            .isSelectZoomAnim(true)\n            .isPageStrategy(true, 50)\n            .isWithSelectVideoImage(true)\n            .setMaxVideoSelectNum(if (maxVideo != 20) maxVideo else maxSelect)\n            .isMaxSelectEnabledMask(true)\n            .isAutoVideoPlay(true)\n            .isFastSlidingSelect(allowSwipeToSelect)\n            .isPageSyncAlbumCount(true)\n            // isPreview\n            .isPreviewImage(isPreview)\n            .isPreviewVideo(isPreview)\n            .isDisplayTimeAxis(true)\n            .setSelectionMode(selectMode)\n            .isOriginalControl(config.isHiddenOriginalButton == false)\n            .setLanguage(getLanguage(config.language))\n            .isPreviewFullScreenMode(true)\n            .forResult(object : OnResultCallbackListener<LocalMedia?> {\n                override fun onResult(localMedia: ArrayList<LocalMedia?>?) {\n                    var data: Array<PickerResult> = arrayOf()\n                    if (localMedia?.size == 0 || localMedia == null) {\n                        resolved(arrayOf())\n                        return\n                    }\n\n                    // set dataList\n                    dataList = localMedia.filterNotNull().toMutableList()\n\n                    localMedia.forEach { item ->\n                        if (item != null) {\n                            val media = getResult(item)\n                            data += media  // Add the media to the data array\n                        }\n                    }\n                    resolved(data)\n                }\n\n                override fun onCancel() {\n                    //\n                }\n            })\n    }\n\n    @ReactMethod\n    fun openCrop(\n        image: String,\n        options: NitroCropConfig,\n        resolved: (result: CropResult) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        cropOption = Options()\n\n        setCropOption(\n            PickerCropConfig(\n                circle = options.circle,\n                ratio = options.ratio,\n                defaultRatio = options.defaultRatio,\n                freeStyle = options.freeStyle\n            )\n        )\n\n        try {\n            val uri = when {\n                // image network\n                image.startsWith(\"http://\") || image.startsWith(\"https://\") -> {\n                    // Handle remote URL\n                    val url = URL(image)\n                    val connection = url.openConnection() as HttpURLConnection\n                    connection.doInput = true\n                    connection.connect()\n\n                    val inputStream = connection.inputStream\n                    // Create a temp file to store the image\n                    val file = File(appContext.cacheDir, \"CROP_\")\n                    file.outputStream().use { output ->\n                        inputStream.copyTo(output)\n                    }\n\n                    Uri.fromFile(file)\n                }\n\n                else -> Uri.parse(image)\n            }\n\n            val destinationUri = Uri.fromFile(\n                File(getSandboxPath(appContext), DateUtils.getCreateFileName(\"CROP_\") + \".jpeg\")\n            )\n            val uCrop = UCrop.of<Any>(uri, destinationUri).withOptions(cropOption)\n\n            // set engine\n            uCrop.setImageEngine(CropImageEngine())\n            // start edit\n\n            val cropActivityEventListener = object : BaseActivityEventListener() {\n                override fun onActivityResult(\n                    activity: Activity,\n                    requestCode: Int,\n                    resultCode: Int,\n                    data: Intent?\n                ) {\n                    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CROP) {\n                        val resultUri = UCrop.getOutput(data!!)\n                        val width = UCrop.getOutputImageWidth(data).toDouble()\n                        val height = UCrop.getOutputImageHeight(data).toDouble()\n\n                        resultUri?.let {\n                            val result = CropResult(\n                                path = it.toString(),\n                                width,\n                                height,\n                            )\n                            resolved(result)\n                        }\n                    } else if (resultCode == UCrop.RESULT_ERROR) {\n                        val cropError = UCrop.getError(data!!)\n                        rejected(0.0)\n                    }\n\n                    // Remove listener after getting result\n                    reactApplicationContext.removeActivityEventListener(this)\n                }\n            }\n\n            // Add listener before starting UCrop\n            reactApplicationContext.addActivityEventListener(cropActivityEventListener)\n\n            reactApplicationContext.currentActivity?.let { uCrop.start(it, REQUEST_CROP) }\n        } catch (e: Exception) {\n            rejected(0.0)\n        }\n    }\n\n    @ReactMethod\n    fun openPreview(\n        media: Array<MediaPreview>,\n        index: Int,\n        config: NitroPreviewConfig,\n        onLongPress: (index: Double) -> Unit\n    ) {\n        val imageEngine = GlideEngine.createGlideEngine()\n\n        val assets: ArrayList<LocalMedia> = arrayListOf()\n\n        val previewStyle = PictureSelectorStyle()\n        val titleBarStyle = TitleBarStyle()\n\n        previewStyle.windowAnimationStyle.setActivityEnterAnimation(R.anim.anim_modal_in)\n        previewStyle.windowAnimationStyle.setActivityExitAnimation(com.luck.picture.lib.R.anim.ps_anim_modal_out)\n        previewStyle.selectMainStyle.previewBackgroundColor = Color.BLACK\n\n        titleBarStyle.previewTitleBackgroundColor = Color.BLACK\n        previewStyle.titleBarStyle = titleBarStyle\n\n        media.withIndex().forEach { (index, mediaItem) ->\n\n            var asset: LocalMedia? = null\n\n            mediaItem.path?.let { path ->\n                // network asset\n                if (path.startsWith(\"https://\") || path.startsWith(\"http://\")) {\n                    val localMedia = LocalMedia.create()\n                    localMedia.path = path\n                    localMedia.mimeType =\n                        if (mediaItem.type == ResultType.VIDEO) \"video/mp4\" else MediaUtils.getMimeTypeFromMediaHttpUrl(\n                            path\n                        ) ?: \"image/jpg\"\n                    asset = localMedia\n                } else {\n                    asset = LocalMedia.generateLocalMedia(appContext, path)\n                }\n            }\n\n            asset?.let {\n                it.setPosition(index)\n                assets.add(it)\n            }\n        }\n\n        val activity = reactApplicationContext.currentActivity\n            ?: throw IllegalStateException(\"No current Activity available\")\n        PictureSelector\n            .create(activity)\n            .openPreview()\n            .setImageEngine(imageEngine)\n            .setLanguage(getLanguage(config.language))\n            .setSelectorUIStyle(previewStyle)\n            .isPreviewFullScreenMode(true)\n            .isAutoVideoPlay(config.videoAutoPlay == true)\n            .setVideoPlayerEngine(ExoPlayerEngine())\n            .isVideoPauseResumePlay(true)\n            .setCustomLoadingListener(getCustomLoadingListener())\n            .setExternalPreviewEventListener(object : OnExternalPreviewEventListener {\n                override fun onPreviewDelete(position: Int) {\n                    //\n                }\n\n                override fun onLongPressDownload(context: Context, media: LocalMedia): Boolean {\n                    onLongPress(media.position.toDouble())\n                    return true\n                }\n            })\n            .startFragmentPreview(index, false, assets)\n    }\n\n\n    private fun getCustomLoadingListener(): OnCustomLoadingListener {\n        return OnCustomLoadingListener { context -> LoadingDialog(context) }\n    }\n\n    @ReactMethod\n    fun openCamera(\n        config: NitroCameraConfig,\n        resolved: (result: CameraResult) -> Unit,\n        rejected: (reject: Double) -> Unit\n    ) {\n        val activity = reactApplicationContext.currentActivity\n            ?: throw IllegalStateException(\"No current Activity available\")\n        val chooseMode = getChooseMode(config.mediaType)\n\n        PictureSelector\n            .create(activity)\n            .openCamera(chooseMode)\n            .setLanguage(getLanguage(config.language))\n            .setCameraInterceptListener(CameraEngine(appContext, config))\n            .isQuickCapture(true)\n            .isOriginalControl(true)\n            .setVideoThumbnailListener(VideoThumbnailEngine(getVideoThumbnailDir()))\n            .apply {\n                if (config.crop != null) {\n                    setCropEngine(CropEngine(cropOption))\n                }\n            }\n            .forResult(object : OnResultCallbackListener<LocalMedia?> {\n                override fun onResult(results: java.util.ArrayList<LocalMedia?>?) {\n                    results?.first()?.let {\n                        val result = getResult(it)\n\n                        resolved(\n                            CameraResult(\n                                path = result.path,\n                                type = result.type,\n                                width = result.width,\n                                height = result.height,\n                                duration = result.duration,\n                                thumbnail = result.thumbnail,\n                                fileName = result.fileName\n                            )\n                        )\n                    }\n                }\n\n                override fun onCancel() {\n//                    rejected(0.0)\n                }\n            })\n    }\n\n    private fun getChooseMode(mediaType: MediaType): Int {\n        return when (mediaType) {\n            MediaType.VIDEO -> SelectMimeType.ofVideo()\n            MediaType.IMAGE -> SelectMimeType.ofImage()\n            else -> SelectMimeType.ofAll()\n        }\n    }\n\n    private fun getVideoThumbnailDir(): String {\n        val externalFilesDir: File? = appContext.getExternalFilesDir(\"\")\n        val customFile = File(externalFilesDir?.absolutePath, \"Thumbnail\")\n        if (!customFile.exists()) {\n            customFile.mkdirs()\n        }\n        return customFile.absolutePath + File.separator\n    }\n\n\n    private fun getLanguage(language: Language): Int {\n        return when (language) {\n            Language.VI -> LanguageConfig.VIETNAM  // -> 🇻🇳 My country. Yeahhh\n            Language.EN -> LanguageConfig.ENGLISH\n            Language.ZH_HANS -> LanguageConfig.CHINESE\n            Language.ZH_HANT -> LanguageConfig.TRADITIONAL_CHINESE\n            Language.DE -> LanguageConfig.GERMANY\n            Language.KO -> LanguageConfig.KOREA\n            Language.FR -> LanguageConfig.FRANCE\n            Language.JA -> LanguageConfig.JAPAN\n            Language.AR -> LanguageConfig.AR\n            Language.RU -> LanguageConfig.RU\n            else -> LanguageConfig.SYSTEM_LANGUAGE\n        }\n    }\n\n    private fun setCropOption(config: PickerCropConfig?) {\n        cropOption.setShowCropFrame(true)\n        cropOption.setShowCropGrid(true)\n        cropOption.setCircleDimmedLayer(config?.circle ?: false)\n        cropOption.setCropOutputPathDir(getSandboxPath(appContext))\n        cropOption.isCropDragSmoothToCenter(true)\n        cropOption.isForbidSkipMultipleCrop(true)\n        cropOption.setMaxScaleMultiplier(100f)\n        cropOption.setToolbarWidgetColor(Color.BLACK)\n        cropOption.setStatusBarColor(Color.WHITE)\n        cropOption.isDarkStatusBarBlack(true)\n        cropOption.isDragCropImages(true)\n        cropOption.setFreeStyleCropEnabled(config?.freeStyle ?: true)\n        cropOption.setSkipCropMimeType(*getNotSupportCrop())\n\n\n        val ratioCount = config?.ratio?.size ?: 0\n\n        if (config?.defaultRatio != null || ratioCount > 0) {\n\n            var ratioList = arrayOf(AspectRatio(\"Original\", 0f, 0f))\n\n            if (ratioCount > 0) {\n                config?.ratio?.take(4)?.toTypedArray()?.forEach { item ->\n                    ratioList += AspectRatio(\n                        item.title, item.width.toFloat(), item.height.toFloat()\n                    )\n                }\n            }\n\n            // Add default Aspects\n            ratioList += arrayOf(\n                AspectRatio(null, 1f, 1f),\n                AspectRatio(null, 16f, 9f),\n                AspectRatio(null, 4f, 3f),\n                AspectRatio(null, 3f, 2f)\n            )\n\n            config?.defaultRatio?.let {\n                val defaultRatio = AspectRatio(it.title, it.width.toFloat(), it.height.toFloat())\n                ratioList = arrayOf(defaultRatio) + ratioList\n\n            }\n\n            cropOption.apply {\n\n                setAspectRatioOptions(\n                    0,\n                    *ratioList.take(5).toTypedArray()\n                )\n            }\n        }\n    }\n\n\n    private fun getNotSupportCrop(): Array<String> {\n        return arrayOf(PictureMimeType.ofGIF(), PictureMimeType.ofWEBP())\n    }\n\n\n    private fun setEditMediaEvent(): OnMediaEditInterceptListener {\n        return MediaEditInterceptListener(getSandboxPath(appContext), cropOption)\n    }\n\n    private fun setStyle() {\n        val primaryColor = ColorPropConverter.getColor(config.primaryColor, appContext)\n        val isNumber =\n            config.selectMode == SelectMode.MULTIPLE && config.selectBoxStyle == SelectBoxStyle.NUMBER\n        val selectType = if (isNumber) R.drawable.picture_selector else R.drawable.checkbox_selector\n        val isDark = config.theme == Theme.DARK\n\n        val backgroundDark = ColorPropConverter.getColor(config.backgroundDark, appContext)\n            ?: ContextCompat.getColor(\n                appContext, com.luck.picture.lib.R.color.ps_color_33\n            )\n\n        val foreground = if (isDark) Color.WHITE else Color.BLACK\n        val background = if (isDark) backgroundDark else Color.WHITE\n\n        val titleBar = TitleBarStyle()\n        val bottomBar = BottomNavBarStyle()\n        val mainStyle = SelectMainStyle()\n        val iconBack =\n            if (isDark) com.luck.picture.lib.R.drawable.ps_ic_back else com.luck.picture.lib.R.drawable.ps_ic_black_back\n\n        cropOption.setLogoColor(primaryColor ?: Color.BLACK)\n\n        // TITLE BAR\n        titleBar.titleBackgroundColor = background\n        titleBar.isAlbumTitleRelativeLeft = true\n        titleBar.titleAlbumBackgroundResource = com.luck.picture.lib.R.drawable.ps_album_bg\n        titleBar.titleDrawableRightResource = com.luck.picture.lib.R.drawable.ps_ic_grey_arrow\n        titleBar.previewTitleLeftBackResource = iconBack\n        titleBar.titleLeftBackResource = iconBack\n        titleBar.isHideCancelButton = true\n\n        // BOTTOM BAR\n        bottomBar.bottomPreviewNormalTextColor = foreground\n        bottomBar.bottomPreviewSelectTextColor = foreground\n        bottomBar.bottomNarBarBackgroundColor = background\n        bottomBar.bottomEditorTextColor = foreground\n        bottomBar.bottomOriginalTextColor = foreground\n        bottomBar.bottomPreviewNarBarBackgroundColor = background\n\n        mainStyle.mainListBackgroundColor = foreground\n        mainStyle.selectNormalTextColor = foreground\n        mainStyle.isDarkStatusBarBlack = !isDark\n        mainStyle.statusBarColor = background\n        mainStyle.mainListBackgroundColor = background\n        mainStyle.adapterPreviewGalleryItemSize = DensityUtil.dip2px(appContext, 52f);\n        mainStyle.adapterPreviewGalleryBackgroundResource =\n            if (isDark) com.luck.picture.lib.R.drawable.ps_preview_gallery_bg else R.drawable.preview_gallery_white_bg\n        mainStyle.adapterPreviewGalleryFrameResource = R.drawable.preview_gallery_item\n        mainStyle.previewBackgroundColor = background\n\n        bottomBar.isCompleteCountTips = false\n        bottomBar.bottomOriginalTextSize = Constant.TOOLBAR_TEXT_SIZE\n        bottomBar.bottomSelectNumTextSize = Constant.TOOLBAR_TEXT_SIZE\n//        bottomBar.bottomPreviewNormalTextSize = Constant.TOOLBAR_TEXT_SIZE\n//        bottomBar.bottomEditorTextSize = Constant.TOOLBAR_TEXT_SIZE\n\n        // MAIN STYLE\n        mainStyle.isCompleteSelectRelativeTop = false\n        mainStyle.isPreviewDisplaySelectGallery = true\n        mainStyle.isAdapterItemIncludeEdge = true\n        mainStyle.isPreviewSelectRelativeBottom = false\n//        mainStyle.previewSelectTextSize = Constant.TOOLBAR_TEXT_SIZE\n        mainStyle.selectTextColor = primaryColor ?: Color.BLACK\n//        mainStyle.selectTextSize = Constant.TOOLBAR_TEXT_SIZE\n        mainStyle.selectBackground = selectType\n        mainStyle.isSelectNumberStyle = isNumber\n        mainStyle.previewSelectBackground = selectType\n        mainStyle.isPreviewSelectNumberStyle = isNumber\n\n        if (config.camera != null) {\n            // hide title camera\n            mainStyle.adapterCameraText = \" \"\n        }\n\n        // custom toolbar text\n        config.text.let { text ->\n            text?.finish.let {\n                mainStyle.selectText = it\n                mainStyle.selectNormalText = it\n                mainStyle.selectText = it\n            }\n\n            text?.preview.let {\n                mainStyle.previewSelectText = it\n            }\n\n            text?.original.let {\n                bottomBar.bottomOriginalText = it\n            }\n\n            text?.edit.let {\n                bottomBar.bottomEditorText = it\n            }\n        }\n\n        // SET STYLE\n        style.titleBarStyle = titleBar\n        style.bottomBarStyle = bottomBar\n        style.selectMainStyle = mainStyle\n\n        // ANIMATION SLIDE FROM BOTTOM\n        val animationStyle = PictureWindowAnimationStyle()\n        animationStyle.setActivityEnterAnimation(com.luck.picture.lib.R.anim.ps_anim_up_in)\n        animationStyle.setActivityExitAnimation(com.luck.picture.lib.R.anim.ps_anim_down_out)\n\n        style.windowAnimationStyle = animationStyle\n    }\n\n    private fun handleSelectedAssets(config: NitroConfig) {\n        val assets = config.selectedAssets\n        val assetIds = assets.map { it.localIdentifier }.toSet()\n        dataList = dataList.filter { media ->\n            assetIds.contains(media.id.toString())\n        }.toMutableList()\n    }\n\n    private fun getResult(item: LocalMedia): PickerResult {\n\n        val type: ResultType =\n            if (item.mimeType.startsWith(\"video/\")) ResultType.VIDEO else ResultType.IMAGE\n\n        var path = item.path\n        var width: Double = item.width.toDouble()\n        var height: Double = item.height.toDouble()\n\n        val thumbnail = item.videoThumbnailPath?.let {\n            if (!it.startsWith(\"file://\")) \"file://$it\" else it\n        }\n\n        if (item.isCut) {\n            path = \"file://${item.cutPath}\"\n            width = item.cropImageWidth.toDouble()\n            height = item.cropImageHeight.toDouble()\n        }\n\n        if (!path.startsWith(\"file://\") && !path.startsWith(\"content://\") && type == ResultType.IMAGE)\n            path = \"file://$path\"\n\n        val media = PickerResult(\n            localIdentifier = item.id.toString(),\n            width,\n            height,\n            mime = item.mimeType,\n            size = item.size.toDouble(),\n            bucketId = item.bucketId.toDouble(),\n            realPath = item.realPath,\n            parentFolderName = item.parentFolderName,\n            creationDate = item.dateAddedTime.toDouble(),\n            crop = item.isCut,\n            path,\n            type,\n            fileName = item.fileName,\n            thumbnail = thumbnail,\n            duration = item.duration.toDouble()\n        )\n\n        return media\n    }\n\n    override fun getAppContext(): Context {\n        return reactApplicationContext\n    }\n\n    override fun getPictureSelectorEngine(): PictureSelectorEngine {\n        return PictureSelectorEngineImp()\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/MultipleImagePickerPackage.java",
    "content": "package com.margelo.nitro.multipleimagepicker;\n\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.facebook.react.bridge.NativeModule;\nimport com.facebook.react.bridge.ReactApplicationContext;\nimport com.facebook.react.module.model.ReactModuleInfoProvider;\nimport com.facebook.react.TurboReactPackage;\n\nimport java.util.HashMap;\n\npublic class MultipleImagePickerPackage extends TurboReactPackage {\n    @Nullable\n    @Override\n    public NativeModule getModule(@NonNull String name, @NonNull ReactApplicationContext reactContext) {\n        return null;\n    }\n\n    @Override\n    public ReactModuleInfoProvider getReactModuleInfoProvider() {\n        return HashMap::new;\n    }\n\n    static {\n        System.loadLibrary(\"MultipleImagePicker\");\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/PictureSelectorEngineImp.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.util.Log\nimport com.luck.picture.lib.basic.IBridgeLoaderFactory\nimport com.luck.picture.lib.engine.*\nimport com.luck.picture.lib.engine.CompressEngine\nimport com.luck.picture.lib.entity.LocalMedia\nimport com.luck.picture.lib.interfaces.OnInjectLayoutResourceListener\nimport com.luck.picture.lib.interfaces.OnResultCallbackListener\n\nclass PictureSelectorEngineImp : PictureSelectorEngine {\n    /**\n     * 重新创建[ImageEngine]引擎\n     *\n     * @return\n     */\n    override fun createImageLoaderEngine(): ImageEngine {\n        return GlideEngine.createGlideEngine()\n    }\n\n    /**\n     * 重新创建[CompressEngine]引擎\n     *\n     * @return\n     */\n    override fun createCompressEngine(): CompressEngine? {\n        // TODO 这种情况是内存极度不足的情况下，比如开启开发者选项中的不保留活动或后台进程限制，导致CompressEngine被回收\n        return null\n    }\n\n    /**\n     * 重新创建[CompressEngine]引擎\n     *\n     * @return\n     */\n    override fun createCompressFileEngine(): CompressFileEngine? {\n        // TODO 这种情况是内存极度不足的情况下，比如开启开发者选项中的不保留活动或后台进程限制，导致CompressFileEngine被回收\n        return null\n    }\n\n    /**\n     * 重新创建[ExtendLoaderEngine]引擎\n     *\n     * @return\n     */\n    override fun createLoaderDataEngine(): ExtendLoaderEngine? {\n        return null\n    }\n\n    override fun createVideoPlayerEngine(): VideoPlayerEngine<*>? {\n        return null\n    }\n\n    override fun onCreateLoader(): IBridgeLoaderFactory? {\n        return null\n    }\n\n    /**\n     * 重新创建[SandboxFileEngine]引擎\n     *\n     * @return\n     */\n    override fun createSandboxFileEngine(): SandboxFileEngine? {\n        return null\n    }\n\n    override fun createUriToFileTransformEngine(): UriToFileTransformEngine? {\n        return null\n    }\n\n    override fun createLayoutResourceListener(): OnInjectLayoutResourceListener? {\n        return null\n    }\n\n    override fun getResultCallbackListener(): OnResultCallbackListener<LocalMedia?> {\n        return object : OnResultCallbackListener<LocalMedia?> {\n            override fun onResult(result: ArrayList<LocalMedia?>) {\n\n                Log.i(TAG, \"onResult:\" + result.size)\n            }\n\n            override fun onCancel() {\n                Log.i(TAG, \"PictureSelector onCancel\")\n            }\n        }\n    }\n\n    companion object {\n        private val TAG = PictureSelectorEngineImp::class.java.simpleName\n    }\n}"
  },
  {
    "path": "android/src/main/java/com/margelo/nitro/multipleimagepicker/VideoThumbnailEngine.kt",
    "content": "package com.margelo.nitro.multipleimagepicker\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.request.target.CustomTarget\nimport com.bumptech.glide.request.transition.Transition\nimport com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener\nimport com.luck.picture.lib.interfaces.OnVideoThumbnailEventListener\nimport com.luck.picture.lib.utils.PictureFileUtils\nimport java.io.ByteArrayOutputStream\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.io.IOException\n\n\nclass VideoThumbnailEngine(private val targetPath: String) : OnVideoThumbnailEventListener {\n    override fun onVideoThumbnail(\n        context: Context, videoPath: String, call: OnKeyValueResultCallbackListener\n    ) {\n        Glide.with(context).asBitmap().sizeMultiplier(0.6f).load(videoPath)\n            .into(object : CustomTarget<Bitmap?>() {\n                override fun onResourceReady(\n                    resource: Bitmap, transition: Transition<in Bitmap?>?\n                ) {\n                    val stream = ByteArrayOutputStream()\n                    resource.compress(Bitmap.CompressFormat.JPEG, 60, stream)\n                    var fos: FileOutputStream? = null\n                    var result: String? = null\n                    try {\n                        val targetFile =\n                            File(targetPath, \"thumbnails_\" + System.currentTimeMillis() + \".jpg\")\n                        fos = FileOutputStream(targetFile)\n                        fos.write(stream.toByteArray())\n                        fos.flush()\n                        result = targetFile.absolutePath\n                    } catch (e: IOException) {\n                        e.printStackTrace()\n                    } finally {\n                        PictureFileUtils.close(fos)\n                        PictureFileUtils.close(stream)\n                    }\n                    call.onCallback(videoPath, result)\n                }\n\n                override fun onLoadCleared(placeholder: Drawable?) {\n                    call.onCallback(videoPath, \"\")\n                }\n            })\n    }\n}"
  },
  {
    "path": "android/src/main/res/anim/anim_modal_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:interpolator=\"@android:anim/linear_interpolator\"\n    android:shareInterpolator=\"true\">\n    <alpha\n        android:fromAlpha=\"0.2\"\n        android:toAlpha=\"1\"\n        android:duration=\"90\"/>\n\n    <scale\n        android:fromXScale=\"0.7\"\n        android:toXScale=\"1.0\"\n        android:fromYScale=\"0.7\"\n        android:toYScale=\"1.0\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:duration=\"135\"/>\n</set>"
  },
  {
    "path": "android/src/main/res/drawable/checkbox_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@drawable/picture_not_selected\" android:state_selected=\"false\" />\n    <item android:drawable=\"@drawable/ic_checkmark\" android:state_selected=\"true\" />\n</selector>\n"
  },
  {
    "path": "android/src/main/res/drawable/complete_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <solid android:color=\"@color/app_color_pri\" />\n    <corners android:radius=\"5dp\" />\n    <padding\n        android:bottom=\"5dp\"\n        android:left=\"10dp\"\n        android:right=\"10dp\"\n        android:top=\"5dp\" />\n</shape>"
  },
  {
    "path": "android/src/main/res/drawable/ic_checkmark.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n  <path\n      android:pathData=\"M12,12m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0\"\n      android:fillColor=\"@color/app_color_33\"/>\n  <path\n      android:pathData=\"M15.7936,6.5936L10.1279,14.0879L7.6847,10.9253C7.4402,10.6113 7.081,10.4072 6.6861,10.358C6.2912,10.3088 5.8928,10.4185 5.5788,10.663C5.2648,10.9075 5.0607,11.2667 5.0115,11.6617C4.9623,12.0566 5.072,12.4549 5.3165,12.7689L8.9588,17.4304C9.0999,17.609 9.2799,17.7532 9.4851,17.8519C9.6902,17.9506 9.9152,18.0012 10.1429,18C10.3718,17.9994 10.5975,17.9465 10.8028,17.8451C11.008,17.7438 11.1873,17.5968 11.327,17.4154L18.1768,8.4222C18.4193,8.1042 18.5255,7.7029 18.4721,7.3065C18.4187,6.9102 18.21,6.5513 17.892,6.3088C17.574,6.0663 17.1727,5.9601 16.7763,6.0135C16.38,6.0669 16.0211,6.2756 15.7786,6.5936H15.7936Z\"\n      android:fillColor=\"#ffffff\"/>\n</vector>\n"
  },
  {
    "path": "android/src/main/res/drawable/ic_down.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n  <path\n      android:pathData=\"M12,16a1,1 0,0 1,-0.71 -0.29l-6,-6a1,1 0,0 1,1.42 -1.42l5.29,5.3 5.29,-5.29a1,1 0,0 1,1.41 1.41l-6,6a1,1 0,0 1,-0.7 0.29z\"\n      android:fillColor=\"@color/app_color_grey\"/>\n</vector>\n"
  },
  {
    "path": "android/src/main/res/drawable/num_oval.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\"\n    android:useLevel=\"false\">\n\n    <solid android:color=\"@color/app_color_33\" />\n    <stroke\n        android:width=\"1.5dp\"\n        android:color=\"@color/app_color_white\" />\n    <size\n        android:width=\"24dp\"\n        android:height=\"24dp\" />\n</shape>"
  },
  {
    "path": "android/src/main/res/drawable/picture_not_selected.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\"\n    android:useLevel=\"false\">\n   <stroke\n        android:width=\"2dp\"\n        android:color=\"@color/app_color_9b\" />\n    <size\n        android:width=\"24dp\"\n        android:height=\"24dp\" />\n</shape>\n"
  },
  {
    "path": "android/src/main/res/drawable/picture_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector android:id=\"@+id/picture_selector\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:drawable=\"@drawable/num_oval\" android:state_selected=\"true\" />\n  <item android:drawable=\"@drawable/picture_not_selected\" android:state_selected=\"false\" />\n</selector>"
  },
  {
    "path": "android/src/main/res/drawable/preview_gallery_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <solid android:color=\"@color/ps_color_transparent\" />\n    <stroke\n        android:width=\"2dp\"\n        android:color=\"@color/app_color_white\" />\n</shape>"
  },
  {
    "path": "android/src/main/res/drawable/preview_gallery_white_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:left=\"-1dp\"\n        android:right=\"-1dp\"\n        android:top=\"-1dp\">\n        <shape android:shape=\"rectangle\">\n            <solid android:color=\"@color/app_color_white_transparent\" />\n            <padding\n                android:left=\"0dp\"\n                android:right=\"0dp\" />\n            <corners android:radius=\"0dp\" />\n        </shape>\n    </item>\n</layer-list>\n"
  },
  {
    "path": "android/src/main/res/layout/loading_dialog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/loading\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@drawable/ps_dialog_loading_bg\"\n    android:orientation=\"vertical\"\n    android:padding=\"10dp\">\n\n    <ProgressBar\n        android:layout_width=\"25dp\"\n        android:layout_height=\"25dp\"\n        android:layout_gravity=\"center_horizontal\"\n        android:indeterminateBehavior=\"repeat\"\n\n        />\n\n</LinearLayout>"
  },
  {
    "path": "android/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <color name=\"app_color_grey\">#393a3e</color>\n  <color name=\"app_color_black\">#000000</color>\n  <color name=\"app_color_f6\">#f6f6f6</color>\n  <color name=\"app_color_fa\">#fafafa</color>\n  <color name=\"app_color_divider\">#B6B6B6</color>\n  <color name=\"app_color_c51\">#f94c51</color>\n  <color name=\"app_color_green\">#43c117</color>\n  <color name=\"app_color_53575e\">#53575e</color>\n  <color name=\"app_color_transparent\">#00000000</color>\n  <color name=\"app_color_white\">#FFFFFF</color>\n  <color name=\"app_color_white_transparent\">#E0DBDBDB</color>\n  <color name=\"app_color_blue\">#7D7DFF</color>\n  <color name=\"app_color_9b\">#9b9b9b</color>\n  <color name=\"app_color_e0ff6100\">#E0FF6100</color>\n  <color name=\"app_color_red\">#FF0000</color>\n  <color name=\"app_color_pri\">#FB9300</color>\n  <color name=\"app_color_33\">#333333</color>\n  <color name=\"app_color_3310\">#0D333333</color>\n</resources>\n"
  },
  {
    "path": "android/src/main/res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"Base.Theme.NoActionBar\" parent=\"Theme.AppCompat.Light.NoActionBar\"> \n        <item name=\"android:windowOptOutEdgeToEdgeEnforcement\">true</item>\n    </style>\n\n    <style name=\"Picture.Theme.Translucent\" parent=\"Base.Theme.NoActionBar\">\n        <item name=\"android:windowBackground\">@color/ps_color_transparent</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowIsTranslucent\">true</item>\n    </style>\n\n    <style name=\"PictureThemeWindowStyle\">\n        <item name=\"android:windowEnterAnimation\">@anim/ps_anim_album_show</item>\n        <item name=\"android:windowExitAnimation\">@anim/ps_anim_album_dismiss</item>\n    </style>\n\n    <style name=\"PictureThemeDialogWindowStyle\">\n        <item name=\"android:windowEnterAnimation\">@anim/ps_anim_modal_in</item>\n        <item name=\"android:windowExitAnimation\">@anim/ps_anim_modal_out</item>\n    </style>\n\n    <style name=\"Picture.Theme.Dialog.AudioStyle\">\n        <item name=\"android:windowEnterAnimation\">@anim/ps_anim_enter</item>\n        <item name=\"android:windowExitAnimation\">@anim/ps_anim_exit</item>\n    </style>\n\n    <style name=\"Picture.Theme.AlertDialog\" parent=\"android:Theme.Dialog\">\n        <item name=\"android:windowIsFloating\">true</item>\n        <item name=\"android:windowIsTranslucent\">false</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowFullscreen\">false</item>\n        <item name=\"android:windowBackground\">@color/ps_color_transparent</item>\n        <item name=\"android:windowAnimationStyle\">@null</item>\n        <item name=\"android:backgroundDimEnabled\">false</item>\n        <item name=\"android:backgroundDimAmount\">0.4</item>\n    </style>\n\n    <style name=\"PictureThemeDialogFragmentAnim\" mce_bogus=\"1\" parent=\"android:Animation\">\n        <item name=\"android:windowEnterAnimation\">@anim/ps_anim_up_in</item>\n        <item name=\"android:windowExitAnimation\">@anim/ps_anim_down_out</item>\n    </style>\n\n    <style name=\"Picture.Theme.Dialog\" parent=\"@android:style/Theme.Dialog\">\n\n        <!-- 边框 -->\n        <item name=\"android:windowFrame\">@android:color/transparent</item>\n        <!-- 是否浮现在activity之上 -->\n        <item name=\"android:windowIsFloating\">true</item>\n        <!-- 半透明 -->\n        <item name=\"android:windowIsTranslucent\">false</item>\n        <!-- 无标题 -->\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n        <item name=\"android:windowAnimationStyle\">@android:style/Animation.Dialog</item>\n        <item name=\"android:windowSoftInputMode\">stateUnspecified|adjustPan</item>\n\n        <!-- 自己想要的背景 -->\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n    </style>\n\n</resources>"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: ['module:metro-react-native-babel-preset'],\n};\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\n\n# Misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "docs/docs/CAMERA.mdx",
    "content": "---\nid: camera\ntitle: Camera 📸\nsidebar_label: Camera 📸\nslug: /camera\n---\n\nimport ReactPlayer from 'react-player'\n\nThe camera module provides a simple interface for capturing photos and recording videos with customizable options.\n\n<ReactPlayer\n  playing\n  controls\n  width=\"100%\"\n  height=\"100%\"\n  url=\"https://github.com/user-attachments/assets/7afbc4cd-07a7-46b0-8501-9f1b3be70699\"\n/>\n\n## Usage\n\n```typescript\nimport { openCamera } from '@baronha/react-native-multiple-image-picker'\n\nconst open = async () => {\n  try {\n    const response = await openCamera({\n      mediaType: 'all',\n      cameraDevice: 'back'\n    })\n    console.log(response)\n  } catch (e) {\n    console.log(e)\n  }\n}\n```\n\n## Configuration Options\n\n### `mediaType`\nSpecifies the type of media that can be captured.\n\n```typescript\nmediaType?: 'video' | 'image' | 'all'\n```\n\n**Default:** `'all'`\n\n### `cameraDevice`\nSelects which camera to use for capture.\n\n```typescript\ncameraDevice?: 'front' | 'back'\n```\n\n**Default:** `'back'`\n\n### `videoMaximumDuration`\nSets the maximum duration for video recording in seconds.\n\n```typescript\nvideoMaximumDuration?: number\n```\n\n**Default:** No limit\n\n### `presentation`\nControls how the camera view is presented (iOS only).\n\n```typescript\npresentation?: 'fullScreenModal' | 'formSheet'\n```\n\n**Default:** `'fullScreenModal'`\n\n### `language`\nSets the interface language.\n\n```typescript\nlanguage?: Language\n```\n\n**Supported values:**\n- 🌐 `'system'`: System default\n- 🇨🇳 `'zh-Hans'`: Simplified Chinese\n- 🇹🇼 `'zh-Hant'`: Traditional Chinese\n- 🇯🇵 `'ja'`: Japanese\n- 🇰🇷 `'ko'`: Korean\n- 🇬🇧 `'en'`: English\n- 🇹🇭 `'th'`: Thai\n- 🇮🇩 `'id'`: Indonesian\n- 🇻🇳 `'vi'`: Vietnamese\n- 🇷🇺 `'ru'`: Russian\n- 🇩🇪 `'de'`: German\n- 🇫🇷 `'fr'`: French\n- 🇸🇦 `'ar'`: Arabic\n\n**Default:** `'system'`\n\n### `crop`\nEnables and configures image cropping after capture.\n\nSee details in [Crop Configuration](/config/#crop-)\n\n### `color`\n\n- **Type**: [**ColorValue**](https://reactnative.dev/docs/colors)\n- **Default**: 🟦 `#2979ff`\n- **Required**: No\n- **Platform**: iOS, Android\n\n## Result Type\n\nThe camera function returns a `CameraResult` object:\n\n```typescript\ninterface CameraResult {\n  /**\n   * Path to the captured media file\n   * - iOS: Starts with 'file://'\n   * - Android: Can start with 'file://' or 'content://'\n   */\n  path: string\n\n  /**\n   * Type of captured media\n   * - 'video': For video recordings\n   * - 'image': For photos\n   */\n  type: 'video' | 'image'\n\n  /**\n   * Width of the media in pixels\n   * For cropped images, this represents the final cropped width\n   */\n  width: number\n\n  /**\n   * Height of the media in pixels\n   * For cropped images, this represents the final cropped height\n   */\n  height: number\n\n  /**\n   * Duration of the video in seconds\n   * Only available when type is 'video'\n   * @platform ios, android\n   */\n  duration: number\n\n  /**\n   * Path to the video thumbnail image\n   * Only available when type is 'video'\n   * Format: 'file://path/to/thumbnail.jpg'\n   * @platform ios, android\n   */\n  thumbnail?: string\n\n  /**\n   * Original filename of the captured media\n   * Example: 'IMG_1234.JPG' or 'VID_5678.MP4'\n   */\n  fileName: string\n}\n```\n\n### Example Response\n\n#### Photo Capture\n```typescript\n{\n  path: 'file:///var/mobile/Containers/.../IMG_0123.JPG',\n  type: 'image',\n  width: 3024,\n  height: 4032,\n  fileName: 'IMG_0123.JPG'\n}\n```\n\n#### Video Recording\n```typescript\n{\n  path: 'file:///var/mobile/Containers/.../VID_0124.MP4',\n  type: 'video',\n  width: 1920,\n  height: 1080,\n  duration: 15.6,\n  thumbnail: 'file:///var/mobile/Containers/.../VID_0124_thumb.JPG',\n  fileName: 'VID_0124.MP4'\n}\n```\n\n### Notes\n\n- The `path` format may vary between iOS and Android. Always use the provided path as-is.\n- Video thumbnails are automatically generated and provided in the `thumbnail` property.\n- For cropped images, the `width` and `height` reflect the dimensions after cropping.\n- The `duration` property is only available for video recordings and is measured in seconds.\n- All file paths are provided with the appropriate prefix (`file://` or `content://`).\n\n## Examples\n\n### Photo Capture\n```typescript\nconst result = await openCamera({\n  mediaType: 'image',\n  cameraDevice: 'back'\n})\n```\n\n### Video Recording\n```typescript\nconst result = await openCamera({\n  mediaType: 'video',\n  videoMaximumDuration: 30,\n  cameraDevice: 'front'\n})\n```\n\n### With Cropping\n```typescript\nconst result = await openCamera({\n  mediaType: 'image',\n  crop: {\n    circle: true,\n    ratio: [\n      { title: \"Square\", width: 1, height: 1 },\n      { title: \"Portrait\", width: 3, height: 4 }\n    ]\n  }\n})\n```\n\n### Custom UI\n```typescript\nconst result = await openCamera({\n  color: '#FF6B6B',\n  language: 'en',\n  presentation: 'fullScreenModal'\n})\n```\n\n## Platform Specific Notes\n\n### iOS\n- Supports `presentation` option for modal style\n- Full support for all UI customization options\n\n### Android\n- Maximum 4 custom crop ratios\n- Some UI elements may appear differently\n\n## Required Permissions\n\n### iOS\nAdd to `Info.plist`:\n```xml\n<key>NSCameraUsageDescription</key>\n<string>Camera access is required to take photos and videos</string>\n<key>NSMicrophoneUsageDescription</key>\n<string>Microphone access is required to record videos</string>\n```\n\n### Android\nAdd to `AndroidManifest.xml`:\n```xml\n<uses-permission android:name=\"android.permission.CAMERA\" />\n<uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n```\n"
  },
  {
    "path": "docs/docs/CONFIG.mdx",
    "content": "---\nid: config\ntitle: Configuration\nsidebar_label: Configuration\nslug: /config\n---\n\n# Configuration\n\n### `selectMode`\n\nMode of selection in the picker.\n\n- **Type**: string\n- **Default**: `multiple`\n- **Required**: No\n- **Options**:\n  - `single`: Single selection mode\n  - `multiple`: Multiple selection mode\n\n### `selectedAssets`\n\nKeep previous selection in Multiple Image Picker <br/>\nSee [**Result**](/result)\n\n- **Type**: Result[]\n- **Default**: `[]`\n- **Required**: No\n\n### `allowedLimit`\n\nDisplay additional select more media when permission on `iOS` is limited.\n\n- **Type**: boolean\n- **Default**: `true`\n- **Required**: No\n- **Platform**: iOS\n\n### `allowSwipeToSelect`\n\nAllow swiping to select items.\n\n- **Type**: boolean\n- **Default**: `true`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `isHiddenOriginalButton`\n\nHide the original button.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `maxSelect`\n\nMaximum number of items that can be selected.\n\n- **Type**: number\n- **Default**: `20`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `maxVideo`\n\nMaximum number of videos allowed.\n\n- **Type**: number\n- **Default**: `20`\n- **Required**: No\n- **Platform**: iOS, Android\n\n## Camera 📸\n\nConfiguration camera functionality.\n\n- **Type**: object\n- **Default**: `{}`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `cameraDevice`\n\nCamera device to be used.\n\n- **Type**: `string`\n- **Default**: `back`\n- **Required**: No\n- **Platform**: iOS\n- **Options**:\n  - `back`: Back camera\n  - `front`: Front camera\n\n### `videoMaximumDuration`\n\nMaximum video duration in seconds.\n\n- **Type**: number\n- **Default**: 60\n- **Required**: No\n- **Platform**: iOS, Android\n\n## Crop 🪚\n\nConfiguration for image cropping functionality.\n\n- **Type**: object\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `circle`\n\nEnable circular crop mask.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `ratio`\n\nAspect ratios for cropping.\nAndroid: Maximum: 4 items\n\n- **Type**: `array`\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Properties**:\n  - `title`: string - Display title for the ratio (e.g., \"Square\", \"16:9\")\n  - `width`: number - Width value for the aspect ratio\n  - `height`: number - Height value for the aspect ratio\n\n### `defaultRatio`\n\nDefault ratio to be selected when opening the crop interface.\n\n- **Type**: `object`\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Properties**:\n  - `title`: string - Display title for the ratio (e.g., \"Square\", \"16:9\")\n  - `width`: number - Width value for the aspect ratio\n  - `height`: number - Height value for the aspect ratio\n\n### `freeStyle`\n\nEnable free style cropping.\n\n- **Type**: `boolean`\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n---\n\n## UI Customize 🌈\n\n### `theme`\n\nTheme mode for the picker.\n\n- **Type**: string\n- **Default**: `system`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Options**:\n  - `light`: Light theme\n  - `dark`: Dark theme\n  - `system`: System default theme\n\n### `primaryColor`\n\nPrimary color for the picker UI elements.\n\n- **Type**: [**ColorValue**](https://reactnative.dev/docs/colors)\n- **Default**: 🟦 `#2979ff`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `backgroundDark`\n\nBackground color for dark mode UI elements.\n\n- **Type**: [**ColorValue**](https://reactnative.dev/docs/colors)\n- **Default**: ⚫️ `#1A1A1A`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `selectBoxStyle`\n\nStyle of selection box in the picker.\n\n- **Type**: string\n- **Default**: `number`\n- **Required**: No\n- **Options**:\n  - `number`: Show numbers in selection box\n  - `tick`: Show checkmark in selection box\n\n### `spacing`\n\nSpacing between items in the grid.\n\n- **Type**: number\n- **Default**: `2`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `numberOfColumn`\n\nNumber of columns in the grid view.\n\n- **Type**: number\n- **Default**: `4`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `presentation`\n\nModal presentation style for the picker.\n\n- **Type**: string\n- **Default**: `fullScreenModal`\n- **Required**: No\n- **Platform**: iOS\n- **Options**:\n  - `fullScreenModal`: Full screen presentation\n  - `formSheet`: Form sheet presentation\n\n---\n\n## Filter data 🎞️\n\n### `mediaType`\n\nType of media to be displayed in the picker.\n\n- **Type**: string\n- **Default**: `all`\n- **Required**: No\n- **Options**:\n  - `video`: Only show videos\n  - `image`: Only show images\n  - `all`: Show both videos and images\n\n### `maxVideoDuration`\n\nMaximum duration for videos in seconds.\n\n- **Type**: number\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `minVideoDuration`\n\nMinimum duration for videos in seconds.\n\n- **Type**: number\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `maxFileSize`\n\nMaximum file size in bytes.\n\n- **Type**: number\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n\n---\n\n## Preview 🌠\n\n### `isPreview`\n\nEnable preview functionality.\n\n- **Type**: boolean\n- **Default**: `true`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `isShowPreviewList`\n\nShow preview list.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS\n\n### `isHiddenPreviewButton`\n\nHide the preview button and button mode.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `allowHapticTouchPreview`\n\nEnable haptic feedback on preview.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS\n\n---\n\n## Localization 🌐\n\n### `text`\n\nCustom text labels for buttons and headers.\n\n- **Type**: object\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Properties**:\n  - `finish`: string - Text for finish/done button\n  - `original`: string - Text for original button\n  - `preview`: string - Text for preview button\n  - `edit`: string - Text for edit button\n\n### `language`\n\nInterface language for the picker.\n\n- **Type**: string\n- **Default**: `system`\n- **Required**: No\n- **Options**:\n\n  - `system`: 🌐 System default\n  - `zh-Hans`: 🇨🇳 Simplified Chinese\n  - `zh-Hant`: 🇹🇼 Traditional Chinese\n  - `ja`: 🇯🇵 Japanese\n  - `ko`: 🇰🇷 Korean\n  - `en`: 🇬🇧 English\n  - `vi`: 🇻🇳 Vietnamese\n  - `ru`: 🇷🇺 Russian\n  - `de`: 🇩🇪 German\n  - `fr`: 🇫🇷 French\n  - `ar`: 🇸🇦 Arabic\n\n  **iOS Only**:\n\n  - `id`: 🇮🇩 Indonesian\n  - `th`: 🇹🇭 Thai\n"
  },
  {
    "path": "docs/docs/CROP.mdx",
    "content": "---\nid: crop\ntitle: Crop 🍕\nsidebar_label: Crop 🍕\nslug: /crop\n---\n\n## Usage\n\n```typescript\nimport { openCropper } from '@baronha/react-native-multiple-image-picker'\n\nconst cropConfig: CropConfig = {\n  // ...\n}\n\nconst open = async () => {\n  try {\n    const response = await openCropper('file://path/to/image.jpg', cropConfig)\n    setImages(response)\n  } catch (e) {\n    // catch error for multiple image picker\n  }\n}\n```\n\n## CropConfig\n\n### `circle`\n\nEnable circular crop mask.\n\n- **Type**: boolean\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `ratio`\n\nAspect ratios for cropping.\nAndroid: Maximum: 4 items\n\n- **Type**: `array`\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Properties**:\n  - `title`: string - Display title for the ratio (e.g., \"Square\", \"16:9\")\n  - `width`: number - Width value for the aspect ratio\n  - `height`: number - Height value for the aspect ratio\n\n### `defaultRatio`\n\nDefault ratio to be selected when opening the crop interface.\n\n- **Type**: `object`\n- **Default**: `undefined`\n- **Required**: No\n- **Platform**: iOS, Android\n- **Properties**:\n  - `title`: string - Display title for the ratio (e.g., \"Square\", \"16:9\")\n  - `width`: number - Width value for the aspect ratio\n  - `height`: number - Height value for the aspect ratio\n\n### `freeStyle`\n\nEnable free style cropping.\n\n- **Type**: `boolean`\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS, Android\n\n### `language`\n\n- **Type**: `string`\n- **Default**: `false`\n- **Required**: No\n- **Platform**: iOS\n\nSee [**Language**](/config/#language)\n\n## Result\n\n### `path`\n\n- **Type**: `string`\n\n### `width`\n\n- **Type**: `number`\n\n### `height`\n\n- **Type**: `number`\n"
  },
  {
    "path": "docs/docs/GETTING_STARTED.mdx",
    "content": "---\nid: getting-started\ntitle: Getting Started\nsidebar_label: Getting Started\nsidebar_id: getting-started\nslug: /getting-started\n---\n\nimport Tabs from '@theme/Tabs'\nimport TabItem from '@theme/TabItem'\nimport useBaseUrl from '@docusaurus/useBaseUrl'\n\n## Requirements\n\nBecause RNMIP uses Nitro Module, it complies with Nitro Modules' requirements.<br />\nView Nitro Modules' requirements [here](https://nitro.margelo.com/docs/minimum-requirements)\n\n<Tabs groupId=\"platform\">\n  <TabItem value=\"ios\" label=\"iOS\" default>\n    - `iOS` 13+\n\n    - `react-native` 0.75+\n\n    - `Xcode` 16+\n\n  </TabItem>\n  <TabItem value=\"android\" label=\"Android\">\n    - `react-native` 0.75+\n\n    - `compileSdkVersion` 34+\n\n  </TabItem>\n</Tabs>\n\n## Installing\n\nInstall [@baronha/react-native-multiple-image-picker](https://www.npmjs.com/package/@baronha/react-native-multiple-image-picker) through npm:\n\n> This package requires `react-native-nitro-modules` to be installed first.\n> See [react-native-nitro-modules](https://github.com/mrousavy/nitro) for more information.\n\n<Tabs\n  groupId=\"environment\"\n  defaultValue=\"rn\"\n  values={[\n    {label: 'React Native', value: 'rn'},\n    {label: 'Expo', value: 'expo'}\n  ]}>\n<TabItem value=\"rn\">\n\n```bash\nyarn add @baronha/react-native-multiple-image-picker\nyarn add -D react-native-nitro-modules\ncd ios && pod install\n```\n\n</TabItem>\n\n<TabItem value=\"expo\">\n\n```bash\nnpx expo install @baronha/react-native-multiple-image-picker \nnpx expo install react-native-nitro-modules -- --dev\nnpx expo prebuild\n```\n\n</TabItem>\n</Tabs>\n\n## Updating manifests\n\n<Tabs\n  groupId=\"environment\"\n  defaultValue=\"rn\"\n  values={[\n    {label: 'React Native', value: 'rn'},\n    {label: 'Expo', value: 'expo'}\n  ]}>\n<TabItem value=\"rn\">\n\n### Info.plist\n\nOpen your project's `Info.plist` and add the following lines inside the outermost `<dict>` tag:\n\n```xml\n<key>NSPhotoLibraryAddUsageDescription</key>\n<string>$(PRODUCT_NAME) needs photo library permissions</string>\n<key>NSPhotoLibraryUsageDescription</key>\n<string>$(PRODUCT_NAME) needs photo library permissions</string>\n<!--  if you allow camera, you need to add this:-->\n<key>NSCameraUsageDescription</key>\n<string>$(PRODUCT_NAME) needs to access your Camera</string>\n<key>NSMicrophoneUsageDescription</key>\n<string>$(PRODUCT_NAME) needs to access your microphone so that you can record audio.</string>\n```\n\n</TabItem>\n<TabItem value=\"expo\">\n\n### Managed Expo\n\nConfig your Expo app (`app.json`, `app.config.json` or `app.config.js`):\n\n```json\n{\n  \"name\": \"my app\",\n  \"ios\": {\n    // ...\n    \"infoPlist\": {\n      \"NSPhotoLibraryAddUsageDescription\": \"$(PRODUCT_NAME) needs photo library permissions\",\n      \"NSPhotoLibraryUsageDescription\": \"$(PRODUCT_NAME) needs photo library permissions\",\n      // if you allow camera, you need to add this\n      \"NSCameraUsageDescription\": \"$(PRODUCT_NAME) needs to access your Camera\",\n      \"NSMicrophoneUsageDescription\": \"$(PRODUCT_NAME) needs to access your microphone so that you can record audio\"\n    }\n    // ...\n  }\n}\n```\n\nFinally, compile the mods:\n\n```bash\nnpx expo prebuild\n```\n\nTo apply the changes, build a new binary with EAS:\n\n```bash\neas build\n```\n\n</TabItem>\n</Tabs>\n\n<br />\n\n#### 🎉 Hooray! You're ready to learn about [Usage](/usage)!\n\n---\n"
  },
  {
    "path": "docs/docs/PREVIEW.mdx",
    "content": "---\nid: preview\ntitle: Preview 🎑\nsidebar_label: Preview 🎑\nslug: /preview\n---\n\nimport ReactPlayer from 'react-player'\n\n## Overview\n\nPreview is a simple image viewer that supports both local and remote media. It allows you to preview images and videos seamlessly.\n\n<ReactPlayer\n  playing\n  controls\n  width=\"100%\"\n  height=\"100%\"\n  url=\"https://github.com/user-attachments/assets/92a1c319-ad99-4d24-892c-7cd878787acd\"\n/>\n\n## Usage\n\n```typescript\nimport {\n  openPreview,\n  PreviewConfig,\n} from '@baronha/react-native-multiple-image-picker'\n\nconst previewConfig: PreviewConfig = {\n  language: 'system',\n}\n\nconst media: MediaPreview[] = [\n  // remote image\n  {\n    path: 'https://images.unsplash.com/photo-1733235015085-fc29c17c4a16?w=500',\n    type: 'image',\n  },\n  // local video\n  {\n    path: 'file://Documents/video-sample/mp4',\n    thumbnail:\n      'https://images.unsplash.com/photo-1733889886752-f4599c954608?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\n    type: 'video',\n  },\n  // remote video\n  {\n    path: 'https://cdn.pixabay.com/video/2024/02/09/199958-911694865_large.mp4',\n    type: 'video',\n  },\n]\n\n// call to preview\nopenPreview(media, 2, previewConfig)\n```\n\n## `MediaPreview[]`\n\n`MediaPreview[]` is an array of media objects that you want to preview. Each object in the array should have the following properties:<br/>\n\n**NOTE**: You can also use [`Result[]`](/result) from openPicker's return result\n\n- `path`: A string representing the URL or file path of the media.\n- `type`: A string indicating the type of media, either `image` or `video`.\n- `thumbnail` (optional): A string representing the URL of the thumbnail image for videos.\n- `localIdentifier` (optional): A string representing the local identifier for media from device gallery.\n\n## `index`\n\ndefault: `0`\n\nThe `index` parameter in the `openPreview` function specifies the initial media item to display. It is a zero-based index, meaning that `0` will display the first item in the `MediaPreview` array.\n\n## `previewConfig`\n\n### [`language`](/config/#language)\n\nsee [`language`](/config/#language)\n\n### `onLongPress`\n\n`onLongPress` is a callback function that is called when a long press is detected on the media item. It is a function that takes an index as an argument and returns void.\n\n```typescript\nonLongPress: (index: number) => void\n```\n\n## Additional Information\n\n- Ensure that the media paths are accessible and correctly formatted.\n- The `openPreview` function is part of the `@baronha/react-native-multiple-image-picker` package, which should be installed and properly configured in your project.\n\nFor more detailed information, refer to the [official documentation](https://github.com/baronha/react-native-multiple-image-picker).\n"
  },
  {
    "path": "docs/docs/RESULT.mdx",
    "content": "---\nid: result\ntitle: Result\nsidebar_label: Result\nslug: /result\n---\n\nThe result object returned for each selected media item.\n\n### `path`\n\n- **Type**: string\n- **Description**: Local file path of the media\n\n### `fileName`\n\n- **Type**: string\n- **Description**: Name of the media file\n\n### `localIdentifier`\n\n- **Type**: string\n- **Description**: Unique identifier for the media asset\n\n### `width`\n\n- **Type**: number\n- **Description**: Width of the media in pixels\n\n### `height`\n\n- **Type**: number\n- **Description**: Height of the media in pixels\n\n### `mime`\n\n- **Type**: string\n- **Description**: MIME type of the media file\n\n### `size`\n\n- **Type**: number\n- **Description**: File size in bytes\n\n### `bucketId`\n\n- **Type**: number\n- **Description**: ID of the bucket containing the media\n- **Platform**: Android\n\n### `realPath`\n\n- **Type**: string\n- **Description**: Actual file path in the device storage\n- **Platform**: Android\n\n### `parentFolderName`\n\n- **Type**: string\n- **Description**: Name of the parent folder\n- **Platform**: Android\n\n### `creationDate`\n\n- **Type**: number\n- **Description**: Creation timestamp of the media\n\n### `type`\n\n- **Type**: string\n- **Options**: `image` | `video`\n- **Description**: Type of the media file\n\n### `duration`\n\n- **Type**: number\n- **Description**: Duration in seconds (for video files)\n\n### `thumbnail`\n\n- **Type**: string\n- **Description**: Thumbnail path for video files\n\n### `crop`\n\n- **Type**: boolean\n- **Description**: Indicates if the media has been cropped\n"
  },
  {
    "path": "docs/docs/SHOWCASE/index.mdx",
    "content": "---\nid: showcase\ntitle: Showcase ✨\nsidebar_label: Showcase ✨\nslug: /showcase\n---\n\nimport style from './showcase.css'\nimport data from './showcase.json'\n\nList of used applications with `@baronha/react-native-multiple-image-picker`\n\n> Contributions are welcome! If you have an application that uses `@baronha/react-native-multiple-image-picker`<br/>\n> please open a [**Pull Request**](https://github.com/baronha/react-native-multiple-image-picker/tree/master/docs/docs/SHOWCASE/showcase.json) to add it to the list.\n\n<br />\n\n<div className=\"showcaseContainer\">\n  {data.map((item, index) => {\n    return (\n      <a\n        key={`showcase-${index}`}\n        href={item.link}\n        target=\"_blank\"\n        className=\"showcaseItem\"\n      >\n        <img src={item.banner} alt={item.title} className=\"showcaseBanner\" />\n        <b>{item.title}</b>\n        <p className=\"showcaseTagline\">{item?.tagline}</p>\n      </a>\n    )\n  })}\n</div>\n"
  },
  {
    "path": "docs/docs/SHOWCASE/showcase.css",
    "content": ".showcaseContainer {\n  display: flex;\n  /* justify-content: space-between; */\n  flex-wrap: wrap;\n  gap: 20px;\n}\n\n.showcaseItem {\n  flex: 1;\n  color: inherit;\n  text-decoration: none;\n}\n\n.showcaseItem a:hover {\n  color: red;\n  text-decoration: none !important;\n}\n\n.showcaseItem b {\n  font-size: 1rem;\n}\n\n.showcaseItem .showcaseTagline {\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  margin: 0;\n}\n\n.showcaseBanner {\n  width: 100%;\n  aspect-ratio: 16/9;\n  object-fit: cover;\n}\n\n@media (max-width: 768px) {\n  .showcaseItem {\n    flex: 100%;\n    margin-right: 0;\n  }\n}\n\n@media (min-width: 992px) {\n  /* lg */\n  .showcaseItem {\n    max-width: 33.333%;\n  }\n}\n\n@media (min-width: 1200px) {\n  /* xl */\n  .showcaseItem {\n    max-width: 33.333%;\n  }\n}\n\n@media (min-width: 1400px) {\n  /* xxl */\n  .showcaseItem {\n    max-width: 33.333%;\n  }\n}\n\n@media (max-width: 480px) {\n  .showcaseItem {\n    flex: 100%;\n  }\n}\n"
  },
  {
    "path": "docs/docs/SHOWCASE/showcase.json",
    "content": "[\n  {\n    \"banner\": \"https://github.com/user-attachments/assets/84ec6432-1557-4649-965c-6100d9c4c12d\",\n    \"title\": \"✨ Binsoo - Photo Filters & Editor\",\n    \"link\": \"https://apps.apple.com/vn/app/binsoo-photo-filters-editor/id6502683720\",\n    \"tagline\": \"Endless aesthetics and effects\"\n  },\n  {\n    \"banner\": \"https://github.com/user-attachments/assets/72a7787a-4a41-40e3-b6bb-a5c7b0eafc83\",\n    \"title\": \"Pupi\",\n    \"link\": \"https://apps.apple.com/vn/app/pupi-h%E1%BB%8Dc-vui-ti%E1%BA%BFn-b%E1%BB%99/id1638474798\",\n    \"tagline\": \"Học vui & tiến b‪ộ\"\n  },\n  {\n    \"banner\": \"https://github.com/user-attachments/assets/dd92d243-7fb0-40ff-9b78-7b4fd2a54092\",\n    \"title\": \"Pety\",\n    \"link\": \"https://apps.apple.com/vn/app/pety/id1506375124\",\n    \"tagline\": \"New Lifestyle for Pet Lovers\"\n  }\n]\n"
  },
  {
    "path": "docs/docs/USAGE.mdx",
    "content": "---\nid: usage\ntitle: Usage\nsidebar_label: Usage\nslug: /usage\n---\n\nHere is a simple usage of the Multiple Image Picker. <br/>\nSee more [**Config**](/config)\n\n```typescript\nimport { openPicker, Config } from '@baronha/react-native-multiple-image-picker'\n\nconst config: Config = {\n  maxSelect: 10,\n  maxVideo: 10,\n  primaryColor: '#FB9300',\n  backgroundDark: '#2f2f2f',\n  numberOfColumn: 4,\n  mediaType: 'all',\n  selectBoxStyle: 'number',\n  selectMode: 'multiple',\n  language: 'vi', // 🇻🇳 Vietnamese\n  theme: 'dark',\n  isHiddenOriginalButton: false,\n  primaryColor: '#F6B35D',\n}\n\nconst onPicker = async () => {\n  try {\n    const response = await openPicker(config)\n    setImages(response)\n  } catch (e) {\n    // catch error for multiple image picker\n  }\n}\n```\n"
  },
  {
    "path": "docs/docs/index.md",
    "content": "---\nid: index\ntitle: Multiple Image Picker | BAO HA\nhide_title: true\nsidebar_label: Multiple Image Picker\ndescription: 🏞 react-native-multiple-image-picker enables applications to pick images and videos from multiple smart albums in iOS/Android\nimage: img/banner.png\nslug: /\n---\n\nimport ReactPlayer from 'react-player'\n\n![Logo][Logo]\n\n<img src=\"img/banner.png\" width=\"100%\" />\n\n[![iOS][iOS]][iOS-URL] [![Android][Android]][Android-URL] [![Swift][Swift]][Swift-URL] [![Kotlin][Kotlin]][Kotlin-URL] [![React-Native][React-Native]][React-Native-URL]\n\n## Overview 🎇\n\n<ReactPlayer playing controls width=\"100%\" height=\"100%\" url='https://github.com/user-attachments/assets/79580bc7-237c-46b7-b92e-1479cc6d9079' />\n\nReact Native Multiple Image Picker **(RNMIP)** enables application to pick images and videos from multiple smart album in iOS/Android. React Native Multiple Image Picker is based on two libraries available, [HXPhotoPicker](https://github.com/SilenceLove/HXPhotoPicker) and [PictureSelector](https://github.com/LuckSiege/PictureSelector)\n\n## Features 🔥\n\n| 🤩  | ![Logo][Logo]                                                                  |\n| --- | ------------------------------------------------------------------------------ |\n| 🍕  | [**Crop**](/crop) single/multiple image.                            |\n| 🎑  | [**Preview**](/preview) image/video.                                |\n| 📸  | [**Camera**](/camera) module for capturing photos and recording videos. |\n| 🐳  | Keep the previous selection.                                                   |\n| 0️⃣  | Selected order index.                                                          |\n| 🎨  | UI Customization (numberOfColumn, spacing, primaryColor ... )                  |\n| 🌚  | Dark Mode, Light Mode                                                          |\n| 🌄  | Choose multiple images/video.                                                  |\n| 📦  | Support smart album `(camera roll, selfies, panoramas, favorites, videos...)`. |\n| 📺  | Display video duration.                                                        |\n| ⛅️ | Support iCloud Photo Library.                                                  |\n| 🌪  | Scrolling performance. ☕️                                                      |\n\n## Sponsor & Support ☕️\n\nTo keep this library maintained and up-to-date please consider [sponsoring it on GitHub](https://github.com/sponsors/baronha). Or if you are looking for a private support or help in customizing the experience, then reach out to me on Twitter [@\\_baronha](https://twitter.com/_baronha).\n\n## Built With ❤️\n\n[![NitroModules](https://img.shields.io/badge/Nitro_Modules-0052CC?style=for-the-badge)](https://nitro.margelo.com/docs/nitro-modules)\n\n[![HXPhotoPicker](https://img.shields.io/badge/HXPhotoPicker-F05138?style=for-the-badge)](https://github.com/SilenceLove/HXPhotoPicker)\n\n[![PictureSelector](https://img.shields.io/badge/Picture_Selector-b07219?style=for-the-badge)](https://github.com/LuckSiege/PictureSelector)\n\n<!-- Badge for README -->\n\n[iOS]: https://img.shields.io/badge/iOS-000000?style=for-the-badge&logo=ios&logoColor=white\n[iOS-URL]: https://www.apple.com/ios\n[Android]: https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white\n[Android-URL]: https://www.android.com/\n[React-Native]: https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB\n[React-Native-URL]: https://reactnative.dev/\n[React-Native]: https://img.shields.io/badge/React_Native-20232A?style=for-the-badge&logo=react&logoColor=61DAFB\n[React-Native-URL]: https://reactnative.dev/\n[Swift]: https://img.shields.io/badge/Swift-FA7343?style=for-the-badge&logo=swift&logoColor=white\n[Swift-URL]: https://developer.apple.com/swift/\n[Kotlin]: https://img.shields.io/badge/Kotlin-0095D5?&style=for-the-badge&logo=kotlin&logoColor=white\n[Kotlin-URL]: https://kotlinlang.org/\n[Logo]: https://img.shields.io/badge/React_Native_Multiple_Image_Picker-DF78C3?style=for-the-badge\n"
  },
  {
    "path": "docs/docusaurus.config.ts",
    "content": "import { themes as prismThemes } from 'prism-react-renderer'\nimport type { Config } from '@docusaurus/types'\nimport type * as Preset from '@docusaurus/preset-classic'\n\n// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)\n\nconst config: Config = {\n  title: 'React Native Multiple Image Picker',\n  tagline: 'High-performance React Native Multiple Image Picker library.',\n  favicon: 'img/favicon.ico',\n\n  // Set the production url of your site here\n  url: 'https://nitrogenzlab.github.io',\n\n  // Set the /<baseUrl>/ pathname under which your site is served\n  // For GitHub pages deployment, it is often '/<projectName>/'\n  baseUrl: '/react-native-multiple-image-picker',\n\n  // GitHub pages deployment config.\n  // If you aren't using GitHub pages, you don't need these.\n  organizationName: 'baronha', // Usually your GitHub org/user name.\n  projectName: 'react-native-multiple-image-picker', // Usually your repo name.\n  trailingSlash: false,\n\n  onBrokenLinks: 'throw',\n  onBrokenMarkdownLinks: 'warn',\n\n  // Even if you don't use internationalization, you can use this field to set\n  // useful metadata like html lang. For example, if your site is Chinese, you\n  // may want to replace \"en\" with \"zh-Hans\".\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en', 'vi'],\n    path: 'i18n',\n    localeConfigs: {\n      en: {\n        label: 'English',\n        direction: 'ltr',\n        htmlLang: 'en-US',\n        calendar: 'gregory',\n        path: 'en',\n      },\n    },\n  },\n\n  presets: [\n    [\n      '@gorhom/docusaurus-preset',\n      {\n        docs: {\n          sidebarPath: './sidebars.ts',\n          routeBasePath: '/',\n          editUrl:\n            'https://github.com/NitrogenZLab/react-native-multiple-image-picker/tree/main/docs/docs',\n          lastVersion: 'current',\n          versions: {\n            current: {\n              label: 'v2.0',\n            },\n          },\n        },\n        theme: {\n          customCss: './src/css/custom.css',\n        },\n      } satisfies Preset.Options,\n    ],\n  ],\n\n  themeConfig: {\n    // Replace with your project's social card\n    image: 'img/banner.png',\n\n    colorMode: {\n      defaultMode: 'dark',\n      disableSwitch: false,\n      respectPrefersColorScheme: true,\n    },\n\n    navbar: {\n      title: 'RNMIP',\n      logo: {\n        alt: 'RNMIP Logo',\n        src: 'img/RNMIP.png',\n      },\n      items: [\n        {\n          type: 'docSidebar',\n          sidebarId: 'multiple-image-picker',\n          position: 'left',\n          label: 'Guides',\n        },\n        {\n          href: 'https://github.com/NitrogenZLab/react-native-multiple-image-picker/tree/main/example',\n          label: 'Example',\n          position: 'left',\n        },\n        {\n          href: '/showcase',\n          label: 'Showcase',\n          position: 'left',\n        },\n        {\n          href: 'https://github.com/NitrogenZLab/react-native-multiple-image-picker',\n          label: 'GitHub',\n          position: 'right',\n        },\n\n        {\n          href: 'https://apps.apple.com/vn/app/binsoo-photo-filters-editor/id6502683720',\n          label: '✨ Binsoo - Photo Editor',\n          position: 'right',\n        },\n      ],\n    },\n\n    footer: {\n      style: 'dark',\n      links: [\n        {\n          title: 'Guides',\n          items: [\n            {\n              label: 'Getting Started',\n              to: '/getting-started',\n            },\n            {\n              label: 'Config',\n              to: '/config',\n            },\n            {\n              label: 'Result',\n              to: '/result',\n            },\n            {\n              label: '☕️ Buy me a coffee',\n              href: 'https://github.com/sponsors/baronha',\n            },\n          ],\n        },\n        {\n          title: 'Community',\n          items: [\n            {\n              label: 'X',\n              href: 'https://x.com/_baronha',\n            },\n            {\n              label: 'Threads',\n              href: 'https://www.threads.net/@___donquijote',\n            },\n          ],\n        },\n        {\n          title: 'More',\n          items: [\n            {\n              label: 'Github',\n              href: 'https://github.com/baronha',\n            },\n            {\n              label: 'Binsoo - Photo Editor',\n              href: 'https://apps.apple.com/vn/app/binsoo-photo-filters-editor/id6502683720',\n            },\n          ],\n        },\n      ],\n      copyright: `Copyright © ${new Date().getFullYear()} Bảo Hà (baronha)`,\n    },\n\n    prism: {\n      theme: prismThemes.github,\n      darkTheme: prismThemes.dracula,\n    },\n  } satisfies Preset.ThemeConfig,\n}\n\nexport default config\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"name\": \"docs\",\n  \"version\": \"2.2.6\",\n  \"private\": true,\n  \"scripts\": {\n    \"docusaurus\": \"docusaurus\",\n    \"start\": \"docusaurus start\",\n    \"build\": \"docusaurus build\",\n    \"swizzle\": \"docusaurus swizzle\",\n    \"deploy\": \"docusaurus deploy\",\n    \"clear\": \"docusaurus clear\",\n    \"serve\": \"docusaurus serve\",\n    \"write-translations\": \"docusaurus write-translations\",\n    \"write-heading-ids\": \"docusaurus write-heading-ids\",\n    \"typecheck\": \"tsc\",\n    \"postinstall\": \"patch-package\"\n  },\n  \"dependencies\": {\n    \"@docusaurus/core\": \"3.5.2\",\n    \"@docusaurus/plugin-google-gtag\": \"^3.5.2\",\n    \"@docusaurus/preset-classic\": \"3.5.2\",\n    \"@gorhom/docusaurus-preset\": \"*\",\n    \"@gorhom/docusaurus-theme\": \"*\",\n    \"@mdx-js/react\": \"^3.0.0\",\n    \"clsx\": \"^2.0.0\",\n    \"prism-react-renderer\": \"^2.3.0\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\",\n    \"react-player\": \"^2.16.0\"\n  },\n  \"devDependencies\": {\n    \"@docusaurus/module-type-aliases\": \"3.5.2\",\n    \"@docusaurus/tsconfig\": \"3.5.2\",\n    \"@docusaurus/types\": \"3.5.2\",\n    \"patch-package\": \"^8.0.0\",\n    \"typescript\": \"~5.6.2\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.5%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 3 chrome version\",\n      \"last 3 firefox version\",\n      \"last 5 safari version\"\n    ]\n  },\n  \"engines\": {\n    \"node\": \">=18.0\"\n  }\n}\n"
  },
  {
    "path": "docs/patches/@gorhom+docusaurus-preset+1.0.2.patch",
    "content": "diff --git a/node_modules/@gorhom/docusaurus-preset/lib/index.js b/node_modules/@gorhom/docusaurus-preset/lib/index.js\nindex 66e815e..7ab6b15 100644\n--- a/node_modules/@gorhom/docusaurus-preset/lib/index.js\n+++ b/node_modules/@gorhom/docusaurus-preset/lib/index.js\n@@ -23,21 +23,21 @@ export default function preset(context, opts = {}) {\n         theme: prismThemes.github,\n         darkTheme: prismThemes.dracula,\n     };\n-    // overrides footer\n-    themeConfig.footer = {\n-        ...(themeConfig.footer ?? {}),\n-        copyright: `Open Source by <a rel=\"noreferrer\" href=\"https://gorhom.dev/\" target=\"_blank\">Mo Gorhom</a>.`,\n-        links: [\n-            {\n-                label: \"Github\",\n-                href: \"https://github.com/gorhom\",\n-            },\n-            {\n-                label: \"X (Twitter)\",\n-                href: \"https://twitter.com/gorhom\",\n-            },\n-        ]\n-    };\n+    \t// overrides footer\n+\tthemeConfig.footer = {\n+\t\t\n+\t\tcopyright: `Open Source by <a rel=\"noreferrer\" href=\"https://baoha.vercel.app/\" target=\"_blank\">Bao Ha</a>.`,\n+\t\tlinks: [\n+\t\t\t{\n+\t\t\t\tlabel: \"Github\",\n+\t\t\t\thref: \"https://github.com/baronha\",\n+\t\t\t},\n+\t\t\t{\n+\t\t\t\tlabel: \"X (Twitter)\",\n+\t\t\t\thref: \"https://twitter.com/_baronha\",\n+\t\t\t},\n+\t\t],\n+\t}\n     const themes = [];\n     themes.push(makePluginConfig(\"@gorhom/docusaurus-theme\", theme));\n     if (algolia) {\n"
  },
  {
    "path": "docs/sidebars.ts",
    "content": "import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'\n\n// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)\n\n/**\n * Creating a sidebar enables you to:\n - create an ordered group of docs\n - render a sidebar for each doc of that group\n - provide next/previous navigation\n\n The sidebars can be generated from the filesystem, or explicitly defined here.\n\n Create as many sidebars as you want.\n */\nconst sidebars: SidebarsConfig = {\n  'multiple-image-picker': [\n    {\n      type: 'category',\n      label: 'RNMIP',\n      link: {\n        type: 'doc',\n        id: 'index',\n      },\n      items: ['getting-started', 'usage', 'config', 'result'],\n    },\n    'crop',\n    'preview',\n    'camera',\n  ],\n}\n\nexport default sidebars\n"
  },
  {
    "path": "docs/src/css/custom.css",
    "content": ""
  },
  {
    "path": "docs/static/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/tsconfig.json",
    "content": "{\n  // This file is not used in compilation. It is here just for a nice editor experience.\n  \"extends\": \"@docusaurus/tsconfig\",\n  \"compilerOptions\": {\n    \"baseUrl\": \".\"\n  },\n  \"exclude\": [\".docusaurus\", \"build\"]\n}\n"
  },
  {
    "path": "example/.gitignore",
    "content": "# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files\n\n# dependencies\nnode_modules/\n\n# Expo\n.expo/\ndist/\nweb-build/\n\n# Native\n*.orig.*\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n\n# Metro\n.metro-health-check*\n\n# debug\nnpm-debug.*\nyarn-debug.*\nyarn-error.*\n\n# macOS\n.DS_Store\n*.pem\n\n# local env files\n.env*.local\n\n# typescript\n*.tsbuildinfo\n\n/ios\n/android"
  },
  {
    "path": "example/App.tsx",
    "content": "import { LogBox, UIManager } from 'react-native'\nimport App from './src'\n\nLogBox.ignoreAllLogs()\n\nUIManager.setLayoutAnimationEnabledExperimental &&\n  UIManager.setLayoutAnimationEnabledExperimental(true)\n\nexport default App\n"
  },
  {
    "path": "example/Gemfile",
    "content": "source 'https://rubygems.org'\n\n# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version\nruby \">= 3.0.0\"\n\n# Exclude problematic versions of cocoapods and activesupport that causes build failures.\ngem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'\ngem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'"
  },
  {
    "path": "example/README.md",
    "content": "# Example\n\nThis website is built using [Expo](https://docs.expo.dev/)\n\nhttps://github.com/user-attachments/assets/79580bc7-237c-46b7-b92e-1479cc6d9079\n\n\n\n### Installation\n\n```\n$ yarn\n$ yarn prebuild --clean\n```\n\n### Step 2\n\n```\n$ NNN Enjoy Bro 🐧\n```\n"
  },
  {
    "path": "example/app.json",
    "content": "{\n  \"expo\": {\n    \"name\": \"MultipleImagePickerExample\",\n    \"slug\": \"MultipleImagePickerExample\",\n    \"version\": \"1.0.0\",\n    \"orientation\": \"portrait\",\n    \"icon\": \"./assets/icon.png\",\n    \"userInterfaceStyle\": \"automatic\",\n    \"splash\": {\n      \"image\": \"./assets/splash.png\",\n      \"resizeMode\": \"contain\",\n      \"backgroundColor\": \"#ffffff\"\n    },\n    \"ios\": {\n      \"supportsTablet\": true,\n      \"infoPlist\": {\n        \"NSCameraUsageDescription\": \"We needs to access your camera so that you can upload your photo: (avatar, etc.)\",\n        \"NSPhotoLibraryAddUsageDescription\": \"We needs photo library permissions to allow you to upload profile images.\",\n        \"NSPhotoLibraryUsageDescription\": \"We needs photo library permissions to allow you to upload profile images.\",\n        \"NSMicrophoneUsageDescription\": \"We needs to access your microphone so that you can take your photo: (avatar, etc.)\"\n      },\n      \"bundleIdentifier\": \"com.baoha.imagepicker\"\n    },\n    \"android\": {\n      \"adaptiveIcon\": {\n        \"foregroundImage\": \"./assets/adaptive-icon.png\",\n        \"backgroundColor\": \"#ffffff\"\n      },\n      \"package\": \"com.baoha.imagepicker\"\n    },\n\n    \"plugins\": [\n      [\n        \"expo-build-properties\",\n        {\n          \"ios\": {\n            \"deploymentTarget\": \"15.6\",\n            \"useFrameworks\": \"static\"\n          },\n          \"android\": {\n            \"compileSdkVersion\": 34,\n            \"targetSdkVersion\": 34,\n            \"buildToolsVersion\": \"34.0.0\"\n          }\n        }\n      ]\n    ]\n  }\n}\n"
  },
  {
    "path": "example/babel.config.js",
    "content": "const path = require('path')\nmodule.exports = function (api) {\n  api.cache(true)\n  return {\n    presets: ['babel-preset-expo'],\n    plugins: [\n      [\n        'module-resolver',\n        {\n          extensions: ['.tsx', '.ts', '.js', '.json'],\n          alias: {\n            // For development, we want to alias the library to the source\n            '@baronha/react-native-multiple-image-picker': path.join(\n              __dirname,\n              '..',\n              'src',\n              'index.ts'\n            ),\n          },\n        },\n      ],\n    ],\n  }\n}\n"
  },
  {
    "path": "example/metro.config.js",
    "content": "// Learn more https://docs.expo.io/guides/customizing-metro\nconst { getDefaultConfig } = require('expo/metro-config')\nconst path = require('path')\n\nconst config = getDefaultConfig(__dirname)\n\n// npm v7+ will install ../node_modules/react-native because of peerDependencies.\n// To prevent the incompatible react-native bewtween ./node_modules/react-native and ../node_modules/react-native,\n// excludes the one from the parent folder when bundling.\nconfig.resolver.blockList = [\n  ...Array.from(config.resolver.blockList ?? []),\n  new RegExp(path.resolve('..', 'node_modules', 'react-native')),\n]\n\nconfig.resolver.nodeModulesPaths = [\n  path.resolve(__dirname, './node_modules'),\n  path.resolve(__dirname, '../node_modules'),\n]\n\nconfig.watchFolders = [path.resolve(__dirname, '..')]\n\nconfig.transformer.getTransformOptions = async () => ({\n  transform: {\n    experimentalImportSupport: false,\n    inlineRequires: true,\n  },\n})\n\nmodule.exports = config\n"
  },
  {
    "path": "example/package.json",
    "content": "{\n  \"name\": \"multipleimagepickerexample\",\n  \"version\": \"2.2.3\",\n  \"main\": \"expo/AppEntry.js\",\n  \"scripts\": {\n    \"start\": \"expo start\",\n    \"android\": \"expo run:android\",\n    \"ios\": \"expo run:ios\",\n    \"web\": \"expo start --web\",\n    \"pod\": \"cd ios && bundle exec pod update\",\n    \"pod-new-arch\": \"cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install\",\n    \"prebuild\": \"expo prebuild\",\n    \"gradle\": \"cd android && ./gradlew clean && ./gradlew build\"\n  },\n  \"dependencies\": {\n    \"@react-native-segmented-control/segmented-control\": \"2.5.7\",\n    \"expo\": \"^54.0.27\",\n    \"expo-build-properties\": \"~1.0.10\",\n    \"expo-status-bar\": \"~3.0.9\",\n    \"expo-system-ui\": \"~6.0.9\",\n    \"immer\": \"^10.1.1\",\n    \"react\": \"19.1.0\",\n    \"react-native\": \"0.81.5\",\n    \"use-immer\": \"^0.10.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.20.0\",\n    \"@react-native/babel-preset\": \"0.75.2\",\n    \"@react-native/metro-config\": \"0.75.2\",\n    \"@react-native/typescript-config\": \"0.75.2\",\n    \"@types/react\": \"~19.1.10\",\n    \"react-native-builder-bob\": \"^0.30.0\",\n    \"react-native-nitro-modules\": \"^0.25.2\",\n    \"typescript\": \"~5.9.2\"\n  },\n  \"private\": true\n}\n"
  },
  {
    "path": "example/react-native.config.js",
    "content": "const path = require('path')\nconst pkg = require('../package.json')\n\nmodule.exports = {\n  project: {\n    ios: {\n      automaticPodsInstallation: true,\n    },\n  },\n  dependencies: {\n    [pkg.name]: {\n      root: path.join(__dirname, '..'),\n    },\n  },\n}\n"
  },
  {
    "path": "example/src/assets/index.ts",
    "content": "const images = {\n  logo: require('./logo.png'),\n  plusSign: require('./plus-sign.png'),\n  check: require('./check.png'),\n}\n\nexport default images\n"
  },
  {
    "path": "example/src/common/const.ts",
    "content": "import { Platform } from 'react-native'\n\nexport const IS_IOS = Platform.OS === 'ios'\nexport const IS_ANDROID = Platform.OS === 'android'\n\nexport const LOCALIZED_LANGUAGES = [\n  {\n    key: 'system',\n    label: 'System 🌐',\n  },\n  {\n    key: 'vi',\n    label: 'Tiếng Việt 🇻🇳',\n  },\n  {\n    key: 'zh-Hans',\n    label: '简体中文 🇨🇳',\n  },\n  {\n    key: 'zh-Hant',\n    label: '繁體中文 🇹🇼',\n  },\n  {\n    key: 'ja',\n    label: '日本語 🇯🇵',\n  },\n  {\n    key: 'ko',\n    label: '한국어 🇰🇷',\n  },\n  {\n    key: 'en',\n    label: 'English 🇺🇸',\n  },\n  {\n    key: 'ru',\n    label: 'Русский 🇷🇺',\n  },\n  {\n    key: 'de',\n    label: 'Deutsch 🇩🇪',\n  },\n  {\n    key: 'fr',\n    label: 'Français 🇫🇷',\n  },\n  {\n    key: 'ar',\n    label: 'العربية 🇸🇦',\n  },\n\n  ...(IS_IOS\n    ? [\n        {\n          key: 'th',\n          label: 'ไทย 🇹🇭',\n        },\n        {\n          key: 'id',\n          label: 'Bahasa Indonesia 🇮🇩',\n        },\n      ]\n    : []),\n]\n"
  },
  {
    "path": "example/src/components/BottomSheet.tsx",
    "content": "import React from 'react'\nimport { View } from 'react-native'\n\nexport function BottomSheet() {\n  return (\n    <View>\n      \n    </View>\n  )\n}\n"
  },
  {
    "path": "example/src/components/Button.tsx",
    "content": "import React from 'react'\nimport {\n  StyleSheet,\n  TouchableOpacity,\n  TouchableOpacityProps,\n} from 'react-native'\nimport useTheme from '../hook/useTheme'\nimport { Text } from './Text'\n\ninterface Props extends TouchableOpacityProps {\n  children: React.ReactNode | string\n  type?: 'full' | 'outline'\n}\n\nexport function Button({\n  children,\n  style: containerStyle,\n  onPress,\n  type = 'full',\n}: Props) {\n  const { foreground, background } = useTheme()\n  const isFull = type === 'full'\n\n  return (\n    <TouchableOpacity\n      style={[\n        style.button,\n        containerStyle,\n        // eslint-disable-next-line react-native/no-inline-styles\n        {\n          backgroundColor: isFull ? foreground : 'transparent',\n          borderColor: isFull ? 'transparent' : foreground,\n        },\n      ]}\n      onPress={onPress}\n    >\n      {typeof children === 'string' ? (\n        <Text style={[style.text, { color: isFull ? background : foreground }]}>\n          {children}\n        </Text>\n      ) : (\n        children\n      )}\n    </TouchableOpacity>\n  )\n}\n\nconst style = StyleSheet.create({\n  button: {\n    padding: 12,\n    alignItems: 'center',\n    borderWidth: 1.5,\n  },\n  text: {\n    fontFamily: 'Avenir',\n    fontWeight: 'bold',\n  },\n})\n"
  },
  {
    "path": "example/src/components/CheckBox.tsx",
    "content": "import React from 'react'\nimport {\n  Image,\n  StyleSheet,\n  TouchableOpacity,\n  TouchableOpacityProps,\n} from 'react-native'\nimport images from '../assets'\nimport useTheme from '../hook/useTheme'\n\ninterface CheckBoxProps extends TouchableOpacityProps {\n  checked?: boolean\n  onChecked?: (checked: boolean) => void\n}\n\nexport function CheckBox({\n  checked = false,\n  onChecked,\n  ...props\n}: CheckBoxProps) {\n  const { foreground, background_2 } = useTheme()\n\n  return (\n    <TouchableOpacity\n      activeOpacity={0.9}\n      onPress={() => onChecked?.(!checked)}\n      {...props}\n      style={[\n        style.container,\n        props.style,\n        {\n          backgroundColor: checked ? foreground : background_2,\n          borderColor: foreground + '64',\n        },\n      ]}\n    >\n      {checked && (\n        <Image\n          style={[style.check, { tintColor: background_2 }]}\n          source={images.check}\n        />\n      )}\n    </TouchableOpacity>\n  )\n}\n\nconst style = StyleSheet.create({\n  container: {\n    width: 24,\n    height: 24,\n    alignItems: 'center',\n    justifyContent: 'center',\n    borderRadius: 4,\n  },\n  check: {\n    width: 16,\n    height: 16,\n  },\n})\n"
  },
  {
    "path": "example/src/components/CodeTag.tsx",
    "content": "import React from 'react'\nimport { View } from './View'\nimport { StyleSheet, TextProps, ViewProps } from 'react-native'\nimport { Text } from './Text'\n\ninterface CodeTagProps extends ViewProps {\n  children: string\n  textProps?: TextProps\n}\n\nexport function CodeTag({ children, textProps, ...props }: CodeTagProps) {\n  return (\n    <View level={3} {...props} style={[style.container, props.style]}>\n      <Text {...textProps} style={[style.text, textProps?.style]}>\n        {children}\n      </Text>\n    </View>\n  )\n}\n\nconst style = StyleSheet.create({\n  text: {\n    // fontFamily: 'monospace',\n    fontWeight: 600,\n    fontSize: 16,\n  },\n  container: {\n    padding: 8,\n    paddingVertical: 6,\n    borderRadius: 4,\n    alignSelf: 'baseline',\n  },\n})\n"
  },
  {
    "path": "example/src/components/Container.tsx",
    "content": "import React from 'react'\nimport { StyleSheet, ViewProps } from 'react-native'\nimport useTheme from '../hook/useTheme'\nimport { View } from './View'\n\ninterface Props extends ViewProps {\n  level?: 0 | 1 | 2 | 3\n}\n\nexport function Container({\n  children,\n  style: containerStyle,\n  level = 0,\n}: Props) {\n  const theme = useTheme()\n  const backgroundColor = !level\n    ? theme.background\n    : theme[`background_${level}` as keyof typeof theme]\n\n  return (\n    <View style={[style.container, { backgroundColor }, containerStyle]}>\n      {children}\n    </View>\n  )\n}\n\nconst style = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n})\n"
  },
  {
    "path": "example/src/components/CounterView.tsx",
    "content": "import React from 'react'\nimport { View } from './View'\nimport { Row, RowProps } from './Row'\nimport { StyleSheet, TouchableOpacity } from 'react-native'\nimport { Text } from './Text'\nimport useTheme from '../hook/useTheme'\n\ninterface CounterViewProps extends RowProps {\n  value?: number\n  onChange: (value: number) => void\n  range?: {\n    min?: number\n    max?: number\n  }\n}\n\nexport function CounterView({\n  value = 0,\n  onChange,\n  range,\n  ...props\n}: CounterViewProps) {\n  const { background_2 } = useTheme()\n\n  return (\n    <Row gap={8} {...props}>\n      <TouchableOpacity\n        activeOpacity={0.9}\n        style={[style.button, { backgroundColor: background_2 }]}\n        onPress={() => {\n          const min = range?.min ?? 0\n          onChange(value - 1 < min ? min : value - 1)\n        }}\n      >\n        <Text style={style.buttonText}>－</Text>\n      </TouchableOpacity>\n      <View style={style.counterView}>\n        <Text style={style.buttonText}>{value}</Text>\n      </View>\n      <TouchableOpacity\n        activeOpacity={0.9}\n        style={[style.button, { backgroundColor: background_2 }]}\n        onPress={() => {\n          const max = range?.max\n          if (max) onChange(value + 1 > max ? max : value + 1)\n          else onChange(value + 1)\n        }}\n      >\n        <Text style={style.buttonText}>+</Text>\n      </TouchableOpacity>\n    </Row>\n  )\n}\n\nconst style = StyleSheet.create({\n  counterView: {\n    //\n    height: 32,\n    paddingHorizontal: 12,\n    borderRadius: 4,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  button: {\n    borderRadius: 4,\n    height: 32,\n    width: 32,\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  buttonText: {\n    fontSize: 16,\n    fontWeight: 'bold',\n    fontFamily: 'Avenir',\n  },\n})\n"
  },
  {
    "path": "example/src/components/Divider.tsx",
    "content": "import React from 'react'\nimport { StyleSheet } from 'react-native'\nimport useTheme from '../hook/useTheme'\nimport { View } from './View'\n\nexport default function Divider() {\n  const { foreground } = useTheme()\n  return <View style={[style.container, { backgroundColor: foreground }]} />\n}\n\nconst style = StyleSheet.create({\n  container: {\n    height: 1,\n    width: '100%',\n    opacity: 0.2,\n  },\n})\n"
  },
  {
    "path": "example/src/components/Input.tsx",
    "content": "import React from 'react'\nimport { StyleSheet, TextInput, TextInputProps } from 'react-native'\nimport useTheme from '../hook/useTheme'\n\ninterface InputProps extends TextInputProps {}\n\nexport function Input({ ...props }: InputProps) {\n  const { background_2, foreground } = useTheme()\n\n  return (\n    <TextInput\n      {...props}\n      selectionColor={foreground}\n      placeholderTextColor={foreground + '92'}\n      style={[\n        style.input,\n        { backgroundColor: background_2, color: foreground },\n      ]}\n    />\n  )\n}\n\nconst style = StyleSheet.create({\n  input: {\n    paddingHorizontal: 12,\n    paddingVertical: 12,\n    borderRadius: 8,\n    fontSize: 16,\n  },\n})\n"
  },
  {
    "path": "example/src/components/Row.tsx",
    "content": "import React from 'react'\nimport { StyleSheet, ViewStyle } from 'react-native'\nimport { View, ViewProps } from './View'\n\nexport interface RowProps extends ViewProps {\n  alignItems?: ViewStyle['alignItems']\n  gap?: number\n}\n\nexport function Row({\n  children,\n  gap,\n  alignItems = 'center',\n  ...props\n}: RowProps) {\n  return (\n    <View\n      {...props}\n      style={[style.container, props.style, { alignItems, gap }]}\n    >\n      {children}\n    </View>\n  )\n}\n\nconst style = StyleSheet.create({\n  container: {\n    flexDirection: 'row',\n  },\n})\n"
  },
  {
    "path": "example/src/components/SectionView.tsx",
    "content": "import React from 'react'\nimport { Row } from './Row'\nimport { CodeTag } from './CodeTag'\nimport { View } from './View'\nimport { Text } from './Text'\nimport { StyleSheet, Switch } from 'react-native'\nimport { useAppContext } from '../hook/context'\nimport { Config } from '@baronha/react-native-multiple-image-picker'\nimport { SegmentControl } from './SegmentControl'\n\ntype key = keyof Config\ninterface SectionViewProps {\n  title: key\n  description: string\n  optionKey?: key\n  children?: React.ReactNode\n  defaultValue?: boolean\n  segmentControl?: string[]\n}\n\nexport default function SectionView({\n  title,\n  description,\n  optionKey,\n  children,\n  defaultValue = false,\n  segmentControl,\n}: SectionViewProps) {\n  const { options, setOptions } = useAppContext()\n\n  return (\n    <View style={style.section}>\n      <Row style={style.section}>\n        <View flex={1} style={style.sectionTitle}>\n          <CodeTag>{title}</CodeTag>\n          <Text style={style.des}>{description}</Text>\n        </View>\n        {children ||\n          (optionKey ? (\n            !segmentControl ? (\n              <Switch\n                value={(options?.[optionKey] as any) ?? defaultValue}\n                onValueChange={(valueChange) =>\n                  setOptions(optionKey, valueChange)\n                }\n              />\n            ) : null\n          ) : null)}\n      </Row>\n\n      {segmentControl && optionKey ? (\n        <SegmentControl\n          selectedIndex={\n            segmentControl.indexOf(\n              (options?.[optionKey] as any) ?? defaultValue ?? ''\n            ) ?? 0\n          }\n          values={segmentControl}\n          onValueChange={(valueChange) => setOptions(optionKey, valueChange)}\n        />\n      ) : null}\n    </View>\n  )\n}\n\nconst style = StyleSheet.create({\n  section: {\n    rowGap: 12,\n    columnGap: 24,\n  },\n  sectionTitle: {\n    gap: 8,\n  },\n\n  des: {\n    fontSize: 12,\n    // marginBottom: 12,\n  },\n})\n"
  },
  {
    "path": "example/src/components/SegmentControl.tsx",
    "content": "import React from 'react'\nimport SegmentedControl, {\n  SegmentedControlProps,\n} from '@react-native-segmented-control/segmented-control'\n\nexport function SegmentControl({ ...props }: SegmentedControlProps) {\n  return <SegmentedControl {...props} />\n}\n"
  },
  {
    "path": "example/src/components/Text.tsx",
    "content": "import React from 'react'\nimport { Text as RNText, TextProps } from 'react-native'\nimport useTheme from '../hook/useTheme'\n\nexport function Text({ children, style: containerStyle }: TextProps) {\n  const { foreground } = useTheme()\n\n  return (\n    <RNText style={[{ color: foreground }, containerStyle]}>{children}</RNText>\n  )\n}\n"
  },
  {
    "path": "example/src/components/View.tsx",
    "content": "import React from 'react'\nimport { View as RNView, ViewProps as RNViewProps } from 'react-native'\nimport useTheme from '../hook/useTheme'\n\nexport interface ViewProps extends RNViewProps {\n  level?: 0 | 1 | 2 | 3\n  flex?: number\n}\n\nexport function View({\n  children,\n  style: containerStyle,\n  level = 0,\n  flex,\n}: ViewProps) {\n  const theme = useTheme()\n  const backgroundColor = !level\n    ? theme.background\n    : theme[`background_${level}` as keyof typeof theme]\n\n  return (\n    <RNView style={[{ backgroundColor, flex }, containerStyle]}>\n      {children}\n    </RNView>\n  )\n}\n"
  },
  {
    "path": "example/src/components/index.tsx",
    "content": "export * from './Container'\nexport * from './Button'\nexport * from './SegmentControl'\nexport * from './Text'\nexport * from './View'\nexport * from './CodeTag'\nexport * from './Row'\nexport * from './Divider'\nexport * from './CheckBox'\nexport * from './SectionView'\nexport * from './Input'\nexport * from './CounterView'\n"
  },
  {
    "path": "example/src/hook/context.ts",
    "content": "import { createContext, useContext } from 'react'\nimport {\n  Config,\n  defaultOptions,\n} from '@baronha/react-native-multiple-image-picker'\n\nexport const AppContext = createContext<{\n  options: Config\n  setOptions: (key: keyof Config, value: Config[keyof Config]) => void\n}>({\n  options: defaultOptions,\n  setOptions: () => {},\n})\n\nexport const useAppContext = () => useContext(AppContext)\n"
  },
  {
    "path": "example/src/hook/index.ts",
    "content": "export * from './useTheme'\n"
  },
  {
    "path": "example/src/hook/useTheme.ts",
    "content": "import { useColorScheme } from 'react-native'\nimport * as color from '../theme/color'\n\nexport default function useTheme() {\n  const colorScheme = useColorScheme() as keyof typeof color\n\n  return color[colorScheme]\n}\n"
  },
  {
    "path": "example/src/index.tsx",
    "content": "import React, { useCallback, useMemo, useState } from 'react'\nimport {\n  ActionSheetIOS,\n  Alert,\n  Appearance,\n  ColorSchemeName,\n  Image,\n  KeyboardAvoidingView,\n  LayoutAnimation,\n  Platform,\n  SafeAreaView,\n  ScrollView,\n  Switch,\n  TouchableOpacity,\n  useColorScheme,\n} from 'react-native'\n\nimport { StyleSheet } from 'react-native'\nimport {\n  openPicker,\n  PickerResult,\n  defaultOptions,\n  Config,\n  openCropper,\n  openPreview,\n  openCamera,\n} from '@baronha/react-native-multiple-image-picker'\nimport { useImmer } from 'use-immer'\nimport { StatusBar } from 'expo-status-bar'\nimport {\n  Button,\n  CodeTag,\n  Container,\n  CounterView,\n  Input,\n  Row,\n  SegmentControl,\n  Text,\n  View,\n} from './components'\nimport useTheme from './hook/useTheme'\nimport assets from './assets'\nimport { WIDTH } from './theme/size'\nimport { IS_IOS, LOCALIZED_LANGUAGES } from './common/const'\nimport { AppContext } from './hook/context'\nimport SectionView from './components/SectionView'\n\nconst layoutEffect = () => {\n  LayoutAnimation.configureNext({\n    duration: 350,\n    create: {\n      type: LayoutAnimation.Types.easeInEaseOut,\n      property: LayoutAnimation.Properties.opacity,\n    },\n    update: {\n      type: LayoutAnimation.Types.easeInEaseOut,\n    },\n  })\n}\n\nconst parseNumber = (value: string): number | undefined => {\n  const parsed = Number(value)\n  return value === '' || Number.isNaN(parsed) ? undefined : parsed\n}\n\nexport default function App() {\n  const { background, foreground } = useTheme()\n  const [images, setImages] = useState<PickerResult[]>([])\n  const [options, changeOptions] = useImmer<Config>(defaultOptions)\n\n  const colorScheme = useColorScheme()\n\n  const setOptions = (key: keyof Config, value: Config[keyof Config]) => {\n    changeOptions((draft) => {\n      draft[key] = value as any\n    })\n  }\n\n  console.log('images: ', images)\n\n  const onPressImage = useCallback(\n    (_: PickerResult, index: number) => {\n      openPreview(images, index, {\n        onLongPress: () => {\n          if (Platform.OS === 'ios') {\n            ActionSheetIOS.showActionSheetWithOptions(\n              {\n                options: ['Download', 'Cancel'],\n                cancelButtonIndex: 1,\n                userInterfaceStyle: colorScheme ?? 'light',\n              },\n              (buttonIndex) => {\n                if (buttonIndex === 0) {\n                  // Download\n                } else if (buttonIndex === 1) {\n                  // Cancel\n                }\n              }\n            )\n          } else {\n            Alert.alert('Options', '', [\n              {\n                text: 'Cancel',\n                style: 'cancel',\n                onPress: () => {\n                  console.log('Cancel')\n                },\n              },\n              {\n                text: 'Download',\n                onPress: () => {\n                  console.log('Download')\n                },\n              },\n            ])\n          }\n        },\n      })\n    },\n    [images, colorScheme]\n  )\n\n  const onPicker = async () => {\n    try {\n      const response = await openPicker({\n        ...options,\n        selectedAssets: images.filter((item) => item.localIdentifier),\n      })\n\n      setImages(Array.isArray(response) ? response : [response])\n      layoutEffect()\n    } catch (e) {\n      console.log('e: ', e)\n    }\n  }\n\n  const onCamera = async () => {\n    try {\n      const response = await openCamera()\n\n      setImages((prev) => {\n        return [response as PickerResult, ...prev]\n      })\n\n      layoutEffect()\n    } catch (e) {\n      console.log('e: ', e)\n    }\n  }\n\n  const onCrop = async () => {\n    try {\n      const response = await openCropper(images[0].path, {\n        ratio: [\n          { title: 'Instagram', width: 1, height: 1 },\n          { title: 'Twitter', width: 16, height: 9 },\n          { title: 'Facebook', width: 12, height: 11 },\n        ],\n      })\n\n      setImages((prev) => {\n        const data = [...prev]\n        data[0].path = response.path\n        data[0].width = response.width\n        data[0].height = response.height\n        return data\n      })\n      layoutEffect()\n    } catch (e) {\n      console.log('e: ', e)\n    }\n  }\n\n  const onRemovePhoto = useCallback(\n    (_: PickerResult, index: number) => {\n      const data = [...images].filter((__, idx) => idx !== index)\n      setImages(data)\n    },\n    [images, setImages]\n  )\n\n  const onChangeTheme = (value: string) => {\n    Appearance.setColorScheme(value as ColorSchemeName)\n  }\n\n  const renderImage = useMemo(() => {\n    return (\n      <View style={style.imageContainer}>\n        {images.map((image, index) => (\n          <TouchableOpacity\n            key={index}\n            onPress={() => onPressImage(image, index)}\n            style={style.image}\n          >\n            <Image source={{ uri: image.path }} style={style.image} />\n            <TouchableOpacity\n              style={style.removeButton}\n              onPress={() => onRemovePhoto(image, index)}\n            >\n              <Image source={assets.plusSign} style={style.trash} />\n            </TouchableOpacity>\n          </TouchableOpacity>\n        ))}\n      </View>\n    )\n  }, [images, onPressImage, onRemovePhoto])\n\n  return (\n    <Container>\n      <SafeAreaView />\n      {Platform.OS === 'android' && (\n        <StatusBar\n          translucent={false}\n          networkActivityIndicatorVisible\n          backgroundColor={background}\n        />\n      )}\n\n      <View style={style.titleView}>\n        <Image source={assets.logo} style={style.logo} />\n        <View style={style.textView}>\n          <Text style={style.mip}>Multiple Image Picker</Text>\n          <CodeTag textProps={{ style: { fontSize: 8 } }}>BY BAOHA</CodeTag>\n        </View>\n      </View>\n\n      <KeyboardAvoidingView\n        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}\n        style={style.keyboardAvoidingView}\n      >\n        <AppContext.Provider value={{ options, setOptions }}>\n          <ScrollView\n            keyboardDismissMode=\"on-drag\"\n            keyboardShouldPersistTaps=\"handled\"\n            showsVerticalScrollIndicator={false}\n            contentContainerStyle={[\n              style.scrollView,\n              { backgroundColor: background },\n            ]}\n            scrollEventThrottle={16}\n          >\n            {images.length > 0 ? (\n              <>\n                {renderImage}\n                <Button style={style.buttonOpen} onPress={onCrop}>\n                  Open Cropping\n                </Button>\n              </>\n            ) : (\n              <TouchableOpacity style={style.buttonPlus} onPress={onPicker}>\n                <Image source={assets.plusSign} style={style.plusSign} />\n              </TouchableOpacity>\n            )}\n\n            <View style={style.content}>\n              <Text style={style.title}>Config</Text>\n\n              {/* mediaType */}\n\n              <View style={style.section}>\n                <SectionView\n                  title=\"mediaType\"\n                  description=\"The type of media that can be selected.\"\n                />\n                <SegmentControl\n                  selectedIndex={\n                    ['all', 'image', 'video'].indexOf(\n                      options.mediaType ?? ''\n                    ) ?? 0\n                  }\n                  values={['all', 'image', 'video']}\n                  onValueChange={(value) => setOptions('mediaType', value)}\n                />\n              </View>\n\n              {/* theme */}\n              <View style={style.section}>\n                <SectionView\n                  title=\"theme\"\n                  description=\"Theme mode for the picker.\"\n                />\n                <SegmentControl\n                  selectedIndex={\n                    ['light', 'dark'].indexOf(colorScheme ?? '') ?? 0\n                  }\n                  values={['light', 'dark']}\n                  onValueChange={onChangeTheme}\n                />\n              </View>\n\n              {/* selectMode */}\n              <View style={style.section}>\n                <SectionView\n                  title=\"selectMode\"\n                  description=\"Mode of selection in the picker.\"\n                />\n                <SegmentControl\n                  selectedIndex={\n                    ['single', 'multiple'].indexOf(options.selectMode ?? '') ??\n                    0\n                  }\n                  values={['single', 'multiple']}\n                  onValueChange={(value) => setOptions('selectMode', value)}\n                />\n              </View>\n\n              {/* selectBoxStyle */}\n              <View style={style.section}>\n                <SectionView\n                  title=\"selectBoxStyle\"\n                  description=\"Select box style for the picker.\"\n                  optionKey=\"selectBoxStyle\"\n                  segmentControl={['number', 'tick']}\n                />\n              </View>\n\n              {/* presentation */}\n              {IS_IOS ? (\n                <SectionView\n                  title=\"presentation\"\n                  description=\"Presentation style for the picker.\"\n                  optionKey=\"presentation\"\n                  segmentControl={['fullScreenModal', 'formSheet']}\n                />\n              ) : null}\n\n              <Text style={style.title}>Camera 📸</Text>\n              <View style={style.section}>\n                <SectionView\n                  title=\"camera\"\n                  description=\"Enable camera functionality.\"\n                >\n                  <Switch\n                    value={options.camera !== undefined}\n                    onValueChange={(value) =>\n                      setOptions('camera', value ? {} : undefined)\n                    }\n                  />\n                </SectionView>\n\n                {/* camera videoMaximumDuration */}\n                <SectionView\n                  title={'camera.videoMaximumDuration' as any}\n                  description=\"The maximum duration of video that can be selected.\"\n                >\n                  <Input\n                    value={\n                      options.camera?.videoMaximumDuration?.toString() ?? ''\n                    }\n                    placeholder=\"Video Duration\"\n                    onChangeText={(value) => {\n                      setOptions('camera', {\n                        ...(options.camera ?? { cameraDevice: 'back' }),\n                        videoMaximumDuration: parseNumber(value),\n                      })\n                    }}\n                  />\n                </SectionView>\n              </View>\n\n              {IS_IOS ? (\n                <>\n                  {/* allowedLimit */}\n                  <SectionView\n                    title=\"allowedLimit\"\n                    description=\"Display additional select more media when permission on iOS is limited.\"\n                    optionKey=\"allowedLimit\"\n                  />\n                </>\n              ) : null}\n\n              {/* allowSwipeToSelect */}\n              <SectionView\n                title=\"allowSwipeToSelect\"\n                description=\"Allow swipe to select media.\"\n                optionKey=\"allowSwipeToSelect\"\n              />\n\n              {/* isHiddenOriginalButton */}\n              <SectionView\n                title=\"isHiddenOriginalButton\"\n                description=\"Hide the original button in the picker.\"\n                optionKey=\"isHiddenOriginalButton\"\n              />\n\n              {/* maxSelect */}\n              <SectionView\n                title=\"maxSelect\"\n                description=\"The maximum number of media that can be selected.\"\n              >\n                <CounterView\n                  range={{ min: 1 }}\n                  value={options.maxSelect}\n                  onChange={(value) => setOptions('maxSelect', value)}\n                />\n              </SectionView>\n\n              {/* maxVideo */}\n              <SectionView\n                title=\"maxVideo\"\n                description=\"The maximum number of video that can be selected.\"\n              >\n                <CounterView\n                  range={{ min: 1 }}\n                  value={options.maxVideo}\n                  onChange={(value) => setOptions('maxVideo', value)}\n                />\n              </SectionView>\n\n              {/* numberOfColumn */}\n              <SectionView\n                title=\"numberOfColumn\"\n                description=\"The number of columns in the picker.\"\n              >\n                <CounterView\n                  range={{ min: 1, max: 10 }}\n                  value={options.numberOfColumn}\n                  onChange={(value) => setOptions('numberOfColumn', value)}\n                />\n              </SectionView>\n\n              {/* spacing */}\n              <SectionView\n                title=\"spacing\"\n                description=\"The spacing between the media in the picker.\"\n              >\n                <CounterView\n                  range={{ min: 1, max: 10 }}\n                  value={options.spacing ?? 2}\n                  onChange={(value) => setOptions('spacing', value)}\n                />\n              </SectionView>\n              {/* Filter data 🎞️ */}\n\n              <Text style={style.title}>Filter data 🎞️</Text>\n              {/* maxVideoDuration */}\n              <SectionView\n                title=\"maxVideoDuration\"\n                description=\"The maximum duration of video that can be selected.\"\n              >\n                <Input\n                  value={options.maxVideoDuration?.toString() ?? ''}\n                  placeholder=\"Max Duration\"\n                  onChangeText={(value) => {\n                    setOptions('maxVideoDuration', parseNumber(value))\n                  }}\n                />\n              </SectionView>\n\n              {/* minVideoDuration */}\n              <SectionView\n                title=\"minVideoDuration\"\n                description=\"The minimum duration of video that can be selected.\"\n              >\n                <Input\n                  value={options.minVideoDuration?.toString() ?? ''}\n                  placeholder=\"Min Duration\"\n                  onChangeText={(value) => {\n                    setOptions('minVideoDuration', parseNumber(value))\n                  }}\n                />\n              </SectionView>\n\n              {/* maxFileSize */}\n              <SectionView\n                title=\"maxFileSize\"\n                description=\"The maximum size of file that can be selected.\"\n              >\n                <Input\n                  value={options.maxFileSize?.toString() ?? ''}\n                  placeholder=\"File Size\"\n                  onChangeText={(value) => {\n                    setOptions('maxFileSize', parseNumber(value))\n                  }}\n                />\n              </SectionView>\n\n              <Text style={style.title}>Crop 🌠</Text>\n              <View style={style.section}>\n                <SectionView\n                  title=\"crop\"\n                  description=\"Enable crop functionality.\"\n                >\n                  <Switch\n                    value={options.crop !== undefined}\n                    onValueChange={(value) =>\n                      setOptions('crop', value ? true : undefined)\n                    }\n                  />\n                </SectionView>\n              </View>\n\n              <View style={style.section}>\n                <SectionView\n                  title={'crop.circle' as any}\n                  description=\"Enable crop circle functionality.\"\n                >\n                  <Switch\n                    value={\n                      typeof options.crop === 'boolean'\n                        ? options.crop\n                        : options.crop?.circle\n                    }\n                    onValueChange={(value) =>\n                      setOptions(\n                        'crop',\n                        value ? { circle: true } : { circle: false }\n                      )\n                    }\n                  />\n                </SectionView>\n              </View>\n\n              {/* Preview */}\n              <Text style={style.title}>Preview 🌠</Text>\n              {/* isPreview */}\n              <SectionView\n                title=\"isPreview\"\n                description=\"Hide the preview button in the picker.\"\n                optionKey=\"isPreview\"\n              />\n\n              {/* isShowPreviewList */}\n              <SectionView\n                title=\"isShowPreviewList\"\n                description=\"Show the preview list.\"\n                optionKey=\"isShowPreviewList\"\n              />\n\n              {/* isHiddenPreviewButton */}\n              <SectionView\n                title=\"isHiddenPreviewButton\"\n                description=\"Hide the preview button in the picker.\"\n                optionKey=\"isHiddenPreviewButton\"\n              />\n\n              {/* allowHapticTouchPreview */}\n              {IS_IOS ? (\n                <SectionView\n                  title=\"allowHapticTouchPreview\"\n                  description=\"Allow haptic touch preview.\"\n                  optionKey=\"allowHapticTouchPreview\"\n                />\n              ) : null}\n\n              <Text style={style.title}>Localization 🌐</Text>\n\n              <View style={style.section}>\n                <SectionView\n                  title=\"text\"\n                  description=\"The locale of the picker.\"\n                />\n\n                {(\n                  [\n                    'finish',\n                    'preview',\n                    'original',\n                    'edit',\n                  ] as (keyof Config['text'])[]\n                ).map((key) => (\n                  <Input\n                    value={options.text?.[key] ?? ''}\n                    placeholder={key}\n                    key={key}\n                    onChangeText={(value) => {\n                      const object = {\n                        ...options.text,\n                        [key]: value,\n                      }\n\n                      Object.entries(object).forEach(([textKey, textValue]) => {\n                        if (textValue === '' || !textValue)\n                          delete object[textKey as keyof Config['text']]\n                      })\n\n                      setOptions(\n                        'text',\n                        Object.entries(object).length > 0 ? object : undefined\n                      )\n                    }}\n                  />\n                ))}\n              </View>\n\n              <View style={style.section}>\n                <SectionView\n                  title=\"language\"\n                  description=\"The language of the picker.\"\n                />\n\n                <Row style={style.language}>\n                  {LOCALIZED_LANGUAGES.map(({ key, label }) => {\n                    const onPress = () => {\n                      setOptions('language', key)\n                    }\n                    const active = options.language === key\n\n                    return (\n                      <TouchableOpacity\n                        style={[\n                          style.languageItem,\n                          {\n                            backgroundColor: active ? foreground : background,\n                            borderColor: foreground + '32',\n                          },\n                        ]}\n                        onPress={onPress}\n                      >\n                        <Text\n                          style={{ color: active ? background : foreground }}\n                        >\n                          {label}\n                        </Text>\n                      </TouchableOpacity>\n                    )\n                  })}\n                </Row>\n              </View>\n            </View>\n          </ScrollView>\n        </AppContext.Provider>\n      </KeyboardAvoidingView>\n\n      <View level={2}>\n        <Row style={style.bottom} level={2} gap={12}>\n          <Button type=\"outline\" onPress={onCamera}>\n            Open Camera\n          </Button>\n          <Button style={style.openPicker} onPress={onPicker}>\n            Open Picker\n          </Button>\n        </Row>\n        <SafeAreaView />\n      </View>\n    </Container>\n  )\n}\n\nconst numberOfColumn = 3\n\nconst style = StyleSheet.create({\n  titleView: {\n    padding: 16,\n    flexDirection: 'row',\n    gap: 12,\n  },\n  mip: {\n    // flex: 1,\n  },\n  textView: {\n    alignItems: 'flex-start',\n    flex: 1,\n    height: 48,\n    gap: 4,\n  },\n  title: {\n    fontWeight: 900,\n    fontSize: 20,\n    fontFamily: 'Avenir',\n    textTransform: 'uppercase',\n    paddingTop: 12,\n    marginBottom: -12,\n  },\n  buttonOpen: {\n    margin: 16,\n  },\n  scrollView: {\n    gap: 12,\n    paddingTop: 12,\n    paddingBottom: 24,\n  },\n  content: {\n    flexDirection: 'column',\n    gap: 32,\n    padding: 16,\n  },\n\n  logo: {\n    aspectRatio: 1,\n    objectFit: 'cover',\n    height: 48,\n    width: 48,\n  },\n  buttonPlus: {\n    alignItems: 'center',\n    justifyContent: 'center',\n    padding: 48,\n    marginHorizontal: 16,\n    // backgroundColor: '#D4D4D432',\n    borderStyle: 'dashed',\n    borderWidth: 2,\n    borderColor: '#D4D4D492',\n    borderRadius: 8,\n  },\n  plusSign: {\n    width: 16,\n    height: 16,\n  },\n  section: {\n    rowGap: 12,\n    columnGap: 24,\n  },\n  sectionTitle: {\n    gap: 8,\n  },\n\n  des: {\n    fontSize: 12,\n  },\n  keyboardAvoidingView: {\n    flex: 1,\n  },\n  language: {\n    flexWrap: 'wrap',\n    rowGap: 12,\n    columnGap: 12,\n  },\n  languageItem: {\n    paddingHorizontal: 12,\n    paddingVertical: 8,\n    borderRadius: 6,\n    borderWidth: 1,\n  },\n  bottom: {\n    padding: 16,\n    paddingHorizontal: 24,\n  },\n  openPicker: {\n    flex: 1,\n  },\n  imageContainer: {\n    flexDirection: 'row',\n    flexWrap: 'wrap',\n    gap: 6,\n    paddingHorizontal: 6,\n  },\n  image: {\n    width: (WIDTH - 24) / numberOfColumn,\n    height: (WIDTH - 24) / numberOfColumn,\n  },\n\n  removeButton: {\n    position: 'absolute',\n    top: 6,\n    right: 6,\n    backgroundColor: 'rgba(0, 0, 0, 0.9)',\n    borderRadius: 100,\n    padding: 6,\n  },\n  trash: {\n    width: 16,\n    height: 16,\n    transform: [{ rotate: '45deg' }],\n  },\n})\n"
  },
  {
    "path": "example/src/theme/color.ts",
    "content": "export const light = {\n  background: '#ffffff',\n  foreground: '#000000',\n  primary: '#000000',\n\n  // background level\n  background_1: '#f0f0f0',\n  background_2: '#f3f3f3',\n  background_3: '#f5f5f5',\n}\n\nexport const dark = {\n  background: '#000000',\n  foreground: '#ffffff',\n  primary: '#ffffff',\n\n  // background level\n  background_1: '#101010',\n  background_2: '#202020',\n  background_3: '#303030',\n}\n\nexport const colors = {\n  ...light,\n  divider: '#D4D4D499',\n}\n"
  },
  {
    "path": "example/src/theme/size.ts",
    "content": "import { Dimensions } from 'react-native'\n\nexport const { width: WIDTH, height: HEIGHT } = Dimensions.get('window')\nexport const HALF_HEIGHT = HEIGHT / 2\nexport const HALF_WIDTH = WIDTH / 2\n"
  },
  {
    "path": "example/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\"\n  },\n  \"extends\": \"../tsconfig\"\n}\n"
  },
  {
    "path": "ios/Assets.swift",
    "content": "//\n//  Assets.swift\n//  Pods\n//\n//  Created by BAO HA on 4/12/24.\n//\n\nimport UIKit\n\nclass Assets {\n    class func bundle() -> Bundle {\n        let podBundle = Bundle(for: Assets.self)\n        if let url = podBundle.url(forResource: \"MultipleImagePicker\", withExtension: \"bundle\") {\n            let bundle = Bundle(url: url)\n            return bundle ?? podBundle\n        }\n        return podBundle\n    }\n}\n\nextension UIImage {\n    static var close = UIImage(name: \"close\")\n\n    convenience init(name: String) {\n        self.init(named: name, in: Assets.bundle(), compatibleWith: nil)!\n    }\n}\n"
  },
  {
    "path": "ios/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "ios/Assets.xcassets/close.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"close.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "ios/ErrorCode.swift",
    "content": "//\n//  ErrorCode.swift\n//  Pods\n//\n//  Created by BAO HA on 3/12/24.\n//\n\n// enum ErrorCode: Int, Error {\n//\n// }\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker+Camera.swift",
    "content": "//\n//  HybridMultipleImagePicker+Camera.swift\n//  Pods\n//\n//  Created by BAO HA on 13/12/24.\n//\n\nimport AVFoundation\nimport HXPhotoPicker\nimport Photos\n\nextension HybridMultipleImagePicker {\n    func openCamera(config: NitroCameraConfig, resolved: @escaping ((CameraResult) -> Void), rejected: @escaping ((Double) -> Void)) throws {\n        var captureType: CameraController.CaptureType = .all\n\n        // check media type\n        switch config.mediaType {\n        case .image:\n            captureType = .photo\n        case .video:\n            captureType = .video\n        default:\n            break\n        }\n\n        // config\n        var cameraConfig = CameraConfiguration()\n\n        cameraConfig.videoMaximumDuration = config.videoMaximumDuration ?? 60\n\n        cameraConfig.modalPresentationStyle = self.setPresentation(config.presentation)\n\n        cameraConfig.editor.modalPresentationStyle = .fullScreen\n\n        if let crop = config.crop {\n            let editor = PickerCropConfig(circle: crop.circle, ratio: crop.ratio, defaultRatio: crop.defaultRatio, freeStyle: crop.freeStyle)\n            cameraConfig.editor = setCropConfig(editor)\n        } else {\n            cameraConfig.allowsEditing = false\n        }\n\n        cameraConfig.languageType = setLocale(language: config.language)\n        cameraConfig.isSaveSystemAlbum = config.isSaveSystemAlbum ?? false\n        cameraConfig.sessionPreset = .hd4K3840x2160\n        cameraConfig.aspectRatio = .fullScreen\n\n        if let color = config.color, let focusColor = getReactColor(Int(color)) {\n            cameraConfig.focusColor = focusColor\n        }\n\n        switch Int(config.cameraDevice?.rawValue ?? 1) {\n        case 0:\n            cameraConfig.position = .front\n        default:\n            cameraConfig.position = .back\n        }\n\n        func getCameraResult(_ result: CameraController.Result, _ asset: PHAsset?) {\n            if let asset {\n                Task {\n                    let photoAsset = PhotoAsset(asset)\n                    let urlResult = try await photoAsset.urlResult()\n                    let path = urlResult.url.absoluteString\n\n                    let phAsset = photoAsset.phAsset\n                    let thumbnail = phAsset?.getVideoAssetThumbnail(from: path, in: 1)\n\n                    resolved(CameraResult(path: path, type: photoAsset.mediaType == .photo ? ResultType.image : ResultType.video, width: photoAsset.imageSize.width, height: photoAsset.imageSize.height, duration: photoAsset.videoDuration, thumbnail: thumbnail, fileName: phAsset?.fileName))\n                }\n\n            } else {\n                switch result {\n                case .image(let uiImage):\n\n                    let fileName = \"IMG_\\(Int(Date().timeIntervalSince1970)).jpg\"\n                    let filePath = uiImage.getPath(fileName: fileName, quality: 1.0)\n\n                    if let filePath {\n                        resolved(CameraResult(path: filePath, type: ResultType.image, width: uiImage.size.width, height: uiImage.size.height, duration: nil, thumbnail: nil, fileName: fileName))\n                    } else {\n                        rejected(1)\n                    }\n\n                case .video(let url):\n\n                    let asset = AVAsset(url: url)\n\n                    let thumbnail = getVideoThumbnail(from: url.absoluteString, in: 1)\n\n                    var result = CameraResult(path: \"file://\\(url.absoluteString)\",\n                                              type: ResultType.video,\n                                              width: nil,\n                                              height: nil,\n                                              duration: asset.duration.seconds,\n                                              thumbnail: thumbnail,\n                                              fileName: url.lastPathComponent)\n\n                    if let track = asset.tracks(withMediaType: AVMediaType.video).first {\n                        let trackSize = track.naturalSize.applying(track.preferredTransform)\n                        let size = CGSize(width: abs(trackSize.width), height: abs(trackSize.height))\n\n                        result.width = Double(size.width)\n                        result.height = Double(size.height)\n                    }\n\n                    resolved(result)\n                }\n            }\n        }\n\n        DispatchQueue.main.async {\n            Photo.capture(cameraConfig, type: captureType) { result, asset, _ in\n                getCameraResult(result, asset)\n            }\n        }\n    }\n\n    func setCameraConfig(_ options: PickerCameraConfig) -> SystemCameraConfiguration {\n        var config = SystemCameraConfiguration()\n\n        config.editExportPreset = .highQuality\n        config.videoQuality = .typeHigh\n\n        switch Int(options.cameraDevice?.rawValue ?? 1) {\n        case 0:\n            config.cameraDevice = .front\n        default:\n            config.cameraDevice = .rear\n        }\n\n        config.videoMaximumDuration = options.videoMaximumDuration ?? 60\n\n        return config\n    }\n}\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker+Config.swift",
    "content": "//\n//  HybridMultipleImagePicker+Config.swift\n//  react-native-multiple-image-picker\n//\n//  Created by BAO HA on 15/10/2024.\n//\n\nimport HXPhotoPicker\nimport UIKit\n\n// Swift enum\n// @objc enum MediaType: SelectBoxView.Style\n\nextension HybridMultipleImagePicker {\n    func setConfig(_ options: NitroConfig) {\n        config = PickerConfiguration.default\n\n        var photoList = config.photoList\n        var previewView = config.previewView\n\n        if let spacing = options.spacing { photoList.spacing = spacing }\n        if let rowNumber = options.numberOfColumn { photoList.rowNumber = Int(rowNumber) }\n\n        if let isHiddenPreviewButton = options.isHiddenPreviewButton {\n            previewView.bottomView.isHiddenPreviewButton = isHiddenPreviewButton\n            photoList.bottomView.isHiddenOriginalButton = isHiddenPreviewButton\n        }\n\n        if let isHiddenOriginalButton = options.isHiddenOriginalButton {\n            previewView.bottomView.isHiddenOriginalButton = isHiddenOriginalButton\n            photoList.bottomView.isHiddenOriginalButton = isHiddenOriginalButton\n        }\n\n        photoList.allowHapticTouchPreview = options.allowHapticTouchPreview ?? true\n\n        photoList.allowSwipeToSelect = options.allowSwipeToSelect ?? true\n\n        photoList.allowAddLimit = options.allowedLimit ?? true\n\n        // check media type\n        switch options.mediaType {\n        case .image:\n            config.selectOptions = [.photo, .livePhoto, .gifPhoto]\n        case .video:\n            config.selectOptions = .video\n        default:\n            config.selectOptions = [.video, .photo, .gifPhoto, .livePhoto]\n        }\n\n        config.indicatorType = .system\n        config.photoList.cell.kf_indicatorColor = .black\n\n        if let boxStyle = SelectBoxView.Style(rawValue: Int(options.selectBoxStyle.rawValue)) {\n            previewView.selectBox.style = boxStyle\n            photoList.cell.selectBox.style = boxStyle\n        }\n\n        photoList.isShowFilterItem = false\n        photoList.sort = .desc\n        photoList.isShowAssetNumber = false\n\n        previewView.disableFinishButtonWhenNotSelected = false\n\n        if let selectMode = PickerSelectMode(rawValue: Int(options.selectMode.rawValue)) {\n            config.selectMode = selectMode\n        }\n\n        if let maxFileSize = options.maxFileSize {\n            config.maximumSelectedPhotoFileSize = Int(maxFileSize)\n            config.maximumSelectedVideoFileSize = Int(maxFileSize)\n        }\n\n        // Setting for video\n        if options.mediaType == .all || options.mediaType == .video {\n            if let maxVideo = options.maxVideo {\n                config.maximumSelectedVideoCount = Int(maxVideo)\n            }\n\n            if let maxVideoDuration = options.maxVideoDuration {\n                config.maximumSelectedVideoDuration = Int(maxVideoDuration)\n            }\n\n            if let minVideoDuration = options.minVideoDuration {\n                config.minimumSelectedVideoDuration = Int(minVideoDuration)\n            }\n        }\n\n        if let maxSelect = options.maxSelect {\n            config.maximumSelectedCount = Int(maxSelect)\n        }\n\n        config.allowSyncICloudWhenSelectPhoto = true\n\n        config.allowCustomTransitionAnimation = true\n\n        config.isSelectedOriginal = false\n\n        let isPreview = options.isPreview ?? true\n\n        previewView.bottomView.isShowPreviewList = isPreview\n        photoList.bottomView.isHiddenPreviewButton = !isPreview\n        photoList.allowHapticTouchPreview = isPreview\n        photoList.bottomView.previewListTickColor = .clear\n        photoList.bottomView.isShowSelectedView = isPreview\n\n        if isPreview {\n            config.videoSelectionTapAction = .preview\n            config.photoSelectionTapAction = .preview\n        } else {\n            config.videoSelectionTapAction = .quickSelect\n            config.photoSelectionTapAction = .quickSelect\n        }\n\n        config.editorOptions = [.photo, .gifPhoto, .livePhoto]\n\n        if let crop = options.crop {\n            config.editor = setCropConfig(crop)\n        } else {\n            previewView.bottomView.isHiddenEditButton = true\n        }\n\n        photoList.finishSelectionAfterTakingPhoto = true\n\n        if let cameraOption = options.camera {\n            photoList.allowAddCamera = true\n\n            photoList.cameraType = .system(setCameraConfig(cameraOption))\n        } else {\n            photoList.allowAddCamera = false\n        }\n\n        config.photoList = photoList\n        config.previewView = previewView\n\n        setLanguage(options)\n        setTheme(options)\n\n        config.modalPresentationStyle = setPresentation(options.presentation)\n    }\n\n    private func setTheme(_ options: NitroConfig) {\n        let isDark = options.theme == Theme.dark\n\n        // custom background dark\n        if let background = options.backgroundDark, let backgroundDark = getReactColor(Int(background)), isDark {\n            config.photoList.backgroundDarkColor = backgroundDark\n            config.photoList.backgroundColor = backgroundDark\n        }\n\n        // LIGHT THEME\n        if !isDark {\n            let background = UIColor.white\n            let barStyle = UIBarStyle.default\n\n            config.statusBarStyle = .darkContent\n            config.appearanceStyle = .normal\n            config.photoList.bottomView.barStyle = barStyle\n            config.navigationBarStyle = barStyle\n            config.previewView.bottomView.barStyle = barStyle\n            config.previewView.backgroundColor = background\n            config.previewView.bottomView.backgroundColor = background\n\n            config.photoList.leftNavigationItems = [PhotoCancelItem.self]\n\n            config.photoList.backgroundColor = .white\n            config.photoList.emptyView.titleColor = .black\n            config.photoList.emptyView.subTitleColor = .darkGray\n            config.photoList.titleView.backgroundColor = UIColor.black.withAlphaComponent(0.5)\n\n            config.albumList.backgroundColor = .white\n            config.albumList.cellBackgroundColor = .white\n            config.albumList.albumNameColor = .black\n            config.albumList.photoCountColor = .black\n            config.albumList.cellSelectedColor = \"#e1e1e1\".hx.color\n            config.albumList.separatorLineColor = \"#e1e1e1\".hx.color\n        }\n\n        if let primaryColor = options.primaryColor, let color = getReactColor(Int(primaryColor)) {\n            config.setThemeColor(color)\n        }\n\n        config.navigationTitleColor = .white\n        config.photoList.titleView.arrow.arrowColor = .white\n        config.photoList.cell.customSelectableCellClass = nil\n    }\n\n    func setPresentation(_ presentation: Presentation?) -> UIModalPresentationStyle {\n        if let presentation {\n            switch Int(presentation.rawValue) {\n            case 1:\n                return .formSheet\n            default:\n                return .fullScreen\n            }\n        }\n\n        return .fullScreen\n    }\n\n    private func setLanguage(_ options: NitroConfig) {\n        if let text = options.text {\n            if let finish = text.finish {\n                config.textManager.picker.photoList.bottomView.finishTitle = .custom(finish)\n                config.textManager.picker.preview.bottomView.finishTitle = .custom(finish)\n                config.textManager.editor.crop.maskListFinishTitle = .custom(finish)\n            }\n\n            if let original = text.original {\n                config.textManager.picker.photoList.bottomView.originalTitle = .custom(original)\n                config.textManager.picker.preview.bottomView.originalTitle = .custom(original)\n            }\n\n            if let preview = text.preview {\n                config.textManager.picker.photoList.bottomView.previewTitle = .custom(preview)\n            }\n\n            if let edit = text.edit {\n                config.textManager.picker.preview.bottomView.editTitle = .custom(edit)\n            }\n        }\n\n        config.languageType = setLocale(language: options.language)\n    }\n\n    func setLocale(language: Language) -> LanguageType {\n        switch language {\n        case .vi:\n            return .vietnamese // -> 🇻🇳 My country. Yeahhh\n        case .zhHans:\n            return .simplifiedChinese\n        case .zhHant:\n            return .traditionalChinese\n        case .ja:\n            return .japanese\n        case .ko:\n            return .korean\n        case .en:\n            return .english\n        case .th:\n            return .thai\n        case .id:\n            return .indonesia\n        case .ru:\n            return .russian\n        case .de:\n            return .german\n        case .fr:\n            return .french\n        case .ar:\n            return .arabic\n        default:\n            return .system\n        }\n    }\n}\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker+Crop.swift",
    "content": "//\n//  HybridMultipleImagePicker+Crop.swift\n//  Pods\n//\n//  Created by BAO HA on 9/12/24.\n//\n\nimport HXPhotoPicker\n\nextension HybridMultipleImagePicker {\n    func openCrop(image: String, config: NitroCropConfig, resolved: @escaping ((CropResult) -> Void), rejected: @escaping ((Double) -> Void)) throws {\n        let asset: EditorAsset\n\n        if image.hasPrefix(\"http://\") || image.hasPrefix(\"https://\") || image.hasPrefix(\"file://\") {\n            guard let url = URL(string: image),\n                  let data = try? Data(contentsOf: url)\n\n            else {\n                rejected(0)\n                return\n            }\n\n            asset = .init(type: .imageData(data))\n        } else {\n            asset = .init(type: .photoAsset(.init(localIdentifier: image)))\n        }\n\n        let cropOption = PickerCropConfig(circle: config.circle, ratio: config.ratio, defaultRatio: config.defaultRatio, freeStyle: config.freeStyle)\n\n        var editConfig = setCropConfig(cropOption)\n\n        editConfig.languageType = setLocale(language: config.language)\n\n        DispatchQueue.main.async {\n            Photo.edit(asset: asset, config: editConfig) { result, _ in\n\n                if let path = result.result?.url.absoluteString, let size = result.result?.image?.size {\n                    let result = CropResult(path: path, width: size.width, height: size.height)\n\n                    resolved(result)\n                }\n            }\n        }\n    }\n\n    func setCropConfig(_ cropConfig: PickerCropConfig) -> EditorConfiguration {\n        var config = EditorConfiguration()\n\n        if let defaultRatio = cropConfig.defaultRatio {\n            config.cropSize.aspectRatio = .init(width: defaultRatio.width, height: defaultRatio.height)\n        }\n\n        config.photo.defaultSelectedToolOption = .cropSize\n\n        config.isFixedCropSizeState = true\n\n        config.cropSize.defaultSeletedIndex = 0\n\n        let freeStyle = cropConfig.freeStyle ?? true\n\n        config.cropSize.isFixedRatio = !freeStyle\n\n        config.isWhetherFinishButtonDisabledInUneditedState = true\n\n        config.cropSize.isRoundCrop = cropConfig.circle ?? false\n\n        config.cropSize.isResetToOriginal = true\n\n        config.toolsView = .init(toolOptions: [.init(imageType: PickerConfiguration.default.editor.imageResource.editor.tools.cropSize, type: .cropSize)])\n\n        config.photo.defaultSelectedToolOption = .cropSize\n\n        if config.cropSize.isRoundCrop {\n            config.cropSize.aspectRatios = []\n        } else {\n            var aspectRatios: [EditorRatioToolConfig] = PickerConfiguration.default.editor.cropSize.aspectRatios\n\n            let ratio = cropConfig.ratio\n            // custom ratio\n            if ratio.count > 0 {\n                ratio.forEach { ratio in\n                    let width = Int(ratio.width)\n                    let height = Int(ratio.height)\n\n                    aspectRatios.insert(.init(title: .custom(ratio.title ?? \"\\(width)/\\(height)\"), ratio: .init(width: width, height: height)), at: 3)\n                }\n            }\n\n            config.cropSize.aspectRatios = freeStyle ? aspectRatios : aspectRatios.filter {\n                // check freeStyle crop\n                if $0.ratio == .zero { return false }\n\n                return true\n            }\n        }\n\n        return config\n    }\n}\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker+Preview.swift",
    "content": "//\n//  HybridMultipleImagePicker+Preview.swift\n//  Pods\n//\n//  Created by BAO HA on 11/12/24.\n//\n\nimport HXPhotoPicker\n\nextension HybridMultipleImagePicker {\n    func openPreview(media: [MediaPreview], index: Double, config: NitroPreviewConfig, onLongPress: @escaping ((Double) -> Void)) throws {\n        var previewConfig = HXPhotoPicker.PhotoBrowser.Configuration()\n        previewConfig.showDelete = false\n\n        var assets: [PhotoAsset] = []\n\n        previewConfig.tintColor = .white\n        previewConfig.videoPlayType = config.videoAutoPlay == true ? .auto : .normal\n        previewConfig.livePhotoPlayType = .auto\n\n        previewConfig.languageType = setLocale(language: config.language)\n\n        media.forEach { mediaItem in\n\n            var asset: PhotoAsset?\n\n            if let localIdentifier = mediaItem.localIdentifier {\n                asset = .init(localIdentifier: localIdentifier)\n\n                // auto play gif\n                if let filePath = mediaItem.path,\n                   let url = URL(string: filePath), isGifFile(url) == true\n                {\n                    asset = .init(.init(imageURL: url))\n                }\n\n            } else if let path = mediaItem.path, let url = URL(string: path) {\n                let thumbnail = URL(string: mediaItem.thumbnail ?? \"\") ?? url\n\n                if mediaItem.type == .image {\n                    // network asset\n                    if path.hasPrefix(\"https://\") || path.hasPrefix(\"http://\") {\n                        asset = PhotoAsset(NetworkImageAsset(\n                            thumbnailURL: thumbnail,\n                            originalURL: url,\n                            thumbnailLoadMode: .alwaysThumbnail,\n                            originalLoadMode: .alwaysThumbnail\n                        ))\n\n                    } else {\n                        asset = .init(.init(imageURL: url))\n                    }\n                } else {\n                    asset = .init(networkVideoAsset: .init(videoURL: url, coverImageURL: thumbnail))\n                }\n            }\n\n            if let asset {\n                assets.append(asset)\n            }\n        }\n\n        if Int(index) > assets.count - 1 { return }\n\n        DispatchQueue.main.async {\n            HXPhotoPicker.PhotoBrowser.show(\n                assets,\n                pageIndex: Int(index),\n                config: previewConfig,\n                longPressHandler: { index, _, _ in\n                    onLongPress(Double(index))\n                }\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker+Result.swift",
    "content": "//\n//  HybridMultipleImagePicker+Result.swift\n//  Pods\n//\n//  Created by BAO HA on 24/10/24.\n//\n\nimport HXPhotoPicker\n\nextension HybridMultipleImagePicker {\n    func getResult(_ asset: PhotoAsset) async throws -> PickerResult {\n        let urlResult = try await asset.urlResult()\n        let url = urlResult.url\n\n        let creationDate = Int(asset.phAsset?.creationDate?.timeIntervalSince1970 ?? 0)\n\n        let mime = url.getMimeType()\n\n        let phAsset = asset.phAsset\n\n        let type: ResultType = .init(fromString: asset.mediaType == .video ? \"video\" : \"image\")!\n        let thumbnail = asset.phAsset?.getVideoAssetThumbnail(from: url.absoluteString, in: 1)\n\n        return PickerResult(localIdentifier: phAsset!.localIdentifier,\n                            width: asset.imageSize.width,\n                            height: asset.imageSize.height,\n                            mime: mime,\n                            size: Double(asset.fileSize),\n                            bucketId: nil,\n                            realPath: nil,\n                            parentFolderName: nil,\n                            creationDate: creationDate > 0 ? Double(creationDate) : nil,\n                            crop: false,\n                            path: \"file://\\(url.absoluteString)\",\n                            type: type,\n                            duration: asset.videoDuration,\n                            thumbnail: thumbnail,\n                            fileName: phAsset?.fileName)\n    }\n}\n"
  },
  {
    "path": "ios/HybridMultipleImagePicker.swift",
    "content": "//\n//  HybridMultipleImagePicker.swift\n//\n//  Created by Marc Rousavy on 18.07.24.\n//\n\nimport Foundation\nimport HXPhotoPicker\nimport NitroModules\nimport Photos\n\nclass HybridMultipleImagePicker: HybridMultipleImagePickerSpec {\n    var selectedAssets: [PhotoAsset] = .init()\n\n    var config: PickerConfiguration = .init()\n\n    func openPicker(config: NitroConfig, resolved: @escaping (([PickerResult]) -> Void), rejected: @escaping ((Double) -> Void)) throws {\n        setConfig(config)\n\n        // get selected photo\n        selectedAssets = selectedAssets.filter { asset in\n            config.selectedAssets.contains {\n                $0.localIdentifier == asset.phAsset?.localIdentifier\n            }\n        }\n\n        DispatchQueue.main.async {\n            Photo.picker(\n                self.config,\n                selectedAssets: self.selectedAssets\n            ) { pickerResult, controller in\n\n                controller.autoDismiss = false\n\n                // check crop for single\n                if let asset = pickerResult.photoAssets.first, config.selectMode == .single, config.crop != nil, asset.mediaType == .photo, asset.editedResult?.url == nil {\n                    // open crop\n                    Photo.edit(asset: .init(type: .photoAsset(asset)), config: self.config.editor, sender: controller) { editedResult, _ in\n\n                        if let photoAsset = pickerResult.photoAssets.first, let result = editedResult.result {\n                            photoAsset.editedResult = .some(result)\n\n                            Task {\n                                let resultData = try await self.getResult(photoAsset)\n\n                                DispatchQueue.main.async {\n                                    resolved([resultData])\n                                    controller.dismiss(true)\n                                }\n                            }\n                        }\n                    }\n\n                    return\n                }\n\n                // show alert view\n                let alert = UIAlertController(title: nil, message: \"Loading...\", preferredStyle: .alert)\n                alert.showLoading()\n                controller.present(alert, animated: true)\n\n                let group = DispatchGroup()\n\n                var data: [PickerResult] = []\n\n                self.selectedAssets = pickerResult.photoAssets\n\n                Task {\n                    for response in pickerResult.photoAssets {\n                        group.enter()\n\n                        let resultData = try await self.getResult(response)\n\n                        data.append(resultData)\n                        group.leave()\n                    }\n\n                    DispatchQueue.main.async {\n                        alert.dismiss(animated: true) {\n                            controller.dismiss(true)\n                            resolved(data)\n                        }\n                    }\n                }\n\n            } cancel: { cancel in\n                cancel.autoDismiss = true\n            }\n        }\n    }\n}\n\nextension UIAlertController {\n    func showLoading() {\n        let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))\n\n        loadingIndicator.hidesWhenStopped = true\n        loadingIndicator.style = UIActivityIndicatorView.Style.medium\n\n        if #available(iOS 13.0, *) {\n            loadingIndicator.color = .secondaryLabel\n        } else {\n            loadingIndicator.color = .black\n        }\n\n        loadingIndicator.startAnimating()\n\n        view.addSubview(loadingIndicator)\n    }\n}\n"
  },
  {
    "path": "ios/MultipleImagePickerOnLoad.mm",
    "content": "//\n//  MultipleImagePickerOnLoad.mm\n//  MultipleImagePicker\n//\n//  Created by Marc Rousavy on 22.07.24.\n//\n\n#import <Foundation/Foundation.h>\n#import <NitroModules/HybridObjectRegistry.hpp>\n#import \"React/RCTBridgeModule.h\"\n\n@interface MultipleImagePickerOnLoad : NSObject\n@end\n\n@implementation MultipleImagePickerOnLoad\n\nusing namespace margelo::nitro;\n\n+ (void)load {\n  // TODO: Register all Swift Hybrid Objects here\n  // TODO: Register all C++ Hybrid Objects here\n}\n\n@end\n"
  },
  {
    "path": "ios/PHAsset+Thumbnail.swift",
    "content": "//\n//  PHAsset+Thumbnail.swift\n//  Pods\n//\n//  Created by BAO HA on 24/10/24.\n//\n\nimport Photos\n\nextension PHAsset {\n    func getVideoAssetThumbnail(from moviePath: String, in seconds: Double) -> String? {\n        if mediaType == .video {\n            if let path = getVideoThumbnail(from: moviePath, in: seconds) {\n                return \"file://\\(path)\"\n            }\n        }\n\n        return nil\n    }\n\n    var fileName: String {\n        if let resources = PHAssetResource.assetResources(for: self).first {\n            return resources.originalFilename\n        }\n\n        return \"\"\n    }\n}\n\nfunc getVideoThumbnail(from moviePath: String, in seconds: Double) -> String? {\n    let filepath = moviePath.replacingOccurrences(of: \"file://\", with: \"\")\n    let vidURL = URL(fileURLWithPath: filepath)\n\n    let asset = AVURLAsset(url: vidURL, options: nil)\n    let generator = AVAssetImageGenerator(asset: asset)\n    generator.appliesPreferredTrackTransform = true\n\n    let time = CMTime(seconds: seconds, preferredTimescale: 600)\n\n    var thumbnail: UIImage?\n\n    do {\n        let imgRef = try generator.copyCGImage(at: time, actualTime: nil)\n        thumbnail = UIImage(cgImage: imgRef)\n    } catch {\n        print(\"Error create thumbnail: \\(error)\")\n        return nil\n    }\n\n    if let thumbnail {\n        return thumbnail.getPath(fileName: nil, quality: 0.8)\n    }\n\n    return nil\n}\n"
  },
  {
    "path": "ios/PhotoCancelItem.swift",
    "content": "//\n//  PhotoCancelItem.swift\n//  Pods\n//\n//  Created by BAO HA on 4/12/24.\n//\n\nimport HXPhotoPicker\nimport UIKit\n\nextension UIView: HXPickerCompatible {\n    var size: CGSize {\n        get { frame.size }\n        set {\n            var rect = frame\n            rect.size = newValue\n            frame = rect\n        }\n    }\n}\n\npublic class PhotoCancelItem: UIView, PhotoNavigationItem {\n    public weak var itemDelegate: PhotoNavigationItemDelegate?\n    public var itemType: PhotoNavigationItemType { .cancel }\n    \n    let config: PickerConfiguration\n    public required init(config: PickerConfiguration) {\n        self.config = config\n        super.init(frame: .zero)\n        initView()\n    }\n    \n    var button: UIButton!\n    func initView() {\n        button = UIButton(type: .custom)\n    \n        button.setImage(UIImage.close, for: .normal)\n        \n        button.addTarget(self, action: #selector(didCancelClick), for: .touchUpInside)\n        \n        addSubview(button)\n        \n        if let btnSize = button.currentImage?.size {\n            button.size = btnSize\n            size = btnSize\n        }\n    }\n    \n    @objc\n    func didCancelClick() {\n        print(\"close ne\")\n        itemDelegate?.photoControllerDidCancel()\n    }\n\n    @available(*, unavailable)\n    required init?(coder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n}\n"
  },
  {
    "path": "ios/TopViewController.swift",
    "content": "//\n//  TopViewController.swift\n//  Pods\n//\n//  Created by BAO HA on 11/12/24.\n//\n\nimport UIKit\n\nfunc getTopViewController() -> UIViewController? {\n    var controller = UIApplication.shared.keyWindow?.rootViewController\n    while let presentedViewController = controller?.presentedViewController {\n        controller = presentedViewController\n    }\n\n    return controller\n}\n"
  },
  {
    "path": "ios/UIColor+Hex.swift",
    "content": "//\n//  UIColor+Hex.swift\n//  react-native-multiple-image-picker\n//\n//  Created by BAO HA on 15/10/2024.\n//\n\nimport UIKit\n\nextension UIColor {\n    convenience init(hex: String, alpha: CGFloat = 1.0) {\n        var cString: String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()\n        var rgbValue: UInt32 = 10066329 // color #999999 if string has wrong format\n\n        if cString.hasPrefix(\"#\") {\n            cString.remove(at: cString.startIndex)\n        }\n\n        if (cString.count) == 6 {\n            Scanner(string: cString).scanHexInt32(&rgbValue)\n        }\n\n        self.init(\n            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,\n            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,\n            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,\n            alpha: alpha\n        )\n    }\n}\n"
  },
  {
    "path": "ios/UIColor+React.swift",
    "content": "//\n//  UIColor+React.swift\n//  Pods\n//\n//  Created by BAO HA on 16/10/24.\n//\n\nimport React\nimport UIKit\n\nfunc getReactColor(_ color: Int?) -> UIColor? {\n    RCTConvert.uiColor(color)\n}\n"
  },
  {
    "path": "ios/UIImage.swift",
    "content": "//\n//  UIImage.swift\n//  Pods\n//\n//  Created by BAO HA on 16/12/24.\n//\n\nextension UIImage {\n    func getPath(fileName name: String? = nil, quality: CGFloat = 1.0) -> String? {\n        let tempDirectoryURL = FileManager.default.temporaryDirectory\n\n        let data = self.jpegData(compressionQuality: 0.9)\n\n        let fileName = name ?? \"IMG_\\(Int(Date().timeIntervalSince1970)).jpg\"\n\n        let fileURL = tempDirectoryURL.appendingPathComponent(fileName)\n\n        if let imageData = self.jpegData(compressionQuality: quality) {\n            do {\n                try imageData.write(to: fileURL)\n                return fileURL.absoluteString\n\n            } catch {\n                return nil\n            }\n        }\n\n        return nil\n    }\n}\n"
  },
  {
    "path": "ios/URL+Mime.swift",
    "content": "//\n//  URL+Mime.swift\n//  Pods\n//\n//  Created by BAO HA on 23/10/24.\n//\n\nimport Foundation\nimport MobileCoreServices\nimport UniformTypeIdentifiers\n\nextension URL {\n    func getMimeType() -> String {\n        let pathExtension = self.pathExtension.lowercased()\n\n        if #available(iOS 14.0, *) {\n            // Sử dụng UniformTypeIdentifiers (UTType) cho iOS 14+\n            if let utType = UTType(filenameExtension: pathExtension) {\n                return utType.preferredMIMEType ?? \"application/octet-stream\"\n            }\n\n        } else {\n            // Sử dụng MobileCoreServices (kUTType) cho iOS 13 trở xuống\n            if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),\n               let mimeType = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue()\n            {\n                return mimeType as String\n            }\n        }\n\n        // Trả về MIME type mặc định nếu không tìm thấy\n        return \"application/octet-stream\"\n    }\n}\n"
  },
  {
    "path": "ios/Utils.swift",
    "content": "//\n//  Utils.swift\n//  Pods\n//\n//  Created by BAO HA on 11/12/24.\n//\n\nimport MobileCoreServices\nimport UniformTypeIdentifiers\n\nfunc isImage(_ urlString: String) -> Bool {\n    guard let url = URL(string: urlString),\n          let pathExtension = url.pathExtension as CFString?,\n          let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil)?\n          .takeRetainedValue()\n    else {\n        return false\n    }\n\n    return UTTypeConformsTo(uti, kUTTypeImage)\n}\n\nfunc isGifFile(_ url: URL) -> Bool {\n    // Kiểm tra phần mở rộng\n    if url.pathExtension.lowercased() == \"gif\" {\n        return true\n    }\n\n    // Kiểm tra UTI\n    let fileExtension = url.pathExtension as CFString\n    guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil)?.takeRetainedValue() else {\n        return false\n    }\n\n    return UTTypeConformsTo(uti, kUTTypeGIF)\n}\n"
  },
  {
    "path": "nitro.json",
    "content": "{\n  \"$schema\": \"https://nitro.margelo.com/nitro.schema.json\",\n  \"cxxNamespace\": [\"multipleimagepicker\"],\n  \"ios\": {\n    \"iosModuleName\": \"MultipleImagePicker\"\n  },\n  \"android\": {\n    \"androidNamespace\": [\"multipleimagepicker\"],\n    \"androidCxxLibName\": \"MultipleImagePicker\"\n  },\n\n  \"autolinking\": {\n    \"MultipleImagePicker\": {\n      \"swift\": \"HybridMultipleImagePicker\",\n      \"kotlin\": \"MultipleImagePicker\"\n    }\n  },\n  \"ignorePaths\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "nitrogen/generated/.gitattributes",
    "content": "* linguist-generated\n"
  },
  {
    "path": "nitrogen/generated/android/MultipleImagePicker+autolinking.cmake",
    "content": "#\n# MultipleImagePicker+autolinking.cmake\n# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n# https://github.com/mrousavy/nitro\n# Copyright © 2025 Marc Rousavy @ Margelo\n#\n\n# This is a CMake file that adds all files generated by Nitrogen\n# to the current CMake project.\n#\n# To use it, add this to your CMakeLists.txt:\n# ```cmake\n# include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/MultipleImagePicker+autolinking.cmake)\n# ```\n\n# Add all headers that were generated by Nitrogen\ninclude_directories(\n  \"../nitrogen/generated/shared/c++\"\n  \"../nitrogen/generated/android/c++\"\n  \"../nitrogen/generated/android/\"\n)\n\n# Add all .cpp sources that were generated by Nitrogen\ntarget_sources(\n  # CMake project name (Android C++ library name)\n  MultipleImagePicker PRIVATE\n  # Autolinking Setup\n  ../nitrogen/generated/android/MultipleImagePickerOnLoad.cpp\n  # Shared Nitrogen C++ sources\n  ../nitrogen/generated/shared/c++/HybridMultipleImagePickerSpec.cpp\n  # Android-specific Nitrogen C++ sources\n  ../nitrogen/generated/android/c++/JHybridMultipleImagePickerSpec.cpp\n)\n\n# Define a flag to check if we are building properly\nadd_definitions(-DBUILDING_MULTIPLEIMAGEPICKER_WITH_GENERATED_CMAKE_PROJECT)\n\n# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake\n# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake\n target_compile_definitions(\n  MultipleImagePicker PRIVATE\n  -DFOLLY_NO_CONFIG=1\n  -DFOLLY_HAVE_CLOCK_GETTIME=1\n  -DFOLLY_USE_LIBCPP=1\n  -DFOLLY_CFG_NO_COROUTINES=1\n  -DFOLLY_MOBILE=1\n  -DFOLLY_HAVE_RECVMMSG=1\n  -DFOLLY_HAVE_PTHREAD=1\n  # Once we target android-23 above, we can comment\n  # the following line. NDK uses GNU style stderror_r() after API 23.\n  -DFOLLY_HAVE_XSI_STRERROR_R=1\n)\n\n# Add all libraries required by the generated specs\nfind_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++\nfind_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule)\nfind_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library\n\n# Link all libraries together\ntarget_link_libraries(\n        MultipleImagePicker\n        fbjni::fbjni                              # <-- Facebook C++ JNI helpers\n        ReactAndroid::jsi                         # <-- RN: JSI\n        react-native-nitro-modules::NitroModules  # <-- NitroModules Core :)\n)\n\n# Link react-native (different prefab between RN 0.75 and RN 0.76)\nif(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)\n    target_link_libraries(\n        MultipleImagePicker\n        ReactAndroid::reactnative                 # <-- RN: Native Modules umbrella prefab\n    )\nelse()\n    target_link_libraries(\n        MultipleImagePicker\n        ReactAndroid::react_nativemodule_core     # <-- RN: TurboModules Core\n    )\nendif()\n"
  },
  {
    "path": "nitrogen/generated/android/MultipleImagePicker+autolinking.gradle",
    "content": "///\n/// MultipleImagePicker+autolinking.gradle\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/// This is a Gradle file that adds all files generated by Nitrogen\n/// to the current Gradle project.\n///\n/// To use it, add this to your build.gradle:\n/// ```gradle\n/// apply from: '../nitrogen/generated/android/MultipleImagePicker+autolinking.gradle'\n/// ```\n\nlogger.warn(\"[NitroModules] 🔥 MultipleImagePicker is boosted by nitro!\")\n\nandroid {\n  sourceSets {\n    main {\n      java.srcDirs += [\n        // Nitrogen files\n        \"${project.projectDir}/../nitrogen/generated/android/kotlin\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/MultipleImagePickerOnLoad.cpp",
    "content": "///\n/// MultipleImagePickerOnLoad.cpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#ifndef BUILDING_MULTIPLEIMAGEPICKER_WITH_GENERATED_CMAKE_PROJECT\n#error MultipleImagePickerOnLoad.cpp is not being built with the autogenerated CMakeLists.txt project. Is a different CMakeLists.txt building this?\n#endif\n\n#include \"MultipleImagePickerOnLoad.hpp\"\n\n#include <jni.h>\n#include <fbjni/fbjni.h>\n#include <NitroModules/HybridObjectRegistry.hpp>\n\n#include \"JHybridMultipleImagePickerSpec.hpp\"\n#include \"JFunc_void_std__vector_PickerResult_.hpp\"\n#include \"JFunc_void_double.hpp\"\n#include \"JFunc_void_CropResult.hpp\"\n#include \"JFunc_void_CameraResult.hpp\"\n#include <NitroModules/JNISharedPtr.hpp>\n#include <NitroModules/DefaultConstructableObject.hpp>\n\nnamespace margelo::nitro::multipleimagepicker {\n\nint initialize(JavaVM* vm) {\n  using namespace margelo::nitro;\n  using namespace margelo::nitro::multipleimagepicker;\n  using namespace facebook;\n\n  return facebook::jni::initialize(vm, [] {\n    // Register native JNI methods\n    margelo::nitro::multipleimagepicker::JHybridMultipleImagePickerSpec::registerNatives();\n    margelo::nitro::multipleimagepicker::JFunc_void_std__vector_PickerResult__cxx::registerNatives();\n    margelo::nitro::multipleimagepicker::JFunc_void_double_cxx::registerNatives();\n    margelo::nitro::multipleimagepicker::JFunc_void_CropResult_cxx::registerNatives();\n    margelo::nitro::multipleimagepicker::JFunc_void_CameraResult_cxx::registerNatives();\n\n    // Register Nitro Hybrid Objects\n    HybridObjectRegistry::registerHybridObjectConstructor(\n      \"MultipleImagePicker\",\n      []() -> std::shared_ptr<HybridObject> {\n        static DefaultConstructableObject<JHybridMultipleImagePickerSpec::javaobject> object(\"com/margelo/nitro/multipleimagepicker/MultipleImagePicker\");\n        auto instance = object.create();\n        auto globalRef = jni::make_global(instance);\n        return JNISharedPtr::make_shared_from_jni<JHybridMultipleImagePickerSpec>(globalRef);\n      }\n    );\n  });\n}\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/MultipleImagePickerOnLoad.hpp",
    "content": "///\n/// MultipleImagePickerOnLoad.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#include <jni.h>\n#include <NitroModules/NitroDefines.hpp>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * Initializes the native (C++) part of MultipleImagePicker, and autolinks all Hybrid Objects.\n   * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`).\n   * Example:\n   * ```cpp (cpp-adapter.cpp)\n   * JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {\n   *   return margelo::nitro::multipleimagepicker::initialize(vm);\n   * }\n   * ```\n   */\n  int initialize(JavaVM* vm);\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JCameraDevice.hpp",
    "content": "///\n/// JCameraDevice.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"CameraDevice.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"CameraDevice\" and the the Kotlin enum \"CameraDevice\".\n   */\n  struct JCameraDevice final: public jni::JavaClass<JCameraDevice> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/CameraDevice;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum CameraDevice.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    CameraDevice toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<CameraDevice>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JCameraDevice> fromCpp(CameraDevice value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldFRONT = clazz->getStaticField<JCameraDevice>(\"FRONT\");\n      static const auto fieldBACK = clazz->getStaticField<JCameraDevice>(\"BACK\");\n      \n      switch (value) {\n        case CameraDevice::FRONT:\n          return clazz->getStaticFieldValue(fieldFRONT);\n        case CameraDevice::BACK:\n          return clazz->getStaticFieldValue(fieldBACK);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JCameraResult.hpp",
    "content": "///\n/// JCameraResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"CameraResult.hpp\"\n\n#include \"JResultType.hpp\"\n#include \"ResultType.hpp\"\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"CameraResult\" and the the Kotlin data class \"CameraResult\".\n   */\n  struct JCameraResult final: public jni::JavaClass<JCameraResult> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/CameraResult;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct CameraResult by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    CameraResult toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldPath = clazz->getField<jni::JString>(\"path\");\n      jni::local_ref<jni::JString> path = this->getFieldValue(fieldPath);\n      static const auto fieldType = clazz->getField<JResultType>(\"type\");\n      jni::local_ref<JResultType> type = this->getFieldValue(fieldType);\n      static const auto fieldWidth = clazz->getField<jni::JDouble>(\"width\");\n      jni::local_ref<jni::JDouble> width = this->getFieldValue(fieldWidth);\n      static const auto fieldHeight = clazz->getField<jni::JDouble>(\"height\");\n      jni::local_ref<jni::JDouble> height = this->getFieldValue(fieldHeight);\n      static const auto fieldDuration = clazz->getField<jni::JDouble>(\"duration\");\n      jni::local_ref<jni::JDouble> duration = this->getFieldValue(fieldDuration);\n      static const auto fieldThumbnail = clazz->getField<jni::JString>(\"thumbnail\");\n      jni::local_ref<jni::JString> thumbnail = this->getFieldValue(fieldThumbnail);\n      static const auto fieldFileName = clazz->getField<jni::JString>(\"fileName\");\n      jni::local_ref<jni::JString> fileName = this->getFieldValue(fieldFileName);\n      return CameraResult(\n        path->toStdString(),\n        type->toCpp(),\n        width != nullptr ? std::make_optional(width->value()) : std::nullopt,\n        height != nullptr ? std::make_optional(height->value()) : std::nullopt,\n        duration != nullptr ? std::make_optional(duration->value()) : std::nullopt,\n        thumbnail != nullptr ? std::make_optional(thumbnail->toStdString()) : std::nullopt,\n        fileName != nullptr ? std::make_optional(fileName->toStdString()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JCameraResult::javaobject> fromCpp(const CameraResult& value) {\n      return newInstance(\n        jni::make_jstring(value.path),\n        JResultType::fromCpp(value.type),\n        value.width.has_value() ? jni::JDouble::valueOf(value.width.value()) : nullptr,\n        value.height.has_value() ? jni::JDouble::valueOf(value.height.value()) : nullptr,\n        value.duration.has_value() ? jni::JDouble::valueOf(value.duration.value()) : nullptr,\n        value.thumbnail.has_value() ? jni::make_jstring(value.thumbnail.value()) : nullptr,\n        value.fileName.has_value() ? jni::make_jstring(value.fileName.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JCropRatio.hpp",
    "content": "///\n/// JCropRatio.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"CropRatio.hpp\"\n\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"CropRatio\" and the the Kotlin data class \"CropRatio\".\n   */\n  struct JCropRatio final: public jni::JavaClass<JCropRatio> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/CropRatio;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct CropRatio by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    CropRatio toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldTitle = clazz->getField<jni::JString>(\"title\");\n      jni::local_ref<jni::JString> title = this->getFieldValue(fieldTitle);\n      static const auto fieldWidth = clazz->getField<double>(\"width\");\n      double width = this->getFieldValue(fieldWidth);\n      static const auto fieldHeight = clazz->getField<double>(\"height\");\n      double height = this->getFieldValue(fieldHeight);\n      return CropRatio(\n        title != nullptr ? std::make_optional(title->toStdString()) : std::nullopt,\n        width,\n        height\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JCropRatio::javaobject> fromCpp(const CropRatio& value) {\n      return newInstance(\n        value.title.has_value() ? jni::make_jstring(value.title.value()) : nullptr,\n        value.width,\n        value.height\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JCropResult.hpp",
    "content": "///\n/// JCropResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"CropResult.hpp\"\n\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"CropResult\" and the the Kotlin data class \"CropResult\".\n   */\n  struct JCropResult final: public jni::JavaClass<JCropResult> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/CropResult;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct CropResult by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    CropResult toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldPath = clazz->getField<jni::JString>(\"path\");\n      jni::local_ref<jni::JString> path = this->getFieldValue(fieldPath);\n      static const auto fieldWidth = clazz->getField<double>(\"width\");\n      double width = this->getFieldValue(fieldWidth);\n      static const auto fieldHeight = clazz->getField<double>(\"height\");\n      double height = this->getFieldValue(fieldHeight);\n      return CropResult(\n        path->toStdString(),\n        width,\n        height\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JCropResult::javaobject> fromCpp(const CropResult& value) {\n      return newInstance(\n        jni::make_jstring(value.path),\n        value.width,\n        value.height\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JFunc_void_CameraResult.hpp",
    "content": "///\n/// JFunc_void_CameraResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include <functional>\n\n#include <functional>\n#include \"CameraResult.hpp\"\n#include \"JCameraResult.hpp\"\n#include <string>\n#include \"ResultType.hpp\"\n#include \"JResultType.hpp\"\n#include <optional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * Represents the Java/Kotlin callback `(result: CameraResult) -> Unit`.\n   * This can be passed around between C++ and Java/Kotlin.\n   */\n  struct JFunc_void_CameraResult: public jni::JavaClass<JFunc_void_CameraResult> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_CameraResult;\";\n\n  public:\n    /**\n     * Invokes the function this `JFunc_void_CameraResult` instance holds through JNI.\n     */\n    void invoke(const CameraResult& result) const {\n      static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JCameraResult> /* result */)>(\"invoke\");\n      method(self(), JCameraResult::fromCpp(result));\n    }\n  };\n\n  /**\n   * An implementation of Func_void_CameraResult that is backed by a C++ implementation (using `std::function<...>`)\n   */\n  struct JFunc_void_CameraResult_cxx final: public jni::HybridClass<JFunc_void_CameraResult_cxx, JFunc_void_CameraResult> {\n  public:\n    static jni::local_ref<JFunc_void_CameraResult::javaobject> fromCpp(const std::function<void(const CameraResult& /* result */)>& func) {\n      return JFunc_void_CameraResult_cxx::newObjectCxxArgs(func);\n    }\n\n  public:\n    /**\n     * Invokes the C++ `std::function<...>` this `JFunc_void_CameraResult_cxx` instance holds.\n     */\n    void invoke_cxx(jni::alias_ref<JCameraResult> result) {\n      _func(result->toCpp());\n    }\n\n  public:\n    [[nodiscard]]\n    inline const std::function<void(const CameraResult& /* result */)>& getFunction() const {\n      return _func;\n    }\n\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_CameraResult_cxx;\";\n    static void registerNatives() {\n      registerHybrid({makeNativeMethod(\"invoke_cxx\", JFunc_void_CameraResult_cxx::invoke_cxx)});\n    }\n\n  private:\n    explicit JFunc_void_CameraResult_cxx(const std::function<void(const CameraResult& /* result */)>& func): _func(func) { }\n\n  private:\n    friend HybridBase;\n    std::function<void(const CameraResult& /* result */)> _func;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JFunc_void_CropResult.hpp",
    "content": "///\n/// JFunc_void_CropResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include <functional>\n\n#include <functional>\n#include \"CropResult.hpp\"\n#include \"JCropResult.hpp\"\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * Represents the Java/Kotlin callback `(result: CropResult) -> Unit`.\n   * This can be passed around between C++ and Java/Kotlin.\n   */\n  struct JFunc_void_CropResult: public jni::JavaClass<JFunc_void_CropResult> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_CropResult;\";\n\n  public:\n    /**\n     * Invokes the function this `JFunc_void_CropResult` instance holds through JNI.\n     */\n    void invoke(const CropResult& result) const {\n      static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JCropResult> /* result */)>(\"invoke\");\n      method(self(), JCropResult::fromCpp(result));\n    }\n  };\n\n  /**\n   * An implementation of Func_void_CropResult that is backed by a C++ implementation (using `std::function<...>`)\n   */\n  struct JFunc_void_CropResult_cxx final: public jni::HybridClass<JFunc_void_CropResult_cxx, JFunc_void_CropResult> {\n  public:\n    static jni::local_ref<JFunc_void_CropResult::javaobject> fromCpp(const std::function<void(const CropResult& /* result */)>& func) {\n      return JFunc_void_CropResult_cxx::newObjectCxxArgs(func);\n    }\n\n  public:\n    /**\n     * Invokes the C++ `std::function<...>` this `JFunc_void_CropResult_cxx` instance holds.\n     */\n    void invoke_cxx(jni::alias_ref<JCropResult> result) {\n      _func(result->toCpp());\n    }\n\n  public:\n    [[nodiscard]]\n    inline const std::function<void(const CropResult& /* result */)>& getFunction() const {\n      return _func;\n    }\n\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_CropResult_cxx;\";\n    static void registerNatives() {\n      registerHybrid({makeNativeMethod(\"invoke_cxx\", JFunc_void_CropResult_cxx::invoke_cxx)});\n    }\n\n  private:\n    explicit JFunc_void_CropResult_cxx(const std::function<void(const CropResult& /* result */)>& func): _func(func) { }\n\n  private:\n    friend HybridBase;\n    std::function<void(const CropResult& /* result */)> _func;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JFunc_void_double.hpp",
    "content": "///\n/// JFunc_void_double.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include <functional>\n\n#include <functional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * Represents the Java/Kotlin callback `(index: Double) -> Unit`.\n   * This can be passed around between C++ and Java/Kotlin.\n   */\n  struct JFunc_void_double: public jni::JavaClass<JFunc_void_double> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_double;\";\n\n  public:\n    /**\n     * Invokes the function this `JFunc_void_double` instance holds through JNI.\n     */\n    void invoke(double index) const {\n      static const auto method = javaClassStatic()->getMethod<void(double /* index */)>(\"invoke\");\n      method(self(), index);\n    }\n  };\n\n  /**\n   * An implementation of Func_void_double that is backed by a C++ implementation (using `std::function<...>`)\n   */\n  struct JFunc_void_double_cxx final: public jni::HybridClass<JFunc_void_double_cxx, JFunc_void_double> {\n  public:\n    static jni::local_ref<JFunc_void_double::javaobject> fromCpp(const std::function<void(double /* index */)>& func) {\n      return JFunc_void_double_cxx::newObjectCxxArgs(func);\n    }\n\n  public:\n    /**\n     * Invokes the C++ `std::function<...>` this `JFunc_void_double_cxx` instance holds.\n     */\n    void invoke_cxx(double index) {\n      _func(index);\n    }\n\n  public:\n    [[nodiscard]]\n    inline const std::function<void(double /* index */)>& getFunction() const {\n      return _func;\n    }\n\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_double_cxx;\";\n    static void registerNatives() {\n      registerHybrid({makeNativeMethod(\"invoke_cxx\", JFunc_void_double_cxx::invoke_cxx)});\n    }\n\n  private:\n    explicit JFunc_void_double_cxx(const std::function<void(double /* index */)>& func): _func(func) { }\n\n  private:\n    friend HybridBase;\n    std::function<void(double /* index */)> _func;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JFunc_void_std__vector_PickerResult_.hpp",
    "content": "///\n/// JFunc_void_std__vector_PickerResult_.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include <functional>\n\n#include <functional>\n#include <vector>\n#include \"PickerResult.hpp\"\n#include \"JPickerResult.hpp\"\n#include <string>\n#include <optional>\n#include \"ResultType.hpp\"\n#include \"JResultType.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * Represents the Java/Kotlin callback `(result: Array<PickerResult>) -> Unit`.\n   * This can be passed around between C++ and Java/Kotlin.\n   */\n  struct JFunc_void_std__vector_PickerResult_: public jni::JavaClass<JFunc_void_std__vector_PickerResult_> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_std__vector_PickerResult_;\";\n\n  public:\n    /**\n     * Invokes the function this `JFunc_void_std__vector_PickerResult_` instance holds through JNI.\n     */\n    void invoke(const std::vector<PickerResult>& result) const {\n      static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JPickerResult>> /* result */)>(\"invoke\");\n      method(self(), [&]() {\n        size_t __size = result.size();\n        jni::local_ref<jni::JArrayClass<JPickerResult>> __array = jni::JArrayClass<JPickerResult>::newArray(__size);\n        for (size_t __i = 0; __i < __size; __i++) {\n          const auto& __element = result[__i];\n          __array->setElement(__i, *JPickerResult::fromCpp(__element));\n        }\n        return __array;\n      }());\n    }\n  };\n\n  /**\n   * An implementation of Func_void_std__vector_PickerResult_ that is backed by a C++ implementation (using `std::function<...>`)\n   */\n  struct JFunc_void_std__vector_PickerResult__cxx final: public jni::HybridClass<JFunc_void_std__vector_PickerResult__cxx, JFunc_void_std__vector_PickerResult_> {\n  public:\n    static jni::local_ref<JFunc_void_std__vector_PickerResult_::javaobject> fromCpp(const std::function<void(const std::vector<PickerResult>& /* result */)>& func) {\n      return JFunc_void_std__vector_PickerResult__cxx::newObjectCxxArgs(func);\n    }\n\n  public:\n    /**\n     * Invokes the C++ `std::function<...>` this `JFunc_void_std__vector_PickerResult__cxx` instance holds.\n     */\n    void invoke_cxx(jni::alias_ref<jni::JArrayClass<JPickerResult>> result) {\n      _func([&]() {\n              size_t __size = result->size();\n              std::vector<PickerResult> __vector;\n              __vector.reserve(__size);\n              for (size_t __i = 0; __i < __size; __i++) {\n                auto __element = result->getElement(__i);\n                __vector.push_back(__element->toCpp());\n              }\n              return __vector;\n            }());\n    }\n\n  public:\n    [[nodiscard]]\n    inline const std::function<void(const std::vector<PickerResult>& /* result */)>& getFunction() const {\n      return _func;\n    }\n\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Func_void_std__vector_PickerResult__cxx;\";\n    static void registerNatives() {\n      registerHybrid({makeNativeMethod(\"invoke_cxx\", JFunc_void_std__vector_PickerResult__cxx::invoke_cxx)});\n    }\n\n  private:\n    explicit JFunc_void_std__vector_PickerResult__cxx(const std::function<void(const std::vector<PickerResult>& /* result */)>& func): _func(func) { }\n\n  private:\n    friend HybridBase;\n    std::function<void(const std::vector<PickerResult>& /* result */)> _func;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JHybridMultipleImagePickerSpec.cpp",
    "content": "///\n/// JHybridMultipleImagePickerSpec.cpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#include \"JHybridMultipleImagePickerSpec.hpp\"\n\n// Forward declaration of `NitroConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroConfig; }\n// Forward declaration of `MediaType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class MediaType; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n// Forward declaration of `SelectBoxStyle` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectBoxStyle; }\n// Forward declaration of `SelectMode` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectMode; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n// Forward declaration of `Text` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct Text; }\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `Theme` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Theme; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `PickerCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCameraConfig; }\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n// Forward declaration of `NitroCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCropConfig; }\n// Forward declaration of `CropResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropResult; }\n// Forward declaration of `MediaPreview` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct MediaPreview; }\n// Forward declaration of `NitroPreviewConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroPreviewConfig; }\n// Forward declaration of `NitroCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCameraConfig; }\n// Forward declaration of `CameraResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CameraResult; }\n\n#include \"NitroConfig.hpp\"\n#include \"JNitroConfig.hpp\"\n#include \"MediaType.hpp\"\n#include \"JMediaType.hpp\"\n#include <vector>\n#include \"PickerResult.hpp\"\n#include \"JPickerResult.hpp\"\n#include <string>\n#include <optional>\n#include \"ResultType.hpp\"\n#include \"JResultType.hpp\"\n#include \"SelectBoxStyle.hpp\"\n#include \"JSelectBoxStyle.hpp\"\n#include \"SelectMode.hpp\"\n#include \"JSelectMode.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"JPickerCropConfig.hpp\"\n#include \"CropRatio.hpp\"\n#include \"JCropRatio.hpp\"\n#include \"Text.hpp\"\n#include \"JText.hpp\"\n#include \"Language.hpp\"\n#include \"JLanguage.hpp\"\n#include \"Theme.hpp\"\n#include \"JTheme.hpp\"\n#include \"Presentation.hpp\"\n#include \"JPresentation.hpp\"\n#include \"PickerCameraConfig.hpp\"\n#include \"JPickerCameraConfig.hpp\"\n#include \"CameraDevice.hpp\"\n#include \"JCameraDevice.hpp\"\n#include <functional>\n#include \"JFunc_void_std__vector_PickerResult_.hpp\"\n#include \"JFunc_void_double.hpp\"\n#include \"NitroCropConfig.hpp\"\n#include \"JNitroCropConfig.hpp\"\n#include \"CropResult.hpp\"\n#include \"JFunc_void_CropResult.hpp\"\n#include \"JCropResult.hpp\"\n#include \"MediaPreview.hpp\"\n#include \"JMediaPreview.hpp\"\n#include \"NitroPreviewConfig.hpp\"\n#include \"JNitroPreviewConfig.hpp\"\n#include \"NitroCameraConfig.hpp\"\n#include \"JNitroCameraConfig.hpp\"\n#include \"CameraResult.hpp\"\n#include \"JFunc_void_CameraResult.hpp\"\n#include \"JCameraResult.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  jni::local_ref<JHybridMultipleImagePickerSpec::jhybriddata> JHybridMultipleImagePickerSpec::initHybrid(jni::alias_ref<jhybridobject> jThis) {\n    return makeCxxInstance(jThis);\n  }\n\n  void JHybridMultipleImagePickerSpec::registerNatives() {\n    registerHybrid({\n      makeNativeMethod(\"initHybrid\", JHybridMultipleImagePickerSpec::initHybrid),\n    });\n  }\n\n  size_t JHybridMultipleImagePickerSpec::getExternalMemorySize() noexcept {\n    static const auto method = javaClassStatic()->getMethod<jlong()>(\"getMemorySize\");\n    return method(_javaPart);\n  }\n\n  // Properties\n  \n\n  // Methods\n  void JHybridMultipleImagePickerSpec::openPicker(const NitroConfig& config, const std::function<void(const std::vector<PickerResult>& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) {\n    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JNitroConfig> /* config */, jni::alias_ref<JFunc_void_std__vector_PickerResult_::javaobject> /* resolved */, jni::alias_ref<JFunc_void_double::javaobject> /* rejected */)>(\"openPicker_cxx\");\n    method(_javaPart, JNitroConfig::fromCpp(config), JFunc_void_std__vector_PickerResult__cxx::fromCpp(resolved), JFunc_void_double_cxx::fromCpp(rejected));\n  }\n  void JHybridMultipleImagePickerSpec::openCrop(const std::string& image, const NitroCropConfig& config, const std::function<void(const CropResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) {\n    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* image */, jni::alias_ref<JNitroCropConfig> /* config */, jni::alias_ref<JFunc_void_CropResult::javaobject> /* resolved */, jni::alias_ref<JFunc_void_double::javaobject> /* rejected */)>(\"openCrop_cxx\");\n    method(_javaPart, jni::make_jstring(image), JNitroCropConfig::fromCpp(config), JFunc_void_CropResult_cxx::fromCpp(resolved), JFunc_void_double_cxx::fromCpp(rejected));\n  }\n  void JHybridMultipleImagePickerSpec::openPreview(const std::vector<MediaPreview>& media, double index, const NitroPreviewConfig& config, const std::function<void(double /* index */)>& onLongPress) {\n    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JMediaPreview>> /* media */, double /* index */, jni::alias_ref<JNitroPreviewConfig> /* config */, jni::alias_ref<JFunc_void_double::javaobject> /* onLongPress */)>(\"openPreview_cxx\");\n    method(_javaPart, [&]() {\n      size_t __size = media.size();\n      jni::local_ref<jni::JArrayClass<JMediaPreview>> __array = jni::JArrayClass<JMediaPreview>::newArray(__size);\n      for (size_t __i = 0; __i < __size; __i++) {\n        const auto& __element = media[__i];\n        __array->setElement(__i, *JMediaPreview::fromCpp(__element));\n      }\n      return __array;\n    }(), index, JNitroPreviewConfig::fromCpp(config), JFunc_void_double_cxx::fromCpp(onLongPress));\n  }\n  void JHybridMultipleImagePickerSpec::openCamera(const NitroCameraConfig& config, const std::function<void(const CameraResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) {\n    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JNitroCameraConfig> /* config */, jni::alias_ref<JFunc_void_CameraResult::javaobject> /* resolved */, jni::alias_ref<JFunc_void_double::javaobject> /* rejected */)>(\"openCamera_cxx\");\n    method(_javaPart, JNitroCameraConfig::fromCpp(config), JFunc_void_CameraResult_cxx::fromCpp(resolved), JFunc_void_double_cxx::fromCpp(rejected));\n  }\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JHybridMultipleImagePickerSpec.hpp",
    "content": "///\n/// HybridMultipleImagePickerSpec.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <NitroModules/JHybridObject.hpp>\n#include <fbjni/fbjni.h>\n#include \"HybridMultipleImagePickerSpec.hpp\"\n\n\n\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  class JHybridMultipleImagePickerSpec: public jni::HybridClass<JHybridMultipleImagePickerSpec, JHybridObject>,\n                                        public virtual HybridMultipleImagePickerSpec {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/HybridMultipleImagePickerSpec;\";\n    static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);\n    static void registerNatives();\n\n  protected:\n    // C++ constructor (called from Java via `initHybrid()`)\n    explicit JHybridMultipleImagePickerSpec(jni::alias_ref<jhybridobject> jThis) :\n      HybridObject(HybridMultipleImagePickerSpec::TAG),\n      _javaPart(jni::make_global(jThis)) {}\n\n  public:\n    ~JHybridMultipleImagePickerSpec() override {\n      // Hermes GC can destroy JS objects on a non-JNI Thread.\n      jni::ThreadScope::WithClassLoader([&] { _javaPart.reset(); });\n    }\n\n  public:\n    size_t getExternalMemorySize() noexcept override;\n\n  public:\n    inline const jni::global_ref<JHybridMultipleImagePickerSpec::javaobject>& getJavaPart() const noexcept {\n      return _javaPart;\n    }\n\n  public:\n    // Properties\n    \n\n  public:\n    // Methods\n    void openPicker(const NitroConfig& config, const std::function<void(const std::vector<PickerResult>& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override;\n    void openCrop(const std::string& image, const NitroCropConfig& config, const std::function<void(const CropResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override;\n    void openPreview(const std::vector<MediaPreview>& media, double index, const NitroPreviewConfig& config, const std::function<void(double /* index */)>& onLongPress) override;\n    void openCamera(const NitroCameraConfig& config, const std::function<void(const CameraResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override;\n\n  private:\n    friend HybridBase;\n    using HybridBase::HybridBase;\n    jni::global_ref<JHybridMultipleImagePickerSpec::javaobject> _javaPart;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JLanguage.hpp",
    "content": "///\n/// JLanguage.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"Language.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"Language\" and the the Kotlin enum \"Language\".\n   */\n  struct JLanguage final: public jni::JavaClass<JLanguage> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Language;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum Language.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    Language toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<Language>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JLanguage> fromCpp(Language value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldSYSTEM = clazz->getStaticField<JLanguage>(\"SYSTEM\");\n      static const auto fieldZH_HANS = clazz->getStaticField<JLanguage>(\"ZH_HANS\");\n      static const auto fieldZH_HANT = clazz->getStaticField<JLanguage>(\"ZH_HANT\");\n      static const auto fieldJA = clazz->getStaticField<JLanguage>(\"JA\");\n      static const auto fieldKO = clazz->getStaticField<JLanguage>(\"KO\");\n      static const auto fieldEN = clazz->getStaticField<JLanguage>(\"EN\");\n      static const auto fieldTH = clazz->getStaticField<JLanguage>(\"TH\");\n      static const auto fieldID = clazz->getStaticField<JLanguage>(\"ID\");\n      static const auto fieldVI = clazz->getStaticField<JLanguage>(\"VI\");\n      static const auto fieldRU = clazz->getStaticField<JLanguage>(\"RU\");\n      static const auto fieldDE = clazz->getStaticField<JLanguage>(\"DE\");\n      static const auto fieldFR = clazz->getStaticField<JLanguage>(\"FR\");\n      static const auto fieldAR = clazz->getStaticField<JLanguage>(\"AR\");\n      \n      switch (value) {\n        case Language::SYSTEM:\n          return clazz->getStaticFieldValue(fieldSYSTEM);\n        case Language::ZH_HANS:\n          return clazz->getStaticFieldValue(fieldZH_HANS);\n        case Language::ZH_HANT:\n          return clazz->getStaticFieldValue(fieldZH_HANT);\n        case Language::JA:\n          return clazz->getStaticFieldValue(fieldJA);\n        case Language::KO:\n          return clazz->getStaticFieldValue(fieldKO);\n        case Language::EN:\n          return clazz->getStaticFieldValue(fieldEN);\n        case Language::TH:\n          return clazz->getStaticFieldValue(fieldTH);\n        case Language::ID:\n          return clazz->getStaticFieldValue(fieldID);\n        case Language::VI:\n          return clazz->getStaticFieldValue(fieldVI);\n        case Language::RU:\n          return clazz->getStaticFieldValue(fieldRU);\n        case Language::DE:\n          return clazz->getStaticFieldValue(fieldDE);\n        case Language::FR:\n          return clazz->getStaticFieldValue(fieldFR);\n        case Language::AR:\n          return clazz->getStaticFieldValue(fieldAR);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JMediaPreview.hpp",
    "content": "///\n/// JMediaPreview.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"MediaPreview.hpp\"\n\n#include \"JResultType.hpp\"\n#include \"ResultType.hpp\"\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"MediaPreview\" and the the Kotlin data class \"MediaPreview\".\n   */\n  struct JMediaPreview final: public jni::JavaClass<JMediaPreview> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/MediaPreview;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct MediaPreview by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    MediaPreview toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldType = clazz->getField<JResultType>(\"type\");\n      jni::local_ref<JResultType> type = this->getFieldValue(fieldType);\n      static const auto fieldPath = clazz->getField<jni::JString>(\"path\");\n      jni::local_ref<jni::JString> path = this->getFieldValue(fieldPath);\n      static const auto fieldThumbnail = clazz->getField<jni::JString>(\"thumbnail\");\n      jni::local_ref<jni::JString> thumbnail = this->getFieldValue(fieldThumbnail);\n      static const auto fieldLocalIdentifier = clazz->getField<jni::JString>(\"localIdentifier\");\n      jni::local_ref<jni::JString> localIdentifier = this->getFieldValue(fieldLocalIdentifier);\n      return MediaPreview(\n        type->toCpp(),\n        path != nullptr ? std::make_optional(path->toStdString()) : std::nullopt,\n        thumbnail != nullptr ? std::make_optional(thumbnail->toStdString()) : std::nullopt,\n        localIdentifier != nullptr ? std::make_optional(localIdentifier->toStdString()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JMediaPreview::javaobject> fromCpp(const MediaPreview& value) {\n      return newInstance(\n        JResultType::fromCpp(value.type),\n        value.path.has_value() ? jni::make_jstring(value.path.value()) : nullptr,\n        value.thumbnail.has_value() ? jni::make_jstring(value.thumbnail.value()) : nullptr,\n        value.localIdentifier.has_value() ? jni::make_jstring(value.localIdentifier.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JMediaType.hpp",
    "content": "///\n/// JMediaType.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"MediaType.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"MediaType\" and the the Kotlin enum \"MediaType\".\n   */\n  struct JMediaType final: public jni::JavaClass<JMediaType> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/MediaType;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum MediaType.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    MediaType toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<MediaType>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JMediaType> fromCpp(MediaType value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldVIDEO = clazz->getStaticField<JMediaType>(\"VIDEO\");\n      static const auto fieldIMAGE = clazz->getStaticField<JMediaType>(\"IMAGE\");\n      static const auto fieldALL = clazz->getStaticField<JMediaType>(\"ALL\");\n      \n      switch (value) {\n        case MediaType::VIDEO:\n          return clazz->getStaticFieldValue(fieldVIDEO);\n        case MediaType::IMAGE:\n          return clazz->getStaticFieldValue(fieldIMAGE);\n        case MediaType::ALL:\n          return clazz->getStaticFieldValue(fieldALL);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JNitroCameraConfig.hpp",
    "content": "///\n/// JNitroCameraConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"NitroCameraConfig.hpp\"\n\n#include \"CameraDevice.hpp\"\n#include \"CropRatio.hpp\"\n#include \"JCameraDevice.hpp\"\n#include \"JCropRatio.hpp\"\n#include \"JLanguage.hpp\"\n#include \"JMediaType.hpp\"\n#include \"JPickerCropConfig.hpp\"\n#include \"JPresentation.hpp\"\n#include \"Language.hpp\"\n#include \"MediaType.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"Presentation.hpp\"\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"NitroCameraConfig\" and the the Kotlin data class \"NitroCameraConfig\".\n   */\n  struct JNitroCameraConfig final: public jni::JavaClass<JNitroCameraConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/NitroCameraConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct NitroCameraConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    NitroCameraConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldMediaType = clazz->getField<JMediaType>(\"mediaType\");\n      jni::local_ref<JMediaType> mediaType = this->getFieldValue(fieldMediaType);\n      static const auto fieldPresentation = clazz->getField<JPresentation>(\"presentation\");\n      jni::local_ref<JPresentation> presentation = this->getFieldValue(fieldPresentation);\n      static const auto fieldLanguage = clazz->getField<JLanguage>(\"language\");\n      jni::local_ref<JLanguage> language = this->getFieldValue(fieldLanguage);\n      static const auto fieldCrop = clazz->getField<JPickerCropConfig>(\"crop\");\n      jni::local_ref<JPickerCropConfig> crop = this->getFieldValue(fieldCrop);\n      static const auto fieldIsSaveSystemAlbum = clazz->getField<jni::JBoolean>(\"isSaveSystemAlbum\");\n      jni::local_ref<jni::JBoolean> isSaveSystemAlbum = this->getFieldValue(fieldIsSaveSystemAlbum);\n      static const auto fieldColor = clazz->getField<jni::JDouble>(\"color\");\n      jni::local_ref<jni::JDouble> color = this->getFieldValue(fieldColor);\n      static const auto fieldCameraDevice = clazz->getField<JCameraDevice>(\"cameraDevice\");\n      jni::local_ref<JCameraDevice> cameraDevice = this->getFieldValue(fieldCameraDevice);\n      static const auto fieldVideoMaximumDuration = clazz->getField<jni::JDouble>(\"videoMaximumDuration\");\n      jni::local_ref<jni::JDouble> videoMaximumDuration = this->getFieldValue(fieldVideoMaximumDuration);\n      return NitroCameraConfig(\n        mediaType->toCpp(),\n        presentation->toCpp(),\n        language->toCpp(),\n        crop != nullptr ? std::make_optional(crop->toCpp()) : std::nullopt,\n        isSaveSystemAlbum != nullptr ? std::make_optional(static_cast<bool>(isSaveSystemAlbum->value())) : std::nullopt,\n        color != nullptr ? std::make_optional(color->value()) : std::nullopt,\n        cameraDevice != nullptr ? std::make_optional(cameraDevice->toCpp()) : std::nullopt,\n        videoMaximumDuration != nullptr ? std::make_optional(videoMaximumDuration->value()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JNitroCameraConfig::javaobject> fromCpp(const NitroCameraConfig& value) {\n      return newInstance(\n        JMediaType::fromCpp(value.mediaType),\n        JPresentation::fromCpp(value.presentation),\n        JLanguage::fromCpp(value.language),\n        value.crop.has_value() ? JPickerCropConfig::fromCpp(value.crop.value()) : nullptr,\n        value.isSaveSystemAlbum.has_value() ? jni::JBoolean::valueOf(value.isSaveSystemAlbum.value()) : nullptr,\n        value.color.has_value() ? jni::JDouble::valueOf(value.color.value()) : nullptr,\n        value.cameraDevice.has_value() ? JCameraDevice::fromCpp(value.cameraDevice.value()) : nullptr,\n        value.videoMaximumDuration.has_value() ? jni::JDouble::valueOf(value.videoMaximumDuration.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JNitroConfig.hpp",
    "content": "///\n/// JNitroConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"NitroConfig.hpp\"\n\n#include \"CameraDevice.hpp\"\n#include \"CropRatio.hpp\"\n#include \"JCameraDevice.hpp\"\n#include \"JCropRatio.hpp\"\n#include \"JLanguage.hpp\"\n#include \"JMediaType.hpp\"\n#include \"JPickerCameraConfig.hpp\"\n#include \"JPickerCropConfig.hpp\"\n#include \"JPickerResult.hpp\"\n#include \"JPresentation.hpp\"\n#include \"JResultType.hpp\"\n#include \"JSelectBoxStyle.hpp\"\n#include \"JSelectMode.hpp\"\n#include \"JText.hpp\"\n#include \"JTheme.hpp\"\n#include \"Language.hpp\"\n#include \"MediaType.hpp\"\n#include \"PickerCameraConfig.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"PickerResult.hpp\"\n#include \"Presentation.hpp\"\n#include \"ResultType.hpp\"\n#include \"SelectBoxStyle.hpp\"\n#include \"SelectMode.hpp\"\n#include \"Text.hpp\"\n#include \"Theme.hpp\"\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"NitroConfig\" and the the Kotlin data class \"NitroConfig\".\n   */\n  struct JNitroConfig final: public jni::JavaClass<JNitroConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/NitroConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct NitroConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    NitroConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldMediaType = clazz->getField<JMediaType>(\"mediaType\");\n      jni::local_ref<JMediaType> mediaType = this->getFieldValue(fieldMediaType);\n      static const auto fieldSelectedAssets = clazz->getField<jni::JArrayClass<JPickerResult>>(\"selectedAssets\");\n      jni::local_ref<jni::JArrayClass<JPickerResult>> selectedAssets = this->getFieldValue(fieldSelectedAssets);\n      static const auto fieldSelectBoxStyle = clazz->getField<JSelectBoxStyle>(\"selectBoxStyle\");\n      jni::local_ref<JSelectBoxStyle> selectBoxStyle = this->getFieldValue(fieldSelectBoxStyle);\n      static const auto fieldSelectMode = clazz->getField<JSelectMode>(\"selectMode\");\n      jni::local_ref<JSelectMode> selectMode = this->getFieldValue(fieldSelectMode);\n      static const auto fieldNumberOfColumn = clazz->getField<jni::JDouble>(\"numberOfColumn\");\n      jni::local_ref<jni::JDouble> numberOfColumn = this->getFieldValue(fieldNumberOfColumn);\n      static const auto fieldIsPreview = clazz->getField<jni::JBoolean>(\"isPreview\");\n      jni::local_ref<jni::JBoolean> isPreview = this->getFieldValue(fieldIsPreview);\n      static const auto fieldPrimaryColor = clazz->getField<jni::JDouble>(\"primaryColor\");\n      jni::local_ref<jni::JDouble> primaryColor = this->getFieldValue(fieldPrimaryColor);\n      static const auto fieldAllowSwipeToSelect = clazz->getField<jni::JBoolean>(\"allowSwipeToSelect\");\n      jni::local_ref<jni::JBoolean> allowSwipeToSelect = this->getFieldValue(fieldAllowSwipeToSelect);\n      static const auto fieldSpacing = clazz->getField<jni::JDouble>(\"spacing\");\n      jni::local_ref<jni::JDouble> spacing = this->getFieldValue(fieldSpacing);\n      static const auto fieldIsHiddenPreviewButton = clazz->getField<jni::JBoolean>(\"isHiddenPreviewButton\");\n      jni::local_ref<jni::JBoolean> isHiddenPreviewButton = this->getFieldValue(fieldIsHiddenPreviewButton);\n      static const auto fieldIsHiddenOriginalButton = clazz->getField<jni::JBoolean>(\"isHiddenOriginalButton\");\n      jni::local_ref<jni::JBoolean> isHiddenOriginalButton = this->getFieldValue(fieldIsHiddenOriginalButton);\n      static const auto fieldIsShowPreviewList = clazz->getField<jni::JBoolean>(\"isShowPreviewList\");\n      jni::local_ref<jni::JBoolean> isShowPreviewList = this->getFieldValue(fieldIsShowPreviewList);\n      static const auto fieldAllowHapticTouchPreview = clazz->getField<jni::JBoolean>(\"allowHapticTouchPreview\");\n      jni::local_ref<jni::JBoolean> allowHapticTouchPreview = this->getFieldValue(fieldAllowHapticTouchPreview);\n      static const auto fieldAllowedLimit = clazz->getField<jni::JBoolean>(\"allowedLimit\");\n      jni::local_ref<jni::JBoolean> allowedLimit = this->getFieldValue(fieldAllowedLimit);\n      static const auto fieldMaxVideo = clazz->getField<jni::JDouble>(\"maxVideo\");\n      jni::local_ref<jni::JDouble> maxVideo = this->getFieldValue(fieldMaxVideo);\n      static const auto fieldMaxSelect = clazz->getField<jni::JDouble>(\"maxSelect\");\n      jni::local_ref<jni::JDouble> maxSelect = this->getFieldValue(fieldMaxSelect);\n      static const auto fieldMaxVideoDuration = clazz->getField<jni::JDouble>(\"maxVideoDuration\");\n      jni::local_ref<jni::JDouble> maxVideoDuration = this->getFieldValue(fieldMaxVideoDuration);\n      static const auto fieldMinVideoDuration = clazz->getField<jni::JDouble>(\"minVideoDuration\");\n      jni::local_ref<jni::JDouble> minVideoDuration = this->getFieldValue(fieldMinVideoDuration);\n      static const auto fieldMaxFileSize = clazz->getField<jni::JDouble>(\"maxFileSize\");\n      jni::local_ref<jni::JDouble> maxFileSize = this->getFieldValue(fieldMaxFileSize);\n      static const auto fieldBackgroundDark = clazz->getField<jni::JDouble>(\"backgroundDark\");\n      jni::local_ref<jni::JDouble> backgroundDark = this->getFieldValue(fieldBackgroundDark);\n      static const auto fieldCrop = clazz->getField<JPickerCropConfig>(\"crop\");\n      jni::local_ref<JPickerCropConfig> crop = this->getFieldValue(fieldCrop);\n      static const auto fieldText = clazz->getField<JText>(\"text\");\n      jni::local_ref<JText> text = this->getFieldValue(fieldText);\n      static const auto fieldLanguage = clazz->getField<JLanguage>(\"language\");\n      jni::local_ref<JLanguage> language = this->getFieldValue(fieldLanguage);\n      static const auto fieldTheme = clazz->getField<JTheme>(\"theme\");\n      jni::local_ref<JTheme> theme = this->getFieldValue(fieldTheme);\n      static const auto fieldPresentation = clazz->getField<JPresentation>(\"presentation\");\n      jni::local_ref<JPresentation> presentation = this->getFieldValue(fieldPresentation);\n      static const auto fieldCamera = clazz->getField<JPickerCameraConfig>(\"camera\");\n      jni::local_ref<JPickerCameraConfig> camera = this->getFieldValue(fieldCamera);\n      return NitroConfig(\n        mediaType->toCpp(),\n        [&]() {\n          size_t __size = selectedAssets->size();\n          std::vector<PickerResult> __vector;\n          __vector.reserve(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            auto __element = selectedAssets->getElement(__i);\n            __vector.push_back(__element->toCpp());\n          }\n          return __vector;\n        }(),\n        selectBoxStyle->toCpp(),\n        selectMode->toCpp(),\n        numberOfColumn != nullptr ? std::make_optional(numberOfColumn->value()) : std::nullopt,\n        isPreview != nullptr ? std::make_optional(static_cast<bool>(isPreview->value())) : std::nullopt,\n        primaryColor != nullptr ? std::make_optional(primaryColor->value()) : std::nullopt,\n        allowSwipeToSelect != nullptr ? std::make_optional(static_cast<bool>(allowSwipeToSelect->value())) : std::nullopt,\n        spacing != nullptr ? std::make_optional(spacing->value()) : std::nullopt,\n        isHiddenPreviewButton != nullptr ? std::make_optional(static_cast<bool>(isHiddenPreviewButton->value())) : std::nullopt,\n        isHiddenOriginalButton != nullptr ? std::make_optional(static_cast<bool>(isHiddenOriginalButton->value())) : std::nullopt,\n        isShowPreviewList != nullptr ? std::make_optional(static_cast<bool>(isShowPreviewList->value())) : std::nullopt,\n        allowHapticTouchPreview != nullptr ? std::make_optional(static_cast<bool>(allowHapticTouchPreview->value())) : std::nullopt,\n        allowedLimit != nullptr ? std::make_optional(static_cast<bool>(allowedLimit->value())) : std::nullopt,\n        maxVideo != nullptr ? std::make_optional(maxVideo->value()) : std::nullopt,\n        maxSelect != nullptr ? std::make_optional(maxSelect->value()) : std::nullopt,\n        maxVideoDuration != nullptr ? std::make_optional(maxVideoDuration->value()) : std::nullopt,\n        minVideoDuration != nullptr ? std::make_optional(minVideoDuration->value()) : std::nullopt,\n        maxFileSize != nullptr ? std::make_optional(maxFileSize->value()) : std::nullopt,\n        backgroundDark != nullptr ? std::make_optional(backgroundDark->value()) : std::nullopt,\n        crop != nullptr ? std::make_optional(crop->toCpp()) : std::nullopt,\n        text != nullptr ? std::make_optional(text->toCpp()) : std::nullopt,\n        language->toCpp(),\n        theme->toCpp(),\n        presentation->toCpp(),\n        camera != nullptr ? std::make_optional(camera->toCpp()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JNitroConfig::javaobject> fromCpp(const NitroConfig& value) {\n      return newInstance(\n        JMediaType::fromCpp(value.mediaType),\n        [&]() {\n          size_t __size = value.selectedAssets.size();\n          jni::local_ref<jni::JArrayClass<JPickerResult>> __array = jni::JArrayClass<JPickerResult>::newArray(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            const auto& __element = value.selectedAssets[__i];\n            __array->setElement(__i, *JPickerResult::fromCpp(__element));\n          }\n          return __array;\n        }(),\n        JSelectBoxStyle::fromCpp(value.selectBoxStyle),\n        JSelectMode::fromCpp(value.selectMode),\n        value.numberOfColumn.has_value() ? jni::JDouble::valueOf(value.numberOfColumn.value()) : nullptr,\n        value.isPreview.has_value() ? jni::JBoolean::valueOf(value.isPreview.value()) : nullptr,\n        value.primaryColor.has_value() ? jni::JDouble::valueOf(value.primaryColor.value()) : nullptr,\n        value.allowSwipeToSelect.has_value() ? jni::JBoolean::valueOf(value.allowSwipeToSelect.value()) : nullptr,\n        value.spacing.has_value() ? jni::JDouble::valueOf(value.spacing.value()) : nullptr,\n        value.isHiddenPreviewButton.has_value() ? jni::JBoolean::valueOf(value.isHiddenPreviewButton.value()) : nullptr,\n        value.isHiddenOriginalButton.has_value() ? jni::JBoolean::valueOf(value.isHiddenOriginalButton.value()) : nullptr,\n        value.isShowPreviewList.has_value() ? jni::JBoolean::valueOf(value.isShowPreviewList.value()) : nullptr,\n        value.allowHapticTouchPreview.has_value() ? jni::JBoolean::valueOf(value.allowHapticTouchPreview.value()) : nullptr,\n        value.allowedLimit.has_value() ? jni::JBoolean::valueOf(value.allowedLimit.value()) : nullptr,\n        value.maxVideo.has_value() ? jni::JDouble::valueOf(value.maxVideo.value()) : nullptr,\n        value.maxSelect.has_value() ? jni::JDouble::valueOf(value.maxSelect.value()) : nullptr,\n        value.maxVideoDuration.has_value() ? jni::JDouble::valueOf(value.maxVideoDuration.value()) : nullptr,\n        value.minVideoDuration.has_value() ? jni::JDouble::valueOf(value.minVideoDuration.value()) : nullptr,\n        value.maxFileSize.has_value() ? jni::JDouble::valueOf(value.maxFileSize.value()) : nullptr,\n        value.backgroundDark.has_value() ? jni::JDouble::valueOf(value.backgroundDark.value()) : nullptr,\n        value.crop.has_value() ? JPickerCropConfig::fromCpp(value.crop.value()) : nullptr,\n        value.text.has_value() ? JText::fromCpp(value.text.value()) : nullptr,\n        JLanguage::fromCpp(value.language),\n        JTheme::fromCpp(value.theme),\n        JPresentation::fromCpp(value.presentation),\n        value.camera.has_value() ? JPickerCameraConfig::fromCpp(value.camera.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JNitroCropConfig.hpp",
    "content": "///\n/// JNitroCropConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"NitroCropConfig.hpp\"\n\n#include \"CropRatio.hpp\"\n#include \"JCropRatio.hpp\"\n#include \"JLanguage.hpp\"\n#include \"JPresentation.hpp\"\n#include \"Language.hpp\"\n#include \"Presentation.hpp\"\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"NitroCropConfig\" and the the Kotlin data class \"NitroCropConfig\".\n   */\n  struct JNitroCropConfig final: public jni::JavaClass<JNitroCropConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/NitroCropConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct NitroCropConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    NitroCropConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldLanguage = clazz->getField<JLanguage>(\"language\");\n      jni::local_ref<JLanguage> language = this->getFieldValue(fieldLanguage);\n      static const auto fieldPresentation = clazz->getField<JPresentation>(\"presentation\");\n      jni::local_ref<JPresentation> presentation = this->getFieldValue(fieldPresentation);\n      static const auto fieldCircle = clazz->getField<jni::JBoolean>(\"circle\");\n      jni::local_ref<jni::JBoolean> circle = this->getFieldValue(fieldCircle);\n      static const auto fieldRatio = clazz->getField<jni::JArrayClass<JCropRatio>>(\"ratio\");\n      jni::local_ref<jni::JArrayClass<JCropRatio>> ratio = this->getFieldValue(fieldRatio);\n      static const auto fieldDefaultRatio = clazz->getField<JCropRatio>(\"defaultRatio\");\n      jni::local_ref<JCropRatio> defaultRatio = this->getFieldValue(fieldDefaultRatio);\n      static const auto fieldFreeStyle = clazz->getField<jni::JBoolean>(\"freeStyle\");\n      jni::local_ref<jni::JBoolean> freeStyle = this->getFieldValue(fieldFreeStyle);\n      return NitroCropConfig(\n        language->toCpp(),\n        presentation->toCpp(),\n        circle != nullptr ? std::make_optional(static_cast<bool>(circle->value())) : std::nullopt,\n        [&]() {\n          size_t __size = ratio->size();\n          std::vector<CropRatio> __vector;\n          __vector.reserve(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            auto __element = ratio->getElement(__i);\n            __vector.push_back(__element->toCpp());\n          }\n          return __vector;\n        }(),\n        defaultRatio != nullptr ? std::make_optional(defaultRatio->toCpp()) : std::nullopt,\n        freeStyle != nullptr ? std::make_optional(static_cast<bool>(freeStyle->value())) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JNitroCropConfig::javaobject> fromCpp(const NitroCropConfig& value) {\n      return newInstance(\n        JLanguage::fromCpp(value.language),\n        JPresentation::fromCpp(value.presentation),\n        value.circle.has_value() ? jni::JBoolean::valueOf(value.circle.value()) : nullptr,\n        [&]() {\n          size_t __size = value.ratio.size();\n          jni::local_ref<jni::JArrayClass<JCropRatio>> __array = jni::JArrayClass<JCropRatio>::newArray(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            const auto& __element = value.ratio[__i];\n            __array->setElement(__i, *JCropRatio::fromCpp(__element));\n          }\n          return __array;\n        }(),\n        value.defaultRatio.has_value() ? JCropRatio::fromCpp(value.defaultRatio.value()) : nullptr,\n        value.freeStyle.has_value() ? jni::JBoolean::valueOf(value.freeStyle.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JNitroPreviewConfig.hpp",
    "content": "///\n/// JNitroPreviewConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"NitroPreviewConfig.hpp\"\n\n#include \"JLanguage.hpp\"\n#include \"Language.hpp\"\n#include <optional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"NitroPreviewConfig\" and the the Kotlin data class \"NitroPreviewConfig\".\n   */\n  struct JNitroPreviewConfig final: public jni::JavaClass<JNitroPreviewConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/NitroPreviewConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct NitroPreviewConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    NitroPreviewConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldLanguage = clazz->getField<JLanguage>(\"language\");\n      jni::local_ref<JLanguage> language = this->getFieldValue(fieldLanguage);\n      static const auto fieldVideoAutoPlay = clazz->getField<jni::JBoolean>(\"videoAutoPlay\");\n      jni::local_ref<jni::JBoolean> videoAutoPlay = this->getFieldValue(fieldVideoAutoPlay);\n      return NitroPreviewConfig(\n        language->toCpp(),\n        videoAutoPlay != nullptr ? std::make_optional(static_cast<bool>(videoAutoPlay->value())) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JNitroPreviewConfig::javaobject> fromCpp(const NitroPreviewConfig& value) {\n      return newInstance(\n        JLanguage::fromCpp(value.language),\n        value.videoAutoPlay.has_value() ? jni::JBoolean::valueOf(value.videoAutoPlay.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JPickerCameraConfig.hpp",
    "content": "///\n/// JPickerCameraConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"PickerCameraConfig.hpp\"\n\n#include \"CameraDevice.hpp\"\n#include \"JCameraDevice.hpp\"\n#include <optional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"PickerCameraConfig\" and the the Kotlin data class \"PickerCameraConfig\".\n   */\n  struct JPickerCameraConfig final: public jni::JavaClass<JPickerCameraConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/PickerCameraConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct PickerCameraConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    PickerCameraConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldCameraDevice = clazz->getField<JCameraDevice>(\"cameraDevice\");\n      jni::local_ref<JCameraDevice> cameraDevice = this->getFieldValue(fieldCameraDevice);\n      static const auto fieldVideoMaximumDuration = clazz->getField<jni::JDouble>(\"videoMaximumDuration\");\n      jni::local_ref<jni::JDouble> videoMaximumDuration = this->getFieldValue(fieldVideoMaximumDuration);\n      return PickerCameraConfig(\n        cameraDevice != nullptr ? std::make_optional(cameraDevice->toCpp()) : std::nullopt,\n        videoMaximumDuration != nullptr ? std::make_optional(videoMaximumDuration->value()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JPickerCameraConfig::javaobject> fromCpp(const PickerCameraConfig& value) {\n      return newInstance(\n        value.cameraDevice.has_value() ? JCameraDevice::fromCpp(value.cameraDevice.value()) : nullptr,\n        value.videoMaximumDuration.has_value() ? jni::JDouble::valueOf(value.videoMaximumDuration.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JPickerCropConfig.hpp",
    "content": "///\n/// JPickerCropConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"PickerCropConfig.hpp\"\n\n#include \"CropRatio.hpp\"\n#include \"JCropRatio.hpp\"\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"PickerCropConfig\" and the the Kotlin data class \"PickerCropConfig\".\n   */\n  struct JPickerCropConfig final: public jni::JavaClass<JPickerCropConfig> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/PickerCropConfig;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct PickerCropConfig by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    PickerCropConfig toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldCircle = clazz->getField<jni::JBoolean>(\"circle\");\n      jni::local_ref<jni::JBoolean> circle = this->getFieldValue(fieldCircle);\n      static const auto fieldRatio = clazz->getField<jni::JArrayClass<JCropRatio>>(\"ratio\");\n      jni::local_ref<jni::JArrayClass<JCropRatio>> ratio = this->getFieldValue(fieldRatio);\n      static const auto fieldDefaultRatio = clazz->getField<JCropRatio>(\"defaultRatio\");\n      jni::local_ref<JCropRatio> defaultRatio = this->getFieldValue(fieldDefaultRatio);\n      static const auto fieldFreeStyle = clazz->getField<jni::JBoolean>(\"freeStyle\");\n      jni::local_ref<jni::JBoolean> freeStyle = this->getFieldValue(fieldFreeStyle);\n      return PickerCropConfig(\n        circle != nullptr ? std::make_optional(static_cast<bool>(circle->value())) : std::nullopt,\n        [&]() {\n          size_t __size = ratio->size();\n          std::vector<CropRatio> __vector;\n          __vector.reserve(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            auto __element = ratio->getElement(__i);\n            __vector.push_back(__element->toCpp());\n          }\n          return __vector;\n        }(),\n        defaultRatio != nullptr ? std::make_optional(defaultRatio->toCpp()) : std::nullopt,\n        freeStyle != nullptr ? std::make_optional(static_cast<bool>(freeStyle->value())) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JPickerCropConfig::javaobject> fromCpp(const PickerCropConfig& value) {\n      return newInstance(\n        value.circle.has_value() ? jni::JBoolean::valueOf(value.circle.value()) : nullptr,\n        [&]() {\n          size_t __size = value.ratio.size();\n          jni::local_ref<jni::JArrayClass<JCropRatio>> __array = jni::JArrayClass<JCropRatio>::newArray(__size);\n          for (size_t __i = 0; __i < __size; __i++) {\n            const auto& __element = value.ratio[__i];\n            __array->setElement(__i, *JCropRatio::fromCpp(__element));\n          }\n          return __array;\n        }(),\n        value.defaultRatio.has_value() ? JCropRatio::fromCpp(value.defaultRatio.value()) : nullptr,\n        value.freeStyle.has_value() ? jni::JBoolean::valueOf(value.freeStyle.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JPickerResult.hpp",
    "content": "///\n/// JPickerResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"PickerResult.hpp\"\n\n#include \"JResultType.hpp\"\n#include \"ResultType.hpp\"\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"PickerResult\" and the the Kotlin data class \"PickerResult\".\n   */\n  struct JPickerResult final: public jni::JavaClass<JPickerResult> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/PickerResult;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct PickerResult by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    PickerResult toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldLocalIdentifier = clazz->getField<jni::JString>(\"localIdentifier\");\n      jni::local_ref<jni::JString> localIdentifier = this->getFieldValue(fieldLocalIdentifier);\n      static const auto fieldWidth = clazz->getField<double>(\"width\");\n      double width = this->getFieldValue(fieldWidth);\n      static const auto fieldHeight = clazz->getField<double>(\"height\");\n      double height = this->getFieldValue(fieldHeight);\n      static const auto fieldMime = clazz->getField<jni::JString>(\"mime\");\n      jni::local_ref<jni::JString> mime = this->getFieldValue(fieldMime);\n      static const auto fieldSize = clazz->getField<double>(\"size\");\n      double size = this->getFieldValue(fieldSize);\n      static const auto fieldBucketId = clazz->getField<jni::JDouble>(\"bucketId\");\n      jni::local_ref<jni::JDouble> bucketId = this->getFieldValue(fieldBucketId);\n      static const auto fieldRealPath = clazz->getField<jni::JString>(\"realPath\");\n      jni::local_ref<jni::JString> realPath = this->getFieldValue(fieldRealPath);\n      static const auto fieldParentFolderName = clazz->getField<jni::JString>(\"parentFolderName\");\n      jni::local_ref<jni::JString> parentFolderName = this->getFieldValue(fieldParentFolderName);\n      static const auto fieldCreationDate = clazz->getField<jni::JDouble>(\"creationDate\");\n      jni::local_ref<jni::JDouble> creationDate = this->getFieldValue(fieldCreationDate);\n      static const auto fieldCrop = clazz->getField<jni::JBoolean>(\"crop\");\n      jni::local_ref<jni::JBoolean> crop = this->getFieldValue(fieldCrop);\n      static const auto fieldPath = clazz->getField<jni::JString>(\"path\");\n      jni::local_ref<jni::JString> path = this->getFieldValue(fieldPath);\n      static const auto fieldType = clazz->getField<JResultType>(\"type\");\n      jni::local_ref<JResultType> type = this->getFieldValue(fieldType);\n      static const auto fieldDuration = clazz->getField<jni::JDouble>(\"duration\");\n      jni::local_ref<jni::JDouble> duration = this->getFieldValue(fieldDuration);\n      static const auto fieldThumbnail = clazz->getField<jni::JString>(\"thumbnail\");\n      jni::local_ref<jni::JString> thumbnail = this->getFieldValue(fieldThumbnail);\n      static const auto fieldFileName = clazz->getField<jni::JString>(\"fileName\");\n      jni::local_ref<jni::JString> fileName = this->getFieldValue(fieldFileName);\n      return PickerResult(\n        localIdentifier->toStdString(),\n        width,\n        height,\n        mime->toStdString(),\n        size,\n        bucketId != nullptr ? std::make_optional(bucketId->value()) : std::nullopt,\n        realPath != nullptr ? std::make_optional(realPath->toStdString()) : std::nullopt,\n        parentFolderName != nullptr ? std::make_optional(parentFolderName->toStdString()) : std::nullopt,\n        creationDate != nullptr ? std::make_optional(creationDate->value()) : std::nullopt,\n        crop != nullptr ? std::make_optional(static_cast<bool>(crop->value())) : std::nullopt,\n        path->toStdString(),\n        type->toCpp(),\n        duration != nullptr ? std::make_optional(duration->value()) : std::nullopt,\n        thumbnail != nullptr ? std::make_optional(thumbnail->toStdString()) : std::nullopt,\n        fileName != nullptr ? std::make_optional(fileName->toStdString()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JPickerResult::javaobject> fromCpp(const PickerResult& value) {\n      return newInstance(\n        jni::make_jstring(value.localIdentifier),\n        value.width,\n        value.height,\n        jni::make_jstring(value.mime),\n        value.size,\n        value.bucketId.has_value() ? jni::JDouble::valueOf(value.bucketId.value()) : nullptr,\n        value.realPath.has_value() ? jni::make_jstring(value.realPath.value()) : nullptr,\n        value.parentFolderName.has_value() ? jni::make_jstring(value.parentFolderName.value()) : nullptr,\n        value.creationDate.has_value() ? jni::JDouble::valueOf(value.creationDate.value()) : nullptr,\n        value.crop.has_value() ? jni::JBoolean::valueOf(value.crop.value()) : nullptr,\n        jni::make_jstring(value.path),\n        JResultType::fromCpp(value.type),\n        value.duration.has_value() ? jni::JDouble::valueOf(value.duration.value()) : nullptr,\n        value.thumbnail.has_value() ? jni::make_jstring(value.thumbnail.value()) : nullptr,\n        value.fileName.has_value() ? jni::make_jstring(value.fileName.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JPresentation.hpp",
    "content": "///\n/// JPresentation.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"Presentation.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"Presentation\" and the the Kotlin enum \"Presentation\".\n   */\n  struct JPresentation final: public jni::JavaClass<JPresentation> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Presentation;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum Presentation.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    Presentation toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<Presentation>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JPresentation> fromCpp(Presentation value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldFULLSCREENMODAL = clazz->getStaticField<JPresentation>(\"FULLSCREENMODAL\");\n      static const auto fieldFORMSHEET = clazz->getStaticField<JPresentation>(\"FORMSHEET\");\n      \n      switch (value) {\n        case Presentation::FULLSCREENMODAL:\n          return clazz->getStaticFieldValue(fieldFULLSCREENMODAL);\n        case Presentation::FORMSHEET:\n          return clazz->getStaticFieldValue(fieldFORMSHEET);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JResultType.hpp",
    "content": "///\n/// JResultType.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"ResultType.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"ResultType\" and the the Kotlin enum \"ResultType\".\n   */\n  struct JResultType final: public jni::JavaClass<JResultType> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/ResultType;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum ResultType.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    ResultType toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<ResultType>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JResultType> fromCpp(ResultType value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldVIDEO = clazz->getStaticField<JResultType>(\"VIDEO\");\n      static const auto fieldIMAGE = clazz->getStaticField<JResultType>(\"IMAGE\");\n      \n      switch (value) {\n        case ResultType::VIDEO:\n          return clazz->getStaticFieldValue(fieldVIDEO);\n        case ResultType::IMAGE:\n          return clazz->getStaticFieldValue(fieldIMAGE);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JSelectBoxStyle.hpp",
    "content": "///\n/// JSelectBoxStyle.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"SelectBoxStyle.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"SelectBoxStyle\" and the the Kotlin enum \"SelectBoxStyle\".\n   */\n  struct JSelectBoxStyle final: public jni::JavaClass<JSelectBoxStyle> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/SelectBoxStyle;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum SelectBoxStyle.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    SelectBoxStyle toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<SelectBoxStyle>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JSelectBoxStyle> fromCpp(SelectBoxStyle value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldNUMBER = clazz->getStaticField<JSelectBoxStyle>(\"NUMBER\");\n      static const auto fieldTICK = clazz->getStaticField<JSelectBoxStyle>(\"TICK\");\n      \n      switch (value) {\n        case SelectBoxStyle::NUMBER:\n          return clazz->getStaticFieldValue(fieldNUMBER);\n        case SelectBoxStyle::TICK:\n          return clazz->getStaticFieldValue(fieldTICK);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JSelectMode.hpp",
    "content": "///\n/// JSelectMode.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"SelectMode.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"SelectMode\" and the the Kotlin enum \"SelectMode\".\n   */\n  struct JSelectMode final: public jni::JavaClass<JSelectMode> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/SelectMode;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum SelectMode.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    SelectMode toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<SelectMode>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JSelectMode> fromCpp(SelectMode value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldSINGLE = clazz->getStaticField<JSelectMode>(\"SINGLE\");\n      static const auto fieldMULTIPLE = clazz->getStaticField<JSelectMode>(\"MULTIPLE\");\n      \n      switch (value) {\n        case SelectMode::SINGLE:\n          return clazz->getStaticFieldValue(fieldSINGLE);\n        case SelectMode::MULTIPLE:\n          return clazz->getStaticFieldValue(fieldMULTIPLE);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JText.hpp",
    "content": "///\n/// JText.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"Text.hpp\"\n\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ struct \"Text\" and the the Kotlin data class \"Text\".\n   */\n  struct JText final: public jni::JavaClass<JText> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Text;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based struct to the C++ struct Text by copying all values to C++.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    Text toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldFinish = clazz->getField<jni::JString>(\"finish\");\n      jni::local_ref<jni::JString> finish = this->getFieldValue(fieldFinish);\n      static const auto fieldOriginal = clazz->getField<jni::JString>(\"original\");\n      jni::local_ref<jni::JString> original = this->getFieldValue(fieldOriginal);\n      static const auto fieldPreview = clazz->getField<jni::JString>(\"preview\");\n      jni::local_ref<jni::JString> preview = this->getFieldValue(fieldPreview);\n      static const auto fieldEdit = clazz->getField<jni::JString>(\"edit\");\n      jni::local_ref<jni::JString> edit = this->getFieldValue(fieldEdit);\n      return Text(\n        finish != nullptr ? std::make_optional(finish->toStdString()) : std::nullopt,\n        original != nullptr ? std::make_optional(original->toStdString()) : std::nullopt,\n        preview != nullptr ? std::make_optional(preview->toStdString()) : std::nullopt,\n        edit != nullptr ? std::make_optional(edit->toStdString()) : std::nullopt\n      );\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.\n     */\n    [[maybe_unused]]\n    static jni::local_ref<JText::javaobject> fromCpp(const Text& value) {\n      return newInstance(\n        value.finish.has_value() ? jni::make_jstring(value.finish.value()) : nullptr,\n        value.original.has_value() ? jni::make_jstring(value.original.value()) : nullptr,\n        value.preview.has_value() ? jni::make_jstring(value.preview.value()) : nullptr,\n        value.edit.has_value() ? jni::make_jstring(value.edit.value()) : nullptr\n      );\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/c++/JTheme.hpp",
    "content": "///\n/// JTheme.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include <fbjni/fbjni.h>\n#include \"Theme.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace facebook;\n\n  /**\n   * The C++ JNI bridge between the C++ enum \"Theme\" and the the Kotlin enum \"Theme\".\n   */\n  struct JTheme final: public jni::JavaClass<JTheme> {\n  public:\n    static auto constexpr kJavaDescriptor = \"Lcom/margelo/nitro/multipleimagepicker/Theme;\";\n\n  public:\n    /**\n     * Convert this Java/Kotlin-based enum to the C++ enum Theme.\n     */\n    [[maybe_unused]]\n    [[nodiscard]]\n    Theme toCpp() const {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldOrdinal = clazz->getField<int>(\"_ordinal\");\n      int ordinal = this->getFieldValue(fieldOrdinal);\n      return static_cast<Theme>(ordinal);\n    }\n\n  public:\n    /**\n     * Create a Java/Kotlin-based enum with the given C++ enum's value.\n     */\n    [[maybe_unused]]\n    static jni::alias_ref<JTheme> fromCpp(Theme value) {\n      static const auto clazz = javaClassStatic();\n      static const auto fieldLIGHT = clazz->getStaticField<JTheme>(\"LIGHT\");\n      static const auto fieldDARK = clazz->getStaticField<JTheme>(\"DARK\");\n      \n      switch (value) {\n        case Theme::LIGHT:\n          return clazz->getStaticFieldValue(fieldLIGHT);\n        case Theme::DARK:\n          return clazz->getStaticFieldValue(fieldDARK);\n        default:\n          std::string stringValue = std::to_string(static_cast<int>(value));\n          throw std::invalid_argument(\"Invalid enum value (\" + stringValue + \"!\");\n      }\n    }\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/CameraDevice.kt",
    "content": "///\n/// CameraDevice.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"CameraDevice\".\n */\n@DoNotStrip\n@Keep\nenum class CameraDevice {\n  FRONT,\n  BACK;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/CameraResult.kt",
    "content": "///\n/// CameraResult.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"CameraResult\".\n */\n@DoNotStrip\n@Keep\ndata class CameraResult\n  @DoNotStrip\n  @Keep\n  constructor(\n    val path: String,\n    val type: ResultType,\n    val width: Double?,\n    val height: Double?,\n    val duration: Double?,\n    val thumbnail: String?,\n    val fileName: String?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/CropRatio.kt",
    "content": "///\n/// CropRatio.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"CropRatio\".\n */\n@DoNotStrip\n@Keep\ndata class CropRatio\n  @DoNotStrip\n  @Keep\n  constructor(\n    val title: String?,\n    val width: Double,\n    val height: Double\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/CropResult.kt",
    "content": "///\n/// CropResult.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"CropResult\".\n */\n@DoNotStrip\n@Keep\ndata class CropResult\n  @DoNotStrip\n  @Keep\n  constructor(\n    val path: String,\n    val width: Double,\n    val height: Double\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Func_void_CameraResult.kt",
    "content": "///\n/// Func_void_CameraResult.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.jni.HybridData\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\nimport dalvik.annotation.optimization.FastNative\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This can be either implemented in C++ (in which case it might be a callback coming from JS),\n * or in Kotlin/Java (in which case it is a native callback).\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\")\nfun interface Func_void_CameraResult: (CameraResult) -> Unit {\n  /**\n   * Call the given JS callback.\n   * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.\n   */\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CameraResult): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This is implemented in C++, via a `std::function<...>`.\n * The callback might be coming from JS.\n */\n@DoNotStrip\n@Keep\n@Suppress(\n  \"KotlinJniMissingFunction\", \"unused\",\n  \"RedundantSuppression\", \"RedundantUnitReturnType\", \"FunctionName\",\n  \"ConvertSecondaryConstructorToPrimary\", \"ClassName\", \"LocalVariableName\",\n)\nclass Func_void_CameraResult_cxx: Func_void_CameraResult {\n  @DoNotStrip\n  @Keep\n  private val mHybridData: HybridData\n\n  @DoNotStrip\n  @Keep\n  private constructor(hybridData: HybridData) {\n    mHybridData = hybridData\n  }\n\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CameraResult): Unit\n    = invoke_cxx(result)\n\n  @FastNative\n  private external fun invoke_cxx(result: CameraResult): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This is implemented in Java/Kotlin, via a `(CameraResult) -> Unit`.\n * The callback is always coming from native.\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\", \"unused\")\nclass Func_void_CameraResult_java(private val function: (CameraResult) -> Unit): Func_void_CameraResult {\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CameraResult): Unit {\n    return this.function(result)\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Func_void_CropResult.kt",
    "content": "///\n/// Func_void_CropResult.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.jni.HybridData\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\nimport dalvik.annotation.optimization.FastNative\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This can be either implemented in C++ (in which case it might be a callback coming from JS),\n * or in Kotlin/Java (in which case it is a native callback).\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\")\nfun interface Func_void_CropResult: (CropResult) -> Unit {\n  /**\n   * Call the given JS callback.\n   * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.\n   */\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CropResult): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This is implemented in C++, via a `std::function<...>`.\n * The callback might be coming from JS.\n */\n@DoNotStrip\n@Keep\n@Suppress(\n  \"KotlinJniMissingFunction\", \"unused\",\n  \"RedundantSuppression\", \"RedundantUnitReturnType\", \"FunctionName\",\n  \"ConvertSecondaryConstructorToPrimary\", \"ClassName\", \"LocalVariableName\",\n)\nclass Func_void_CropResult_cxx: Func_void_CropResult {\n  @DoNotStrip\n  @Keep\n  private val mHybridData: HybridData\n\n  @DoNotStrip\n  @Keep\n  private constructor(hybridData: HybridData) {\n    mHybridData = hybridData\n  }\n\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CropResult): Unit\n    = invoke_cxx(result)\n\n  @FastNative\n  private external fun invoke_cxx(result: CropResult): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: struct) => void`.\n * This is implemented in Java/Kotlin, via a `(CropResult) -> Unit`.\n * The callback is always coming from native.\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\", \"unused\")\nclass Func_void_CropResult_java(private val function: (CropResult) -> Unit): Func_void_CropResult {\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: CropResult): Unit {\n    return this.function(result)\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Func_void_double.kt",
    "content": "///\n/// Func_void_double.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.jni.HybridData\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\nimport dalvik.annotation.optimization.FastNative\n\n/**\n * Represents the JavaScript callback `(index: number) => void`.\n * This can be either implemented in C++ (in which case it might be a callback coming from JS),\n * or in Kotlin/Java (in which case it is a native callback).\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\")\nfun interface Func_void_double: (Double) -> Unit {\n  /**\n   * Call the given JS callback.\n   * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.\n   */\n  @DoNotStrip\n  @Keep\n  override fun invoke(index: Double): Unit\n}\n\n/**\n * Represents the JavaScript callback `(index: number) => void`.\n * This is implemented in C++, via a `std::function<...>`.\n * The callback might be coming from JS.\n */\n@DoNotStrip\n@Keep\n@Suppress(\n  \"KotlinJniMissingFunction\", \"unused\",\n  \"RedundantSuppression\", \"RedundantUnitReturnType\", \"FunctionName\",\n  \"ConvertSecondaryConstructorToPrimary\", \"ClassName\", \"LocalVariableName\",\n)\nclass Func_void_double_cxx: Func_void_double {\n  @DoNotStrip\n  @Keep\n  private val mHybridData: HybridData\n\n  @DoNotStrip\n  @Keep\n  private constructor(hybridData: HybridData) {\n    mHybridData = hybridData\n  }\n\n  @DoNotStrip\n  @Keep\n  override fun invoke(index: Double): Unit\n    = invoke_cxx(index)\n\n  @FastNative\n  private external fun invoke_cxx(index: Double): Unit\n}\n\n/**\n * Represents the JavaScript callback `(index: number) => void`.\n * This is implemented in Java/Kotlin, via a `(Double) -> Unit`.\n * The callback is always coming from native.\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\", \"unused\")\nclass Func_void_double_java(private val function: (Double) -> Unit): Func_void_double {\n  @DoNotStrip\n  @Keep\n  override fun invoke(index: Double): Unit {\n    return this.function(index)\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Func_void_std__vector_PickerResult_.kt",
    "content": "///\n/// Func_void_std__vector_PickerResult_.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.jni.HybridData\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\nimport dalvik.annotation.optimization.FastNative\n\n/**\n * Represents the JavaScript callback `(result: array) => void`.\n * This can be either implemented in C++ (in which case it might be a callback coming from JS),\n * or in Kotlin/Java (in which case it is a native callback).\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\")\nfun interface Func_void_std__vector_PickerResult_: (Array<PickerResult>) -> Unit {\n  /**\n   * Call the given JS callback.\n   * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.\n   */\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: Array<PickerResult>): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: array) => void`.\n * This is implemented in C++, via a `std::function<...>`.\n * The callback might be coming from JS.\n */\n@DoNotStrip\n@Keep\n@Suppress(\n  \"KotlinJniMissingFunction\", \"unused\",\n  \"RedundantSuppression\", \"RedundantUnitReturnType\", \"FunctionName\",\n  \"ConvertSecondaryConstructorToPrimary\", \"ClassName\", \"LocalVariableName\",\n)\nclass Func_void_std__vector_PickerResult__cxx: Func_void_std__vector_PickerResult_ {\n  @DoNotStrip\n  @Keep\n  private val mHybridData: HybridData\n\n  @DoNotStrip\n  @Keep\n  private constructor(hybridData: HybridData) {\n    mHybridData = hybridData\n  }\n\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: Array<PickerResult>): Unit\n    = invoke_cxx(result)\n\n  @FastNative\n  private external fun invoke_cxx(result: Array<PickerResult>): Unit\n}\n\n/**\n * Represents the JavaScript callback `(result: array) => void`.\n * This is implemented in Java/Kotlin, via a `(Array<PickerResult>) -> Unit`.\n * The callback is always coming from native.\n */\n@DoNotStrip\n@Keep\n@Suppress(\"ClassName\", \"RedundantUnitReturnType\", \"unused\")\nclass Func_void_std__vector_PickerResult__java(private val function: (Array<PickerResult>) -> Unit): Func_void_std__vector_PickerResult_ {\n  @DoNotStrip\n  @Keep\n  override fun invoke(result: Array<PickerResult>): Unit {\n    return this.function(result)\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/HybridMultipleImagePickerSpec.kt",
    "content": "///\n/// HybridMultipleImagePickerSpec.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.jni.HybridData\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * A Kotlin class representing the MultipleImagePicker HybridObject.\n * Implement this abstract class to create Kotlin-based instances of MultipleImagePicker.\n */\n@DoNotStrip\n@Keep\n@Suppress(\n  \"KotlinJniMissingFunction\", \"unused\",\n  \"RedundantSuppression\", \"RedundantUnitReturnType\", \"SimpleRedundantLet\",\n  \"LocalVariableName\", \"PropertyName\", \"PrivatePropertyName\", \"FunctionName\"\n)\nabstract class HybridMultipleImagePickerSpec: HybridObject() {\n  @DoNotStrip\n  private var mHybridData: HybridData = initHybrid()\n\n  init {\n    super.updateNative(mHybridData)\n  }\n\n  override fun updateNative(hybridData: HybridData) {\n    mHybridData = hybridData\n    super.updateNative(hybridData)\n  }\n\n  // Properties\n  \n\n  // Methods\n  abstract fun openPicker(config: NitroConfig, resolved: (result: Array<PickerResult>) -> Unit, rejected: (reject: Double) -> Unit): Unit\n  \n  @DoNotStrip\n  @Keep\n  private fun openPicker_cxx(config: NitroConfig, resolved: Func_void_std__vector_PickerResult_, rejected: Func_void_double): Unit {\n    val __result = openPicker(config, resolved, rejected)\n    return __result\n  }\n  \n  abstract fun openCrop(image: String, config: NitroCropConfig, resolved: (result: CropResult) -> Unit, rejected: (reject: Double) -> Unit): Unit\n  \n  @DoNotStrip\n  @Keep\n  private fun openCrop_cxx(image: String, config: NitroCropConfig, resolved: Func_void_CropResult, rejected: Func_void_double): Unit {\n    val __result = openCrop(image, config, resolved, rejected)\n    return __result\n  }\n  \n  abstract fun openPreview(media: Array<MediaPreview>, index: Double, config: NitroPreviewConfig, onLongPress: (index: Double) -> Unit): Unit\n  \n  @DoNotStrip\n  @Keep\n  private fun openPreview_cxx(media: Array<MediaPreview>, index: Double, config: NitroPreviewConfig, onLongPress: Func_void_double): Unit {\n    val __result = openPreview(media, index, config, onLongPress)\n    return __result\n  }\n  \n  abstract fun openCamera(config: NitroCameraConfig, resolved: (result: CameraResult) -> Unit, rejected: (reject: Double) -> Unit): Unit\n  \n  @DoNotStrip\n  @Keep\n  private fun openCamera_cxx(config: NitroCameraConfig, resolved: Func_void_CameraResult, rejected: Func_void_double): Unit {\n    val __result = openCamera(config, resolved, rejected)\n    return __result\n  }\n\n  private external fun initHybrid(): HybridData\n\n  companion object {\n    private const val TAG = \"HybridMultipleImagePickerSpec\"\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Language.kt",
    "content": "///\n/// Language.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"Language\".\n */\n@DoNotStrip\n@Keep\nenum class Language {\n  SYSTEM,\n  ZH_HANS,\n  ZH_HANT,\n  JA,\n  KO,\n  EN,\n  TH,\n  ID,\n  VI,\n  RU,\n  DE,\n  FR,\n  AR;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/MediaPreview.kt",
    "content": "///\n/// MediaPreview.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"MediaPreview\".\n */\n@DoNotStrip\n@Keep\ndata class MediaPreview\n  @DoNotStrip\n  @Keep\n  constructor(\n    val type: ResultType,\n    val path: String?,\n    val thumbnail: String?,\n    val localIdentifier: String?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/MediaType.kt",
    "content": "///\n/// MediaType.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"MediaType\".\n */\n@DoNotStrip\n@Keep\nenum class MediaType {\n  VIDEO,\n  IMAGE,\n  ALL;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/MultipleImagePickerOnLoad.kt",
    "content": "///\n/// MultipleImagePickerOnLoad.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport android.util.Log\n\ninternal class MultipleImagePickerOnLoad {\n  companion object {\n    private const val TAG = \"MultipleImagePickerOnLoad\"\n    private var didLoad = false\n    /**\n     * Initializes the native part of \"MultipleImagePicker\".\n     * This method is idempotent and can be called more than once.\n     */\n    @JvmStatic\n    fun initializeNative() {\n      if (didLoad) return\n      try {\n        Log.i(TAG, \"Loading MultipleImagePicker C++ library...\")\n        System.loadLibrary(\"MultipleImagePicker\")\n        Log.i(TAG, \"Successfully loaded MultipleImagePicker C++ library!\")\n        didLoad = true\n      } catch (e: Error) {\n        Log.e(TAG, \"Failed to load MultipleImagePicker C++ library! Is it properly installed and linked? \" +\n                    \"Is the name correct? (see `CMakeLists.txt`, at `add_library(...)`)\", e)\n        throw e\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/NitroCameraConfig.kt",
    "content": "///\n/// NitroCameraConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"NitroCameraConfig\".\n */\n@DoNotStrip\n@Keep\ndata class NitroCameraConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val mediaType: MediaType,\n    val presentation: Presentation,\n    val language: Language,\n    val crop: PickerCropConfig?,\n    val isSaveSystemAlbum: Boolean?,\n    val color: Double?,\n    val cameraDevice: CameraDevice?,\n    val videoMaximumDuration: Double?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/NitroConfig.kt",
    "content": "///\n/// NitroConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"NitroConfig\".\n */\n@DoNotStrip\n@Keep\ndata class NitroConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val mediaType: MediaType,\n    val selectedAssets: Array<PickerResult>,\n    val selectBoxStyle: SelectBoxStyle,\n    val selectMode: SelectMode,\n    val numberOfColumn: Double?,\n    val isPreview: Boolean?,\n    val primaryColor: Double?,\n    val allowSwipeToSelect: Boolean?,\n    val spacing: Double?,\n    val isHiddenPreviewButton: Boolean?,\n    val isHiddenOriginalButton: Boolean?,\n    val isShowPreviewList: Boolean?,\n    val allowHapticTouchPreview: Boolean?,\n    val allowedLimit: Boolean?,\n    val maxVideo: Double?,\n    val maxSelect: Double?,\n    val maxVideoDuration: Double?,\n    val minVideoDuration: Double?,\n    val maxFileSize: Double?,\n    val backgroundDark: Double?,\n    val crop: PickerCropConfig?,\n    val text: Text?,\n    val language: Language,\n    val theme: Theme,\n    val presentation: Presentation,\n    val camera: PickerCameraConfig?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/NitroCropConfig.kt",
    "content": "///\n/// NitroCropConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"NitroCropConfig\".\n */\n@DoNotStrip\n@Keep\ndata class NitroCropConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val language: Language,\n    val presentation: Presentation,\n    val circle: Boolean?,\n    val ratio: Array<CropRatio>,\n    val defaultRatio: CropRatio?,\n    val freeStyle: Boolean?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/NitroPreviewConfig.kt",
    "content": "///\n/// NitroPreviewConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"NitroPreviewConfig\".\n */\n@DoNotStrip\n@Keep\ndata class NitroPreviewConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val language: Language,\n    val videoAutoPlay: Boolean?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/PickerCameraConfig.kt",
    "content": "///\n/// PickerCameraConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"PickerCameraConfig\".\n */\n@DoNotStrip\n@Keep\ndata class PickerCameraConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val cameraDevice: CameraDevice?,\n    val videoMaximumDuration: Double?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/PickerCropConfig.kt",
    "content": "///\n/// PickerCropConfig.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"PickerCropConfig\".\n */\n@DoNotStrip\n@Keep\ndata class PickerCropConfig\n  @DoNotStrip\n  @Keep\n  constructor(\n    val circle: Boolean?,\n    val ratio: Array<CropRatio>,\n    val defaultRatio: CropRatio?,\n    val freeStyle: Boolean?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/PickerResult.kt",
    "content": "///\n/// PickerResult.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"PickerResult\".\n */\n@DoNotStrip\n@Keep\ndata class PickerResult\n  @DoNotStrip\n  @Keep\n  constructor(\n    val localIdentifier: String,\n    val width: Double,\n    val height: Double,\n    val mime: String,\n    val size: Double,\n    val bucketId: Double?,\n    val realPath: String?,\n    val parentFolderName: String?,\n    val creationDate: Double?,\n    val crop: Boolean?,\n    val path: String,\n    val type: ResultType,\n    val duration: Double?,\n    val thumbnail: String?,\n    val fileName: String?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Presentation.kt",
    "content": "///\n/// Presentation.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"Presentation\".\n */\n@DoNotStrip\n@Keep\nenum class Presentation {\n  FULLSCREENMODAL,\n  FORMSHEET;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/ResultType.kt",
    "content": "///\n/// ResultType.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"ResultType\".\n */\n@DoNotStrip\n@Keep\nenum class ResultType {\n  VIDEO,\n  IMAGE;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/SelectBoxStyle.kt",
    "content": "///\n/// SelectBoxStyle.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"SelectBoxStyle\".\n */\n@DoNotStrip\n@Keep\nenum class SelectBoxStyle {\n  NUMBER,\n  TICK;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/SelectMode.kt",
    "content": "///\n/// SelectMode.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"SelectMode\".\n */\n@DoNotStrip\n@Keep\nenum class SelectMode {\n  SINGLE,\n  MULTIPLE;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Text.kt",
    "content": "///\n/// Text.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\nimport com.margelo.nitro.core.*\n\n/**\n * Represents the JavaScript object/struct \"Text\".\n */\n@DoNotStrip\n@Keep\ndata class Text\n  @DoNotStrip\n  @Keep\n  constructor(\n    val finish: String?,\n    val original: String?,\n    val preview: String?,\n    val edit: String?\n  ) {\n  /* main constructor */\n}\n"
  },
  {
    "path": "nitrogen/generated/android/kotlin/com/margelo/nitro/multipleimagepicker/Theme.kt",
    "content": "///\n/// Theme.kt\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npackage com.margelo.nitro.multipleimagepicker\n\nimport androidx.annotation.Keep\nimport com.facebook.proguard.annotations.DoNotStrip\n\n/**\n * Represents the JavaScript enum/union \"Theme\".\n */\n@DoNotStrip\n@Keep\nenum class Theme {\n  LIGHT,\n  DARK;\n\n  @DoNotStrip\n  @Keep\n  private val _ordinal = ordinal\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePicker+autolinking.rb",
    "content": "#\n# MultipleImagePicker+autolinking.rb\n# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n# https://github.com/mrousavy/nitro\n# Copyright © 2025 Marc Rousavy @ Margelo\n#\n\n# This is a Ruby script that adds all files generated by Nitrogen\n# to the given podspec.\n#\n# To use it, add this to your .podspec:\n# ```ruby\n# Pod::Spec.new do |spec|\n#   # ...\n#\n#   # Add all files generated by Nitrogen\n#   load 'nitrogen/generated/ios/MultipleImagePicker+autolinking.rb'\n#   add_nitrogen_files(spec)\n# end\n# ```\n\ndef add_nitrogen_files(spec)\n  Pod::UI.puts \"[NitroModules] 🔥 MultipleImagePicker is boosted by nitro!\"\n\n  spec.dependency \"NitroModules\"\n\n  current_source_files = Array(spec.attributes_hash['source_files'])\n  spec.source_files = current_source_files + [\n    # Generated cross-platform specs\n    \"nitrogen/generated/shared/**/*.{h,hpp,c,cpp,swift}\",\n    # Generated bridges for the cross-platform specs\n    \"nitrogen/generated/ios/**/*.{h,hpp,c,cpp,mm,swift}\",\n  ]\n\n  current_public_header_files = Array(spec.attributes_hash['public_header_files'])\n  spec.public_header_files = current_public_header_files + [\n    # Generated specs\n    \"nitrogen/generated/shared/**/*.{h,hpp}\",\n    # Swift to C++ bridging helpers\n    \"nitrogen/generated/ios/MultipleImagePicker-Swift-Cxx-Bridge.hpp\"\n  ]\n\n  current_private_header_files = Array(spec.attributes_hash['private_header_files'])\n  spec.private_header_files = current_private_header_files + [\n    # iOS specific specs\n    \"nitrogen/generated/ios/c++/**/*.{h,hpp}\",\n    # Views are framework-specific and should be private\n    \"nitrogen/generated/shared/**/views/**/*\"\n  ]\n\n  current_pod_target_xcconfig = spec.attributes_hash['pod_target_xcconfig'] || {}\n  spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({\n    # Use C++ 20\n    \"CLANG_CXX_LANGUAGE_STANDARD\" => \"c++20\",\n    # Enables C++ <-> Swift interop (by default it's only C)\n    \"SWIFT_OBJC_INTEROP_MODE\" => \"objcxx\",\n    # Enables stricter modular headers\n    \"DEFINES_MODULE\" => \"YES\",\n  })\nend\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePicker-Swift-Cxx-Bridge.cpp",
    "content": "///\n/// MultipleImagePicker-Swift-Cxx-Bridge.cpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#include \"MultipleImagePicker-Swift-Cxx-Bridge.hpp\"\n\n// Include C++ implementation defined types\n#include \"HybridMultipleImagePickerSpecSwift.hpp\"\n#include \"MultipleImagePicker-Swift-Cxx-Umbrella.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker::bridge::swift {\n\n  // pragma MARK: std::function<void(const std::vector<PickerResult>& /* result */)>\n  Func_void_std__vector_PickerResult_ create_Func_void_std__vector_PickerResult_(void* _Nonnull swiftClosureWrapper) {\n    auto swiftClosure = MultipleImagePicker::Func_void_std__vector_PickerResult_::fromUnsafe(swiftClosureWrapper);\n    return [swiftClosure = std::move(swiftClosure)](const std::vector<PickerResult>& result) mutable -> void {\n      swiftClosure.call(result);\n    };\n  }\n  \n  // pragma MARK: std::function<void(double /* reject */)>\n  Func_void_double create_Func_void_double(void* _Nonnull swiftClosureWrapper) {\n    auto swiftClosure = MultipleImagePicker::Func_void_double::fromUnsafe(swiftClosureWrapper);\n    return [swiftClosure = std::move(swiftClosure)](double reject) mutable -> void {\n      swiftClosure.call(reject);\n    };\n  }\n  \n  // pragma MARK: std::function<void(const CropResult& /* result */)>\n  Func_void_CropResult create_Func_void_CropResult(void* _Nonnull swiftClosureWrapper) {\n    auto swiftClosure = MultipleImagePicker::Func_void_CropResult::fromUnsafe(swiftClosureWrapper);\n    return [swiftClosure = std::move(swiftClosure)](const CropResult& result) mutable -> void {\n      swiftClosure.call(result);\n    };\n  }\n  \n  // pragma MARK: std::function<void(const CameraResult& /* result */)>\n  Func_void_CameraResult create_Func_void_CameraResult(void* _Nonnull swiftClosureWrapper) {\n    auto swiftClosure = MultipleImagePicker::Func_void_CameraResult::fromUnsafe(swiftClosureWrapper);\n    return [swiftClosure = std::move(swiftClosure)](const CameraResult& result) mutable -> void {\n      swiftClosure.call(result);\n    };\n  }\n  \n  // pragma MARK: std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>\n  std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec> create_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(void* _Nonnull swiftUnsafePointer) {\n    MultipleImagePicker::HybridMultipleImagePickerSpec_cxx swiftPart = MultipleImagePicker::HybridMultipleImagePickerSpec_cxx::fromUnsafe(swiftUnsafePointer);\n    return std::make_shared<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpecSwift>(swiftPart);\n  }\n  void* _Nonnull get_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ cppType) {\n    std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpecSwift> swiftWrapper = std::dynamic_pointer_cast<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpecSwift>(cppType);\n  #ifdef NITRO_DEBUG\n    if (swiftWrapper == nullptr) [[unlikely]] {\n      throw std::runtime_error(\"Class \\\"HybridMultipleImagePickerSpec\\\" is not implemented in Swift!\");\n    }\n  #endif\n    MultipleImagePicker::HybridMultipleImagePickerSpec_cxx& swiftPart = swiftWrapper->getSwiftPart();\n    return swiftPart.toUnsafe();\n  }\n\n} // namespace margelo::nitro::multipleimagepicker::bridge::swift\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePicker-Swift-Cxx-Bridge.hpp",
    "content": "///\n/// MultipleImagePicker-Swift-Cxx-Bridge.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n// Forward declarations of C++ defined types\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n// Forward declaration of `CameraResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CameraResult; }\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n// Forward declaration of `CropResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropResult; }\n// Forward declaration of `HybridMultipleImagePickerSpec` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { class HybridMultipleImagePickerSpec; }\n// Forward declaration of `MediaPreview` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct MediaPreview; }\n// Forward declaration of `PickerCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCameraConfig; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n// Forward declaration of `Text` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct Text; }\n\n// Forward declarations of Swift defined types\n// Forward declaration of `HybridMultipleImagePickerSpec_cxx` to properly resolve imports.\nnamespace MultipleImagePicker { class HybridMultipleImagePickerSpec_cxx; }\n\n// Include C++ defined types\n#include \"CameraDevice.hpp\"\n#include \"CameraResult.hpp\"\n#include \"CropRatio.hpp\"\n#include \"CropResult.hpp\"\n#include \"HybridMultipleImagePickerSpec.hpp\"\n#include \"MediaPreview.hpp\"\n#include \"PickerCameraConfig.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"PickerResult.hpp\"\n#include \"ResultType.hpp\"\n#include \"Text.hpp\"\n#include <NitroModules/Result.hpp>\n#include <exception>\n#include <functional>\n#include <memory>\n#include <optional>\n#include <string>\n#include <vector>\n\n/**\n * Contains specialized versions of C++ templated types so they can be accessed from Swift,\n * as well as helper functions to interact with those C++ types from Swift.\n */\nnamespace margelo::nitro::multipleimagepicker::bridge::swift {\n\n  // pragma MARK: std::optional<double>\n  /**\n   * Specialized version of `std::optional<double>`.\n   */\n  using std__optional_double_ = std::optional<double>;\n  inline std::optional<double> create_std__optional_double_(const double& value) {\n    return std::optional<double>(value);\n  }\n  \n  // pragma MARK: std::optional<std::string>\n  /**\n   * Specialized version of `std::optional<std::string>`.\n   */\n  using std__optional_std__string_ = std::optional<std::string>;\n  inline std::optional<std::string> create_std__optional_std__string_(const std::string& value) {\n    return std::optional<std::string>(value);\n  }\n  \n  // pragma MARK: std::optional<bool>\n  /**\n   * Specialized version of `std::optional<bool>`.\n   */\n  using std__optional_bool_ = std::optional<bool>;\n  inline std::optional<bool> create_std__optional_bool_(const bool& value) {\n    return std::optional<bool>(value);\n  }\n  \n  // pragma MARK: std::vector<PickerResult>\n  /**\n   * Specialized version of `std::vector<PickerResult>`.\n   */\n  using std__vector_PickerResult_ = std::vector<PickerResult>;\n  inline std::vector<PickerResult> create_std__vector_PickerResult_(size_t size) {\n    std::vector<PickerResult> vector;\n    vector.reserve(size);\n    return vector;\n  }\n  \n  // pragma MARK: std::vector<CropRatio>\n  /**\n   * Specialized version of `std::vector<CropRatio>`.\n   */\n  using std__vector_CropRatio_ = std::vector<CropRatio>;\n  inline std::vector<CropRatio> create_std__vector_CropRatio_(size_t size) {\n    std::vector<CropRatio> vector;\n    vector.reserve(size);\n    return vector;\n  }\n  \n  // pragma MARK: std::optional<CropRatio>\n  /**\n   * Specialized version of `std::optional<CropRatio>`.\n   */\n  using std__optional_CropRatio_ = std::optional<CropRatio>;\n  inline std::optional<CropRatio> create_std__optional_CropRatio_(const CropRatio& value) {\n    return std::optional<CropRatio>(value);\n  }\n  \n  // pragma MARK: std::optional<PickerCropConfig>\n  /**\n   * Specialized version of `std::optional<PickerCropConfig>`.\n   */\n  using std__optional_PickerCropConfig_ = std::optional<PickerCropConfig>;\n  inline std::optional<PickerCropConfig> create_std__optional_PickerCropConfig_(const PickerCropConfig& value) {\n    return std::optional<PickerCropConfig>(value);\n  }\n  \n  // pragma MARK: std::optional<Text>\n  /**\n   * Specialized version of `std::optional<Text>`.\n   */\n  using std__optional_Text_ = std::optional<Text>;\n  inline std::optional<Text> create_std__optional_Text_(const Text& value) {\n    return std::optional<Text>(value);\n  }\n  \n  // pragma MARK: std::optional<CameraDevice>\n  /**\n   * Specialized version of `std::optional<CameraDevice>`.\n   */\n  using std__optional_CameraDevice_ = std::optional<CameraDevice>;\n  inline std::optional<CameraDevice> create_std__optional_CameraDevice_(const CameraDevice& value) {\n    return std::optional<CameraDevice>(value);\n  }\n  \n  // pragma MARK: std::optional<PickerCameraConfig>\n  /**\n   * Specialized version of `std::optional<PickerCameraConfig>`.\n   */\n  using std__optional_PickerCameraConfig_ = std::optional<PickerCameraConfig>;\n  inline std::optional<PickerCameraConfig> create_std__optional_PickerCameraConfig_(const PickerCameraConfig& value) {\n    return std::optional<PickerCameraConfig>(value);\n  }\n  \n  // pragma MARK: std::function<void(const std::vector<PickerResult>& /* result */)>\n  /**\n   * Specialized version of `std::function<void(const std::vector<PickerResult>&)>`.\n   */\n  using Func_void_std__vector_PickerResult_ = std::function<void(const std::vector<PickerResult>& /* result */)>;\n  /**\n   * Wrapper class for a `std::function<void(const std::vector<PickerResult>& / * result * /)>`, this can be used from Swift.\n   */\n  class Func_void_std__vector_PickerResult__Wrapper final {\n  public:\n    explicit Func_void_std__vector_PickerResult__Wrapper(std::function<void(const std::vector<PickerResult>& /* result */)>&& func): _function(std::make_shared<std::function<void(const std::vector<PickerResult>& /* result */)>>(std::move(func))) {}\n    inline void call(std::vector<PickerResult> result) const {\n      _function->operator()(result);\n    }\n  private:\n    std::shared_ptr<std::function<void(const std::vector<PickerResult>& /* result */)>> _function;\n  };\n  Func_void_std__vector_PickerResult_ create_Func_void_std__vector_PickerResult_(void* _Nonnull swiftClosureWrapper);\n  inline Func_void_std__vector_PickerResult__Wrapper wrap_Func_void_std__vector_PickerResult_(Func_void_std__vector_PickerResult_ value) {\n    return Func_void_std__vector_PickerResult__Wrapper(std::move(value));\n  }\n  \n  // pragma MARK: std::function<void(double /* reject */)>\n  /**\n   * Specialized version of `std::function<void(double)>`.\n   */\n  using Func_void_double = std::function<void(double /* reject */)>;\n  /**\n   * Wrapper class for a `std::function<void(double / * reject * /)>`, this can be used from Swift.\n   */\n  class Func_void_double_Wrapper final {\n  public:\n    explicit Func_void_double_Wrapper(std::function<void(double /* reject */)>&& func): _function(std::make_shared<std::function<void(double /* reject */)>>(std::move(func))) {}\n    inline void call(double reject) const {\n      _function->operator()(reject);\n    }\n  private:\n    std::shared_ptr<std::function<void(double /* reject */)>> _function;\n  };\n  Func_void_double create_Func_void_double(void* _Nonnull swiftClosureWrapper);\n  inline Func_void_double_Wrapper wrap_Func_void_double(Func_void_double value) {\n    return Func_void_double_Wrapper(std::move(value));\n  }\n  \n  // pragma MARK: std::function<void(const CropResult& /* result */)>\n  /**\n   * Specialized version of `std::function<void(const CropResult&)>`.\n   */\n  using Func_void_CropResult = std::function<void(const CropResult& /* result */)>;\n  /**\n   * Wrapper class for a `std::function<void(const CropResult& / * result * /)>`, this can be used from Swift.\n   */\n  class Func_void_CropResult_Wrapper final {\n  public:\n    explicit Func_void_CropResult_Wrapper(std::function<void(const CropResult& /* result */)>&& func): _function(std::make_shared<std::function<void(const CropResult& /* result */)>>(std::move(func))) {}\n    inline void call(CropResult result) const {\n      _function->operator()(result);\n    }\n  private:\n    std::shared_ptr<std::function<void(const CropResult& /* result */)>> _function;\n  };\n  Func_void_CropResult create_Func_void_CropResult(void* _Nonnull swiftClosureWrapper);\n  inline Func_void_CropResult_Wrapper wrap_Func_void_CropResult(Func_void_CropResult value) {\n    return Func_void_CropResult_Wrapper(std::move(value));\n  }\n  \n  // pragma MARK: std::vector<MediaPreview>\n  /**\n   * Specialized version of `std::vector<MediaPreview>`.\n   */\n  using std__vector_MediaPreview_ = std::vector<MediaPreview>;\n  inline std::vector<MediaPreview> create_std__vector_MediaPreview_(size_t size) {\n    std::vector<MediaPreview> vector;\n    vector.reserve(size);\n    return vector;\n  }\n  \n  // pragma MARK: std::function<void(const CameraResult& /* result */)>\n  /**\n   * Specialized version of `std::function<void(const CameraResult&)>`.\n   */\n  using Func_void_CameraResult = std::function<void(const CameraResult& /* result */)>;\n  /**\n   * Wrapper class for a `std::function<void(const CameraResult& / * result * /)>`, this can be used from Swift.\n   */\n  class Func_void_CameraResult_Wrapper final {\n  public:\n    explicit Func_void_CameraResult_Wrapper(std::function<void(const CameraResult& /* result */)>&& func): _function(std::make_shared<std::function<void(const CameraResult& /* result */)>>(std::move(func))) {}\n    inline void call(CameraResult result) const {\n      _function->operator()(result);\n    }\n  private:\n    std::shared_ptr<std::function<void(const CameraResult& /* result */)>> _function;\n  };\n  Func_void_CameraResult create_Func_void_CameraResult(void* _Nonnull swiftClosureWrapper);\n  inline Func_void_CameraResult_Wrapper wrap_Func_void_CameraResult(Func_void_CameraResult value) {\n    return Func_void_CameraResult_Wrapper(std::move(value));\n  }\n  \n  // pragma MARK: std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>\n  /**\n   * Specialized version of `std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>`.\n   */\n  using std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ = std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>;\n  std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec> create_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(void* _Nonnull swiftUnsafePointer);\n  void* _Nonnull get_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ cppType);\n  \n  // pragma MARK: std::weak_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>\n  using std__weak_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ = std::weak_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>;\n  inline std__weak_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ weakify_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(const std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>& strong) { return strong; }\n  \n  // pragma MARK: Result<void>\n  using Result_void_ = Result<void>;\n  inline Result_void_ create_Result_void_() {\n    return Result<void>::withValue();\n  }\n  inline Result_void_ create_Result_void_(const std::exception_ptr& error) {\n    return Result<void>::withError(error);\n  }\n\n} // namespace margelo::nitro::multipleimagepicker::bridge::swift\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePicker-Swift-Cxx-Umbrella.hpp",
    "content": "///\n/// MultipleImagePicker-Swift-Cxx-Umbrella.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n// Forward declarations of C++ defined types\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n// Forward declaration of `CameraResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CameraResult; }\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n// Forward declaration of `CropResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropResult; }\n// Forward declaration of `HybridMultipleImagePickerSpec` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { class HybridMultipleImagePickerSpec; }\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `MediaPreview` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct MediaPreview; }\n// Forward declaration of `MediaType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class MediaType; }\n// Forward declaration of `NitroCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCameraConfig; }\n// Forward declaration of `NitroConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroConfig; }\n// Forward declaration of `NitroCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCropConfig; }\n// Forward declaration of `NitroPreviewConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroPreviewConfig; }\n// Forward declaration of `PickerCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCameraConfig; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n// Forward declaration of `SelectBoxStyle` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectBoxStyle; }\n// Forward declaration of `SelectMode` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectMode; }\n// Forward declaration of `Text` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct Text; }\n// Forward declaration of `Theme` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Theme; }\n\n// Include C++ defined types\n#include \"CameraDevice.hpp\"\n#include \"CameraResult.hpp\"\n#include \"CropRatio.hpp\"\n#include \"CropResult.hpp\"\n#include \"HybridMultipleImagePickerSpec.hpp\"\n#include \"Language.hpp\"\n#include \"MediaPreview.hpp\"\n#include \"MediaType.hpp\"\n#include \"NitroCameraConfig.hpp\"\n#include \"NitroConfig.hpp\"\n#include \"NitroCropConfig.hpp\"\n#include \"NitroPreviewConfig.hpp\"\n#include \"PickerCameraConfig.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"PickerResult.hpp\"\n#include \"Presentation.hpp\"\n#include \"ResultType.hpp\"\n#include \"SelectBoxStyle.hpp\"\n#include \"SelectMode.hpp\"\n#include \"Text.hpp\"\n#include \"Theme.hpp\"\n#include <NitroModules/Result.hpp>\n#include <exception>\n#include <functional>\n#include <memory>\n#include <optional>\n#include <string>\n#include <vector>\n\n// C++ helpers for Swift\n#include \"MultipleImagePicker-Swift-Cxx-Bridge.hpp\"\n\n// Common C++ types used in Swift\n#include <NitroModules/ArrayBufferHolder.hpp>\n#include <NitroModules/AnyMapHolder.hpp>\n#include <NitroModules/RuntimeError.hpp>\n\n// Forward declarations of Swift defined types\n// Forward declaration of `HybridMultipleImagePickerSpec_cxx` to properly resolve imports.\nnamespace MultipleImagePicker { class HybridMultipleImagePickerSpec_cxx; }\n\n// Include Swift defined types\n#if __has_include(\"MultipleImagePicker-Swift.h\")\n// This header is generated by Xcode/Swift on every app build.\n// If it cannot be found, make sure the Swift module's name (= podspec name) is actually \"MultipleImagePicker\".\n#include \"MultipleImagePicker-Swift.h\"\n// Same as above, but used when building with frameworks (`use_frameworks`)\n#elif __has_include(<MultipleImagePicker/MultipleImagePicker-Swift.h>)\n#include <MultipleImagePicker/MultipleImagePicker-Swift.h>\n#else\n#error MultipleImagePicker's autogenerated Swift header cannot be found! Make sure the Swift module's name (= podspec name) is actually \"MultipleImagePicker\", and try building the app first.\n#endif\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePickerAutolinking.mm",
    "content": "///\n/// MultipleImagePickerAutolinking.mm\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#import <Foundation/Foundation.h>\n#import <NitroModules/HybridObjectRegistry.hpp>\n#import \"MultipleImagePicker-Swift-Cxx-Umbrella.hpp\"\n#import <type_traits>\n\n#include \"HybridMultipleImagePickerSpecSwift.hpp\"\n\n@interface MultipleImagePickerAutolinking : NSObject\n@end\n\n@implementation MultipleImagePickerAutolinking\n\n+ (void) load {\n  using namespace margelo::nitro;\n  using namespace margelo::nitro::multipleimagepicker;\n\n  HybridObjectRegistry::registerHybridObjectConstructor(\n    \"MultipleImagePicker\",\n    []() -> std::shared_ptr<HybridObject> {\n      std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec> hybridObject = MultipleImagePicker::MultipleImagePickerAutolinking::createMultipleImagePicker();\n      return hybridObject;\n    }\n  );\n}\n\n@end\n"
  },
  {
    "path": "nitrogen/generated/ios/MultipleImagePickerAutolinking.swift",
    "content": "///\n/// MultipleImagePickerAutolinking.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\npublic final class MultipleImagePickerAutolinking {\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Creates an instance of a Swift class that implements `HybridMultipleImagePickerSpec`,\n   * and wraps it in a Swift class that can directly interop with C++ (`HybridMultipleImagePickerSpec_cxx`)\n   *\n   * This is generated by Nitrogen and will initialize the class specified\n   * in the `\"autolinking\"` property of `nitro.json` (in this case, `HybridMultipleImagePicker`).\n   */\n  public static func createMultipleImagePicker() -> bridge.std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ {\n    let hybridObject = HybridMultipleImagePicker()\n    return { () -> bridge.std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ in\n      let __cxxWrapped = hybridObject.getCxxWrapper()\n      return __cxxWrapped.getCxxPart()\n    }()\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/c++/HybridMultipleImagePickerSpecSwift.cpp",
    "content": "///\n/// HybridMultipleImagePickerSpecSwift.cpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#include \"HybridMultipleImagePickerSpecSwift.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/ios/c++/HybridMultipleImagePickerSpecSwift.hpp",
    "content": "///\n/// HybridMultipleImagePickerSpecSwift.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#include \"HybridMultipleImagePickerSpec.hpp\"\n\n// Forward declaration of `HybridMultipleImagePickerSpec_cxx` to properly resolve imports.\nnamespace MultipleImagePicker { class HybridMultipleImagePickerSpec_cxx; }\n\n// Forward declaration of `NitroConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroConfig; }\n// Forward declaration of `MediaType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class MediaType; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n// Forward declaration of `SelectBoxStyle` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectBoxStyle; }\n// Forward declaration of `SelectMode` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectMode; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n// Forward declaration of `Text` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct Text; }\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `Theme` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Theme; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `PickerCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCameraConfig; }\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n// Forward declaration of `NitroCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCropConfig; }\n// Forward declaration of `CropResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropResult; }\n// Forward declaration of `MediaPreview` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct MediaPreview; }\n// Forward declaration of `NitroPreviewConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroPreviewConfig; }\n// Forward declaration of `NitroCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCameraConfig; }\n// Forward declaration of `CameraResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CameraResult; }\n\n#include \"NitroConfig.hpp\"\n#include \"MediaType.hpp\"\n#include <vector>\n#include \"PickerResult.hpp\"\n#include <string>\n#include <optional>\n#include \"ResultType.hpp\"\n#include \"SelectBoxStyle.hpp\"\n#include \"SelectMode.hpp\"\n#include \"PickerCropConfig.hpp\"\n#include \"CropRatio.hpp\"\n#include \"Text.hpp\"\n#include \"Language.hpp\"\n#include \"Theme.hpp\"\n#include \"Presentation.hpp\"\n#include \"PickerCameraConfig.hpp\"\n#include \"CameraDevice.hpp\"\n#include <functional>\n#include \"NitroCropConfig.hpp\"\n#include \"CropResult.hpp\"\n#include \"MediaPreview.hpp\"\n#include \"NitroPreviewConfig.hpp\"\n#include \"NitroCameraConfig.hpp\"\n#include \"CameraResult.hpp\"\n\n#include \"MultipleImagePicker-Swift-Cxx-Umbrella.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * The C++ part of HybridMultipleImagePickerSpec_cxx.swift.\n   *\n   * HybridMultipleImagePickerSpecSwift (C++) accesses HybridMultipleImagePickerSpec_cxx (Swift), and might\n   * contain some additional bridging code for C++ <> Swift interop.\n   *\n   * Since this obviously introduces an overhead, I hope at some point in\n   * the future, HybridMultipleImagePickerSpec_cxx can directly inherit from the C++ class HybridMultipleImagePickerSpec\n   * to simplify the whole structure and memory management.\n   */\n  class HybridMultipleImagePickerSpecSwift: public virtual HybridMultipleImagePickerSpec {\n  public:\n    // Constructor from a Swift instance\n    explicit HybridMultipleImagePickerSpecSwift(const MultipleImagePicker::HybridMultipleImagePickerSpec_cxx& swiftPart):\n      HybridObject(HybridMultipleImagePickerSpec::TAG),\n      _swiftPart(swiftPart) { }\n\n  public:\n    // Get the Swift part\n    inline MultipleImagePicker::HybridMultipleImagePickerSpec_cxx& getSwiftPart() noexcept {\n      return _swiftPart;\n    }\n\n  public:\n    // Get memory pressure\n    inline size_t getExternalMemorySize() noexcept override {\n      return _swiftPart.getMemorySize();\n    }\n\n  public:\n    // Properties\n    \n\n  public:\n    // Methods\n    inline void openPicker(const NitroConfig& config, const std::function<void(const std::vector<PickerResult>& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override {\n      auto __result = _swiftPart.openPicker(config, resolved, rejected);\n      if (__result.hasError()) [[unlikely]] {\n        std::rethrow_exception(__result.error());\n      }\n    }\n    inline void openCrop(const std::string& image, const NitroCropConfig& config, const std::function<void(const CropResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override {\n      auto __result = _swiftPart.openCrop(image, config, resolved, rejected);\n      if (__result.hasError()) [[unlikely]] {\n        std::rethrow_exception(__result.error());\n      }\n    }\n    inline void openPreview(const std::vector<MediaPreview>& media, double index, const NitroPreviewConfig& config, const std::function<void(double /* index */)>& onLongPress) override {\n      auto __result = _swiftPart.openPreview(media, std::forward<decltype(index)>(index), config, onLongPress);\n      if (__result.hasError()) [[unlikely]] {\n        std::rethrow_exception(__result.error());\n      }\n    }\n    inline void openCamera(const NitroCameraConfig& config, const std::function<void(const CameraResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) override {\n      auto __result = _swiftPart.openCamera(config, resolved, rejected);\n      if (__result.hasError()) [[unlikely]] {\n        std::rethrow_exception(__result.error());\n      }\n    }\n\n  private:\n    MultipleImagePicker::HybridMultipleImagePickerSpec_cxx _swiftPart;\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/CameraDevice.swift",
    "content": "///\n/// CameraDevice.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `CameraDevice`, backed by a C++ enum.\n */\npublic typealias CameraDevice = margelo.nitro.multipleimagepicker.CameraDevice\n\npublic extension CameraDevice {\n  /**\n   * Get a CameraDevice for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"front\":\n        self = .front\n      case \"back\":\n        self = .back\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this CameraDevice represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .front:\n        return \"front\"\n      case .back:\n        return \"back\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/CameraResult.swift",
    "content": "///\n/// CameraResult.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `CameraResult`, backed by a C++ struct.\n */\npublic typealias CameraResult = margelo.nitro.multipleimagepicker.CameraResult\n\npublic extension CameraResult {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `CameraResult`.\n   */\n  init(path: String, type: ResultType, width: Double?, height: Double?, duration: Double?, thumbnail: String?, fileName: String?) {\n    self.init(std.string(path), type, { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = width {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = height {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = duration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = thumbnail {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = fileName {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var path: String {\n    @inline(__always)\n    get {\n      return String(self.__path)\n    }\n    @inline(__always)\n    set {\n      self.__path = std.string(newValue)\n    }\n  }\n  \n  var type: ResultType {\n    @inline(__always)\n    get {\n      return self.__type\n    }\n    @inline(__always)\n    set {\n      self.__type = newValue\n    }\n  }\n  \n  var width: Double? {\n    @inline(__always)\n    get {\n      return self.__width.value\n    }\n    @inline(__always)\n    set {\n      self.__width = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var height: Double? {\n    @inline(__always)\n    get {\n      return self.__height.value\n    }\n    @inline(__always)\n    set {\n      self.__height = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var duration: Double? {\n    @inline(__always)\n    get {\n      return self.__duration.value\n    }\n    @inline(__always)\n    set {\n      self.__duration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var thumbnail: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__thumbnail.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__thumbnail = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var fileName: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__fileName.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__fileName = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/CropRatio.swift",
    "content": "///\n/// CropRatio.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `CropRatio`, backed by a C++ struct.\n */\npublic typealias CropRatio = margelo.nitro.multipleimagepicker.CropRatio\n\npublic extension CropRatio {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `CropRatio`.\n   */\n  init(title: String?, width: Double, height: Double) {\n    self.init({ () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = title {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), width, height)\n  }\n\n  var title: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__title.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__title = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var width: Double {\n    @inline(__always)\n    get {\n      return self.__width\n    }\n    @inline(__always)\n    set {\n      self.__width = newValue\n    }\n  }\n  \n  var height: Double {\n    @inline(__always)\n    get {\n      return self.__height\n    }\n    @inline(__always)\n    set {\n      self.__height = newValue\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/CropResult.swift",
    "content": "///\n/// CropResult.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `CropResult`, backed by a C++ struct.\n */\npublic typealias CropResult = margelo.nitro.multipleimagepicker.CropResult\n\npublic extension CropResult {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `CropResult`.\n   */\n  init(path: String, width: Double, height: Double) {\n    self.init(std.string(path), width, height)\n  }\n\n  var path: String {\n    @inline(__always)\n    get {\n      return String(self.__path)\n    }\n    @inline(__always)\n    set {\n      self.__path = std.string(newValue)\n    }\n  }\n  \n  var width: Double {\n    @inline(__always)\n    get {\n      return self.__width\n    }\n    @inline(__always)\n    set {\n      self.__width = newValue\n    }\n  }\n  \n  var height: Double {\n    @inline(__always)\n    get {\n      return self.__height\n    }\n    @inline(__always)\n    set {\n      self.__height = newValue\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Func_void_CameraResult.swift",
    "content": "///\n/// Func_void_CameraResult.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Wraps a Swift `(_ result: CameraResult) -> Void` as a class.\n * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.\n */\npublic final class Func_void_CameraResult {\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  private let closure: (_ result: CameraResult) -> Void\n\n  public init(_ closure: @escaping (_ result: CameraResult) -> Void) {\n    self.closure = closure\n  }\n\n  @inline(__always)\n  public func call(result: CameraResult) -> Void {\n    self.closure(result)\n  }\n\n  /**\n   * Casts this instance to a retained unsafe raw pointer.\n   * This acquires one additional strong reference on the object!\n   */\n  @inline(__always)\n  public func toUnsafe() -> UnsafeMutableRawPointer {\n    return Unmanaged.passRetained(self).toOpaque()\n  }\n\n  /**\n   * Casts an unsafe pointer to a `Func_void_CameraResult`.\n   * The pointer has to be a retained opaque `Unmanaged<Func_void_CameraResult>`.\n   * This removes one strong reference from the object!\n   */\n  @inline(__always)\n  public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_CameraResult {\n    return Unmanaged<Func_void_CameraResult>.fromOpaque(pointer).takeRetainedValue()\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Func_void_CropResult.swift",
    "content": "///\n/// Func_void_CropResult.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Wraps a Swift `(_ result: CropResult) -> Void` as a class.\n * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.\n */\npublic final class Func_void_CropResult {\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  private let closure: (_ result: CropResult) -> Void\n\n  public init(_ closure: @escaping (_ result: CropResult) -> Void) {\n    self.closure = closure\n  }\n\n  @inline(__always)\n  public func call(result: CropResult) -> Void {\n    self.closure(result)\n  }\n\n  /**\n   * Casts this instance to a retained unsafe raw pointer.\n   * This acquires one additional strong reference on the object!\n   */\n  @inline(__always)\n  public func toUnsafe() -> UnsafeMutableRawPointer {\n    return Unmanaged.passRetained(self).toOpaque()\n  }\n\n  /**\n   * Casts an unsafe pointer to a `Func_void_CropResult`.\n   * The pointer has to be a retained opaque `Unmanaged<Func_void_CropResult>`.\n   * This removes one strong reference from the object!\n   */\n  @inline(__always)\n  public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_CropResult {\n    return Unmanaged<Func_void_CropResult>.fromOpaque(pointer).takeRetainedValue()\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Func_void_double.swift",
    "content": "///\n/// Func_void_double.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Wraps a Swift `(_ index: Double) -> Void` as a class.\n * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.\n */\npublic final class Func_void_double {\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  private let closure: (_ index: Double) -> Void\n\n  public init(_ closure: @escaping (_ index: Double) -> Void) {\n    self.closure = closure\n  }\n\n  @inline(__always)\n  public func call(index: Double) -> Void {\n    self.closure(index)\n  }\n\n  /**\n   * Casts this instance to a retained unsafe raw pointer.\n   * This acquires one additional strong reference on the object!\n   */\n  @inline(__always)\n  public func toUnsafe() -> UnsafeMutableRawPointer {\n    return Unmanaged.passRetained(self).toOpaque()\n  }\n\n  /**\n   * Casts an unsafe pointer to a `Func_void_double`.\n   * The pointer has to be a retained opaque `Unmanaged<Func_void_double>`.\n   * This removes one strong reference from the object!\n   */\n  @inline(__always)\n  public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_double {\n    return Unmanaged<Func_void_double>.fromOpaque(pointer).takeRetainedValue()\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Func_void_std__vector_PickerResult_.swift",
    "content": "///\n/// Func_void_std__vector_PickerResult_.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Wraps a Swift `(_ result: [PickerResult]) -> Void` as a class.\n * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.\n */\npublic final class Func_void_std__vector_PickerResult_ {\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  private let closure: (_ result: [PickerResult]) -> Void\n\n  public init(_ closure: @escaping (_ result: [PickerResult]) -> Void) {\n    self.closure = closure\n  }\n\n  @inline(__always)\n  public func call(result: bridge.std__vector_PickerResult_) -> Void {\n    self.closure(result.map({ __item in __item }))\n  }\n\n  /**\n   * Casts this instance to a retained unsafe raw pointer.\n   * This acquires one additional strong reference on the object!\n   */\n  @inline(__always)\n  public func toUnsafe() -> UnsafeMutableRawPointer {\n    return Unmanaged.passRetained(self).toOpaque()\n  }\n\n  /**\n   * Casts an unsafe pointer to a `Func_void_std__vector_PickerResult_`.\n   * The pointer has to be a retained opaque `Unmanaged<Func_void_std__vector_PickerResult_>`.\n   * This removes one strong reference from the object!\n   */\n  @inline(__always)\n  public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_std__vector_PickerResult_ {\n    return Unmanaged<Func_void_std__vector_PickerResult_>.fromOpaque(pointer).takeRetainedValue()\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/HybridMultipleImagePickerSpec.swift",
    "content": "///\n/// HybridMultipleImagePickerSpec.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport Foundation\nimport NitroModules\n\n/// See ``HybridMultipleImagePickerSpec``\npublic protocol HybridMultipleImagePickerSpec_protocol: HybridObject {\n  // Properties\n  \n\n  // Methods\n  func openPicker(config: NitroConfig, resolved: @escaping (_ result: [PickerResult]) -> Void, rejected: @escaping (_ reject: Double) -> Void) throws -> Void\n  func openCrop(image: String, config: NitroCropConfig, resolved: @escaping (_ result: CropResult) -> Void, rejected: @escaping (_ reject: Double) -> Void) throws -> Void\n  func openPreview(media: [MediaPreview], index: Double, config: NitroPreviewConfig, onLongPress: @escaping (_ index: Double) -> Void) throws -> Void\n  func openCamera(config: NitroCameraConfig, resolved: @escaping (_ result: CameraResult) -> Void, rejected: @escaping (_ reject: Double) -> Void) throws -> Void\n}\n\n/// See ``HybridMultipleImagePickerSpec``\npublic class HybridMultipleImagePickerSpec_base {\n  private weak var cxxWrapper: HybridMultipleImagePickerSpec_cxx? = nil\n  public func getCxxWrapper() -> HybridMultipleImagePickerSpec_cxx {\n  #if DEBUG\n    guard self is HybridMultipleImagePickerSpec else {\n      fatalError(\"`self` is not a `HybridMultipleImagePickerSpec`! Did you accidentally inherit from `HybridMultipleImagePickerSpec_base` instead of `HybridMultipleImagePickerSpec`?\")\n    }\n  #endif\n    if let cxxWrapper = self.cxxWrapper {\n      return cxxWrapper\n    } else {\n      let cxxWrapper = HybridMultipleImagePickerSpec_cxx(self as! HybridMultipleImagePickerSpec)\n      self.cxxWrapper = cxxWrapper\n      return cxxWrapper\n    }\n  }\n}\n\n/**\n * A Swift base-protocol representing the MultipleImagePicker HybridObject.\n * Implement this protocol to create Swift-based instances of MultipleImagePicker.\n * ```swift\n * class HybridMultipleImagePicker : HybridMultipleImagePickerSpec {\n *   // ...\n * }\n * ```\n */\npublic typealias HybridMultipleImagePickerSpec = HybridMultipleImagePickerSpec_protocol & HybridMultipleImagePickerSpec_base\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/HybridMultipleImagePickerSpec_cxx.swift",
    "content": "///\n/// HybridMultipleImagePickerSpec_cxx.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport Foundation\nimport NitroModules\n\n/**\n * A class implementation that bridges HybridMultipleImagePickerSpec over to C++.\n * In C++, we cannot use Swift protocols - so we need to wrap it in a class to make it strongly defined.\n *\n * Also, some Swift types need to be bridged with special handling:\n * - Enums need to be wrapped in Structs, otherwise they cannot be accessed bi-directionally (Swift bug: https://github.com/swiftlang/swift/issues/75330)\n * - Other HybridObjects need to be wrapped/unwrapped from the Swift TCxx wrapper\n * - Throwing methods need to be wrapped with a Result<T, Error> type, as exceptions cannot be propagated to C++\n */\npublic class HybridMultipleImagePickerSpec_cxx {\n  /**\n   * The Swift <> C++ bridge's namespace (`margelo::nitro::multipleimagepicker::bridge::swift`)\n   * from `MultipleImagePicker-Swift-Cxx-Bridge.hpp`.\n   * This contains specialized C++ templates, and C++ helper functions that can be accessed from Swift.\n   */\n  public typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Holds an instance of the `HybridMultipleImagePickerSpec` Swift protocol.\n   */\n  private var __implementation: any HybridMultipleImagePickerSpec\n\n  /**\n   * Holds a weak pointer to the C++ class that wraps the Swift class.\n   */\n  private var __cxxPart: bridge.std__weak_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_\n\n  /**\n   * Create a new `HybridMultipleImagePickerSpec_cxx` that wraps the given `HybridMultipleImagePickerSpec`.\n   * All properties and methods bridge to C++ types.\n   */\n  public init(_ implementation: any HybridMultipleImagePickerSpec) {\n    self.__implementation = implementation\n    self.__cxxPart = .init()\n    /* no base class */\n  }\n\n  /**\n   * Get the actual `HybridMultipleImagePickerSpec` instance this class wraps.\n   */\n  @inline(__always)\n  public func getHybridMultipleImagePickerSpec() -> any HybridMultipleImagePickerSpec {\n    return __implementation\n  }\n\n  /**\n   * Casts this instance to a retained unsafe raw pointer.\n   * This acquires one additional strong reference on the object!\n   */\n  public func toUnsafe() -> UnsafeMutableRawPointer {\n    return Unmanaged.passRetained(self).toOpaque()\n  }\n\n  /**\n   * Casts an unsafe pointer to a `HybridMultipleImagePickerSpec_cxx`.\n   * The pointer has to be a retained opaque `Unmanaged<HybridMultipleImagePickerSpec_cxx>`.\n   * This removes one strong reference from the object!\n   */\n  public class func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> HybridMultipleImagePickerSpec_cxx {\n    return Unmanaged<HybridMultipleImagePickerSpec_cxx>.fromOpaque(pointer).takeRetainedValue()\n  }\n\n  /**\n   * Gets (or creates) the C++ part of this Hybrid Object.\n   * The C++ part is a `std::shared_ptr<margelo::nitro::multipleimagepicker::HybridMultipleImagePickerSpec>`.\n   */\n  public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_ {\n    let cachedCxxPart = self.__cxxPart.lock()\n    if cachedCxxPart.__convertToBool() {\n      return cachedCxxPart\n    } else {\n      let newCxxPart = bridge.create_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(self.toUnsafe())\n      __cxxPart = bridge.weakify_std__shared_ptr_margelo__nitro__multipleimagepicker__HybridMultipleImagePickerSpec_(newCxxPart)\n      return newCxxPart\n    }\n  }\n\n  \n\n  /**\n   * Get the memory size of the Swift class (plus size of any other allocations)\n   * so the JS VM can properly track it and garbage-collect the JS object if needed.\n   */\n  @inline(__always)\n  public var memorySize: Int {\n    return MemoryHelper.getSizeOf(self.__implementation) + self.__implementation.memorySize\n  }\n\n  // Properties\n  \n\n  // Methods\n  @inline(__always)\n  public final func openPicker(config: NitroConfig, resolved: bridge.Func_void_std__vector_PickerResult_, rejected: bridge.Func_void_double) -> bridge.Result_void_ {\n    do {\n      try self.__implementation.openPicker(config: config, resolved: { () -> ([PickerResult]) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_std__vector_PickerResult_(resolved)\n        return { (__result: [PickerResult]) -> Void in\n          __wrappedFunction.call({ () -> bridge.std__vector_PickerResult_ in\n            var __vector = bridge.create_std__vector_PickerResult_(__result.count)\n            for __item in __result {\n              __vector.push_back(__item)\n            }\n            return __vector\n          }())\n        }\n      }(), rejected: { () -> (Double) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_double(rejected)\n        return { (__reject: Double) -> Void in\n          __wrappedFunction.call(__reject)\n        }\n      }())\n      return bridge.create_Result_void_()\n    } catch (let __error) {\n      let __exceptionPtr = __error.toCpp()\n      return bridge.create_Result_void_(__exceptionPtr)\n    }\n  }\n  \n  @inline(__always)\n  public final func openCrop(image: std.string, config: NitroCropConfig, resolved: bridge.Func_void_CropResult, rejected: bridge.Func_void_double) -> bridge.Result_void_ {\n    do {\n      try self.__implementation.openCrop(image: String(image), config: config, resolved: { () -> (CropResult) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_CropResult(resolved)\n        return { (__result: CropResult) -> Void in\n          __wrappedFunction.call(__result)\n        }\n      }(), rejected: { () -> (Double) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_double(rejected)\n        return { (__reject: Double) -> Void in\n          __wrappedFunction.call(__reject)\n        }\n      }())\n      return bridge.create_Result_void_()\n    } catch (let __error) {\n      let __exceptionPtr = __error.toCpp()\n      return bridge.create_Result_void_(__exceptionPtr)\n    }\n  }\n  \n  @inline(__always)\n  public final func openPreview(media: bridge.std__vector_MediaPreview_, index: Double, config: NitroPreviewConfig, onLongPress: bridge.Func_void_double) -> bridge.Result_void_ {\n    do {\n      try self.__implementation.openPreview(media: media.map({ __item in __item }), index: index, config: config, onLongPress: { () -> (Double) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_double(onLongPress)\n        return { (__index: Double) -> Void in\n          __wrappedFunction.call(__index)\n        }\n      }())\n      return bridge.create_Result_void_()\n    } catch (let __error) {\n      let __exceptionPtr = __error.toCpp()\n      return bridge.create_Result_void_(__exceptionPtr)\n    }\n  }\n  \n  @inline(__always)\n  public final func openCamera(config: NitroCameraConfig, resolved: bridge.Func_void_CameraResult, rejected: bridge.Func_void_double) -> bridge.Result_void_ {\n    do {\n      try self.__implementation.openCamera(config: config, resolved: { () -> (CameraResult) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_CameraResult(resolved)\n        return { (__result: CameraResult) -> Void in\n          __wrappedFunction.call(__result)\n        }\n      }(), rejected: { () -> (Double) -> Void in\n        let __wrappedFunction = bridge.wrap_Func_void_double(rejected)\n        return { (__reject: Double) -> Void in\n          __wrappedFunction.call(__reject)\n        }\n      }())\n      return bridge.create_Result_void_()\n    } catch (let __error) {\n      let __exceptionPtr = __error.toCpp()\n      return bridge.create_Result_void_(__exceptionPtr)\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Language.swift",
    "content": "///\n/// Language.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `Language`, backed by a C++ enum.\n */\npublic typealias Language = margelo.nitro.multipleimagepicker.Language\n\npublic extension Language {\n  /**\n   * Get a Language for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"system\":\n        self = .system\n      case \"zh-Hans\":\n        self = .zhHans\n      case \"zh-Hant\":\n        self = .zhHant\n      case \"ja\":\n        self = .ja\n      case \"ko\":\n        self = .ko\n      case \"en\":\n        self = .en\n      case \"th\":\n        self = .th\n      case \"id\":\n        self = .id\n      case \"vi\":\n        self = .vi\n      case \"ru\":\n        self = .ru\n      case \"de\":\n        self = .de\n      case \"fr\":\n        self = .fr\n      case \"ar\":\n        self = .ar\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this Language represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .system:\n        return \"system\"\n      case .zhHans:\n        return \"zh-Hans\"\n      case .zhHant:\n        return \"zh-Hant\"\n      case .ja:\n        return \"ja\"\n      case .ko:\n        return \"ko\"\n      case .en:\n        return \"en\"\n      case .th:\n        return \"th\"\n      case .id:\n        return \"id\"\n      case .vi:\n        return \"vi\"\n      case .ru:\n        return \"ru\"\n      case .de:\n        return \"de\"\n      case .fr:\n        return \"fr\"\n      case .ar:\n        return \"ar\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/MediaPreview.swift",
    "content": "///\n/// MediaPreview.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `MediaPreview`, backed by a C++ struct.\n */\npublic typealias MediaPreview = margelo.nitro.multipleimagepicker.MediaPreview\n\npublic extension MediaPreview {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `MediaPreview`.\n   */\n  init(type: ResultType, path: String?, thumbnail: String?, localIdentifier: String?) {\n    self.init(type, { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = path {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = thumbnail {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = localIdentifier {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var type: ResultType {\n    @inline(__always)\n    get {\n      return self.__type\n    }\n    @inline(__always)\n    set {\n      self.__type = newValue\n    }\n  }\n  \n  var path: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__path.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__path = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var thumbnail: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__thumbnail.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__thumbnail = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var localIdentifier: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__localIdentifier.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__localIdentifier = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/MediaType.swift",
    "content": "///\n/// MediaType.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `MediaType`, backed by a C++ enum.\n */\npublic typealias MediaType = margelo.nitro.multipleimagepicker.MediaType\n\npublic extension MediaType {\n  /**\n   * Get a MediaType for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"video\":\n        self = .video\n      case \"image\":\n        self = .image\n      case \"all\":\n        self = .all\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this MediaType represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .video:\n        return \"video\"\n      case .image:\n        return \"image\"\n      case .all:\n        return \"all\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/NitroCameraConfig.swift",
    "content": "///\n/// NitroCameraConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `NitroCameraConfig`, backed by a C++ struct.\n */\npublic typealias NitroCameraConfig = margelo.nitro.multipleimagepicker.NitroCameraConfig\n\npublic extension NitroCameraConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `NitroCameraConfig`.\n   */\n  init(mediaType: MediaType, presentation: Presentation, language: Language, crop: PickerCropConfig?, isSaveSystemAlbum: Bool?, color: Double?, cameraDevice: CameraDevice?, videoMaximumDuration: Double?) {\n    self.init(mediaType, presentation, language, { () -> bridge.std__optional_PickerCropConfig_ in\n      if let __unwrappedValue = crop {\n        return bridge.create_std__optional_PickerCropConfig_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = isSaveSystemAlbum {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = color {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_CameraDevice_ in\n      if let __unwrappedValue = cameraDevice {\n        return bridge.create_std__optional_CameraDevice_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = videoMaximumDuration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var mediaType: MediaType {\n    @inline(__always)\n    get {\n      return self.__mediaType\n    }\n    @inline(__always)\n    set {\n      self.__mediaType = newValue\n    }\n  }\n  \n  var presentation: Presentation {\n    @inline(__always)\n    get {\n      return self.__presentation\n    }\n    @inline(__always)\n    set {\n      self.__presentation = newValue\n    }\n  }\n  \n  var language: Language {\n    @inline(__always)\n    get {\n      return self.__language\n    }\n    @inline(__always)\n    set {\n      self.__language = newValue\n    }\n  }\n  \n  var crop: PickerCropConfig? {\n    @inline(__always)\n    get {\n      return { () -> PickerCropConfig? in\n        if let __unwrapped = self.__crop.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__crop = { () -> bridge.std__optional_PickerCropConfig_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_PickerCropConfig_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var isSaveSystemAlbum: Bool? {\n    @inline(__always)\n    get {\n      return self.__isSaveSystemAlbum.value\n    }\n    @inline(__always)\n    set {\n      self.__isSaveSystemAlbum = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var color: Double? {\n    @inline(__always)\n    get {\n      return self.__color.value\n    }\n    @inline(__always)\n    set {\n      self.__color = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var cameraDevice: CameraDevice? {\n    @inline(__always)\n    get {\n      return self.__cameraDevice.value\n    }\n    @inline(__always)\n    set {\n      self.__cameraDevice = { () -> bridge.std__optional_CameraDevice_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_CameraDevice_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var videoMaximumDuration: Double? {\n    @inline(__always)\n    get {\n      return self.__videoMaximumDuration.value\n    }\n    @inline(__always)\n    set {\n      self.__videoMaximumDuration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/NitroConfig.swift",
    "content": "///\n/// NitroConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `NitroConfig`, backed by a C++ struct.\n */\npublic typealias NitroConfig = margelo.nitro.multipleimagepicker.NitroConfig\n\npublic extension NitroConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `NitroConfig`.\n   */\n  init(mediaType: MediaType, selectedAssets: [PickerResult], selectBoxStyle: SelectBoxStyle, selectMode: SelectMode, numberOfColumn: Double?, isPreview: Bool?, primaryColor: Double?, allowSwipeToSelect: Bool?, spacing: Double?, isHiddenPreviewButton: Bool?, isHiddenOriginalButton: Bool?, isShowPreviewList: Bool?, allowHapticTouchPreview: Bool?, allowedLimit: Bool?, maxVideo: Double?, maxSelect: Double?, maxVideoDuration: Double?, minVideoDuration: Double?, maxFileSize: Double?, backgroundDark: Double?, crop: PickerCropConfig?, text: Text?, language: Language, theme: Theme, presentation: Presentation, camera: PickerCameraConfig?) {\n    self.init(mediaType, { () -> bridge.std__vector_PickerResult_ in\n      var __vector = bridge.create_std__vector_PickerResult_(selectedAssets.count)\n      for __item in selectedAssets {\n        __vector.push_back(__item)\n      }\n      return __vector\n    }(), selectBoxStyle, selectMode, { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = numberOfColumn {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = isPreview {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = primaryColor {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = allowSwipeToSelect {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = spacing {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = isHiddenPreviewButton {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = isHiddenOriginalButton {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = isShowPreviewList {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = allowHapticTouchPreview {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = allowedLimit {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = maxVideo {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = maxSelect {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = maxVideoDuration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = minVideoDuration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = maxFileSize {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = backgroundDark {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_PickerCropConfig_ in\n      if let __unwrappedValue = crop {\n        return bridge.create_std__optional_PickerCropConfig_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_Text_ in\n      if let __unwrappedValue = text {\n        return bridge.create_std__optional_Text_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), language, theme, presentation, { () -> bridge.std__optional_PickerCameraConfig_ in\n      if let __unwrappedValue = camera {\n        return bridge.create_std__optional_PickerCameraConfig_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var mediaType: MediaType {\n    @inline(__always)\n    get {\n      return self.__mediaType\n    }\n    @inline(__always)\n    set {\n      self.__mediaType = newValue\n    }\n  }\n  \n  var selectedAssets: [PickerResult] {\n    @inline(__always)\n    get {\n      return self.__selectedAssets.map({ __item in __item })\n    }\n    @inline(__always)\n    set {\n      self.__selectedAssets = { () -> bridge.std__vector_PickerResult_ in\n        var __vector = bridge.create_std__vector_PickerResult_(newValue.count)\n        for __item in newValue {\n          __vector.push_back(__item)\n        }\n        return __vector\n      }()\n    }\n  }\n  \n  var selectBoxStyle: SelectBoxStyle {\n    @inline(__always)\n    get {\n      return self.__selectBoxStyle\n    }\n    @inline(__always)\n    set {\n      self.__selectBoxStyle = newValue\n    }\n  }\n  \n  var selectMode: SelectMode {\n    @inline(__always)\n    get {\n      return self.__selectMode\n    }\n    @inline(__always)\n    set {\n      self.__selectMode = newValue\n    }\n  }\n  \n  var numberOfColumn: Double? {\n    @inline(__always)\n    get {\n      return self.__numberOfColumn.value\n    }\n    @inline(__always)\n    set {\n      self.__numberOfColumn = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var isPreview: Bool? {\n    @inline(__always)\n    get {\n      return self.__isPreview.value\n    }\n    @inline(__always)\n    set {\n      self.__isPreview = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var primaryColor: Double? {\n    @inline(__always)\n    get {\n      return self.__primaryColor.value\n    }\n    @inline(__always)\n    set {\n      self.__primaryColor = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var allowSwipeToSelect: Bool? {\n    @inline(__always)\n    get {\n      return self.__allowSwipeToSelect.value\n    }\n    @inline(__always)\n    set {\n      self.__allowSwipeToSelect = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var spacing: Double? {\n    @inline(__always)\n    get {\n      return self.__spacing.value\n    }\n    @inline(__always)\n    set {\n      self.__spacing = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var isHiddenPreviewButton: Bool? {\n    @inline(__always)\n    get {\n      return self.__isHiddenPreviewButton.value\n    }\n    @inline(__always)\n    set {\n      self.__isHiddenPreviewButton = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var isHiddenOriginalButton: Bool? {\n    @inline(__always)\n    get {\n      return self.__isHiddenOriginalButton.value\n    }\n    @inline(__always)\n    set {\n      self.__isHiddenOriginalButton = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var isShowPreviewList: Bool? {\n    @inline(__always)\n    get {\n      return self.__isShowPreviewList.value\n    }\n    @inline(__always)\n    set {\n      self.__isShowPreviewList = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var allowHapticTouchPreview: Bool? {\n    @inline(__always)\n    get {\n      return self.__allowHapticTouchPreview.value\n    }\n    @inline(__always)\n    set {\n      self.__allowHapticTouchPreview = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var allowedLimit: Bool? {\n    @inline(__always)\n    get {\n      return self.__allowedLimit.value\n    }\n    @inline(__always)\n    set {\n      self.__allowedLimit = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var maxVideo: Double? {\n    @inline(__always)\n    get {\n      return self.__maxVideo.value\n    }\n    @inline(__always)\n    set {\n      self.__maxVideo = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var maxSelect: Double? {\n    @inline(__always)\n    get {\n      return self.__maxSelect.value\n    }\n    @inline(__always)\n    set {\n      self.__maxSelect = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var maxVideoDuration: Double? {\n    @inline(__always)\n    get {\n      return self.__maxVideoDuration.value\n    }\n    @inline(__always)\n    set {\n      self.__maxVideoDuration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var minVideoDuration: Double? {\n    @inline(__always)\n    get {\n      return self.__minVideoDuration.value\n    }\n    @inline(__always)\n    set {\n      self.__minVideoDuration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var maxFileSize: Double? {\n    @inline(__always)\n    get {\n      return self.__maxFileSize.value\n    }\n    @inline(__always)\n    set {\n      self.__maxFileSize = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var backgroundDark: Double? {\n    @inline(__always)\n    get {\n      return self.__backgroundDark.value\n    }\n    @inline(__always)\n    set {\n      self.__backgroundDark = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var crop: PickerCropConfig? {\n    @inline(__always)\n    get {\n      return { () -> PickerCropConfig? in\n        if let __unwrapped = self.__crop.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__crop = { () -> bridge.std__optional_PickerCropConfig_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_PickerCropConfig_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var text: Text? {\n    @inline(__always)\n    get {\n      return { () -> Text? in\n        if let __unwrapped = self.__text.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__text = { () -> bridge.std__optional_Text_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_Text_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var language: Language {\n    @inline(__always)\n    get {\n      return self.__language\n    }\n    @inline(__always)\n    set {\n      self.__language = newValue\n    }\n  }\n  \n  var theme: Theme {\n    @inline(__always)\n    get {\n      return self.__theme\n    }\n    @inline(__always)\n    set {\n      self.__theme = newValue\n    }\n  }\n  \n  var presentation: Presentation {\n    @inline(__always)\n    get {\n      return self.__presentation\n    }\n    @inline(__always)\n    set {\n      self.__presentation = newValue\n    }\n  }\n  \n  var camera: PickerCameraConfig? {\n    @inline(__always)\n    get {\n      return { () -> PickerCameraConfig? in\n        if let __unwrapped = self.__camera.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__camera = { () -> bridge.std__optional_PickerCameraConfig_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_PickerCameraConfig_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/NitroCropConfig.swift",
    "content": "///\n/// NitroCropConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `NitroCropConfig`, backed by a C++ struct.\n */\npublic typealias NitroCropConfig = margelo.nitro.multipleimagepicker.NitroCropConfig\n\npublic extension NitroCropConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `NitroCropConfig`.\n   */\n  init(language: Language, presentation: Presentation, circle: Bool?, ratio: [CropRatio], defaultRatio: CropRatio?, freeStyle: Bool?) {\n    self.init(language, presentation, { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = circle {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__vector_CropRatio_ in\n      var __vector = bridge.create_std__vector_CropRatio_(ratio.count)\n      for __item in ratio {\n        __vector.push_back(__item)\n      }\n      return __vector\n    }(), { () -> bridge.std__optional_CropRatio_ in\n      if let __unwrappedValue = defaultRatio {\n        return bridge.create_std__optional_CropRatio_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = freeStyle {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var language: Language {\n    @inline(__always)\n    get {\n      return self.__language\n    }\n    @inline(__always)\n    set {\n      self.__language = newValue\n    }\n  }\n  \n  var presentation: Presentation {\n    @inline(__always)\n    get {\n      return self.__presentation\n    }\n    @inline(__always)\n    set {\n      self.__presentation = newValue\n    }\n  }\n  \n  var circle: Bool? {\n    @inline(__always)\n    get {\n      return self.__circle.value\n    }\n    @inline(__always)\n    set {\n      self.__circle = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var ratio: [CropRatio] {\n    @inline(__always)\n    get {\n      return self.__ratio.map({ __item in __item })\n    }\n    @inline(__always)\n    set {\n      self.__ratio = { () -> bridge.std__vector_CropRatio_ in\n        var __vector = bridge.create_std__vector_CropRatio_(newValue.count)\n        for __item in newValue {\n          __vector.push_back(__item)\n        }\n        return __vector\n      }()\n    }\n  }\n  \n  var defaultRatio: CropRatio? {\n    @inline(__always)\n    get {\n      return { () -> CropRatio? in\n        if let __unwrapped = self.__defaultRatio.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__defaultRatio = { () -> bridge.std__optional_CropRatio_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_CropRatio_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var freeStyle: Bool? {\n    @inline(__always)\n    get {\n      return self.__freeStyle.value\n    }\n    @inline(__always)\n    set {\n      self.__freeStyle = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/NitroPreviewConfig.swift",
    "content": "///\n/// NitroPreviewConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `NitroPreviewConfig`, backed by a C++ struct.\n */\npublic typealias NitroPreviewConfig = margelo.nitro.multipleimagepicker.NitroPreviewConfig\n\npublic extension NitroPreviewConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `NitroPreviewConfig`.\n   */\n  init(language: Language, videoAutoPlay: Bool?) {\n    self.init(language, { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = videoAutoPlay {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var language: Language {\n    @inline(__always)\n    get {\n      return self.__language\n    }\n    @inline(__always)\n    set {\n      self.__language = newValue\n    }\n  }\n  \n  var videoAutoPlay: Bool? {\n    @inline(__always)\n    get {\n      return self.__videoAutoPlay.value\n    }\n    @inline(__always)\n    set {\n      self.__videoAutoPlay = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/PickerCameraConfig.swift",
    "content": "///\n/// PickerCameraConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `PickerCameraConfig`, backed by a C++ struct.\n */\npublic typealias PickerCameraConfig = margelo.nitro.multipleimagepicker.PickerCameraConfig\n\npublic extension PickerCameraConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `PickerCameraConfig`.\n   */\n  init(cameraDevice: CameraDevice?, videoMaximumDuration: Double?) {\n    self.init({ () -> bridge.std__optional_CameraDevice_ in\n      if let __unwrappedValue = cameraDevice {\n        return bridge.create_std__optional_CameraDevice_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = videoMaximumDuration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var cameraDevice: CameraDevice? {\n    @inline(__always)\n    get {\n      return self.__cameraDevice.value\n    }\n    @inline(__always)\n    set {\n      self.__cameraDevice = { () -> bridge.std__optional_CameraDevice_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_CameraDevice_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var videoMaximumDuration: Double? {\n    @inline(__always)\n    get {\n      return self.__videoMaximumDuration.value\n    }\n    @inline(__always)\n    set {\n      self.__videoMaximumDuration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/PickerCropConfig.swift",
    "content": "///\n/// PickerCropConfig.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `PickerCropConfig`, backed by a C++ struct.\n */\npublic typealias PickerCropConfig = margelo.nitro.multipleimagepicker.PickerCropConfig\n\npublic extension PickerCropConfig {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `PickerCropConfig`.\n   */\n  init(circle: Bool?, ratio: [CropRatio], defaultRatio: CropRatio?, freeStyle: Bool?) {\n    self.init({ () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = circle {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__vector_CropRatio_ in\n      var __vector = bridge.create_std__vector_CropRatio_(ratio.count)\n      for __item in ratio {\n        __vector.push_back(__item)\n      }\n      return __vector\n    }(), { () -> bridge.std__optional_CropRatio_ in\n      if let __unwrappedValue = defaultRatio {\n        return bridge.create_std__optional_CropRatio_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = freeStyle {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var circle: Bool? {\n    @inline(__always)\n    get {\n      return self.__circle.value\n    }\n    @inline(__always)\n    set {\n      self.__circle = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var ratio: [CropRatio] {\n    @inline(__always)\n    get {\n      return self.__ratio.map({ __item in __item })\n    }\n    @inline(__always)\n    set {\n      self.__ratio = { () -> bridge.std__vector_CropRatio_ in\n        var __vector = bridge.create_std__vector_CropRatio_(newValue.count)\n        for __item in newValue {\n          __vector.push_back(__item)\n        }\n        return __vector\n      }()\n    }\n  }\n  \n  var defaultRatio: CropRatio? {\n    @inline(__always)\n    get {\n      return { () -> CropRatio? in\n        if let __unwrapped = self.__defaultRatio.value {\n          return __unwrapped\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__defaultRatio = { () -> bridge.std__optional_CropRatio_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_CropRatio_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var freeStyle: Bool? {\n    @inline(__always)\n    get {\n      return self.__freeStyle.value\n    }\n    @inline(__always)\n    set {\n      self.__freeStyle = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/PickerResult.swift",
    "content": "///\n/// PickerResult.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `PickerResult`, backed by a C++ struct.\n */\npublic typealias PickerResult = margelo.nitro.multipleimagepicker.PickerResult\n\npublic extension PickerResult {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `PickerResult`.\n   */\n  init(localIdentifier: String, width: Double, height: Double, mime: String, size: Double, bucketId: Double?, realPath: String?, parentFolderName: String?, creationDate: Double?, crop: Bool?, path: String, type: ResultType, duration: Double?, thumbnail: String?, fileName: String?) {\n    self.init(std.string(localIdentifier), width, height, std.string(mime), size, { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = bucketId {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = realPath {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = parentFolderName {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = creationDate {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_bool_ in\n      if let __unwrappedValue = crop {\n        return bridge.create_std__optional_bool_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), std.string(path), type, { () -> bridge.std__optional_double_ in\n      if let __unwrappedValue = duration {\n        return bridge.create_std__optional_double_(__unwrappedValue)\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = thumbnail {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = fileName {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var localIdentifier: String {\n    @inline(__always)\n    get {\n      return String(self.__localIdentifier)\n    }\n    @inline(__always)\n    set {\n      self.__localIdentifier = std.string(newValue)\n    }\n  }\n  \n  var width: Double {\n    @inline(__always)\n    get {\n      return self.__width\n    }\n    @inline(__always)\n    set {\n      self.__width = newValue\n    }\n  }\n  \n  var height: Double {\n    @inline(__always)\n    get {\n      return self.__height\n    }\n    @inline(__always)\n    set {\n      self.__height = newValue\n    }\n  }\n  \n  var mime: String {\n    @inline(__always)\n    get {\n      return String(self.__mime)\n    }\n    @inline(__always)\n    set {\n      self.__mime = std.string(newValue)\n    }\n  }\n  \n  var size: Double {\n    @inline(__always)\n    get {\n      return self.__size\n    }\n    @inline(__always)\n    set {\n      self.__size = newValue\n    }\n  }\n  \n  var bucketId: Double? {\n    @inline(__always)\n    get {\n      return self.__bucketId.value\n    }\n    @inline(__always)\n    set {\n      self.__bucketId = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var realPath: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__realPath.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__realPath = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var parentFolderName: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__parentFolderName.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__parentFolderName = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var creationDate: Double? {\n    @inline(__always)\n    get {\n      return self.__creationDate.value\n    }\n    @inline(__always)\n    set {\n      self.__creationDate = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var crop: Bool? {\n    @inline(__always)\n    get {\n      return self.__crop.value\n    }\n    @inline(__always)\n    set {\n      self.__crop = { () -> bridge.std__optional_bool_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_bool_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var path: String {\n    @inline(__always)\n    get {\n      return String(self.__path)\n    }\n    @inline(__always)\n    set {\n      self.__path = std.string(newValue)\n    }\n  }\n  \n  var type: ResultType {\n    @inline(__always)\n    get {\n      return self.__type\n    }\n    @inline(__always)\n    set {\n      self.__type = newValue\n    }\n  }\n  \n  var duration: Double? {\n    @inline(__always)\n    get {\n      return self.__duration.value\n    }\n    @inline(__always)\n    set {\n      self.__duration = { () -> bridge.std__optional_double_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_double_(__unwrappedValue)\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var thumbnail: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__thumbnail.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__thumbnail = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var fileName: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__fileName.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__fileName = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Presentation.swift",
    "content": "///\n/// Presentation.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `Presentation`, backed by a C++ enum.\n */\npublic typealias Presentation = margelo.nitro.multipleimagepicker.Presentation\n\npublic extension Presentation {\n  /**\n   * Get a Presentation for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"fullScreenModal\":\n        self = .fullscreenmodal\n      case \"formSheet\":\n        self = .formsheet\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this Presentation represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .fullscreenmodal:\n        return \"fullScreenModal\"\n      case .formsheet:\n        return \"formSheet\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/ResultType.swift",
    "content": "///\n/// ResultType.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `ResultType`, backed by a C++ enum.\n */\npublic typealias ResultType = margelo.nitro.multipleimagepicker.ResultType\n\npublic extension ResultType {\n  /**\n   * Get a ResultType for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"video\":\n        self = .video\n      case \"image\":\n        self = .image\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this ResultType represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .video:\n        return \"video\"\n      case .image:\n        return \"image\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/SelectBoxStyle.swift",
    "content": "///\n/// SelectBoxStyle.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `SelectBoxStyle`, backed by a C++ enum.\n */\npublic typealias SelectBoxStyle = margelo.nitro.multipleimagepicker.SelectBoxStyle\n\npublic extension SelectBoxStyle {\n  /**\n   * Get a SelectBoxStyle for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"number\":\n        self = .number\n      case \"tick\":\n        self = .tick\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this SelectBoxStyle represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .number:\n        return \"number\"\n      case .tick:\n        return \"tick\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/SelectMode.swift",
    "content": "///\n/// SelectMode.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `SelectMode`, backed by a C++ enum.\n */\npublic typealias SelectMode = margelo.nitro.multipleimagepicker.SelectMode\n\npublic extension SelectMode {\n  /**\n   * Get a SelectMode for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"single\":\n        self = .single\n      case \"multiple\":\n        self = .multiple\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this SelectMode represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .single:\n        return \"single\"\n      case .multiple:\n        return \"multiple\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Text.swift",
    "content": "///\n/// Text.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\nimport NitroModules\n\n/**\n * Represents an instance of `Text`, backed by a C++ struct.\n */\npublic typealias Text = margelo.nitro.multipleimagepicker.Text\n\npublic extension Text {\n  private typealias bridge = margelo.nitro.multipleimagepicker.bridge.swift\n\n  /**\n   * Create a new instance of `Text`.\n   */\n  init(finish: String?, original: String?, preview: String?, edit: String?) {\n    self.init({ () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = finish {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = original {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = preview {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }(), { () -> bridge.std__optional_std__string_ in\n      if let __unwrappedValue = edit {\n        return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n      } else {\n        return .init()\n      }\n    }())\n  }\n\n  var finish: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__finish.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__finish = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var original: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__original.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__original = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var preview: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__preview.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__preview = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n  \n  var edit: String? {\n    @inline(__always)\n    get {\n      return { () -> String? in\n        if let __unwrapped = self.__edit.value {\n          return String(__unwrapped)\n        } else {\n          return nil\n        }\n      }()\n    }\n    @inline(__always)\n    set {\n      self.__edit = { () -> bridge.std__optional_std__string_ in\n        if let __unwrappedValue = newValue {\n          return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))\n        } else {\n          return .init()\n        }\n      }()\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/ios/swift/Theme.swift",
    "content": "///\n/// Theme.swift\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n/**\n * Represents the JS union `Theme`, backed by a C++ enum.\n */\npublic typealias Theme = margelo.nitro.multipleimagepicker.Theme\n\npublic extension Theme {\n  /**\n   * Get a Theme for the given String value, or\n   * return `nil` if the given value was invalid/unknown.\n   */\n  init?(fromString string: String) {\n    switch string {\n      case \"light\":\n        self = .light\n      case \"dark\":\n        self = .dark\n      default:\n        return nil\n    }\n  }\n\n  /**\n   * Get the String value this Theme represents.\n   */\n  var stringValue: String {\n    switch self {\n      case .light:\n        return \"light\"\n      case .dark:\n        return \"dark\"\n    }\n  }\n}\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/CameraDevice.hpp",
    "content": "///\n/// CameraDevice.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (CameraDevice).\n   */\n  enum class CameraDevice {\n    FRONT      SWIFT_NAME(front) = 0,\n    BACK      SWIFT_NAME(back) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ CameraDevice <> JS CameraDevice (union)\n  template <>\n  struct JSIConverter<CameraDevice> final {\n    static inline CameraDevice fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"front\"): return CameraDevice::FRONT;\n        case hashString(\"back\"): return CameraDevice::BACK;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum CameraDevice - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, CameraDevice arg) {\n      switch (arg) {\n        case CameraDevice::FRONT: return JSIConverter<std::string>::toJSI(runtime, \"front\");\n        case CameraDevice::BACK: return JSIConverter<std::string>::toJSI(runtime, \"back\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert CameraDevice to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"front\"):\n        case hashString(\"back\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/CameraResult.hpp",
    "content": "///\n/// CameraResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n\n#include <string>\n#include \"ResultType.hpp\"\n#include <optional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (CameraResult).\n   */\n  struct CameraResult {\n  public:\n    std::string path     SWIFT_PRIVATE;\n    ResultType type     SWIFT_PRIVATE;\n    std::optional<double> width     SWIFT_PRIVATE;\n    std::optional<double> height     SWIFT_PRIVATE;\n    std::optional<double> duration     SWIFT_PRIVATE;\n    std::optional<std::string> thumbnail     SWIFT_PRIVATE;\n    std::optional<std::string> fileName     SWIFT_PRIVATE;\n\n  public:\n    CameraResult() = default;\n    explicit CameraResult(std::string path, ResultType type, std::optional<double> width, std::optional<double> height, std::optional<double> duration, std::optional<std::string> thumbnail, std::optional<std::string> fileName): path(path), type(type), width(width), height(height), duration(duration), thumbnail(thumbnail), fileName(fileName) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ CameraResult <> JS CameraResult (object)\n  template <>\n  struct JSIConverter<CameraResult> final {\n    static inline CameraResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return CameraResult(\n        JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, \"path\")),\n        JSIConverter<ResultType>::fromJSI(runtime, obj.getProperty(runtime, \"type\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"width\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"height\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"duration\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"thumbnail\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"fileName\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const CameraResult& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"path\", JSIConverter<std::string>::toJSI(runtime, arg.path));\n      obj.setProperty(runtime, \"type\", JSIConverter<ResultType>::toJSI(runtime, arg.type));\n      obj.setProperty(runtime, \"width\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.width));\n      obj.setProperty(runtime, \"height\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.height));\n      obj.setProperty(runtime, \"duration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.duration));\n      obj.setProperty(runtime, \"thumbnail\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.thumbnail));\n      obj.setProperty(runtime, \"fileName\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.fileName));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, \"path\"))) return false;\n      if (!JSIConverter<ResultType>::canConvert(runtime, obj.getProperty(runtime, \"type\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"width\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"height\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"duration\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"thumbnail\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"fileName\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/CropRatio.hpp",
    "content": "///\n/// CropRatio.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n\n\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (CropRatio).\n   */\n  struct CropRatio {\n  public:\n    std::optional<std::string> title     SWIFT_PRIVATE;\n    double width     SWIFT_PRIVATE;\n    double height     SWIFT_PRIVATE;\n\n  public:\n    CropRatio() = default;\n    explicit CropRatio(std::optional<std::string> title, double width, double height): title(title), width(width), height(height) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ CropRatio <> JS CropRatio (object)\n  template <>\n  struct JSIConverter<CropRatio> final {\n    static inline CropRatio fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return CropRatio(\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"title\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"width\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"height\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const CropRatio& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"title\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.title));\n      obj.setProperty(runtime, \"width\", JSIConverter<double>::toJSI(runtime, arg.width));\n      obj.setProperty(runtime, \"height\", JSIConverter<double>::toJSI(runtime, arg.height));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"title\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"width\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"height\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/CropResult.hpp",
    "content": "///\n/// CropResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n\n\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (CropResult).\n   */\n  struct CropResult {\n  public:\n    std::string path     SWIFT_PRIVATE;\n    double width     SWIFT_PRIVATE;\n    double height     SWIFT_PRIVATE;\n\n  public:\n    CropResult() = default;\n    explicit CropResult(std::string path, double width, double height): path(path), width(width), height(height) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ CropResult <> JS CropResult (object)\n  template <>\n  struct JSIConverter<CropResult> final {\n    static inline CropResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return CropResult(\n        JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, \"path\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"width\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"height\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const CropResult& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"path\", JSIConverter<std::string>::toJSI(runtime, arg.path));\n      obj.setProperty(runtime, \"width\", JSIConverter<double>::toJSI(runtime, arg.width));\n      obj.setProperty(runtime, \"height\", JSIConverter<double>::toJSI(runtime, arg.height));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, \"path\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"width\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"height\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/HybridMultipleImagePickerSpec.cpp",
    "content": "///\n/// HybridMultipleImagePickerSpec.cpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#include \"HybridMultipleImagePickerSpec.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  void HybridMultipleImagePickerSpec::loadHybridMethods() {\n    // load base methods/properties\n    HybridObject::loadHybridMethods();\n    // load custom methods/properties\n    registerHybrids(this, [](Prototype& prototype) {\n      prototype.registerHybridMethod(\"openPicker\", &HybridMultipleImagePickerSpec::openPicker);\n      prototype.registerHybridMethod(\"openCrop\", &HybridMultipleImagePickerSpec::openCrop);\n      prototype.registerHybridMethod(\"openPreview\", &HybridMultipleImagePickerSpec::openPreview);\n      prototype.registerHybridMethod(\"openCamera\", &HybridMultipleImagePickerSpec::openCamera);\n    });\n  }\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/HybridMultipleImagePickerSpec.hpp",
    "content": "///\n/// HybridMultipleImagePickerSpec.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/HybridObject.hpp>)\n#include <NitroModules/HybridObject.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `NitroConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroConfig; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `NitroCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCropConfig; }\n// Forward declaration of `CropResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropResult; }\n// Forward declaration of `MediaPreview` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct MediaPreview; }\n// Forward declaration of `NitroPreviewConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroPreviewConfig; }\n// Forward declaration of `NitroCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct NitroCameraConfig; }\n// Forward declaration of `CameraResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CameraResult; }\n\n#include \"NitroConfig.hpp\"\n#include <functional>\n#include <vector>\n#include \"PickerResult.hpp\"\n#include <string>\n#include \"NitroCropConfig.hpp\"\n#include \"CropResult.hpp\"\n#include \"MediaPreview.hpp\"\n#include \"NitroPreviewConfig.hpp\"\n#include \"NitroCameraConfig.hpp\"\n#include \"CameraResult.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  using namespace margelo::nitro;\n\n  /**\n   * An abstract base class for `MultipleImagePicker`\n   * Inherit this class to create instances of `HybridMultipleImagePickerSpec` in C++.\n   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.\n   * @example\n   * ```cpp\n   * class HybridMultipleImagePicker: public HybridMultipleImagePickerSpec {\n   * public:\n   *   HybridMultipleImagePicker(...): HybridObject(TAG) { ... }\n   *   // ...\n   * };\n   * ```\n   */\n  class HybridMultipleImagePickerSpec: public virtual HybridObject {\n    public:\n      // Constructor\n      explicit HybridMultipleImagePickerSpec(): HybridObject(TAG) { }\n\n      // Destructor\n      ~HybridMultipleImagePickerSpec() override = default;\n\n    public:\n      // Properties\n      \n\n    public:\n      // Methods\n      virtual void openPicker(const NitroConfig& config, const std::function<void(const std::vector<PickerResult>& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) = 0;\n      virtual void openCrop(const std::string& image, const NitroCropConfig& config, const std::function<void(const CropResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) = 0;\n      virtual void openPreview(const std::vector<MediaPreview>& media, double index, const NitroPreviewConfig& config, const std::function<void(double /* index */)>& onLongPress) = 0;\n      virtual void openCamera(const NitroCameraConfig& config, const std::function<void(const CameraResult& /* result */)>& resolved, const std::function<void(double /* reject */)>& rejected) = 0;\n\n    protected:\n      // Hybrid Setup\n      void loadHybridMethods() override;\n\n    protected:\n      // Tag for logging\n      static constexpr auto TAG = \"MultipleImagePicker\";\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/Language.hpp",
    "content": "///\n/// Language.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (Language).\n   */\n  enum class Language {\n    SYSTEM      SWIFT_NAME(system) = 0,\n    ZH_HANS      SWIFT_NAME(zhHans) = 1,\n    ZH_HANT      SWIFT_NAME(zhHant) = 2,\n    JA      SWIFT_NAME(ja) = 3,\n    KO      SWIFT_NAME(ko) = 4,\n    EN      SWIFT_NAME(en) = 5,\n    TH      SWIFT_NAME(th) = 6,\n    ID      SWIFT_NAME(id) = 7,\n    VI      SWIFT_NAME(vi) = 8,\n    RU      SWIFT_NAME(ru) = 9,\n    DE      SWIFT_NAME(de) = 10,\n    FR      SWIFT_NAME(fr) = 11,\n    AR      SWIFT_NAME(ar) = 12,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ Language <> JS Language (union)\n  template <>\n  struct JSIConverter<Language> final {\n    static inline Language fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"system\"): return Language::SYSTEM;\n        case hashString(\"zh-Hans\"): return Language::ZH_HANS;\n        case hashString(\"zh-Hant\"): return Language::ZH_HANT;\n        case hashString(\"ja\"): return Language::JA;\n        case hashString(\"ko\"): return Language::KO;\n        case hashString(\"en\"): return Language::EN;\n        case hashString(\"th\"): return Language::TH;\n        case hashString(\"id\"): return Language::ID;\n        case hashString(\"vi\"): return Language::VI;\n        case hashString(\"ru\"): return Language::RU;\n        case hashString(\"de\"): return Language::DE;\n        case hashString(\"fr\"): return Language::FR;\n        case hashString(\"ar\"): return Language::AR;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum Language - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, Language arg) {\n      switch (arg) {\n        case Language::SYSTEM: return JSIConverter<std::string>::toJSI(runtime, \"system\");\n        case Language::ZH_HANS: return JSIConverter<std::string>::toJSI(runtime, \"zh-Hans\");\n        case Language::ZH_HANT: return JSIConverter<std::string>::toJSI(runtime, \"zh-Hant\");\n        case Language::JA: return JSIConverter<std::string>::toJSI(runtime, \"ja\");\n        case Language::KO: return JSIConverter<std::string>::toJSI(runtime, \"ko\");\n        case Language::EN: return JSIConverter<std::string>::toJSI(runtime, \"en\");\n        case Language::TH: return JSIConverter<std::string>::toJSI(runtime, \"th\");\n        case Language::ID: return JSIConverter<std::string>::toJSI(runtime, \"id\");\n        case Language::VI: return JSIConverter<std::string>::toJSI(runtime, \"vi\");\n        case Language::RU: return JSIConverter<std::string>::toJSI(runtime, \"ru\");\n        case Language::DE: return JSIConverter<std::string>::toJSI(runtime, \"de\");\n        case Language::FR: return JSIConverter<std::string>::toJSI(runtime, \"fr\");\n        case Language::AR: return JSIConverter<std::string>::toJSI(runtime, \"ar\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert Language to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"system\"):\n        case hashString(\"zh-Hans\"):\n        case hashString(\"zh-Hant\"):\n        case hashString(\"ja\"):\n        case hashString(\"ko\"):\n        case hashString(\"en\"):\n        case hashString(\"th\"):\n        case hashString(\"id\"):\n        case hashString(\"vi\"):\n        case hashString(\"ru\"):\n        case hashString(\"de\"):\n        case hashString(\"fr\"):\n        case hashString(\"ar\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/MediaPreview.hpp",
    "content": "///\n/// MediaPreview.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n\n#include \"ResultType.hpp\"\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (MediaPreview).\n   */\n  struct MediaPreview {\n  public:\n    ResultType type     SWIFT_PRIVATE;\n    std::optional<std::string> path     SWIFT_PRIVATE;\n    std::optional<std::string> thumbnail     SWIFT_PRIVATE;\n    std::optional<std::string> localIdentifier     SWIFT_PRIVATE;\n\n  public:\n    MediaPreview() = default;\n    explicit MediaPreview(ResultType type, std::optional<std::string> path, std::optional<std::string> thumbnail, std::optional<std::string> localIdentifier): type(type), path(path), thumbnail(thumbnail), localIdentifier(localIdentifier) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ MediaPreview <> JS MediaPreview (object)\n  template <>\n  struct JSIConverter<MediaPreview> final {\n    static inline MediaPreview fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return MediaPreview(\n        JSIConverter<ResultType>::fromJSI(runtime, obj.getProperty(runtime, \"type\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"path\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"thumbnail\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"localIdentifier\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const MediaPreview& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"type\", JSIConverter<ResultType>::toJSI(runtime, arg.type));\n      obj.setProperty(runtime, \"path\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.path));\n      obj.setProperty(runtime, \"thumbnail\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.thumbnail));\n      obj.setProperty(runtime, \"localIdentifier\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.localIdentifier));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<ResultType>::canConvert(runtime, obj.getProperty(runtime, \"type\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"path\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"thumbnail\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"localIdentifier\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/MediaType.hpp",
    "content": "///\n/// MediaType.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (MediaType).\n   */\n  enum class MediaType {\n    VIDEO      SWIFT_NAME(video) = 0,\n    IMAGE      SWIFT_NAME(image) = 1,\n    ALL      SWIFT_NAME(all) = 2,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ MediaType <> JS MediaType (union)\n  template <>\n  struct JSIConverter<MediaType> final {\n    static inline MediaType fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"video\"): return MediaType::VIDEO;\n        case hashString(\"image\"): return MediaType::IMAGE;\n        case hashString(\"all\"): return MediaType::ALL;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum MediaType - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, MediaType arg) {\n      switch (arg) {\n        case MediaType::VIDEO: return JSIConverter<std::string>::toJSI(runtime, \"video\");\n        case MediaType::IMAGE: return JSIConverter<std::string>::toJSI(runtime, \"image\");\n        case MediaType::ALL: return JSIConverter<std::string>::toJSI(runtime, \"all\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert MediaType to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"video\"):\n        case hashString(\"image\"):\n        case hashString(\"all\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/NitroCameraConfig.hpp",
    "content": "///\n/// NitroCameraConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `MediaType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class MediaType; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n\n#include \"MediaType.hpp\"\n#include \"Presentation.hpp\"\n#include \"Language.hpp\"\n#include <optional>\n#include \"PickerCropConfig.hpp\"\n#include \"CameraDevice.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (NitroCameraConfig).\n   */\n  struct NitroCameraConfig {\n  public:\n    MediaType mediaType     SWIFT_PRIVATE;\n    Presentation presentation     SWIFT_PRIVATE;\n    Language language     SWIFT_PRIVATE;\n    std::optional<PickerCropConfig> crop     SWIFT_PRIVATE;\n    std::optional<bool> isSaveSystemAlbum     SWIFT_PRIVATE;\n    std::optional<double> color     SWIFT_PRIVATE;\n    std::optional<CameraDevice> cameraDevice     SWIFT_PRIVATE;\n    std::optional<double> videoMaximumDuration     SWIFT_PRIVATE;\n\n  public:\n    NitroCameraConfig() = default;\n    explicit NitroCameraConfig(MediaType mediaType, Presentation presentation, Language language, std::optional<PickerCropConfig> crop, std::optional<bool> isSaveSystemAlbum, std::optional<double> color, std::optional<CameraDevice> cameraDevice, std::optional<double> videoMaximumDuration): mediaType(mediaType), presentation(presentation), language(language), crop(crop), isSaveSystemAlbum(isSaveSystemAlbum), color(color), cameraDevice(cameraDevice), videoMaximumDuration(videoMaximumDuration) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ NitroCameraConfig <> JS NitroCameraConfig (object)\n  template <>\n  struct JSIConverter<NitroCameraConfig> final {\n    static inline NitroCameraConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return NitroCameraConfig(\n        JSIConverter<MediaType>::fromJSI(runtime, obj.getProperty(runtime, \"mediaType\")),\n        JSIConverter<Presentation>::fromJSI(runtime, obj.getProperty(runtime, \"presentation\")),\n        JSIConverter<Language>::fromJSI(runtime, obj.getProperty(runtime, \"language\")),\n        JSIConverter<std::optional<PickerCropConfig>>::fromJSI(runtime, obj.getProperty(runtime, \"crop\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"isSaveSystemAlbum\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"color\")),\n        JSIConverter<std::optional<CameraDevice>>::fromJSI(runtime, obj.getProperty(runtime, \"cameraDevice\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"videoMaximumDuration\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const NitroCameraConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"mediaType\", JSIConverter<MediaType>::toJSI(runtime, arg.mediaType));\n      obj.setProperty(runtime, \"presentation\", JSIConverter<Presentation>::toJSI(runtime, arg.presentation));\n      obj.setProperty(runtime, \"language\", JSIConverter<Language>::toJSI(runtime, arg.language));\n      obj.setProperty(runtime, \"crop\", JSIConverter<std::optional<PickerCropConfig>>::toJSI(runtime, arg.crop));\n      obj.setProperty(runtime, \"isSaveSystemAlbum\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isSaveSystemAlbum));\n      obj.setProperty(runtime, \"color\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.color));\n      obj.setProperty(runtime, \"cameraDevice\", JSIConverter<std::optional<CameraDevice>>::toJSI(runtime, arg.cameraDevice));\n      obj.setProperty(runtime, \"videoMaximumDuration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.videoMaximumDuration));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<MediaType>::canConvert(runtime, obj.getProperty(runtime, \"mediaType\"))) return false;\n      if (!JSIConverter<Presentation>::canConvert(runtime, obj.getProperty(runtime, \"presentation\"))) return false;\n      if (!JSIConverter<Language>::canConvert(runtime, obj.getProperty(runtime, \"language\"))) return false;\n      if (!JSIConverter<std::optional<PickerCropConfig>>::canConvert(runtime, obj.getProperty(runtime, \"crop\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"isSaveSystemAlbum\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"color\"))) return false;\n      if (!JSIConverter<std::optional<CameraDevice>>::canConvert(runtime, obj.getProperty(runtime, \"cameraDevice\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"videoMaximumDuration\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/NitroConfig.hpp",
    "content": "///\n/// NitroConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `MediaType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class MediaType; }\n// Forward declaration of `PickerResult` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerResult; }\n// Forward declaration of `SelectBoxStyle` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectBoxStyle; }\n// Forward declaration of `SelectMode` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class SelectMode; }\n// Forward declaration of `PickerCropConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCropConfig; }\n// Forward declaration of `Text` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct Text; }\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `Theme` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Theme; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `PickerCameraConfig` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct PickerCameraConfig; }\n\n#include \"MediaType.hpp\"\n#include <vector>\n#include \"PickerResult.hpp\"\n#include \"SelectBoxStyle.hpp\"\n#include \"SelectMode.hpp\"\n#include <optional>\n#include \"PickerCropConfig.hpp\"\n#include \"Text.hpp\"\n#include \"Language.hpp\"\n#include \"Theme.hpp\"\n#include \"Presentation.hpp\"\n#include \"PickerCameraConfig.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (NitroConfig).\n   */\n  struct NitroConfig {\n  public:\n    MediaType mediaType     SWIFT_PRIVATE;\n    std::vector<PickerResult> selectedAssets     SWIFT_PRIVATE;\n    SelectBoxStyle selectBoxStyle     SWIFT_PRIVATE;\n    SelectMode selectMode     SWIFT_PRIVATE;\n    std::optional<double> numberOfColumn     SWIFT_PRIVATE;\n    std::optional<bool> isPreview     SWIFT_PRIVATE;\n    std::optional<double> primaryColor     SWIFT_PRIVATE;\n    std::optional<bool> allowSwipeToSelect     SWIFT_PRIVATE;\n    std::optional<double> spacing     SWIFT_PRIVATE;\n    std::optional<bool> isHiddenPreviewButton     SWIFT_PRIVATE;\n    std::optional<bool> isHiddenOriginalButton     SWIFT_PRIVATE;\n    std::optional<bool> isShowPreviewList     SWIFT_PRIVATE;\n    std::optional<bool> allowHapticTouchPreview     SWIFT_PRIVATE;\n    std::optional<bool> allowedLimit     SWIFT_PRIVATE;\n    std::optional<double> maxVideo     SWIFT_PRIVATE;\n    std::optional<double> maxSelect     SWIFT_PRIVATE;\n    std::optional<double> maxVideoDuration     SWIFT_PRIVATE;\n    std::optional<double> minVideoDuration     SWIFT_PRIVATE;\n    std::optional<double> maxFileSize     SWIFT_PRIVATE;\n    std::optional<double> backgroundDark     SWIFT_PRIVATE;\n    std::optional<PickerCropConfig> crop     SWIFT_PRIVATE;\n    std::optional<Text> text     SWIFT_PRIVATE;\n    Language language     SWIFT_PRIVATE;\n    Theme theme     SWIFT_PRIVATE;\n    Presentation presentation     SWIFT_PRIVATE;\n    std::optional<PickerCameraConfig> camera     SWIFT_PRIVATE;\n\n  public:\n    NitroConfig() = default;\n    explicit NitroConfig(MediaType mediaType, std::vector<PickerResult> selectedAssets, SelectBoxStyle selectBoxStyle, SelectMode selectMode, std::optional<double> numberOfColumn, std::optional<bool> isPreview, std::optional<double> primaryColor, std::optional<bool> allowSwipeToSelect, std::optional<double> spacing, std::optional<bool> isHiddenPreviewButton, std::optional<bool> isHiddenOriginalButton, std::optional<bool> isShowPreviewList, std::optional<bool> allowHapticTouchPreview, std::optional<bool> allowedLimit, std::optional<double> maxVideo, std::optional<double> maxSelect, std::optional<double> maxVideoDuration, std::optional<double> minVideoDuration, std::optional<double> maxFileSize, std::optional<double> backgroundDark, std::optional<PickerCropConfig> crop, std::optional<Text> text, Language language, Theme theme, Presentation presentation, std::optional<PickerCameraConfig> camera): mediaType(mediaType), selectedAssets(selectedAssets), selectBoxStyle(selectBoxStyle), selectMode(selectMode), numberOfColumn(numberOfColumn), isPreview(isPreview), primaryColor(primaryColor), allowSwipeToSelect(allowSwipeToSelect), spacing(spacing), isHiddenPreviewButton(isHiddenPreviewButton), isHiddenOriginalButton(isHiddenOriginalButton), isShowPreviewList(isShowPreviewList), allowHapticTouchPreview(allowHapticTouchPreview), allowedLimit(allowedLimit), maxVideo(maxVideo), maxSelect(maxSelect), maxVideoDuration(maxVideoDuration), minVideoDuration(minVideoDuration), maxFileSize(maxFileSize), backgroundDark(backgroundDark), crop(crop), text(text), language(language), theme(theme), presentation(presentation), camera(camera) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ NitroConfig <> JS NitroConfig (object)\n  template <>\n  struct JSIConverter<NitroConfig> final {\n    static inline NitroConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return NitroConfig(\n        JSIConverter<MediaType>::fromJSI(runtime, obj.getProperty(runtime, \"mediaType\")),\n        JSIConverter<std::vector<PickerResult>>::fromJSI(runtime, obj.getProperty(runtime, \"selectedAssets\")),\n        JSIConverter<SelectBoxStyle>::fromJSI(runtime, obj.getProperty(runtime, \"selectBoxStyle\")),\n        JSIConverter<SelectMode>::fromJSI(runtime, obj.getProperty(runtime, \"selectMode\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"numberOfColumn\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"isPreview\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"primaryColor\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"allowSwipeToSelect\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"spacing\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"isHiddenPreviewButton\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"isHiddenOriginalButton\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"isShowPreviewList\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"allowHapticTouchPreview\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"allowedLimit\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"maxVideo\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"maxSelect\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"maxVideoDuration\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"minVideoDuration\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"maxFileSize\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"backgroundDark\")),\n        JSIConverter<std::optional<PickerCropConfig>>::fromJSI(runtime, obj.getProperty(runtime, \"crop\")),\n        JSIConverter<std::optional<Text>>::fromJSI(runtime, obj.getProperty(runtime, \"text\")),\n        JSIConverter<Language>::fromJSI(runtime, obj.getProperty(runtime, \"language\")),\n        JSIConverter<Theme>::fromJSI(runtime, obj.getProperty(runtime, \"theme\")),\n        JSIConverter<Presentation>::fromJSI(runtime, obj.getProperty(runtime, \"presentation\")),\n        JSIConverter<std::optional<PickerCameraConfig>>::fromJSI(runtime, obj.getProperty(runtime, \"camera\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const NitroConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"mediaType\", JSIConverter<MediaType>::toJSI(runtime, arg.mediaType));\n      obj.setProperty(runtime, \"selectedAssets\", JSIConverter<std::vector<PickerResult>>::toJSI(runtime, arg.selectedAssets));\n      obj.setProperty(runtime, \"selectBoxStyle\", JSIConverter<SelectBoxStyle>::toJSI(runtime, arg.selectBoxStyle));\n      obj.setProperty(runtime, \"selectMode\", JSIConverter<SelectMode>::toJSI(runtime, arg.selectMode));\n      obj.setProperty(runtime, \"numberOfColumn\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.numberOfColumn));\n      obj.setProperty(runtime, \"isPreview\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isPreview));\n      obj.setProperty(runtime, \"primaryColor\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.primaryColor));\n      obj.setProperty(runtime, \"allowSwipeToSelect\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.allowSwipeToSelect));\n      obj.setProperty(runtime, \"spacing\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.spacing));\n      obj.setProperty(runtime, \"isHiddenPreviewButton\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isHiddenPreviewButton));\n      obj.setProperty(runtime, \"isHiddenOriginalButton\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isHiddenOriginalButton));\n      obj.setProperty(runtime, \"isShowPreviewList\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.isShowPreviewList));\n      obj.setProperty(runtime, \"allowHapticTouchPreview\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.allowHapticTouchPreview));\n      obj.setProperty(runtime, \"allowedLimit\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.allowedLimit));\n      obj.setProperty(runtime, \"maxVideo\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.maxVideo));\n      obj.setProperty(runtime, \"maxSelect\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.maxSelect));\n      obj.setProperty(runtime, \"maxVideoDuration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.maxVideoDuration));\n      obj.setProperty(runtime, \"minVideoDuration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.minVideoDuration));\n      obj.setProperty(runtime, \"maxFileSize\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.maxFileSize));\n      obj.setProperty(runtime, \"backgroundDark\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.backgroundDark));\n      obj.setProperty(runtime, \"crop\", JSIConverter<std::optional<PickerCropConfig>>::toJSI(runtime, arg.crop));\n      obj.setProperty(runtime, \"text\", JSIConverter<std::optional<Text>>::toJSI(runtime, arg.text));\n      obj.setProperty(runtime, \"language\", JSIConverter<Language>::toJSI(runtime, arg.language));\n      obj.setProperty(runtime, \"theme\", JSIConverter<Theme>::toJSI(runtime, arg.theme));\n      obj.setProperty(runtime, \"presentation\", JSIConverter<Presentation>::toJSI(runtime, arg.presentation));\n      obj.setProperty(runtime, \"camera\", JSIConverter<std::optional<PickerCameraConfig>>::toJSI(runtime, arg.camera));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<MediaType>::canConvert(runtime, obj.getProperty(runtime, \"mediaType\"))) return false;\n      if (!JSIConverter<std::vector<PickerResult>>::canConvert(runtime, obj.getProperty(runtime, \"selectedAssets\"))) return false;\n      if (!JSIConverter<SelectBoxStyle>::canConvert(runtime, obj.getProperty(runtime, \"selectBoxStyle\"))) return false;\n      if (!JSIConverter<SelectMode>::canConvert(runtime, obj.getProperty(runtime, \"selectMode\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"numberOfColumn\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"isPreview\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"primaryColor\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"allowSwipeToSelect\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"spacing\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"isHiddenPreviewButton\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"isHiddenOriginalButton\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"isShowPreviewList\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"allowHapticTouchPreview\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"allowedLimit\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"maxVideo\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"maxSelect\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"maxVideoDuration\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"minVideoDuration\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"maxFileSize\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"backgroundDark\"))) return false;\n      if (!JSIConverter<std::optional<PickerCropConfig>>::canConvert(runtime, obj.getProperty(runtime, \"crop\"))) return false;\n      if (!JSIConverter<std::optional<Text>>::canConvert(runtime, obj.getProperty(runtime, \"text\"))) return false;\n      if (!JSIConverter<Language>::canConvert(runtime, obj.getProperty(runtime, \"language\"))) return false;\n      if (!JSIConverter<Theme>::canConvert(runtime, obj.getProperty(runtime, \"theme\"))) return false;\n      if (!JSIConverter<Presentation>::canConvert(runtime, obj.getProperty(runtime, \"presentation\"))) return false;\n      if (!JSIConverter<std::optional<PickerCameraConfig>>::canConvert(runtime, obj.getProperty(runtime, \"camera\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/NitroCropConfig.hpp",
    "content": "///\n/// NitroCropConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n// Forward declaration of `Presentation` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Presentation; }\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n\n#include \"Language.hpp\"\n#include \"Presentation.hpp\"\n#include <optional>\n#include <vector>\n#include \"CropRatio.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (NitroCropConfig).\n   */\n  struct NitroCropConfig {\n  public:\n    Language language     SWIFT_PRIVATE;\n    Presentation presentation     SWIFT_PRIVATE;\n    std::optional<bool> circle     SWIFT_PRIVATE;\n    std::vector<CropRatio> ratio     SWIFT_PRIVATE;\n    std::optional<CropRatio> defaultRatio     SWIFT_PRIVATE;\n    std::optional<bool> freeStyle     SWIFT_PRIVATE;\n\n  public:\n    NitroCropConfig() = default;\n    explicit NitroCropConfig(Language language, Presentation presentation, std::optional<bool> circle, std::vector<CropRatio> ratio, std::optional<CropRatio> defaultRatio, std::optional<bool> freeStyle): language(language), presentation(presentation), circle(circle), ratio(ratio), defaultRatio(defaultRatio), freeStyle(freeStyle) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ NitroCropConfig <> JS NitroCropConfig (object)\n  template <>\n  struct JSIConverter<NitroCropConfig> final {\n    static inline NitroCropConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return NitroCropConfig(\n        JSIConverter<Language>::fromJSI(runtime, obj.getProperty(runtime, \"language\")),\n        JSIConverter<Presentation>::fromJSI(runtime, obj.getProperty(runtime, \"presentation\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"circle\")),\n        JSIConverter<std::vector<CropRatio>>::fromJSI(runtime, obj.getProperty(runtime, \"ratio\")),\n        JSIConverter<std::optional<CropRatio>>::fromJSI(runtime, obj.getProperty(runtime, \"defaultRatio\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"freeStyle\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const NitroCropConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"language\", JSIConverter<Language>::toJSI(runtime, arg.language));\n      obj.setProperty(runtime, \"presentation\", JSIConverter<Presentation>::toJSI(runtime, arg.presentation));\n      obj.setProperty(runtime, \"circle\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.circle));\n      obj.setProperty(runtime, \"ratio\", JSIConverter<std::vector<CropRatio>>::toJSI(runtime, arg.ratio));\n      obj.setProperty(runtime, \"defaultRatio\", JSIConverter<std::optional<CropRatio>>::toJSI(runtime, arg.defaultRatio));\n      obj.setProperty(runtime, \"freeStyle\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.freeStyle));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<Language>::canConvert(runtime, obj.getProperty(runtime, \"language\"))) return false;\n      if (!JSIConverter<Presentation>::canConvert(runtime, obj.getProperty(runtime, \"presentation\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"circle\"))) return false;\n      if (!JSIConverter<std::vector<CropRatio>>::canConvert(runtime, obj.getProperty(runtime, \"ratio\"))) return false;\n      if (!JSIConverter<std::optional<CropRatio>>::canConvert(runtime, obj.getProperty(runtime, \"defaultRatio\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"freeStyle\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/NitroPreviewConfig.hpp",
    "content": "///\n/// NitroPreviewConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `Language` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class Language; }\n\n#include \"Language.hpp\"\n#include <optional>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (NitroPreviewConfig).\n   */\n  struct NitroPreviewConfig {\n  public:\n    Language language     SWIFT_PRIVATE;\n    std::optional<bool> videoAutoPlay     SWIFT_PRIVATE;\n\n  public:\n    NitroPreviewConfig() = default;\n    explicit NitroPreviewConfig(Language language, std::optional<bool> videoAutoPlay): language(language), videoAutoPlay(videoAutoPlay) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ NitroPreviewConfig <> JS NitroPreviewConfig (object)\n  template <>\n  struct JSIConverter<NitroPreviewConfig> final {\n    static inline NitroPreviewConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return NitroPreviewConfig(\n        JSIConverter<Language>::fromJSI(runtime, obj.getProperty(runtime, \"language\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"videoAutoPlay\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const NitroPreviewConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"language\", JSIConverter<Language>::toJSI(runtime, arg.language));\n      obj.setProperty(runtime, \"videoAutoPlay\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.videoAutoPlay));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<Language>::canConvert(runtime, obj.getProperty(runtime, \"language\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"videoAutoPlay\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/PickerCameraConfig.hpp",
    "content": "///\n/// PickerCameraConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `CameraDevice` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class CameraDevice; }\n\n#include <optional>\n#include \"CameraDevice.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (PickerCameraConfig).\n   */\n  struct PickerCameraConfig {\n  public:\n    std::optional<CameraDevice> cameraDevice     SWIFT_PRIVATE;\n    std::optional<double> videoMaximumDuration     SWIFT_PRIVATE;\n\n  public:\n    PickerCameraConfig() = default;\n    explicit PickerCameraConfig(std::optional<CameraDevice> cameraDevice, std::optional<double> videoMaximumDuration): cameraDevice(cameraDevice), videoMaximumDuration(videoMaximumDuration) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ PickerCameraConfig <> JS PickerCameraConfig (object)\n  template <>\n  struct JSIConverter<PickerCameraConfig> final {\n    static inline PickerCameraConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return PickerCameraConfig(\n        JSIConverter<std::optional<CameraDevice>>::fromJSI(runtime, obj.getProperty(runtime, \"cameraDevice\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"videoMaximumDuration\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const PickerCameraConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"cameraDevice\", JSIConverter<std::optional<CameraDevice>>::toJSI(runtime, arg.cameraDevice));\n      obj.setProperty(runtime, \"videoMaximumDuration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.videoMaximumDuration));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::optional<CameraDevice>>::canConvert(runtime, obj.getProperty(runtime, \"cameraDevice\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"videoMaximumDuration\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/PickerCropConfig.hpp",
    "content": "///\n/// PickerCropConfig.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `CropRatio` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { struct CropRatio; }\n\n#include <optional>\n#include <vector>\n#include \"CropRatio.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (PickerCropConfig).\n   */\n  struct PickerCropConfig {\n  public:\n    std::optional<bool> circle     SWIFT_PRIVATE;\n    std::vector<CropRatio> ratio     SWIFT_PRIVATE;\n    std::optional<CropRatio> defaultRatio     SWIFT_PRIVATE;\n    std::optional<bool> freeStyle     SWIFT_PRIVATE;\n\n  public:\n    PickerCropConfig() = default;\n    explicit PickerCropConfig(std::optional<bool> circle, std::vector<CropRatio> ratio, std::optional<CropRatio> defaultRatio, std::optional<bool> freeStyle): circle(circle), ratio(ratio), defaultRatio(defaultRatio), freeStyle(freeStyle) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ PickerCropConfig <> JS PickerCropConfig (object)\n  template <>\n  struct JSIConverter<PickerCropConfig> final {\n    static inline PickerCropConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return PickerCropConfig(\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"circle\")),\n        JSIConverter<std::vector<CropRatio>>::fromJSI(runtime, obj.getProperty(runtime, \"ratio\")),\n        JSIConverter<std::optional<CropRatio>>::fromJSI(runtime, obj.getProperty(runtime, \"defaultRatio\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"freeStyle\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const PickerCropConfig& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"circle\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.circle));\n      obj.setProperty(runtime, \"ratio\", JSIConverter<std::vector<CropRatio>>::toJSI(runtime, arg.ratio));\n      obj.setProperty(runtime, \"defaultRatio\", JSIConverter<std::optional<CropRatio>>::toJSI(runtime, arg.defaultRatio));\n      obj.setProperty(runtime, \"freeStyle\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.freeStyle));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"circle\"))) return false;\n      if (!JSIConverter<std::vector<CropRatio>>::canConvert(runtime, obj.getProperty(runtime, \"ratio\"))) return false;\n      if (!JSIConverter<std::optional<CropRatio>>::canConvert(runtime, obj.getProperty(runtime, \"defaultRatio\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"freeStyle\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/PickerResult.hpp",
    "content": "///\n/// PickerResult.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n// Forward declaration of `ResultType` to properly resolve imports.\nnamespace margelo::nitro::multipleimagepicker { enum class ResultType; }\n\n#include <string>\n#include <optional>\n#include \"ResultType.hpp\"\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (PickerResult).\n   */\n  struct PickerResult {\n  public:\n    std::string localIdentifier     SWIFT_PRIVATE;\n    double width     SWIFT_PRIVATE;\n    double height     SWIFT_PRIVATE;\n    std::string mime     SWIFT_PRIVATE;\n    double size     SWIFT_PRIVATE;\n    std::optional<double> bucketId     SWIFT_PRIVATE;\n    std::optional<std::string> realPath     SWIFT_PRIVATE;\n    std::optional<std::string> parentFolderName     SWIFT_PRIVATE;\n    std::optional<double> creationDate     SWIFT_PRIVATE;\n    std::optional<bool> crop     SWIFT_PRIVATE;\n    std::string path     SWIFT_PRIVATE;\n    ResultType type     SWIFT_PRIVATE;\n    std::optional<double> duration     SWIFT_PRIVATE;\n    std::optional<std::string> thumbnail     SWIFT_PRIVATE;\n    std::optional<std::string> fileName     SWIFT_PRIVATE;\n\n  public:\n    PickerResult() = default;\n    explicit PickerResult(std::string localIdentifier, double width, double height, std::string mime, double size, std::optional<double> bucketId, std::optional<std::string> realPath, std::optional<std::string> parentFolderName, std::optional<double> creationDate, std::optional<bool> crop, std::string path, ResultType type, std::optional<double> duration, std::optional<std::string> thumbnail, std::optional<std::string> fileName): localIdentifier(localIdentifier), width(width), height(height), mime(mime), size(size), bucketId(bucketId), realPath(realPath), parentFolderName(parentFolderName), creationDate(creationDate), crop(crop), path(path), type(type), duration(duration), thumbnail(thumbnail), fileName(fileName) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ PickerResult <> JS PickerResult (object)\n  template <>\n  struct JSIConverter<PickerResult> final {\n    static inline PickerResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return PickerResult(\n        JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, \"localIdentifier\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"width\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"height\")),\n        JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, \"mime\")),\n        JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, \"size\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"bucketId\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"realPath\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"parentFolderName\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"creationDate\")),\n        JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, \"crop\")),\n        JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, \"path\")),\n        JSIConverter<ResultType>::fromJSI(runtime, obj.getProperty(runtime, \"type\")),\n        JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, \"duration\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"thumbnail\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"fileName\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const PickerResult& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"localIdentifier\", JSIConverter<std::string>::toJSI(runtime, arg.localIdentifier));\n      obj.setProperty(runtime, \"width\", JSIConverter<double>::toJSI(runtime, arg.width));\n      obj.setProperty(runtime, \"height\", JSIConverter<double>::toJSI(runtime, arg.height));\n      obj.setProperty(runtime, \"mime\", JSIConverter<std::string>::toJSI(runtime, arg.mime));\n      obj.setProperty(runtime, \"size\", JSIConverter<double>::toJSI(runtime, arg.size));\n      obj.setProperty(runtime, \"bucketId\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.bucketId));\n      obj.setProperty(runtime, \"realPath\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.realPath));\n      obj.setProperty(runtime, \"parentFolderName\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.parentFolderName));\n      obj.setProperty(runtime, \"creationDate\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.creationDate));\n      obj.setProperty(runtime, \"crop\", JSIConverter<std::optional<bool>>::toJSI(runtime, arg.crop));\n      obj.setProperty(runtime, \"path\", JSIConverter<std::string>::toJSI(runtime, arg.path));\n      obj.setProperty(runtime, \"type\", JSIConverter<ResultType>::toJSI(runtime, arg.type));\n      obj.setProperty(runtime, \"duration\", JSIConverter<std::optional<double>>::toJSI(runtime, arg.duration));\n      obj.setProperty(runtime, \"thumbnail\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.thumbnail));\n      obj.setProperty(runtime, \"fileName\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.fileName));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, \"localIdentifier\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"width\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"height\"))) return false;\n      if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, \"mime\"))) return false;\n      if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, \"size\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"bucketId\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"realPath\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"parentFolderName\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"creationDate\"))) return false;\n      if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, \"crop\"))) return false;\n      if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, \"path\"))) return false;\n      if (!JSIConverter<ResultType>::canConvert(runtime, obj.getProperty(runtime, \"type\"))) return false;\n      if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, \"duration\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"thumbnail\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"fileName\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/Presentation.hpp",
    "content": "///\n/// Presentation.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (Presentation).\n   */\n  enum class Presentation {\n    FULLSCREENMODAL      SWIFT_NAME(fullscreenmodal) = 0,\n    FORMSHEET      SWIFT_NAME(formsheet) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ Presentation <> JS Presentation (union)\n  template <>\n  struct JSIConverter<Presentation> final {\n    static inline Presentation fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"fullScreenModal\"): return Presentation::FULLSCREENMODAL;\n        case hashString(\"formSheet\"): return Presentation::FORMSHEET;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum Presentation - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, Presentation arg) {\n      switch (arg) {\n        case Presentation::FULLSCREENMODAL: return JSIConverter<std::string>::toJSI(runtime, \"fullScreenModal\");\n        case Presentation::FORMSHEET: return JSIConverter<std::string>::toJSI(runtime, \"formSheet\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert Presentation to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"fullScreenModal\"):\n        case hashString(\"formSheet\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/ResultType.hpp",
    "content": "///\n/// ResultType.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (ResultType).\n   */\n  enum class ResultType {\n    VIDEO      SWIFT_NAME(video) = 0,\n    IMAGE      SWIFT_NAME(image) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ ResultType <> JS ResultType (union)\n  template <>\n  struct JSIConverter<ResultType> final {\n    static inline ResultType fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"video\"): return ResultType::VIDEO;\n        case hashString(\"image\"): return ResultType::IMAGE;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum ResultType - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, ResultType arg) {\n      switch (arg) {\n        case ResultType::VIDEO: return JSIConverter<std::string>::toJSI(runtime, \"video\");\n        case ResultType::IMAGE: return JSIConverter<std::string>::toJSI(runtime, \"image\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert ResultType to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"video\"):\n        case hashString(\"image\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/SelectBoxStyle.hpp",
    "content": "///\n/// SelectBoxStyle.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (SelectBoxStyle).\n   */\n  enum class SelectBoxStyle {\n    NUMBER      SWIFT_NAME(number) = 0,\n    TICK      SWIFT_NAME(tick) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ SelectBoxStyle <> JS SelectBoxStyle (union)\n  template <>\n  struct JSIConverter<SelectBoxStyle> final {\n    static inline SelectBoxStyle fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"number\"): return SelectBoxStyle::NUMBER;\n        case hashString(\"tick\"): return SelectBoxStyle::TICK;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum SelectBoxStyle - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, SelectBoxStyle arg) {\n      switch (arg) {\n        case SelectBoxStyle::NUMBER: return JSIConverter<std::string>::toJSI(runtime, \"number\");\n        case SelectBoxStyle::TICK: return JSIConverter<std::string>::toJSI(runtime, \"tick\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert SelectBoxStyle to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"number\"):\n        case hashString(\"tick\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/SelectMode.hpp",
    "content": "///\n/// SelectMode.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (SelectMode).\n   */\n  enum class SelectMode {\n    SINGLE      SWIFT_NAME(single) = 0,\n    MULTIPLE      SWIFT_NAME(multiple) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ SelectMode <> JS SelectMode (union)\n  template <>\n  struct JSIConverter<SelectMode> final {\n    static inline SelectMode fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"single\"): return SelectMode::SINGLE;\n        case hashString(\"multiple\"): return SelectMode::MULTIPLE;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum SelectMode - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, SelectMode arg) {\n      switch (arg) {\n        case SelectMode::SINGLE: return JSIConverter<std::string>::toJSI(runtime, \"single\");\n        case SelectMode::MULTIPLE: return JSIConverter<std::string>::toJSI(runtime, \"multiple\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert SelectMode to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"single\"):\n        case hashString(\"multiple\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/Text.hpp",
    "content": "///\n/// Text.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\n\n\n#include <optional>\n#include <string>\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * A struct which can be represented as a JavaScript object (Text).\n   */\n  struct Text {\n  public:\n    std::optional<std::string> finish     SWIFT_PRIVATE;\n    std::optional<std::string> original     SWIFT_PRIVATE;\n    std::optional<std::string> preview     SWIFT_PRIVATE;\n    std::optional<std::string> edit     SWIFT_PRIVATE;\n\n  public:\n    Text() = default;\n    explicit Text(std::optional<std::string> finish, std::optional<std::string> original, std::optional<std::string> preview, std::optional<std::string> edit): finish(finish), original(original), preview(preview), edit(edit) {}\n  };\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ Text <> JS Text (object)\n  template <>\n  struct JSIConverter<Text> final {\n    static inline Text fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      jsi::Object obj = arg.asObject(runtime);\n      return Text(\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"finish\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"original\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"preview\")),\n        JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, \"edit\"))\n      );\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, const Text& arg) {\n      jsi::Object obj(runtime);\n      obj.setProperty(runtime, \"finish\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.finish));\n      obj.setProperty(runtime, \"original\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.original));\n      obj.setProperty(runtime, \"preview\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.preview));\n      obj.setProperty(runtime, \"edit\", JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.edit));\n      return obj;\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isObject()) {\n        return false;\n      }\n      jsi::Object obj = value.getObject(runtime);\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"finish\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"original\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"preview\"))) return false;\n      if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, \"edit\"))) return false;\n      return true;\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "nitrogen/generated/shared/c++/Theme.hpp",
    "content": "///\n/// Theme.hpp\n/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.\n/// https://github.com/mrousavy/nitro\n/// Copyright © 2025 Marc Rousavy @ Margelo\n///\n\n#pragma once\n\n#if __has_include(<NitroModules/NitroHash.hpp>)\n#include <NitroModules/NitroHash.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/JSIConverter.hpp>)\n#include <NitroModules/JSIConverter.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n#if __has_include(<NitroModules/NitroDefines.hpp>)\n#include <NitroModules/NitroDefines.hpp>\n#else\n#error NitroModules cannot be found! Are you sure you installed NitroModules properly?\n#endif\n\nnamespace margelo::nitro::multipleimagepicker {\n\n  /**\n   * An enum which can be represented as a JavaScript union (Theme).\n   */\n  enum class Theme {\n    LIGHT      SWIFT_NAME(light) = 0,\n    DARK      SWIFT_NAME(dark) = 1,\n  } CLOSED_ENUM;\n\n} // namespace margelo::nitro::multipleimagepicker\n\nnamespace margelo::nitro {\n\n  using namespace margelo::nitro::multipleimagepicker;\n\n  // C++ Theme <> JS Theme (union)\n  template <>\n  struct JSIConverter<Theme> final {\n    static inline Theme fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"light\"): return Theme::LIGHT;\n        case hashString(\"dark\"): return Theme::DARK;\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert \\\"\" + unionValue + \"\\\" to enum Theme - invalid value!\");\n      }\n    }\n    static inline jsi::Value toJSI(jsi::Runtime& runtime, Theme arg) {\n      switch (arg) {\n        case Theme::LIGHT: return JSIConverter<std::string>::toJSI(runtime, \"light\");\n        case Theme::DARK: return JSIConverter<std::string>::toJSI(runtime, \"dark\");\n        default: [[unlikely]]\n          throw std::invalid_argument(\"Cannot convert Theme to JS - invalid value: \"\n                                    + std::to_string(static_cast<int>(arg)) + \"!\");\n      }\n    }\n    static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {\n      if (!value.isString()) {\n        return false;\n      }\n      std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);\n      switch (hashString(unionValue.c_str(), unionValue.size())) {\n        case hashString(\"light\"):\n        case hashString(\"dark\"):\n          return true;\n        default:\n          return false;\n      }\n    }\n  };\n\n} // namespace margelo::nitro\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@baronha/react-native-multiple-image-picker\",\n  \"version\": \"2.2.5\",\n  \"description\": \"� react-native-multiple-image-picker enables applications to pick images and videos from multiple smart albums in iOS/Android �\",\n  \"main\": \"./lib/commonjs/index.js\",\n  \"module\": \"./lib/module/index.js\",\n  \"types\": \"./lib/typescript/index.d.ts\",\n  \"react-native\": \"src/index\",\n  \"source\": \"src/index\",\n  \"files\": [\n    \"src\",\n    \"nitrogen\",\n    \"react-native.config.js\",\n    \"lib\",\n    \"android/build.gradle\",\n    \"android/gradle.properties\",\n    \"android/CMakeLists.txt\",\n    \"android/src\",\n    \"ios/**/*.h\",\n    \"ios/**/*.m\",\n    \"ios/**/*.mm\",\n    \"ios/**/*.cpp\",\n    \"ios/**/*.swift\",\n    \"ios/Assets.xcassets\",\n    \"app.plugin.js\",\n    \"*.podspec\",\n    \"README.md\"\n  ],\n  \"scripts\": {\n    \"typecheck\": \"tsc --project tsconfig.build.json --noEmit\",\n    \"clean\": \"rm -rf android/build node_modules/**/android/build lib\",\n    \"lint\": \"eslint \\\"**/*.{js,ts,tsx}\\\" --fix\",\n    \"lint-ci\": \"eslint \\\"**/*.{js,ts,tsx}\\\" -f @jamesacarr/github-actions\",\n    \"typescript\": \"tsc --noEmit false\",\n    \"specs\": \"bun run --filter=\\\"**\\\" typescript && bun nitro-codegen --logLevel=\\\"debug\\\"\",\n    \"nitro\": \"yarn nitro-codegen\",\n    \"example\": \"yarn --cwd MultipleImagePickerExample\",\n    \"pod\": \"cd MultipleImagePickerExample && pod-install --quiet\",\n    \"bootstrap\": \"yarn example && yarn && yarn pod\",\n    \"prepare\": \"bob build\"\n  },\n  \"keywords\": [\n    \"react-native\",\n    \"ios\",\n    \"android\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/NitrogenZLab/react-native-multiple-image-picker.git\"\n  },\n  \"author\": \"Bảo Hà. <baronn.ha@gmail.com> (https://github.com/baronha)\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/NitrogenZLab/react-native-multiple-image-picker/issues\"\n  },\n  \"homepage\": \"https://github.com/NitrogenZLab/react-native-multiple-image-picker#readme\",\n  \"publishConfig\": {\n    \"registry\": \"https://registry.npmjs.org/\"\n  },\n  \"devDependencies\": {\n    \"@react-native/eslint-config\": \"^0.75.2\",\n    \"@types/jest\": \"^29.5.12\",\n    \"@types/react\": \"^18.3.4\",\n    \"eslint\": \"^8.57.0\",\n    \"eslint-config-prettier\": \"^9.1.0\",\n    \"eslint-plugin-prettier\": \"^5.2.1\",\n    \"nitro-codegen\": \"0.25.2\",\n    \"prettier\": \"^3.3.3\",\n    \"react\": \"^18.3.1\",\n    \"react-native\": \"^0.75.2\",\n    \"react-native-builder-bob\": \"^0.30.0\",\n    \"react-native-nitro-modules\": \"0.25.2\",\n    \"typescript\": \"^5.5.4\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"*\",\n    \"react-native\": \"*\"\n  },\n  \"eslintConfig\": {\n    \"root\": true,\n    \"extends\": [\n      \"@react-native\",\n      \"prettier\"\n    ],\n    \"plugins\": [\n      \"prettier\"\n    ],\n    \"rules\": {\n      \"prettier/prettier\": [\n        \"warn\",\n        {\n          \"quoteProps\": \"consistent\",\n          \"singleQuote\": true,\n          \"tabWidth\": 2,\n          \"trailingComma\": \"es5\",\n          \"useTabs\": false\n        }\n      ]\n    }\n  },\n  \"eslintIgnore\": [\n    \"node_modules/\",\n    \"lib/\"\n  ],\n  \"prettier\": {\n    \"quoteProps\": \"consistent\",\n    \"singleQuote\": true,\n    \"tabWidth\": 2,\n    \"trailingComma\": \"es5\",\n    \"useTabs\": false,\n    \"semi\": false\n  },\n  \"react-native-builder-bob\": {\n    \"source\": \"src\",\n    \"output\": \"lib\",\n    \"targets\": [\n      \"commonjs\",\n      \"module\",\n      [\n        \"typescript\",\n        {\n          \"project\": \"tsconfig.build.json\"\n        }\n      ]\n    ]\n  },\n  \"packageManager\": \"yarn@1.22.22\"\n}\n"
  },
  {
    "path": "react-native.config.js",
    "content": "// https://github.com/react-native-community/cli/blob/main/docs/dependencies.md\n\nmodule.exports = {\n  dependency: {\n    platforms: {\n      /**\n       * @type {import('@react-native-community/cli-types').IOSDependencyParams}\n       */\n      ios: {},\n      /**\n       * @type {import('@react-native-community/cli-types').AndroidDependencyParams}\n       */\n      android: {},\n    },\n  },\n}\n"
  },
  {
    "path": "scripts/bootstrap.js",
    "content": "const path = require('path');\nconst child_process = require('child_process');\n\nconst root = path.resolve(__dirname, '..');\nconst args = process.argv.slice(2);\nconst options = {\n  cwd: process.cwd(),\n  env: process.env,\n  stdio: 'inherit',\n  encoding: 'utf-8',\n};\n\nlet result;\n\nif (process.cwd() !== root || args.length) {\n  // We're not in the root of the project, or additional arguments were passed\n  // In this case, forward the command to `yarn`\n  result = child_process.spawnSync('yarn', args, options);\n} else {\n  // If `yarn` is run without arguments, perform bootstrap\n  result = child_process.spawnSync('yarn', ['bootstrap'], options);\n}\n\nprocess.exitCode = result.status;\n"
  },
  {
    "path": "src/index.ts",
    "content": "export * from './specs/MultipleImagePicker.nitro'\nexport * from './types'\n\nimport { NitroModules } from 'react-native-nitro-modules'\n\nimport { type MultipleImagePicker } from './specs/MultipleImagePicker.nitro'\n\nimport { processColor, Appearance } from 'react-native'\n\nimport {\n  PickerResult,\n  Config,\n  NitroConfig,\n  CropResult,\n  CropConfig,\n  NitroCropConfig,\n  PreviewConfig,\n  NitroPreviewConfig,\n  MediaPreview,\n  CameraConfig,\n  NitroCameraConfig,\n  CameraResult,\n  Language,\n} from './types'\nimport { CropReject, CameraError } from './types/error'\n\nconst Picker = NitroModules.createHybridObject<MultipleImagePicker>(\n  'MultipleImagePicker'\n)\n\ntype IPromisePicker<T extends Config> = T['selectMode'] extends 'single'\n  ? PickerResult\n  : PickerResult[]\n\nexport async function openPicker<T extends Config>(\n  conf: T\n): Promise<IPromisePicker<T>> {\n  return new Promise((resolved, rejected) => {\n    const config = { ...defaultOptions, ...conf } as NitroConfig\n    config.primaryColor = processColor(config.primaryColor) as any\n    config.backgroundDark = processColor(config.backgroundDark) as any\n\n    if ((config as Config)?.theme === 'system') {\n      const theme = Appearance.getColorScheme() ?? 'light'\n      config.theme = theme\n    }\n\n    config.language = validateLanguage(config.language)\n\n    if (typeof config.crop === 'boolean') {\n      config.crop = config.crop ? { ratio: [] } : undefined\n    }\n\n    if (config.crop) config.crop.ratio = config.crop?.ratio ?? []\n\n    return Picker.openPicker(\n      config,\n      (result: PickerResult[]) => {\n        resolved(result as IPromisePicker<T>)\n      },\n      (reject: number) => {\n        rejected(reject)\n      }\n    )\n  })\n}\n\nexport async function openCropper(\n  image: string,\n  config?: CropConfig\n): Promise<CropResult> {\n  return new Promise(\n    (resolved, rejected: (reason: (typeof CropReject)[0]) => void) => {\n      const cropConfig = {\n        presentation: 'fullScreenModal',\n        language: 'system',\n        ratio: [],\n        ...config,\n      } as NitroCropConfig\n\n      cropConfig.language = validateLanguage(cropConfig.language)\n\n      return Picker.openCrop(\n        image,\n        cropConfig,\n        (result: CropResult) => {\n          resolved(result)\n        },\n        (error: number) => {\n          rejected(CropReject?.[error as 0 | 1] ?? CropReject[0])\n        }\n      )\n    }\n  )\n}\n\nexport function openPreview(\n  media: MediaPreview[] | PickerResult[],\n  index: number = 0,\n  conf?: PreviewConfig\n): void {\n  const config: PreviewConfig = {\n    language: conf?.language ?? 'system',\n    videoAutoPlay: true,\n    ...conf,\n  }\n\n  if (config?.language && !LANGUAGES.includes(config.language)) {\n    config.language = 'system'\n  }\n\n  if (media.length === 0) {\n    throw new Error('Media is required')\n  }\n\n  return Picker.openPreview(\n    media as MediaPreview[],\n    index,\n    config as NitroPreviewConfig,\n    config?.onLongPress ?? (() => {})\n  )\n}\n\nexport async function openCamera(config?: CameraConfig): Promise<CameraResult> {\n  return new Promise((resolved, rejected) => {\n    const cameraConfig = {\n      cameraDevice: 'back',\n      presentation: 'fullScreenModal',\n      language: 'system',\n      mediaType: 'all',\n      allowLocation: true,\n      isSaveSystemAlbum: false,\n      ...config,\n    } as NitroCameraConfig\n\n    cameraConfig.color = processColor(cameraConfig.color ?? primaryColor) as any\n\n    cameraConfig.language = validateLanguage(cameraConfig.language)\n\n    if (typeof cameraConfig.crop === 'boolean') {\n      cameraConfig.crop = cameraConfig.crop ? { ratio: [] } : undefined\n    }\n\n    if (cameraConfig.crop && !cameraConfig.crop?.ratio)\n      cameraConfig.crop.ratio = []\n\n    return Picker.openCamera(\n      cameraConfig,\n      (result: CameraResult) => {\n        resolved(result)\n      },\n      (error: CameraError) => {\n        rejected(error)\n      }\n    )\n  })\n}\n\nconst DEFAULT_COUNT = 20\n\nconst validateLanguage = (language?: Language): Language => {\n  if (!language || !LANGUAGES.includes(language)) {\n    return 'system'\n  }\n  return language\n}\n\nconst primaryColor = '#2979ff'\n\nexport const defaultOptions: Config = {\n  maxSelect: DEFAULT_COUNT,\n  maxVideo: DEFAULT_COUNT,\n  primaryColor,\n  backgroundDark: '#2f2f2f',\n  allowedLimit: true,\n  numberOfColumn: 3,\n  isPreview: true,\n  mediaType: 'all',\n  selectedAssets: [],\n  selectBoxStyle: 'number',\n  selectMode: 'multiple',\n  presentation: 'fullScreenModal',\n  language: 'system',\n  theme: 'system',\n  isHiddenOriginalButton: false,\n  allowSwipeToSelect: true,\n  camera: {\n    cameraDevice: 'back',\n    videoMaximumDuration: 60,\n  },\n}\n\nconst LANGUAGES = [\n  'system',\n  'zh-Hans',\n  'zh-Hant',\n  'ja',\n  'ko',\n  'en',\n  'th',\n  'id',\n  'vi',\n  'ru',\n  'de',\n  'fr',\n  'ar',\n] as const\n"
  },
  {
    "path": "src/specs/MultipleImagePicker.nitro.ts",
    "content": "import { type HybridObject } from 'react-native-nitro-modules'\nimport {\n  CameraResult,\n  CropResult,\n  MediaPreview,\n  NitroCameraConfig,\n  NitroConfig,\n  NitroCropConfig,\n  NitroPreviewConfig,\n  PickerResult,\n} from '../types'\n\nexport interface MultipleImagePicker\n  extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {\n  openPicker(\n    config: NitroConfig,\n    resolved: (result: PickerResult[]) => void,\n    rejected: (reject: number) => void\n  ): void\n\n  openCrop(\n    image: string,\n    config: NitroCropConfig,\n    resolved: (result: CropResult) => void,\n    rejected: (reject: number) => void\n  ): void\n\n  openPreview(\n    media: MediaPreview[],\n    index: number,\n    config: NitroPreviewConfig,\n    onLongPress: (index: number) => void\n  ): void\n\n  openCamera(\n    config: NitroCameraConfig,\n    resolved: (result: CameraResult) => void,\n    rejected: (reject: number) => void\n  ): void\n}\n"
  },
  {
    "path": "src/types/camera.ts",
    "content": "import { ColorValue } from 'react-native'\nimport { Language, MediaType, Presentation } from './config'\nimport { PickerCropConfig, CropRatio } from './crop'\nimport { BaseResult } from './result'\n\nexport type CameraDevice = 'front' | 'back'\n\nexport type PickerCameraConfig = {\n  /**\n   * Type of camera\n   * @typedef {'front' | 'back'} CameraDevice\n   */\n  cameraDevice?: CameraDevice\n\n  /**\n   * Maximum duration of video\n   * @type {number}\n   */\n  videoMaximumDuration?: number\n}\n\nexport interface NitroCameraConfig extends PickerCameraConfig {\n  mediaType: MediaType\n\n  presentation: Presentation\n\n  language: Language\n\n  crop?: PickerCropConfig\n\n  /**\n   * Save image to system album\n   * @type {boolean}\n   */\n  isSaveSystemAlbum?: boolean\n\n  color?: number\n}\n\nexport interface CameraConfig\n  extends Omit<\n    NitroCameraConfig,\n    'mediaType' | 'language' | 'presentation' | 'crop' | 'color'\n  > {\n  /**\n   * Type of media to be displayed\n   * @typedef {'video' | 'image' | 'all'} MediaType\n   */\n  mediaType?: MediaType\n\n  /**\n   * Modal presentation style for the picker.\n   * - 'fullScreenModal': Opens picker in full screen\n   * - 'formSheet': Opens picker in a form sheet style\n   *\n   * @platform ios\n   * @default 'fullScreenModal'\n   * @type {Presentation}\n   * @example\n   * ```ts\n   * presentation: 'formSheet'\n   * ```\n   */\n  presentation?: Presentation\n\n  /**\n   * Language options for the picker.\n   * @description\n   * - 'system': 🌐 System default\n   * - 'zh-Hans': 🇨🇳 Simplified Chinese\n   * - 'zh-Hant': 🇹🇼 Traditional Chinese\n   * - 'ja': 🇯🇵 Japanese\n   * - 'ko': 🇰🇷 Korean\n   * - 'en': 🇬🇧 English\n   * - 'th': 🇹🇭 Thai\n   * - 'id': 🇮🇩 Indonesian\n   * - 'vi': 🇻🇳 Vietnamese (My Country)\n   * - 'ru': 🇷🇺 Russian\n   * - 'de': 🇩🇪 German\n   * - 'fr': 🇫🇷 French\n   * - 'ar': 🇸🇦 Arabic\n   */\n  language?: Language\n\n  crop?:\n    | boolean\n    | (Omit<PickerCropConfig, 'ratio'> & {\n        /**\n         * Array of aspect ratios for image cropping. The ratios will be inserted after the default ratios (Original and Square).\n         * Android: Maximum: 4 items\n         *\n         * @platform ios, Android\n         *\n         * @property {Array<CropRatio>} ratio - Array of custom aspect ratios\n         * @property {string} [ratio[].title] - Optional display title for the ratio (e.g., \"16:9\"). If not provided, will use \"width/height\"\n         * @property {number} ratio[].width - Width value for aspect ratio\n         * @property {number} ratio[].height - Height value for aspect ratio\n         *\n         * @example\n         * ```ts\n         * ratio: [\n         *   { title: \"Instagram\", width: 1, height: 1 },\n         *   { title: \"Twitter\", width: 16, height: 9 },\n         *   { width: 12, height: 11 }\n         * ]\n         * ```\n         */\n        ratio?: CropRatio[]\n\n        /**\n         * Camera configuration\n         * @type {CameraConfig}\n         */\n      })\n\n  /**\n   * Primary color for the picker UI elements.\n   * Accepts various color formats:\n   * - Hex strings: '#RGB', '#RGBA', '#RRGGBB', '#RRGGBBAA'\n   * - RGB/RGBA strings: 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 0.5)'\n   * - Named colors: 'red', 'blue', etc.\n   * - Numbers for RGB values\n   *\n   * @platform ios, android\n   * @type {ColorValue}\n   * @example\n   * ```ts\n   * primaryColor: '#FF0000'\n   * primaryColor: 'rgb(255, 0, 0)'\n   * primaryColor: 'red'\n   * ```\n   */\n  color?: ColorValue\n}\n\nexport interface CameraResult extends BaseResult {\n  //\n}\n"
  },
  {
    "path": "src/types/config.ts",
    "content": "export type Theme = 'light' | 'dark'\n\nexport type Presentation = 'fullScreenModal' | 'formSheet'\n\nexport type Language =\n  | 'system'\n  | 'zh-Hans'\n  | 'zh-Hant'\n  | 'ja'\n  | 'ko'\n  | 'en'\n  | 'th'\n  | 'id'\n  | 'vi'\n  | 'ru'\n  | 'de'\n  | 'fr'\n  | 'ar'\n\nexport type MediaType = 'video' | 'image' | 'all'\n"
  },
  {
    "path": "src/types/crop.ts",
    "content": "import { Language, Presentation } from './config'\n\nexport type CropRatio = { title?: string; width: number; height: number }\n\n/**\n * Configuration for image cropping\n * @interface PickerCropConfig\n */\nexport type PickerCropConfig = {\n  /** Enable circular crop mask */\n  circle?: boolean\n\n  ratio: CropRatio[]\n\n  /**\n   * Default ratio to be selected when opening the crop interface.\n   * If not specified, the first ratio in the list will be selected.\n   *\n   * @platform ios, android\n   *\n   * @example\n   * ```ts\n   * // Custom ratio without title\n   * defaultRatio: { width: 4, height: 3 }\n   */\n  defaultRatio?: CropRatio\n\n  /** Enable free style cropping */\n  freeStyle?: boolean\n}\n\n// CROP\nexport interface NitroCropConfig extends PickerCropConfig {\n  /**\n   * Interface language\n   * @type {Language}\n   */\n  language: Language\n\n  presentation: Presentation\n}\n\nexport interface CropConfig\n  extends Omit<NitroCropConfig, 'language' | 'presentation' | 'ratio'> {\n  /**\n   * Language options for the picker.\n   *\n   * @platform ios\n   *\n   * @description\n   * - 'system': 🌐 System default\n   * - 'zh-Hans': 🇨🇳 Simplified Chinese\n   * - 'zh-Hant': 🇹🇼 Traditional Chinese\n   * - 'ja': 🇯🇵 Japanese\n   * - 'ko': 🇰🇷 Korean\n   * - 'en': 🇬🇧 English\n   * - 'th': 🇹🇭 Thai\n   * - 'id': 🇮🇩 Indonesian\n   * - 'vi': 🇻🇳 Vietnamese (My Country)\n   * - 'ru': 🇷🇺 Russian\n   * - 'de': 🇩🇪 German\n   * - 'fr': 🇫🇷 French\n   * - 'ar': 🇸🇦 Arabic\n   */\n  language?: Language\n\n  /**\n   * Array of aspect ratios for image cropping. The ratios will be inserted after the default ratios (Original and Square).\n   * Android: Maximum: 4 items\n   *\n   * @platform ios, android\n   *\n   * @property {Array<CropRatio>} ratio - Array of custom aspect ratios\n   * @property {string} [ratio[].title] - Optional display title for the ratio (e.g., \"16:9\"). If not provided, will use \"width/height\"\n   * @property {number} ratio[].width - Width value for aspect ratio\n   * @property {number} ratio[].height - Height value for aspect ratio\n   *\n   * @example\n   * ```ts\n   * ratio: [\n   *   { title: \"Instagram\", width: 1, height: 1 },\n   *   { title: \"Twitter\", width: 16, height: 9 },\n   *   {  width: 12, height: 11 }\n   * ]\n   * ```\n   */\n  ratio?: CropRatio[]\n}\n\nexport interface CropResult {\n  path: string\n  width: number\n  height: number\n}\n"
  },
  {
    "path": "src/types/error.ts",
    "content": "export enum MultipleImagePickerError {\n  CANCELLED = 0,\n}\n\nexport enum CameraError {\n  INVALID_OUTPUT_FILE = 1,\n}\n\nexport const CropReject = {\n  0: {\n    code: 0,\n    message: 'Invalid Image',\n  },\n  1: {\n    code: 1,\n    message: 'User Cancelled',\n  },\n}\n"
  },
  {
    "path": "src/types/index.ts",
    "content": "export * from './result'\nexport * from './config'\nexport * from './crop'\nexport * from './preview'\nexport * from './picker'\nexport * from './camera'\n"
  },
  {
    "path": "src/types/picker.ts",
    "content": "import { ColorValue } from 'react-native'\nimport { Language, MediaType, Presentation, Theme } from './config'\nimport { PickerCropConfig, CropRatio } from './crop'\nimport { PickerCameraConfig } from './camera'\nimport { PickerResult } from './result'\n\nexport type SelectBoxStyle = 'number' | 'tick'\n\nexport type SelectMode = 'single' | 'multiple'\n\n/**\n * Custom text labels for buttons and headers\n * @interface Text\n */\nexport interface Text {\n  /** Text for finish/done button */\n  finish?: string\n  /** Text for original button */\n  original?: string\n  /** Text for preview button */\n  preview?: string\n  /** Text for edit button */\n  edit?: string\n}\n\n/**\n * Main configuration interface for the Nitro image picker\n * @interface NitroConfig\n */\nexport interface NitroConfig {\n  /**\n   * Type of media to display in picker\n   * @type {MediaType}\n   */\n  mediaType: MediaType\n\n  /**\n   * Array of currently selected assets\n   * @type {Result[]}\n   */\n  selectedAssets: PickerResult[]\n\n  /**\n   * Style of the selection box\n   * @type {SelectBoxStyle}\n   */\n  selectBoxStyle: SelectBoxStyle\n\n  /**\n   * Selection mode for picker\n   * @type {SelectMode}\n   */\n  selectMode: SelectMode\n\n  /**\n   * Number of columns in the grid view\n   * @type {number}\n   */\n  numberOfColumn?: number\n\n  /**\n   * Enable preview functionality\n   * @type {boolean}\n   */\n  isPreview?: boolean\n\n  /**\n   * Primary color value in number format\n   * @type {number}\n   */\n  primaryColor?: number\n  /**\n   * Enable swipe gesture for selection\n   * @type {boolean}\n   */\n  allowSwipeToSelect?: boolean\n\n  /**\n   * Spacing between items in the grid\n   * @type {number}\n   */\n  spacing?: number\n\n  /**\n   * Hide the preview button and button mode\n   * @type {boolean}\n   */\n  isHiddenPreviewButton?: boolean\n\n  /**\n   * Hide the original button\n   * @type {boolean}\n   */\n  isHiddenOriginalButton?: boolean\n\n  /**\n   * Show preview list\n   * @type {boolean}\n   * @platform ios\n   */\n  isShowPreviewList?: boolean\n\n  /**\n   * Enable haptic feedback on preview\n   * @type {boolean}\n   * @platform ios\n   */\n  allowHapticTouchPreview?: boolean\n\n  /**\n   * Enable selection limit\n   * @type {boolean}\n   */\n  allowedLimit?: boolean\n\n  /**\n   * Maximum number of videos allowed\n   * @type {number}\n   */\n  maxVideo?: number\n\n  /**\n   * Maximum number of items that can be selected\n   * @type {number}\n   */\n  maxSelect?: number\n\n  /**\n   * Maximum duration for videos in seconds\n   * @type {number}\n   */\n  maxVideoDuration?: number\n\n  /**\n   * Minimum duration for videos in seconds\n   * @type {number}\n   */\n  minVideoDuration?: number\n\n  /**\n   * Maximum file size in bytes\n   * @type {number}\n   */\n  maxFileSize?: number\n\n  /**\n   * Background color for dark mode in number format\n   * @type {number}\n   */\n  backgroundDark?: number\n\n  /**\n   * Configuration options for image cropping functionality.\n   *\n   * @type {PickerCropConfig}\n   * @property {boolean} [circle] - Enable circular crop mask for profile pictures\n   *\n   * @example\n   * ```ts\n   * // -> Enable basic cropping with default settings\n   * crop: {}\n   *\n   * // -> Enable cropping with circle crop mask\n   * crop: {\n   *   circle: true,\n   * }\n   * ```\n   *\n   * @platform ios, android\n   */\n  crop?: PickerCropConfig\n\n  /**\n   * Custom text labels for various UI elements in the picker.\n   * Allows customization of button labels and headers to support localization and branding.\n   *\n   * @type {Text}\n   * @property {string} [finish] - Label for the finish/done button\n   * @property {string} [original] - Label for the original button\n   * @property {string} [preview] - Label for the preview button\n   * @property {string} [edit] - Label for the edit button\n   *\n   * @example\n   * ```ts\n   * text: {\n   *   finish: 'Complete',\n   *   original: 'Original',\n   *   preview: 'Preview',\n   *   edit: 'Edit'\n   * }\n   * ```\n   *\n   * @remarks\n   * - All properties are optional and will use default values if not specified\n   * - Useful for localization and customizing the user interface\n   */\n  text?: Text\n\n  /**\n   * Interface language\n   * @type {Language}\n   */\n  language: Language\n\n  /**\n   * Theme mode\n   * @type {Theme}\n   */\n  theme: Theme\n\n  presentation: Presentation\n\n  /**\n   * Camera configuration\n   * @type {PickerCameraConfig}\n   */\n  camera?: PickerCameraConfig\n}\n\n// CONFIG TYPE\nexport interface Config\n  extends Omit<\n    NitroConfig,\n    | 'selectedAssets'\n    | 'mediaType'\n    | 'selectMode'\n    | 'selectBoxStyle'\n    | 'primaryColor'\n    | 'presentation'\n    | 'language'\n    | 'theme'\n    | 'backgroundDark'\n    | 'crop'\n    | 'camera'\n  > {\n  /**\n   * Type of media to be displayed\n   * @typedef {'video' | 'image' | 'all'} MediaType\n   */\n  mediaType?: MediaType\n\n  /**\n   * Array of currently selected assets\n   * @type {Result[]}\n   */\n  selectedAssets?: PickerResult[]\n\n  /**\n   * Style of selection box in the picker\n   * @typedef {'number' | 'tick'} SelectBoxStyle\n   */\n  selectBoxStyle?: SelectBoxStyle\n\n  /**\n   * Mode of selection in the picker\n   * @typedef {'single' | 'multiple'} SelectMode\n   */\n  selectMode?: SelectMode\n\n  /**\n   * Primary color for the picker UI elements.\n   * Accepts various color formats:\n   * - Hex strings: '#RGB', '#RGBA', '#RRGGBB', '#RRGGBBAA'\n   * - RGB/RGBA strings: 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 0.5)'\n   * - Named colors: 'red', 'blue', etc.\n   * - Numbers for RGB values\n   *\n   * @platform ios, android\n   * @type {ColorValue}\n   * @example\n   * ```ts\n   * primaryColor: '#FF0000'\n   * primaryColor: 'rgb(255, 0, 0)'\n   * primaryColor: 'red'\n   * ```\n   */\n  primaryColor?: ColorValue\n\n  /**\n   * Modal presentation style for the picker.\n   * - 'fullScreenModal': Opens picker in full screen\n   * - 'formSheet': Opens picker in a form sheet style\n   *\n   * @platform ios\n   * @default 'fullScreenModal'\n   * @type {Presentation}\n   * @example\n   * ```ts\n   * presentation: 'formSheet'\n   * ```\n   */\n  presentation?: Presentation\n\n  /**\n   * Language options for the picker.\n   * @description\n   * - 'system': 🌐 System default\n   * - 'zh-Hans': 🇨🇳 Simplified Chinese\n   * - 'zh-Hant': 🇹🇼 Traditional Chinese\n   * - 'ja': 🇯🇵 Japanese\n   * - 'ko': 🇰🇷 Korean\n   * - 'en': 🇬🇧 English\n   * - 'th': 🇹🇭 Thai\n   * - 'id': 🇮🇩 Indonesian\n   * - 'vi': 🇻🇳 Vietnamese (My Country)\n   * - 'ru': 🇷🇺 Russian\n   * - 'de': 🇩🇪 German\n   * - 'fr': 🇫🇷 French\n   * - 'ar': 🇸🇦 Arabic\n   */\n  language?: Language\n\n  /**\n   * Theme mode for the picker.\n   * - 'light': Uses light theme\n   * - 'dark': Uses dark theme\n   * - 'system': Uses system default theme\n   *\n   * @platform ios, android\n   * @default 'system'\n   * @type {'light' | 'dark' | 'system'}\n   */\n  theme?: Theme | 'system'\n\n  /**\n   * Background color for dark mode UI elements.\n   * Accepts various color formats:\n   * - Hex strings: '#RGB', '#RGBA', '#RRGGBB', '#RRGGBBAA'\n   * - RGB/RGBA strings: 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 0.5)'\n   * - Named colors: 'red', 'blue', etc.\n   * - Numbers for RGB values\n   *\n   * @platform ios, android\n   * @type {ColorValue}\n   * @example\n   * ```ts\n   * backgroundDark: '#000000'\n   * backgroundDark: 'rgb(0, 0, 0)'\n   * backgroundDark: 'black'\n   * ```\n   */\n  backgroundDark?: ColorValue\n\n  /**\n   * Configuration for image cropping\n   * @interface PickerCropConfig\n   */\n\n  crop?:\n    | boolean\n    | (Omit<PickerCropConfig, 'ratio'> & {\n        /**\n         * Array of aspect ratios for image cropping. The ratios will be inserted after the default ratios (Original and Square).\n         * Android: Maximum: 4 items\n         *\n         * @platform ios, Android\n         *\n         * @property {Array<CropRatio>} ratio - Array of custom aspect ratios\n         * @property {string} [ratio[].title] - Optional display title for the ratio (e.g., \"16:9\"). If not provided, will use \"width/height\"\n         * @property {number} ratio[].width - Width value for aspect ratio\n         * @property {number} ratio[].height - Height value for aspect ratio\n         *\n         * @example\n         * ```ts\n         * ratio: [\n         *   { title: \"Instagram\", width: 1, height: 1 },\n         *   { title: \"Twitter\", width: 16, height: 9 },\n         *   { width: 12, height: 11 }\n         * ]\n         * ```\n         */\n        ratio?: CropRatio[]\n\n        /**\n         * Camera configuration\n         * @type {CameraConfig}\n         */\n      })\n\n  camera?: PickerCameraConfig\n}\n"
  },
  {
    "path": "src/types/preview.ts",
    "content": "import { Language } from './config'\nimport { ResultType } from './result'\n\n// PREVIEW\nexport type NitroPreviewConfig = {\n  language: Language\n\n  /**\n   * Auto play video when open preview.\n   *\n   * @platform iOS, Android\n   */\n  videoAutoPlay?: boolean\n}\n\nexport interface PreviewConfig\n  extends Omit<NitroPreviewConfig, 'language' | 'backgroundColor'> {\n  /**\n   * Language options for the picker.\n   *\n   * @platform ios\n   *\n   * @description\n   * - 'system': 🌐 System default\n   * - 'zh-Hans': 🇨🇳 Simplified Chinese\n   * - 'zh-Hant': 🇹🇼 Traditional Chinese\n   * - 'ja': 🇯🇵 Japanese\n   * - 'ko': 🇰🇷 Korean\n   * - 'en': 🇬🇧 English\n   * - 'th': 🇹🇭 Thai\n   * - 'id': 🇮🇩 Indonesian\n   * - 'vi': 🇻🇳 Vietnamese (My Country)\n   * - 'ru': 🇷🇺 Russian\n   * - 'de': 🇩🇪 German\n   * - 'fr': 🇫🇷 French\n   * - 'ar': 🇸🇦 Arabic\n   */\n  language?: Language\n\n  onLongPress?: (index: number) => void\n}\n\nexport interface MediaPreview {\n  type: ResultType\n  path?: string\n  thumbnail?: string\n  localIdentifier?: string\n}\n"
  },
  {
    "path": "src/types/result.ts",
    "content": "/**\n * Represents the type of media content\n * @example\n * const type: ResultType = 'image'\n * const type: ResultType = 'video'\n */\nexport type ResultType = 'image' | 'video'\n\n/**\n * Base interface containing common properties for media results.\n * Used as a foundation for more specific result types.\n *\n * @example\n * const baseResult: BaseResult = {\n *   path: '/path/to/media/file.jpg',\n *   type: 'image',\n *   width: 1920,\n *   height: 1080,\n *   fileName: 'file.jpg'\n * }\n */\nexport interface BaseResult {\n  /**\n   * File path of the media asset\n   * Can be relative or absolute depending on context\n   */\n  path: string\n\n  /**\n   * Type of media content\n   * Used to determine how the asset should be handled\n   */\n  type: ResultType\n\n  /**\n   * Width of the media in pixels\n   * Optional in base result as it may not be immediately available\n   */\n  width?: number\n\n  /**\n   * Height of the media in pixels\n   * Optional in base result as it may not be immediately available\n   */\n  height?: number\n\n  /**\n   * Duration of the media in seconds\n   * Only applicable for video content\n   * @example 120.5 // 2 minutes and 30 seconds\n   */\n  duration?: number\n\n  /**\n   * Path to a thumbnail image representation\n   * Useful for previews and grid displays\n   * Can be a local path or URL depending on implementation\n   */\n  thumbnail?: string\n\n  /**\n   * Original filename of the media asset\n   * Includes the file extension\n   * @example \"IMG_20240301_123456.jpg\"\n   */\n  fileName?: string\n}\n\n/**\n * Extended result interface with complete metadata and file information.\n * Used for fully processed media assets where all properties are known.\n *\n * @extends BaseResult\n *\n * @example\n * const result: Result = {\n *   path: '/path/to/media/file.jpg',\n *   type: 'image',\n *   width: 1920,\n *   height: 1080,\n *   fileName: 'file.jpg',\n *   localIdentifier: 'unique-id-123',\n *   mime: 'image/jpeg',\n *   size: 1024000,\n *   creationDate: 1709312436000\n * }\n */\nexport interface PickerResult extends BaseResult {\n  /**\n   * Unique identifier for the media asset\n   * Used for local database tracking and reference\n   * Format may vary depending on platform/implementation\n   */\n  localIdentifier: string\n\n  /**\n   * Width of the media in pixels\n   * Required in Result interface as it should be known after processing\n   */\n  width: number\n\n  /**\n   * Height of the media in pixels\n   * Required in Result interface as it should be known after processing\n   */\n  height: number\n\n  /**\n   * MIME type of the media file\n   * @example \"image/jpeg\", \"video/mp4\"\n   */\n  mime: string\n\n  /**\n   * File size in bytes\n   * @example 1024000 // 1MB\n   */\n  size: number\n\n  /**\n   * Optional identifier for storage bucket\n   * Used when assets are stored in cloud storage systems\n   * @platform android\n   */\n  bucketId?: number\n\n  /**\n   * Actual file path on the system\n   * May differ from the `path` property in cases where\n   * the file is stored in a different location than referenced\n   * @platform android\n   */\n  realPath?: string\n\n  /**\n   * Name of the containing folder\n   * Useful for organization and grouping\n   * @platform android\n   */\n  parentFolderName?: string\n\n  /**\n   * Unix timestamp in milliseconds of when the media was created\n   * @example 1709312436000 // March 1, 2024 12:34:56 PM\n   */\n  creationDate?: number\n\n  /**\n   * Indicates if the media has been cropped from its original dimensions\n   * Used to track image modifications\n   */\n  crop?: boolean\n}\n"
  },
  {
    "path": "tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig\",\n  \"exclude\": [\"example\", \"docs\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@baronha/react-native-multiple-image-picker\": [\"src\"]\n    },\n    \"allowUnreachableCode\": false,\n    \"allowUnusedLabels\": false,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"jsx\": \"react\",\n    \"lib\": [\"esnext\"],\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitUseStrict\": false,\n    \"noStrictGenericChecks\": false,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"resolveJsonModule\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"target\": \"esnext\"\n  }\n}\n"
  }
]