@arbidocs/blocks 0.4.106 → 0.4.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/bin/arbidocs-render-take.mjs +27 -0
  2. package/dist/NativeDocxEditor-3VKJT43D.js +10 -0
  3. package/dist/NativeDocxEditor-3VKJT43D.js.map +1 -0
  4. package/dist/NativeDocxEditor-GNG5QV7V.cjs +31 -0
  5. package/dist/NativeDocxEditor-GNG5QV7V.cjs.map +1 -0
  6. package/dist/agents/index.cjs +209 -209
  7. package/dist/agents/index.js +4 -4
  8. package/dist/chat/index.cjs +125 -125
  9. package/dist/chat/index.js +3 -3
  10. package/dist/{chunk-PIT2YZCK.js → chunk-2PYENCW5.js} +3 -3
  11. package/dist/{chunk-PIT2YZCK.js.map → chunk-2PYENCW5.js.map} +1 -1
  12. package/dist/{chunk-W2RTZOK3.js → chunk-2SJTXYRM.js} +1749 -1778
  13. package/dist/chunk-2SJTXYRM.js.map +1 -0
  14. package/dist/{chunk-S7RHJI5Q.js → chunk-7NLPKJV5.js} +3 -3
  15. package/dist/{chunk-S7RHJI5Q.js.map → chunk-7NLPKJV5.js.map} +1 -1
  16. package/dist/{chunk-ZWWN4CUL.cjs → chunk-BHKFENKT.cjs} +1748 -1778
  17. package/dist/chunk-BHKFENKT.cjs.map +1 -0
  18. package/dist/{chunk-3R6XBYL7.cjs → chunk-DTBSGG36.cjs} +7 -2
  19. package/dist/chunk-DTBSGG36.cjs.map +1 -0
  20. package/dist/{chunk-3Y6NQIDE.js → chunk-EB7QAZLH.js} +5 -5
  21. package/dist/{chunk-3Y6NQIDE.js.map → chunk-EB7QAZLH.js.map} +1 -1
  22. package/dist/{chunk-TP3FAP5J.cjs → chunk-FZGMY6NQ.cjs} +5 -5
  23. package/dist/{chunk-TP3FAP5J.cjs.map → chunk-FZGMY6NQ.cjs.map} +1 -1
  24. package/dist/{chunk-W7NZRZ54.js → chunk-GFYGYME3.js} +3 -3
  25. package/dist/{chunk-W7NZRZ54.js.map → chunk-GFYGYME3.js.map} +1 -1
  26. package/dist/chunk-GYAUJ4KT.js +71 -0
  27. package/dist/chunk-GYAUJ4KT.js.map +1 -0
  28. package/dist/{chunk-XMBYDLZQ.cjs → chunk-HUJLKDWX.cjs} +4 -4
  29. package/dist/{chunk-XMBYDLZQ.cjs.map → chunk-HUJLKDWX.cjs.map} +1 -1
  30. package/dist/{chunk-4GFB5U3K.js → chunk-LHBJJ2GE.js} +4 -3
  31. package/dist/chunk-LHBJJ2GE.js.map +1 -0
  32. package/dist/{chunk-MP6FK43E.cjs → chunk-O5NDG4EA.cjs} +3 -3
  33. package/dist/{chunk-MP6FK43E.cjs.map → chunk-O5NDG4EA.cjs.map} +1 -1
  34. package/dist/{chunk-5YXG342J.cjs → chunk-OR4CO743.cjs} +3 -3
  35. package/dist/{chunk-5YXG342J.cjs.map → chunk-OR4CO743.cjs.map} +1 -1
  36. package/dist/{chunk-LGX6UFYG.js → chunk-P2KPDPFF.js} +8 -3
  37. package/dist/chunk-P2KPDPFF.js.map +1 -0
  38. package/dist/{chunk-DDF5GPIJ.js → chunk-P5ST47VY.js} +3 -3
  39. package/dist/{chunk-DDF5GPIJ.js.map → chunk-P5ST47VY.js.map} +1 -1
  40. package/dist/{chunk-EWSEQEPL.js → chunk-PFA43QNX.js} +3 -3
  41. package/dist/{chunk-EWSEQEPL.js.map → chunk-PFA43QNX.js.map} +1 -1
  42. package/dist/{chunk-7LLLQUM7.cjs → chunk-Q57MEBCK.cjs} +6 -5
  43. package/dist/chunk-Q57MEBCK.cjs.map +1 -0
  44. package/dist/{chunk-LLFW2T6S.cjs → chunk-R6APX23R.cjs} +11 -11
  45. package/dist/{chunk-LLFW2T6S.cjs.map → chunk-R6APX23R.cjs.map} +1 -1
  46. package/dist/{chunk-24ND4S6Y.cjs → chunk-RILMICOP.cjs} +5 -5
  47. package/dist/{chunk-24ND4S6Y.cjs.map → chunk-RILMICOP.cjs.map} +1 -1
  48. package/dist/chunk-S24XEVPS.cjs +73 -0
  49. package/dist/chunk-S24XEVPS.cjs.map +1 -0
  50. package/dist/{chunk-XQDM6T6C.js → chunk-WDD255XQ.js} +3 -3
  51. package/dist/{chunk-XQDM6T6C.js.map → chunk-WDD255XQ.js.map} +1 -1
  52. package/dist/{chunk-Z5VUZ6YD.cjs → chunk-ZV3BKLFY.cjs} +3 -3
  53. package/dist/{chunk-Z5VUZ6YD.cjs.map → chunk-ZV3BKLFY.cjs.map} +1 -1
  54. package/dist/collaboration/index.cjs +15 -15
  55. package/dist/collaboration/index.js +1 -1
  56. package/dist/collaboration/mail/MailMessageView.d.ts +3 -1
  57. package/dist/connect/docx.cjs +7 -6
  58. package/dist/connect/docx.cjs.map +1 -1
  59. package/dist/connect/docx.js +5 -4
  60. package/dist/connect/docx.js.map +1 -1
  61. package/dist/connect/index.cjs +407 -91
  62. package/dist/connect/index.cjs.map +1 -1
  63. package/dist/connect/index.js +361 -46
  64. package/dist/connect/index.js.map +1 -1
  65. package/dist/connection/mail/ConnectedMailComposer.d.ts +12 -2
  66. package/dist/connection/mail/ConnectedMailMessage.d.ts +19 -0
  67. package/dist/connection/mail/ConnectedMailbox.d.ts +7 -3
  68. package/dist/connection/mail/MailComposerForm.d.ts +12 -2
  69. package/dist/connection/mail/index.d.ts +2 -1
  70. package/dist/connection/mail/types.d.ts +15 -0
  71. package/dist/connection/mail/useWordBody.d.ts +48 -0
  72. package/dist/docx/NativeDocxEditor.d.ts +9 -1
  73. package/dist/docx/index.cjs +51 -50
  74. package/dist/docx/index.cjs.map +1 -1
  75. package/dist/docx/index.js +4 -3
  76. package/dist/docx/index.js.map +1 -1
  77. package/dist/facts/index.cjs +2 -2
  78. package/dist/facts/index.js +2 -2
  79. package/dist/files/index.cjs +2 -2
  80. package/dist/files/index.js +2 -2
  81. package/dist/home/index.cjs +17 -17
  82. package/dist/home/index.js +3 -3
  83. package/dist/index.cjs +442 -442
  84. package/dist/index.js +8 -8
  85. package/dist/record/index.cjs +307 -66
  86. package/dist/record/index.cjs.map +1 -1
  87. package/dist/record/index.d.ts +145 -26
  88. package/dist/record/index.js +301 -67
  89. package/dist/record/index.js.map +1 -1
  90. package/dist/retrieval/index.cjs +1 -1
  91. package/dist/retrieval/index.js +1 -1
  92. package/dist/settings/index.cjs +35 -35
  93. package/dist/settings/index.js +2 -2
  94. package/dist/shell/index.cjs +1 -1
  95. package/dist/shell/index.js +1 -1
  96. package/dist/studio/index.cjs +4 -4
  97. package/dist/studio/index.js +3 -3
  98. package/dist/workflow-canvas/index.cjs +11 -11
  99. package/dist/workflow-canvas/index.js +4 -4
  100. package/dist/workspaces/index.cjs +2 -2
  101. package/dist/workspaces/index.js +2 -2
  102. package/node_modules/@arbidocs/coedit/package.json +1 -1
  103. package/package.json +8 -5
  104. package/record/render-overlays.mjs +152 -0
  105. package/record/render-take.py +985 -0
  106. package/src/docx/styles.css +22 -0
  107. package/dist/chunk-3R6XBYL7.cjs.map +0 -1
  108. package/dist/chunk-4GFB5U3K.js.map +0 -1
  109. package/dist/chunk-7LLLQUM7.cjs.map +0 -1
  110. package/dist/chunk-LGX6UFYG.js.map +0 -1
  111. package/dist/chunk-W2RTZOK3.js.map +0 -1
  112. package/dist/chunk-ZWWN4CUL.cjs.map +0 -1
