peachsim 0.1.527

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +640 -0
  3. package/cli/app-config.ts +82 -0
  4. package/cli/app-fonts.ts +388 -0
  5. package/cli/app-project.ts +59 -0
  6. package/cli/app-splash.ts +171 -0
  7. package/cli/app-state-reset.ts +26 -0
  8. package/cli/auth.ts +184 -0
  9. package/cli/bin.ts +59 -0
  10. package/cli/bridge-diagnostics.ts +226 -0
  11. package/cli/bridge-flow-runner.ts +2806 -0
  12. package/cli/browser-backend.ts +44 -0
  13. package/cli/browser-evals.ts +96 -0
  14. package/cli/cli-update.ts +261 -0
  15. package/cli/cloud-client.ts +1530 -0
  16. package/cli/cloud-dispatch.ts +206 -0
  17. package/cli/cloud-session.ts +227 -0
  18. package/cli/command-contract.ts +221 -0
  19. package/cli/command-registry.ts +304 -0
  20. package/cli/commands/agent-wrapper.ts +1048 -0
  21. package/cli/commands/agent.ts +439 -0
  22. package/cli/commands/app-fonts.ts +99 -0
  23. package/cli/commands/assert.ts +542 -0
  24. package/cli/commands/auth.ts +71 -0
  25. package/cli/commands/box/bundle-plane.ts +71 -0
  26. package/cli/commands/box/checkout-plane.ts +256 -0
  27. package/cli/commands/box/plane-share.ts +208 -0
  28. package/cli/commands/box/rnx-command.ts +60 -0
  29. package/cli/commands/box/search-command.ts +157 -0
  30. package/cli/commands/box.ts +925 -0
  31. package/cli/commands/camera.ts +266 -0
  32. package/cli/commands/cleanup.ts +169 -0
  33. package/cli/commands/compat.ts +176 -0
  34. package/cli/commands/config.ts +34 -0
  35. package/cli/commands/control.ts +2154 -0
  36. package/cli/commands/cpu-profile.ts +941 -0
  37. package/cli/commands/daemon-mac-app.ts +165 -0
  38. package/cli/commands/daemon.ts +800 -0
  39. package/cli/commands/debug.ts +751 -0
  40. package/cli/commands/desktop.ts +39 -0
  41. package/cli/commands/detect.ts +201 -0
  42. package/cli/commands/detox.ts +481 -0
  43. package/cli/commands/device.ts +134 -0
  44. package/cli/commands/diagnose.ts +589 -0
  45. package/cli/commands/do-chain.ts +408 -0
  46. package/cli/commands/electron.ts +94 -0
  47. package/cli/commands/film.ts +379 -0
  48. package/cli/commands/flow.ts +1240 -0
  49. package/cli/commands/inspect/actions.ts +516 -0
  50. package/cli/commands/inspect/core.ts +2086 -0
  51. package/cli/commands/inspect/count.ts +17 -0
  52. package/cli/commands/inspect/describe.ts +119 -0
  53. package/cli/commands/inspect/env.ts +25 -0
  54. package/cli/commands/inspect/find.ts +169 -0
  55. package/cli/commands/inspect/get-layout.ts +53 -0
  56. package/cli/commands/inspect/keyboard.ts +54 -0
  57. package/cli/commands/inspect/list.ts +175 -0
  58. package/cli/commands/inspect/memory.ts +215 -0
  59. package/cli/commands/inspect/redaction.ts +39 -0
  60. package/cli/commands/inspect/resolve-target.ts +77 -0
  61. package/cli/commands/inspect/screens.ts +78 -0
  62. package/cli/commands/inspect/settle.ts +32 -0
  63. package/cli/commands/inspect/settling.ts +197 -0
  64. package/cli/commands/inspect/shared.ts +259 -0
  65. package/cli/commands/inspect/sleep.ts +15 -0
  66. package/cli/commands/inspect/tree.ts +23 -0
  67. package/cli/commands/inspect/url.ts +17 -0
  68. package/cli/commands/inspect/wait-event.ts +211 -0
  69. package/cli/commands/inspect/wait-idle.ts +25 -0
  70. package/cli/commands/inspect/wait-ready.ts +87 -0
  71. package/cli/commands/inspect/wait-selector.ts +59 -0
  72. package/cli/commands/inspect/wait.ts +32 -0
  73. package/cli/commands/inspect.ts +4738 -0
  74. package/cli/commands/install-cli.ts +275 -0
  75. package/cli/commands/install-desktop.ts +385 -0
  76. package/cli/commands/login.ts +357 -0
  77. package/cli/commands/logout.ts +24 -0
  78. package/cli/commands/maestro-generate.ts +375 -0
  79. package/cli/commands/maestro.ts +536 -0
  80. package/cli/commands/mode.ts +58 -0
  81. package/cli/commands/no-bridge-hint.ts +80 -0
  82. package/cli/commands/perf.ts +67 -0
  83. package/cli/commands/permissions.ts +203 -0
  84. package/cli/commands/platform.ts +410 -0
  85. package/cli/commands/preview.ts +103 -0
  86. package/cli/commands/profile.ts +106 -0
  87. package/cli/commands/react.ts +353 -0
  88. package/cli/commands/record.ts +1435 -0
  89. package/cli/commands/report-issue.ts +305 -0
  90. package/cli/commands/reset.ts +89 -0
  91. package/cli/commands/runtime.ts +348 -0
  92. package/cli/commands/screenshot-command.ts +106 -0
  93. package/cli/commands/screenshot-layers.ts +144 -0
  94. package/cli/commands/screenshot-mode.ts +38 -0
  95. package/cli/commands/screenshot.ts +492 -0
  96. package/cli/commands/screenshots-capture.ts +608 -0
  97. package/cli/commands/screenshots.ts +127 -0
  98. package/cli/commands/serve.ts +139 -0
  99. package/cli/commands/setup.ts +416 -0
  100. package/cli/commands/shell-boolean-mode.ts +82 -0
  101. package/cli/commands/skills.ts +468 -0
  102. package/cli/commands/slides.ts +357 -0
  103. package/cli/commands/state.ts +94 -0
  104. package/cli/commands/storage.ts +58 -0
  105. package/cli/commands/telemetry.ts +55 -0
  106. package/cli/commands/test.ts +535 -0
  107. package/cli/commands/three-mode.ts +771 -0
  108. package/cli/commands/timeline.ts +121 -0
  109. package/cli/commands/upgrade.ts +167 -0
  110. package/cli/commands/upload.ts +1203 -0
  111. package/cli/commands/version.ts +63 -0
  112. package/cli/commands/welcome.ts +17 -0
  113. package/cli/commands/what-happened.ts +328 -0
  114. package/cli/current-sim.ts +217 -0
  115. package/cli/desktop-companion.ts +315 -0
  116. package/cli/drivers/electron.ts +70 -0
  117. package/cli/drivers/index.ts +20 -0
  118. package/cli/drivers/playwright-provisioning.ts +184 -0
  119. package/cli/drivers/playwright-sim-host.ts +537 -0
  120. package/cli/drivers/playwright.ts +209 -0
  121. package/cli/drivers/registry.ts +65 -0
  122. package/cli/drivers/types.ts +102 -0
  123. package/cli/flow-export.ts +55 -0
  124. package/cli/flow-file.ts +142 -0
  125. package/cli/flow-live-status.ts +126 -0
  126. package/cli/flow-session.ts +140 -0
  127. package/cli/help-core.ts +143 -0
  128. package/cli/help.ts +44 -0
  129. package/cli/hidden-runtime-alias.ts +19 -0
  130. package/cli/hints.ts +214 -0
  131. package/cli/inspect-notice-state.ts +114 -0
  132. package/cli/internal-child.ts +176 -0
  133. package/cli/maestro-js.ts +323 -0
  134. package/cli/main.ts +704 -0
  135. package/cli/open-url.ts +8 -0
  136. package/cli/outbound-endpoints.ts +830 -0
  137. package/cli/parent-pid.ts +204 -0
  138. package/cli/parse-args.ts +189 -0
  139. package/cli/privacy.ts +53 -0
  140. package/cli/prompt.ts +56 -0
  141. package/cli/recording-access.ts +108 -0
  142. package/cli/registry.ts +2 -0
  143. package/cli/resolve-assets.ts +63 -0
  144. package/cli/rnx-in-process.ts +98 -0
  145. package/cli/run-registry.ts +226 -0
  146. package/cli/run-rnx-core.ts +148 -0
  147. package/cli/run-rnx.ts +137 -0
  148. package/cli/runtime-notes.ts +66 -0
  149. package/cli/runtime-summary.ts +25 -0
  150. package/cli/secure-file.ts +31 -0
  151. package/cli/self-invocation.ts +58 -0
  152. package/cli/send-to-box.ts +109 -0
  153. package/cli/setup-repository.ts +191 -0
  154. package/cli/shell-init.ts +98 -0
  155. package/cli/standalone.ts +4 -0
  156. package/cli/telemetry.ts +84 -0
  157. package/cli/ui.ts +68 -0
  158. package/cli/ws-bridge.ts +1020 -0
  159. package/detox/attempt-events.cjs +23 -0
  160. package/detox/colors.ts +54 -0
  161. package/detox/config-loader.ts +135 -0
  162. package/detox/element-types.ts +48 -0
  163. package/detox/expectations.ts +534 -0
  164. package/detox/gestures.ts +501 -0
  165. package/detox/index.ts +2694 -0
  166. package/detox/jest-preset.cjs +29 -0
  167. package/detox/jest-setup-after-env.cjs +22 -0
  168. package/detox/matchers.ts +30 -0
  169. package/detox/motion-change.cjs +109 -0
  170. package/detox/motion-change.d.cts +35 -0
  171. package/detox/navigation-lifecycle.ts +290 -0
  172. package/detox/navigation.ts +43 -0
  173. package/detox/proof-frame.cjs +114 -0
  174. package/detox/record-block-execution.cjs +78 -0
  175. package/detox/screenshots/animated-color-test-rest-norngh.png +0 -0
  176. package/detox/screenshots/color-test-after-drag-norngh.png +0 -0
  177. package/detox/screenshots/color-test-rest-norngh.png +0 -0
  178. package/detox/screenshots/theme-blue-toggle.png +0 -0
  179. package/detox/screenshots/theme-blue.png +0 -0
  180. package/detox/screenshots/theme-red-toggle.png +0 -0
  181. package/detox/screenshots/theme-red.png +0 -0
  182. package/dist-lib/agent-daemon-client.cjs +502 -0
  183. package/dist-lib/agent-events.cjs +48 -0
  184. package/dist-lib/agent-identity.cjs +53 -0
  185. package/dist-lib/agent-sessions.cjs +759 -0
  186. package/dist-lib/attached-projects.cjs +526 -0
  187. package/dist-lib/auth/shared-session.cjs +208 -0
  188. package/dist-lib/backend-origin.cjs +88 -0
  189. package/dist-lib/beta.cjs +41 -0
  190. package/dist-lib/beta.mjs +13 -0
  191. package/dist-lib/bridge-constants.cjs +161 -0
  192. package/dist-lib/bridge-contract-input.cjs +451 -0
  193. package/dist-lib/bridge-contract-input.mjs +414 -0
  194. package/dist-lib/bridge-contract.cjs +130 -0
  195. package/dist-lib/bridge-contract.mjs +94 -0
  196. package/dist-lib/capture-contract.cjs +220 -0
  197. package/dist-lib/capture-contract.mjs +190 -0
  198. package/dist-lib/cli-constants.cjs +32 -0
  199. package/dist-lib/cloud-contract.cjs +194 -0
  200. package/dist-lib/cloud-contract.mjs +145 -0
  201. package/dist-lib/cloud.cjs +670 -0
  202. package/dist-lib/cloud.mjs +639 -0
  203. package/dist-lib/config.cjs +96 -0
  204. package/dist-lib/detox/index.cjs +3789 -0
  205. package/dist-lib/detox/jest-preset.cjs +29 -0
  206. package/dist-lib/dev-bundle-resolution.cjs +290 -0
  207. package/dist-lib/home-paths.cjs +638 -0
  208. package/dist-lib/host/bridge-host.cjs +10903 -0
  209. package/dist-lib/host/fetch-proxy-handler.cjs +421 -0
  210. package/dist-lib/host/fetch-proxy-overrides.cjs +63 -0
  211. package/dist-lib/host/fetch-proxy-overrides.mjs +37 -0
  212. package/dist-lib/host/replacement-module-handler.cjs +469 -0
  213. package/dist-lib/host/websocket-proxy.cjs +298 -0
  214. package/dist-lib/index.cjs +4268 -0
  215. package/dist-lib/jump-to-source-babel.cjs +93 -0
  216. package/dist-lib/jump-to-source-native.cjs +112 -0
  217. package/dist-lib/menu.cjs +646 -0
  218. package/dist-lib/menu.mjs +604 -0
  219. package/dist-lib/metro-fingerprint-registry.cjs +186 -0
  220. package/dist-lib/metro-fingerprint-registry.mjs +156 -0
  221. package/dist-lib/metro-production-bundle.cjs +329 -0
  222. package/dist-lib/metro-production-bundle.mjs +295 -0
  223. package/dist-lib/metro.cjs +904 -0
  224. package/dist-lib/profiles.cjs +246 -0
  225. package/dist-lib/public-brand.cjs +39 -0
  226. package/dist-lib/react-native-host-modules.cjs +51 -0
  227. package/dist-lib/react-native-host-modules.mjs +25 -0
  228. package/dist-lib/render-mode.cjs +54 -0
  229. package/dist-lib/scripts/dev-server-scanner.cjs +1232 -0
  230. package/dist-lib/sdk.cjs +2433 -0
  231. package/dist-lib/sdk.mjs +2336 -0
  232. package/dist-lib/skills.cjs +39132 -0
  233. package/dist-lib/swift-submit.cjs +92 -0
  234. package/dist-lib/swift-submit.mjs +65 -0
  235. package/dist-lib/swift.cjs +1646 -0
  236. package/dist-lib/vite.cjs +1591 -0
  237. package/package.json +290 -0
  238. package/scripts/dev-server-scanner.ts +1291 -0
  239. package/scripts/optional-demo-registry.ts +113 -0
  240. package/skills/contrast/SKILL.md +165 -0
  241. package/skills/rnx-debug/SKILL.md +433 -0
  242. package/skills/rnx-perf/SKILL.md +399 -0
  243. package/skills/rnx-setup/SKILL.md +172 -0
  244. package/skills/rnx-test/SKILL.md +321 -0
  245. package/skills/rnx-visual/SKILL.md +126 -0
  246. package/src/agent-daemon-client.ts +410 -0
  247. package/src/agent-events.ts +71 -0
  248. package/src/agent-identity.ts +23 -0
  249. package/src/agent-prompt.ts +71 -0
  250. package/src/agent-sessions.ts +580 -0
  251. package/src/app-url.ts +39 -0
  252. package/src/attached-projects.ts +539 -0
  253. package/src/auth/shared-session.ts +235 -0
  254. package/src/backend-origin.ts +70 -0
  255. package/src/beta.ts +19 -0
  256. package/src/bridge-constants.ts +175 -0
  257. package/src/bridge-contract-input.ts +502 -0
  258. package/src/bridge-contract.ts +558 -0
  259. package/src/browser-cache.ts +16 -0
  260. package/src/capture-contract.ts +587 -0
  261. package/src/cli-constants.ts +1 -0
  262. package/src/cli-version.ts +40 -0
  263. package/src/cloud-contract.ts +274 -0
  264. package/src/cloud.ts +762 -0
  265. package/src/codex-client.ts +234 -0
  266. package/src/config.ts +132 -0
  267. package/src/connect.ts +101 -0
  268. package/src/dev-bundle-resolution.ts +346 -0
  269. package/src/dev-server-open.ts +198 -0
  270. package/src/disk-cleanup.ts +540 -0
  271. package/src/flow-timeout-scale.ts +15 -0
  272. package/src/home-paths.ts +806 -0
  273. package/src/host/agent-host.ts +666 -0
  274. package/src/host/bridge-host.ts +2788 -0
  275. package/src/host/fetch-proxy-handler.ts +449 -0
  276. package/src/host/fetch-proxy-overrides.ts +51 -0
  277. package/src/host/open-url.ts +89 -0
  278. package/src/host/plane-host.ts +203 -0
  279. package/src/host/replacement-module-handler.ts +158 -0
  280. package/src/host/websocket-proxy.ts +315 -0
  281. package/src/index.ts +71 -0
  282. package/src/jump-to-source-babel.ts +135 -0
  283. package/src/jump-to-source-native.ts +102 -0
  284. package/src/menu.ts +777 -0
  285. package/src/metro-fingerprint-registry.ts +302 -0
  286. package/src/metro-plugin.ts +341 -0
  287. package/src/metro-production-bundle.ts +471 -0
  288. package/src/native-dev-bundle-url.ts +118 -0
  289. package/src/native-seam-manifest.ts +341 -0
  290. package/src/playwright-host-log.ts +16 -0
  291. package/src/plist.ts +27 -0
  292. package/src/poll-until.ts +123 -0
  293. package/src/profiles.ts +179 -0
  294. package/src/public-brand.ts +9 -0
  295. package/src/react-native-host-modules.ts +26 -0
  296. package/src/render-mode.ts +27 -0
  297. package/src/rolldown-plugin-swift.ts +240 -0
  298. package/src/runtime-assets.ts +233 -0
  299. package/src/runtime-delivery.ts +54 -0
  300. package/src/screenshots/compose.ts +422 -0
  301. package/src/screenshots/frame-compose.ts +514 -0
  302. package/src/screenshots/orchestrate.ts +256 -0
  303. package/src/screenshots/org-deck.ts +91 -0
  304. package/src/screenshots/registry.ts +58 -0
  305. package/src/screenshots/schema.ts +364 -0
  306. package/src/sdk.ts +15 -0
  307. package/src/settings-bundle.ts +418 -0
  308. package/src/shell-bridge-identity.ts +15 -0
  309. package/src/sim-client.ts +697 -0
  310. package/src/skills/builtin/a11y-review.ts +132 -0
  311. package/src/skills/builtin/compat-check.ts +71 -0
  312. package/src/skills/builtin/maestro-test.ts +121 -0
  313. package/src/skills/builtin/perf-profile.ts +90 -0
  314. package/src/skills/builtin/screenshot-all.ts +52 -0
  315. package/src/skills/builtin/visual-diff.ts +100 -0
  316. package/src/skills/registry.ts +107 -0
  317. package/src/skills/types.ts +41 -0
  318. package/src/swift-submit.ts +185 -0
  319. package/src/swift.ts +7 -0
  320. package/src/team-machine-prompt.ts +73 -0
  321. package/src/vite-plugin-one.ts +264 -0
  322. package/src/vite-plugin-swift.ts +620 -0
  323. package/src/vite-plugin.ts +1946 -0
  324. package/src/worklets-babel.ts +250 -0
