playwriter 0.0.63 → 0.0.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/a11y-client.js +18 -8
  2. package/dist/aria-snapshot.d.ts +41 -3
  3. package/dist/aria-snapshot.d.ts.map +1 -1
  4. package/dist/aria-snapshot.js +134 -55
  5. package/dist/aria-snapshot.js.map +1 -1
  6. package/dist/aria-snapshot.test.js +5 -2
  7. package/dist/aria-snapshot.test.js.map +1 -1
  8. package/dist/aria-snapshot.unit.test.js +83 -41
  9. package/dist/aria-snapshot.unit.test.js.map +1 -1
  10. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts +5 -0
  11. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts.map +1 -0
  12. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js +5 -0
  13. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js.map +1 -0
  14. package/dist/bippy.js +1 -1
  15. package/dist/cdp-log.d.ts +1 -1
  16. package/dist/cdp-log.d.ts.map +1 -1
  17. package/dist/cdp-log.js +1 -1
  18. package/dist/cdp-log.js.map +1 -1
  19. package/dist/cdp-relay.d.ts.map +1 -1
  20. package/dist/cdp-relay.js +492 -298
  21. package/dist/cdp-relay.js.map +1 -1
  22. package/dist/cdp-session.d.ts.map +1 -1
  23. package/dist/cdp-session.js.map +1 -1
  24. package/dist/cdp-types.d.ts.map +1 -1
  25. package/dist/cdp-types.js +7 -7
  26. package/dist/cdp-types.js.map +1 -1
  27. package/dist/clean-html.d.ts.map +1 -1
  28. package/dist/clean-html.js +4 -5
  29. package/dist/clean-html.js.map +1 -1
  30. package/dist/cli.js +45 -27
  31. package/dist/cli.js.map +1 -1
  32. package/dist/create-logger.d.ts.map +1 -1
  33. package/dist/create-logger.js +3 -1
  34. package/dist/create-logger.js.map +1 -1
  35. package/dist/debugger-examples-types.d.ts.map +1 -1
  36. package/dist/debugger.d.ts.map +1 -1
  37. package/dist/debugger.js +1 -3
  38. package/dist/debugger.js.map +1 -1
  39. package/dist/diff-utils.d.ts.map +1 -1
  40. package/dist/diff-utils.js +1 -4
  41. package/dist/diff-utils.js.map +1 -1
  42. package/dist/editor-api.md +12 -2
  43. package/dist/editor-examples.d.ts +1 -1
  44. package/dist/editor-examples.d.ts.map +1 -1
  45. package/dist/editor-examples.js +1 -1
  46. package/dist/editor-examples.js.map +1 -1
  47. package/dist/editor.d.ts +1 -1
  48. package/dist/editor.d.ts.map +1 -1
  49. package/dist/editor.js +1 -1
  50. package/dist/editor.js.map +1 -1
  51. package/dist/executor.d.ts +26 -3
  52. package/dist/executor.d.ts.map +1 -1
  53. package/dist/executor.js +297 -64
  54. package/dist/executor.js.map +1 -1
  55. package/dist/executor.unit.test.js +38 -1
  56. package/dist/executor.unit.test.js.map +1 -1
  57. package/dist/extension-connection.test.js +139 -36
  58. package/dist/extension-connection.test.js.map +1 -1
  59. package/dist/ffmpeg.d.ts +148 -0
  60. package/dist/ffmpeg.d.ts.map +1 -0
  61. package/dist/ffmpeg.js +523 -0
  62. package/dist/ffmpeg.js.map +1 -0
  63. package/dist/ghost-browser.d.ts.map +1 -1
  64. package/dist/ghost-browser.js.map +1 -1
  65. package/dist/ghost-cursor-client.js +287 -0
  66. package/dist/ghost-cursor.d.ts +27 -0
  67. package/dist/ghost-cursor.d.ts.map +1 -0
  68. package/dist/ghost-cursor.js +63 -0
  69. package/dist/ghost-cursor.js.map +1 -0
  70. package/dist/htmlrewrite.d.ts.map +1 -1
  71. package/dist/htmlrewrite.js +17 -55
  72. package/dist/htmlrewrite.js.map +1 -1
  73. package/dist/htmlrewrite.test.js.map +1 -1
  74. package/dist/kill-port.d.ts.map +1 -1
  75. package/dist/kill-port.js +1 -3
  76. package/dist/kill-port.js.map +1 -1
  77. package/dist/locator-selector.test.d.ts +2 -0
  78. package/dist/locator-selector.test.d.ts.map +1 -0
  79. package/dist/locator-selector.test.js +96 -0
  80. package/dist/locator-selector.test.js.map +1 -0
  81. package/dist/mcp-client.js.map +1 -1
  82. package/dist/mcp.d.ts.map +1 -1
  83. package/dist/mcp.js +8 -3
  84. package/dist/mcp.js.map +1 -1
  85. package/dist/on-mouse-action.test.d.ts +2 -0
  86. package/dist/on-mouse-action.test.d.ts.map +1 -0
  87. package/dist/on-mouse-action.test.js +155 -0
  88. package/dist/on-mouse-action.test.js.map +1 -0
  89. package/dist/page-markdown.js +4 -4
  90. package/dist/page-markdown.js.map +1 -1
  91. package/dist/prompt.md +450 -377
  92. package/dist/protocol.d.ts +4 -0
  93. package/dist/protocol.d.ts.map +1 -1
  94. package/dist/readability.js +16 -2
  95. package/dist/recording-ghost-cursor.d.ts +41 -0
  96. package/dist/recording-ghost-cursor.d.ts.map +1 -0
  97. package/dist/recording-ghost-cursor.js +79 -0
  98. package/dist/recording-ghost-cursor.js.map +1 -0
  99. package/dist/recording-relay.d.ts.map +1 -1
  100. package/dist/recording-relay.js +8 -8
  101. package/dist/recording-relay.js.map +1 -1
  102. package/dist/relay-client.d.ts +17 -4
  103. package/dist/relay-client.d.ts.map +1 -1
  104. package/dist/relay-client.js +45 -11
  105. package/dist/relay-client.js.map +1 -1
  106. package/dist/relay-core.test.d.ts.map +1 -1
  107. package/dist/relay-core.test.js +515 -26
  108. package/dist/relay-core.test.js.map +1 -1
  109. package/dist/relay-navigation.test.d.ts.map +1 -1
  110. package/dist/relay-navigation.test.js +169 -31
  111. package/dist/relay-navigation.test.js.map +1 -1
  112. package/dist/relay-session.test.d.ts.map +1 -1
  113. package/dist/relay-session.test.js +113 -65
  114. package/dist/relay-session.test.js.map +1 -1
  115. package/dist/relay-state.d.ts +158 -0
  116. package/dist/relay-state.d.ts.map +1 -0
  117. package/dist/relay-state.js +306 -0
  118. package/dist/relay-state.js.map +1 -0
  119. package/dist/relay-state.test.d.ts +2 -0
  120. package/dist/relay-state.test.d.ts.map +1 -0
  121. package/dist/relay-state.test.js +472 -0
  122. package/dist/relay-state.test.js.map +1 -0
  123. package/dist/scoped-fs.d.ts.map +1 -1
  124. package/dist/scoped-fs.js.map +1 -1
  125. package/dist/screen-recording.d.ts +66 -4
  126. package/dist/screen-recording.d.ts.map +1 -1
  127. package/dist/screen-recording.js +150 -13
  128. package/dist/screen-recording.js.map +1 -1
  129. package/dist/screen-recording.test.d.ts +2 -0
  130. package/dist/screen-recording.test.d.ts.map +1 -0
  131. package/dist/screen-recording.test.js +102 -0
  132. package/dist/screen-recording.test.js.map +1 -0
  133. package/dist/selector-generator.js +1 -1
  134. package/dist/snapshot-tools.test.js +71 -28
  135. package/dist/snapshot-tools.test.js.map +1 -1
  136. package/dist/start-relay-server.d.ts +1 -1
  137. package/dist/start-relay-server.d.ts.map +1 -1
  138. package/dist/start-relay-server.js +1 -1
  139. package/dist/start-relay-server.js.map +1 -1
  140. package/dist/styles-api.md +8 -1
  141. package/dist/styles-examples.d.ts +1 -1
  142. package/dist/styles-examples.d.ts.map +1 -1
  143. package/dist/styles-examples.js +1 -1
  144. package/dist/styles-examples.js.map +1 -1
  145. package/dist/styles.d.ts.map +1 -1
  146. package/dist/styles.js +1 -3
  147. package/dist/styles.js.map +1 -1
  148. package/dist/test-declarations.d.ts.map +1 -1
  149. package/dist/test-utils.d.ts +1 -1
  150. package/dist/test-utils.d.ts.map +1 -1
  151. package/dist/test-utils.js +7 -5
  152. package/dist/test-utils.js.map +1 -1
  153. package/dist/utils.d.ts.map +1 -1
  154. package/dist/utils.js.map +1 -1
  155. package/dist/wait-for-page-load.d.ts.map +1 -1
  156. package/dist/wait-for-page-load.js +1 -1
  157. package/dist/wait-for-page-load.js.map +1 -1
  158. package/package.json +4 -3
  159. package/src/a11y-client.ts +5 -4
  160. package/src/aria-snapshot.test.ts +5 -2
  161. package/src/aria-snapshot.ts +306 -117
  162. package/src/aria-snapshot.unit.test.ts +199 -141
  163. package/src/aria-snapshots/github-interactive.txt +2 -0
  164. package/src/aria-snapshots/github-raw.txt +5 -1
  165. package/src/aria-snapshots/hackernews-interactive.txt +238 -241
  166. package/src/aria-snapshots/hackernews-raw.txt +265 -269
  167. package/src/assets/aria-labels-example.png +0 -0
  168. package/src/assets/aria-labels-github.png +0 -0
  169. package/src/assets/aria-labels-hacker-news.png +0 -0
  170. package/src/assets/aria-labels-old-reddit.png +0 -0
  171. package/src/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.ts +5 -0
  172. package/src/assets/cursors/screen-studio/pointer-macos-tahoe.svg +18 -0
  173. package/src/cdp-log.ts +4 -1
  174. package/src/cdp-relay.ts +1059 -737
  175. package/src/cdp-session.ts +12 -3
  176. package/src/cdp-types.ts +51 -51
  177. package/src/clean-html.ts +4 -5
  178. package/src/cli.ts +82 -55
  179. package/src/create-logger.ts +5 -3
  180. package/src/debugger-examples-types.ts +4 -1
  181. package/src/debugger.ts +1 -5
  182. package/src/diff-utils.ts +2 -5
  183. package/src/editor-examples.ts +11 -1
  184. package/src/editor.ts +10 -2
  185. package/src/executor.ts +374 -73
  186. package/src/executor.unit.test.ts +48 -1
  187. package/src/extension-connection.test.ts +612 -488
  188. package/src/ffmpeg.ts +769 -0
  189. package/src/ghost-browser.ts +4 -6
  190. package/src/ghost-cursor-client.ts +369 -0
  191. package/src/ghost-cursor.ts +110 -0
  192. package/src/htmlrewrite.test.ts +6 -2
  193. package/src/htmlrewrite.ts +348 -386
  194. package/src/kill-port.ts +1 -3
  195. package/src/locator-selector.test.ts +115 -0
  196. package/src/mcp-client.ts +1 -1
  197. package/src/mcp.ts +21 -15
  198. package/src/on-mouse-action.test.ts +196 -0
  199. package/src/page-markdown.ts +7 -7
  200. package/src/protocol.ts +73 -57
  201. package/src/recording-ghost-cursor.ts +113 -0
  202. package/src/recording-relay.ts +20 -12
  203. package/src/relay-client.ts +85 -18
  204. package/src/relay-core.test.ts +1117 -578
  205. package/src/relay-navigation.test.ts +648 -483
  206. package/src/relay-session.test.ts +984 -929
  207. package/src/relay-state.test.ts +570 -0
  208. package/src/relay-state.ts +497 -0
  209. package/src/resource.md +21 -49
  210. package/src/scoped-fs.ts +9 -3
  211. package/src/screen-recording.test.ts +111 -0
  212. package/src/screen-recording.ts +256 -31
  213. package/src/skill.md +476 -396
  214. package/src/snapshot-tools.test.ts +580 -528
  215. package/src/snapshots/shadcn-ui-accessibility-full.md +8 -8
  216. package/src/snapshots/shadcn-ui-accessibility-interactive.md +8 -8
  217. package/src/start-relay-server.ts +14 -11
  218. package/src/styles-examples.ts +8 -1
  219. package/src/styles.ts +20 -21
  220. package/src/test-declarations.ts +6 -6
  221. package/src/test-utils.ts +104 -91
  222. package/src/utils.ts +2 -1
  223. package/src/wait-for-page-load.ts +6 -1
