autokap 1.0.6 → 1.0.8
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/assets/chrome/ios-statusbar-comparison-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-dark-reference.jpg +0 -0
- package/assets/chrome/ios-statusbar-light-reference.jpg +0 -0
- package/assets/cursors/macos.svg +4 -0
- package/assets/cursors/windows.svg +15 -0
- package/assets/devices/ipad-pro-11-m4.json +52 -0
- package/assets/devices/iphone-16-pro.json +53 -0
- package/assets/devices/macbook-air-13.json +45 -0
- package/assets/frames/MacBook Air 13.svg +242 -0
- package/assets/frames/Status bar - iPhone.png +0 -0
- Menu bar- iPad.png +0 -0
- package/assets/frames/iPad Pro M4 11_.png +0 -0
- package/assets/frames/iPhone 16 Pro.png +0 -0
- package/assets/icons/Cellular Connection.svg +3 -0
- package/assets/icons/Union.svg +6 -0
- package/assets/icons/Wifi.svg +3 -0
- package/assets/icons/battery.svg +5 -0
- package/assets/icons/battery_charging.svg +8 -0
- package/assets/skill/OPCODE-REFERENCE.md +607 -0
- package/assets/skill/README.md +39 -0
- package/assets/skill/SKILL.md +453 -468
- package/assets/skill/STUDIO-SKILL.md +476 -0
- package/assets/skill/references/examples.md +104 -0
- package/assets/skill/references/interactive-demo.md +225 -0
- package/assets/skill/references/mock-data.md +178 -0
- package/dist/abort.d.ts +5 -0
- package/dist/abort.js +44 -0
- package/dist/action-verifier.d.ts +29 -0
- package/dist/action-verifier.js +133 -0
- package/dist/agent-action-recovery.d.ts +45 -0
- package/dist/agent-action-recovery.js +370 -0
- package/dist/agent-message-utils.d.ts +21 -0
- package/dist/agent-message-utils.js +77 -0
- package/dist/agent-url-utils.d.ts +30 -0
- package/dist/agent-url-utils.js +138 -0
- package/dist/agent.d.ts +226 -0
- package/dist/agent.js +6666 -0
- package/dist/ak-tree.d.ts +39 -0
- package/dist/ak-tree.js +368 -0
- package/dist/alt-text.d.ts +26 -0
- package/dist/alt-text.js +55 -0
- package/dist/auth-capture.d.ts +17 -0
- package/dist/auth-capture.js +164 -0
- package/dist/benchmark.d.ts +59 -0
- package/dist/benchmark.js +135 -0
- package/dist/billing-operation-logging.d.ts +38 -0
- package/dist/billing-operation-logging.js +248 -0
- package/dist/browser-bar.d.ts +48 -0
- package/dist/browser-bar.js +284 -0
- package/dist/browser-pool.d.ts +7 -0
- package/dist/browser-pool.js +15 -5
- package/dist/browser-utils.d.ts +31 -0
- package/dist/browser-utils.js +97 -0
- package/dist/browser.d.ts +76 -1
- package/dist/browser.js +1657 -39
- package/dist/capture-alt-text.d.ts +12 -0
- package/dist/capture-alt-text.js +52 -0
- package/dist/capture-encryption.d.ts +10 -0
- package/dist/capture-encryption.js +41 -0
- package/dist/capture-language-preflight.d.ts +41 -0
- package/dist/capture-language-preflight.js +300 -0
- package/dist/capture-llm-page-identity.d.ts +15 -0
- package/dist/capture-llm-page-identity.js +128 -0
- package/dist/capture-model-resolution.d.ts +9 -0
- package/dist/capture-model-resolution.js +21 -0
- package/dist/capture-page-identity.d.ts +7 -0
- package/dist/capture-page-identity.js +352 -0
- package/dist/capture-preset-credentials.d.ts +62 -0
- package/dist/capture-preset-credentials.js +184 -0
- package/dist/capture-request-plan.d.ts +58 -0
- package/dist/capture-request-plan.js +264 -0
- package/dist/capture-run-optimizer.d.ts +139 -0
- package/dist/capture-run-optimizer.js +863 -0
- package/dist/capture-selector-memory.d.ts +31 -0
- package/dist/capture-selector-memory.js +345 -0
- package/dist/capture-session-profile-encryption.d.ts +2 -0
- package/dist/capture-session-profile-encryption.js +22 -0
- package/dist/capture-step-timeout.d.ts +10 -0
- package/dist/capture-step-timeout.js +30 -0
- package/dist/capture-strategy.d.ts +36 -0
- package/dist/capture-strategy.js +95 -0
- package/dist/capture-studio-sync.d.ts +23 -0
- package/dist/capture-studio-sync.js +172 -0
- package/dist/capture-surface-contract.d.ts +36 -0
- package/dist/capture-surface-contract.js +299 -0
- package/dist/capture-transition-engine.d.ts +28 -0
- package/dist/capture-transition-engine.js +292 -0
- package/dist/capture-variant-state.d.ts +56 -0
- package/dist/capture-variant-state.js +182 -0
- package/dist/capture-verification.d.ts +35 -0
- package/dist/capture-verification.js +95 -0
- package/dist/capture-viewport-lock.d.ts +48 -0
- package/dist/capture-viewport-lock.js +74 -0
- package/dist/circuit-breaker.d.ts +42 -0
- package/dist/circuit-breaker.js +119 -0
- package/dist/cli-config.d.ts +8 -1
- package/dist/cli-config.js +62 -6
- package/dist/cli-contract.d.ts +15 -0
- package/dist/cli-contract.js +167 -0
- package/dist/cli-runner-local.d.ts +12 -0
- package/dist/cli-runner-local.js +102 -0
- package/dist/cli-runner.d.ts +34 -0
- package/dist/cli-runner.js +433 -0
- package/dist/cli-utils.d.ts +0 -1
- package/dist/cli-utils.js +2 -5
- package/dist/cli.js +1005 -252
- package/dist/clip-orchestrator.d.ts +148 -0
- package/dist/clip-orchestrator.js +957 -0
- package/dist/clip-postprocess.d.ts +42 -0
- package/dist/clip-postprocess.js +201 -0
- package/dist/cookie-dismiss.d.ts +2 -0
- package/dist/cookie-dismiss.js +48 -13
- package/dist/cost-logging.d.ts +35 -0
- package/dist/cost-logging.js +242 -0
- package/dist/cost-resolution-monitor.d.ts +16 -0
- package/dist/cost-resolution-monitor.js +34 -0
- package/dist/credential-templates.d.ts +5 -0
- package/dist/credential-templates.js +60 -0
- package/dist/cursor-overlay-script.d.ts +6 -0
- package/dist/cursor-overlay-script.js +169 -0
- package/dist/dom-css-purger.d.ts +65 -0
- package/dist/dom-css-purger.js +333 -0
- package/dist/dom-font-inliner.d.ts +45 -0
- package/dist/dom-font-inliner.js +148 -0
- package/dist/dom-patch-resolver.d.ts +52 -0
- package/dist/dom-patch-resolver.js +242 -0
- package/dist/dom-serializer.d.ts +82 -0
- package/dist/dom-serializer.js +378 -0
- package/dist/element-capture.d.ts +13 -0
- package/dist/element-capture.js +522 -0
- package/dist/env-validation.d.ts +5 -0
- package/dist/env-validation.js +29 -0
- package/dist/execution-schema.d.ts +4423 -0
- package/dist/execution-schema.js +507 -0
- package/dist/execution-types.d.ts +886 -0
- package/dist/execution-types.js +65 -0
- package/dist/fonts-loader.d.ts +14 -0
- package/dist/fonts-loader.js +55 -0
- package/dist/hybrid-navigator.d.ts +138 -0
- package/dist/hybrid-navigator.js +468 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/legacy/agent-action-recovery.d.ts +45 -0
- package/dist/legacy/agent-action-recovery.js +370 -0
- package/dist/legacy/agent-message-utils.d.ts +21 -0
- package/dist/legacy/agent-message-utils.js +77 -0
- package/dist/legacy/agent-url-utils.d.ts +30 -0
- package/dist/legacy/agent-url-utils.js +138 -0
- package/dist/legacy/agent.d.ts +226 -0
- package/dist/legacy/agent.js +6666 -0
- package/dist/legacy/clip-orchestrator.d.ts +148 -0
- package/dist/legacy/clip-orchestrator.js +957 -0
- package/dist/legacy/credential-templates.d.ts +5 -0
- package/dist/legacy/credential-templates.js +60 -0
- package/dist/legacy/hybrid-navigator.d.ts +138 -0
- package/dist/legacy/hybrid-navigator.js +468 -0
- package/dist/legacy/llm-usage.d.ts +17 -0
- package/dist/legacy/llm-usage.js +45 -0
- package/dist/legacy/prompt-cache.d.ts +10 -0
- package/dist/legacy/prompt-cache.js +24 -0
- package/dist/legacy/prompts.d.ts +175 -0
- package/dist/legacy/prompts.js +1038 -0
- package/dist/legacy/tools.d.ts +4 -0
- package/dist/legacy/tools.js +216 -0
- package/dist/legacy/video-agent.d.ts +143 -0
- package/dist/legacy/video-agent.js +4788 -0
- package/dist/legacy/video-observation.d.ts +36 -0
- package/dist/legacy/video-observation.js +192 -0
- package/dist/legacy/video-planner.d.ts +12 -0
- package/dist/legacy/video-planner.js +501 -0
- package/dist/legacy/video-prompts.d.ts +37 -0
- package/dist/legacy/video-prompts.js +569 -0
- package/dist/legacy/video-tools.d.ts +3 -0
- package/dist/legacy/video-tools.js +59 -0
- package/dist/legacy/video-variant-state.d.ts +29 -0
- package/dist/legacy/video-variant-state.js +80 -0
- package/dist/legacy/vision-model.d.ts +17 -0
- package/dist/legacy/vision-model.js +74 -0
- package/dist/llm-healer.d.ts +63 -0
- package/dist/llm-healer.js +166 -0
- package/dist/llm-provider.d.ts +29 -0
- package/dist/llm-provider.js +80 -0
- package/dist/llm-usage.d.ts +17 -0
- package/dist/llm-usage.js +45 -0
- package/dist/logger.d.ts +6 -2
- package/dist/logger.js +15 -1
- package/dist/mockup-html.d.ts +119 -0
- package/dist/mockup-html.js +263 -0
- package/dist/mockup.d.ts +187 -0
- package/dist/mockup.js +869 -0
- package/dist/mouse-animation.d.ts +46 -0
- package/dist/mouse-animation.js +114 -0
- package/dist/opcode-actions.d.ts +42 -0
- package/dist/opcode-actions.js +511 -0
- package/dist/opcode-runner.d.ts +51 -0
- package/dist/opcode-runner.js +770 -0
- package/dist/openrouter-client.d.ts +40 -0
- package/dist/openrouter-client.js +16 -0
- package/dist/overlay-engine.d.ts +24 -0
- package/dist/overlay-engine.js +176 -0
- package/dist/overlay-utils.d.ts +14 -0
- package/dist/overlay-utils.js +13 -0
- package/dist/postcondition.d.ts +16 -0
- package/dist/postcondition.js +269 -0
- package/dist/posthog.d.ts +4 -0
- package/dist/posthog.js +26 -0
- package/dist/program-patcher.d.ts +25 -0
- package/dist/program-patcher.js +44 -0
- package/dist/prompt-cache.d.ts +10 -0
- package/dist/prompt-cache.js +24 -0
- package/dist/prompts.d.ts +175 -0
- package/dist/prompts.js +1038 -0
- package/dist/provider-config.d.ts +12 -0
- package/dist/provider-config.js +15 -0
- package/dist/recovery-chain.d.ts +37 -0
- package/dist/recovery-chain.js +350 -0
- package/dist/remote-browser.d.ts +215 -0
- package/dist/remote-browser.js +360 -0
- package/dist/safari-browser-bar.d.ts +15 -0
- package/dist/safari-browser-bar.js +95 -0
- package/dist/safari-toolbar-asset.d.ts +15 -0
- package/dist/safari-toolbar-asset.js +12 -0
- package/dist/security.d.ts +21 -0
- package/dist/security.js +608 -0
- package/dist/selector-resolver.d.ts +34 -0
- package/dist/selector-resolver.js +181 -0
- package/dist/semantic-resolver.d.ts +35 -0
- package/dist/semantic-resolver.js +161 -0
- package/dist/server-capture-runtime.d.ts +125 -0
- package/dist/server-capture-runtime.js +585 -0
- package/dist/server-credit-usage.d.ts +12 -0
- package/dist/server-credit-usage.js +41 -0
- package/dist/server-posthog.d.ts +2 -0
- package/dist/server-posthog.js +16 -0
- package/dist/server-project-webhooks.d.ts +59 -0
- package/dist/server-project-webhooks.js +123 -0
- package/dist/server-screenshot-watermark.d.ts +7 -0
- package/dist/server-screenshot-watermark.js +60 -0
- package/dist/session-profile.d.ts +86 -0
- package/dist/session-profile.js +1536 -0
- package/dist/sf-pro-fonts.d.ts +4 -0
- package/dist/sf-pro-fonts.js +7 -0
- package/dist/sf-pro-symbols.d.ts +1 -0
- package/dist/sf-pro-symbols.js +55 -0
- package/dist/skill-packaging.d.ts +28 -0
- package/dist/skill-packaging.js +169 -0
- package/dist/smart-wait.d.ts +27 -0
- package/dist/smart-wait.js +81 -0
- package/dist/status-bar-l10n.d.ts +14 -0
- package/dist/status-bar-l10n.js +177 -0
- package/dist/status-bar-render.d.ts +20 -0
- package/dist/status-bar-render.js +410 -0
- package/dist/status-bar.d.ts +53 -0
- package/dist/status-bar.js +620 -0
- package/dist/svg-browser-bar.d.ts +33 -0
- package/dist/svg-browser-bar.js +206 -0
- package/dist/svg-status-bar.d.ts +36 -0
- package/dist/svg-status-bar.js +597 -0
- package/dist/svg-text.d.ts +61 -0
- package/dist/svg-text.js +118 -0
- package/dist/tools.d.ts +4 -0
- package/dist/tools.js +216 -0
- package/dist/types.d.ts +240 -5
- package/dist/types.js +23 -1
- package/dist/v2/action-verifier.d.ts +29 -0
- package/dist/v2/action-verifier.js +133 -0
- package/dist/v2/alt-text.d.ts +26 -0
- package/dist/v2/alt-text.js +55 -0
- package/dist/v2/benchmark.d.ts +59 -0
- package/dist/v2/benchmark.js +135 -0
- package/dist/v2/capture-strategy.d.ts +30 -0
- package/dist/v2/capture-strategy.js +67 -0
- package/dist/v2/capture-verification.d.ts +35 -0
- package/dist/v2/capture-verification.js +95 -0
- package/dist/v2/circuit-breaker.d.ts +42 -0
- package/dist/v2/circuit-breaker.js +119 -0
- package/dist/v2/cli-runner-local.d.ts +11 -0
- package/dist/v2/cli-runner-local.js +91 -0
- package/dist/v2/cli-runner.d.ts +34 -0
- package/dist/v2/cli-runner.js +300 -0
- package/dist/v2/compiler-prompts.d.ts +27 -0
- package/dist/v2/compiler-prompts.js +123 -0
- package/dist/v2/compiler.d.ts +37 -0
- package/dist/v2/compiler.js +147 -0
- package/dist/v2/explorer.d.ts +41 -0
- package/dist/v2/explorer.js +56 -0
- package/dist/v2/index.d.ts +37 -0
- package/dist/v2/index.js +31 -0
- package/dist/v2/llm-healer.d.ts +62 -0
- package/dist/v2/llm-healer.js +166 -0
- package/dist/v2/llm-provider.d.ts +29 -0
- package/dist/v2/llm-provider.js +80 -0
- package/dist/v2/opcode-runner.d.ts +47 -0
- package/dist/v2/opcode-runner.js +634 -0
- package/dist/v2/overlay-engine.d.ts +24 -0
- package/dist/v2/overlay-engine.js +150 -0
- package/dist/v2/postcondition.d.ts +16 -0
- package/dist/v2/postcondition.js +249 -0
- package/dist/v2/program-patcher.d.ts +25 -0
- package/dist/v2/program-patcher.js +44 -0
- package/dist/v2/recovery-chain.d.ts +30 -0
- package/dist/v2/recovery-chain.js +368 -0
- package/dist/v2/schema.d.ts +2580 -0
- package/dist/v2/schema.js +295 -0
- package/dist/v2/selector-resolver.d.ts +34 -0
- package/dist/v2/selector-resolver.js +181 -0
- package/dist/v2/semantic-resolver.d.ts +35 -0
- package/dist/v2/semantic-resolver.js +161 -0
- package/dist/v2/smart-wait.d.ts +27 -0
- package/dist/v2/smart-wait.js +81 -0
- package/dist/v2/types.d.ts +444 -0
- package/dist/v2/types.js +19 -0
- package/dist/v2/web-playwright-local.d.ts +69 -0
- package/dist/v2/web-playwright-local.js +392 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/video-agent.d.ts +143 -0
- package/dist/video-agent.js +4788 -0
- package/dist/video-observation.d.ts +36 -0
- package/dist/video-observation.js +192 -0
- package/dist/video-planner.d.ts +12 -0
- package/dist/video-planner.js +501 -0
- package/dist/video-prompts.d.ts +37 -0
- package/dist/video-prompts.js +554 -0
- package/dist/video-tools.d.ts +3 -0
- package/dist/video-tools.js +59 -0
- package/dist/video-variant-state.d.ts +29 -0
- package/dist/video-variant-state.js +80 -0
- package/dist/vision-model.d.ts +17 -0
- package/dist/vision-model.js +74 -0
- package/dist/web-playwright-local.d.ts +126 -0
- package/dist/web-playwright-local.js +819 -0
- package/dist/ws-auth.d.ts +20 -0
- package/dist/ws-auth.js +70 -0
- package/dist/ws-broadcast.d.ts +34 -0
- package/dist/ws-broadcast.js +85 -0
- package/dist/ws-connection-limits.d.ts +12 -0
- package/dist/ws-connection-limits.js +44 -0
- package/dist/ws-handler-utils.d.ts +32 -0
- package/dist/ws-handler-utils.js +139 -0
- package/dist/ws-handler.d.ts +10 -0
- package/dist/ws-handler.js +1793 -0
- package/dist/ws-metrics-server.d.ts +9 -0
- package/dist/ws-metrics-server.js +31 -0
- package/dist/ws-server.d.ts +9 -0
- package/dist/ws-server.js +92 -0
- package/package.json +142 -71
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared mockup HTML generator — single source of truth for mockup rendering.
|
|
3
|
+
*
|
|
4
|
+
* Used by:
|
|
5
|
+
* - Server-side: src/mockup.ts (applyDeviceFrame → Playwright screenshot)
|
|
6
|
+
* - Client-side: web/components/mockup-renderer.tsx (dangerouslySetInnerHTML)
|
|
7
|
+
*
|
|
8
|
+
* Z-index scheme (all absolute within the same parent):
|
|
9
|
+
* 0 — frame image (when frameBehindContent)
|
|
10
|
+
* 1 — screen background + safe area fills
|
|
11
|
+
* 2 — content slot (screenshot img on server, React children on client)
|
|
12
|
+
* 4 — home indicator
|
|
13
|
+
* 5 — status bar
|
|
14
|
+
* 6 — overlay slot (dock on client)
|
|
15
|
+
* 8 — frame image (when !frameBehindContent)
|
|
16
|
+
*/
|
|
17
|
+
import type { StatusBarDeviceType, StatusBarLayout, StatusBarConfig } from './status-bar.js';
|
|
18
|
+
import type { BrowserBarConfig } from './browser-bar.js';
|
|
19
|
+
export interface MockupHtmlParams {
|
|
20
|
+
frameSrc?: string;
|
|
21
|
+
frameWidth: number;
|
|
22
|
+
frameHeight: number;
|
|
23
|
+
frameRotation?: number;
|
|
24
|
+
frameBehindContent?: boolean;
|
|
25
|
+
screenRect: {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
31
|
+
cornerRadius: number;
|
|
32
|
+
screenBackground?: string;
|
|
33
|
+
isLaptop?: boolean;
|
|
34
|
+
safeArea: {
|
|
35
|
+
top: number;
|
|
36
|
+
bottom: number;
|
|
37
|
+
left?: number;
|
|
38
|
+
right?: number;
|
|
39
|
+
};
|
|
40
|
+
scale: number;
|
|
41
|
+
showSafeAreaTop?: boolean;
|
|
42
|
+
showSafeAreaBottom?: boolean;
|
|
43
|
+
showSafeAreaLeft?: boolean;
|
|
44
|
+
showSafeAreaRight?: boolean;
|
|
45
|
+
safeAreaColors?: {
|
|
46
|
+
top?: string;
|
|
47
|
+
bottom?: string;
|
|
48
|
+
left?: string;
|
|
49
|
+
right?: string;
|
|
50
|
+
};
|
|
51
|
+
statusBar?: {
|
|
52
|
+
height: number;
|
|
53
|
+
width: number;
|
|
54
|
+
type: StatusBarDeviceType;
|
|
55
|
+
layout?: StatusBarLayout;
|
|
56
|
+
};
|
|
57
|
+
showStatusBar?: boolean;
|
|
58
|
+
statusBarConfig?: StatusBarConfig;
|
|
59
|
+
colorScheme?: 'light' | 'dark';
|
|
60
|
+
homeIndicator?: {
|
|
61
|
+
width: number;
|
|
62
|
+
height: number;
|
|
63
|
+
cornerRadius: number;
|
|
64
|
+
bottomOffset: number;
|
|
65
|
+
};
|
|
66
|
+
showHomeIndicator?: boolean;
|
|
67
|
+
homeIndicatorColor?: string;
|
|
68
|
+
showBrowserBar?: boolean;
|
|
69
|
+
browserBarConfig?: BrowserBarConfig;
|
|
70
|
+
windowBorder?: {
|
|
71
|
+
color: string;
|
|
72
|
+
width: number;
|
|
73
|
+
radius: number;
|
|
74
|
+
};
|
|
75
|
+
contentHtml?: string;
|
|
76
|
+
overlayHtml?: string;
|
|
77
|
+
pixelScale?: number;
|
|
78
|
+
}
|
|
79
|
+
export interface MockupLayout {
|
|
80
|
+
/** Post-rotation container dimensions */
|
|
81
|
+
containerWidth: number;
|
|
82
|
+
containerHeight: number;
|
|
83
|
+
/** Content area (inside safe areas) relative to the container */
|
|
84
|
+
contentArea: {
|
|
85
|
+
x: number;
|
|
86
|
+
y: number;
|
|
87
|
+
width: number;
|
|
88
|
+
height: number;
|
|
89
|
+
};
|
|
90
|
+
/** Screen area relative to the container */
|
|
91
|
+
screenArea: {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
width: number;
|
|
95
|
+
height: number;
|
|
96
|
+
};
|
|
97
|
+
/** CSS border-radius for the screen area */
|
|
98
|
+
screenBorderRadius: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Compute the mockup layout — positions and dimensions for all elements.
|
|
102
|
+
* This is the single source of truth for both server and client rendering.
|
|
103
|
+
*/
|
|
104
|
+
export declare function computeMockupLayout(params: MockupHtmlParams): MockupLayout;
|
|
105
|
+
/**
|
|
106
|
+
* Generate the complete mockup HTML structure.
|
|
107
|
+
*
|
|
108
|
+
* All elements are absolutely positioned within a container div
|
|
109
|
+
* (position:relative). This allows the client to inject React children
|
|
110
|
+
* as siblings at z-index:2 (between screen bg and status bar).
|
|
111
|
+
*
|
|
112
|
+
* The returned HTML is a FRAGMENT (no wrapping div), meant to be placed
|
|
113
|
+
* inside a position:relative container of the correct dimensions.
|
|
114
|
+
*/
|
|
115
|
+
export declare function generateMockupHtml(params: MockupHtmlParams): string;
|
|
116
|
+
/**
|
|
117
|
+
* Generate a complete HTML page wrapping the mockup (for server-side Playwright rendering).
|
|
118
|
+
*/
|
|
119
|
+
export declare function generateMockupPage(params: MockupHtmlParams): string;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared mockup HTML generator — single source of truth for mockup rendering.
|
|
3
|
+
*
|
|
4
|
+
* Used by:
|
|
5
|
+
* - Server-side: src/mockup.ts (applyDeviceFrame → Playwright screenshot)
|
|
6
|
+
* - Client-side: web/components/mockup-renderer.tsx (dangerouslySetInnerHTML)
|
|
7
|
+
*
|
|
8
|
+
* Z-index scheme (all absolute within the same parent):
|
|
9
|
+
* 0 — frame image (when frameBehindContent)
|
|
10
|
+
* 1 — screen background + safe area fills
|
|
11
|
+
* 2 — content slot (screenshot img on server, React children on client)
|
|
12
|
+
* 4 — home indicator
|
|
13
|
+
* 5 — status bar
|
|
14
|
+
* 6 — overlay slot (dock on client)
|
|
15
|
+
* 8 — frame image (when !frameBehindContent)
|
|
16
|
+
*/
|
|
17
|
+
import { generateStatusBarHtml, STATUS_BAR_FONT_CSS } from './status-bar.js';
|
|
18
|
+
import { generateBrowserBarHtml } from './browser-bar.js';
|
|
19
|
+
// ── Layout Computation ──────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Compute the mockup layout — positions and dimensions for all elements.
|
|
22
|
+
* This is the single source of truth for both server and client rendering.
|
|
23
|
+
*/
|
|
24
|
+
export function computeMockupLayout(params) {
|
|
25
|
+
const { frameWidth, frameHeight, frameRotation = 0, screenRect, cornerRadius, safeArea, scale, isLaptop = false, showSafeAreaTop = true, showSafeAreaBottom = true, showSafeAreaLeft = true, showSafeAreaRight = true, } = params;
|
|
26
|
+
const is90or270 = frameRotation % 180 !== 0;
|
|
27
|
+
const containerWidth = is90or270 ? frameHeight : frameWidth;
|
|
28
|
+
const containerHeight = is90or270 ? frameWidth : frameHeight;
|
|
29
|
+
const showTop = showSafeAreaTop && safeArea.top > 0;
|
|
30
|
+
const showBottom = showSafeAreaBottom && safeArea.bottom > 0;
|
|
31
|
+
const showLeft = showSafeAreaLeft && (safeArea.left ?? 0) > 0;
|
|
32
|
+
const showRight = showSafeAreaRight && (safeArea.right ?? 0) > 0;
|
|
33
|
+
const topPx = showTop ? safeArea.top * scale : 0;
|
|
34
|
+
const bottomPx = showBottom ? safeArea.bottom * scale : 0;
|
|
35
|
+
const leftPx = showLeft ? (safeArea.left ?? 0) * scale : 0;
|
|
36
|
+
const rightPx = showRight ? (safeArea.right ?? 0) * scale : 0;
|
|
37
|
+
const contentW = Math.max(1, screenRect.width - leftPx - rightPx);
|
|
38
|
+
const contentH = Math.max(1, screenRect.height - topPx - bottomPx);
|
|
39
|
+
const borderW = params.windowBorder?.width ?? 0;
|
|
40
|
+
const screenCornerRadius = Math.max(0, cornerRadius);
|
|
41
|
+
const screenBorderRadius = isLaptop
|
|
42
|
+
? `${screenCornerRadius}px ${screenCornerRadius}px 0 0`
|
|
43
|
+
: `${screenCornerRadius}px`;
|
|
44
|
+
return {
|
|
45
|
+
containerWidth,
|
|
46
|
+
containerHeight,
|
|
47
|
+
contentArea: {
|
|
48
|
+
x: screenRect.x + leftPx,
|
|
49
|
+
y: screenRect.y + topPx,
|
|
50
|
+
width: contentW,
|
|
51
|
+
height: contentH,
|
|
52
|
+
},
|
|
53
|
+
screenArea: {
|
|
54
|
+
x: screenRect.x,
|
|
55
|
+
y: screenRect.y,
|
|
56
|
+
width: screenRect.width,
|
|
57
|
+
height: screenRect.height,
|
|
58
|
+
},
|
|
59
|
+
screenBorderRadius,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// ── HTML Generation ─────────────────────────────────────────────────────
|
|
63
|
+
/**
|
|
64
|
+
* Generate the complete mockup HTML structure.
|
|
65
|
+
*
|
|
66
|
+
* All elements are absolutely positioned within a container div
|
|
67
|
+
* (position:relative). This allows the client to inject React children
|
|
68
|
+
* as siblings at z-index:2 (between screen bg and status bar).
|
|
69
|
+
*
|
|
70
|
+
* The returned HTML is a FRAGMENT (no wrapping div), meant to be placed
|
|
71
|
+
* inside a position:relative container of the correct dimensions.
|
|
72
|
+
*/
|
|
73
|
+
export function generateMockupHtml(params) {
|
|
74
|
+
return generateMockupHtmlInternal(params, { includeInlineStatusBarFontStyles: true });
|
|
75
|
+
}
|
|
76
|
+
function generateMockupHtmlInternal(params, options) {
|
|
77
|
+
const { frameSrc, frameWidth, frameHeight, frameRotation = 0, frameBehindContent = false, screenRect, cornerRadius, screenBackground = 'transparent', isLaptop = false, safeArea, scale, showSafeAreaTop = true, showSafeAreaBottom = true, showSafeAreaLeft = true, showSafeAreaRight = true, safeAreaColors, statusBar, showStatusBar = true, statusBarConfig, colorScheme = 'light', showBrowserBar = false, browserBarConfig, homeIndicator, showHomeIndicator = true, homeIndicatorColor, windowBorder, contentHtml = '', overlayHtml = '', pixelScale = 1, } = params;
|
|
78
|
+
const px = (v) => Math.round(v * pixelScale);
|
|
79
|
+
const layout = computeMockupLayout(params);
|
|
80
|
+
const borderW = windowBorder?.width ?? 0;
|
|
81
|
+
const sr = { x: screenRect.x, y: screenRect.y, width: screenRect.width, height: screenRect.height };
|
|
82
|
+
const ca = layout.contentArea;
|
|
83
|
+
// Safe area visibility
|
|
84
|
+
const showTop = showSafeAreaTop && safeArea.top > 0;
|
|
85
|
+
const showBottom = showSafeAreaBottom && safeArea.bottom > 0;
|
|
86
|
+
const showLeft = showSafeAreaLeft && (safeArea.left ?? 0) > 0;
|
|
87
|
+
const showRight = showSafeAreaRight && (safeArea.right ?? 0) > 0;
|
|
88
|
+
const topPx = showTop ? safeArea.top * scale : 0;
|
|
89
|
+
const bottomPx = showBottom ? safeArea.bottom * scale : 0;
|
|
90
|
+
const leftPx = showLeft ? (safeArea.left ?? 0) * scale : 0;
|
|
91
|
+
const rightPx = showRight ? (safeArea.right ?? 0) * scale : 0;
|
|
92
|
+
const cornerPx = Math.max(0, cornerRadius);
|
|
93
|
+
const screenBorderRadius = layout.screenBorderRadius;
|
|
94
|
+
const screenBorderRadiusCss = screenBorderRadius
|
|
95
|
+
.split(' ')
|
|
96
|
+
.map((v) => px(parseFloat(v)) + 'px')
|
|
97
|
+
.join(' ');
|
|
98
|
+
// ── Screen background + safe area fills (z:1) ──
|
|
99
|
+
let safeAreaFillsHtml = '';
|
|
100
|
+
const topColor = safeAreaColors?.top ?? screenBackground;
|
|
101
|
+
const bottomColor = safeAreaColors?.bottom ?? screenBackground;
|
|
102
|
+
const leftColor = safeAreaColors?.left ?? screenBackground;
|
|
103
|
+
const rightColor = safeAreaColors?.right ?? screenBackground;
|
|
104
|
+
if (showLeft) {
|
|
105
|
+
safeAreaFillsHtml += `<div style="position:absolute;top:0;left:0;bottom:0;width:${px(leftPx)}px;background:${leftColor}"></div>`;
|
|
106
|
+
}
|
|
107
|
+
if (showRight) {
|
|
108
|
+
safeAreaFillsHtml += `<div style="position:absolute;top:0;right:0;bottom:0;width:${px(rightPx)}px;background:${rightColor}"></div>`;
|
|
109
|
+
}
|
|
110
|
+
if (showTop) {
|
|
111
|
+
safeAreaFillsHtml += `<div style="position:absolute;top:0;left:${px(leftPx)}px;right:${px(rightPx)}px;height:${px(topPx)}px;background:${topColor}"></div>`;
|
|
112
|
+
}
|
|
113
|
+
if (showBottom) {
|
|
114
|
+
safeAreaFillsHtml += `<div style="position:absolute;bottom:0;left:${px(leftPx)}px;right:${px(rightPx)}px;height:${px(bottomPx)}px;background:${bottomColor}"></div>`;
|
|
115
|
+
}
|
|
116
|
+
const screenBgHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${px(sr.width)}px;height:${px(sr.height)}px;border-radius:${screenBorderRadiusCss};overflow:hidden;background:${screenBackground};z-index:1">${safeAreaFillsHtml}</div>`;
|
|
117
|
+
// ── Content (z:2) ──
|
|
118
|
+
let contentSlotHtml = '';
|
|
119
|
+
if (contentHtml) {
|
|
120
|
+
// Content area border-radius: only round corners where the content
|
|
121
|
+
// touches the screen edge (no safe area on that side).
|
|
122
|
+
const contentBorderRadius = topPx > 0 && bottomPx > 0
|
|
123
|
+
? '0' // Content doesn't touch any rounded edge
|
|
124
|
+
: topPx > 0
|
|
125
|
+
? (isLaptop ? '0' : `0 0 ${px(cornerPx)}px ${px(cornerPx)}px`)
|
|
126
|
+
: bottomPx > 0
|
|
127
|
+
? `${px(cornerPx)}px ${px(cornerPx)}px 0 0`
|
|
128
|
+
: screenBorderRadiusCss;
|
|
129
|
+
contentSlotHtml = `<div style="position:absolute;left:${px(ca.x)}px;top:${px(ca.y)}px;width:${px(ca.width)}px;height:${px(ca.height)}px;z-index:2;overflow:hidden;border-radius:${contentBorderRadius}">${contentHtml}</div>`;
|
|
130
|
+
}
|
|
131
|
+
// ── Home indicator (z:4) ──
|
|
132
|
+
let homeIndicatorHtml = '';
|
|
133
|
+
if (showHomeIndicator && homeIndicator && safeArea.bottom > 0) {
|
|
134
|
+
const hiW = homeIndicator.width * scale;
|
|
135
|
+
const hiH = homeIndicator.height * scale;
|
|
136
|
+
const hiR = homeIndicator.cornerRadius * scale;
|
|
137
|
+
const hiBottom = homeIndicator.bottomOffset * scale;
|
|
138
|
+
const hiColor = homeIndicatorColor ??
|
|
139
|
+
(colorScheme === 'dark' ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.35)');
|
|
140
|
+
// Position: centered horizontally in screen rect, offset from bottom of screen rect
|
|
141
|
+
const hiLeft = sr.x + (sr.width - hiW) / 2;
|
|
142
|
+
const hiTop = sr.y + sr.height - hiBottom - hiH;
|
|
143
|
+
homeIndicatorHtml = `<div style="position:absolute;left:${px(hiLeft)}px;top:${px(hiTop)}px;width:${px(hiW)}px;height:${px(hiH)}px;border-radius:${px(hiR)}px;background:${hiColor};z-index:4"></div>`;
|
|
144
|
+
}
|
|
145
|
+
// ── Status bar (z:5) ──
|
|
146
|
+
let statusBarHtml = '';
|
|
147
|
+
if (showStatusBar && statusBar && safeArea.top > 0) {
|
|
148
|
+
const sbH = statusBar.height * scale;
|
|
149
|
+
const sbConfig = {
|
|
150
|
+
time: '9:41',
|
|
151
|
+
signalStrength: 4,
|
|
152
|
+
networkType: '5G',
|
|
153
|
+
wifiStrength: 3,
|
|
154
|
+
batteryLevel: 100,
|
|
155
|
+
batteryCharging: false,
|
|
156
|
+
colorScheme,
|
|
157
|
+
...statusBarConfig,
|
|
158
|
+
};
|
|
159
|
+
const sbInnerHtml = generateStatusBarHtml({
|
|
160
|
+
config: sbConfig,
|
|
161
|
+
width: sr.width,
|
|
162
|
+
height: sbH,
|
|
163
|
+
scale,
|
|
164
|
+
deviceType: statusBar.type,
|
|
165
|
+
layout: statusBar.layout,
|
|
166
|
+
includeFontStyles: options.includeInlineStatusBarFontStyles,
|
|
167
|
+
});
|
|
168
|
+
if (pixelScale === 1) {
|
|
169
|
+
// Client: render at 1× (status bar HTML handles its own internal scaling)
|
|
170
|
+
const sbBR = `${px(cornerPx)}px ${px(cornerPx)}px 0 0`;
|
|
171
|
+
statusBarHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${px(sr.width)}px;height:${px(safeArea.top * scale)}px;overflow:hidden;border-radius:${sbBR};z-index:5;pointer-events:none">${sbInnerHtml}</div>`;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Server: inner content is at 1× dimensions → use raw (unscaled) container
|
|
175
|
+
// and let transform:scale(pixelScale) bring it to final pixel size.
|
|
176
|
+
// Position (left/top) stays px-scaled since it's in the already-scaled page.
|
|
177
|
+
const sbBR = `${cornerPx}px ${cornerPx}px 0 0`;
|
|
178
|
+
statusBarHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${sr.width}px;height:${sbH}px;overflow:hidden;border-radius:${sbBR};z-index:5;transform:scale(${pixelScale});transform-origin:top left">${sbInnerHtml}</div>`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// ── Browser bar (z:5) — coded Chrome/Safari toolbar, same pattern as status bar ──
|
|
182
|
+
let browserBarHtml = '';
|
|
183
|
+
if (showBrowserBar && safeArea.top > 0) {
|
|
184
|
+
const bbH = safeArea.top * scale;
|
|
185
|
+
const bbConfig = {
|
|
186
|
+
url: 'example.com',
|
|
187
|
+
pageTitle: 'New Tab',
|
|
188
|
+
colorScheme,
|
|
189
|
+
...browserBarConfig,
|
|
190
|
+
};
|
|
191
|
+
// Browser bar handles its own internal scaling (SVG transform:scale).
|
|
192
|
+
// We generate it at the FINAL pixel dimensions and place it without extra transform.
|
|
193
|
+
const bbInnerHtml = generateBrowserBarHtml({
|
|
194
|
+
config: bbConfig,
|
|
195
|
+
width: px(sr.width),
|
|
196
|
+
height: px(bbH),
|
|
197
|
+
scale,
|
|
198
|
+
pixelScale: 1,
|
|
199
|
+
});
|
|
200
|
+
const bbBorderRadius = `${px(cornerPx)}px ${px(cornerPx)}px 0 0`;
|
|
201
|
+
browserBarHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${px(sr.width)}px;height:${px(safeArea.top * scale)}px;overflow:hidden;border-radius:${bbBorderRadius};z-index:5;pointer-events:none">${bbInnerHtml}</div>`;
|
|
202
|
+
}
|
|
203
|
+
// ── Overlay (z:6) ──
|
|
204
|
+
let overlaySlotHtml = '';
|
|
205
|
+
if (overlayHtml) {
|
|
206
|
+
overlaySlotHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${px(sr.width)}px;height:${px(sr.height)}px;z-index:6;pointer-events:none">${overlayHtml}</div>`;
|
|
207
|
+
}
|
|
208
|
+
// ── Frame image ──
|
|
209
|
+
const frameZ = frameBehindContent ? 0 : 8;
|
|
210
|
+
const is90or270 = frameRotation % 180 !== 0;
|
|
211
|
+
const effectiveWidth = is90or270 ? frameHeight : frameWidth;
|
|
212
|
+
let frameTransform = '';
|
|
213
|
+
let frameMargins = '';
|
|
214
|
+
if (frameRotation) {
|
|
215
|
+
frameTransform = `transform:rotate(${frameRotation}deg);transform-origin:top left;`;
|
|
216
|
+
if (frameRotation === 90) {
|
|
217
|
+
frameMargins = `margin-left:${px(effectiveWidth)}px;`;
|
|
218
|
+
}
|
|
219
|
+
else if (frameRotation === 180) {
|
|
220
|
+
const effectiveHeight = is90or270 ? frameWidth : frameHeight;
|
|
221
|
+
frameMargins = `margin-left:${px(effectiveWidth)}px;margin-top:${px(effectiveHeight)}px;`;
|
|
222
|
+
}
|
|
223
|
+
else if (frameRotation === 270 || frameRotation === -90) {
|
|
224
|
+
const effectiveHeight = is90or270 ? frameWidth : frameHeight;
|
|
225
|
+
frameMargins = `margin-top:${px(effectiveHeight)}px;`;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const frameHtml = frameSrc
|
|
229
|
+
? `<img src="${frameSrc}" alt="Device frame" style="position:absolute;top:0;left:0;width:${px(frameWidth)}px;height:${px(frameHeight)}px;max-width:none;pointer-events:none;z-index:${frameZ};${frameTransform}${frameMargins}" draggable="false">`
|
|
230
|
+
: '';
|
|
231
|
+
// ── Window border (z:9, outside the screen rect) ──
|
|
232
|
+
let windowBorderHtml = '';
|
|
233
|
+
if (windowBorder && windowBorder.width > 0) {
|
|
234
|
+
const bw = px(windowBorder.width);
|
|
235
|
+
const br = px(windowBorder.radius);
|
|
236
|
+
windowBorderHtml = `<div style="position:absolute;left:0;top:0;width:${px(sr.width)}px;height:${px(sr.height)}px;border:${bw}px solid ${windowBorder.color};border-radius:${br}px;pointer-events:none;z-index:9;box-sizing:border-box"></div>`;
|
|
237
|
+
}
|
|
238
|
+
// ── Assemble ──
|
|
239
|
+
return [screenBgHtml, contentSlotHtml, homeIndicatorHtml, statusBarHtml, browserBarHtml, overlaySlotHtml, frameHtml, windowBorderHtml].join('\n');
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Generate a complete HTML page wrapping the mockup (for server-side Playwright rendering).
|
|
243
|
+
*/
|
|
244
|
+
export function generateMockupPage(params) {
|
|
245
|
+
const layout = computeMockupLayout(params);
|
|
246
|
+
const ps = params.pixelScale ?? 1;
|
|
247
|
+
const w = Math.round(layout.containerWidth * ps);
|
|
248
|
+
const h = Math.round(layout.containerHeight * ps);
|
|
249
|
+
const shouldInjectStatusBarFonts = params.showStatusBar !== false && !!params.statusBar && params.safeArea.top > 0;
|
|
250
|
+
const inner = generateMockupHtmlInternal(params, { includeInlineStatusBarFontStyles: !shouldInjectStatusBarFonts });
|
|
251
|
+
const fontCss = shouldInjectStatusBarFonts ? `${STATUS_BAR_FONT_CSS}\n` : '';
|
|
252
|
+
return `<!DOCTYPE html>
|
|
253
|
+
<html><head><meta charset="utf-8"><style>
|
|
254
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
255
|
+
${fontCss}
|
|
256
|
+
body{width:${w}px;height:${h}px;overflow:hidden;background:transparent}
|
|
257
|
+
</style></head><body>
|
|
258
|
+
<div style="position:relative;width:${w}px;height:${h}px">
|
|
259
|
+
${inner}
|
|
260
|
+
</div>
|
|
261
|
+
</body></html>`;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=mockup-html.js.map
|
package/dist/mockup.d.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { StatusBarConfig, StatusBarLayout, StatusBarDeviceType } from './status-bar.js';
|
|
2
|
+
import type { BrowserBarConfig } from './browser-bar.js';
|
|
3
|
+
export type DeviceCategory = 'phone' | 'tablet' | 'laptop' | 'browser';
|
|
4
|
+
export type DeviceFrameId = 'iphone-16-pro' | (string & {});
|
|
5
|
+
export interface DeviceFrameDefinition {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
category: DeviceCategory;
|
|
9
|
+
viewport: {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface OrientationConfigData {
|
|
15
|
+
screen: {
|
|
16
|
+
logicalWidth: number;
|
|
17
|
+
logicalHeight: number;
|
|
18
|
+
scale: number;
|
|
19
|
+
cornerRadius: number;
|
|
20
|
+
};
|
|
21
|
+
viewport: {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
};
|
|
25
|
+
safeArea?: {
|
|
26
|
+
top: number;
|
|
27
|
+
bottom: number;
|
|
28
|
+
left?: number;
|
|
29
|
+
right?: number;
|
|
30
|
+
};
|
|
31
|
+
statusBar?: {
|
|
32
|
+
asset?: string;
|
|
33
|
+
height: number;
|
|
34
|
+
width: number;
|
|
35
|
+
type?: StatusBarDeviceType;
|
|
36
|
+
layout?: StatusBarLayout;
|
|
37
|
+
};
|
|
38
|
+
homeIndicator?: {
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
cornerRadius: number;
|
|
42
|
+
bottomOffset: number;
|
|
43
|
+
};
|
|
44
|
+
frame: {
|
|
45
|
+
type: 'png' | 'svg';
|
|
46
|
+
asset: string;
|
|
47
|
+
width: number;
|
|
48
|
+
height: number;
|
|
49
|
+
screenRect: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
/** Rotation angle (degrees CW) applied to the frame image */
|
|
57
|
+
frameRotation?: number;
|
|
58
|
+
/** When true, the frame is rendered behind the screen content */
|
|
59
|
+
frameBehindContent?: boolean;
|
|
60
|
+
frameUrl?: string;
|
|
61
|
+
/** Window border for frameless browser mockups */
|
|
62
|
+
windowBorder?: {
|
|
63
|
+
color: string;
|
|
64
|
+
width: number;
|
|
65
|
+
radius: number;
|
|
66
|
+
};
|
|
67
|
+
/** Dark-mode frame URL (browser category) */
|
|
68
|
+
frameDarkUrl?: string;
|
|
69
|
+
/** Configurable zones for browser bar dynamic content */
|
|
70
|
+
browserBarZones?: {
|
|
71
|
+
favicon?: {
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
width: number;
|
|
75
|
+
height: number;
|
|
76
|
+
};
|
|
77
|
+
pageTitle?: {
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
width: number;
|
|
81
|
+
height: number;
|
|
82
|
+
fontSize?: number;
|
|
83
|
+
fontWeight?: number | string;
|
|
84
|
+
textAlign?: 'left' | 'center' | 'right';
|
|
85
|
+
};
|
|
86
|
+
url?: {
|
|
87
|
+
x: number;
|
|
88
|
+
y: number;
|
|
89
|
+
width: number;
|
|
90
|
+
height: number;
|
|
91
|
+
fontSize?: number;
|
|
92
|
+
fontWeight?: number | string;
|
|
93
|
+
textAlign?: 'left' | 'center' | 'right';
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/** Which coded browser chrome style to render. Defaults to 'chrome'. */
|
|
97
|
+
browserStyle?: 'chrome' | 'safari';
|
|
98
|
+
}
|
|
99
|
+
export type MockupOrientation = 'portrait' | 'landscape';
|
|
100
|
+
export interface MockupOptions {
|
|
101
|
+
orientation?: MockupOrientation;
|
|
102
|
+
outputScale?: number;
|
|
103
|
+
showStatusBar?: boolean;
|
|
104
|
+
showSafeAreaTop?: boolean;
|
|
105
|
+
showSafeAreaBottom?: boolean;
|
|
106
|
+
showSafeAreaLeft?: boolean;
|
|
107
|
+
showSafeAreaRight?: boolean;
|
|
108
|
+
showHomeIndicator?: boolean;
|
|
109
|
+
safeAreaTopColor?: string;
|
|
110
|
+
safeAreaBottomColor?: string;
|
|
111
|
+
safeAreaLeftColor?: string;
|
|
112
|
+
safeAreaRightColor?: string;
|
|
113
|
+
statusBar?: StatusBarConfig;
|
|
114
|
+
browserBar?: BrowserBarConfig;
|
|
115
|
+
/** Window border for frameless mockups (browser category) */
|
|
116
|
+
windowBorder?: {
|
|
117
|
+
color: string;
|
|
118
|
+
width: number;
|
|
119
|
+
radius: number;
|
|
120
|
+
};
|
|
121
|
+
/** Explicit color scheme override — bypasses auto-detection from edge colors */
|
|
122
|
+
colorScheme?: 'light' | 'dark';
|
|
123
|
+
}
|
|
124
|
+
export interface ResolvedDeviceFrameDescriptor {
|
|
125
|
+
id: string;
|
|
126
|
+
name: string;
|
|
127
|
+
category: DeviceCategory;
|
|
128
|
+
orientation: MockupOrientation;
|
|
129
|
+
/** Pre-computed viewport from the device config (content area) */
|
|
130
|
+
viewport?: {
|
|
131
|
+
width: number;
|
|
132
|
+
height: number;
|
|
133
|
+
};
|
|
134
|
+
screen: {
|
|
135
|
+
logicalWidth: number;
|
|
136
|
+
logicalHeight: number;
|
|
137
|
+
scale: number;
|
|
138
|
+
cornerRadius: number;
|
|
139
|
+
};
|
|
140
|
+
safeArea: {
|
|
141
|
+
top: number;
|
|
142
|
+
bottom: number;
|
|
143
|
+
left?: number;
|
|
144
|
+
right?: number;
|
|
145
|
+
};
|
|
146
|
+
statusBar?: {
|
|
147
|
+
asset?: string;
|
|
148
|
+
height: number;
|
|
149
|
+
width: number;
|
|
150
|
+
type?: StatusBarDeviceType;
|
|
151
|
+
layout?: StatusBarLayout;
|
|
152
|
+
};
|
|
153
|
+
homeIndicator?: {
|
|
154
|
+
width: number;
|
|
155
|
+
height: number;
|
|
156
|
+
cornerRadius: number;
|
|
157
|
+
bottomOffset: number;
|
|
158
|
+
};
|
|
159
|
+
frame: {
|
|
160
|
+
type: 'png' | 'svg';
|
|
161
|
+
asset: string;
|
|
162
|
+
width: number;
|
|
163
|
+
height: number;
|
|
164
|
+
};
|
|
165
|
+
frameUrl?: string;
|
|
166
|
+
frameWidth: number;
|
|
167
|
+
frameHeight: number;
|
|
168
|
+
screenRect: {
|
|
169
|
+
x: number;
|
|
170
|
+
y: number;
|
|
171
|
+
width: number;
|
|
172
|
+
height: number;
|
|
173
|
+
};
|
|
174
|
+
frameRotation: number;
|
|
175
|
+
frameBehindContent: boolean;
|
|
176
|
+
browserStyle?: OrientationConfigData['browserStyle'];
|
|
177
|
+
disableOverlays: boolean;
|
|
178
|
+
}
|
|
179
|
+
export declare function invalidateDeviceConfigCache(): void;
|
|
180
|
+
export declare function resolveDeviceFrameDescriptor(id: DeviceFrameId, options?: {
|
|
181
|
+
orientation?: MockupOrientation;
|
|
182
|
+
}): Promise<ResolvedDeviceFrameDescriptor | null>;
|
|
183
|
+
export declare function rasterizeDeviceFrame(descriptor: ResolvedDeviceFrameDescriptor, outputScale: number): Promise<Buffer>;
|
|
184
|
+
export declare function getDeviceFrames(): Promise<DeviceFrameDefinition[]>;
|
|
185
|
+
export declare function getDeviceFrame(id: DeviceFrameId): Promise<DeviceFrameDefinition | undefined>;
|
|
186
|
+
export declare function applyDeviceFrame(screenshot: Buffer, deviceId: DeviceFrameId, options?: MockupOptions): Promise<Buffer>;
|
|
187
|
+
export {};
|