autokap 1.0.2 → 1.0.4
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/dist/cli-config.d.ts +13 -0
- package/dist/cli-config.js +42 -0
- package/dist/cli-utils.d.ts +0 -19
- package/dist/cli-utils.js +2 -65
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +266 -305
- package/package.json +26 -19
- 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/devices/ipad-pro-11-m4.json +0 -52
- package/assets/devices/iphone-16-pro.json +0 -53
- package/assets/devices/macbook-air-13.json +0 -45
- package/assets/frames/MacBook Air 13.svg +0 -242
- package/assets/frames/Status bar - iPhone.png +0 -0
- package/assets/frames/Status bar and 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 +0 -3
- package/assets/icons/Union.svg +0 -6
- package/assets/icons/Wifi.svg +0 -3
- package/assets/icons/battery.svg +0 -5
- package/assets/icons/battery_charging.svg +0 -8
- package/dist/abort.d.ts +0 -5
- package/dist/abort.js +0 -44
- package/dist/agent.d.ts +0 -142
- package/dist/agent.js +0 -4504
- package/dist/browser-bar.d.ts +0 -40
- package/dist/browser-bar.js +0 -147
- package/dist/clip-orchestrator.d.ts +0 -148
- package/dist/clip-orchestrator.js +0 -950
- package/dist/clip-postprocess.d.ts +0 -42
- package/dist/clip-postprocess.js +0 -192
- package/dist/credential-templates.d.ts +0 -5
- package/dist/credential-templates.js +0 -60
- package/dist/element-capture.d.ts +0 -53
- package/dist/element-capture.js +0 -766
- package/dist/hybrid-navigator.d.ts +0 -138
- package/dist/hybrid-navigator.js +0 -468
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -11
- package/dist/llm-usage.d.ts +0 -17
- package/dist/llm-usage.js +0 -45
- package/dist/mockup-html.d.ts +0 -119
- package/dist/mockup-html.js +0 -253
- package/dist/mockup.d.ts +0 -94
- package/dist/mockup.js +0 -604
- package/dist/mouse-animation.d.ts +0 -46
- package/dist/mouse-animation.js +0 -100
- package/dist/overlay-utils.d.ts +0 -14
- package/dist/overlay-utils.js +0 -13
- package/dist/posthog.d.ts +0 -4
- package/dist/posthog.js +0 -26
- package/dist/prompt-cache.d.ts +0 -10
- package/dist/prompt-cache.js +0 -24
- package/dist/prompts.d.ts +0 -167
- package/dist/prompts.js +0 -1165
- package/dist/security.d.ts +0 -20
- package/dist/security.js +0 -569
- package/dist/session-profile.d.ts +0 -86
- package/dist/session-profile.js +0 -1471
- package/dist/sf-pro-fonts.d.ts +0 -4
- package/dist/sf-pro-fonts.js +0 -7
- package/dist/status-bar-l10n.d.ts +0 -14
- package/dist/status-bar-l10n.js +0 -177
- package/dist/status-bar.d.ts +0 -44
- package/dist/status-bar.js +0 -336
- package/dist/tools.d.ts +0 -4
- package/dist/tools.js +0 -578
- package/dist/video-agent.d.ts +0 -143
- package/dist/video-agent.js +0 -4783
- package/dist/video-observation.d.ts +0 -36
- package/dist/video-observation.js +0 -192
- package/dist/video-planner.d.ts +0 -12
- package/dist/video-planner.js +0 -500
- package/dist/video-prompts.d.ts +0 -37
- package/dist/video-prompts.js +0 -554
- package/dist/video-tools.d.ts +0 -3
- package/dist/video-tools.js +0 -59
- package/dist/video-variant-state.d.ts +0 -29
- package/dist/video-variant-state.js +0 -80
- package/dist/vision-model.d.ts +0 -17
- package/dist/vision-model.js +0 -74
package/dist/llm-usage.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export function extractLlmUsageSnapshot(response) {
|
|
2
|
-
const usageDetails = response.usage;
|
|
3
|
-
const promptDetails = usageDetails?.prompt_tokens_details;
|
|
4
|
-
const completionDetails = usageDetails?.completion_tokens_details;
|
|
5
|
-
return {
|
|
6
|
-
generationId: response.id ?? null,
|
|
7
|
-
modelUsed: response.model ?? null,
|
|
8
|
-
promptTokens: response.usage?.prompt_tokens ?? null,
|
|
9
|
-
completionTokens: response.usage?.completion_tokens ?? null,
|
|
10
|
-
totalTokens: response.usage?.total_tokens ?? null,
|
|
11
|
-
cacheReadTokens: promptDetails?.cached_tokens
|
|
12
|
-
?? usageDetails?.cache_read_input_tokens
|
|
13
|
-
?? null,
|
|
14
|
-
cacheWriteTokens: promptDetails?.cache_creation_input_tokens
|
|
15
|
-
?? usageDetails?.cache_write_input_tokens
|
|
16
|
-
?? null,
|
|
17
|
-
reasoningTokens: completionDetails?.reasoning_tokens
|
|
18
|
-
?? null,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export function buildStepUsageFromSnapshot(snapshot, params) {
|
|
22
|
-
return {
|
|
23
|
-
stepNumber: params.stepNumber,
|
|
24
|
-
stepType: params.stepType,
|
|
25
|
-
modelRequested: params.modelRequested,
|
|
26
|
-
imagesInPrompt: params.imagesInPrompt,
|
|
27
|
-
...snapshot,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
export function normalizeLlmUsageSnapshot(snapshot) {
|
|
31
|
-
return {
|
|
32
|
-
generationId: snapshot.generationId ?? null,
|
|
33
|
-
modelUsed: snapshot.modelUsed ?? null,
|
|
34
|
-
promptTokens: snapshot.promptTokens ?? null,
|
|
35
|
-
completionTokens: snapshot.completionTokens ?? null,
|
|
36
|
-
totalTokens: snapshot.totalTokens ?? null,
|
|
37
|
-
cacheReadTokens: snapshot.cacheReadTokens ?? null,
|
|
38
|
-
cacheWriteTokens: snapshot.cacheWriteTokens ?? null,
|
|
39
|
-
reasoningTokens: snapshot.reasoningTokens ?? null,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
export function extractStepUsage(response, params) {
|
|
43
|
-
return buildStepUsageFromSnapshot(extractLlmUsageSnapshot(response), params);
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=llm-usage.js.map
|
package/dist/mockup-html.d.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
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;
|
package/dist/mockup-html.js
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
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 } 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
|
-
// Expand container for window border (browser frameless mockups)
|
|
45
|
-
const finalContainerWidth = containerWidth + borderW * 2;
|
|
46
|
-
const finalContainerHeight = containerHeight + borderW * 2;
|
|
47
|
-
return {
|
|
48
|
-
containerWidth: finalContainerWidth,
|
|
49
|
-
containerHeight: finalContainerHeight,
|
|
50
|
-
contentArea: {
|
|
51
|
-
x: screenRect.x + leftPx + borderW,
|
|
52
|
-
y: screenRect.y + topPx + borderW,
|
|
53
|
-
width: contentW,
|
|
54
|
-
height: contentH,
|
|
55
|
-
},
|
|
56
|
-
screenArea: {
|
|
57
|
-
x: screenRect.x + borderW,
|
|
58
|
-
y: screenRect.y + borderW,
|
|
59
|
-
width: screenRect.width,
|
|
60
|
-
height: screenRect.height,
|
|
61
|
-
},
|
|
62
|
-
screenBorderRadius,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
// ── HTML Generation ─────────────────────────────────────────────────────
|
|
66
|
-
/**
|
|
67
|
-
* Generate the complete mockup HTML structure.
|
|
68
|
-
*
|
|
69
|
-
* All elements are absolutely positioned within a container div
|
|
70
|
-
* (position:relative). This allows the client to inject React children
|
|
71
|
-
* as siblings at z-index:2 (between screen bg and status bar).
|
|
72
|
-
*
|
|
73
|
-
* The returned HTML is a FRAGMENT (no wrapping div), meant to be placed
|
|
74
|
-
* inside a position:relative container of the correct dimensions.
|
|
75
|
-
*/
|
|
76
|
-
export function generateMockupHtml(params) {
|
|
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
|
-
// Offset screen rect by border width so everything shifts inward
|
|
82
|
-
const sr = { x: screenRect.x + borderW, y: screenRect.y + borderW, width: screenRect.width, height: screenRect.height };
|
|
83
|
-
const ca = layout.contentArea;
|
|
84
|
-
// Safe area visibility
|
|
85
|
-
const showTop = showSafeAreaTop && safeArea.top > 0;
|
|
86
|
-
const showBottom = showSafeAreaBottom && safeArea.bottom > 0;
|
|
87
|
-
const showLeft = showSafeAreaLeft && (safeArea.left ?? 0) > 0;
|
|
88
|
-
const showRight = showSafeAreaRight && (safeArea.right ?? 0) > 0;
|
|
89
|
-
const topPx = showTop ? safeArea.top * scale : 0;
|
|
90
|
-
const bottomPx = showBottom ? safeArea.bottom * scale : 0;
|
|
91
|
-
const leftPx = showLeft ? (safeArea.left ?? 0) * scale : 0;
|
|
92
|
-
const rightPx = showRight ? (safeArea.right ?? 0) * scale : 0;
|
|
93
|
-
const cornerPx = Math.max(0, cornerRadius);
|
|
94
|
-
const screenBorderRadius = layout.screenBorderRadius;
|
|
95
|
-
const screenBorderRadiusCss = screenBorderRadius
|
|
96
|
-
.split(' ')
|
|
97
|
-
.map((v) => px(parseFloat(v)) + 'px')
|
|
98
|
-
.join(' ');
|
|
99
|
-
// ── Screen background + safe area fills (z:1) ──
|
|
100
|
-
let safeAreaFillsHtml = '';
|
|
101
|
-
const topColor = safeAreaColors?.top ?? screenBackground;
|
|
102
|
-
const bottomColor = safeAreaColors?.bottom ?? screenBackground;
|
|
103
|
-
const leftColor = safeAreaColors?.left ?? screenBackground;
|
|
104
|
-
const rightColor = safeAreaColors?.right ?? screenBackground;
|
|
105
|
-
if (showLeft) {
|
|
106
|
-
safeAreaFillsHtml += `<div style="position:absolute;top:0;left:0;bottom:0;width:${px(leftPx)}px;background:${leftColor}"></div>`;
|
|
107
|
-
}
|
|
108
|
-
if (showRight) {
|
|
109
|
-
safeAreaFillsHtml += `<div style="position:absolute;top:0;right:0;bottom:0;width:${px(rightPx)}px;background:${rightColor}"></div>`;
|
|
110
|
-
}
|
|
111
|
-
if (showTop) {
|
|
112
|
-
safeAreaFillsHtml += `<div style="position:absolute;top:0;left:${px(leftPx)}px;right:${px(rightPx)}px;height:${px(topPx)}px;background:${topColor}"></div>`;
|
|
113
|
-
}
|
|
114
|
-
if (showBottom) {
|
|
115
|
-
safeAreaFillsHtml += `<div style="position:absolute;bottom:0;left:${px(leftPx)}px;right:${px(rightPx)}px;height:${px(bottomPx)}px;background:${bottomColor}"></div>`;
|
|
116
|
-
}
|
|
117
|
-
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>`;
|
|
118
|
-
// ── Content (z:2) ──
|
|
119
|
-
let contentSlotHtml = '';
|
|
120
|
-
if (contentHtml) {
|
|
121
|
-
const contentBorderRadius = topPx > 0
|
|
122
|
-
? `0 0 ${px(cornerPx)}px ${px(cornerPx)}px`
|
|
123
|
-
: screenBorderRadiusCss;
|
|
124
|
-
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>`;
|
|
125
|
-
}
|
|
126
|
-
// ── Home indicator (z:4) ──
|
|
127
|
-
let homeIndicatorHtml = '';
|
|
128
|
-
if (showHomeIndicator && homeIndicator && safeArea.bottom > 0) {
|
|
129
|
-
const hiW = homeIndicator.width * scale;
|
|
130
|
-
const hiH = homeIndicator.height * scale;
|
|
131
|
-
const hiR = homeIndicator.cornerRadius * scale;
|
|
132
|
-
const hiBottom = homeIndicator.bottomOffset * scale;
|
|
133
|
-
const hiColor = homeIndicatorColor ??
|
|
134
|
-
(colorScheme === 'dark' ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.35)');
|
|
135
|
-
// Position: centered horizontally in screen rect, offset from bottom of screen rect
|
|
136
|
-
const hiLeft = sr.x + (sr.width - hiW) / 2;
|
|
137
|
-
const hiTop = sr.y + sr.height - hiBottom - hiH;
|
|
138
|
-
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>`;
|
|
139
|
-
}
|
|
140
|
-
// ── Status bar (z:5) ──
|
|
141
|
-
let statusBarHtml = '';
|
|
142
|
-
if (showStatusBar && statusBar && safeArea.top > 0) {
|
|
143
|
-
const sbH = statusBar.height * scale;
|
|
144
|
-
const sbConfig = {
|
|
145
|
-
time: '9:41',
|
|
146
|
-
signalStrength: 4,
|
|
147
|
-
networkType: '5G',
|
|
148
|
-
wifiStrength: 3,
|
|
149
|
-
batteryLevel: 100,
|
|
150
|
-
batteryCharging: false,
|
|
151
|
-
colorScheme,
|
|
152
|
-
...statusBarConfig,
|
|
153
|
-
};
|
|
154
|
-
const sbInnerHtml = generateStatusBarHtml({
|
|
155
|
-
config: sbConfig,
|
|
156
|
-
width: sr.width,
|
|
157
|
-
height: sbH,
|
|
158
|
-
scale,
|
|
159
|
-
deviceType: statusBar.type,
|
|
160
|
-
layout: statusBar.layout,
|
|
161
|
-
});
|
|
162
|
-
// Status bar needs its own border-radius clipping (top corners only)
|
|
163
|
-
const sbBorderRadius = `${px(cornerPx)}px ${px(cornerPx)}px 0 0`;
|
|
164
|
-
if (pixelScale === 1) {
|
|
165
|
-
// Client: render at 1× (status bar HTML handles its own internal scaling)
|
|
166
|
-
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:${sbBorderRadius};z-index:5;pointer-events:none">${sbInnerHtml}</div>`;
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
// Server: render at pixelScale× with transform
|
|
170
|
-
statusBarHtml = `<div style="position:absolute;left:${px(sr.x)}px;top:${px(sr.y)}px;width:${px(sr.width)}px;height:${px(sbH)}px;overflow:hidden;border-radius:${sbBorderRadius};z-index:5;transform:scale(${pixelScale});transform-origin:top left">${sbInnerHtml}</div>`;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// ── Browser bar (z:5) — full Chrome toolbar, same pattern as status bar ──
|
|
174
|
-
let browserBarHtml = '';
|
|
175
|
-
if (showBrowserBar && safeArea.top > 0) {
|
|
176
|
-
const bbH = safeArea.top * scale;
|
|
177
|
-
const bbConfig = {
|
|
178
|
-
url: 'example.com',
|
|
179
|
-
pageTitle: 'New Tab',
|
|
180
|
-
colorScheme,
|
|
181
|
-
...browserBarConfig,
|
|
182
|
-
};
|
|
183
|
-
// Browser bar handles its own internal scaling (SVG transform:scale).
|
|
184
|
-
// We generate it at the FINAL pixel dimensions and place it without extra transform.
|
|
185
|
-
const bbInnerHtml = generateBrowserBarHtml({
|
|
186
|
-
config: bbConfig,
|
|
187
|
-
width: px(sr.width),
|
|
188
|
-
height: px(bbH),
|
|
189
|
-
scale,
|
|
190
|
-
pixelScale: 1,
|
|
191
|
-
});
|
|
192
|
-
const bbBorderRadius = `${px(cornerPx)}px ${px(cornerPx)}px 0 0`;
|
|
193
|
-
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>`;
|
|
194
|
-
}
|
|
195
|
-
// ── Overlay (z:6) ──
|
|
196
|
-
let overlaySlotHtml = '';
|
|
197
|
-
if (overlayHtml) {
|
|
198
|
-
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>`;
|
|
199
|
-
}
|
|
200
|
-
// ── Frame image ──
|
|
201
|
-
const frameZ = frameBehindContent ? 0 : 8;
|
|
202
|
-
const is90or270 = frameRotation % 180 !== 0;
|
|
203
|
-
const effectiveWidth = is90or270 ? frameHeight : frameWidth;
|
|
204
|
-
let frameTransform = '';
|
|
205
|
-
let frameMargins = '';
|
|
206
|
-
if (frameRotation) {
|
|
207
|
-
frameTransform = `transform:rotate(${frameRotation}deg);transform-origin:top left;`;
|
|
208
|
-
if (frameRotation === 90) {
|
|
209
|
-
frameMargins = `margin-left:${px(effectiveWidth)}px;`;
|
|
210
|
-
}
|
|
211
|
-
else if (frameRotation === 180) {
|
|
212
|
-
const effectiveHeight = is90or270 ? frameWidth : frameHeight;
|
|
213
|
-
frameMargins = `margin-left:${px(effectiveWidth)}px;margin-top:${px(effectiveHeight)}px;`;
|
|
214
|
-
}
|
|
215
|
-
else if (frameRotation === 270 || frameRotation === -90) {
|
|
216
|
-
const effectiveHeight = is90or270 ? frameWidth : frameHeight;
|
|
217
|
-
frameMargins = `margin-top:${px(effectiveHeight)}px;`;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const frameHtml = frameSrc
|
|
221
|
-
? `<img src="${frameSrc}" alt="Device frame" style="position:absolute;top:${px(borderW)}px;left:${px(borderW)}px;width:${px(frameWidth)}px;height:${px(frameHeight)}px;max-width:none;pointer-events:none;z-index:${frameZ};${frameTransform}${frameMargins}" draggable="false">`
|
|
222
|
-
: '';
|
|
223
|
-
// ── Window border (z:9, outside the screen rect) ──
|
|
224
|
-
let windowBorderHtml = '';
|
|
225
|
-
if (windowBorder && windowBorder.width > 0) {
|
|
226
|
-
const bw = px(windowBorder.width);
|
|
227
|
-
const br = px(windowBorder.radius);
|
|
228
|
-
// Border wraps around the screen rect — container was expanded by borderW on each side
|
|
229
|
-
windowBorderHtml = `<div style="position:absolute;left:0;top:0;width:${px(sr.width + borderW * 2)}px;height:${px(sr.height + borderW * 2)}px;border:${bw}px solid ${windowBorder.color};border-radius:${br}px;pointer-events:none;z-index:9;box-sizing:border-box"></div>`;
|
|
230
|
-
}
|
|
231
|
-
// ── Assemble ──
|
|
232
|
-
return [screenBgHtml, contentSlotHtml, homeIndicatorHtml, statusBarHtml, browserBarHtml, overlaySlotHtml, frameHtml, windowBorderHtml].join('\n');
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Generate a complete HTML page wrapping the mockup (for server-side Playwright rendering).
|
|
236
|
-
*/
|
|
237
|
-
export function generateMockupPage(params) {
|
|
238
|
-
const layout = computeMockupLayout(params);
|
|
239
|
-
const ps = params.pixelScale ?? 1;
|
|
240
|
-
const w = Math.round(layout.containerWidth * ps);
|
|
241
|
-
const h = Math.round(layout.containerHeight * ps);
|
|
242
|
-
const inner = generateMockupHtml(params);
|
|
243
|
-
return `<!DOCTYPE html>
|
|
244
|
-
<html><head><meta charset="utf-8"><style>
|
|
245
|
-
*{margin:0;padding:0;box-sizing:border-box}
|
|
246
|
-
body{width:${w}px;height:${h}px;overflow:hidden;background:transparent}
|
|
247
|
-
</style></head><body>
|
|
248
|
-
<div style="position:relative;width:${w}px;height:${h}px">
|
|
249
|
-
${inner}
|
|
250
|
-
</div>
|
|
251
|
-
</body></html>`;
|
|
252
|
-
}
|
|
253
|
-
//# sourceMappingURL=mockup-html.js.map
|
package/dist/mockup.d.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type { BrowserContext } from 'playwright';
|
|
2
|
-
import type { StatusBarConfig, StatusBarLayout, StatusBarDeviceType } from './status-bar.js';
|
|
3
|
-
import type { BrowserBarConfig } from './browser-bar.js';
|
|
4
|
-
export type DeviceCategory = 'phone' | 'tablet' | 'laptop' | 'browser';
|
|
5
|
-
export type DeviceFrameId = 'iphone-16-pro' | (string & {});
|
|
6
|
-
export interface DeviceFrameDefinition {
|
|
7
|
-
id: string;
|
|
8
|
-
name: string;
|
|
9
|
-
category: DeviceCategory;
|
|
10
|
-
viewport: {
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export type MockupOrientation = 'portrait' | 'landscape';
|
|
16
|
-
export interface MockupOptions {
|
|
17
|
-
orientation?: MockupOrientation;
|
|
18
|
-
outputScale?: number;
|
|
19
|
-
showStatusBar?: boolean;
|
|
20
|
-
showSafeAreaTop?: boolean;
|
|
21
|
-
showSafeAreaBottom?: boolean;
|
|
22
|
-
showSafeAreaLeft?: boolean;
|
|
23
|
-
showSafeAreaRight?: boolean;
|
|
24
|
-
showHomeIndicator?: boolean;
|
|
25
|
-
safeAreaTopColor?: string;
|
|
26
|
-
safeAreaBottomColor?: string;
|
|
27
|
-
safeAreaLeftColor?: string;
|
|
28
|
-
safeAreaRightColor?: string;
|
|
29
|
-
statusBar?: StatusBarConfig;
|
|
30
|
-
browserBar?: BrowserBarConfig;
|
|
31
|
-
/** Window border for frameless mockups (browser category) */
|
|
32
|
-
windowBorder?: {
|
|
33
|
-
color: string;
|
|
34
|
-
width: number;
|
|
35
|
-
radius: number;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
export interface ResolvedDeviceFrameDescriptor {
|
|
39
|
-
id: string;
|
|
40
|
-
name: string;
|
|
41
|
-
category: DeviceCategory;
|
|
42
|
-
orientation: MockupOrientation;
|
|
43
|
-
screen: {
|
|
44
|
-
logicalWidth: number;
|
|
45
|
-
logicalHeight: number;
|
|
46
|
-
scale: number;
|
|
47
|
-
cornerRadius: number;
|
|
48
|
-
};
|
|
49
|
-
safeArea: {
|
|
50
|
-
top: number;
|
|
51
|
-
bottom: number;
|
|
52
|
-
left?: number;
|
|
53
|
-
right?: number;
|
|
54
|
-
};
|
|
55
|
-
statusBar?: {
|
|
56
|
-
asset?: string;
|
|
57
|
-
height: number;
|
|
58
|
-
width: number;
|
|
59
|
-
type?: StatusBarDeviceType;
|
|
60
|
-
layout?: StatusBarLayout;
|
|
61
|
-
};
|
|
62
|
-
homeIndicator?: {
|
|
63
|
-
width: number;
|
|
64
|
-
height: number;
|
|
65
|
-
cornerRadius: number;
|
|
66
|
-
bottomOffset: number;
|
|
67
|
-
};
|
|
68
|
-
frame: {
|
|
69
|
-
type: 'png' | 'svg';
|
|
70
|
-
asset: string;
|
|
71
|
-
width: number;
|
|
72
|
-
height: number;
|
|
73
|
-
};
|
|
74
|
-
frameUrl?: string;
|
|
75
|
-
frameWidth: number;
|
|
76
|
-
frameHeight: number;
|
|
77
|
-
screenRect: {
|
|
78
|
-
x: number;
|
|
79
|
-
y: number;
|
|
80
|
-
width: number;
|
|
81
|
-
height: number;
|
|
82
|
-
};
|
|
83
|
-
frameRotation: number;
|
|
84
|
-
frameBehindContent: boolean;
|
|
85
|
-
disableOverlays: boolean;
|
|
86
|
-
}
|
|
87
|
-
export declare function invalidateDeviceConfigCache(): void;
|
|
88
|
-
export declare function resolveDeviceFrameDescriptor(id: DeviceFrameId, options?: {
|
|
89
|
-
orientation?: MockupOrientation;
|
|
90
|
-
}): Promise<ResolvedDeviceFrameDescriptor | null>;
|
|
91
|
-
export declare function rasterizeDeviceFrame(descriptor: ResolvedDeviceFrameDescriptor, outputScale: number): Promise<Buffer>;
|
|
92
|
-
export declare function getDeviceFrames(): Promise<DeviceFrameDefinition[]>;
|
|
93
|
-
export declare function getDeviceFrame(id: DeviceFrameId): Promise<DeviceFrameDefinition | undefined>;
|
|
94
|
-
export declare function applyDeviceFrame(screenshot: Buffer, deviceId: DeviceFrameId, browserContext: BrowserContext, options?: MockupOptions): Promise<Buffer>;
|