├── .github
└── workflows
│ └── publish.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── bin
└── run
├── examples
├── Instagram_direct_message_openai.ts
├── download_app.txt
├── instagram_direct_message_anthropic.ts
├── linkedIn_automation.txt
├── open_zepto_azure.ts
├── porter_booking.txt
├── youtube_search
└── zomato_order.txt
├── package-lock.json
├── package.json
├── scripts
├── export_ui_dump.ts
└── take_screenshot.ts
├── src
├── adb_client.ts
├── index.ts
├── mobile_computer.ts
├── ui_dump_parser.ts
└── utils.ts
└── tsconfig.json
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Package to npmjs
2 | on:
3 | release:
4 | types: [published]
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | permissions:
9 | contents: read
10 | id-token: write
11 | steps:
12 | - uses: actions/checkout@v4
13 | # Setup .npmrc file to publish to npm
14 | - uses: actions/setup-node@v4
15 | with:
16 | node-version: "20.x"
17 | registry-url: "https://registry.npmjs.org"
18 | - run: npm ci
19 | - run: npm run build
20 | - run: npm publish --provenance --access public
21 | env:
22 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | temp
4 | .env.local
5 | test
6 | .DS_Store
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 |
2 | # Contributor Covenant Code of Conduct
3 |
4 | ## Our Pledge
5 |
6 | We as members, contributors, and leaders pledge to make participation in our
7 | community a harassment-free experience for everyone, regardless of age, body
8 | size, visible or invisible disability, ethnicity, sex characteristics, gender
9 | identity and expression, level of experience, education, socio-economic status,
10 | nationality, personal appearance, race, caste, color, religion, or sexual
11 | identity and orientation.
12 |
13 | We pledge to act and interact in ways that contribute to an open, welcoming,
14 | diverse, inclusive, and healthy community.
15 |
16 | ## Our Standards
17 |
18 | Examples of behavior that contributes to a positive environment for our
19 | community include:
20 |
21 | * Demonstrating empathy and kindness toward other people
22 | * Being respectful of differing opinions, viewpoints, and experiences
23 | * Giving and gracefully accepting constructive feedback
24 | * Accepting responsibility and apologizing to those affected by our mistakes,
25 | and learning from the experience
26 | * Focusing on what is best not just for us as individuals, but for the overall
27 | community
28 |
29 | Examples of unacceptable behavior include:
30 |
31 | * The use of sexualized language or imagery, and sexual attention or advances of
32 | any kind
33 | * Trolling, insulting or derogatory comments, and personal or political attacks
34 | * Public or private harassment
35 | * Publishing others' private information, such as a physical or email address,
36 | without their explicit permission
37 | * Other conduct which could reasonably be considered inappropriate in a
38 | professional setting
39 |
40 | ## Enforcement Responsibilities
41 |
42 | Community leaders are responsible for clarifying and enforcing our standards of
43 | acceptable behavior and will take appropriate and fair corrective action in
44 | response to any behavior that they deem inappropriate, threatening, offensive,
45 | or harmful.
46 |
47 | Community leaders have the right and responsibility to remove, edit, or reject
48 | comments, commits, code, wiki edits, issues, and other contributions that are
49 | not aligned to this Code of Conduct, and will communicate reasons for moderation
50 | decisions when appropriate.
51 |
52 | ## Scope
53 |
54 | This Code of Conduct applies within all community spaces, and also applies when
55 | an individual is officially representing the community in public spaces.
56 | Examples of representing our community include using an official email address,
57 | posting via an official social media account, or acting as an appointed
58 | representative at an online or offline event.
59 |
60 | ## Enforcement
61 |
62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
63 | reported to the community leaders responsible for enforcement to @cloudycotton.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series of
86 | actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or permanent
93 | ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within the
113 | community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.1, available at
119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120 |
121 | Community Impact Guidelines were inspired by
122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123 |
124 | For answers to common questions about this code of conduct, see the FAQ at
125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
126 | [https://www.contributor-covenant.org/translations][translations].
127 |
128 | [homepage]: https://www.contributor-covenant.org
129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130 | [Mozilla CoC]: https://github.com/mozilla/diversity
131 | [FAQ]: https://www.contributor-covenant.org/faq
132 | [translations]: https://www.contributor-covenant.org/translations
133 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2025 cloudycotton
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 📱 mobile-use
4 | **Use AI to control your Android phone — with natural language.**
5 |
6 | [](LICENSE)
7 | [](https://discord.gg/BcWWRCnap6)
8 | [](https://www.npmjs.com/package/mobile-use)
9 | [](https://github.com/runablehq/mobile-use/stargazers)
10 |
11 | https://github.com/user-attachments/assets/88ab0a2d-d6e6-4d80-922e-b13d3ae91c85
12 |
13 |
14 |
15 | ---
16 |
17 | ## ✨ What is this?
18 |
19 | **`mobile-use`** lets you control your Android phone using simple, natural-language instructions.
20 |
21 | Just type:
22 |
23 | > 🗣 *“Open Instagram, go to DMs, and send ‘hi’ to the first person.”*
24 |
25 | …and watch it run on your device — powered by AI.
26 |
27 | Think RPA, but for mobile — built for devs, hackers, and productivity nerds.
28 |
29 | ---
30 |
31 | ## 🚀 Quick Start
32 |
33 | ### 📦 Install via npm
34 |
35 | ```bash
36 | npm install mobile-use
37 | ```
38 |
39 | Or run the MCP server (includes setup):
40 |
41 | ```bash
42 | npx mobile-mcp install
43 | ```
44 |
45 | ---
46 |
47 | ## 🧠 AI in Action
48 |
49 | ```ts
50 | import { mobileUse } from "mobile-use";
51 |
52 | const response = await mobileUse({
53 | task: "Open instagram and go to direct messages, send hi to first person",
54 | // Optional: use your own LLM via API
55 | // llm: { provider: "your-llm", apiKey: process.env.YOUR_API_KEY }
56 | });
57 |
58 | console.log(response.text);
59 | ```
60 |
61 | > Default model: Claude (via Anthropic).
62 | > Set `ANTHROPIC_API_KEY` in your `.env` or environment to use it.
63 |
64 | ---
65 |
66 | ## 🖥️ Command Line Usage
67 |
68 | ```bash
69 | # Run a task directly from your terminal
70 | npx mobile-use "Open Instagram and send 'hi'"
71 |
72 | # Run a task from a file
73 | npx mobile-use instruction.txt
74 | ```
75 |
76 | ---
77 |
78 | ## 📱 Requirements
79 |
80 | - Android phone or Emulator running in background(iOS not supported yet)
81 | - [Android SDK Platform Tools](https://developer.android.com/studio/releases/platform-tools) installed (`adb`)(For Emulators)
82 | - USB Debugging enabled
83 |
84 | ---
85 |
86 | ## 💬 Join the Community
87 |
88 | Have a feature idea? Want to see what others are building?
89 |
90 | Join our developer Discord — we’re shaping the roadmap with the community!
91 |
92 | [](https://discord.gg/BcWWRCnap6)
93 |
94 | ---
95 |
96 | ## 🧩 What's Coming Next?
97 |
98 | - iOS support (experimental)
99 | - Visual workflows
100 | - Common protocol for mobiles, browsers and computers
101 |
102 | > Have ideas? We’re building it *with you* — hop into Discord or open a GitHub issue.
103 |
104 | ---
105 |
106 | ## ⭐ Like it?
107 |
108 | If this project made you say "whoa!", help us grow:
109 |
110 | - ⭐ [Star this repo](https://github.com/runablehq/mobile-use)
111 | - 🐦 Share on Twitter/X
112 | - 💬 [Invite friends to Discord](https://discord.gg/BcWWRCnap6)
113 |
114 | ---
115 |
116 | ## 📄 License
117 |
118 | MIT — free to use, fork, and build on.
119 |
120 | ---
121 |
122 | ## 🙌 Built with love for devs by devs
--------------------------------------------------------------------------------
/bin/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const { mobileUse } = require("../dist");
4 | const { readFile, access } = require("node:fs/promises");
5 | const yargs = require("yargs");
6 | const { hideBin } = require("yargs/helpers");
7 |
8 | const argv = yargs(hideBin(process.argv))
9 | .usage("Usage: $0 [options]")
10 | .demandCommand(1, "Please provide either a command string or a file path")
11 | .help().argv;
12 |
13 | async function run() {
14 | const input = argv._[0].toString();
15 | let task;
16 | try {
17 | await access(input);
18 | task = (await readFile(input, "utf-8")).trim();
19 | } catch {
20 | task = input;
21 | }
22 | const response = await mobileUse({
23 | task,
24 | });
25 | return response.text;
26 | }
27 |
28 | run()
29 | .catch((error) => console.error(error))
30 | .then((result) => console.log(result));
31 |
--------------------------------------------------------------------------------
/examples/Instagram_direct_message_openai.ts:
--------------------------------------------------------------------------------
1 | import { mobileUse } from "@/src";
2 | import { openai } from "@ai-sdk/openai";
3 |
4 | async function main() {
5 | process.env.OPENAI_API_KEY = "";
6 |
7 | const response = await mobileUse({
8 | task: "Open instagram and go to direct messages, send hi {instagram_username} to the first person",
9 | llm: openai("gpt-4o"),
10 | });
11 | console.log("OpenAI LLM response:", response.text);
12 | }
13 |
14 | main();
15 |
--------------------------------------------------------------------------------
/examples/download_app.txt:
--------------------------------------------------------------------------------
1 | 1. Go to playstore
2 | 2. Search for 'fampay'
3 | 3. Go to the app page
4 | 4. Install the app
5 | 5. Wait for it to install
--------------------------------------------------------------------------------
/examples/instagram_direct_message_anthropic.ts:
--------------------------------------------------------------------------------
1 | import { mobileUse } from "@/src";
2 |
3 | async function main() {
4 | // here we are using claude 3.5 sonnet
5 | const response = await mobileUse({
6 | task: "Open instagram and go to direct messages, send hi {instagram_username} to the first person",
7 | });
8 | console.log(response.text);
9 | }
10 |
11 | main();
12 |
--------------------------------------------------------------------------------
/examples/linkedIn_automation.txt:
--------------------------------------------------------------------------------
1 | 1. Open LinkedIn
2 | 2. search for Ankit Chowdhary, He is at south park commons
3 | 3. Open His profile
4 | 4. Send connection request if not already connected
5 | 5. See all his posts and like top 2 of them
--------------------------------------------------------------------------------
/examples/open_zepto_azure.ts:
--------------------------------------------------------------------------------
1 | import { mobileUse } from "@/src";
2 | import { azure } from '@ai-sdk/azure';
3 |
4 | async function main() {
5 | process.env.AZURE_RESOURCE_NAME = '';
6 | process.env.AZURE_API_KEY = '';
7 |
8 | const response = await mobileUse({
9 | task: "Open zepto",
10 | llm: azure("gpt-4o"),
11 | });
12 | console.log("Azure LLM response:", response.text);
13 | }
14 |
15 | main();
--------------------------------------------------------------------------------
/examples/porter_booking.txt:
--------------------------------------------------------------------------------
1 | 1. Open porter app
2 | 2. Book a 2 wheeler
3 | 3. Select pickup location as '20th a cross road, bangalore'
4 | 4. Select drop location as 'asha tiffins, bangalore'
5 | 5. Select other things as defult
6 | 6. Payment mode as 'cash'
7 | 7. After booking, confirm the sending a message on whatsapp to 'saksham boi'.
--------------------------------------------------------------------------------
/examples/youtube_search:
--------------------------------------------------------------------------------
1 | Open youtube app
2 | Search for cute cat video
3 | Click on first video
4 | Go to comment section of the video
5 | Write a comment after analyzing comment section
--------------------------------------------------------------------------------
/examples/zomato_order.txt:
--------------------------------------------------------------------------------
1 | 1. Open zomato app
2 | 2. Set default address to bangalore, house 951 (Home)
3 | 3. Go to delivery part of zomato
4 | 4. Search for masala chaas.
5 | 5. Order masala chaas and complete the payment using default payment option.
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mobile-use",
3 | "version": "0.0.7",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "mobile-use",
9 | "version": "0.0.7",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@ai-sdk/anthropic": "^1.1.17",
13 | "@ai-sdk/azure": "^1.2.7",
14 | "@ai-sdk/google": "^1.1.25",
15 | "@ai-sdk/openai": "^1.2.5",
16 | "@openrouter/ai-sdk-provider": "^0.4.3",
17 | "ai": "^4.1.61",
18 | "fast-xml-parser": "^5.0.9",
19 | "playwright": "^1.51.1",
20 | "sharp": "^0.33.5",
21 | "tsx": "^4.19.2",
22 | "typescript": "^5.7.3",
23 | "yargs": "^17.7.2",
24 | "zod": "^3.24.2"
25 | },
26 | "bin": {
27 | "mobile-use": "bin/run"
28 | },
29 | "devDependencies": {
30 | "@types/node": "^22.13.10",
31 | "tsup": "^8.4.0"
32 | }
33 | },
34 | "node_modules/@ai-sdk/anthropic": {
35 | "version": "1.1.17",
36 | "resolved": "https://registry.npmjs.org/@ai-sdk/anthropic/-/anthropic-1.1.17.tgz",
37 | "integrity": "sha512-t4ipxope34TFvWa4SrFsg2//aAFk3hUv2gxlM5W39IdsT7Hq2nMxJIcXE6C19YdhE/0Kep32iv38BgPaDZet6A==",
38 | "dependencies": {
39 | "@ai-sdk/provider": "1.0.11",
40 | "@ai-sdk/provider-utils": "2.1.13"
41 | },
42 | "engines": {
43 | "node": ">=18"
44 | },
45 | "peerDependencies": {
46 | "zod": "^3.0.0"
47 | }
48 | },
49 | "node_modules/@ai-sdk/azure": {
50 | "version": "1.2.7",
51 | "resolved": "https://registry.npmjs.org/@ai-sdk/azure/-/azure-1.2.7.tgz",
52 | "integrity": "sha512-TfNFkpPLC7vOzACYUONwLCVYrC+evYprNqapgAleOHIWESDabshYRw5IxRn+/xhNZG0A/JcpKGkqQFj6Ejcvxg==",
53 | "license": "Apache-2.0",
54 | "dependencies": {
55 | "@ai-sdk/openai": "1.2.7",
56 | "@ai-sdk/provider": "1.0.12",
57 | "@ai-sdk/provider-utils": "2.1.15"
58 | },
59 | "engines": {
60 | "node": ">=18"
61 | },
62 | "peerDependencies": {
63 | "zod": "^3.0.0"
64 | }
65 | },
66 | "node_modules/@ai-sdk/azure/node_modules/@ai-sdk/provider": {
67 | "version": "1.0.12",
68 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.12.tgz",
69 | "integrity": "sha512-88Uu1zJIE1UUOVJWfE2ybJXgiH8JJ97QY9fbmplErEbfa/k/1kF+tWMVAAJolF2aOGmazQGyQLhv4I9CCuVACw==",
70 | "license": "Apache-2.0",
71 | "dependencies": {
72 | "json-schema": "^0.4.0"
73 | },
74 | "engines": {
75 | "node": ">=18"
76 | }
77 | },
78 | "node_modules/@ai-sdk/azure/node_modules/@ai-sdk/provider-utils": {
79 | "version": "2.1.15",
80 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.15.tgz",
81 | "integrity": "sha512-ndMVtDm2xS86t45CJZSfyl7UblZFewRB8gZkXQHeNi7BhjCYkhE+XQMwfDl6UOAO7kaV60IC1R4JLDWxWiiHug==",
82 | "license": "Apache-2.0",
83 | "dependencies": {
84 | "@ai-sdk/provider": "1.0.12",
85 | "eventsource-parser": "^3.0.0",
86 | "nanoid": "^3.3.8",
87 | "secure-json-parse": "^2.7.0"
88 | },
89 | "engines": {
90 | "node": ">=18"
91 | },
92 | "peerDependencies": {
93 | "zod": "^3.0.0"
94 | },
95 | "peerDependenciesMeta": {
96 | "zod": {
97 | "optional": true
98 | }
99 | }
100 | },
101 | "node_modules/@ai-sdk/google": {
102 | "version": "1.1.25",
103 | "resolved": "https://registry.npmjs.org/@ai-sdk/google/-/google-1.1.25.tgz",
104 | "integrity": "sha512-4eIssVphgVmAAsrDqWbH+YH0LXgHpXXY7ye7yuxK+fobpDifZ7LLLEwsbjtg9mfjwSUJ4dSyI/L5mlZ1eQqu0A==",
105 | "dependencies": {
106 | "@ai-sdk/provider": "1.0.11",
107 | "@ai-sdk/provider-utils": "2.1.13"
108 | },
109 | "engines": {
110 | "node": ">=18"
111 | },
112 | "peerDependencies": {
113 | "zod": "^3.0.0"
114 | }
115 | },
116 | "node_modules/@ai-sdk/openai": {
117 | "version": "1.2.7",
118 | "resolved": "https://registry.npmjs.org/@ai-sdk/openai/-/openai-1.2.7.tgz",
119 | "integrity": "sha512-0yYAr7wFrRAoP4BnZ5g4kL6BpsLzDN4m4cmw8C273FZn3Sqz7LsJ3h2YJv2EVB12GZDsgzmsRlMkLeKZI5JCPw==",
120 | "license": "Apache-2.0",
121 | "dependencies": {
122 | "@ai-sdk/provider": "1.0.12",
123 | "@ai-sdk/provider-utils": "2.1.15"
124 | },
125 | "engines": {
126 | "node": ">=18"
127 | },
128 | "peerDependencies": {
129 | "zod": "^3.0.0"
130 | }
131 | },
132 | "node_modules/@ai-sdk/openai/node_modules/@ai-sdk/provider": {
133 | "version": "1.0.12",
134 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.12.tgz",
135 | "integrity": "sha512-88Uu1zJIE1UUOVJWfE2ybJXgiH8JJ97QY9fbmplErEbfa/k/1kF+tWMVAAJolF2aOGmazQGyQLhv4I9CCuVACw==",
136 | "license": "Apache-2.0",
137 | "dependencies": {
138 | "json-schema": "^0.4.0"
139 | },
140 | "engines": {
141 | "node": ">=18"
142 | }
143 | },
144 | "node_modules/@ai-sdk/openai/node_modules/@ai-sdk/provider-utils": {
145 | "version": "2.1.15",
146 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.15.tgz",
147 | "integrity": "sha512-ndMVtDm2xS86t45CJZSfyl7UblZFewRB8gZkXQHeNi7BhjCYkhE+XQMwfDl6UOAO7kaV60IC1R4JLDWxWiiHug==",
148 | "license": "Apache-2.0",
149 | "dependencies": {
150 | "@ai-sdk/provider": "1.0.12",
151 | "eventsource-parser": "^3.0.0",
152 | "nanoid": "^3.3.8",
153 | "secure-json-parse": "^2.7.0"
154 | },
155 | "engines": {
156 | "node": ">=18"
157 | },
158 | "peerDependencies": {
159 | "zod": "^3.0.0"
160 | },
161 | "peerDependenciesMeta": {
162 | "zod": {
163 | "optional": true
164 | }
165 | }
166 | },
167 | "node_modules/@ai-sdk/provider": {
168 | "version": "1.0.11",
169 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.11.tgz",
170 | "integrity": "sha512-CPyImHGiT3svyfmvPvAFTianZzWFtm0qK82XjwlQIA1C3IQ2iku/PMQXi7aFyrX0TyMh3VTkJPB03tjU2VXVrw==",
171 | "dependencies": {
172 | "json-schema": "^0.4.0"
173 | },
174 | "engines": {
175 | "node": ">=18"
176 | }
177 | },
178 | "node_modules/@ai-sdk/provider-utils": {
179 | "version": "2.1.13",
180 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.13.tgz",
181 | "integrity": "sha512-kLjqsfOdONr6DGcGEntFYM1niXz1H05vyZNf9OAzK+KKKc64izyP4/q/9HX7W4+6g8hm6BnmKxu8vkr6FSOqDg==",
182 | "dependencies": {
183 | "@ai-sdk/provider": "1.0.11",
184 | "eventsource-parser": "^3.0.0",
185 | "nanoid": "^3.3.8",
186 | "secure-json-parse": "^2.7.0"
187 | },
188 | "engines": {
189 | "node": ">=18"
190 | },
191 | "peerDependencies": {
192 | "zod": "^3.0.0"
193 | },
194 | "peerDependenciesMeta": {
195 | "zod": {
196 | "optional": true
197 | }
198 | }
199 | },
200 | "node_modules/@ai-sdk/react": {
201 | "version": "1.1.23",
202 | "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-1.1.23.tgz",
203 | "integrity": "sha512-R+PG9ya0GLs6orzt+1MxmjrWFuZM0gVs+l8ihBr1u+42wwkVeojY4CAtQjW4nrfGTVbdJYkl5y+r/VKfjr42aQ==",
204 | "dependencies": {
205 | "@ai-sdk/provider-utils": "2.1.13",
206 | "@ai-sdk/ui-utils": "1.1.19",
207 | "swr": "^2.2.5",
208 | "throttleit": "2.1.0"
209 | },
210 | "engines": {
211 | "node": ">=18"
212 | },
213 | "peerDependencies": {
214 | "react": "^18 || ^19 || ^19.0.0-rc",
215 | "zod": "^3.0.0"
216 | },
217 | "peerDependenciesMeta": {
218 | "react": {
219 | "optional": true
220 | },
221 | "zod": {
222 | "optional": true
223 | }
224 | }
225 | },
226 | "node_modules/@ai-sdk/ui-utils": {
227 | "version": "1.1.19",
228 | "resolved": "https://registry.npmjs.org/@ai-sdk/ui-utils/-/ui-utils-1.1.19.tgz",
229 | "integrity": "sha512-rDHy2uxlPMt3jjS9L6mBrsfhEInZ5BVoWevmD13fsAt2s/XWy2OwwKmgmUQkdLlY4mn/eyeYAfDGK8+5CbOAgg==",
230 | "dependencies": {
231 | "@ai-sdk/provider": "1.0.11",
232 | "@ai-sdk/provider-utils": "2.1.13",
233 | "zod-to-json-schema": "^3.24.1"
234 | },
235 | "engines": {
236 | "node": ">=18"
237 | },
238 | "peerDependencies": {
239 | "zod": "^3.0.0"
240 | },
241 | "peerDependenciesMeta": {
242 | "zod": {
243 | "optional": true
244 | }
245 | }
246 | },
247 | "node_modules/@emnapi/runtime": {
248 | "version": "1.4.0",
249 | "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz",
250 | "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==",
251 | "optional": true,
252 | "dependencies": {
253 | "tslib": "^2.4.0"
254 | }
255 | },
256 | "node_modules/@esbuild/aix-ppc64": {
257 | "version": "0.25.1",
258 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
259 | "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
260 | "cpu": [
261 | "ppc64"
262 | ],
263 | "optional": true,
264 | "os": [
265 | "aix"
266 | ],
267 | "engines": {
268 | "node": ">=18"
269 | }
270 | },
271 | "node_modules/@esbuild/android-arm": {
272 | "version": "0.25.1",
273 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
274 | "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
275 | "cpu": [
276 | "arm"
277 | ],
278 | "optional": true,
279 | "os": [
280 | "android"
281 | ],
282 | "engines": {
283 | "node": ">=18"
284 | }
285 | },
286 | "node_modules/@esbuild/android-arm64": {
287 | "version": "0.25.1",
288 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
289 | "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
290 | "cpu": [
291 | "arm64"
292 | ],
293 | "optional": true,
294 | "os": [
295 | "android"
296 | ],
297 | "engines": {
298 | "node": ">=18"
299 | }
300 | },
301 | "node_modules/@esbuild/android-x64": {
302 | "version": "0.25.1",
303 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
304 | "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
305 | "cpu": [
306 | "x64"
307 | ],
308 | "optional": true,
309 | "os": [
310 | "android"
311 | ],
312 | "engines": {
313 | "node": ">=18"
314 | }
315 | },
316 | "node_modules/@esbuild/darwin-arm64": {
317 | "version": "0.25.1",
318 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
319 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
320 | "cpu": [
321 | "arm64"
322 | ],
323 | "optional": true,
324 | "os": [
325 | "darwin"
326 | ],
327 | "engines": {
328 | "node": ">=18"
329 | }
330 | },
331 | "node_modules/@esbuild/darwin-x64": {
332 | "version": "0.25.1",
333 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
334 | "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
335 | "cpu": [
336 | "x64"
337 | ],
338 | "optional": true,
339 | "os": [
340 | "darwin"
341 | ],
342 | "engines": {
343 | "node": ">=18"
344 | }
345 | },
346 | "node_modules/@esbuild/freebsd-arm64": {
347 | "version": "0.25.1",
348 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
349 | "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
350 | "cpu": [
351 | "arm64"
352 | ],
353 | "optional": true,
354 | "os": [
355 | "freebsd"
356 | ],
357 | "engines": {
358 | "node": ">=18"
359 | }
360 | },
361 | "node_modules/@esbuild/freebsd-x64": {
362 | "version": "0.25.1",
363 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
364 | "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
365 | "cpu": [
366 | "x64"
367 | ],
368 | "optional": true,
369 | "os": [
370 | "freebsd"
371 | ],
372 | "engines": {
373 | "node": ">=18"
374 | }
375 | },
376 | "node_modules/@esbuild/linux-arm": {
377 | "version": "0.25.1",
378 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
379 | "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
380 | "cpu": [
381 | "arm"
382 | ],
383 | "optional": true,
384 | "os": [
385 | "linux"
386 | ],
387 | "engines": {
388 | "node": ">=18"
389 | }
390 | },
391 | "node_modules/@esbuild/linux-arm64": {
392 | "version": "0.25.1",
393 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
394 | "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
395 | "cpu": [
396 | "arm64"
397 | ],
398 | "optional": true,
399 | "os": [
400 | "linux"
401 | ],
402 | "engines": {
403 | "node": ">=18"
404 | }
405 | },
406 | "node_modules/@esbuild/linux-ia32": {
407 | "version": "0.25.1",
408 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
409 | "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
410 | "cpu": [
411 | "ia32"
412 | ],
413 | "optional": true,
414 | "os": [
415 | "linux"
416 | ],
417 | "engines": {
418 | "node": ">=18"
419 | }
420 | },
421 | "node_modules/@esbuild/linux-loong64": {
422 | "version": "0.25.1",
423 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
424 | "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
425 | "cpu": [
426 | "loong64"
427 | ],
428 | "optional": true,
429 | "os": [
430 | "linux"
431 | ],
432 | "engines": {
433 | "node": ">=18"
434 | }
435 | },
436 | "node_modules/@esbuild/linux-mips64el": {
437 | "version": "0.25.1",
438 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
439 | "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
440 | "cpu": [
441 | "mips64el"
442 | ],
443 | "optional": true,
444 | "os": [
445 | "linux"
446 | ],
447 | "engines": {
448 | "node": ">=18"
449 | }
450 | },
451 | "node_modules/@esbuild/linux-ppc64": {
452 | "version": "0.25.1",
453 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
454 | "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
455 | "cpu": [
456 | "ppc64"
457 | ],
458 | "optional": true,
459 | "os": [
460 | "linux"
461 | ],
462 | "engines": {
463 | "node": ">=18"
464 | }
465 | },
466 | "node_modules/@esbuild/linux-riscv64": {
467 | "version": "0.25.1",
468 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
469 | "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
470 | "cpu": [
471 | "riscv64"
472 | ],
473 | "optional": true,
474 | "os": [
475 | "linux"
476 | ],
477 | "engines": {
478 | "node": ">=18"
479 | }
480 | },
481 | "node_modules/@esbuild/linux-s390x": {
482 | "version": "0.25.1",
483 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
484 | "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
485 | "cpu": [
486 | "s390x"
487 | ],
488 | "optional": true,
489 | "os": [
490 | "linux"
491 | ],
492 | "engines": {
493 | "node": ">=18"
494 | }
495 | },
496 | "node_modules/@esbuild/linux-x64": {
497 | "version": "0.25.1",
498 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
499 | "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
500 | "cpu": [
501 | "x64"
502 | ],
503 | "optional": true,
504 | "os": [
505 | "linux"
506 | ],
507 | "engines": {
508 | "node": ">=18"
509 | }
510 | },
511 | "node_modules/@esbuild/netbsd-arm64": {
512 | "version": "0.25.1",
513 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
514 | "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
515 | "cpu": [
516 | "arm64"
517 | ],
518 | "optional": true,
519 | "os": [
520 | "netbsd"
521 | ],
522 | "engines": {
523 | "node": ">=18"
524 | }
525 | },
526 | "node_modules/@esbuild/netbsd-x64": {
527 | "version": "0.25.1",
528 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
529 | "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
530 | "cpu": [
531 | "x64"
532 | ],
533 | "optional": true,
534 | "os": [
535 | "netbsd"
536 | ],
537 | "engines": {
538 | "node": ">=18"
539 | }
540 | },
541 | "node_modules/@esbuild/openbsd-arm64": {
542 | "version": "0.25.1",
543 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
544 | "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
545 | "cpu": [
546 | "arm64"
547 | ],
548 | "optional": true,
549 | "os": [
550 | "openbsd"
551 | ],
552 | "engines": {
553 | "node": ">=18"
554 | }
555 | },
556 | "node_modules/@esbuild/openbsd-x64": {
557 | "version": "0.25.1",
558 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
559 | "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
560 | "cpu": [
561 | "x64"
562 | ],
563 | "optional": true,
564 | "os": [
565 | "openbsd"
566 | ],
567 | "engines": {
568 | "node": ">=18"
569 | }
570 | },
571 | "node_modules/@esbuild/sunos-x64": {
572 | "version": "0.25.1",
573 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
574 | "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
575 | "cpu": [
576 | "x64"
577 | ],
578 | "optional": true,
579 | "os": [
580 | "sunos"
581 | ],
582 | "engines": {
583 | "node": ">=18"
584 | }
585 | },
586 | "node_modules/@esbuild/win32-arm64": {
587 | "version": "0.25.1",
588 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
589 | "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
590 | "cpu": [
591 | "arm64"
592 | ],
593 | "optional": true,
594 | "os": [
595 | "win32"
596 | ],
597 | "engines": {
598 | "node": ">=18"
599 | }
600 | },
601 | "node_modules/@esbuild/win32-ia32": {
602 | "version": "0.25.1",
603 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
604 | "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
605 | "cpu": [
606 | "ia32"
607 | ],
608 | "optional": true,
609 | "os": [
610 | "win32"
611 | ],
612 | "engines": {
613 | "node": ">=18"
614 | }
615 | },
616 | "node_modules/@esbuild/win32-x64": {
617 | "version": "0.25.1",
618 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
619 | "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
620 | "cpu": [
621 | "x64"
622 | ],
623 | "optional": true,
624 | "os": [
625 | "win32"
626 | ],
627 | "engines": {
628 | "node": ">=18"
629 | }
630 | },
631 | "node_modules/@img/sharp-darwin-arm64": {
632 | "version": "0.33.5",
633 | "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
634 | "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
635 | "cpu": [
636 | "arm64"
637 | ],
638 | "optional": true,
639 | "os": [
640 | "darwin"
641 | ],
642 | "engines": {
643 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
644 | },
645 | "funding": {
646 | "url": "https://opencollective.com/libvips"
647 | },
648 | "optionalDependencies": {
649 | "@img/sharp-libvips-darwin-arm64": "1.0.4"
650 | }
651 | },
652 | "node_modules/@img/sharp-darwin-x64": {
653 | "version": "0.33.5",
654 | "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
655 | "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
656 | "cpu": [
657 | "x64"
658 | ],
659 | "optional": true,
660 | "os": [
661 | "darwin"
662 | ],
663 | "engines": {
664 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
665 | },
666 | "funding": {
667 | "url": "https://opencollective.com/libvips"
668 | },
669 | "optionalDependencies": {
670 | "@img/sharp-libvips-darwin-x64": "1.0.4"
671 | }
672 | },
673 | "node_modules/@img/sharp-libvips-darwin-arm64": {
674 | "version": "1.0.4",
675 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
676 | "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
677 | "cpu": [
678 | "arm64"
679 | ],
680 | "optional": true,
681 | "os": [
682 | "darwin"
683 | ],
684 | "funding": {
685 | "url": "https://opencollective.com/libvips"
686 | }
687 | },
688 | "node_modules/@img/sharp-libvips-darwin-x64": {
689 | "version": "1.0.4",
690 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
691 | "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
692 | "cpu": [
693 | "x64"
694 | ],
695 | "optional": true,
696 | "os": [
697 | "darwin"
698 | ],
699 | "funding": {
700 | "url": "https://opencollective.com/libvips"
701 | }
702 | },
703 | "node_modules/@img/sharp-libvips-linux-arm": {
704 | "version": "1.0.5",
705 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
706 | "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
707 | "cpu": [
708 | "arm"
709 | ],
710 | "optional": true,
711 | "os": [
712 | "linux"
713 | ],
714 | "funding": {
715 | "url": "https://opencollective.com/libvips"
716 | }
717 | },
718 | "node_modules/@img/sharp-libvips-linux-arm64": {
719 | "version": "1.0.4",
720 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
721 | "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
722 | "cpu": [
723 | "arm64"
724 | ],
725 | "optional": true,
726 | "os": [
727 | "linux"
728 | ],
729 | "funding": {
730 | "url": "https://opencollective.com/libvips"
731 | }
732 | },
733 | "node_modules/@img/sharp-libvips-linux-s390x": {
734 | "version": "1.0.4",
735 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
736 | "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
737 | "cpu": [
738 | "s390x"
739 | ],
740 | "optional": true,
741 | "os": [
742 | "linux"
743 | ],
744 | "funding": {
745 | "url": "https://opencollective.com/libvips"
746 | }
747 | },
748 | "node_modules/@img/sharp-libvips-linux-x64": {
749 | "version": "1.0.4",
750 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
751 | "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
752 | "cpu": [
753 | "x64"
754 | ],
755 | "optional": true,
756 | "os": [
757 | "linux"
758 | ],
759 | "funding": {
760 | "url": "https://opencollective.com/libvips"
761 | }
762 | },
763 | "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
764 | "version": "1.0.4",
765 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
766 | "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
767 | "cpu": [
768 | "arm64"
769 | ],
770 | "optional": true,
771 | "os": [
772 | "linux"
773 | ],
774 | "funding": {
775 | "url": "https://opencollective.com/libvips"
776 | }
777 | },
778 | "node_modules/@img/sharp-libvips-linuxmusl-x64": {
779 | "version": "1.0.4",
780 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
781 | "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
782 | "cpu": [
783 | "x64"
784 | ],
785 | "optional": true,
786 | "os": [
787 | "linux"
788 | ],
789 | "funding": {
790 | "url": "https://opencollective.com/libvips"
791 | }
792 | },
793 | "node_modules/@img/sharp-linux-arm": {
794 | "version": "0.33.5",
795 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
796 | "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
797 | "cpu": [
798 | "arm"
799 | ],
800 | "optional": true,
801 | "os": [
802 | "linux"
803 | ],
804 | "engines": {
805 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
806 | },
807 | "funding": {
808 | "url": "https://opencollective.com/libvips"
809 | },
810 | "optionalDependencies": {
811 | "@img/sharp-libvips-linux-arm": "1.0.5"
812 | }
813 | },
814 | "node_modules/@img/sharp-linux-arm64": {
815 | "version": "0.33.5",
816 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
817 | "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
818 | "cpu": [
819 | "arm64"
820 | ],
821 | "optional": true,
822 | "os": [
823 | "linux"
824 | ],
825 | "engines": {
826 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
827 | },
828 | "funding": {
829 | "url": "https://opencollective.com/libvips"
830 | },
831 | "optionalDependencies": {
832 | "@img/sharp-libvips-linux-arm64": "1.0.4"
833 | }
834 | },
835 | "node_modules/@img/sharp-linux-s390x": {
836 | "version": "0.33.5",
837 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
838 | "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
839 | "cpu": [
840 | "s390x"
841 | ],
842 | "optional": true,
843 | "os": [
844 | "linux"
845 | ],
846 | "engines": {
847 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
848 | },
849 | "funding": {
850 | "url": "https://opencollective.com/libvips"
851 | },
852 | "optionalDependencies": {
853 | "@img/sharp-libvips-linux-s390x": "1.0.4"
854 | }
855 | },
856 | "node_modules/@img/sharp-linux-x64": {
857 | "version": "0.33.5",
858 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
859 | "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
860 | "cpu": [
861 | "x64"
862 | ],
863 | "optional": true,
864 | "os": [
865 | "linux"
866 | ],
867 | "engines": {
868 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
869 | },
870 | "funding": {
871 | "url": "https://opencollective.com/libvips"
872 | },
873 | "optionalDependencies": {
874 | "@img/sharp-libvips-linux-x64": "1.0.4"
875 | }
876 | },
877 | "node_modules/@img/sharp-linuxmusl-arm64": {
878 | "version": "0.33.5",
879 | "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
880 | "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
881 | "cpu": [
882 | "arm64"
883 | ],
884 | "optional": true,
885 | "os": [
886 | "linux"
887 | ],
888 | "engines": {
889 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
890 | },
891 | "funding": {
892 | "url": "https://opencollective.com/libvips"
893 | },
894 | "optionalDependencies": {
895 | "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
896 | }
897 | },
898 | "node_modules/@img/sharp-linuxmusl-x64": {
899 | "version": "0.33.5",
900 | "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
901 | "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
902 | "cpu": [
903 | "x64"
904 | ],
905 | "optional": true,
906 | "os": [
907 | "linux"
908 | ],
909 | "engines": {
910 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
911 | },
912 | "funding": {
913 | "url": "https://opencollective.com/libvips"
914 | },
915 | "optionalDependencies": {
916 | "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
917 | }
918 | },
919 | "node_modules/@img/sharp-wasm32": {
920 | "version": "0.33.5",
921 | "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
922 | "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
923 | "cpu": [
924 | "wasm32"
925 | ],
926 | "optional": true,
927 | "dependencies": {
928 | "@emnapi/runtime": "^1.2.0"
929 | },
930 | "engines": {
931 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
932 | },
933 | "funding": {
934 | "url": "https://opencollective.com/libvips"
935 | }
936 | },
937 | "node_modules/@img/sharp-win32-ia32": {
938 | "version": "0.33.5",
939 | "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
940 | "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
941 | "cpu": [
942 | "ia32"
943 | ],
944 | "optional": true,
945 | "os": [
946 | "win32"
947 | ],
948 | "engines": {
949 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
950 | },
951 | "funding": {
952 | "url": "https://opencollective.com/libvips"
953 | }
954 | },
955 | "node_modules/@img/sharp-win32-x64": {
956 | "version": "0.33.5",
957 | "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
958 | "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
959 | "cpu": [
960 | "x64"
961 | ],
962 | "optional": true,
963 | "os": [
964 | "win32"
965 | ],
966 | "engines": {
967 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
968 | },
969 | "funding": {
970 | "url": "https://opencollective.com/libvips"
971 | }
972 | },
973 | "node_modules/@isaacs/cliui": {
974 | "version": "8.0.2",
975 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
976 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
977 | "dev": true,
978 | "dependencies": {
979 | "string-width": "^5.1.2",
980 | "string-width-cjs": "npm:string-width@^4.2.0",
981 | "strip-ansi": "^7.0.1",
982 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
983 | "wrap-ansi": "^8.1.0",
984 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
985 | },
986 | "engines": {
987 | "node": ">=12"
988 | }
989 | },
990 | "node_modules/@jridgewell/gen-mapping": {
991 | "version": "0.3.8",
992 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
993 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
994 | "dev": true,
995 | "dependencies": {
996 | "@jridgewell/set-array": "^1.2.1",
997 | "@jridgewell/sourcemap-codec": "^1.4.10",
998 | "@jridgewell/trace-mapping": "^0.3.24"
999 | },
1000 | "engines": {
1001 | "node": ">=6.0.0"
1002 | }
1003 | },
1004 | "node_modules/@jridgewell/resolve-uri": {
1005 | "version": "3.1.2",
1006 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
1007 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
1008 | "dev": true,
1009 | "engines": {
1010 | "node": ">=6.0.0"
1011 | }
1012 | },
1013 | "node_modules/@jridgewell/set-array": {
1014 | "version": "1.2.1",
1015 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
1016 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
1017 | "dev": true,
1018 | "engines": {
1019 | "node": ">=6.0.0"
1020 | }
1021 | },
1022 | "node_modules/@jridgewell/sourcemap-codec": {
1023 | "version": "1.5.0",
1024 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
1025 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
1026 | "dev": true
1027 | },
1028 | "node_modules/@jridgewell/trace-mapping": {
1029 | "version": "0.3.25",
1030 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
1031 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
1032 | "dev": true,
1033 | "dependencies": {
1034 | "@jridgewell/resolve-uri": "^3.1.0",
1035 | "@jridgewell/sourcemap-codec": "^1.4.14"
1036 | }
1037 | },
1038 | "node_modules/@openrouter/ai-sdk-provider": {
1039 | "version": "0.4.3",
1040 | "resolved": "https://registry.npmjs.org/@openrouter/ai-sdk-provider/-/ai-sdk-provider-0.4.3.tgz",
1041 | "integrity": "sha512-/MAUj5XFKs6IRZ3WwD8qFyUC6I+yhQ4TsemxvwDk+mbXNiVuJvP5Qc+yJ4fKTfIP4vRiV1sApA/t/La5MgA2FQ==",
1042 | "dependencies": {
1043 | "@ai-sdk/provider": "1.0.9",
1044 | "@ai-sdk/provider-utils": "2.1.10"
1045 | },
1046 | "engines": {
1047 | "node": ">=18"
1048 | },
1049 | "peerDependencies": {
1050 | "zod": "^3.0.0"
1051 | }
1052 | },
1053 | "node_modules/@openrouter/ai-sdk-provider/node_modules/@ai-sdk/provider": {
1054 | "version": "1.0.9",
1055 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.9.tgz",
1056 | "integrity": "sha512-jie6ZJT2ZR0uVOVCDc9R2xCX5I/Dum/wEK28lx21PJx6ZnFAN9EzD2WsPhcDWfCgGx3OAZZ0GyM3CEobXpa9LA==",
1057 | "dependencies": {
1058 | "json-schema": "^0.4.0"
1059 | },
1060 | "engines": {
1061 | "node": ">=18"
1062 | }
1063 | },
1064 | "node_modules/@openrouter/ai-sdk-provider/node_modules/@ai-sdk/provider-utils": {
1065 | "version": "2.1.10",
1066 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.10.tgz",
1067 | "integrity": "sha512-4GZ8GHjOFxePFzkl3q42AU0DQOtTQ5w09vmaWUf/pKFXJPizlnzKSUkF0f+VkapIUfDugyMqPMT1ge8XQzVI7Q==",
1068 | "dependencies": {
1069 | "@ai-sdk/provider": "1.0.9",
1070 | "eventsource-parser": "^3.0.0",
1071 | "nanoid": "^3.3.8",
1072 | "secure-json-parse": "^2.7.0"
1073 | },
1074 | "engines": {
1075 | "node": ">=18"
1076 | },
1077 | "peerDependencies": {
1078 | "zod": "^3.0.0"
1079 | },
1080 | "peerDependenciesMeta": {
1081 | "zod": {
1082 | "optional": true
1083 | }
1084 | }
1085 | },
1086 | "node_modules/@opentelemetry/api": {
1087 | "version": "1.9.0",
1088 | "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
1089 | "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
1090 | "engines": {
1091 | "node": ">=8.0.0"
1092 | }
1093 | },
1094 | "node_modules/@pkgjs/parseargs": {
1095 | "version": "0.11.0",
1096 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
1097 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
1098 | "dev": true,
1099 | "optional": true,
1100 | "engines": {
1101 | "node": ">=14"
1102 | }
1103 | },
1104 | "node_modules/@rollup/rollup-android-arm-eabi": {
1105 | "version": "4.35.0",
1106 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz",
1107 | "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==",
1108 | "cpu": [
1109 | "arm"
1110 | ],
1111 | "dev": true,
1112 | "optional": true,
1113 | "os": [
1114 | "android"
1115 | ]
1116 | },
1117 | "node_modules/@rollup/rollup-android-arm64": {
1118 | "version": "4.35.0",
1119 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz",
1120 | "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==",
1121 | "cpu": [
1122 | "arm64"
1123 | ],
1124 | "dev": true,
1125 | "optional": true,
1126 | "os": [
1127 | "android"
1128 | ]
1129 | },
1130 | "node_modules/@rollup/rollup-darwin-arm64": {
1131 | "version": "4.35.0",
1132 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz",
1133 | "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==",
1134 | "cpu": [
1135 | "arm64"
1136 | ],
1137 | "dev": true,
1138 | "optional": true,
1139 | "os": [
1140 | "darwin"
1141 | ]
1142 | },
1143 | "node_modules/@rollup/rollup-darwin-x64": {
1144 | "version": "4.35.0",
1145 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz",
1146 | "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==",
1147 | "cpu": [
1148 | "x64"
1149 | ],
1150 | "dev": true,
1151 | "optional": true,
1152 | "os": [
1153 | "darwin"
1154 | ]
1155 | },
1156 | "node_modules/@rollup/rollup-freebsd-arm64": {
1157 | "version": "4.35.0",
1158 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz",
1159 | "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==",
1160 | "cpu": [
1161 | "arm64"
1162 | ],
1163 | "dev": true,
1164 | "optional": true,
1165 | "os": [
1166 | "freebsd"
1167 | ]
1168 | },
1169 | "node_modules/@rollup/rollup-freebsd-x64": {
1170 | "version": "4.35.0",
1171 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz",
1172 | "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==",
1173 | "cpu": [
1174 | "x64"
1175 | ],
1176 | "dev": true,
1177 | "optional": true,
1178 | "os": [
1179 | "freebsd"
1180 | ]
1181 | },
1182 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1183 | "version": "4.35.0",
1184 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz",
1185 | "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==",
1186 | "cpu": [
1187 | "arm"
1188 | ],
1189 | "dev": true,
1190 | "optional": true,
1191 | "os": [
1192 | "linux"
1193 | ]
1194 | },
1195 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
1196 | "version": "4.35.0",
1197 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz",
1198 | "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==",
1199 | "cpu": [
1200 | "arm"
1201 | ],
1202 | "dev": true,
1203 | "optional": true,
1204 | "os": [
1205 | "linux"
1206 | ]
1207 | },
1208 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
1209 | "version": "4.35.0",
1210 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz",
1211 | "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==",
1212 | "cpu": [
1213 | "arm64"
1214 | ],
1215 | "dev": true,
1216 | "optional": true,
1217 | "os": [
1218 | "linux"
1219 | ]
1220 | },
1221 | "node_modules/@rollup/rollup-linux-arm64-musl": {
1222 | "version": "4.35.0",
1223 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz",
1224 | "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==",
1225 | "cpu": [
1226 | "arm64"
1227 | ],
1228 | "dev": true,
1229 | "optional": true,
1230 | "os": [
1231 | "linux"
1232 | ]
1233 | },
1234 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
1235 | "version": "4.35.0",
1236 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz",
1237 | "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==",
1238 | "cpu": [
1239 | "loong64"
1240 | ],
1241 | "dev": true,
1242 | "optional": true,
1243 | "os": [
1244 | "linux"
1245 | ]
1246 | },
1247 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
1248 | "version": "4.35.0",
1249 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz",
1250 | "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==",
1251 | "cpu": [
1252 | "ppc64"
1253 | ],
1254 | "dev": true,
1255 | "optional": true,
1256 | "os": [
1257 | "linux"
1258 | ]
1259 | },
1260 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1261 | "version": "4.35.0",
1262 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz",
1263 | "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==",
1264 | "cpu": [
1265 | "riscv64"
1266 | ],
1267 | "dev": true,
1268 | "optional": true,
1269 | "os": [
1270 | "linux"
1271 | ]
1272 | },
1273 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
1274 | "version": "4.35.0",
1275 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz",
1276 | "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==",
1277 | "cpu": [
1278 | "s390x"
1279 | ],
1280 | "dev": true,
1281 | "optional": true,
1282 | "os": [
1283 | "linux"
1284 | ]
1285 | },
1286 | "node_modules/@rollup/rollup-linux-x64-gnu": {
1287 | "version": "4.35.0",
1288 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz",
1289 | "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==",
1290 | "cpu": [
1291 | "x64"
1292 | ],
1293 | "dev": true,
1294 | "optional": true,
1295 | "os": [
1296 | "linux"
1297 | ]
1298 | },
1299 | "node_modules/@rollup/rollup-linux-x64-musl": {
1300 | "version": "4.35.0",
1301 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz",
1302 | "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==",
1303 | "cpu": [
1304 | "x64"
1305 | ],
1306 | "dev": true,
1307 | "optional": true,
1308 | "os": [
1309 | "linux"
1310 | ]
1311 | },
1312 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
1313 | "version": "4.35.0",
1314 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz",
1315 | "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==",
1316 | "cpu": [
1317 | "arm64"
1318 | ],
1319 | "dev": true,
1320 | "optional": true,
1321 | "os": [
1322 | "win32"
1323 | ]
1324 | },
1325 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
1326 | "version": "4.35.0",
1327 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz",
1328 | "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==",
1329 | "cpu": [
1330 | "ia32"
1331 | ],
1332 | "dev": true,
1333 | "optional": true,
1334 | "os": [
1335 | "win32"
1336 | ]
1337 | },
1338 | "node_modules/@rollup/rollup-win32-x64-msvc": {
1339 | "version": "4.35.0",
1340 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz",
1341 | "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==",
1342 | "cpu": [
1343 | "x64"
1344 | ],
1345 | "dev": true,
1346 | "optional": true,
1347 | "os": [
1348 | "win32"
1349 | ]
1350 | },
1351 | "node_modules/@types/diff-match-patch": {
1352 | "version": "1.0.36",
1353 | "resolved": "https://registry.npmjs.org/@types/diff-match-patch/-/diff-match-patch-1.0.36.tgz",
1354 | "integrity": "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg=="
1355 | },
1356 | "node_modules/@types/estree": {
1357 | "version": "1.0.6",
1358 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
1359 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
1360 | "dev": true
1361 | },
1362 | "node_modules/@types/node": {
1363 | "version": "22.13.10",
1364 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
1365 | "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
1366 | "dev": true,
1367 | "dependencies": {
1368 | "undici-types": "~6.20.0"
1369 | }
1370 | },
1371 | "node_modules/ai": {
1372 | "version": "4.1.61",
1373 | "resolved": "https://registry.npmjs.org/ai/-/ai-4.1.61.tgz",
1374 | "integrity": "sha512-Y9SAyGJEeW23F6C7PSHZXYNEvbH2cqJm0rVW2AoeFaXFT13ttx8rAqs8wz2w466C1UB329yl5PXayFcHqofSEA==",
1375 | "dependencies": {
1376 | "@ai-sdk/provider": "1.0.11",
1377 | "@ai-sdk/provider-utils": "2.1.13",
1378 | "@ai-sdk/react": "1.1.23",
1379 | "@ai-sdk/ui-utils": "1.1.19",
1380 | "@opentelemetry/api": "1.9.0",
1381 | "eventsource-parser": "^3.0.0",
1382 | "jsondiffpatch": "0.6.0"
1383 | },
1384 | "engines": {
1385 | "node": ">=18"
1386 | },
1387 | "peerDependencies": {
1388 | "react": "^18 || ^19 || ^19.0.0-rc",
1389 | "zod": "^3.0.0"
1390 | },
1391 | "peerDependenciesMeta": {
1392 | "react": {
1393 | "optional": true
1394 | },
1395 | "zod": {
1396 | "optional": true
1397 | }
1398 | }
1399 | },
1400 | "node_modules/ansi-regex": {
1401 | "version": "6.1.0",
1402 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
1403 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
1404 | "dev": true,
1405 | "engines": {
1406 | "node": ">=12"
1407 | },
1408 | "funding": {
1409 | "url": "https://github.com/chalk/ansi-regex?sponsor=1"
1410 | }
1411 | },
1412 | "node_modules/ansi-styles": {
1413 | "version": "6.2.1",
1414 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
1415 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
1416 | "dev": true,
1417 | "engines": {
1418 | "node": ">=12"
1419 | },
1420 | "funding": {
1421 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1422 | }
1423 | },
1424 | "node_modules/any-promise": {
1425 | "version": "1.3.0",
1426 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
1427 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
1428 | "dev": true
1429 | },
1430 | "node_modules/balanced-match": {
1431 | "version": "1.0.2",
1432 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1433 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1434 | "dev": true
1435 | },
1436 | "node_modules/brace-expansion": {
1437 | "version": "2.0.1",
1438 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
1439 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
1440 | "dev": true,
1441 | "dependencies": {
1442 | "balanced-match": "^1.0.0"
1443 | }
1444 | },
1445 | "node_modules/bundle-require": {
1446 | "version": "5.1.0",
1447 | "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz",
1448 | "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==",
1449 | "dev": true,
1450 | "dependencies": {
1451 | "load-tsconfig": "^0.2.3"
1452 | },
1453 | "engines": {
1454 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1455 | },
1456 | "peerDependencies": {
1457 | "esbuild": ">=0.18"
1458 | }
1459 | },
1460 | "node_modules/cac": {
1461 | "version": "6.7.14",
1462 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1463 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1464 | "dev": true,
1465 | "engines": {
1466 | "node": ">=8"
1467 | }
1468 | },
1469 | "node_modules/chalk": {
1470 | "version": "5.4.1",
1471 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
1472 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
1473 | "engines": {
1474 | "node": "^12.17.0 || ^14.13 || >=16.0.0"
1475 | },
1476 | "funding": {
1477 | "url": "https://github.com/chalk/chalk?sponsor=1"
1478 | }
1479 | },
1480 | "node_modules/chokidar": {
1481 | "version": "4.0.3",
1482 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
1483 | "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
1484 | "dev": true,
1485 | "dependencies": {
1486 | "readdirp": "^4.0.1"
1487 | },
1488 | "engines": {
1489 | "node": ">= 14.16.0"
1490 | },
1491 | "funding": {
1492 | "url": "https://paulmillr.com/funding/"
1493 | }
1494 | },
1495 | "node_modules/cliui": {
1496 | "version": "8.0.1",
1497 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
1498 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
1499 | "dependencies": {
1500 | "string-width": "^4.2.0",
1501 | "strip-ansi": "^6.0.1",
1502 | "wrap-ansi": "^7.0.0"
1503 | },
1504 | "engines": {
1505 | "node": ">=12"
1506 | }
1507 | },
1508 | "node_modules/cliui/node_modules/ansi-regex": {
1509 | "version": "5.0.1",
1510 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1511 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1512 | "engines": {
1513 | "node": ">=8"
1514 | }
1515 | },
1516 | "node_modules/cliui/node_modules/ansi-styles": {
1517 | "version": "4.3.0",
1518 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1519 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1520 | "dependencies": {
1521 | "color-convert": "^2.0.1"
1522 | },
1523 | "engines": {
1524 | "node": ">=8"
1525 | },
1526 | "funding": {
1527 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1528 | }
1529 | },
1530 | "node_modules/cliui/node_modules/emoji-regex": {
1531 | "version": "8.0.0",
1532 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1533 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
1534 | },
1535 | "node_modules/cliui/node_modules/string-width": {
1536 | "version": "4.2.3",
1537 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1538 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1539 | "dependencies": {
1540 | "emoji-regex": "^8.0.0",
1541 | "is-fullwidth-code-point": "^3.0.0",
1542 | "strip-ansi": "^6.0.1"
1543 | },
1544 | "engines": {
1545 | "node": ">=8"
1546 | }
1547 | },
1548 | "node_modules/cliui/node_modules/strip-ansi": {
1549 | "version": "6.0.1",
1550 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1551 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1552 | "dependencies": {
1553 | "ansi-regex": "^5.0.1"
1554 | },
1555 | "engines": {
1556 | "node": ">=8"
1557 | }
1558 | },
1559 | "node_modules/cliui/node_modules/wrap-ansi": {
1560 | "version": "7.0.0",
1561 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1562 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1563 | "dependencies": {
1564 | "ansi-styles": "^4.0.0",
1565 | "string-width": "^4.1.0",
1566 | "strip-ansi": "^6.0.0"
1567 | },
1568 | "engines": {
1569 | "node": ">=10"
1570 | },
1571 | "funding": {
1572 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1573 | }
1574 | },
1575 | "node_modules/color": {
1576 | "version": "4.2.3",
1577 | "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
1578 | "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
1579 | "dependencies": {
1580 | "color-convert": "^2.0.1",
1581 | "color-string": "^1.9.0"
1582 | },
1583 | "engines": {
1584 | "node": ">=12.5.0"
1585 | }
1586 | },
1587 | "node_modules/color-convert": {
1588 | "version": "2.0.1",
1589 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1590 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1591 | "dependencies": {
1592 | "color-name": "~1.1.4"
1593 | },
1594 | "engines": {
1595 | "node": ">=7.0.0"
1596 | }
1597 | },
1598 | "node_modules/color-name": {
1599 | "version": "1.1.4",
1600 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1601 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
1602 | },
1603 | "node_modules/color-string": {
1604 | "version": "1.9.1",
1605 | "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
1606 | "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
1607 | "dependencies": {
1608 | "color-name": "^1.0.0",
1609 | "simple-swizzle": "^0.2.2"
1610 | }
1611 | },
1612 | "node_modules/consola": {
1613 | "version": "3.4.0",
1614 | "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz",
1615 | "integrity": "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==",
1616 | "dev": true,
1617 | "engines": {
1618 | "node": "^14.18.0 || >=16.10.0"
1619 | }
1620 | },
1621 | "node_modules/cross-spawn": {
1622 | "version": "7.0.6",
1623 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1624 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1625 | "dev": true,
1626 | "dependencies": {
1627 | "path-key": "^3.1.0",
1628 | "shebang-command": "^2.0.0",
1629 | "which": "^2.0.1"
1630 | },
1631 | "engines": {
1632 | "node": ">= 8"
1633 | }
1634 | },
1635 | "node_modules/dequal": {
1636 | "version": "2.0.3",
1637 | "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
1638 | "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
1639 | "engines": {
1640 | "node": ">=6"
1641 | }
1642 | },
1643 | "node_modules/detect-libc": {
1644 | "version": "2.0.3",
1645 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
1646 | "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
1647 | "engines": {
1648 | "node": ">=8"
1649 | }
1650 | },
1651 | "node_modules/diff-match-patch": {
1652 | "version": "1.0.5",
1653 | "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
1654 | "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
1655 | },
1656 | "node_modules/eastasianwidth": {
1657 | "version": "0.2.0",
1658 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
1659 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
1660 | "dev": true
1661 | },
1662 | "node_modules/emoji-regex": {
1663 | "version": "9.2.2",
1664 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
1665 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
1666 | "dev": true
1667 | },
1668 | "node_modules/esbuild": {
1669 | "version": "0.25.1",
1670 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
1671 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
1672 | "hasInstallScript": true,
1673 | "bin": {
1674 | "esbuild": "bin/esbuild"
1675 | },
1676 | "engines": {
1677 | "node": ">=18"
1678 | },
1679 | "optionalDependencies": {
1680 | "@esbuild/aix-ppc64": "0.25.1",
1681 | "@esbuild/android-arm": "0.25.1",
1682 | "@esbuild/android-arm64": "0.25.1",
1683 | "@esbuild/android-x64": "0.25.1",
1684 | "@esbuild/darwin-arm64": "0.25.1",
1685 | "@esbuild/darwin-x64": "0.25.1",
1686 | "@esbuild/freebsd-arm64": "0.25.1",
1687 | "@esbuild/freebsd-x64": "0.25.1",
1688 | "@esbuild/linux-arm": "0.25.1",
1689 | "@esbuild/linux-arm64": "0.25.1",
1690 | "@esbuild/linux-ia32": "0.25.1",
1691 | "@esbuild/linux-loong64": "0.25.1",
1692 | "@esbuild/linux-mips64el": "0.25.1",
1693 | "@esbuild/linux-ppc64": "0.25.1",
1694 | "@esbuild/linux-riscv64": "0.25.1",
1695 | "@esbuild/linux-s390x": "0.25.1",
1696 | "@esbuild/linux-x64": "0.25.1",
1697 | "@esbuild/netbsd-arm64": "0.25.1",
1698 | "@esbuild/netbsd-x64": "0.25.1",
1699 | "@esbuild/openbsd-arm64": "0.25.1",
1700 | "@esbuild/openbsd-x64": "0.25.1",
1701 | "@esbuild/sunos-x64": "0.25.1",
1702 | "@esbuild/win32-arm64": "0.25.1",
1703 | "@esbuild/win32-ia32": "0.25.1",
1704 | "@esbuild/win32-x64": "0.25.1"
1705 | }
1706 | },
1707 | "node_modules/escalade": {
1708 | "version": "3.2.0",
1709 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1710 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1711 | "engines": {
1712 | "node": ">=6"
1713 | }
1714 | },
1715 | "node_modules/eventsource-parser": {
1716 | "version": "3.0.0",
1717 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz",
1718 | "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==",
1719 | "engines": {
1720 | "node": ">=18.0.0"
1721 | }
1722 | },
1723 | "node_modules/fast-xml-parser": {
1724 | "version": "5.0.9",
1725 | "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz",
1726 | "integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==",
1727 | "funding": [
1728 | {
1729 | "type": "github",
1730 | "url": "https://github.com/sponsors/NaturalIntelligence"
1731 | }
1732 | ],
1733 | "dependencies": {
1734 | "strnum": "^2.0.5"
1735 | },
1736 | "bin": {
1737 | "fxparser": "src/cli/cli.js"
1738 | }
1739 | },
1740 | "node_modules/fdir": {
1741 | "version": "6.4.3",
1742 | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
1743 | "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
1744 | "dev": true,
1745 | "peerDependencies": {
1746 | "picomatch": "^3 || ^4"
1747 | },
1748 | "peerDependenciesMeta": {
1749 | "picomatch": {
1750 | "optional": true
1751 | }
1752 | }
1753 | },
1754 | "node_modules/foreground-child": {
1755 | "version": "3.3.1",
1756 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
1757 | "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
1758 | "dev": true,
1759 | "dependencies": {
1760 | "cross-spawn": "^7.0.6",
1761 | "signal-exit": "^4.0.1"
1762 | },
1763 | "engines": {
1764 | "node": ">=14"
1765 | },
1766 | "funding": {
1767 | "url": "https://github.com/sponsors/isaacs"
1768 | }
1769 | },
1770 | "node_modules/fsevents": {
1771 | "version": "2.3.2",
1772 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1773 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1774 | "hasInstallScript": true,
1775 | "optional": true,
1776 | "os": [
1777 | "darwin"
1778 | ],
1779 | "engines": {
1780 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1781 | }
1782 | },
1783 | "node_modules/get-caller-file": {
1784 | "version": "2.0.5",
1785 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
1786 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
1787 | "engines": {
1788 | "node": "6.* || 8.* || >= 10.*"
1789 | }
1790 | },
1791 | "node_modules/get-tsconfig": {
1792 | "version": "4.10.0",
1793 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
1794 | "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
1795 | "dependencies": {
1796 | "resolve-pkg-maps": "^1.0.0"
1797 | },
1798 | "funding": {
1799 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
1800 | }
1801 | },
1802 | "node_modules/glob": {
1803 | "version": "10.4.5",
1804 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
1805 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
1806 | "dev": true,
1807 | "dependencies": {
1808 | "foreground-child": "^3.1.0",
1809 | "jackspeak": "^3.1.2",
1810 | "minimatch": "^9.0.4",
1811 | "minipass": "^7.1.2",
1812 | "package-json-from-dist": "^1.0.0",
1813 | "path-scurry": "^1.11.1"
1814 | },
1815 | "bin": {
1816 | "glob": "dist/esm/bin.mjs"
1817 | },
1818 | "funding": {
1819 | "url": "https://github.com/sponsors/isaacs"
1820 | }
1821 | },
1822 | "node_modules/is-arrayish": {
1823 | "version": "0.3.2",
1824 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
1825 | "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
1826 | },
1827 | "node_modules/is-fullwidth-code-point": {
1828 | "version": "3.0.0",
1829 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1830 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1831 | "engines": {
1832 | "node": ">=8"
1833 | }
1834 | },
1835 | "node_modules/isexe": {
1836 | "version": "2.0.0",
1837 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1838 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1839 | "dev": true
1840 | },
1841 | "node_modules/jackspeak": {
1842 | "version": "3.4.3",
1843 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
1844 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
1845 | "dev": true,
1846 | "dependencies": {
1847 | "@isaacs/cliui": "^8.0.2"
1848 | },
1849 | "funding": {
1850 | "url": "https://github.com/sponsors/isaacs"
1851 | },
1852 | "optionalDependencies": {
1853 | "@pkgjs/parseargs": "^0.11.0"
1854 | }
1855 | },
1856 | "node_modules/joycon": {
1857 | "version": "3.1.1",
1858 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
1859 | "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
1860 | "dev": true,
1861 | "engines": {
1862 | "node": ">=10"
1863 | }
1864 | },
1865 | "node_modules/json-schema": {
1866 | "version": "0.4.0",
1867 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
1868 | "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
1869 | },
1870 | "node_modules/jsondiffpatch": {
1871 | "version": "0.6.0",
1872 | "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.6.0.tgz",
1873 | "integrity": "sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==",
1874 | "dependencies": {
1875 | "@types/diff-match-patch": "^1.0.36",
1876 | "chalk": "^5.3.0",
1877 | "diff-match-patch": "^1.0.5"
1878 | },
1879 | "bin": {
1880 | "jsondiffpatch": "bin/jsondiffpatch.js"
1881 | },
1882 | "engines": {
1883 | "node": "^18.0.0 || >=20.0.0"
1884 | }
1885 | },
1886 | "node_modules/lilconfig": {
1887 | "version": "3.1.3",
1888 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
1889 | "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
1890 | "dev": true,
1891 | "engines": {
1892 | "node": ">=14"
1893 | },
1894 | "funding": {
1895 | "url": "https://github.com/sponsors/antonk52"
1896 | }
1897 | },
1898 | "node_modules/lines-and-columns": {
1899 | "version": "1.2.4",
1900 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1901 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1902 | "dev": true
1903 | },
1904 | "node_modules/load-tsconfig": {
1905 | "version": "0.2.5",
1906 | "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
1907 | "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
1908 | "dev": true,
1909 | "engines": {
1910 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1911 | }
1912 | },
1913 | "node_modules/lodash.sortby": {
1914 | "version": "4.7.0",
1915 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
1916 | "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
1917 | "dev": true
1918 | },
1919 | "node_modules/lru-cache": {
1920 | "version": "10.4.3",
1921 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1922 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1923 | "dev": true
1924 | },
1925 | "node_modules/minimatch": {
1926 | "version": "9.0.5",
1927 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
1928 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
1929 | "dev": true,
1930 | "dependencies": {
1931 | "brace-expansion": "^2.0.1"
1932 | },
1933 | "engines": {
1934 | "node": ">=16 || 14 >=14.17"
1935 | },
1936 | "funding": {
1937 | "url": "https://github.com/sponsors/isaacs"
1938 | }
1939 | },
1940 | "node_modules/minipass": {
1941 | "version": "7.1.2",
1942 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1943 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
1944 | "dev": true,
1945 | "engines": {
1946 | "node": ">=16 || 14 >=14.17"
1947 | }
1948 | },
1949 | "node_modules/ms": {
1950 | "version": "2.1.3",
1951 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1952 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1953 | "dev": true
1954 | },
1955 | "node_modules/mz": {
1956 | "version": "2.7.0",
1957 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
1958 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
1959 | "dev": true,
1960 | "dependencies": {
1961 | "any-promise": "^1.0.0",
1962 | "object-assign": "^4.0.1",
1963 | "thenify-all": "^1.0.0"
1964 | }
1965 | },
1966 | "node_modules/nanoid": {
1967 | "version": "3.3.9",
1968 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz",
1969 | "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==",
1970 | "funding": [
1971 | {
1972 | "type": "github",
1973 | "url": "https://github.com/sponsors/ai"
1974 | }
1975 | ],
1976 | "bin": {
1977 | "nanoid": "bin/nanoid.cjs"
1978 | },
1979 | "engines": {
1980 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1981 | }
1982 | },
1983 | "node_modules/object-assign": {
1984 | "version": "4.1.1",
1985 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1986 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
1987 | "dev": true,
1988 | "engines": {
1989 | "node": ">=0.10.0"
1990 | }
1991 | },
1992 | "node_modules/package-json-from-dist": {
1993 | "version": "1.0.1",
1994 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
1995 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
1996 | "dev": true
1997 | },
1998 | "node_modules/path-key": {
1999 | "version": "3.1.1",
2000 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2001 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2002 | "dev": true,
2003 | "engines": {
2004 | "node": ">=8"
2005 | }
2006 | },
2007 | "node_modules/path-scurry": {
2008 | "version": "1.11.1",
2009 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
2010 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
2011 | "dev": true,
2012 | "dependencies": {
2013 | "lru-cache": "^10.2.0",
2014 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
2015 | },
2016 | "engines": {
2017 | "node": ">=16 || 14 >=14.18"
2018 | },
2019 | "funding": {
2020 | "url": "https://github.com/sponsors/isaacs"
2021 | }
2022 | },
2023 | "node_modules/picocolors": {
2024 | "version": "1.1.1",
2025 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
2026 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
2027 | "dev": true
2028 | },
2029 | "node_modules/picomatch": {
2030 | "version": "4.0.2",
2031 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
2032 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
2033 | "dev": true,
2034 | "engines": {
2035 | "node": ">=12"
2036 | },
2037 | "funding": {
2038 | "url": "https://github.com/sponsors/jonschlinkert"
2039 | }
2040 | },
2041 | "node_modules/pirates": {
2042 | "version": "4.0.6",
2043 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
2044 | "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
2045 | "dev": true,
2046 | "engines": {
2047 | "node": ">= 6"
2048 | }
2049 | },
2050 | "node_modules/playwright": {
2051 | "version": "1.51.1",
2052 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz",
2053 | "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==",
2054 | "dependencies": {
2055 | "playwright-core": "1.51.1"
2056 | },
2057 | "bin": {
2058 | "playwright": "cli.js"
2059 | },
2060 | "engines": {
2061 | "node": ">=18"
2062 | },
2063 | "optionalDependencies": {
2064 | "fsevents": "2.3.2"
2065 | }
2066 | },
2067 | "node_modules/playwright-core": {
2068 | "version": "1.51.1",
2069 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz",
2070 | "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==",
2071 | "bin": {
2072 | "playwright-core": "cli.js"
2073 | },
2074 | "engines": {
2075 | "node": ">=18"
2076 | }
2077 | },
2078 | "node_modules/postcss-load-config": {
2079 | "version": "6.0.1",
2080 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
2081 | "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
2082 | "dev": true,
2083 | "funding": [
2084 | {
2085 | "type": "opencollective",
2086 | "url": "https://opencollective.com/postcss/"
2087 | },
2088 | {
2089 | "type": "github",
2090 | "url": "https://github.com/sponsors/ai"
2091 | }
2092 | ],
2093 | "dependencies": {
2094 | "lilconfig": "^3.1.1"
2095 | },
2096 | "engines": {
2097 | "node": ">= 18"
2098 | },
2099 | "peerDependencies": {
2100 | "jiti": ">=1.21.0",
2101 | "postcss": ">=8.0.9",
2102 | "tsx": "^4.8.1",
2103 | "yaml": "^2.4.2"
2104 | },
2105 | "peerDependenciesMeta": {
2106 | "jiti": {
2107 | "optional": true
2108 | },
2109 | "postcss": {
2110 | "optional": true
2111 | },
2112 | "tsx": {
2113 | "optional": true
2114 | },
2115 | "yaml": {
2116 | "optional": true
2117 | }
2118 | }
2119 | },
2120 | "node_modules/punycode": {
2121 | "version": "2.3.1",
2122 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
2123 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
2124 | "dev": true,
2125 | "engines": {
2126 | "node": ">=6"
2127 | }
2128 | },
2129 | "node_modules/react": {
2130 | "version": "19.0.0",
2131 | "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
2132 | "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
2133 | "peer": true,
2134 | "engines": {
2135 | "node": ">=0.10.0"
2136 | }
2137 | },
2138 | "node_modules/readdirp": {
2139 | "version": "4.1.2",
2140 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
2141 | "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
2142 | "dev": true,
2143 | "engines": {
2144 | "node": ">= 14.18.0"
2145 | },
2146 | "funding": {
2147 | "type": "individual",
2148 | "url": "https://paulmillr.com/funding/"
2149 | }
2150 | },
2151 | "node_modules/require-directory": {
2152 | "version": "2.1.1",
2153 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2154 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
2155 | "engines": {
2156 | "node": ">=0.10.0"
2157 | }
2158 | },
2159 | "node_modules/resolve-from": {
2160 | "version": "5.0.0",
2161 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
2162 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
2163 | "dev": true,
2164 | "engines": {
2165 | "node": ">=8"
2166 | }
2167 | },
2168 | "node_modules/resolve-pkg-maps": {
2169 | "version": "1.0.0",
2170 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
2171 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
2172 | "funding": {
2173 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
2174 | }
2175 | },
2176 | "node_modules/rollup": {
2177 | "version": "4.35.0",
2178 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz",
2179 | "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==",
2180 | "dev": true,
2181 | "dependencies": {
2182 | "@types/estree": "1.0.6"
2183 | },
2184 | "bin": {
2185 | "rollup": "dist/bin/rollup"
2186 | },
2187 | "engines": {
2188 | "node": ">=18.0.0",
2189 | "npm": ">=8.0.0"
2190 | },
2191 | "optionalDependencies": {
2192 | "@rollup/rollup-android-arm-eabi": "4.35.0",
2193 | "@rollup/rollup-android-arm64": "4.35.0",
2194 | "@rollup/rollup-darwin-arm64": "4.35.0",
2195 | "@rollup/rollup-darwin-x64": "4.35.0",
2196 | "@rollup/rollup-freebsd-arm64": "4.35.0",
2197 | "@rollup/rollup-freebsd-x64": "4.35.0",
2198 | "@rollup/rollup-linux-arm-gnueabihf": "4.35.0",
2199 | "@rollup/rollup-linux-arm-musleabihf": "4.35.0",
2200 | "@rollup/rollup-linux-arm64-gnu": "4.35.0",
2201 | "@rollup/rollup-linux-arm64-musl": "4.35.0",
2202 | "@rollup/rollup-linux-loongarch64-gnu": "4.35.0",
2203 | "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0",
2204 | "@rollup/rollup-linux-riscv64-gnu": "4.35.0",
2205 | "@rollup/rollup-linux-s390x-gnu": "4.35.0",
2206 | "@rollup/rollup-linux-x64-gnu": "4.35.0",
2207 | "@rollup/rollup-linux-x64-musl": "4.35.0",
2208 | "@rollup/rollup-win32-arm64-msvc": "4.35.0",
2209 | "@rollup/rollup-win32-ia32-msvc": "4.35.0",
2210 | "@rollup/rollup-win32-x64-msvc": "4.35.0",
2211 | "fsevents": "~2.3.2"
2212 | }
2213 | },
2214 | "node_modules/secure-json-parse": {
2215 | "version": "2.7.0",
2216 | "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
2217 | "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="
2218 | },
2219 | "node_modules/semver": {
2220 | "version": "7.7.1",
2221 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
2222 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
2223 | "bin": {
2224 | "semver": "bin/semver.js"
2225 | },
2226 | "engines": {
2227 | "node": ">=10"
2228 | }
2229 | },
2230 | "node_modules/sharp": {
2231 | "version": "0.33.5",
2232 | "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
2233 | "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
2234 | "hasInstallScript": true,
2235 | "dependencies": {
2236 | "color": "^4.2.3",
2237 | "detect-libc": "^2.0.3",
2238 | "semver": "^7.6.3"
2239 | },
2240 | "engines": {
2241 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
2242 | },
2243 | "funding": {
2244 | "url": "https://opencollective.com/libvips"
2245 | },
2246 | "optionalDependencies": {
2247 | "@img/sharp-darwin-arm64": "0.33.5",
2248 | "@img/sharp-darwin-x64": "0.33.5",
2249 | "@img/sharp-libvips-darwin-arm64": "1.0.4",
2250 | "@img/sharp-libvips-darwin-x64": "1.0.4",
2251 | "@img/sharp-libvips-linux-arm": "1.0.5",
2252 | "@img/sharp-libvips-linux-arm64": "1.0.4",
2253 | "@img/sharp-libvips-linux-s390x": "1.0.4",
2254 | "@img/sharp-libvips-linux-x64": "1.0.4",
2255 | "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
2256 | "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
2257 | "@img/sharp-linux-arm": "0.33.5",
2258 | "@img/sharp-linux-arm64": "0.33.5",
2259 | "@img/sharp-linux-s390x": "0.33.5",
2260 | "@img/sharp-linux-x64": "0.33.5",
2261 | "@img/sharp-linuxmusl-arm64": "0.33.5",
2262 | "@img/sharp-linuxmusl-x64": "0.33.5",
2263 | "@img/sharp-wasm32": "0.33.5",
2264 | "@img/sharp-win32-ia32": "0.33.5",
2265 | "@img/sharp-win32-x64": "0.33.5"
2266 | }
2267 | },
2268 | "node_modules/shebang-command": {
2269 | "version": "2.0.0",
2270 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2271 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2272 | "dev": true,
2273 | "dependencies": {
2274 | "shebang-regex": "^3.0.0"
2275 | },
2276 | "engines": {
2277 | "node": ">=8"
2278 | }
2279 | },
2280 | "node_modules/shebang-regex": {
2281 | "version": "3.0.0",
2282 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2283 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2284 | "dev": true,
2285 | "engines": {
2286 | "node": ">=8"
2287 | }
2288 | },
2289 | "node_modules/signal-exit": {
2290 | "version": "4.1.0",
2291 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
2292 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
2293 | "dev": true,
2294 | "engines": {
2295 | "node": ">=14"
2296 | },
2297 | "funding": {
2298 | "url": "https://github.com/sponsors/isaacs"
2299 | }
2300 | },
2301 | "node_modules/simple-swizzle": {
2302 | "version": "0.2.2",
2303 | "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
2304 | "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
2305 | "dependencies": {
2306 | "is-arrayish": "^0.3.1"
2307 | }
2308 | },
2309 | "node_modules/source-map": {
2310 | "version": "0.8.0-beta.0",
2311 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
2312 | "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
2313 | "dev": true,
2314 | "dependencies": {
2315 | "whatwg-url": "^7.0.0"
2316 | },
2317 | "engines": {
2318 | "node": ">= 8"
2319 | }
2320 | },
2321 | "node_modules/string-width": {
2322 | "version": "5.1.2",
2323 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
2324 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
2325 | "dev": true,
2326 | "dependencies": {
2327 | "eastasianwidth": "^0.2.0",
2328 | "emoji-regex": "^9.2.2",
2329 | "strip-ansi": "^7.0.1"
2330 | },
2331 | "engines": {
2332 | "node": ">=12"
2333 | },
2334 | "funding": {
2335 | "url": "https://github.com/sponsors/sindresorhus"
2336 | }
2337 | },
2338 | "node_modules/string-width-cjs": {
2339 | "name": "string-width",
2340 | "version": "4.2.3",
2341 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2342 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2343 | "dev": true,
2344 | "dependencies": {
2345 | "emoji-regex": "^8.0.0",
2346 | "is-fullwidth-code-point": "^3.0.0",
2347 | "strip-ansi": "^6.0.1"
2348 | },
2349 | "engines": {
2350 | "node": ">=8"
2351 | }
2352 | },
2353 | "node_modules/string-width-cjs/node_modules/ansi-regex": {
2354 | "version": "5.0.1",
2355 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2356 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2357 | "dev": true,
2358 | "engines": {
2359 | "node": ">=8"
2360 | }
2361 | },
2362 | "node_modules/string-width-cjs/node_modules/emoji-regex": {
2363 | "version": "8.0.0",
2364 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2365 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2366 | "dev": true
2367 | },
2368 | "node_modules/string-width-cjs/node_modules/strip-ansi": {
2369 | "version": "6.0.1",
2370 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2371 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2372 | "dev": true,
2373 | "dependencies": {
2374 | "ansi-regex": "^5.0.1"
2375 | },
2376 | "engines": {
2377 | "node": ">=8"
2378 | }
2379 | },
2380 | "node_modules/strip-ansi": {
2381 | "version": "7.1.0",
2382 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
2383 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
2384 | "dev": true,
2385 | "dependencies": {
2386 | "ansi-regex": "^6.0.1"
2387 | },
2388 | "engines": {
2389 | "node": ">=12"
2390 | },
2391 | "funding": {
2392 | "url": "https://github.com/chalk/strip-ansi?sponsor=1"
2393 | }
2394 | },
2395 | "node_modules/strip-ansi-cjs": {
2396 | "name": "strip-ansi",
2397 | "version": "6.0.1",
2398 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2399 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2400 | "dev": true,
2401 | "dependencies": {
2402 | "ansi-regex": "^5.0.1"
2403 | },
2404 | "engines": {
2405 | "node": ">=8"
2406 | }
2407 | },
2408 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
2409 | "version": "5.0.1",
2410 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2411 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2412 | "dev": true,
2413 | "engines": {
2414 | "node": ">=8"
2415 | }
2416 | },
2417 | "node_modules/strnum": {
2418 | "version": "2.0.5",
2419 | "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz",
2420 | "integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q==",
2421 | "funding": [
2422 | {
2423 | "type": "github",
2424 | "url": "https://github.com/sponsors/NaturalIntelligence"
2425 | }
2426 | ]
2427 | },
2428 | "node_modules/sucrase": {
2429 | "version": "3.35.0",
2430 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
2431 | "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
2432 | "dev": true,
2433 | "dependencies": {
2434 | "@jridgewell/gen-mapping": "^0.3.2",
2435 | "commander": "^4.0.0",
2436 | "glob": "^10.3.10",
2437 | "lines-and-columns": "^1.1.6",
2438 | "mz": "^2.7.0",
2439 | "pirates": "^4.0.1",
2440 | "ts-interface-checker": "^0.1.9"
2441 | },
2442 | "bin": {
2443 | "sucrase": "bin/sucrase",
2444 | "sucrase-node": "bin/sucrase-node"
2445 | },
2446 | "engines": {
2447 | "node": ">=16 || 14 >=14.17"
2448 | }
2449 | },
2450 | "node_modules/sucrase/node_modules/commander": {
2451 | "version": "4.1.1",
2452 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
2453 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
2454 | "dev": true,
2455 | "engines": {
2456 | "node": ">= 6"
2457 | }
2458 | },
2459 | "node_modules/swr": {
2460 | "version": "2.3.3",
2461 | "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.3.tgz",
2462 | "integrity": "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==",
2463 | "dependencies": {
2464 | "dequal": "^2.0.3",
2465 | "use-sync-external-store": "^1.4.0"
2466 | },
2467 | "peerDependencies": {
2468 | "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2469 | }
2470 | },
2471 | "node_modules/thenify": {
2472 | "version": "3.3.1",
2473 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
2474 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
2475 | "dev": true,
2476 | "dependencies": {
2477 | "any-promise": "^1.0.0"
2478 | }
2479 | },
2480 | "node_modules/thenify-all": {
2481 | "version": "1.6.0",
2482 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
2483 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
2484 | "dev": true,
2485 | "dependencies": {
2486 | "thenify": ">= 3.1.0 < 4"
2487 | },
2488 | "engines": {
2489 | "node": ">=0.8"
2490 | }
2491 | },
2492 | "node_modules/throttleit": {
2493 | "version": "2.1.0",
2494 | "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz",
2495 | "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==",
2496 | "engines": {
2497 | "node": ">=18"
2498 | },
2499 | "funding": {
2500 | "url": "https://github.com/sponsors/sindresorhus"
2501 | }
2502 | },
2503 | "node_modules/tinyexec": {
2504 | "version": "0.3.2",
2505 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
2506 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
2507 | "dev": true
2508 | },
2509 | "node_modules/tinyglobby": {
2510 | "version": "0.2.12",
2511 | "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz",
2512 | "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==",
2513 | "dev": true,
2514 | "dependencies": {
2515 | "fdir": "^6.4.3",
2516 | "picomatch": "^4.0.2"
2517 | },
2518 | "engines": {
2519 | "node": ">=12.0.0"
2520 | },
2521 | "funding": {
2522 | "url": "https://github.com/sponsors/SuperchupuDev"
2523 | }
2524 | },
2525 | "node_modules/tr46": {
2526 | "version": "1.0.1",
2527 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
2528 | "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
2529 | "dev": true,
2530 | "dependencies": {
2531 | "punycode": "^2.1.0"
2532 | }
2533 | },
2534 | "node_modules/tree-kill": {
2535 | "version": "1.2.2",
2536 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
2537 | "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
2538 | "dev": true,
2539 | "bin": {
2540 | "tree-kill": "cli.js"
2541 | }
2542 | },
2543 | "node_modules/ts-interface-checker": {
2544 | "version": "0.1.13",
2545 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
2546 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
2547 | "dev": true
2548 | },
2549 | "node_modules/tslib": {
2550 | "version": "2.8.1",
2551 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
2552 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
2553 | "optional": true
2554 | },
2555 | "node_modules/tsup": {
2556 | "version": "8.4.0",
2557 | "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.4.0.tgz",
2558 | "integrity": "sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==",
2559 | "dev": true,
2560 | "dependencies": {
2561 | "bundle-require": "^5.1.0",
2562 | "cac": "^6.7.14",
2563 | "chokidar": "^4.0.3",
2564 | "consola": "^3.4.0",
2565 | "debug": "^4.4.0",
2566 | "esbuild": "^0.25.0",
2567 | "joycon": "^3.1.1",
2568 | "picocolors": "^1.1.1",
2569 | "postcss-load-config": "^6.0.1",
2570 | "resolve-from": "^5.0.0",
2571 | "rollup": "^4.34.8",
2572 | "source-map": "0.8.0-beta.0",
2573 | "sucrase": "^3.35.0",
2574 | "tinyexec": "^0.3.2",
2575 | "tinyglobby": "^0.2.11",
2576 | "tree-kill": "^1.2.2"
2577 | },
2578 | "bin": {
2579 | "tsup": "dist/cli-default.js",
2580 | "tsup-node": "dist/cli-node.js"
2581 | },
2582 | "engines": {
2583 | "node": ">=18"
2584 | },
2585 | "peerDependencies": {
2586 | "@microsoft/api-extractor": "^7.36.0",
2587 | "@swc/core": "^1",
2588 | "postcss": "^8.4.12",
2589 | "typescript": ">=4.5.0"
2590 | },
2591 | "peerDependenciesMeta": {
2592 | "@microsoft/api-extractor": {
2593 | "optional": true
2594 | },
2595 | "@swc/core": {
2596 | "optional": true
2597 | },
2598 | "postcss": {
2599 | "optional": true
2600 | },
2601 | "typescript": {
2602 | "optional": true
2603 | }
2604 | }
2605 | },
2606 | "node_modules/tsup/node_modules/debug": {
2607 | "version": "4.4.0",
2608 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
2609 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
2610 | "dev": true,
2611 | "dependencies": {
2612 | "ms": "^2.1.3"
2613 | },
2614 | "engines": {
2615 | "node": ">=6.0"
2616 | },
2617 | "peerDependenciesMeta": {
2618 | "supports-color": {
2619 | "optional": true
2620 | }
2621 | }
2622 | },
2623 | "node_modules/tsx": {
2624 | "version": "4.19.3",
2625 | "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz",
2626 | "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==",
2627 | "dependencies": {
2628 | "esbuild": "~0.25.0",
2629 | "get-tsconfig": "^4.7.5"
2630 | },
2631 | "bin": {
2632 | "tsx": "dist/cli.mjs"
2633 | },
2634 | "engines": {
2635 | "node": ">=18.0.0"
2636 | },
2637 | "optionalDependencies": {
2638 | "fsevents": "~2.3.3"
2639 | }
2640 | },
2641 | "node_modules/tsx/node_modules/fsevents": {
2642 | "version": "2.3.3",
2643 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
2644 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
2645 | "hasInstallScript": true,
2646 | "optional": true,
2647 | "os": [
2648 | "darwin"
2649 | ],
2650 | "engines": {
2651 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2652 | }
2653 | },
2654 | "node_modules/typescript": {
2655 | "version": "5.8.2",
2656 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
2657 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
2658 | "bin": {
2659 | "tsc": "bin/tsc",
2660 | "tsserver": "bin/tsserver"
2661 | },
2662 | "engines": {
2663 | "node": ">=14.17"
2664 | }
2665 | },
2666 | "node_modules/undici-types": {
2667 | "version": "6.20.0",
2668 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
2669 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
2670 | "dev": true
2671 | },
2672 | "node_modules/use-sync-external-store": {
2673 | "version": "1.4.0",
2674 | "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
2675 | "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
2676 | "peerDependencies": {
2677 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2678 | }
2679 | },
2680 | "node_modules/webidl-conversions": {
2681 | "version": "4.0.2",
2682 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
2683 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
2684 | "dev": true
2685 | },
2686 | "node_modules/whatwg-url": {
2687 | "version": "7.1.0",
2688 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
2689 | "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
2690 | "dev": true,
2691 | "dependencies": {
2692 | "lodash.sortby": "^4.7.0",
2693 | "tr46": "^1.0.1",
2694 | "webidl-conversions": "^4.0.2"
2695 | }
2696 | },
2697 | "node_modules/which": {
2698 | "version": "2.0.2",
2699 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2700 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2701 | "dev": true,
2702 | "dependencies": {
2703 | "isexe": "^2.0.0"
2704 | },
2705 | "bin": {
2706 | "node-which": "bin/node-which"
2707 | },
2708 | "engines": {
2709 | "node": ">= 8"
2710 | }
2711 | },
2712 | "node_modules/wrap-ansi": {
2713 | "version": "8.1.0",
2714 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
2715 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
2716 | "dev": true,
2717 | "dependencies": {
2718 | "ansi-styles": "^6.1.0",
2719 | "string-width": "^5.0.1",
2720 | "strip-ansi": "^7.0.1"
2721 | },
2722 | "engines": {
2723 | "node": ">=12"
2724 | },
2725 | "funding": {
2726 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2727 | }
2728 | },
2729 | "node_modules/wrap-ansi-cjs": {
2730 | "name": "wrap-ansi",
2731 | "version": "7.0.0",
2732 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2733 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2734 | "dev": true,
2735 | "dependencies": {
2736 | "ansi-styles": "^4.0.0",
2737 | "string-width": "^4.1.0",
2738 | "strip-ansi": "^6.0.0"
2739 | },
2740 | "engines": {
2741 | "node": ">=10"
2742 | },
2743 | "funding": {
2744 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2745 | }
2746 | },
2747 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2748 | "version": "5.0.1",
2749 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2750 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2751 | "dev": true,
2752 | "engines": {
2753 | "node": ">=8"
2754 | }
2755 | },
2756 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2757 | "version": "4.3.0",
2758 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2759 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2760 | "dev": true,
2761 | "dependencies": {
2762 | "color-convert": "^2.0.1"
2763 | },
2764 | "engines": {
2765 | "node": ">=8"
2766 | },
2767 | "funding": {
2768 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2769 | }
2770 | },
2771 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
2772 | "version": "8.0.0",
2773 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2774 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
2775 | "dev": true
2776 | },
2777 | "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2778 | "version": "4.2.3",
2779 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2780 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2781 | "dev": true,
2782 | "dependencies": {
2783 | "emoji-regex": "^8.0.0",
2784 | "is-fullwidth-code-point": "^3.0.0",
2785 | "strip-ansi": "^6.0.1"
2786 | },
2787 | "engines": {
2788 | "node": ">=8"
2789 | }
2790 | },
2791 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2792 | "version": "6.0.1",
2793 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2794 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2795 | "dev": true,
2796 | "dependencies": {
2797 | "ansi-regex": "^5.0.1"
2798 | },
2799 | "engines": {
2800 | "node": ">=8"
2801 | }
2802 | },
2803 | "node_modules/y18n": {
2804 | "version": "5.0.8",
2805 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
2806 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
2807 | "engines": {
2808 | "node": ">=10"
2809 | }
2810 | },
2811 | "node_modules/yargs": {
2812 | "version": "17.7.2",
2813 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
2814 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
2815 | "dependencies": {
2816 | "cliui": "^8.0.1",
2817 | "escalade": "^3.1.1",
2818 | "get-caller-file": "^2.0.5",
2819 | "require-directory": "^2.1.1",
2820 | "string-width": "^4.2.3",
2821 | "y18n": "^5.0.5",
2822 | "yargs-parser": "^21.1.1"
2823 | },
2824 | "engines": {
2825 | "node": ">=12"
2826 | }
2827 | },
2828 | "node_modules/yargs-parser": {
2829 | "version": "21.1.1",
2830 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
2831 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
2832 | "engines": {
2833 | "node": ">=12"
2834 | }
2835 | },
2836 | "node_modules/yargs/node_modules/ansi-regex": {
2837 | "version": "5.0.1",
2838 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2839 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2840 | "engines": {
2841 | "node": ">=8"
2842 | }
2843 | },
2844 | "node_modules/yargs/node_modules/emoji-regex": {
2845 | "version": "8.0.0",
2846 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
2847 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
2848 | },
2849 | "node_modules/yargs/node_modules/string-width": {
2850 | "version": "4.2.3",
2851 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2852 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2853 | "dependencies": {
2854 | "emoji-regex": "^8.0.0",
2855 | "is-fullwidth-code-point": "^3.0.0",
2856 | "strip-ansi": "^6.0.1"
2857 | },
2858 | "engines": {
2859 | "node": ">=8"
2860 | }
2861 | },
2862 | "node_modules/yargs/node_modules/strip-ansi": {
2863 | "version": "6.0.1",
2864 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2865 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2866 | "dependencies": {
2867 | "ansi-regex": "^5.0.1"
2868 | },
2869 | "engines": {
2870 | "node": ">=8"
2871 | }
2872 | },
2873 | "node_modules/zod": {
2874 | "version": "3.24.2",
2875 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
2876 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
2877 | "funding": {
2878 | "url": "https://github.com/sponsors/colinhacks"
2879 | }
2880 | },
2881 | "node_modules/zod-to-json-schema": {
2882 | "version": "3.24.3",
2883 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz",
2884 | "integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==",
2885 | "peerDependencies": {
2886 | "zod": "^3.24.1"
2887 | }
2888 | }
2889 | }
2890 | }
2891 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mobile-use",
3 | "version": "0.0.7",
4 | "main": "dist/index.js",
5 | "types": "dist/index.d.ts",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "tsup src/index.ts --dts"
9 | },
10 | "bin": {
11 | "mobile-use": "./bin/run"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "https://github.com/runablehq/mobile-use.git"
16 | },
17 | "license": "MIT",
18 | "description": "Use AI to control your mobile",
19 | "dependencies": {
20 | "@ai-sdk/anthropic": "^1.1.17",
21 | "@ai-sdk/azure": "^1.2.7",
22 | "@ai-sdk/google": "^1.1.25",
23 | "@ai-sdk/openai": "^1.2.5",
24 | "@openrouter/ai-sdk-provider": "^0.4.3",
25 | "ai": "^4.1.61",
26 | "fast-xml-parser": "^5.0.9",
27 | "playwright": "^1.51.1",
28 | "sharp": "^0.33.5",
29 | "tsx": "^4.19.2",
30 | "typescript": "^5.7.3",
31 | "yargs": "^17.7.2",
32 | "zod": "^3.24.2"
33 | },
34 | "devDependencies": {
35 | "@types/node": "^22.13.10",
36 | "tsup": "^8.4.0"
37 | },
38 | "files": [
39 | "bin",
40 | "dist",
41 | "src"
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/scripts/export_ui_dump.ts:
--------------------------------------------------------------------------------
1 | import { ADBClient } from "../src/adb_client";
2 |
3 | async function main() {
4 | const adb = new ADBClient();
5 | const ui = await adb.dumpUI();
6 | console.log(ui);
7 | }
8 |
9 | main();
10 |
--------------------------------------------------------------------------------
/scripts/take_screenshot.ts:
--------------------------------------------------------------------------------
1 | import { writeFile } from "node:fs/promises";
2 | import { ADBClient } from "../src/adb_client";
3 |
4 | async function main() {
5 | const adb = new ADBClient();
6 | const screenshot = await adb.screenshot();
7 | console.log(await adb.screenSize());
8 | await writeFile("mobile.png", screenshot);
9 | }
10 |
11 | main();
12 |
--------------------------------------------------------------------------------
/src/adb_client.ts:
--------------------------------------------------------------------------------
1 | import { exec } from "child_process";
2 | import { promisify } from "util";
3 | import { parseUiDump } from "./ui_dump_parser";
4 | import { homedir } from "os";
5 | import { join } from "path";
6 | import { existsSync } from "fs";
7 | import sharp from "sharp";
8 |
9 | const execAsync = promisify(exec);
10 |
11 | const ANDROID_KEY_EVENTS: Record = Object.entries({
12 | Enter: "KEYCODE_ENTER",
13 | Backspace: "KEYCODE_DEL",
14 | Tab: "KEYCODE_TAB",
15 | ArrowUp: "KEYCODE_DPAD_UP",
16 | ArrowDown: "KEYCODE_DPAD_DOWN",
17 | ArrowLeft: "KEYCODE_DPAD_LEFT",
18 | ArrowRight: "KEYCODE_DPAD_RIGHT",
19 | Escape: "KEYCODE_ESCAPE",
20 | Home: "KEYCODE_HOME",
21 | Back: "KEYCODE_BACK",
22 | }).reduce((keyMap, [key, value]) => {
23 | keyMap[key.toLowerCase().trim()] = value;
24 | return keyMap;
25 | }, {} as Record);
26 |
27 | interface Coordinate {
28 | x: number;
29 | y: number;
30 | }
31 |
32 | export function getPotentialADBPaths(): string[] {
33 | const home = homedir();
34 | const platform = process.platform;
35 | const paths: string[] = [];
36 |
37 | if (platform === "win32") {
38 | // Windows-specific paths
39 | paths.push(
40 | join(
41 | process.env.LOCALAPPDATA ?? "",
42 | "Android/Sdk/platform-tools/adb.exe"
43 | ),
44 | "C:\\Android\\sdk\\platform-tools\\adb.exe",
45 | join(home, "AppData/Local/Android/Sdk/platform-tools/adb.exe"),
46 | join(home, "AppData/Local/Android/android-sdk/platform-tools/adb.exe"),
47 | "C:\\Program Files\\Android\\android-sdk\\platform-tools\\adb.exe",
48 | "C:\\Program Files (x86)\\Android\\android-sdk\\platform-tools\\adb.exe"
49 | );
50 | } else if (platform === "darwin") {
51 | // macOS-specific paths
52 | paths.push(
53 | "/usr/local/bin/adb",
54 | "/opt/homebrew/bin/adb",
55 | join(home, "Library/Android/sdk/platform-tools/adb"),
56 | "/Applications/Android Studio.app/Contents/sdk/platform-tools/adb"
57 | );
58 | } else if (platform === "linux") {
59 | // Linux-specific paths
60 | paths.push(
61 | "/usr/local/bin/adb",
62 | "/usr/bin/adb",
63 | join(home, "Android/Sdk/platform-tools/adb"),
64 | "/opt/android-sdk/platform-tools/adb",
65 | "/opt/android-studio/sdk/platform-tools/adb"
66 | );
67 | } else {
68 | // Other platforms (FreeBSD, OpenBSD, etc.)
69 | paths.push(
70 | "/usr/local/bin/adb",
71 | "/usr/bin/adb",
72 | join(home, "android-sdk/platform-tools/adb")
73 | );
74 | }
75 |
76 | // Add ANDROID_HOME path for all platforms
77 | if (process.env.ANDROID_HOME) {
78 | const adbExecutable = platform === "win32" ? "adb.exe" : "adb";
79 | paths.push(join(process.env.ANDROID_HOME, "platform-tools", adbExecutable));
80 | }
81 |
82 | return paths;
83 | }
84 |
85 | export interface ADBClientOptions {
86 | adbPath?: string;
87 | }
88 |
89 | export class ADBClient {
90 | private adbPath: string;
91 |
92 | constructor(options?: ADBClientOptions) {
93 | if (!options?.adbPath) {
94 | this.adbPath = this.getAdbPath();
95 | } else {
96 | this.adbPath = options.adbPath;
97 | }
98 | }
99 |
100 | getAdbPath() {
101 | const paths = getPotentialADBPaths();
102 | const validPath = paths.find((path) => existsSync(path));
103 |
104 | if (!validPath) {
105 | throw new Error(
106 | "ADB not found. Please ensure Android SDK is installed and properly configured."
107 | );
108 | }
109 | return validPath;
110 | }
111 |
112 | async init() {
113 | await this.shell("settings put global window_animation_scale 0");
114 | await this.shell("settings put global transition_animation_scale 0");
115 | await this.shell("settings put global animator_duration_scale 0");
116 | }
117 |
118 | async screenshot() {
119 | const { stdout } = await execAsync(
120 | `"${this.adbPath}" exec-out screencap -p`,
121 | {
122 | encoding: "buffer",
123 | maxBuffer: 25 * 1024 * 1024,
124 | }
125 | );
126 | return sharp(stdout)
127 | .png({
128 | quality: 25,
129 | })
130 | .toBuffer();
131 | }
132 |
133 | async screenSize() {
134 | const { stdout } = await this.execOut("wm size");
135 | const match = stdout.match(/Physical size: (\d+)x(\d+)/);
136 | if (!match) {
137 | throw new Error("Failed to get viewport size");
138 | }
139 | return {
140 | width: parseInt(match[1]),
141 | height: parseInt(match[2]),
142 | };
143 | }
144 |
145 | async execOut(command: string) {
146 | return execAsync(`"${this.adbPath}" exec-out ${command}`);
147 | }
148 |
149 | async shell(command: string) {
150 | return execAsync(`"${this.adbPath}" shell ${command}`);
151 | }
152 |
153 | async doubleTap(coordinate: Coordinate) {
154 | const { x, y } = coordinate;
155 | await this.shell(`input tap ${x} ${y}`);
156 | return this.shell(`input tap ${x} ${y}`);
157 | }
158 |
159 | async tap(coordinate: Coordinate) {
160 | const { x, y } = coordinate;
161 | return this.shell(`input tap ${x} ${y}`);
162 | }
163 |
164 | async swipe(start: Coordinate, end: Coordinate, duration: number = 300) {
165 | const { x: startX, y: startY } = start;
166 | const { x: endX, y: endY } = end;
167 | return this.shell(
168 | `input swipe ${startX} ${startY} ${endX} ${endY} ${duration}`
169 | );
170 | }
171 |
172 | async type(text: string) {
173 | return this.shell(`input text "${text.replace(/["\s]/g, "\\ ")}"`);
174 | }
175 |
176 | async keyPress(key: string) {
177 | const androidKey = ANDROID_KEY_EVENTS[key.toLowerCase()];
178 | if (!androidKey) {
179 | throw new Error(`Unsupported key: ${key}`);
180 | }
181 |
182 | return this.shell(`input keyevent ${androidKey}`);
183 | }
184 |
185 | async listPackages(filter?: string) {
186 | const { stdout } = await this.execOut(`pm list packages ${filter || ""}`);
187 | return stdout
188 | .split("\n")
189 | .map((line) => line.replace("package:", "").trim())
190 | .filter(Boolean);
191 | }
192 |
193 | async openApp(packageName: string) {
194 | const result = await this.shell(`monkey -p ${packageName} 1`);
195 | if (result.stderr && result.stderr.includes("No activities found")) {
196 | throw new Error(`Failed to open app: ${result.stderr}`);
197 | }
198 | return result;
199 | }
200 |
201 | async dumpUI() {
202 | try {
203 | const { stdout } = await this.execOut(
204 | `uiautomator dump --compressed /dev/tty`
205 | );
206 | const ui = JSON.stringify(parseUiDump(stdout));
207 | return ui;
208 | } catch (error) {
209 | throw new Error(`Failed to get UI hierarchy: ${error.message}`);
210 | }
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { generateText, LanguageModel, tool } from "ai";
2 | import { z } from "zod";
3 | import { ADBClient } from "./adb_client";
4 | import { createMobileComputer } from "./mobile_computer";
5 | import { openai } from "@ai-sdk/openai";
6 | export { ADBClient } from "./adb_client";
7 |
8 | const MobileUsePrompt = `You are an experienced mobile automation engineer.
9 | Your job is to navigate an android device and perform actions to fullfil request of the user.
10 |
11 |
12 | If the user asks to use a specific app in the request, open it before performing any other action.
13 | Do not take ui dump more than once per action. If you think you don't need to take ui dump, skip it. Use it sparingly.
14 |
15 | `;
16 |
17 | interface MobileUseOptions {
18 | task: string;
19 | llm?: LanguageModel;
20 | }
21 |
22 | export async function mobileUse({
23 | task,
24 | llm = openai("gpt-4o"),
25 | }: MobileUseOptions) {
26 | const adbClient = new ADBClient();
27 | await adbClient.init();
28 | const computer = await createMobileComputer(adbClient);
29 | const response = await generateText({
30 | messages: [
31 | {
32 | role: "system",
33 | content: MobileUsePrompt,
34 | },
35 | {
36 | role: "user",
37 | content: task,
38 | },
39 | ],
40 | model: llm,
41 | maxRetries: 3,
42 | maxSteps: 100,
43 | tools: {
44 | openApp: tool({
45 | parameters: z.object({
46 | name: z
47 | .string()
48 | .describe(
49 | "package name of the app to open such as com.google.android.dialer"
50 | ),
51 | }),
52 | description: "Open an on on android device.",
53 | async execute({ name }) {
54 | await adbClient.openApp(name);
55 | return `Successfull opened ${name}`;
56 | },
57 | }),
58 | listApps: tool({
59 | parameters: z.object({
60 | name: z.string().describe("Name of the package to filter."),
61 | }),
62 | description: "Use this to list packages.",
63 | async execute({ name }) {
64 | const list = await adbClient.listPackages(name);
65 | return list.join("\n");
66 | },
67 | }),
68 | computer,
69 | },
70 | });
71 | return response;
72 | }
73 |
--------------------------------------------------------------------------------
/src/mobile_computer.ts:
--------------------------------------------------------------------------------
1 | import { tool } from "ai";
2 | import { ADBClient } from "./adb_client";
3 | import { z } from "zod";
4 | import { wait } from "./utils";
5 |
6 | const Coordinate = z.array(z.number());
7 |
8 | export const createMobileComputer = async (adbClient: ADBClient) => {
9 | const viewportSize = await adbClient.screenSize();
10 | const mobileComputer = tool({
11 | description: `Mobile tool to perform actions on a mobile device.`,
12 |
13 | experimental_toToolResultContent(result: any) {
14 | return typeof result === "string"
15 | ? [{ type: "text", text: result }]
16 | : [{ type: "image", data: result?.data, mimeType: "image/png" }];
17 | },
18 | args: {
19 | displayHeightPx: viewportSize.height,
20 | displayWidthPx: viewportSize.width,
21 | displayNumber: 0,
22 | },
23 | parameters: z.object({
24 | action: z.enum([
25 | "ui_dump",
26 | "tap",
27 | "swipe",
28 | "type",
29 | "press",
30 | "wait",
31 | "screenshot",
32 | ])
33 | .describe(`ui_dump: Get UI elements you can interact with for the current screen.
34 | tap: Tap on the provided coordinate.
35 | swipe: Swipe from start_coordinate to end_coordinate.
36 | type: Type in the box.
37 | press: Press mobile key or button.
38 | screenshot: Take a screenshot of the current screen if UI dump is not helpful or where you need to see visuals.
39 | `),
40 | coordinate: Coordinate.optional(),
41 | start_coordinate: Coordinate.optional(),
42 | end_coordinate: Coordinate.optional(),
43 | text: z.string().optional(),
44 | duration: z.number().optional(),
45 | }),
46 | async execute({
47 | action,
48 | coordinate,
49 | text,
50 | duration,
51 | start_coordinate,
52 | end_coordinate,
53 | }) {
54 | if (action === "ui_dump") {
55 | return adbClient.dumpUI();
56 | }
57 |
58 | if (action === "tap") {
59 | const [x, y] = coordinate;
60 | await adbClient.tap({ x, y });
61 | return adbClient.dumpUI();
62 | }
63 |
64 | if (action === "press") {
65 | await adbClient.keyPress(text);
66 | return adbClient.dumpUI();
67 | }
68 |
69 | if (action === "type") {
70 | await adbClient.type(text);
71 | return adbClient.dumpUI();
72 | }
73 |
74 | if (action === "screenshot") {
75 | const screenshot = await adbClient.screenshot();
76 | return {
77 | data: screenshot.toString("base64"),
78 | type: "image/png",
79 | };
80 | }
81 |
82 | if (action === "swipe") {
83 | const [start_coordinate_x, start_coordinate_y] = start_coordinate;
84 | const [end_coordinate_x, end_coordinate_y] = end_coordinate;
85 | await adbClient.swipe(
86 | { x: start_coordinate_x, y: start_coordinate_y },
87 | {
88 | x: end_coordinate_x,
89 | y: end_coordinate_y,
90 | },
91 | duration
92 | );
93 | return adbClient.dumpUI();
94 | }
95 |
96 | if (action === "wait") {
97 | await wait(duration);
98 | }
99 | },
100 | });
101 |
102 | return mobileComputer;
103 | };
104 |
--------------------------------------------------------------------------------
/src/ui_dump_parser.ts:
--------------------------------------------------------------------------------
1 | import { XMLParser } from "fast-xml-parser";
2 |
3 | interface UiElement {
4 | id?: string;
5 | type: string;
6 | text?: string;
7 | desc?: string;
8 | clickable: boolean;
9 | bounds: string;
10 | children?: UiElement[];
11 | }
12 |
13 | /**
14 | * Parses ADB UI dumps into a simplified tree for AI agent navigation
15 | */
16 | export function parseUiDump(xmlDump: string): UiElement {
17 | const options = {
18 | ignoreAttributes: false,
19 | attributeNamePrefix: "",
20 | parseAttributeValue: true,
21 | isArray: (name: string) => name === "node",
22 | };
23 |
24 | const parser = new XMLParser(options);
25 | const parsed = parser.parse(xmlDump);
26 |
27 | if (parsed.hierarchy && parsed.hierarchy.node && parsed.hierarchy.node[0]) {
28 | return simplifyNode(parsed.hierarchy.node[0]);
29 | }
30 |
31 | return { type: "root", clickable: false, bounds: "[0,0][0,0]" };
32 | }
33 |
34 | /**
35 | * Safely checks if a string has content
36 | */
37 | function hasContent(str: any): boolean {
38 | return typeof str === "string" && str !== "";
39 | }
40 |
41 | /**
42 | * Converts a complex node into a simplified structure
43 | */
44 | function simplifyNode(node: any): UiElement {
45 | // Extract only the most essential properties
46 | const element: UiElement = {
47 | type: getElementType(node),
48 | clickable: node.clickable === "true",
49 | bounds: node.bounds || "[0,0][0,0]",
50 | };
51 |
52 | // Only include text if it exists and has content
53 | if (hasContent(node.text)) {
54 | element.text = node.text;
55 | }
56 |
57 | // Include content description if available
58 | if (hasContent(node["content-desc"])) {
59 | element.desc = node["content-desc"];
60 | }
61 |
62 | // Include resource ID but simplify it
63 | if (hasContent(node["resource-id"])) {
64 | // Extract just the name part of the ID for readability
65 | const idParts = node["resource-id"].split("/");
66 | element.id = idParts[idParts.length - 1];
67 | }
68 |
69 | // Process children if they exist
70 | if (node.node && node.node.length > 0) {
71 | // Skip intermediate containers
72 | if (shouldCollapseContainer(node)) {
73 | // Directly include children of this container instead
74 | element.children = flattenChildren(node.node);
75 | } else {
76 | // Only include meaningful children
77 | const meaningfulChildren = node.node
78 | .filter((child: any) => isMeaningfulNode(child))
79 | .map((child: any) => simplifyNode(child));
80 |
81 | if (meaningfulChildren.length > 0) {
82 | element.children = meaningfulChildren;
83 | }
84 | }
85 | }
86 |
87 | return element;
88 | }
89 |
90 | /**
91 | * Determines if a container node should be collapsed to reduce tree depth
92 | */
93 | function shouldCollapseContainer(node: any): boolean {
94 | // Skip intermediate containers that just add nesting
95 | return (
96 | !hasContent(node.text) &&
97 | !hasContent(node["content-desc"]) &&
98 | node.clickable !== "true" &&
99 | node.scrollable !== "true" &&
100 | !hasContent(node["resource-id"]) &&
101 | (node.class?.includes("Layout") || node.class?.includes("ViewGroup"))
102 | );
103 | }
104 |
105 | /**
106 | * Flattens children of intermediate containers
107 | */
108 | function flattenChildren(nodes: any[]): UiElement[] {
109 | let result: UiElement[] = [];
110 |
111 | for (const child of nodes) {
112 | if (shouldCollapseContainer(child) && child.node) {
113 | // Recursively flatten this container's children
114 | result = result.concat(flattenChildren(child.node));
115 | } else if (isMeaningfulNode(child)) {
116 | // Add this meaningful node
117 | result.push(simplifyNode(child));
118 | }
119 | }
120 |
121 | return result;
122 | }
123 |
124 | /**
125 | * Determines if a node has meaningful content for an agent
126 | */
127 | function isMeaningfulNode(node: any): boolean {
128 | // Keep nodes that are interactive
129 | if (node.clickable === "true" || node.scrollable === "true") {
130 | return true;
131 | }
132 |
133 | // Keep nodes with text or content description
134 | if (hasContent(node.text) || hasContent(node["content-desc"])) {
135 | return true;
136 | }
137 |
138 | // Keep nodes with specific resource IDs
139 | if (hasContent(node["resource-id"])) {
140 | return true;
141 | }
142 |
143 | // Check if the node has meaningful children
144 | if (node.node && node.node.length > 0) {
145 | return node.node.some((child: any) => isMeaningfulNode(child));
146 | }
147 |
148 | return false;
149 | }
150 |
151 | /**
152 | * Maps Android UI element classes to simpler type names
153 | */
154 | function getElementType(node: any): string {
155 | const className = node.class || "";
156 |
157 | // Map common Android classes to simpler types
158 | if (className.includes("Button")) return "button";
159 | if (className.includes("EditText")) return "input";
160 | if (className.includes("TextView")) return "text";
161 | if (className.includes("ImageView")) return "image";
162 | if (className.includes("CheckBox")) return "checkbox";
163 | if (className.includes("RadioButton")) return "radio";
164 | if (className.includes("RecyclerView") || className.includes("ListView"))
165 | return "list";
166 | if (className.includes("CardView")) return "card";
167 |
168 | // Special case for dialpad buttons
169 | if (
170 | hasContent(node["resource-id"]) &&
171 | (node["resource-id"].includes("one") ||
172 | node["resource-id"].includes("two") ||
173 | node["resource-id"].includes("three") ||
174 | node["resource-id"].includes("four") ||
175 | node["resource-id"].includes("five") ||
176 | node["resource-id"].includes("six") ||
177 | node["resource-id"].includes("seven") ||
178 | node["resource-id"].includes("eight") ||
179 | node["resource-id"].includes("nine") ||
180 | node["resource-id"].includes("zero") ||
181 | node["resource-id"].includes("star") ||
182 | node["resource-id"].includes("pound"))
183 | ) {
184 | return "dialpad_button";
185 | }
186 |
187 | return "view";
188 | }
189 |
190 | /**
191 | * Creates a simple text summary of key UI elements for the agent
192 | */
193 | export function describeUi(ui: UiElement): string {
194 | const interactiveElements = findAllInteractiveElements(ui);
195 |
196 | if (interactiveElements.length === 0) {
197 | return "No interactive elements found.";
198 | }
199 |
200 | let summary = `Found ${interactiveElements.length} interactive elements:\n`;
201 |
202 | interactiveElements.forEach((el, i) => {
203 | const description = [
204 | el.text ? `"${el.text}"` : "",
205 | el.desc ? `(${el.desc})` : "",
206 | el.id ? `[${el.id}]` : "",
207 | el.type,
208 | ]
209 | .filter(Boolean)
210 | .join(" ");
211 |
212 | summary += `${i + 1}. ${description} at ${el.bounds}\n`;
213 | });
214 |
215 | return summary;
216 | }
217 |
218 | /**
219 | * Finds all interactive elements in the UI
220 | */
221 | function findAllInteractiveElements(element: UiElement): UiElement[] {
222 | let results: UiElement[] = [];
223 |
224 | if (
225 | element.clickable ||
226 | element.type === "input" ||
227 | element.type === "list"
228 | ) {
229 | results.push(element);
230 | }
231 |
232 | if (element.children) {
233 | for (const child of element.children) {
234 | results = results.concat(findAllInteractiveElements(child));
235 | }
236 | }
237 |
238 | return results;
239 | }
240 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const wait = (ms: number) =>
2 | new Promise((resolve) => setTimeout(resolve, ms));
3 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "esModuleInterop": true,
5 | "target": "ES2022",
6 | "noImplicitAny": true,
7 | "moduleResolution": "node",
8 | "sourceMap": true,
9 | "outDir": "dist",
10 | "baseUrl": ".",
11 | "paths": {
12 | "*": ["node_modules/*", "lib/types/*"],
13 | "@/*": ["./*"]
14 | },
15 | "skipLibCheck": true,
16 | "declaration": true
17 | },
18 | "exclude": ["node_modules", "dist", ".eslintrc.cjs"]
19 | }
--------------------------------------------------------------------------------