@@ -0,0 +1,1646 @@
1
+ /*! rnx v0.1.527 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
+ "use strict";
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+
32
+ // src/swift.ts
33
+ var swift_exports = {};
34
+ __export(swift_exports, {
35
+ createSwiftEntry: () => createSwiftEntry
36
+ });
37
+ module.exports = __toCommonJS(swift_exports);
38
+
39
+ // ../sootsim-swift/src/mount.tsx
40
+ var import_native = require("@react-navigation/native");
41
+ var import_native_stack = require("@react-navigation/native-stack");
42
+ var import_runtime = require("contrast-kit/runtime");
43
+ var import_ui = require("contrast-kit/ui");
44
+ var import_react = require("react");
45
+ var import_react_native = require("react-native");
46
+ var import_react_native_bottom_tabs = __toESM(require("react-native-bottom-tabs"), 1);
47
+
48
+ // ../sootsim-swift/src/bundleAssets.ts
49
+ function resolveImageSource(source, table, onMiss) {
50
+ if (typeof source !== "string") return source;
51
+ const url = table[source];
52
+ if (typeof url === "string") return { uri: url };
53
+ onMiss(source);
54
+ return source;
55
+ }
56
+
57
+ // ../sootsim-swift/src/resfs.ts
58
+ var RES_BADF = 8;
59
+ var RES_INVAL = 28;
60
+ var RES_NOENT = 44;
61
+ var RES_NOTDIR = 54;
62
+ var RES_NOTCAPABLE = 76;
63
+ var RES_DIRTYPE = 3;
64
+ var RES_FILETYPE = 4;
65
+ var O_CREAT = 1;
66
+ var O_DIRECTORY = 2;
67
+ var O_EXCL = 4;
68
+ var O_TRUNC = 8;
69
+ var RES_PREOPEN = 3;
70
+ var RES_DIR_NAME = "/res";
71
+ var B64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
72
+ function decodeBase64(text) {
73
+ const clean = text.replace(/\s/g, "");
74
+ if (clean.length % 4 !== 0) {
75
+ throw new Error(`swift bundle file is not base64 (length ${clean.length})`);
76
+ }
77
+ const values = new Uint8Array(clean.length);
78
+ let length = clean.length;
79
+ let pad = 0;
80
+ if (clean.endsWith("==")) pad = 2;
81
+ else if (clean.endsWith("=")) pad = 1;
82
+ length -= pad;
83
+ for (let index = 0; index < clean.length - pad; index += 1) {
84
+ const digit = B64_DIGITS.indexOf(clean[index]);
85
+ if (digit < 0) {
86
+ throw new Error(`swift bundle file is not base64 (char '${clean[index]}')`);
87
+ }
88
+ values[index] = digit;
89
+ }
90
+ const out = new Uint8Array((clean.length / 4 | 0) * 3 - pad);
91
+ let at = 0;
92
+ for (let index = 0; index < clean.length; index += 4) {
93
+ const group = values[index] << 18 | values[index + 1] << 12 | values[index + 2] << 6 | values[index + 3];
94
+ out[at] = group >> 16 & 255;
95
+ if (at + 1 < out.length) out[at + 1] = group >> 8 & 255;
96
+ if (at + 2 < out.length) out[at + 2] = group & 255;
97
+ at += 3;
98
+ }
99
+ return out;
100
+ }
101
+ function resIno(name) {
102
+ let hash = 0xcbf29ce484222325n;
103
+ const bytes = new TextEncoder().encode(name);
104
+ for (const byte of bytes) {
105
+ hash ^= BigInt(byte);
106
+ hash = hash * 0x100000001b3n & 0xffffffffffffffffn;
107
+ }
108
+ return hash === 0n ? 1n : hash;
109
+ }
110
+ function resArgv0(moduleUrl) {
111
+ const base = moduleUrl.split("/").pop()?.split("?")[0] ?? "app.wasm";
112
+ return `${RES_DIR_NAME}/${base === "" ? "app.wasm" : base}`;
113
+ }
114
+ function resolveName(files, rel) {
115
+ let rest = rel;
116
+ if (rest === RES_DIR_NAME || rest === `${RES_DIR_NAME}/`) return null;
117
+ if (rest.startsWith(`${RES_DIR_NAME}/`)) rest = rest.slice(RES_DIR_NAME.length + 1);
118
+ if (rest.startsWith("/")) rest = rest.slice(1);
119
+ while (rest.startsWith("./")) rest = rest.slice(2);
120
+ if (rest === "" || rest === ".") return null;
121
+ if (rest.includes("/")) return null;
122
+ return Object.prototype.hasOwnProperty.call(files, rest) ? rest : null;
123
+ }
124
+ function writeStat(mem, ptr, filetype, size, ino) {
125
+ mem.bytes().fill(0, ptr, ptr + 64);
126
+ mem.bytes()[ptr + 16] = filetype;
127
+ mem.writeU64(ptr + 8, ino);
128
+ mem.writeU64(ptr + 32, BigInt(size));
129
+ }
130
+ function createResFs(files) {
131
+ const names = Object.keys(files).sort();
132
+ const fds = /* @__PURE__ */ new Map();
133
+ let nextFd = RES_PREOPEN + 1;
134
+ const freeFds = [];
135
+ let preopenOpen = true;
136
+ const allocFd = () => {
137
+ if (freeFds.length > 0) return freeFds.shift();
138
+ nextFd += 1;
139
+ return nextFd - 1;
140
+ };
141
+ const dirFdOk = (fd) => {
142
+ if (fd === RES_PREOPEN) return preopenOpen;
143
+ const found = fds.get(fd);
144
+ return found !== void 0 && found.kind === "dir";
145
+ };
146
+ const inoOf = (name) => resIno(name);
147
+ return {
148
+ imports(mem) {
149
+ return {
150
+ path_open: (dirfd, _dirflags, pathPtr, pathLen, oflags, _r1, _r2, _r3, fdPtr) => {
151
+ if (!dirFdOk(dirfd)) return RES_BADF;
152
+ if ((oflags & (O_CREAT | O_EXCL | O_TRUNC)) !== 0) return RES_INVAL;
153
+ const rel = mem.readString(pathPtr, pathLen);
154
+ if (rel === "." || rel === "./" || rel === RES_DIR_NAME || rel === `${RES_DIR_NAME}/`) {
155
+ const fd2 = allocFd();
156
+ fds.set(fd2, { kind: "dir" });
157
+ mem.writeU32(fdPtr, fd2);
158
+ return 0;
159
+ }
160
+ const hit = resolveName(files, rel);
161
+ if (hit === null) return RES_NOENT;
162
+ if ((oflags & O_DIRECTORY) !== 0) return RES_NOTDIR;
163
+ const fd = allocFd();
164
+ fds.set(fd, { kind: "file", name: hit, bytes: files[hit], offset: 0 });
165
+ mem.writeU32(fdPtr, fd);
166
+ return 0;
167
+ },
168
+ path_filestat_get: (dirfd, _flags, pathPtr, pathLen, statPtr) => {
169
+ if (!dirFdOk(dirfd)) return RES_BADF;
170
+ const rel = mem.readString(pathPtr, pathLen);
171
+ if (rel === "." || rel === "./" || rel === RES_DIR_NAME || rel === `${RES_DIR_NAME}/`) {
172
+ writeStat(mem, statPtr, RES_DIRTYPE, 0, inoOf(RES_DIR_NAME));
173
+ return 0;
174
+ }
175
+ const hit = resolveName(files, rel);
176
+ if (hit === null) return RES_NOENT;
177
+ writeStat(mem, statPtr, RES_FILETYPE, files[hit].length, inoOf(hit));
178
+ return 0;
179
+ },
180
+ fd_fdstat_get: (fd, statPtr) => {
181
+ if (fd === RES_PREOPEN) {
182
+ if (!preopenOpen) return RES_BADF;
183
+ mem.bytes().fill(0, statPtr, statPtr + 24);
184
+ mem.bytes()[statPtr] = RES_DIRTYPE;
185
+ return 0;
186
+ }
187
+ const found = fds.get(fd);
188
+ if (!found) return RES_BADF;
189
+ mem.bytes().fill(0, statPtr, statPtr + 24);
190
+ mem.bytes()[statPtr] = found.kind === "dir" ? RES_DIRTYPE : RES_FILETYPE;
191
+ return 0;
192
+ },
193
+ fd_filestat_get: (fd, statPtr) => {
194
+ const found = fds.get(fd);
195
+ if (!found) return RES_BADF;
196
+ if (found.kind === "dir") {
197
+ writeStat(mem, statPtr, RES_DIRTYPE, 0, inoOf(RES_DIR_NAME));
198
+ return 0;
199
+ }
200
+ writeStat(mem, statPtr, RES_FILETYPE, found.bytes.length, inoOf(found.name));
201
+ return 0;
202
+ },
203
+ fd_prestat_get: (fd, prestatPtr) => {
204
+ if (fd === RES_PREOPEN && preopenOpen) {
205
+ mem.bytes().fill(0, prestatPtr, prestatPtr + 8);
206
+ mem.bytes()[prestatPtr] = 0;
207
+ mem.writeU32(prestatPtr + 4, RES_DIR_NAME.length);
208
+ return 0;
209
+ }
210
+ return RES_BADF;
211
+ },
212
+ fd_prestat_dir_name: (fd, pathPtr, pathLen) => {
213
+ if (fd !== RES_PREOPEN || !preopenOpen) return RES_BADF;
214
+ if (pathLen < RES_DIR_NAME.length) return RES_INVAL;
215
+ mem.bytes().set(new TextEncoder().encode(RES_DIR_NAME), pathPtr);
216
+ return 0;
217
+ },
218
+ fd_readdir: (fd, bufPtr, bufLen, cookie, usedPtr) => {
219
+ const isPreopen = fd === RES_PREOPEN && preopenOpen;
220
+ const found = fds.get(fd);
221
+ if (!isPreopen && !found) return RES_BADF;
222
+ if (!isPreopen && found?.kind !== "dir") return RES_NOTCAPABLE;
223
+ let used = 0;
224
+ names.forEach((name, index) => {
225
+ const next = index + 1;
226
+ if (next <= cookie) return;
227
+ const encoded = new TextEncoder().encode(name);
228
+ if (used + 24 + encoded.length > bufLen) return;
229
+ const at = bufPtr + used;
230
+ mem.writeU64(at, BigInt(next));
231
+ mem.writeU64(at + 8, inoOf(name));
232
+ mem.writeU32(at + 16, encoded.length);
233
+ mem.bytes()[at + 20] = RES_FILETYPE;
234
+ mem.bytes().fill(0, at + 21, at + 24);
235
+ mem.bytes().set(encoded, at + 24);
236
+ used += 24 + encoded.length;
237
+ });
238
+ mem.writeU32(usedPtr, used);
239
+ return 0;
240
+ },
241
+ fd_read: (fd, iovsPtr, iovsLen, donePtr) => {
242
+ const found = fds.get(fd);
243
+ if (!found) return RES_BADF;
244
+ if (found.kind !== "file") return RES_NOTCAPABLE;
245
+ let done = 0;
246
+ for (let index = 0; index < iovsLen; index += 1) {
247
+ const ptr = mem.readU32(iovsPtr + index * 8);
248
+ const want = mem.readU32(iovsPtr + index * 8 + 4);
249
+ const chunk = found.bytes.subarray(found.offset, found.offset + want);
250
+ mem.bytes().set(chunk, ptr);
251
+ found.offset += chunk.length;
252
+ done += chunk.length;
253
+ if (chunk.length < want) break;
254
+ }
255
+ mem.writeU32(donePtr, done);
256
+ return 0;
257
+ },
258
+ // the tree is read-only: any write to it is not-capable, and an
259
+ // unknown fd is a bad descriptor. stdio never reaches here; the
260
+ // mount answers fds 0-2 itself before delegating.
261
+ fd_write: (fd, _iovsPtr, _iovsLen, _donePtr) => {
262
+ if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
263
+ return RES_BADF;
264
+ },
265
+ fd_pread: (fd, _iovsPtr, _iovsLen, _offset, _donePtr) => {
266
+ if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
267
+ return RES_BADF;
268
+ },
269
+ fd_seek: (fd, _offLo, _offHi, _whence, _posPtr) => {
270
+ if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
271
+ return RES_BADF;
272
+ },
273
+ fd_tell: (fd, _posPtr) => {
274
+ if (fd === RES_PREOPEN || fds.has(fd)) return RES_NOTCAPABLE;
275
+ return RES_BADF;
276
+ },
277
+ fd_close: (fd) => {
278
+ if (fd === RES_PREOPEN) {
279
+ if (!preopenOpen) return RES_BADF;
280
+ preopenOpen = false;
281
+ return 0;
282
+ }
283
+ if (!fds.has(fd)) return RES_BADF;
284
+ fds.delete(fd);
285
+ const at = freeFds.findIndex((other) => other > fd);
286
+ if (at < 0) freeFds.push(fd);
287
+ else freeFds.splice(at, 0, fd);
288
+ return 0;
289
+ }
290
+ };
291
+ }
292
+ };
293
+ }
294
+
295
+ // ../sootsim-swift/src/mount.tsx
296
+ var import_jsx_runtime = require("react/jsx-runtime");
297
+ function isRecord(value) {
298
+ return typeof value === "object" && value !== null;
299
+ }
300
+ function readModifier(value) {
301
+ if (!isRecord(value) || typeof value.$type !== "string") {
302
+ throw new Error("swift modifier is not a { $type } object");
303
+ }
304
+ return { ...value, $type: value.$type };
305
+ }
306
+ function readNode(value) {
307
+ if (!isRecord(value)) throw new Error("swift node is not an object");
308
+ const { t, id, p, m, c, h } = value;
309
+ if (typeof t !== "string" || typeof id !== "string") {
310
+ throw new Error("swift node has no type or identity");
311
+ }
312
+ const node = { t, id };
313
+ if (p !== void 0) {
314
+ if (!isRecord(p)) throw new Error(`swift node ${id} has a non-object props`);
315
+ node.p = p;
316
+ }
317
+ if (m !== void 0) {
318
+ if (!Array.isArray(m)) throw new Error(`swift node ${id} has a non-array modifiers`);
319
+ node.m = m.map(readModifier);
320
+ }
321
+ if (c !== void 0) {
322
+ if (!Array.isArray(c)) throw new Error(`swift node ${id} has non-array children`);
323
+ node.c = c.map(readNode);
324
+ }
325
+ if (h !== void 0) {
326
+ if (!isRecord(h)) throw new Error(`swift node ${id} has non-object handlers`);
327
+ const handlers = {};
328
+ for (const [name, handlerId2] of Object.entries(h)) {
329
+ if (typeof handlerId2 !== "number") {
330
+ throw new Error(`swift node ${id} handler ${name} is not a number`);
331
+ }
332
+ handlers[name] = handlerId2;
333
+ }
334
+ node.h = handlers;
335
+ }
336
+ return node;
337
+ }
338
+ function readTree(text) {
339
+ const value = JSON.parse(text);
340
+ if (!Array.isArray(value)) throw new Error("swift tree is not an array");
341
+ return value.map(readNode);
342
+ }
343
+ var WASI_BADF = 8;
344
+ var WASI_INVAL = 28;
345
+ function wasiImports(host, argv, resFiles) {
346
+ const argvBytes = argv.map((arg) => new TextEncoder().encode(`${arg}\0`));
347
+ const resImports = createResFs(resFiles).imports(host);
348
+ return {
349
+ args_get: (argvPtr, bufPtr) => {
350
+ let argp = argvPtr;
351
+ let bufp = bufPtr;
352
+ for (const bytes of argvBytes) {
353
+ host.writeU32(argp, bufp);
354
+ host.bytes().set(bytes, bufp);
355
+ argp += 4;
356
+ bufp += bytes.length;
357
+ }
358
+ host.writeU32(argp, 0);
359
+ return 0;
360
+ },
361
+ args_sizes_get: (argcPtr, argvSizePtr) => {
362
+ host.writeU32(argcPtr, argvBytes.length);
363
+ host.writeU32(
364
+ argvSizePtr,
365
+ argvBytes.reduce((total, bytes) => total + bytes.length, 0)
366
+ );
367
+ return 0;
368
+ },
369
+ environ_get: () => 0,
370
+ environ_sizes_get: (countPtr, sizePtr) => {
371
+ host.writeU32(countPtr, 0);
372
+ host.writeU32(sizePtr, 0);
373
+ return 0;
374
+ },
375
+ fd_close: (...args) => resImports.fd_close(...args),
376
+ fd_fdstat_get: (...args) => resImports.fd_fdstat_get(...args),
377
+ fd_fdstat_set_flags: () => WASI_BADF,
378
+ fd_filestat_get: (...args) => resImports.fd_filestat_get(...args),
379
+ fd_filestat_set_size: () => WASI_BADF,
380
+ fd_filestat_set_times: () => WASI_BADF,
381
+ fd_pread: (...args) => resImports.fd_pread(...args),
382
+ fd_prestat_get: (...args) => resImports.fd_prestat_get(...args),
383
+ fd_prestat_dir_name: (...args) => resImports.fd_prestat_dir_name(...args),
384
+ fd_read: (...args) => resImports.fd_read(...args),
385
+ fd_readdir: (...args) => resImports.fd_readdir(...args),
386
+ fd_seek: (...args) => resImports.fd_seek(...args),
387
+ fd_sync: () => WASI_BADF,
388
+ fd_tell: (...args) => resImports.fd_tell(...args),
389
+ fd_write: (fd, iovsPtr, iovsLen, writtenPtr) => {
390
+ if (fd !== 1 && fd !== 2)
391
+ return resImports.fd_write(fd, iovsPtr, iovsLen, writtenPtr);
392
+ const view = new DataView(host.bytes().buffer);
393
+ let written = 0;
394
+ for (let index = 0; index < iovsLen; index += 1) {
395
+ written += view.getUint32(iovsPtr + index * 8 + 4, true);
396
+ }
397
+ host.writeU32(writtenPtr, written);
398
+ return 0;
399
+ },
400
+ path_create_directory: () => WASI_BADF,
401
+ path_filestat_get: (...args) => resImports.path_filestat_get(...args),
402
+ path_filestat_set_times: () => WASI_BADF,
403
+ path_link: () => WASI_BADF,
404
+ path_open: (...args) => resImports.path_open(...args),
405
+ path_readlink: () => WASI_BADF,
406
+ path_remove_directory: () => WASI_BADF,
407
+ path_rename: () => WASI_BADF,
408
+ path_symlink: () => WASI_BADF,
409
+ path_unlink_file: () => WASI_BADF,
410
+ // the 6.3 sdk's libraries call the clocks even when the app never reads
411
+ // the time, so instantiation fails without them. clock 0 is realtime
412
+ // and clock 1 is monotonic, the only two swift asks for here; anything
413
+ // else is a loud inval. the resolutions are wasi-libc's for those two:
414
+ // a millisecond for the wall clock and a nanosecond for the monotonic one.
415
+ clock_res_get: (clockId, resolutionPtr) => {
416
+ const resolution = clockId === 1 ? 1n : clockId === 0 ? 1000000n : null;
417
+ if (resolution === null) return WASI_INVAL;
418
+ host.writeU64(resolutionPtr, resolution);
419
+ return 0;
420
+ },
421
+ clock_time_get: (clockId, _precision, timePtr) => {
422
+ const nanos = clockId === 1 ? BigInt(Math.round(performance.now() * 1e6)) : clockId === 0 ? BigInt(Date.now()) * 1000000n : null;
423
+ if (nanos === null) return WASI_INVAL;
424
+ host.writeU64(timePtr, nanos);
425
+ return 0;
426
+ },
427
+ // a poll is the one call the tenant cannot answer: there is no descriptor
428
+ // to wait on and no clock to sleep against, so it says so instead of
429
+ // returning an event nobody subscribed to.
430
+ poll_oneoff: () => {
431
+ throw new Error("swift app polled for events, which the tenant has no source for");
432
+ },
433
+ proc_exit: (code) => {
434
+ throw new Error(`swift app exited with code ${code}`);
435
+ },
436
+ random_get: (bufferPtr, length) => {
437
+ crypto.getRandomValues(host.bytes().subarray(bufferPtr, bufferPtr + length));
438
+ return 0;
439
+ }
440
+ };
441
+ }
442
+ function rawExport(exports2, name) {
443
+ const value = exports2[name];
444
+ if (typeof value !== "function") {
445
+ throw new Error(`swift artifact has no exported function ${name}`);
446
+ }
447
+ return value;
448
+ }
449
+ function pointerExport(exports2, name) {
450
+ const fn = rawExport(exports2, name);
451
+ return (...args) => {
452
+ const result = Reflect.apply(fn, void 0, args);
453
+ if (typeof result !== "number") {
454
+ throw new Error(`swift export ${name} returned ${typeof result}`);
455
+ }
456
+ return result;
457
+ };
458
+ }
459
+ function voidExport(exports2, name) {
460
+ const fn = rawExport(exports2, name);
461
+ return (...args) => {
462
+ Reflect.apply(fn, void 0, args);
463
+ };
464
+ }
465
+ function instantiate(module2, bundle) {
466
+ let memory;
467
+ const requireMemory = () => {
468
+ if (!memory) throw new Error("swift artifact memory is not live");
469
+ return memory;
470
+ };
471
+ const host = {
472
+ writeU32(ptr, value) {
473
+ new DataView(requireMemory().buffer).setUint32(ptr, value, true);
474
+ },
475
+ writeU64(ptr, value) {
476
+ new DataView(requireMemory().buffer).setBigUint64(ptr, value, true);
477
+ },
478
+ readU32(ptr) {
479
+ return new DataView(requireMemory().buffer).getUint32(ptr, true);
480
+ },
481
+ readString(ptr, len) {
482
+ return new TextDecoder().decode(
483
+ new Uint8Array(requireMemory().buffer).subarray(ptr, ptr + len)
484
+ );
485
+ },
486
+ bytes: () => new Uint8Array(requireMemory().buffer)
487
+ };
488
+ const argv = bundle === null ? [] : [bundle.argv0];
489
+ const instance = new WebAssembly.Instance(module2, {
490
+ wasi_snapshot_preview1: wasiImports(host, argv, bundle?.files ?? {})
491
+ });
492
+ const exportedMemory = instance.exports.memory;
493
+ if (!(exportedMemory instanceof WebAssembly.Memory)) {
494
+ throw new Error("swift artifact does not export its memory");
495
+ }
496
+ memory = exportedMemory;
497
+ const initialize = voidExport(instance.exports, "_initialize");
498
+ const mainArgv = voidExport(instance.exports, "__main_argc_argv");
499
+ const mount = pointerExport(instance.exports, "rnx_mount");
500
+ const mountViewExport = pointerExport(instance.exports, "rnx_mount_view");
501
+ const hasViewExport = pointerExport(instance.exports, "rnx_has_view");
502
+ const event = pointerExport(instance.exports, "rnx_event");
503
+ const stateExport = pointerExport(instance.exports, "rnx_state_export");
504
+ const stateImport = voidExport(instance.exports, "rnx_state_import");
505
+ const alloc = pointerExport(instance.exports, "rnx_alloc");
506
+ const free = voidExport(instance.exports, "rnx_free");
507
+ const openURLDrain = typeof instance.exports.rnx_open_url_drain === "function" ? pointerExport(instance.exports, "rnx_open_url_drain") : null;
508
+ const drainOpenURLs = () => {
509
+ if (!openURLDrain) return;
510
+ let urls;
511
+ try {
512
+ urls = JSON.parse(readBuffer(openURLDrain()));
513
+ } catch {
514
+ return;
515
+ }
516
+ if (!Array.isArray(urls)) return;
517
+ for (const url of urls) {
518
+ if (typeof url !== "string") continue;
519
+ import_react_native.Linking.canOpenURL(url).then(
520
+ (open) => {
521
+ if (open) import_react_native.Linking.openURL(url).catch(() => {
522
+ });
523
+ },
524
+ () => {
525
+ }
526
+ );
527
+ }
528
+ };
529
+ const readBuffer = (ptr) => {
530
+ const view = new DataView(requireMemory().buffer);
531
+ const length = view.getUint32(ptr, true);
532
+ return new TextDecoder().decode(
533
+ new Uint8Array(requireMemory().buffer, ptr + 4, length)
534
+ );
535
+ };
536
+ const withPayload = (value, run) => {
537
+ const encoded = new TextEncoder().encode(JSON.stringify(value));
538
+ const ptr = alloc(encoded.length);
539
+ new Uint8Array(requireMemory().buffer).set(encoded, ptr);
540
+ const result = run(ptr, encoded.length);
541
+ free(ptr);
542
+ return result;
543
+ };
544
+ initialize();
545
+ if (bundle === null) {
546
+ mainArgv(0, 0);
547
+ } else {
548
+ const encoded = new TextEncoder().encode(`${bundle.argv0}\0`);
549
+ const ptr = alloc(encoded.length + 4);
550
+ new Uint8Array(requireMemory().buffer).set(encoded, ptr + 4);
551
+ new DataView(requireMemory().buffer).setUint32(ptr, ptr + 4, true);
552
+ mainArgv(1, ptr);
553
+ }
554
+ return {
555
+ mount: () => {
556
+ if (hasViewExport() === 1) {
557
+ throw new Error(
558
+ "swift package has an RNXPackage entry, not an App entry; mount it as a view or make its @main type conform to App"
559
+ );
560
+ }
561
+ const tree = readTree(readBuffer(mount()));
562
+ drainOpenURLs();
563
+ return tree;
564
+ },
565
+ mountView: (props) => {
566
+ if (hasViewExport() !== 1) {
567
+ throw new Error(
568
+ "swift package has no RNXPackage entry; its @main type must conform to RNXPackage to mount as a view"
569
+ );
570
+ }
571
+ const tree = readTree(
572
+ readBuffer(withPayload(props, (ptr, length) => mountViewExport(ptr, length)))
573
+ );
574
+ drainOpenURLs();
575
+ return tree;
576
+ },
577
+ hasView: () => hasViewExport() === 1,
578
+ deliver: (handlerId2, payload) => {
579
+ const tree = readTree(
580
+ readBuffer(
581
+ withPayload(
582
+ payload,
583
+ (ptr, length) => (
584
+ // handler ids are opaque to the tenant: they come from the tree
585
+ // this instance just returned and they are only meaningful to it
586
+ event(handlerId2, ptr, length)
587
+ )
588
+ )
589
+ )
590
+ );
591
+ drainOpenURLs();
592
+ return tree;
593
+ },
594
+ exportState: () => readBuffer(stateExport()),
595
+ importState: (state) => {
596
+ withPayload(JSON.parse(state), (ptr, length) => {
597
+ stateImport(ptr, length);
598
+ return 0;
599
+ });
600
+ }
601
+ };
602
+ }
603
+ var compiledModules = /* @__PURE__ */ new Map();
604
+ function decodeBundle(moduleUrl, packed) {
605
+ if (packed === void 0) return null;
606
+ const files = {};
607
+ for (const [name, base64] of Object.entries(packed)) {
608
+ try {
609
+ files[name] = decodeBase64(base64);
610
+ } catch (error) {
611
+ throw new Error(
612
+ `swift bundle file '${name}' is not decodable: ${error instanceof Error ? error.message : String(error)}`
613
+ );
614
+ }
615
+ }
616
+ if (Object.keys(files).length === 0) return null;
617
+ return { files, argv0: resArgv0(moduleUrl) };
618
+ }
619
+ function compile(url) {
620
+ const cached = compiledModules.get(url);
621
+ if (cached) return cached;
622
+ const pending = fetch(url).then((response) => {
623
+ if (!response.ok) {
624
+ throw new Error(`swift artifact ${url} answered ${response.status}`);
625
+ }
626
+ return response.arrayBuffer();
627
+ }).then((bytes) => WebAssembly.compile(bytes));
628
+ compiledModules.set(url, pending);
629
+ return pending;
630
+ }
631
+ var HIERARCHICAL = /* @__PURE__ */ new Map([
632
+ ["label", "primary"],
633
+ ["secondaryLabel", "secondary"]
634
+ ]);
635
+ function withAlpha(color, alpha) {
636
+ const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color);
637
+ if (hex) {
638
+ const digits = hex[1];
639
+ const full = digits.length === 3 ? digits.split("").map((digit) => digit + digit).join("") : digits;
640
+ const value = Number.parseInt(full, 16);
641
+ return `rgba(${value >> 16 & 255},${value >> 8 & 255},${value & 255},${alpha})`;
642
+ }
643
+ const rgba = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)$/.exec(color);
644
+ if (rgba) {
645
+ return `rgba(${rgba[1]},${rgba[2]},${rgba[3]},${Number(rgba[4]) * alpha})`;
646
+ }
647
+ throw new Error(`swift color ${color} cannot take opacity ${alpha}`);
648
+ }
649
+ function splitColor(value) {
650
+ const at = value.lastIndexOf("@");
651
+ return at === -1 ? { name: value, alpha: 1 } : { name: value.slice(0, at), alpha: Number(value.slice(at + 1)) };
652
+ }
653
+ function resolveColor(value) {
654
+ const { name, alpha } = splitColor(value);
655
+ const resolved = (0, import_react_native.PlatformColor)(name);
656
+ if (alpha === 1) return resolved;
657
+ if (typeof resolved === "string") return withAlpha(resolved, alpha);
658
+ if (isRecord(resolved) && isRecord(resolved.dynamic)) {
659
+ const variants = {};
660
+ for (const [scheme, variant] of Object.entries(resolved.dynamic)) {
661
+ if (typeof variant !== "string") {
662
+ throw new Error(`swift color ${name} has a non-string ${scheme} variant`);
663
+ }
664
+ variants[scheme] = withAlpha(variant, alpha);
665
+ }
666
+ return { dynamic: variants };
667
+ }
668
+ throw new Error(`swift color ${name} cannot take opacity ${alpha}`);
669
+ }
670
+ function resolveModifier(modifier) {
671
+ const color = modifier.color;
672
+ if (typeof color !== "string") {
673
+ const glass = modifier.glass;
674
+ if (modifier.$type === "glassEffect" && isRecord(glass) && typeof glass.tint === "string") {
675
+ return { ...modifier, glass: { ...glass, tint: resolveColor(glass.tint) } };
676
+ }
677
+ return modifier;
678
+ }
679
+ const { name, alpha } = splitColor(color);
680
+ const level = modifier.$type === "foregroundStyle" ? HIERARCHICAL.get(name) : void 0;
681
+ if (level !== void 0 && alpha === 1) {
682
+ return {
683
+ $type: "foregroundStyle",
684
+ styleType: "hierarchical",
685
+ hierarchicalStyle: level
686
+ };
687
+ }
688
+ return { ...modifier, color: resolveColor(color) };
689
+ }
690
+ var SwiftResourcesContext = (0, import_react.createContext)(void 0);
691
+ function SwiftImage(props) {
692
+ const table = (0, import_react.useContext)(SwiftResourcesContext);
693
+ const { source, ...rest } = props ?? {};
694
+ const resolved = resolveImageSource(source, table ?? {}, (name) => {
695
+ console.error(`swift: no bundle asset named '${name}' in this mount's resources`);
696
+ });
697
+ return (0, import_react.createElement)(import_ui.Image, {
698
+ ...rest,
699
+ ...source === void 0 ? {} : { source: resolved }
700
+ });
701
+ }
702
+ var NODE_COMPONENTS = {
703
+ Alert: SwiftAlert,
704
+ BottomSheet: import_ui.BottomSheet,
705
+ Button: import_ui.Button,
706
+ Capsule: import_ui.Capsule,
707
+ Circle: import_ui.Circle,
708
+ ConfirmationDialog: import_ui.ConfirmationDialog,
709
+ ContextMenu: import_ui.ContextMenu,
710
+ DatePicker: import_ui.DatePicker,
711
+ Divider: import_ui.Divider,
712
+ Ellipse: import_ui.Ellipse,
713
+ Form: import_ui.Form,
714
+ GeometryReader: import_ui.GeometryReader,
715
+ GlassEffectContainer: import_ui.GlassEffectContainer,
716
+ Group: import_ui.Group,
717
+ HStack: import_ui.HStack,
718
+ Image: SwiftImage,
719
+ Label: import_ui.Label,
720
+ LazyVStack: import_ui.LazyVStack,
721
+ LinearGradient: import_ui.LinearGradient,
722
+ List: import_ui.List,
723
+ Menu: import_ui.Menu,
724
+ Path: import_ui.Path,
725
+ Picker: import_ui.Picker,
726
+ ProgressView: import_ui.ProgressView,
727
+ Rectangle: import_ui.Rectangle,
728
+ RoundedRectangle: import_ui.RoundedRectangle,
729
+ ScrollView: import_ui.ScrollView,
730
+ Section: import_ui.Section,
731
+ SecureField: import_ui.SecureField,
732
+ Slider: import_ui.Slider,
733
+ Spacer: import_ui.Spacer,
734
+ Stepper: import_ui.Stepper,
735
+ SwipeActions: import_ui.SwipeActions,
736
+ Text: import_ui.Text,
737
+ TextField: import_ui.TextField,
738
+ Toggle: import_ui.Toggle,
739
+ Tab: SwiftTabScene,
740
+ TabView: SwiftTabView,
741
+ VStack: import_ui.VStack,
742
+ ZStack: import_ui.ZStack
743
+ };
744
+ var TEXT_STYLE_SIZES = /* @__PURE__ */ new Map([
745
+ ["largeTitle", 34],
746
+ ["title", 28],
747
+ ["title2", 22],
748
+ ["title3", 20],
749
+ ["headline", 17],
750
+ ["subheadline", 15],
751
+ ["body", 17],
752
+ ["callout", 16],
753
+ ["footnote", 13],
754
+ ["caption", 12],
755
+ ["caption2", 11]
756
+ ]);
757
+ var FONT_WEIGHTS = /* @__PURE__ */ new Map([
758
+ ["ultraLight", "100"],
759
+ ["thin", "200"],
760
+ ["light", "300"],
761
+ ["regular", "400"],
762
+ ["medium", "500"],
763
+ ["semibold", "600"],
764
+ ["bold", "700"],
765
+ ["heavy", "800"],
766
+ ["black", "900"]
767
+ ]);
768
+ function fontModifier(modifiers) {
769
+ return modifiers?.find((modifier) => modifier.$type === "font");
770
+ }
771
+ function fontStyle(font) {
772
+ if (!font) return void 0;
773
+ const style = {};
774
+ if (typeof font.size === "number") style.fontSize = font.size;
775
+ else if (typeof font.style === "string") {
776
+ const size = TEXT_STYLE_SIZES.get(font.style);
777
+ if (size === void 0) throw new Error(`swift font style ${font.style} has no size`);
778
+ style.fontSize = size;
779
+ }
780
+ if (typeof font.weight === "string") {
781
+ const weight = FONT_WEIGHTS.get(font.weight);
782
+ if (weight === void 0)
783
+ throw new Error(`swift font weight ${font.weight} has no value`);
784
+ style.fontWeight = weight;
785
+ }
786
+ return style;
787
+ }
788
+ function sameValue(a, b) {
789
+ if (a === b) return true;
790
+ if (Array.isArray(a) && Array.isArray(b)) {
791
+ if (a.length !== b.length) return false;
792
+ for (let index = 0; index < a.length; index += 1) {
793
+ if (!sameValue(a[index], b[index])) return false;
794
+ }
795
+ return true;
796
+ }
797
+ if (isRecord(a) && isRecord(b)) {
798
+ const keys = Object.keys(a);
799
+ if (keys.length !== Object.keys(b).length) return false;
800
+ for (const key of keys) {
801
+ if (!sameValue(a[key], b[key])) return false;
802
+ }
803
+ return true;
804
+ }
805
+ return false;
806
+ }
807
+ function sameNode(a, b) {
808
+ if (a === b) return true;
809
+ if (a.t !== b.t || a.id !== b.id) return false;
810
+ if (!sameValue(a.p, b.p) || !sameValue(a.m, b.m) || !sameValue(a.h, b.h)) return false;
811
+ const left = a.c ?? [];
812
+ const right = b.c ?? [];
813
+ if (left.length !== right.length) return false;
814
+ for (let index = 0; index < left.length; index += 1) {
815
+ if (!sameNode(left[index], right[index])) return false;
816
+ }
817
+ return true;
818
+ }
819
+ function handlerId(node, name) {
820
+ return node.h?.[name];
821
+ }
822
+ function pressProps(node, deliver) {
823
+ const presses = [];
824
+ for (const name of ["onPress", "onTap"]) {
825
+ const id = handlerId(node, name);
826
+ if (id !== void 0) presses.push(id);
827
+ }
828
+ if (presses.length === 0) return {};
829
+ return {
830
+ onPress: () => {
831
+ for (const id of presses) deliver(id, null);
832
+ }
833
+ };
834
+ }
835
+ function SwiftTabScene({ children }) {
836
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
837
+ }
838
+ function SwiftTabView({
839
+ tabs,
840
+ selection,
841
+ onSelect,
842
+ modifiers,
843
+ children
844
+ }) {
845
+ const scenes = import_react.Children.toArray(children);
846
+ const routes = tabs.map((tab, index2) => ({
847
+ key: tab.testID,
848
+ name: tab.title ?? `tab-${index2}`,
849
+ title: tab.title,
850
+ sfSymbol: tab.systemImage,
851
+ testID: tab.testID
852
+ }));
853
+ const index = selection >= 0 && selection < routes.length ? selection : 0;
854
+ (0, import_react.useEffect)(() => {
855
+ if (selection !== index) onSelect?.(index);
856
+ }, [selection, index, onSelect]);
857
+ const bar = (0, import_react.createElement)(import_react_native_bottom_tabs.default, {
858
+ navigationState: { index, routes },
859
+ renderScene: ({ route }) => scenes[routes.findIndex((candidate) => candidate.key === route.key)],
860
+ onIndexChange: (next) => onSelect?.(next),
861
+ getLabelText: ({ route }) => route.title ?? route.key,
862
+ getIcon: ({ route }) => route.sfSymbol ? { sfSymbol: route.sfSymbol } : void 0,
863
+ getTestID: ({ route }) => route.testID
864
+ });
865
+ return (0, import_react.createElement)(
866
+ import_ui.VStack,
867
+ {
868
+ ...modifiers?.length ? { modifiers } : {},
869
+ style: {
870
+ alignSelf: "stretch",
871
+ alignItems: "stretch",
872
+ flexGrow: 1,
873
+ flexShrink: 1,
874
+ flexBasis: "auto"
875
+ }
876
+ },
877
+ bar
878
+ );
879
+ }
880
+ function SwiftAlert({
881
+ title,
882
+ message,
883
+ buttons,
884
+ onButtonPress,
885
+ onDismiss
886
+ }) {
887
+ const latest = (0, import_react.useRef)({ title, message, buttons, onButtonPress, onDismiss });
888
+ (0, import_react.useEffect)(() => {
889
+ latest.current = { title, message, buttons, onButtonPress, onDismiss };
890
+ });
891
+ (0, import_react.useEffect)(() => {
892
+ const handle = (0, import_runtime.getNativeAlerts)().show(
893
+ latest.current.title,
894
+ latest.current.message,
895
+ latest.current.buttons.map((button, index) => ({
896
+ text: button.text,
897
+ style: button.role === "destructive" ? "destructive" : button.role === "cancel" ? "cancel" : "default",
898
+ // the tapped action runs its swift closure and clears isPresented,
899
+ // which is the order the system alert uses on the way out: the action
900
+ // body is the last thing that runs with the alert still up. the
901
+ // handlers come off the ref at tap time, not from this render.
902
+ onPress: () => {
903
+ latest.current.onButtonPress?.(index);
904
+ latest.current.onDismiss?.();
905
+ }
906
+ }))
907
+ );
908
+ return () => {
909
+ (0, import_runtime.getNativeAlerts)().dismiss(handle);
910
+ };
911
+ }, []);
912
+ return null;
913
+ }
914
+ function readAlertButtons(value) {
915
+ if (!Array.isArray(value)) return [];
916
+ return value.map((entry) => {
917
+ if (!isRecord(entry)) return {};
918
+ return {
919
+ ...typeof entry.text === "string" ? { text: entry.text } : {},
920
+ ...typeof entry.role === "string" ? { role: entry.role } : {}
921
+ };
922
+ });
923
+ }
924
+ function nodeProps(node, deliver) {
925
+ const props = node.p ?? {};
926
+ switch (node.t) {
927
+ case "Text": {
928
+ const style = fontStyle(fontModifier(node.m));
929
+ return {
930
+ children: typeof props.children === "string" ? props.children : "",
931
+ ...style ? { style } : {},
932
+ ...pressProps(node, deliver)
933
+ };
934
+ }
935
+ case "Image": {
936
+ const font = fontModifier(node.m);
937
+ const size = typeof font?.size === "number" ? font.size : void 0;
938
+ return {
939
+ ...typeof props.systemName === "string" ? { systemName: props.systemName } : {},
940
+ // a bundle asset name rides as the kit image source; the kit paints
941
+ // resolved { uri } sources and keeps its placeholder for names the
942
+ // table could not resolve.
943
+ ...typeof props.name === "string" ? { source: props.name } : {},
944
+ ...props.resizable === true ? { resizable: true } : {},
945
+ ...typeof props.renderingMode === "string" ? { renderingMode: props.renderingMode } : {},
946
+ ...size === void 0 ? {} : { size },
947
+ ...pressProps(node, deliver)
948
+ };
949
+ }
950
+ case "Toggle": {
951
+ const onValueChange = handlerId(node, "onValueChange");
952
+ return {
953
+ isOn: props.value === true,
954
+ ...onValueChange === void 0 ? {} : { onIsOnChange: (value) => deliver(onValueChange, value) },
955
+ // the gesture replaces the row's own press (a label tap runs it and
956
+ // does not toggle); the switch keeps toggling through onValueChange.
957
+ ...pressProps(node, deliver)
958
+ };
959
+ }
960
+ case "TextField": {
961
+ const onChangeText = handlerId(node, "onChangeText");
962
+ return {
963
+ ...typeof props.placeholder === "string" ? { placeholder: props.placeholder } : {},
964
+ ...typeof props.defaultValue === "string" ? { defaultValue: props.defaultValue } : {},
965
+ ...onChangeText === void 0 ? {} : { onChangeText: (value) => deliver(onChangeText, value) }
966
+ };
967
+ }
968
+ case "Slider": {
969
+ const onValueChange = handlerId(node, "onValueChange");
970
+ return {
971
+ value: typeof props.value === "number" ? props.value : 0,
972
+ min: typeof props.min === "number" ? props.min : 0,
973
+ max: typeof props.max === "number" ? props.max : 1,
974
+ ...onValueChange === void 0 ? {} : { onValueChange: (value) => deliver(onValueChange, value) },
975
+ // a tap runs the gesture and leaves the value alone: only a drag
976
+ // moves it, so the gesture rides onPress beside the drag handler.
977
+ ...pressProps(node, deliver)
978
+ };
979
+ }
980
+ case "Button":
981
+ return pressProps(node, deliver);
982
+ case "EditButton":
983
+ return pressProps(node, deliver);
984
+ case "TabView": {
985
+ const onSelect = handlerId(node, "onSelect");
986
+ const tabs = (node.c ?? []).map((tab, index) => {
987
+ const tabProps = tab.p ?? {};
988
+ return {
989
+ ...typeof tabProps.title === "string" ? { title: tabProps.title } : {},
990
+ ...typeof tabProps.systemImage === "string" ? { systemImage: tabProps.systemImage } : {},
991
+ ...typeof tabProps.role === "string" ? { role: tabProps.role } : {},
992
+ testID: `swift-tab-${index}`
993
+ };
994
+ });
995
+ return {
996
+ tabs,
997
+ selection: typeof props.selection === "number" ? props.selection : 0,
998
+ ...onSelect === void 0 ? {} : { onSelect: (index) => deliver(onSelect, index) }
999
+ };
1000
+ }
1001
+ case "BottomSheet": {
1002
+ const onDismiss = handlerId(node, "onDismiss");
1003
+ const detents = (node.c ?? []).flatMap((child) => nodeModifiers(child) ?? []).filter((modifier) => modifier.$type === "presentationDetents");
1004
+ return {
1005
+ isOpened: props.isOpened === true,
1006
+ ...detents.length === 0 ? {} : { modifiers: detents },
1007
+ ...onDismiss === void 0 ? {} : { onDismiss: () => deliver(onDismiss, null) }
1008
+ };
1009
+ }
1010
+ case "ConfirmationDialog": {
1011
+ return { isPresented: props.isPresented === true };
1012
+ }
1013
+ case "Alert": {
1014
+ const onButtonPress = handlerId(node, "onButtonPress");
1015
+ const onDismiss = handlerId(node, "onDismiss");
1016
+ return {
1017
+ title: typeof props.title === "string" ? props.title : "",
1018
+ ...typeof props.message === "string" ? { message: props.message } : {},
1019
+ buttons: readAlertButtons(props.buttons),
1020
+ ...onButtonPress === void 0 ? {} : { onButtonPress: (index) => deliver(onButtonPress, index) },
1021
+ ...onDismiss === void 0 ? {} : { onDismiss: () => deliver(onDismiss, null) }
1022
+ };
1023
+ }
1024
+ case "SecureField": {
1025
+ const onChangeText = handlerId(node, "onChangeText");
1026
+ return {
1027
+ ...typeof props.placeholder === "string" ? { placeholder: props.placeholder } : {},
1028
+ ...typeof props.prompt === "string" ? { prompt: props.prompt } : {},
1029
+ ...typeof props.defaultValue === "string" ? { defaultValue: props.defaultValue } : {},
1030
+ ...onChangeText === void 0 ? {} : { onChangeText: (value) => deliver(onChangeText, value) }
1031
+ };
1032
+ }
1033
+ case "Picker": {
1034
+ const onSelectionChange = handlerId(node, "onSelectionChange");
1035
+ return {
1036
+ ...typeof props.title === "string" ? { label: props.title } : {},
1037
+ ...props.selection === void 0 ? {} : { selection: props.selection },
1038
+ ...onSelectionChange === void 0 ? {} : {
1039
+ onSelectionChange: (value) => deliver(onSelectionChange, value)
1040
+ }
1041
+ };
1042
+ }
1043
+ case "DatePicker": {
1044
+ return {
1045
+ ...typeof props.title === "string" ? { label: props.title } : {},
1046
+ // the wire carries epoch seconds; the kit takes a Date and formats it
1047
+ ...typeof props.value === "number" ? { value: new Date(props.value * 1e3) } : {},
1048
+ ...Array.isArray(props.components) ? { components: props.components } : {}
1049
+ };
1050
+ }
1051
+ case "GlassEffectContainer":
1052
+ return {};
1053
+ case "ProgressView":
1054
+ return {
1055
+ ...typeof props.title === "string" ? { label: props.title } : {},
1056
+ ...typeof props.value === "number" || props.value === null ? { value: props.value } : {},
1057
+ ...typeof props.total === "number" ? { total: props.total } : {}
1058
+ };
1059
+ default:
1060
+ return { ...props, ...pressProps(node, deliver) };
1061
+ }
1062
+ }
1063
+ function numberProp(node, name) {
1064
+ const value = node.p?.[name];
1065
+ return typeof value === "number" ? value : 0;
1066
+ }
1067
+ function menuItemLabel(node) {
1068
+ const [only] = node.c ?? [];
1069
+ if (node.t !== "Button" || node.c?.length !== 1 || !only) return void 0;
1070
+ if (only.t === "Text" && typeof only.p?.children === "string") {
1071
+ return { label: only.p.children };
1072
+ }
1073
+ if (only.t === "Label" && typeof only.p?.title === "string" && (only.p?.systemImage === void 0 || typeof only.p?.systemImage === "string")) {
1074
+ return {
1075
+ label: only.p.title,
1076
+ ...typeof only.p?.systemImage === "string" ? { systemImage: only.p.systemImage } : {}
1077
+ };
1078
+ }
1079
+ return void 0;
1080
+ }
1081
+ function renderMenuItem(node, deliver, cache) {
1082
+ const item = menuItemLabel(node);
1083
+ if (item !== void 0) {
1084
+ const modifiers = nodeModifiers(node);
1085
+ return (0, import_react.createElement)(import_ui.Button, {
1086
+ key: node.id,
1087
+ ...item,
1088
+ ...modifiers === void 0 ? {} : { modifiers },
1089
+ ...pressProps(node, deliver)
1090
+ });
1091
+ }
1092
+ return renderNode(node, deliver, cache);
1093
+ }
1094
+ function renderMenu(node, deliver, cache) {
1095
+ const labelCount = numberProp(node, "labelCount");
1096
+ const kids = node.c ?? [];
1097
+ const labels = kids.slice(0, labelCount);
1098
+ const items = kids.slice(labelCount);
1099
+ const [only] = labels;
1100
+ const onlyText = labels.length === 1 && only.t === "Text" && typeof only.p?.children === "string" ? only.p.children : void 0;
1101
+ const onlyLabel = labels.length === 1 && only.t === "Label" && typeof only.p?.title === "string" && (only.p?.systemImage === void 0 || typeof only.p?.systemImage === "string") ? only : void 0;
1102
+ const label = onlyText !== void 0 || onlyLabel !== void 0 ? void 0 : (0, import_react.createElement)(
1103
+ import_react.Fragment,
1104
+ null,
1105
+ ...labels.map((child) => renderNode(child, deliver, cache))
1106
+ );
1107
+ const labelModifiers = labels.length === 1 ? nodeModifiers(only) : void 0;
1108
+ const modifiers = nodeModifiers(node);
1109
+ const combined = [...labelModifiers ?? [], ...modifiers ?? []];
1110
+ return (0, import_react.createElement)(
1111
+ import_ui.Menu,
1112
+ {
1113
+ key: node.id,
1114
+ ...combined.length > 0 ? { modifiers: combined } : {},
1115
+ ...onlyText !== void 0 ? { label: onlyText } : {},
1116
+ ...onlyLabel !== void 0 ? {
1117
+ label: onlyLabel.p?.title,
1118
+ ...typeof onlyLabel.p?.systemImage === "string" ? { systemImage: onlyLabel.p.systemImage } : {}
1119
+ } : {},
1120
+ ...label === void 0 ? {} : { label }
1121
+ },
1122
+ ...items.map((child) => renderMenuItem(child, deliver))
1123
+ );
1124
+ }
1125
+ function renderContextMenu(node, deliver, cache) {
1126
+ const kids = node.c ?? [];
1127
+ const contentCount = numberProp(node, "contentCount");
1128
+ const itemCount = numberProp(node, "itemCount");
1129
+ const content = kids.slice(0, contentCount);
1130
+ const items = kids.slice(contentCount, contentCount + itemCount);
1131
+ const preview = kids.slice(contentCount + itemCount);
1132
+ const modifiers = nodeModifiers(node);
1133
+ return (0, import_react.createElement)(
1134
+ import_ui.ContextMenu,
1135
+ {
1136
+ key: node.id,
1137
+ ...modifiers === void 0 ? {} : { modifiers }
1138
+ },
1139
+ (0, import_react.createElement)(
1140
+ import_ui.Trigger,
1141
+ { key: `${node.id}/trigger` },
1142
+ ...content.map((child) => renderNode(child, deliver, cache))
1143
+ ),
1144
+ (0, import_react.createElement)(
1145
+ import_ui.Items,
1146
+ { key: `${node.id}/items` },
1147
+ ...items.map((child) => renderMenuItem(child, deliver))
1148
+ ),
1149
+ ...preview.length > 0 ? [
1150
+ (0, import_react.createElement)(
1151
+ import_ui.Preview,
1152
+ { key: `${node.id}/preview` },
1153
+ ...preview.map((child) => renderNode(child, deliver, cache))
1154
+ )
1155
+ ] : []
1156
+ );
1157
+ }
1158
+ function renderSwipeActions(node, deliver, cache) {
1159
+ const kids = node.c ?? [];
1160
+ const content = kids.slice(0, numberProp(node, "contentCount"));
1161
+ const actions = kids.slice(numberProp(node, "contentCount"));
1162
+ const modifiers = nodeModifiers(node);
1163
+ const { Actions } = import_ui.SwipeActions;
1164
+ return (0, import_react.createElement)(
1165
+ import_ui.SwipeActions,
1166
+ {
1167
+ key: node.id,
1168
+ ...modifiers === void 0 ? {} : { modifiers }
1169
+ },
1170
+ ...content.map((child) => renderNode(child, deliver, cache)),
1171
+ ...actions.length > 0 ? [
1172
+ (0, import_react.createElement)(
1173
+ Actions,
1174
+ {
1175
+ key: `${node.id}/actions`,
1176
+ edge: node.p?.edge === "leading" ? "leading" : "trailing",
1177
+ ...typeof node.p?.allowsFullSwipe === "boolean" ? { allowsFullSwipe: node.p.allowsFullSwipe } : {}
1178
+ },
1179
+ ...actions.map((child) => renderNode(child, deliver, cache))
1180
+ )
1181
+ ] : []
1182
+ );
1183
+ }
1184
+ function ClosureStepper({
1185
+ deliver,
1186
+ onIncrement,
1187
+ onDecrement,
1188
+ ...rest
1189
+ }) {
1190
+ const last = (0, import_react.useRef)(0);
1191
+ return (0, import_react.createElement)(import_ui.Stepper, {
1192
+ ...rest,
1193
+ onValueChange: (next) => {
1194
+ if (next > last.current && onIncrement !== void 0) {
1195
+ deliver(onIncrement, null);
1196
+ } else if (next < last.current && onDecrement !== void 0) {
1197
+ deliver(onDecrement, null);
1198
+ }
1199
+ last.current = next;
1200
+ }
1201
+ });
1202
+ }
1203
+ function renderStepper(node, deliver, cache) {
1204
+ const kids = node.c ?? [];
1205
+ const label = kids.length === 0 ? void 0 : (0, import_react.createElement)(
1206
+ import_react.Fragment,
1207
+ null,
1208
+ ...kids.map((child) => renderNode(child, deliver, cache))
1209
+ );
1210
+ const modifiers = nodeModifiers(node);
1211
+ const shared = {
1212
+ key: node.id,
1213
+ ...modifiers === void 0 ? {} : { modifiers },
1214
+ ...label === void 0 ? {} : { label },
1215
+ ...typeof node.p?.min === "number" ? { min: node.p.min } : {},
1216
+ ...typeof node.p?.max === "number" ? { max: node.p.max } : {},
1217
+ ...typeof node.p?.step === "number" ? { step: node.p.step } : {}
1218
+ };
1219
+ const onValueChange = handlerId(node, "onValueChange");
1220
+ if (onValueChange !== void 0) {
1221
+ return (0, import_react.createElement)(import_ui.Stepper, {
1222
+ ...shared,
1223
+ ...typeof node.p?.value === "number" ? { value: node.p.value } : {},
1224
+ onValueChange: (value) => deliver(onValueChange, value)
1225
+ });
1226
+ }
1227
+ return (0, import_react.createElement)(ClosureStepper, {
1228
+ ...shared,
1229
+ deliver,
1230
+ ...handlerId(node, "onIncrement") === void 0 ? {} : { onIncrement: handlerId(node, "onIncrement") },
1231
+ ...handlerId(node, "onDecrement") === void 0 ? {} : { onDecrement: handlerId(node, "onDecrement") }
1232
+ });
1233
+ }
1234
+ function buttonModifier(modifier) {
1235
+ if (modifier.$type === "glassEffect") {
1236
+ const glass = modifier.glass;
1237
+ const variant = isRecord(glass) && typeof glass.variant === "string" ? glass.variant : "regular";
1238
+ return variant === "identity" ? modifier : { $type: "buttonStyle", style: "glass" };
1239
+ }
1240
+ if (modifier.$type === "foregroundStyle" && modifier.color !== void 0) {
1241
+ return { $type: "tint", color: modifier.color };
1242
+ }
1243
+ return modifier;
1244
+ }
1245
+ function nodeModifiers(node) {
1246
+ const resolved = node.m?.map(resolveModifier);
1247
+ if (node.t !== "Button") return resolved;
1248
+ return resolved?.map(buttonModifier);
1249
+ }
1250
+ function dialogChildren(node, deliver) {
1251
+ const children = node.c?.map((child) => renderNode(child, deliver));
1252
+ const props = node.p ?? {};
1253
+ if (props.showsTitle !== true || typeof props.title !== "string") return children;
1254
+ const title = (0, import_react.createElement)(import_ui.Text, { key: `${node.id}/title`, children: props.title });
1255
+ return [title, ...children ?? []];
1256
+ }
1257
+ var Stack = (0, import_native_stack.createNativeStackNavigator)();
1258
+ var NAVIGATOR_FILL = { flex: 1, alignSelf: "stretch" };
1259
+ function readNodes(value) {
1260
+ if (!Array.isArray(value)) return [];
1261
+ return value.map(readNode);
1262
+ }
1263
+ function hasPrefix(names, of) {
1264
+ return names.every((name, index) => of[index] === name);
1265
+ }
1266
+ function sameNames(a, b) {
1267
+ return a.length === b.length && a.every((name, index) => b[index] === name);
1268
+ }
1269
+ function commonPrefixLength(a, b) {
1270
+ let length = 0;
1271
+ while (length < a.length && length < b.length && a[length] === b[length]) length++;
1272
+ return length;
1273
+ }
1274
+ function reconcilePlan(names, desired) {
1275
+ const common = commonPrefixLength(names, desired);
1276
+ if (common === names.length && common === desired.length) return { kind: "in-step" };
1277
+ if (common === names.length) return { kind: "push" };
1278
+ if (common === desired.length) return { kind: "pop" };
1279
+ const top = desired[desired.length - 1];
1280
+ return { kind: "replace", replaceAnimation: names.includes(top) ? "pop" : "push" };
1281
+ }
1282
+ function resolveLargeTitles(modes) {
1283
+ let previous = true;
1284
+ return modes.map((mode) => {
1285
+ const large = mode === "inline" ? false : mode === "large" ? true : previous;
1286
+ previous = large;
1287
+ return large;
1288
+ });
1289
+ }
1290
+ function screenOptions(node, deliver, largeTitle, replaceAnimation) {
1291
+ const props = node.p ?? {};
1292
+ const options = {
1293
+ title: typeof props.title === "string" ? props.title : "",
1294
+ headerLargeTitleEnabled: largeTitle
1295
+ };
1296
+ if (replaceAnimation !== void 0) options.animationTypeForReplace = replaceAnimation;
1297
+ const leading = readNodes(props.leading);
1298
+ const trailing = readNodes(props.trailing);
1299
+ const principal = readNodes(props.principal);
1300
+ const render = (nodes) => () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: nodes.map((child) => renderNode(child, deliver)) });
1301
+ if (leading.length > 0) {
1302
+ options.headerLeft = render(leading);
1303
+ options.headerBackVisible = true;
1304
+ }
1305
+ if (trailing.length > 0) options.headerRight = render(trailing);
1306
+ if (principal.length > 0) options.headerTitle = render(principal);
1307
+ return options;
1308
+ }
1309
+ function SwiftScreen({
1310
+ node,
1311
+ navigation,
1312
+ deliver,
1313
+ report
1314
+ }) {
1315
+ const routes = (0, import_native.useNavigationState)(
1316
+ (state) => state.routes.map((route) => route.name).join("\0")
1317
+ );
1318
+ (0, import_react.useEffect)(() => {
1319
+ report(navigation, routes === "" ? [] : routes.split("\0"));
1320
+ });
1321
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: node.c?.map((child) => renderNode(child, deliver)) });
1322
+ }
1323
+ function NavigationStackHost({ node, deliver }) {
1324
+ const screens = (node.c ?? []).filter((child) => child.t === "NavigationScreen");
1325
+ const desired = screens.map((screen) => screen.id);
1326
+ const largeTitles = resolveLargeTitles(
1327
+ screens.map((screen) => {
1328
+ const mode = screen.p?.titleDisplayMode;
1329
+ return typeof mode === "string" ? mode : void 0;
1330
+ })
1331
+ );
1332
+ const onPop = node.h?.onPop;
1333
+ const reportRef = (0, import_react.useRef)(null);
1334
+ const reportedRef = (0, import_react.useRef)([]);
1335
+ const expectedRef = (0, import_react.useRef)(null);
1336
+ const syncedRef = (0, import_react.useRef)(null);
1337
+ const [, rerender] = (0, import_react.useReducer)((count) => count + 1, 0);
1338
+ const report = (0, import_react.useCallback)((navigation, names) => {
1339
+ const previous = reportRef.current;
1340
+ reportRef.current = { navigation, names };
1341
+ if (previous && sameNames(previous.names, names)) return;
1342
+ rerender();
1343
+ }, []);
1344
+ const reported = reportRef.current?.names ?? [];
1345
+ const plan = reportRef.current ? reconcilePlan(reported, desired) : null;
1346
+ const replaceTop = plan?.kind === "replace" ? desired[desired.length - 1] : void 0;
1347
+ (0, import_react.useEffect)(() => {
1348
+ const current = reportRef.current;
1349
+ if (!current) return;
1350
+ const names = current.names;
1351
+ const previous = reportedRef.current;
1352
+ const isReport = !sameNames(previous, names);
1353
+ if (isReport) reportedRef.current = names;
1354
+ const expected = expectedRef.current;
1355
+ if (expected) {
1356
+ if (sameNames(expected, names)) expectedRef.current = null;
1357
+ else if (!isReport) return;
1358
+ else expectedRef.current = null;
1359
+ }
1360
+ const dropped = previous.slice(names.length);
1361
+ const settled = syncedRef.current;
1362
+ const navigatorPopped = isReport && dropped.length > 0 && settled !== null && sameNames(settled, desired) && hasPrefix(names, desired) && hasPrefix(desired.slice(names.length), dropped);
1363
+ if (navigatorPopped && onPop !== void 0) {
1364
+ deliver(onPop, { count: dropped.length });
1365
+ return;
1366
+ }
1367
+ const next = reconcilePlan(names, desired);
1368
+ if (next.kind === "in-step") {
1369
+ expectedRef.current = null;
1370
+ syncedRef.current = desired;
1371
+ return;
1372
+ }
1373
+ expectedRef.current = desired;
1374
+ if (next.kind === "push") {
1375
+ for (const name of desired.slice(names.length)) current.navigation.push(name);
1376
+ return;
1377
+ }
1378
+ if (next.kind === "pop") {
1379
+ current.navigation.pop(names.length - desired.length);
1380
+ return;
1381
+ }
1382
+ current.navigation.reset({
1383
+ index: Math.max(0, desired.length - 1),
1384
+ routes: desired.map((name) => ({ name }))
1385
+ });
1386
+ });
1387
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Stack.Navigator, { initialRouteName: desired[0], children: screens.map((screen, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1388
+ Stack.Screen,
1389
+ {
1390
+ name: screen.id,
1391
+ options: screenOptions(
1392
+ screen,
1393
+ deliver,
1394
+ largeTitles[index],
1395
+ screen.id === replaceTop ? plan?.kind === "replace" ? plan.replaceAnimation : void 0 : void 0
1396
+ ),
1397
+ children: (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1398
+ SwiftScreen,
1399
+ {
1400
+ node: screen,
1401
+ navigation: props.navigation,
1402
+ deliver,
1403
+ report
1404
+ }
1405
+ )
1406
+ },
1407
+ screen.id
1408
+ )) });
1409
+ }
1410
+ var REGULAR_WIDTH = 768;
1411
+ function SplitViewHost({
1412
+ node,
1413
+ deliver,
1414
+ cache
1415
+ }) {
1416
+ const { width } = (0, import_react_native.useWindowDimensions)();
1417
+ const screens = (node.c ?? []).filter((child) => child.t === "NavigationScreen");
1418
+ if (width < REGULAR_WIDTH) {
1419
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: NAVIGATOR_FILL, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node, deliver }) });
1420
+ }
1421
+ const sidebar = screens[0];
1422
+ const pushed = screens.slice(1);
1423
+ const detailProp = node.p?.detail;
1424
+ const detail = isRecord(detailProp) && detailProp.t === "SplitDetail" ? readNodes(detailProp.c) : [];
1425
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: { flex: 1, flexDirection: "row", alignSelf: "stretch" }, children: [
1426
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { width: 320 }, children: sidebar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node: { ...node, c: [sidebar] }, deliver }) : null }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { flex: 1 }, children: pushed.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node: { ...node, c: pushed }, deliver }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: detail.map((child) => renderNode(child, deliver, cache)) }) })
1428
+ ] });
1429
+ }
1430
+ function SwiftAppear({
1431
+ node,
1432
+ deliver,
1433
+ children
1434
+ }) {
1435
+ const onAppear = handlerId(node, "onAppear");
1436
+ const onDisappear = handlerId(node, "onDisappear");
1437
+ (0, import_react.useEffect)(() => {
1438
+ if (onAppear !== void 0) deliver(onAppear, null);
1439
+ return () => {
1440
+ if (onDisappear !== void 0) deliver(onDisappear, null);
1441
+ };
1442
+ }, []);
1443
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
1444
+ }
1445
+ function renderNode(node, deliver, cache) {
1446
+ const cached = cache?.entries.get(node.id);
1447
+ if (cached && sameNode(cached.node, node)) return cached.element;
1448
+ const built = buildNode(node, deliver, cache);
1449
+ const element = node.h?.onAppear !== void 0 || node.h?.onDisappear !== void 0 ? (0, import_react.createElement)(SwiftAppear, { key: node.id, node, deliver }, built) : built;
1450
+ cache?.entries.set(node.id, { node, element });
1451
+ return element;
1452
+ }
1453
+ function buildNode(node, deliver, cache) {
1454
+ if (node.t === "Menu") return renderMenu(node, deliver, cache);
1455
+ if (node.t === "ContextMenu") return renderContextMenu(node, deliver, cache);
1456
+ if (node.t === "SwipeActions") return renderSwipeActions(node, deliver, cache);
1457
+ if (node.t === "Stepper") return renderStepper(node, deliver, cache);
1458
+ if (node.t === "NavigationStack") {
1459
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: NAVIGATOR_FILL, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node, deliver }) }, node.id);
1460
+ }
1461
+ if (node.t === "NavigationSplitView") {
1462
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SplitViewHost, { node, deliver, cache }, node.id);
1463
+ }
1464
+ if (node.t === "NavigationLink") {
1465
+ return (0, import_react.createElement)(
1466
+ import_ui.Button,
1467
+ {
1468
+ key: node.id,
1469
+ ...pressProps(node, deliver)
1470
+ },
1471
+ ...(node.c ?? []).map((child) => renderNode(child, deliver, cache))
1472
+ );
1473
+ }
1474
+ const component = NODE_COMPONENTS[node.t];
1475
+ if (!component) throw new Error(`swift view ${node.t} has no rnx kit component`);
1476
+ const modifiers = nodeModifiers(node);
1477
+ const children = node.t === "ConfirmationDialog" ? dialogChildren(node, deliver) : node.c?.map((child) => renderNode(child, deliver));
1478
+ return (0, import_react.createElement)(
1479
+ component,
1480
+ {
1481
+ key: node.id,
1482
+ ...modifiers === void 0 ? {} : { modifiers },
1483
+ ...nodeProps(node, deliver)
1484
+ },
1485
+ ...children ?? []
1486
+ );
1487
+ }
1488
+ function SwiftTree({
1489
+ tree,
1490
+ deliver,
1491
+ cache,
1492
+ resources
1493
+ }) {
1494
+ return (
1495
+ // a navigation stack at the root lays its own bar out under the status
1496
+ // bar and insets each screen itself, so the host must not also pad it
1497
+ // down: that pad would move the whole stack a status bar lower
1498
+ // a swiftui scene is opaque: the window behind every screen is
1499
+ // systemBackground, and lists paint their grouped fill over it (the kit's
1500
+ // grouped container already does). without this a listless screen shows
1501
+ // whatever sits beneath the mount. RAN on the safeArea probe (iphone 17
1502
+ // pro): (600,1300) reads #ffffff ios against #f2f2f7 rnx, 99.92% of the
1503
+ // frame; dark matches on both legs (the oracle's falsifier: the two
1504
+ // fills coincide there). PlatformColor is this lane's spelling for a
1505
+ // semantic color.
1506
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1507
+ import_ui.Host,
1508
+ {
1509
+ style: { flex: 1, backgroundColor: (0, import_react_native.PlatformColor)("systemBackground") },
1510
+ ignoreSafeArea: tree.some(
1511
+ (node) => node.t === "NavigationStack" || node.t === "NavigationSplitView"
1512
+ ),
1513
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationIndependentTree, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: tree.map((node) => renderNode(node, deliver, cache)) }) }) })
1514
+ }
1515
+ )
1516
+ );
1517
+ }
1518
+ var ROOT_KEY = "__rnx_swift_roots__";
1519
+ function rootRegistry() {
1520
+ const existing = Reflect.get(globalThis, ROOT_KEY);
1521
+ if (existing instanceof Map) return existing;
1522
+ const created = /* @__PURE__ */ new Map();
1523
+ Reflect.set(globalThis, ROOT_KEY, created);
1524
+ return created;
1525
+ }
1526
+ function slotFor(rootId, mountTree) {
1527
+ const registry = rootRegistry();
1528
+ const existing = registry.get(rootId);
1529
+ if (existing) return existing;
1530
+ const created = { root: createRoot(mountTree) };
1531
+ registry.set(rootId, created);
1532
+ return created;
1533
+ }
1534
+ function createRoot(mountTree) {
1535
+ let instance = null;
1536
+ let source = null;
1537
+ let refresh;
1538
+ let state = { tree: null, isView: false, error: null };
1539
+ let swap = Promise.resolve();
1540
+ const listeners = /* @__PURE__ */ new Set();
1541
+ const cache = { entries: /* @__PURE__ */ new Map() };
1542
+ const publish = (next) => {
1543
+ state = next;
1544
+ for (const listener of listeners) listener();
1545
+ };
1546
+ const apply = async (options, props) => {
1547
+ const carried = instance?.exportState() ?? null;
1548
+ const created = instantiate(
1549
+ await compile(options.url),
1550
+ decodeBundle(options.url, options.bundleFiles)
1551
+ );
1552
+ if (carried !== null) created.importState(carried);
1553
+ if (source !== options) return;
1554
+ instance = created;
1555
+ const mounted = mountTree(created, props);
1556
+ publish({ tree: mounted.tree, isView: mounted.isView, error: null });
1557
+ };
1558
+ const component = function SwiftRoot() {
1559
+ const rendered = (0, import_react.useSyncExternalStore)(
1560
+ (listener) => {
1561
+ listeners.add(listener);
1562
+ return () => listeners.delete(listener);
1563
+ },
1564
+ () => state
1565
+ );
1566
+ if (rendered.error) throw rendered.error;
1567
+ if (!rendered.tree) return null;
1568
+ const deliver = (handlerId2, payload) => {
1569
+ if (!instance) throw new Error("swift app received an event before it mounted");
1570
+ publish({
1571
+ tree: instance.deliver(handlerId2, payload),
1572
+ isView: rendered.isView,
1573
+ error: null
1574
+ });
1575
+ };
1576
+ const resources = source?.resources;
1577
+ if (rendered.isView)
1578
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: rendered.tree.map((node) => renderNode(node, deliver, cache)) }) });
1579
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1580
+ SwiftTree,
1581
+ {
1582
+ tree: rendered.tree,
1583
+ deliver,
1584
+ cache,
1585
+ resources
1586
+ }
1587
+ );
1588
+ };
1589
+ return {
1590
+ component,
1591
+ use(options, refreshKey, props) {
1592
+ const changed = source === null || source.hash !== options.hash || source.url !== options.url || JSON.stringify(source.resources ?? null) !== JSON.stringify(options.resources ?? null) || JSON.stringify(source.bundleFiles ?? null) !== JSON.stringify(options.bundleFiles ?? null) || refreshKey !== void 0 && refreshKey !== refresh;
1593
+ if (changed) {
1594
+ source = options;
1595
+ refresh = refreshKey;
1596
+ const next = props ?? {};
1597
+ swap = swap.then(
1598
+ () => apply(options, next),
1599
+ () => apply(options, next)
1600
+ );
1601
+ swap.catch((error) => {
1602
+ publish({
1603
+ tree: null,
1604
+ isView: false,
1605
+ error: error instanceof Error ? error : new Error(String(error))
1606
+ });
1607
+ });
1608
+ }
1609
+ return component;
1610
+ }
1611
+ };
1612
+ }
1613
+ function propsSignature(props) {
1614
+ try {
1615
+ return JSON.stringify(props, (_key, value) => {
1616
+ if (typeof value === "function" || typeof value === "symbol" || typeof value === "bigint") {
1617
+ throw new Error(`swift view props must be json; found ${typeof value}`);
1618
+ }
1619
+ return value;
1620
+ }) ?? "null";
1621
+ } catch (error) {
1622
+ if (error instanceof Error && error.message.startsWith("swift view props"))
1623
+ throw error;
1624
+ throw new Error(
1625
+ `swift view props must be json: ${error instanceof Error ? error.message : String(error)}`
1626
+ );
1627
+ }
1628
+ }
1629
+ function createSwiftEntry(options) {
1630
+ const rootId = options.rootId ?? "root";
1631
+ const slot = slotFor(
1632
+ rootId,
1633
+ (instance, props) => instance.hasView() ? { tree: instance.mountView(props), isView: true } : { tree: instance.mount(), isView: false }
1634
+ );
1635
+ return function SwiftEntry(props) {
1636
+ if (props.children !== void 0) {
1637
+ throw new Error("swift entries take data props, not children");
1638
+ }
1639
+ const component = slot.root.use(options, propsSignature(props), props);
1640
+ return (0, import_react.createElement)(component);
1641
+ };
1642
+ }
1643
+ // Annotate the CommonJS export names for ESM import in node:
1644
+ 0 && (module.exports = {
1645
+ createSwiftEntry
1646
+ });