@@ -1,4 +1,135 @@
1
+ import { mkdirSync, writeFileSync } from 'fs';
2
+ import path from 'path';
3
+
1
4
  // src/record/index.ts
5
+ var TIMECODE_CELL = 8;
6
+ var round = (n) => Math.round(n * 100) / 100;
7
+ var Take = class _Take {
8
+ constructor(page, options, brand) {
9
+ this.page = page;
10
+ this.options = options;
11
+ this.brand = brand ? cinematicSkin(brand) : {};
12
+ const dir = path.resolve(options.dir ?? "recordings");
13
+ this.file = path.join(dir, `${options.name}.waits.json`);
14
+ this.focusFile = path.join(dir, `${options.name}.focus.json`);
15
+ this.timeline.viewport = page.viewportSize();
16
+ mkdirSync(dir, { recursive: true });
17
+ _Take.active = this;
18
+ this.save();
19
+ }
20
+ page;
21
+ options;
22
+ /** The take running now (one at a time: recordings run one after another). */
23
+ static active = null;
24
+ t0 = Date.now();
25
+ waits = [];
26
+ /** The brand the edit paints the cards, captions and callouts in. */
27
+ brand;
28
+ file;
29
+ focusFile;
30
+ timeline = {
31
+ sync: null,
32
+ viewport: null,
33
+ focus: [],
34
+ cards: [],
35
+ lowerThirds: [],
36
+ captions: []
37
+ };
38
+ /** The take running on `page`, if any. */
39
+ static on(page) {
40
+ return _Take.active?.page === page ? _Take.active : null;
41
+ }
42
+ /** Seconds since the take started. */
43
+ now() {
44
+ return (Date.now() - this.t0) / 1e3;
45
+ }
46
+ /** Log a wait (written at once, so a take that fails part-way still has its cut list). */
47
+ log(label, start, end = this.now()) {
48
+ if (end - start < 1) return;
49
+ this.waits.push({ label, start: round(start), end: round(end) });
50
+ this.save();
51
+ }
52
+ /** Wait for `until` (a UI state), logged as a wait the edit may cut. */
53
+ async wait(label, until) {
54
+ const start = this.now();
55
+ try {
56
+ return await until();
57
+ } finally {
58
+ this.log(label, start);
59
+ }
60
+ }
61
+ /**
62
+ * Paint the sync marker: a magenta frame for a moment, at a logged time. The edit finds it in the
63
+ * video and lines the take's clock up with the video's. Call it before the first navigation.
64
+ */
65
+ async markSync() {
66
+ await this.page.evaluate(
67
+ () => new Promise((done) => {
68
+ document.documentElement.style.background = "#ff00ff";
69
+ if (document.body) document.body.style.background = "#ff00ff";
70
+ requestAnimationFrame(() => requestAnimationFrame(() => done()));
71
+ })
72
+ );
73
+ this.timeline.sync = round(this.now());
74
+ await this.page.waitForTimeout(400);
75
+ this.save();
76
+ }
77
+ /** Log a focus event (a `point` with no end lasts until the next event). */
78
+ record(event) {
79
+ const { focus } = this.timeline;
80
+ const open = focus[focus.length - 1];
81
+ if (open && open.kind === "point" && open.end === void 0) open.end = round(event.start);
82
+ focus.push({
83
+ ...event,
84
+ start: round(event.start),
85
+ end: event.end === void 0 ? void 0 : round(event.end)
86
+ });
87
+ this.save();
88
+ }
89
+ /** @internal The stage's cards, lower-thirds and captions (drawn by the edit). */
90
+ cardStart(card) {
91
+ this.cardEnd();
92
+ this.captionEnd();
93
+ this.timeline.cards.push({ ...card, start: round(this.now()), end: null });
94
+ this.save();
95
+ }
96
+ cardEnd() {
97
+ const last = this.timeline.cards[this.timeline.cards.length - 1];
98
+ if (last && last.end === null) {
99
+ last.end = round(this.now());
100
+ this.save();
101
+ }
102
+ }
103
+ lowerThird(kicker, title, holdMs) {
104
+ const start = round(this.now());
105
+ this.timeline.lowerThirds.push({ kicker, title, start, end: round(start + holdMs / 1e3) });
106
+ this.save();
107
+ }
108
+ captionStart(text) {
109
+ this.captionEnd();
110
+ this.timeline.captions.push({ text, start: round(this.now()), end: null });
111
+ this.save();
112
+ }
113
+ captionEnd() {
114
+ const last = this.timeline.captions[this.timeline.captions.length - 1];
115
+ if (last && last.end === null) {
116
+ last.end = round(this.now());
117
+ this.save();
118
+ }
119
+ }
120
+ save() {
121
+ const { zoom, maxZoom, pip } = this.options;
122
+ writeFileSync(this.file, JSON.stringify({ t0: this.t0, waits: this.waits }, null, 1));
123
+ writeFileSync(
124
+ this.focusFile,
125
+ JSON.stringify(
126
+ { t0: this.t0, config: { zoom, maxZoom, pip }, brand: this.brand, ...this.timeline },
127
+ null,
128
+ 1
129
+ )
130
+ );
131
+ }
132
+ };
2
133
  var DEFAULTS = {
3
134
  displayFont: "ui-serif, Georgia, serif",
4
135
  sansFont: "Inter, ui-sans-serif, system-ui, sans-serif",
@@ -9,9 +140,8 @@ var DEFAULTS = {
9
140
  ink: "#0e1b2d",
10
141
  coverTitle: "#f4f6f8"
11
142
  };
12
- function createCinematic(config) {
13
- const b = config.brand;
14
- const skin = {
143
+ function cinematicSkin(b) {
144
+ return {
15
145
  firmLabel: b.firmLabel,
16
146
  displayFont: b.displayFont ?? DEFAULTS.displayFont,
17
147
  sansFont: b.sansFont ?? DEFAULTS.sansFont,
@@ -23,8 +153,13 @@ function createCinematic(config) {
23
153
  coverTo: b.cover?.to ?? DEFAULTS.cover.to,
24
154
  accent: b.accent ?? DEFAULTS.accent,
25
155
  ink: b.ink ?? DEFAULTS.ink,
26
- coverTitle: b.coverTitle ?? DEFAULTS.coverTitle
156
+ coverTitle: b.coverTitle ?? DEFAULTS.coverTitle,
157
+ fontFiles: b.fontFiles ?? []
27
158
  };
159
+ }
160
+ function createCinematic(config) {
161
+ const b = config.brand;
162
+ const skin = cinematicSkin(b);
28
163
  const loginPath = config.loginPath ?? "/app/login";
29
164
  const appUrlPattern = config.appUrlPattern ?? /\/app$/;
30
165
  const ids = {
@@ -33,113 +168,207 @@ function createCinematic(config) {
33
168
  submit: config.testIds?.submit ?? "auth-login-submit"
34
169
  };
35
170
  const resolve = (page, t) => typeof t === "string" ? page.getByTestId(t) : t;
171
+ async function boxOf(page, loc) {
172
+ const box = await loc.boundingBox().catch(() => null);
173
+ const vp = page.viewportSize();
174
+ if (!box || !vp) return box;
175
+ const x = Math.max(box.x, 0);
176
+ const y = Math.max(box.y, 0);
177
+ const width = Math.min(box.x + box.width, vp.width) - x;
178
+ const height = Math.min(box.y + box.height, vp.height) - y;
179
+ return width > 0 && height > 0 ? { x: round(x), y: round(y), width: round(width), height: round(height) } : null;
180
+ }
181
+ async function glide(page, target) {
182
+ const loc = resolve(page, target).first();
183
+ await loc.scrollIntoViewIfNeeded().catch(() => {
184
+ });
185
+ const box = await boxOf(page, loc);
186
+ if (box) {
187
+ await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2, { steps: 26 });
188
+ await page.waitForTimeout(180);
189
+ }
190
+ return { loc, box };
191
+ }
192
+ async function take(page, options) {
193
+ return new Take(page, options, b);
194
+ }
36
195
  async function installStage(page) {
37
- await page.addInitScript((s) => {
38
- const boot = () => {
39
- if (document.getElementById("__cine_cursor")) return;
40
- const cursor = document.createElement("div");
41
- cursor.id = "__cine_cursor";
42
- cursor.style.cssText = `position:fixed;left:0;top:0;z-index:2147483647;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;pointer-events:none;transition:transform .09s ease-out;background:radial-gradient(circle at 35% 35%, ${s.cursorFrom}, ${s.cursorTo});box-shadow:0 0 0 3px rgba(255,255,255,.6),0 2px 10px rgba(0,0,0,.4);`;
43
- document.body.appendChild(cursor);
44
- window.addEventListener(
45
- "mousemove",
46
- (e) => {
47
- cursor.style.transform = `translate(${e.clientX}px,${e.clientY}px)`;
48
- },
49
- true
50
- );
51
- window.addEventListener(
52
- "mousedown",
53
- (e) => {
54
- const m = e;
55
- const r = document.createElement("div");
56
- r.style.cssText = `position:fixed;left:${m.clientX}px;top:${m.clientY}px;z-index:2147483646;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;pointer-events:none;border:2px solid ${s.ripple};animation:__cine_ripple .55s ease-out forwards;`;
57
- document.body.appendChild(r);
58
- setTimeout(() => r.remove(), 600);
59
- },
60
- true
61
- );
62
- const cap = document.createElement("div");
63
- cap.id = "__cine_cap";
64
- cap.style.cssText = `position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(8px);z-index:2147483646;max-width:72%;padding:13px 24px;border-radius:13px;font:500 17px/1.45 ${s.sansFont};color:#fff;letter-spacing:.01em;background:${s.ink}e0;backdrop-filter:blur(7px);box-shadow:0 10px 34px rgba(0,0,0,.4);text-align:center;opacity:0;transition:opacity .35s,transform .35s;`;
65
- document.body.appendChild(cap);
66
- const style = document.createElement("style");
67
- style.textContent = "@keyframes __cine_ripple{to{width:46px;height:46px;margin:-23px 0 0 -23px;opacity:0}}";
68
- document.head.appendChild(style);
69
- window.__cine_cap = (t) => {
70
- cap.textContent = t;
71
- cap.style.opacity = t ? "1" : "0";
72
- cap.style.transform = `translateX(-50%) translateY(${t ? 0 : 8}px)`;
196
+ await page.addInitScript(
197
+ ({ s, t0, TC }) => {
198
+ const boot = () => {
199
+ if (document.getElementById("__cine_cursor")) return;
200
+ const cursor = document.createElement("div");
201
+ cursor.id = "__cine_cursor";
202
+ cursor.style.cssText = `position:fixed;left:0;top:0;z-index:2147483647;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;pointer-events:none;transition:transform .09s ease-out;background:radial-gradient(circle at 35% 35%, ${s.cursorFrom}, ${s.cursorTo});box-shadow:0 0 0 3px rgba(255,255,255,.6),0 2px 10px rgba(0,0,0,.4);`;
203
+ document.body.appendChild(cursor);
204
+ window.addEventListener(
205
+ "mousemove",
206
+ (e) => {
207
+ cursor.style.transform = `translate(${e.clientX}px,${e.clientY}px)`;
208
+ },
209
+ true
210
+ );
211
+ window.addEventListener(
212
+ "mousedown",
213
+ (e) => {
214
+ const m = e;
215
+ const r = document.createElement("div");
216
+ r.style.cssText = `position:fixed;left:${m.clientX}px;top:${m.clientY}px;z-index:2147483646;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;pointer-events:none;border:2px solid ${s.ripple};animation:__cine_ripple .55s ease-out forwards;`;
217
+ document.body.appendChild(r);
218
+ setTimeout(() => r.remove(), 600);
219
+ },
220
+ true
221
+ );
222
+ const cap = document.createElement("div");
223
+ cap.id = "__cine_cap";
224
+ cap.style.cssText = `position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(8px);z-index:2147483646;max-width:72%;padding:13px 24px;border-radius:13px;font:500 17px/1.45 ${s.sansFont};color:#fff;letter-spacing:.01em;background:${s.ink}e0;backdrop-filter:blur(7px);box-shadow:0 10px 34px rgba(0,0,0,.4);text-align:center;opacity:0;transition:opacity .35s,transform .35s;`;
225
+ document.body.appendChild(cap);
226
+ const style = document.createElement("style");
227
+ style.textContent = "@keyframes __cine_ripple{to{width:46px;height:46px;margin:-23px 0 0 -23px;opacity:0}}";
228
+ document.head.appendChild(style);
229
+ window.__cine_cap = (t) => {
230
+ cap.textContent = t;
231
+ cap.style.opacity = t ? "1" : "0";
232
+ cap.style.transform = `translateX(-50%) translateY(${t ? 0 : 8}px)`;
233
+ };
234
+ if (t0 !== null) {
235
+ const strip = document.createElement("div");
236
+ strip.id = "__cine_timecode";
237
+ strip.style.cssText = `position:fixed;right:0;bottom:0;z-index:2147483647;display:flex;pointer-events:none;height:${TC}px`;
238
+ const cells = Array.from({ length: 18 }, (_, i) => {
239
+ const cell = document.createElement("div");
240
+ cell.style.cssText = `width:${TC}px;height:${TC}px;background:${i === 0 ? "#fff" : "#000"}`;
241
+ strip.appendChild(cell);
242
+ return cell;
243
+ });
244
+ document.body.appendChild(strip);
245
+ const tick = () => {
246
+ const ds = Math.max(0, Math.round((Date.now() - t0) / 100)) & 65535;
247
+ for (let bit = 0; bit < 16; bit += 1)
248
+ cells[bit + 2].style.background = ds >> 15 - bit & 1 ? "#fff" : "#000";
249
+ requestAnimationFrame(tick);
250
+ };
251
+ tick();
252
+ }
73
253
  };
74
- };
75
- if (document.body) boot();
76
- else document.addEventListener("DOMContentLoaded", boot);
77
- }, skin);
254
+ if (document.body) boot();
255
+ else document.addEventListener("DOMContentLoaded", boot);
256
+ },
257
+ { s: skin, t0: Take.on(page)?.t0 ?? null, TC: TIMECODE_CELL }
258
+ );
78
259
  }
79
260
  async function cover(page, { kicker, title, subtitle }, holdMs = 2600) {
261
+ const running = Take.on(page);
262
+ running?.cardStart({ kicker, title, subtitle });
80
263
  await page.evaluate(
81
- ({ kicker: kicker2, title: title2, subtitle: subtitle2, s }) => {
264
+ ({ kicker: kicker2, title: title2, subtitle: subtitle2, s, instant }) => {
82
265
  document.getElementById("__cine_cover")?.remove();
83
266
  const el = document.createElement("div");
84
267
  el.id = "__cine_cover";
85
- el.style.cssText = `position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 8%;background:linear-gradient(135deg,${s.coverFrom} 0%,${s.coverMid} 48%,${s.coverTo} 165%);opacity:0;transition:opacity .5s ease;font-family:${s.sansFont};`;
268
+ el.style.cssText = `position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:0 8%;background:linear-gradient(135deg,${s.coverFrom} 0%,${s.coverMid} 48%,${s.coverTo} 165%);opacity:${instant ? 1 : 0};transition:opacity ${instant ? 0 : 0.5}s ease;font-family:${s.sansFont};`;
86
269
  el.innerHTML = `<div style="text-transform:uppercase;letter-spacing:.26em;font-size:13px;font-weight:600;color:${s.accent};margin-bottom:22px">${kicker2}</div><div style="font-family:${s.displayFont};font-weight:600;font-size:52px;line-height:1.08;letter-spacing:-.02em;color:${s.coverTitle};max-width:16ch">${title2}</div>` + (subtitle2 ? `<div style="margin-top:22px;font-size:19px;line-height:1.5;color:${s.coverTitle}b8;max-width:46ch">${subtitle2}</div>` : "") + `<div style="margin-top:44px;display:flex;align-items:center;gap:10px;color:${s.coverTitle}80;font-size:13px;letter-spacing:.02em"><span style="width:26px;height:1px;background:${s.accent}"></span>${s.firmLabel}</div>`;
87
270
  document.body.appendChild(el);
88
271
  requestAnimationFrame(() => el.style.opacity = "1");
89
272
  },
90
- { kicker, title, subtitle: subtitle ?? "", s: skin }
273
+ { kicker, title, subtitle: subtitle ?? "", s: skin, instant: !!running }
91
274
  );
92
275
  await page.waitForTimeout(holdMs);
93
276
  }
94
- async function uncover(page) {
277
+ async function chapter(page, card, holdMs) {
278
+ await cover(page, card, holdMs);
95
279
  await page.evaluate(() => {
280
+ const el = document.getElementById("__cine_cover");
281
+ if (el) el.style.pointerEvents = "none";
282
+ });
283
+ }
284
+ async function uncover(page) {
285
+ const running = Take.on(page);
286
+ await page.evaluate((instant) => {
96
287
  const el = document.getElementById("__cine_cover");
97
288
  if (!el) return;
289
+ if (instant) return el.remove();
98
290
  el.style.opacity = "0";
99
291
  setTimeout(() => el.remove(), 520);
100
- });
292
+ }, !!running);
293
+ running?.cardEnd();
101
294
  await page.waitForTimeout(560);
102
295
  }
296
+ function lowerThird(page, kicker, title, holdMs = 3200) {
297
+ Take.on(page)?.lowerThird(kicker, title, holdMs);
298
+ }
103
299
  async function caption(page, text, holdMs) {
104
- await page.evaluate(
105
- (t) => window.__cine_cap?.(t),
106
- text
107
- );
300
+ const running = Take.on(page);
301
+ if (running) running.captionStart(text);
302
+ else
303
+ await page.evaluate(
304
+ (t) => window.__cine_cap?.(t),
305
+ text
306
+ );
108
307
  const hold = holdMs ?? Math.min(4200, 900 + text.length * 45);
109
308
  await page.waitForTimeout(hold);
110
309
  }
111
310
  async function clearCaption(page) {
112
- await page.evaluate(
113
- () => window.__cine_cap?.("")
114
- );
311
+ const running = Take.on(page);
312
+ if (running) running.captionEnd();
313
+ else
314
+ await page.evaluate(
315
+ () => window.__cine_cap?.("")
316
+ );
115
317
  }
116
318
  async function beat(page, ms = 650) {
117
319
  await page.waitForTimeout(ms);
118
320
  }
119
321
  async function glideTo(page, target) {
120
- const loc = resolve(page, target).first();
121
- await loc.scrollIntoViewIfNeeded().catch(() => {
122
- });
123
- const box = await loc.boundingBox();
124
- if (box) {
125
- await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2, { steps: 26 });
126
- await page.waitForTimeout(180);
127
- }
322
+ const running = Take.on(page);
323
+ const start = running?.now() ?? 0;
324
+ const { loc, box } = await glide(page, target);
325
+ if (running && box) running.record({ kind: "point", start, box });
128
326
  return loc;
129
327
  }
130
328
  async function click(page, target) {
131
- const loc = await glideTo(page, target);
329
+ const running = Take.on(page);
330
+ const start = running?.now() ?? 0;
331
+ const { loc, box } = await glide(page, target);
132
332
  await loc.click();
133
333
  await page.waitForTimeout(260);
334
+ if (running && box) running.record({ kind: "click", start, end: running.now(), box });
134
335
  }
135
336
  async function type(page, target, text) {
136
- const loc = await glideTo(page, target);
337
+ const running = Take.on(page);
338
+ const start = running?.now() ?? 0;
339
+ const { loc, box } = await glide(page, target);
137
340
  await loc.click();
138
341
  await loc.fill("");
139
342
  await loc.pressSequentially(text, { delay: 42 });
140
343
  await page.waitForTimeout(240);
344
+ if (running && box) running.record({ kind: "type", start, end: running.now(), box });
345
+ }
346
+ async function focusOn(page, target, label, {
347
+ holdMs = 2200,
348
+ callout = true,
349
+ mode
350
+ } = {}) {
351
+ const running = Take.on(page);
352
+ const start = running?.now() ?? 0;
353
+ const { box } = await glide(page, target);
354
+ await page.waitForTimeout(holdMs);
355
+ if (running && box)
356
+ running.record({ kind: "focus", label, start, end: running.now(), box, callout, mode });
357
+ }
358
+ async function readDown(page, target, scrolls = 3, pauseMs = 1600) {
359
+ const running = Take.on(page);
360
+ const start = running?.now() ?? 0;
361
+ const { box } = await glide(page, target);
362
+ for (let i = 0; i < scrolls; i += 1) {
363
+ await page.mouse.wheel(0, 320);
364
+ await beat(page, pauseMs);
365
+ }
366
+ await page.mouse.wheel(0, -320 * scrolls);
367
+ await beat(page, 500);
368
+ if (running && box) running.record({ kind: "read", start, end: running.now(), box });
141
369
  }
142
370
  async function login(page, opts = {}) {
371
+ if (!config.creds) throw new Error("createCinematic: pass creds to sign in");
143
372
  await page.goto(loginPath);
144
373
  if (opts.show === false) {
145
374
  await page.getByTestId(ids.email).fill(config.creds.email);
@@ -156,19 +385,24 @@ function createCinematic(config) {
156
385
  await beat(page, 800);
157
386
  }
158
387
  return {
388
+ take,
159
389
  installStage,
160
390
  cover,
391
+ chapter,
161
392
  uncover,
393
+ lowerThird,
162
394
  caption,
163
395
  clearCaption,
164
396
  beat,
165
397
  glideTo,
166
398
  click,
167
399
  type,
400
+ focusOn,
401
+ readDown,
168
402
  login
169
403
  };
170
404
  }
171
405
 
172
- export { createCinematic };
406
+ export { TIMECODE_CELL, Take, cinematicSkin, createCinematic };
173
407
  //# sourceMappingURL=index.js.map
174
408
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/record/index.ts"],"names":["kicker","title","subtitle"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cinematic recording harness — host-agnostic.\n *\n * Turns a Playwright run into a narrated product demo: a visible cursor that\n * glides between targets, a click ripple, a caption bar that narrates each step,\n * full-screen chapter \"cover\" cards, and human-speed pacing. Every host app gets\n * the same polished demo capability from one factory — brand colours, fonts,\n * credentials and the login flow arrive as config, so nothing here names a host.\n *\n * Pair with a Playwright project that records video (see the host's\n * `playwright.record.config.ts`: video on, a large viewport, some slowMo).\n *\n * Usage in a `*.record.ts` spec:\n * const cine = createCinematic({ brand, creds })\n * await cine.installStage(page) // before the first navigation\n * await cine.cover(page, { kicker, title, subtitle })\n * await cine.login(page)\n * await cine.uncover(page)\n * await cine.caption(page, \"Opening the flagship matter…\")\n * await cine.click(page, \"matters-row-…\")\n *\n * `@playwright/test` is an optional peer used for TYPES only (no runtime import), so\n * importing this entry never loads Playwright.\n */\nimport type { Page, Locator } from '@playwright/test'\n\n/** Brand skin for the on-screen chrome. All optional — sensible neutral defaults. */\nexport interface CinematicBrand {\n /** Footer line on chapter cards, e.g. \"Meridian · AI-native counsel\". */\n firmLabel: string\n /** Serif display font for cover titles (CSS font-family value). */\n displayFont?: string\n /** Sans font for captions + cover body. */\n sansFont?: string\n /** Cursor dot radial-gradient stops. */\n cursor?: { from: string; to: string }\n /** Click-ripple ring colour. */\n ripple?: string\n /** Chapter-card background gradient stops. */\n cover?: { from: string; mid: string; to: string }\n /** Accent (kicker text + rule) on chapter cards. */\n accent?: string\n /** Caption bar background base colour. */\n ink?: string\n /** Cover title text colour. */\n coverTitle?: string\n}\n\nexport interface CinematicCreds {\n email: string\n password: string\n}\n\nexport interface CinematicConfig {\n brand: CinematicBrand\n creds: CinematicCreds\n /** Login route (default \"/app/login\"). */\n loginPath?: string\n /** URL the app lands on after auth (default /\\/app$/). */\n appUrlPattern?: RegExp\n /** Login form testids (defaults match the shared AppShell/login convention). */\n testIds?: { email?: string; password?: string; submit?: string }\n}\n\nexport interface Cinematic {\n installStage(page: Page): Promise<void>\n cover(\n page: Page,\n opts: { kicker: string; title: string; subtitle?: string },\n holdMs?: number\n ): Promise<void>\n uncover(page: Page): Promise<void>\n caption(page: Page, text: string, holdMs?: number): Promise<void>\n clearCaption(page: Page): Promise<void>\n beat(page: Page, ms?: number): Promise<void>\n glideTo(page: Page, target: string | Locator): Promise<Locator>\n click(page: Page, target: string | Locator): Promise<void>\n type(page: Page, target: string | Locator, text: string): Promise<void>\n /** Sign in. `{ show: false }` authenticates fast + silent (no animation/caption). */\n login(page: Page, opts?: { show?: boolean; caption?: string }): Promise<void>\n}\n\nconst DEFAULTS = {\n displayFont: 'ui-serif, Georgia, serif',\n sansFont: 'Inter, ui-sans-serif, system-ui, sans-serif',\n cursor: { from: 'rgba(31,111,235,.98)', to: 'rgba(11,42,74,.92)' },\n ripple: 'rgba(11,42,74,.85)',\n cover: { from: '#0b1622', mid: '#0e1b2c', to: '#1f6feb' },\n accent: '#c9a24b',\n ink: '#0e1b2d',\n coverTitle: '#f4f6f8',\n}\n\nexport function createCinematic(config: CinematicConfig): Cinematic {\n const b = config.brand\n const skin = {\n firmLabel: b.firmLabel,\n displayFont: b.displayFont ?? DEFAULTS.displayFont,\n sansFont: b.sansFont ?? DEFAULTS.sansFont,\n cursorFrom: b.cursor?.from ?? DEFAULTS.cursor.from,\n cursorTo: b.cursor?.to ?? DEFAULTS.cursor.to,\n ripple: b.ripple ?? DEFAULTS.ripple,\n coverFrom: b.cover?.from ?? DEFAULTS.cover.from,\n coverMid: b.cover?.mid ?? DEFAULTS.cover.mid,\n coverTo: b.cover?.to ?? DEFAULTS.cover.to,\n accent: b.accent ?? DEFAULTS.accent,\n ink: b.ink ?? DEFAULTS.ink,\n coverTitle: b.coverTitle ?? DEFAULTS.coverTitle,\n }\n const loginPath = config.loginPath ?? '/app/login'\n const appUrlPattern = config.appUrlPattern ?? /\\/app$/\n const ids = {\n email: config.testIds?.email ?? 'auth-email',\n password: config.testIds?.password ?? 'auth-password',\n submit: config.testIds?.submit ?? 'auth-login-submit',\n }\n\n const resolve = (page: Page, t: string | Locator): Locator =>\n typeof t === 'string' ? page.getByTestId(t) : t\n\n async function installStage(page: Page): Promise<void> {\n await page.addInitScript((s: typeof skin) => {\n const boot = () => {\n if (document.getElementById('__cine_cursor')) return\n\n const cursor = document.createElement('div')\n cursor.id = '__cine_cursor'\n cursor.style.cssText =\n 'position:fixed;left:0;top:0;z-index:2147483647;width:22px;height:22px;' +\n 'margin:-11px 0 0 -11px;border-radius:50%;pointer-events:none;' +\n 'transition:transform .09s ease-out;' +\n `background:radial-gradient(circle at 35% 35%, ${s.cursorFrom}, ${s.cursorTo});` +\n 'box-shadow:0 0 0 3px rgba(255,255,255,.6),0 2px 10px rgba(0,0,0,.4);'\n document.body.appendChild(cursor)\n\n window.addEventListener(\n 'mousemove',\n (e) => {\n cursor.style.transform = `translate(${(e as MouseEvent).clientX}px,${(e as MouseEvent).clientY}px)`\n },\n true\n )\n window.addEventListener(\n 'mousedown',\n (e) => {\n const m = e as MouseEvent\n const r = document.createElement('div')\n r.style.cssText =\n `position:fixed;left:${m.clientX}px;top:${m.clientY}px;z-index:2147483646;` +\n 'width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;pointer-events:none;' +\n `border:2px solid ${s.ripple};animation:__cine_ripple .55s ease-out forwards;`\n document.body.appendChild(r)\n setTimeout(() => r.remove(), 600)\n },\n true\n )\n\n const cap = document.createElement('div')\n cap.id = '__cine_cap'\n cap.style.cssText =\n 'position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(8px);' +\n 'z-index:2147483646;max-width:72%;padding:13px 24px;border-radius:13px;' +\n `font:500 17px/1.45 ${s.sansFont};color:#fff;letter-spacing:.01em;` +\n `background:${s.ink}e0;backdrop-filter:blur(7px);` +\n 'box-shadow:0 10px 34px rgba(0,0,0,.4);text-align:center;opacity:0;transition:opacity .35s,transform .35s;'\n document.body.appendChild(cap)\n\n const style = document.createElement('style')\n style.textContent =\n '@keyframes __cine_ripple{to{width:46px;height:46px;margin:-23px 0 0 -23px;opacity:0}}'\n document.head.appendChild(style)\n\n ;(window as unknown as { __cine_cap: (t: string) => void }).__cine_cap = (t: string) => {\n cap.textContent = t\n cap.style.opacity = t ? '1' : '0'\n cap.style.transform = `translateX(-50%) translateY(${t ? 0 : 8}px)`\n }\n }\n if (document.body) boot()\n else document.addEventListener('DOMContentLoaded', boot)\n }, skin)\n }\n\n async function cover(\n page: Page,\n { kicker, title, subtitle }: { kicker: string; title: string; subtitle?: string },\n holdMs = 2600\n ): Promise<void> {\n await page.evaluate(\n ({ kicker, title, subtitle, s }) => {\n document.getElementById('__cine_cover')?.remove()\n const el = document.createElement('div')\n el.id = '__cine_cover'\n el.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;' +\n 'align-items:center;justify-content:center;text-align:center;padding:0 8%;' +\n `background:linear-gradient(135deg,${s.coverFrom} 0%,${s.coverMid} 48%,${s.coverTo} 165%);` +\n `opacity:0;transition:opacity .5s ease;font-family:${s.sansFont};`\n el.innerHTML =\n `<div style=\"text-transform:uppercase;letter-spacing:.26em;font-size:13px;font-weight:600;color:${s.accent};margin-bottom:22px\">${kicker}</div>` +\n `<div style=\"font-family:${s.displayFont};font-weight:600;font-size:52px;line-height:1.08;letter-spacing:-.02em;color:${s.coverTitle};max-width:16ch\">${title}</div>` +\n (subtitle\n ? `<div style=\"margin-top:22px;font-size:19px;line-height:1.5;color:${s.coverTitle}b8;max-width:46ch\">${subtitle}</div>`\n : '') +\n `<div style=\"margin-top:44px;display:flex;align-items:center;gap:10px;color:${s.coverTitle}80;font-size:13px;letter-spacing:.02em\">` +\n `<span style=\"width:26px;height:1px;background:${s.accent}\"></span>${s.firmLabel}</div>`\n document.body.appendChild(el)\n requestAnimationFrame(() => (el.style.opacity = '1'))\n },\n { kicker, title, subtitle: subtitle ?? '', s: skin }\n )\n await page.waitForTimeout(holdMs)\n }\n\n async function uncover(page: Page): Promise<void> {\n await page.evaluate(() => {\n const el = document.getElementById('__cine_cover')\n if (!el) return\n el.style.opacity = '0'\n setTimeout(() => el.remove(), 520)\n })\n await page.waitForTimeout(560)\n }\n\n async function caption(page: Page, text: string, holdMs?: number): Promise<void> {\n await page.evaluate(\n (t) => (window as unknown as { __cine_cap?: (s: string) => void }).__cine_cap?.(t),\n text\n )\n const hold = holdMs ?? Math.min(4200, 900 + text.length * 45)\n await page.waitForTimeout(hold)\n }\n\n async function clearCaption(page: Page): Promise<void> {\n await page.evaluate(() =>\n (window as unknown as { __cine_cap?: (s: string) => void }).__cine_cap?.('')\n )\n }\n\n async function beat(page: Page, ms = 650): Promise<void> {\n await page.waitForTimeout(ms)\n }\n\n async function glideTo(page: Page, target: string | Locator): Promise<Locator> {\n const loc = resolve(page, target).first()\n await loc.scrollIntoViewIfNeeded().catch(() => {})\n const box = await loc.boundingBox()\n if (box) {\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2, { steps: 26 })\n await page.waitForTimeout(180)\n }\n return loc\n }\n\n async function click(page: Page, target: string | Locator): Promise<void> {\n const loc = await glideTo(page, target)\n await loc.click()\n await page.waitForTimeout(260)\n }\n\n async function type(page: Page, target: string | Locator, text: string): Promise<void> {\n const loc = await glideTo(page, target)\n await loc.click()\n await loc.fill('')\n await loc.pressSequentially(text, { delay: 42 })\n await page.waitForTimeout(240)\n }\n\n async function login(page: Page, opts: { show?: boolean; caption?: string } = {}): Promise<void> {\n await page.goto(loginPath)\n if (opts.show === false) {\n await page.getByTestId(ids.email).fill(config.creds.email)\n await page.getByTestId(ids.password).fill(config.creds.password)\n await page.getByTestId(ids.submit).click()\n await page.waitForURL(appUrlPattern, { timeout: 45_000 })\n return\n }\n await caption(page, opts.caption ?? `${b.firmLabel} — signing in.`, 1600)\n await type(page, ids.email, config.creds.email)\n await type(page, ids.password, config.creds.password)\n await click(page, ids.submit)\n await page.waitForURL(appUrlPattern, { timeout: 45_000 })\n await beat(page, 800)\n }\n\n return {\n installStage,\n cover,\n uncover,\n caption,\n clearCaption,\n beat,\n glideTo,\n click,\n type,\n login,\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/record/index.ts"],"names":["kicker","title","subtitle"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cinematic recording harness — host-agnostic.\n *\n * Turns a Playwright run into a narrated product demo: a visible cursor that glides between\n * targets, a click ripple, captions, full-screen chapter cards, lower-thirds and human-speed\n * pacing. Every host app gets the same demo capability from one factory: brand colours, fonts,\n * credentials and the login flow arrive as config, so nothing here names a host.\n *\n * With a take running (`cine.take`), the run is also logged for the edit, in seconds from the\n * start of the video:\n * - every wait (the AI working, a file uploading) to `<dir>/<name>.waits.json`, so the edit can\n * cut the middle of each long one;\n * - the focus timeline to `<dir>/<name>.focus.json`: each click, type and read with its target's\n * box on screen, the key moments `focusOn` marks, the cards, lower-thirds and captions, the\n * take's config (zoom, max zoom, picture-in-picture) and the brand.\n * Captions, cards and lower-thirds are then drawn by the edit (brand PNGs over the video, outside\n * any zoom), not in the page, and a timecode strip in the corner lines the two clocks up.\n * `arbidocs-render-take` (this package's bin) renders the cut, zoomed, titled video from them.\n *\n * Usage in a recording script:\n * const cine = createCinematic({ brand, creds })\n * const take = await cine.take(page, { name: 'reply-with-arbi', dir: 'recordings' })\n * await cine.installStage(page) // after the take, before the first navigation\n * await take.markSync()\n * await page.goto('/')\n * await cine.chapter(page, { kicker, title, subtitle })\n * await cine.login(page, { show: false })\n * await cine.uncover(page)\n * await cine.click(page, 'sidebar-mail-button')\n * await take.wait('ARBI drafting', () => expect(reply).toBeVisible())\n * await cine.focusOn(page, reply, 'ARBI’s reply, as tracked changes')\n *\n * `@playwright/test` is an optional peer used for TYPES only (no runtime import), so importing\n * this entry never loads Playwright.\n */\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Page, Locator } from '@playwright/test'\n\n/** Brand skin for the on-screen chrome. All optional — sensible neutral defaults. */\nexport interface CinematicBrand {\n /** Footer line on chapter cards, e.g. \"Meridian · AI-native counsel\". */\n firmLabel: string\n /** Serif display font for cover titles (CSS font-family value). */\n displayFont?: string\n /** Sans font for captions + cover body. */\n sansFont?: string\n /** Cursor dot radial-gradient stops. */\n cursor?: { from: string; to: string }\n /** Click-ripple ring colour. */\n ripple?: string\n /** Chapter-card background gradient stops. */\n cover?: { from: string; mid: string; to: string }\n /** Accent (kicker text + rule) on chapter cards, callouts and lower-thirds. */\n accent?: string\n /** Caption bar background base colour. */\n ink?: string\n /** Cover title text colour. */\n coverTitle?: string\n /**\n * Font files for the edit's overlays (cards, captions), when the display or sans font is not\n * installed where the video is rendered: each a family name and a `file://` or `https://` URL.\n */\n fontFiles?: { family: string; url: string; weight?: string; unicodeRange?: string }[]\n}\n\nexport interface CinematicCreds {\n email: string\n password: string\n}\n\nexport interface CinematicConfig {\n brand: CinematicBrand\n /** For `login`. */\n creds?: CinematicCreds\n /** Login route (default \"/app/login\"). */\n loginPath?: string\n /** URL the app lands on after auth (default /\\/app$/). */\n appUrlPattern?: RegExp\n /** Login form testids (defaults match the shared AppShell/login convention). */\n testIds?: { email?: string; password?: string; submit?: string }\n}\n\n/** A box on screen, in page pixels. */\nexport interface Box {\n x: number\n y: number\n width: number\n height: number\n}\n\n/**\n * A moment the edit may frame: a click, typing, reading down a result, a glide-and-look (`point`,\n * which lasts until the next gesture), or a key moment marked with `focusOn`.\n */\nexport interface FocusEvent {\n kind: 'click' | 'type' | 'read' | 'point' | 'focus'\n label?: string\n start: number\n end?: number\n box: Box\n /** Draw a highlight (and the label as its tag) round the box. */\n callout?: boolean\n /** How to frame it: zoom in, a picture-in-picture inset, or not at all (default: the edit decides). */\n mode?: 'zoom' | 'pip' | 'none'\n}\n\n/** A take's say in its edit. */\nexport interface TakeOptions {\n /** The take's name: its files are `<dir>/<name>.waits.json` and `<dir>/<name>.focus.json`. */\n name: string\n /** Where the take's files go (default `recordings`). */\n dir?: string\n /** Zoom and pan onto the action (default true). */\n zoom?: boolean\n /** At most this much (default 1.8). */\n maxZoom?: number\n /** A picture-in-picture inset for long typing (default true). */\n pip?: boolean\n}\n\nexport interface Wait {\n label: string\n start: number\n end: number\n}\n\ninterface Card {\n kicker: string\n title: string\n subtitle?: string\n start: number\n end: number | null\n}\n\n/** The timecode's square, in page pixels (the renderer reads it at this size). */\nexport const TIMECODE_CELL = 8\n\nconst round = (n: number) => Math.round(n * 100) / 100\n\n/**\n * One recorded take: its clock, its waits and its focus timeline. Start it first thing (the video\n * starts with the page, a moment before; `markSync` lines the two clocks up exactly).\n */\nexport class Take {\n /** The take running now (one at a time: recordings run one after another). */\n private static active: Take | null = null\n\n readonly t0 = Date.now()\n readonly waits: Wait[] = []\n /** The brand the edit paints the cards, captions and callouts in. */\n private readonly brand: object\n readonly file: string\n readonly focusFile: string\n private readonly timeline = {\n sync: null as number | null,\n viewport: null as { width: number; height: number } | null,\n focus: [] as FocusEvent[],\n cards: [] as Card[],\n lowerThirds: [] as { kicker: string; title: string; start: number; end: number }[],\n captions: [] as { text: string; start: number; end: number | null }[],\n }\n\n constructor(\n readonly page: Page,\n private readonly options: TakeOptions,\n brand?: CinematicBrand\n ) {\n this.brand = brand ? cinematicSkin(brand) : {}\n const dir = path.resolve(options.dir ?? 'recordings')\n this.file = path.join(dir, `${options.name}.waits.json`)\n this.focusFile = path.join(dir, `${options.name}.focus.json`)\n this.timeline.viewport = page.viewportSize()\n mkdirSync(dir, { recursive: true })\n Take.active = this\n this.save()\n }\n\n /** The take running on `page`, if any. */\n static on(page: Page): Take | null {\n return Take.active?.page === page ? Take.active : null\n }\n\n /** Seconds since the take started. */\n now(): number {\n return (Date.now() - this.t0) / 1000\n }\n\n /** Log a wait (written at once, so a take that fails part-way still has its cut list). */\n log(label: string, start: number, end = this.now()): void {\n if (end - start < 1) return\n this.waits.push({ label, start: round(start), end: round(end) })\n this.save()\n }\n\n /** Wait for `until` (a UI state), logged as a wait the edit may cut. */\n async wait<T>(label: string, until: () => Promise<T>): Promise<T> {\n const start = this.now()\n try {\n return await until()\n } finally {\n this.log(label, start)\n }\n }\n\n /**\n * Paint the sync marker: a magenta frame for a moment, at a logged time. The edit finds it in the\n * video and lines the take's clock up with the video's. Call it before the first navigation.\n */\n async markSync(): Promise<void> {\n await this.page.evaluate(\n () =>\n new Promise<void>((done) => {\n document.documentElement.style.background = '#ff00ff'\n if (document.body) document.body.style.background = '#ff00ff'\n requestAnimationFrame(() => requestAnimationFrame(() => done()))\n })\n )\n this.timeline.sync = round(this.now())\n await this.page.waitForTimeout(400)\n this.save()\n }\n\n /** Log a focus event (a `point` with no end lasts until the next event). */\n record(event: Omit<FocusEvent, 'start' | 'end'> & { start: number; end?: number }): void {\n const { focus } = this.timeline\n const open = focus[focus.length - 1]\n if (open && open.kind === 'point' && open.end === undefined) open.end = round(event.start)\n focus.push({\n ...event,\n start: round(event.start),\n end: event.end === undefined ? undefined : round(event.end),\n })\n this.save()\n }\n\n /** @internal The stage's cards, lower-thirds and captions (drawn by the edit). */\n cardStart(card: Omit<Card, 'start' | 'end'>): void {\n this.cardEnd()\n this.captionEnd()\n this.timeline.cards.push({ ...card, start: round(this.now()), end: null })\n this.save()\n }\n\n cardEnd(): void {\n const last = this.timeline.cards[this.timeline.cards.length - 1]\n if (last && last.end === null) {\n last.end = round(this.now())\n this.save()\n }\n }\n\n lowerThird(kicker: string, title: string, holdMs: number): void {\n const start = round(this.now())\n this.timeline.lowerThirds.push({ kicker, title, start, end: round(start + holdMs / 1000) })\n this.save()\n }\n\n captionStart(text: string): void {\n this.captionEnd()\n this.timeline.captions.push({ text, start: round(this.now()), end: null })\n this.save()\n }\n\n captionEnd(): void {\n const last = this.timeline.captions[this.timeline.captions.length - 1]\n if (last && last.end === null) {\n last.end = round(this.now())\n this.save()\n }\n }\n\n private save(): void {\n const { zoom, maxZoom, pip } = this.options\n writeFileSync(this.file, JSON.stringify({ t0: this.t0, waits: this.waits }, null, 1))\n writeFileSync(\n this.focusFile,\n JSON.stringify(\n { t0: this.t0, config: { zoom, maxZoom, pip }, brand: this.brand, ...this.timeline },\n null,\n 1\n )\n )\n }\n}\n\nexport interface Cinematic {\n /** Start a take on `page` (before `installStage`, so the stage paints its timecode). */\n take(page: Page, options: TakeOptions): Promise<Take>\n installStage(page: Page): Promise<void>\n cover(\n page: Page,\n opts: { kicker: string; title: string; subtitle?: string },\n holdMs?: number\n ): Promise<void>\n /** A cover the work can go on behind (clicks pass through it) until `uncover`. */\n chapter(\n page: Page,\n opts: { kicker: string; title: string; subtitle?: string },\n holdMs?: number\n ): Promise<void>\n uncover(page: Page): Promise<void>\n /** A section's name over the bottom left while the work goes on (drawn by the edit). */\n lowerThird(page: Page, kicker: string, title: string, holdMs?: number): void\n caption(page: Page, text: string, holdMs?: number): Promise<void>\n clearCaption(page: Page): Promise<void>\n beat(page: Page, ms?: number): Promise<void>\n glideTo(page: Page, target: string | Locator): Promise<Locator>\n click(page: Page, target: string | Locator): Promise<void>\n type(page: Page, target: string | Locator, text: string): Promise<void>\n /** A key moment: glide to it and hold; the edit zooms onto it and draws a callout with `label`. */\n focusOn(\n page: Page,\n target: string | Locator,\n label?: string,\n opts?: { holdMs?: number; callout?: boolean; mode?: FocusEvent['mode'] }\n ): Promise<void>\n /** Read down a result at a reader's pace, then back to the top. */\n readDown(page: Page, target: string | Locator, scrolls?: number, pauseMs?: number): Promise<void>\n /** Sign in. `{ show: false }` authenticates fast + silent (no animation/caption). */\n login(page: Page, opts?: { show?: boolean; caption?: string }): Promise<void>\n}\n\nconst DEFAULTS = {\n displayFont: 'ui-serif, Georgia, serif',\n sansFont: 'Inter, ui-sans-serif, system-ui, sans-serif',\n cursor: { from: 'rgba(31,111,235,.98)', to: 'rgba(11,42,74,.92)' },\n ripple: 'rgba(11,42,74,.85)',\n cover: { from: '#0b1622', mid: '#0e1b2c', to: '#1f6feb' },\n accent: '#c9a24b',\n ink: '#0e1b2d',\n coverTitle: '#f4f6f8',\n}\n\n/** A brand with every default filled in: what the stage paints and the take hands the edit. */\nexport function cinematicSkin(b: CinematicBrand) {\n return {\n firmLabel: b.firmLabel,\n displayFont: b.displayFont ?? DEFAULTS.displayFont,\n sansFont: b.sansFont ?? DEFAULTS.sansFont,\n cursorFrom: b.cursor?.from ?? DEFAULTS.cursor.from,\n cursorTo: b.cursor?.to ?? DEFAULTS.cursor.to,\n ripple: b.ripple ?? DEFAULTS.ripple,\n coverFrom: b.cover?.from ?? DEFAULTS.cover.from,\n coverMid: b.cover?.mid ?? DEFAULTS.cover.mid,\n coverTo: b.cover?.to ?? DEFAULTS.cover.to,\n accent: b.accent ?? DEFAULTS.accent,\n ink: b.ink ?? DEFAULTS.ink,\n coverTitle: b.coverTitle ?? DEFAULTS.coverTitle,\n fontFiles: b.fontFiles ?? [],\n }\n}\n\nexport function createCinematic(config: CinematicConfig): Cinematic {\n const b = config.brand\n const skin = cinematicSkin(b)\n const loginPath = config.loginPath ?? '/app/login'\n const appUrlPattern = config.appUrlPattern ?? /\\/app$/\n const ids = {\n email: config.testIds?.email ?? 'auth-email',\n password: config.testIds?.password ?? 'auth-password',\n submit: config.testIds?.submit ?? 'auth-login-submit',\n }\n\n const resolve = (page: Page, t: string | Locator): Locator =>\n typeof t === 'string' ? page.getByTestId(t) : t\n\n /** The target's box on screen (clipped to the viewport), or null when it is not on screen. */\n async function boxOf(page: Page, loc: Locator): Promise<Box | null> {\n const box = await loc.boundingBox().catch(() => null)\n const vp = page.viewportSize()\n if (!box || !vp) return box\n const x = Math.max(box.x, 0)\n const y = Math.max(box.y, 0)\n const width = Math.min(box.x + box.width, vp.width) - x\n const height = Math.min(box.y + box.height, vp.height) - y\n return width > 0 && height > 0\n ? { x: round(x), y: round(y), width: round(width), height: round(height) }\n : null\n }\n\n /** Move the cursor to the centre of a target, smoothly; its box once there. */\n async function glide(\n page: Page,\n target: string | Locator\n ): Promise<{ loc: Locator; box: Box | null }> {\n const loc = resolve(page, target).first()\n await loc.scrollIntoViewIfNeeded().catch(() => {})\n const box = await boxOf(page, loc)\n if (box) {\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2, { steps: 26 })\n await page.waitForTimeout(180)\n }\n return { loc, box }\n }\n\n async function take(page: Page, options: TakeOptions): Promise<Take> {\n return new Take(page, options, b)\n }\n\n async function installStage(page: Page): Promise<void> {\n await page.addInitScript(\n ({ s, t0, TC }: { s: typeof skin; t0: number | null; TC: number }) => {\n const boot = () => {\n if (document.getElementById('__cine_cursor')) return\n\n const cursor = document.createElement('div')\n cursor.id = '__cine_cursor'\n cursor.style.cssText =\n 'position:fixed;left:0;top:0;z-index:2147483647;width:22px;height:22px;' +\n 'margin:-11px 0 0 -11px;border-radius:50%;pointer-events:none;' +\n 'transition:transform .09s ease-out;' +\n `background:radial-gradient(circle at 35% 35%, ${s.cursorFrom}, ${s.cursorTo});` +\n 'box-shadow:0 0 0 3px rgba(255,255,255,.6),0 2px 10px rgba(0,0,0,.4);'\n document.body.appendChild(cursor)\n\n window.addEventListener(\n 'mousemove',\n (e) => {\n cursor.style.transform = `translate(${(e as MouseEvent).clientX}px,${(e as MouseEvent).clientY}px)`\n },\n true\n )\n window.addEventListener(\n 'mousedown',\n (e) => {\n const m = e as MouseEvent\n const r = document.createElement('div')\n r.style.cssText =\n `position:fixed;left:${m.clientX}px;top:${m.clientY}px;z-index:2147483646;` +\n 'width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;pointer-events:none;' +\n `border:2px solid ${s.ripple};animation:__cine_ripple .55s ease-out forwards;`\n document.body.appendChild(r)\n setTimeout(() => r.remove(), 600)\n },\n true\n )\n\n const cap = document.createElement('div')\n cap.id = '__cine_cap'\n cap.style.cssText =\n 'position:fixed;left:50%;bottom:34px;transform:translateX(-50%) translateY(8px);' +\n 'z-index:2147483646;max-width:72%;padding:13px 24px;border-radius:13px;' +\n `font:500 17px/1.45 ${s.sansFont};color:#fff;letter-spacing:.01em;` +\n `background:${s.ink}e0;backdrop-filter:blur(7px);` +\n 'box-shadow:0 10px 34px rgba(0,0,0,.4);text-align:center;opacity:0;transition:opacity .35s,transform .35s;'\n document.body.appendChild(cap)\n\n const style = document.createElement('style')\n style.textContent =\n '@keyframes __cine_ripple{to{width:46px;height:46px;margin:-23px 0 0 -23px;opacity:0}}'\n document.head.appendChild(style)\n\n ;(window as unknown as { __cine_cap: (t: string) => void }).__cine_cap = (t: string) => {\n cap.textContent = t\n cap.style.opacity = t ? '1' : '0'\n cap.style.transform = `translateX(-50%) translateY(${t ? 0 : 8}px)`\n }\n\n // The timecode: with a take running, the take's clock in tenths of a second as 16 squares\n // (white = 1, most significant first) after a white and a black guard, in the bottom right\n // corner. The edit reads it from every frame to line the timeline up with the video (the\n // video's clock drifts from the wall clock over a long take), and paints it out.\n if (t0 !== null) {\n const strip = document.createElement('div')\n strip.id = '__cine_timecode'\n strip.style.cssText = `position:fixed;right:0;bottom:0;z-index:2147483647;display:flex;pointer-events:none;height:${TC}px`\n const cells = Array.from({ length: 18 }, (_, i) => {\n const cell = document.createElement('div')\n cell.style.cssText = `width:${TC}px;height:${TC}px;background:${i === 0 ? '#fff' : '#000'}`\n strip.appendChild(cell)\n return cell\n })\n document.body.appendChild(strip)\n const tick = () => {\n const ds = Math.max(0, Math.round((Date.now() - t0) / 100)) & 0xffff\n for (let bit = 0; bit < 16; bit += 1)\n cells[bit + 2].style.background = (ds >> (15 - bit)) & 1 ? '#fff' : '#000'\n requestAnimationFrame(tick)\n }\n tick()\n }\n }\n if (document.body) boot()\n else document.addEventListener('DOMContentLoaded', boot)\n },\n { s: skin, t0: Take.on(page)?.t0 ?? null, TC: TIMECODE_CELL }\n )\n }\n\n async function cover(\n page: Page,\n { kicker, title, subtitle }: { kicker: string; title: string; subtitle?: string },\n holdMs = 2600\n ): Promise<void> {\n // With a take running, the edit draws the card over this one from the brand PNG (crisp, cut to\n // length) and does the fades, so in the page it shows and goes at once.\n const running = Take.on(page)\n running?.cardStart({ kicker, title, subtitle })\n await page.evaluate(\n ({ kicker, title, subtitle, s, instant }) => {\n document.getElementById('__cine_cover')?.remove()\n const el = document.createElement('div')\n el.id = '__cine_cover'\n el.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;' +\n 'align-items:center;justify-content:center;text-align:center;padding:0 8%;' +\n `background:linear-gradient(135deg,${s.coverFrom} 0%,${s.coverMid} 48%,${s.coverTo} 165%);` +\n `opacity:${instant ? 1 : 0};transition:opacity ${instant ? 0 : 0.5}s ease;font-family:${s.sansFont};`\n el.innerHTML =\n `<div style=\"text-transform:uppercase;letter-spacing:.26em;font-size:13px;font-weight:600;color:${s.accent};margin-bottom:22px\">${kicker}</div>` +\n `<div style=\"font-family:${s.displayFont};font-weight:600;font-size:52px;line-height:1.08;letter-spacing:-.02em;color:${s.coverTitle};max-width:16ch\">${title}</div>` +\n (subtitle\n ? `<div style=\"margin-top:22px;font-size:19px;line-height:1.5;color:${s.coverTitle}b8;max-width:46ch\">${subtitle}</div>`\n : '') +\n `<div style=\"margin-top:44px;display:flex;align-items:center;gap:10px;color:${s.coverTitle}80;font-size:13px;letter-spacing:.02em\">` +\n `<span style=\"width:26px;height:1px;background:${s.accent}\"></span>${s.firmLabel}</div>`\n document.body.appendChild(el)\n requestAnimationFrame(() => (el.style.opacity = '1'))\n },\n { kicker, title, subtitle: subtitle ?? '', s: skin, instant: !!running }\n )\n await page.waitForTimeout(holdMs)\n }\n\n async function chapter(\n page: Page,\n card: { kicker: string; title: string; subtitle?: string },\n holdMs?: number\n ): Promise<void> {\n await cover(page, card, holdMs)\n await page.evaluate(() => {\n const el = document.getElementById('__cine_cover')\n if (el) el.style.pointerEvents = 'none'\n })\n }\n\n async function uncover(page: Page): Promise<void> {\n const running = Take.on(page)\n await page.evaluate((instant) => {\n const el = document.getElementById('__cine_cover')\n if (!el) return\n if (instant) return el.remove()\n el.style.opacity = '0'\n setTimeout(() => el.remove(), 520)\n }, !!running)\n running?.cardEnd()\n await page.waitForTimeout(560)\n }\n\n function lowerThird(page: Page, kicker: string, title: string, holdMs = 3200): void {\n Take.on(page)?.lowerThird(kicker, title, holdMs)\n }\n\n async function caption(page: Page, text: string, holdMs?: number): Promise<void> {\n const running = Take.on(page)\n if (running) running.captionStart(text)\n else\n await page.evaluate(\n (t) => (window as unknown as { __cine_cap?: (s: string) => void }).__cine_cap?.(t),\n text\n )\n const hold = holdMs ?? Math.min(4200, 900 + text.length * 45)\n await page.waitForTimeout(hold)\n }\n\n async function clearCaption(page: Page): Promise<void> {\n const running = Take.on(page)\n if (running) running.captionEnd()\n else\n await page.evaluate(() =>\n (window as unknown as { __cine_cap?: (s: string) => void }).__cine_cap?.('')\n )\n }\n\n async function beat(page: Page, ms = 650): Promise<void> {\n await page.waitForTimeout(ms)\n }\n\n async function glideTo(page: Page, target: string | Locator): Promise<Locator> {\n const running = Take.on(page)\n const start = running?.now() ?? 0\n const { loc, box } = await glide(page, target)\n if (running && box) running.record({ kind: 'point', start, box })\n return loc\n }\n\n async function click(page: Page, target: string | Locator): Promise<void> {\n const running = Take.on(page)\n const start = running?.now() ?? 0\n const { loc, box } = await glide(page, target)\n await loc.click()\n await page.waitForTimeout(260)\n if (running && box) running.record({ kind: 'click', start, end: running.now(), box })\n }\n\n async function type(page: Page, target: string | Locator, text: string): Promise<void> {\n const running = Take.on(page)\n const start = running?.now() ?? 0\n const { loc, box } = await glide(page, target)\n await loc.click()\n await loc.fill('')\n await loc.pressSequentially(text, { delay: 42 })\n await page.waitForTimeout(240)\n if (running && box) running.record({ kind: 'type', start, end: running.now(), box })\n }\n\n async function focusOn(\n page: Page,\n target: string | Locator,\n label?: string,\n {\n holdMs = 2200,\n callout = true,\n mode,\n }: { holdMs?: number; callout?: boolean; mode?: FocusEvent['mode'] } = {}\n ): Promise<void> {\n const running = Take.on(page)\n const start = running?.now() ?? 0\n const { box } = await glide(page, target)\n await page.waitForTimeout(holdMs)\n if (running && box)\n running.record({ kind: 'focus', label, start, end: running.now(), box, callout, mode })\n }\n\n async function readDown(\n page: Page,\n target: string | Locator,\n scrolls = 3,\n pauseMs = 1600\n ): Promise<void> {\n const running = Take.on(page)\n const start = running?.now() ?? 0\n const { box } = await glide(page, target)\n for (let i = 0; i < scrolls; i += 1) {\n await page.mouse.wheel(0, 320)\n await beat(page, pauseMs)\n }\n await page.mouse.wheel(0, -320 * scrolls)\n await beat(page, 500)\n if (running && box) running.record({ kind: 'read', start, end: running.now(), box })\n }\n\n async function login(page: Page, opts: { show?: boolean; caption?: string } = {}): Promise<void> {\n if (!config.creds) throw new Error('createCinematic: pass creds to sign in')\n await page.goto(loginPath)\n if (opts.show === false) {\n await page.getByTestId(ids.email).fill(config.creds.email)\n await page.getByTestId(ids.password).fill(config.creds.password)\n await page.getByTestId(ids.submit).click()\n await page.waitForURL(appUrlPattern, { timeout: 45_000 })\n return\n }\n await caption(page, opts.caption ?? `${b.firmLabel} — signing in.`, 1600)\n await type(page, ids.email, config.creds.email)\n await type(page, ids.password, config.creds.password)\n await click(page, ids.submit)\n await page.waitForURL(appUrlPattern, { timeout: 45_000 })\n await beat(page, 800)\n }\n\n return {\n take,\n installStage,\n cover,\n chapter,\n uncover,\n lowerThird,\n caption,\n clearCaption,\n beat,\n glideTo,\n click,\n type,\n focusOn,\n readDown,\n login,\n }\n}\n"]}
@@ -3,8 +3,8 @@
3
3
 
4
4
  var chunkQI6AIHWP_cjs = require('../chunk-QI6AIHWP.cjs');
5
5
  var chunkOUW6G4O2_cjs = require('../chunk-OUW6G4O2.cjs');
6
- require('../chunk-C54XEN5T.cjs');
7
6
  require('../chunk-MHVNT4J3.cjs');
7
+ require('../chunk-C54XEN5T.cjs');
8
8
  require('../chunk-DES3K4SD.cjs');
9
9
 
10
10
 
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  export { ApplyLabelButton, ApplyLabelDialog, DEFAULT_APPLY_LABEL_DIALOG_LABELS, DEFAULT_RELEVANCE_STEPS, DEFAULT_SEARCH_BAR_LABELS, DEFAULT_SEARCH_EMPTY_STATE_LABELS, DEFAULT_SEARCH_GROUP_HEADER_LABELS, DEFAULT_SEARCH_NO_RESULTS_LABELS, DEFAULT_SEARCH_PAGINATION_LABELS, DEFAULT_SEARCH_TOTALS_LABELS, DOCUMENT_SEARCH_NOUNS, Highlight, RelevanceThreshold, SearchBar, SearchControlsBar, SearchEmptyState, SearchErrorBanner, SearchGroupCard, SearchGroupHeader, SearchNoResults, SearchPageBody, SearchPageFrame, SearchPageHeader, SearchPagination, SearchPillToggle, SearchResultList, SearchResultsInner, SearchResultsMain, SearchToolbarRow, SearchTotalsHeadline, getPageNumbers, highlightTerms, searchNouns, splitByTerms, stripMarkdownLinks } from '../chunk-2MJWWPHY.js';
3
3
  export { DEFAULT_SEARCH_HIT_LABELS, SearchHit } from '../chunk-A2YAC22G.js';
4
- import '../chunk-76JDDMSP.js';
5
4
  import '../chunk-7F6CBP3Z.js';
5
+ import '../chunk-76JDDMSP.js';
6
6
  import '../chunk-VUNV25KB.js';
7
7
  //# sourceMappingURL=index.js.map
8
8
  //# sourceMappingURL=index.js.map