@codefilm/recorder 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/core/FilmRecorder.d.ts.map +1 -1
- package/dist/core/FilmRecorder.js +59 -48
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.umd.cjs +20 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -196,19 +196,21 @@ recorder.setElementPadding(1.2); // 20% margin around the element
|
|
|
196
196
|
recorder.setElementSelector(null);
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
To keep the recording box at a fixed size while it moves between targets, opt into
|
|
200
|
-
|
|
199
|
+
To keep the recording box at a fixed size while it moves between targets, opt into a
|
|
200
|
+
16:9 fixed region preset:
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
203
|
const recorder = new FilmRecorder({
|
|
204
|
-
fixedRecordingRegion: "
|
|
204
|
+
fixedRecordingRegion: "medium",
|
|
205
205
|
});
|
|
206
206
|
|
|
207
207
|
recorder.setElementSelector(".thread-thinking-status");
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
With `fixedRecordingRegion`, the SDK centers the fixed 16:9 capture box on the target
|
|
211
|
-
instead of expanding the box to fit the full element.
|
|
211
|
+
instead of expanding the box to fit the full element. Presets are linear 1.5x steps:
|
|
212
|
+
`"smallest-16:9"` is the compact 6-column box, `"medium"` is 9 columns, and `"large"`
|
|
213
|
+
is 14 columns. `"medium-16:9"` and `"large-16:9"` are accepted aliases.
|
|
212
214
|
|
|
213
215
|
### Iframe Recording Bridge
|
|
214
216
|
|
|
@@ -1485,7 +1487,7 @@ You can customize the recorder behavior by passing options:
|
|
|
1485
1487
|
| `enableShortcuts` | `boolean` | `true` | Bind key combinations (`Ctrl+J` / `Cmd+J` for record toggle, etc.). |
|
|
1486
1488
|
| `elementSelector` | `string \| null` | `null` | Query selector of the DOM element to track and record. |
|
|
1487
1489
|
| `elementPadding` | `number` | `1.1` | Proportional padding multiplier around the tracked element. |
|
|
1488
|
-
| `fixedRecordingRegion` | `"smallest-16:9" \| null` | `null` | Keep the capture box at
|
|
1490
|
+
| `fixedRecordingRegion` | `"smallest-16:9" \| "medium" \| "medium-16:9" \| "large" \| "large-16:9" \| null` | `null` | Keep the capture box at a fixed 16:9 grid size instead of auto-fitting elements. |
|
|
1489
1491
|
| `movePointerToSelector` | `string \| null` | `null` | CSS Selector to automatically run a simulated pointer zoom tour. |
|
|
1490
1492
|
| `pointerClassName` | `string` | `""` | Additional CSS class names applied to the virtual pointer element. |
|
|
1491
1493
|
| `pointerFillColor` | `string` | `"#ffffff"` | Six-digit hex fill color for the virtual pointer SVG. |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilmRecorder.d.ts","sourceRoot":"","sources":["../../src/core/FilmRecorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EAEV,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAKjB,mBAAmB,EACnB,aAAa,EAEb,eAAe,EACf,0BAA0B,EAE1B,uBAAuB,EACvB,oBAAoB,EAGpB,0BAA0B,EAC1B,oBAAoB,EACpB,sBAAsB,EACtB,6BAA6B,EAC7B,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAOjB,eAAO,MAAM,mBAAmB,EAAE,UAAU,EAM3C,CAAC;AAEF,eAAO,MAAM,IAAI,KAAK,CAAC;AACvB,eAAO,MAAM,YAAY,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FilmRecorder.d.ts","sourceRoot":"","sources":["../../src/core/FilmRecorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,18 +5,24 @@ const O = [
|
|
|
5
5
|
{ label: "Instagram Post (4:5)", w: 1080, h: 1350 },
|
|
6
6
|
{ label: "Instagram Reel / Story (9:16)", w: 1080, h: 1920 },
|
|
7
7
|
{ label: "TikTok (9:16)", w: 1080, h: 1920 }
|
|
8
|
-
], g = 24,
|
|
8
|
+
], g = 24, R = 6, z = {
|
|
9
|
+
"smallest-16:9": R,
|
|
10
|
+
medium: Math.round(R * 1.5),
|
|
11
|
+
"medium-16:9": Math.round(R * 1.5),
|
|
12
|
+
large: Math.round(R * 1.5 * 1.5),
|
|
13
|
+
"large-16:9": Math.round(R * 1.5 * 1.5)
|
|
14
|
+
}, B = 1e3, H = 12, N = 0.08, $ = 0.015, G = 3e3, _ = 500, A = 56, V = 2, j = "j", U = 12e4, W = 3e3, X = Object.freeze({
|
|
9
15
|
cps: 24,
|
|
10
16
|
jitter: 0.22,
|
|
11
17
|
punctuationPauseMs: 120,
|
|
12
18
|
mistakeRate: 0.012
|
|
13
|
-
}),
|
|
19
|
+
}), Q = Object.freeze({
|
|
14
20
|
cps: 24,
|
|
15
21
|
jitter: 0.22,
|
|
16
22
|
punctuationPauseMs: 120,
|
|
17
23
|
mistakeRate: 0.012
|
|
18
24
|
});
|
|
19
|
-
class
|
|
25
|
+
class J {
|
|
20
26
|
options;
|
|
21
27
|
listeners = /* @__PURE__ */ new Set();
|
|
22
28
|
state;
|
|
@@ -77,7 +83,7 @@ class Q {
|
|
|
77
83
|
overlays: e.overlays ?? [],
|
|
78
84
|
autoDownload: e.autoDownload ?? !0,
|
|
79
85
|
includeTimelineMetadata: e.includeTimelineMetadata ?? !1,
|
|
80
|
-
selectorTimeoutMs: e.selectorTimeoutMs ??
|
|
86
|
+
selectorTimeoutMs: e.selectorTimeoutMs ?? W,
|
|
81
87
|
typingDefaults: this.resolveTypingOptions(e.typingDefaults),
|
|
82
88
|
typingSeed: e.typingSeed ?? "",
|
|
83
89
|
onRecordingStart: e.onRecordingStart ?? (() => {
|
|
@@ -169,7 +175,7 @@ class Q {
|
|
|
169
175
|
}
|
|
170
176
|
// Grid and Aspect Helper Methods
|
|
171
177
|
computeGrid(e, t) {
|
|
172
|
-
const i = e / g, o = i * 9 / 16, n = Math.max(0, t -
|
|
178
|
+
const i = e / g, o = i * 9 / 16, n = Math.max(0, t - A), r = Math.max(1, Math.floor(n / o));
|
|
173
179
|
return { cellW: i, cellH: o, rows: r };
|
|
174
180
|
}
|
|
175
181
|
getAspectBox(e, t, i, o) {
|
|
@@ -185,14 +191,19 @@ class Q {
|
|
|
185
191
|
return { w: n, h: r };
|
|
186
192
|
}
|
|
187
193
|
getRecordingRegionBox(e, t, i, o) {
|
|
188
|
-
return this.options.fixedRecordingRegion
|
|
194
|
+
return this.options.fixedRecordingRegion ? this.getAspectBox(
|
|
195
|
+
16 / 9,
|
|
196
|
+
t,
|
|
197
|
+
i,
|
|
198
|
+
z[this.options.fixedRecordingRegion]
|
|
199
|
+
) : this.getAspectBox(e, t, i, o);
|
|
189
200
|
}
|
|
190
201
|
clampRect(e, t) {
|
|
191
202
|
const i = Math.min(g, Math.max(1, e.w)), o = Math.min(t, Math.max(1, e.h)), n = Math.min(g - i, Math.max(0, e.col)), r = Math.min(t - o, Math.max(0, e.row));
|
|
192
203
|
return { col: n, row: r, w: i, h: o };
|
|
193
204
|
}
|
|
194
205
|
centeredRectOnPoint(e, t, i, o, n) {
|
|
195
|
-
const { cellW: r, cellH: s, rows: a } = this.computeGrid(i, o), c = Math.max(0, t -
|
|
206
|
+
const { cellW: r, cellH: s, rows: a } = this.computeGrid(i, o), c = Math.max(0, t - A), h = Math.min(g - 1, Math.max(0, Math.floor(e / r))), d = Math.min(a - 1, Math.max(0, Math.floor(c / s))), { w: p, h: u } = this.getRecordingRegionBox(n, g, a, R);
|
|
196
207
|
return this.clampRect(
|
|
197
208
|
{
|
|
198
209
|
col: Math.round(h - p / 2 + 0.5),
|
|
@@ -217,10 +228,10 @@ class Q {
|
|
|
217
228
|
this.targetRect = { col: s, row: a, w: n, h: r };
|
|
218
229
|
};
|
|
219
230
|
handleMouseMove = (e) => {
|
|
220
|
-
this.state.mousePaused || this.options.elementSelector || (this.mousePosGlobal = { x: e.clientX, y: e.clientY }, Math.hypot(e.clientX - this.anchorX, e.clientY - this.anchorY) >
|
|
231
|
+
this.state.mousePaused || this.options.elementSelector || (this.mousePosGlobal = { x: e.clientX, y: e.clientY }, Math.hypot(e.clientX - this.anchorX, e.clientY - this.anchorY) > H && (this.armHold(e.clientX, e.clientY), this.zoomOutTimer && (clearTimeout(this.zoomOutTimer), this.zoomOutTimer = null)));
|
|
221
232
|
};
|
|
222
233
|
handleScrollOrWheel = () => {
|
|
223
|
-
this.options.elementSelector || (this.scrollPausedUntil = performance.now() +
|
|
234
|
+
this.options.elementSelector || (this.scrollPausedUntil = performance.now() + _, this.holdTimer && clearTimeout(this.holdTimer));
|
|
224
235
|
};
|
|
225
236
|
handleKeyDown = (e) => {
|
|
226
237
|
if (!(e.metaKey || e.ctrlKey)) return;
|
|
@@ -230,34 +241,34 @@ class Q {
|
|
|
230
241
|
armHold(e, t) {
|
|
231
242
|
this.holdTimer && clearTimeout(this.holdTimer), this.anchorX = e, this.anchorY = t, this.holdTimer = setTimeout(() => {
|
|
232
243
|
this.state.autoZoom && (this.state.pauseDuringScroll && performance.now() < this.scrollPausedUntil || (this.zoomToMouse(), this.scheduleIdleZoomOut()));
|
|
233
|
-
},
|
|
244
|
+
}, B);
|
|
234
245
|
}
|
|
235
246
|
scheduleIdleZoomOut() {
|
|
236
247
|
this.zoomOutTimer && clearTimeout(this.zoomOutTimer), this.zoomOutTimer = setTimeout(() => {
|
|
237
248
|
this.zoomOutTimer = null, !(!this.state.autoZoom || this.options.elementSelector) && (this.state.pauseDuringScroll && performance.now() < this.scrollPausedUntil || this.resetFullScreen());
|
|
238
|
-
},
|
|
249
|
+
}, G);
|
|
239
250
|
}
|
|
240
251
|
calculateElementRect(e, t = 1.1, i) {
|
|
241
252
|
if (typeof document > "u") return null;
|
|
242
253
|
const o = document.querySelector(e);
|
|
243
254
|
if (!o) return null;
|
|
244
|
-
const n = o.getBoundingClientRect(), r = window.innerWidth, s = window.innerHeight, a = this.computeGrid(r, s), c = n.left + n.width / 2, h = n.top + n.height / 2, d = c / a.cellW, p = (h -
|
|
255
|
+
const n = o.getBoundingClientRect(), r = window.innerWidth, s = window.innerHeight, a = this.computeGrid(r, s), c = n.left + n.width / 2, h = n.top + n.height / 2, d = c / a.cellW, p = (h - A) / a.cellH, u = n.width / a.cellW, m = n.height / a.cellH, l = i ?? this.state.resolution.w / this.state.resolution.h, f = a.cellH / a.cellW, v = l * f;
|
|
245
256
|
if (this.options.fixedRecordingRegion) {
|
|
246
|
-
const { w:
|
|
257
|
+
const { w: x, h: T } = this.getRecordingRegionBox(l, g, a.rows, R);
|
|
247
258
|
return this.clampRect(
|
|
248
259
|
{
|
|
249
|
-
col: d -
|
|
250
|
-
row: p -
|
|
251
|
-
w:
|
|
252
|
-
h:
|
|
260
|
+
col: d - x / 2,
|
|
261
|
+
row: p - T / 2,
|
|
262
|
+
w: x,
|
|
263
|
+
h: T
|
|
253
264
|
},
|
|
254
265
|
a.rows
|
|
255
266
|
);
|
|
256
267
|
}
|
|
257
268
|
const w = u * t, y = m * t;
|
|
258
269
|
let E = Math.max(w, y * v), b = E / v;
|
|
259
|
-
const
|
|
260
|
-
return this.clampRect({ col:
|
|
270
|
+
const P = d - E / 2, F = p - b / 2;
|
|
271
|
+
return this.clampRect({ col: P, row: F, w: E, h: b }, a.rows);
|
|
261
272
|
}
|
|
262
273
|
// Camera Zoom Loop
|
|
263
274
|
startCameraLoop() {
|
|
@@ -269,7 +280,7 @@ class Q {
|
|
|
269
280
|
);
|
|
270
281
|
r && (this.targetRect = r);
|
|
271
282
|
}
|
|
272
|
-
const t = this.targetRect, i = this.liveRect, n = t.w > i.w ? $ :
|
|
283
|
+
const t = this.targetRect, i = this.liveRect, n = t.w > i.w ? $ : N;
|
|
273
284
|
this.liveRect = {
|
|
274
285
|
col: i.col + (t.col - i.col) * n,
|
|
275
286
|
row: i.row + (t.row - i.row) * n,
|
|
@@ -537,7 +548,7 @@ class Q {
|
|
|
537
548
|
i.drawImage(
|
|
538
549
|
this.videoEl,
|
|
539
550
|
d.col * h.cellW * p,
|
|
540
|
-
(
|
|
551
|
+
(A + d.row * h.cellH) * u,
|
|
541
552
|
d.w * h.cellW * p,
|
|
542
553
|
d.h * h.cellH * u,
|
|
543
554
|
0,
|
|
@@ -806,19 +817,19 @@ class Q {
|
|
|
806
817
|
return u;
|
|
807
818
|
let w = 1;
|
|
808
819
|
if (!v && l > 0) {
|
|
809
|
-
const
|
|
810
|
-
|
|
820
|
+
const M = t[l - 1], C = f;
|
|
821
|
+
C === M && /[a-zA-Z0-9]/.test(C) ? w = 0.4 : /[a-zA-Z0-9]/.test(M) && /[a-zA-Z0-9]/.test(C) ? w = 0.75 : C === " " ? w = 1.5 : M === " " && /[a-zA-Z0-9]/.test(C) && (w = 1.25);
|
|
811
822
|
}
|
|
812
823
|
const y = /[A-Z]/.test(f), E = l > 0 && /[A-Z]/.test(t[l - 1]);
|
|
813
824
|
y && !E && !v && (w += 0.4);
|
|
814
|
-
const b = n(),
|
|
815
|
-
let
|
|
825
|
+
const b = n(), P = n(), F = Math.sqrt(-2 * Math.log(b || 1e-4)) * Math.cos(2 * Math.PI * P), x = Math.exp(F * c * 0.8);
|
|
826
|
+
let T = u * w * x;
|
|
816
827
|
if (!v && l > 0 && l % 18 === 0 && n() < 0.6) {
|
|
817
|
-
const
|
|
818
|
-
|
|
828
|
+
const M = u * (1.5 + n() * 2) * c;
|
|
829
|
+
T += M;
|
|
819
830
|
}
|
|
820
831
|
const k = Math.max(10, u * 0.25), L = u * 4;
|
|
821
|
-
return Math.min(L, Math.max(k,
|
|
832
|
+
return Math.min(L, Math.max(k, T));
|
|
822
833
|
};
|
|
823
834
|
for (let l = 0; l < t.length; l++) {
|
|
824
835
|
this.throwIfAborted(o);
|
|
@@ -986,7 +997,7 @@ class Q {
|
|
|
986
997
|
return t;
|
|
987
998
|
}
|
|
988
999
|
resolveTypingOptions(...e) {
|
|
989
|
-
const t = { ...
|
|
1000
|
+
const t = { ...X };
|
|
990
1001
|
for (const i of e)
|
|
991
1002
|
if (i)
|
|
992
1003
|
for (const o of Object.keys(i)) {
|
|
@@ -1077,7 +1088,7 @@ Suggested fix: Ensure the element is mounted in the DOM, or add a stable attribu
|
|
|
1077
1088
|
);
|
|
1078
1089
|
}
|
|
1079
1090
|
validateFilmScript(e) {
|
|
1080
|
-
const t =
|
|
1091
|
+
const t = q(e), i = [];
|
|
1081
1092
|
t.length === 0 && i.push({
|
|
1082
1093
|
line: 1,
|
|
1083
1094
|
scene: null,
|
|
@@ -1166,7 +1177,7 @@ ${t}`);
|
|
|
1166
1177
|
}
|
|
1167
1178
|
}
|
|
1168
1179
|
executeFilmScript(e, t = {}) {
|
|
1169
|
-
this.activeFilmTitle =
|
|
1180
|
+
this.activeFilmTitle = Y(e), this.timelineMetadata && !this.timelineMetadata.title && (this.timelineMetadata.title = this.activeFilmTitle);
|
|
1170
1181
|
const i = this.validateFilmScript(e);
|
|
1171
1182
|
if (!i.valid)
|
|
1172
1183
|
return Promise.reject(this.createScriptValidationError(i.diagnostics));
|
|
@@ -1401,11 +1412,11 @@ ${t}`);
|
|
|
1401
1412
|
this.destroyed = !0, this.cleanupEventListeners(), cancelAnimationFrame(this.cameraRafId), cancelAnimationFrame(this.renderRafId), this.holdTimer && clearTimeout(this.holdTimer), this.zoomOutTimer && clearTimeout(this.zoomOutTimer), this.state.recording ? this.stopRecording() : (this.stopCaptureStream(), this.restoreIgnoredElements()), this.pointerEl && this.pointerEl.parentNode && (this.pointerEl.parentNode.removeChild(this.pointerEl), this.pointerEl = null), this.overlays.forEach((e) => e.destroy()), this.overlays.clear(), this.tourRafId && cancelAnimationFrame(this.tourRafId), this.videoEl && this.videoEl.parentNode && this.videoEl.parentNode.removeChild(this.videoEl), this.canvasEl && this.canvasEl.parentNode && this.canvasEl.parentNode.removeChild(this.canvasEl), this.clearLastRecording(), this.listeners.clear();
|
|
1402
1413
|
}
|
|
1403
1414
|
}
|
|
1404
|
-
function
|
|
1415
|
+
function Y(S) {
|
|
1405
1416
|
const e = /\bfilm\s+"([^"]+)"/.exec(S);
|
|
1406
1417
|
return e ? e[1] : null;
|
|
1407
1418
|
}
|
|
1408
|
-
function
|
|
1419
|
+
function q(S) {
|
|
1409
1420
|
const e = [], t = /scene\s+"([^"]+)"\s+@(\d+(?:\.\d+)?)s\s*->\s*(\d+(?:\.\d+)?)s\s*\{/g;
|
|
1410
1421
|
let i;
|
|
1411
1422
|
for (; (i = t.exec(S)) !== null; ) {
|
|
@@ -1417,7 +1428,7 @@ function Y(S) {
|
|
|
1417
1428
|
u === "{" ? s++ : u === "}" && s--, a++;
|
|
1418
1429
|
}
|
|
1419
1430
|
const h = S.substring(c, a - 1), d = S.slice(0, i.index).split(`
|
|
1420
|
-
`).length, p =
|
|
1431
|
+
`).length, p = Z(h, d);
|
|
1421
1432
|
e.push({
|
|
1422
1433
|
name: o,
|
|
1423
1434
|
startTime: n,
|
|
@@ -1427,7 +1438,7 @@ function Y(S) {
|
|
|
1427
1438
|
}
|
|
1428
1439
|
return e;
|
|
1429
1440
|
}
|
|
1430
|
-
function
|
|
1441
|
+
function Z(S, e) {
|
|
1431
1442
|
const t = [], i = S.replace(/\/\/.*$/gm, (s) => " ".repeat(s.length)), o = (s, a) => {
|
|
1432
1443
|
Object.defineProperty(s, "sourceLine", {
|
|
1433
1444
|
value: a,
|
|
@@ -1486,19 +1497,19 @@ export {
|
|
|
1486
1497
|
g as COLS,
|
|
1487
1498
|
U as DEFAULT_COMPLETION_TIMEOUT_MS,
|
|
1488
1499
|
O as DEFAULT_RESOLUTIONS,
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1500
|
+
W as DEFAULT_SELECTOR_TIMEOUT_MS,
|
|
1501
|
+
J as FilmRecorder,
|
|
1502
|
+
A as HEADER_PX,
|
|
1503
|
+
B as HOLD_MS,
|
|
1504
|
+
H as HOLD_RADIUS_PX,
|
|
1505
|
+
Q as HUMAN_TYPING_PRESET,
|
|
1506
|
+
N as LERP_IN,
|
|
1496
1507
|
$ as LERP_OUT,
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1508
|
+
R as MIN_BOX_COLS,
|
|
1509
|
+
V as OUTLINE_PX,
|
|
1510
|
+
_ as SCROLL_PAUSE_MS,
|
|
1511
|
+
X as SDK_TYPING_DEFAULTS,
|
|
1501
1512
|
j as SHORTCUT_KEY,
|
|
1502
|
-
|
|
1503
|
-
|
|
1513
|
+
G as ZOOM_OUT_AFTER_MOVE_MS,
|
|
1514
|
+
q as parseFilmScript
|
|
1504
1515
|
};
|
package/dist/core/types.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export interface RecorderState {
|
|
|
68
68
|
executionState: "idle" | "executing" | "waiting" | "finalizing" | "finished" | "error";
|
|
69
69
|
currentScene: string | null;
|
|
70
70
|
}
|
|
71
|
-
export type FixedRecordingRegion = "smallest-16:9";
|
|
71
|
+
export type FixedRecordingRegion = "smallest-16:9" | "medium" | "medium-16:9" | "large" | "large-16:9";
|
|
72
72
|
export interface RecordingArtifact {
|
|
73
73
|
blob: Blob;
|
|
74
74
|
url: string;
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
(function(f,v){typeof exports=="object"&&typeof module<"u"?v(exports,require("react"),require("react/jsx-runtime"),require("@openai/agents"),require("openai")):typeof define=="function"&&define.amd?define(["exports","react","react/jsx-runtime","@openai/agents","openai"],v):(f=typeof globalThis<"u"?globalThis:f||self,v(f.CodeFilm={},f.React,f.React,f.OpenAIAgents,f.OpenAI))})(this,(function(f,v,g,A,Fe){"use strict";function Ie(i){return{type:"camera",...i}}function $e(i,e){return new Ne(i,e)}function Le(i,e){return new ze(i,e)}class Ne{id;element;includeInCapture=!0;videoEl;fallbackEl;resizeHandle;stream=null;visible=!1;position;size;minSize;maxSize;shape;draggable;resizable;mirror;requestOnShow;onEvent;constructor(e,t){this.id=e.id,this.position=e.position??"top-left",this.size=e.size??168,this.minSize=e.minSize??96,this.maxSize=e.maxSize??360,this.shape=e.shape??"circle",this.draggable=e.draggable??!0,this.resizable=e.resizable??!0,this.mirror=e.mirror??!0,this.requestOnShow=e.requestOnShow??!0,this.onEvent=t,this.element=document.createElement("div"),this.element.className=["cfr-recording-overlay","cfr-camera-overlay",e.className].filter(Boolean).join(" "),this.element.dataset.codeFilmOverlay=this.id,this.videoEl=document.createElement("video"),this.videoEl.muted=!0,this.videoEl.playsInline=!0,this.videoEl.autoplay=!0,this.fallbackEl=document.createElement("div"),this.fallbackEl.className="cfr-camera-overlay-fallback",this.fallbackEl.textContent="Camera unavailable",this.resizeHandle=document.createElement("div"),this.resizeHandle.className="cfr-recording-overlay-resize",this.element.append(this.videoEl,this.fallbackEl,this.resizeHandle),this.applyElementStyle(),this.installPointerHandlers(),(e.enabled??!1)&&this.show()}async requestPermission(){if(this.stream)return!0;try{if(!navigator.mediaDevices?.getUserMedia)throw new Error("Camera capture is not available in this browser.");return this.stream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1}),this.videoEl.srcObject=this.stream,this.fallbackEl.style.display="none",await this.videoEl.play().catch(()=>{}),!0}catch(e){return this.stopTracks(),this.fallbackEl.style.display="flex",this.emit("error",{message:e instanceof Error?e.message:String(e)}),!1}}async show(){this.mount(),this.visible=!0,this.element.style.display="block",this.requestOnShow&&await this.requestPermission(),this.emit("shown",this.snapshot())}hide(){this.visible=!1,this.element.style.display="none",this.stopTracks(),this.emit("hidden",this.snapshot())}moveTo(e){this.position=e,this.applyElementStyle(),this.emit("moved",this.snapshot())}setSize(e){this.size=U(e,this.minSize,this.maxSize),this.applyElementStyle(),this.emit("resized",this.snapshot())}destroy(){this.hide(),this.element.remove()}draw(e,t,r){if(!this.visible)return;const n=$(this.position,this.size,t,r);De(e,n.x,n.y,n.size,this.shape,()=>{this.stream&&this.videoEl.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA?this.mirror?(e.save(),e.translate(n.x+n.size,n.y),e.scale(-1,1),e.drawImage(this.videoEl,0,0,n.size,n.size),e.restore()):e.drawImage(this.videoEl,n.x,n.y,n.size,n.size):Be(e,n.x,n.y,n.size)})}mount(){typeof document>"u"||this.element.isConnected||document.body.appendChild(this.element)}applyElementStyle(){const e=$(this.position,this.size,typeof window>"u"?1280:window.innerWidth,typeof window>"u"?720:window.innerHeight);Object.assign(this.element.style,{display:this.visible?"block":"none",position:"fixed",left:`${e.x}px`,top:`${e.y}px`,width:`${e.size}px`,height:`${e.size}px`,borderRadius:this.shape==="circle"?"9999px":this.shape==="rounded"?"24px":"0",overflow:"hidden",zIndex:"2147483646",background:"#111827",boxShadow:"0 18px 55px rgba(0,0,0,0.32), 0 0 0 1px rgba(255,255,255,0.2)",touchAction:"none",cursor:this.draggable?"grab":"default"}),Object.assign(this.videoEl.style,{width:"100%",height:"100%",objectFit:"cover",transform:this.mirror?"scaleX(-1)":"none"}),this.resizeHandle.style.display=this.resizable?"block":"none"}installPointerHandlers(){let e=null;const t=o=>{const a=o.target===this.resizeHandle;!this.draggable&&!a||!this.resizable&&a||(o.preventDefault(),this.element.setPointerCapture(o.pointerId),e={type:a?"resize":"move",pointerId:o.pointerId,startX:o.clientX,startY:o.clientY,startPosition:this.position,startSize:this.size})},r=o=>{if(!e||e.pointerId!==o.pointerId)return;const a=o.clientX-e.startX,l=o.clientY-e.startY;if(e.type==="resize")this.setSize(e.startSize+Math.max(a,l));else{const s=$(e.startPosition,e.startSize,window.innerWidth,window.innerHeight);this.moveTo({x:s.x+a,y:s.y+l})}},n=o=>{!e||e.pointerId!==o.pointerId||(this.element.releasePointerCapture(o.pointerId),e=null)};this.element.addEventListener("pointerdown",t),this.element.addEventListener("pointermove",r),this.element.addEventListener("pointerup",n),this.element.addEventListener("pointercancel",n)}stopTracks(){this.stream?.getTracks().forEach(e=>e.stop()),this.stream=null,this.videoEl.srcObject=null}emit(e,t){this.onEvent?.({id:this.id,type:e,data:t})}snapshot(){return{position:this.position,size:this.size,shape:this.shape}}}class ze{id;element;includeInCapture;visible;position;size;trackTimeline;onEvent;constructor(e,t){this.id=e.id,this.element=e.element,this.includeInCapture=e.includeInCapture??!0,this.trackTimeline=e.trackTimeline??!0,this.visible=e.enabled??!0,this.position=e.position??"top-left",this.size=e.size??168,this.onEvent=t,e.optOutOfSdkStyles||(this.element.classList.add("cfr-recording-overlay"),e.className&&this.element.classList.add(...e.className.split(/\s+/)),this.element.dataset.codeFilmOverlay=this.id),this.applyElementStyle()}show(){this.visible=!0,this.element.style.display="",this.emit("shown",this.snapshot())}hide(){this.visible=!1,this.element.style.display="none",this.emit("hidden",this.snapshot())}moveTo(e){this.position=e,this.applyElementStyle(),this.emit("moved",this.snapshot())}setSize(e){this.size=Math.max(1,e),this.applyElementStyle(),this.emit("resized",this.snapshot())}destroy(){this.hide()}draw(e,t,r){if(!this.visible||!this.includeInCapture)return;const n=$(this.position,this.size,t,r);this.element instanceof HTMLCanvasElement?e.drawImage(this.element,n.x,n.y,n.size,n.size):(this.element instanceof HTMLImageElement||this.element instanceof HTMLVideoElement)&&e.drawImage(this.element,n.x,n.y,n.size,n.size)}applyElementStyle(){const e=$(this.position,this.size,typeof window>"u"?1280:window.innerWidth,typeof window>"u"?720:window.innerHeight);Object.assign(this.element.style,{position:"fixed",left:`${e.x}px`,top:`${e.y}px`,width:`${e.size}px`,height:`${e.size}px`,zIndex:"2147483646"})}emit(e,t){this.trackTimeline&&this.onEvent?.({id:this.id,type:e,data:t})}snapshot(){return{position:this.position,size:this.size}}}function $(i,e,t,r){if(typeof i=="object")return{x:U(i.x,0,Math.max(0,t-e)),y:U(i.y,0,Math.max(0,r-e)),size:e};const n=t-e-24,o=r-e-24;return{x:i.endsWith("right")?n:24,y:i.startsWith("bottom")?o:24,size:e}}function De(i,e,t,r,n,o){i.save(),n==="circle"?(i.beginPath(),i.arc(e+r/2,t+r/2,r/2,0,Math.PI*2),i.clip()):n==="rounded"&&(je(i,e,t,r,r,Math.min(24,r/5)),i.clip()),o(),i.restore()}function Be(i,e,t,r){i.save(),i.fillStyle="#111827",i.fillRect(e,t,r,r),i.fillStyle="#e5e7eb",i.font=`${Math.max(12,Math.round(r/12))}px system-ui, sans-serif`,i.textAlign="center",i.textBaseline="middle",i.fillText("Camera unavailable",e+r/2,t+r/2,r-20),i.restore()}function je(i,e,t,r,n,o){i.beginPath(),i.moveTo(e+o,t),i.lineTo(e+r-o,t),i.quadraticCurveTo(e+r,t,e+r,t+o),i.lineTo(e+r,t+n-o),i.quadraticCurveTo(e+r,t+n,e+r-o,t+n),i.lineTo(e+o,t+n),i.quadraticCurveTo(e,t+n,e,t+n-o),i.lineTo(e,t+o),i.quadraticCurveTo(e,t,e+o,t),i.closePath()}function U(i,e,t){return Math.min(t,Math.max(e,i))}const H=[{label:"YouTube HD (16:9)",w:1920,h:1080},{label:"Twitter / X (16:9)",w:1200,h:675},{label:"Instagram Post (4:5)",w:1080,h:1350},{label:"Instagram Reel / Story (9:16)",w:1080,h:1920},{label:"TikTok (9:16)",w:1080,h:1920}],b=24,B=6,_e=1e3,qe=12,Ue=.08,He=.015,Ge=3e3,We=500,P=56,O=2,L="j",te=12e4,ie=3e3,re=Object.freeze({cps:24,jitter:.22,punctuationPauseMs:120,mistakeRate:.012}),Ze=Object.freeze({cps:24,jitter:.22,punctuationPauseMs:120,mistakeRate:.012});class ne{options;listeners=new Set;state;videoEl;canvasEl;recorder=null;stream=null;chunks=[];lastRecording=null;lastRecordingError=null;recordingStartedAt=0;timelineMetadata=null;activeFilmTitle=null;destroyed=!1;cameraRafId=0;renderRafId=0;targetRect;liveRect;mousePosGlobal={x:0,y:0};holdTimer=null;zoomOutTimer=null;scrollPausedUntil=0;anchorX=0;anchorY=0;pointerEl=null;pointerX=0;pointerY=0;tourRafId=0;tourAbortController=null;activeFilmScriptContext=null;activeFilmScriptOptions=null;activeExecutionPromise=null;finalizationPromise=null;pendingActionGates=[];activeTypingRandom=Math.random;ignoredElements=new Map;overlays=new Map;constructor(e={}){const t={fps:e.fps??60,resolutions:e.resolutions??H,defaultResolutionIndex:e.defaultResolutionIndex??0,autoZoom:e.autoZoom??!0,pauseDuringScroll:e.pauseDuringScroll??!0,showGrid:e.showGrid??!0,showOutline:e.showOutline??!1,enableShortcuts:e.enableShortcuts??!0,elementSelector:e.elementSelector??null,elementPadding:e.elementPadding??1.1,fixedRecordingRegion:e.fixedRecordingRegion??null,movePointerToSelector:e.movePointerToSelector??null,pointerClassName:e.pointerClassName??"",pointerFillColor:e.pointerFillColor??"#ffffff",pointerBorderColor:e.pointerBorderColor??"#18181b",pointerRippleColor:e.pointerRippleColor??"#64748b",disableRipple:e.disableRipple??!1,ignoreSelector:e.ignoreSelector??null,overlays:e.overlays??[],autoDownload:e.autoDownload??!0,includeTimelineMetadata:e.includeTimelineMetadata??!1,selectorTimeoutMs:e.selectorTimeoutMs??ie,typingDefaults:this.resolveTypingOptions(e.typingDefaults),typingSeed:e.typingSeed??"",onRecordingStart:e.onRecordingStart??(()=>{}),onRecordingStop:e.onRecordingStop??(()=>{}),onRecordingError:e.onRecordingError??(()=>{}),onTourStart:e.onTourStart??(()=>{}),onTourStop:e.onTourStop??(()=>{}),onReadyToEnd:e.onReadyToEnd??(()=>{}),onTourError:e.onTourError??(()=>{}),onSceneStart:e.onSceneStart??(()=>{}),onSceneEnd:e.onSceneEnd??(()=>{}),onActionStart:e.onActionStart??(()=>{}),onActionEnd:e.onActionEnd??(()=>{})};this.options=t;const r=this.options.resolutions[this.options.defaultResolutionIndex]||H[0],n={w:typeof window<"u"?window.innerWidth:1280,h:typeof window<"u"?window.innerHeight:720},o=this.computeGrid(n.w,n.h);let a;if(this.options.elementSelector){const l=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding,r.w/r.h);if(l)a=l;else{const s=this.getRecordingRegionBox(r.w/r.h,b,o.rows,b),u=Math.floor((b-s.w)/2),c=Math.floor((o.rows-s.h)/2);a={col:u,row:c,w:s.w,h:s.h}}}else{const l=this.getRecordingRegionBox(r.w/r.h,b,o.rows,b),s=Math.floor((b-l.w)/2),u=Math.floor((o.rows-l.h)/2);a={col:s,row:u,w:l.w,h:l.h}}this.targetRect={col:a.col,row:a.row,w:a.w,h:a.h},this.liveRect={...this.targetRect},this.state={recording:!1,showGrid:this.options.showGrid,autoZoom:this.options.autoZoom,pauseDuringScroll:this.options.pauseDuringScroll,resolution:r,mousePaused:!1,viewport:n,displayRect:{...this.liveRect},showOutline:this.options.showOutline,elementSelector:this.options.elementSelector,elementPadding:this.options.elementPadding,fixedRecordingRegion:this.options.fixedRecordingRegion,movePointerToSelector:this.options.movePointerToSelector,pointerClassName:this.options.pointerClassName,pointerFillColor:this.options.pointerFillColor,pointerBorderColor:this.options.pointerBorderColor,pointerRippleColor:this.options.pointerRippleColor,disableRipple:this.options.disableRipple,ignoreSelector:this.options.ignoreSelector,tourState:"idle",executionState:"idle",currentScene:null},typeof window<"u"?(this.videoEl=document.createElement("video"),this.videoEl.muted=!0,this.videoEl.playsInline=!0,this.videoEl.style.display="none",document.body.appendChild(this.videoEl),this.canvasEl=document.createElement("canvas"),this.canvasEl.style.display="none",document.body.appendChild(this.canvasEl),this.setupEventListeners(),this.startCameraLoop(),this.options.overlays.forEach(l=>{l.type==="camera"&&this.createCameraOverlay(l)})):(this.videoEl={},this.canvasEl={})}computeGrid(e,t){const r=e/b,n=r*9/16,o=Math.max(0,t-P),a=Math.max(1,Math.floor(o/n));return{cellW:r,cellH:n,rows:a}}getAspectBox(e,t,r,n){let o=1,a=1,l=1/0;const s=Math.min(t,n);for(let u=1;u<=s;u++){const c=u*16/(9*e),d=[Math.floor(c),Math.ceil(c)].filter(h=>h>=1&&h<=r);for(const h of d){const m=u/h*1.7777777777777777,y=Math.abs(m-e);(y<l-1e-6||Math.abs(y-l)<1e-6&&u>o)&&(l=y,o=u,a=h)}}return{w:o,h:a}}getRecordingRegionBox(e,t,r,n){return this.options.fixedRecordingRegion==="smallest-16:9"?this.getAspectBox(16/9,t,r,B):this.getAspectBox(e,t,r,n)}clampRect(e,t){const r=Math.min(b,Math.max(1,e.w)),n=Math.min(t,Math.max(1,e.h)),o=Math.min(b-r,Math.max(0,e.col)),a=Math.min(t-n,Math.max(0,e.row));return{col:o,row:a,w:r,h:n}}centeredRectOnPoint(e,t,r,n,o){const{cellW:a,cellH:l,rows:s}=this.computeGrid(r,n),u=Math.max(0,t-P),c=Math.min(b-1,Math.max(0,Math.floor(e/a))),d=Math.min(s-1,Math.max(0,Math.floor(u/l))),{w:h,h:m}=this.getRecordingRegionBox(o,b,s,B);return this.clampRect({col:Math.round(c-h/2+.5),row:Math.round(d-m/2+.5),w:h,h:m},s)}setupEventListeners(){window.addEventListener("resize",this.handleResize),window.addEventListener("mousemove",this.handleMouseMove),window.addEventListener("wheel",this.handleScrollOrWheel,{passive:!0}),window.addEventListener("scroll",this.handleScrollOrWheel,{passive:!0}),this.options.enableShortcuts&&window.addEventListener("keydown",this.handleKeyDown)}cleanupEventListeners(){window.removeEventListener("resize",this.handleResize),window.removeEventListener("mousemove",this.handleMouseMove),window.removeEventListener("wheel",this.handleScrollOrWheel),window.removeEventListener("scroll",this.handleScrollOrWheel),window.removeEventListener("keydown",this.handleKeyDown)}handleResize=()=>{const e=window.innerWidth,t=window.innerHeight;if(this.updateState({viewport:{w:e,h:t}}),this.options.elementSelector)return;const r=this.computeGrid(e,t),n=this.state.resolution.w/this.state.resolution.h,{w:o,h:a}=this.getRecordingRegionBox(n,b,r.rows,b),l=Math.floor((b-o)/2),s=Math.floor((r.rows-a)/2);this.targetRect={col:l,row:s,w:o,h:a}};handleMouseMove=e=>{this.state.mousePaused||this.options.elementSelector||(this.mousePosGlobal={x:e.clientX,y:e.clientY},Math.hypot(e.clientX-this.anchorX,e.clientY-this.anchorY)>qe&&(this.armHold(e.clientX,e.clientY),this.zoomOutTimer&&(clearTimeout(this.zoomOutTimer),this.zoomOutTimer=null)))};handleScrollOrWheel=()=>{this.options.elementSelector||(this.scrollPausedUntil=performance.now()+We,this.holdTimer&&clearTimeout(this.holdTimer))};handleKeyDown=e=>{if(!(e.metaKey||e.ctrlKey))return;const r=e.key.toLowerCase();r===L?(e.preventDefault(),this.state.recording?this.stopRecording():this.startRecording()):r==="l"?(e.preventDefault(),this.setMousePaused(!this.state.mousePaused)):e.key==="ArrowUp"?(e.preventDefault(),this.options.elementSelector?this.setElementSelector(null):this.zoomTop()):e.key==="ArrowDown"&&(e.preventDefault(),this.options.elementSelector||this.zoomBottom())};armHold(e,t){this.holdTimer&&clearTimeout(this.holdTimer),this.anchorX=e,this.anchorY=t,this.holdTimer=setTimeout(()=>{this.state.autoZoom&&(this.state.pauseDuringScroll&&performance.now()<this.scrollPausedUntil||(this.zoomToMouse(),this.scheduleIdleZoomOut()))},_e)}scheduleIdleZoomOut(){this.zoomOutTimer&&clearTimeout(this.zoomOutTimer),this.zoomOutTimer=setTimeout(()=>{this.zoomOutTimer=null,!(!this.state.autoZoom||this.options.elementSelector)&&(this.state.pauseDuringScroll&&performance.now()<this.scrollPausedUntil||this.resetFullScreen())},Ge)}calculateElementRect(e,t=1.1,r){if(typeof document>"u")return null;const n=document.querySelector(e);if(!n)return null;const o=n.getBoundingClientRect(),a=window.innerWidth,l=window.innerHeight,s=this.computeGrid(a,l),u=o.left+o.width/2,c=o.top+o.height/2,d=u/s.cellW,h=(c-P)/s.cellH,m=o.width/s.cellW,y=o.height/s.cellH,p=r??this.state.resolution.w/this.state.resolution.h,w=s.cellH/s.cellW,E=p*w;if(this.options.fixedRecordingRegion){const{w:q,h:N}=this.getRecordingRegionBox(p,b,s.rows,B);return this.clampRect({col:d-q/2,row:h-N/2,w:q,h:N},s.rows)}const S=m*t,T=y*t;let R=Math.max(S,T*E),M=R/E;const Q=d-R/2,ee=h-M/2;return this.clampRect({col:Q,row:ee,w:R,h:M},s.rows)}startCameraLoop(){const e=()=>{if(this.options.elementSelector){const a=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding);a&&(this.targetRect=a)}const t=this.targetRect,r=this.liveRect,o=t.w>r.w?He:Ue;this.liveRect={col:r.col+(t.col-r.col)*o,row:r.row+(t.row-r.row)*o,w:r.w+(t.w-r.w)*o,h:r.h+(t.h-r.h)*o},this.updateState({displayRect:{...this.liveRect}}),this.cameraRafId=requestAnimationFrame(e)};this.cameraRafId=requestAnimationFrame(e)}zoomToMouse(){const e=this.state.resolution.w/this.state.resolution.h;this.targetRect=this.centeredRectOnPoint(this.mousePosGlobal.x,this.mousePosGlobal.y,window.innerWidth,window.innerHeight,e)}getFullFrameRect(e){const t=this.state.resolution.w/this.state.resolution.h,r=this.computeGrid(window.innerWidth,window.innerHeight),{w:n,h:o}=this.getRecordingRegionBox(t,b,r.rows,b),a=e==="top"?0:e==="bottom"?r.rows-o:Math.floor((r.rows-o)/2);return{col:Math.floor((b-n)/2),row:a,w:n,h:o}}setFullFrameRect(e,t=!1){const r=this.getFullFrameRect(e);this.targetRect=r,t&&(this.liveRect={...r},this.updateState({displayRect:{...r}}))}zoomTop(e=!1){this.setFullFrameRect("top",e)}zoomCenter(e=!1){this.setFullFrameRect("center",e)}zoomBottom(e=!1){this.setFullFrameRect("bottom",e)}zoomBottomFold(){this.zoomBottom()}zoomTopFold(e=!1){this.zoomTop(e)}resetFullScreen(){this.zoomCenter()}zoomTopFullFrame(e=!1){this.zoomTop(e)}getRecordingElapsedMs(){return this.recordingStartedAt?Math.max(0,Math.round(performance.now()-this.recordingStartedAt)):0}beginTimelineMetadata(){if(!this.options.includeTimelineMetadata){this.timelineMetadata=null;return}this.timelineMetadata={schema:"code-film.timeline.v1",title:this.activeFilmTitle,fps:this.options.fps,width:this.state.resolution.w,height:this.state.resolution.h,scenes:[],actions:[],markers:[]},this.recordTimelineMarker("recording:start")}finishTimelineMetadata(){if(this.timelineMetadata)return this.recordTimelineMarker("recording:stop"),{...this.timelineMetadata,scenes:this.timelineMetadata.scenes.map(e=>({...e})),actions:this.timelineMetadata.actions.map(e=>({...e})),markers:this.timelineMetadata.markers.map(e=>({...e}))}}recordTimelineMarker(e,t={}){this.timelineMetadata&&this.timelineMetadata.markers.push({timeMs:this.getRecordingElapsedMs(),name:e,...t})}recordOverlayEvent(e){this.recordTimelineMarker(`overlay:${e.type}`,{data:{id:e.id,...e.data}})}renderRecordingOverlays(e){this.overlays.forEach(t=>{t.includeInCapture&&t.draw(e,this.state.resolution.w,this.state.resolution.h)})}createCameraOverlay(e){if(typeof document>"u")throw new Error("[FilmRecorder] createCameraOverlay requires a browser document.");const t=$e(e,r=>{this.recordOverlayEvent(r)});return this.overlays.set(t.id,t),t}registerOverlay(e){if(typeof document>"u")throw new Error("[FilmRecorder] registerOverlay requires a browser document.");const t=Le(e,r=>{this.recordOverlayEvent(r)});return this.overlays.set(t.id,t),t}getOverlay(e){return this.overlays.get(e)??null}removeOverlay(e){const t=this.overlays.get(e);t&&(t.destroy(),this.overlays.delete(e))}setOverlays(e){this.overlays.forEach(t=>t.destroy()),this.overlays.clear(),e.forEach(t=>{t.type==="camera"&&this.createCameraOverlay(t)})}startTimelineScene(e,t){if(!this.timelineMetadata)return null;const r={id:`scene-${t+1}`,name:e.name,declaredStartMs:Math.round(e.startTime*1e3),declaredEndMs:Math.round(e.endTime*1e3),actualStartMs:this.getRecordingElapsedMs(),actualEndMs:null};return this.timelineMetadata.scenes.push(r),this.recordTimelineMarker("scene:start",{data:{label:e.name},scene:e.name}),r}endTimelineScene(e){e&&(e.actualEndMs=this.getRecordingElapsedMs(),this.recordTimelineMarker("scene:end",{data:{label:e.name},scene:e.name}))}startTimelineAction(e,t,r){if(!this.timelineMetadata||!e)return null;const n={type:t.type,startMs:this.getRecordingElapsedMs(),endMs:null,commandIndex:r,scene:e.name,selector:t.selector,to:t.to,padding:t.padding,text:t.text,durationMs:t.durationMs};return this.timelineMetadata.actions.push(n),this.recordTimelineMarker(`command:${t.type}:start`,{data:{label:t.selector??t.to??t.text??t.type},scene:e.name,commandIndex:r}),n}endTimelineAction(e,t){!e||!t||(t.endMs=this.getRecordingElapsedMs(),this.recordTimelineMarker(`command:${t.type}:end`,{data:{label:t.selector??t.to??t.text??t.type},scene:e.name,commandIndex:t.commandIndex}))}getLastRecording(){return this.lastRecording}clearLastRecording(){this.lastRecording&&(URL.revokeObjectURL(this.lastRecording.url),this.lastRecording=null)}getLastRecordingError(){return this.lastRecordingError}normalizeRecordingError(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown recording error")}handleRecordingError(e){const t=this.normalizeRecordingError(e);return this.lastRecordingError=t,this.updateState({showGrid:this.options.showGrid}),this.options.onRecordingError?.(t),t}async requestCaptureStream(){return navigator.mediaDevices.getDisplayMedia({video:{frameRate:this.options.fps,width:{ideal:3840},height:{ideal:2160}},audio:!0,preferCurrentTab:!0})}async attachCaptureStream(e){this.stream=e,this.videoEl.srcObject=e,await this.videoEl.play(),await this.waitForCaptureVideoFrame()}async waitForCaptureVideoFrame(e=3e3){this.videoEl.videoWidth>0&&this.videoEl.videoHeight>0||await new Promise((t,r)=>{let n=0;const o=window.setTimeout(()=>{a(),r(new Error("Screen capture started, but no video frame was available."))},e),a=()=>{window.clearTimeout(o),n&&cancelAnimationFrame(n),this.videoEl.removeEventListener("loadedmetadata",l),this.videoEl.removeEventListener("canplay",l)},l=()=>{if(this.videoEl.videoWidth>0&&this.videoEl.videoHeight>0){a(),t();return}n=requestAnimationFrame(l)};this.videoEl.addEventListener("loadedmetadata",l),this.videoEl.addEventListener("canplay",l),l()})}stopCaptureStream(){this.stream?.getTracks().forEach(e=>e.stop()),this.stream=null,this.videoEl.srcObject=null}hideIgnoredElements(){this.restoreIgnoredElements(),!(!this.options.ignoreSelector||typeof document>"u")&&document.querySelectorAll(this.options.ignoreSelector).forEach(e=>{e instanceof HTMLElement&&(e.closest(".cfr-settings-bar, .cfr-recording-overlay")||(this.ignoredElements.set(e,{visibility:e.style.getPropertyValue("visibility"),priority:e.style.getPropertyPriority("visibility")}),e.style.setProperty("visibility","hidden","important")))})}restoreIgnoredElements(){this.ignoredElements.forEach((e,t)=>{t.style.setProperty("visibility",e.visibility,e.priority)}),this.ignoredElements.clear()}getActiveCaptureStream(){return this.stream&&this.stream.getTracks().some(e=>e.readyState==="live")?this.stream:null}async prepareCapture(){if(this.getActiveCaptureStream())return!0;try{const e=await this.requestCaptureStream();return await this.attachCaptureStream(e),this.lastRecordingError=null,!0}catch(e){throw this.stopCaptureStream(),this.handleRecordingError(e)}}async startRecording(){if(this.state.recording)return!1;try{const e=this.getActiveCaptureStream();e?await this.attachCaptureStream(e):await this.prepareCapture();const t=this.getActiveCaptureStream();if(!t)throw new Error("No active capture stream is available.");this.options.elementSelector&&(this.options.elementSelector=null,this.updateState({elementSelector:null})),this.zoomTopFullFrame(!0),this.resetPointerEntryPosition(),this.hideIgnoredElements(),this.updateState({showGrid:!1});const r=this.canvasEl.getContext("2d");r.imageSmoothingEnabled=!0,r.imageSmoothingQuality="high",this.canvasEl.width=this.state.resolution.w,this.canvasEl.height=this.state.resolution.h;const n=()=>{const s=window.innerWidth,u=window.innerHeight,c=this.computeGrid(s,u),d=this.liveRect,h=this.videoEl.videoWidth/s,m=this.videoEl.videoHeight/u;r.drawImage(this.videoEl,d.col*c.cellW*h,(P+d.row*c.cellH)*m,d.w*c.cellW*h,d.h*c.cellH*m,0,0,this.state.resolution.w,this.state.resolution.h),this.renderRecordingOverlays(r),this.renderRafId=requestAnimationFrame(n)};n();const o=this.canvasEl.captureStream(this.options.fps);t.getAudioTracks().forEach(s=>o.addTrack(s));const a=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"].find(s=>MediaRecorder.isTypeSupported(s)),l=new MediaRecorder(o,{...a&&{mimeType:a},videoBitsPerSecond:1e7});return this.chunks=[],this.recordingStartedAt=performance.now(),this.beginTimelineMetadata(),l.ondataavailable=s=>{s.data.size&&this.chunks.push(s.data)},l.onstop=()=>{const s=performance.now(),u=new Blob(this.chunks,{type:l.mimeType}),c=URL.createObjectURL(u),d=l.mimeType.includes("mp4")?"capture.mp4":"capture.webm",h=Math.max(0,Math.round(s-this.recordingStartedAt)),m={blob:u,url:c,mimeType:l.mimeType,filename:d,durationMs:h,startedAt:this.recordingStartedAt,stoppedAt:s,timeline:this.finishTimelineMetadata(),webm:l.mimeType.includes("webm")?{seekable:!1,hasDurationMetadata:!1,durationMs:h,sizeBytes:u.size}:void 0};this.clearLastRecording(),this.lastRecording=m;try{this.options.onRecordingStop?.(m)}finally{if(this.options.autoDownload){const y=document.createElement("a");y.href=m.url,y.download=m.filename,y.click()}this.destroyed&&this.clearLastRecording(),this.timelineMetadata=null,this.recordingStartedAt=0,this.activeFilmTitle=null}},l.start(1e3),this.recorder=l,this.lastRecordingError=null,this.updateState({recording:!0}),this.options.onRecordingStart?.(),this.options.movePointerToSelector&&setTimeout(()=>{this.options.movePointerToSelector&&this.state.recording&&this.playPointerTour(this.options.movePointerToSelector)},500),!0}catch(e){throw e===this.lastRecordingError?e:(cancelAnimationFrame(this.renderRafId),this.renderRafId=0,this.stopCaptureStream(),this.restoreIgnoredElements(),this.recorder=null,this.handleRecordingError(e))}}stopRecording(){this.state.recording&&(cancelAnimationFrame(this.renderRafId),this.recorder?.stop(),this.stopCaptureStream(),this.restoreIgnoredElements(),this.recorder=null,this.pointerEl&&(this.pointerEl.style.display="none",this.pointerEl.classList.remove("cfr-holding")),this.tourRafId&&(cancelAnimationFrame(this.tourRafId),this.tourRafId=0),this.updateState({recording:!1,showGrid:this.options.showGrid}))}captureBitmap(){this.state.recording&&this.canvasEl.toBlob(e=>{if(!e)return;const t=document.createElement("a");t.href=URL.createObjectURL(e),t.download="capture.png",t.click(),setTimeout(()=>URL.revokeObjectURL(t.href),1e3)},"image/png")}ensurePointerEl(){typeof window>"u"||typeof document>"u"||(this.pointerEl||(this.pointerEl=document.createElement("div"),this.pointerX=window.innerWidth/2,this.pointerY=window.innerHeight+40,this.pointerEl.style.left=`${this.pointerX}px`,this.pointerEl.style.top=`${this.pointerY}px`,document.body.appendChild(this.pointerEl)),this.applyPointerClassName(),this.applyPointerColors(),this.pointerEl.style.display="block")}applyPointerClassName(){if(!this.pointerEl)return;const e=this.pointerEl.classList.contains("cfr-holding"),t=this.options.pointerClassName.split(/\s+/).filter(Boolean);this.pointerEl.className=["cfr-simulated-pointer",...t].join(" "),e&&this.pointerEl.classList.add("cfr-holding"),this.pointerEl.classList.toggle("cfr-ripple-disabled",this.options.disableRipple)}validatePointerColor(e,t){if(!/^#[0-9a-f]{6}$/i.test(e))throw new TypeError(`[FilmRecorder] ${t} must be a 6-digit hex color.`);return e}applyPointerColors(){if(!this.pointerEl)return;const e=this.validatePointerColor(this.options.pointerFillColor,"pointerFillColor"),t=this.validatePointerColor(this.options.pointerBorderColor,"pointerBorderColor"),r=this.validatePointerColor(this.options.pointerRippleColor,"pointerRippleColor"),n=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="30" viewBox="0 0 24 30" fill="none"><path d="M2 2.25V23.15L7.55 17.83L11.65 27.4L16.05 25.52L12.08 16.25H20.2L2 2.25Z" fill="${e}" stroke="${t}" stroke-width="2.2" stroke-linejoin="round"/></svg>`;this.pointerEl.style.backgroundImage=`url("data:image/svg+xml,${encodeURIComponent(n)}")`,this.pointerEl.style.setProperty("--cfr-pointer-ripple-color",r)}resetPointerEntryPosition(){this.ensurePointerEl(),this.pointerEl&&(this.pointerX=window.innerWidth/2,this.pointerY=window.innerHeight+40,this.pointerEl.style.left=`${this.pointerX}px`,this.pointerEl.style.top=`${this.pointerY}px`,this.pointerEl.classList.remove("cfr-holding"))}async getTargetElement(e,t,r,n=this.options.selectorTimeoutMs){if(typeof e!="string")return e;const o=performance.now();for(;;){if(r?.aborted)throw new DOMException("Aborted","AbortError");const a=document.querySelector(e);if(a)return a;if(performance.now()-o>n)throw this.createSelectorError(e,t);await new Promise(l=>setTimeout(l,50))}}async animatePointerTo(e,t=800,r,n=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;if(this.ensurePointerEl(),r?.aborted)throw new DOMException("Aborted","AbortError");const o=await this.getTargetElement(e,"animatePointerTo",r,n),a=o.getBoundingClientRect(),l=a.left+a.width/2,s=a.top+a.height/2,u=this.pointerX,c=this.pointerY,d=performance.now();return this.tourRafId&&cancelAnimationFrame(this.tourRafId),new Promise((h,m)=>{const y=()=>{cancelAnimationFrame(this.tourRafId),m(new DOMException("Aborted","AbortError"))};r&&r.addEventListener("abort",y);const p=w=>{if(r?.aborted)return;const E=w-d,S=Math.min(E/t,1),T=S<.5?2*S*S:1-Math.pow(-2*S+2,2)/2,R=u+(l-u)*T,M=c+(s-c)*T;this.pointerX=R,this.pointerY=M,this.pointerEl&&(this.pointerEl.style.left=`${R}px`,this.pointerEl.style.top=`${M}px`),S<1?this.tourRafId=requestAnimationFrame(p):(this.dispatchPointerHover(o,l,s),r&&r.removeEventListener("abort",y),h())};this.tourRafId=requestAnimationFrame(p)})}dispatchPointerHover(e,t,r){const n={bubbles:!0,cancelable:!0,view:window,clientX:t,clientY:r};e.dispatchEvent(new MouseEvent("mouseover",n)),e.dispatchEvent(new MouseEvent("mouseenter",{...n,bubbles:!1})),e.dispatchEvent(new MouseEvent("mousemove",n))}async simulateClick(e,t,r=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;if(t?.aborted)throw new DOMException("Aborted","AbortError");if(await this.animatePointerTo(e,600,t,r),t?.aborted)throw new DOMException("Aborted","AbortError");this.pointerEl&&this.pointerEl.classList.add("cfr-holding");let n;try{n=await this.getTargetElement(e,"simulateClick",t,r)}catch(s){throw this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),s}const o=new MouseEvent("mousedown",{bubbles:!0,cancelable:!0,view:window}),a=new MouseEvent("mouseup",{bubbles:!0,cancelable:!0,view:window}),l=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window});n.dispatchEvent(o),n.dispatchEvent(a),n instanceof HTMLElement?n.click():n.dispatchEvent(l),await new Promise((s,u)=>{const c=()=>{clearTimeout(d),this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),u(new DOMException("Aborted","AbortError"))};t&&t.addEventListener("abort",c);const d=setTimeout(()=>{t&&t.removeEventListener("abort",c),this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),s()},250)})}isFormTypingTarget(e){return typeof HTMLInputElement<"u"&&typeof HTMLTextAreaElement<"u"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)?!0:"value"in e&&typeof e.value=="string"}isContentEditableTypingTarget(e){return e instanceof HTMLElement&&e.isContentEditable}dispatchKeyboardInputEvents(e,t,r="insertText"){const n=new KeyboardEvent("keydown",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0}),o=new KeyboardEvent("keypress",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0}),a=new InputEvent("input",{data:r==="insertText"?t:null,inputType:r,bubbles:!0}),l=new KeyboardEvent("keyup",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0});e.dispatchEvent(n),r==="insertText"&&e.dispatchEvent(o),e.dispatchEvent(a),e.dispatchEvent(l)}typeChar(e,t){if(!this.isFormTypingTarget(e)){this.typeContentEditableChar(e,t);return}const r=e.selectionStart??e.value.length,n=e.selectionEnd??e.value.length,o=e.value;e.value=o.substring(0,r)+t+o.substring(n),e.selectionStart=e.selectionEnd=r+1;const a=e._valueTracker;a&&a.setValue(o),this.dispatchKeyboardInputEvents(e,t),e.dispatchEvent(new Event("change",{bubbles:!0}))}typeContentEditableChar(e,t){const r=window.getSelection();if(!r)return;if(!r.rangeCount||!e.contains(r.anchorNode)){const a=document.createRange();a.selectNodeContents(e),a.collapse(!1),r.removeAllRanges(),r.addRange(a)}const n=r.getRangeAt(0);n.deleteContents();const o=document.createTextNode(t);n.insertNode(o),n.setStartAfter(o),n.collapse(!0),r.removeAllRanges(),r.addRange(n),this.dispatchKeyboardInputEvents(e,t),e.dispatchEvent(new Event("change",{bubbles:!0}))}simulateBackspace(e){if(!this.isFormTypingTarget(e)){this.simulateContentEditableBackspace(e);return}const t=e.value;if(t.length===0)return;const r=e.selectionStart??t.length,n=e.selectionEnd??t.length;let o=t,a=r;r!==n?o=t.substring(0,r)+t.substring(n):r>0&&(o=t.substring(0,r-1)+t.substring(r),a=r-1),e.value=o,e.selectionStart=e.selectionEnd=a;const l=e._valueTracker;l&&l.setValue(t),this.dispatchKeyboardInputEvents(e,"Backspace","deleteContentBackward"),e.dispatchEvent(new Event("change",{bubbles:!0}))}simulateContentEditableBackspace(e){const t=window.getSelection();if(!t)return;if(!t.rangeCount||!e.contains(t.anchorNode)){const n=document.createRange();n.selectNodeContents(e),n.collapse(!1),t.removeAllRanges(),t.addRange(n)}const r=t.getRangeAt(0);if(!r.collapsed)r.deleteContents();else if(r.startContainer.nodeType===Node.TEXT_NODE&&r.startOffset>0){const n=r.startContainer;n.textContent=(n.textContent??"").slice(0,r.startOffset-1)+(n.textContent??"").slice(r.startOffset),r.setStart(n,r.startOffset-1),r.collapse(!0)}else return;t.removeAllRanges(),t.addRange(r),this.dispatchKeyboardInputEvents(e,"Backspace","deleteContentBackward"),e.dispatchEvent(new Event("change",{bubbles:!0}))}async focusTypingTarget(e,t,r=this.options.selectorTimeoutMs){const n=await this.getTargetElement(e,"simulateType",t,r);if(!(n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||this.isContentEditableTypingTarget(n)))throw new Error("[FilmRecorder] Target element for simulateType must be an input, textarea, or contenteditable element.");return await this.simulateClick(n,t,r),n.focus(),n}async simulateType(e,t,r,n){await this.simulateTypeWithRandom(e,t,r,n,Math.random,this.options.selectorTimeoutMs)}async simulateTypeWithRandom(e,t,r,n,o,a=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;this.throwIfAborted(n);const l=this.resolveTypingOptions(typeof r=="number"?{cps:r}:r),{cps:s,jitter:u,punctuationPauseMs:c,mistakeRate:d}=l,h=await this.focusTypingTarget(e,n,a),m=1e3/s,y=(p,w,E=!1)=>{if(u<=0)return m;let S=1;if(!E&&p>0){const z=t[p-1],D=w;D===z&&/[a-zA-Z0-9]/.test(D)?S=.4:/[a-zA-Z0-9]/.test(z)&&/[a-zA-Z0-9]/.test(D)?S=.75:D===" "?S=1.5:z===" "&&/[a-zA-Z0-9]/.test(D)&&(S=1.25)}const T=/[A-Z]/.test(w),R=p>0&&/[A-Z]/.test(t[p-1]);T&&!R&&!E&&(S+=.4);const M=o(),Q=o(),ee=Math.sqrt(-2*Math.log(M||1e-4))*Math.cos(2*Math.PI*Q),q=Math.exp(ee*u*.8);let N=m*S*q;if(!E&&p>0&&p%18===0&&o()<.6){const z=m*(1.5+o()*2)*u;N+=z}const Ot=Math.max(10,m*.25),Ft=m*4;return Math.min(Ft,Math.max(Ot,N))};for(let p=0;p<t.length;p++){this.throwIfAborted(n);const w=t[p];if(d>0&&o()<d&&/[a-z0-9]/i.test(w)){const S=this.getPlausibleTypo(w,o);this.typeChar(h,S);const T=y(p,S,!0)*1.3;await this.delay(T,n),this.throwIfAborted(n),this.simulateBackspace(h);const R=y(p,"Backspace",!0)*1.1;await this.delay(R,n)}this.typeChar(h,w);let E=y(p,w);/[.,!?;;:]/.test(w)&&(E+=c),await this.delay(E,n)}}getPlausibleTypo(e,t){const r={a:"sqwz",b:"vghn",c:"xdfv",d:"ersfcx",e:"wsdr",f:"rtgdvc",g:"tyfhvb",h:"yugjbn",i:"ujko",j:"uikhmn",k:"ijolm",l:"kop",m:"njk",n:"bhjm",o:"iklp",p:"ol",q:"wa",r:"edft",s:"wedxza",t:"rfgy",u:"yhji",v:"cfgb",w:"qase",x:"zsdc",y:"tghu",z:"asx"},n=e.toLowerCase(),o=r[n]??"abcdefghijklmnopqrstuvwxyz",a=o[Math.floor(t()*o.length)];return e===e.toUpperCase()?a.toUpperCase():a}playPointerTour(e,t){if(typeof window>"u"||typeof document>"u")return Promise.resolve();const r=t?.moveDuration??1e3,n=t?.holdDuration??2e3;if(this.ensurePointerEl(),!this.pointerEl)return Promise.resolve();this.pointerEl.style.display="block",this.pointerEl.classList.remove("cfr-holding"),this.resetFullScreen();const o=document.querySelector(e);if(!o)return console.warn(`[FilmRecorder] Pointer tour target element not found: ${e}`),Promise.resolve();const a=o.getBoundingClientRect(),l=a.left+a.width/2,s=a.top+a.height/2,u=this.pointerX,c=this.pointerY,d=performance.now();return this.tourRafId&&cancelAnimationFrame(this.tourRafId),new Promise(h=>{const m=y=>{const p=y-d,w=Math.min(p/r,1),E=w<.5?2*w*w:1-Math.pow(-2*w+2,2)/2,S=u+(l-u)*E,T=c+(s-c)*E;if(this.pointerX=S,this.pointerY=T,this.pointerEl&&(this.pointerEl.style.left=`${S}px`,this.pointerEl.style.top=`${T}px`),w<1)this.tourRafId=requestAnimationFrame(m);else{this.pointerEl&&this.pointerEl.classList.add("cfr-holding"),this.mousePosGlobal={x:l,y:s};const R=this.state.resolution.w/this.state.resolution.h;this.targetRect=this.centeredRectOnPoint(l,s,window.innerWidth,window.innerHeight,R),setTimeout(()=>{this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),this.resetFullScreen(),setTimeout(()=>{this.pointerEl&&!this.pointerEl.classList.contains("cfr-holding")&&(this.pointerEl.style.display="none"),h()},1e3)},n)}};this.tourRafId=requestAnimationFrame(m)})}getState(){return{...this.state}}onStateChange(e){return this.listeners.add(e),e(this.getState()),()=>this.listeners.delete(e)}updateState(e){this.state={...this.state,...e},this.listeners.forEach(t=>t(this.state))}setResolution(e){if(this.state.recording)return;this.updateState({resolution:e});const t=this.computeGrid(window.innerWidth,window.innerHeight),r=e.w/e.h,{w:n,h:o}=this.getRecordingRegionBox(r,b,t.rows,b),a=Math.floor((b-n)/2),l=Math.floor((t.rows-o)/2);this.targetRect={col:a,row:l,w:n,h:o},this.liveRect={...this.targetRect}}setAutoZoom(e){this.updateState({autoZoom:e})}setPauseDuringScroll(e){this.updateState({pauseDuringScroll:e})}setShowGrid(e){this.updateState({showGrid:e})}setShowOutline(e){this.updateState({showOutline:e})}setMousePaused(e){this.updateState({mousePaused:e})}setElementSelector(e){if(this.options.elementSelector=e,this.updateState({elementSelector:e}),e){const t=this.calculateElementRect(e,this.options.elementPadding);t&&(this.targetRect=t)}else this.resetFullScreen()}setElementPadding(e){if(this.options.elementPadding=e,this.updateState({elementPadding:e}),this.options.elementSelector){const t=this.calculateElementRect(this.options.elementSelector,e);t&&(this.targetRect=t)}}setFixedRecordingRegion(e){if(this.options.fixedRecordingRegion=e,this.updateState({fixedRecordingRegion:e}),this.options.elementSelector){const t=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding);t&&(this.targetRect=t)}else this.resetFullScreen()}setMovePointerToSelector(e){this.options.movePointerToSelector=e,this.updateState({movePointerToSelector:e})}setPointerClassName(e){this.options.pointerClassName=e,this.updateState({pointerClassName:e}),this.applyPointerClassName()}setPointerFillColor(e){this.options.pointerFillColor=this.validatePointerColor(e,"pointerFillColor"),this.updateState({pointerFillColor:this.options.pointerFillColor}),this.applyPointerColors()}setPointerBorderColor(e){this.options.pointerBorderColor=this.validatePointerColor(e,"pointerBorderColor"),this.updateState({pointerBorderColor:this.options.pointerBorderColor}),this.applyPointerColors()}setPointerRippleColor(e){this.options.pointerRippleColor=this.validatePointerColor(e,"pointerRippleColor"),this.updateState({pointerRippleColor:this.options.pointerRippleColor}),this.applyPointerColors()}setDisableRipple(e){this.options.disableRipple=e,this.updateState({disableRipple:e}),this.applyPointerClassName()}setIgnoreSelector(e){this.restoreIgnoredElements(),this.options.ignoreSelector=e,this.updateState({ignoreSelector:e}),this.state.recording&&this.hideIgnoredElements()}setTypingDefaults(e){this.options.typingDefaults=this.resolveTypingOptions(e)}resolveSelectorTimeoutMs(e){const t=e??this.options.selectorTimeoutMs;if(!Number.isFinite(t)||t<0)throw new TypeError("[FilmRecorder] selectorTimeoutMs must be a finite number >= 0.");return t}resolveTypingOptions(...e){const t={...re};for(const r of e)if(r)for(const n of Object.keys(r)){const o=r[n];o!==void 0&&(t[n]=o)}return this.validateTypingOptions(t),{...t}}validateTypingOptions(e,t="[FilmRecorder] Invalid typing options"){const r=[["cps",e.cps,"must be a finite number greater than 0"],["jitter",e.jitter,"must be between 0 and 1"],["punctuationPauseMs",e.punctuationPauseMs,"must be a finite number greater than or equal to 0"],["mistakeRate",e.mistakeRate,"must be between 0 and 1"]];for(const[n,o,a]of r){if(o===void 0)continue;if(!(Number.isFinite(o)&&(n==="cps"?o>0:n==="punctuationPauseMs"?o>=0:o>=0&&o<=1)))throw new TypeError(`${t}: ${n} ${a}; received ${String(o)}.`)}}delay(e,t){return new Promise((r,n)=>{if(t?.aborted)return n(new DOMException("Aborted","AbortError"));const o=()=>{clearTimeout(a),n(new DOMException("Aborted","AbortError"))};t&&t.addEventListener("abort",o);const a=setTimeout(()=>{t&&t.removeEventListener("abort",o),r()},e)})}findElementByText(e){if(typeof document>"u")return null;try{const r=`//*[text()='${e}' or contains(text(), '${e}')]`,o=document.evaluate(r,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(o)return o}catch{}const t=Array.from(document.querySelectorAll("button, a, label, span, div, h1, h2, h3, h4, p"));for(const r of t)if(r.textContent?.trim()===e)return r;for(const r of t)if(r.textContent?.includes(e))return r;return null}async findElementByTextAsync(e,t,r=3e3){const n=performance.now();for(;;){if(t?.aborted)throw new DOMException("Aborted","AbortError");const o=this.findElementByText(e);if(o)return o;if(performance.now()-n>r)return null;await new Promise(a=>setTimeout(a,50))}}async clickText(e,t){const r=await this.findElementByTextAsync(e,t,this.options.selectorTimeoutMs);if(!r)throw this.createSelectorError(e,"clickText");await this.simulateClick(r,t)}async focusText(e,t){const r=await this.findElementByTextAsync(e,t,this.options.selectorTimeoutMs);if(!r)throw this.createSelectorError(e,"focusText");const n="data-cfr-temp-focus";r.setAttribute(n,"true"),this.setElementSelector(`[${n}="true"]`),await this.animatePointerTo(r,800,t)}createSelectorError(e,t){const r=this.state.currentScene?` in scene "${this.state.currentScene}"`:"";return new Error(`[FilmRecorder] Selector safety check failed for "${e}" during action "${t}"${r}.
|
|
1
|
+
(function(f,v){typeof exports=="object"&&typeof module<"u"?v(exports,require("react"),require("react/jsx-runtime"),require("@openai/agents"),require("openai")):typeof define=="function"&&define.amd?define(["exports","react","react/jsx-runtime","@openai/agents","openai"],v):(f=typeof globalThis<"u"?globalThis:f||self,v(f.CodeFilm={},f.React,f.React,f.OpenAIAgents,f.OpenAI))})(this,(function(f,v,g,A,Fe){"use strict";function Ie(i){return{type:"camera",...i}}function $e(i,e){return new Ne(i,e)}function Le(i,e){return new ze(i,e)}class Ne{id;element;includeInCapture=!0;videoEl;fallbackEl;resizeHandle;stream=null;visible=!1;position;size;minSize;maxSize;shape;draggable;resizable;mirror;requestOnShow;onEvent;constructor(e,t){this.id=e.id,this.position=e.position??"top-left",this.size=e.size??168,this.minSize=e.minSize??96,this.maxSize=e.maxSize??360,this.shape=e.shape??"circle",this.draggable=e.draggable??!0,this.resizable=e.resizable??!0,this.mirror=e.mirror??!0,this.requestOnShow=e.requestOnShow??!0,this.onEvent=t,this.element=document.createElement("div"),this.element.className=["cfr-recording-overlay","cfr-camera-overlay",e.className].filter(Boolean).join(" "),this.element.dataset.codeFilmOverlay=this.id,this.videoEl=document.createElement("video"),this.videoEl.muted=!0,this.videoEl.playsInline=!0,this.videoEl.autoplay=!0,this.fallbackEl=document.createElement("div"),this.fallbackEl.className="cfr-camera-overlay-fallback",this.fallbackEl.textContent="Camera unavailable",this.resizeHandle=document.createElement("div"),this.resizeHandle.className="cfr-recording-overlay-resize",this.element.append(this.videoEl,this.fallbackEl,this.resizeHandle),this.applyElementStyle(),this.installPointerHandlers(),(e.enabled??!1)&&this.show()}async requestPermission(){if(this.stream)return!0;try{if(!navigator.mediaDevices?.getUserMedia)throw new Error("Camera capture is not available in this browser.");return this.stream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1}),this.videoEl.srcObject=this.stream,this.fallbackEl.style.display="none",await this.videoEl.play().catch(()=>{}),!0}catch(e){return this.stopTracks(),this.fallbackEl.style.display="flex",this.emit("error",{message:e instanceof Error?e.message:String(e)}),!1}}async show(){this.mount(),this.visible=!0,this.element.style.display="block",this.requestOnShow&&await this.requestPermission(),this.emit("shown",this.snapshot())}hide(){this.visible=!1,this.element.style.display="none",this.stopTracks(),this.emit("hidden",this.snapshot())}moveTo(e){this.position=e,this.applyElementStyle(),this.emit("moved",this.snapshot())}setSize(e){this.size=U(e,this.minSize,this.maxSize),this.applyElementStyle(),this.emit("resized",this.snapshot())}destroy(){this.hide(),this.element.remove()}draw(e,t,r){if(!this.visible)return;const n=L(this.position,this.size,t,r);De(e,n.x,n.y,n.size,this.shape,()=>{this.stream&&this.videoEl.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA?this.mirror?(e.save(),e.translate(n.x+n.size,n.y),e.scale(-1,1),e.drawImage(this.videoEl,0,0,n.size,n.size),e.restore()):e.drawImage(this.videoEl,n.x,n.y,n.size,n.size):Be(e,n.x,n.y,n.size)})}mount(){typeof document>"u"||this.element.isConnected||document.body.appendChild(this.element)}applyElementStyle(){const e=L(this.position,this.size,typeof window>"u"?1280:window.innerWidth,typeof window>"u"?720:window.innerHeight);Object.assign(this.element.style,{display:this.visible?"block":"none",position:"fixed",left:`${e.x}px`,top:`${e.y}px`,width:`${e.size}px`,height:`${e.size}px`,borderRadius:this.shape==="circle"?"9999px":this.shape==="rounded"?"24px":"0",overflow:"hidden",zIndex:"2147483646",background:"#111827",boxShadow:"0 18px 55px rgba(0,0,0,0.32), 0 0 0 1px rgba(255,255,255,0.2)",touchAction:"none",cursor:this.draggable?"grab":"default"}),Object.assign(this.videoEl.style,{width:"100%",height:"100%",objectFit:"cover",transform:this.mirror?"scaleX(-1)":"none"}),this.resizeHandle.style.display=this.resizable?"block":"none"}installPointerHandlers(){let e=null;const t=o=>{const a=o.target===this.resizeHandle;!this.draggable&&!a||!this.resizable&&a||(o.preventDefault(),this.element.setPointerCapture(o.pointerId),e={type:a?"resize":"move",pointerId:o.pointerId,startX:o.clientX,startY:o.clientY,startPosition:this.position,startSize:this.size})},r=o=>{if(!e||e.pointerId!==o.pointerId)return;const a=o.clientX-e.startX,l=o.clientY-e.startY;if(e.type==="resize")this.setSize(e.startSize+Math.max(a,l));else{const s=L(e.startPosition,e.startSize,window.innerWidth,window.innerHeight);this.moveTo({x:s.x+a,y:s.y+l})}},n=o=>{!e||e.pointerId!==o.pointerId||(this.element.releasePointerCapture(o.pointerId),e=null)};this.element.addEventListener("pointerdown",t),this.element.addEventListener("pointermove",r),this.element.addEventListener("pointerup",n),this.element.addEventListener("pointercancel",n)}stopTracks(){this.stream?.getTracks().forEach(e=>e.stop()),this.stream=null,this.videoEl.srcObject=null}emit(e,t){this.onEvent?.({id:this.id,type:e,data:t})}snapshot(){return{position:this.position,size:this.size,shape:this.shape}}}class ze{id;element;includeInCapture;visible;position;size;trackTimeline;onEvent;constructor(e,t){this.id=e.id,this.element=e.element,this.includeInCapture=e.includeInCapture??!0,this.trackTimeline=e.trackTimeline??!0,this.visible=e.enabled??!0,this.position=e.position??"top-left",this.size=e.size??168,this.onEvent=t,e.optOutOfSdkStyles||(this.element.classList.add("cfr-recording-overlay"),e.className&&this.element.classList.add(...e.className.split(/\s+/)),this.element.dataset.codeFilmOverlay=this.id),this.applyElementStyle()}show(){this.visible=!0,this.element.style.display="",this.emit("shown",this.snapshot())}hide(){this.visible=!1,this.element.style.display="none",this.emit("hidden",this.snapshot())}moveTo(e){this.position=e,this.applyElementStyle(),this.emit("moved",this.snapshot())}setSize(e){this.size=Math.max(1,e),this.applyElementStyle(),this.emit("resized",this.snapshot())}destroy(){this.hide()}draw(e,t,r){if(!this.visible||!this.includeInCapture)return;const n=L(this.position,this.size,t,r);this.element instanceof HTMLCanvasElement?e.drawImage(this.element,n.x,n.y,n.size,n.size):(this.element instanceof HTMLImageElement||this.element instanceof HTMLVideoElement)&&e.drawImage(this.element,n.x,n.y,n.size,n.size)}applyElementStyle(){const e=L(this.position,this.size,typeof window>"u"?1280:window.innerWidth,typeof window>"u"?720:window.innerHeight);Object.assign(this.element.style,{position:"fixed",left:`${e.x}px`,top:`${e.y}px`,width:`${e.size}px`,height:`${e.size}px`,zIndex:"2147483646"})}emit(e,t){this.trackTimeline&&this.onEvent?.({id:this.id,type:e,data:t})}snapshot(){return{position:this.position,size:this.size}}}function L(i,e,t,r){if(typeof i=="object")return{x:U(i.x,0,Math.max(0,t-e)),y:U(i.y,0,Math.max(0,r-e)),size:e};const n=t-e-24,o=r-e-24;return{x:i.endsWith("right")?n:24,y:i.startsWith("bottom")?o:24,size:e}}function De(i,e,t,r,n,o){i.save(),n==="circle"?(i.beginPath(),i.arc(e+r/2,t+r/2,r/2,0,Math.PI*2),i.clip()):n==="rounded"&&(je(i,e,t,r,r,Math.min(24,r/5)),i.clip()),o(),i.restore()}function Be(i,e,t,r){i.save(),i.fillStyle="#111827",i.fillRect(e,t,r,r),i.fillStyle="#e5e7eb",i.font=`${Math.max(12,Math.round(r/12))}px system-ui, sans-serif`,i.textAlign="center",i.textBaseline="middle",i.fillText("Camera unavailable",e+r/2,t+r/2,r-20),i.restore()}function je(i,e,t,r,n,o){i.beginPath(),i.moveTo(e+o,t),i.lineTo(e+r-o,t),i.quadraticCurveTo(e+r,t,e+r,t+o),i.lineTo(e+r,t+n-o),i.quadraticCurveTo(e+r,t+n,e+r-o,t+n),i.lineTo(e+o,t+n),i.quadraticCurveTo(e,t+n,e,t+n-o),i.lineTo(e,t+o),i.quadraticCurveTo(e,t,e+o,t),i.closePath()}function U(i,e,t){return Math.min(t,Math.max(e,i))}const H=[{label:"YouTube HD (16:9)",w:1920,h:1080},{label:"Twitter / X (16:9)",w:1200,h:675},{label:"Instagram Post (4:5)",w:1080,h:1350},{label:"Instagram Reel / Story (9:16)",w:1080,h:1920},{label:"TikTok (9:16)",w:1080,h:1920}],b=24,P=6,_e={"smallest-16:9":P,medium:Math.round(P*1.5),"medium-16:9":Math.round(P*1.5),large:Math.round(P*1.5*1.5),"large-16:9":Math.round(P*1.5*1.5)},qe=1e3,Ue=12,He=.08,Ge=.015,We=3e3,Ze=500,k=56,F=2,N="j",te=12e4,ie=3e3,re=Object.freeze({cps:24,jitter:.22,punctuationPauseMs:120,mistakeRate:.012}),Xe=Object.freeze({cps:24,jitter:.22,punctuationPauseMs:120,mistakeRate:.012});class ne{options;listeners=new Set;state;videoEl;canvasEl;recorder=null;stream=null;chunks=[];lastRecording=null;lastRecordingError=null;recordingStartedAt=0;timelineMetadata=null;activeFilmTitle=null;destroyed=!1;cameraRafId=0;renderRafId=0;targetRect;liveRect;mousePosGlobal={x:0,y:0};holdTimer=null;zoomOutTimer=null;scrollPausedUntil=0;anchorX=0;anchorY=0;pointerEl=null;pointerX=0;pointerY=0;tourRafId=0;tourAbortController=null;activeFilmScriptContext=null;activeFilmScriptOptions=null;activeExecutionPromise=null;finalizationPromise=null;pendingActionGates=[];activeTypingRandom=Math.random;ignoredElements=new Map;overlays=new Map;constructor(e={}){const t={fps:e.fps??60,resolutions:e.resolutions??H,defaultResolutionIndex:e.defaultResolutionIndex??0,autoZoom:e.autoZoom??!0,pauseDuringScroll:e.pauseDuringScroll??!0,showGrid:e.showGrid??!0,showOutline:e.showOutline??!1,enableShortcuts:e.enableShortcuts??!0,elementSelector:e.elementSelector??null,elementPadding:e.elementPadding??1.1,fixedRecordingRegion:e.fixedRecordingRegion??null,movePointerToSelector:e.movePointerToSelector??null,pointerClassName:e.pointerClassName??"",pointerFillColor:e.pointerFillColor??"#ffffff",pointerBorderColor:e.pointerBorderColor??"#18181b",pointerRippleColor:e.pointerRippleColor??"#64748b",disableRipple:e.disableRipple??!1,ignoreSelector:e.ignoreSelector??null,overlays:e.overlays??[],autoDownload:e.autoDownload??!0,includeTimelineMetadata:e.includeTimelineMetadata??!1,selectorTimeoutMs:e.selectorTimeoutMs??ie,typingDefaults:this.resolveTypingOptions(e.typingDefaults),typingSeed:e.typingSeed??"",onRecordingStart:e.onRecordingStart??(()=>{}),onRecordingStop:e.onRecordingStop??(()=>{}),onRecordingError:e.onRecordingError??(()=>{}),onTourStart:e.onTourStart??(()=>{}),onTourStop:e.onTourStop??(()=>{}),onReadyToEnd:e.onReadyToEnd??(()=>{}),onTourError:e.onTourError??(()=>{}),onSceneStart:e.onSceneStart??(()=>{}),onSceneEnd:e.onSceneEnd??(()=>{}),onActionStart:e.onActionStart??(()=>{}),onActionEnd:e.onActionEnd??(()=>{})};this.options=t;const r=this.options.resolutions[this.options.defaultResolutionIndex]||H[0],n={w:typeof window<"u"?window.innerWidth:1280,h:typeof window<"u"?window.innerHeight:720},o=this.computeGrid(n.w,n.h);let a;if(this.options.elementSelector){const l=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding,r.w/r.h);if(l)a=l;else{const s=this.getRecordingRegionBox(r.w/r.h,b,o.rows,b),u=Math.floor((b-s.w)/2),c=Math.floor((o.rows-s.h)/2);a={col:u,row:c,w:s.w,h:s.h}}}else{const l=this.getRecordingRegionBox(r.w/r.h,b,o.rows,b),s=Math.floor((b-l.w)/2),u=Math.floor((o.rows-l.h)/2);a={col:s,row:u,w:l.w,h:l.h}}this.targetRect={col:a.col,row:a.row,w:a.w,h:a.h},this.liveRect={...this.targetRect},this.state={recording:!1,showGrid:this.options.showGrid,autoZoom:this.options.autoZoom,pauseDuringScroll:this.options.pauseDuringScroll,resolution:r,mousePaused:!1,viewport:n,displayRect:{...this.liveRect},showOutline:this.options.showOutline,elementSelector:this.options.elementSelector,elementPadding:this.options.elementPadding,fixedRecordingRegion:this.options.fixedRecordingRegion,movePointerToSelector:this.options.movePointerToSelector,pointerClassName:this.options.pointerClassName,pointerFillColor:this.options.pointerFillColor,pointerBorderColor:this.options.pointerBorderColor,pointerRippleColor:this.options.pointerRippleColor,disableRipple:this.options.disableRipple,ignoreSelector:this.options.ignoreSelector,tourState:"idle",executionState:"idle",currentScene:null},typeof window<"u"?(this.videoEl=document.createElement("video"),this.videoEl.muted=!0,this.videoEl.playsInline=!0,this.videoEl.style.display="none",document.body.appendChild(this.videoEl),this.canvasEl=document.createElement("canvas"),this.canvasEl.style.display="none",document.body.appendChild(this.canvasEl),this.setupEventListeners(),this.startCameraLoop(),this.options.overlays.forEach(l=>{l.type==="camera"&&this.createCameraOverlay(l)})):(this.videoEl={},this.canvasEl={})}computeGrid(e,t){const r=e/b,n=r*9/16,o=Math.max(0,t-k),a=Math.max(1,Math.floor(o/n));return{cellW:r,cellH:n,rows:a}}getAspectBox(e,t,r,n){let o=1,a=1,l=1/0;const s=Math.min(t,n);for(let u=1;u<=s;u++){const c=u*16/(9*e),d=[Math.floor(c),Math.ceil(c)].filter(h=>h>=1&&h<=r);for(const h of d){const m=u/h*1.7777777777777777,y=Math.abs(m-e);(y<l-1e-6||Math.abs(y-l)<1e-6&&u>o)&&(l=y,o=u,a=h)}}return{w:o,h:a}}getRecordingRegionBox(e,t,r,n){return this.options.fixedRecordingRegion?this.getAspectBox(16/9,t,r,_e[this.options.fixedRecordingRegion]):this.getAspectBox(e,t,r,n)}clampRect(e,t){const r=Math.min(b,Math.max(1,e.w)),n=Math.min(t,Math.max(1,e.h)),o=Math.min(b-r,Math.max(0,e.col)),a=Math.min(t-n,Math.max(0,e.row));return{col:o,row:a,w:r,h:n}}centeredRectOnPoint(e,t,r,n,o){const{cellW:a,cellH:l,rows:s}=this.computeGrid(r,n),u=Math.max(0,t-k),c=Math.min(b-1,Math.max(0,Math.floor(e/a))),d=Math.min(s-1,Math.max(0,Math.floor(u/l))),{w:h,h:m}=this.getRecordingRegionBox(o,b,s,P);return this.clampRect({col:Math.round(c-h/2+.5),row:Math.round(d-m/2+.5),w:h,h:m},s)}setupEventListeners(){window.addEventListener("resize",this.handleResize),window.addEventListener("mousemove",this.handleMouseMove),window.addEventListener("wheel",this.handleScrollOrWheel,{passive:!0}),window.addEventListener("scroll",this.handleScrollOrWheel,{passive:!0}),this.options.enableShortcuts&&window.addEventListener("keydown",this.handleKeyDown)}cleanupEventListeners(){window.removeEventListener("resize",this.handleResize),window.removeEventListener("mousemove",this.handleMouseMove),window.removeEventListener("wheel",this.handleScrollOrWheel),window.removeEventListener("scroll",this.handleScrollOrWheel),window.removeEventListener("keydown",this.handleKeyDown)}handleResize=()=>{const e=window.innerWidth,t=window.innerHeight;if(this.updateState({viewport:{w:e,h:t}}),this.options.elementSelector)return;const r=this.computeGrid(e,t),n=this.state.resolution.w/this.state.resolution.h,{w:o,h:a}=this.getRecordingRegionBox(n,b,r.rows,b),l=Math.floor((b-o)/2),s=Math.floor((r.rows-a)/2);this.targetRect={col:l,row:s,w:o,h:a}};handleMouseMove=e=>{this.state.mousePaused||this.options.elementSelector||(this.mousePosGlobal={x:e.clientX,y:e.clientY},Math.hypot(e.clientX-this.anchorX,e.clientY-this.anchorY)>Ue&&(this.armHold(e.clientX,e.clientY),this.zoomOutTimer&&(clearTimeout(this.zoomOutTimer),this.zoomOutTimer=null)))};handleScrollOrWheel=()=>{this.options.elementSelector||(this.scrollPausedUntil=performance.now()+Ze,this.holdTimer&&clearTimeout(this.holdTimer))};handleKeyDown=e=>{if(!(e.metaKey||e.ctrlKey))return;const r=e.key.toLowerCase();r===N?(e.preventDefault(),this.state.recording?this.stopRecording():this.startRecording()):r==="l"?(e.preventDefault(),this.setMousePaused(!this.state.mousePaused)):e.key==="ArrowUp"?(e.preventDefault(),this.options.elementSelector?this.setElementSelector(null):this.zoomTop()):e.key==="ArrowDown"&&(e.preventDefault(),this.options.elementSelector||this.zoomBottom())};armHold(e,t){this.holdTimer&&clearTimeout(this.holdTimer),this.anchorX=e,this.anchorY=t,this.holdTimer=setTimeout(()=>{this.state.autoZoom&&(this.state.pauseDuringScroll&&performance.now()<this.scrollPausedUntil||(this.zoomToMouse(),this.scheduleIdleZoomOut()))},qe)}scheduleIdleZoomOut(){this.zoomOutTimer&&clearTimeout(this.zoomOutTimer),this.zoomOutTimer=setTimeout(()=>{this.zoomOutTimer=null,!(!this.state.autoZoom||this.options.elementSelector)&&(this.state.pauseDuringScroll&&performance.now()<this.scrollPausedUntil||this.resetFullScreen())},We)}calculateElementRect(e,t=1.1,r){if(typeof document>"u")return null;const n=document.querySelector(e);if(!n)return null;const o=n.getBoundingClientRect(),a=window.innerWidth,l=window.innerHeight,s=this.computeGrid(a,l),u=o.left+o.width/2,c=o.top+o.height/2,d=u/s.cellW,h=(c-k)/s.cellH,m=o.width/s.cellW,y=o.height/s.cellH,p=r??this.state.resolution.w/this.state.resolution.h,w=s.cellH/s.cellW,E=p*w;if(this.options.fixedRecordingRegion){const{w:q,h:z}=this.getRecordingRegionBox(p,b,s.rows,P);return this.clampRect({col:d-q/2,row:h-z/2,w:q,h:z},s.rows)}const S=m*t,T=y*t;let R=Math.max(S,T*E),M=R/E;const Q=d-R/2,ee=h-M/2;return this.clampRect({col:Q,row:ee,w:R,h:M},s.rows)}startCameraLoop(){const e=()=>{if(this.options.elementSelector){const a=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding);a&&(this.targetRect=a)}const t=this.targetRect,r=this.liveRect,o=t.w>r.w?Ge:He;this.liveRect={col:r.col+(t.col-r.col)*o,row:r.row+(t.row-r.row)*o,w:r.w+(t.w-r.w)*o,h:r.h+(t.h-r.h)*o},this.updateState({displayRect:{...this.liveRect}}),this.cameraRafId=requestAnimationFrame(e)};this.cameraRafId=requestAnimationFrame(e)}zoomToMouse(){const e=this.state.resolution.w/this.state.resolution.h;this.targetRect=this.centeredRectOnPoint(this.mousePosGlobal.x,this.mousePosGlobal.y,window.innerWidth,window.innerHeight,e)}getFullFrameRect(e){const t=this.state.resolution.w/this.state.resolution.h,r=this.computeGrid(window.innerWidth,window.innerHeight),{w:n,h:o}=this.getRecordingRegionBox(t,b,r.rows,b),a=e==="top"?0:e==="bottom"?r.rows-o:Math.floor((r.rows-o)/2);return{col:Math.floor((b-n)/2),row:a,w:n,h:o}}setFullFrameRect(e,t=!1){const r=this.getFullFrameRect(e);this.targetRect=r,t&&(this.liveRect={...r},this.updateState({displayRect:{...r}}))}zoomTop(e=!1){this.setFullFrameRect("top",e)}zoomCenter(e=!1){this.setFullFrameRect("center",e)}zoomBottom(e=!1){this.setFullFrameRect("bottom",e)}zoomBottomFold(){this.zoomBottom()}zoomTopFold(e=!1){this.zoomTop(e)}resetFullScreen(){this.zoomCenter()}zoomTopFullFrame(e=!1){this.zoomTop(e)}getRecordingElapsedMs(){return this.recordingStartedAt?Math.max(0,Math.round(performance.now()-this.recordingStartedAt)):0}beginTimelineMetadata(){if(!this.options.includeTimelineMetadata){this.timelineMetadata=null;return}this.timelineMetadata={schema:"code-film.timeline.v1",title:this.activeFilmTitle,fps:this.options.fps,width:this.state.resolution.w,height:this.state.resolution.h,scenes:[],actions:[],markers:[]},this.recordTimelineMarker("recording:start")}finishTimelineMetadata(){if(this.timelineMetadata)return this.recordTimelineMarker("recording:stop"),{...this.timelineMetadata,scenes:this.timelineMetadata.scenes.map(e=>({...e})),actions:this.timelineMetadata.actions.map(e=>({...e})),markers:this.timelineMetadata.markers.map(e=>({...e}))}}recordTimelineMarker(e,t={}){this.timelineMetadata&&this.timelineMetadata.markers.push({timeMs:this.getRecordingElapsedMs(),name:e,...t})}recordOverlayEvent(e){this.recordTimelineMarker(`overlay:${e.type}`,{data:{id:e.id,...e.data}})}renderRecordingOverlays(e){this.overlays.forEach(t=>{t.includeInCapture&&t.draw(e,this.state.resolution.w,this.state.resolution.h)})}createCameraOverlay(e){if(typeof document>"u")throw new Error("[FilmRecorder] createCameraOverlay requires a browser document.");const t=$e(e,r=>{this.recordOverlayEvent(r)});return this.overlays.set(t.id,t),t}registerOverlay(e){if(typeof document>"u")throw new Error("[FilmRecorder] registerOverlay requires a browser document.");const t=Le(e,r=>{this.recordOverlayEvent(r)});return this.overlays.set(t.id,t),t}getOverlay(e){return this.overlays.get(e)??null}removeOverlay(e){const t=this.overlays.get(e);t&&(t.destroy(),this.overlays.delete(e))}setOverlays(e){this.overlays.forEach(t=>t.destroy()),this.overlays.clear(),e.forEach(t=>{t.type==="camera"&&this.createCameraOverlay(t)})}startTimelineScene(e,t){if(!this.timelineMetadata)return null;const r={id:`scene-${t+1}`,name:e.name,declaredStartMs:Math.round(e.startTime*1e3),declaredEndMs:Math.round(e.endTime*1e3),actualStartMs:this.getRecordingElapsedMs(),actualEndMs:null};return this.timelineMetadata.scenes.push(r),this.recordTimelineMarker("scene:start",{data:{label:e.name},scene:e.name}),r}endTimelineScene(e){e&&(e.actualEndMs=this.getRecordingElapsedMs(),this.recordTimelineMarker("scene:end",{data:{label:e.name},scene:e.name}))}startTimelineAction(e,t,r){if(!this.timelineMetadata||!e)return null;const n={type:t.type,startMs:this.getRecordingElapsedMs(),endMs:null,commandIndex:r,scene:e.name,selector:t.selector,to:t.to,padding:t.padding,text:t.text,durationMs:t.durationMs};return this.timelineMetadata.actions.push(n),this.recordTimelineMarker(`command:${t.type}:start`,{data:{label:t.selector??t.to??t.text??t.type},scene:e.name,commandIndex:r}),n}endTimelineAction(e,t){!e||!t||(t.endMs=this.getRecordingElapsedMs(),this.recordTimelineMarker(`command:${t.type}:end`,{data:{label:t.selector??t.to??t.text??t.type},scene:e.name,commandIndex:t.commandIndex}))}getLastRecording(){return this.lastRecording}clearLastRecording(){this.lastRecording&&(URL.revokeObjectURL(this.lastRecording.url),this.lastRecording=null)}getLastRecordingError(){return this.lastRecordingError}normalizeRecordingError(e){return e instanceof Error?e:new Error(typeof e=="string"?e:"Unknown recording error")}handleRecordingError(e){const t=this.normalizeRecordingError(e);return this.lastRecordingError=t,this.updateState({showGrid:this.options.showGrid}),this.options.onRecordingError?.(t),t}async requestCaptureStream(){return navigator.mediaDevices.getDisplayMedia({video:{frameRate:this.options.fps,width:{ideal:3840},height:{ideal:2160}},audio:!0,preferCurrentTab:!0})}async attachCaptureStream(e){this.stream=e,this.videoEl.srcObject=e,await this.videoEl.play(),await this.waitForCaptureVideoFrame()}async waitForCaptureVideoFrame(e=3e3){this.videoEl.videoWidth>0&&this.videoEl.videoHeight>0||await new Promise((t,r)=>{let n=0;const o=window.setTimeout(()=>{a(),r(new Error("Screen capture started, but no video frame was available."))},e),a=()=>{window.clearTimeout(o),n&&cancelAnimationFrame(n),this.videoEl.removeEventListener("loadedmetadata",l),this.videoEl.removeEventListener("canplay",l)},l=()=>{if(this.videoEl.videoWidth>0&&this.videoEl.videoHeight>0){a(),t();return}n=requestAnimationFrame(l)};this.videoEl.addEventListener("loadedmetadata",l),this.videoEl.addEventListener("canplay",l),l()})}stopCaptureStream(){this.stream?.getTracks().forEach(e=>e.stop()),this.stream=null,this.videoEl.srcObject=null}hideIgnoredElements(){this.restoreIgnoredElements(),!(!this.options.ignoreSelector||typeof document>"u")&&document.querySelectorAll(this.options.ignoreSelector).forEach(e=>{e instanceof HTMLElement&&(e.closest(".cfr-settings-bar, .cfr-recording-overlay")||(this.ignoredElements.set(e,{visibility:e.style.getPropertyValue("visibility"),priority:e.style.getPropertyPriority("visibility")}),e.style.setProperty("visibility","hidden","important")))})}restoreIgnoredElements(){this.ignoredElements.forEach((e,t)=>{t.style.setProperty("visibility",e.visibility,e.priority)}),this.ignoredElements.clear()}getActiveCaptureStream(){return this.stream&&this.stream.getTracks().some(e=>e.readyState==="live")?this.stream:null}async prepareCapture(){if(this.getActiveCaptureStream())return!0;try{const e=await this.requestCaptureStream();return await this.attachCaptureStream(e),this.lastRecordingError=null,!0}catch(e){throw this.stopCaptureStream(),this.handleRecordingError(e)}}async startRecording(){if(this.state.recording)return!1;try{const e=this.getActiveCaptureStream();e?await this.attachCaptureStream(e):await this.prepareCapture();const t=this.getActiveCaptureStream();if(!t)throw new Error("No active capture stream is available.");this.options.elementSelector&&(this.options.elementSelector=null,this.updateState({elementSelector:null})),this.zoomTopFullFrame(!0),this.resetPointerEntryPosition(),this.hideIgnoredElements(),this.updateState({showGrid:!1});const r=this.canvasEl.getContext("2d");r.imageSmoothingEnabled=!0,r.imageSmoothingQuality="high",this.canvasEl.width=this.state.resolution.w,this.canvasEl.height=this.state.resolution.h;const n=()=>{const s=window.innerWidth,u=window.innerHeight,c=this.computeGrid(s,u),d=this.liveRect,h=this.videoEl.videoWidth/s,m=this.videoEl.videoHeight/u;r.drawImage(this.videoEl,d.col*c.cellW*h,(k+d.row*c.cellH)*m,d.w*c.cellW*h,d.h*c.cellH*m,0,0,this.state.resolution.w,this.state.resolution.h),this.renderRecordingOverlays(r),this.renderRafId=requestAnimationFrame(n)};n();const o=this.canvasEl.captureStream(this.options.fps);t.getAudioTracks().forEach(s=>o.addTrack(s));const a=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"].find(s=>MediaRecorder.isTypeSupported(s)),l=new MediaRecorder(o,{...a&&{mimeType:a},videoBitsPerSecond:1e7});return this.chunks=[],this.recordingStartedAt=performance.now(),this.beginTimelineMetadata(),l.ondataavailable=s=>{s.data.size&&this.chunks.push(s.data)},l.onstop=()=>{const s=performance.now(),u=new Blob(this.chunks,{type:l.mimeType}),c=URL.createObjectURL(u),d=l.mimeType.includes("mp4")?"capture.mp4":"capture.webm",h=Math.max(0,Math.round(s-this.recordingStartedAt)),m={blob:u,url:c,mimeType:l.mimeType,filename:d,durationMs:h,startedAt:this.recordingStartedAt,stoppedAt:s,timeline:this.finishTimelineMetadata(),webm:l.mimeType.includes("webm")?{seekable:!1,hasDurationMetadata:!1,durationMs:h,sizeBytes:u.size}:void 0};this.clearLastRecording(),this.lastRecording=m;try{this.options.onRecordingStop?.(m)}finally{if(this.options.autoDownload){const y=document.createElement("a");y.href=m.url,y.download=m.filename,y.click()}this.destroyed&&this.clearLastRecording(),this.timelineMetadata=null,this.recordingStartedAt=0,this.activeFilmTitle=null}},l.start(1e3),this.recorder=l,this.lastRecordingError=null,this.updateState({recording:!0}),this.options.onRecordingStart?.(),this.options.movePointerToSelector&&setTimeout(()=>{this.options.movePointerToSelector&&this.state.recording&&this.playPointerTour(this.options.movePointerToSelector)},500),!0}catch(e){throw e===this.lastRecordingError?e:(cancelAnimationFrame(this.renderRafId),this.renderRafId=0,this.stopCaptureStream(),this.restoreIgnoredElements(),this.recorder=null,this.handleRecordingError(e))}}stopRecording(){this.state.recording&&(cancelAnimationFrame(this.renderRafId),this.recorder?.stop(),this.stopCaptureStream(),this.restoreIgnoredElements(),this.recorder=null,this.pointerEl&&(this.pointerEl.style.display="none",this.pointerEl.classList.remove("cfr-holding")),this.tourRafId&&(cancelAnimationFrame(this.tourRafId),this.tourRafId=0),this.updateState({recording:!1,showGrid:this.options.showGrid}))}captureBitmap(){this.state.recording&&this.canvasEl.toBlob(e=>{if(!e)return;const t=document.createElement("a");t.href=URL.createObjectURL(e),t.download="capture.png",t.click(),setTimeout(()=>URL.revokeObjectURL(t.href),1e3)},"image/png")}ensurePointerEl(){typeof window>"u"||typeof document>"u"||(this.pointerEl||(this.pointerEl=document.createElement("div"),this.pointerX=window.innerWidth/2,this.pointerY=window.innerHeight+40,this.pointerEl.style.left=`${this.pointerX}px`,this.pointerEl.style.top=`${this.pointerY}px`,document.body.appendChild(this.pointerEl)),this.applyPointerClassName(),this.applyPointerColors(),this.pointerEl.style.display="block")}applyPointerClassName(){if(!this.pointerEl)return;const e=this.pointerEl.classList.contains("cfr-holding"),t=this.options.pointerClassName.split(/\s+/).filter(Boolean);this.pointerEl.className=["cfr-simulated-pointer",...t].join(" "),e&&this.pointerEl.classList.add("cfr-holding"),this.pointerEl.classList.toggle("cfr-ripple-disabled",this.options.disableRipple)}validatePointerColor(e,t){if(!/^#[0-9a-f]{6}$/i.test(e))throw new TypeError(`[FilmRecorder] ${t} must be a 6-digit hex color.`);return e}applyPointerColors(){if(!this.pointerEl)return;const e=this.validatePointerColor(this.options.pointerFillColor,"pointerFillColor"),t=this.validatePointerColor(this.options.pointerBorderColor,"pointerBorderColor"),r=this.validatePointerColor(this.options.pointerRippleColor,"pointerRippleColor"),n=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="30" viewBox="0 0 24 30" fill="none"><path d="M2 2.25V23.15L7.55 17.83L11.65 27.4L16.05 25.52L12.08 16.25H20.2L2 2.25Z" fill="${e}" stroke="${t}" stroke-width="2.2" stroke-linejoin="round"/></svg>`;this.pointerEl.style.backgroundImage=`url("data:image/svg+xml,${encodeURIComponent(n)}")`,this.pointerEl.style.setProperty("--cfr-pointer-ripple-color",r)}resetPointerEntryPosition(){this.ensurePointerEl(),this.pointerEl&&(this.pointerX=window.innerWidth/2,this.pointerY=window.innerHeight+40,this.pointerEl.style.left=`${this.pointerX}px`,this.pointerEl.style.top=`${this.pointerY}px`,this.pointerEl.classList.remove("cfr-holding"))}async getTargetElement(e,t,r,n=this.options.selectorTimeoutMs){if(typeof e!="string")return e;const o=performance.now();for(;;){if(r?.aborted)throw new DOMException("Aborted","AbortError");const a=document.querySelector(e);if(a)return a;if(performance.now()-o>n)throw this.createSelectorError(e,t);await new Promise(l=>setTimeout(l,50))}}async animatePointerTo(e,t=800,r,n=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;if(this.ensurePointerEl(),r?.aborted)throw new DOMException("Aborted","AbortError");const o=await this.getTargetElement(e,"animatePointerTo",r,n),a=o.getBoundingClientRect(),l=a.left+a.width/2,s=a.top+a.height/2,u=this.pointerX,c=this.pointerY,d=performance.now();return this.tourRafId&&cancelAnimationFrame(this.tourRafId),new Promise((h,m)=>{const y=()=>{cancelAnimationFrame(this.tourRafId),m(new DOMException("Aborted","AbortError"))};r&&r.addEventListener("abort",y);const p=w=>{if(r?.aborted)return;const E=w-d,S=Math.min(E/t,1),T=S<.5?2*S*S:1-Math.pow(-2*S+2,2)/2,R=u+(l-u)*T,M=c+(s-c)*T;this.pointerX=R,this.pointerY=M,this.pointerEl&&(this.pointerEl.style.left=`${R}px`,this.pointerEl.style.top=`${M}px`),S<1?this.tourRafId=requestAnimationFrame(p):(this.dispatchPointerHover(o,l,s),r&&r.removeEventListener("abort",y),h())};this.tourRafId=requestAnimationFrame(p)})}dispatchPointerHover(e,t,r){const n={bubbles:!0,cancelable:!0,view:window,clientX:t,clientY:r};e.dispatchEvent(new MouseEvent("mouseover",n)),e.dispatchEvent(new MouseEvent("mouseenter",{...n,bubbles:!1})),e.dispatchEvent(new MouseEvent("mousemove",n))}async simulateClick(e,t,r=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;if(t?.aborted)throw new DOMException("Aborted","AbortError");if(await this.animatePointerTo(e,600,t,r),t?.aborted)throw new DOMException("Aborted","AbortError");this.pointerEl&&this.pointerEl.classList.add("cfr-holding");let n;try{n=await this.getTargetElement(e,"simulateClick",t,r)}catch(s){throw this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),s}const o=new MouseEvent("mousedown",{bubbles:!0,cancelable:!0,view:window}),a=new MouseEvent("mouseup",{bubbles:!0,cancelable:!0,view:window}),l=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window});n.dispatchEvent(o),n.dispatchEvent(a),n instanceof HTMLElement?n.click():n.dispatchEvent(l),await new Promise((s,u)=>{const c=()=>{clearTimeout(d),this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),u(new DOMException("Aborted","AbortError"))};t&&t.addEventListener("abort",c);const d=setTimeout(()=>{t&&t.removeEventListener("abort",c),this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),s()},250)})}isFormTypingTarget(e){return typeof HTMLInputElement<"u"&&typeof HTMLTextAreaElement<"u"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)?!0:"value"in e&&typeof e.value=="string"}isContentEditableTypingTarget(e){return e instanceof HTMLElement&&e.isContentEditable}dispatchKeyboardInputEvents(e,t,r="insertText"){const n=new KeyboardEvent("keydown",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0}),o=new KeyboardEvent("keypress",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0}),a=new InputEvent("input",{data:r==="insertText"?t:null,inputType:r,bubbles:!0}),l=new KeyboardEvent("keyup",{key:t,charCode:t.length===1?t.charCodeAt(0):0,bubbles:!0});e.dispatchEvent(n),r==="insertText"&&e.dispatchEvent(o),e.dispatchEvent(a),e.dispatchEvent(l)}typeChar(e,t){if(!this.isFormTypingTarget(e)){this.typeContentEditableChar(e,t);return}const r=e.selectionStart??e.value.length,n=e.selectionEnd??e.value.length,o=e.value;e.value=o.substring(0,r)+t+o.substring(n),e.selectionStart=e.selectionEnd=r+1;const a=e._valueTracker;a&&a.setValue(o),this.dispatchKeyboardInputEvents(e,t),e.dispatchEvent(new Event("change",{bubbles:!0}))}typeContentEditableChar(e,t){const r=window.getSelection();if(!r)return;if(!r.rangeCount||!e.contains(r.anchorNode)){const a=document.createRange();a.selectNodeContents(e),a.collapse(!1),r.removeAllRanges(),r.addRange(a)}const n=r.getRangeAt(0);n.deleteContents();const o=document.createTextNode(t);n.insertNode(o),n.setStartAfter(o),n.collapse(!0),r.removeAllRanges(),r.addRange(n),this.dispatchKeyboardInputEvents(e,t),e.dispatchEvent(new Event("change",{bubbles:!0}))}simulateBackspace(e){if(!this.isFormTypingTarget(e)){this.simulateContentEditableBackspace(e);return}const t=e.value;if(t.length===0)return;const r=e.selectionStart??t.length,n=e.selectionEnd??t.length;let o=t,a=r;r!==n?o=t.substring(0,r)+t.substring(n):r>0&&(o=t.substring(0,r-1)+t.substring(r),a=r-1),e.value=o,e.selectionStart=e.selectionEnd=a;const l=e._valueTracker;l&&l.setValue(t),this.dispatchKeyboardInputEvents(e,"Backspace","deleteContentBackward"),e.dispatchEvent(new Event("change",{bubbles:!0}))}simulateContentEditableBackspace(e){const t=window.getSelection();if(!t)return;if(!t.rangeCount||!e.contains(t.anchorNode)){const n=document.createRange();n.selectNodeContents(e),n.collapse(!1),t.removeAllRanges(),t.addRange(n)}const r=t.getRangeAt(0);if(!r.collapsed)r.deleteContents();else if(r.startContainer.nodeType===Node.TEXT_NODE&&r.startOffset>0){const n=r.startContainer;n.textContent=(n.textContent??"").slice(0,r.startOffset-1)+(n.textContent??"").slice(r.startOffset),r.setStart(n,r.startOffset-1),r.collapse(!0)}else return;t.removeAllRanges(),t.addRange(r),this.dispatchKeyboardInputEvents(e,"Backspace","deleteContentBackward"),e.dispatchEvent(new Event("change",{bubbles:!0}))}async focusTypingTarget(e,t,r=this.options.selectorTimeoutMs){const n=await this.getTargetElement(e,"simulateType",t,r);if(!(n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement||this.isContentEditableTypingTarget(n)))throw new Error("[FilmRecorder] Target element for simulateType must be an input, textarea, or contenteditable element.");return await this.simulateClick(n,t,r),n.focus(),n}async simulateType(e,t,r,n){await this.simulateTypeWithRandom(e,t,r,n,Math.random,this.options.selectorTimeoutMs)}async simulateTypeWithRandom(e,t,r,n,o,a=this.options.selectorTimeoutMs){if(typeof window>"u"||typeof document>"u")return;this.throwIfAborted(n);const l=this.resolveTypingOptions(typeof r=="number"?{cps:r}:r),{cps:s,jitter:u,punctuationPauseMs:c,mistakeRate:d}=l,h=await this.focusTypingTarget(e,n,a),m=1e3/s,y=(p,w,E=!1)=>{if(u<=0)return m;let S=1;if(!E&&p>0){const D=t[p-1],B=w;B===D&&/[a-zA-Z0-9]/.test(B)?S=.4:/[a-zA-Z0-9]/.test(D)&&/[a-zA-Z0-9]/.test(B)?S=.75:B===" "?S=1.5:D===" "&&/[a-zA-Z0-9]/.test(B)&&(S=1.25)}const T=/[A-Z]/.test(w),R=p>0&&/[A-Z]/.test(t[p-1]);T&&!R&&!E&&(S+=.4);const M=o(),Q=o(),ee=Math.sqrt(-2*Math.log(M||1e-4))*Math.cos(2*Math.PI*Q),q=Math.exp(ee*u*.8);let z=m*S*q;if(!E&&p>0&&p%18===0&&o()<.6){const D=m*(1.5+o()*2)*u;z+=D}const Ft=Math.max(10,m*.25),It=m*4;return Math.min(It,Math.max(Ft,z))};for(let p=0;p<t.length;p++){this.throwIfAborted(n);const w=t[p];if(d>0&&o()<d&&/[a-z0-9]/i.test(w)){const S=this.getPlausibleTypo(w,o);this.typeChar(h,S);const T=y(p,S,!0)*1.3;await this.delay(T,n),this.throwIfAborted(n),this.simulateBackspace(h);const R=y(p,"Backspace",!0)*1.1;await this.delay(R,n)}this.typeChar(h,w);let E=y(p,w);/[.,!?;;:]/.test(w)&&(E+=c),await this.delay(E,n)}}getPlausibleTypo(e,t){const r={a:"sqwz",b:"vghn",c:"xdfv",d:"ersfcx",e:"wsdr",f:"rtgdvc",g:"tyfhvb",h:"yugjbn",i:"ujko",j:"uikhmn",k:"ijolm",l:"kop",m:"njk",n:"bhjm",o:"iklp",p:"ol",q:"wa",r:"edft",s:"wedxza",t:"rfgy",u:"yhji",v:"cfgb",w:"qase",x:"zsdc",y:"tghu",z:"asx"},n=e.toLowerCase(),o=r[n]??"abcdefghijklmnopqrstuvwxyz",a=o[Math.floor(t()*o.length)];return e===e.toUpperCase()?a.toUpperCase():a}playPointerTour(e,t){if(typeof window>"u"||typeof document>"u")return Promise.resolve();const r=t?.moveDuration??1e3,n=t?.holdDuration??2e3;if(this.ensurePointerEl(),!this.pointerEl)return Promise.resolve();this.pointerEl.style.display="block",this.pointerEl.classList.remove("cfr-holding"),this.resetFullScreen();const o=document.querySelector(e);if(!o)return console.warn(`[FilmRecorder] Pointer tour target element not found: ${e}`),Promise.resolve();const a=o.getBoundingClientRect(),l=a.left+a.width/2,s=a.top+a.height/2,u=this.pointerX,c=this.pointerY,d=performance.now();return this.tourRafId&&cancelAnimationFrame(this.tourRafId),new Promise(h=>{const m=y=>{const p=y-d,w=Math.min(p/r,1),E=w<.5?2*w*w:1-Math.pow(-2*w+2,2)/2,S=u+(l-u)*E,T=c+(s-c)*E;if(this.pointerX=S,this.pointerY=T,this.pointerEl&&(this.pointerEl.style.left=`${S}px`,this.pointerEl.style.top=`${T}px`),w<1)this.tourRafId=requestAnimationFrame(m);else{this.pointerEl&&this.pointerEl.classList.add("cfr-holding"),this.mousePosGlobal={x:l,y:s};const R=this.state.resolution.w/this.state.resolution.h;this.targetRect=this.centeredRectOnPoint(l,s,window.innerWidth,window.innerHeight,R),setTimeout(()=>{this.pointerEl&&this.pointerEl.classList.remove("cfr-holding"),this.resetFullScreen(),setTimeout(()=>{this.pointerEl&&!this.pointerEl.classList.contains("cfr-holding")&&(this.pointerEl.style.display="none"),h()},1e3)},n)}};this.tourRafId=requestAnimationFrame(m)})}getState(){return{...this.state}}onStateChange(e){return this.listeners.add(e),e(this.getState()),()=>this.listeners.delete(e)}updateState(e){this.state={...this.state,...e},this.listeners.forEach(t=>t(this.state))}setResolution(e){if(this.state.recording)return;this.updateState({resolution:e});const t=this.computeGrid(window.innerWidth,window.innerHeight),r=e.w/e.h,{w:n,h:o}=this.getRecordingRegionBox(r,b,t.rows,b),a=Math.floor((b-n)/2),l=Math.floor((t.rows-o)/2);this.targetRect={col:a,row:l,w:n,h:o},this.liveRect={...this.targetRect}}setAutoZoom(e){this.updateState({autoZoom:e})}setPauseDuringScroll(e){this.updateState({pauseDuringScroll:e})}setShowGrid(e){this.updateState({showGrid:e})}setShowOutline(e){this.updateState({showOutline:e})}setMousePaused(e){this.updateState({mousePaused:e})}setElementSelector(e){if(this.options.elementSelector=e,this.updateState({elementSelector:e}),e){const t=this.calculateElementRect(e,this.options.elementPadding);t&&(this.targetRect=t)}else this.resetFullScreen()}setElementPadding(e){if(this.options.elementPadding=e,this.updateState({elementPadding:e}),this.options.elementSelector){const t=this.calculateElementRect(this.options.elementSelector,e);t&&(this.targetRect=t)}}setFixedRecordingRegion(e){if(this.options.fixedRecordingRegion=e,this.updateState({fixedRecordingRegion:e}),this.options.elementSelector){const t=this.calculateElementRect(this.options.elementSelector,this.options.elementPadding);t&&(this.targetRect=t)}else this.resetFullScreen()}setMovePointerToSelector(e){this.options.movePointerToSelector=e,this.updateState({movePointerToSelector:e})}setPointerClassName(e){this.options.pointerClassName=e,this.updateState({pointerClassName:e}),this.applyPointerClassName()}setPointerFillColor(e){this.options.pointerFillColor=this.validatePointerColor(e,"pointerFillColor"),this.updateState({pointerFillColor:this.options.pointerFillColor}),this.applyPointerColors()}setPointerBorderColor(e){this.options.pointerBorderColor=this.validatePointerColor(e,"pointerBorderColor"),this.updateState({pointerBorderColor:this.options.pointerBorderColor}),this.applyPointerColors()}setPointerRippleColor(e){this.options.pointerRippleColor=this.validatePointerColor(e,"pointerRippleColor"),this.updateState({pointerRippleColor:this.options.pointerRippleColor}),this.applyPointerColors()}setDisableRipple(e){this.options.disableRipple=e,this.updateState({disableRipple:e}),this.applyPointerClassName()}setIgnoreSelector(e){this.restoreIgnoredElements(),this.options.ignoreSelector=e,this.updateState({ignoreSelector:e}),this.state.recording&&this.hideIgnoredElements()}setTypingDefaults(e){this.options.typingDefaults=this.resolveTypingOptions(e)}resolveSelectorTimeoutMs(e){const t=e??this.options.selectorTimeoutMs;if(!Number.isFinite(t)||t<0)throw new TypeError("[FilmRecorder] selectorTimeoutMs must be a finite number >= 0.");return t}resolveTypingOptions(...e){const t={...re};for(const r of e)if(r)for(const n of Object.keys(r)){const o=r[n];o!==void 0&&(t[n]=o)}return this.validateTypingOptions(t),{...t}}validateTypingOptions(e,t="[FilmRecorder] Invalid typing options"){const r=[["cps",e.cps,"must be a finite number greater than 0"],["jitter",e.jitter,"must be between 0 and 1"],["punctuationPauseMs",e.punctuationPauseMs,"must be a finite number greater than or equal to 0"],["mistakeRate",e.mistakeRate,"must be between 0 and 1"]];for(const[n,o,a]of r){if(o===void 0)continue;if(!(Number.isFinite(o)&&(n==="cps"?o>0:n==="punctuationPauseMs"?o>=0:o>=0&&o<=1)))throw new TypeError(`${t}: ${n} ${a}; received ${String(o)}.`)}}delay(e,t){return new Promise((r,n)=>{if(t?.aborted)return n(new DOMException("Aborted","AbortError"));const o=()=>{clearTimeout(a),n(new DOMException("Aborted","AbortError"))};t&&t.addEventListener("abort",o);const a=setTimeout(()=>{t&&t.removeEventListener("abort",o),r()},e)})}findElementByText(e){if(typeof document>"u")return null;try{const r=`//*[text()='${e}' or contains(text(), '${e}')]`,o=document.evaluate(r,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(o)return o}catch{}const t=Array.from(document.querySelectorAll("button, a, label, span, div, h1, h2, h3, h4, p"));for(const r of t)if(r.textContent?.trim()===e)return r;for(const r of t)if(r.textContent?.includes(e))return r;return null}async findElementByTextAsync(e,t,r=3e3){const n=performance.now();for(;;){if(t?.aborted)throw new DOMException("Aborted","AbortError");const o=this.findElementByText(e);if(o)return o;if(performance.now()-n>r)return null;await new Promise(a=>setTimeout(a,50))}}async clickText(e,t){const r=await this.findElementByTextAsync(e,t,this.options.selectorTimeoutMs);if(!r)throw this.createSelectorError(e,"clickText");await this.simulateClick(r,t)}async focusText(e,t){const r=await this.findElementByTextAsync(e,t,this.options.selectorTimeoutMs);if(!r)throw this.createSelectorError(e,"focusText");const n="data-cfr-temp-focus";r.setAttribute(n,"true"),this.setElementSelector(`[${n}="true"]`),await this.animatePointerTo(r,800,t)}createSelectorError(e,t){const r=this.state.currentScene?` in scene "${this.state.currentScene}"`:"";return new Error(`[FilmRecorder] Selector safety check failed for "${e}" during action "${t}"${r}.
|
|
2
2
|
Suggested fix: Ensure the element is mounted in the DOM, or add a stable attribute like data-film-target="${e}" or data-testid.`)}validateFilmScript(e){const t=G(e),r=[];t.length===0&&r.push({line:1,scene:null,commandIndex:null,message:"No film script scenes were found."});for(const n of t)n.commands.forEach((o,a)=>{if(["camera","type","click","pointer","move"].includes(o.type)&&o.type!=="camera"&&!o.selector&&r.push({line:o.sourceLine??1,scene:n.name,commandIndex:a,message:`${o.type} requires a non-empty selector.`}),o.type==="type"&&o.text===void 0&&r.push({line:o.sourceLine??1,scene:n.name,commandIndex:a,message:"type requires text."}),o.type==="type")try{this.validateTypingOptions({cps:o.cps,jitter:o.jitter,punctuationPauseMs:o.punctuationPauseMs,mistakeRate:o.mistakeRate},`[FilmRecorder] Invalid type command in scene "${n.name}"`)}catch(l){r.push({line:o.sourceLine??1,scene:n.name,commandIndex:a,message:l instanceof Error?l.message:String(l)})}});return{valid:r.length===0,scenes:t,diagnostics:r}}createScriptValidationError(e){const t=e.map(r=>{const n=r.scene?` scene "${r.scene}"`:"",o=r.commandIndex===null?"":` command ${r.commandIndex}`;return`line ${r.line}${n}${o}: ${r.message}`}).join(`
|
|
3
3
|
`);return new Error(`[FilmRecorder] Invalid film script:
|
|
4
|
-
${t}`)}updateTourState(e,t=null){this.updateState({tourState:e,currentScene:t})}async stopTour(){this.tourAbortController&&(this.tourAbortController.abort(),this.tourAbortController=null),this.activeExecutionPromise=null,this.finalizationPromise=null,this.pendingActionGates=[],this.activeFilmScriptContext=null,this.activeFilmScriptOptions=null,this.updateState({tourState:"stopped",executionState:"finished",currentScene:null}),await this.options.onTourStop?.()}async stopAll(){await this.stopTour(),this.stopRecording()}finishRecording(e){const t=typeof e=="function"?{onReadyToEnd:e}:e??{};if(this.finalizationPromise&&!t.force)return this.finalizationPromise;const r=this.finalizeRecording(t);return t.force||(this.finalizationPromise=r),r}async finalizeRecording(e){const t=this.activeFilmScriptContext??{recorder:this,signal:new AbortController().signal,scenes:[]};try{e.force?this.tourAbortController?.abort():(await this.activeExecutionPromise,this.updateState({executionState:"waiting"}),await this.awaitActionGates(t)),this.updateState({executionState:"finalizing"}),await e.onReadyToEnd?.(t),await this.activeFilmScriptOptions?.onReadyToEnd?.(t),await this.options.onReadyToEnd?.(t),this.options.elementSelector&&(this.options.elementSelector=null,this.updateState({elementSelector:null})),this.zoomTopFullFrame(),await this.delay(1e3,e.force?void 0:t.signal),this.state.recording&&this.stopRecording(),await this.completeActiveFilmScript(t)}catch(r){throw await this.failActiveFilmScript(t,r),r}}executeFilmScript(e,t={}){this.activeFilmTitle=
|
|
5
|
-
`).length,h=
|
|
6
|
-
`).length;if(a[3]){const p=parseFloat(a[3]);n({type:"wait",durationMs:a[4]==="s"?p*1e3:p},l);continue}const s=a[1],u=a[2],c=p=>{const w=new RegExp(`${p}:\\s*(?:"([^"]*)"|'([^']*)')`).exec(u);return w?w[1]??w[2]:void 0},d=p=>{const w=new RegExp(`${p}:\\s*([^\\s}]+)`).exec(u);return w?Number(w[1]):void 0},h=()=>{const p=c("to")??c("position");return p==="top"||p==="bottom"||p==="center"?p:void 0},y=/selector:\s*(null|undefined)/.exec(u)?null:c("selector");n(s==="camera"?{type:s,selector:y??null,padding:d("padding")??1.1}:s==="zoom"?{type:s,to:h()??"center"}:s==="type"?{type:s,selector:y,text:c("text"),cps:d("cps"),jitter:d("jitter"),punctuationPauseMs:d("punctuationPauseMs"),mistakeRate:d("mistakeRate")}:s==="pointer"||s==="move"?{type:s,selector:y,durationMs:d("durationMs")??800}:{type:s,selector:y},l)}return t}class
|
|
4
|
+
${t}`)}updateTourState(e,t=null){this.updateState({tourState:e,currentScene:t})}async stopTour(){this.tourAbortController&&(this.tourAbortController.abort(),this.tourAbortController=null),this.activeExecutionPromise=null,this.finalizationPromise=null,this.pendingActionGates=[],this.activeFilmScriptContext=null,this.activeFilmScriptOptions=null,this.updateState({tourState:"stopped",executionState:"finished",currentScene:null}),await this.options.onTourStop?.()}async stopAll(){await this.stopTour(),this.stopRecording()}finishRecording(e){const t=typeof e=="function"?{onReadyToEnd:e}:e??{};if(this.finalizationPromise&&!t.force)return this.finalizationPromise;const r=this.finalizeRecording(t);return t.force||(this.finalizationPromise=r),r}async finalizeRecording(e){const t=this.activeFilmScriptContext??{recorder:this,signal:new AbortController().signal,scenes:[]};try{e.force?this.tourAbortController?.abort():(await this.activeExecutionPromise,this.updateState({executionState:"waiting"}),await this.awaitActionGates(t)),this.updateState({executionState:"finalizing"}),await e.onReadyToEnd?.(t),await this.activeFilmScriptOptions?.onReadyToEnd?.(t),await this.options.onReadyToEnd?.(t),this.options.elementSelector&&(this.options.elementSelector=null,this.updateState({elementSelector:null})),this.zoomTopFullFrame(),await this.delay(1e3,e.force?void 0:t.signal),this.state.recording&&this.stopRecording(),await this.completeActiveFilmScript(t)}catch(r){throw await this.failActiveFilmScript(t,r),r}}executeFilmScript(e,t={}){this.activeFilmTitle=Ye(e),this.timelineMetadata&&!this.timelineMetadata.title&&(this.timelineMetadata.title=this.activeFilmTitle);const r=this.validateFilmScript(e);if(!r.valid)return Promise.reject(this.createScriptValidationError(r.diagnostics));try{this.resolveTypingOptions(this.options.typingDefaults,t.typingDefaults)}catch(o){return Promise.reject(o)}this.tourAbortController&&this.tourAbortController.abort(),this.pendingActionGates=[],this.finalizationPromise=null;const n=this.executeFilmScriptScenes(r.scenes,t);return this.activeExecutionPromise=n,n.finally(()=>{this.activeExecutionPromise===n&&(this.activeExecutionPromise=null),this.state.executionState==="executing"&&this.updateState({executionState:"waiting"})})}async executeFilmScriptScenes(e,t){const r=this.resolveTypingOptions(this.options.typingDefaults,t.typingDefaults);this.activeTypingRandom=this.createSeededRandom(t.typingSeed??this.options.typingSeed);const n=this.resolveSelectorTimeoutMs(t.selectorTimeoutMs);this.tourAbortController=new AbortController;const o=t.signal?this.linkAbortSignals(t.signal,this.tourAbortController.signal):this.tourAbortController.signal,a={recorder:this,signal:o,scenes:e};this.activeFilmScriptContext=a,this.activeFilmScriptOptions=t,this.updateState({tourState:"running",executionState:"executing",currentScene:null});try{await this.options.onTourStart?.();for(const[l,s]of e.entries()){this.throwIfAborted(o);const u=performance.now(),c=this.startTimelineScene(s,l);this.updateTourState("running",s.name),await t.onSceneStart?.(s),await this.options.onSceneStart?.(s);for(const[y,p]of s.commands.entries()){this.throwIfAborted(o);const w=performance.now(),E=this.startTimelineAction(c,p,y),S=R=>{const M=Promise.resolve(R).then(()=>{});M.catch(()=>{}),this.pendingActionGates.push({promise:M,scene:s,command:p,commandIndex:y})},T=()=>({...a,scene:s,command:p,commandIndex:y,elapsedMs:performance.now()-w,waitUntil:S});switch(await t.onActionStart?.(T()),await this.options.onActionStart?.(T()),p.type){case"camera":p.selector?(this.setElementSelector(p.selector),this.setElementPadding(p.padding??1.1)):(this.setElementSelector(null),this.zoomCenter());break;case"zoom":this.setElementSelector(null),p.to==="top"?this.zoomTop():p.to==="bottom"?this.zoomBottom():this.zoomCenter();break;case"type":if(p.selector&&p.text){const R=this.resolveTypingOptions(r,{cps:p.cps,jitter:p.jitter,punctuationPauseMs:p.punctuationPauseMs,mistakeRate:p.mistakeRate});await this.simulateTypeWithRandom(p.selector,p.text,R,o,this.activeTypingRandom,n)}break;case"click":p.selector&&await this.simulateClick(p.selector,o,n);break;case"pointer":case"move":p.selector&&await this.animatePointerTo(p.selector,p.durationMs??800,o,n);break;case"wait":p.durationMs&&await this.delay(p.durationMs,o);break}await t.onActionEnd?.(T()),await this.options.onActionEnd?.(T()),this.endTimelineAction(c,E)}const d=(s.endTime-s.startTime)*1e3,h=performance.now()-u,m=d-h;m>0&&await this.delay(m,o),await t.onSceneEnd?.(s),await this.options.onSceneEnd?.(s),this.endTimelineScene(c)}}catch(l){throw await this.failActiveFilmScript(a,l),l}}async runFilmScript(e,t={}){try{await this.executeFilmScript(e,t);const r=this.activeFilmScriptContext;if(!r)return;if(t.waitForCompletion){const n=Promise.resolve(t.waitForCompletion(r)).then(()=>{});n.catch(()=>{}),this.pendingActionGates.push({promise:n,scene:r.scenes[r.scenes.length-1]??{name:"completion",startTime:0,endTime:0,commands:[]},command:{type:"wait"},commandIndex:-1})}await this.finishRecording()}catch(r){const n=this.activeFilmScriptContext;if(n&&await this.failActiveFilmScript(n,r),!this.isAbortError(r))throw r}}async awaitActionGates(e){const t=this.activeFilmScriptOptions?.completionTimeoutMs??te;for(let r=0;r<this.pendingActionGates.length;r++){const n=this.pendingActionGates[r];try{await this.waitForCompletion(n.promise,e.signal,t)}catch(o){if(this.isAbortError(o))throw o;const a=o instanceof Error?o.message:String(o);throw new Error(`[FilmRecorder] Completion gate failed in scene "${n.scene.name}", command ${n.commandIndex} (${n.command.type}): ${a}`)}}}async waitForCompletion(e,t,r){if(!Number.isFinite(r)||r<=0)throw new Error("[FilmRecorder] completionTimeoutMs must be a positive finite number.");this.throwIfAborted(t);let n,o;const a=new Promise((s,u)=>{n=setTimeout(()=>{u(new Error(`[FilmRecorder] waitForCompletion timed out after ${r}ms.`))},r)}),l=new Promise((s,u)=>{o=()=>u(new DOMException("Aborted","AbortError")),t.addEventListener("abort",o,{once:!0})});try{await Promise.race([Promise.resolve(e),a,l])}finally{n&&clearTimeout(n),o&&t.removeEventListener("abort",o)}}throwIfAborted(e){if(e?.aborted)throw new DOMException("Aborted","AbortError")}createSeededRandom(e){if(e===void 0||e==="")return Math.random;let t=2166136261;for(const r of String(e))t^=r.charCodeAt(0),t=Math.imul(t,16777619);return()=>{t+=1831565813;let r=t;return r=Math.imul(r^r>>>15,r|1),r^=r+Math.imul(r^r>>>7,r|61),((r^r>>>14)>>>0)/4294967296}}isAbortError(e){return typeof e=="object"&&e!==null&&"name"in e&&e.name==="AbortError"}async completeActiveFilmScript(e){if(!this.activeFilmScriptContext&&e.scenes.length===0){this.updateState({executionState:"finished"});return}this.activeFilmScriptContext===e&&(this.activeFilmScriptContext=null,this.activeFilmScriptOptions=null,this.tourAbortController=null,this.activeExecutionPromise=null,this.pendingActionGates=[],this.updateState({tourState:"stopped",executionState:"finished",currentScene:null}),await this.options.onTourStop?.())}async failActiveFilmScript(e,t){if(this.activeFilmScriptContext!==e)return;if(this.tourAbortController?.abort(),this.activeFilmScriptContext=null,this.activeFilmScriptOptions=null,this.tourAbortController=null,this.activeExecutionPromise=null,this.pendingActionGates=[],this.isAbortError(t)){this.updateState({tourState:"stopped",executionState:"finished",currentScene:null}),await this.options.onTourStop?.();return}const r=t instanceof Error?t:new Error(String(t));this.updateState({tourState:"error",executionState:"error",currentScene:null}),await this.options.onTourError?.(r)}linkAbortSignals(e,t){const r=new AbortController,n=()=>r.abort();return e.aborted||t.aborted?(r.abort(),r.signal):(e.addEventListener("abort",n),t.addEventListener("abort",n),r.signal.addEventListener("abort",()=>{e.removeEventListener("abort",n),t.removeEventListener("abort",n)}),r.signal)}destroy(){this.destroyed=!0,this.cleanupEventListeners(),cancelAnimationFrame(this.cameraRafId),cancelAnimationFrame(this.renderRafId),this.holdTimer&&clearTimeout(this.holdTimer),this.zoomOutTimer&&clearTimeout(this.zoomOutTimer),this.state.recording?this.stopRecording():(this.stopCaptureStream(),this.restoreIgnoredElements()),this.pointerEl&&this.pointerEl.parentNode&&(this.pointerEl.parentNode.removeChild(this.pointerEl),this.pointerEl=null),this.overlays.forEach(e=>e.destroy()),this.overlays.clear(),this.tourRafId&&cancelAnimationFrame(this.tourRafId),this.videoEl&&this.videoEl.parentNode&&this.videoEl.parentNode.removeChild(this.videoEl),this.canvasEl&&this.canvasEl.parentNode&&this.canvasEl.parentNode.removeChild(this.canvasEl),this.clearLastRecording(),this.listeners.clear()}}function Ye(i){const e=/\bfilm\s+"([^"]+)"/.exec(i);return e?e[1]:null}function G(i){const e=[],t=/scene\s+"([^"]+)"\s+@(\d+(?:\.\d+)?)s\s*->\s*(\d+(?:\.\d+)?)s\s*\{/g;let r;for(;(r=t.exec(i))!==null;){const n=r[1],o=parseFloat(r[2]),a=parseFloat(r[3]);let l=1,s=t.lastIndex;const u=s;for(;l>0&&s<i.length;){const m=i[s];m==="{"?l++:m==="}"&&l--,s++}const c=i.substring(u,s-1),d=i.slice(0,r.index).split(`
|
|
5
|
+
`).length,h=Ke(c,d);e.push({name:n,startTime:o,endTime:a,commands:h})}return e}function Ke(i,e){const t=[],r=i.replace(/\/\/.*$/gm,l=>" ".repeat(l.length)),n=(l,s)=>{Object.defineProperty(l,"sourceLine",{value:s,enumerable:!1,configurable:!0}),t.push(l)},o=/\b(camera|zoom|type|click|pointer|move)\s*\{([\s\S]*?)\}|\bwait\s+(\d+(?:\.\d+)?)(ms|s)/g;let a;for(;(a=o.exec(r))!==null;){const l=e+i.slice(0,a.index).split(`
|
|
6
|
+
`).length;if(a[3]){const p=parseFloat(a[3]);n({type:"wait",durationMs:a[4]==="s"?p*1e3:p},l);continue}const s=a[1],u=a[2],c=p=>{const w=new RegExp(`${p}:\\s*(?:"([^"]*)"|'([^']*)')`).exec(u);return w?w[1]??w[2]:void 0},d=p=>{const w=new RegExp(`${p}:\\s*([^\\s}]+)`).exec(u);return w?Number(w[1]):void 0},h=()=>{const p=c("to")??c("position");return p==="top"||p==="bottom"||p==="center"?p:void 0},y=/selector:\s*(null|undefined)/.exec(u)?null:c("selector");n(s==="camera"?{type:s,selector:y??null,padding:d("padding")??1.1}:s==="zoom"?{type:s,to:h()??"center"}:s==="type"?{type:s,selector:y,text:c("text"),cps:d("cps"),jitter:d("jitter"),punctuationPauseMs:d("punctuationPauseMs"),mistakeRate:d("mistakeRate")}:s==="pointer"||s==="move"?{type:s,selector:y,durationMs:d("durationMs")??800}:{type:s,selector:y},l)}return t}class Ve{recorder;container;unsubscribe=null;settingsBar=null;gridOverlay=null;cropBox=null;recordBtn=null;pngBtn=null;resSelect=null;gridCheckbox=null;autoZoomCheckbox=null;pauseScrollCheckbox=null;outlineCheckbox=null;constructor(e,t=document.body){this.recorder=e,this.container=t,this.mount()}mount(){if(typeof window>"u")return;this.settingsBar=document.createElement("div"),this.settingsBar.className="cfr-settings-bar",this.settingsBar.innerHTML=`
|
|
7
7
|
<div class="cfr-settings-bar-content">
|
|
8
8
|
<button class="cfr-btn cfr-btn-default" id="cfr-record-btn" aria-label="Start recording">
|
|
9
9
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><circle cx="12" cy="12" r="10"/></svg>
|
|
@@ -47,21 +47,21 @@ ${t}`)}updateTourState(e,t=null){this.updateState({tourState:e,currentScene:t})}
|
|
|
47
47
|
<span class="cfr-label">Show outline border</span>
|
|
48
48
|
</label>
|
|
49
49
|
</div>
|
|
50
|
-
`,this.container.appendChild(this.settingsBar),this.gridOverlay=document.createElement("div"),this.gridOverlay.className="cfr-grid-overlay",this.gridOverlay.setAttribute("aria-hidden","true"),this.gridOverlay.style.top=`${
|
|
50
|
+
`,this.container.appendChild(this.settingsBar),this.gridOverlay=document.createElement("div"),this.gridOverlay.className="cfr-grid-overlay",this.gridOverlay.setAttribute("aria-hidden","true"),this.gridOverlay.style.top=`${k}px`,this.container.appendChild(this.gridOverlay),this.cropBox=document.createElement("div"),this.cropBox.className="cfr-crop-box",this.cropBox.setAttribute("aria-label","Cinematic 16:9 capture region");const e=this.recorder.getState().showOutline;this.cropBox.style.outline=e?`${F}px solid var(--cfr-outline)`:"none",this.cropBox.style.outlineOffset=e?`${F}px`:"0",this.container.appendChild(this.cropBox),this.recordBtn=this.container.querySelector("#cfr-record-btn"),this.pngBtn=this.container.querySelector("#cfr-png-btn"),this.resSelect=this.container.querySelector("#cfr-res-select"),this.gridCheckbox=this.container.querySelector("#cfr-grid-check"),this.autoZoomCheckbox=this.container.querySelector("#cfr-auto-zoom-check"),this.pauseScrollCheckbox=this.container.querySelector("#cfr-pause-scroll-check"),this.outlineCheckbox=this.container.querySelector("#cfr-outline-check");const t=this.container.querySelector("#cfr-full-btn"),r=this.container.querySelector("#cfr-focus-btn"),n=this.container.querySelector("#cfr-pause-mouse-btn"),o=/Mac/i.test(navigator.platform)?"⌘":"Ctrl";this.recordBtn&&(this.recordBtn.querySelector(".cfr-kbd").textContent=`${o}+${N.toUpperCase()}`),t&&(t.querySelector(".cfr-kbd").textContent=`${o}+↑`),r&&(r.querySelector(".cfr-kbd").textContent=`${o}+↓`),n&&(n.querySelector(".cfr-kbd").textContent=`${o}+L`),this.recorder.getState();const a=this.recorder.options.resolutions;a.forEach(l=>{const s=document.createElement("option");s.value=l.label,s.textContent=l.label,this.resSelect&&this.resSelect.appendChild(s)}),this.recordBtn?.addEventListener("click",()=>{this.recorder.getState().recording?this.recorder.stopRecording():this.recorder.startRecording()}),this.pngBtn?.addEventListener("click",()=>this.recorder.captureBitmap()),t?.addEventListener("click",()=>this.recorder.resetFullScreen()),r?.addEventListener("click",()=>this.recorder.zoomToMouse()),n?.addEventListener("click",()=>{const l=this.recorder.getState().mousePaused;this.recorder.setMousePaused(!l)}),this.resSelect?.addEventListener("change",l=>{const s=l.target.value,u=a.find(c=>c.label===s);u&&this.recorder.setResolution(u)}),this.gridCheckbox?.addEventListener("change",l=>{this.recorder.setShowGrid(l.target.checked)}),this.autoZoomCheckbox?.addEventListener("change",l=>{this.recorder.setAutoZoom(l.target.checked)}),this.pauseScrollCheckbox?.addEventListener("change",l=>{this.recorder.setPauseDuringScroll(l.target.checked)}),this.outlineCheckbox?.addEventListener("change",l=>{this.recorder.setShowOutline(l.target.checked)}),this.unsubscribe=this.recorder.onStateChange(l=>this.updateDOM(l))}updateDOM(e){if(typeof window>"u")return;const t=this.recorder.computeGrid(e.viewport.w,e.viewport.h);if(this.recordBtn&&(e.recording?(this.recordBtn.className="cfr-btn cfr-btn-destructive",this.recordBtn.innerHTML=`
|
|
51
51
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>
|
|
52
52
|
${e.mousePaused?"Paused":"Stop"}
|
|
53
|
-
<span class="cfr-kbd">${/Mac/i.test(navigator.platform)?"⌘":"Ctrl"}+${
|
|
53
|
+
<span class="cfr-kbd">${/Mac/i.test(navigator.platform)?"⌘":"Ctrl"}+${N.toUpperCase()}</span>
|
|
54
54
|
`):(this.recordBtn.className="cfr-btn cfr-btn-default",this.recordBtn.innerHTML=`
|
|
55
55
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><circle cx="12" cy="12" r="10"/></svg>
|
|
56
56
|
Record
|
|
57
|
-
<span class="cfr-kbd">${/Mac/i.test(navigator.platform)?"⌘":"Ctrl"}+${
|
|
57
|
+
<span class="cfr-kbd">${/Mac/i.test(navigator.platform)?"⌘":"Ctrl"}+${N.toUpperCase()}</span>
|
|
58
58
|
`)),this.pngBtn&&(this.pngBtn.disabled=!e.recording),this.resSelect&&(this.resSelect.disabled=e.recording,this.resSelect.value=e.resolution.label),this.gridCheckbox&&(this.gridCheckbox.disabled=e.recording,this.gridCheckbox.checked=e.showGrid),this.autoZoomCheckbox&&(this.autoZoomCheckbox.checked=e.autoZoom),this.pauseScrollCheckbox&&(this.pauseScrollCheckbox.checked=e.pauseDuringScroll),this.outlineCheckbox&&(this.outlineCheckbox.checked=e.showOutline),this.gridOverlay){const r=e.showGrid&&!e.recording;this.gridOverlay.style.display=r?"block":"none",r&&(this.gridOverlay.style.backgroundImage=`
|
|
59
59
|
linear-gradient(to right, var(--cfr-border) 1px, transparent 1px),
|
|
60
60
|
linear-gradient(to bottom, var(--cfr-border) 1px, transparent 1px)
|
|
61
|
-
`,this.gridOverlay.style.backgroundSize=`${t.cellW}px ${t.cellH}px`)}if(this.cropBox){const r={x:e.displayRect.col*t.cellW,y:
|
|
61
|
+
`,this.gridOverlay.style.backgroundSize=`${t.cellW}px ${t.cellH}px`)}if(this.cropBox){const r={x:e.displayRect.col*t.cellW,y:k+e.displayRect.row*t.cellH,width:e.displayRect.w*t.cellW,height:e.displayRect.h*t.cellH};this.cropBox.style.left=`${r.x}px`,this.cropBox.style.top=`${r.y}px`,this.cropBox.style.width=`${r.width}px`,this.cropBox.style.height=`${r.height}px`,this.cropBox.style.outline=e.showOutline?`${F}px solid var(--cfr-outline)`:"none",this.cropBox.style.outlineOffset=e.showOutline?`${F}px`:"0"}}unmount(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null),this.settingsBar&&this.settingsBar.parentNode&&this.settingsBar.parentNode.removeChild(this.settingsBar),this.gridOverlay&&this.gridOverlay.parentNode&&this.gridOverlay.parentNode.removeChild(this.gridOverlay),this.cropBox&&this.cropBox.parentNode&&this.cropBox.parentNode.removeChild(this.cropBox)}}function oe(i={}){const e=v.useRef(i);e.current=i;const[t,r]=v.useState(null),[n,o]=v.useState("idle"),[a,l]=v.useState(null),s=v.useRef(null);v.useEffect(()=>{const d=new ne(e.current);s.current=d;const h=d.getState();r(h),o(h.tourState),l(h.currentScene);const m=d.onStateChange(y=>{r(y),o(y.tourState),l(y.currentScene)});return()=>{m(),d.destroy(),s.current=null}},[]),v.useEffect(()=>{s.current&&i.autoZoom!==void 0&&s.current.setAutoZoom(i.autoZoom)},[i.autoZoom]),v.useEffect(()=>{s.current&&i.pauseDuringScroll!==void 0&&s.current.setPauseDuringScroll(i.pauseDuringScroll)},[i.pauseDuringScroll]),v.useEffect(()=>{s.current&&i.showGrid!==void 0&&s.current.setShowGrid(i.showGrid)},[i.showGrid]),v.useEffect(()=>{s.current&&i.showOutline!==void 0&&s.current.setShowOutline(i.showOutline)},[i.showOutline]),v.useEffect(()=>{s.current&&i.elementSelector!==void 0&&s.current.setElementSelector(i.elementSelector)},[i.elementSelector]),v.useEffect(()=>{s.current&&i.elementPadding!==void 0&&s.current.setElementPadding(i.elementPadding)},[i.elementPadding]),v.useEffect(()=>{s.current&&i.fixedRecordingRegion!==void 0&&s.current.setFixedRecordingRegion(i.fixedRecordingRegion)},[i.fixedRecordingRegion]),v.useEffect(()=>{s.current&&i.movePointerToSelector!==void 0&&s.current.setMovePointerToSelector(i.movePointerToSelector)},[i.movePointerToSelector]),v.useEffect(()=>{s.current&&i.ignoreSelector!==void 0&&s.current.setIgnoreSelector(i.ignoreSelector)},[i.ignoreSelector]),v.useEffect(()=>{s.current&&i.pointerClassName!==void 0&&s.current.setPointerClassName(i.pointerClassName)},[i.pointerClassName]),v.useEffect(()=>{s.current&&i.pointerFillColor!==void 0&&s.current.setPointerFillColor(i.pointerFillColor)},[i.pointerFillColor]),v.useEffect(()=>{s.current&&i.pointerBorderColor!==void 0&&s.current.setPointerBorderColor(i.pointerBorderColor)},[i.pointerBorderColor]),v.useEffect(()=>{s.current&&i.pointerRippleColor!==void 0&&s.current.setPointerRippleColor(i.pointerRippleColor)},[i.pointerRippleColor]),v.useEffect(()=>{s.current&&i.disableRipple!==void 0&&s.current.setDisableRipple(i.disableRipple)},[i.disableRipple]),v.useEffect(()=>{s.current&&i.overlays!==void 0&&s.current.setOverlays(i.overlays)},[i.overlays]);const u=()=>s.current?.stopTour()??Promise.resolve(),c=()=>s.current?.stopAll()??Promise.resolve();return{recorder:s.current,state:t,tourState:n,currentScene:a,stopTour:u,stopAll:c}}const Je=({options:i={}})=>{const{recorder:e,state:t}=oe(i);if(!t||!e)return null;const r=e.computeGrid(t.viewport.w,t.viewport.h),n={x:t.displayRect.col*r.cellW,y:k+t.displayRect.row*r.cellH,width:t.displayRect.w*r.cellW,height:t.displayRect.h*r.cellH},o=typeof navigator<"u"&&/Mac/i.test(navigator.platform)?"⌘":"Ctrl",a=t.showGrid&&!t.recording,l=e.options.resolutions;return g.jsxs(g.Fragment,{children:[g.jsx("div",{className:"cfr-settings-bar",children:g.jsxs("div",{className:"cfr-settings-bar-content",children:[g.jsxs("button",{onClick:()=>t.recording?e.stopRecording():e.startRecording(),className:`cfr-btn ${t.recording?"cfr-btn-destructive":"cfr-btn-default"}`,"aria-label":t.recording?"Stop recording":"Start recording",children:[t.recording?g.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor",style:{marginRight:4},children:g.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"})}):g.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor",style:{marginRight:4},children:g.jsx("circle",{cx:"12",cy:"12",r:"10"})}),t.recording?t.mousePaused?"Paused":"Stop":"Record",g.jsxs("kbd",{className:"cfr-kbd",children:[o,"+",N.toUpperCase()]})]}),g.jsx("button",{onClick:()=>e.captureBitmap(),className:"cfr-btn cfr-btn-secondary",disabled:!t.recording,children:"PNG frame"}),g.jsxs("button",{onClick:()=>e.resetFullScreen(),className:"cfr-btn cfr-btn-ghost",children:["Full ",g.jsxs("kbd",{className:"cfr-kbd",children:[o,"+↑"]})]}),g.jsxs("button",{onClick:()=>e.zoomToMouse(),className:"cfr-btn cfr-btn-ghost",children:["Focus mouse ",g.jsxs("kbd",{className:"cfr-kbd",children:[o,"+↓"]})]}),g.jsxs("button",{onClick:()=>e.setMousePaused(!t.mousePaused),className:`cfr-btn ${t.mousePaused?"cfr-btn-secondary":"cfr-btn-ghost"}`,children:[t.mousePaused?"Resume mouse":"Pause mouse"," ",g.jsxs("kbd",{className:"cfr-kbd",children:[o,"+L"]})]}),g.jsx("div",{className:"cfr-divider"}),g.jsx("div",{className:"cfr-select-wrapper",children:g.jsx("select",{value:t.resolution.label,onChange:s=>{const u=l.find(c=>c.label===s.target.value);u&&e.setResolution(u)},disabled:t.recording,className:"cfr-select",children:l.map(s=>g.jsx("option",{value:s.label,children:s.label},s.label))})}),g.jsx("div",{className:"cfr-divider"}),g.jsxs("label",{className:"cfr-checkbox-container",children:[g.jsx("input",{type:"checkbox",checked:t.showGrid,onChange:s=>e.setShowGrid(s.target.checked),disabled:t.recording,className:"cfr-checkbox"}),g.jsx("span",{className:"cfr-label",children:"Grid"})]}),g.jsxs("label",{className:"cfr-checkbox-container",children:[g.jsx("input",{type:"checkbox",checked:t.autoZoom,onChange:s=>e.setAutoZoom(s.target.checked),className:"cfr-checkbox"}),g.jsx("span",{className:"cfr-label",children:"Auto-zoom on hold"})]}),g.jsxs("label",{className:"cfr-checkbox-container",children:[g.jsx("input",{type:"checkbox",checked:t.pauseDuringScroll,onChange:s=>e.setPauseDuringScroll(s.target.checked),className:"cfr-checkbox"}),g.jsx("span",{className:"cfr-label",children:"Pause zoom while scrolling"})]}),g.jsxs("label",{className:"cfr-checkbox-container",children:[g.jsx("input",{type:"checkbox",checked:t.showOutline,onChange:s=>e.setShowOutline(s.target.checked),className:"cfr-checkbox"}),g.jsx("span",{className:"cfr-label",children:"Show outline border"})]})]})}),a&&g.jsx("div",{"aria-hidden":!0,className:"cfr-grid-overlay",style:{top:k,backgroundImage:`
|
|
62
62
|
linear-gradient(to right, var(--cfr-border) 1px, transparent 1px),
|
|
63
63
|
linear-gradient(to bottom, var(--cfr-border) 1px, transparent 1px)
|
|
64
|
-
`,backgroundSize:`${r.cellW}px ${r.cellH}px`}}),g.jsx("div",{"aria-label":"Cinematic 16:9 capture region",className:"cfr-crop-box",style:{left:n.x,top:n.y,width:n.width,height:n.height,outline:t.showOutline?`${
|
|
64
|
+
`,backgroundSize:`${r.cellW}px ${r.cellH}px`}}),g.jsx("div",{"aria-label":"Cinematic 16:9 capture region",className:"cfr-crop-box",style:{left:n.x,top:n.y,width:n.width,height:n.height,outline:t.showOutline?`${F}px solid var(--cfr-outline)`:"none",outlineOffset:t.showOutline?`${F}px`:"0"}})]})};function se(i,e={}){const t=A.tool({name:"navigate",description:"Navigate browser or shell to a target route, URL hash, or URL",strict:!0,parameters:{type:"object",properties:{url:{type:"string",description:"The URL path, hash route, or URL to navigate to"}},required:["url"],additionalProperties:!1},execute:async c=>{const{url:d}=c;return typeof window>"u"?"Cannot navigate: not in browser context":(window.router?window.router.navigate({to:d}):window.location.hash=d,`Successfully navigated to: ${d}`)}}),r=A.tool({name:"click",description:"Simulate a visual pointer click and trigger a DOM click event on the target selector",strict:!0,parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the target element to click"}},required:["selector"],additionalProperties:!1},execute:async c=>{const{selector:d}=c;try{return await i.simulateClick(d),`Successfully clicked element: ${d}`}catch(h){return`Failed to click ${d}: ${h.message}`}}}),n=A.tool({name:"moveMousePointerTo",description:"Smoothly move the simulated visual pointer cursor to the center of the specified selector",strict:!0,parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the target element to hover"},durationMs:{type:"number",description:"Duration of the pointer movement in milliseconds",default:800}},required:["selector","durationMs"],additionalProperties:!1},execute:async c=>{const{selector:d,durationMs:h=800}=c;try{return await i.animatePointerTo(d,h),`Moved mouse pointer to: ${d}`}catch(m){return`Failed to move pointer to ${d}: ${m.message}`}}}),o=A.tool({name:"drawRegionAroundCssSelector",description:"Adjust the recording camera crop-box to focus/zoom onto the specified element, or reset to fullscreen",strict:!0,parameters:{type:"object",properties:{selector:{type:["string","null"],description:"CSS selector to zoom into. Provide null or empty string to zoom out to full screen"},padding:{type:"number",description:"Padding multiplier around the selector boundaries",default:1.1}},required:["selector","padding"],additionalProperties:!1},execute:async c=>{const{selector:d,padding:h=1.1}=c;return d?(i.setElementSelector(d),i.setElementPadding(h),`Focused camera region on element: ${d}`):(i.setElementSelector(null),i.resetFullScreen(),"Reset camera to full viewport")}}),a=A.tool({name:"typeText",description:"Simulate keystrokes to type text into an input field or textarea",strict:!0,parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the target input/textarea element"},text:{type:"string",description:"The text content to type into the field"},cps:{type:"number",description:"Typing speed in characters per second",default:24},jitter:{type:"number",description:"Per-character timing variation from 0 to 1",default:.22},punctuationPauseMs:{type:"number",description:"Extra pause after punctuation in milliseconds",default:120},mistakeRate:{type:"number",description:"Corrected typo probability from 0 to 1",default:.012}},required:["selector","text","cps","jitter","punctuationPauseMs","mistakeRate"],additionalProperties:!1},execute:async c=>{const{selector:d,text:h,cps:m=24,jitter:y=.22,punctuationPauseMs:p=120,mistakeRate:w=.012}=c;try{return await i.simulateType(d,h,{cps:m,jitter:y,punctuationPauseMs:p,mistakeRate:w}),`Typed "${h}" into element: ${d}`}catch(E){return`Failed to type text into ${d}: ${E.message}`}}}),l=A.tool({name:"wait",description:"Pause execution for a specific duration in milliseconds to align with scene timing",strict:!0,parameters:{type:"object",properties:{durationMs:{type:"number",description:"Duration to pause in milliseconds"}},required:["durationMs"],additionalProperties:!1},execute:async c=>{const{durationMs:d}=c;return await new Promise(h=>setTimeout(h,d)),`Waited for ${d}ms`}}),s=`
|
|
65
65
|
You are an automated video-demo assistant. Your task is to interpret a film script scene-by-scene
|
|
66
66
|
and execute the corresponding UI interactions (navigating, moving the cursor, typing, and clicking)
|
|
67
67
|
while adjusting the recording camera zoom around active components.
|
|
@@ -104,32 +104,32 @@ Reject or regenerate scripts when:
|
|
|
104
104
|
`,u=e.instructions?`${s}
|
|
105
105
|
|
|
106
106
|
Additional Instructions:
|
|
107
|
-
${e.instructions}`:s;return new A.Agent({name:"Web Assistant",instructions:u,tools:[t,r,n,o,a,l]})}function
|
|
108
|
-
`).replace(/^\s+/,"")}function ae(i){return i.entries.map(e=>`# setup ${e.type}: ${
|
|
109
|
-
`)}function
|
|
110
|
-
`),s=e.stripSetupForDisplay??!0,u=e.stripSetupForPlayback??!0;return{isFilmScript:/^\s*film\s+/i.test(a),fullScript:t,displayScript:s?a:t,runnableScript:u?a:t,setup:o,setupComments:l,filmBody:a}}function j(i,e){const t=V(
|
|
107
|
+
${e.instructions}`:s;return new A.Agent({name:"Web Assistant",instructions:u,tools:[t,r,n,o,a,l]})}function Qe(i,e={}){const t=e.apiKey||"proxied-by-server",r=e.baseURL,n=e.tracingDisabled??!0,o=new Fe({apiKey:t,baseURL:r,dangerouslyAllowBrowser:!0}),a=new A.OpenAIProvider({openAIClient:o}),l=new A.Runner({modelProvider:a,tracingDisabled:n,model:e.model}),s=l.run.bind(l);l.run=(async(c,d,h={})=>{const m=await s(c,d,{maxTurns:e.maxTurns??20,...h});return i.getState().recording&&await i.finishRecording(),m});const u=se(i,{instructions:e.instructions});return{runner:l,agent:u}}class W extends Error{trace;constructor(e,t){super(e),this.name="AppFilmGenerationError",this.cause=t?.cause,this.trace=t?.trace}}const Z=/^\s*#\s*setup\s+([A-Za-z0-9_.:-]+)\s*:\s*(.*)$/;function I(i,e=""){const t=[];for(const r of i.split(/\r?\n/)){const n=Z.exec(r);n&&t.push({type:n[1],value:pt(n[2].trim())})}return{appId:e,entries:t}}function $(i){return i.split(/\r?\n/).filter(e=>!Z.test(e)).join(`
|
|
108
|
+
`).replace(/^\s+/,"")}function ae(i){return i.entries.map(e=>`# setup ${e.type}: ${ht(e.value)}`).join(`
|
|
109
|
+
`)}function et(i,e={}){const t=i.trim(),r=mt(e.app)||e.setup?.appId||"",n=I(t,r),o=ft(n,e.setup,r),a=$(t).trim(),l=t.split(/\r?\n/).filter(d=>Z.test(d)).join(`
|
|
110
|
+
`),s=e.stripSetupForDisplay??!0,u=e.stripSetupForPlayback??!0;return{isFilmScript:/^\s*film\s+/i.test(a),fullScript:t,displayScript:s?a:t,runnableScript:u?a:t,setup:o,setupComments:l,filmBody:a}}function j(i,e){const t=V(I(i,e.id),e),r=G($(i)),n=[];r.length===0&&n.push({line:1,scene:null,commandIndex:null,message:"No film script scenes were found."});const o=wt(t),a=Object.values(e.selectors);for(const l of r)l.commands.forEach((s,u)=>{if(!s.selector)return;const c=a.find(d=>d.selector===s.selector);if(!c){n.push({line:s.sourceLine??1,scene:l.name,commandIndex:u,message:`Selector "${s.selector}" is not declared in app profile "${e.id}".`});return}for(const d of c.requiresSetup??[])o.has(d)||n.push({line:s.sourceLine??1,scene:l.name,commandIndex:u,message:`Selector "${s.selector}" requires setup "${d}", but that setup was not provided.`})});return vt(t,e,n),bt($(i),t,e,n),{valid:n.length===0,scenes:r,diagnostics:n}}async function tt(i){Me(i.signal);const e=ue(i.trace);try{let t,r=[];const n=[];if(nt(i)){t=await rt(i,e);const c=Ee(t,i.app);r=c.diagnostics,n.push(...c.warnings),Y(e,"intent",{diagnostics:c.diagnostics,warnings:c.warnings})}const o=await X("script",{instructions:ce(i.app,t),input:de(i.input,t),tools:[we(i.app)],toolChoice:"required",signal:i.signal},i.complete,e),a=Te(o);if(t=t??a.intent,a.intent){const c=Ee(a.intent,i.app);r.push(...c.diagnostics),n.push(...c.warnings)}let l=V(yt(a.setup??I(a.script,i.app.id),t,i.app),i.app),s=J(a.script,l),u=j(s,i.app);if(n.push(...a.warnings??[]),Y(e,"script",{diagnostics:[...r,...u.diagnostics],warnings:n}),(r.length>0||!u.valid)&&i.repair){const c=await le(s,{app:i.app,input:de(i.input,t),complete:i.complete,signal:i.signal,diagnostics:[...r,...u.diagnostics]},e);s=c.script,l=c.setup,u={valid:c.diagnostics.length===0,scenes:G($(c.script)),diagnostics:c.diagnostics},n.push(...c.warnings)}return me({intent:t,script:s,setup:l,diagnostics:[...r,...u.diagnostics],warnings:n},e)}catch(t){fe(t,e)}}async function it(i,e){Me(e.signal);const t=ue(e.trace);return le(i,e,t)}async function le(i,e,t){try{const r=e.diagnostics??j(i,e.app).diagnostics,n=await X("repair",{instructions:ot(e.app,r),input:[e.input?`User request:
|
|
111
111
|
${e.input}`:"",`Invalid script:
|
|
112
112
|
${i}`,`Diagnostics:
|
|
113
113
|
${r.map(u=>u.message).join(`
|
|
114
114
|
`)}`].filter(Boolean).join(`
|
|
115
115
|
|
|
116
|
-
`),tools:[we(e.app)],toolChoice:"required",signal:e.signal},e.complete,t),o=Te(n),a=V(o.setup??
|
|
116
|
+
`),tools:[we(e.app)],toolChoice:"required",signal:e.signal},e.complete,t),o=Te(n),a=V(o.setup??I(o.script,e.app.id),e.app),l=J(o.script,a),s=j(l,e.app);return Y(t,"repair",{diagnostics:s.diagnostics,warnings:o.warnings??[]}),me({script:l,setup:a,diagnostics:s.diagnostics,warnings:o.warnings??[]},t)}catch(r){fe(r,t)}}async function rt(i,e){const t=await X("intent",{instructions:st(i.app),input:i.input,tools:[ut(i.app)],toolChoice:"required",signal:i.signal},i.complete,e);return Rt(Ct(t),i.app)}function nt(i){return i.intentMode!=="off"&&(i.app.intents?.length??0)>0}function ce(i,e){return[`You generate code.film scripts for ${i.name}.`,i.description?`App description: ${i.description}`:"","Return the result by calling the create_film_script tool.","Do not return prose outside the tool call.","Use only selectors declared in the app profile.","Honor any approval or permission-mode guidance declared by the app profile; do not invent older permission labels.","Include setup entries for every selector that requires setup.","Prefer the smallest meaningful camera scope unless the user asks for page chrome, navigation, sidebars, collections, or multiple regions.",e?"Follow the resolved intent exactly. Only submit a prompt when resolvedIntent.submitPrompt is true.":"",e?`Resolved intent:
|
|
117
117
|
${JSON.stringify(e,null,2)}`:"","Preserve setup comments at the top of the script for compatibility.","",ye(i)].filter(Boolean).join(`
|
|
118
|
-
`)}function
|
|
118
|
+
`)}function ot(i,e){return[ce(i),"","Repair the script so validation passes.","Keep the user intent, but add missing setup or switch to valid selectors as needed.","Validation diagnostics:",e.map(t=>`- ${t.message}`).join(`
|
|
119
119
|
`)].join(`
|
|
120
|
-
`)}function
|
|
120
|
+
`)}function st(i){return[`Resolve user film requests for ${i.name}.`,i.description?`App description: ${i.description}`:"","Return the result by calling the resolve_film_intent tool.","Do not return prose outside the tool call.","Choose exactly one declared intent recipe.","Use examples, synonyms, and negative examples as model context, not as literal substring rules.","Do not assume a short prompt should be submitted to the app. Only set submitPrompt true when the chosen intent requires app prompt submission.","When prompt tools or attachments are needed, return them as structured promptTools or attachments.","",ye(i)].filter(Boolean).join(`
|
|
121
121
|
`)}function de(i,e){return e?[`User request:
|
|
122
122
|
${i}`,`Resolved intent:
|
|
123
123
|
${JSON.stringify(e,null,2)}`].join(`
|
|
124
124
|
|
|
125
|
-
`):i}function ue(i){const e=
|
|
125
|
+
`):i}function ue(i){const e=at(i);return{options:e,trace:e.enabled?{calls:[]}:void 0}}function at(i){return i?i===!0?{enabled:!0,includeInstructions:!0,includeRaw:!1}:{enabled:i.enabled!==!1,includeInstructions:i.includeInstructions??!0,includeRaw:i.includeRaw??!1,redact:i.redact}:{enabled:!1,includeInstructions:!1,includeRaw:!1}}async function X(i,e,t,r){if(!r.trace)return t(e);const n=Date.now(),o={phase:i,request:lt(e,r.options),startedAt:new Date(n).toISOString()};r.trace.calls.push(o);try{const a=await t(e);return o.response=ct(a,r.options),pe(o,n),he(r,o),a}catch(a){throw o.error=dt(a),pe(o,n),he(r,o),a}}function lt(i,e){return{instructions:e.includeInstructions?i.instructions:void 0,input:i.input,tools:i.tools,toolChoice:i.toolChoice}}function ct(i,e){return{toolName:i.toolName,arguments:i.arguments,raw:e.includeRaw?i.raw:void 0}}function pe(i,e){const t=Date.now();i.finishedAt=new Date(t).toISOString(),i.durationMs=t-e}function Y(i,e,t){if(!i.trace)return;const r=[...i.trace.calls].reverse().find(n=>n.phase===e);r&&(t.diagnostics&&(r.diagnostics=t.diagnostics),t.warnings&&(r.warnings=t.warnings))}function he(i,e){if(!i.trace||!i.options.redact)return;const t=i.trace.calls.indexOf(e);t!==-1&&(i.trace.calls[t]=i.options.redact(e))}function me(i,e){return e.trace?{...i,trace:e.trace}:i}function fe(i,e){throw e.trace?i instanceof W?(i.trace=i.trace??e.trace,i):new W(ge(i),{cause:i,trace:e.trace}):i}function dt(i){return{message:ge(i),name:i instanceof Error?i.name:void 0}}function ge(i){return i instanceof Error?i.message:String(i)}function ye(i){const e=Object.entries(i.selectors).map(([c,d])=>{const h=d.requiresSetup?.length?` Requires setup: ${d.requiresSetup.join(", ")}.`:"";return`- ${c}: ${d.selector} (${d.role??"component"}) - ${d.description}.${h}`}).join(`
|
|
126
126
|
`),t=Object.entries(i.pages).map(([c,d])=>`- ${c}: ${d.description}; container ${d.containerSelector}`+(d.defaultScopeSelector?`; default scope ${d.defaultScopeSelector}`:"")).join(`
|
|
127
127
|
`),r=i.setupCapabilities.map(c=>`- ${c}`).join(`
|
|
128
128
|
`),n=(i.rules??[]).map(c=>`- ${c}`).join(`
|
|
129
129
|
`),o=Object.entries(i.vocabulary??{}).map(([c,d])=>`- ${c}: ${d.join(", ")}`).join(`
|
|
130
130
|
`),a=(i.examples??[]).map(c=>`User: ${c.input}
|
|
131
131
|
Script:
|
|
132
|
-
${J(c.script,c.setup??
|
|
132
|
+
${J(c.script,c.setup??I(c.script,i.id))}`).join(`
|
|
133
133
|
|
|
134
134
|
`),l=(i.intents??[]).map(c=>[`- ${c.id}: ${c.description}`,` Page: ${c.page}; submitPrompt: ${c.submitPrompt}`,c.defaultScopeSelector?` Default scope: ${c.defaultScopeSelector}`:"",c.examples.length?` Examples: ${c.examples.join("; ")}`:"",c.synonyms?.length?` Synonyms: ${c.synonyms.join("; ")}`:"",c.negativeExamples?.length?` Negative examples: ${c.negativeExamples.join("; ")}`:"",c.requiredSetup?.length?` Required setup: ${c.requiredSetup.join(", ")}`:"",c.scriptGuidance?` Script guidance: ${c.scriptGuidance}`:""].filter(Boolean).join(`
|
|
135
135
|
`)).join(`
|
|
@@ -152,5 +152,5 @@ Vocabulary:
|
|
|
152
152
|
${o}`:"",a?`
|
|
153
153
|
Examples:
|
|
154
154
|
${a}`:""].join(`
|
|
155
|
-
`)}function
|
|
156
|
-
${t}`}function C(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function
|
|
155
|
+
`)}function ut(i){const e=(i.intents??[]).map(o=>o.id),t=Object.keys(i.pages),r=(i.promptTools??[]).map(o=>o.id),n=(i.attachmentTypes??[]).map(o=>o.id);return{type:"function",name:"resolve_film_intent",description:"Resolve a user film request into one declared app intent.",strict:!0,parameters:{type:"object",properties:{intentId:_(e),confidence:K({type:"number"}),page:_(t),scopeSelector:x(),submitPrompt:{type:"boolean"},promptText:x(),promptTools:{anyOf:[{type:"array",items:ve(r)},{type:"null"}]},attachments:{anyOf:[{type:"array",items:be(n)},{type:"null"}]},setupNeeded:{anyOf:[{type:"array",items:{type:"string"}},{type:"null"}]},rationale:{type:"string"}},required:["intentId","confidence","page","scopeSelector","submitPrompt","promptText","promptTools","attachments","setupNeeded","rationale"],additionalProperties:!1}}}function we(i){const e=(i.promptTools??[]).map(r=>r.id),t=(i.attachmentTypes??[]).map(r=>r.id);return{type:"function",name:"create_film_script",description:"Create a code.film script and structured setup for a host app.",strict:!0,parameters:{type:"object",properties:{intent:{anyOf:[{type:"object",properties:{id:{type:"string"},confidence:K({type:"number"}),page:{type:"string"},scopeSelector:x(),submitPrompt:{type:"boolean"},promptText:x(),promptTools:{anyOf:[{type:"array",items:ve(e)},{type:"null"}]},attachments:{anyOf:[{type:"array",items:be(t)},{type:"null"}]},setupNeeded:{anyOf:[{type:"array",items:{type:"string"}},{type:"null"}]},rationale:x()},required:["id","confidence","page","scopeSelector","submitPrompt","promptText","promptTools","attachments","setupNeeded","rationale"],additionalProperties:!1},{type:"null"}]},script:{type:"string",description:"Complete code.film script. Include setup comments at the top when setup is required."},setup:{type:"object",properties:{appId:{type:"string",enum:[i.id]},entries:{type:"array",items:{type:"object",properties:{type:{type:"string"},value:{type:"string",description:"Setup value as JSON text for objects/arrays/strings, or plain text for simple values."}},required:["type","value"],additionalProperties:!1}}},required:["appId","entries"],additionalProperties:!1},warnings:{type:"array",items:{type:"string"}}},required:["intent","script","setup","warnings"],additionalProperties:!1}}}function _(i=[]){return i.length>0?{type:"string",enum:i}:{type:"string"}}function x(){return K({type:"string"})}function K(i){return{anyOf:[i,{type:"null"}]}}function ve(i=[]){return{type:"object",properties:{id:_(i),mention:{type:"string"},label:x(),reason:x()},required:["id","mention","label","reason"],additionalProperties:!1}}function be(i=[]){return{type:"object",properties:{type:_(i),name:x(),label:x(),reason:x()},required:["type","name","label","reason"],additionalProperties:!1}}function pt(i){if(i==="")return"";try{return JSON.parse(i)}catch{return i}}function ht(i){return typeof i=="string"?i:JSON.stringify(i)}function V(i,e){return{appId:i.appId||e.id,entries:i.entries.map(t=>({type:e.setupAliases?.[t.type]??t.type,value:t.value}))}}function mt(i){return i?typeof i=="string"?i:i.id:""}function ft(i,e,t){const r=[...i.entries];for(const n of e?.entries??[])r.some(o=>gt(o,n))||r.push(n);return{appId:t||i.appId||e?.appId||"",entries:r}}function gt(i,e){return i.type===e.type&&JSON.stringify(i.value)===JSON.stringify(e.value)}function yt(i,e,t){if(!e)return i;const r=t.intents?.find(o=>o.id===e.id),n=[...i.entries];for(const o of r?.setup??[])n.some(a=>a.type===o.type)||n.push(o);for(const o of e.promptTools??[])n.some(a=>Se(a,o))||n.push({type:"promptTool",value:o});for(const o of e.attachments??[])n.some(a=>St(a,o))||n.push({type:"attachment",value:o});return{...i,entries:n}}function wt(i){const e=new Set;for(const t of i.entries)e.add(t.type),C(t.value)&&(typeof t.value.type=="string"&&e.add(`${t.type}:${t.value.type}`),typeof t.value.id=="string"&&e.add(`${t.type}:${t.value.id}`));return e}function vt(i,e,t){const r=new Set(e.setupCapabilities),n=new Set(e.setupCapabilities.map(o=>o.split(":")[0]));for(const o of i.entries)!(r.has(o.type)||C(o.value)&&typeof o.value.type=="string"&&r.has(`${o.type}:${o.value.type}`))&&!n.has(o.type)&&t.push({line:1,scene:null,commandIndex:null,message:`Setup "${o.type}" is not declared in app profile "${e.id}".`})}function bt(i,e,t,r){for(const n of t.promptTools??[]){if(!i.includes(n.mention))continue;e.entries.some(a=>Se(a,{id:n.id,mention:n.mention}))||r.push(O(`Script uses prompt tool mention "${n.mention}" without matching promptTool setup.`))}}function Se(i,e){return i.type!=="promptTool"||!C(i.value)?!1:i.value.id===e.id||i.value.mention===e.mention}function St(i,e){return i.type!=="attachment"||!C(i.value)?!1:i.value.type===e.type&&(e.name===void 0||i.value.name===e.name)}function Et(i,e){const t=new Set(e.setupCapabilities),r=new Set(e.setupCapabilities.map(n=>n.split(":")[0]));return t.has(i)||r.has(i.split(":")[0])}function Ee(i,e){const t=[],r=[],n=e.intents?.find(o=>o.id===i.id);n||t.push(O(`Resolved intent "${i.id}" is not declared in app profile "${e.id}".`)),e.pages[i.page]||t.push(O(`Resolved intent page "${i.page}" is not declared in app profile "${e.id}".`)),i.scopeSelector&&!Tt(i.scopeSelector,e)&&t.push(O(`Resolved intent scope selector "${i.scopeSelector}" is not declared in app profile "${e.id}".`));for(const o of i.setupNeeded??[])Et(o,e)||t.push(O(`Resolved intent setup "${o}" is not declared in app profile "${e.id}".`));for(const o of i.promptTools??[]){const a=e.promptTools?.find(l=>l.id===o.id);if(!a){t.push(O(`Resolved prompt tool "${o.id}" is not declared in app profile "${e.id}".`));continue}o.mention!==a.mention&&t.push(O(`Resolved prompt tool "${o.id}" mention "${o.mention}" does not match declared mention "${a.mention}".`)),a.installed===!1&&r.push(`Prompt tool "${a.name}" is declared but not installed.`)}for(const o of i.attachments??[])e.attachmentTypes?.some(a=>a.id===o.type)||t.push(O(`Resolved attachment type "${o.type}" is not declared in app profile "${e.id}".`));return n&&i.submitPrompt!==n.submitPrompt&&r.push(`Resolved intent "${i.id}" changed submitPrompt from recipe default ${n.submitPrompt} to ${i.submitPrompt}.`),{diagnostics:t,warnings:r}}function Tt(i,e){return Object.values(e.selectors).some(t=>t.selector===i)?!0:Object.values(e.pages).some(t=>t.containerSelector===i||t.defaultScopeSelector===i)}function O(i){return{line:1,scene:null,commandIndex:null,message:i}}function Rt(i,e){const t=e.intents?.find(r=>r.id===i.intentId);return{id:i.intentId,confidence:i.confidence,page:i.page||t?.page||"",scopeSelector:i.scopeSelector??t?.defaultScopeSelector,submitPrompt:i.submitPrompt,promptText:i.promptText,promptTools:i.promptTools,attachments:i.attachments,setupNeeded:i.setupNeeded??t?.requiredSetup,rationale:i.rationale}}function Ct(i){if(i.toolName!=="resolve_film_intent")throw new Error(`[code-film] Expected resolve_film_intent tool call, received "${i.toolName}".`);if(!C(i.arguments))throw new Error("[code-film] resolve_film_intent arguments must be an object.");if(typeof i.arguments.intentId!="string")throw new Error("[code-film] resolve_film_intent.intentId must be a string.");if(typeof i.arguments.page!="string")throw new Error("[code-film] resolve_film_intent.page must be a string.");if(typeof i.arguments.submitPrompt!="boolean")throw new Error("[code-film] resolve_film_intent.submitPrompt must be a boolean.");if(typeof i.arguments.rationale!="string")throw new Error("[code-film] resolve_film_intent.rationale must be a string.");return{intentId:i.arguments.intentId,confidence:typeof i.arguments.confidence=="number"?i.arguments.confidence:void 0,page:i.arguments.page,scopeSelector:typeof i.arguments.scopeSelector=="string"?i.arguments.scopeSelector:void 0,submitPrompt:i.arguments.submitPrompt,promptText:typeof i.arguments.promptText=="string"?i.arguments.promptText:void 0,promptTools:Re(i.arguments.promptTools),attachments:Ce(i.arguments.attachments),setupNeeded:xe(i.arguments.setupNeeded),rationale:i.arguments.rationale}}function Te(i){if(i.toolName!=="create_film_script")throw new Error(`[code-film] Expected create_film_script tool call, received "${i.toolName}".`);if(!C(i.arguments))throw new Error("[code-film] create_film_script arguments must be an object.");if(typeof i.arguments.script!="string")throw new Error("[code-film] create_film_script.script must be a string.");return{intent:xt(i.arguments.intent),script:i.arguments.script,setup:Mt(i.arguments.setup)?i.arguments.setup:void 0,warnings:Array.isArray(i.arguments.warnings)?i.arguments.warnings.filter(e=>typeof e=="string"):[]}}function xt(i){if(C(i)&&!(typeof i.id!="string"||typeof i.page!="string"||typeof i.submitPrompt!="boolean"))return{id:i.id,confidence:typeof i.confidence=="number"?i.confidence:void 0,page:i.page,scopeSelector:typeof i.scopeSelector=="string"?i.scopeSelector:void 0,submitPrompt:i.submitPrompt,promptText:typeof i.promptText=="string"?i.promptText:void 0,promptTools:Re(i.promptTools),attachments:Ce(i.attachments),setupNeeded:xe(i.setupNeeded),rationale:typeof i.rationale=="string"?i.rationale:void 0}}function Re(i){if(Array.isArray(i))return i.filter(C).flatMap(e=>typeof e.id!="string"||typeof e.mention!="string"?[]:[{id:e.id,mention:e.mention,label:typeof e.label=="string"?e.label:void 0,reason:typeof e.reason=="string"?e.reason:void 0}])}function Ce(i){if(Array.isArray(i))return i.filter(C).flatMap(e=>typeof e.type!="string"?[]:[{type:e.type,name:typeof e.name=="string"?e.name:void 0,label:typeof e.label=="string"?e.label:void 0,reason:typeof e.reason=="string"?e.reason:void 0}])}function xe(i){if(Array.isArray(i))return i.filter(e=>typeof e=="string")}function J(i,e){const t=$(i);return e.entries.length===0?t:`${ae(e)}
|
|
156
|
+
${t}`}function C(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function Mt(i){return C(i)&&typeof i.appId=="string"&&Array.isArray(i.entries)&&i.entries.every(e=>C(e)&&typeof e.type=="string"&&"value"in e)}function Me(i){if(i?.aborted)throw new DOMException("Aborted","AbortError")}function At(i,e={}){let t=!1;const r=o=>{kt(o.origin,e.allowedOrigins)&&Pe(o.data)&&Oe(i,o.data.command)},n={start(){return t||typeof window>"u"||(window.addEventListener("message",r),t=!0),n},stop(){!t||typeof window>"u"||(window.removeEventListener("message",r),t=!1)},destroy(){n.stop()},execute(o){return Oe(i,o)}};return n}function Pt(i){let e=!1;const t=i.shortcuts??!0,r=a=>{const l=i.targetWindow??(typeof window<"u"?window.parent:void 0);l&&l.postMessage(Ae(a),i.targetOrigin)},n=a=>{const l=ke(a);l&&(a.preventDefault(),r(l))},o={start(){return e||!t||typeof window>"u"||(window.addEventListener("keydown",n),e=!0),o},stop(){!e||typeof window>"u"||(window.removeEventListener("keydown",n),e=!1)},destroy(){o.stop()},sendCommand:r};return o}function Ae(i){return{source:"code-film",channel:"recorder-iframe",type:"command",command:i}}function Pe(i){if(!i||typeof i!="object")return!1;const e=i;return e.source==="code-film"&&e.channel==="recorder-iframe"&&e.type==="command"&&Ot(e.command)}function ke(i){if(!(i.ctrlKey||i.metaKey))return null;const t=i.key.toLowerCase();return t==="j"?"toggle-recording":t==="l"?"toggle-mouse-pause":i.key==="ArrowUp"?"reset-full":i.key==="ArrowDown"?"focus-mouse":null}async function Oe(i,e){switch(e){case"toggle-recording":i.getState().recording?i.stopRecording():await i.startRecording();return;case"start-recording":await i.startRecording();return;case"stop-recording":i.stopRecording();return;case"focus-mouse":i.zoomToMouse();return;case"reset-full":i.setElementSelector(null),i.resetFullScreen();return;case"toggle-mouse-pause":{const t=i.getState();i.setMousePaused(!t.mousePaused);return}}}function kt(i,e){return!e||e.length===0?!0:e.includes("*")||e.includes(i)}function Ot(i){return i==="toggle-recording"||i==="start-recording"||i==="stop-recording"||i==="focus-mouse"||i==="reset-full"||i==="toggle-mouse-pause"}f.AppFilmGenerationError=W,f.COLS=b,f.DEFAULT_COMPLETION_TIMEOUT_MS=te,f.DEFAULT_RESOLUTIONS=H,f.DEFAULT_SELECTOR_TIMEOUT_MS=ie,f.FilmRecorder=ne,f.HUMAN_TYPING_PRESET=Xe,f.MIN_BOX_COLS=P,f.RegionRecorder=Je,f.RegionRecorderUI=Ve,f.SDK_TYPING_DEFAULTS=re,f.cameraOverlay=Ie,f.createRecorderAgentRunner=Qe,f.createRecorderIframeClient=Pt,f.createRecorderIframeHost=At,f.createRecorderIframeMessage=Ae,f.createWebAssistantAgent=se,f.generateAppFilmScript=tt,f.getRecorderIframeShortcutCommand=ke,f.isRecorderIframeMessage=Pe,f.parseAppFilmSetup=I,f.prepareAppFilmScript=et,f.repairAppFilmScript=it,f.serializeAppFilmSetup=ae,f.stripAppFilmSetup=$,f.useFilmRecorder=oe,f.validateAppFilmScript=j,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED