peachsim 0.1.1641 → 0.1.1653
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/cli/app-bundle-resources.ts +57 -0
- package/cli/app-catalog.ts +1 -1
- package/cli/app-fonts.ts +11 -80
- package/cli/app-splash.ts +18 -12
- package/cli/bridge-flow-runner.ts +11 -7
- package/cli/cloud-client.ts +10 -13
- package/cli/command-registry.ts +13 -4
- package/cli/commands/box.ts +4 -4
- package/cli/commands/control.ts +105 -53
- package/cli/commands/coverage-parser.ts +67 -0
- package/cli/commands/coverage.ts +550 -0
- package/cli/commands/debug.ts +9 -18
- package/cli/commands/desktop.ts +19 -7
- package/cli/commands/device.ts +14 -9
- package/cli/commands/guest-host.ts +6 -10
- package/cli/commands/inspect/core.ts +81 -17
- package/cli/commands/inspect.ts +13 -8
- package/cli/commands/kotlin.ts +2 -2
- package/cli/commands/maestro-compare.ts +1 -1
- package/cli/commands/platform.ts +20 -11
- package/cli/commands/preview.ts +16 -18
- package/cli/commands/runtime.ts +3 -2
- package/cli/commands/screenshot-layers.ts +1 -1
- package/cli/commands/screenshot.ts +1 -1
- package/cli/commands/serve.ts +5 -1
- package/cli/commands/support.ts +4 -4
- package/cli/commands/three-mode.ts +22 -15
- package/cli/commands/upload.ts +44 -45
- package/cli/current-sim.ts +38 -0
- package/cli/desktop-companion.ts +36 -8
- package/cli/device-option.ts +1 -1
- package/cli/drivers/playwright.ts +40 -0
- package/cli/drivers/types.ts +4 -0
- package/cli/help-core.ts +1 -1
- package/cli/internal-child.ts +2 -1
- package/cli/main.ts +9 -3
- package/cli/outbound-endpoints.ts +15 -5
- package/cli/output-redaction.ts +39 -14
- package/cli/remote-simulators.ts +4 -1
- package/cli/scene-video.ts +5 -2
- package/cli/send-to-box.ts +7 -10
- package/cli/telemetry.ts +1 -1
- package/cli/ws-bridge.ts +8 -1
- package/detox/attempt-events.cjs +3 -1
- package/detox/attempt-events.d.cts +1 -1
- package/detox/expectations.ts +108 -99
- package/detox/frame-offset.d.mts +6 -0
- package/detox/frame-offset.mjs +35 -0
- package/detox/gestures.ts +6 -18
- package/detox/index.ts +169 -101
- package/detox/jest-preset.cjs +1 -3
- package/detox/jest-transform.cjs +4 -0
- package/detox/matchers.ts +3 -0
- package/detox/motion-change.cjs +52 -118
- package/detox/motion-change.d.cts +6 -27
- package/detox/motion-leg-starts.cjs +20 -0
- package/detox/motion-leg-starts.d.cts +8 -0
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +3 -3
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +65 -1
- package/dist-lib/bridge-contract-input.mjs +63 -1
- package/dist-lib/bridge-contract.cjs +19 -1
- package/dist-lib/bridge-contract.mjs +17 -1
- package/dist-lib/bundle-channel.cjs +38332 -14940
- package/dist-lib/capture-contract.cjs +1 -1
- package/dist-lib/capture-contract.mjs +1 -1
- package/dist-lib/cloud-contract.cjs +1 -1
- package/dist-lib/cloud-contract.mjs +1 -1
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +1 -1
- package/dist-lib/cloud.mjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/config.mjs +5 -3
- package/dist-lib/detox/index.cjs +1247 -4511
- package/dist-lib/detox/jest-preset.cjs +1 -3
- package/dist-lib/detox/jest-transform.cjs +4 -0
- package/dist-lib/dev-bundle-resolution.cjs +28 -24
- package/dist-lib/expo-swift-bundle.cjs +35243 -13172
- package/dist-lib/expo-swift-metadata.cjs +1 -1
- package/dist-lib/expo-swift-metadata.mjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +45285 -63163
- package/dist-lib/host/fetch-proxy-handler.cjs +3544 -11
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +1 -1
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +1997 -2069
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +2 -2
- package/dist-lib/menu.cjs +14 -6
- package/dist-lib/menu.mjs +14 -6
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +468 -563
- package/dist-lib/native-app-identity-project.cjs +128 -292
- package/dist-lib/native-app-identity-project.mjs +1262 -51
- package/dist-lib/native-app-identity.cjs +8 -3
- package/dist-lib/native-app-identity.mjs +8 -3
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +2 -244
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/public-origins-lib-esm.json +290 -0
- package/dist-lib/public-origins-lib-static.json +1 -0
- package/dist-lib/public-origins-lib.json +1852 -0
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +14 -253
- package/dist-lib/sdk.cjs +84 -16
- package/dist-lib/sdk.mjs +82 -15
- package/dist-lib/skills.cjs +51248 -75450
- package/dist-lib/swift-compile.cjs +26154 -1245
- package/dist-lib/swift-compile.mjs +26151 -1230
- package/dist-lib/swift-package.cjs +79 -1
- package/dist-lib/swift-package.mjs +75 -1
- package/dist-lib/swift-submit.cjs +1 -1
- package/dist-lib/swift-submit.mjs +1 -1
- package/dist-lib/swift-toolchain.cjs +1 -1
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +34394 -12323
- package/dist-lib/vite.cjs +373 -298
- package/dist-lib/worklet-executable.cjs +1 -1
- package/dist-lib/worklet-executable.mjs +1 -1
- package/dist-types/packages/peach-compat/src/engine-config.d.ts +2 -0
- package/dist-types/packages/peach-compat/src/stubs/form-sheet-spring.d.ts +9 -0
- package/dist-types/packages/peach-compat/src/stubs/native-evaluation-lease.d.ts +47 -0
- package/dist-types/packages/peach-compat/src/stubs/native-seams/react-native-cookies.d.ts +113 -0
- package/dist-types/packages/peach-compat/src/stubs/native-seams/react-native-gesture-handler.d.ts +154 -0
- package/dist-types/packages/peach-compat/src/stubs/screen-transition-math.d.ts +756 -0
- package/dist-types/packages/peach-compat/src/stubs/transition-scalar.d.ts +25 -0
- package/dist-types/packages/peach-engine/src/billing/plans.d.ts +64 -0
- package/dist-types/packages/peach-engine/src/browser-page-target.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/bundle-platform-url.d.ts +3 -0
- package/dist-types/packages/peach-engine/src/capture/browser-accessibility-host.d.ts +3 -0
- package/dist-types/packages/peach-engine/src/capture/browser-composite.d.ts +55 -0
- package/dist-types/packages/peach-engine/src/capture/browserAccessibilityContract.d.ts +27 -0
- package/dist-types/packages/peach-engine/src/capture/nativeScreenCaptureContract.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/cli-companion.d.ts +36 -0
- package/dist-types/packages/peach-engine/src/components/native-ui/webview-frame-bridge.d.ts +34 -0
- package/dist-types/packages/peach-engine/src/config.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/engine/android-stretch-effect.d.ts +57 -0
- package/dist-types/packages/peach-engine/src/engine/animated-driven-style.d.ts +47 -0
- package/dist-types/packages/peach-engine/src/engine/animated-value.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/engine/animated.d.ts +195 -0
- package/dist-types/packages/peach-engine/src/engine/animation-clockContract.d.ts +15 -0
- package/dist-types/packages/peach-engine/src/engine/animation-graph.d.ts +148 -0
- package/dist-types/packages/peach-engine/src/engine/app-catalog-wire.d.ts +10 -0
- package/dist-types/packages/peach-engine/src/engine/app-font-registry.d.ts +87 -0
- package/dist-types/packages/peach-engine/src/engine/attributed-paragraph-paint.d.ts +7 -0
- package/dist-types/packages/peach-engine/src/engine/attributed-paragraph.d.ts +123 -0
- package/dist-types/packages/peach-engine/src/engine/audioContract.d.ts +16 -0
- package/dist-types/packages/peach-engine/src/engine/canvaskit-api.d.ts +93 -0
- package/dist-types/packages/peach-engine/src/engine/canvaskit-renderer.d.ts +216 -0
- package/dist-types/packages/peach-engine/src/engine/config-plugin-fonts.d.ts +40 -0
- package/dist-types/packages/peach-engine/src/engine/config-plugin-splash.d.ts +25 -0
- package/dist-types/packages/peach-engine/src/engine/cull-visibility.d.ts +44 -0
- package/dist-types/packages/peach-engine/src/engine/damage-rect.d.ts +19 -0
- package/dist-types/packages/peach-engine/src/engine/engine-resource.d.ts +6 -0
- package/dist-types/packages/peach-engine/src/engine/expo-manifest.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/engine/fiber-debug-metadata.d.ts +30 -0
- package/dist-types/packages/peach-engine/src/engine/font-config.d.ts +139 -0
- package/dist-types/packages/peach-engine/src/engine/generated/sf-pro-font.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/glass-material.d.ts +31 -0
- package/dist-types/packages/peach-engine/src/engine/host-composite.d.ts +100 -0
- package/dist-types/packages/peach-engine/src/engine/hosted-semantics.d.ts +49 -0
- package/dist-types/packages/peach-engine/src/engine/image-audit.d.ts +70 -0
- package/dist-types/packages/peach-engine/src/engine/image-loader.d.ts +350 -0
- package/dist-types/packages/peach-engine/src/engine/inspect-info.d.ts +27 -0
- package/dist-types/packages/peach-engine/src/engine/inspect-outline.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/engine/inspect-visibility.d.ts +33 -0
- package/dist-types/packages/peach-engine/src/engine/ios-fast-scroll.d.ts +16 -0
- package/dist-types/packages/peach-engine/src/engine/layout-sab.d.ts +43 -0
- package/dist-types/packages/peach-engine/src/engine/liquid-glass-rect.d.ts +23 -0
- package/dist-types/packages/peach-engine/src/engine/liquid-glass-shaders.d.ts +9 -0
- package/dist-types/packages/peach-engine/src/engine/liquid-glass.d.ts +283 -0
- package/dist-types/packages/peach-engine/src/engine/live-object-counts.d.ts +6 -0
- package/dist-types/packages/peach-engine/src/engine/lottie-runtime.d.ts +32 -0
- package/dist-types/packages/peach-engine/src/engine/lottie-types.d.ts +138 -0
- package/dist-types/packages/peach-engine/src/engine/memory-counts.d.ts +27 -0
- package/dist-types/packages/peach-engine/src/engine/metalDirectContract.d.ts +108 -0
- package/dist-types/packages/peach-engine/src/engine/metalShaderContract.d.ts +217 -0
- package/dist-types/packages/peach-engine/src/engine/native-animation-driver.d.ts +112 -0
- package/dist-types/packages/peach-engine/src/engine/native-animation-graph.d.ts +62 -0
- package/dist-types/packages/peach-engine/src/engine/native-layout.d.ts +133 -0
- package/dist-types/packages/peach-engine/src/engine/native-resources.d.ts +26 -0
- package/dist-types/packages/peach-engine/src/engine/nativeReanimatedContract.d.ts +25 -0
- package/dist-types/packages/peach-engine/src/engine/nativeReplayContract.d.ts +64 -0
- package/dist-types/packages/peach-engine/src/engine/node.d.ts +589 -0
- package/dist-types/packages/peach-engine/src/engine/paint-boundary-types.d.ts +112 -0
- package/dist-types/packages/peach-engine/src/engine/paint-boundary.d.ts +57 -0
- package/dist-types/packages/peach-engine/src/engine/portalContract.d.ts +21 -0
- package/dist-types/packages/peach-engine/src/engine/portals.d.ts +20 -0
- package/dist-types/packages/peach-engine/src/engine/render-damage.d.ts +107 -0
- package/dist-types/packages/peach-engine/src/engine/riveContract.d.ts +420 -0
- package/dist-types/packages/peach-engine/src/engine/rn-spring.d.ts +51 -0
- package/dist-types/packages/peach-engine/src/engine/scene-table.d.ts +379 -0
- package/dist-types/packages/peach-engine/src/engine/scroll-momentum-math.d.ts +152 -0
- package/dist-types/packages/peach-engine/src/engine/scroll-pan-contacts.d.ts +10 -0
- package/dist-types/packages/peach-engine/src/engine/scroll-platform.d.ts +75 -0
- package/dist-types/packages/peach-engine/src/engine/scroll-range.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/engine/scroll-velocity.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/engine/scroll.d.ts +320 -0
- package/dist-types/packages/peach-engine/src/engine/signal.d.ts +7 -0
- package/dist-types/packages/peach-engine/src/engine/snapshot-cache-policy.d.ts +6 -0
- package/dist-types/packages/peach-engine/src/engine/svg-geometry.d.ts +41 -0
- package/dist-types/packages/peach-engine/src/engine/text-attachment-paragraphs.d.ts +10 -0
- package/dist-types/packages/peach-engine/src/engine/text-decoration.d.ts +11 -0
- package/dist-types/packages/peach-engine/src/engine/text-line-break.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/engine/text-paint-receipt.d.ts +98 -0
- package/dist-types/packages/peach-engine/src/engine/text-paragraph.d.ts +11 -0
- package/dist-types/packages/peach-engine/src/engine/text-paragraphContract.d.ts +34 -0
- package/dist-types/packages/peach-engine/src/engine/text-transform.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/engine/types.d.ts +657 -0
- package/dist-types/packages/peach-engine/src/engine/visible-frame.d.ts +54 -0
- package/dist-types/packages/peach-engine/src/engine/webrtcContract.d.ts +74 -0
- package/dist-types/packages/peach-engine/src/graphite-stats-fields.d.ts +184 -0
- package/dist-types/packages/peach-engine/src/guest-import-meta.d.ts +12 -0
- package/dist-types/packages/peach-engine/src/guest-module-overrides.d.ts +7 -0
- package/dist-types/packages/peach-engine/src/ios/app-card-types.d.ts +7 -0
- package/dist-types/packages/peach-engine/src/ios/apps/canvas-map-data.d.ts +177 -0
- package/dist-types/packages/peach-engine/src/ios/aux-home-scene.d.ts +54 -0
- package/dist-types/packages/peach-engine/src/ios/chrome-metrics.d.ts +47 -0
- package/dist-types/packages/peach-engine/src/ios/constants.d.ts +21 -0
- package/dist-types/packages/peach-engine/src/ios/duo-housing.d.ts +37 -0
- package/dist-types/packages/peach-engine/src/ios/home/types.d.ts +29 -0
- package/dist-types/packages/peach-engine/src/ios/home-app-catalog.d.ts +43 -0
- package/dist-types/packages/peach-engine/src/ios/photo-store.d.ts +73 -0
- package/dist-types/packages/peach-engine/src/ios/photoLibraryContract.d.ts +166 -0
- package/dist-types/packages/peach-engine/src/ios/shell-controller-types.d.ts +21 -0
- package/dist-types/packages/peach-engine/src/ios/shell-transition-debug.d.ts +18 -0
- package/dist-types/packages/peach-engine/src/metro-asset-path.d.ts +21 -0
- package/dist-types/packages/peach-engine/src/metro-fingerprint-registry-client.d.ts +11 -0
- package/dist-types/packages/peach-engine/src/metro-fingerprint.d.ts +38 -0
- package/dist-types/packages/peach-engine/src/native-preview-bundle.d.ts +44 -0
- package/dist-types/packages/peach-engine/src/observability/types.d.ts +74 -0
- package/dist-types/packages/peach-engine/src/peach-warm-manifest.d.ts +32 -0
- package/dist-types/packages/peach-engine/src/permissions/app-settings-client.d.ts +25 -0
- package/dist-types/packages/peach-engine/src/permissions/system-permission-types.d.ts +20 -0
- package/dist-types/packages/peach-engine/src/platform/android-back-panel.d.ts +131 -0
- package/dist-types/packages/peach-engine/src/platform/android-gesture-exclusion.d.ts +28 -0
- package/dist-types/packages/peach-engine/src/platform/android-predictive-back.d.ts +33 -0
- package/dist-types/packages/peach-engine/src/platform/system-bars-state.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/playwright-sim-host.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/preview/bundle-layout.d.ts +8 -0
- package/dist-types/packages/peach-engine/src/preview/bundle-variantContract.d.ts +24 -0
- package/dist-types/packages/peach-engine/src/preview/capture-bundle.d.ts +26 -0
- package/dist-types/packages/peach-engine/src/preview/compress-node.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/preview/compress.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/preview/presigned-upload.d.ts +60 -0
- package/dist-types/packages/peach-engine/src/preview/trace.d.ts +144 -0
- package/dist-types/packages/peach-engine/src/preview/upload-protocol.d.ts +152 -0
- package/dist-types/packages/peach-engine/src/profiler/animation-recording-loader.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/profiler/profile-trace.d.ts +4 -0
- package/dist-types/packages/peach-engine/src/react-bridge.d.ts +3 -0
- package/dist-types/packages/peach-engine/src/react-native/AppState.d.ts +45 -0
- package/dist-types/packages/peach-engine/src/react-native/Appearance.d.ts +34 -0
- package/dist-types/packages/peach-engine/src/react-native/framework-colors-data.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/react-native/host-services.d.ts +42 -0
- package/dist-types/packages/peach-engine/src/react-native/layout-animation.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/react-native/platform-colors.d.ts +17 -0
- package/dist-types/packages/peach-engine/src/remote-stream/client-config.d.ts +10 -0
- package/dist-types/packages/peach-engine/src/remote-stream/cloud-display.d.ts +58 -0
- package/dist-types/packages/peach-engine/src/remote-stream/scene-recording.d.ts +45 -0
- package/dist-types/packages/peach-engine/src/render-worker/animated-drive-output.d.ts +35 -0
- package/dist-types/packages/peach-engine/src/render-worker/app-load.d.ts +16 -0
- package/dist-types/packages/peach-engine/src/render-worker/aux-surface-types.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/render-worker/canvaskit-shared.d.ts +42 -0
- package/dist-types/packages/peach-engine/src/render-worker/canvaskit-webgpu.d.ts +434 -0
- package/dist-types/packages/peach-engine/src/render-worker/canvaskit-worker-init.d.ts +12 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-backend.d.ts +31 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-gpu.d.ts +202 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-protocol.d.ts +1945 -0
- package/dist-types/packages/peach-engine/src/render-worker/compositor-runtime/scroll-drag-resample.d.ts +44 -0
- package/dist-types/packages/peach-engine/src/render-worker/css-keyframes-drive.d.ts +36 -0
- package/dist-types/packages/peach-engine/src/render-worker/edit-menu-geometry.d.ts +8 -0
- package/dist-types/packages/peach-engine/src/render-worker/engine-resource-relay.d.ts +21 -0
- package/dist-types/packages/peach-engine/src/render-worker/expo-widgetContract.d.ts +16 -0
- package/dist-types/packages/peach-engine/src/render-worker/gesture-seam-protocol.d.ts +152 -0
- package/dist-types/packages/peach-engine/src/render-worker/graph-linked-value.d.ts +29 -0
- package/dist-types/packages/peach-engine/src/render-worker/graphite-pipeline-compiler-contract.d.ts +49 -0
- package/dist-types/packages/peach-engine/src/render-worker/graphite-pipeline-compiler.d.ts +12 -0
- package/dist-types/packages/peach-engine/src/render-worker/host-service-protocol.d.ts +756 -0
- package/dist-types/packages/peach-engine/src/render-worker/image-lifecycle-event.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/render-worker/image-pixel-contract.d.ts +48 -0
- package/dist-types/packages/peach-engine/src/render-worker/live-frame-mirror.d.ts +34 -0
- package/dist-types/packages/peach-engine/src/render-worker/map-command-channel.d.ts +189 -0
- package/dist-types/packages/peach-engine/src/render-worker/mapNativeContract.d.ts +101 -0
- package/dist-types/packages/peach-engine/src/render-worker/native-dynamic-synchronizable.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/render-worker/native-menu-gesture.d.ts +9 -0
- package/dist-types/packages/peach-engine/src/render-worker/native-ui-commandContract.d.ts +23 -0
- package/dist-types/packages/peach-engine/src/render-worker/native-ui-protocol.d.ts +1087 -0
- package/dist-types/packages/peach-engine/src/render-worker/native-widgetContract.d.ts +100 -0
- package/dist-types/packages/peach-engine/src/render-worker/nativeAnimMirrorContract.d.ts +174 -0
- package/dist-types/packages/peach-engine/src/render-worker/nativeSyncReplyContract.d.ts +11 -0
- package/dist-types/packages/peach-engine/src/render-worker/one-native-contentContract.d.ts +54 -0
- package/dist-types/packages/peach-engine/src/render-worker/pointerSampleContract.d.ts +14 -0
- package/dist-types/packages/peach-engine/src/render-worker/protocol.d.ts +880 -0
- package/dist-types/packages/peach-engine/src/render-worker/reanimated-css-contract.d.ts +63 -0
- package/dist-types/packages/peach-engine/src/render-worker/reanimated-readiness.d.ts +29 -0
- package/dist-types/packages/peach-engine/src/render-worker/resilient-frame-clock.d.ts +22 -0
- package/dist-types/packages/peach-engine/src/render-worker/retained-app-load.d.ts +20 -0
- package/dist-types/packages/peach-engine/src/render-worker/screen-edge-swipe-commit-protocol.d.ts +1 -0
- package/dist-types/packages/peach-engine/src/render-worker/screen-form-sheet-commit-protocol.d.ts +26 -0
- package/dist-types/packages/peach-engine/src/render-worker/scroll-mirror-tenant.d.ts +37 -0
- package/dist-types/packages/peach-engine/src/render-worker/scroll-mirror.d.ts +164 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-event-registry.d.ts +119 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-gesture-regions.d.ts +41 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-protocol.d.ts +603 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-scene-schema.d.ts +101 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-tree-inline-sources.d.ts +13 -0
- package/dist-types/packages/peach-engine/src/render-worker/shell-tree-wire.d.ts +87 -0
- package/dist-types/packages/peach-engine/src/render-worker/test-bridge-protocol.d.ts +47 -0
- package/dist-types/packages/peach-engine/src/render-worker/text-inputContract.d.ts +93 -0
- package/dist-types/packages/peach-engine/src/render-worker/tree-sync-port.d.ts +102 -0
- package/dist-types/packages/peach-engine/src/render-worker/webgpu-frame-transaction.d.ts +292 -0
- package/dist-types/packages/peach-engine/src/render-worker/webgpu-readback-scheduler.d.ts +107 -0
- package/dist-types/packages/peach-engine/src/render-worker/webview-capture-protocol.d.ts +16 -0
- package/dist-types/packages/peach-engine/src/render-worker/worker-input-runtime.d.ts +211 -0
- package/dist-types/packages/peach-engine/src/render-worker/worker-storage.d.ts +33 -0
- package/dist-types/packages/peach-engine/src/render-worker/worklet-runtime.d.ts +987 -0
- package/dist-types/packages/peach-engine/src/render-worker/worklet-sab.d.ts +24 -0
- package/dist-types/packages/peach-engine/src/rolldown-bundle-inventory.d.ts +84 -0
- package/dist-types/packages/peach-engine/src/rolldown-production-fingerprint.d.ts +31 -0
- package/dist-types/packages/peach-engine/src/screenshots/timeline-assets.d.ts +10 -0
- package/dist-types/packages/peach-engine/src/screenshots/tokens.d.ts +9 -0
- package/dist-types/packages/peach-engine/src/settings/devices.d.ts +70 -0
- package/dist-types/packages/peach-engine/src/settings/duo-fold-bus.d.ts +87 -0
- package/dist-types/packages/peach-engine/src/settings/interface-rotation.d.ts +30 -0
- package/dist-types/packages/peach-engine/src/settings/react-native-configuration.d.ts +12 -0
- package/dist-types/packages/peach-engine/src/settings/scene-geometryContract.d.ts +40 -0
- package/dist-types/packages/peach-engine/src/settings/store.d.ts +37 -0
- package/dist-types/packages/peach-engine/src/shell-events.d.ts +203 -0
- package/dist-types/packages/peach-engine/src/shell-intent.d.ts +68 -0
- package/dist-types/packages/peach-engine/src/sootsim-event.d.ts +35 -0
- package/dist-types/packages/peach-engine/src/top-overlay-state.d.ts +5 -0
- package/dist-types/packages/peach-engine/src/web-authentication-automation-host.d.ts +2 -0
- package/dist-types/packages/peach-engine/src/webAuthenticationContract.d.ts +34 -0
- package/dist-types/packages/peach-engine/src/webview-automation-host.d.ts +180 -0
- package/dist-types/packages/peach-engine/src/wireframe-mode.d.ts +16 -0
- package/dist-types/packages/peach-globals/src/frameBreakdownContract.d.ts +16 -0
- package/dist-types/packages/peach-globals/src/index.d.ts +3311 -0
- package/dist-types/packages/peach-globals/src/nativeSurfaceContract.d.ts +76 -0
- package/dist-types/packages/peach-globals/src/pointerSourceEventContract.d.ts +8 -0
- package/dist-types/packages/peach-globals/src/profileTrace.d.ts +11 -0
- package/dist-types/packages/peach-globals/src/profilerContract.d.ts +223 -0
- package/dist-types/packages/peach-kit/src/capabilities.d.ts +721 -0
- package/dist-types/packages/peach-kit/src/internal.d.ts +4 -0
- package/dist-types/packages/peach-kit/src/materials/types.d.ts +27 -0
- package/dist-types/packages/peach-kit/src/materials/uikit-blur-material.d.ts +14 -0
- package/dist-types/packages/peach-kit/src/navigation-types.d.ts +11 -0
- package/dist-types/packages/peach-kit/src/react-bridge.d.ts +53 -0
- package/dist-types/packages/peach-kit/src/runtime.d.ts +26 -0
- package/dist-types/packages/peach-kit/src/ui/hosting-safe-area.d.ts +24 -0
- package/dist-types/packages/peach-kit/src/ui/popover-placement.d.ts +53 -0
- package/dist-types/packages/peach-kit/src/ui/presentationContract.d.ts +17 -0
- package/kotlin/ComposeSources/PeachComposeHost.kt +1 -1
- package/kotlin/JniSources/com/facebook/jni/HybridData.kt +0 -2
- package/kotlin/JniSources/dev/peach/jni/NativeBindings.kt +0 -2
- package/kotlin/JniTransportSources/dev/peach/jni/integration/JniTransport.kt +0 -2
- package/kotlin/README.md +6 -0
- package/package.json +22 -2
- package/runtime-companion.json +1 -0
- package/skills/contrast/SKILL.md +1 -0
- package/src/appBundleResourcesContract.ts +51 -0
- package/src/assetCatalogContract.ts +21 -0
- package/src/backend-origin.ts +3 -1
- package/src/bridge-contract-input.ts +84 -0
- package/src/bridge-contract.ts +35 -3
- package/src/browser-launch-policy.ts +1 -0
- package/src/bundle-channel.mjs +4 -2
- package/src/cli-runtime.ts +55 -0
- package/src/crash-fingerprint.ts +26 -0
- package/src/dev-bundle-resolution.ts +50 -23
- package/src/device-catalog.ts +1159 -0
- package/src/host/bridge-host.ts +20 -37
- package/src/host/browser-pointer.ts +71 -0
- package/src/host/dev-server-package-versions.ts +23 -0
- package/src/host/fetch-proxy-handler.ts +17 -4
- package/src/host/staged-host-files.ts +28 -4
- package/src/installed-package-versions.ts +142 -38
- package/src/kotlin-host.ts +1 -1
- package/src/launchMetadataContract.ts +1 -0
- package/src/menu.ts +12 -4
- package/src/metro-plugin.ts +4 -4
- package/src/metro-project-root.ts +68 -0
- package/src/native-app-identity-project.ts +47 -38
- package/src/nitro-adapter.lock.json +26 -0
- package/src/nitro-adapter.ts +103 -0
- package/src/nitro-bundle.ts +24 -10
- package/src/nitro-compile.ts +33 -51
- package/src/nitro-source.ts +177 -96
- package/src/nitroAdapterContract.ts +217 -0
- package/src/nitroContract.ts +24 -11
- package/src/process-group.ts +41 -34
- package/src/react-bridge-importers.ts +28 -0
- package/src/reactNativeConfigurationContract.ts +36 -0
- package/src/runtime-assets.ts +7 -2
- package/src/runtime-delivery.ts +8 -7
- package/src/runtimePlatformContract.ts +70 -0
- package/src/screenshots/frame-compose.ts +42 -43
- package/src/screenshots/org-deck.ts +9 -4
- package/src/screenshots/preset-names.ts +29 -0
- package/src/screenshots/registry.ts +5 -5
- package/src/screenshots/schema.ts +1 -1
- package/src/screenshots/screenshotContract.ts +971 -0
- package/src/settings-flags.ts +107 -0
- package/src/settingsContract.ts +609 -0
- package/src/storageSnapshotContract.ts +344 -0
- package/src/stub-pattern-matcher.ts +550 -0
- package/src/swift-compile.ts +926 -47
- package/src/swift-compiler-digest.ts +17 -3
- package/src/swift-distribution.lock.json +49 -22
- package/src/swift-host.ts +167 -52
- package/src/swift-objc-compile.ts +86 -26
- package/src/swift-objc-export.ts +532 -0
- package/src/swift-objc-import.ts +769 -0
- package/src/swift-objc-metadata.ts +285 -10
- package/src/swift-objc-sdk.ts +13970 -158
- package/src/swift-objc-standin.ts +137 -1
- package/src/swift-package.ts +94 -0
- package/src/swift-packages.ts +5 -5
- package/src/swift-root-lock.ts +241 -92
- package/src/swift-submit.ts +6 -0
- package/src/swiftContract.ts +99 -0
- package/src/target-matcher.ts +6 -1
- package/src/vite-plugin.ts +14 -40
- package/src/worker-system-chunks.ts +1 -1
- package/src/workerChunkContract.ts +5 -0
- package/src/worklets-babel.ts +24 -5
- package/src/xcode-project.ts +103 -11
- package/src/xcode-target-members.ts +10 -3
- package/cli/drivers/playwright-sim-host.ts +0 -825
- package/kotlin/fixtures/counter/Counter.d.kt.ts +0 -17
- package/kotlin/fixtures/counter/Counter.kt +0 -51
- package/kotlin/fixtures/counter/CounterApp.native.tsx +0 -61
- package/kotlin/fixtures/counter/CounterApp.tsx +0 -3
- package/kotlin/fixtures/counter/CounterScreen.d.kt.ts +0 -8
- package/kotlin/fixtures/counter/CounterScreen.kt +0 -56
- package/kotlin/fixtures/counter/app/_layout.tsx +0 -4
- package/kotlin/fixtures/counter/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/counter/app/routes.d.ts +0 -18
- package/kotlin/fixtures/counter/package.json +0 -20
- package/kotlin/fixtures/counter/tsconfig.json +0 -19
- package/kotlin/fixtures/counter/vite.config.ts +0 -20
- package/kotlin/fixtures/headless-counter/Headless.kt +0 -234
- package/kotlin/fixtures/import-animation/Animation.d.kt.ts +0 -7
- package/kotlin/fixtures/import-animation/Animation.kt +0 -80
- package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +0 -13
- package/kotlin/fixtures/import-animation/README.md +0 -24
- package/kotlin/fixtures/import-animation/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-animation/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-animation/app/routes.d.ts +0 -18
- package/kotlin/fixtures/import-animation/package.json +0 -23
- package/kotlin/fixtures/import-animation/tsconfig.json +0 -20
- package/kotlin/fixtures/import-animation/vite.config.ts +0 -20
- package/kotlin/fixtures/import-drawing/Drawing.d.kt.ts +0 -7
- package/kotlin/fixtures/import-drawing/Drawing.kt +0 -101
- package/kotlin/fixtures/import-drawing/ImportDrawing.native.tsx +0 -18
- package/kotlin/fixtures/import-drawing/README.md +0 -34
- package/kotlin/fixtures/import-drawing/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-drawing/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-drawing/package.json +0 -23
- package/kotlin/fixtures/import-drawing/tsconfig.json +0 -20
- package/kotlin/fixtures/import-drawing/vite.config.ts +0 -20
- package/kotlin/fixtures/import-editor/Editor.d.kt.ts +0 -7
- package/kotlin/fixtures/import-editor/Editor.kt +0 -59
- package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +0 -23
- package/kotlin/fixtures/import-editor/README.md +0 -27
- package/kotlin/fixtures/import-editor/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-editor/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-editor/package.json +0 -23
- package/kotlin/fixtures/import-editor/tsconfig.json +0 -20
- package/kotlin/fixtures/import-editor/vite.config.ts +0 -20
- package/kotlin/fixtures/import-effects/Effects.d.kt.ts +0 -7
- package/kotlin/fixtures/import-effects/Effects.kt +0 -87
- package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +0 -13
- package/kotlin/fixtures/import-effects/README.md +0 -19
- package/kotlin/fixtures/import-effects/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-effects/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-effects/package.json +0 -23
- package/kotlin/fixtures/import-effects/tsconfig.json +0 -20
- package/kotlin/fixtures/import-effects/vite.config.ts +0 -20
- package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +0 -13
- package/kotlin/fixtures/import-layout/Layout.d.kt.ts +0 -7
- package/kotlin/fixtures/import-layout/Layout.kt +0 -72
- package/kotlin/fixtures/import-layout/README.md +0 -24
- package/kotlin/fixtures/import-layout/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-layout/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-layout/package.json +0 -23
- package/kotlin/fixtures/import-layout/tsconfig.json +0 -20
- package/kotlin/fixtures/import-layout/vite.config.ts +0 -20
- package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +0 -18
- package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +0 -7
- package/kotlin/fixtures/import-navigation/Navigation.kt +0 -104
- package/kotlin/fixtures/import-navigation/README.md +0 -31
- package/kotlin/fixtures/import-navigation/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-navigation/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-navigation/package.json +0 -23
- package/kotlin/fixtures/import-navigation/tsconfig.json +0 -20
- package/kotlin/fixtures/import-navigation/vite.config.ts +0 -20
- package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +0 -29
- package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +0 -7
- package/kotlin/fixtures/import-overlays/Overlays.kt +0 -93
- package/kotlin/fixtures/import-overlays/README.md +0 -34
- package/kotlin/fixtures/import-overlays/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-overlays/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-overlays/package.json +0 -23
- package/kotlin/fixtures/import-overlays/tsconfig.json +0 -20
- package/kotlin/fixtures/import-overlays/vite.config.ts +0 -20
- package/kotlin/fixtures/import-resources/ImportResources.native.tsx +0 -18
- package/kotlin/fixtures/import-resources/README.md +0 -26
- package/kotlin/fixtures/import-resources/Resources.d.kt.ts +0 -6
- package/kotlin/fixtures/import-resources/Resources.kt +0 -72
- package/kotlin/fixtures/import-resources/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-resources/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-resources/package.json +0 -23
- package/kotlin/fixtures/import-resources/tsconfig.json +0 -20
- package/kotlin/fixtures/import-resources/vite.config.ts +0 -20
- package/kotlin/fixtures/import-scroll/ImportNested.native.tsx +0 -10
- package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +0 -13
- package/kotlin/fixtures/import-scroll/Nested.d.kt.ts +0 -4
- package/kotlin/fixtures/import-scroll/Nested.kt +0 -64
- package/kotlin/fixtures/import-scroll/README.md +0 -38
- package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +0 -7
- package/kotlin/fixtures/import-scroll/Scroll.kt +0 -91
- package/kotlin/fixtures/import-scroll/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-scroll/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-scroll/app/nested+spa.tsx +0 -1
- package/kotlin/fixtures/import-scroll/package.json +0 -23
- package/kotlin/fixtures/import-scroll/tsconfig.json +0 -20
- package/kotlin/fixtures/import-scroll/vite.config.ts +0 -20
- package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +0 -44
- package/kotlin/fixtures/import-selection/README.md +0 -32
- package/kotlin/fixtures/import-selection/Selection.d.kt.ts +0 -8
- package/kotlin/fixtures/import-selection/Selection.kt +0 -78
- package/kotlin/fixtures/import-selection/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-selection/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-selection/package.json +0 -23
- package/kotlin/fixtures/import-selection/tsconfig.json +0 -20
- package/kotlin/fixtures/import-selection/vite.config.ts +0 -20
- package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +0 -13
- package/kotlin/fixtures/import-surfaces/README.md +0 -22
- package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +0 -7
- package/kotlin/fixtures/import-surfaces/Surfaces.kt +0 -64
- package/kotlin/fixtures/import-surfaces/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-surfaces/package.json +0 -23
- package/kotlin/fixtures/import-surfaces/tsconfig.json +0 -20
- package/kotlin/fixtures/import-surfaces/vite.config.ts +0 -20
- package/kotlin/fixtures/import-values/ImportValues.native.tsx +0 -61
- package/kotlin/fixtures/import-values/README.md +0 -28
- package/kotlin/fixtures/import-values/Values.d.kt.ts +0 -15
- package/kotlin/fixtures/import-values/Values.kt +0 -84
- package/kotlin/fixtures/import-values/app/_layout.tsx +0 -4
- package/kotlin/fixtures/import-values/app/index+spa.tsx +0 -1
- package/kotlin/fixtures/import-values/package.json +0 -23
- package/kotlin/fixtures/import-values/tsconfig.json +0 -20
- package/kotlin/fixtures/import-values/vite.config.ts +0 -20
- package/kotlin/fixtures/kotlin-app/app/build.gradle.kts +0 -30
- package/kotlin/fixtures/kotlin-app/app/src/main/AndroidManifest.xml +0 -13
- package/kotlin/fixtures/kotlin-app/app/src/main/java/dev/contrast/kotlinapp/MainActivity.kt +0 -60
- package/kotlin/fixtures/kotlin-app/app/src/main/java/dev/contrast/kotlinapp/ProbeApplication.kt +0 -18
- package/kotlin/fixtures/kotlin-app/build.gradle.kts +0 -5
- package/kotlin/fixtures/kotlin-app/gradle.properties +0 -4
- package/kotlin/fixtures/kotlin-app/settings.gradle.kts +0 -4
- package/kotlin/fixtures/kotlin-app-variants/Anim.kt +0 -62
- package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +0 -38
- package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +0 -36
- package/kotlin/fixtures/kotlin-app-variants/Bitmaps.kt +0 -50
- package/kotlin/fixtures/kotlin-app-variants/Browse.kt +0 -73
- package/kotlin/fixtures/kotlin-app-variants/Colors.kt +0 -41
- package/kotlin/fixtures/kotlin-app-variants/Controls.kt +0 -62
- package/kotlin/fixtures/kotlin-app-variants/Drag.kt +0 -56
- package/kotlin/fixtures/kotlin-app-variants/Draw.kt +0 -74
- package/kotlin/fixtures/kotlin-app-variants/Drawables.kt +0 -53
- package/kotlin/fixtures/kotlin-app-variants/Focus.kt +0 -62
- package/kotlin/fixtures/kotlin-app-variants/Form.kt +0 -47
- package/kotlin/fixtures/kotlin-app-variants/Icons.kt +0 -59
- package/kotlin/fixtures/kotlin-app-variants/Ime.kt +0 -53
- package/kotlin/fixtures/kotlin-app-variants/Lists.kt +0 -57
- package/kotlin/fixtures/kotlin-app-variants/Nav.kt +0 -47
- package/kotlin/fixtures/kotlin-app-variants/Note.kt +0 -40
- package/kotlin/fixtures/kotlin-app-variants/Overlays.kt +0 -56
- package/kotlin/fixtures/kotlin-app-variants/Pan.kt +0 -38
- package/kotlin/fixtures/kotlin-app-variants/Pickers.kt +0 -44
- package/kotlin/fixtures/kotlin-app-variants/Press.kt +0 -43
- package/kotlin/fixtures/kotlin-app-variants/Scroll.kt +0 -63
- package/kotlin/fixtures/kotlin-app-variants/Sheet.kt +0 -43
- package/kotlin/fixtures/kotlin-app-variants/Strings.kt +0 -49
- package/kotlin/fixtures/kotlin-app-variants/Tabs.kt +0 -47
- package/kotlin/fixtures/kotlin-app-variants/TextWidth.kt +0 -45
- package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +0 -50
- package/kotlin/fixtures/kotlin-app-variants/Transition.kt +0 -69
- package/kotlin/fixtures/kotlin-app-variants/ViewConfig.kt +0 -22
- package/kotlin/fixtures/kotlin-app-variants/Widgets.kt +0 -67
- package/kotlin/fixtures/runtime-state/RuntimeState.kt +0 -200
- package/kotlin/fork/README.md +0 -97
- package/kotlin/fork/build.sh +0 -176
- package/kotlin/fork/compose-worker-globals.patch +0 -1247
- package/kotlin/fork/fork.json +0 -46
- package/kotlin/fork/publish.ts +0 -99
- package/kotlin/fork/skia-android-shaping.patch +0 -189
- package/kotlin/fork/skiko-local.init.gradle +0 -10
- package/kotlin/fork/skiko-worker-clock.patch +0 -122
|
@@ -0,0 +1,1159 @@
|
|
|
1
|
+
export type RuntimePlatform = 'ios' | 'android'
|
|
2
|
+
|
|
3
|
+
// hardware side-button layout. top/height are in the frame's coordinate
|
|
4
|
+
// system (y=0 is the top of the device chrome, not the screen) so shell's
|
|
5
|
+
// DeviceFrame can position them without re-doing the math per device.
|
|
6
|
+
export interface HardwareButtonSpec {
|
|
7
|
+
side: 'left' | 'right' | 'top' | 'bottom'
|
|
8
|
+
top: number
|
|
9
|
+
height: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface HardwareButtons {
|
|
13
|
+
// mechanical width of all side buttons for this device class.
|
|
14
|
+
width: number
|
|
15
|
+
lock: HardwareButtonSpec // right side (power / sleep)
|
|
16
|
+
ringToggle: HardwareButtonSpec // left side
|
|
17
|
+
volumeUp: HardwareButtonSpec // left side
|
|
18
|
+
volumeDown: HardwareButtonSpec // left side
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// "modern" era (home indicator, dynamic island or notch) iPhones. button
|
|
22
|
+
// positions mirror Apple's own Simulator chrome, pixel-measured per chrome
|
|
23
|
+
// class from real Simulator.app device windows (method + full matrix in
|
|
24
|
+
// packages/peach-engine/assets/device-frame-geometry). frameInsets is the
|
|
25
|
+
// visible 2d chrome around the display: the black border plus however much
|
|
26
|
+
// of the housing rail the front view actually shows. every profile keeps its
|
|
27
|
+
// simulator calibration except the iphone air. its curved housing edge turns
|
|
28
|
+
// away from a head-on view, so it renders the bare 1.435mm display border.
|
|
29
|
+
// top/height are points from the top of the device chrome (frame-outer top),
|
|
30
|
+
// so they don't depend on the device height. each arg is [top, height]: the
|
|
31
|
+
// action / ring-silent switch, volume up, volume down (all on the left rail)
|
|
32
|
+
// and the power / side button (right).
|
|
33
|
+
function modernButtons(
|
|
34
|
+
action: [number, number],
|
|
35
|
+
volumeUp: [number, number],
|
|
36
|
+
volumeDown: [number, number],
|
|
37
|
+
power: [number, number],
|
|
38
|
+
): HardwareButtons {
|
|
39
|
+
return {
|
|
40
|
+
width: 3,
|
|
41
|
+
ringToggle: { side: 'left', top: action[0], height: action[1] },
|
|
42
|
+
volumeUp: { side: 'left', top: volumeUp[0], height: volumeUp[1] },
|
|
43
|
+
volumeDown: { side: 'left', top: volumeDown[0], height: volumeDown[1] },
|
|
44
|
+
lock: { side: 'right', top: power[0], height: power[1] },
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// "legacy" era (home button) iPhones. Apple-derived from bezel.supply's
|
|
49
|
+
// iphone-se-3rd-gen frame (see packages/peach-engine/assets/device-frame-geometry): top/height
|
|
50
|
+
// are points from the top of the device chrome (frame-outer top), the same
|
|
51
|
+
// origin the modern buttons use. the SE shell has a symmetric ~111pt
|
|
52
|
+
// forehead+chin, so these sit lower than the old placeholder values did.
|
|
53
|
+
export const LEGACY_HARDWARE_BUTTONS: HardwareButtons = {
|
|
54
|
+
width: 2.5,
|
|
55
|
+
lock: { side: 'right', top: 188.7, height: 68.1 },
|
|
56
|
+
ringToggle: { side: 'left', top: 113.2, height: 36 },
|
|
57
|
+
volumeUp: { side: 'left', top: 188.2, height: 68.1 },
|
|
58
|
+
volumeDown: { side: 'left', top: 269, height: 68.1 },
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const PIXEL_HARDWARE_BUTTONS: HardwareButtons = {
|
|
62
|
+
width: 3,
|
|
63
|
+
// pixel 8 android studio art has right-edge opaque runs at y=671..833
|
|
64
|
+
// (power) and y=971..1301 (the continuous volume rocker), at 2.625x.
|
|
65
|
+
lock: { side: 'right', top: 671 / 2.625, height: 163 / 2.625 },
|
|
66
|
+
ringToggle: { side: 'left', top: -1000, height: 0 },
|
|
67
|
+
volumeUp: { side: 'right', top: 971 / 2.625, height: 165 / 2.625 },
|
|
68
|
+
volumeDown: { side: 'right', top: 1136 / 2.625, height: 166 / 2.625 },
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const GALAXY_HARDWARE_BUTTONS: HardwareButtons = {
|
|
72
|
+
width: 3,
|
|
73
|
+
lock: { side: 'right', top: 248, height: 72 },
|
|
74
|
+
ringToggle: { side: 'left', top: -1000, height: 0 },
|
|
75
|
+
volumeUp: { side: 'right', top: 144, height: 62 },
|
|
76
|
+
volumeDown: { side: 'right', top: 216, height: 62 },
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const ANDROID_GESTURE_NAV_BAR_HEIGHT = 24
|
|
80
|
+
|
|
81
|
+
const ANDROID_OS_VERSION = '17'
|
|
82
|
+
|
|
83
|
+
const ANDROID_API_LEVEL = 37
|
|
84
|
+
|
|
85
|
+
const PIXEL_8_WIDTH = 1080 / 2.625
|
|
86
|
+
|
|
87
|
+
const PIXEL_8_HEIGHT = 2400 / 2.625
|
|
88
|
+
|
|
89
|
+
// pixel 8 api 37 rev6: qwerty, symbol and pad ime bounds include the
|
|
90
|
+
// gesture bar, 883 physical pixels at 420dpi.
|
|
91
|
+
const GBOARD_PANEL_HEIGHTS = {
|
|
92
|
+
qwerty: 883 / 2.625,
|
|
93
|
+
pad: 883 / 2.625,
|
|
94
|
+
emoji: 395,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const PIXEL_8_STATUS_BAR_HEIGHT = 132 / 2.625
|
|
98
|
+
|
|
99
|
+
// api 37 pixel 8 overlay: status_bar_height_landscape=28dp; pixel rounding yields 74px.
|
|
100
|
+
const PIXEL_8_LANDSCAPE_STATUS_BAR_HEIGHT = Math.round(28 * 2.625) / 2.625
|
|
101
|
+
|
|
102
|
+
export interface FrameInsets {
|
|
103
|
+
top: number
|
|
104
|
+
right: number
|
|
105
|
+
bottom: number
|
|
106
|
+
left: number
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function uniformFrameInsets(value: number): FrameInsets {
|
|
110
|
+
return { top: value, right: value, bottom: value, left: value }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type DevicePosture = 'closed' | 'open'
|
|
114
|
+
|
|
115
|
+
// width of a foldable's central division (fold) band, in points. on the duo
|
|
116
|
+
// the ios 27.1 simulator reports a 40pt division region which reads inactive
|
|
117
|
+
// at fullyOpen, so a flat inner display lays out one continuous surface
|
|
118
|
+
// (scripts/ops/duo-sim.ts); the band turns active as the hinge leaves flat,
|
|
119
|
+
// and at book each split pane holds 20pt of margin on its hinge side
|
|
120
|
+
// (packages/peach-engine/src/ios/SplitView.tsx). surfaces that compose two
|
|
121
|
+
// groups side by side on the flat display (home) still balance their margins
|
|
122
|
+
// around the band centre, so no group straddles the hinge line
|
|
123
|
+
// (packages/peach-engine/src/ios/home/layout.ts).
|
|
124
|
+
export const DUO_DIVISION_REGION_WIDTH = 40
|
|
125
|
+
|
|
126
|
+
export interface CameraCutout {
|
|
127
|
+
diameter: number
|
|
128
|
+
top?: number
|
|
129
|
+
// distance from the trailing display edge on a camera that is not centred
|
|
130
|
+
trailing?: number
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface PhysicalCutoutRect {
|
|
134
|
+
left: number
|
|
135
|
+
top: number
|
|
136
|
+
width: number
|
|
137
|
+
height: number
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// display corner radii, clockwise from the top left. every device carries all
|
|
141
|
+
// four; a uniform display repeats one value. a consumer that can only take one
|
|
142
|
+
// scalar names the corner it reads and says why; nothing averages them.
|
|
143
|
+
export interface CornerRadii {
|
|
144
|
+
topLeft: number
|
|
145
|
+
topRight: number
|
|
146
|
+
bottomRight: number
|
|
147
|
+
bottomLeft: number
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function cornerRadii(value: number): CornerRadii {
|
|
151
|
+
return { topLeft: value, topRight: value, bottomRight: value, bottomLeft: value }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// the barrel is a stadium lying along a folded display's leading edge, absent
|
|
155
|
+
// when the display is open. `width` is its full thickness, `endInset` how far
|
|
156
|
+
// its cap sits below the top of the body, and `protrusion` how much of it
|
|
157
|
+
// stands out past the body's own silhouette (the rest hides behind the body).
|
|
158
|
+
export interface DeviceHingeBarrel {
|
|
159
|
+
width: number
|
|
160
|
+
endInset: number
|
|
161
|
+
protrusion: number
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// a housing whose body is a light rail around a black glass ring, measured
|
|
165
|
+
// from apple's product art. `rail` is the visible rail width per edge, so the
|
|
166
|
+
// black glass ring is frameInsets minus rail. devices without a housing draw
|
|
167
|
+
// one black body with a metallic ring.
|
|
168
|
+
export interface DeviceHousing {
|
|
169
|
+
rail: FrameInsets
|
|
170
|
+
hingeBarrel: DeviceHingeBarrel | null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface DeviceSpec {
|
|
174
|
+
// the registry key this profile came from, so a consumer holding only a
|
|
175
|
+
// published spec can still ask the registry model-keyed questions. the
|
|
176
|
+
// device-spec bus is the only channel some consumers have, and a display
|
|
177
|
+
// name is not an identity.
|
|
178
|
+
model: DeviceModel
|
|
179
|
+
platform: RuntimePlatform
|
|
180
|
+
name: string
|
|
181
|
+
width: number
|
|
182
|
+
height: number
|
|
183
|
+
scale: number
|
|
184
|
+
statusBarHeight: number
|
|
185
|
+
landscapeStatusBarHeight: number
|
|
186
|
+
homeIndicatorHeight: number
|
|
187
|
+
// terminal panel heights, excluding any input accessory. layout
|
|
188
|
+
// families can differ on the same display, so they are recorded separately.
|
|
189
|
+
keyboardPanelHeights: { qwerty: number; pad: number; emoji: number }
|
|
190
|
+
navigationBarHeight: number
|
|
191
|
+
navigationBarMode: 'gesture' | 'three-button' | 'none'
|
|
192
|
+
displayCutout: { top: number; left: number; right: number; bottom: number }
|
|
193
|
+
// effective circular fit of the native display mask, per corner. canvas
|
|
194
|
+
// renderers that only support circular corners use this value.
|
|
195
|
+
cornerRadius: CornerRadii
|
|
196
|
+
// tangent extent of the native corner curve, retained for future exact-shape
|
|
197
|
+
// profiling. the live DOM frame uses cornerRadius because Safari does not
|
|
198
|
+
// support CSS corner-shape and treats this larger value as a circular radius.
|
|
199
|
+
continuousCornerRadius: CornerRadii
|
|
200
|
+
// UIScreen _displayCornerRadius, the corner UIKit builds concentric sheet
|
|
201
|
+
// corners from, where it is not the mask fit above.
|
|
202
|
+
systemCornerRadius?: CornerRadii
|
|
203
|
+
// rendered frame body around the screen. per-edge values preserve asymmetric
|
|
204
|
+
// native device artwork instead of forcing every body through one bezel scalar.
|
|
205
|
+
frameInsets: FrameInsets
|
|
206
|
+
// body corner radii, when the body is not concentric with the display. a
|
|
207
|
+
// folded device's spine is a flat cut, so its corners there are far tighter
|
|
208
|
+
// than display radius plus inset. omit it and the concentric rule applies.
|
|
209
|
+
frameCornerRadius?: CornerRadii
|
|
210
|
+
housing?: DeviceHousing
|
|
211
|
+
// dynamic island geometry in points, uikit's own: the width and bottom edge
|
|
212
|
+
// of the sensor cutout in the ios 27.0 runtime's BoundingPathBitmap for the
|
|
213
|
+
// panel (UIKitCore BoundingPathData.bundle), and the 36.67pt height of the
|
|
214
|
+
// screen's _exclusionArea measured on the iphone 16 and 17 pro.
|
|
215
|
+
dynamicIsland: { width: number; height: number; top: number } | null
|
|
216
|
+
// the vertical centre line ios lays the status bar clock and icons on, in
|
|
217
|
+
// points. it is not the island's centre: the ios 27.0 17 pro row sits 3.33pt
|
|
218
|
+
// below the iphone 16 row while its island sits 2.67pt lower. framebuffer
|
|
219
|
+
// measured on the iphone 16, 17 pro and air; the other profiles keep their
|
|
220
|
+
// earlier island-derived values.
|
|
221
|
+
statusRowCenter?: number
|
|
222
|
+
cameraCutout: CameraCutout | null
|
|
223
|
+
safeAreaInsets: { top: number; bottom: number; left: number; right: number }
|
|
224
|
+
osVersion: string
|
|
225
|
+
iosVersion: string
|
|
226
|
+
androidApiLevel: number | null
|
|
227
|
+
systemName: 'iOS' | 'Android'
|
|
228
|
+
manufacturer: string
|
|
229
|
+
brand: string
|
|
230
|
+
modelName: string
|
|
231
|
+
// native screen pixel density (ppi) — used by Physical Size mode to render
|
|
232
|
+
// the device at its real-world dimensions on the user's display.
|
|
233
|
+
physicalPPI: number
|
|
234
|
+
// side button layout. modern devices build one per-device via modernButtons()
|
|
235
|
+
// (Apple-derived positions); iphone-se (home button) uses
|
|
236
|
+
// LEGACY_HARDWARE_BUTTONS; Android uses PIXEL_/GALAXY_HARDWARE_BUTTONS.
|
|
237
|
+
hardwareButtons: HardwareButtons
|
|
238
|
+
// experimental prototypes resolve by exact id on contributor surfaces
|
|
239
|
+
// (spec lookup, ?device= param, `device set <model>`) but are hidden from
|
|
240
|
+
// every picker/list UI and unresolvable off dev, so an in-progress
|
|
241
|
+
// experiment never surfaces to users. see isDeviceResolvableById.
|
|
242
|
+
experimental?: boolean
|
|
243
|
+
// unreleased hardware. it resolves by exact id on contributor surfaces but
|
|
244
|
+
// only a development surface offers it in a picker, and it stays
|
|
245
|
+
// unresolvable off dev, so a shipped build cannot boot it. see
|
|
246
|
+
// isDeviceResolvableById.
|
|
247
|
+
developmentOnly?: boolean
|
|
248
|
+
// posture is present on a resolved posture-aware profile. ordinary devices
|
|
249
|
+
// keep it absent so their existing device shape remains unchanged.
|
|
250
|
+
posture?: DevicePosture
|
|
251
|
+
// central fold (division) band width in points, present on an open foldable
|
|
252
|
+
// profile. the os region is active only while folded; flat-open it reads
|
|
253
|
+
// zero-width, but the band centre (the hinge line) still anchors two-group
|
|
254
|
+
// compositions. see DUO_DIVISION_REGION_WIDTH.
|
|
255
|
+
reservedDivisionWidth?: number
|
|
256
|
+
supportedPostures?: readonly DevicePosture[]
|
|
257
|
+
orientation?: InterfaceOrientation
|
|
258
|
+
// which landscape a rotated profile shows. on an open duo's portrait
|
|
259
|
+
// profile this selects its turn from the wide frame: left counterclockwise,
|
|
260
|
+
// right clockwise. both native physical poses show the portrait interface.
|
|
261
|
+
landscapeSide?: LandscapeSide
|
|
262
|
+
// the foreground scene turned the duo's vertical bar off
|
|
263
|
+
// (withSceneVerticalBar). absent while the bar is automatic.
|
|
264
|
+
verticalBar?: 'disabled'
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export type DeviceModel =
|
|
268
|
+
| 'canvas-workspace'
|
|
269
|
+
| 'iphone-se'
|
|
270
|
+
| 'iphone-14'
|
|
271
|
+
| 'iphone-15'
|
|
272
|
+
| 'iphone-15-plus'
|
|
273
|
+
| 'iphone-15-pro'
|
|
274
|
+
| 'iphone-15-pro-max'
|
|
275
|
+
| 'iphone-16'
|
|
276
|
+
| 'iphone-16-plus'
|
|
277
|
+
| 'iphone-16-pro'
|
|
278
|
+
| 'iphone-16-pro-max'
|
|
279
|
+
| 'iphone-17'
|
|
280
|
+
| 'iphone-17-air'
|
|
281
|
+
| 'iphone-17-pro'
|
|
282
|
+
| 'iphone-17-pro-max'
|
|
283
|
+
| 'iphone-duo'
|
|
284
|
+
| 'ipad-pro-11'
|
|
285
|
+
| 'ipad-pro-13'
|
|
286
|
+
| 'pixel-8'
|
|
287
|
+
| 'pixel-8-three-button'
|
|
288
|
+
| 'pixel-9-pro-xl'
|
|
289
|
+
| 'pixel-10'
|
|
290
|
+
| 'galaxy-s24'
|
|
291
|
+
| 'galaxy-s24-ultra'
|
|
292
|
+
|
|
293
|
+
function iosDevice(
|
|
294
|
+
spec: Omit<
|
|
295
|
+
DeviceSpec,
|
|
296
|
+
| 'statusBarHeight'
|
|
297
|
+
| 'platform'
|
|
298
|
+
| 'navigationBarHeight'
|
|
299
|
+
| 'navigationBarMode'
|
|
300
|
+
| 'displayCutout'
|
|
301
|
+
| 'cameraCutout'
|
|
302
|
+
| 'osVersion'
|
|
303
|
+
| 'androidApiLevel'
|
|
304
|
+
| 'systemName'
|
|
305
|
+
| 'manufacturer'
|
|
306
|
+
| 'brand'
|
|
307
|
+
| 'modelName'
|
|
308
|
+
| 'scale'
|
|
309
|
+
| 'landscapeStatusBarHeight'
|
|
310
|
+
| 'homeIndicatorHeight'
|
|
311
|
+
| 'iosVersion'
|
|
312
|
+
| 'dynamicIsland'
|
|
313
|
+
| 'keyboardPanelHeights'
|
|
314
|
+
> &
|
|
315
|
+
Partial<
|
|
316
|
+
Pick<
|
|
317
|
+
DeviceSpec,
|
|
318
|
+
| 'scale'
|
|
319
|
+
| 'landscapeStatusBarHeight'
|
|
320
|
+
| 'homeIndicatorHeight'
|
|
321
|
+
| 'iosVersion'
|
|
322
|
+
| 'keyboardPanelHeights'
|
|
323
|
+
>
|
|
324
|
+
> &
|
|
325
|
+
(
|
|
326
|
+
| { dynamicIsland: NonNullable<DeviceSpec['dynamicIsland']> }
|
|
327
|
+
| { dynamicIsland?: null; statusBarHeight: number }
|
|
328
|
+
),
|
|
329
|
+
): DeviceSpec {
|
|
330
|
+
const profile = {
|
|
331
|
+
// normal-scale dynamic split providers share this intrinsic height and
|
|
332
|
+
// linked-sdk whole-point rounding. safe areas are independent.
|
|
333
|
+
// source receipt: docs/ios-framework-oracle/status-bar-hit-region-and-scene-routing.md
|
|
334
|
+
statusBarHeight:
|
|
335
|
+
'statusBarHeight' in spec ? spec.statusBarHeight : Math.round(53.666666666666664),
|
|
336
|
+
scale: 3,
|
|
337
|
+
landscapeStatusBarHeight: 0,
|
|
338
|
+
homeIndicatorHeight: 34,
|
|
339
|
+
iosVersion: '27.0',
|
|
340
|
+
dynamicIsland: null,
|
|
341
|
+
keyboardPanelHeights: { qwerty: 301, pad: 301, emoji: 395 },
|
|
342
|
+
...spec,
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
...profile,
|
|
346
|
+
platform: 'ios',
|
|
347
|
+
navigationBarHeight: 0,
|
|
348
|
+
navigationBarMode: profile.homeIndicatorHeight > 0 ? 'gesture' : 'none',
|
|
349
|
+
displayCutout: {
|
|
350
|
+
top: profile.dynamicIsland ? profile.safeAreaInsets.top : 0,
|
|
351
|
+
bottom: 0,
|
|
352
|
+
left: 0,
|
|
353
|
+
right: 0,
|
|
354
|
+
},
|
|
355
|
+
cameraCutout: null,
|
|
356
|
+
osVersion: profile.iosVersion,
|
|
357
|
+
androidApiLevel: null,
|
|
358
|
+
systemName: 'iOS',
|
|
359
|
+
manufacturer: 'Apple',
|
|
360
|
+
brand: 'Apple',
|
|
361
|
+
modelName: profile.name,
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// corner metrics come from Apple's framebufferMask PDFs in each
|
|
366
|
+
// .simdevicetype bundle. cornerRadius is the effective circle fit;
|
|
367
|
+
// continuousCornerRadius is the straight-edge tangent extent of the mask.
|
|
368
|
+
// they are deliberately different because no circular arc can reproduce an
|
|
369
|
+
// Apple continuous corner.
|
|
370
|
+
// profile construction is pure; helper-only imports must not retain the catalog.
|
|
371
|
+
export const devices: Record<DeviceModel, DeviceSpec> = {
|
|
372
|
+
'canvas-workspace': /* @__PURE__ */ iosDevice({
|
|
373
|
+
model: 'canvas-workspace',
|
|
374
|
+
name: 'Canvas Workspace',
|
|
375
|
+
width: 1440,
|
|
376
|
+
height: 900,
|
|
377
|
+
scale: 1,
|
|
378
|
+
statusBarHeight: 0,
|
|
379
|
+
homeIndicatorHeight: 0,
|
|
380
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(0),
|
|
381
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(0),
|
|
382
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(16),
|
|
383
|
+
safeAreaInsets: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
384
|
+
// no native device has this geometry; carries the iphone 16 keyboard
|
|
385
|
+
// height so the experimental profile still shows a keyboard.
|
|
386
|
+
physicalPPI: 110,
|
|
387
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
388
|
+
[185.8, 41.7],
|
|
389
|
+
[258.2, 67.6],
|
|
390
|
+
[344, 67.6],
|
|
391
|
+
[281.5, 106.9],
|
|
392
|
+
),
|
|
393
|
+
experimental: true,
|
|
394
|
+
}),
|
|
395
|
+
'iphone-se': /* @__PURE__ */ iosDevice({
|
|
396
|
+
model: 'iphone-se',
|
|
397
|
+
name: 'iPhone SE',
|
|
398
|
+
width: 375,
|
|
399
|
+
height: 667,
|
|
400
|
+
scale: 2,
|
|
401
|
+
statusBarHeight: 20,
|
|
402
|
+
homeIndicatorHeight: 0,
|
|
403
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(0),
|
|
404
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(0),
|
|
405
|
+
// legacy home-button frame uses asymmetric LEGACY_*_BEZEL constants in the
|
|
406
|
+
// shell (111pt forehead/chin, 29pt sides); uniform frameInsets are a sane
|
|
407
|
+
// modern-path value and mirror the SE's ~28.7pt side bezel.
|
|
408
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(28.7),
|
|
409
|
+
safeAreaInsets: { top: 20, bottom: 0, left: 0, right: 0 },
|
|
410
|
+
keyboardPanelHeights: { qwerty: 226, pad: 226, emoji: 320 },
|
|
411
|
+
physicalPPI: 326,
|
|
412
|
+
hardwareButtons: LEGACY_HARDWARE_BUTTONS,
|
|
413
|
+
}),
|
|
414
|
+
'iphone-14': /* @__PURE__ */ iosDevice({
|
|
415
|
+
model: 'iphone-14',
|
|
416
|
+
name: 'iPhone 14',
|
|
417
|
+
width: 390,
|
|
418
|
+
height: 844,
|
|
419
|
+
statusBarHeight: 47,
|
|
420
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(46.2),
|
|
421
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(67.462),
|
|
422
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(19.5),
|
|
423
|
+
safeAreaInsets: { top: 47, bottom: 34, left: 0, right: 0 },
|
|
424
|
+
physicalPPI: 460,
|
|
425
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
426
|
+
[141.7, 29.7],
|
|
427
|
+
[205.9, 69.6],
|
|
428
|
+
[289.5, 69.6],
|
|
429
|
+
[228.9, 114.5],
|
|
430
|
+
),
|
|
431
|
+
}),
|
|
432
|
+
'iphone-15': /* @__PURE__ */ iosDevice({
|
|
433
|
+
model: 'iphone-15',
|
|
434
|
+
name: 'iPhone 15',
|
|
435
|
+
width: 393,
|
|
436
|
+
height: 852,
|
|
437
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
438
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(73.402),
|
|
439
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(18.2),
|
|
440
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
441
|
+
statusRowCenter: 32.75,
|
|
442
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
443
|
+
physicalPPI: 460,
|
|
444
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
445
|
+
[171.7, 32],
|
|
446
|
+
[235.8, 65.3],
|
|
447
|
+
[320.5, 65.3],
|
|
448
|
+
[280.6, 105.2],
|
|
449
|
+
),
|
|
450
|
+
}),
|
|
451
|
+
'iphone-15-plus': /* @__PURE__ */ iosDevice({
|
|
452
|
+
model: 'iphone-15-plus',
|
|
453
|
+
name: 'iPhone 15 Plus',
|
|
454
|
+
width: 430,
|
|
455
|
+
height: 932,
|
|
456
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
457
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(74.654),
|
|
458
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(17.3),
|
|
459
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
460
|
+
statusRowCenter: 30.05,
|
|
461
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
462
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
463
|
+
physicalPPI: 460,
|
|
464
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
465
|
+
[172.1, 33],
|
|
466
|
+
[236.1, 66.6],
|
|
467
|
+
[321.2, 66.6],
|
|
468
|
+
[281, 106.8],
|
|
469
|
+
),
|
|
470
|
+
}),
|
|
471
|
+
'iphone-15-pro': /* @__PURE__ */ iosDevice({
|
|
472
|
+
model: 'iphone-15-pro',
|
|
473
|
+
name: 'iPhone 15 Pro',
|
|
474
|
+
width: 393,
|
|
475
|
+
height: 852,
|
|
476
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
477
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(73.402),
|
|
478
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
479
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
480
|
+
statusRowCenter: 32.4,
|
|
481
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
482
|
+
physicalPPI: 460,
|
|
483
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
484
|
+
[159.1, 31.5],
|
|
485
|
+
[220.1, 61.9],
|
|
486
|
+
[299, 61.9],
|
|
487
|
+
[260.8, 98.9],
|
|
488
|
+
),
|
|
489
|
+
}),
|
|
490
|
+
'iphone-15-pro-max': /* @__PURE__ */ iosDevice({
|
|
491
|
+
model: 'iphone-15-pro-max',
|
|
492
|
+
name: 'iPhone 15 Pro Max',
|
|
493
|
+
width: 430,
|
|
494
|
+
height: 932,
|
|
495
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
496
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(74.654),
|
|
497
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
498
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
499
|
+
statusRowCenter: 32.3,
|
|
500
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
501
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
502
|
+
physicalPPI: 460,
|
|
503
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
504
|
+
[173.3, 32.2],
|
|
505
|
+
[253.4, 61.7],
|
|
506
|
+
[343.3, 61.7],
|
|
507
|
+
[268.5, 98.5],
|
|
508
|
+
),
|
|
509
|
+
}),
|
|
510
|
+
'iphone-16': /* @__PURE__ */ iosDevice({
|
|
511
|
+
model: 'iphone-16',
|
|
512
|
+
name: 'iPhone 16',
|
|
513
|
+
width: 393,
|
|
514
|
+
height: 852,
|
|
515
|
+
// 2026-07-10: cornerRadius corrected 58 → 53.9 to Apple's own framebuffer
|
|
516
|
+
// mask (extracted from the simdevicetype bundle PDF; see
|
|
517
|
+
// packages/peach-engine/assets/device-frame-geometry). radius is a paint clip only — the
|
|
518
|
+
// calibrated conformance-oracle layout fields below are unchanged.
|
|
519
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
520
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(73.402),
|
|
521
|
+
// uikit's concentric-corner getter on the ios 27 iphone 16 returns 55.
|
|
522
|
+
systemCornerRadius: /* @__PURE__ */ cornerRadii(55),
|
|
523
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
524
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 34 / 3 },
|
|
525
|
+
statusRowCenter: 29.65,
|
|
526
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
527
|
+
keyboardPanelHeights: { qwerty: 301, pad: 302, emoji: 395 },
|
|
528
|
+
physicalPPI: 460,
|
|
529
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
530
|
+
[159.1, 31.5],
|
|
531
|
+
[220.1, 61.9],
|
|
532
|
+
[299, 61.9],
|
|
533
|
+
[260.8, 98.9],
|
|
534
|
+
),
|
|
535
|
+
}),
|
|
536
|
+
'iphone-16-plus': /* @__PURE__ */ iosDevice({
|
|
537
|
+
model: 'iphone-16-plus',
|
|
538
|
+
name: 'iPhone 16 Plus',
|
|
539
|
+
width: 430,
|
|
540
|
+
height: 932,
|
|
541
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(53.9),
|
|
542
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(74.654),
|
|
543
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
544
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 34 / 3 },
|
|
545
|
+
statusRowCenter: 30.05,
|
|
546
|
+
safeAreaInsets: { top: 59, bottom: 34, left: 0, right: 0 },
|
|
547
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
548
|
+
physicalPPI: 460,
|
|
549
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
550
|
+
[173.3, 32.2],
|
|
551
|
+
[253.4, 61.7],
|
|
552
|
+
[343.3, 61.7],
|
|
553
|
+
[268.5, 98.5],
|
|
554
|
+
),
|
|
555
|
+
}),
|
|
556
|
+
'iphone-16-pro': /* @__PURE__ */ iosDevice({
|
|
557
|
+
model: 'iphone-16-pro',
|
|
558
|
+
name: 'iPhone 16 Pro',
|
|
559
|
+
width: 402,
|
|
560
|
+
height: 874,
|
|
561
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(61),
|
|
562
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(84.661),
|
|
563
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
564
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
565
|
+
statusRowCenter: 32.5,
|
|
566
|
+
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
567
|
+
physicalPPI: 460,
|
|
568
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
569
|
+
[159.1, 31.5],
|
|
570
|
+
[220.1, 61.9],
|
|
571
|
+
[299, 61.9],
|
|
572
|
+
[260.8, 98.9],
|
|
573
|
+
),
|
|
574
|
+
}),
|
|
575
|
+
'iphone-16-pro-max': /* @__PURE__ */ iosDevice({
|
|
576
|
+
model: 'iphone-16-pro-max',
|
|
577
|
+
name: 'iPhone 16 Pro Max',
|
|
578
|
+
width: 440,
|
|
579
|
+
height: 956,
|
|
580
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(61.3),
|
|
581
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(85.163),
|
|
582
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.4),
|
|
583
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 14 },
|
|
584
|
+
statusRowCenter: 33,
|
|
585
|
+
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
586
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
587
|
+
physicalPPI: 460,
|
|
588
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
589
|
+
[178.8, 32.2],
|
|
590
|
+
[266.8, 61.8],
|
|
591
|
+
[352.7, 61.8],
|
|
592
|
+
[292.2, 98.3],
|
|
593
|
+
),
|
|
594
|
+
}),
|
|
595
|
+
'iphone-17': /* @__PURE__ */ iosDevice({
|
|
596
|
+
model: 'iphone-17',
|
|
597
|
+
name: 'iPhone 17',
|
|
598
|
+
width: 402,
|
|
599
|
+
height: 874,
|
|
600
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(61),
|
|
601
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(84.661),
|
|
602
|
+
// display border 1.44mm plus the visible flat housing rail.
|
|
603
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
604
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
605
|
+
statusRowCenter: 32.65,
|
|
606
|
+
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
607
|
+
physicalPPI: 460,
|
|
608
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
609
|
+
[159.1, 31.5],
|
|
610
|
+
[220.1, 61.9],
|
|
611
|
+
[299, 61.9],
|
|
612
|
+
[260.8, 98.9],
|
|
613
|
+
),
|
|
614
|
+
}),
|
|
615
|
+
'iphone-17-air': /* @__PURE__ */ iosDevice({
|
|
616
|
+
model: 'iphone-17-air',
|
|
617
|
+
// apple markets this as "iphone air" (not "iphone 17 air"). the real air
|
|
618
|
+
// is 420x912 with thin bezels and a lower-sitting island. it is not the
|
|
619
|
+
// 430x932 Plus body it used to be cloned from.
|
|
620
|
+
name: 'iPhone Air',
|
|
621
|
+
width: 420,
|
|
622
|
+
height: 912,
|
|
623
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(64.6),
|
|
624
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(88.313),
|
|
625
|
+
// WHICH QUANTITY THIS IS, because it has been flipped twice and each pass
|
|
626
|
+
// read the other one as a bug: frameInsets is the VISIBLE FACE-ON frame —
|
|
627
|
+
// the black display border plus however much housing rail you actually see
|
|
628
|
+
// looking straight at the phone. It is NOT the caliper silhouette.
|
|
629
|
+
//
|
|
630
|
+
// Apple publishes a 74.7×156.2mm body around a 1260×2736 display at 460ppi,
|
|
631
|
+
// which is 15.475pt per side to the silhouette; that is the number to use if
|
|
632
|
+
// you ever need physical dimensions, and it is what commit 4966fe6cac put
|
|
633
|
+
// here. But most of that width on the Air is curved titanium turning away
|
|
634
|
+
// from a head-on view, so rendering it as frame draws the Air with the
|
|
635
|
+
// THICKEST bezel of any iPhone we ship when the real Air has the thinnest.
|
|
636
|
+
//
|
|
637
|
+
// So: 1.435mm display border = 8.69pt, plus ~2pt of rail that is actually
|
|
638
|
+
// face-on. The 17 Pro's flat rail contributes ~6.6pt on the same basis,
|
|
639
|
+
// which is why it sits at 15.3 and the Air should not.
|
|
640
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(10.7),
|
|
641
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 20 },
|
|
642
|
+
statusRowCenter: 39,
|
|
643
|
+
safeAreaInsets: { top: 68, bottom: 34, left: 0, right: 0 },
|
|
644
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
645
|
+
physicalPPI: 460,
|
|
646
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
647
|
+
[178.8, 32.2],
|
|
648
|
+
[266.8, 61.8],
|
|
649
|
+
[352.7, 61.8],
|
|
650
|
+
[292.2, 98.3],
|
|
651
|
+
),
|
|
652
|
+
}),
|
|
653
|
+
'iphone-17-pro': /* @__PURE__ */ iosDevice({
|
|
654
|
+
model: 'iphone-17-pro',
|
|
655
|
+
name: 'iPhone 17 Pro',
|
|
656
|
+
width: 402,
|
|
657
|
+
height: 874,
|
|
658
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(61),
|
|
659
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(84.661),
|
|
660
|
+
// the ios 27 simulator's ContainerRelativeShape at the root draws 62
|
|
661
|
+
// less its smallest inset from the display (54 at 8pt, 32 at 30pt).
|
|
662
|
+
systemCornerRadius: /* @__PURE__ */ cornerRadii(62),
|
|
663
|
+
// display border 1.44mm plus the visible flat housing rail.
|
|
664
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.3),
|
|
665
|
+
dynamicIsland: { width: 125, height: 110 / 3, top: 14 },
|
|
666
|
+
statusRowCenter: 33,
|
|
667
|
+
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
668
|
+
// keyboardDidShow on the ios 27.0 simulator: 301 for the default keyboard,
|
|
669
|
+
// 302 for the number pad.
|
|
670
|
+
keyboardPanelHeights: { qwerty: 301, pad: 302, emoji: 395 },
|
|
671
|
+
physicalPPI: 460,
|
|
672
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
673
|
+
[159.1, 31.5],
|
|
674
|
+
[220.1, 61.9],
|
|
675
|
+
[299, 61.9],
|
|
676
|
+
[260.8, 98.9],
|
|
677
|
+
),
|
|
678
|
+
}),
|
|
679
|
+
'iphone-17-pro-max': /* @__PURE__ */ iosDevice({
|
|
680
|
+
model: 'iphone-17-pro-max',
|
|
681
|
+
name: 'iPhone 17 Pro Max',
|
|
682
|
+
width: 440,
|
|
683
|
+
height: 956,
|
|
684
|
+
// same ios 26.4 440x956 dynamic island max profile as the measured
|
|
685
|
+
// iphone 16 pro max screens proof oracle.
|
|
686
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(61.3),
|
|
687
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(85.163),
|
|
688
|
+
// display border 1.36mm plus the visible flat housing rail.
|
|
689
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(15.4),
|
|
690
|
+
dynamicIsland: { width: 376 / 3, height: 110 / 3, top: 14 },
|
|
691
|
+
statusRowCenter: 33,
|
|
692
|
+
safeAreaInsets: { top: 62, bottom: 34, left: 0, right: 0 },
|
|
693
|
+
keyboardPanelHeights: { qwerty: 311, pad: 311, emoji: 405 },
|
|
694
|
+
physicalPPI: 460,
|
|
695
|
+
hardwareButtons: /* @__PURE__ */ modernButtons(
|
|
696
|
+
[178.8, 32.2],
|
|
697
|
+
[266.8, 61.8],
|
|
698
|
+
[352.7, 61.8],
|
|
699
|
+
[292.2, 98.3],
|
|
700
|
+
),
|
|
701
|
+
}),
|
|
702
|
+
'iphone-duo': {
|
|
703
|
+
// offered on contributor surfaces only while the 27 home and the hinge
|
|
704
|
+
// measurements are still settling (nate, 2026-09-15).
|
|
705
|
+
developmentOnly: true,
|
|
706
|
+
.../* @__PURE__ */ iosDevice({
|
|
707
|
+
model: 'iphone-duo',
|
|
708
|
+
name: 'iPhone Duo',
|
|
709
|
+
width: 466,
|
|
710
|
+
height: 678,
|
|
711
|
+
statusBarHeight: 66,
|
|
712
|
+
// the ios 27.1 duo simulator draws the gesture home indicator in both
|
|
713
|
+
// postures: a 167pt x 5pt pill 8pt above the display bottom on the
|
|
714
|
+
// cover, sized by the same rule as the other iphones (HomeIndicator).
|
|
715
|
+
// hinge on the left. the hinge-side display corners measure 5pt in
|
|
716
|
+
// apple's 2d outer product art; the free side keeps the 61pt pro curve.
|
|
717
|
+
cornerRadius: { topLeft: 5, topRight: 61, bottomRight: 61, bottomLeft: 5 },
|
|
718
|
+
continuousCornerRadius: {
|
|
719
|
+
topLeft: 5,
|
|
720
|
+
topRight: 61,
|
|
721
|
+
bottomRight: 61,
|
|
722
|
+
bottomLeft: 5,
|
|
723
|
+
},
|
|
724
|
+
// the ios 27.1 duo simulator reports 59, and sheets 8pt in on the free
|
|
725
|
+
// side carry 51 there (41 at 18pt in).
|
|
726
|
+
systemCornerRadius: { topLeft: 5, topRight: 59, bottomRight: 59, bottomLeft: 5 },
|
|
727
|
+
// display edge to silhouette, measured off apple's 2d outer product art
|
|
728
|
+
// at 3x. the barrel is not part of the body: it protrudes 11.67pt past
|
|
729
|
+
// the left silhouette, so the full outer width is frame + protrusion.
|
|
730
|
+
frameInsets: { top: 16.3333, right: 16.3333, bottom: 16, left: 14 },
|
|
731
|
+
// the spine is a flat cut, so its corners are tiny; the free side keeps
|
|
732
|
+
// the 75pt body curve the pro bodies use.
|
|
733
|
+
frameCornerRadius: {
|
|
734
|
+
topLeft: 4.3333,
|
|
735
|
+
topRight: 75,
|
|
736
|
+
bottomRight: 75,
|
|
737
|
+
bottomLeft: 3.3333,
|
|
738
|
+
},
|
|
739
|
+
housing: {
|
|
740
|
+
rail: { top: 7.5, right: 8, bottom: 7.3333, left: 5.3333 },
|
|
741
|
+
hingeBarrel: { width: 16.6667, endInset: 7.3333, protrusion: 11.6667 },
|
|
742
|
+
},
|
|
743
|
+
// 84pt trailing Vertical Bar on the outer display (Apple iOS 27 UI kit).
|
|
744
|
+
safeAreaInsets: { top: 0, bottom: 34, left: 0, right: 84 },
|
|
745
|
+
iosVersion: '27.1',
|
|
746
|
+
// focused keyboard frames on the ios 27.1 duo simulator's cover: qwerty
|
|
747
|
+
// (0,426,466,252), number pad 256, emoji (0,340,466,338)pt
|
|
748
|
+
// (plans/contrast/duo-platform.md)
|
|
749
|
+
keyboardPanelHeights: { qwerty: 252, pad: 256, emoji: 338 },
|
|
750
|
+
physicalPPI: 460,
|
|
751
|
+
// official model extraction for button positions is outside this slice.
|
|
752
|
+
hardwareButtons: /* @__PURE__ */ modernButtons([0, 0], [0, 0], [0, 0], [0, 0]),
|
|
753
|
+
posture: 'closed',
|
|
754
|
+
supportedPostures: ['closed', 'open'],
|
|
755
|
+
}),
|
|
756
|
+
// the ios 27.1 simulator's camera occlusion region: 37pt, 29 1/3 in from
|
|
757
|
+
// the top and trailing edges
|
|
758
|
+
cameraCutout: {
|
|
759
|
+
diameter: 37,
|
|
760
|
+
top: 88 / 3,
|
|
761
|
+
trailing: 88 / 3,
|
|
762
|
+
},
|
|
763
|
+
},
|
|
764
|
+
'ipad-pro-11': {
|
|
765
|
+
// frame and hardware buttons are not sourced yet, so this stays off the
|
|
766
|
+
// shipping picker the same way the duo does.
|
|
767
|
+
developmentOnly: true,
|
|
768
|
+
.../* @__PURE__ */ ipadProDevice(
|
|
769
|
+
'ipad-pro-11',
|
|
770
|
+
'iPad Pro 11-inch (M5)',
|
|
771
|
+
834,
|
|
772
|
+
1210,
|
|
773
|
+
11,
|
|
774
|
+
),
|
|
775
|
+
},
|
|
776
|
+
'ipad-pro-13': /* @__PURE__ */ ipadProDevice(
|
|
777
|
+
'ipad-pro-13',
|
|
778
|
+
'iPad Pro 13-inch (M5)',
|
|
779
|
+
1032,
|
|
780
|
+
1376,
|
|
781
|
+
13,
|
|
782
|
+
),
|
|
783
|
+
'pixel-8': {
|
|
784
|
+
model: 'pixel-8',
|
|
785
|
+
platform: 'android',
|
|
786
|
+
name: 'Pixel 8',
|
|
787
|
+
width: PIXEL_8_WIDTH,
|
|
788
|
+
height: PIXEL_8_HEIGHT,
|
|
789
|
+
scale: 2.625,
|
|
790
|
+
statusBarHeight: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
791
|
+
landscapeStatusBarHeight: PIXEL_8_LANDSCAPE_STATUS_BAR_HEIGHT,
|
|
792
|
+
homeIndicatorHeight: 0,
|
|
793
|
+
navigationBarHeight: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
794
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
795
|
+
navigationBarMode: 'gesture',
|
|
796
|
+
displayCutout: {
|
|
797
|
+
top: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
798
|
+
bottom: 0,
|
|
799
|
+
left: 0,
|
|
800
|
+
right: 0,
|
|
801
|
+
},
|
|
802
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(39),
|
|
803
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(39),
|
|
804
|
+
// android studio's pixel 8 device art places the 1080x2400 display at
|
|
805
|
+
// (49,55) in a 1187x2513 body. the right side button occupies the final
|
|
806
|
+
// 8 physical pixels, so the body insets are 49/50/58/55 at 2.625x.
|
|
807
|
+
frameInsets: {
|
|
808
|
+
top: 55 / 2.625,
|
|
809
|
+
right: 50 / 2.625,
|
|
810
|
+
bottom: 58 / 2.625,
|
|
811
|
+
left: 49 / 2.625,
|
|
812
|
+
},
|
|
813
|
+
dynamicIsland: null,
|
|
814
|
+
cameraCutout: { diameter: 72.5 / 2.625 },
|
|
815
|
+
safeAreaInsets: {
|
|
816
|
+
top: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
817
|
+
bottom: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
818
|
+
left: 0,
|
|
819
|
+
right: 0,
|
|
820
|
+
},
|
|
821
|
+
osVersion: ANDROID_OS_VERSION,
|
|
822
|
+
iosVersion: '',
|
|
823
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
824
|
+
systemName: 'Android',
|
|
825
|
+
manufacturer: 'Google',
|
|
826
|
+
brand: 'google',
|
|
827
|
+
modelName: 'Pixel 8',
|
|
828
|
+
physicalPPI: 428,
|
|
829
|
+
hardwareButtons: PIXEL_HARDWARE_BUTTONS,
|
|
830
|
+
},
|
|
831
|
+
'pixel-8-three-button': {
|
|
832
|
+
model: 'pixel-8-three-button',
|
|
833
|
+
platform: 'android',
|
|
834
|
+
name: 'Pixel 8 (3-button)',
|
|
835
|
+
width: PIXEL_8_WIDTH,
|
|
836
|
+
height: PIXEL_8_HEIGHT,
|
|
837
|
+
scale: 2.625,
|
|
838
|
+
statusBarHeight: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
839
|
+
landscapeStatusBarHeight: PIXEL_8_LANDSCAPE_STATUS_BAR_HEIGHT,
|
|
840
|
+
homeIndicatorHeight: 0,
|
|
841
|
+
navigationBarHeight: 48,
|
|
842
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
843
|
+
navigationBarMode: 'three-button',
|
|
844
|
+
displayCutout: {
|
|
845
|
+
top: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
846
|
+
bottom: 0,
|
|
847
|
+
left: 0,
|
|
848
|
+
right: 0,
|
|
849
|
+
},
|
|
850
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(39),
|
|
851
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(39),
|
|
852
|
+
frameInsets: {
|
|
853
|
+
top: 55 / 2.625,
|
|
854
|
+
right: 50 / 2.625,
|
|
855
|
+
bottom: 58 / 2.625,
|
|
856
|
+
left: 49 / 2.625,
|
|
857
|
+
},
|
|
858
|
+
dynamicIsland: null,
|
|
859
|
+
cameraCutout: { diameter: 72.5 / 2.625 },
|
|
860
|
+
safeAreaInsets: {
|
|
861
|
+
top: PIXEL_8_STATUS_BAR_HEIGHT,
|
|
862
|
+
bottom: 48,
|
|
863
|
+
left: 0,
|
|
864
|
+
right: 0,
|
|
865
|
+
},
|
|
866
|
+
osVersion: ANDROID_OS_VERSION,
|
|
867
|
+
iosVersion: '',
|
|
868
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
869
|
+
systemName: 'Android',
|
|
870
|
+
manufacturer: 'Google',
|
|
871
|
+
brand: 'google',
|
|
872
|
+
modelName: 'Pixel 8',
|
|
873
|
+
physicalPPI: 428,
|
|
874
|
+
hardwareButtons: PIXEL_HARDWARE_BUTTONS,
|
|
875
|
+
},
|
|
876
|
+
'pixel-9-pro-xl': {
|
|
877
|
+
model: 'pixel-9-pro-xl',
|
|
878
|
+
platform: 'android',
|
|
879
|
+
name: 'Pixel 9 Pro XL',
|
|
880
|
+
width: 448,
|
|
881
|
+
height: 997,
|
|
882
|
+
scale: 3,
|
|
883
|
+
statusBarHeight: 40,
|
|
884
|
+
landscapeStatusBarHeight: 40,
|
|
885
|
+
homeIndicatorHeight: 0,
|
|
886
|
+
navigationBarHeight: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
887
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
888
|
+
navigationBarMode: 'gesture',
|
|
889
|
+
displayCutout: { top: 40, bottom: 0, left: 0, right: 0 },
|
|
890
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(41),
|
|
891
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(41),
|
|
892
|
+
// Pixel 9 Pro XL body 162.8×76.6mm over a 70.2mm panel → ~1.8mm ≈ 12pt.
|
|
893
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(12),
|
|
894
|
+
dynamicIsland: null,
|
|
895
|
+
cameraCutout: { diameter: 24 },
|
|
896
|
+
safeAreaInsets: {
|
|
897
|
+
top: 40,
|
|
898
|
+
bottom: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
899
|
+
left: 0,
|
|
900
|
+
right: 0,
|
|
901
|
+
},
|
|
902
|
+
osVersion: ANDROID_OS_VERSION,
|
|
903
|
+
iosVersion: '',
|
|
904
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
905
|
+
systemName: 'Android',
|
|
906
|
+
manufacturer: 'Google',
|
|
907
|
+
brand: 'google',
|
|
908
|
+
modelName: 'Pixel 9 Pro XL',
|
|
909
|
+
physicalPPI: 486,
|
|
910
|
+
hardwareButtons: PIXEL_HARDWARE_BUTTONS,
|
|
911
|
+
},
|
|
912
|
+
'pixel-10': {
|
|
913
|
+
model: 'pixel-10',
|
|
914
|
+
platform: 'android',
|
|
915
|
+
name: 'Pixel 10',
|
|
916
|
+
width: 360,
|
|
917
|
+
height: 808,
|
|
918
|
+
scale: 3,
|
|
919
|
+
statusBarHeight: 40,
|
|
920
|
+
landscapeStatusBarHeight: 40,
|
|
921
|
+
homeIndicatorHeight: 0,
|
|
922
|
+
navigationBarHeight: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
923
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
924
|
+
navigationBarMode: 'gesture',
|
|
925
|
+
displayCutout: { top: 40, bottom: 0, left: 0, right: 0 },
|
|
926
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(40),
|
|
927
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(40),
|
|
928
|
+
// the 72mm body surrounds a roughly 65.1mm-wide 6.3-inch panel, which
|
|
929
|
+
// resolves to about 18 logical points of frame around the 1080px display.
|
|
930
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(18),
|
|
931
|
+
dynamicIsland: null,
|
|
932
|
+
cameraCutout: { diameter: 26 },
|
|
933
|
+
safeAreaInsets: {
|
|
934
|
+
top: 40,
|
|
935
|
+
bottom: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
936
|
+
left: 0,
|
|
937
|
+
right: 0,
|
|
938
|
+
},
|
|
939
|
+
osVersion: ANDROID_OS_VERSION,
|
|
940
|
+
iosVersion: '',
|
|
941
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
942
|
+
systemName: 'Android',
|
|
943
|
+
manufacturer: 'Google',
|
|
944
|
+
brand: 'google',
|
|
945
|
+
modelName: 'Pixel 10',
|
|
946
|
+
physicalPPI: 422,
|
|
947
|
+
hardwareButtons: PIXEL_HARDWARE_BUTTONS,
|
|
948
|
+
},
|
|
949
|
+
'galaxy-s24': {
|
|
950
|
+
model: 'galaxy-s24',
|
|
951
|
+
platform: 'android',
|
|
952
|
+
name: 'Galaxy S24',
|
|
953
|
+
width: 360,
|
|
954
|
+
height: 780,
|
|
955
|
+
scale: 3,
|
|
956
|
+
statusBarHeight: 36,
|
|
957
|
+
landscapeStatusBarHeight: 36,
|
|
958
|
+
homeIndicatorHeight: 0,
|
|
959
|
+
navigationBarHeight: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
960
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
961
|
+
navigationBarMode: 'gesture',
|
|
962
|
+
displayCutout: { top: 36, bottom: 0, left: 0, right: 0 },
|
|
963
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(36),
|
|
964
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(36),
|
|
965
|
+
// Galaxy S24 body 147.0×70.6mm over a 65.9mm panel → ~1.2mm ≈ 8pt (Samsung
|
|
966
|
+
// flat-display bezels are noticeably thinner than Pixel's).
|
|
967
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(8),
|
|
968
|
+
dynamicIsland: null,
|
|
969
|
+
cameraCutout: { diameter: 18 },
|
|
970
|
+
safeAreaInsets: {
|
|
971
|
+
top: 36,
|
|
972
|
+
bottom: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
973
|
+
left: 0,
|
|
974
|
+
right: 0,
|
|
975
|
+
},
|
|
976
|
+
osVersion: ANDROID_OS_VERSION,
|
|
977
|
+
iosVersion: '',
|
|
978
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
979
|
+
systemName: 'Android',
|
|
980
|
+
manufacturer: 'Samsung',
|
|
981
|
+
brand: 'samsung',
|
|
982
|
+
modelName: 'SM-S921B',
|
|
983
|
+
physicalPPI: 416,
|
|
984
|
+
hardwareButtons: GALAXY_HARDWARE_BUTTONS,
|
|
985
|
+
},
|
|
986
|
+
'galaxy-s24-ultra': {
|
|
987
|
+
model: 'galaxy-s24-ultra',
|
|
988
|
+
platform: 'android',
|
|
989
|
+
name: 'Galaxy S24 Ultra',
|
|
990
|
+
width: 384,
|
|
991
|
+
// samsung publishes a 1440x3120 panel; 3.75x resolves to 384x832.
|
|
992
|
+
height: 832,
|
|
993
|
+
scale: 3.75,
|
|
994
|
+
statusBarHeight: 36,
|
|
995
|
+
landscapeStatusBarHeight: 36,
|
|
996
|
+
homeIndicatorHeight: 0,
|
|
997
|
+
navigationBarHeight: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
998
|
+
keyboardPanelHeights: GBOARD_PANEL_HEIGHTS,
|
|
999
|
+
navigationBarMode: 'gesture',
|
|
1000
|
+
displayCutout: { top: 36, bottom: 0, left: 0, right: 0 },
|
|
1001
|
+
cornerRadius: /* @__PURE__ */ cornerRadii(24),
|
|
1002
|
+
continuousCornerRadius: /* @__PURE__ */ cornerRadii(24),
|
|
1003
|
+
// Galaxy S24 Ultra body 162.3×79.0mm over a 72.4mm panel → ~1.5mm ≈ 9pt.
|
|
1004
|
+
frameInsets: /* @__PURE__ */ uniformFrameInsets(9),
|
|
1005
|
+
dynamicIsland: null,
|
|
1006
|
+
cameraCutout: { diameter: 18 },
|
|
1007
|
+
safeAreaInsets: {
|
|
1008
|
+
top: 36,
|
|
1009
|
+
bottom: ANDROID_GESTURE_NAV_BAR_HEIGHT,
|
|
1010
|
+
left: 0,
|
|
1011
|
+
right: 0,
|
|
1012
|
+
},
|
|
1013
|
+
osVersion: ANDROID_OS_VERSION,
|
|
1014
|
+
iosVersion: '',
|
|
1015
|
+
androidApiLevel: ANDROID_API_LEVEL,
|
|
1016
|
+
systemName: 'Android',
|
|
1017
|
+
manufacturer: 'Samsung',
|
|
1018
|
+
brand: 'samsung',
|
|
1019
|
+
modelName: 'SM-S928B',
|
|
1020
|
+
physicalPPI: 505,
|
|
1021
|
+
hardwareButtons: GALAXY_HARDWARE_BUTTONS,
|
|
1022
|
+
},
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
export const DEFAULT_DEVICE: DeviceModel = 'iphone-17-pro'
|
|
1026
|
+
|
|
1027
|
+
// the device `peach ios` / `peach android` fall back to when the current setting
|
|
1028
|
+
// belongs to the other platform. lives here so the CLI never hardcodes a
|
|
1029
|
+
// model id the device registry owns.
|
|
1030
|
+
export const DEFAULT_DEVICE_BY_PLATFORM: Record<RuntimePlatform, DeviceModel> = {
|
|
1031
|
+
ios: DEFAULT_DEVICE,
|
|
1032
|
+
android: 'pixel-10',
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
// the interface poses a scene can support, uikit's interface orientations
|
|
1036
|
+
// without upside down (no home-indicator iphone presents it). landscape left
|
|
1037
|
+
// is the body turned clockwise. a scene's poses keep this order, so the first
|
|
1038
|
+
// is the one it arrives in from a pose it does not support: a landscape-only
|
|
1039
|
+
// app comes up in landscape right from portrait, as expo's orientation
|
|
1040
|
+
// registry deduces it.
|
|
1041
|
+
export type InterfacePose = 'portrait' | 'landscape-left' | 'landscape-right'
|
|
1042
|
+
|
|
1043
|
+
export const ALL_INTERFACE_POSES: readonly InterfacePose[] = [
|
|
1044
|
+
'portrait',
|
|
1045
|
+
'landscape-right',
|
|
1046
|
+
'landscape-left',
|
|
1047
|
+
]
|
|
1048
|
+
|
|
1049
|
+
// springboard does not rotate on the phones that hold a scene's interface
|
|
1050
|
+
export const HOME_INTERFACE_POSES: readonly InterfacePose[] = ['portrait']
|
|
1051
|
+
|
|
1052
|
+
// the turn, clockwise in degrees, that shows a display interface laid out in
|
|
1053
|
+
// `display` on the glass of a body standing in `body`: zero when the interface
|
|
1054
|
+
// turned with the body, otherwise the body's turn away from it.
|
|
1055
|
+
export type DisplayHold = -90 | 0 | 90 | 180
|
|
1056
|
+
|
|
1057
|
+
export type SizeClass = 'compact' | 'regular'
|
|
1058
|
+
|
|
1059
|
+
export type InterfaceOrientation = 'portrait' | 'landscape'
|
|
1060
|
+
|
|
1061
|
+
// uikit's UIInterfaceOrientationLandscapeLeft and ...Right: left is the
|
|
1062
|
+
// portrait device turned clockwise, the top of the glass on the right; right
|
|
1063
|
+
// is the mirror, as detox's setOrientation('landscape') requests.
|
|
1064
|
+
export type LandscapeSide = 'left' | 'right'
|
|
1065
|
+
|
|
1066
|
+
export type RotateDirection = 'left' | 'right'
|
|
1067
|
+
|
|
1068
|
+
// the iphones whose HORIZONTAL size class is regular in landscape. apple never
|
|
1069
|
+
// published a width threshold past the iphone 6 plus, so this is a family rule
|
|
1070
|
+
// and deliberately not a number: plus, pro max and air bodies go regular in
|
|
1071
|
+
// landscape, every other iphone stays compact, and every iphone is compact x
|
|
1072
|
+
// regular in portrait. sources are in plans/sootsim/ios-size-class-table.md,
|
|
1073
|
+
// where apple's own word covers the 6 plus and the family rule, and the rows for
|
|
1074
|
+
// iphone 12 and later are marked INFERRED from that rule rather than measured on
|
|
1075
|
+
// a device. a surprise here is a bug in that table, not in the caller.
|
|
1076
|
+
|
|
1077
|
+
// UIViewController.preferredVerticalBarBehavior, per horizontal size class:
|
|
1078
|
+
// what the foreground scene asks of the duo's vertical bar.
|
|
1079
|
+
export type VerticalBarBehavior = 'automatic' | 'disabled'
|
|
1080
|
+
|
|
1081
|
+
export type SceneVerticalBar = Readonly<Record<SizeClass, VerticalBarBehavior>>
|
|
1082
|
+
|
|
1083
|
+
export const AUTOMATIC_VERTICAL_BAR: SceneVerticalBar = {
|
|
1084
|
+
compact: 'automatic',
|
|
1085
|
+
regular: 'automatic',
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
export function isDeviceModel(value: string): value is DeviceModel {
|
|
1089
|
+
return Object.hasOwn(devices, value)
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
export function listDeviceModels(): DeviceModel[] {
|
|
1093
|
+
return Object.keys(devices).filter(isDeviceModel)
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// devices a picker, tray, or list may offer. experimental prototypes never
|
|
1097
|
+
// appear, and developmentOnly devices appear only where the caller says it is
|
|
1098
|
+
// running on a development surface.
|
|
1099
|
+
export function listSelectableDeviceModels(options?: {
|
|
1100
|
+
developmentMode?: boolean
|
|
1101
|
+
}): DeviceModel[] {
|
|
1102
|
+
return listDeviceModels().filter((model) => {
|
|
1103
|
+
const spec = devices[model]
|
|
1104
|
+
if (spec.experimental) return false
|
|
1105
|
+
return spec.developmentOnly !== true || options?.developmentMode === true
|
|
1106
|
+
})
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// reverse lookup by display name (e.g. "iPhone 16 Pro Max" → 'iphone-16-pro-max').
|
|
1110
|
+
// useful for consuming external manifests that record the human-readable
|
|
1111
|
+
// device name without a slug. returns null when no match exists.
|
|
1112
|
+
export function getDeviceByName(name: string): DeviceSpec | null {
|
|
1113
|
+
for (const spec of Object.values(devices)) {
|
|
1114
|
+
if (spec.name === name) return spec
|
|
1115
|
+
}
|
|
1116
|
+
return null
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
function ipadProDevice(
|
|
1120
|
+
model: 'ipad-pro-11' | 'ipad-pro-13',
|
|
1121
|
+
name: string,
|
|
1122
|
+
width: number,
|
|
1123
|
+
height: number,
|
|
1124
|
+
diagonalInches: number,
|
|
1125
|
+
): DeviceSpec {
|
|
1126
|
+
return iosDevice({
|
|
1127
|
+
model,
|
|
1128
|
+
name,
|
|
1129
|
+
// iPad Pro 11-inch (M5) 12GB, iOS 27.0, simulator DBD4B183, UIKit probe
|
|
1130
|
+
// scenario `metrics`. portrait UIScreen.bounds 834×1210, scale 2,
|
|
1131
|
+
// nativeBounds 1668×2420. the window matched the screen.
|
|
1132
|
+
width,
|
|
1133
|
+
height,
|
|
1134
|
+
scale: 2,
|
|
1135
|
+
// portrait statusBarFrame was 834×32 at the top, and safeAreaInsets.top
|
|
1136
|
+
// was 32. landscape statusBarFrame stayed 32 tall while safeAreaInsets.top
|
|
1137
|
+
// was 10; this field is the portrait bar.
|
|
1138
|
+
statusBarHeight: 32,
|
|
1139
|
+
landscapeStatusBarHeight: 32,
|
|
1140
|
+
// portrait and landscape safeAreaInsets.bottom were both 20. the probe
|
|
1141
|
+
// has no separate home-indicator height.
|
|
1142
|
+
homeIndicatorHeight: 20,
|
|
1143
|
+
// UIScreen _displayCornerRadius, both orientations. the framebuffer
|
|
1144
|
+
// mask's tangent extent was not measured separately.
|
|
1145
|
+
cornerRadius: cornerRadii(30),
|
|
1146
|
+
continuousCornerRadius: cornerRadii(30),
|
|
1147
|
+
// housing is unsourced. the frame is the display until it is measured.
|
|
1148
|
+
frameInsets: uniformFrameInsets(0),
|
|
1149
|
+
// portrait safeAreaInsets. landscape was top 10, left 0, bottom 20, right 0.
|
|
1150
|
+
safeAreaInsets: { top: 32, bottom: 20, left: 0, right: 0 },
|
|
1151
|
+
// portrait docked keyboard, UIKeyboardFrameEndUserInfoKey
|
|
1152
|
+
// {0, 870, 834, 340}. landscape posted a zero-height frame.
|
|
1153
|
+
keyboardPanelHeights: { qwerty: 340, pad: 340, emoji: 427 },
|
|
1154
|
+
// hypot(1668, 2420) / 11, measured native pixels over the device type's
|
|
1155
|
+
// 11-inch name. not a separate density read.
|
|
1156
|
+
physicalPPI: Math.hypot(width * 2, height * 2) / diagonalInches,
|
|
1157
|
+
hardwareButtons: modernButtons([0, 0], [0, 0], [0, 0], [0, 0]),
|
|
1158
|
+
})
|
|
1159
|
+
}
|