@@ -3,9 +3,10 @@
3
3
  * Recording happens in the extension context, so it survives page navigation.
4
4
  *
5
5
  * This module communicates with the relay server which forwards commands to the extension.
6
- * SessionId (pw-tab-X format) is used to identify which tab to record.
6
+ * sessionId (pw-tab-* format) is used to identify which tab to record.
7
7
  */
8
- import type { Page } from '@xmorse/playwright-core';
8
+ import type { BrowserContext, Page } from '@xmorse/playwright-core';
9
+ import { RecordingGhostCursorController } from './recording-ghost-cursor.js';
9
10
  /**
10
11
  * Generate a shell command to quit and restart Chrome with flags that allow automatic tab capture.
11
12
  * This enables screen recording without user interaction (clicking extension icon).
@@ -15,10 +16,25 @@ import type { Page } from '@xmorse/playwright-core';
15
16
  * - --auto-accept-this-tab-capture - auto-accepts tab capture permission requests
16
17
  */
17
18
  export declare function getChromeRestartCommand(): string;
19
+ /**
20
+ * Compute the largest viewport that fits inside `current` at the target aspect ratio.
21
+ * Never increases width or height beyond current values — only shrinks the
22
+ * dimension that's "too large" relative to the target ratio.
23
+ */
24
+ export declare function fitToAspectRatio(current: {
25
+ width: number;
26
+ height: number;
27
+ }, ratio?: {
28
+ width: number;
29
+ height: number;
30
+ }): {
31
+ width: number;
32
+ height: number;
33
+ };
18
34
  export interface StartRecordingOptions {
19
35
  /** Target page to record */
20
36
  page: Page;
21
- /** Session ID (pw-tab-X format) to identify which tab to record */
37
+ /** CDP tab session ID (pw-tab-* format) to identify which tab to record */
22
38
  sessionId?: string;
23
39
  /** Frame rate (default: 30) */
24
40
  frameRate?: number;
@@ -32,11 +48,20 @@ export interface StartRecordingOptions {
32
48
  outputPath: string;
33
49
  /** Relay server port (default: 19988) */
34
50
  relayPort?: number;
51
+ /** Aspect ratio to fit viewport to before recording (default: { width: 16, height: 9 }).
52
+ * Set to null to skip viewport resizing. */
53
+ aspectRatio?: {
54
+ width: number;
55
+ height: number;
56
+ } | null;
57
+ /** Max recording duration in ms (default: 15 min = 900000). Auto-stops recording
58
+ * when exceeded to prevent accidentally filling disk. Set to 0 or Infinity to disable. */
59
+ maxDurationMs?: number;
35
60
  }
36
61
  export interface StopRecordingOptions {
37
62
  /** Target page that is being recorded */
38
63
  page: Page;
39
- /** Session ID (pw-tab-X format) to identify which tab to stop recording */
64
+ /** CDP tab session ID (pw-tab-* format) to identify which tab to stop recording */
40
65
  sessionId?: string;
41
66
  /** Relay server port (default: 19988) */
42
67
  relayPort?: number;
@@ -46,6 +71,42 @@ export interface RecordingState {
46
71
  startedAt?: number;
47
72
  tabId?: number;
48
73
  }
74
+ export interface ExecutionTimestamp {
75
+ start: number;
76
+ end: number;
77
+ }
78
+ interface CreateRecordingApiOptions {
79
+ context: BrowserContext;
80
+ defaultPage: Page;
81
+ relayPort: number;
82
+ ghostCursorController: RecordingGhostCursorController;
83
+ onStart: () => void;
84
+ onFinish: () => void;
85
+ getExecutionTimestamps: () => ExecutionTimestamp[];
86
+ }
87
+ interface StartRecordingWithDefaultsOptions extends Omit<StartRecordingOptions, 'relayPort'> {
88
+ }
89
+ interface StopRecordingWithDefaultsOptions extends Omit<StopRecordingOptions, 'relayPort'> {
90
+ }
91
+ interface IsRecordingWithDefaultsOptions {
92
+ page?: Page;
93
+ sessionId?: string;
94
+ }
95
+ interface CancelRecordingWithDefaultsOptions {
96
+ page?: Page;
97
+ sessionId?: string;
98
+ }
99
+ export declare function createRecordingApi(options: CreateRecordingApiOptions): {
100
+ start: (opts?: StartRecordingWithDefaultsOptions) => Promise<RecordingState>;
101
+ stop: (opts?: StopRecordingWithDefaultsOptions) => Promise<{
102
+ path: string;
103
+ duration: number;
104
+ size: number;
105
+ executionTimestamps: ExecutionTimestamp[];
106
+ }>;
107
+ isRecording: (opts?: IsRecordingWithDefaultsOptions) => Promise<RecordingState>;
108
+ cancel: (opts?: CancelRecordingWithDefaultsOptions) => Promise<void>;
109
+ };
49
110
  /**
50
111
  * Start recording the page.
51
112
  * The recording is handled by the extension, so it survives page navigation.
@@ -76,4 +137,5 @@ export declare function cancelRecording(options: {
76
137
  sessionId?: string;
77
138
  relayPort?: number;
78
139
  }): Promise<void>;
140
+ export {};
79
141
  //# sourceMappingURL=screen-recording.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screen-recording.d.ts","sourceRoot":"","sources":["../src/screen-recording.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAA;AASnD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAYhD;AAWD,MAAM,WAAW,qBAAqB;IACpC,4BAA4B;IAC5B,IAAI,EAAE,IAAI,CAAA;IACV,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yDAAyD;IACzD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,IAAI,EAAE,IAAI,CAAA;IACV,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8C5F;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5H;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAU1H;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpH"}
1
+ {"version":3,"file":"screen-recording.d.ts","sourceRoot":"","sources":["../src/screen-recording.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  * Recording happens in the extension context, so it survives page navigation.
4
4
  *
5
5
  * This module communicates with the relay server which forwards commands to the extension.
6
- * SessionId (pw-tab-X format) is used to identify which tab to record.
6
+ * sessionId (pw-tab-* format) is used to identify which tab to record.
7
7
  */
8
8
  import os from 'node:os';
9
9
  import path from 'node:path';
@@ -18,7 +18,9 @@ import { EXTENSION_IDS } from './utils.js';
18
18
  */
19
19
  export function getChromeRestartCommand() {
20
20
  const platform = os.platform();
21
- const flags = EXTENSION_IDS.map(id => `--allowlisted-extension-id=${id}`).join(' ') + ' --auto-accept-this-tab-capture';
21
+ const extensionFlags = EXTENSION_IDS.map((id) => `--allowlisted-extension-id=${id}`).join(' ');
22
+ // --profile-directory=Default skips the profile picker on startup, preventing Chrome from hanging
23
+ const flags = `${extensionFlags} --auto-accept-this-tab-capture --profile-directory=Default`;
22
24
  if (platform === 'darwin') {
23
25
  return `osascript -e 'quit app "Google Chrome"' && sleep 1 && open -a "Google Chrome" --args ${flags}`;
24
26
  }
@@ -28,13 +30,140 @@ export function getChromeRestartCommand() {
28
30
  // Linux
29
31
  return `pkill chrome; sleep 1; google-chrome ${flags}`;
30
32
  }
33
+ const DEFAULT_ASPECT_RATIO = { width: 16, height: 9 };
34
+ /** Default max recording duration: 15 minutes in milliseconds */
35
+ const DEFAULT_MAX_DURATION_MS = 15 * 60 * 1000;
36
+ /**
37
+ * Compute the largest viewport that fits inside `current` at the target aspect ratio.
38
+ * Never increases width or height beyond current values — only shrinks the
39
+ * dimension that's "too large" relative to the target ratio.
40
+ */
41
+ export function fitToAspectRatio(current, ratio = DEFAULT_ASPECT_RATIO) {
42
+ const targetRatio = ratio.width / ratio.height;
43
+ const currentRatio = current.width / current.height;
44
+ if (currentRatio > targetRatio) {
45
+ // Too wide — keep height, shrink width
46
+ return { width: Math.round(current.height * targetRatio), height: current.height };
47
+ }
48
+ // Too tall (or already exact) — keep width, shrink height
49
+ return { width: current.width, height: Math.round(current.width / targetRatio) };
50
+ }
31
51
  /**
32
52
  * Check if an error is related to missing activeTab permission for recording.
33
53
  */
34
54
  function isActiveTabPermissionError(error) {
35
- return error.includes('Extension has not been invoked') ||
55
+ return (error.includes('Extension has not been invoked') ||
36
56
  error.includes('activeTab') ||
37
- error.includes('enable recording');
57
+ error.includes('enable recording'));
58
+ }
59
+ function resolveRecordingTargetPage(options) {
60
+ return options.ghostCursorController.resolveRecordingTargetPage({
61
+ context: options.context,
62
+ defaultPage: options.defaultPage,
63
+ target: options.target,
64
+ });
65
+ }
66
+ function withRecordingDefaults(options) {
67
+ const { relayPort, defaultPage, fn } = options;
68
+ return async (input = {}) => {
69
+ const targetPage = input.page || defaultPage;
70
+ const sessionId = input.sessionId || targetPage.sessionId() || undefined;
71
+ return fn({ page: targetPage, sessionId, relayPort, ...input });
72
+ };
73
+ }
74
+ export function createRecordingApi(options) {
75
+ const { context, defaultPage, relayPort, ghostCursorController, onStart, onFinish, getExecutionTimestamps } = options;
76
+ // Stores the original viewport before aspect-ratio resize so we can restore on stop/cancel
77
+ let preRecordingViewport = null;
78
+ // Auto-stop timer to prevent unbounded recordings
79
+ let maxDurationTimer = null;
80
+ const startWithDefaults = withRecordingDefaults({
81
+ relayPort,
82
+ defaultPage,
83
+ fn: startRecording,
84
+ });
85
+ const stopWithDefaults = withRecordingDefaults({
86
+ relayPort,
87
+ defaultPage,
88
+ fn: stopRecording,
89
+ });
90
+ const isRecordingWithDefaults = async (opts = {}) => {
91
+ const targetPage = opts.page || defaultPage;
92
+ const sessionId = opts.sessionId || targetPage.sessionId() || undefined;
93
+ return isRecording({ page: targetPage, sessionId, relayPort });
94
+ };
95
+ const cancelWithDefaults = async (opts = {}) => {
96
+ const targetPage = opts.page || defaultPage;
97
+ const sessionId = opts.sessionId || targetPage.sessionId() || undefined;
98
+ await cancelRecording({ page: targetPage, sessionId, relayPort });
99
+ };
100
+ const start = async (opts) => {
101
+ const targetPage = resolveRecordingTargetPage({ context, defaultPage, ghostCursorController, target: opts });
102
+ // Resize viewport to target aspect ratio (default 16:9) before recording.
103
+ // Only shrinks — never increases width or height beyond current values.
104
+ const aspectRatio = opts?.aspectRatio === undefined ? DEFAULT_ASPECT_RATIO : opts.aspectRatio;
105
+ if (aspectRatio) {
106
+ const current = targetPage.viewportSize();
107
+ if (current) {
108
+ const fitted = fitToAspectRatio(current, aspectRatio);
109
+ if (fitted.width !== current.width || fitted.height !== current.height) {
110
+ preRecordingViewport = current;
111
+ await targetPage.setViewportSize(fitted);
112
+ }
113
+ }
114
+ }
115
+ const result = await startWithDefaults(opts);
116
+ onStart();
117
+ await ghostCursorController.enableForRecording({ page: targetPage });
118
+ // Schedule auto-stop to prevent unbounded recordings filling disk.
119
+ // Default 15 min. Set maxDurationMs to 0 or Infinity to disable.
120
+ const maxMs = opts?.maxDurationMs ?? DEFAULT_MAX_DURATION_MS;
121
+ if (maxMs > 0 && maxMs < Infinity) {
122
+ maxDurationTimer = setTimeout(() => {
123
+ maxDurationTimer = null;
124
+ stop(opts ? { page: opts.page, sessionId: opts.sessionId } : undefined).catch(() => { });
125
+ }, maxMs);
126
+ }
127
+ return result;
128
+ };
129
+ const clearMaxDurationTimer = () => {
130
+ if (maxDurationTimer) {
131
+ clearTimeout(maxDurationTimer);
132
+ maxDurationTimer = null;
133
+ }
134
+ };
135
+ const restoreViewport = async (targetPage) => {
136
+ if (!preRecordingViewport) {
137
+ return;
138
+ }
139
+ const saved = preRecordingViewport;
140
+ preRecordingViewport = null;
141
+ await targetPage.setViewportSize(saved);
142
+ };
143
+ const stop = async (opts) => {
144
+ clearMaxDurationTimer();
145
+ const targetPage = resolveRecordingTargetPage({ context, defaultPage, ghostCursorController, target: opts });
146
+ const result = await stopWithDefaults(opts);
147
+ const executionTimestamps = [...getExecutionTimestamps()];
148
+ onFinish();
149
+ await ghostCursorController.disableForRecording({ page: targetPage });
150
+ await restoreViewport(targetPage);
151
+ return { ...result, executionTimestamps };
152
+ };
153
+ const cancel = async (opts) => {
154
+ clearMaxDurationTimer();
155
+ const targetPage = resolveRecordingTargetPage({ context, defaultPage, ghostCursorController, target: opts });
156
+ await cancelWithDefaults(opts);
157
+ onFinish();
158
+ await ghostCursorController.disableForRecording({ page: targetPage });
159
+ await restoreViewport(targetPage);
160
+ };
161
+ return {
162
+ start,
163
+ stop,
164
+ isRecording: isRecordingWithDefaults,
165
+ cancel,
166
+ };
38
167
  }
39
168
  /**
40
169
  * Start recording the page.
@@ -48,9 +177,16 @@ export async function startRecording(options) {
48
177
  const response = await fetch(`http://127.0.0.1:${relayPort}/recording/start`, {
49
178
  method: 'POST',
50
179
  headers: { 'Content-Type': 'application/json' },
51
- body: JSON.stringify({ sessionId, frameRate, videoBitsPerSecond, audioBitsPerSecond, audio, outputPath: absoluteOutputPath }),
180
+ body: JSON.stringify({
181
+ sessionId,
182
+ frameRate,
183
+ videoBitsPerSecond,
184
+ audioBitsPerSecond,
185
+ audio,
186
+ outputPath: absoluteOutputPath,
187
+ }),
52
188
  });
53
- const result = await response.json();
189
+ const result = (await response.json());
54
190
  if (!result.success) {
55
191
  const errorMsg = result.error || 'Unknown error';
56
192
  // If the error is about missing activeTab permission, provide helpful guidance
@@ -81,7 +217,7 @@ export async function stopRecording(options) {
81
217
  headers: { 'Content-Type': 'application/json' },
82
218
  body: JSON.stringify({ sessionId }),
83
219
  });
84
- const result = await response.json();
220
+ const result = (await response.json());
85
221
  if (!result.success) {
86
222
  throw new Error(`Failed to stop recording: ${result.error}`);
87
223
  }
@@ -92,11 +228,12 @@ export async function stopRecording(options) {
92
228
  */
93
229
  export async function isRecording(options) {
94
230
  const { sessionId, relayPort = 19988 } = options;
95
- const url = sessionId
96
- ? `http://127.0.0.1:${relayPort}/recording/status?sessionId=${encodeURIComponent(sessionId)}`
97
- : `http://127.0.0.1:${relayPort}/recording/status`;
98
- const response = await fetch(url);
99
- const result = await response.json();
231
+ const url = new URL(`http://127.0.0.1:${relayPort}/recording/status`);
232
+ if (sessionId) {
233
+ url.searchParams.set('sessionId', sessionId);
234
+ }
235
+ const response = await fetch(url.toString());
236
+ const result = (await response.json());
100
237
  return { isRecording: result.isRecording, startedAt: result.startedAt, tabId: result.tabId };
101
238
  }
102
239
  /**
@@ -109,7 +246,7 @@ export async function cancelRecording(options) {
109
246
  headers: { 'Content-Type': 'application/json' },
110
247
  body: JSON.stringify({ sessionId }),
111
248
  });
112
- const result = await response.json();
249
+ const result = (await response.json());
113
250
  if (!result.success) {
114
251
  throw new Error(`Failed to cancel recording: ${result.error}`);
115
252
  }
@@ -1 +1 @@
1
- {"version":3,"file":"screen-recording.js","sourceRoot":"","sources":["../src/screen-recording.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAQ5B,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAA;IAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iCAAiC,CAAA;IAEvH,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,wFAAwF,KAAK,EAAE,CAAA;IACxG,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,gEAAgE,KAAK,EAAE,CAAA;IAChF,CAAC;IACD,QAAQ;IACR,OAAO,wCAAwC,KAAK,EAAE,CAAA;AACxD,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CAAC,KAAa;IAC/C,OAAO,KAAK,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAChD,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC3B,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;AAC3C,CAAC;AAoCD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IACjE,MAAM,EACJ,SAAS,EACT,SAAS,GAAG,EAAE,EACd,kBAAkB,GAAG,OAAO,EAC5B,kBAAkB,GAAG,MAAM,EAC3B,KAAK,GAAG,KAAK,EACb,UAAU,EACV,SAAS,GAAG,KAAK,GAClB,GAAG,OAAO,CAAA;IAEX,6DAA6D;IAC7D,sEAAsE;IACtE,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAEnD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,SAAS,kBAAkB,EAAE;QAC5E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;KAC9H,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA0B,CAAA;IAE5D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,eAAe,CAAA;QAEhD,+EAA+E;QAC/E,IAAI,0BAA0B,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,uBAAuB,EAAE,CAAA;YAC5C,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,MAAM;gBAC5C,yEAAyE;gBACzE,wEAAwE;gBACxE,KAAK,UAAU,MAAM;gBACrB,6EAA6E,CAC9E,CAAA;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO;QACL,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAEhD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,SAAS,iBAAiB,EAAE;QAC3E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;KACpC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,CAAA;IAE3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC9D,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA+D;IAC/F,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAEhD,MAAM,GAAG,GAAG,SAAS;QACnB,CAAC,CAAC,oBAAoB,SAAS,+BAA+B,kBAAkB,CAAC,SAAS,CAAC,EAAE;QAC7F,CAAC,CAAC,oBAAoB,SAAS,mBAAmB,CAAA;IACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAuB,CAAA;IAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;AAC9F,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA+D;IACnG,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAEhD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,SAAS,mBAAmB,EAAE;QAC7E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;KACpC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA2B,CAAA;IAE7D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAChE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"screen-recording.js","sourceRoot":"","sources":["../src/screen-recording.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=screen-recording.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-recording.test.d.ts","sourceRoot":"","sources":["../src/screen-recording.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Unit tests for fitToAspectRatio — verifies viewport shrink-to-fit
3
+ * for common screen sizes and aspect ratios.
4
+ */
5
+ import { describe, test, expect } from 'vitest';
6
+ import { fitToAspectRatio } from './screen-recording.js';
7
+ describe('fitToAspectRatio', () => {
8
+ test('common sizes → 16:9', () => {
9
+ const ratio = { width: 16, height: 9 };
10
+ // Already 16:9 — no change
11
+ expect(fitToAspectRatio({ width: 1920, height: 1080 }, ratio)).toMatchInlineSnapshot(`
12
+ {
13
+ "height": 1080,
14
+ "width": 1920,
15
+ }
16
+ `);
17
+ expect(fitToAspectRatio({ width: 1280, height: 720 }, ratio)).toMatchInlineSnapshot(`
18
+ {
19
+ "height": 720,
20
+ "width": 1280,
21
+ }
22
+ `);
23
+ // 16:10 (MacBook default) — too tall, shrink height
24
+ expect(fitToAspectRatio({ width: 1440, height: 900 }, ratio)).toMatchInlineSnapshot(`
25
+ {
26
+ "height": 810,
27
+ "width": 1440,
28
+ }
29
+ `);
30
+ expect(fitToAspectRatio({ width: 1680, height: 1050 }, ratio)).toMatchInlineSnapshot(`
31
+ {
32
+ "height": 945,
33
+ "width": 1680,
34
+ }
35
+ `);
36
+ // 4:3 — too tall, shrink height
37
+ expect(fitToAspectRatio({ width: 1024, height: 768 }, ratio)).toMatchInlineSnapshot(`
38
+ {
39
+ "height": 576,
40
+ "width": 1024,
41
+ }
42
+ `);
43
+ // Ultra-wide 21:9 — too wide, shrink width
44
+ expect(fitToAspectRatio({ width: 2560, height: 1080 }, ratio)).toMatchInlineSnapshot(`
45
+ {
46
+ "height": 1080,
47
+ "width": 1920,
48
+ }
49
+ `);
50
+ expect(fitToAspectRatio({ width: 3440, height: 1440 }, ratio)).toMatchInlineSnapshot(`
51
+ {
52
+ "height": 1440,
53
+ "width": 2560,
54
+ }
55
+ `);
56
+ // Square — too tall, shrink height
57
+ expect(fitToAspectRatio({ width: 1000, height: 1000 }, ratio)).toMatchInlineSnapshot(`
58
+ {
59
+ "height": 563,
60
+ "width": 1000,
61
+ }
62
+ `);
63
+ });
64
+ test('custom aspect ratios', () => {
65
+ // 4:3
66
+ expect(fitToAspectRatio({ width: 1920, height: 1080 }, { width: 4, height: 3 })).toMatchInlineSnapshot(`
67
+ {
68
+ "height": 1080,
69
+ "width": 1440,
70
+ }
71
+ `);
72
+ // 1:1
73
+ expect(fitToAspectRatio({ width: 1920, height: 1080 }, { width: 1, height: 1 })).toMatchInlineSnapshot(`
74
+ {
75
+ "height": 1080,
76
+ "width": 1080,
77
+ }
78
+ `);
79
+ // 9:16 vertical
80
+ expect(fitToAspectRatio({ width: 1920, height: 1080 }, { width: 9, height: 16 })).toMatchInlineSnapshot(`
81
+ {
82
+ "height": 1080,
83
+ "width": 608,
84
+ }
85
+ `);
86
+ });
87
+ test('never increases dimensions', () => {
88
+ const ratio = { width: 16, height: 9 };
89
+ const sizes = [
90
+ { width: 800, height: 600 },
91
+ { width: 1440, height: 900 },
92
+ { width: 2560, height: 1080 },
93
+ { width: 1000, height: 1000 },
94
+ ];
95
+ for (const size of sizes) {
96
+ const result = fitToAspectRatio(size, ratio);
97
+ expect(result.width).toBeLessThanOrEqual(size.width);
98
+ expect(result.height).toBeLessThanOrEqual(size.height);
99
+ }
100
+ });
101
+ });
102
+ //# sourceMappingURL=screen-recording.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-recording.test.js","sourceRoot":"","sources":["../src/screen-recording.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC/B,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;QAEtC,2BAA2B;QAC3B,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpF,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKnF,CAAC,CAAA;QAEF,oDAAoD;QACpD,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKnF,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpF,CAAC,CAAA;QAEF,gCAAgC;QAChC,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKnF,CAAC,CAAA;QAEF,2CAA2C;QAC3C,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpF,CAAC,CAAA;QACF,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpF,CAAC,CAAA;QAEF,mCAAmC;QACnC,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAChC,MAAM;QACN,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKtG,CAAC,CAAA;QAEF,MAAM;QACN,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKtG,CAAC,CAAA;QAEF,gBAAgB;QAChB,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKvG,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACtC,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;QACtC,MAAM,KAAK,GAAG;YACZ,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;YAC3B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;YAC5B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;YAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;SAC9B,CAAA;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC5C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACpD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACxD,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -7373,6 +7373,6 @@ x-locator-editor.does-not-match {
7373
7373
  return asLocator2(lang, selector);
7374
7374
  }
7375
7375
 
7376
- // dist/_selector-generator-entry-97179-1771340082183.js
7376
+ // dist/_selector-generator-entry-64982-1773397884857.js
7377
7377
  globalThis.__selectorGenerator = { createSelectorGenerator, toLocator };
7378
7378
  })();